| @@ -4,6 +4,7 @@ | |||||
| #include <math.hpp> | #include <math.hpp> | ||||
| #include <system.hpp> | #include <system.hpp> | ||||
| #include <map> | #include <map> | ||||
| #include <algorithm> | |||||
| #pragma GCC diagnostic push | #pragma GCC diagnostic push | ||||
| #ifndef __clang__ | #ifndef __clang__ | ||||
| @@ -23,7 +24,7 @@ struct RtAudioDevice : audio::Device { | |||||
| RtAudio::StreamParameters inputParameters; | RtAudio::StreamParameters inputParameters; | ||||
| RtAudio::StreamParameters outputParameters; | RtAudio::StreamParameters outputParameters; | ||||
| RtAudio::StreamOptions options; | RtAudio::StreamOptions options; | ||||
| int blockSize = 256; | |||||
| int blockSize = 0; | |||||
| int sampleRate = 44100; | int sampleRate = 44100; | ||||
| RtAudioDevice(RtAudio::Api api, int deviceId) { | RtAudioDevice(RtAudio::Api api, int deviceId) { | ||||
| @@ -31,6 +32,8 @@ struct RtAudioDevice : audio::Device { | |||||
| if (!rtAudio) { | if (!rtAudio) { | ||||
| throw Exception(string::f("Failed to create RtAudio driver %d", api)); | throw Exception(string::f("Failed to create RtAudio driver %d", api)); | ||||
| } | } | ||||
| rtAudio->showWarnings(false); | |||||
| try { | try { | ||||
| deviceInfo = rtAudio->getDeviceInfo(deviceId); | deviceInfo = rtAudio->getDeviceInfo(deviceId); | ||||
| } | } | ||||
| @@ -70,17 +73,24 @@ struct RtAudioDevice : audio::Device { | |||||
| options.streamName = "VCV Rack"; | options.streamName = "VCV Rack"; | ||||
| int closestSampleRate = deviceInfo.preferredSampleRate; | int closestSampleRate = deviceInfo.preferredSampleRate; | ||||
| for (int sr : deviceInfo.sampleRates) { | |||||
| if (std::abs(sr - sampleRate) < std::abs(closestSampleRate - sampleRate)) { | |||||
| closestSampleRate = sr; | |||||
| if (sampleRate > 0) { | |||||
| // Find the closest sample rate to the requested one. | |||||
| for (int sr : deviceInfo.sampleRates) { | |||||
| if (std::abs(sr - sampleRate) < std::abs(closestSampleRate - sampleRate)) { | |||||
| closestSampleRate = sr; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| if (blockSize <= 0) { | |||||
| blockSize = 256; | |||||
| } | |||||
| INFO("Opening audio RtAudio device %d with %d in %d out", deviceId, inputParameters.nChannels, outputParameters.nChannels); | INFO("Opening audio RtAudio device %d with %d in %d out", deviceId, inputParameters.nChannels, outputParameters.nChannels); | ||||
| try { | try { | ||||
| rtAudio->openStream( | rtAudio->openStream( | ||||
| outputParameters.nChannels == 0 ? NULL : &outputParameters, | |||||
| inputParameters.nChannels == 0 ? NULL : &inputParameters, | |||||
| outputParameters.nChannels > 0 ? &outputParameters : NULL, | |||||
| inputParameters.nChannels > 0 ? &inputParameters : NULL, | |||||
| RTAUDIO_FLOAT32, closestSampleRate, (unsigned int*) &blockSize, | RTAUDIO_FLOAT32, closestSampleRate, (unsigned int*) &blockSize, | ||||
| &rtAudioCallback, this, &options, NULL); | &rtAudioCallback, this, &options, NULL); | ||||
| } | } | ||||
| @@ -270,9 +280,24 @@ struct RtAudioDriver : audio::Driver { | |||||
| void rtaudioInit() { | void rtaudioInit() { | ||||
| std::vector<RtAudio::Api> apis; | std::vector<RtAudio::Api> apis; | ||||
| RtAudio::getCompiledApi(apis); | RtAudio::getCompiledApi(apis); | ||||
| for (RtAudio::Api api : apis) { | |||||
| RtAudioDriver* driver = new RtAudioDriver(api); | |||||
| audio::addDriver((int) api, driver); | |||||
| // I don't like the order returned by getCompiledApi(), so reorder it here. | |||||
| std::vector<RtAudio::Api> orderedApis = { | |||||
| RtAudio::LINUX_ALSA, | |||||
| RtAudio::UNIX_JACK, | |||||
| RtAudio::LINUX_PULSE, | |||||
| RtAudio::LINUX_OSS, | |||||
| RtAudio::WINDOWS_WASAPI, | |||||
| RtAudio::WINDOWS_ASIO, | |||||
| RtAudio::WINDOWS_DS, | |||||
| RtAudio::MACOSX_CORE, | |||||
| }; | |||||
| for (RtAudio::Api api : orderedApis) { | |||||
| auto it = std::find(apis.begin(), apis.end(), api); | |||||
| if (it != apis.end()) { | |||||
| RtAudioDriver* driver = new RtAudioDriver(api); | |||||
| audio::addDriver((int) api, driver); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||