For those familiar with XAudio2 you should know that in order to play a sound you have to load the audio data into a IXAudio2SourceVoice. Currently I am able to load the proper data into a IXAudio2SourceVoice and play it back. My problem is once I start a IXAudio2SourceVoice playing the sound, I can't then restart the same IXAudio2SourceVoice.
// Populate and load IXAudio2SourceVoice// Play voice the 1st timevoice->Start( 0 );// Voice is done playing// Play voice the 2nd timevoice->Start( 0 ); // Nothing happens
#include "AudioPrecompile.h"#include "Audio.h"#include "Wave.h"//-------------------------------------------------------------------------------// Constructor//-------------------------------------------------------------------------------Audio::Audio(){ m_xAudio2 = NULL; m_masteringVoice = NULL;}//-------------------------------------------------------------------------------// Destructor//-------------------------------------------------------------------------------Audio::~Audio(){ DeleteAllTracks(); SAFE_RELEASE(m_xAudio2); SAFE_NULL( m_masteringVoice ); CoUninitialize();}//-------------------------------------------------------------------------------// Iterate through all tracks and free resources//-------------------------------------------------------------------------------void Audio::DeleteAllTracks(){ for( std::map< std::wstring, Track >::iterator i = m_tracks.begin(); i != m_tracks.end(); i++) { i->second.GetSourceVoice()->DestroyVoice(); //SAFE_DELETE_ARRAY( i->second.GetData() ); }}//-------------------------------------------------------------------------------// Set up XAudio2 Engine and parse audio card for Master Voice//-------------------------------------------------------------------------------HRESULT Audio::Initialize(){ HRESULT hr = S_OK; // If we are using windows Initialize COM#ifndef _XBOX CoInitializeEx(NULL, COINIT_MULTITHREADED);#endif // Set up engine based of debug or release#ifdef NO_DEBUG // Release // Create standard instance of the XAudio2 if( FAILED ( hr = XAudio2Create(&m_xAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR) ) ) return hr;#else // Debug // Create debug instance of XAudio2 if( FAILED ( hr = XAudio2Create(&m_xAudio2, XAUDIO2_DEBUG_ENGINE, XAUDIO2_DEFAULT_PROCESSOR) ) ) return hr;#endif // Determine the number of audio devices UINT32 deviceCount; // Number of devices m_xAudio2->GetDeviceCount(&deviceCount); XAUDIO2_DEVICE_DETAILS deviceDetails; // Structure to hold details about audio device int preferredDevice = 0; // Device to be used // Loop through devices for (unsigned int i = 0; i < deviceCount; i++) { // Get device details m_xAudio2->GetDeviceDetails(i,&deviceDetails); // Check conditions ( default device ) if (deviceDetails.Role == DefaultCommunicationsDevice) { preferredDevice = i; break; } } // Create and configure a mastering voice using preferred device if( FAILED ( hr = m_xAudio2->CreateMasteringVoice( &m_masteringVoice, XAUDIO2_DEFAULT_CHANNELS, XAUDIO2_DEFAULT_SAMPLERATE, 0, preferredDevice, NULL ) ) ) return hr; return hr;}//-------------------------------------------------------------------------------// Load a RIFF wave file//-------------------------------------------------------------------------------HRESULT Audio::AddTrack( std::wstring path, std::wstring ID, bool loop ){ HRESULT hr = S_OK; Wave wav; // Create and clear a track Track track; ZeroMemory( &track, sizeof( Track ) ); // Use Wave object to open a .wav file // This will fill out a WAVEFORMATEXTENSIBLE and XAUDIO2_BUFFER structure if( FAILED( hr = wav.Open( path, track ) ) ) return hr; // Create a voice using the WAVEFORMATEXTENSIBLE structure IXAudio2SourceVoice * voice; if( FAILED( hr = m_xAudio2->CreateSourceVoice( &voice, // Pointer to source voice (WAVEFORMATEX*)&track.m_waveformat, // Pointer to wave data 0, // Flags XAUDIO2_DEFAULT_FREQ_RATIO // Highest allowable frequency ratio ) ) ) return hr; // Store the new voice in the track track.SetSourceVoice( voice ); // Buffer to submit XAUDIO2_BUFFER buffer = {0}; // Determine if we are to loop this file buffer.LoopCount = loop ? XAUDIO2_LOOP_INFINITE : 0; //get a pointer to the SoundData's internal buffer buffer.pAudioData = track.m_sampleData; buffer.AudioBytes = track.m_size; //no more audio data follows this buffer.Flags = XAUDIO2_END_OF_STREAM; // Submit data to voice if( FAILED( hr = track.GetSourceVoice()->SubmitSourceBuffer( &buffer ) ) ) return hr; // Store are track m_tracks[ID] = track; return S_OK;}//-----------------------------------------------------------------------------// Perform per-frame update of audio//-----------------------------------------------------------------------------HRESULT Audio::UpdateAudio(){ //OutputDebugString(L"testestestest"); return S_OK;}//-------------------------------------------------------------------------------// Play source voice//-------------------------------------------------------------------------------HRESULT Audio::Play( std::wstring ID ){ HRESULT hr = S_OK; //Starts consumption and processing of audio by the voice if ( FAILED ( hr = m_tracks[ ID ].GetSourceVoice()->Start( 0 ) ) ) return hr; return S_OK;}//-------------------------------------------------------------------------------// Stop source voice//-------------------------------------------------------------------------------HRESULT Audio::Stop( std::wstring ID ){ HRESULT hr = S_OK; // Stops consumption and processing of audio by the voice if ( FAILED ( hr = m_tracks[ ID ].GetSourceVoice()->Stop( 0, XAUDIO2_COMMIT_NOW ) ) ) return hr; return S_OK;}
I am not sure what I doing wrong or how to go about fixing it. If you need any other code let me know?
Regards
Chad