-1

I am trying to load a .wav file into memory so that I can play it using the PlaySound function.

Currently, I am able to play the sound with this line of code.

PlaySound(TEXT("C:\\DEV\\beep-07a.wav"), NULL, SND_FILENAME);

The problem is I am also displaying graphics when the sound is made, and when the sound plays, the graphics freeze while it is being played. I am assuming that this is due to the fact that the .wav file is being read from the disk each time it is played, and not from memory.

I did some searching and see that I can either load the file directly into my memory buffer or can use a resource file to do this, but I was unable to find any good resources on how to do this, so any help is greatly appreciated!

wovano
  • 4,543
  • 5
  • 22
  • 49
Spencer349
  • 37
  • 8
  • Do you execute `PlaySound` on main thread? If you did that, try to do music playback on another thread use `CreateThread` – Neo Ko Jul 11 '22 at 20:01
  • https://learn.microsoft.com/en-us/windows/win32/multimedia/playing-wave-resources – Sneftel Jul 11 '22 at 20:11

3 Answers3

1

If you want to resolve the issue of PlaySound blocking your thread, you can adjust your call like so

PlaySound(..., SND_FILENAME | SND_ASYNC);

From the documentation, including this will change the behaviour such that

The sound is played asynchronously and PlaySound returns immediately after beginning the sound. To terminate an asynchronously played waveform sound, call PlaySound with pszSound set to NULL.

If performance is a concern, you can bundle the sound into a resource file which you can link with your program, and instead load your resource by an ID rather than file path.

mitch_
  • 1,048
  • 5
  • 14
  • 1
    I made that change and now the graphics don't freeze but there is a long delay (around 2 seconds) from when I press the key to when the sound plays. – Spencer349 Jul 11 '22 at 20:27
  • Testing with a local file on my machine has no noticeable delay even when reading from the filesystem. Are you reading from a network drive or hard drive that has a noticeable amount of latency? Or, does your audio file have a period of silence at the start? – mitch_ Jul 11 '22 at 20:37
  • 1
    "*you can bundle the sound into a resource file*" - or into a memory buffer (played with `SND_MEMORY`) if you want the `.wav` to stay as a separate file instead of embedding it in the `.exe` file (ie, if you want users to be able to use custom `.wav` files). – Remy Lebeau Jul 11 '22 at 21:02
  • @mitch_ So I went and tried it again and noticed something this time. I have different sections of my graphics rendering, one section where I am just rendering a static image and another where I am rendering three circles that are controlled by an external device. When I use your version of the PlaySound call on and make the sound on the static image screen, it works perfectly, but when I make the sound while rendering the three circles, there is a delay between the keypress and the production of the sound. – Spencer349 Jul 12 '22 at 18:39
1

There are existing questions for reading a file into a memory buffer, such as:

C++ read the whole file in buffer
Reading file into buffer
How to read a binary file into a vector of unsigned chars
just to name a few...

Once you have the WAV file data in memory, simply pass a pointer to the WAV data in memory to PlaySound(), specifying the SND_MEMORY flag, eg:

PlaySound((LPCTSTR)data_pointer, NULL, SND_MEMORY);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks! I was able to do this (using the first link) and play the sound from the memory buffer but unfortunately that did not help. I am having the same issue of the graphics freezing when I play the sound. I think I need to figure out how to play the sound in it's own thread, I was able to create a thread for sound but am still working on playing the sound within it. – Spencer349 Jul 12 '22 at 19:50
  • "*I am having the same issue of the graphics freezing when I play the sound*" - I never said this would solve that. That issue happens when you play the sound *synchronously* on the same thread that handles the graphics. So either 1) play the sound *asynchronously*, or 2) move the playback to a different thread. – Remy Lebeau Jul 12 '22 at 20:14
  • Thank you for the clarification! Playing the sound asynchronously still ends up with the delay issue I mentioned so I'm going to try and get it to work in a different thread, appreciate all the help! – Spencer349 Jul 12 '22 at 20:23
0

I'm not sure why, but just using sndPlaySound instead of PlaySound fixed the latency and all of the freezing issues I was having with my graphics without needing to create a new thread or even having to load the file into my memory buffer. This was the line of code I ended up using.

 sndPlaySound(TEXT("C:\\DEV\\beep-07a.wav"), SND_ASYNC | SND_NOSTOP);
Spencer349
  • 37
  • 8
  • Hi ,glad to know you've found the solution to resolve this issue! Please consider accepting it as an answer to change its status to Answered. Just a reminder :) – Minxin Yu - MSFT Jul 26 '22 at 06:51