void Sound_Engine::Internal::Init(){ pXAudio2=0; pMasteringVoice=0; pSubmixVoice=0; pReverbEffect=0; nFrameToApply3DAudio=0; dwChannelMask=0; nChannels=0; CoInitializeEx(NULL, COINIT_MULTITHREADED); HR(XAudio2Create( &pXAudio2, 0 )) ; HR(pXAudio2->CreateMasteringVoice( &pMasteringVoice ) ); // Check device details to make sure it's within our sample supported parameters XAUDIO2_DEVICE_DETAILS details; HR(pXAudio2->GetDeviceDetails( 0, &details ) ); if( details.OutputFormat.Format.nChannels > OUTPUTCHANNELS ){ RELEASECOM( pXAudio2 ); assert(true); } dwChannelMask = details.OutputFormat.dwChannelMask; nChannels = details.OutputFormat.Format.nChannels; HR(XAudio2CreateReverb( &pReverbEffect, 0 ) ); // Create reverb effect // Create a submix voice // Performance tip: you need not run global FX with the sample number // of channels as the final mix. For example, this sample runs // the reverb in mono mode, thus reducing CPU overhead. XAUDIO2_EFFECT_DESCRIPTOR effects[] = { { pReverbEffect, TRUE, 1 } }; XAUDIO2_EFFECT_CHAIN effectChain = { 1, effects }; HR(pXAudio2->CreateSubmixVoice( &pSubmixVoice, 1,details.OutputFormat.Format.nSamplesPerSec, 0, 0, NULL, &effectChain ) ); // Set default FX params XAUDIO2FX_REVERB_PARAMETERS native; ReverbConvertI3DL2ToNative( &g_PRESET_PARAMS[0], &native ); pSubmixVoice->SetEffectParameters( 0, &native, sizeof( native ) ); // // Initialize X3DAudio // Speaker geometry configuration on the final mix, specifies assignment of channels // to speaker positions, defined as per WAVEFORMATEXTENSIBLE.dwChannelMask X3DAudioInitialize( details.OutputFormat.dwChannelMask, X3DAUDIO_SPEED_OF_SOUND, x3DInstance ); CurrentListenerPos = D3DXVECTOR3( 0, 0, 0 ); listener.Position = CurrentListenerPos; listener.OrientFront = D3DXVECTOR3( 0, 0, 1 ); listener.OrientTop = D3DXVECTOR3( 0, 1, 0 ); listener.pCone = (X3DAUDIO_CONE*)&Listener_DirectionalCone; dspSettings.SrcChannelCount = INPUTCHANNELS; dspSettings.DstChannelCount = nChannels; dspSettings.pMatrixCoefficients = matrixCoefficients; }
int CZPlayer::InitAudio() { ZeroMemory(m_audioState,sizeof(AUDIO_STATE)); CoInitializeEx(NULL,COINIT_MULTITHREADED); UINT32 flags = 0; #ifdef _DEBUG flags |= XAUDIO2_DEBUG_ENGINE; #endif HRESULT hr; if(FAILED(hr = XAudio2Create(&m_audioState->pXAudio2,flags))) return -1; if( FAILED( hr = m_audioState->pXAudio2->CreateMasteringVoice( &m_audioState->pMasteringVoice ) ) ) { SAFE_RELEASE( m_audioState->pXAudio2 ); return -1; } if( FAILED( hr = m_audioState->pXAudio2->GetDeviceDetails( 0, &m_details ) ) ) { SAFE_RELEASE( m_audioState->pXAudio2 ); return -1; } // // Create reverb effect // flags = 0; #ifdef _DEBUG flags |= XAUDIO2FX_DEBUG; #endif if( FAILED( hr = XAudio2CreateReverb( &m_audioState->pReverbEffect, flags ) ) ) { SAFE_RELEASE( m_audioState->pXAudio2 ); return -1; } //Create a submix voice //Performance tip: you need not run global FX with the sample number //of channels as the final mix. For example, this sample runs //the reverb in mono mode, thus reducing CPU overhead. XAUDIO2_EFFECT_DESCRIPTOR effects[] = { { m_audioState->pReverbEffect, TRUE, 1 } }; XAUDIO2_EFFECT_CHAIN effectChain = { 1, effects }; if( FAILED( hr = m_audioState->pXAudio2->CreateSubmixVoice( &m_audioState->pSubmixVoice, 1, m_details.OutputFormat.Format.nSamplesPerSec, 0, 0, NULL, &effectChain ) ) ) { SAFE_RELEASE( m_audioState->pXAudio2 ); SAFE_RELEASE( m_audioState->pReverbEffect ); return -1; } XAUDIO2FX_REVERB_PARAMETERS native; ReverbConvertI3DL2ToNative( &g_PRESET_PARAMS[1], &native ); m_audioState->pSubmixVoice->SetEffectParameters( 0, &native, sizeof( native ) ); m_audioState->pSourceVoice = 0; // done m_audioState->bInitialized = true; m_playerState.stop = true; return 0; }
bool Audio3D::initialiseAudio() { if (m_masteringVoice != NULL) m_masteringVoice->DestroyVoice(); SAFE_RELEASE(m_XAudio2); HRESULT hr; if (FAILED(hr = XAudio2Create( &m_XAudio2, 0))) { LOG->logMsg(LT_ERROR, "Error while creating XAudio2: %#X", hr); SAFE_RELEASE(m_XAudio2); return false; } if (FAILED(hr = m_XAudio2->CreateMasteringVoice(&m_masteringVoice))) { LOG->logMsg(LT_ERROR, "Audio3D: Error while creating master voice: %#X", hr); return false; } XAUDIO2_DEVICE_DETAILS details; if( FAILED( hr = m_XAudio2->GetDeviceDetails( 0, &details ) ) ) { SAFE_RELEASE( m_XAudio2 ); LOG->logMsg(LT_ERROR, "Failed to retrieve DeviceDetails: %#X", hr); return false; } if( details.OutputFormat.Format.nChannels > OUTPUTCHANNELS ) { SAFE_RELEASE( m_XAudio2 ); LOG->logMsg(LT_ERROR, "nChannels too large."); return false; } m_channelMask = details.OutputFormat.dwChannelMask; m_channels = details.OutputFormat.Format.nChannels; //Create reverb effect: if( FAILED( hr = XAudio2CreateReverb( &m_reverbEffect, 0 ) ) ) { SAFE_RELEASE( m_XAudio2 ); LOG->logMsg(LT_ERROR, "Failed to create reverb: %#X", hr); return false; } //Create submix voice for mixing effects XAUDIO2_EFFECT_DESCRIPTOR effects[] = { { m_reverbEffect, TRUE, 1 } }; XAUDIO2_EFFECT_CHAIN effectChain = { 1, effects }; if( FAILED( hr = m_XAudio2->CreateSubmixVoice( &m_submixVoice, 1, details.OutputFormat.Format.nSamplesPerSec, 0, 0, NULL, &effectChain ) ) ) { SAFE_RELEASE( m_XAudio2 ); SAFE_RELEASE( m_reverbEffect ); LOG->logMsg(LT_ERROR, "Failed to create submix voice: %#X", hr); return false; } // Set default FX params XAUDIO2FX_REVERB_PARAMETERS native; ReverbConvertI3DL2ToNative( &PRESET_PARAMS[0], &native ); m_submixVoice->SetEffectParameters( 0, &native, sizeof( native ) ); const float SPEEDOFSOUND = X3DAUDIO_SPEED_OF_SOUND; X3DAudioInitialize( details.OutputFormat.dwChannelMask, SPEEDOFSOUND, m_x3DInstance ); m_useInnerRadius = true; m_listenerPos = D3DXVECTOR3( 0, 0, 0 ); m_useRedirectToLFE = ((details.OutputFormat.dwChannelMask & SPEAKER_LOW_FREQUENCY) != 0); // // Setup 3D audio structs // m_listener.Position = m_listenerPos; m_listener.OrientFront = D3DXVECTOR3( 0, 1, 0 ); m_listener.OrientTop = D3DXVECTOR3( 0, 1, 0 ); m_listener.pCone = (X3DAUDIO_CONE*)&m_listener_DirectionalCone; //LOG->logMsg(LT_STATUS, "Audio3D: initialized."); this->m_curveDistanceScaler = 60.0f; m_initialized = true; return true; }
void Sound::Play() { ASSERT(m_currentSource); XAUDIO2_DEVICE_DETAILS& deviceDetails = Gui::deviceDetails; AudioClip* source = dynamic_cast<AudioClip*>(m_currentSource); if (m_sourceVoice == nullptr) { // // Create reverb effect // UINT32 flags = 0; #ifdef _DEBUG flags |= XAUDIO2FX_DEBUG; #endif XAudio2CreateReverb(&m_reverbEffect, flags); // Performance tip: you need not run global FX with the sample number // of channels as the final mix. For example, this sample runs // the reverb in mono mode, thus reducing CPU overhead. XAUDIO2_EFFECT_DESCRIPTOR effects[] = { { m_reverbEffect, TRUE, 1 } }; XAUDIO2_EFFECT_CHAIN effectChain = { _countof(effects), effects }; Gui::pXAudio2->CreateSubmixVoice(&m_submixVoice, 1, // Input channels deviceDetails.OutputFormat.Format.nSamplesPerSec, // Input sample rate 0, // Flags 0, // ProcessingStage nullptr, // SendList &effectChain); XAUDIO2FX_REVERB_I3DL2_PARAMETERS g_PRESET_PARAMS[1] = { XAUDIO2FX_I3DL2_PRESET_FOREST }; // Set default FX params XAUDIO2FX_REVERB_PARAMETERS native; ReverbConvertI3DL2ToNative(&g_PRESET_PARAMS[0], &native); m_submixVoice->SetEffectParameters(0, &native, sizeof(native)); // // Play the wave using a source voice that sends to both the submix and mastering voices // XAUDIO2_SEND_DESCRIPTOR sendDescriptors[2]; sendDescriptors[0].Flags = XAUDIO2_SEND_USEFILTER; // LPF direct-path sendDescriptors[0].pOutputVoice = Gui::pMasteringVoice; sendDescriptors[1].Flags = XAUDIO2_SEND_USEFILTER; // LPF reverb-path -- omit for better performance at the cost of less realistic occlusion sendDescriptors[1].pOutputVoice = m_submixVoice; const XAUDIO2_VOICE_SENDS sendList = { _countof(sendDescriptors), sendDescriptors }; Gui::pXAudio2->CreateSourceVoice(&m_sourceVoice, &source->m_wave->get_Format(), XAUDIO2_VOICE_USEFILTER, XAUDIO2_DEFAULT_FREQ_RATIO, nullptr, &sendList, nullptr); #if 0 XAUDIO2_SEND_DESCRIPTOR SFXSend[] = { {0/*XAUDIO2_SEND_USEFILTER*/, m_scene->m_submixVoice}, {0/*XAUDIO2_SEND_USEFILTER*/, Gui::pMasteringVoice}, }; XAUDIO2_VOICE_SENDS SFXSendList = {_countof(SFXSend), SFXSend}; Gui::pXAudio2->CreateSourceVoice(&m_sourceVoice, (WAVEFORMATEX*)&source->m_wfx, XAUDIO2_VOICE_USEFILTER, XAUDIO2_DEFAULT_FREQ_RATIO, NULL, &SFXSendList, NULL); #endif } ASSERT(source->m_wave->m_audioBytes <= XAUDIO2_MAX_BUFFER_BYTES); XAUDIO2_BUFFER buffer; buffer.AudioBytes = source->m_wave->m_audioBytes; buffer.Flags = XAUDIO2_END_OF_STREAM; buffer.LoopBegin = 0; buffer.LoopCount = XAUDIO2_LOOP_INFINITE; buffer.LoopLength = 0; buffer.pAudioData = source->m_wave->m_audioData; buffer.pContext = nullptr; buffer.PlayBegin = 0; buffer.PlayLength = 0; float volume = getIntensity(); // TODO ?? m_sourceVoice->SetVolume(volume); m_sourceVoice->SubmitSourceBuffer(&buffer); m_sourceVoice->Start(0, XAUDIO2_COMMIT_NOW); }
M3D_RESULT __stdcall M3D_activate(int enable) { if(enable) { if(pXAudio2) return M3D_ALREADY_STARTED; char ReverbVolumeText[256]; if(!GothicReadIniString("PARAMETERS", "ReverbVolume", "3.0", ReverbVolumeText, 256, "SystemPack.ini")) GothicWriteIniString("PARAMETERS", "ReverbVolume", "3.0", "SystemPack.ini"); ReverbVolume = (float)atof(ReverbVolumeText); HRESULT hResult = S_OK; if(FAILED(hResult = XAudio2Create(&pXAudio2, 0, XAUDIO2_DEFAULT_PROCESSOR))) { #ifdef LOG fprintf(Log, "M3D_activate XAudio2Create failed %d\n", hResult); #endif return M3D_NOT_INIT; } memset(&deviceDetails, 0, sizeof(XAUDIO2_DEVICE_DETAILS)); if(FAILED(hResult = pXAudio2->GetDeviceDetails(0, &deviceDetails))) { pXAudio2->Release(); pXAudio2 = NULL; #ifdef LOG fprintf(Log, "M3D_activate GetDeviceDetails failed %d\n", hResult); #endif return M3D_NOT_INIT; } UINT32 SampleRate = MIN(MAX(deviceDetails.OutputFormat.Format.nSamplesPerSec, XAUDIO2FX_REVERB_MIN_FRAMERATE), XAUDIO2FX_REVERB_MAX_FRAMERATE); if(FAILED(hResult = pXAudio2->CreateMasteringVoice(&pMasterVoice, XAUDIO2_DEFAULT_CHANNELS, SampleRate))) { pXAudio2->Release(); pXAudio2 = NULL; #ifdef LOG fprintf(Log, "M3D_activate CreateMasteringVoice failed %d\n", hResult); #endif return M3D_NOT_INIT; } X3DAudioInitialize(deviceDetails.OutputFormat.dwChannelMask, X3DAUDIO_SPEED_OF_SOUND, X3DAudioInstance); memset(&Listener, 0, sizeof(M3D_Listener)); Listener.pMasterVoice = pMasterVoice; Listener.Z_face = 1.0f; Listener.Y_up = 1.0f; UpdateAllSamples(); X3DDSPSettings.SrcChannelCount = 1; X3DDSPSettings.DstChannelCount = deviceDetails.OutputFormat.Format.nChannels; X3DDSPSettings.pMatrixCoefficients = new FLOAT32[deviceDetails.OutputFormat.Format.nChannels]; memset(X3DDSPSettings.pMatrixCoefficients, 0, sizeof(FLOAT32) * deviceDetails.OutputFormat.Format.nChannels); Samples = new M3D_Source[MAX_SAMPLES_COUNT]; memset(Samples, 0, sizeof(M3D_Source) * MAX_SAMPLES_COUNT); for(int i = 0; i < MAX_SAMPLES_COUNT; i++) { SetSampleDefaults(&Samples[i]); if(FAILED(hResult = XAudio2CreateReverb(&Samples[i].pReverbEffect))) { pMasterVoice->DestroyVoice(); pMasterVoice = NULL; pXAudio2->Release(); pXAudio2 = NULL; #ifdef LOG fprintf(Log, "M3D_activate XAudio2CreateReverb failed %d\n", hResult); #endif return M3D_NOT_INIT; } XAUDIO2_EFFECT_DESCRIPTOR effects[] = { { Samples[i].pReverbEffect, TRUE, 1 } }; XAUDIO2_EFFECT_CHAIN effectChain = { 1, effects }; if(FAILED(hResult = pXAudio2->CreateSubmixVoice(&Samples[i].pSubmixVoice, 1, SampleRate, 0, 0, NULL, Samples[i].pReverbEffect ? &effectChain : NULL))) { Samples[i].pReverbEffect->Release(); Samples[i].pReverbEffect = NULL; pMasterVoice->DestroyVoice(); pMasterVoice = NULL; pXAudio2->Release(); pXAudio2 = NULL; #ifdef LOG fprintf(Log, "M3D_activate CreateSubmixVoice(%d) failed %d\n", deviceDetails.OutputFormat.Format.nSamplesPerSec, hResult); #endif return M3D_NOT_INIT; } XAUDIO2FX_REVERB_PARAMETERS native; ReverbConvertI3DL2ToNative( &ROOM_PRESET_PARAMS[Current_EAX_room_type], &native ); Samples[i].pSubmixVoice->SetEffectParameters(0, &native, sizeof(native)); } } else { if(!pXAudio2) return M3D_NOT_INIT; if(Samples) { for(int i = 0; i < MAX_SAMPLES_COUNT; i++) { M3D_end_3D_sample((M3D_SAMPLE)&Samples[i]); if(Samples[i].pSubmixVoice) { Samples[i].pSubmixVoice->DestroyVoice(); Samples[i].pSubmixVoice = NULL; } if(Samples[i].pReverbEffect) { Samples[i].pReverbEffect->Release(); Samples[i].pReverbEffect = NULL; } } delete[] Samples; Samples = NULL; } if(pMasterVoice) { pMasterVoice->DestroyVoice(); pMasterVoice = NULL; } if(X3DDSPSettings.pMatrixCoefficients) { delete[] X3DDSPSettings.pMatrixCoefficients; X3DDSPSettings.pMatrixCoefficients = NULL; } if(pXAudio2) { pXAudio2->Release(); pXAudio2 = NULL; } } #ifdef LOG fprintf(Log, "M3D_activate(%d) ok\n", enable); #endif return M3D_NOERR; }