| @@ -127,8 +127,7 @@ AudioDeviceManager& getSharedAudioDeviceManager (int numInputChannels, int numOu | |||||
| if (sharedAudioDeviceManager->getCurrentAudioDevice() != nullptr) | if (sharedAudioDeviceManager->getCurrentAudioDevice() != nullptr) | ||||
| { | { | ||||
| AudioDeviceManager::AudioDeviceSetup setup; | |||||
| sharedAudioDeviceManager->getAudioDeviceSetup (setup); | |||||
| auto setup = sharedAudioDeviceManager->getAudioDeviceSetup(); | |||||
| auto numInputs = jmax (numInputChannels, setup.inputChannels.countNumberOfSetBits()); | auto numInputs = jmax (numInputChannels, setup.inputChannels.countNumberOfSetBits()); | ||||
| auto numOutputs = jmax (numOutputChannels, setup.outputChannels.countNumberOfSetBits()); | auto numOutputs = jmax (numOutputChannels, setup.outputChannels.countNumberOfSetBits()); | ||||
| @@ -0,0 +1,79 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library. | |||||
| Copyright (c) 2017 - ROLI Ltd. | |||||
| JUCE is an open source library subject to commercial or open-source | |||||
| licensing. | |||||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||||
| 27th April 2017). | |||||
| End User License Agreement: www.juce.com/juce-5-licence | |||||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||||
| Or: You may also use this code under the terms of the GPL v3 (see | |||||
| www.gnu.org/licenses). | |||||
| 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 | |||||
| { | |||||
| AudioProcessLoadMeasurer::AudioProcessLoadMeasurer() {} | |||||
| AudioProcessLoadMeasurer::~AudioProcessLoadMeasurer() {} | |||||
| void AudioProcessLoadMeasurer::reset() | |||||
| { | |||||
| reset (0, 0); | |||||
| } | |||||
| void AudioProcessLoadMeasurer::reset (double sampleRate, int blockSize) | |||||
| { | |||||
| cpuUsageMs = 0; | |||||
| xruns = 0; | |||||
| if (sampleRate > 0.0 && blockSize > 0) | |||||
| { | |||||
| msPerBlock = 1000.0 * blockSize / sampleRate; | |||||
| timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0; | |||||
| } | |||||
| else | |||||
| { | |||||
| msPerBlock = 0; | |||||
| timeToCpuScale = 0; | |||||
| } | |||||
| } | |||||
| void AudioProcessLoadMeasurer::registerBlockRenderTime (double milliseconds) | |||||
| { | |||||
| const double filterAmount = 0.2; | |||||
| cpuUsageMs += filterAmount * (milliseconds - cpuUsageMs); | |||||
| if (milliseconds > msPerBlock) | |||||
| ++xruns; | |||||
| } | |||||
| double AudioProcessLoadMeasurer::getLoadAsProportion() const { return jlimit (0.0, 1.0, timeToCpuScale * cpuUsageMs); } | |||||
| double AudioProcessLoadMeasurer::getLoadAsPercentage() const { return 100.0 * getLoadAsProportion(); } | |||||
| int AudioProcessLoadMeasurer::getXRunCount() const { return xruns; } | |||||
| AudioProcessLoadMeasurer::ScopedTimer::ScopedTimer (AudioProcessLoadMeasurer& p) | |||||
| : owner (p), startTime (Time::getMillisecondCounterHiRes()) | |||||
| { | |||||
| } | |||||
| AudioProcessLoadMeasurer::ScopedTimer::~ScopedTimer() | |||||
| { | |||||
| owner.registerBlockRenderTime (Time::getMillisecondCounterHiRes() - startTime); | |||||
| } | |||||
| } // namespace juce | |||||
| @@ -0,0 +1,96 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library. | |||||
| Copyright (c) 2017 - ROLI Ltd. | |||||
| JUCE is an open source library subject to commercial or open-source | |||||
| licensing. | |||||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||||
| 27th April 2017). | |||||
| End User License Agreement: www.juce.com/juce-5-licence | |||||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||||
| Or: You may also use this code under the terms of the GPL v3 (see | |||||
| www.gnu.org/licenses). | |||||
| 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 | |||||
| { | |||||
| //============================================================================== | |||||
| /** | |||||
| Maintains an ongoing measurement of the proportion of time which is being | |||||
| spent inside an audio callback. | |||||
| */ | |||||
| class JUCE_API AudioProcessLoadMeasurer | |||||
| { | |||||
| public: | |||||
| /** */ | |||||
| AudioProcessLoadMeasurer(); | |||||
| /** Destructor. */ | |||||
| ~AudioProcessLoadMeasurer(); | |||||
| //============================================================================== | |||||
| /** Resets the state. */ | |||||
| void reset(); | |||||
| /** Resets the counter, in preparation for use with the given sample rate and block size. */ | |||||
| void reset (double sampleRate, int blockSize); | |||||
| /** Returns the current load as a proportion 0 to 1.0 */ | |||||
| double getLoadAsProportion() const; | |||||
| /** Returns the current load as a percentage 0 to 100.0 */ | |||||
| double getLoadAsPercentage() const; | |||||
| /** Returns the number of over- (or under-) runs recorded since the state was reset. */ | |||||
| int getXRunCount() const; | |||||
| //============================================================================== | |||||
| /** This class measures the time between its construction and destruction and | |||||
| adds it to an AudioProcessLoadMeasurer. | |||||
| e.g. | |||||
| @code | |||||
| { | |||||
| AudioProcessLoadMeasurer::ScopedTimer timer (myProcessLoadMeasurer); | |||||
| myCallback->doTheCallback(); | |||||
| } | |||||
| @endcode | |||||
| */ | |||||
| struct JUCE_API ScopedTimer | |||||
| { | |||||
| ScopedTimer (AudioProcessLoadMeasurer&); | |||||
| ~ScopedTimer(); | |||||
| private: | |||||
| AudioProcessLoadMeasurer& owner; | |||||
| double startTime; | |||||
| JUCE_DECLARE_NON_COPYABLE (ScopedTimer) | |||||
| }; | |||||
| /** Can be called manually to add the time of a callback to the stats. | |||||
| Normally you probably would never call this - it's simpler and more robust to | |||||
| use a ScopedTimer to measure the time using an RAII pattern. | |||||
| */ | |||||
| void registerBlockRenderTime (double millisecondsTaken); | |||||
| private: | |||||
| double cpuUsageMs = 0, timeToCpuScale = 0, msPerBlock = 0; | |||||
| int xruns = 0; | |||||
| }; | |||||
| } // namespace juce | |||||
| @@ -56,6 +56,7 @@ | |||||
| #include "buffers/juce_AudioDataConverters.cpp" | #include "buffers/juce_AudioDataConverters.cpp" | ||||
| #include "buffers/juce_FloatVectorOperations.cpp" | #include "buffers/juce_FloatVectorOperations.cpp" | ||||
| #include "buffers/juce_AudioChannelSet.cpp" | #include "buffers/juce_AudioChannelSet.cpp" | ||||
| #include "buffers/juce_AudioProcessLoadMeasurer.cpp" | |||||
| #include "effects/juce_IIRFilter.cpp" | #include "effects/juce_IIRFilter.cpp" | ||||
| #include "effects/juce_LagrangeInterpolator.cpp" | #include "effects/juce_LagrangeInterpolator.cpp" | ||||
| #include "effects/juce_CatmullRomInterpolator.cpp" | #include "effects/juce_CatmullRomInterpolator.cpp" | ||||
| @@ -84,6 +84,7 @@ | |||||
| #include "buffers/juce_FloatVectorOperations.h" | #include "buffers/juce_FloatVectorOperations.h" | ||||
| #include "buffers/juce_AudioSampleBuffer.h" | #include "buffers/juce_AudioSampleBuffer.h" | ||||
| #include "buffers/juce_AudioChannelSet.h" | #include "buffers/juce_AudioChannelSet.h" | ||||
| #include "buffers/juce_AudioProcessLoadMeasurer.h" | |||||
| #include "effects/juce_Decibels.h" | #include "effects/juce_Decibels.h" | ||||
| #include "effects/juce_IIRFilter.h" | #include "effects/juce_IIRFilter.h" | ||||
| #include "effects/juce_LagrangeInterpolator.h" | #include "effects/juce_LagrangeInterpolator.h" | ||||
| @@ -23,14 +23,6 @@ | |||||
| namespace juce | namespace juce | ||||
| { | { | ||||
| AudioDeviceManager::AudioDeviceSetup::AudioDeviceSetup() | |||||
| : sampleRate (0), | |||||
| bufferSize (0), | |||||
| useDefaultInputChannels (true), | |||||
| useDefaultOutputChannels (true) | |||||
| { | |||||
| } | |||||
| bool AudioDeviceManager::AudioDeviceSetup::operator== (const AudioDeviceManager::AudioDeviceSetup& other) const | bool AudioDeviceManager::AudioDeviceSetup::operator== (const AudioDeviceManager::AudioDeviceSetup& other) const | ||||
| { | { | ||||
| return outputDeviceName == other.outputDeviceName | return outputDeviceName == other.outputDeviceName | ||||
| @@ -367,6 +359,11 @@ AudioIODeviceType* AudioDeviceManager::findType (const String& inputName, const | |||||
| return {}; | return {}; | ||||
| } | } | ||||
| AudioDeviceManager::AudioDeviceSetup AudioDeviceManager::getAudioDeviceSetup() const | |||||
| { | |||||
| return currentSetup; | |||||
| } | |||||
| void AudioDeviceManager::getAudioDeviceSetup (AudioDeviceSetup& setup) const | void AudioDeviceManager::getAudioDeviceSetup (AudioDeviceSetup& setup) const | ||||
| { | { | ||||
| setup = currentSetup; | setup = currentSetup; | ||||
| @@ -582,7 +579,7 @@ void AudioDeviceManager::closeAudioDevice() | |||||
| { | { | ||||
| stopDevice(); | stopDevice(); | ||||
| currentAudioDevice.reset(); | currentAudioDevice.reset(); | ||||
| cpuUsageMs = 0; | |||||
| loadMeasurer.reset(); | |||||
| } | } | ||||
| void AudioDeviceManager::restartLastAudioDevice() | void AudioDeviceManager::restartLastAudioDevice() | ||||
| @@ -694,7 +691,7 @@ void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelDat | |||||
| if (callbacks.size() > 0) | if (callbacks.size() > 0) | ||||
| { | { | ||||
| auto callbackStartTime = Time::getMillisecondCounterHiRes(); | |||||
| AudioProcessLoadMeasurer::ScopedTimer timer (loadMeasurer); | |||||
| tempBuffer.setSize (jmax (1, numOutputChannels), jmax (1, numSamples), false, false, true); | tempBuffer.setSize (jmax (1, numOutputChannels), jmax (1, numSamples), false, false, true); | ||||
| @@ -716,13 +713,6 @@ void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelDat | |||||
| dst[j] += src[j]; | dst[j] += src[j]; | ||||
| } | } | ||||
| } | } | ||||
| auto msTaken = Time::getMillisecondCounterHiRes() - callbackStartTime; | |||||
| const double filterAmount = 0.2; | |||||
| cpuUsageMs += filterAmount * (msTaken - cpuUsageMs); | |||||
| if (msTaken > msPerBlock) | |||||
| ++xruns; | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -748,17 +738,8 @@ void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelDat | |||||
| void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device) | void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device) | ||||
| { | { | ||||
| cpuUsageMs = 0; | |||||
| xruns = 0; | |||||
| auto sampleRate = device->getCurrentSampleRate(); | |||||
| auto blockSize = device->getCurrentBufferSizeSamples(); | |||||
| if (sampleRate > 0.0 && blockSize > 0) | |||||
| { | |||||
| msPerBlock = 1000.0 * blockSize / sampleRate; | |||||
| timeToCpuScale = (msPerBlock > 0.0) ? (1.0 / msPerBlock) : 0.0; | |||||
| } | |||||
| loadMeasurer.reset (device->getCurrentSampleRate(), | |||||
| device->getCurrentBufferSizeSamples()); | |||||
| { | { | ||||
| const ScopedLock sl (audioCallbackLock); | const ScopedLock sl (audioCallbackLock); | ||||
| @@ -772,13 +753,12 @@ void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device | |||||
| void AudioDeviceManager::audioDeviceStoppedInt() | void AudioDeviceManager::audioDeviceStoppedInt() | ||||
| { | { | ||||
| cpuUsageMs = 0; | |||||
| timeToCpuScale = 0; | |||||
| xruns = 0; | |||||
| sendChangeMessage(); | sendChangeMessage(); | ||||
| const ScopedLock sl (audioCallbackLock); | const ScopedLock sl (audioCallbackLock); | ||||
| loadMeasurer.reset(); | |||||
| for (int i = callbacks.size(); --i >= 0;) | for (int i = callbacks.size(); --i >= 0;) | ||||
| callbacks.getUnchecked(i)->audioDeviceStopped(); | callbacks.getUnchecked(i)->audioDeviceStopped(); | ||||
| } | } | ||||
| @@ -793,7 +773,7 @@ void AudioDeviceManager::audioDeviceErrorInt (const String& message) | |||||
| double AudioDeviceManager::getCpuUsage() const | double AudioDeviceManager::getCpuUsage() const | ||||
| { | { | ||||
| return jlimit (0.0, 1.0, timeToCpuScale * cpuUsageMs); | |||||
| return loadMeasurer.getLoadAsProportion(); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -980,7 +960,7 @@ void AudioDeviceManager::playTestSound() | |||||
| auto phasePerSample = MathConstants<double>::twoPi / (sampleRate / frequency); | auto phasePerSample = MathConstants<double>::twoPi / (sampleRate / frequency); | ||||
| auto* newSound = new AudioBuffer<float> (1, soundLength); | |||||
| std::unique_ptr<AudioBuffer<float>> newSound (new AudioBuffer<float> (1, soundLength)); | |||||
| for (int i = 0; i < soundLength; ++i) | for (int i = 0; i < soundLength; ++i) | ||||
| newSound->setSample (0, i, amplitude * (float) std::sin (i * phasePerSample)); | newSound->setSample (0, i, amplitude * (float) std::sin (i * phasePerSample)); | ||||
| @@ -988,15 +968,17 @@ void AudioDeviceManager::playTestSound() | |||||
| newSound->applyGainRamp (0, 0, soundLength / 10, 0.0f, 1.0f); | newSound->applyGainRamp (0, 0, soundLength / 10, 0.0f, 1.0f); | ||||
| newSound->applyGainRamp (0, soundLength - soundLength / 4, soundLength / 4, 1.0f, 0.0f); | newSound->applyGainRamp (0, soundLength - soundLength / 4, soundLength / 4, 1.0f, 0.0f); | ||||
| const ScopedLock sl (audioCallbackLock); | |||||
| testSound.reset (newSound); | |||||
| { | |||||
| const ScopedLock sl (audioCallbackLock); | |||||
| std::swap (testSound, newSound); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| int AudioDeviceManager::getXRunCount() const noexcept | int AudioDeviceManager::getXRunCount() const noexcept | ||||
| { | { | ||||
| auto deviceXRuns = (currentAudioDevice != nullptr ? currentAudioDevice->getXRunCount() : -1); | auto deviceXRuns = (currentAudioDevice != nullptr ? currentAudioDevice->getXRunCount() : -1); | ||||
| return jmax (0, deviceXRuns) + xruns; | |||||
| return jmax (0, deviceXRuns) + loadMeasurer.getXRunCount(); | |||||
| } | } | ||||
| } // namespace juce | } // namespace juce | ||||
| @@ -89,17 +89,6 @@ public: | |||||
| */ | */ | ||||
| struct JUCE_API AudioDeviceSetup | struct JUCE_API AudioDeviceSetup | ||||
| { | { | ||||
| /** Creates an AudioDeviceSetup object. | |||||
| The default constructor sets all the member variables to indicate default values. | |||||
| You can then fill-in any values you want to before passing the object to | |||||
| AudioDeviceManager::initialise(). | |||||
| */ | |||||
| AudioDeviceSetup(); | |||||
| bool operator== (const AudioDeviceSetup& other) const; | |||||
| bool operator!= (const AudioDeviceSetup& other) const; | |||||
| /** The name of the audio device used for output. | /** The name of the audio device used for output. | ||||
| The name has to be one of the ones listed by the AudioDeviceManager's currently | The name has to be one of the ones listed by the AudioDeviceManager's currently | ||||
| selected device type. | selected device type. | ||||
| @@ -119,13 +108,13 @@ public: | |||||
| A value of 0 indicates that you don't care what rate is used, and the | A value of 0 indicates that you don't care what rate is used, and the | ||||
| device will choose a sensible rate for you. | device will choose a sensible rate for you. | ||||
| */ | */ | ||||
| double sampleRate; | |||||
| double sampleRate = 0; | |||||
| /** The buffer size, in samples. | /** The buffer size, in samples. | ||||
| This buffer size is used for both the input and output devices. | This buffer size is used for both the input and output devices. | ||||
| A value of 0 indicates the default buffer size. | A value of 0 indicates the default buffer size. | ||||
| */ | */ | ||||
| int bufferSize; | |||||
| int bufferSize = 0; | |||||
| /** The set of active input channels. | /** The set of active input channels. | ||||
| The bits that are set in this array indicate the channels of the | The bits that are set in this array indicate the channels of the | ||||
| @@ -138,7 +127,7 @@ public: | |||||
| should be ignored, and instead, the device's default channels | should be ignored, and instead, the device's default channels | ||||
| should be used. | should be used. | ||||
| */ | */ | ||||
| bool useDefaultInputChannels; | |||||
| bool useDefaultInputChannels = true; | |||||
| /** The set of active output channels. | /** The set of active output channels. | ||||
| The bits that are set in this array indicate the channels of the | The bits that are set in this array indicate the channels of the | ||||
| @@ -151,7 +140,10 @@ public: | |||||
| should be ignored, and instead, the device's default channels | should be ignored, and instead, the device's default channels | ||||
| should be used. | should be used. | ||||
| */ | */ | ||||
| bool useDefaultOutputChannels; | |||||
| bool useDefaultOutputChannels = true; | |||||
| bool operator== (const AudioDeviceSetup&) const; | |||||
| bool operator!= (const AudioDeviceSetup&) const; | |||||
| }; | }; | ||||
| @@ -211,6 +203,13 @@ public: | |||||
| /** Returns the current device properties that are in use. | /** Returns the current device properties that are in use. | ||||
| @see setAudioDeviceSetup | @see setAudioDeviceSetup | ||||
| */ | */ | ||||
| AudioDeviceSetup getAudioDeviceSetup() const; | |||||
| /** Returns the current device properties that are in use. | |||||
| This is an old method, kept around for compatibility, but you should prefer the new | |||||
| version which returns the result rather than taking an out-parameter. | |||||
| @see getAudioDeviceSetup() | |||||
| */ | |||||
| void getAudioDeviceSetup (AudioDeviceSetup& result) const; | void getAudioDeviceSetup (AudioDeviceSetup& result) const; | ||||
| /** Changes the current device or its settings. | /** Changes the current device or its settings. | ||||
| @@ -232,8 +231,7 @@ public: | |||||
| @see getAudioDeviceSetup | @see getAudioDeviceSetup | ||||
| */ | */ | ||||
| String setAudioDeviceSetup (const AudioDeviceSetup& newSetup, | |||||
| bool treatAsChosenDevice); | |||||
| String setAudioDeviceSetup (const AudioDeviceSetup& newSetup, bool treatAsChosenDevice); | |||||
| /** Returns the currently-active audio device. */ | /** Returns the currently-active audio device. */ | ||||
| @@ -257,8 +255,7 @@ public: | |||||
| For a list of types, see getAvailableDeviceTypes(). | For a list of types, see getAvailableDeviceTypes(). | ||||
| */ | */ | ||||
| void setCurrentAudioDeviceType (const String& type, | |||||
| bool treatAsChosenDevice); | |||||
| void setCurrentAudioDeviceType (const String& type, bool treatAsChosenDevice); | |||||
| /** Closes the currently-open device. | /** Closes the currently-open device. | ||||
| You can call restartLastAudioDevice() later to reopen it in the same state | You can call restartLastAudioDevice() later to reopen it in the same state | ||||
| @@ -496,8 +493,7 @@ private: | |||||
| std::unique_ptr<AudioBuffer<float>> testSound; | std::unique_ptr<AudioBuffer<float>> testSound; | ||||
| int testSoundPosition = 0; | int testSoundPosition = 0; | ||||
| double cpuUsageMs = 0, timeToCpuScale = 0, msPerBlock = 0; | |||||
| int xruns = 0; | |||||
| AudioProcessLoadMeasurer loadMeasurer; | |||||
| LevelMeter::Ptr inputLevelGetter { new LevelMeter() }, | LevelMeter::Ptr inputLevelGetter { new LevelMeter() }, | ||||
| outputLevelGetter { new LevelMeter() }; | outputLevelGetter { new LevelMeter() }; | ||||
| @@ -52,11 +52,10 @@ void AudioAppComponent::setAudioChannels (int numInputChannels, int numOutputCha | |||||
| if (usingCustomDeviceManager && xml == nullptr) | if (usingCustomDeviceManager && xml == nullptr) | ||||
| { | { | ||||
| AudioDeviceManager::AudioDeviceSetup setup; | |||||
| deviceManager.getAudioDeviceSetup (setup); | |||||
| auto setup = deviceManager.getAudioDeviceSetup(); | |||||
| if (setup.inputChannels.countNumberOfSetBits() != numInputChannels | if (setup.inputChannels.countNumberOfSetBits() != numInputChannels | ||||
| || setup.outputChannels.countNumberOfSetBits() != numOutputChannels) | |||||
| || setup.outputChannels.countNumberOfSetBits() != numOutputChannels) | |||||
| { | { | ||||
| setup.inputChannels.clear(); | setup.inputChannels.clear(); | ||||
| setup.outputChannels.clear(); | setup.outputChannels.clear(); | ||||
| @@ -330,8 +330,7 @@ public: | |||||
| void updateConfig (bool updateOutputDevice, bool updateInputDevice, bool updateSampleRate, bool updateBufferSize) | void updateConfig (bool updateOutputDevice, bool updateInputDevice, bool updateSampleRate, bool updateBufferSize) | ||||
| { | { | ||||
| AudioDeviceManager::AudioDeviceSetup config; | |||||
| setup.manager->getAudioDeviceSetup (config); | |||||
| auto config = setup.manager->getAudioDeviceSetup(); | |||||
| String error; | String error; | ||||
| if (updateOutputDevice || updateInputDevice) | if (updateOutputDevice || updateInputDevice) | ||||
| @@ -769,9 +768,7 @@ public: | |||||
| auto item = items[row]; | auto item = items[row]; | ||||
| bool enabled = false; | bool enabled = false; | ||||
| AudioDeviceManager::AudioDeviceSetup config; | |||||
| setup.manager->getAudioDeviceSetup (config); | |||||
| auto config = setup.manager->getAudioDeviceSetup(); | |||||
| if (setup.useStereoPairs) | if (setup.useStereoPairs) | ||||
| { | { | ||||
| @@ -868,8 +865,7 @@ public: | |||||
| if (isPositiveAndBelow (row, items.size())) | if (isPositiveAndBelow (row, items.size())) | ||||
| { | { | ||||
| AudioDeviceManager::AudioDeviceSetup config; | |||||
| setup.manager->getAudioDeviceSetup (config); | |||||
| auto config = setup.manager->getAudioDeviceSetup(); | |||||
| if (setup.useStereoPairs) | if (setup.useStereoPairs) | ||||
| { | { | ||||