Original Post
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
SoundManager.cpp
main.cpp
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(); };}#endifSoundManager.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;}