Sign in to follow this  
itsdbest

XAudio2: Does not play sound

Recommended Posts

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

//Destructor
SoundManager::~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();
}

//Constructor
SoundManager::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[/color]
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;
}

Share this post


Link to post
Share on other sites
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";
}


Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this