Jump to content
  • Advertisement
Sign in to follow this  
dev578

waveOutReset()? crashing my program [Solved, thank you]

This topic is 4586 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Every time I try to stop waveform audio, my program hangs on waveOutUnprepareHeader(). Why would this be happening? I can't find a single reason why it would crash on it. I guess I can post the relevant code:
//
//My Callback Function
//
int CALLBACK VoiceWaveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
	//this message can be sent if a buffer is sent back, or if the stop button was pressed
 	if (uMsg == WOM_DONE)
	{
		//get a pointer to the instance of CSound
		CSound* pCSound = reinterpret_cast<CSound*>((DWORD_PTR)dwInstance);
		unsigned long result;

		char *Buffer;
		//get the number of the buffer returned
		int nBufferReturned = 0;
		
		for (int x = 0; x < NBUFFERS; x++)
		{
			if (dwParam1 == (DWORD_PTR)&pCSound->WaveHeader[x])
			{
				nBufferReturned = x;
				Buffer = pCSound->Buffer[x];
				if (x!= NBUFFERS-1)
					pCSound->CurrentBuffer = pCSound->Buffer[x+1];
				else
					pCSound->CurrentBuffer = pCSound->Buffer[0];
			}
		}


		//if we aren't playing, return
		if (pCSound->iAction == -1)
		{
			char TempChar[512];
			sprintf(TempChar,"Buffer %i returned for clearing\n",nBufferReturned);
			OutputDebugString(TempChar);

//CRASHES RIGHT HERE, the first time it is called
			result = waveOutUnprepareHeader(pCSound->outHandle, pCSound->WaveHeader[nBufferReturned], sizeof(WAVEHDR));
			if(result) return 1;

			for (int i = 0; i < (int)pCSound->m_dwLength; i++)
				Buffer = NULL;
			return 0;
		}
//...
}
}

//Play Function
int CSound::Play()
{
	if (iAction == 2)
	{
		waveOutRestart(outHandle);
		iAction = 0;
		return 0;
	}
	
	for (int x = 0; x < NBUFFERS; x++)
		for (int i = 0; i < (int)m_dwLength; i++)
			Buffer[x] = 0;

	PlayOffset = 0;

	FILE *fp = fopen(CurFile,"rb");
	fseek(fp,0,SEEK_END);
	PlaySize = (int)ftell(fp);
	fseek(fp,0,SEEK_SET);
	if (PlaySize == 0)
	{
		fclose(fp);
		PlayDone();
		return 0;
	}

	unsigned long result;
	
	for (int x = 0; x < NBUFFERS; x++)
	{
		fread(Buffer[x],sizeof(char),(int)m_dwLength,fp);
		PlayOffset+=1;

		WaveHeader[x].lpData = Buffer[x];
		WaveHeader[x].dwBufferLength=m_dwLength;
		WaveHeader[x].dwBytesRecorded=0;
		WaveHeader[x].dwUser=0;
		WaveHeader[x].dwFlags=0;
		WaveHeader[x].reserved=0;
		WaveHeader[x].lpNext=0;

		result = waveOutPrepareHeader(outHandle,&WaveHeader[x],sizeof(WAVEHDR));
		if(result) return 1;

		result = waveOutWrite(outHandle,&WaveHeader[x],sizeof(WAVEHDR));
		if(result) return 1;
	}

	fclose(fp);
	
	iAction = 0;

	CurrentBuffer = Buffer[0];

	return 0;
}

//Stop Function
//...
iAction = -1;
result = waveOutReset(outHandle);
//...

//Additional Info

#define NBUFFERS 16

//in class
WAVEHDR WaveHeader[NBUFFERS];
WAVEFORMATEX waveFormat;
char* Buffer[NBUFFERS];

//Initialization
for (int x = 0; x < NBUFFERS; x++)
{
	Buffer[x] = new char[m_dwLength];
	for (int i = 0; i < (int)m_dwLength; i++)
		Buffer[x] = 0;
}




Urgh, I don't see any reason for it to hang on that. If anyone has any ideas, I would appreciate them. Thank you, Dev578 [Edited by - dev578 on March 5, 2006 2:10:39 PM]

Share this post


Link to post
Share on other sites
Advertisement
You really need to give more info to be helpful.

- by 'hang' do you mean crash?
- What info does the debugger give you? (expception information, addresses etc.)
- Do you have a full callstack when it crashes?
- Does it crash in Debug?
- Has it ever worked? (i.e. is this old code that has recently been changed, or is it completely new work)

Thanks

Paul

Share this post


Link to post
Share on other sites
By hang, I mean the program just becomes unresponsive. There is no debug error or anything. I have to stop it from the debugger, there is also no error messages. No it has never worked correctly, although when I ran all the waveOutUnprepareHeaders() in the stop function after waveOutReset(), I altered between playing and stoping. It would work right for awile, and then hang like it is doing now. The way I have it now, it hangs the first time you play and then hit the stop button. Hope this helps, I don't see what is going wrong.

Thank you,



Dev578

Share this post


Link to post
Share on other sites
After doing some googling it might be that you cannot use any of the WaveOut... functions within the callback, just google "waveOutUnprepareHeader hang callback" to find people with the same problem as you,

Paul

Share this post


Link to post
Share on other sites
Ok, if that is the case, on my CALLBACK, I will just return when the buffers get sent back when stop is pressed. In my stop function I will call waveOutReset() and then after it cycle through and Unprepare all the Headers as well as zero out all the buffers. Now something interesting happens here. It works seemingly perfect for a random amount of times, and then when you hit stop, it freezes. This time it doesn't freeze on unpreparing the header, it freezes on waveOutReset(), it never returns. Umm... ??? I still can't see any reason for this.


Dev578

