Question

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 d'utilisateur et mathématiques?

Par « données de forme d'onde » Je veux dire SPL Valeurs (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 de flux arrangement tampon.

Notez que cela doit être en direct / en temps réel, donc il suffit de créer un fichier .wav puis jouer ce ne sera pas suffisant. VB.NET est préférable, mais C # est également acceptable.

Juste pour préciser:. Ce que je cherche est un simple exemple de code de travail

Était-ce utile?

La solution

Vous pouvez le faire en utilisant NAudio . Vous créez un flux qui découle de WaveStream et dans sa méthode Read surchargée, 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 permet de contrôler le temps d'attente.

Autres conseils

Comment jouer à partir d'un tableau de 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();
    }

Consultez ce fil sur le chargement des DirectSound tampon avec des données arbitraires et jouer .

Par commentaire: Oui, je sais. Vous aurez besoin de traduire le C ++ en C # ou VB.NET. Mais, le concept est ce qui est important. Vous créez un tampon DirectSound secondaire, puis l'utiliser pour diffuser sur votre tampon primaire et jouer.

IrrKlang , BASS.net (sous la rubrique "Autres API"), NAudio , CLAM, G3D , et d'autres qui peuvent le faire.

Je pense que vous aurez besoin d'utiliser DirectSound ( API DirectX ) pour cela. Il travaille à l'extérieur des tampons que vous pouvez remplir avec vos données générées.

Peut-être quelque chose comme cette (

J'ai ce code, mais vous devez avoir un code pour générer votre fichier wav dans la 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
scroll top