Reputation: 54103
I'm making a game in native vc++ (not .Net)
I'm looking for a way to play a noise (maybe 8 bit or something) through the real speakers (not internal). I know about PlaySound, but I don't want to make my EXE big. I want to program the sound.
Is there an api way (kinda like Beep() ) but that plays through the real speakers?
Thanks
Upvotes: 4
Views: 7386
Reputation: 2015
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; // 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)
};
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(WaveHeader); //jumps to beginning of data
// 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 (OLD - not working now)
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 :)
Upvotes: 11
Reputation: 1578
My answer to another question could be helpfull, check it out here
I talk about an easy to use opensource api (The Synthesis Toolkit) that has classes to read/write wav files, and has easy to use wrapper classes to do realtime output to different drivers (wdm, asio, jack,...)
Imho it is easier to use than the winapi functions
Upvotes: 0
Reputation: 98984
While there are several possibilities on windows, one of the simplest is sndPlaySound():
mmsystem.h
winmm.lib
::sndPlaySound("sound.wav", SND_ASYNC|SND_NODEFAULT);
::sndPlaySound(NULL, NULL);
Of course there are other ways like mci and direct sound which might suit your needs better if you see more clearly what you need.
Upvotes: 1
Reputation: 488
I found this: http://www.xtremevbtalk.com/showthread.php?p=829281 it could be of some use to you
Upvotes: 0