Share this post


Link to post
Share on other sites
I think a pointer is needed in the second parameter of waveOutUnprepareHeader()

//OLD
result = waveOutUnprepareHeader(pCSound->outHandle, pCSound->WaveHeader[nBufferReturned], sizeof(WAVEHDR));
//NEW
result = waveOutUnprepareHeader(pCSound->outHandle, &(pCSound->WaveHeader[nBufferReturned]), sizeof(WAVEHDR));

Share this post


Link to post
Share on other sites
Oh, yes it is a pointer. That would explain why it crashed there that time. It is still doing the same thing though. In my callback, when waveOutReset() is called, I just return 0; Like:

if (pCSound->iAction == -1) return 0;

Then after waveOutReset() finishes, I unprepare all the headers and clear the buffers like so:

for (int x = 0; x < NBUFFERS; x++)
{
result = waveOutUnprepareHeader(outHandle,&(WaveHeader[x]), sizeof(WAVEHDR));
if(result) return 1;

for (int i = 0; i < (int)m_dwLength; i++)
Buffer[x] = NULL;
}

I keep playing a file and then stopping it. It will work perfectly for a random amount of times, and then just lock up and become unresponsive. I don't even know what else it can be. Further tests show that the time I hit stop and it crashes, waveOutReset() never returns, and the callback is never called with the buffers being returned. The other times that the stop works, this all works fine. Any ideas?

Thank you,



Dev578

Share this post


Link to post
Share on other sites
Sorry, more information needed. I'm not familiar with the waveOut*/audioform interface.

-What are you trying to do (streaming audio)?
-How are you using waveOut* to do it(general overview of implementation using waveOut*)?
-Can you provide a minimal program that reproduces that crash(helps others to debug the problem)?

Good Luck.

Share this post


Link to post
Share on other sites
Interesting find, I ran it on another Windows XP Pro machine in VC++ debug mode and it didn't crash. On my computer, it still crashes though. It works fine and does exactly what it is supposed to for awile, and then when you hit stop and it calls waveOutReset(), the CALLBACK funcion is never even called (it is supposed to to return the buffers that were in the queue), and it just freezes as mentioned before. Here is the code with the slight change that I unprepare all the headers on the stop function, and not in the CALLBACK, just incase that is what is freezing it:


int CSound::Play()
{
if (iAction == 2)
{
waveOutRestart(outHandle);
iAction = 0;
return 0;
}

for (int x = 0; x < NBUFFERS; x++)
for (int i = 0; i < (int)m_dwLength; i++)
Buffer[x] = 0;

PlayOffset = 0;

FILE *fp = fopen(CurFile,"rb");
fseek(fp,0,SEEK_END);
PlaySize = (int)ftell(fp);
fseek(fp,0,SEEK_SET);
if (PlaySize == 0)
{
fclose(fp);
PlayDone();
return 0;
}

unsigned long result;

for (int x = 0; x < NBUFFERS; x++)
{
fread(Buffer[x],sizeof(char),(int)m_dwLength,fp);
PlayOffset+=1;

WaveHeader[x].lpData = Buffer[x];
WaveHeader[x].dwBufferLength=m_dwLength;
WaveHeader[x].dwBytesRecorded=0;
WaveHeader[x].dwUser=0;
WaveHeader[x].dwFlags=0;
WaveHeader[x].reserved=0;
WaveHeader[x].lpNext=0;

result = waveOutPrepareHeader(outHandle,&(WaveHeader[x]),sizeof(WAVEHDR));
if(result) return 1;

result = waveOutWrite(outHandle,&WaveHeader[x],sizeof(WAVEHDR));
if(result) return 1;
}

fclose(fp);

iAction = 0;

CurrentBuffer = Buffer[0];

return 0;
}









int CALLBACK VoiceWaveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
OutputDebugString("CallBack Called\n");
//this message can be sent if a buffer is sent back, or if the stop button was pressed
if (uMsg == WOM_DONE)
{
OutputDebugString("WOM_DONE Message Called\n");
//get a pointer to the instance of CSound
CSound* pCSound = reinterpret_cast<CSound*>((DWORD_PTR)dwInstance);
unsigned long result;

OutputDebugString("About to Return if pCSound->iAction == -1\n");

if (pCSound->iAction == -1) return 0;
//the rest should be irrelevant, if it didn't return, I just fill the buffer with more data and send it back to the driver, I know it works, it never crashes on Play
}
}








//if stop is called and it is playing:
OutputDebugString("About to Call WaveOutReset\n");
iAction = -1;
//THIS IS WHAT CRASHES WHEN THE PROGRAM FREEZES, IT NEVER CALLS THE CALLBACK WHEN IT FREEZES
waveOutReset(outHandle);

for (int x = 0; x < NBUFFERS; x++)
{
result = waveOutUnprepareHeader(outHandle,&(WaveHeader[x]), sizeof(WAVEHDR));
if(result) return 1;

for (int i = 0; i < (int)m_dwLength; i++)
Buffer[x] = NULL;
}









//Additional Info

#define NBUFFERS 16

//in class
WAVEHDR WaveHeader[NBUFFERS];
WAVEFORMATEX waveFormat;
char* Buffer[NBUFFERS];

//Initialization
for (int x = 0; x < NBUFFERS; x++)
{
Buffer[x] = new char[m_dwLength];
for (int i = 0; i < (int)m_dwLength; i++)
Buffer[x] = 0;
}




Any Ideas? Thank you for your time.



Dev578

Edit: I am trying to play and stop uncompressed PCM sound, and I don't think I can produce a smaller example that crashes because it needs all this to work.

Share this post


Link to post
Share on other sites
I don't quite understand why you are using so many buffers for one sound. I've been able to quite easily play them with just one or two.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!