7
votes

Jouer au son dans .NET à l'aide de données de forme d'onde générée

Comment puis-je jouer un son basé sur des données de forme d'onde que mon programme .NET génère des fonctions d'entrée et de mathématiques de l'utilisateur?

Par "Données de forme d'onde" Je veux dire SPL (niveau de pression acoustique) dans une série de temps d'intervalle fixe (probablement 44,1 kHz). Je présume que cela nécessite une sorte d'arrangement tampon en streaming.

note, que cela doit être en direct / en temps réel, alors créez un fichier .wav, puis de jouer cela ne suffira pas. Vb.net est préféré, mais c # est également acceptable.

juste pour clarifier: ce que je recherche est un exemple de code de travail simple.


2 commentaires

Je suis enfin arrivé à essayer la solution Naudio et c'est excellent! Tellement mieux et plus facile que craint que j'aurais vraiment dû l'avoir essayé depuis longtemps.


Une réponse plus opérationnelle à cette question est dans la question de la pile de débordement Naudio jouant une onde sinusoïdale pour x millisecondes en utilisant c # .


6 Réponses :


0
votes

Je pense que vous devrez utiliser DirectSound ( DirectX API) pour cela. Il fonctionne des tampons sur lesquels vous pourriez remplir avec vos données générées.

Peut-être quelque chose comme Ce ( Ici dans le chemin du retour) aidera


0 commentaires

1
votes

Consultez Ce fil sur le chargement DirectSound tampon avec des données arbitraires et la lecture .

Par commentaire: Oui, je sais. Vous devrez traduire le C ++ en c # ou vb.net. Mais, le concept est ce qui est important. Vous créez un tampon DirectSound secondaire, puis utilisez-le pour diffuser votre tampon principal et votre jeu.


1 commentaires

Eh bien c'est pas vb.net ou c #. En fait, cela n'a pas l'air de .NET du tout.



4
votes

Vous pouvez le faire en utilisant Naudio . Vous créez un flux qui dérive de WaveStream et dans sa méthode de lecture de remplacement, vous retournez vos échantillons que vous pouvez générer à la volée. Vous avez le contrôle sur la taille des tampons utilisés par la carte son qui vous donne le contrôle sur la latence.


1 commentaires

J'ai enfin eu la chance d'essayer Naudio et c'est excellent. Merci pour le pointeur.



1
votes

IGNLLANG , BASS.NET (sous" Autres API "), Nadio , clam , G3D et d'autres qui peuvent le faire.


0 commentaires


0
votes

J'ai ce code mais vous devrez avoir du code pour générer votre fichier WAV en mémoire.

Option Strict Off
Option Explicit On
Imports Microsoft.DirectX.DirectSound
Imports Microsoft.DirectX
Imports System.Threading

Public Class Form1
Const SRATE As Integer = 44100
Const FREQ As Integer = 440
Const DUR As Integer = 1

Private dsDesc As BufferDescription
Private wvFormat As WaveFormat
Private DS As Device

Dim SecondaryBuffer As Microsoft.DirectX.DirectSound.SecondaryBuffer
Dim BufferDescription As Microsoft.DirectX.DirectSound.BufferDescription
Dim DXFormat As Microsoft.DirectX.DirectSound.WaveFormat
Dim sbuf(DUR * SRATE) As Short


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Show()
    DS = New Microsoft.DirectX.DirectSound.Device
    DS.SetCooperativeLevel(Me, CooperativeLevel.Normal)
    wvFormat.FormatTag = WaveFormatTag.Pcm
    wvFormat.Channels = 1
    wvFormat.SamplesPerSecond = SRATE
    wvFormat.BitsPerSample = 16
    wvFormat.AverageBytesPerSecond = 2 * SRATE
    wvFormat.BlockAlign = 2
    dsDesc = New BufferDescription(wvFormat)
    dsDesc.BufferBytes = 2 * DUR * SRATE
    dsDesc.Flags = 0
    Dim buff1 = PlayWave(400)
    Dim buff2 = PlayWave(600)
    buff1 = PlayWave(400)
    buff1.Play(0, Microsoft.DirectX.DirectSound.BufferPlayFlags.Default)
    Thread.Sleep(1000)
    buff1 = PlayWave(600)
    buff1.Play(0, Microsoft.DirectX.DirectSound.BufferPlayFlags.Default)
    ' End
End Sub
Function PlayWave(FREQ As Integer) As SecondaryBuffer
    ' create a buffer
    Dim dsBuffer As SecondaryBuffer
    dsBuffer = New SecondaryBuffer(dsDesc, DS)
    Dim sbuf(DUR * SRATE) As Short
    ' create tone                
    For i As Integer = 0 To DUR * SRATE
        sbuf(i) = CShort(10000 * Math.Sin(2 * Math.PI * FREQ * i / SRATE))
    Next
    ' copy to buffer
    dsBuffer.Write(0, sbuf, LockFlag.EntireBuffer)
    Return dsBuffer
End Function


0 commentaires