Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play sound in .NET using generated waveform data

How can I play a sound based on waveform data that my .NET program is generating from user input and mathematical functions?

By "waveform data" I mean SPL (sound pressure level) values in a fixed interval time-series (probably 44.1 kHz). I presume that this requires some kind of streaming buffer arrangement.

Note, that this has to be live/real-time, so just creating a .wav file and then playing that will not be sufficient. VB.NET is preferred, but C# is acceptable also.

Just to clarify: What I am looking for is a simple working code example.

like image 898
RBarryYoung Avatar asked Jul 05 '09 16:07

RBarryYoung


4 Answers

You can do this using NAudio. You create a stream that derives from WaveStream and in its overriden Read method, you return your samples which you can generate on the fly. You have control over the size of the buffers used by the soundcard which gives you control over the latency.

like image 86
Mark Heath Avatar answered Nov 10 '22 04:11

Mark Heath


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();
    }
like image 3
Basil Avatar answered Nov 10 '22 03:11

Basil


Check out this thread on loading up a DirectSound buffer with arbitrary data and playing it.

Per comment: Yes, I know. You will need to translate the C++ into C# or VB.NET. But, the concept is what's important. You create a secondary DirectSound buffer and then use it to stream over to your primary buffer and play.

like image 1
JP Alioto Avatar answered Nov 10 '22 05:11

JP Alioto


IrrKlang, BASS.net (under "Other APIs"), NAudio, CLAM, G3D, and others that can do this.

like image 1
Infro Avatar answered Nov 10 '22 05:11

Infro