// JP opened flex table

Click to See Complete Forum and Search --> : Wav file doesn't play fast enough


Bluefox815
June 23rd, 2008, 09:15 PM
I made a program that uses wav files, but they don't load and play fast enough (PlaySound("file.wav", NULL, SND_FILENAME | SND_ASYNC) in windows.h). Is there a way I can load a wav file into memory (as a variable), and then play it next to instantaneously? That is all I need to do, and I've seen many examples of which I don't understand involving wav files in memory, so if someone could help me I'd greatly appreciate it!

Marc G
June 24th, 2008, 08:12 AM
Take a look at Playing WAVE Resources (http://msdn.microsoft.com/en-us/library/ms712876(VS.85).aspx), should give you an idea how to play from memory.

Ali Imran
June 24th, 2008, 11:05 AM
Another link also might help.

http://www.apitalk.com/document.php?id=1184208002_1

regards

Bluefox815
June 24th, 2008, 02:08 PM
Marc G, I've seen the resource method before, but I have a question. When I create a resource for a wav file, is it included in the exe when I link or something? This is what confuses me, as I don't know how to use resources.

EDIT: Nevermind, I see this is not the case, I can see how it works now, thank you. I'll post back whether it worked right for me or not. And Ali Imran, your link doesn't load for me.

VladimirF
June 24th, 2008, 03:31 PM
Is there a way I can load a wav file into memory (as a variable), and then play it next to instantaneously?If you are still interested in that, use SND_MEMORY flag instead of SND_MEMORY:
HANDLE hFile = ::CreateFile(L"c:\\file.wav", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
DWORD nLength = ::GetFileSize(hFile, 0);
DWORD nRead(0);
BYTE* pBuffer = new BYTE[nLength];
::ReadFile(hFile, pBuffer, nLength, &nRead, 0);
::CloseHandle(hFile);
PlaySound((LPCTSTR)pBuffer, NULL, SND_MEMORY | SND_SYNC);
delete[] pBuffer;
Note: add error checking; if you use SND_ASYNC, make sure that your buffer is valid for the duration of the sound (or it could crash).

Bluefox815
June 24th, 2008, 04:34 PM
Thanks Vladimir, your code works great, but I still have a problem. I have the file loaded into memory, but it still takes about one full second to load(which is good because it used to be about 4-5 seconds) but I want it to be faster than that, so the sound plays instantly. I read somewhere that PlaySound has to create a new thread for the sound each time and then destroys the thread. Is there a different function or set of functions I can use to read from memory quicker? (waveOut() or sndPlaySound() possibly?)

VladimirF
June 24th, 2008, 05:34 PM
Is there a different function or set of functions I can use to read from memory quicker? (waveOut() or sndPlaySound() possibly?)Not sure about waveOut, but sndPlaySound "is being maintained for backward compatibility", so I don't think it will do better than PlaySound().
So you are saying that after you read your file, it takes a second from the call to PlaySound() to the actual sound? What flags did you use? SND_ASYNC? Could you try SND_SYNC? How big is your file? How good is your computer?

Bluefox815
June 24th, 2008, 05:47 PM
Not sure about waveOut, but sndPlaySound "is being maintained for backward compatibility", so I don't think it will do better than PlaySound().
So you are saying that after you read your file, it takes a second from the call to PlaySound() to the actual sound? What flags did you use? SND_ASYNC? Could you try SND_SYNC? How big is your file? How good is your computer?

Ok, it does take about one second for the sound to play after my call to PlaySound(), I'm using SND_ASYNC because the sound is supposed to play when a key is pressed, and stop when the key is lifted, and SND_SYNC caused the sound to play when the key was lifted. Each file is around 410 kb, I have 1.63 GHz CPU and 224 mb RAM (with windows XP pagefiling at around 600 mb)

What I did is I made a BYTE** to store my wav data (I have multiple sounds) and it stays loaded until the application is closed. All sounds play correctly, everything works exactly as expected (with SND_ASYNC) it just takes too long to play each sound.

EDIT: I have just tried SND_SYNC, and it does play instantly, so now my only problem is making the sound stop when I want it to.

Would I be able to use multi-threading to launch an asynchronous thread which holds the call to PlaySound() that I can terminate causing PlaySound to abruptly be interrupted? (I wouldn't think that any memory stream closing would be absolutely necessary, as it is only reading and not writing, unless this causes a 'memory could not be read' error later on)
If so, would someone be able to give me a good link with sample code that shows how to use the Win32 threading API?

//JP added flex table