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

War es hilfreich?

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.

irrKlang , BASS.net (unter "andere APIs"), NAudio , MUSCHEL , G3D , und andere, die dies tun können.

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
scroll top