diff --git a/modules/juce_audio_devices/audio_io/juce_SampleRateHelpers.cpp b/modules/juce_audio_devices/audio_io/juce_SampleRateHelpers.cpp new file mode 100644 index 0000000000..ce8c6b1ec1 --- /dev/null +++ b/modules/juce_audio_devices/audio_io/juce_SampleRateHelpers.cpp @@ -0,0 +1,48 @@ +/* + ============================================================================== + + This file is part of the JUCE library. + Copyright (c) 2020 - Raw Material Software Limited + + JUCE is an open source library subject to commercial or open-source + licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + To use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ +namespace SampleRateHelpers +{ + +const auto& getAllSampleRates() +{ + static auto sampleRates = [] + { + std::vector result; + constexpr double baseRates[] = { 8000.0, 11025.0, 12000.0 }; + constexpr double maxRate = 768000.0; + + for (auto rate : baseRates) + for (; rate <= maxRate; rate *= 2) + result.insert (std::upper_bound (result.begin(), result.end(), rate), + rate); + + return result; + }(); + + return sampleRates; +} + +} // namespace SampleRateHelpers +} // namespace juce diff --git a/modules/juce_audio_devices/juce_audio_devices.cpp b/modules/juce_audio_devices/juce_audio_devices.cpp index c76663a1e7..b9e29b1ad4 100644 --- a/modules/juce_audio_devices/juce_audio_devices.cpp +++ b/modules/juce_audio_devices/juce_audio_devices.cpp @@ -45,6 +45,8 @@ #include "juce_audio_devices.h" +#include "audio_io/juce_SampleRateHelpers.cpp" + //============================================================================== #if JUCE_MAC || JUCE_IOS #include diff --git a/modules/juce_audio_devices/native/juce_linux_ALSA.cpp b/modules/juce_audio_devices/native/juce_linux_ALSA.cpp index 1b010c3e86..644a54db31 100644 --- a/modules/juce_audio_devices/native/juce_linux_ALSA.cpp +++ b/modules/juce_audio_devices/native/juce_linux_ALSA.cpp @@ -50,17 +50,15 @@ namespace static void getDeviceSampleRates (snd_pcm_t* handle, Array& rates) { - const int ratesToTry[] = { 22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 0 }; - snd_pcm_hw_params_t* hwParams; snd_pcm_hw_params_alloca (&hwParams); - for (int i = 0; ratesToTry[i] != 0; ++i) + for (const auto rateToTry : SampleRateHelpers::getAllSampleRates()) { if (snd_pcm_hw_params_any (handle, hwParams) >= 0 - && snd_pcm_hw_params_test_rate (handle, hwParams, (unsigned int) ratesToTry[i], 0) == 0) + && snd_pcm_hw_params_test_rate (handle, hwParams, (unsigned int) rateToTry, 0) == 0) { - rates.addIfNotAlreadyThere ((double) ratesToTry[i]); + rates.addIfNotAlreadyThere (rateToTry); } } } diff --git a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp index 232d713136..70c3ee483e 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp @@ -294,15 +294,11 @@ public: if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, ranges))) { - for (auto r : { 8000, 11025, 16000, 22050, 24000, 32000, - 44100, 48000, 88200, 96000, 176400, - 192000, 352800, 384000, 705600, 768000 }) + for (const auto rate : SampleRateHelpers::getAllSampleRates()) { - auto rate = (double) r; - for (int j = size / (int) sizeof (AudioValueRange); --j >= 0;) { - if (rate >= ranges[j].mMinimum - 2 && rate <= ranges[j].mMaximum + 2) + if (ranges[j].mMinimum - 2 <= rate && rate <= ranges[j].mMaximum + 2) { newSampleRates.add (rate); break; @@ -315,6 +311,11 @@ public: if (newSampleRates.isEmpty() && sampleRate > 0) newSampleRates.add (sampleRate); + auto nominalRate = getNominalSampleRate(); + + if ((nominalRate > 0) && ! newSampleRates.contains (nominalRate)) + newSampleRates.addUsingDefaultSort (nominalRate); + return newSampleRates; } diff --git a/modules/juce_audio_devices/native/juce_win32_ASIO.cpp b/modules/juce_audio_devices/native/juce_win32_ASIO.cpp index 904c7f4baf..20385a084a 100644 --- a/modules/juce_audio_devices/native/juce_win32_ASIO.cpp +++ b/modules/juce_audio_devices/native/juce_win32_ASIO.cpp @@ -349,13 +349,9 @@ public: Array newRates; if (asioObject != nullptr) - { - for (auto rate : { 8000, 11025, 16000, 22050, 24000, 32000, - 44100, 48000, 88200, 96000, 176400, - 192000, 352800, 384000, 705600, 768000 }) - if (asioObject->canSampleRate ((double) rate) == 0) - newRates.add ((double) rate); - } + for (const auto rate : SampleRateHelpers::getAllSampleRates()) + if (asioObject->canSampleRate (rate) == 0) + newRates.add (rate); if (newRates.isEmpty()) { diff --git a/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp b/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp index ae927e08c6..07afc84890 100644 --- a/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp +++ b/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp @@ -676,9 +676,7 @@ private: void querySupportedSampleRates (WAVEFORMATEXTENSIBLE format, ComSmartPtr& audioClient) { - for (auto rate : { 8000, 11025, 16000, 22050, 24000, 32000, - 44100, 48000, 88200, 96000, 176400, - 192000, 352800, 384000, 705600, 768000 }) + for (auto rate : SampleRateHelpers::getAllSampleRates()) { if (rates.contains (rate)) continue; @@ -695,7 +693,7 @@ private: : &nearestFormat))) { if (nearestFormat != nullptr) - rate = (int) nearestFormat->nSamplesPerSec; + rate = (double) nearestFormat->nSamplesPerSec; if (! rates.contains (rate)) rates.addUsingDefaultSort (rate);