//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 DeviceAudioDX11::tick (const DTfloat dt) { PROFILER(PROFILER_SOUND); if (!_x_audio_2) return; DTfloat sound_on = castFromString<DTboolean>(Globals::getGlobal("SYS_SOUND")) ? 1.0F : 0.0F; DTfloat sound_gain = Globals::hasGlobal("SYS_SOUND_GAIN") ? castFromString<DTfloat>(Globals::getGlobal("SYS_SOUND_GAIN")) : 1.0F; _gain = sound_on * sound_gain; // // Update Camera // if (getCamera()) { // Update Listener Vector3 position = getCamera()->getTranslation(); Vector3 velocity = getCamera()->getVelocity(); Vector3 forward = getCamera()->getForwards(); Vector3 up = getCamera()->getUp(); _x3_listener.OrientFront = X3DAUDIO_VECTOR(forward.x,forward.y,forward.z); _x3_listener.OrientTop = X3DAUDIO_VECTOR(up.x,up.y,up.z); _x3_listener.Position = X3DAUDIO_VECTOR(position.x,position.y,position.z); _x3_listener.Velocity = X3DAUDIO_VECTOR(velocity.x,velocity.y,velocity.z); _x_master_voice->SetVolume(_gain); } else { _x3_listener.OrientFront = X3DAUDIO_VECTOR(0.0F,0.0F,-1.0F); _x3_listener.OrientTop = X3DAUDIO_VECTOR(0.0F,1.0F,0.0F); _x3_listener.Position = X3DAUDIO_VECTOR(0.0F,0.0F,0.0F); _x3_listener.Velocity = X3DAUDIO_VECTOR(0.0F,0.0F,0.0F); _x_master_voice->SetVolume(_gain); } // // Update channels // for (DTuint c = 0; c < _channels.size(); ++c) { DeviceAudioDX11Channel &channel = _channels[c]; SoundSource *source = channel._source; // If there's a source and a sound then this channel is playing if (source) { SoundPacket &packet = channel._packets[channel._current_packet]; // Check to see if sound buffer was starved if (!channel._ready_to_start && packet.getNumBytes() > 0 && !channel._is_playing) { channel._ready_to_start = true; LOG_MESSAGE << "Audio stream starved"; // Check if sound data has been depleted } else if (!channel._ready_to_start && packet.getNumBytes() == 0 && !channel._is_playing) { #if DT2_MULTITHREADED_AUDIO AutoSpinLockRecursive lock(&_lock); #endif stopOnChannel(channel); LOG_MESSAGE << "Audio stream done"; // Update sound } else { // Maybe channel needs to be started if (channel._ready_to_start) { #if DT2_MULTITHREADED_AUDIO AutoSpinLockRecursive lock(&_lock); #endif // Fill buffers if (channel._needs_priming) primeStreaming (channel); channel._is_playing = true; channel._x_voice->Start(); channel._ready_to_start = false; } Vector3 position = source->getTranslation(); Vector3 velocity = source->getVelocity(); //DTboolean looping = source->Get_Looping(); // Instead we loop sounds ourselves DTfloat pitch = source->getPitch(); DTfloat rolloff = source->getRolloff(); DTfloat gain = source->getGain(); // position sound if (!getCamera()) { channel._x3_emitter.Position = X3DAUDIO_VECTOR(0.0F,0.0F,0.0F); } else if (position == Vector3(0.0F,0.0F,0.0F)) { Vector3 camera_position = getCamera()->getTranslation(); channel._x3_emitter.Position = X3DAUDIO_VECTOR(camera_position.x, camera_position.y, camera_position.z); } else { channel._x3_emitter.Position = X3DAUDIO_VECTOR(position.x, position.y, position.z); } channel._x3_emitter.Velocity = X3DAUDIO_VECTOR(velocity.x, velocity.y, velocity.z); channel._x_voice->SetVolume(gain); //::alSourcef(channel._al_source, AL_PITCH, pitch); //CheckAL(); //::alSourcef(channel._al_source, AL_ROLLOFF_FACTOR, rolloff); //CheckAL(); } } } // Update Busses List<Bus>::iterator i; FOR_EACH (i,_busses) { Bus &bus = *i; // Get the number of buffers that have been processed //ALint num_buffers; //::alGetSourcei(bus._al_source, AL_BUFFERS_PROCESSED, &num_buffers); //bus._num_active -= num_buffers; // Pump all of the buffers //while (bus._num_active < 3) { // // // Deque one buffer // //ALuint buffer; // //while (num_buffers > 0) { // // ::alSourceUnqueueBuffers(bus._al_source, 1, &buffer ); // // --num_buffers; // // CheckAL(); // //} // // // Stream chunk in // SoundPacket packet = bus._source->getNextSoundPacket(); // if (packet.getNumBytes() == 0) // break; // // Choose appropriate format // //ALenum format; // //switch(packet.getFormat()) { // // case SoundResource::FORMAT_MONO8: format = AL_FORMAT_MONO8; break; // // case SoundResource::FORMAT_MONO16: format = AL_FORMAT_MONO16; break; // // case SoundResource::FORMAT_STEREO8: format = AL_FORMAT_STEREO8; break; // // case SoundResource::FORMAT_STEREO16: format = AL_FORMAT_STEREO16; break; // //}; // // // Store data into the buffer // //CheckAL(); // //::alBufferData(bus._buffer[0], format, packet.getBuffer(), packet.getNumBytes(), packet.getFrequency()); // //CheckAL(); // // // Enqueue the buffer // //::alSourceQueueBuffers(bus._al_source, 1, &(bus._buffer[0])); // // // Rotate the ring buffer // //ALuint temp = bus._buffer[0]; // //bus._buffer[0] = bus._buffer[1]; // //bus._buffer[1] = bus._buffer[2]; // //bus._buffer[2] = temp; // ++bus._num_active; //} if (bus._num_active > 0) { // Check to make sure source is playing if there is new data //ALenum state; //::alGetSourcei(bus._al_source, AL_SOURCE_STATE, &state); //CheckAL(); // //// Check to see if sound buffer was starved //if (state != AL_PLAYING) { // ::alSourcePlay(bus._al_source); //} } }
void Sound::initialize() { HRESULT res; if (FAILED(res = XAudio2Create(&audio))) { // Failed to create XAudio2 engine instance initialized = false; return; } audio->GetDeviceDetails(0, &details); if (FAILED(res = audio->CreateMasteringVoice(&mVoice, details.OutputFormat.Format.nChannels))) { // Failed to create mastering voice initialized = false; return; } mVoice->SetVolume(1.0f); // Create Sound Effects submix voice (ALL sound effects pass through here) // A Sound Effect must have exactly ONE channel, sample rate of 44100 Hz audio->CreateSubmixVoice(&smSFX, details.OutputFormat.Format.nChannels, 44100); // Create Music submix voice (ALL music passes through here) // Music must have exactly TWO channels, sample rate of 48000 Hz audio->CreateSubmixVoice(&smMusic, 2, 48000); SFXSend.Flags = XAUDIO2_SEND_USEFILTER; SFXSend.pOutputVoice = smSFX; SFXSendList.SendCount = 1; SFXSendList.pSends = &SFXSend; musicSend.Flags = 0; musicSend.pOutputVoice = smMusic; musicSendList.SendCount = 1; musicSendList.pSends = &musicSend; // Set music volume HERE smMusic->SetVolume(0.4f); // Set sound effect volume HERE smSFX->SetVolume(1.0f); wfm = new WAVEFORMATEXTENSIBLE(); ZeroMemory(wfm, sizeof(WAVEFORMATEXTENSIBLE)); loadMusic(ingamemusic, "sounds/ingamemusic.xwm", ingamemusicBuffer, ingameMusicXMABuffer); loadMusic(menumusic, "sounds/menumusic.xwm", menumusicBuffer, menuMusicXMABuffer); loadSound(SFX_ROCKET, "sounds/rocket.xwm"); loadSound(SFX_CRASH, "sounds/crash.xwm"); loadSound(SFX_ENGINE, "sounds/engine.xwm"); loadSound(SFX_BOOST, "sounds/boost.xwm"); loadSound(SFX_LASER, "sounds/laser.xwm"); loadSound(SFX_DROPMINE, "sounds/dropmine.xwm"); loadSound(SFX_SCREAM1, "sounds/scream1.xwm"); loadSound(SFX_SCREAM2, "sounds/scream2.xwm"); loadSound(SFX_SCREAM3, "sounds/scream3.xwm"); loadSound(SFX_CAREXPLODE, "sounds/carexplode.xwm"); loadSound(SFX_EXPLOSION, "sounds/explosion.xwm"); loadSound(SFX_BEEP, "sounds/beep.xwm"); loadSound(SFX_ROCKETLAUNCH, "sounds/rocketlaunch.xwm"); loadSound(SFX_PICKUP, "sounds/pickup.xwm"); loadSound(SFX_SELECT, "sounds/select.xwm"); loadSound(SFX_SHOTGUN, "sounds/shotgun.xwm"); loadSound(SFX_TAKENLEAD, "sounds/takenlead.xwm"); loadSound(SFX_LOSTLEAD, "sounds/lostlead.xwm"); loadSound(SFX_NOAMMO, "sounds/noammo.xwm"); loadSound(SFX_ONE, "sounds/one.xwm"); loadSound(SFX_TWO, "sounds/two.xwm"); loadSound(SFX_THREE, "sounds/three.xwm"); // Now set up 3D audio X3DAudioInitialize(details.OutputFormat.dwChannelMask, X3DAUDIO_SPEED_OF_SOUND, audio3DHandle); listener.pCone = NULL; X3DAUDIO_VECTOR vec; vec.x = 0.0f; vec.y = 0.0f; vec.z = 1.0f; listener.OrientFront = X3DAUDIO_VECTOR(vec); vec.y = 1.0f; vec.z = 0.0f; listener.OrientTop = X3DAUDIO_VECTOR(vec); listener.Position.x = 0.0f; listener.Position.y = 0.0f; listener.Position.z = 0.0f; listener.Velocity.x = 0.0f; listener.Velocity.y = 0.0f; listener.Velocity.z = 0.0f; // Now set up emitters emitters = new X3DAUDIO_EMITTER[NUM_EMITTERS]; for (int i = 0; i < NUM_EMITTERS; i++) { ZeroMemory(&(emitters[i]), sizeof(emitters[i])); emitters[i].ChannelCount = 1; emitters[i].InnerRadius = 6.0f; emitters[i].InnerRadiusAngle = X3DAUDIO_PI * 2.0f; emitters[i].CurveDistanceScaler = 8.0f; emitters[i].DopplerScaler = 1.0f; } ZeroMemory(&dspSettings, sizeof(X3DAUDIO_DSP_SETTINGS)); float* mat = new float[details.OutputFormat.Format.nChannels]; dspSettings.SrcChannelCount = 1; dspSettings.DstChannelCount = details.OutputFormat.Format.nChannels; dspSettings.pMatrixCoefficients = mat; voiceBuffer = new IXAudio2SourceVoice*[maxVoices]; for (int i = 0; i < maxVoices; i++) { voiceBuffer[i] = NULL; audio->CreateSourceVoice(&(voiceBuffer[i]), (WAVEFORMATEX*) wfm, XAUDIO2_VOICE_USEFILTER, XAUDIO2_MAX_FREQ_RATIO, 0, &SFXSendList, 0); } voiceBufferReserved = new IXAudio2SourceVoice*[maxReservedVoices]; for (int i = 0; i < maxReservedVoices; i++) { voiceBufferReserved[i] = NULL; audio->CreateSourceVoice(&(voiceBufferReserved[i]), (WAVEFORMATEX*) wfm, XAUDIO2_VOICE_USEFILTER, XAUDIO2_MAX_FREQ_RATIO, 0, &SFXSendList, 0); } initialized = true; return; }