| 128 | } |
| 129 | |
| 130 | bool SoundSystemOAL::Init() |
| 131 | { |
| 132 | _device = alcOpenDevice(nullptr); |
| 133 | if (!_device) |
| 134 | { |
| 135 | LOG_ERROR(Audio, "alcOpenDevice failed"); |
| 136 | return false; |
| 137 | } |
| 138 | _context = alcCreateContext(static_cast<ALCdevice*>(_device), nullptr); |
| 139 | if (!_context) |
| 140 | { |
| 141 | LOG_ERROR(Audio, "alcCreateContext failed"); |
| 142 | alcCloseDevice(static_cast<ALCdevice*>(_device)); |
| 143 | _device = nullptr; |
| 144 | return false; |
| 145 | } |
| 146 | alcMakeContextCurrent(static_cast<ALCcontext*>(_context)); |
| 147 | |
| 148 | // Check EFX extension availability (DX8 parity: soundDX8.cpp:2108-2114) |
| 149 | _canEAX = alcIsExtensionPresent(static_cast<ALCdevice*>(_device), "ALC_EXT_EFX") == ALC_TRUE; |
| 150 | LOG_INFO(Audio, "EFX extension: {}", _canEAX ? "available" : "not available"); |
| 151 | |
| 152 | // Set distance model for 3D audio |
| 153 | alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); |
| 154 | alDopplerFactor(1.0f); |
| 155 | |
| 156 | // Default listener orientation: looking down -Z, up +Y |
| 157 | float orientation[6] = {0.f, 0.f, -1.f, 0.f, 1.f, 0.f}; |
| 158 | alListener3f(AL_POSITION, 0.f, 0.f, 0.f); |
| 159 | alListener3f(AL_VELOCITY, 0.f, 0.f, 0.f); |
| 160 | alListenerfv(AL_ORIENTATION, orientation); |
| 161 | |
| 162 | // Default volumes matching DX8 reference (soundDX8.cpp:2000-2002) |
| 163 | SetSpeechVolume(5.f); |
| 164 | SetWaveVolume(5.f); |
| 165 | SetCDVolume(5.f); |
| 166 | |
| 167 | LoadConfig(); |
| 168 | |
| 169 | const char* deviceName = alcGetString(static_cast<ALCdevice*>(_device), ALC_DEVICE_SPECIFIER); |
| 170 | LOG_INFO(Audio, "Init OK: {}", deviceName ? deviceName : "unknown"); |
| 171 | |
| 172 | _soundReady = true; |
| 173 | _doPreview = false; |
| 174 | |
| 175 | StartStreamThread(); |
| 176 | |
| 177 | return true; |
| 178 | } |
| 179 | |
| 180 | void SoundSystemOAL::StartStreamThread() |
| 181 | { |
no outgoing calls
no test coverage detected