From ac73ef478a0ef87dc1f7360bf2c735459ba41943 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Thu, 20 Jan 2022 05:35:01 -0500 Subject: [PATCH] Update RtAudio to 5.2.0. Rewrite error handling in RtAudioDevice. --- dep/rtaudio | 2 +- src/rtaudio.cpp | 113 +++++++++++++++++++++--------------------------- 2 files changed, 51 insertions(+), 64 deletions(-) diff --git a/dep/rtaudio b/dep/rtaudio index 8128053f..e5cfcd55 160000 --- a/dep/rtaudio +++ b/dep/rtaudio @@ -1 +1 @@ -Subproject commit 8128053f4bd83463c7c901d9f5d40b272c2f4e4e +Subproject commit e5cfcd557a480cc1a6a1ef1204474221798abb60 diff --git a/src/rtaudio.cpp b/src/rtaudio.cpp index be4740c1..d7d4b04f 100644 --- a/src/rtaudio.cpp +++ b/src/rtaudio.cpp @@ -48,36 +48,31 @@ struct RtAudioDevice : audio::Device { this->deviceId = deviceId; // Create RtAudio object - INFO("Creating RtAudio %s context", RTAUDIO_API_NAMES.at(api).c_str()); - try { - rtAudio = new RtAudio(api); - } - catch (RtAudioError& e) { - throw Exception("Failed to create RtAudio %s context: %s", RTAUDIO_API_NAMES.at(api).c_str(), e.what()); - } + INFO("Creating RtAudio %s device", RTAUDIO_API_NAMES.at(api).c_str()); + rtAudio = new RtAudio(api, [](RtAudioErrorType type, const std::string& errorText) { + WARN("RtAudio error %d: %s", type, errorText.c_str()); + }); rtAudio->showWarnings(false); - // Query device ID try { + // Query device ID deviceInfo = rtAudio->getDeviceInfo(deviceId); + if (!deviceInfo.probed) { + throw Exception("Failed to query RtAudio %s device %d", RTAUDIO_API_NAMES.at(api).c_str(), deviceId); + } + + openStream(); } - catch (RtAudioError& e) { - throw Exception("Failed to query RtAudio %s device %d: %s", RTAUDIO_API_NAMES.at(api).c_str(), deviceId, e.what()); + catch (Exception& e) { + delete rtAudio; + throw; } - - openStream(); } ~RtAudioDevice() { - try { - closeStream(); - delete rtAudio; - } - catch (Exception& e) { - WARN("Failed to destroy RtAudio %s context: %s", RTAUDIO_API_NAMES.at(api).c_str(), e.what()); - // Ignore exceptions - } + closeStream(); + delete rtAudio; } void openStream() { @@ -102,10 +97,10 @@ struct RtAudioDevice : audio::Device { options.numberOfBuffers = 2; options.streamName = "VCV Rack"; - float closestSampleRate = deviceInfo.preferredSampleRate; + int32_t closestSampleRate = deviceInfo.preferredSampleRate; if (sampleRate > 0) { // Find the closest sample rate to the requested one. - for (float sr : deviceInfo.sampleRates) { + for (int32_t sr : deviceInfo.sampleRates) { if (std::fabs(sr - sampleRate) < std::fabs(closestSampleRate - sampleRate)) { closestSampleRate = sr; } @@ -120,52 +115,42 @@ struct RtAudioDevice : audio::Device { blockSize = 256; } - INFO("Opening RtAudio %s device %d: %s (%d in, %d out, %g sample rate, %d block size)", RTAUDIO_API_NAMES.at(api).c_str(), deviceId, deviceInfo.name.c_str(), inputParameters.nChannels, outputParameters.nChannels, closestSampleRate, blockSize); - try { - rtAudio->openStream( - outputParameters.nChannels > 0 ? &outputParameters : NULL, - inputParameters.nChannels > 0 ? &inputParameters : NULL, - RTAUDIO_FLOAT32, closestSampleRate, (unsigned int*) &blockSize, - &rtAudioCallback, this, &options, NULL); - } - catch (RtAudioError& e) { - throw Exception("Failed to open RtAudio %s device %d: %s", RTAUDIO_API_NAMES.at(api).c_str(), deviceId, e.what()); + INFO("Opening RtAudio %s device %d: %s (%d in, %d out, %d sample rate, %d block size)", RTAUDIO_API_NAMES.at(api).c_str(), deviceId, deviceInfo.name.c_str(), inputParameters.nChannels, outputParameters.nChannels, closestSampleRate, blockSize); + if (rtAudio->openStream( + outputParameters.nChannels > 0 ? &outputParameters : NULL, + inputParameters.nChannels > 0 ? &inputParameters : NULL, + RTAUDIO_FLOAT32, closestSampleRate, (unsigned int*) &blockSize, + &rtAudioCallback, this, &options)) { + throw Exception("Failed to open RtAudio %s device %d", RTAUDIO_API_NAMES.at(api).c_str(), deviceId); } - INFO("Starting RtAudio %s device %d", RTAUDIO_API_NAMES.at(api).c_str(), deviceId); try { - rtAudio->startStream(); + INFO("Starting RtAudio %s device %d", RTAUDIO_API_NAMES.at(api).c_str(), deviceId); + if (rtAudio->startStream()) { + throw Exception("Failed to start RtAudio %s device %d", RTAUDIO_API_NAMES.at(api).c_str(), deviceId); + } + + // Update sample rate to actual value + sampleRate = rtAudio->getStreamSampleRate(); + + onStartStream(); } - catch (RtAudioError& e) { - throw Exception("Failed to start RtAudio %s device %d: %s", RTAUDIO_API_NAMES.at(api).c_str(), deviceId, e.what()); + catch (Exception& e) { + rtAudio->closeStream(); + throw; } - - // Update sample rate to actual value - sampleRate = rtAudio->getStreamSampleRate(); - INFO("Opened RtAudio %s device %d", RTAUDIO_API_NAMES.at(api).c_str(), deviceId); - onStartStream(); } void closeStream() { - INFO("Stopping RtAudio %s device %d", RTAUDIO_API_NAMES.at(api).c_str(), deviceId); if (rtAudio->isStreamRunning()) { - try { - rtAudio->stopStream(); - } - catch (RtAudioError& e) { - throw Exception("Failed to stop RtAudio %s device %d: %s", RTAUDIO_API_NAMES.at(api).c_str(), deviceId, e.what()); - } + INFO("Stopping RtAudio %s device %d", RTAUDIO_API_NAMES.at(api).c_str(), deviceId); + rtAudio->stopStream(); } - INFO("Closing RtAudio %s device %d", RTAUDIO_API_NAMES.at(api).c_str(), deviceId); if (rtAudio->isStreamOpen()) { - try { - rtAudio->closeStream(); - } - catch (RtAudioError& e) { - throw Exception("Failed to close RtAudio %s device %d: %s", RTAUDIO_API_NAMES.at(api).c_str(), deviceId, e.what()); - } + INFO("Closing RtAudio %s device %d", RTAUDIO_API_NAMES.at(api).c_str(), deviceId); + rtAudio->closeStream(); } - INFO("Closed RtAudio %s device %d", RTAUDIO_API_NAMES.at(api).c_str(), deviceId); + onStopStream(); } @@ -224,7 +209,12 @@ struct RtAudioDevice : audio::Device { int inputStride = that->getNumInputs(); int outputStride = that->getNumOutputs(); - that->processBuffer((const float*) inputBuffer, inputStride, (float*) outputBuffer, outputStride, nFrames); + try { + that->processBuffer((const float*) inputBuffer, inputStride, (float*) outputBuffer, outputStride, nFrames); + } + catch (Exception& e) { + // Log nothing to avoid spamming the log. + } return 0; } }; @@ -241,12 +231,9 @@ struct RtAudioDriver : audio::Driver { this->api = api; INFO("Creating RtAudio %s driver", RTAUDIO_API_NAMES.at(api).c_str()); - try { - rtAudio = new RtAudio(api); - } - catch (RtAudioError& e) { - throw Exception("Failed to create RtAudio %s driver: %s", RTAUDIO_API_NAMES.at(api).c_str(), e.what()); - } + rtAudio = new RtAudio(api, [](RtAudioErrorType type, const std::string& errorText) { + WARN("RtAudio error %d: %s", type, errorText.c_str()); + }); rtAudio->showWarnings(false);