Skip to main content
GameDev.net gamedev.net
🔒 Locked

XAudio2: Does not play sound

Started by itsdbest Nov 10, 2010 at 11:14 PM 11 replies 9.4k views
Original Post
itsdbest
itsdbest
This is my first attempt at writing a sound class manager using XAudio2 and I ran into some trouble. I have used code from the MSDN and the SDK samples.

The issue is that even after the sound is loaded into memory, I cannot hear it after I start the sound. Also, I run into an 'Access violation reading location' error.

I have tried to debug and noticed that the sound is loaded successfully and the Start function returns an S_OK too. The unhandled exception error takes place after the Start function and no sound is heard.

This is the error I receive....
Unhandled exception at 0x5f7d032d in SoundManagerTest.exe: 0xC0000005: Access violation reading location 0x9a3a99d8.

And the following is the code

SoundManager.h
/** Sound Manager v 0.1 - To handle all sound related tasks* Coded by - Andy Dbest*/#ifndef _SOUND_MANAGER#define _SOUND_MANAGER#include <XAudio2.h>#include <windows.h>#include <iostream>using namespace std;namespace GameZombies {	#define fourccRIFF 'FFIR'	#define fourccDATA 'atad'	#define fourccFMT ' tmf'	#define fourccWAVE 'EVAW'	#define fourccXWMA 'AMWX'	#define fourccDPDS 'sdpd'	class SoundManager 	{	private:		IXAudio2* pXAudio2; //core of the XAudio2 engine		IXAudio2MasteringVoice* pMasterVoice; //encapsulates an audio device, 											  //and is the ultimate destination for all audio		UINT32 flags; //flag to set while creating XAudio2 interface		XAUDIO2_BUFFER Buffer; 		IXAudio2SourceVoice* pSourceVoice;		HRESULT FindChunk(HANDLE, DWORD, DWORD &, DWORD &); //To find a chunk in a RIFF file		HRESULT ReadChunkData(HANDLE , void *, DWORD, DWORD); //To read data in a chunk after it has been located	public:		SoundManager(void);		~SoundManager(void);		bool InitializeSound();		int LoadSound(LPWSTR);		HRESULT Play();	};}#endif


