2009-07-05 7 views
7

Wie kann ich einen Sound wiedergeben, der auf Wellenformdaten basiert, die mein .NET-Programm aus Benutzereingaben und mathematischen Funktionen generiert?Abspielen von Sound in .NET mit generierten Wellenformdaten

Mit "Wellenformdaten" meine ich SPL (Schalldruckpegel) Werte in einem festen Intervall Zeitreihe (wahrscheinlich 44,1 kHz). Ich nehme an, dass dies eine Art von Streaming-Puffer-Anordnung erfordert.

Beachten Sie, dass dies Live/Echtzeit sein muss, also nur eine .wav-Datei zu erstellen und dann zu spielen, wird nicht ausreichen. VB.NET ist bevorzugt, aber C# ist auch akzeptabel.

Nur um zu verdeutlichen: Was ich suche, ist ein einfaches Arbeitscodebeispiel.

+0

Ich bin endlich dazu gekommen, die NAudio-Lösung auszuprobieren, und sie ist ausgezeichnet! So viel besser und einfacher als ich befürchtet hatte, hätte ich es schon lange ausprobiert. – RBarryYoung

+1

Eine funktionalere Antwort auf diese Frage finden Sie in der Frage Stack Overflow * [NAudio spielt eine Sinuswelle für x Millisekunden mit C#] (http://stackoverflow.com/questions/5485577) *. –

Antwort

4

Sie können dies mit NAudio tun. Sie erstellen einen Stream, der von WaveStream abgeleitet ist, und geben in der überschriebenen Read-Methode Ihre Samples zurück, die Sie im laufenden Betrieb generieren können. Sie haben die Kontrolle über die Größe der von der Soundkarte verwendeten Puffer, mit denen Sie die Latenz steuern können.

+0

Ich habe endlich eine Chance bekommen, NAudio zu probieren und es ist ausgezeichnet. Danke für den Zeiger. – RBarryYoung

0

Ich denke, Sie müssen dafür DirectSound (DirectX API) verwenden. Es arbeitet Puffer aus, die Sie mit Ihren generierten Daten füllen könnten.

Vielleicht so etwas wie this (here in Rückweg Maschine) wird

1

überprüfen helfen this thread beim Laden eines DirectSound Puffer mit beliebigen Daten und spielen es.

Pro Kommentar: Ja, ich weiß. Sie müssen das C++ in C# oder VB.NET übersetzen. Aber das Konzept ist wichtig. Sie erstellen einen sekundären DirectSound-Puffer und verwenden ihn dann, um zu Ihrem primären Puffer zu streamen und zu spielen.

+0

Nun, das ist * nicht * VB.net oder C#. Tatsächlich sieht es überhaupt nicht nach .Net aus. – RBarryYoung

3

How to play from an array of doubles

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(); 
    } 
0

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