//-------------------------------------------------------------------------------------- // Initialize XACT engine //-------------------------------------------------------------------------------------- HRESULT InitXACT( IXACT3Engine** ppXACTEngine ) { // Init COM and create XACT engine HRESULT hr; hr = CoInitializeEx( NULL, COINIT_MULTITHREADED ); if( SUCCEEDED( hr ) ) { // Switch to auditioning mode based on command line. Change if desired bool bAuditionMode = DoesCommandLineContainAuditionSwitch(); bool bDebugMode = false; DWORD dwCreationFlags = 0; if( bAuditionMode ) dwCreationFlags |= XACT_FLAG_API_AUDITION_MODE; if( bDebugMode ) dwCreationFlags |= XACT_FLAG_API_DEBUG_MODE; hr = XACT3CreateEngine( dwCreationFlags, ppXACTEngine ); } if( FAILED( hr ) || *ppXACTEngine == NULL ) return E_FAIL; XACT_RENDERER_DETAILS rendererDetails = {0}; if( FAILED( hr = ( *ppXACTEngine )->GetRendererDetails( 0, &rendererDetails ) ) ) return hr; XACT_RUNTIME_PARAMETERS xrParams = {0}; xrParams.fnNotificationCallback = NULL; xrParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; xrParams.pRendererID = rendererDetails.rendererID; if( FAILED( hr = ( *ppXACTEngine )->Initialize( &xrParams ) ) ) return hr; return S_OK; }
// //////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////// HRESULT SJ_InitSound( ) { HRESULT hr; if ( FAILED( hr = CoInitializeEx( NULL, COINIT_MULTITHREADED ) ) ) return hr; if ( FAILED( hr = XACT3CreateEngine( 0, &s_pXACTEngine ) ) || ! s_pXACTEngine ) return hr; XACT_RENDERER_DETAILS rendererDetails = {0}; if ( FAILED( hr = s_pXACTEngine->GetRendererDetails( 0, &rendererDetails ) ) ) return hr; XACT_RUNTIME_PARAMETERS xrParams = {0}; xrParams.fnNotificationCallback = NULL; xrParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; xrParams.pRendererID = rendererDetails.rendererID; if ( FAILED( hr = s_pXACTEngine->Initialize( &xrParams ) ) ) return hr; return S_OK; }
//---------------------------------- //機能:オーディオのエンジンを生成 //引数:なし //戻値:成功or失敗 //---------------------------------- HRESULT Audio::InitEngine() { //COMライブラリの初期化 CoInitializeEx(NULL, COINIT_MULTITHREADED); //エンジン作成 if (FAILED(XACT3CreateEngine(0, &xactEngine))) { MessageBox(0, "XACTエンジンの作成に失敗しました", "エラー", MB_OK); return E_FAIL; } //パラメータ設定 XACT_RUNTIME_PARAMETERS xactParam = { 0 }; xactParam.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; if (FAILED(xactEngine->Initialize(&xactParam))) { MessageBox(0, "XACTエンジンのパラメータ設定に失敗しました", "エラー", MB_OK); return E_FAIL; } return S_OK; }
//============================================================================= // initialize // This function does the following: // 1. Initialize XACT by calling xactEngine->Initialize // 2. Create the XACT wave bank(s) you want to use // 3. Create the XACT sound bank(s) you want to use // 4. Store indices to the XACT cue(s) your game uses //============================================================================= HRESULT Audio::initialize() { HRESULT result = E_FAIL; HANDLE hFile; DWORD fileSize; DWORD bytesRead; HANDLE hMapFile; result = CoInitializeEx( NULL, COINIT_MULTITHREADED ); if( SUCCEEDED(result) ) result = XACT3CreateEngine( 0, &xactEngine ); if( FAILED( result ) || xactEngine == NULL ) return E_FAIL; result = XACT3CreateEngine( 0, &xactEngine ); if( FAILED( result ) || xactEngine == NULL ) return E_FAIL; // Load the global settings file and pass it into XACTInitialize VOID* pGlobalSettingsData = NULL; DWORD dwGlobalSettingsFileSize = 0; bool bSuccess = false; hFile = CreateFile( XGS_FILE, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile ) { dwGlobalSettingsFileSize = GetFileSize( hFile, NULL ); if( dwGlobalSettingsFileSize != INVALID_FILE_SIZE ) { pGlobalSettingsData = CoTaskMemAlloc( dwGlobalSettingsFileSize ); if( pGlobalSettingsData ) { if( 0 != ReadFile( hFile, pGlobalSettingsData, dwGlobalSettingsFileSize, &bytesRead, NULL ) ) { bSuccess = true; } } } CloseHandle( hFile ); } if( !bSuccess ) { if( pGlobalSettingsData ) CoTaskMemFree( pGlobalSettingsData ); pGlobalSettingsData = NULL; dwGlobalSettingsFileSize = 0; } // Initialize & create the XACT runtime XACT_RUNTIME_PARAMETERS xactParams = {0}; xactParams.pGlobalSettingsBuffer = pGlobalSettingsData; xactParams.globalSettingsBufferSize = dwGlobalSettingsFileSize; // delete the buffer when not needed xactParams.globalSettingsFlags = XACT_FLAG_GLOBAL_SETTINGS_MANAGEDATA; // Set the look agead time to default xactParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; // Initialize the XACT engine result = xactEngine->Initialize( &xactParams ); if( FAILED( result ) ) return result; // Create an "in memory" XACT wave bank file using memory mapped file IO result = E_FAIL; // default to failure code, replaced on success hFile = CreateFile( WAVE_BANK, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { fileSize = GetFileSize( hFile, NULL ); if( fileSize != -1 ) { hMapFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, fileSize, NULL ); if( hMapFile ) { mapWaveBank = MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, 0 ); if( mapWaveBank ) result = xactEngine->CreateInMemoryWaveBank( mapWaveBank, fileSize, 0, 0, &waveBank ); CloseHandle( hMapFile ); // mapWaveBank maintains a handle on the file so close this unneeded handle } } CloseHandle( hFile ); // mapWaveBank maintains a handle on the file so close this unneeded handle } if( FAILED( result ) ) return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ); // Read and register the sound bank file with XACT. result = E_FAIL; // default to failure code, replaced on success hFile = CreateFile( SOUND_BANK, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { fileSize = GetFileSize( hFile, NULL ); if( fileSize != -1 ) { soundBankData = new BYTE[fileSize]; // reserve memory for sound bank if( soundBankData ) { if( 0 != ReadFile( hFile, soundBankData, fileSize, &bytesRead, NULL ) ) result = xactEngine->CreateSoundBank( soundBankData, fileSize, 0, 0, &soundBank ); } } CloseHandle( hFile ); } if( FAILED( result ) ) return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ); return S_OK; }
HRESULT Audio::initialize() { HRESULT result = E_FAIL; HANDLE hFile; DWORD fileSize; DWORD bytesRead; HANDLE hMapFile; if( coInitialized == false) return E_FAIL; result = XACT3CreateEngine( 0, &xactEngine ); if( FAILED( result ) || xactEngine == NULL ) return E_FAIL; XACT_RUNTIME_PARAMETERS xactParams = {0}; xactParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; result = xactEngine->Initialize( &xactParams ); if( FAILED( result ) ) return result; result = E_FAIL; hFile = CreateFile( WAVE_BANK, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { fileSize = GetFileSize( hFile, NULL ); if( fileSize != -1 ) { hMapFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, fileSize, NULL ); if( hMapFile ) { mapWaveBank = MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, 0 ); if( mapWaveBank ) result = xactEngine->CreateInMemoryWaveBank( mapWaveBank, fileSize, 0, 0, &waveBank ); CloseHandle( hMapFile ); } } CloseHandle( hFile ); } if( FAILED( result ) ) return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ); result = E_FAIL; hFile = CreateFile( SOUND_BANK, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { fileSize = GetFileSize( hFile, NULL ); if( fileSize != -1 ) { soundBankData = new BYTE[fileSize]; if( soundBankData ) { if( 0 != ReadFile( hFile, soundBankData, fileSize, &bytesRead, NULL ) ) result = xactEngine->CreateSoundBank( soundBankData, fileSize, 0, 0, &soundBank ); } } CloseHandle( hFile ); } if( FAILED( result ) ) return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ); return S_OK; }
//============================================================================= // initialize // This function does the following: // 1. Initialize XACT by calling xactEngine->Initialize // 2. Create the XACT wave bank(s) you want to use // 3. Create the XACT sound bank(s) you want to use // 4. Store indices to the XACT cue(s) your game uses //============================================================================= HRESULT CAudioMgr::initialize() { HRESULT result = E_FAIL; HANDLE hFile; DWORD fileSize; DWORD bytesRead; HANDLE hMapFile; if (coInitialized == false) return E_FAIL; result = XACT3CreateEngine(0, &xactEngine); if (FAILED(result) || xactEngine == NULL) return E_FAIL; // Initialize & create the XACT runtime XACT_RUNTIME_PARAMETERS xactParams = { 0 }; xactParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; result = xactEngine->Initialize(&xactParams); if (FAILED(result)) return result; // Create an "in memory" XACT wave bank file using memory mapped file IO result = E_FAIL; // default to failure code, replaced on success hFile = CreateFile(WAVE_BANK, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hFile != INVALID_HANDLE_VALUE) { fileSize = GetFileSize(hFile, NULL); if (fileSize != -1) { hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, fileSize, NULL); if (hMapFile) { mapWaveBank = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); if (mapWaveBank) result = xactEngine->CreateInMemoryWaveBank(mapWaveBank, fileSize, 0, 0, &waveBank); CloseHandle(hMapFile); // mapWaveBank maintains a handle on the file so close this unneeded handle } } CloseHandle(hFile); // mapWaveBank maintains a handle on the file so close this unneeded handle } if (FAILED(result)) return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); // Read and register the sound bank file with XACT. result = E_FAIL; // default to failure code, replaced on success hFile = CreateFile(SOUND_BANK, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hFile != INVALID_HANDLE_VALUE) { fileSize = GetFileSize(hFile, NULL); if (fileSize != -1) { soundBankData = new BYTE[fileSize]; // reserve memory for sound bank if (soundBankData) { if (0 != ReadFile(hFile, soundBankData, fileSize, &bytesRead, NULL)) result = xactEngine->CreateSoundBank(soundBankData, fileSize, 0, 0, &soundBank); } } CloseHandle(hFile); } if (FAILED(result)) return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); return S_OK; }
/**************************************************************************** * Initialize: * Creates and initializes the XACT engine *****************************************************************************/ void SoundController::Init() { CoInitializeEx(NULL, COINIT_MULTITHREADED); XACT3CreateEngine( /*XACT_FLAG_API_DEBUG_MODE*/ 0, &pXACT3Engine ); // Load the global settings file and pass it into XACTInitialize VOID* pGlobalSettingsData = NULL; DWORD dwGlobalSettingsFileSize = 0; bool bSuccess = false; DWORD dwBytesRead; HANDLE hFile; DWORD dwFileSize; HANDLE hMapFile; hFile = CreateFile( gsPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile ) { dwGlobalSettingsFileSize = GetFileSize( hFile, NULL ); if( dwGlobalSettingsFileSize != INVALID_FILE_SIZE ) { // Using CoTaskMemAlloc so that XACT can clean up this data when its done pGlobalSettingsData = CoTaskMemAlloc( dwGlobalSettingsFileSize ); if( pGlobalSettingsData ) { if( 0 != ReadFile( hFile, pGlobalSettingsData, dwGlobalSettingsFileSize, &dwBytesRead, NULL ) ) { bSuccess = true; } } } CloseHandle( hFile ); } if( !bSuccess ) { if( pGlobalSettingsData ) CoTaskMemFree( pGlobalSettingsData ); pGlobalSettingsData = NULL; dwGlobalSettingsFileSize = 0; } XACT_RUNTIME_PARAMETERS xrParams = {0}; xrParams.pGlobalSettingsBuffer = pGlobalSettingsData; xrParams.globalSettingsBufferSize = dwGlobalSettingsFileSize; xrParams.globalSettingsFlags = XACT_FLAG_GLOBAL_SETTINGS_MANAGEDATA; // this will tell XACT to delete[] the buffer when its unneeded //xrParams.fnNotificationCallback = XACTNotificationCallback; xrParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; pXACT3Engine->Initialize( &xrParams ); // Setup 3D audio structs ZeroMemory( &listener, sizeof( X3DAUDIO_LISTENER ) ); listener.OrientFront = D3DXVECTOR3( 0, 0, 1 ); listener.OrientTop = D3DXVECTOR3( 0, 1, 0 ); listener.Position = D3DXVECTOR3( 0, 5, 0 ); listener.Velocity = D3DXVECTOR3( 0, 0, 0 ); ZeroMemory( &emitter, sizeof( X3DAUDIO_EMITTER ) ); emitter.pCone = NULL; emitter.OrientFront = D3DXVECTOR3( 0, 0, 1 ); emitter.OrientTop = D3DXVECTOR3( 0, 1, 0 ); emitter.Position = D3DXVECTOR3( 0, 0, 0 ); emitter.Velocity = D3DXVECTOR3( 0, 0, 0 ); emitter.ChannelCount = 2; emitter.ChannelRadius = 1.0f; emitter.pChannelAzimuths = NULL; emitter.pVolumeCurve = NULL; emitter.pLFECurve = NULL; emitter.pLPFDirectCurve = NULL; emitter.pLPFReverbCurve = NULL; emitter.pReverbCurve = NULL; emitter.CurveDistanceScaler = 1.0f; emitter.DopplerScaler = NULL; DelayTimes[0] = 0.0f; DelayTimes[1] = 0.0f; // Init MatrixCoefficients. XACT will fill in the values ZeroMemory( &MatrixCoefficients, sizeof( FLOAT32 ) * 8 * 2 ); // query number of channels on the final mix WAVEFORMATEXTENSIBLE wfxFinalMixFormat; pXACT3Engine->GetFinalMixFormat( &wfxFinalMixFormat ); WORD nDstChannelCount = wfxFinalMixFormat.Format.nChannels; ZeroMemory( &dspSettings, sizeof( X3DAUDIO_DSP_SETTINGS ) ); dspSettings.pMatrixCoefficients = MatrixCoefficients; dspSettings.pDelayTimes = DelayTimes; dspSettings.SrcChannelCount = 2; dspSettings.DstChannelCount = nDstChannelCount; // Initialize 3D settings XACT3DInitialize( pXACT3Engine, x3DInstance ); // Read and register the wave bank file with XACT using memory mapped file IO // Memory mapped files tend to be the fastest for most situations assuming you // have enough virtual address space for a full map of the file hFile = CreateFile( wbPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { dwFileSize = GetFileSize( hFile, NULL ); if( dwFileSize != -1 ) { hMapFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, dwFileSize, NULL ); if( hMapFile ) { pbWaveBank = MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, 0 ); if( pbWaveBank ) { pXACT3Engine->CreateInMemoryWaveBank( pbWaveBank, dwFileSize, 0, 0, &pWaveBank ); } CloseHandle( hMapFile ); // pbWaveBank is maintains a handle on the file so close this unneeded handle } } CloseHandle( hFile ); // pbWaveBank is maintains a handle on the file so close this unneeded handle } // Read and register the sound bank file with XACT. Do not use memory mapped file IO because the // memory needs to be read/write and the working set of sound banks are small. hFile = CreateFile( sbPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { dwFileSize = GetFileSize( hFile, NULL ); if( dwFileSize != -1 ) { // Allocate the data here and free the data when recieving the sound bank destroyed notification pbSoundBank = new BYTE[dwFileSize]; if( pbSoundBank ) { if( 0 != ReadFile( hFile, pbSoundBank, dwFileSize, &dwBytesRead, NULL ) ) { pXACT3Engine->CreateSoundBank( pbSoundBank, dwFileSize, 0, 0, &pSoundBank ); } } } CloseHandle( hFile ); } bInitialized = true; iBackgroundMusic = pSoundBank->GetCueIndex( "Test" ); iHCIdle = pSoundBank->GetCueIndex( "HC_Idle" ); }
HRESULT Sound::init() { ZeroMemory( &audioState, sizeof( AUDIO_STATE ) ); InitializeCriticalSection( &audioState.cs ); audioState.nCurSongPlaying = -1; audioState.nCurWorld = -1; audioState.bInBattle = false; audioState.bGlobalPaused = false; audioState.bMusicPaused = false; audioState.bBGMPaused = false; audioState.bBGMStopped = false; audioState.bBGMFade = false; audioState.fGlobalVolume = 1.0f; audioState.fMusicVolume = 1.0f; audioState.fBGMVolume = 1.0f; hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ); // COINIT_APARTMENTTHREADED will work too if( SUCCEEDED( hr ) ) { // Switch to auditioning mode based on command line. Change if desired bool bAuditionMode = DoesCommandLineContainAuditionSwitch(); bool bDebugMode = false; DWORD dwCreationFlags = 0; if( bAuditionMode ) dwCreationFlags |= XACT_FLAG_API_AUDITION_MODE; if( bDebugMode ) dwCreationFlags |= XACT_FLAG_API_DEBUG_MODE; #ifdef USE_XACT3 hr = XACT3CreateEngine( dwCreationFlags, &audioState.pEngine ); #else hr = XACTCreateEngine( dwCreationFlags, &audioState.pEngine ); #endif } if( FAILED( hr ) || audioState.pEngine == NULL ) return E_FAIL; // Load the global settings file and pass it into XACTInitialize VOID* pGlobalSettingsData = NULL; DWORD dwGlobalSettingsFileSize = 0; bool bSuccess = false; hFile = CreateFile( L"Sounds.xgs", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile ) { dwGlobalSettingsFileSize = GetFileSize( hFile, NULL ); if( dwGlobalSettingsFileSize != INVALID_FILE_SIZE ) { pGlobalSettingsData = CoTaskMemAlloc( dwGlobalSettingsFileSize ); if( pGlobalSettingsData ) { if( 0 != ReadFile( hFile, pGlobalSettingsData, dwGlobalSettingsFileSize, reinterpret_cast<LPDWORD>(&dwBytesRead), NULL ) ) { bSuccess = true; } } } CloseHandle( hFile ); } if( !bSuccess ) { if( pGlobalSettingsData ) CoTaskMemFree( pGlobalSettingsData ); pGlobalSettingsData = NULL; dwGlobalSettingsFileSize = 0; } // Initialize & create the XACT runtime XACT_RUNTIME_PARAMETERS xrParams = {0}; xrParams.pGlobalSettingsBuffer = pGlobalSettingsData; xrParams.globalSettingsBufferSize = dwGlobalSettingsFileSize; xrParams.globalSettingsFlags = XACT_FLAG_GLOBAL_SETTINGS_MANAGEDATA; // this will tell XACT to delete[] the buffer when its unneeded xrParams.lookAheadTime = 250; xrParams.fnNotificationCallback = XACTNotificationCallback; hr = audioState.pEngine->Initialize( &xrParams ); if( FAILED( hr ) ) return hr; //----------------------------------------------------------------------------------------- // Register for XACT notifications //----------------------------------------------------------------------------------------- // The "wave bank prepared" notification will let the app know when it is save to use // play cues that reference streaming wave data. XACT_NOTIFICATION_DESCRIPTION desc = {0}; desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; desc.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED; audioState.pEngine->RegisterNotification( &desc ); // The "sound bank destroyed" notification will let the app know when it is save to use // play cues that reference streaming wave data. desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; desc.type = XACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED; audioState.pEngine->RegisterNotification( &desc ); // The "cue stop" notification will let the app know when it a song stops so a new one // can be played desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; desc.type = XACTNOTIFICATIONTYPE_CUESTOP; desc.cueIndex = XACTINDEX_INVALID; audioState.pEngine->RegisterNotification( &desc ); // The "cue prepared" notification will let the app know when it a a cue that uses // streaming data has been prepared so it is ready to be used for zero latency streaming desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; desc.type = XACTNOTIFICATIONTYPE_CUEPREPARED; desc.cueIndex = XACTINDEX_INVALID; audioState.pEngine->RegisterNotification( &desc ); // Create an "in memory" XACT wave bank file using memory mapped file IO // Memory mapped files tend to be the fastest for most situations assuming you // have enough virtual address space for a full map of the file hr = E_FAIL; // assume failure hFile = CreateFile( L"InMemory.xwb", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { dwFileSize = GetFileSize( hFile, NULL ); if( dwFileSize != -1 ) { hMapFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, dwFileSize, NULL ); if( hMapFile ) { audioState.pbInMemoryWaveBank = MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, 0 ); if( audioState.pbInMemoryWaveBank ) { hr = audioState.pEngine->CreateInMemoryWaveBank( audioState.pbInMemoryWaveBank, dwFileSize, 0, 0, &audioState.pInMemoryWaveBank ); } CloseHandle( hMapFile ); // pbInMemoryWaveBank maintains a handle on the file so close this unneeded handle } } CloseHandle( hFile ); // pbInMemoryWaveBank maintains a handle on the file so close this unneeded handle } if( FAILED( hr ) ) return E_FAIL; // CleanupXACT() will cleanup state before exiting //----------------------------------------------------------------------------------------- // Create a streaming XACT wave bank file. // Take note of the following: // 1) This wave bank in the XACT project file must marked as a streaming wave bank // This is set inside the XACT authoring tool) // 2) Use FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING flags when opening the file // 3) To use cues that reference this streaming wave bank, you must wait for the // wave bank to prepared first or the playing the cue will fail //----------------------------------------------------------------------------------------- hr = E_FAIL; // assume failure audioState.hStreamingWaveBankFile = CreateFile( L"Stream.xwb", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL ); if( audioState.hStreamingWaveBankFile != INVALID_HANDLE_VALUE ) { XACT_WAVEBANK_STREAMING_PARAMETERS wsParams; ZeroMemory( &wsParams, sizeof( XACT_WAVEBANK_STREAMING_PARAMETERS ) ); wsParams.file = audioState.hStreamingWaveBankFile; wsParams.offset = 0; // 64 means to allocate a 64 * 2k buffer for streaming. // This is a good size for DVD streaming and takes good advantage of the read ahead cache wsParams.packetSize = 64; hr = audioState.pEngine->CreateStreamingWaveBank( &wsParams, &audioState.pStreamingWaveBank ); } if( FAILED( hr ) ) return E_FAIL; // CleanupXACT() will cleanup state before exiting // Read and register the sound bank file with XACT. Do not use memory mapped file IO because the // memory needs to be read/write and the working set of sound banks are small. hr = E_FAIL; // assume failure hFile = CreateFile( L"Sounds.xsb", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { dwFileSize = GetFileSize( hFile, NULL ); if( dwFileSize != -1 ) { // Allocate the data here and free the data when recieving the sound bank destroyed notification audioState.pbSoundBank = new BYTE[dwFileSize]; if( audioState.pbSoundBank ) { if( 0 != ReadFile( hFile, audioState.pbSoundBank, dwFileSize, reinterpret_cast<LPDWORD>(&dwBytesRead), NULL ) ) { hr = audioState.pEngine->CreateSoundBank( audioState.pbSoundBank, dwFileSize, 0, 0, &audioState.pSoundBank ); } } } CloseHandle( hFile ); } if( FAILED( hr ) ) return E_FAIL; // CleanupXACT() will cleanup state before exiting // Get the sound cue index from the sound bank // // Note that if the cue does not exist in the sound bank, the index will be XACTINDEX_INVALID // however this is ok especially during development. The Play or Prepare call will just fail. audioState.iSE = audioState.pSoundBank->GetCueIndex( "se" ); for( int i = 0; i < 2; i++ ) { for( int j = 0; j < 2; j++) { CHAR sz[256]; StringCchPrintfA( sz, 256, "stage%d-%d", i + 1, j + 1 ); audioState.iStage[i][j] = audioState.pSoundBank->GetCueIndex( sz ); } } for( int i = 0; i < 2; i++ ) { CHAR sz[256]; StringCchPrintfA( sz, 256, "battle%d", i + 1 ); audioState.iBattle[i] = audioState.pSoundBank->GetCueIndex( sz ); } audioState.iOpening = audioState.pSoundBank->GetCueIndex( "opening" ); audioState.iBoss = audioState.pSoundBank->GetCueIndex( "boss" ); audioState.iCeiling = audioState.pSoundBank->GetCueIndex( "ceiling" ); audioState.iAttack = audioState.pSoundBank->GetCueIndex( "attack" ); audioState.iBomb = audioState.pSoundBank->GetCueIndex( "bomb" ); audioState.iHit = audioState.pSoundBank->GetCueIndex( "hit" ); audioState.iPuzzleClear = audioState.pSoundBank->GetCueIndex( "puzzleclear" ); audioState.iWalk = audioState.pSoundBank->GetCueIndex( "walk" ); audioState.iGlobalCategory = audioState.pEngine->GetCategory( "Global" ); audioState.iMusicCategory = audioState.pEngine->GetCategory( "Music" ); audioState.iBGMCategory = audioState.pEngine->GetCategory( "BGM" ); return S_OK; }
bool CSoundComponent::InitXACT(const char* engine_xgs) { HRESULT hr; CoInitializeEx( NULL, COINIT_MULTITHREADED ); // COINIT_APARTMENTTHREADED will work too //TODO("Create the XACT engine"); hr=XACT3CreateEngine(0, &mpXEngine); if( FAILED( hr ) || mpXEngine == NULL ) { FAIL("Problems creating XACT engine","InitXACT Failed"); return false; } // Load the global settings file and pass it into XACTInitialize VOID* pGlobalSettingsData = NULL; DWORD dwGlobalSettingsFileSize = 0; bool bSuccess = false; HANDLE hFile = CreateFile( engine_xgs, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile!=INVALID_HANDLE_VALUE ) { dwGlobalSettingsFileSize = GetFileSize( hFile, NULL ); if( dwGlobalSettingsFileSize != INVALID_FILE_SIZE ) { pGlobalSettingsData = CoTaskMemAlloc( dwGlobalSettingsFileSize ); if( pGlobalSettingsData ) { DWORD dwBytesRead; if( 0 != ReadFile( hFile, pGlobalSettingsData, dwGlobalSettingsFileSize, &dwBytesRead, NULL ) ) { bSuccess = true; } } } CloseHandle( hFile ); } if( !bSuccess ) { if( pGlobalSettingsData ) CoTaskMemFree( pGlobalSettingsData ); pGlobalSettingsData = NULL; dwGlobalSettingsFileSize = 0; FAIL(engine_xgs,"Problems opening engine file"); return false; } // Initialize & create the XACT runtime XACT_RUNTIME_PARAMETERS xrParams = {0}; xrParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; xrParams.pGlobalSettingsBuffer = pGlobalSettingsData; xrParams.globalSettingsBufferSize = dwGlobalSettingsFileSize; xrParams.globalSettingsFlags = XACT_FLAG_GLOBAL_SETTINGS_MANAGEDATA; // this will tell XACT to delete[] the buffer when its unneeded //TODO(Initalise the XACT engine); hr=mpXEngine->Initialize(&xrParams); if( FAILED( hr ) ) { FAIL(engine_xgs,"Problems Initalising XACT engine"); return false; } X3DAUDIO_EMITTER emitter = {0}; X3DAUDIO_LISTENER listener = {0}; listener.OrientFront = D3DXVECTOR3( 0, 0, 1 ); listener.OrientTop = D3DXVECTOR3( 0, 1, 0 ); listener.Position = D3DXVECTOR3( 0, 0, 0 ); listener.Velocity = D3DXVECTOR3( 0, 0, 0 ); // the following need to be orthonormal emitter.OrientFront = D3DXVECTOR3( 0, 0, 1 ); emitter.OrientTop = D3DXVECTOR3( 0, 1, 0 ); emitter.Position = D3DXVECTOR3( 0, 0, 0 ); emitter.Velocity = D3DXVECTOR3( 0, 0, 0 ); // needs to not be zero if you want to hear Doppler effect // emitter ChannelCount and DSP Setting's SrcChannelCount must match emitter.ChannelCount = 2; // this will be set by XACT3DCalculate if ChannelCount > 1. emitter.ChannelRadius = 1.0f; // will be set by XACT3DCalculate emitter.pChannelAzimuths = NULL; // will be set by XACT3DCalculate emitter.pVolumeCurve = emitter.pLFECurve = emitter.pLPFDirectCurve = emitter.pLPFReverbCurve = emitter.pReverbCurve = NULL; emitter.CurveDistanceScaler = 1.0; emitter.DopplerScaler = 1.0f; hr = XACT3DInitialize(mpXEngine, xact3dInstance); if( FAILED( hr ) ) { FAIL(engine_xgs,"Problems Initalising XACT 3D engine"); return false; } // check how many output channels are supported WAVEFORMATEXTENSIBLE format; hr = mpXEngine->GetFinalMixFormat(&format); if(FAILED(hr)) { FAIL("BLABLBA"); } // fill the DSP ZeroMemory(&dspSettings,sizeof(dspSettings)); // different code's seem to suggest 1 or 2 channels for the emitter dspSettings.SrcChannelCount = 1; dspSettings.DstChannelCount = format.Format.nChannels; // as supported dspSettings.pMatrixCoefficients = new FLOAT32[dspSettings.SrcChannelCount * dspSettings.DstChannelCount]; ZeroMemory(dspSettings.pMatrixCoefficients ,sizeof(FLOAT32)*dspSettings.SrcChannelCount * dspSettings.DstChannelCount); return true; }
//----------------------------------------------------------------------------------------- // This function does the following steps: // // 1. Initialize XACT by calling pEngine->Initialize // 2. Register for the XACT notification desired // 3. Create the in memory XACT wave bank(s) you want to use // 4. Create the streaming XACT wave bank(s) you want to use // 5. Create the XACT sound bank(s) you want to use // 6. Store indices to the XACT cue(s) your game uses //----------------------------------------------------------------------------------------- HRESULT PrepareXACT() { HRESULT hr; WCHAR str[MAX_PATH]; HANDLE hFile; DWORD dwFileSize; DWORD dwBytesRead; HANDLE hMapFile; // Clear struct ZeroMemory( &g_audioState, sizeof( AUDIO_STATE ) ); InitializeCriticalSection( &g_audioState.cs ); hr = CoInitializeEx( NULL, COINIT_MULTITHREADED ); // COINIT_APARTMENTTHREADED will work too if( SUCCEEDED( hr ) ) { // Switch to auditioning mode based on command line. Change if desired bool bAuditionMode = DoesCommandLineContainAuditionSwitch(); bool bDebugMode = false; DWORD dwCreationFlags = 0; if( bAuditionMode ) dwCreationFlags |= XACT_FLAG_API_AUDITION_MODE; if( bDebugMode ) dwCreationFlags |= XACT_FLAG_API_DEBUG_MODE; hr = XACT3CreateEngine( dwCreationFlags, &g_audioState.pEngine ); } if( FAILED( hr ) || g_audioState.pEngine == NULL ) return E_FAIL; // Initialize & create the XACT runtime XACT_RUNTIME_PARAMETERS xrParams = {0}; xrParams.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; xrParams.fnNotificationCallback = XACTNotificationCallback; hr = g_audioState.pEngine->Initialize( &xrParams ); if( FAILED( hr ) ) return hr; //----------------------------------------------------------------------------------------- // Register for XACT notifications //----------------------------------------------------------------------------------------- // The "wave bank prepared" notification will let the app know when it is save to use // play cues that reference streaming wave data. XACT_NOTIFICATION_DESCRIPTION desc = {0}; desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; desc.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED; g_audioState.pEngine->RegisterNotification( &desc ); // The "sound bank destroyed" notification will let the app know when it is save to use // play cues that reference streaming wave data. desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; desc.type = XACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED; g_audioState.pEngine->RegisterNotification( &desc ); // The "cue stop" notification will let the app know when it a song stops so a new one // can be played desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; desc.type = XACTNOTIFICATIONTYPE_CUESTOP; desc.cueIndex = XACTINDEX_INVALID; g_audioState.pEngine->RegisterNotification( &desc ); // The "cue prepared" notification will let the app know when it a a cue that uses // streaming data has been prepared so it is ready to be used for zero latency streaming desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; desc.type = XACTNOTIFICATIONTYPE_CUEPREPARED; desc.cueIndex = XACTINDEX_INVALID; g_audioState.pEngine->RegisterNotification( &desc ); if( FAILED( hr = FindMediaFileCch( str, MAX_PATH, L"InMemoryWaveBank.xwb" ) ) ) return hr; // Create an "in memory" XACT wave bank file using memory mapped file IO hr = E_FAIL; // assume failure hFile = CreateFile( str, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { dwFileSize = GetFileSize( hFile, NULL ); if( dwFileSize != -1 ) { hMapFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, dwFileSize, NULL ); if( hMapFile ) { g_audioState.pbInMemoryWaveBank = MapViewOfFile( hMapFile, FILE_MAP_READ, 0, 0, 0 ); if( g_audioState.pbInMemoryWaveBank ) { hr = g_audioState.pEngine->CreateInMemoryWaveBank( g_audioState.pbInMemoryWaveBank, dwFileSize, 0, 0, &g_audioState.pInMemoryWaveBank ); } CloseHandle( hMapFile ); // pbInMemoryWaveBank maintains a handle on the file so close this unneeded handle } } CloseHandle( hFile ); // pbInMemoryWaveBank maintains a handle on the file so close this unneeded handle } if( FAILED( hr ) ) return E_FAIL; // CleanupXACT() will cleanup state before exiting //----------------------------------------------------------------------------------------- // Create a streaming XACT wave bank file. // Take note of the following: // 1) This wave bank in the XACT project file must marked as a streaming wave bank // This is set inside the XACT authoring tool) // 2) Use FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING flags when opening the file // 3) To use cues that reference this streaming wave bank, you must wait for the // wave bank to prepared first or the playing the cue will fail //----------------------------------------------------------------------------------------- if( FAILED( hr = FindMediaFileCch( str, MAX_PATH, L"StreamingWaveBank.xwb" ) ) ) return hr; hr = E_FAIL; // assume failure g_audioState.hStreamingWaveBankFile = CreateFile( str, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL ); if( g_audioState.hStreamingWaveBankFile != INVALID_HANDLE_VALUE ) { XACT_WAVEBANK_STREAMING_PARAMETERS wsParams; ZeroMemory( &wsParams, sizeof( XACT_WAVEBANK_STREAMING_PARAMETERS ) ); wsParams.file = g_audioState.hStreamingWaveBankFile; wsParams.offset = 0; // 64 means to allocate a 64 * 2k buffer for streaming. // This is a good size for DVD streaming and takes good advantage of the read ahead cache wsParams.packetSize = 64; hr = g_audioState.pEngine->CreateStreamingWaveBank( &wsParams, &g_audioState.pStreamingWaveBank ); } if( FAILED( hr ) ) return E_FAIL; // CleanupXACT() will cleanup state before exiting // Create the XACT sound bank file with using memory mapped file IO if( FAILED( hr = FindMediaFileCch( str, MAX_PATH, L"sounds.xsb" ) ) ) return hr; hr = E_FAIL; // assume failure hFile = CreateFile( str, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { dwFileSize = GetFileSize( hFile, NULL ); if( dwFileSize != -1 ) { // Allocate the data here and free the data when recieving the sound bank destroyed notification g_audioState.pbSoundBank = new BYTE[dwFileSize]; if( g_audioState.pbSoundBank ) { if( 0 != ReadFile( hFile, g_audioState.pbSoundBank, dwFileSize, &dwBytesRead, NULL ) ) { hr = g_audioState.pEngine->CreateSoundBank( g_audioState.pbSoundBank, dwFileSize, 0, 0, &g_audioState.pSoundBank ); } } } CloseHandle( hFile ); // pbInMemoryWaveBank maintains a handle on the file so close this unneeded handle } if( FAILED( hr ) ) return E_FAIL; // CleanupXACT() will cleanup state before exiting // Get the cue indices from the sound bank g_audioState.iZap = g_audioState.pSoundBank->GetCueIndex( "zap" ); g_audioState.iRev = g_audioState.pSoundBank->GetCueIndex( "rev" ); for( int i = 0; i < 3; i++ ) { CHAR sz[256]; StringCchPrintfA( sz, 256, "song%d", i + 1 ); g_audioState.iSong[i] = g_audioState.pSoundBank->GetCueIndex( sz ); } return S_OK; }