26 bool AudioDeviceManager::AudioDeviceSetup::operator== (
const AudioDeviceManager::AudioDeviceSetup& other)
const
38 bool AudioDeviceManager::AudioDeviceSetup::operator!= (
const AudioDeviceManager::AudioDeviceSetup& other)
const
40 return ! operator== (other);
52 void audioDeviceIOCallback (
const float** ins,
int numIns,
float** outs,
int numOuts,
int numSamples)
override
54 owner.audioDeviceIOCallbackInt (ins, numIns, outs, numOuts, numSamples);
59 owner.audioDeviceAboutToStartInt (device);
62 void audioDeviceStopped()
override
64 owner.audioDeviceStoppedInt();
67 void audioDeviceError (
const String& message)
override
69 owner.audioDeviceErrorInt (message);
74 owner.handleIncomingMidiMessageInt (source, message);
77 void audioDeviceListChanged()
override
79 owner.audioDeviceListChanged();
95 currentAudioDevice.reset();
96 defaultMidiOutput.reset();
100 void AudioDeviceManager::createDeviceTypesIfNeeded()
102 if (availableDeviceTypes.size() == 0)
107 for (
auto* t : types)
112 if (
auto* first = availableDeviceTypes.getFirst())
113 currentDeviceType = first->getTypeName();
119 scanDevicesIfNeeded();
120 return availableDeviceTypes;
123 void AudioDeviceManager::audioDeviceListChanged()
125 if (currentAudioDevice !=
nullptr)
127 auto isCurrentDeviceStillAvailable = [&]
129 for (
auto* dt : availableDeviceTypes)
130 if (currentAudioDevice->getTypeName() == dt->getTypeName())
131 for (
auto& dn : dt->getDeviceNames())
132 if (currentAudioDevice->getName() == dn)
138 if (! isCurrentDeviceStillAvailable())
145 initialiseDefault (preferredDeviceName, ¤tSetup);
147 initialiseFromXML (*e,
true, preferredDeviceName, ¤tSetup);
150 if (currentAudioDevice !=
nullptr)
152 currentSetup.
sampleRate = currentAudioDevice->getCurrentSampleRate();
153 currentSetup.
bufferSize = currentAudioDevice->getCurrentBufferSizeSamples();
154 currentSetup.
inputChannels = currentAudioDevice->getActiveInputChannels();
155 currentSetup.
outputChannels = currentAudioDevice->getActiveOutputChannels();
163 static void addIfNotNull (OwnedArray<AudioIODeviceType>& list, AudioIODeviceType*
const device)
165 if (device !=
nullptr)
187 if (newDeviceType !=
nullptr)
189 jassert (lastDeviceTypeConfigs.size() == availableDeviceTypes.size());
190 availableDeviceTypes.add (newDeviceType);
193 newDeviceType->
addListener (callbackHandler.get());
200 if (deviceName.trim().equalsIgnoreCase (name.
trim()))
208 const int numOutputChannelsNeeded,
210 const bool selectDefaultDeviceOnFailure,
211 const String& preferredDefaultDeviceName,
214 scanDevicesIfNeeded();
216 numInputChansNeeded = numInputChannelsNeeded;
217 numOutputChansNeeded = numOutputChannelsNeeded;
218 preferredDeviceName = preferredDefaultDeviceName;
220 if (xml !=
nullptr && xml->
hasTagName (
"DEVICESETUP"))
221 return initialiseFromXML (*xml, selectDefaultDeviceOnFailure,
222 preferredDeviceName, preferredSetupOptions);
224 return initialiseDefault (preferredDeviceName, preferredSetupOptions);
227 String AudioDeviceManager::initialiseDefault (
const String& preferredDefaultDeviceName,
228 const AudioDeviceSetup* preferredSetupOptions)
230 AudioDeviceSetup setup;
232 if (preferredSetupOptions !=
nullptr)
234 setup = *preferredSetupOptions;
236 else if (preferredDefaultDeviceName.
isNotEmpty())
238 for (
auto* type : availableDeviceTypes)
242 if (out.matchesWildcard (preferredDefaultDeviceName,
true))
244 setup.outputDeviceName = out;
251 if (in.matchesWildcard (preferredDefaultDeviceName,
true))
253 setup.inputDeviceName = in;
260 insertDefaultDeviceNames (setup);
264 String AudioDeviceManager::initialiseFromXML (
const XmlElement& xml,
265 bool selectDefaultDeviceOnFailure,
266 const String& preferredDefaultDeviceName,
267 const AudioDeviceSetup* preferredSetupOptions)
269 lastExplicitSettings.reset (
new XmlElement (xml));
272 AudioDeviceSetup setup;
274 if (preferredSetupOptions !=
nullptr)
275 setup = *preferredSetupOptions;
277 if (xml.getStringAttribute (
"audioDeviceName").isNotEmpty())
279 setup.inputDeviceName = setup.outputDeviceName
280 = xml.getStringAttribute (
"audioDeviceName");
284 setup.inputDeviceName = xml.getStringAttribute (
"audioInputDeviceName");
285 setup.outputDeviceName = xml.getStringAttribute (
"audioOutputDeviceName");
288 currentDeviceType = xml.getStringAttribute (
"deviceType");
290 if (findType (currentDeviceType) ==
nullptr)
292 if (
auto* type = findType (setup.inputDeviceName, setup.outputDeviceName))
294 else if (
auto* firstType = availableDeviceTypes.getFirst())
295 currentDeviceType = firstType->getTypeName();
298 setup.bufferSize = xml.getIntAttribute (
"audioDeviceBufferSize", setup.bufferSize);
299 setup.sampleRate = xml.getDoubleAttribute (
"audioDeviceRate", setup.sampleRate);
301 setup.inputChannels .parseString (xml.getStringAttribute (
"audioDeviceInChans",
"11"), 2);
302 setup.outputChannels.parseString (xml.getStringAttribute (
"audioDeviceOutChans",
"11"), 2);
304 setup.useDefaultInputChannels = ! xml.hasAttribute (
"audioDeviceInChans");
305 setup.useDefaultOutputChannels = ! xml.hasAttribute (
"audioDeviceOutChans");
309 midiInsFromXml.
clear();
311 forEachXmlChildElementWithTagName (xml, c,
"MIDIINPUT")
312 midiInsFromXml.add (c->getStringAttribute ("name"));
314 for (auto& m : MidiInput::getDevices())
317 if (error.isNotEmpty() && selectDefaultDeviceOnFailure)
318 error =
initialise (numInputChansNeeded, numOutputChansNeeded,
319 nullptr, false, preferredDefaultDeviceName);
327 int numOutputChannelsNeeded)
329 lastExplicitSettings.reset();
331 return initialise (numInputChannelsNeeded, numOutputChannelsNeeded,
332 nullptr,
false, {},
nullptr);
335 void AudioDeviceManager::insertDefaultDeviceNames (AudioDeviceSetup& setup)
const
339 if (numOutputChansNeeded > 0 && setup.outputDeviceName.isEmpty())
342 if (numInputChansNeeded > 0 && setup.inputDeviceName.isEmpty())
349 return createCopyIfNotNull (lastExplicitSettings.get());
353 void AudioDeviceManager::scanDevicesIfNeeded()
355 if (listNeedsScanning)
357 listNeedsScanning =
false;
359 createDeviceTypesIfNeeded();
361 for (
auto* type : availableDeviceTypes)
366 AudioIODeviceType* AudioDeviceManager::findType (
const String& typeName)
368 scanDevicesIfNeeded();
370 for (
auto* type : availableDeviceTypes)
377 AudioIODeviceType* AudioDeviceManager::findType (
const String& inputName,
const String& outputName)
379 scanDevicesIfNeeded();
381 for (
auto* type : availableDeviceTypes)
382 if ((inputName.isNotEmpty() && deviceListContains (type,
true, inputName))
383 || (outputName.isNotEmpty() && deviceListContains (type,
false, outputName)))
396 setup = currentSetup;
399 void AudioDeviceManager::deleteCurrentDevice()
401 currentAudioDevice.reset();
408 for (
int i = 0; i < availableDeviceTypes.size(); ++i)
410 if (availableDeviceTypes.getUnchecked(i)->getTypeName() == type
411 && currentDeviceType != type)
413 if (currentAudioDevice !=
nullptr)
420 currentDeviceType = type;
423 insertDefaultDeviceNames (s);
435 for (
auto* type : availableDeviceTypes)
439 return availableDeviceTypes.getFirst();
443 bool treatAsChosenDevice)
445 jassert (&newSetup != ¤tSetup);
447 if (newSetup == currentSetup && currentAudioDevice !=
nullptr)
450 if (! (newSetup == currentSetup))
465 deleteCurrentDevice();
467 if (treatAsChosenDevice)
477 || currentAudioDevice ==
nullptr)
479 deleteCurrentDevice();
480 scanDevicesIfNeeded();
490 if (currentAudioDevice ==
nullptr)
491 error =
"Can't open the audio device!\n\n"
492 "This may be because another application is currently using the same device - "
493 "if so, you should close any other applications and try again!";
495 error = currentAudioDevice->getLastError();
499 deleteCurrentDevice();
505 inputChannels.
clear();
506 inputChannels.
setRange (0, numInputChansNeeded,
true);
511 outputChannels.
clear();
512 outputChannels.
setRange (0, numOutputChansNeeded,
true);
525 currentSetup = newSetup;
529 if (treatAsChosenDevice)
538 error = currentAudioDevice->open (inputChannels,
545 currentDeviceType = currentAudioDevice->getTypeName();
547 currentAudioDevice->start (callbackHandler.get());
549 currentSetup.
sampleRate = currentAudioDevice->getCurrentSampleRate();
550 currentSetup.
bufferSize = currentAudioDevice->getCurrentBufferSizeSamples();
551 currentSetup.
inputChannels = currentAudioDevice->getActiveInputChannels();
552 currentSetup.
outputChannels = currentAudioDevice->getActiveOutputChannels();
554 for (
int i = 0; i < availableDeviceTypes.size(); ++i)
555 if (availableDeviceTypes.getUnchecked (i)->getTypeName() == currentDeviceType)
556 *(lastDeviceTypeConfigs.getUnchecked (i)) = currentSetup;
558 if (treatAsChosenDevice)
563 deleteCurrentDevice();
569 double AudioDeviceManager::chooseBestSampleRate (
double rate)
const
571 jassert (currentAudioDevice !=
nullptr);
573 auto rates = currentAudioDevice->getAvailableSampleRates();
575 if (rate > 0 && rates.contains (rate))
578 rate = currentAudioDevice->getCurrentSampleRate();
580 if (rate > 0 && rates.contains (rate))
583 double lowestAbove44 = 0.0;
585 for (
int i = rates.size(); --i >= 0;)
589 if (sr >= 44100.0 && (lowestAbove44 < 1.0 || sr < lowestAbove44))
593 if (lowestAbove44 > 0.0)
594 return lowestAbove44;
599 int AudioDeviceManager::chooseBestBufferSize (
int bufferSize)
const
601 jassert (currentAudioDevice !=
nullptr);
603 if (bufferSize > 0 && currentAudioDevice->getAvailableBufferSizes().contains (bufferSize))
606 return currentAudioDevice->getDefaultBufferSize();
609 void AudioDeviceManager::stopDevice()
611 if (currentAudioDevice !=
nullptr)
612 currentAudioDevice->stop();
620 currentAudioDevice.reset();
621 loadMeasurer.
reset();
626 if (currentAudioDevice ==
nullptr)
643 void AudioDeviceManager::updateXml()
645 lastExplicitSettings.reset (
new XmlElement (
"DEVICESETUP"));
647 lastExplicitSettings->setAttribute (
"deviceType", currentDeviceType);
648 lastExplicitSettings->setAttribute (
"audioOutputDeviceName", currentSetup.
outputDeviceName);
649 lastExplicitSettings->setAttribute (
"audioInputDeviceName", currentSetup.
inputDeviceName);
651 if (currentAudioDevice !=
nullptr)
653 lastExplicitSettings->setAttribute (
"audioDeviceRate", currentAudioDevice->getCurrentSampleRate());
655 if (currentAudioDevice->getDefaultBufferSize() != currentAudioDevice->getCurrentBufferSizeSamples())
656 lastExplicitSettings->setAttribute (
"audioDeviceBufferSize", currentAudioDevice->getCurrentBufferSizeSamples());
665 for (
int i = 0; i < enabledMidiInputs.size(); ++i)
666 lastExplicitSettings->createNewChildElement (
"MIDIINPUT")
667 ->setAttribute (
"name", enabledMidiInputs[i]->getName());
669 if (midiInsFromXml.
size() > 0)
675 for (
int i = 0; i < midiInsFromXml.
size(); ++i)
676 if (! availableMidiDevices.contains (midiInsFromXml[i],
true))
677 lastExplicitSettings->createNewChildElement (
"MIDIINPUT")
678 ->setAttribute (
"name", midiInsFromXml[i]);
682 lastExplicitSettings->setAttribute (
"defaultMidiOutput", defaultMidiOutputName);
691 if (callbacks.contains (newCallback))
695 if (currentAudioDevice !=
nullptr && newCallback !=
nullptr)
699 callbacks.add (newCallback);
704 if (callbackToRemove !=
nullptr)
706 bool needsDeinitialising = currentAudioDevice !=
nullptr;
711 needsDeinitialising = needsDeinitialising && callbacks.contains (callbackToRemove);
712 callbacks.removeFirstMatchingValue (callbackToRemove);
715 if (needsDeinitialising)
720 void AudioDeviceManager::audioDeviceIOCallbackInt (
const float** inputChannelData,
721 int numInputChannels,
722 float** outputChannelData,
723 int numOutputChannels,
728 inputLevelGetter->updateLevel (inputChannelData, numInputChannels, numSamples);
729 outputLevelGetter->updateLevel (
const_cast<const float**
> (outputChannelData), numOutputChannels, numSamples);
731 if (callbacks.size() > 0)
735 tempBuffer.
setSize (jmax (1, numOutputChannels), jmax (1, numSamples),
false,
false,
true);
737 callbacks.getUnchecked(0)->audioDeviceIOCallback (inputChannelData, numInputChannels,
738 outputChannelData, numOutputChannels, numSamples);
742 for (
int i = callbacks.size(); --i > 0;)
744 callbacks.getUnchecked(i)->audioDeviceIOCallback (inputChannelData, numInputChannels,
745 tempChans, numOutputChannels, numSamples);
747 for (
int chan = 0; chan < numOutputChannels; ++chan)
749 if (
auto* src = tempChans [chan])
750 if (
auto* dst = outputChannelData [chan])
751 for (
int j = 0; j < numSamples; ++j)
758 for (
int i = 0; i < numOutputChannels; ++i)
759 zeromem (outputChannelData[i],
sizeof (
float) * (
size_t) numSamples);
762 if (testSound !=
nullptr)
764 auto numSamps = jmin (numSamples, testSound->getNumSamples() - testSoundPosition);
765 auto* src = testSound->getReadPointer (0, testSoundPosition);
767 for (
int i = 0; i < numOutputChannels; ++i)
768 for (
int j = 0; j < numSamps; ++j)
769 outputChannelData [i][j] += src[j];
771 testSoundPosition += numSamps;
773 if (testSoundPosition >= testSound->getNumSamples())
778 void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice*
const device)
780 loadMeasurer.
reset (device->getCurrentSampleRate(),
781 device->getCurrentBufferSizeSamples());
784 const ScopedLock sl (audioCallbackLock);
786 for (
int i = callbacks.size(); --i >= 0;)
787 callbacks.getUnchecked(i)->audioDeviceAboutToStart (device);
793 void AudioDeviceManager::audioDeviceStoppedInt()
797 const ScopedLock sl (audioCallbackLock);
799 loadMeasurer.
reset();
801 for (
int i = callbacks.size(); --i >= 0;)
802 callbacks.getUnchecked(i)->audioDeviceStopped();
805 void AudioDeviceManager::audioDeviceErrorInt (
const String& message)
807 const ScopedLock sl (audioCallbackLock);
809 for (
int i = callbacks.size(); --i >= 0;)
810 callbacks.getUnchecked(i)->audioDeviceError (message);
831 enabledMidiInputs.add (midiIn);
838 for (
int i = enabledMidiInputs.size(); --i >= 0;)
839 if (enabledMidiInputs[i]->getName() == name)
840 enabledMidiInputs.remove (i);
850 for (
auto* mi : enabledMidiInputs)
851 if (mi->getName() == name)
866 mc.deviceName = name;
867 mc.callback = callbackToAdd;
868 midiCallbacks.
add (mc);
874 for (
int i = midiCallbacks.
size(); --i >= 0;)
878 if (mc.callback == callbackToRemove && mc.deviceName == name)
886 void AudioDeviceManager::handleIncomingMidiMessageInt (
MidiInput* source,
const MidiMessage& message)
892 for (
auto& mc : midiCallbacks)
893 if (mc.deviceName.isEmpty() || mc.deviceName == source->
getName())
894 mc.callback->handleIncomingMidiMessage (source, message);
901 if (defaultMidiOutputName != deviceName)
910 if (currentAudioDevice !=
nullptr)
911 for (
int i = oldCallbacks.
size(); --i >= 0;)
914 defaultMidiOutput.reset();
915 defaultMidiOutputName = deviceName;
920 if (currentAudioDevice !=
nullptr)
921 for (
auto* c : oldCallbacks)
922 c->audioDeviceAboutToStart (currentAudioDevice.get());
926 oldCallbacks.swapWith (callbacks);
935 AudioDeviceManager::LevelMeter::LevelMeter() noexcept : level() {}
937 void AudioDeviceManager::LevelMeter::updateLevel (
const float*
const* channelData,
int numChannels,
int numSamples) noexcept
939 if (getReferenceCount() <= 1)
942 auto localLevel = level.get();
946 for (
int j = 0; j < numSamples; ++j)
950 for (
int i = 0; i < numChannels; ++i)
951 s += std::abs (channelData[i][j]);
953 s /= (float) numChannels;
955 const float decayFactor = 0.99992f;
959 else if (localLevel > 0.001f)
960 localLevel *= decayFactor;
973 double AudioDeviceManager::LevelMeter::getCurrentLevel() const noexcept
975 jassert (getReferenceCount() > 1);
982 std::unique_ptr<AudioBuffer<float>> oldSound;
986 std::swap (oldSound, testSound);
990 testSoundPosition = 0;
992 if (currentAudioDevice !=
nullptr)
994 auto sampleRate = currentAudioDevice->getCurrentSampleRate();
995 auto soundLength = (int) sampleRate;
997 double frequency = 440.0;
998 float amplitude = 0.5f;
1002 std::unique_ptr<AudioBuffer<float>> newSound (
new AudioBuffer<float> (1, soundLength));
1004 for (
int i = 0; i < soundLength; ++i)
1005 newSound->setSample (0, i, amplitude * (
float) std::sin (i * phasePerSample));
1007 newSound->applyGainRamp (0, 0, soundLength / 10, 0.0f, 1.0f);
1008 newSound->applyGainRamp (0, soundLength - soundLength / 4, soundLength / 4, 1.0f, 0.0f);
1012 std::swap (testSound, newSound);
1019 auto deviceXRuns = (currentAudioDevice !=
nullptr ? currentAudioDevice->getXRunCount() : -1);
1020 return jmax (0, deviceXRuns) + loadMeasurer.
getXRunCount();