SoundManager.cpp
#include "SoundManager.h"using namespace GameZombies;#ifndef SAFE_RELEASE#define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } }#endif//DestructorSoundManager::~SoundManager(void){	// All XAudio2 interfaces are released when the engine is destroyed, but being tidy	if (pSourceVoice != NULL)	{		pSourceVoice->Stop(0);		pSourceVoice->DestroyVoice();	}    pMasterVoice->DestroyVoice();    SAFE_RELEASE( pXAudio2 );    CoUninitialize();}//ConstructorSoundManager::SoundManager(void){	pXAudio2 = NULL;	pMasterVoice = NULL;	flags = 0;	CoInitializeEx(NULL, COINIT_MULTITHREADED);	cout<<"COM initialized\n";}bool SoundManager::InitializeSound(){	HRESULT hr;	if (FAILED(hr = XAudio2Create( &pXAudio2, flags)))	{		cout<<"Failed to create Audio2\n";		return false;	}	if (FAILED(hr = pXAudio2->CreateMasteringVoice(&pMasterVoice)))	{		cout<<"Failed to create MasteringVoice\n";		return false;	}	cout<<"SoundManager Initialized Successfully\n";		return true;}int SoundManager::LoadSound(LPWSTR fileName){	WAVEFORMATEXTENSIBLE wfx = {0}; //defines the format of the audio file		//Open the file	HANDLE hFile = CreateFile(fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);	if( INVALID_HANDLE_VALUE == hFile )		return HRESULT_FROM_WIN32( GetLastError() );	if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, 0, NULL, FILE_BEGIN ) )		return HRESULT_FROM_WIN32( GetLastError() );		//Locate the 'RIFF' chunk in the audio file, and check the file type	DWORD dwChunkSize;	DWORD dwChunkPosition;	//check the file type, should be fourccWAVE or 'XWMA'	FindChunk(hFile,fourccRIFF,dwChunkSize, dwChunkPosition );	DWORD filetype;	ReadChunkData(hFile,&filetype,sizeof(DWORD),dwChunkPosition);	if (filetype != fourccWAVE)		return S_FALSE;		//Locate the 'fmt ' chunk, and copy its contents into a WAVEFORMATEXTENSIBLE structure	FindChunk(hFile,fourccFMT, dwChunkSize, dwChunkPosition );	ReadChunkData(hFile, &wfx, dwChunkSize, dwChunkPosition );	//Locate the 'data' chunk, and read its contents into a buffer	FindChunk(hFile,fourccDATA,dwChunkSize, dwChunkPosition );	BYTE * pDataBuffer = new BYTE[dwChunkSize];	ReadChunkData(hFile, pDataBuffer, dwChunkSize, dwChunkPosition);		//Populate the XAudio2 Buffer	Buffer.AudioBytes = dwChunkSize;	Buffer.pAudioData = pDataBuffer;	Buffer.Flags = XAUDIO2_END_OF_STREAM; 		HRESULT hr;	//Create the source voice	if (FAILED(hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx)))	{		cout<<"Error while creating source voice\n";		return false;	}	if( FAILED(hr = pSourceVoice->SubmitSourceBuffer( &Buffer ) ) )		return hr;		cout<<"Sound Loaded Successfully\n";	return S_OK;}HRESULT SoundManager::Play(){	HRESULT hr;	if ( FAILED(hr = pSourceVoice->Start( 0 ) ) )		return hr;	cout<<"Sound Playing\n";[color=Red]//ERROR OCCURS HERE	return hr;}HRESULT SoundManager::FindChunk(HANDLE hFile, DWORD fourcc, DWORD & dwChunkSize, DWORD & dwChunkDataPosition){    HRESULT hr = S_OK;    if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, 0, NULL, FILE_BEGIN ) )        return HRESULT_FROM_WIN32( GetLastError() );    DWORD dwChunkType;    DWORD dwChunkDataSize;    DWORD dwRIFFDataSize = 0;    DWORD dwFileType;    DWORD bytesRead = 0;    DWORD dwOffset = 0;    while (hr == S_OK)    {        DWORD dwRead;        if( 0 == ReadFile( hFile, &dwChunkType, sizeof(DWORD), &dwRead, NULL ) )            hr = HRESULT_FROM_WIN32( GetLastError() );        if( 0 == ReadFile( hFile, &dwChunkDataSize, sizeof(DWORD), &dwRead, NULL ) )            hr = HRESULT_FROM_WIN32( GetLastError() );        switch (dwChunkType)        {        case fourccRIFF:            dwRIFFDataSize = dwChunkDataSize;            dwChunkDataSize = 4;            if( 0 == ReadFile( hFile, &dwFileType, sizeof(DWORD), &dwRead, NULL ) )                hr = HRESULT_FROM_WIN32( GetLastError() );            break;        default:            if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, dwChunkDataSize, NULL, FILE_CURRENT ) )            return HRESULT_FROM_WIN32( GetLastError() );                    }        dwOffset += sizeof(DWORD) * 2;                if (dwChunkType == fourcc)        {            dwChunkSize = dwChunkDataSize;            dwChunkDataPosition = dwOffset;            return S_OK;        }        dwOffset += dwChunkDataSize;                if (bytesRead >= dwRIFFDataSize) return S_FALSE;    }        return S_OK;    }HRESULT SoundManager::ReadChunkData(HANDLE hFile, void * buffer, DWORD buffersize, DWORD bufferoffset){    HRESULT hr = S_OK;    if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, bufferoffset, NULL, FILE_BEGIN ) )        return HRESULT_FROM_WIN32( GetLastError() );    DWORD dwRead;    if( 0 == ReadFile( hFile, buffer, buffersize, &dwRead, NULL ) )        hr = HRESULT_FROM_WIN32( GetLastError() );    return hr;}


