IDirectSound8::CreateSoundBuffer() - Invalid call?

Started by
14 comments, last by InsaneBoarder234 17 years, 8 months ago
One thing I noticed: You said that after loading the file, wfmt.cbSize = 12. Which means that in addition to the size of the WAVEFORMATEX structure, there are 12 more bytes of data. But you had LoadWavFile() load all this data into a WAVEFORMATEX structure, which doesn't have those 12 extra bytes. Which means that you're writing to memory that you shouldn't be; by itself this is bad, and that extra 12 bytes is probably getting altered before or while you pass the wfmt structure to DirectSound. When DirectSound tries to get info from those 12 bytes, it's all corrupt, so it issues an invalid call.

What those 12 bytes are for, I don't know. It's apparently not a WAVEFORMATEXTENSIBLE, since that should add 22 bytes extra, I believe. Perhaps the cbSize member should be 0, but you simply never initialized it properly?
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Advertisement
Also, it seems that your dsbd.dwBufferBytes, wfmt.nChannels, wfmt.nSamplesPerSec, wfmt.nAvgBytesPerSec, wfmt.nBlockAlign, and wfmt.wBitsPerSample completley disagree.

If there are indeed an average of 2000 bytes per second, and there are a total of 1976 bytes, then that means that your file is 0.988 seconds long. If there is one channel and each block is 1 byte, then your bits per sample should be 8, not 0. And if you have 1 byte per sample/block, then you should have 2000 samples per second, to match your bytes per second, instead of 11025. Because otherwise, if your file is actually 0.988 seconds long, and you have 11025 samples per second, then you should have ~10893 samples, and thus ~10893 bytes.

So it seems that the LoadWavFile() is doing a poor job of initializing the data in wfmt.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Can you post the code to the LoadWAVFile() function? In addition, DSBUFFERDESC::dwSize should equal sizeof(DSBUFFERDESC).
Anthony Rufrano
RealityFactory 2 Programmer
Here is the source for the LoadWav function.
m_dsbd is the DSBUFFERDESC object.
m_wfmt is the WAVEFORMATEX object.

bool SoundLoader::LoadWav(std::string sFilename){	HMMIO hFile;	MMCKINFO ckParent;	MMCKINFO ckChild;	//-----------------	// Load wav file	//-----------------	//Open the file	hFile = mmioOpen((char*)sFilename.c_str(), 0, MMIO_READ | MMIO_ALLOCBUF);	if(hFile == 0)	{		//Error		Log::get()<<"[Sound] ERROR: LoadWav("<<sFilename<<") mmioOpen failed.\n";		return false;	}	//Search for a WAVE chunk header	ckParent.fccType = mmioFOURCC('W', 'A', 'V', 'E');	if(mmioDescend(hFile, &ckParent, 0, MMIO_FINDRIFF) != MMSYSERR_NOERROR)	{		//Error, the file doesn't contain WAVE data		Log::get()<<"[Sound] ERROR: LoadWav("<<sFilename<<") WAVE chunk not found.\n";		mmioClose(hFile, 0);		return false;	}	//Search for the fmt chunk	ckChild.ckid = mmioFOURCC('f', 'm', 't', ' ');	if(mmioDescend(hFile, &ckChild, &ckParent, MMIO_FINDCHUNK) != MMSYSERR_NOERROR)	{		//Error, fmt chunk not found		Log::get()<<"[Sound] ERROR: LoadWav("<<sFilename<<") fmt chunk not found.\n";		mmioClose(hFile, 0);		return false;	}	//Read in the fmt chunk	if(mmioRead(hFile, (HPSTR)&m_wfmt, sizeof(WAVEFORMATEX)) != sizeof(WAVEFORMATEX))	{		//Error reading in the wave format		Log::get()<<"[Sound] ERROR: LoadWav("<<sFilename<<") error reading fmt chunk.\n";		mmioClose(hFile, 0);		return false;	}	//Ascend out of the fmt chunk	mmioAscend(hFile, &ckChild, 0);	//Search for the data chunk	ckChild.ckid = mmioFOURCC('d', 'a', 't', 'a');	if(mmioDescend(hFile, &ckChild, &ckParent, MMIO_FINDCHUNK) != MMSYSERR_NOERROR)	{		//Error finding the data chunk		Log::get()<<"[Sound] ERROR: LoadWav("<<sFilename<<") data chunk not found.\n";		mmioClose(hFile, 0);		return false;	}	//Get the size of the sound data	m_Length = ckChild.cksize;	//Allocate a buffer for the sound data	m_Data = new unsigned char[m_Length];	//Read in the sound data	if(mmioRead(hFile, (HPSTR)m_Data, m_Length) != m_Length)	{		//Error reading in the wave data		Log::get()<<"[Sound] ERROR: LoadWav("<<sFilename<<") error reading in the sound data.\n";		mmioClose(hFile, 0);		delete[] m_Data;		return false;	}	//Close the file	mmioClose(hFile, 0);	//-----------------	// Set up the DSBUFFERDESC object	//-----------------	m_dsbd.dwSize = sizeof(DSBUFFERDESC);	m_dsbd.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME;	m_dsbd.dwBufferBytes = m_Length;	m_dsbd.dwReserved = 0;	m_dsbd.lpwfxFormat = &m_wfmt;	m_dsbd.guid3DAlgorithm = GUID_NULL;	//-----------------	// Success	//-----------------	return true;}


Also, the wav file I'm opening opens and plays fine in Windows Media Player.

[Edited by - InsaneBoarder234 on July 29, 2006 8:42:02 AM]
Progress is born from the opportunity to make mistakes.

My prize winning Connect 4 AI looks one move ahead, can you beat it? @nickstadb
Try using a WAVEFORMAT instead of a WAVEFORMATEX struct. That may be why your numbers are off.
Anthony Rufrano
RealityFactory 2 Programmer
I tried the WAVEFORMAT change and it was still reading in the same values, so as those values are invalid I thought I'd check them via some other method and checked the file properties in explorer to find that the wav file was MP3 encoded. Argh!

I'll add a check in there to make sure that the format is WAVE_FORMAT_PCM. I've tested the code with one of the .wav files that comes with Windows and it works up to a different point that I'm about to look into.

Thanks for the help all, and I apologise for the dodgy wav file!
Progress is born from the opportunity to make mistakes.

My prize winning Connect 4 AI looks one move ahead, can you beat it? @nickstadb

This topic is closed to new replies.

Advertisement