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? P>
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. P>
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. P>
juste pour clarifier: ce que je recherche est un exemple de code de travail simple. P>
6 Réponses :
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. p>
Peut-être quelque chose comme Ce ( Ici dans le chemin du retour) aidera p>
Consultez Ce fil sur le chargement DirectSound tampon avec des données arbitraires et la lecture . P>
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. P>
Eh bien c'est pas i> vb.net ou c #. En fait, cela n'a pas l'air de .NET du tout.
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. P>
J'ai enfin eu la chance d'essayer Naudio et c'est excellent. Merci pour le pointeur.
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
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 # i >.