void AudioWorld::simulate() { if (!mainListener_) { std::fill(std::begin(levelMatrix_), std::end(levelMatrix_), 0.0f); for (const auto& e : emitters_) { e->voice->applyFrequencyRatio(1); e->voice->applyOutputMatrix(deviceDetails_.numSrcCannels, deviceDetails_.numDestCannels, levelMatrix_.data()); } return; } X3DAUDIO_LISTENER listenerParam; ZeroMemory(&listenerParam, sizeof(listenerParam)); listenerParam.OrientFront = toX3DAudioVector(mainListener_->orientation * Vector3::UNIT_Z); listenerParam.OrientTop = toX3DAudioVector(mainListener_->orientation * Vector3::UNIT_Y); listenerParam.Position = toX3DAudioVector(mainListener_->position); listenerParam.Velocity = toX3DAudioVector(mainListener_->velocity); X3DAUDIO_EMITTER emitterParam; ZeroMemory(&emitterParam, sizeof(emitterParam)); /// TODO: emitterParam.InnerRadius = 30; emitterParam.ChannelCount = 1; emitterParam.pVolumeCurve = const_cast<X3DAUDIO_DISTANCE_CURVE*>(&X3DAudioDefault_LinearCurve); emitterParam.CurveDistanceScaler = 500; emitterParam.DopplerScaler = 1; for (const auto& e : emitters_) { emitterParam.OrientFront = toX3DAudioVector(e->orientation * Vector3::UNIT_Z); emitterParam.OrientTop = toX3DAudioVector(e->orientation * Vector3::UNIT_Y); emitterParam.Position = toX3DAudioVector(e->position); emitterParam.Velocity = toX3DAudioVector(e->velocity); X3DAUDIO_DSP_SETTINGS dsp; dsp.pMatrixCoefficients = levelMatrix_.data(); dsp.pDelayTimes = NULL; dsp.SrcChannelCount = deviceDetails_.numSrcCannels; dsp.DstChannelCount = deviceDetails_.numDestCannels; X3DAudioCalculate(x3DAudio_, &listenerParam, &emitterParam, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER, &dsp); e->voice->applyFrequencyRatio(dsp.DopplerFactor); e->voice->applyOutputMatrix(deviceDetails_.numSrcCannels, deviceDetails_.numDestCannels, levelMatrix_.data()); } }
void SoundManager::update(Camera* p_gameCamera) { m_masterVoice->SetVolume(m_masterVolume,0); updateListener(p_gameCamera); X3DAudioCalculate(m_X3DAudioInstance, &m_listener, &m_music->getEmitter(), X3DAUDIO_CALCULATE_MATRIX, &m_music->getDSPSettings()); IXAudio2SourceVoice* voice = m_music->getSource(); m_left = m_matrixCoefficients[0]; m_right = m_matrixCoefficients[1]; voice->SetOutputMatrix( m_masterVoice, 1, m_destChannels, m_matrixCoefficients); if(!m_music->isPlaying()) m_music->play(); }
void Sound::playRocket(X3DAUDIO_EMITTER* emit, IXAudio2SourceVoice* rocket) { rocket->FlushSourceBuffers(); rocket->SubmitSourceBuffer(rocketBufferDetails, rocketWMABuffer); X3DAudioCalculate(audio3DHandle, &listener, emit, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_LPF_DIRECT, &dspSettings); rocket->SetFrequencyRatio(3.0f * dspSettings.DopplerFactor); rocket->SetOutputMatrix(smSFX, 1, details.OutputFormat.Format.nChannels, dspSettings.pMatrixCoefficients); XAUDIO2_FILTER_PARAMETERS filterParameters = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * dspSettings.LPFDirectCoefficient), 1.0f }; rocket->SetFilterParameters(&filterParameters); rocket->Start(); }
void Sound::playEngine(X3DAUDIO_EMITTER* emit, float freq, IXAudio2SourceVoice* engine) { engine->FlushSourceBuffers(); engine->SubmitSourceBuffer(engineBufferDetails, engineWMABuffer); X3DAudioCalculate(audio3DHandle, &listener, emit, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_LPF_DIRECT, &dspSettings); engine->SetOutputMatrix(smSFX, 1, details.OutputFormat.Format.nChannels, dspSettings.pMatrixCoefficients); engine->SetFrequencyRatio(freq); XAUDIO2_FILTER_PARAMETERS filterParameters = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * dspSettings.LPFDirectCoefficient), 1.0f }; engine->SetFilterParameters(&filterParameters); engine->Start(); }
// update updates the position and the orientation of the api sound // void APISound::update(const Vector& position, const Vector& front) { if (pSourceVoice) { X3DAUDIO_VECTOR eFront = {front.x, front.y, front.z}; X3DAUDIO_VECTOR ePosition = {position.x, position.y, position.z}; Emitter.OrientFront = eFront; Emitter.Position = ePosition; // What about Velocity (Doppler) and OrientTop (apparently only for multi-channel audio?) // X3DAudioCalculate() http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.x3daudio.x3daudiocalculate(v=VS.85).aspx X3DAudioCalculate(*pX3DInstance, pListener, &Emitter, X3DAUDIO_CALCULATE_MATRIX, &DSPSettings ); pSourceVoice->SetVolume(volume); pSourceVoice->SetFrequencyRatio(frequencyRatio); pSourceVoice->SetOutputMatrix(pMasteringVoice, DSPSettings.SrcChannelCount, DSPSettings.DstChannelCount, DSPSettings.pMatrixCoefficients); } }
void Sound_Engine::Internal::Update(float dt){ if( nFrameToApply3DAudio == 0 ){// apply settings every other frame //update my position and velicoty D3DXVECTOR3 lVelocity = ( CurrentListenerPos - listener.Position ) / dt; listener.Position = CurrentListenerPos; listener.Velocity = lVelocity; // update each emitter std::vector<int> indextoremove; for(size_t i(0); i<Emitters.size(); i++){ if(Emitters[i].use_count() == 1) { indextoremove.push_back(i); continue; } if(!Emitters[i]->Active) continue;// skip this emitter, it is not active D3DXVECTOR3 eVelocity = ( Emitters[i]->Pos - Emitters[i]->emitter.Position ) / dt; Emitters[i]->emitter.Position = Emitters[i]->Pos; Emitters[i]->emitter.Velocity = eVelocity; X3DAudioCalculate( x3DInstance, &listener, &Emitters[i]->emitter, CALCULATION3D, &dspSettings ); // Apply X3DAudio generated DSP settings to XAudio2 Emitters[i]->sound->SourceVoice->SetFrequencyRatio( dspSettings.DopplerFactor ); Emitters[i]->sound->SourceVoice->SetOutputMatrix( pMasteringVoice, INPUTCHANNELS, nChannels, matrixCoefficients ); Emitters[i]->sound->SourceVoice->SetOutputMatrix(pSubmixVoice, 1, 1, &dspSettings.ReverbLevel); XAUDIO2_FILTER_PARAMETERS FilterParametersDirect = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * dspSettings.LPFDirectCoefficient), 1.0f }; // see XAudio2CutoffFrequencyToRadians() in XAudio2.h for more information on the formula used here Emitters[i]->sound->SourceVoice->SetOutputFilterParameters(pMasteringVoice, &FilterParametersDirect); XAUDIO2_FILTER_PARAMETERS FilterParametersReverb = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * dspSettings.LPFReverbCoefficient), 1.0f }; // see XAudio2CutoffFrequencyToRadians() in XAudio2.h for more information on the formula used here Emitters[i]->sound->SourceVoice->SetOutputFilterParameters(pSubmixVoice, &FilterParametersReverb); } for(size_t i =0; i< indextoremove.size(); i++){ Emitters.erase(Emitters.begin() + i); } } nFrameToApply3DAudio++; nFrameToApply3DAudio &= 1; }
//--- Calculate and apply 3D audio DSP settings to a voice. //--- handles output matrix, doppler effect and filter flags. //--- Only applies those settings compatible with the supplied flags and source voice creation flags. void XACore::Apply3D(IXAudio2SourceVoice *aVoice, const X3DAUDIO_EMITTER* anEmitter, const X3DAUDIO_LISTENER* aListener, const unsigned int flags) const { // Guard against invalid initialisation. if (mStatus != OK) return; // get relevant details from the source voice. XAUDIO2_VOICE_DETAILS voiceDetails; aVoice->GetVoiceDetails(&voiceDetails); // Set up DSP settings. X3DAUDIO_DSP_SETTINGS DSPSettings; SecureZeroMemory(&DSPSettings, sizeof(X3DAUDIO_DSP_SETTINGS)); DSPSettings.SrcChannelCount = voiceDetails.InputChannels; DSPSettings.DstChannelCount = mChannelCount; if (flags & X3DAUDIO_CALCULATE_MATRIX) { // only allocate matrix space if calculate flag is set. DSPSettings.pMatrixCoefficients = new FLOAT32[DSPSettings.SrcChannelCount * DSPSettings.DstChannelCount]; } X3DAudioCalculate(m3DHandle, aListener, anEmitter, flags, &DSPSettings); // Apply the DSP settings identified by the flags to the supplied voice. // check that the voice has the relevant capability through its creation flags. if (flags & X3DAUDIO_CALCULATE_MATRIX) { aVoice->SetOutputMatrix(NULL, DSPSettings.SrcChannelCount, DSPSettings.DstChannelCount, DSPSettings.pMatrixCoefficients); // Free output matrix space that was allocated. delete[] DSPSettings.pMatrixCoefficients; } if ((flags & X3DAUDIO_CALCULATE_DOPPLER) && !(voiceDetails.CreationFlags & XAUDIO2_VOICE_NOPITCH)) { aVoice->SetFrequencyRatio(DSPSettings.DopplerFactor); } if ((flags & X3DAUDIO_CALCULATE_LPF_DIRECT) && (voiceDetails.CreationFlags & XAUDIO2_VOICE_USEFILTER)) { XAUDIO2_FILTER_PARAMETERS FilterParameters = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI / 6.0f * DSPSettings.LPFDirectCoefficient), 1.0f }; aVoice->SetFilterParameters(&FilterParameters); } } // end Apply3D function.
/// Commit all the changes made to 3D settings of listener and sources void CSourceXAudio2::commit3DChanges() { nlassert(_SourceVoice); // Only mono buffers get 3d sound, multi-channel buffers go directly to the speakers without any distance rolloff. if (_Channels > 1) { // _SoundDriver->getDSPSettings()->DstChannelCount = 1; // _Emitter.pVolumeCurve = NULL; // todo: everything // calculate without doppler // 1 result in matrix, use with setvolume // todo: some more stuff... // this isn't really used anyways _SourceVoice->SetFrequencyRatio(_Pitch, _OperationSet); // nlerror(NLSOUND_XAUDIO2_PREFIX "Stereo16 and Stereo8 not fully implemented, have fun! :)"); } else { XAUDIO2_VOICE_DETAILS voiceDetails; _SoundDriver->getMasteringVoice()->GetVoiceDetails(&voiceDetails); FLOAT32 matrixCoefficients[32 * 32]; // technical limit is 32 speakers X3DAUDIO_DSP_SETTINGS dspSettings = { 0 }; dspSettings.pMatrixCoefficients = matrixCoefficients; dspSettings.SrcChannelCount = 1; dspSettings.DstChannelCount = voiceDetails.InputChannels; // // nldebug(NLSOUND_XAUDIO2_PREFIX "_SampleVoice->getBuffer() %u", (uint32)_SampleVoice->getBuffer()); _Emitter.DopplerScaler = _SoundDriver->getListener()->getDopplerScaler(); X3DAUDIO_DISTANCE_CURVE_POINT curve_points[2]; X3DAUDIO_DISTANCE_CURVE curve = { (X3DAUDIO_DISTANCE_CURVE_POINT *)&curve_points[0], 2 }; if (_SoundDriver->getOption(ISoundDriver::OptionManualRolloff)) { float sqrdist = _Relative ? getPos().sqrnorm() : (getPos() - _SoundDriver->getListener()->getPos()).sqrnorm(); float rolloff = ISource::computeManualRolloff(_Alpha, sqrdist, _MinDistance, _MaxDistance); curve_points[0].Distance = 0.f; curve_points[0].DSPSetting = rolloff; curve_points[1].Distance = 1.f; curve_points[1].DSPSetting = rolloff; _Emitter.pVolumeCurve = &curve; _Emitter.pLFECurve = &curve; } else { // divide min distance (distance from where to start attenuation) with rolloff scaler (factor to get faster attenuation) _Emitter.CurveDistanceScaler = _MinDistance / _SoundDriver->getListener()->getRolloffScaler(); // _MaxDistance not implemented (basically should cut off sound beyond maxdistance) } X3DAudioCalculate(_SoundDriver->getX3DAudio(), _Relative ? _SoundDriver->getEmptyListener() // position is relative to listener (we use 0pos listener) : _SoundDriver->getListener()->getListener(), // position is absolute &_Emitter, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER, &dspSettings); FLOAT32 outputMatrix[32 * 32]; if (_DirectDryEnabled) { float directDryGain = _DirectFilterEnabled ? _DirectFilterPassGain * _DirectGain : _DirectGain; for (uint32 i = 0; i < dspSettings.DstChannelCount; ++i) outputMatrix[i] = matrixCoefficients[i] * directDryGain; _SourceVoice->SetOutputMatrix(_DirectDryVoice, 1, dspSettings.DstChannelCount, outputMatrix, _OperationSet); if (_DirectFilterEnabled) { float directFilterGain = _DirectGain - directDryGain; for (uint32 i = 0; i < dspSettings.DstChannelCount; ++i) outputMatrix[i] = matrixCoefficients[i] * directFilterGain; _SourceVoice->SetOutputMatrix(_DirectFilterVoice, 1, dspSettings.DstChannelCount, outputMatrix, _OperationSet); } } if (_EffectDryEnabled) { float monoRolloff = 0.0f; for (uint32 i = 0; i < dspSettings.DstChannelCount; ++i) monoRolloff += matrixCoefficients[i]; monoRolloff /= (float)dspSettings.DstChannelCount; float effectDryGain = _EffectFilterEnabled ? _EffectFilterPassGain * _EffectGain : _EffectGain; float outputSingle = monoRolloff * effectDryGain; _SourceVoice->SetOutputMatrix(_EffectDryVoice, 1, 1, &outputSingle, _OperationSet); if (_EffectFilterEnabled) { float effectFilterGain = _EffectGain - effectDryGain; outputSingle = monoRolloff * effectFilterGain; _SourceVoice->SetOutputMatrix(_EffectFilterVoice, 1, 1, &outputSingle, _OperationSet); } } // nldebug(NLSOUND_XAUDIO2_PREFIX "left: %f, right %f", _SoundDriver->getDSPSettings()->pMatrixCoefficients[0], _SoundDriver->getDSPSettings()->pMatrixCoefficients[1]); _Doppler = dspSettings.DopplerFactor; _SourceVoice->SetFrequencyRatio(_Pitch * _Doppler); } _SoundDriver->getXAudio2()->CommitChanges(_OperationSet); // todo: delay? }
// Starting a sound means adding it // to the current list of active sounds // in the internal channels. // As the SFX info struct contains // e.g. a pointer to the raw data, // it is ignored. // As our sound handling does not handle // priority, it is ignored. // Pitching (that is, increased speed of playback) is set // int I_StartSound2 ( int id, int player, mobj_t *origin, mobj_t *listener_origin, int pitch, int priority ) { if ( !soundHardwareInitialized ) { return id; } int i; XAUDIO2_VOICE_STATE state; activeSound_t* sound = 0; int oldest = 0, oldestnum = -1; // these id's should not overlap if ( id == sfx_sawup || id == sfx_sawidl || id == sfx_sawful || id == sfx_sawhit || id == sfx_stnmov ) { // Loop all channels, check. for (i=0 ; i < NUM_SOUNDBUFFERS ; i++) { sound = &activeSounds[i]; if (sound->valid && ( sound->id == id && sound->player == player ) ) { I_StopSound( sound->id, player ); break; } } } // find a valid channel, or one that has finished playing for (i = 0; i < NUM_SOUNDBUFFERS; ++i) { sound = &activeSounds[i]; if (!sound->valid) break; if (!oldest || oldest > sound->start) { oldestnum = i; oldest = sound->start; } sound->m_pSourceVoice->GetState( &state ); if ( state.BuffersQueued == 0 ) { break; } } // none found, so use the oldest one if (i == NUM_SOUNDBUFFERS) { i = oldestnum; sound = &activeSounds[i]; } // stop the sound with a FlushPackets sound->m_pSourceVoice->Stop(); sound->m_pSourceVoice->FlushSourceBuffers(); // Set up packet XAUDIO2_BUFFER Packet = { 0 }; Packet.Flags = XAUDIO2_END_OF_STREAM; Packet.AudioBytes = lengths[id]; Packet.pAudioData = (BYTE*)S_sfx[id].data; Packet.PlayBegin = 0; Packet.PlayLength = 0; Packet.LoopBegin = XAUDIO2_NO_LOOP_REGION; Packet.LoopLength = 0; Packet.LoopCount = 0; Packet.pContext = NULL; // Set voice volumes sound->m_pSourceVoice->SetVolume( x_SoundVolume ); // Set voice pitch sound->m_pSourceVoice->SetFrequencyRatio( 1 + ((float)pitch-128.f)/95.f ); // Set initial spatialization if ( origin && origin != listener_origin ) { // Update Emitter Position sound->m_Emitter.Position.x = (float)(origin->x >> FRACBITS); sound->m_Emitter.Position.y = 0.f; sound->m_Emitter.Position.z = (float)(origin->y >> FRACBITS); // Calculate 3D positioned speaker volumes DWORD dwCalculateFlags = X3DAUDIO_CALCULATE_MATRIX; X3DAudioCalculate( X3DAudioInstance, &doom_Listener, &sound->m_Emitter, dwCalculateFlags, &sound->m_DSPSettings ); // Pan the voice according to X3DAudio calculation sound->m_pSourceVoice->SetOutputMatrix( NULL, 1, numOutputChannels, sound->m_DSPSettings.pMatrixCoefficients ); sound->localSound = false; } else {
//ACRE_RESULT CFilterPosition::process(short* samples, int sampleCount, int channels, CPlayer *player, const unsigned int* channelSpeakerArray, unsigned int *channelMask, ACRE_VOLUME volume) { ACRE_RESULT CFilterPosition::process(short* samples, int sampleCount, int channels, const unsigned int speakerMask, CSoundMixdownEffect *params) { X3DAUDIO_LISTENER Listener = {}; X3DAUDIO_EMITTER Emitter = {0}; X3DAUDIO_DSP_SETTINGS DSPSettings = {0}; X3DAUDIO_CONE emitterCone = {0}; X3DAUDIO_VECTOR listener_position; X3DAUDIO_VECTOR speaker_position; X3DAUDIO_VECTOR vector_listenerDirection; X3DAUDIO_VECTOR vector_speakerDirection; //LOCK(player); //LOCK(CEngine::getInstance()->getSelf()); float killCoef; float *Matrix = new float[1 * channels]; //LOG("channels: %d", channels); if (!this->p_IsInitialized) { // we need to figure out what channel mask we want to use. /* unsigned int initSpeakers = channelSpeakerArray[0]; LOG("Speaker 1: %d", channelSpeakerArray[0]); for (int i = 1; i < channels; i++) { LOG("Speaker %d: %d", i+1, channelSpeakerArray[i]); initSpeakers = initSpeakers | channelSpeakerArray[i]; } */ X3DAudioInitialize(speakerMask, X3DAUDIO_SPEED_OF_SOUND, this->p_X3DInstance); this->p_IsInitialized = TRUE; } if (CAcreSettings::getInstance()->getDisablePosition()) return ACRE_OK; DSPSettings.SrcChannelCount = 1; DSPSettings.DstChannelCount = channels; DSPSettings.pMatrixCoefficients = Matrix; speaker_position.x = params->getParam("speakerPosX"); speaker_position.y = params->getParam("speakerPosY"); speaker_position.z = params->getParam("speakerPosZ"); Emitter.Position = speaker_position; vector_speakerDirection.x = params->getParam("headVectorX"); vector_speakerDirection.y = params->getParam("headVectorY"); vector_speakerDirection.z = params->getParam("headVectorZ"); Emitter.OrientFront = vector_speakerDirection; Emitter.OrientTop = this->getUpVector(vector_speakerDirection); Emitter.Velocity = X3DAUDIO_VECTOR( 0, 0, 0 ); Emitter.ChannelCount = 1; if (params->getParam("isWorld") == POSITIONAL_EFFECT_ISWORLD) { listener_position.x = CEngine::getInstance()->getSelf()->getWorldPosition().x; listener_position.y = CEngine::getInstance()->getSelf()->getWorldPosition().y; listener_position.z = CEngine::getInstance()->getSelf()->getWorldPosition().z; vector_listenerDirection.x = CEngine::getInstance()->getSelf()->getHeadVector().x; vector_listenerDirection.y = CEngine::getInstance()->getSelf()->getHeadVector().y; vector_listenerDirection.z = CEngine::getInstance()->getSelf()->getHeadVector().z; if (params->getParam("speakingType") == ACRE_SPEAKING_DIRECT) { /*if(CEngine::getInstance()->getSoundEngine()->getCurveModel() == ACRE_CURVE_MODEL_AMPLITUDE) { Emitter.CurveDistanceScaler = (player->getAmplitudeCoef())*(CEngine::getInstance()->getSoundEngine()->getCurveScale()); Emitter.pVolumeCurve = NULL; } else */ if (CEngine::getInstance()->getSoundEngine()->getCurveModel() == ACRE_CURVE_MODEL_SELECTABLE_A) { Emitter.CurveDistanceScaler = 1.0f*(params->getParam("curveScale")); Emitter.pVolumeCurve = NULL; } else if (CEngine::getInstance()->getSoundEngine()->getCurveModel() == ACRE_CURVE_MODEL_SELECTABLE_B) { Emitter.CurveDistanceScaler = 1.0f*(params->getParam("curveScale")); Emitter.pVolumeCurve = (X3DAUDIO_DISTANCE_CURVE *)&distanceCurve; } else { Emitter.CurveDistanceScaler = 1.0f; Emitter.pVolumeCurve = NULL; //Emitter.pVolumeCurve = (X3DAUDIO_DISTANCE_CURVE *)&distanceCurve; } } else { Emitter.CurveDistanceScaler = 1.0f; Emitter.pVolumeCurve = (X3DAUDIO_DISTANCE_CURVE *)&distanceCurve; } } else { listener_position.x = 0.0f; listener_position.y = 0.0f; listener_position.z = 0.0f; vector_listenerDirection.x = 0.0f; vector_listenerDirection.y = 1.0f; vector_listenerDirection.z = 0.0f; Emitter.CurveDistanceScaler = 1.0f; Emitter.pVolumeCurve = (X3DAUDIO_DISTANCE_CURVE *)&distanceCurve; } Emitter.DopplerScaler = 1.0f; Emitter.ChannelRadius = 1.0f; emitterCone.InnerAngle = X3DAUDIO_PI/4; emitterCone.OuterAngle = X3DAUDIO_PI/2; emitterCone.InnerVolume = 1.2f; emitterCone.OuterVolume = 1.0f; Emitter.pCone = &emitterCone; //Listener.pCone = &emitterCone; Emitter.InnerRadius = 2.0f; Emitter.InnerRadiusAngle = X3DAUDIO_PI/4.0f; X3DAUDIO_VECTOR listener_topVec = this->getUpVector(vector_listenerDirection); //float listenerDot = vector_listenerDirection.x*listener_topVec.x + vector_listenerDirection.y*listener_topVec.y + vector_listenerDirection.z*listener_topVec.z; //TRACE("Listener Dot Product: %f", listenerDot); Listener.OrientFront = vector_listenerDirection; Listener.OrientTop = listener_topVec; Listener.Position = listener_position; //UNLOCK(CEngine::getInstance()->getSelf()); //UNLOCK(player); X3DAudioCalculate(this->p_X3DInstance, &Listener, &Emitter, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_EMITTER_ANGLE, &DSPSettings ); /* std::string matrixVals = std::string(""); for (int i = 0; i < channels; i++) { char *mAppend; sprintf(mAppend, "%f, ", Matrix[i]); matrixVals.append(std::string(mAppend)); } TRACE("MATRIX: %s", matrixVals.c_str()); */ TRACE("matrix: c:[%d], %f, %f, %f", channels, Matrix[0], Matrix[1], (Matrix[0] + Matrix[1]));// +Matrix[2] + Matrix[3] + Matrix[4] + Matrix[5])); /* LOG("Positions: d:[%f], l:[%f,%f,%f] s:[%f,%f,%f]", DSPSettings.EmitterToListenerDistance, Listener.Position.x, Listener.Position.y, Listener.Position.z, Emitter.Position.x, Emitter.Position.y, Emitter.Position.z ); */ if (CEngine::getInstance()->getSoundEngine()->getCurveModel() == ACRE_CURVE_MODEL_AMPLITUDE || CEngine::getInstance()->getSoundEngine()->getCurveModel() == ACRE_CURVE_MODEL_SELECTABLE_A) { killCoef = std::max(0.0f,(1-((DSPSettings.EmitterToListenerDistance-(MAX_FALLOFF_DISTANCE))/MAX_FALLOFF_RANGE))); if (DSPSettings.EmitterToListenerDistance < (MAX_FALLOFF_DISTANCE)) { killCoef = 1; } killCoef = std::min(1.0f, killCoef); } else { killCoef = 1; }; //LOG("dis: %f kc: %f ac: %f", DSPSettings.EmitterToListenerDistance, killCoef, this->getPlayer()->getAmplitudeCoef()); for (int x = 0; x < sampleCount * channels; x+=channels) { for (int i = 0; i < channels; i++) { samples[x+i] = (short)(samples[x+i] * Matrix[i] * killCoef); } } if (Matrix) delete Matrix; return ACRE_OK; }
void Sound::playSoundEffect(SoundEffect effect, X3DAUDIO_EMITTER* emit) { IXAudio2SourceVoice* voice = getSFXVoice(); voice->FlushSourceBuffers(); switch (effect) { case SFX_LASER: { voice->SubmitSourceBuffer(laserBufferDetails, laserWMABuffer); break; } case SFX_CRASH: { voice->SubmitSourceBuffer(crashBufferDetails, crashWMABuffer); break; } case SFX_BOOST: { voice->SubmitSourceBuffer(boostBufferDetails, boostWMABuffer); break; } case SFX_DROPMINE: { voice->SubmitSourceBuffer(dropmineBufferDetails, dropmineWMABuffer); break; } case SFX_SCREAM: { // Now pick one of the three screams randomly int choice = std::rand() % 3; voice->SetVolume(2.0f); switch (choice) { case 0: voice->SubmitSourceBuffer(scream1BufferDetails, scream1WMABuffer); break; case 1: voice->SubmitSourceBuffer(scream2BufferDetails, scream2WMABuffer); break; case 2: voice->SubmitSourceBuffer(scream3BufferDetails, scream3WMABuffer); break; default: voice->SubmitSourceBuffer(scream1BufferDetails, scream1WMABuffer); } break; } case SFX_CAREXPLODE: { voice->SetVolume(2.0f); voice->SubmitSourceBuffer(carexplodeBufferDetails, carexplodeWMABuffer); break; } case SFX_EXPLOSION: { voice->SubmitSourceBuffer(explosionBufferDetails, explosionWMABuffer); break; } case SFX_BEEP: { voice->SubmitSourceBuffer(beepBufferDetails, beepWMABuffer); break; } case SFX_ROCKETLAUNCH: { voice->SubmitSourceBuffer(rocketlaunchBufferDetails, rocketlaunchWMABuffer); break; } case SFX_PICKUP: { voice->SetVolume(2.0f); voice->SubmitSourceBuffer(pickupBufferDetails, pickupWMABuffer); break; } case SFX_SELECT: { voice->SubmitSourceBuffer(selectBufferDetails, selectWMABuffer); break; } case SFX_SHOTGUN: { voice->SetVolume(2.5f); voice->SubmitSourceBuffer(shotgunBufferDetails, shotgunWMABuffer); break; } case SFX_TAKENLEAD: { voice->SubmitSourceBuffer(takenleadBufferDetails, takenleadWMABuffer); break; } case SFX_LOSTLEAD: { voice->SubmitSourceBuffer(lostleadBufferDetails, lostleadWMABuffer); break; } case SFX_NOAMMO: { voice->SubmitSourceBuffer(noammoBufferDetails, noammoWMABuffer); break; } case SFX_ONE: { voice->SubmitSourceBuffer(oneBufferDetails, oneWMABuffer); break; } case SFX_TWO: { voice->SubmitSourceBuffer(twoBufferDetails, twoWMABuffer); break; } case SFX_THREE: { voice->SubmitSourceBuffer(threeBufferDetails, threeWMABuffer); break; } default: break; } X3DAudioCalculate(audio3DHandle, &listener, emit, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER | X3DAUDIO_CALCULATE_LPF_DIRECT, &dspSettings); voice->SetOutputMatrix(smSFX, 1, details.OutputFormat.Format.nChannels, dspSettings.pMatrixCoefficients); voice->SetFrequencyRatio(dspSettings.DopplerFactor); XAUDIO2_FILTER_PARAMETERS filterParameters = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * dspSettings.LPFDirectCoefficient), 1.0f }; voice->SetFilterParameters(&filterParameters); voice->Start(); }
void Sound::Draw(X3DDrawContext* pDC) { if (!m_bPlaying) { m_bPlaying = true; Play(); } XAUDIO2_DEVICE_DETAILS& deviceDetails = Gui::deviceDetails; int destChannels = 1; destChannels = deviceDetails.OutputFormat.Format.nChannels; AudioClip* source = dynamic_cast<AudioClip*>(m_currentSource); X3DAUDIO_EMITTER emitter = {0}; emitter.ChannelCount = 1;//source->m_wfx.nChannels; emitter.CurveDistanceScaler = 10;//FLT_MIN; emitter.DopplerScaler = 1; X3DAUDIO_DSP_SETTINGS dspSettings = {0}; FLOAT32* matrix = new FLOAT32[destChannels * 1]; dspSettings.SrcChannelCount = source->m_wave->get_Format().nChannels; dspSettings.DstChannelCount = destChannels; dspSettings.pMatrixCoefficients = matrix; D3DXVECTOR3 emitterPosition = transform(pDC->m_renderContext->modelViewMatrix(), getLocation()); D3DXVECTOR3 emitterVelocity(0, 0, 0); D3DXVECTOR3 emitterOrientTop(0, 1, 0); D3DXVECTOR3 emitterOrientFront(1, 0, 0); emitter.OrientFront = emitterOrientFront; emitter.OrientTop = emitterOrientTop; emitter.Position = emitterPosition; emitter.Velocity = emitterVelocity; // emitter.InnerRadius = 2.0f; // emitter.InnerRadiusAngle = X3DAUDIO_PI/4.0f; emitter.ChannelRadius = 1.0; X3DAudioCalculate(Gui::X3DInstance, &pDC->m_listener, &emitter, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER | X3DAUDIO_CALCULATE_LPF_DIRECT | X3DAUDIO_CALCULATE_REVERB, &dspSettings); m_sourceVoice->SetOutputMatrix(Gui::pMasteringVoice, source->m_wave->get_Format().nChannels, destChannels, dspSettings.pMatrixCoefficients); m_sourceVoice->SetFrequencyRatio(dspSettings.DopplerFactor); m_sourceVoice->SetOutputMatrix(m_submixVoice, 1, 1, &dspSettings.ReverbLevel); XAUDIO2_FILTER_PARAMETERS FilterParametersDirect = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * dspSettings.LPFDirectCoefficient), 1.0f }; // see XAudio2CutoffFrequencyToRadians() in XAudio2.h for more information on the formula used here m_sourceVoice->SetOutputFilterParameters(Gui::pMasteringVoice, &FilterParametersDirect); XAUDIO2_FILTER_PARAMETERS FilterParametersReverb = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * dspSettings.LPFReverbCoefficient), 1.0f }; // see XAudio2CutoffFrequencyToRadians() in XAudio2.h for more information on the formula used here m_sourceVoice->SetOutputFilterParameters(m_submixVoice, &FilterParametersReverb); // XAUDIO2_FILTER_PARAMETERS FilterParameters = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * DSPSettings.LPFDirectCoefficient), 1.0f }; // m_sourceVoice->SetFilterParameters(&FilterParameters); #if 0 if (m_source->m_value) { // Add us the audioclips list of sounds for (int i = 0; i < static_cast<CLAudioClip*>(m_source->m_value)->m_sounds.GetSize(); i++) { if (static_cast<CLAudioClip*>(m_source->m_value)->m_sounds[i] == this) break; } if (i == static_cast<CLAudioClip*>(m_source->m_value)->m_sounds.GetSize()) { static_cast<CLAudioClip*>(m_source->m_value)->m_sounds.Add(this); } } #endif }
void UpdateSample(M3D_Source* sample) { if(sample->pSourceVoice) { X3DAUDIO_EMITTER X3DEmitter; memset(&X3DEmitter, 0, sizeof(X3DAUDIO_EMITTER)); X3DEmitter.ChannelCount = 1; X3DEmitter.Position.x = sample->X; X3DEmitter.Position.y = sample->Y; X3DEmitter.Position.z = sample->Z; X3DEmitter.OrientFront.x = sample->X_face; X3DEmitter.OrientFront.y = sample->Y_face; X3DEmitter.OrientFront.z = sample->Z_face; X3DEmitter.OrientTop.x = sample->X_up; X3DEmitter.OrientTop.y = sample->Y_up; X3DEmitter.OrientTop.z = sample->Z_up; X3DEmitter.Velocity.x = sample->dX_per_ms * 1000.0f; X3DEmitter.Velocity.y = sample->dY_per_ms * 1000.0f; X3DEmitter.Velocity.z = sample->dZ_per_ms * 1000.0f; X3DEmitter.CurveDistanceScaler = sample->min_dist; X3DAUDIO_CONE Cone; memset(&Cone, 0, sizeof(X3DAUDIO_CONE)); X3DEmitter.pCone = &Cone; X3DEmitter.pCone->InnerAngle = (sample->inner_angle / 180.0f) * X3DAUDIO_PI; X3DEmitter.pCone->OuterAngle = (sample->outer_angle / 180.0f) * X3DAUDIO_PI; if(X3DEmitter.pCone->OuterAngle < X3DEmitter.pCone->InnerAngle) X3DEmitter.pCone->OuterAngle = X3DEmitter.pCone->InnerAngle; X3DEmitter.pCone->InnerVolume = 1.0f; X3DEmitter.pCone->OuterVolume = (float)sample->outer_volume / G32_SCALE; X3DEmitter.pCone->InnerLPF = 1.0f; X3DEmitter.pCone->OuterLPF = (float)sample->outer_volume / G32_SCALE; X3DEmitter.pCone->InnerReverb = 1.0f; X3DEmitter.pCone->OuterReverb = (float)sample->outer_volume / G32_SCALE; X3DAUDIO_DISTANCE_CURVE_POINT ReverbCurvePoints[2]; ReverbCurvePoints[0].Distance = 0.0f; ReverbCurvePoints[0].DSPSetting = 1.0f; ReverbCurvePoints[1].Distance = 1.0f; ReverbCurvePoints[1].DSPSetting = 1.0f; X3DAUDIO_DISTANCE_CURVE ReverbCurve; ReverbCurve.PointCount = 2; ReverbCurve.pPoints = ReverbCurvePoints; X3DEmitter.pReverbCurve = &ReverbCurve; X3DAudioCalculate(X3DAudioInstance, &Listener.X3DListener, &X3DEmitter, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER | X3DAUDIO_CALCULATE_LPF_DIRECT | X3DAUDIO_CALCULATE_REVERB | X3DAUDIO_CALCULATE_LPF_REVERB, &X3DDSPSettings); sample->pSourceVoice->SetOutputMatrix(pMasterVoice, 1, X3DDSPSettings.DstChannelCount, X3DDSPSettings.pMatrixCoefficients); if(sample->pSubmixVoice) { X3DDSPSettings.ReverbLevel *= ReverbVolume; sample->pSourceVoice->SetOutputMatrix(sample->pSubmixVoice, 1, 1, &X3DDSPSettings.ReverbLevel); } float FreqRatioScale = 1.0f; if(sample->playback_rate && sample->Format.nSamplesPerSec) FreqRatioScale = ((float)sample->playback_rate / (float)sample->Format.nSamplesPerSec); sample->pSourceVoice->SetFrequencyRatio(FreqRatioScale * X3DDSPSettings.DopplerFactor); float VolumeScale = 1.0f; if(sample->obstruction <= 1.0f) VolumeScale -= sample->obstruction; sample->pSourceVoice->SetVolume((float)sample->volume / G32_SCALE * VolumeScale); float LowPassScale = 1.0f; if(sample->occlusion <= 1.0f) LowPassScale -= sample->occlusion; XAUDIO2_FILTER_PARAMETERS FilterParametersDirect = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * X3DDSPSettings.LPFDirectCoefficient) * LowPassScale, 1.0f }; sample->pSourceVoice->SetOutputFilterParameters(pMasterVoice, &FilterParametersDirect); if(sample->pSubmixVoice) { XAUDIO2_FILTER_PARAMETERS FilterParametersReverb = { LowPassFilter, 2.0f * sinf(X3DAUDIO_PI/6.0f * X3DDSPSettings.LPFReverbCoefficient) * LowPassScale, 1.0f }; sample->pSourceVoice->SetOutputFilterParameters(sample->pSubmixVoice, &FilterParametersReverb); } } }