Play a wav data

https://www.cplusplus.com/forum/beginner/166954/

Hello community. I hope that all is good for you. At the link above I read an interesting way in order to create from scratch a wav file. The code which is available at the end of the thread works as expected - and it generates a wav file according to its header. Now I have a question, but even searching on the web I cannot find any answer. I expose my request.
If I can write some data, I guess I could play them without any file creation. In the previous code, we needed to use PlaySound() or mciSendString() so as to play sound after its creation. If I don't want to open an external file, is there a way to play a buffer with wav data directly ?
Last edited on
searching on the web I cannot find any answer. I expose my request.

https://stackoverflow.com/questions/65851460/playing-sound-from-a-memory-buffer-in-pure-winapi

It really wasn't hard to find, the meta search I used:

https://duckduckgo.com/?q=winapi+playing+in+memory+wav+file&t=ffsb&ia=web

PlaySound() can play from a "resource" embedded in your EXE file as well as from a memory buffer.

To play Wave sound from an embedded resource:
1
2
HMODULE mainModule = GetModuleHandle(NULL); // <-- get handle to the executing EXE file
PlaySound(TEXT("YOUR_RESOURCE_NAME_HERE"), mainModule, SND_RESOURCE);


You can use a tool like ResourceHacker to add/modify WAVE resources in your EXE file:
http://www.angusj.com/resourcehacker/

To play Wave sound from a "raw" memory buffer you can do:
1
2
BYTE *ptr = get_pointer_to_wave();
PlaySound((LPCTSTR)ptr, NULL, SND_MEMORY);
Last edited on
An embedded resource wave is pre-created, what was requested was if it is possible to create a wave resource "on the fly" at run-time and be able to play it.

Prepend a WAV header to the start of the raw data and then pass a pointer to that chunk of data to PlaySound().

Playing an already created WAV, either as a disk file or embedded resource, is a lot easier to manage.
The second example of PlaySource() with flag SND_MEMORY does exactly that.
Hello. Thank you for your answers. Obviously my requests on Google were pretty bad. I missed the key word "memory" using instead "buffer". This is exactly what I need :)

There is a clear explanation here too :
http://www.cplusplus.com/forum/beginner/88542/

One hour after my previous post :/

I cannot point to the buffer and I don't understand why :

1
2
3
4
5
6
7
WaveGenerator wg(SAMPLE_RATE, SAMPLE_WIDTH, DURATION);
static uint32_t buff[BUFF_SIZE];
memset(&buff[0], (uint32_t)0, BUFF_SIZE); // init
// create wave and fill my buffer
wg.sineTransform(&buff[0], (and other stuff));
// trying to point at start of the buffer
PlaySound((LPCTSTR)(&buff[0]), NULL, SND_MEMORY);
Last edited on
What do you mean with "I cannot point to the buffer" ??

I'm using this code and it works fine:
1
2
3
4
if(const unsigned char *data = get_sound_from_cache(name))
{
    return PlaySoundW(LPCWSTR(data), NULL, (SND_MEMORY | (bAsync ? SND_ASYNC : SND_SYNC)));
}


But be aware that the buffer needs to contain a proper WAVE structure, not just "raw" PCM samples:
http://soundfile.sapp.org/doc/WaveFormat/

(pretty much a complete WAVE file, just mapped into memory)
Last edited on
But be aware that the buffer needs to contain a proper WAVE structure, not just "raw" PCM samples

You are right. I have my filled buffer, but I don't hear anything. However the same buffer, but saved as a file works well with mciSendString() - not PlaySound(). PCM is the key. Thanks for the link ++
Last edited on
You may use a library like libsndfile to create a WAVE file from "raw" audio samples:
http://www.mega-nerd.com/libsndfile/

Use function sf_open_virtual() in order to open a "virtual" WAVE file, which allows you to read WAVE file data from a memory buffer, or write WAVE file data to a memory buffer, as you can provide your own SF_VIRTUAL_IO.
Last edited on
That link to libsndfile is a bit outdated, here's a link with newer library versions:
http://libsndfile.github.io/libsndfile/

Coincidentally it is a library available by vcpkg.
I would definitely encourage newer programmers to write their own .wav readers & writers. Reading binary files correctly is a very important skill, and .wav is about as simple a format as you're likely to find.
Topic archived. No new replies allowed.