Pregunta

¿Cómo puedo reproducir un sonido basado en los datos de forma de onda que mi programa .NET está generando a partir de las funciones de entrada de usuario y matemáticas?

Por "datos de forma de onda" me refiero a valores en una serie de tiempo de intervalo fijo SPL (nivel de presión sonora) (probablemente 44,1 kHz). Supongo que esto requiere algún tipo de streaming a disposición de tampón.

Tenga en cuenta, que esto tiene que ser vivo / en tiempo real, por lo que sólo la creación de un archivo .wav y luego jugar que no va a ser suficiente. se prefiere VB.NET, pero C # es aceptable también.

Solo para aclarar:. Lo que busco es un simple ejemplo de código de trabajo

¿Fue útil?

Solución

Puede hacer esto utilizando NAudio . Se crea una corriente que se deriva de WaveStream y en su método Read overriden, regresar tus muestras que se pueden generar sobre la marcha. Usted tiene control sobre el tamaño de las memorias intermedias utilizadas por la tarjeta de sonido que le da control sobre la latencia.

Otros consejos

¿Cómo se juega a partir de una serie de dobles

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

este hilo en carga hasta un DirectSound buffer con datos arbitrarios y jugarlo .

Por comentario: Sí, lo sé. Usted tendrá que traducir el C ++ en C # o VB.NET. Sin embargo, el concepto es lo importante. Se crea un búfer DirectSound secundaria y luego usarlo para transmitir a su memoria intermedia primaria y jugar.

IrrKlang , BASS.net (bajo "Otras API"), NAudio , CLAM , G3D , y otros que pueden hacer esto.

Creo que tendrá que utilizar DirectSound ( DirectX API) para eso. Funciona fuera de tampones que se podría llenar con sus datos generados.

Tal vez algo así como este ( aquí en forma de máquina de nuevo) ayudará

tengo este código, sino que tendrá que tener código para generar el archivo WAV en la memoria.

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top