Вы упоминаете, что знаете о PlaySound
. Один из его флагов (SND_MEMORY
) позволит вам воспроизвести WAVE, который уже загружен в память, то есть буфер, который вы создали сами. Пока в буфере есть соответствующий заголовок WAVE, все, что вы вставляете туда, должно воспроизводиться через динамики.
Заголовок является 44-байтовым блоком, который является довольно прямым
struct WaveHeader
{
DWORD chunkID; // 0x46464952 "RIFF" in little endian
DWORD chunkSize; // 4 + (8 + subChunk1Size) + (8 + subChunk2Size)
DWORD format; // 0x45564157 "WAVE" in little endian
DWORD subChunk1ID; // 0x20746d66 "fmt " in little endian
DWORD subChunk1Size; // 16 for PCM
WORD audioFormat; // 1 for PCM, 3 fot EEE floating point , 7 for μ-law
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; // 0x61746164 "data" in little endian
DWORD subChunk2Size; // numSamples * numChannels * bitsPerSample/8 (this is the actual data size in bytes)
};
Вы бы настроили свой буфер с чем-то похожим на:
char *myBuffer = new char[sizeof(WaveHeader) + myDataSize];
WaveHeader *header = (WaveHeader*)myBuffer;
// fill out the header...
char *data = myBuffer + sizeof(WaveHeader); //jumps to beginning of data
// fill out waveform data...
Итак, вы используете что-то вроде:
PlaySound(myBuffer, NULL, SND_MEMORY | SND_ASYNC);
Я предполагаю, что вы будете использовать сгенерированный звук на протяжении всего срока службы вашего приложения. Если нет, будьте осторожны с этим SND_ASYNC
флагом. То есть не освобождайте буфер сразу после вызова PlaySound (пока он еще используется).
Документы MSDN PlaySound
Страница с более подробной информацией о заголовке WAV ( OLD - сейчас не работает)
DirectX также поддерживает воспроизведение звука из буферов в памяти и является гораздо более мощным API, но, возможно, излишним для того, что вам нужно сделать:)