main.cpp
#include "SoundManager.h"using namespace GameZombies;int main(){	SoundManager sound;	HRESULT hr;	//CoInitializeEx(NULL, COINIT_MULTITHREADED);	if (!sound.InitializeSound())		cout <<"Error initializing sound\n";	else {		if (FAILED(hr = sound.LoadSound(L"Mono.wav"))){			cout <<"Error Loading sound\n";			cout <<hr;		}		else {			sound.Play();		}	}	system ("pause");	return 0;}
Burnt_Fyr
Burnt_Fyr
You are using pSourceVoice without ever initializing, which is genereally the root of 0xC000005 errors, uninitialized pointers.

SoundManager::SoundManager(void){	pXAudio2 = NULL;	pMasterVoice = NULL;	pSourceVoice = NULL; // this should fix	flags = 0;	CoInitializeEx(NULL, COINIT_MULTITHREADED);	cout<<"COM initialized\n";}

itsdbest
itsdbest
This is teh same code in a procedural format and I have the same issue.. The exception occurs before the system("pause") line.

#include <XAudio2.h>#include <windows.h>#include <iostream>using namespace std;#ifndef SAFE_RELEASE#define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } }#endif#define fourccRIFF 'FFIR'	#define fourccDATA 'atad'	#define fourccFMT ' tmf'	#define fourccWAVE 'EVAW'	#define fourccXWMA 'AMWX'	#define fourccDPDS 'sdpd'HRESULT FindChunk(HANDLE hFile, DWORD fourcc, DWORD & dwChunkSize, DWORD & dwChunkDataPosition){    HRESULT hr = S_OK;    if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, 0, NULL, FILE_BEGIN ) )        return HRESULT_FROM_WIN32( GetLastError() );    DWORD dwChunkType;    DWORD dwChunkDataSize;    DWORD dwRIFFDataSize = 0;    DWORD dwFileType;    DWORD bytesRead = 0;    DWORD dwOffset = 0;    while (hr == S_OK)    {        DWORD dwRead;        if( 0 == ReadFile( hFile, &dwChunkType, sizeof(DWORD), &dwRead, NULL ) )            hr = HRESULT_FROM_WIN32( GetLastError() );        if( 0 == ReadFile( hFile, &dwChunkDataSize, sizeof(DWORD), &dwRead, NULL ) )            hr = HRESULT_FROM_WIN32( GetLastError() );        switch (dwChunkType)        {        case fourccRIFF:            dwRIFFDataSize = dwChunkDataSize;            dwChunkDataSize = 4;            if( 0 == ReadFile( hFile, &dwFileType, sizeof(DWORD), &dwRead, NULL ) )                hr = HRESULT_FROM_WIN32( GetLastError() );            break;        default:            if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, dwChunkDataSize, NULL, FILE_CURRENT ) )            return HRESULT_FROM_WIN32( GetLastError() );                    }        dwOffset += sizeof(DWORD) * 2;                if (dwChunkType == fourcc)        {            dwChunkSize = dwChunkDataSize;            dwChunkDataPosition = dwOffset;            return S_OK;        }        dwOffset += dwChunkDataSize;                if (bytesRead >= dwRIFFDataSize) return S_FALSE;    }        return S_OK;    }HRESULT ReadChunkData(HANDLE hFile, void * buffer, DWORD buffersize, DWORD bufferoffset){    HRESULT hr = S_OK;    if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, bufferoffset, NULL, FILE_BEGIN ) )        return HRESULT_FROM_WIN32( GetLastError() );    DWORD dwRead;    if( 0 == ReadFile( hFile, buffer, buffersize, &dwRead, NULL ) )        hr = HRESULT_FROM_WIN32( GetLastError() );    return hr;}int main(){	IXAudio2* pXAudio2; //core of the XAudio2 engine	IXAudio2MasteringVoice* pMasterVoice; //encapsulates an audio device, 											  //and is the ultimate destination for all audio	UINT32 flags; //flag to set while creating XAudio2 interface	XAUDIO2_BUFFER Buffer; 	IXAudio2SourceVoice* pSourceVoice;	BYTE * pDataBuffer;		HRESULT hr;	//intialize variables	pXAudio2 = NULL;	pMasterVoice = NULL;	pSourceVoice = NULL;	flags = 0;	CoInitializeEx(NULL, COINIT_MULTITHREADED);	cout<<"COM initialized\n";	//initialize sound	if (FAILED(hr = XAudio2Create( &pXAudio2, flags)))	{		cout<<"Failed to create Audio2\n";		return false;	}	if (FAILED(hr = pXAudio2->CreateMasteringVoice(&pMasterVoice)))	{		cout<<"Failed to create MasteringVoice\n";		return false;	}	cout<<"SoundManager Initialized Successfully\n";		//load sound into memory	LPWSTR fileName = L"Mono.wav";	WAVEFORMATEXTENSIBLE wfx = {0}; //defines the format of the audio file		//Open the file	HANDLE hFile = CreateFile(fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);	if( INVALID_HANDLE_VALUE == hFile )		return HRESULT_FROM_WIN32( GetLastError() );	if( INVALID_SET_FILE_POINTER == SetFilePointer( hFile, 0, NULL, FILE_BEGIN ) )		return HRESULT_FROM_WIN32( GetLastError() );		//Locate the 'RIFF' chunk in the audio file, and check the file type	DWORD dwChunkSize;	DWORD dwChunkPosition;	//check the file type, should be fourccWAVE or 'XWMA'	FindChunk(hFile,fourccRIFF,dwChunkSize, dwChunkPosition );	DWORD filetype;	ReadChunkData(hFile,&filetype,sizeof(DWORD),dwChunkPosition);	if (filetype != fourccWAVE)		return S_FALSE;		//Locate the 'fmt ' chunk, and copy its contents into a WAVEFORMATEXTENSIBLE structure	FindChunk(hFile,fourccFMT, dwChunkSize, dwChunkPosition );	ReadChunkData(hFile, &wfx, dwChunkSize, dwChunkPosition );	//Locate the 'data' chunk, and read its contents into a buffer	FindChunk(hFile,fourccDATA,dwChunkSize, dwChunkPosition );	pDataBuffer = new BYTE[dwChunkSize];	ReadChunkData(hFile, pDataBuffer, dwChunkSize, dwChunkPosition);		//Populate the XAudio2 Buffer	Buffer.AudioBytes = dwChunkSize;	Buffer.pAudioData = pDataBuffer;	Buffer.Flags = XAUDIO2_END_OF_STREAM; 		//HRESULT hr;	//Create the source voice	if (FAILED(hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx)))	{		cout<<"Error while creating source voice\n";		return false;	}	if( FAILED(hr = pSourceVoice->SubmitSourceBuffer( &Buffer ) ) )		return hr;	cout<<"Sound Loaded Successfully\n";	//play the sound	if ( FAILED(hr = pSourceVoice->Start( 0, XAUDIO2_COMMIT_NOW ) ) )		return hr;	cout<<"Sound Playing\n";	system ("pause");	// All XAudio2 interfaces are released when the engine is destroyed, but being tidy	if (pSourceVoice != NULL)	{		pSourceVoice->Stop(0);		pSourceVoice->DestroyVoice();	}    pMasterVoice->DestroyVoice();    SAFE_RELEASE( pXAudio2 );    CoUninitialize();	return 0;}
Buckeye
Buckeye
Quote:
The exception occurs before the system("pause") line.

Which line exactly? If you don't know, set breakpoints and step through the code. You need to know where the exception is taking place.
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
itsdbest
itsdbest
cout<<"Sound Playing\n";

I get the "S" (from Sound) printed on the console and thats where i get the error. Debugging also shows the error there. pSourceVoice->Start( 0, XAUDIO2_COMMIT_NOW ) returns an S_OK.
Buckeye
Buckeye
Interesting! What happened when you commented out that line?
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
JackOfAllTrades
JackOfAllTrades
I just took a quick look at your code and I don't see you doing anything except XAudio2Create and CreateMasteringVoice to initialize XAudio2.

You need to do all of these steps:

	// Initialize XAudio2	XAudio2Create( &instance->XAudio2, 0);	instance->XAudio2->CreateMasteringVoice( &instance->MasteringVoice );	instance->XAudio2->GetDeviceDetails( 0, &instance->DeviceDetails );	X3DAudioInitialize( instance->DeviceDetails.OutputFormat.dwChannelMask, X3DAUDIO_SPEED_OF_SOUND, instance->X3DAudio );	ZeroMemory( &instance->DSPSettings, sizeof( instance->DSPSettings ) );	instance->DSPSettings.SrcChannelCount = 2;	instance->DSPSettings.DstChannelCount = instance->DeviceDetails.OutputFormat.Format.nChannels;	DWORD dwSize = (instance->DSPSettings.SrcChannelCount * instance->DSPSettings.DstChannelCount);	FLOAT32* MatrixCoefficients = new FLOAT32[dwSize];	ZeroMemory( MatrixCoefficients, sizeof( FLOAT32 ) * dwSize );	instance->DSPSettings.pMatrixCoefficients = MatrixCoefficients;


This code was copied from my project.
itsdbest
itsdbest
Quote:
Original post by Buckeye
Interesting! What happened when you commented out that line?


The exception still occurs on the next line.

@Steve - I will look into that...
Burnt_Fyr
Burnt_Fyr
I think that is another red herring, as my initialization of XAudio is nothing more than what you, and the SDK Example have done. It has been a while since i was working with XAudio, and I remember having many issues as well and found little if any help for them. I'll try to work through your code today
itsdbest
itsdbest
A minimal initialization should not be the cause of the issue.

@Burnt_Fyr - would appreciate that.
Burnt_Fyr
Burnt_Fyr
Alright I loaded up your project and my first peice of advice is, Read This . I'm sure you have read the DX forums, and have seen countless people be reminded to makes sure the debug runtimes are set( myself included recently). Debugging blind is essentially a waste of time. So once you add:

SoundManager::SoundManager(void){	pXAudio2 = NULL;	pMasterVoice = NULL;	pSourceVoice = NULL;	flags = XAUDIO2_DEBUG_ENGINE; // Enable debugging faculties	CoInitializeEx(NULL, COINIT_MULTITHREADED);	cout<<"COM initialized\n";}


You get:

XAUDIO2: ERROR: Loop count (3435973836) must be XAUDIO2_LOOP_INFINITE (255) or no greater than XAUDIO2_MAX_LOOP_COUNT (254)XAUDIO2: ERROR: Loop region (3435973836-2576980376) begins after play region (3435973836-2576980376)XAUDIO2: ERROR: Loop region (3435973836-2576980376) ends before play region (3435973836-2576980376)XAUDIO2: ERROR: Play region (3435973836-2576980376) does not start within the audio buffer (size 43983)XAUDIO2: ERROR: Play region (3435973836-2576980376) does not end within the audio buffer (size 43983)XAUDIO2: ERROR: Loop region (3435973836-2576980376) does not start within the audio buffer (size 43983)XAUDIO2: ERROR: Loop region (3435973836-2576980376) does not end within the audio buffer (size 43983)XAUDIO2: ERROR: Invalid source buffer


Old adage..."Garbage in = garbage out ". Your not ensuring all the fields in the buffer struct are empty, and end up with the GIGO effect.

adding:

::ZeroMemory(&Buffer, sizeof(XAUDIO2_BUFFER));


to SoundManager's constructor fixed it for me.

edit: Blasted hyperlinks never work for me... Does the forum have spoiler tags, would have liked to use them on this post.
itsdbest
itsdbest
That solved it. Thanks.

Also appreciate the tip for enabling debugging.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.