| @@ -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<double> 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 | |||||
| @@ -45,6 +45,8 @@ | |||||
| #include "juce_audio_devices.h" | #include "juce_audio_devices.h" | ||||
| #include "audio_io/juce_SampleRateHelpers.cpp" | |||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_MAC || JUCE_IOS | #if JUCE_MAC || JUCE_IOS | ||||
| #include <juce_audio_basics/midi/ump/juce_UMP.h> | #include <juce_audio_basics/midi/ump/juce_UMP.h> | ||||
| @@ -50,17 +50,15 @@ namespace | |||||
| static void getDeviceSampleRates (snd_pcm_t* handle, Array<double>& rates) | static void getDeviceSampleRates (snd_pcm_t* handle, Array<double>& rates) | ||||
| { | { | ||||
| const int ratesToTry[] = { 22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 0 }; | |||||
| snd_pcm_hw_params_t* hwParams; | snd_pcm_hw_params_t* hwParams; | ||||
| snd_pcm_hw_params_alloca (&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 | 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); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -294,15 +294,11 @@ public: | |||||
| if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, ranges))) | 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;) | 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); | newSampleRates.add (rate); | ||||
| break; | break; | ||||
| @@ -315,6 +311,11 @@ public: | |||||
| if (newSampleRates.isEmpty() && sampleRate > 0) | if (newSampleRates.isEmpty() && sampleRate > 0) | ||||
| newSampleRates.add (sampleRate); | newSampleRates.add (sampleRate); | ||||
| auto nominalRate = getNominalSampleRate(); | |||||
| if ((nominalRate > 0) && ! newSampleRates.contains (nominalRate)) | |||||
| newSampleRates.addUsingDefaultSort (nominalRate); | |||||
| return newSampleRates; | return newSampleRates; | ||||
| } | } | ||||
| @@ -349,13 +349,9 @@ public: | |||||
| Array<double> newRates; | Array<double> newRates; | ||||
| if (asioObject != nullptr) | 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()) | if (newRates.isEmpty()) | ||||
| { | { | ||||
| @@ -676,9 +676,7 @@ private: | |||||
| void querySupportedSampleRates (WAVEFORMATEXTENSIBLE format, ComSmartPtr<IAudioClient>& audioClient) | void querySupportedSampleRates (WAVEFORMATEXTENSIBLE format, ComSmartPtr<IAudioClient>& 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)) | if (rates.contains (rate)) | ||||
| continue; | continue; | ||||
| @@ -695,7 +693,7 @@ private: | |||||
| : &nearestFormat))) | : &nearestFormat))) | ||||
| { | { | ||||
| if (nearestFormat != nullptr) | if (nearestFormat != nullptr) | ||||
| rate = (int) nearestFormat->nSamplesPerSec; | |||||
| rate = (double) nearestFormat->nSamplesPerSec; | |||||
| if (! rates.contains (rate)) | if (! rates.contains (rate)) | ||||
| rates.addUsingDefaultSort (rate); | rates.addUsingDefaultSort (rate); | ||||