Loading a Wave From Disk

My engine has the really nice ability to reload all the graphics and sounds whenever you press F3 without restarting the game. This allows for rapid iteration because you can quickly test new graphic or audio assets. The only problem it had is that when a sound was loaded from disk using mmioOpen() the mmio system would not let go of that file! This was driving me nuts because I was forced to shut down and restart the game every single time I wanted to audition new sounds. I finally fixed the issue and it’s a pretty simple solution that I hope others will benefit from.

So the old way I was loading a sound was with this super simple one line of code…

// this is the easy way but it won't release the file handle
m_hmmio = mmioOpen(filename, NULL, MMIO_ALLOCBUF|MMIO_READ);

Like I said that way works fine if you don’t care about being preventing from changing the file. I looked into mmioOpen(), searched online, and tried some things like removing the MMIO_ALLOCBUF but I can’t seem to get it to release the file. Sure, I could just call mmioClose() to release the file but then the sound won’t stay loaded which is kind of the whole point. I discovered that instead of letting mmioOpen open file directly, I can open it myself and copy the entire file to memory then close the file and have mmio point to the copy. Here is the solution…

// try to read a local wave file from disk
fstream waveFile(filename, fstream::in | fstream::binary);
if (!waveFile.is_open())
	return;

// get the file size
waveFile.seekg(0, std::ios::end);
DWORD dwSize = (DWORD)waveFile.tellg();
waveFile.seekg(0, std::ios::beg);

// create the buffer
m_pResourceBuffer = new CHAR[dwSize];

// copy the file into memory
waveFile.read(m_pResourceBuffer, dwSize);

// close the file so we can still make changes and reload it
waveFile.close();

// open the mmio from our memory buffer
MMIOINFO mmioInfo;
ZeroMemory(&mmioInfo, sizeof(mmioInfo));
mmioInfo.fccIOProc = FOURCC_MEM;
mmioInfo.cchBuffer = dwSize;
mmioInfo.pchBuffer = (CHAR*)m_pResourceBuffer;
m_hmmio = mmioOpen(NULL, &mmioInfo, MMIO_ALLOCBUF | MMIO_READ);
This entry was posted in Game Dev and tagged , , , . Bookmark the permalink.

Leave A Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.