From 23ae66151b35750be4b83cf2d3020b947c55e07a Mon Sep 17 00:00:00 2001 From: Henner Zeller Date: Sun, 21 Jan 2024 10:32:43 -0800 Subject: [PATCH] Make compatible with rtaudio API 5 and 6. Recent rtaudio changed the API to not throw exceptions anymore and also have DeviceIDs not queried by index but IDs that are provided separately ( https://github.com/thestk/rtaudio/releases ). Adapt the code-base to be compatible with the old and the new API as we have to exepect that in a transition period both APIs are common on various build platforms. --- sink_modules/audio_sink/src/main.cpp | 36 ++++++++++++++++++++---- source_modules/audio_source/src/main.cpp | 33 +++++++++++++++++++--- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/sink_modules/audio_sink/src/main.cpp b/sink_modules/audio_sink/src/main.cpp index 15b7c2600..147e7782f 100644 --- a/sink_modules/audio_sink/src/main.cpp +++ b/sink_modules/audio_sink/src/main.cpp @@ -31,6 +31,10 @@ class AudioSink : SinkManager::Sink { monoPacker.init(&s2m.out, 512); stereoPacker.init(_stream->sinkOut, 512); +#if RTAUDIO_VERSION_MAJOR >= 6 + audio.setErrorCallback(&reportErrorsAsException); +#endif + bool created = false; std::string device = ""; config.acquire(); @@ -42,12 +46,15 @@ class AudioSink : SinkManager::Sink { device = config.conf[_streamName]["device"]; config.release(created); - int count = audio.getDeviceCount(); RtAudio::DeviceInfo info; +#if RTAUDIO_VERSION_MAJOR >= 6 + for (int i : audio.getDeviceIds()) { +#else + int count = audio.getDeviceCount(); for (int i = 0; i < count; i++) { +#endif try { info = audio.getDeviceInfo(i); - if (!info.probed) { continue; } if (info.outputChannels == 0) { continue; } if (info.isDefaultOutput) { defaultDevId = devList.size(); } devList.push_back(info); @@ -55,8 +62,8 @@ class AudioSink : SinkManager::Sink { txtDevList += info.name; txtDevList += '\0'; } - catch (std::exception e) { - flog::error("AudioSinkModule Error getting audio device info: {0}", e.what()); + catch (const std::exception& e) { + flog::error("AudioSinkModule Error getting audio device info: id={0}: {1}", i, e.what()); } } selectByName(device); @@ -156,6 +163,23 @@ class AudioSink : SinkManager::Sink { } } +#if RTAUDIO_VERSION_MAJOR >= 6 + static void reportErrorsAsException(RtAudioErrorType type, + const std::string& errorText) { + switch (type) { + case RtAudioErrorType::RTAUDIO_NO_ERROR: + return; + case RtAudioErrorType::RTAUDIO_WARNING: + case RtAudioErrorType::RTAUDIO_NO_DEVICES_FOUND: + case RtAudioErrorType::RTAUDIO_DEVICE_DISCONNECT: + flog::warn("AudioSink: {0} ({1})", errorText, (int)type); + break; + default: + throw std::runtime_error(errorText); + } + } +#endif + private: bool doStart() { RtAudio::StreamParameters parameters; @@ -172,8 +196,8 @@ class AudioSink : SinkManager::Sink { audio.startStream(); stereoPacker.start(); } - catch (RtAudioError& e) { - flog::error("Could not open audio device"); + catch (const std::exception& e) { + flog::error("Could not open audio device {0}", e.what()); return false; } diff --git a/source_modules/audio_source/src/main.cpp b/source_modules/audio_source/src/main.cpp index 99efa3798..b7abe2536 100644 --- a/source_modules/audio_source/src/main.cpp +++ b/source_modules/audio_source/src/main.cpp @@ -35,6 +35,10 @@ class AudioSourceModule : public ModuleManager::Instance { AudioSourceModule(std::string name) { this->name = name; +#if RTAUDIO_VERSION_MAJOR >= 6 + audio.setErrorCallback(&reportErrorsAsException); +#endif + sampleRate = 48000.0; handler.ctx = this; @@ -83,21 +87,25 @@ class AudioSourceModule : public ModuleManager::Instance { void refresh() { devices.clear(); +#if RTAUDIO_VERSION_MAJOR >= 6 + for (int i : audio.getDeviceIds()) { +#else int count = audio.getDeviceCount(); for (int i = 0; i < count; i++) { +#endif try { // Get info auto info = audio.getDeviceInfo(i); // Check that it has a stereo input - if (info.probed && info.inputChannels < 2) { continue; } + if (info.inputChannels < 2) { continue; } // Save info DeviceInfo dinfo = { info, i }; devices.define(info.name, info.name, dinfo); } - catch (std::exception e) { - flog::error("Error getting audio device info: {0}", e.what()); + catch (const std::exception& e) { + flog::error("Error getting audio device info: id={0}: {1}", i, e.what()); } } } @@ -254,6 +262,23 @@ class AudioSourceModule : public ModuleManager::Instance { return 0; } +#if RTAUDIO_VERSION_MAJOR >= 6 + static void reportErrorsAsException(RtAudioErrorType type, + const std::string& errorText) { + switch (type) { + case RtAudioErrorType::RTAUDIO_NO_ERROR: + return; + case RtAudioErrorType::RTAUDIO_WARNING: + case RtAudioErrorType::RTAUDIO_NO_DEVICES_FOUND: + case RtAudioErrorType::RTAUDIO_DEVICE_DISCONNECT: + flog::warn("AudioSource: {0} ({1})", errorText, (int)type); + break; + default: + throw std::runtime_error(errorText); + } + } +#endif + std::string name; bool enabled = true; dsp::stream stream; @@ -290,4 +315,4 @@ MOD_EXPORT void _DELETE_INSTANCE_(ModuleManager::Instance* instance) { MOD_EXPORT void _END_() { config.disableAutoSave(); config.save(); -} \ No newline at end of file +}