You mention that you know about PlaySound
. One of the it's flags (SND_MEMORY
) will allow you to play a WAVE that is already loaded into memory, i.e. a buffer that you have created yourself. As long as the buffer has the appropriate WAVE header, whatever you you put in there should play through the speakers.
The header is a 44 byte block that is fairly straight forward
struct WaveHeader
{
DWORD chunkID; // 0x52494646 "RIFF" in big endian
DWORD chunkSize; // 4 + (8 + subChunk1Size) + (8 + subChunk2Size)
DWORD format; // 0x57415645 "WAVE" in big endian
DWORD subChunk1ID; // 0x666d7420 "fmt " in big endian
DWORD subChunk1Size; // 16 for PCM
WORD audioFormat; // 1 for PCM
WORD numChannels; // 1 for mono, 2 for stereo
DWORD sampleRate; // 8000, 22050, 44100, etc...
DWORD byteRate; // sampleRate * numChannels * bitsPerSample/8
WORD blockAlign; // numChannels * bitsPerSample/8
WORD bitsPerSample; // number of bits (8 for 8 bits, etc...)
DWORD subChunk2ID; // 0x64617461 "data" in big endian
DWORD subChunk2Size; // numSamples * numChannels * bitsPerSample/8 (this is the actual data size in bytes)
};
You'd set up your buffer with something similar to:
char *myBuffer = new char[sizeof(WaveHeader) + myDataSize];
WaveHeader *header = (WaveHeader*)myBuffer;
// fill out the header...
char *data = myBuffer + sizeof(WavHeader);
// fill out waveform data...
So you use it something like:
PlaySound(myBuffer, NULL, SND_MEMORY | SND_ASYNC);
I'm assuming that you're going to be using you generated sound for the lifetime of you app. If you aren't, be careful with that SND_ASYNC
flag. That is, don't go freeing the buffer directly after you call PlaySound (while it is still in use).
MSDN PlaySound Docs
A page with more detail on the WAV header
DirectX also supports playing audio from in-memory buffers and is a much more powerful API, but it maybe overkill for what you need to do :)