openal: Enable AL_DIRECT_CHANNELS_SOFT when present. (#7202)

This commit is contained in:
Steveice10 2023-11-22 23:09:22 -08:00 committed by GitHub
parent 1dc0fa7bb5
commit 09b36c589b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 23 deletions

View file

@ -30,20 +30,20 @@ OpenALSink::OpenALSink(std::string device_name) : impl(std::make_unique<Impl>())
device_name != auto_device_name && !device_name.empty() ? device_name.c_str() : nullptr); device_name != auto_device_name && !device_name.empty() ? device_name.c_str() : nullptr);
if (!impl->device) { if (!impl->device) {
LOG_CRITICAL(Audio_Sink, "alcOpenDevice failed."); LOG_CRITICAL(Audio_Sink, "alcOpenDevice failed.");
Close();
return; return;
} }
impl->context = alcCreateContext(impl->device, nullptr); impl->context = alcCreateContext(impl->device, nullptr);
if (impl->context == nullptr) { if (impl->context == nullptr) {
LOG_CRITICAL(Audio_Sink, "alcCreateContext failed: {}", alcGetError(impl->device)); LOG_CRITICAL(Audio_Sink, "alcCreateContext failed: {}", alcGetError(impl->device));
alcCloseDevice(impl->device); Close();
return; return;
} }
if (alcMakeContextCurrent(impl->context) == ALC_FALSE) { if (alcMakeContextCurrent(impl->context) == ALC_FALSE) {
LOG_CRITICAL(Audio_Sink, "alcMakeContextCurrent failed: {}", alcGetError(impl->device)); LOG_CRITICAL(Audio_Sink, "alcMakeContextCurrent failed: {}", alcGetError(impl->device));
alcDestroyContext(impl->context); Close();
alcCloseDevice(impl->device);
return; return;
} }
@ -53,25 +53,21 @@ OpenALSink::OpenALSink(std::string device_name) : impl(std::make_unique<Impl>())
} else { } else {
LOG_CRITICAL(Audio_Sink, "Missing required extension AL_SOFT_callback_buffer."); LOG_CRITICAL(Audio_Sink, "Missing required extension AL_SOFT_callback_buffer.");
} }
alcDestroyContext(impl->context); Close();
alcCloseDevice(impl->device);
return; return;
} }
alGenBuffers(1, &impl->buffer); alGenBuffers(1, &impl->buffer);
if (alGetError() != AL_NO_ERROR) { if (alGetError() != AL_NO_ERROR) {
LOG_CRITICAL(Audio_Sink, "alGetError failed: {}", alGetError()); LOG_CRITICAL(Audio_Sink, "alGetError failed: {}", alGetError());
alcDestroyContext(impl->context); Close();
alcCloseDevice(impl->device);
return; return;
} }
alGenSources(1, &impl->source); alGenSources(1, &impl->source);
if (alGetError() != AL_NO_ERROR) { if (alGetError() != AL_NO_ERROR) {
LOG_CRITICAL(Audio_Sink, "alGenSources failed: {}", alGetError()); LOG_CRITICAL(Audio_Sink, "alGenSources failed: {}", alGetError());
alDeleteBuffers(1, &impl->buffer); Close();
alcDestroyContext(impl->context);
alcCloseDevice(impl->device);
return; return;
} }
@ -81,35 +77,44 @@ OpenALSink::OpenALSink(std::string device_name) : impl(std::make_unique<Impl>())
impl.get()); impl.get());
if (alGetError() != AL_NO_ERROR) { if (alGetError() != AL_NO_ERROR) {
LOG_CRITICAL(Audio_Sink, "alBufferCallbackSOFT failed: {}", alGetError()); LOG_CRITICAL(Audio_Sink, "alBufferCallbackSOFT failed: {}", alGetError());
alDeleteSources(1, &impl->source); Close();
alDeleteBuffers(1, &impl->buffer);
alcDestroyContext(impl->context);
alcCloseDevice(impl->device);
return; return;
} }
alSourcei(impl->source, AL_BUFFER, static_cast<ALint>(impl->buffer)); alSourcei(impl->source, AL_BUFFER, static_cast<ALint>(impl->buffer));
if (alGetError() != AL_NO_ERROR) { if (alGetError() != AL_NO_ERROR) {
LOG_CRITICAL(Audio_Sink, "alSourcei failed: {}", alGetError()); LOG_CRITICAL(Audio_Sink, "alSourcei(AL_BUFFER) failed: {}", alGetError());
alDeleteSources(1, &impl->source); Close();
alDeleteBuffers(1, &impl->buffer);
alcDestroyContext(impl->context);
alcCloseDevice(impl->device);
return; return;
} }
if (alIsExtensionPresent("AL_SOFT_direct_channels") == AL_TRUE) {
// Set up direct channels to bypass processing spatialization and other effects we don't
// need.
alSourcei(impl->source, AL_DIRECT_CHANNELS_SOFT, AL_TRUE);
if (alGetError() != AL_NO_ERROR) {
LOG_CRITICAL(Audio_Sink, "alSourcei(AL_DIRECT_CHANNELS_SOFT) failed: {}", alGetError());
Close();
return;
}
} else {
LOG_WARNING(Audio_Sink,
"AL_SOFT_direct_channels not present, audio latency may be higher.");
}
alSourcePlay(impl->source); alSourcePlay(impl->source);
if (alGetError() != AL_NO_ERROR) { if (alGetError() != AL_NO_ERROR) {
LOG_CRITICAL(Audio_Sink, "alSourcePlay failed: {}", alGetError()); LOG_CRITICAL(Audio_Sink, "alSourcePlay failed: {}", alGetError());
alDeleteSources(1, &impl->source); Close();
alDeleteBuffers(1, &impl->buffer);
alcDestroyContext(impl->context);
alcCloseDevice(impl->device);
return; return;
} }
} }
OpenALSink::~OpenALSink() { OpenALSink::~OpenALSink() {
Close();
}
void OpenALSink::Close() {
if (impl->source) { if (impl->source) {
alSourceStop(impl->source); alSourceStop(impl->source);
alDeleteSources(1, &impl->source); alDeleteSources(1, &impl->source);

View file

@ -23,6 +23,8 @@ public:
private: private:
struct Impl; struct Impl;
std::unique_ptr<Impl> impl; std::unique_ptr<Impl> impl;
void Close();
}; };
std::vector<std::string> ListOpenALSinkDevices(); std::vector<std::string> ListOpenALSinkDevices();