62 LOGSTREAM <<
"No audio device configured, opening default.";
78 LOGSTREAM <<
"Failed to open default audio device. Sound disabled.";
95 if (alGetString(AL_VENDOR))
LOG(
"SoundManager: OpenAL vendor is: " + String(alGetString(AL_VENDOR)));
96 if (alGetString(AL_VERSION))
LOG(
"SoundManager: OpenAL version is: " + String(alGetString(AL_VERSION)));
97 if (alGetString(AL_RENDERER))
LOG(
"SoundManager: OpenAL renderer is: " + String(alGetString(AL_RENDERER)));
98 if (alGetString(AL_EXTENSIONS))
LOG(
"SoundManager: OpenAL extensions are: " + String(alGetString(AL_EXTENSIONS)));
99 if (alcGetString(
audio_device, ALC_DEVICE_SPECIFIER))
LOG(
"SoundManager: OpenAL device is: " + String(alcGetString(
audio_device, ALC_DEVICE_SPECIFIER)));
100 if (alcGetString(
audio_device, ALC_EXTENSIONS))
LOG(
"SoundManager: OpenAL ALC extensions are: " + String(alcGetString(
audio_device, ALC_EXTENSIONS)));
106 LOG(
"SoundManager: Found OpenAL EFX extension");
109 alGenEffects = (LPALGENEFFECTS)alGetProcAddress(
"alGenEffects");
110 alDeleteEffects = (LPALDELETEEFFECTS)alGetProcAddress(
"alDeleteEffects");
111 alIsEffect = (LPALISEFFECT)alGetProcAddress(
"alIsEffect");
112 alEffecti = (LPALEFFECTI)alGetProcAddress(
"alEffecti");
113 alEffectf = (LPALEFFECTF)alGetProcAddress(
"alEffectf");
114 alEffectfv = (LPALEFFECTFV)alGetProcAddress(
"alEffectfv");
115 alGenFilters = (LPALGENFILTERS)alGetProcAddress(
"alGenFilters");
116 alDeleteFilters = (LPALDELETEFILTERS)alGetProcAddress(
"alDeleteFilters");
117 alIsFilter = (LPALISFILTER)alGetProcAddress(
"alIsFilter");
118 alFilteri = (LPALFILTERI)alGetProcAddress(
"alFilteri");
119 alFilterf = (LPALFILTERF)alGetProcAddress(
"alFilterf");
136 LOG(
"SoundManager: Reverb engine disabled");
141 if (alGetEnumValue(
"AL_EFFECT_EAXREVERB") != 0)
143 LOG(
"SoundManager: OpenAL driver supports AL_EFFECT_EAXREVERB, using it");
147 LOG(
"SoundManager: AL_EFFECT_EAXREVERB requested but OpenAL driver does not support it, falling back to standard reverb. Advanced features, such as reflection panning, will not be available");
153 LOG(
"SoundManager: Using OpenAL standard reverb");
162 ALuint error = alGetError();
164 if (error != AL_NO_ERROR)
166 LOG(
"SoundManager: alGenAuxiliaryEffectSlots for listener_slot failed: " +
TOSTRING(alGetString(error)));
182 ALuint e = alGetError();
184 if (e != AL_NO_ERROR)
206 if (e != AL_NO_ERROR)
220 LOG(
"SoundManager: OpenAL EFX extension not found, disabling EFX");
229 if (alGetError() != AL_NO_ERROR)
243 alSpeedOfSound(343.3f);
345 m_efx_properties_map[
"EFX_REVERB_PRESET_CASTLE_SHORTPASSAGE"] = EFX_REVERB_PRESET_CASTLE_SHORTPASSAGE;
346 m_efx_properties_map[
"EFX_REVERB_PRESET_CASTLE_LARGEROOM"] = EFX_REVERB_PRESET_CASTLE_LARGEROOM;
347 m_efx_properties_map[
"EFX_REVERB_PRESET_CASTLE_LONGPASSAGE"] = EFX_REVERB_PRESET_CASTLE_LONGPASSAGE;
349 m_efx_properties_map[
"EFX_REVERB_PRESET_CASTLE_COURTYARD"] = EFX_REVERB_PRESET_CASTLE_COURTYARD;
350 m_efx_properties_map[
"EFX_REVERB_PRESET_FACTORY_SMALLROOM"] = EFX_REVERB_PRESET_FACTORY_SMALLROOM;
351 m_efx_properties_map[
"EFX_REVERB_PRESET_FACTORY_SHORTPASSAGE"] = EFX_REVERB_PRESET_FACTORY_SHORTPASSAGE;
352 m_efx_properties_map[
"EFX_REVERB_PRESET_FACTORY_MEDIUMROOM"] = EFX_REVERB_PRESET_FACTORY_MEDIUMROOM;
353 m_efx_properties_map[
"EFX_REVERB_PRESET_FACTORY_LARGEROOM"] = EFX_REVERB_PRESET_FACTORY_LARGEROOM;
354 m_efx_properties_map[
"EFX_REVERB_PRESET_FACTORY_LONGPASSAGE"] = EFX_REVERB_PRESET_FACTORY_LONGPASSAGE;
356 m_efx_properties_map[
"EFX_REVERB_PRESET_FACTORY_COURTYARD"] = EFX_REVERB_PRESET_FACTORY_COURTYARD;
358 m_efx_properties_map[
"EFX_REVERB_PRESET_SPACESTATION_SMALLROOM"] = EFX_REVERB_PRESET_SPACESTATION_SMALLROOM;
359 m_efx_properties_map[
"EFX_REVERB_PRESET_SPACESTATION_SHORTPASSAGE"] = EFX_REVERB_PRESET_SPACESTATION_SHORTPASSAGE;
360 m_efx_properties_map[
"EFX_REVERB_PRESET_SPACESTATION_MEDIUMROOM"] = EFX_REVERB_PRESET_SPACESTATION_MEDIUMROOM;
361 m_efx_properties_map[
"EFX_REVERB_PRESET_SPACESTATION_LARGEROOM"] = EFX_REVERB_PRESET_SPACESTATION_LARGEROOM;
362 m_efx_properties_map[
"EFX_REVERB_PRESET_SPACESTATION_LONGPASSAGE"] = EFX_REVERB_PRESET_SPACESTATION_LONGPASSAGE;
363 m_efx_properties_map[
"EFX_REVERB_PRESET_SPACESTATION_HALL"] = EFX_REVERB_PRESET_SPACESTATION_HALL;
364 m_efx_properties_map[
"EFX_REVERB_PRESET_WOODEN_SMALLROOM"] = EFX_REVERB_PRESET_WOODEN_SMALLROOM;
365 m_efx_properties_map[
"EFX_REVERB_PRESET_WOODEN_SHORTPASSAGE"] = EFX_REVERB_PRESET_WOODEN_SHORTPASSAGE;
366 m_efx_properties_map[
"EFX_REVERB_PRESET_WOODEN_MEDIUMROOM"] = EFX_REVERB_PRESET_WOODEN_MEDIUMROOM;
367 m_efx_properties_map[
"EFX_REVERB_PRESET_WOODEN_LARGEROOM"] = EFX_REVERB_PRESET_WOODEN_LARGEROOM;
368 m_efx_properties_map[
"EFX_REVERB_PRESET_WOODEN_LONGPASSAGE"] = EFX_REVERB_PRESET_WOODEN_LONGPASSAGE;
370 m_efx_properties_map[
"EFX_REVERB_PRESET_WOODEN_COURTYARD"] = EFX_REVERB_PRESET_WOODEN_COURTYARD;
372 m_efx_properties_map[
"EFX_REVERB_PRESET_SPORT_EMPTYSTADIUM"] = EFX_REVERB_PRESET_SPORT_EMPTYSTADIUM;
373 m_efx_properties_map[
"EFX_REVERB_PRESET_SPORT_FULLSTADIUM"] = EFX_REVERB_PRESET_SPORT_FULLSTADIUM;
374 m_efx_properties_map[
"EFX_REVERB_PRESET_SPORT_STADIUMTANNOY"] = EFX_REVERB_PRESET_SPORT_STADIUMTANNOY;
381 m_efx_properties_map[
"EFX_REVERB_PRESET_OUTDOORS_BACKYARD"] = EFX_REVERB_PRESET_OUTDOORS_BACKYARD;
382 m_efx_properties_map[
"EFX_REVERB_PRESET_OUTDOORS_ROLLINGPLAINS"] = EFX_REVERB_PRESET_OUTDOORS_ROLLINGPLAINS;
383 m_efx_properties_map[
"EFX_REVERB_PRESET_OUTDOORS_DEEPCANYON"] = EFX_REVERB_PRESET_OUTDOORS_DEEPCANYON;
389 m_efx_properties_map[
"EFX_REVERB_PRESET_DRIVING_COMMENTATOR"] = EFX_REVERB_PRESET_DRIVING_COMMENTATOR;
390 m_efx_properties_map[
"EFX_REVERB_PRESET_DRIVING_PITGARAGE"] = EFX_REVERB_PRESET_DRIVING_PITGARAGE;
391 m_efx_properties_map[
"EFX_REVERB_PRESET_DRIVING_INCAR_RACER"] = EFX_REVERB_PRESET_DRIVING_INCAR_RACER;
392 m_efx_properties_map[
"EFX_REVERB_PRESET_DRIVING_INCAR_SPORTS"] = EFX_REVERB_PRESET_DRIVING_INCAR_SPORTS;
393 m_efx_properties_map[
"EFX_REVERB_PRESET_DRIVING_INCAR_LUXURY"] = EFX_REVERB_PRESET_DRIVING_INCAR_LUXURY;
394 m_efx_properties_map[
"EFX_REVERB_PRESET_DRIVING_FULLGRANDSTAND"] = EFX_REVERB_PRESET_DRIVING_FULLGRANDSTAND;
395 m_efx_properties_map[
"EFX_REVERB_PRESET_DRIVING_EMPTYGRANDSTAND"] = EFX_REVERB_PRESET_DRIVING_EMPTYGRANDSTAND;
622 const float time_to_target = 0.333f;
624 const float step = std::min(dt / time_to_target, 0.5f);
625 static std::map<ALuint, EFXEAXREVERBPROPERTIES> current_efx_properties_of_slot;
627 if (target_efx_properties ==
nullptr)
633 const auto it = current_efx_properties_of_slot.find(slot_id);
634 if (it == current_efx_properties_of_slot.end())
637 current_efx_properties_of_slot[slot_id] = *target_efx_properties;
640 ALuint efx_effect_id;
653 current_efx_properties_of_slot[slot_id] =
655 current_efx_properties_of_slot[slot_id].flDensity + step * (target_efx_properties->flDensity - current_efx_properties_of_slot[slot_id].flDensity),
656 current_efx_properties_of_slot[slot_id].flDiffusion + step * (target_efx_properties->flDiffusion - current_efx_properties_of_slot[slot_id].flDiffusion),
657 current_efx_properties_of_slot[slot_id].flGain + step * (target_efx_properties->flGain - current_efx_properties_of_slot[slot_id].flGain),
658 current_efx_properties_of_slot[slot_id].flGainHF + step * (target_efx_properties->flGainHF - current_efx_properties_of_slot[slot_id].flGainHF),
659 current_efx_properties_of_slot[slot_id].flGainLF + step * (target_efx_properties->flGainLF - current_efx_properties_of_slot[slot_id].flGainLF),
660 current_efx_properties_of_slot[slot_id].flDecayTime + step * (target_efx_properties->flDecayTime - current_efx_properties_of_slot[slot_id].flDecayTime),
661 current_efx_properties_of_slot[slot_id].flDecayHFRatio + step * (target_efx_properties->flDecayHFRatio - current_efx_properties_of_slot[slot_id].flDecayHFRatio),
662 current_efx_properties_of_slot[slot_id].flDecayLFRatio + step * (target_efx_properties->flDecayLFRatio - current_efx_properties_of_slot[slot_id].flDecayLFRatio),
663 current_efx_properties_of_slot[slot_id].flReflectionsGain + step * (target_efx_properties->flReflectionsGain - current_efx_properties_of_slot[slot_id].flReflectionsGain),
664 current_efx_properties_of_slot[slot_id].flReflectionsDelay + step * (target_efx_properties->flReflectionsDelay - current_efx_properties_of_slot[slot_id].flReflectionsDelay),
665 current_efx_properties_of_slot[slot_id].flReflectionsPan[0] + step * (target_efx_properties->flReflectionsPan[0] - current_efx_properties_of_slot[slot_id].flReflectionsPan[0]),
666 current_efx_properties_of_slot[slot_id].flReflectionsPan[1] + step * (target_efx_properties->flReflectionsPan[1] - current_efx_properties_of_slot[slot_id].flReflectionsPan[1]),
667 current_efx_properties_of_slot[slot_id].flReflectionsPan[2] + step * (target_efx_properties->flReflectionsPan[2] - current_efx_properties_of_slot[slot_id].flReflectionsPan[2]),
668 current_efx_properties_of_slot[slot_id].flLateReverbGain + step * (target_efx_properties->flLateReverbGain - current_efx_properties_of_slot[slot_id].flLateReverbGain),
669 current_efx_properties_of_slot[slot_id].flLateReverbDelay + step * (target_efx_properties->flLateReverbDelay - current_efx_properties_of_slot[slot_id].flLateReverbDelay),
670 current_efx_properties_of_slot[slot_id].flLateReverbPan[0] + step * (target_efx_properties->flLateReverbPan[0] - current_efx_properties_of_slot[slot_id].flLateReverbPan[0]),
671 current_efx_properties_of_slot[slot_id].flLateReverbPan[1] + step * (target_efx_properties->flLateReverbPan[1] - current_efx_properties_of_slot[slot_id].flLateReverbPan[1]),
672 current_efx_properties_of_slot[slot_id].flLateReverbPan[2] + step * (target_efx_properties->flLateReverbPan[2] - current_efx_properties_of_slot[slot_id].flLateReverbPan[2]),
673 current_efx_properties_of_slot[slot_id].flEchoTime + step * (target_efx_properties->flEchoTime - current_efx_properties_of_slot[slot_id].flEchoTime),
674 current_efx_properties_of_slot[slot_id].flEchoDepth + step * (target_efx_properties->flEchoDepth - current_efx_properties_of_slot[slot_id].flEchoDepth),
675 current_efx_properties_of_slot[slot_id].flModulationTime + step * (target_efx_properties->flModulationTime - current_efx_properties_of_slot[slot_id].flModulationTime),
676 current_efx_properties_of_slot[slot_id].flModulationDepth + step * (target_efx_properties->flModulationDepth - current_efx_properties_of_slot[slot_id].flModulationDepth),
677 current_efx_properties_of_slot[slot_id].flAirAbsorptionGainHF + step * (target_efx_properties->flAirAbsorptionGainHF - current_efx_properties_of_slot[slot_id].flAirAbsorptionGainHF),
678 current_efx_properties_of_slot[slot_id].flHFReference + step * (target_efx_properties->flHFReference - current_efx_properties_of_slot[slot_id].flHFReference),
679 current_efx_properties_of_slot[slot_id].flLFReference + step * (target_efx_properties->flLFReference - current_efx_properties_of_slot[slot_id].flLFReference),
680 current_efx_properties_of_slot[slot_id].flRoomRolloffFactor + step * (target_efx_properties->flRoomRolloffFactor - current_efx_properties_of_slot[slot_id].flRoomRolloffFactor),
681 static_cast<int>(std::round(current_efx_properties_of_slot[slot_id].iDecayHFLimit + step * (target_efx_properties->iDecayHFLimit - current_efx_properties_of_slot[slot_id].iDecayHFLimit))),
688 this->
alEffectf( efx_effect_id, AL_EAXREVERB_DENSITY, current_efx_properties_of_slot[slot_id].flDensity);
689 this->
alEffectf( efx_effect_id, AL_EAXREVERB_DIFFUSION, current_efx_properties_of_slot[slot_id].flDiffusion);
690 this->
alEffectf( efx_effect_id, AL_EAXREVERB_GAIN, current_efx_properties_of_slot[slot_id].flGain);
691 this->
alEffectf( efx_effect_id, AL_EAXREVERB_GAINHF, current_efx_properties_of_slot[slot_id].flGainHF);
692 this->
alEffectf( efx_effect_id, AL_EAXREVERB_GAINLF, current_efx_properties_of_slot[slot_id].flGainLF);
693 this->
alEffectf( efx_effect_id, AL_EAXREVERB_DECAY_TIME, current_efx_properties_of_slot[slot_id].flDecayTime);
694 this->
alEffectf( efx_effect_id, AL_EAXREVERB_DECAY_HFRATIO, current_efx_properties_of_slot[slot_id].flDecayHFRatio);
695 this->
alEffectf( efx_effect_id, AL_EAXREVERB_DECAY_LFRATIO, current_efx_properties_of_slot[slot_id].flDecayLFRatio);
696 this->
alEffectf( efx_effect_id, AL_EAXREVERB_REFLECTIONS_GAIN, current_efx_properties_of_slot[slot_id].flReflectionsGain);
697 this->
alEffectf( efx_effect_id, AL_EAXREVERB_REFLECTIONS_DELAY, current_efx_properties_of_slot[slot_id].flReflectionsDelay);
698 this->
alEffectfv(efx_effect_id, AL_EAXREVERB_REFLECTIONS_PAN, current_efx_properties_of_slot[slot_id].flReflectionsPan);
699 this->
alEffectf( efx_effect_id, AL_EAXREVERB_LATE_REVERB_GAIN, current_efx_properties_of_slot[slot_id].flLateReverbGain);
700 this->
alEffectf( efx_effect_id, AL_EAXREVERB_LATE_REVERB_DELAY, current_efx_properties_of_slot[slot_id].flLateReverbDelay);
701 this->
alEffectfv(efx_effect_id, AL_EAXREVERB_LATE_REVERB_PAN, current_efx_properties_of_slot[slot_id].flLateReverbPan);
702 this->
alEffectf( efx_effect_id, AL_EAXREVERB_ECHO_TIME, current_efx_properties_of_slot[slot_id].flEchoTime);
703 this->
alEffectf( efx_effect_id, AL_EAXREVERB_ECHO_DEPTH, current_efx_properties_of_slot[slot_id].flEchoDepth);
704 this->
alEffectf( efx_effect_id, AL_EAXREVERB_MODULATION_TIME, current_efx_properties_of_slot[slot_id].flModulationTime);
705 this->
alEffectf( efx_effect_id, AL_EAXREVERB_MODULATION_DEPTH, current_efx_properties_of_slot[slot_id].flModulationDepth);
706 this->
alEffectf( efx_effect_id, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, current_efx_properties_of_slot[slot_id].flAirAbsorptionGainHF);
707 this->
alEffectf( efx_effect_id, AL_EAXREVERB_HFREFERENCE, current_efx_properties_of_slot[slot_id].flHFReference);
708 this->
alEffectf( efx_effect_id, AL_EAXREVERB_LFREFERENCE, current_efx_properties_of_slot[slot_id].flLFReference);
709 this->
alEffectf( efx_effect_id, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, current_efx_properties_of_slot[slot_id].flRoomRolloffFactor);
710 this->
alEffecti( efx_effect_id, AL_EAXREVERB_DECAY_HFLIMIT, current_efx_properties_of_slot[slot_id].iDecayHFLimit);
714 this->
alEffectf( efx_effect_id, AL_REVERB_DENSITY, current_efx_properties_of_slot[slot_id].flDensity);
715 this->
alEffectf( efx_effect_id, AL_REVERB_DIFFUSION, current_efx_properties_of_slot[slot_id].flDiffusion);
716 this->
alEffectf( efx_effect_id, AL_REVERB_GAIN, current_efx_properties_of_slot[slot_id].flGain);
717 this->
alEffectf( efx_effect_id, AL_REVERB_GAINHF, current_efx_properties_of_slot[slot_id].flGainHF);
718 this->
alEffectf( efx_effect_id, AL_REVERB_DECAY_TIME, current_efx_properties_of_slot[slot_id].flDecayTime);
719 this->
alEffectf( efx_effect_id, AL_REVERB_DECAY_HFRATIO, current_efx_properties_of_slot[slot_id].flDecayHFRatio);
720 this->
alEffectf( efx_effect_id, AL_REVERB_REFLECTIONS_GAIN, current_efx_properties_of_slot[slot_id].flReflectionsGain);
721 this->
alEffectf( efx_effect_id, AL_REVERB_REFLECTIONS_DELAY, current_efx_properties_of_slot[slot_id].flReflectionsDelay);
722 this->
alEffectf( efx_effect_id, AL_REVERB_LATE_REVERB_GAIN, current_efx_properties_of_slot[slot_id].flLateReverbGain);
723 this->
alEffectf( efx_effect_id, AL_REVERB_LATE_REVERB_DELAY, current_efx_properties_of_slot[slot_id].flLateReverbDelay);
724 this->
alEffectf( efx_effect_id, AL_REVERB_AIR_ABSORPTION_GAINHF, current_efx_properties_of_slot[slot_id].flAirAbsorptionGainHF);
725 this->
alEffectf( efx_effect_id, AL_REVERB_ROOM_ROLLOFF_FACTOR, current_efx_properties_of_slot[slot_id].flRoomRolloffFactor);
726 this->
alEffectf( efx_effect_id, AL_REVERB_DECAY_HFLIMIT, current_efx_properties_of_slot[slot_id].iDecayHFLimit);
740 const float max_distance = 2.0f;
741 const float reflections_gain_boost_max = 2.0f;
742 float early_reflections_gain;
743 float early_reflections_delay;
745 Ogre::Vector3 early_reflections_pan = { 0.0f, 0.0f, 0.0f};
752 bool nearby_surface_detected =
false;
753 const float angle_step_size = 90;
754 float closest_surface_distance = std::numeric_limits<float>::max();
756 for (
float angle = 0; angle < 360; angle += angle_step_size)
758 float closest_surface_distance_in_this_direction = std::numeric_limits<float>::max();
760 raycast_direction.normalise();
767 if (intersection.first)
769 closest_surface_distance_in_this_direction = intersection.second * max_distance;
772 ray.setDirection(ray.getDirection().normalisedCopy());
777 if (!collision_box.enabled || collision_box.virt) {
continue; }
778 intersection = ray.intersects(Ogre::AxisAlignedBox(collision_box.lo, collision_box.hi));
779 if (intersection.first && intersection.second <= max_distance)
781 closest_surface_distance_in_this_direction = std::min(closest_surface_distance_in_this_direction, intersection.second);
787 for (
const ActorPtr& actor : actors)
792 intersection = ray.intersects(actor->ar_bounding_box);
793 if (intersection.first && intersection.second <= max_distance)
795 closest_surface_distance_in_this_direction = std::min(closest_surface_distance_in_this_direction, intersection.second);
799 closest_surface_distance = std::min(closest_surface_distance, closest_surface_distance_in_this_direction);
801 if (closest_surface_distance_in_this_direction <= max_distance)
803 early_reflections_pan += raycast_direction * (max_distance - closest_surface_distance_in_this_direction);
807 nearby_surface_detected = closest_surface_distance <= max_distance;
811 if (!nearby_surface_detected)
820 magnitude = 1.0f - early_reflections_pan.length() / Ogre::Math::Sqrt(2.0f * Ogre::Math::Pow(max_distance, 2));
823 early_reflections_delay = closest_surface_distance / this->
GetSpeedOfSound();
825 early_reflections_gain = std::min(
827 + reflections_gain_boost_max
828 - (reflections_gain_boost_max * (magnitude))),
829 AL_EAXREVERB_MAX_REFLECTIONS_GAIN);
836 Ogre::Quaternion horizontal_rotation;
846 early_reflections_pan = horizontal_rotation * early_reflections_pan;
847 early_reflections_pan.normalise();
849 early_reflections_pan = magnitude * early_reflections_pan;
851 return std::make_tuple(early_reflections_pan, early_reflections_gain, early_reflections_delay);
864 this->
alEffecti( effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
866 this->
alEffectf( effect, AL_EAXREVERB_DENSITY, efx_properties->flDensity);
867 this->
alEffectf( effect, AL_EAXREVERB_DIFFUSION, efx_properties->flDiffusion);
868 this->
alEffectf( effect, AL_EAXREVERB_GAIN, efx_properties->flGain);
869 this->
alEffectf( effect, AL_EAXREVERB_GAINHF, efx_properties->flGainHF);
870 this->
alEffectf( effect, AL_EAXREVERB_GAINLF, efx_properties->flGainLF);
871 this->
alEffectf( effect, AL_EAXREVERB_DECAY_TIME, efx_properties->flDecayTime);
872 this->
alEffectf( effect, AL_EAXREVERB_DECAY_HFRATIO, efx_properties->flDecayHFRatio);
873 this->
alEffectf( effect, AL_EAXREVERB_DECAY_LFRATIO, efx_properties->flDecayLFRatio);
874 this->
alEffectf( effect, AL_EAXREVERB_REFLECTIONS_GAIN, efx_properties->flReflectionsGain);
875 this->
alEffectf( effect, AL_EAXREVERB_REFLECTIONS_DELAY, efx_properties->flReflectionsDelay);
876 this->
alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, efx_properties->flReflectionsPan);
877 this->
alEffectf( effect, AL_EAXREVERB_LATE_REVERB_GAIN, efx_properties->flLateReverbGain);
878 this->
alEffectf( effect, AL_EAXREVERB_LATE_REVERB_DELAY, efx_properties->flLateReverbDelay);
879 this->
alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, efx_properties->flLateReverbPan);
880 this->
alEffectf( effect, AL_EAXREVERB_ECHO_TIME, efx_properties->flEchoTime);
881 this->
alEffectf( effect, AL_EAXREVERB_ECHO_DEPTH, efx_properties->flEchoDepth);
882 this->
alEffectf( effect, AL_EAXREVERB_MODULATION_TIME, efx_properties->flModulationTime);
883 this->
alEffectf( effect, AL_EAXREVERB_MODULATION_DEPTH, efx_properties->flModulationDepth);
884 this->
alEffectf( effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, efx_properties->flAirAbsorptionGainHF);
885 this->
alEffectf( effect, AL_EAXREVERB_HFREFERENCE, efx_properties->flHFReference);
886 this->
alEffectf( effect, AL_EAXREVERB_LFREFERENCE, efx_properties->flLFReference);
887 this->
alEffectf( effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, efx_properties->flRoomRolloffFactor);
888 this->
alEffecti( effect, AL_EAXREVERB_DECAY_HFLIMIT, efx_properties->iDecayHFLimit);
892 this->
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
894 this->
alEffectf(effect, AL_REVERB_DENSITY, efx_properties->flDensity);
895 this->
alEffectf(effect, AL_REVERB_DIFFUSION, efx_properties->flDiffusion);
896 this->
alEffectf(effect, AL_REVERB_GAIN, efx_properties->flGain);
897 this->
alEffectf(effect, AL_REVERB_GAINHF, efx_properties->flGainHF);
898 this->
alEffectf(effect, AL_REVERB_DECAY_TIME, efx_properties->flDecayTime);
899 this->
alEffectf(effect, AL_REVERB_DECAY_HFRATIO, efx_properties->flDecayHFRatio);
900 this->
alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN, efx_properties->flReflectionsGain);
901 this->
alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY, efx_properties->flReflectionsDelay);
902 this->
alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN, efx_properties->flLateReverbGain);
903 this->
alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY, efx_properties->flLateReverbDelay);
904 this->
alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, efx_properties->flAirAbsorptionGainHF);
905 this->
alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, efx_properties->flRoomRolloffFactor);
906 this->
alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, efx_properties->iDecayHFLimit);
911 LOG(
"SoundManager: No usable reverb engine set, not creating reverb effect");
914 error = alGetError();
915 if (error != AL_NO_ERROR)
917 LOG(
"SoundManager: Could not create EFX effect:" +
TOSTRING(alGetString(error)));
1169 for (
const ActorPtr& actor : actors)
1174 for (
int soundsource_index = 0; soundsource_index < actor->ar_num_soundsources; ++soundsource_index)
1176 const soundsource_t& soundsource = actor->ar_soundsources[soundsource_index];
1178 for (
int num_sound = 0; num_sound < num_sounds; ++num_sound)
1180 if (soundsource.
ssi->
getSound(num_sound) == corresponding_sound)
1182 sound_node = soundsource.
nodenum;
1195 const std::vector<Exhaust>& exhausts = actor->GetGfxActor()->getExhausts();
1196 for (
const Exhaust& exhaust : exhausts)
1198 if ( sound_node == exhaust.emitterNode
1199 || sound_node == exhaust.directionNode)
1201 const Ogre::Vector3 emitter_node_pos = actor->getNodePosition(exhaust.emitterNode);
1202 const Ogre::Vector3 direction_node_pos = actor->getNodePosition(exhaust.directionNode);
1206 emitter_node_pos - direction_node_pos,
1216 switch(actor->getTruckType())
1220 for (
int engine_num = 0; engine_num < actor->ar_num_aeroengines; ++engine_num)
1222 const auto& aero_engine = actor->ar_aeroengines[engine_num];
1224 switch(aero_engine->getType())
1227 if ( sound_node == aero_engine->getNoderef()
1228 || sound_node == aero_engine->GetBackNode())
1230 const Ogre::Vector3 aero_engine_ref_node = actor->getNodePosition(aero_engine->getNoderef());
1231 const Ogre::Vector3 aero_engine_back_node = actor->getNodePosition(aero_engine->GetBackNode());
1235 aero_engine_ref_node - aero_engine_back_node,
1253 if ( sound_node == aero_engine->getNoderef()
1254 || sound_node == aero_engine->GetFrontNode())
1256 const Ogre::Vector3 aero_engine_ref_node = actor->getNodePosition(aero_engine->getNoderef());
1257 const Ogre::Vector3 aero_engine_front_node = actor->getNodePosition(aero_engine->GetFrontNode());
1261 aero_engine_ref_node - aero_engine_front_node,
1277 for (
int screwprop_num = 0; screwprop_num < actor->ar_num_screwprops; ++screwprop_num)
1279 const auto& screwprop = actor->ar_screwprops[screwprop_num];
1281 if ( sound_node == screwprop->GetRefNode()
1282 || sound_node == screwprop->GetBackNode())
1284 const Ogre::Vector3 screwprop_ref_node = actor->getNodePosition(screwprop->GetRefNode());
1285 const Ogre::Vector3 screwprop_back_node = actor->getNodePosition(screwprop->GetBackNode());
1289 screwprop_ref_node - screwprop_back_node,
1524 LOG(
"Loading WAV file "+filename);
1527 ResourceGroupManager* rgm = ResourceGroupManager::getSingletonPtr();
1528 if (resource_group_name ==
"")
1530 resource_group_name = rgm->findGroupContainingResource(filename);
1532 DataStreamPtr stream = rgm->openResource(filename, resource_group_name);
1538 unsigned short sbuf;
1541 if (stream->read(magic, 4) != 4)
1543 LOG(
"Could not read file "+filename);
1546 if (String(magic) != String(
"RIFF"))
1548 LOG(
"Invalid WAV file (no RIFF): "+filename);
1554 if (stream->read(magic, 4) != 4)
1556 LOG(
"Could not read file "+filename);
1559 if (String(magic) != String(
"WAVE"))
1561 LOG(
"Invalid WAV file (no WAVE): "+filename);
1565 if (stream->read(magic, 4) != 4)
1567 LOG(
"Could not read file "+filename);
1570 if (String(magic) != String(
"fmt "))
1572 LOG(
"Invalid WAV file (no fmt): "+filename);
1576 if (stream->read(&lbuf, 4) != 4)
1578 LOG(
"Could not read file "+filename);
1581 unsigned long subChunk1Size = lbuf;
1582 if (subChunk1Size < 16)
1584 LOG(
"Invalid WAV file (invalid subChunk1Size): "+filename);
1588 if (stream->read(&sbuf, 2) != 2)
1590 LOG(
"Could not read file "+filename);
1593 unsigned short audioFormat = sbuf;
1594 if (audioFormat != 1)
1596 LOG(
"Invalid WAV file (invalid audioformat "+
TOSTRING(audioFormat)+
"): "+filename);
1600 if (stream->read(&sbuf, 2) != 2)
1602 LOG(
"Could not read file "+filename);
1605 unsigned short channels = sbuf;
1607 if (stream->read(&lbuf, 4) != 4)
1609 LOG(
"Could not read file "+filename);
1612 unsigned long freq = lbuf;
1616 if (stream->read(&sbuf, 2) != 2)
1618 LOG(
"Could not read file "+filename);
1621 unsigned short bps = sbuf;
1623 if (stream->read(magic, 4) != 4)
1625 LOG(
"Could not read file "+filename);
1628 if (String(magic) != String(
"data") && String(magic) != String(
"fact"))
1630 LOG(
"Invalid WAV file (no data/fact): "+filename);
1634 if (String(magic) == String(
"fact"))
1638 if (stream->read(magic, 4) != 4)
1640 LOG(
"Could not read file "+filename);
1643 if (String(magic) != String(
"data"))
1645 LOG(
"Invalid WAV file (no data): "+filename);
1650 if (stream->read(&lbuf, 4) != 4)
1652 LOG(
"Could not read file "+filename);
1656 unsigned long dataSize = lbuf;
1659 if (channels == 1 && bps == 8)
1660 format = AL_FORMAT_MONO8;
1661 else if (channels == 1 && bps == 16)
1662 format = AL_FORMAT_MONO16;
1663 else if (channels == 2 && bps == 8)
1664 format = AL_FORMAT_STEREO16;
1665 else if (channels == 2 && bps == 16)
1666 format = AL_FORMAT_STEREO16;
1669 LOG(
"Invalid WAV file (wrong channels/bps): "+filename);
1673 if (channels != 1)
LOG(
"Invalid WAV file: the file needs to be mono, and nothing else. Will try to continue anyways ...");
1676 void* bdata = malloc(dataSize);
1679 LOG(
"Memory error reading file "+filename);
1682 if (stream->read(bdata, dataSize) != dataSize)
1684 LOG(
"Could not read file "+filename);
1692 alBufferData(buffer, format, bdata, dataSize, freq);
1693 error = alGetError();
1698 if (error != AL_NO_ERROR)
1700 LOG(
"OpenAL error while loading buffer for "+filename+
" : "+
TOSTRING(error));