Sound abspielen in .NET erzeugten Wellenformdaten unter Verwendung von
Frage
Wie kann ich einen Ton basierend auf Wellenformdaten wiedergeben, die mein .NET-Programm wird von der Benutzereingabe und mathematischen Funktionen zu erzeugen?
Mit „Wellenformdaten“ meine ich SPL (Schalldruckpegel) Werte in einem festen Intervall zeitseriellen (vermutlich 44,1 kHz). Ich nehme an, dass dies eine Art erfordert Pufferanordnung von Streaming.
Beachten Sie, dass diese live / Echtzeit sein muss, so dass nur eine .wav-Datei erstellen und dann, dass das Spiel nicht ausreichen werden. VB.NET wird bevorzugt, aber C # ist auch akzeptabel.
Nur um zu klären. Was ich suche ist ein einfaches Arbeitscodebeispiel
Lösung
Sie können dies tun, indem NAudio . Sie erstellen einen Stream, der von Wavestream und in seiner überschriebenen Methode Read leitet, können Sie Ihre Proben zurück, die Sie im laufenden Betrieb erzeugen können. Sie haben die Kontrolle über die Größe der Puffer durch die Soundkarte verwendet, die Sie über die Latenz Kontrolle gibt.
Andere Tipps
Wie aus einem Array von Doppel
spielen PlayerEx pl = new PlayerEx();
private static void PlayArray(PlayerEx pl)
{
double fs = 8000; // sample freq
double freq = 1000; // desired tone
short[] mySound = new short[4000];
for (int i = 0; i < 4000; i++)
{
double t = (double)i / fs; // current time
mySound[i] = (short)(Math.Cos(t * freq) * (short.MaxValue));
}
IntPtr format = AudioCompressionManager.GetPcmFormat(1, 16, (int)fs);
pl.OpenPlayer(format);
byte[] mySoundByte = new byte[mySound.Length * 2];
Buffer.BlockCopy(mySound, 0, mySoundByte, 0, mySoundByte.Length);
pl.AddData(mySoundByte);
pl.StartPlay();
}
Schauen Sie sich diesen Thread auf Einladendes ein DirectSound- mit beliebigen Datenpuffer und es spielen .
Per Kommentar: Ja, ich weiß. Sie müssen die C ++ in C # oder VB.NET übersetzen. Aber ist das Konzept, was wichtig ist. Sie erstellen einen sekundären Directsound-Puffer und dann verwenden, um Ihre primären Puffer zu streamen und spielen.
Ich denke, Sie DirectSound- ( DirectX API) für die. Es funktioniert aus Puffern, die Sie mit Ihrem generierten Daten füllen könnte.
Vielleicht so etwas wie dieser (
Ich habe diesen Code, aber Sie werden Code haben, um Ihre WAV-Datei im Speicher zu erzeugen. 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