OpenShot Audio Library | OpenShotAudio 0.3.2

Loading...
Searching...
No Matches
juce_AudioDeviceManager.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23 namespace juce
24{
25
26 bool AudioDeviceManager::AudioDeviceSetup::operator== (const AudioDeviceManager::AudioDeviceSetup& other) const
27{
28 return outputDeviceName == other.outputDeviceName
29 && inputDeviceName == other.inputDeviceName
30 && sampleRate == other.sampleRate
31 && bufferSize == other.bufferSize
32 && inputChannels == other.inputChannels
33 && useDefaultInputChannels == other.useDefaultInputChannels
34 && outputChannels == other.outputChannels
35 && useDefaultOutputChannels == other.useDefaultOutputChannels;
36}
37
38 bool AudioDeviceManager::AudioDeviceSetup::operator!= (const AudioDeviceManager::AudioDeviceSetup& other) const
39{
40 return ! operator== (other);
41}
42
43//==============================================================================
44 class AudioDeviceManager::CallbackHandler : public AudioIODeviceCallback,
45 public MidiInputCallback,
46 public AudioIODeviceType::Listener
47{
48 public:
49 CallbackHandler (AudioDeviceManager& adm) noexcept : owner (adm) {}
50
51 private:
52 void audioDeviceIOCallback (const float** ins, int numIns, float** outs, int numOuts, int numSamples) override
53 {
54 owner.audioDeviceIOCallbackInt (ins, numIns, outs, numOuts, numSamples);
55 }
56
57 void audioDeviceAboutToStart (AudioIODevice* device) override
58 {
59 owner.audioDeviceAboutToStartInt (device);
60 }
61
62 void audioDeviceStopped() override
63 {
64 owner.audioDeviceStoppedInt();
65 }
66
67 void audioDeviceError (const String& message) override
68 {
69 owner.audioDeviceErrorInt (message);
70 }
71
72 void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message) override
73 {
74 owner.handleIncomingMidiMessageInt (source, message);
75 }
76
77 void audioDeviceListChanged() override
78 {
79 owner.audioDeviceListChanged();
80 }
81
82 AudioDeviceManager& owner;
83
84 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CallbackHandler)
85};
86
87//==============================================================================
88 AudioDeviceManager::AudioDeviceManager()
89{
90 callbackHandler.reset (new CallbackHandler (*this));
91}
92
93 AudioDeviceManager::~AudioDeviceManager()
94{
95 currentAudioDevice.reset();
96 defaultMidiOutput.reset();
97}
98
99//==============================================================================
100 void AudioDeviceManager::createDeviceTypesIfNeeded()
101{
102 if (availableDeviceTypes.size() == 0)
103 {
104 OwnedArray<AudioIODeviceType> types;
105 createAudioDeviceTypes (types);
106
107 for (auto* t : types)
108 addAudioDeviceType (std::unique_ptr<AudioIODeviceType> (t));
109
110 types.clear (false);
111
112 if (auto* first = availableDeviceTypes.getFirst())
113 currentDeviceType = first->getTypeName();
114 }
115}
116
117 const OwnedArray<AudioIODeviceType>& AudioDeviceManager::getAvailableDeviceTypes()
118{
119 scanDevicesIfNeeded();
120 return availableDeviceTypes;
121}
122
123 void AudioDeviceManager::audioDeviceListChanged()
124{
125 if (currentAudioDevice != nullptr)
126 {
127 auto isCurrentDeviceStillAvailable = [&]
128 {
129 for (auto* dt : availableDeviceTypes)
130 if (currentAudioDevice->getTypeName() == dt->getTypeName())
131 for (auto& dn : dt->getDeviceNames())
132 if (currentAudioDevice->getName() == dn)
133 return true;
134
135 return false;
136 };
137
138 if (! isCurrentDeviceStillAvailable())
139 {
140 closeAudioDevice();
141
142 if (auto e = createStateXml())
143 initialiseFromXML (*e, true, preferredDeviceName, &currentSetup);
144 else
145 initialiseDefault (preferredDeviceName, &currentSetup);
146 }
147
148 if (currentAudioDevice != nullptr)
149 {
150 currentSetup.sampleRate = currentAudioDevice->getCurrentSampleRate();
151 currentSetup.bufferSize = currentAudioDevice->getCurrentBufferSizeSamples();
152 currentSetup.inputChannels = currentAudioDevice->getActiveInputChannels();
153 currentSetup.outputChannels = currentAudioDevice->getActiveOutputChannels();
154 }
155 }
156
157 sendChangeMessage();
158}
159
160//==============================================================================
161 static void addIfNotNull (OwnedArray<AudioIODeviceType>& list, AudioIODeviceType* const device)
162{
163 if (device != nullptr)
164 list.add (device);
165}
166
167 void AudioDeviceManager::createAudioDeviceTypes (OwnedArray<AudioIODeviceType>& list)
168{
169 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (false));
170 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI (true));
171 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_DirectSound());
172 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ASIO());
173 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_CoreAudio());
174 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_iOSAudio());
175 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Bela());
176 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ALSA());
177 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK());
178 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Oboe());
179 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_OpenSLES());
180 addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_Android());
181}
182
183 void AudioDeviceManager::addAudioDeviceType (std::unique_ptr<AudioIODeviceType> newDeviceType)
184{
185 if (newDeviceType != nullptr)
186 {
187 jassert (lastDeviceTypeConfigs.size() == availableDeviceTypes.size());
188
189 availableDeviceTypes.add (newDeviceType.release());
190 lastDeviceTypeConfigs.add (new AudioDeviceSetup());
191
192 availableDeviceTypes.getLast()->addListener (callbackHandler.get());
193 }
194}
195
196 void AudioDeviceManager::removeAudioDeviceType (AudioIODeviceType* deviceTypeToRemove)
197{
198 if (deviceTypeToRemove != nullptr)
199 {
200 jassert (lastDeviceTypeConfigs.size() == availableDeviceTypes.size());
201
202 auto index = availableDeviceTypes.indexOf (deviceTypeToRemove);
203
204 if (auto removed = std::unique_ptr<AudioIODeviceType> (availableDeviceTypes.removeAndReturn (index)))
205 {
206 removed->removeListener (callbackHandler.get());
207 lastDeviceTypeConfigs.remove (index, true);
208 }
209 }
210}
211
212 static bool deviceListContains (AudioIODeviceType* type, bool isInput, const String& name)
213{
214 for (auto& deviceName : type->getDeviceNames (isInput))
215 if (deviceName.trim().equalsIgnoreCase (name.trim()))
216 return true;
217
218 return false;
219}
220
221//==============================================================================
222 String AudioDeviceManager::initialise (const int numInputChannelsNeeded,
223 const int numOutputChannelsNeeded,
224 const XmlElement* const xml,
225 const bool selectDefaultDeviceOnFailure,
226 const String& preferredDefaultDeviceName,
227 const AudioDeviceSetup* preferredSetupOptions)
228{
229 scanDevicesIfNeeded();
230
231 numInputChansNeeded = numInputChannelsNeeded;
232 numOutputChansNeeded = numOutputChannelsNeeded;
233 preferredDeviceName = preferredDefaultDeviceName;
234
235 if (xml != nullptr && xml->hasTagName ("DEVICESETUP"))
236 return initialiseFromXML (*xml, selectDefaultDeviceOnFailure,
237 preferredDeviceName, preferredSetupOptions);
238
239 return initialiseDefault (preferredDeviceName, preferredSetupOptions);
240}
241
242 String AudioDeviceManager::initialiseDefault (const String& preferredDefaultDeviceName,
243 const AudioDeviceSetup* preferredSetupOptions)
244{
245 AudioDeviceSetup setup;
246
247 if (preferredSetupOptions != nullptr)
248 {
249 setup = *preferredSetupOptions;
250 }
251 else if (preferredDefaultDeviceName.isNotEmpty())
252 {
253 for (auto* type : availableDeviceTypes)
254 {
255 for (auto& out : type->getDeviceNames (false))
256 {
257 if (out.matchesWildcard (preferredDefaultDeviceName, true))
258 {
259 setup.outputDeviceName = out;
260 break;
261 }
262 }
263
264 for (auto& in : type->getDeviceNames (true))
265 {
266 if (in.matchesWildcard (preferredDefaultDeviceName, true))
267 {
268 setup.inputDeviceName = in;
269 break;
270 }
271 }
272 }
273 }
274
275 insertDefaultDeviceNames (setup);
276 return setAudioDeviceSetup (setup, false);
277}
278
279String AudioDeviceManager::initialiseFromXML (const XmlElement& xml,
280 bool selectDefaultDeviceOnFailure,
281 const String& preferredDefaultDeviceName,
282 const AudioDeviceSetup* preferredSetupOptions)
283{
284 lastExplicitSettings.reset (new XmlElement (xml));
285
286 String error;
287 AudioDeviceSetup setup;
288
289 if (preferredSetupOptions != nullptr)
290 setup = *preferredSetupOptions;
291
292 if (xml.getStringAttribute ("audioDeviceName").isNotEmpty())
293 {
294 setup.inputDeviceName = setup.outputDeviceName
295 = xml.getStringAttribute ("audioDeviceName");
296 }
297 else
298 {
299 setup.inputDeviceName = xml.getStringAttribute ("audioInputDeviceName");
300 setup.outputDeviceName = xml.getStringAttribute ("audioOutputDeviceName");
301 }
302
303 currentDeviceType = xml.getStringAttribute ("deviceType");
304
305 if (findType (currentDeviceType) == nullptr)
306 {
307 if (auto* type = findType (setup.inputDeviceName, setup.outputDeviceName))
308 currentDeviceType = type->getTypeName();
309 else if (auto* firstType = availableDeviceTypes.getFirst())
310 currentDeviceType = firstType->getTypeName();
311 }
312
313 setup.bufferSize = xml.getIntAttribute ("audioDeviceBufferSize", setup.bufferSize);
314 setup.sampleRate = xml.getDoubleAttribute ("audioDeviceRate", setup.sampleRate);
315
316 setup.inputChannels .parseString (xml.getStringAttribute ("audioDeviceInChans", "11"), 2);
317 setup.outputChannels.parseString (xml.getStringAttribute ("audioDeviceOutChans", "11"), 2);
318
319 setup.useDefaultInputChannels = ! xml.hasAttribute ("audioDeviceInChans");
320 setup.useDefaultOutputChannels = ! xml.hasAttribute ("audioDeviceOutChans");
321
322 error = setAudioDeviceSetup (setup, true);
323
324 if (error.isNotEmpty() && selectDefaultDeviceOnFailure)
325 error = initialise (numInputChansNeeded, numOutputChansNeeded, nullptr, false, preferredDefaultDeviceName);
326
327 midiDeviceInfosFromXml.clear();
328 enabledMidiInputs.clear();
329
330 forEachXmlChildElementWithTagName (xml, c, "MIDIINPUT")
331 midiDeviceInfosFromXml.add ({ c->getStringAttribute ("name"), c->getStringAttribute ("identifier") });
332
333 auto isIdentifierAvailable = [] (const Array<MidiDeviceInfo>& available, const String& identifier)
334 {
335 for (auto& device : available)
336 if (device.identifier == identifier)
337 return true;
338
339 return false;
340 };
341
342 auto getUpdatedIdentifierForName = [&] (const Array<MidiDeviceInfo>& available, const String& name) -> String
343 {
344 for (auto& device : available)
345 if (device.name == name)
346 return device.identifier;
347
348 return {};
349 };
350
351 auto inputs = MidiInput::getAvailableDevices();
352
353 for (auto& info : midiDeviceInfosFromXml)
354 {
355 if (isIdentifierAvailable (inputs, info.identifier))
356 {
357 setMidiInputDeviceEnabled (info.identifier, true);
358 }
359 else
360 {
361 auto identifier = getUpdatedIdentifierForName (inputs, info.name);
362
363 if (identifier.isNotEmpty())
364 setMidiInputDeviceEnabled (identifier, true);
365 }
366 }
367
368 MidiDeviceInfo defaultOutputDeviceInfo (xml.getStringAttribute ("defaultMidiOutput"),
369 xml.getStringAttribute ("defaultMidiOutputDevice"));
370
371 auto outputs = MidiOutput::getAvailableDevices();
372
373 if (isIdentifierAvailable (outputs, defaultOutputDeviceInfo.identifier))
374 {
375 setDefaultMidiOutputDevice (defaultOutputDeviceInfo.identifier);
376 }
377 else
378 {
379 auto identifier = getUpdatedIdentifierForName (outputs, defaultOutputDeviceInfo.name);
380
381 if (identifier.isNotEmpty())
382 setDefaultMidiOutputDevice (identifier);
383 }
384
385 return error;
386}
387
388 String AudioDeviceManager::initialiseWithDefaultDevices (int numInputChannelsNeeded,
389 int numOutputChannelsNeeded)
390{
391 lastExplicitSettings.reset();
392
393 return initialise (numInputChannelsNeeded, numOutputChannelsNeeded,
394 nullptr, false, {}, nullptr);
395}
396
397 void AudioDeviceManager::insertDefaultDeviceNames (AudioDeviceSetup& setup) const
398{
399 if (auto* type = getCurrentDeviceTypeObject())
400 {
401 if (numOutputChansNeeded > 0 && setup.outputDeviceName.isEmpty())
402 setup.outputDeviceName = type->getDeviceNames (false) [type->getDefaultDeviceIndex (false)];
403
404 if (numInputChansNeeded > 0 && setup.inputDeviceName.isEmpty())
405 setup.inputDeviceName = type->getDeviceNames (true) [type->getDefaultDeviceIndex (true)];
406 }
407}
408
409std::unique_ptr<XmlElement> AudioDeviceManager::createStateXml() const
410{
411 if (lastExplicitSettings != nullptr)
412 return std::make_unique<XmlElement> (*lastExplicitSettings);
413
414 return {};
415}
416
417//==============================================================================
418 void AudioDeviceManager::scanDevicesIfNeeded()
419{
420 if (listNeedsScanning)
421 {
422 listNeedsScanning = false;
423
424 createDeviceTypesIfNeeded();
425
426 for (auto* type : availableDeviceTypes)
427 type->scanForDevices();
428 }
429}
430
431AudioIODeviceType* AudioDeviceManager::findType (const String& typeName)
432{
433 scanDevicesIfNeeded();
434
435 for (auto* type : availableDeviceTypes)
436 if (type->getTypeName() == typeName)
437 return type;
438
439 return {};
440}
441
442AudioIODeviceType* AudioDeviceManager::findType (const String& inputName, const String& outputName)
443{
444 scanDevicesIfNeeded();
445
446 for (auto* type : availableDeviceTypes)
447 if ((inputName.isNotEmpty() && deviceListContains (type, true, inputName))
448 || (outputName.isNotEmpty() && deviceListContains (type, false, outputName)))
449 return type;
450
451 return {};
452}
453
454 AudioDeviceManager::AudioDeviceSetup AudioDeviceManager::getAudioDeviceSetup() const
455{
456 return currentSetup;
457}
458
459 void AudioDeviceManager::getAudioDeviceSetup (AudioDeviceSetup& setup) const
460{
461 setup = currentSetup;
462}
463
464 void AudioDeviceManager::deleteCurrentDevice()
465{
466 currentAudioDevice.reset();
467 currentSetup.inputDeviceName.clear();
468 currentSetup.outputDeviceName.clear();
469}
470
471 void AudioDeviceManager::setCurrentAudioDeviceType (const String& type, bool treatAsChosenDevice)
472{
473 for (int i = 0; i < availableDeviceTypes.size(); ++i)
474 {
475 if (availableDeviceTypes.getUnchecked(i)->getTypeName() == type
476 && currentDeviceType != type)
477 {
478 if (currentAudioDevice != nullptr)
479 {
480 closeAudioDevice();
481 Thread::sleep (1500); // allow a moment for OS devices to sort themselves out, to help
482 // avoid things like DirectSound/ASIO clashes
483 }
484
485 currentDeviceType = type;
486
487 AudioDeviceSetup s (*lastDeviceTypeConfigs.getUnchecked(i));
488 insertDefaultDeviceNames (s);
489
490 setAudioDeviceSetup (s, treatAsChosenDevice);
491
492 sendChangeMessage();
493 break;
494 }
495 }
496}
497
498 AudioIODeviceType* AudioDeviceManager::getCurrentDeviceTypeObject() const
499{
500 for (auto* type : availableDeviceTypes)
501 if (type->getTypeName() == currentDeviceType)
502 return type;
503
504 return availableDeviceTypes.getFirst();
505}
506
507 static void updateSetupChannels (AudioDeviceManager::AudioDeviceSetup& setup, int defaultNumIns, int defaultNumOuts)
508{
509 auto updateChannels = [](const String& deviceName, BigInteger& channels, int defaultNumChannels)
510 {
511 if (deviceName.isEmpty())
512 {
513 channels.clear();
514 }
515 else if (defaultNumChannels != -1)
516 {
517 channels.clear();
518 channels.setRange (0, defaultNumChannels, true);
519 }
520 };
521
522 updateChannels (setup.inputDeviceName, setup.inputChannels, setup.useDefaultInputChannels ? defaultNumIns : -1);
523 updateChannels (setup.outputDeviceName, setup.outputChannels, setup.useDefaultOutputChannels ? defaultNumOuts : -1);
524}
525
526 String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup,
527 bool treatAsChosenDevice)
528{
529 jassert (&newSetup != &currentSetup); // this will have no effect
530
531 if (newSetup != currentSetup)
532 sendChangeMessage();
533 else if (currentAudioDevice != nullptr)
534 return {};
535
536 if (getCurrentDeviceTypeObject() == nullptr
537 || (newSetup.inputDeviceName.isEmpty() && newSetup.outputDeviceName.isEmpty()))
538 {
539 deleteCurrentDevice();
540
541 if (treatAsChosenDevice)
542 updateXml();
543
544 return {};
545 }
546
547 stopDevice();
548
549 String error;
550
551 if (currentSetup.inputDeviceName != newSetup.inputDeviceName
552 || currentSetup.outputDeviceName != newSetup.outputDeviceName
553 || currentAudioDevice == nullptr)
554 {
555 deleteCurrentDevice();
556 scanDevicesIfNeeded();
557
558 auto* type = getCurrentDeviceTypeObject();
559
560 if (newSetup.outputDeviceName.isNotEmpty() && ! deviceListContains (type, false, newSetup.outputDeviceName))
561 return "No such device: " + newSetup.outputDeviceName;
562
563 if (newSetup.inputDeviceName.isNotEmpty() && ! deviceListContains (type, true, newSetup.inputDeviceName))
564 return "No such device: " + newSetup.inputDeviceName;
565
566 currentAudioDevice.reset (type->createDevice (newSetup.outputDeviceName, newSetup.inputDeviceName));
567
568 if (currentAudioDevice == nullptr)
569 error = "Can't open the audio device!\n\n"
570 "This may be because another application is currently using the same device - "
571 "if so, you should close any other applications and try again!";
572 else
573 error = currentAudioDevice->getLastError();
574
575 if (error.isNotEmpty())
576 {
577 deleteCurrentDevice();
578 return error;
579 }
580 }
581
582 currentSetup = newSetup;
583
584 if (! currentSetup.useDefaultInputChannels) numInputChansNeeded = currentSetup.inputChannels.countNumberOfSetBits();
585 if (! currentSetup.useDefaultOutputChannels) numOutputChansNeeded = currentSetup.outputChannels.countNumberOfSetBits();
586
587 updateSetupChannels (currentSetup, numInputChansNeeded, numOutputChansNeeded);
588
589 if (currentSetup.inputChannels.isZero() && currentSetup.outputChannels.isZero())
590 {
591 if (treatAsChosenDevice)
592 updateXml();
593
594 return {};
595 }
596
597 currentSetup.sampleRate = chooseBestSampleRate (currentSetup.sampleRate);
598 currentSetup.bufferSize = chooseBestBufferSize (currentSetup.bufferSize);
599
600 error = currentAudioDevice->open (currentSetup.inputChannels,
601 currentSetup.outputChannels,
602 currentSetup.sampleRate,
603 currentSetup.bufferSize);
604
605 if (error.isEmpty())
606 {
607 currentDeviceType = currentAudioDevice->getTypeName();
608
609 currentAudioDevice->start (callbackHandler.get());
610
611 currentSetup.sampleRate = currentAudioDevice->getCurrentSampleRate();
612 currentSetup.bufferSize = currentAudioDevice->getCurrentBufferSizeSamples();
613 currentSetup.inputChannels = currentAudioDevice->getActiveInputChannels();
614 currentSetup.outputChannels = currentAudioDevice->getActiveOutputChannels();
615
616 for (int i = 0; i < availableDeviceTypes.size(); ++i)
617 if (availableDeviceTypes.getUnchecked (i)->getTypeName() == currentDeviceType)
618 *(lastDeviceTypeConfigs.getUnchecked (i)) = currentSetup;
619
620 if (treatAsChosenDevice)
621 updateXml();
622 }
623 else
624 {
625 deleteCurrentDevice();
626 }
627
628 return error;
629}
630
631 double AudioDeviceManager::chooseBestSampleRate (double rate) const
632{
633 jassert (currentAudioDevice != nullptr);
634
635 auto rates = currentAudioDevice->getAvailableSampleRates();
636
637 if (rate > 0 && rates.contains (rate))
638 return rate;
639
640 rate = currentAudioDevice->getCurrentSampleRate();
641
642 if (rate > 0 && rates.contains (rate))
643 return rate;
644
645 double lowestAbove44 = 0.0;
646
647 for (int i = rates.size(); --i >= 0;)
648 {
649 auto sr = rates[i];
650
651 if (sr >= 44100.0 && (lowestAbove44 < 1.0 || sr < lowestAbove44))
652 lowestAbove44 = sr;
653 }
654
655 if (lowestAbove44 > 0.0)
656 return lowestAbove44;
657
658 return rates[0];
659}
660
661 int AudioDeviceManager::chooseBestBufferSize (int bufferSize) const
662{
663 jassert (currentAudioDevice != nullptr);
664
665 if (bufferSize > 0 && currentAudioDevice->getAvailableBufferSizes().contains (bufferSize))
666 return bufferSize;
667
668 return currentAudioDevice->getDefaultBufferSize();
669}
670
671 void AudioDeviceManager::stopDevice()
672{
673 if (currentAudioDevice != nullptr)
674 currentAudioDevice->stop();
675
676 testSound.reset();
677}
678
679 void AudioDeviceManager::closeAudioDevice()
680{
681 stopDevice();
682 currentAudioDevice.reset();
683 loadMeasurer.reset();
684}
685
686 void AudioDeviceManager::restartLastAudioDevice()
687{
688 if (currentAudioDevice == nullptr)
689 {
690 if (currentSetup.inputDeviceName.isEmpty()
691 && currentSetup.outputDeviceName.isEmpty())
692 {
693 // This method will only reload the last device that was running
694 // before closeAudioDevice() was called - you need to actually open
695 // one first, with setAudioDevice().
696 jassertfalse;
697 return;
698 }
699
700 AudioDeviceSetup s (currentSetup);
701 setAudioDeviceSetup (s, false);
702 }
703}
704
705 void AudioDeviceManager::updateXml()
706{
707 lastExplicitSettings.reset (new XmlElement ("DEVICESETUP"));
708
709 lastExplicitSettings->setAttribute ("deviceType", currentDeviceType);
710 lastExplicitSettings->setAttribute ("audioOutputDeviceName", currentSetup.outputDeviceName);
711 lastExplicitSettings->setAttribute ("audioInputDeviceName", currentSetup.inputDeviceName);
712
713 if (currentAudioDevice != nullptr)
714 {
715 lastExplicitSettings->setAttribute ("audioDeviceRate", currentAudioDevice->getCurrentSampleRate());
716
717 if (currentAudioDevice->getDefaultBufferSize() != currentAudioDevice->getCurrentBufferSizeSamples())
718 lastExplicitSettings->setAttribute ("audioDeviceBufferSize", currentAudioDevice->getCurrentBufferSizeSamples());
719
720 if (! currentSetup.useDefaultInputChannels)
721 lastExplicitSettings->setAttribute ("audioDeviceInChans", currentSetup.inputChannels.toString (2));
722
723 if (! currentSetup.useDefaultOutputChannels)
724 lastExplicitSettings->setAttribute ("audioDeviceOutChans", currentSetup.outputChannels.toString (2));
725 }
726
727 for (auto& input : enabledMidiInputs)
728 {
729 auto* child = lastExplicitSettings->createNewChildElement ("MIDIINPUT");
730
731 child->setAttribute ("name", input->getName());
732 child->setAttribute ("identifier", input->getIdentifier());
733 }
734
735 if (midiDeviceInfosFromXml.size() > 0)
736 {
737 // Add any midi devices that have been enabled before, but which aren't currently
738 // open because the device has been disconnected.
739 auto availableMidiDevices = MidiInput::getAvailableDevices();
740
741 for (auto& d : midiDeviceInfosFromXml)
742 {
743 if (! availableMidiDevices.contains (d))
744 {
745 auto* child = lastExplicitSettings->createNewChildElement ("MIDIINPUT");
746
747 child->setAttribute ("name", d.name);
748 child->setAttribute ("identifier", d.identifier);
749 }
750 }
751 }
752
753 if (defaultMidiOutputDeviceInfo != MidiDeviceInfo())
754 {
755 lastExplicitSettings->setAttribute ("defaultMidiOutput", defaultMidiOutputDeviceInfo.name);
756 lastExplicitSettings->setAttribute ("defaultMidiOutputDevice", defaultMidiOutputDeviceInfo.identifier);
757 }
758}
759
760//==============================================================================
761 void AudioDeviceManager::addAudioCallback (AudioIODeviceCallback* newCallback)
762{
763 {
764 const ScopedLock sl (audioCallbackLock);
765
766 if (callbacks.contains (newCallback))
767 return;
768 }
769
770 if (currentAudioDevice != nullptr && newCallback != nullptr)
771 newCallback->audioDeviceAboutToStart (currentAudioDevice.get());
772
773 const ScopedLock sl (audioCallbackLock);
774 callbacks.add (newCallback);
775}
776
777 void AudioDeviceManager::removeAudioCallback (AudioIODeviceCallback* callbackToRemove)
778{
779 if (callbackToRemove != nullptr)
780 {
781 bool needsDeinitialising = currentAudioDevice != nullptr;
782
783 {
784 const ScopedLock sl (audioCallbackLock);
785
786 needsDeinitialising = needsDeinitialising && callbacks.contains (callbackToRemove);
787 callbacks.removeFirstMatchingValue (callbackToRemove);
788 }
789
790 if (needsDeinitialising)
791 callbackToRemove->audioDeviceStopped();
792 }
793}
794
795 void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelData,
796 int numInputChannels,
797 float** outputChannelData,
798 int numOutputChannels,
799 int numSamples)
800{
801 const ScopedLock sl (audioCallbackLock);
802
803 inputLevelGetter->updateLevel (inputChannelData, numInputChannels, numSamples);
804 outputLevelGetter->updateLevel (const_cast<const float**> (outputChannelData), numOutputChannels, numSamples);
805
806 if (callbacks.size() > 0)
807 {
808 AudioProcessLoadMeasurer::ScopedTimer timer (loadMeasurer);
809
810 tempBuffer.setSize (jmax (1, numOutputChannels), jmax (1, numSamples), false, false, true);
811
812 callbacks.getUnchecked(0)->audioDeviceIOCallback (inputChannelData, numInputChannels,
813 outputChannelData, numOutputChannels, numSamples);
814
815 auto** tempChans = tempBuffer.getArrayOfWritePointers();
816
817 for (int i = callbacks.size(); --i > 0;)
818 {
819 callbacks.getUnchecked(i)->audioDeviceIOCallback (inputChannelData, numInputChannels,
820 tempChans, numOutputChannels, numSamples);
821
822 for (int chan = 0; chan < numOutputChannels; ++chan)
823 {
824 if (auto* src = tempChans [chan])
825 if (auto* dst = outputChannelData [chan])
826 for (int j = 0; j < numSamples; ++j)
827 dst[j] += src[j];
828 }
829 }
830 }
831 else
832 {
833 for (int i = 0; i < numOutputChannels; ++i)
834 zeromem (outputChannelData[i], (size_t) numSamples * sizeof (float));
835 }
836
837 if (testSound != nullptr)
838 {
839 auto numSamps = jmin (numSamples, testSound->getNumSamples() - testSoundPosition);
840 auto* src = testSound->getReadPointer (0, testSoundPosition);
841
842 for (int i = 0; i < numOutputChannels; ++i)
843 for (int j = 0; j < numSamps; ++j)
844 outputChannelData [i][j] += src[j];
845
846 testSoundPosition += numSamps;
847
848 if (testSoundPosition >= testSound->getNumSamples())
849 testSound.reset();
850 }
851}
852
853 void AudioDeviceManager::audioDeviceAboutToStartInt (AudioIODevice* const device)
854{
855 loadMeasurer.reset (device->getCurrentSampleRate(),
856 device->getCurrentBufferSizeSamples());
857
858 {
859 const ScopedLock sl (audioCallbackLock);
860
861 for (int i = callbacks.size(); --i >= 0;)
862 callbacks.getUnchecked(i)->audioDeviceAboutToStart (device);
863 }
864
865 sendChangeMessage();
866}
867
868 void AudioDeviceManager::audioDeviceStoppedInt()
869{
870 sendChangeMessage();
871
872 const ScopedLock sl (audioCallbackLock);
873
874 loadMeasurer.reset();
875
876 for (int i = callbacks.size(); --i >= 0;)
877 callbacks.getUnchecked(i)->audioDeviceStopped();
878}
879
880 void AudioDeviceManager::audioDeviceErrorInt (const String& message)
881{
882 const ScopedLock sl (audioCallbackLock);
883
884 for (int i = callbacks.size(); --i >= 0;)
885 callbacks.getUnchecked(i)->audioDeviceError (message);
886}
887
888 double AudioDeviceManager::getCpuUsage() const
889{
890 return loadMeasurer.getLoadAsProportion();
891}
892
893//==============================================================================
894 void AudioDeviceManager::setMidiInputDeviceEnabled (const String& identifier, bool enabled)
895{
896 if (enabled != isMidiInputDeviceEnabled (identifier))
897 {
898 if (enabled)
899 {
900 if (auto midiIn = MidiInput::openDevice (identifier, callbackHandler.get()))
901 {
902 enabledMidiInputs.push_back (std::move (midiIn));
903 enabledMidiInputs.back()->start();
904 }
905 }
906 else
907 {
908 auto removePredicate = [identifier] (const std::unique_ptr<MidiInput>& in) { return in->getIdentifier() == identifier; };
909 enabledMidiInputs.erase (std::remove_if (std::begin (enabledMidiInputs), std::end (enabledMidiInputs), removePredicate),
910 std::end (enabledMidiInputs));
911 }
912
913 updateXml();
914 sendChangeMessage();
915 }
916}
917
918 bool AudioDeviceManager::isMidiInputDeviceEnabled (const String& identifier) const
919{
920 for (auto& mi : enabledMidiInputs)
921 if (mi->getIdentifier() == identifier)
922 return true;
923
924 return false;
925}
926
927 void AudioDeviceManager::addMidiInputDeviceCallback (const String& identifier, MidiInputCallback* callbackToAdd)
928{
929 removeMidiInputDeviceCallback (identifier, callbackToAdd);
930
931 if (identifier.isEmpty() || isMidiInputDeviceEnabled (identifier))
932 {
933 const ScopedLock sl (midiCallbackLock);
934 midiCallbacks.add ({ identifier, callbackToAdd });
935 }
936}
937
938 void AudioDeviceManager::removeMidiInputDeviceCallback (const String& identifier, MidiInputCallback* callbackToRemove)
939{
940 for (int i = midiCallbacks.size(); --i >= 0;)
941 {
942 auto& mc = midiCallbacks.getReference (i);
943
944 if (mc.callback == callbackToRemove && mc.deviceIdentifier == identifier)
945 {
946 const ScopedLock sl (midiCallbackLock);
947 midiCallbacks.remove (i);
948 }
949 }
950}
951
952 void AudioDeviceManager::handleIncomingMidiMessageInt (MidiInput* source, const MidiMessage& message)
953{
954 if (! message.isActiveSense())
955 {
956 const ScopedLock sl (midiCallbackLock);
957
958 for (auto& mc : midiCallbacks)
959 if (mc.deviceIdentifier.isEmpty() || mc.deviceIdentifier == source->getIdentifier())
960 mc.callback->handleIncomingMidiMessage (source, message);
961 }
962}
963
964//==============================================================================
965 void AudioDeviceManager::setDefaultMidiOutputDevice (const String& identifier)
966{
967 if (defaultMidiOutputDeviceInfo.identifier != identifier)
968 {
969 Array<AudioIODeviceCallback*> oldCallbacks;
970
971 {
972 const ScopedLock sl (audioCallbackLock);
973 oldCallbacks.swapWith (callbacks);
974 }
975
976 if (currentAudioDevice != nullptr)
977 for (int i = oldCallbacks.size(); --i >= 0;)
978 oldCallbacks.getUnchecked (i)->audioDeviceStopped();
979
980 defaultMidiOutput.reset();
981
982 if (identifier.isNotEmpty())
983 defaultMidiOutput = MidiOutput::openDevice (identifier);
984
985 if (defaultMidiOutput != nullptr)
986 defaultMidiOutputDeviceInfo = defaultMidiOutput->getDeviceInfo();
987 else
988 defaultMidiOutputDeviceInfo = {};
989
990 if (currentAudioDevice != nullptr)
991 for (auto* c : oldCallbacks)
992 c->audioDeviceAboutToStart (currentAudioDevice.get());
993
994 {
995 const ScopedLock sl (audioCallbackLock);
996 oldCallbacks.swapWith (callbacks);
997 }
998
999 updateXml();
1000 sendChangeMessage();
1001 }
1002}
1003
1004//==============================================================================
1005AudioDeviceManager::LevelMeter::LevelMeter() noexcept : level() {}
1006
1007 void AudioDeviceManager::LevelMeter::updateLevel (const float* const* channelData, int numChannels, int numSamples) noexcept
1008{
1009 if (getReferenceCount() <= 1)
1010 return;
1011
1012 auto localLevel = level.get();
1013
1014 if (numChannels > 0)
1015 {
1016 for (int j = 0; j < numSamples; ++j)
1017 {
1018 float s = 0;
1019
1020 for (int i = 0; i < numChannels; ++i)
1021 s += std::abs (channelData[i][j]);
1022
1023 s /= (float) numChannels;
1024
1025 const float decayFactor = 0.99992f;
1026
1027 if (s > localLevel)
1028 localLevel = s;
1029 else if (localLevel > 0.001f)
1030 localLevel *= decayFactor;
1031 else
1032 localLevel = 0;
1033 }
1034 }
1035 else
1036 {
1037 localLevel = 0;
1038 }
1039
1040 level = localLevel;
1041}
1042
1043 double AudioDeviceManager::LevelMeter::getCurrentLevel() const noexcept
1044{
1045 jassert (getReferenceCount() > 1);
1046 return level.get();
1047}
1048
1049 void AudioDeviceManager::playTestSound()
1050{
1051 { // cunningly nested to swap, unlock and delete in that order.
1052 std::unique_ptr<AudioBuffer<float>> oldSound;
1053
1054 {
1055 const ScopedLock sl (audioCallbackLock);
1056 std::swap (oldSound, testSound);
1057 }
1058 }
1059
1060 testSoundPosition = 0;
1061
1062 if (currentAudioDevice != nullptr)
1063 {
1064 auto sampleRate = currentAudioDevice->getCurrentSampleRate();
1065 auto soundLength = (int) sampleRate;
1066
1067 double frequency = 440.0;
1068 float amplitude = 0.5f;
1069
1070 auto phasePerSample = MathConstants<double>::twoPi / (sampleRate / frequency);
1071
1072 std::unique_ptr<AudioBuffer<float>> newSound (new AudioBuffer<float> (1, soundLength));
1073
1074 for (int i = 0; i < soundLength; ++i)
1075 newSound->setSample (0, i, amplitude * (float) std::sin (i * phasePerSample));
1076
1077 newSound->applyGainRamp (0, 0, soundLength / 10, 0.0f, 1.0f);
1078 newSound->applyGainRamp (0, soundLength - soundLength / 4, soundLength / 4, 1.0f, 0.0f);
1079
1080 {
1081 const ScopedLock sl (audioCallbackLock);
1082 std::swap (testSound, newSound);
1083 }
1084 }
1085}
1086
1087 int AudioDeviceManager::getXRunCount() const noexcept
1088{
1089 auto deviceXRuns = (currentAudioDevice != nullptr ? currentAudioDevice->getXRunCount() : -1);
1090 return jmax (0, deviceXRuns) + loadMeasurer.getXRunCount();
1091}
1092
1093//==============================================================================
1094// Deprecated
1095 void AudioDeviceManager::setMidiInputEnabled (const String& name, const bool enabled)
1096{
1097 for (auto& device : MidiInput::getAvailableDevices())
1098 {
1099 if (device.name == name)
1100 {
1101 setMidiInputDeviceEnabled (device.identifier, enabled);
1102 return;
1103 }
1104 }
1105}
1106
1107 bool AudioDeviceManager::isMidiInputEnabled (const String& name) const
1108{
1109 for (auto& device : MidiInput::getAvailableDevices())
1110 if (device.name == name)
1111 return isMidiInputDeviceEnabled (device.identifier);
1112
1113 return false;
1114}
1115
1116 void AudioDeviceManager::addMidiInputCallback (const String& name, MidiInputCallback* callbackToAdd)
1117{
1118 if (name.isEmpty())
1119 {
1120 addMidiInputDeviceCallback ({}, callbackToAdd);
1121 }
1122 else
1123 {
1124 for (auto& device : MidiInput::getAvailableDevices())
1125 {
1126 if (device.name == name)
1127 {
1128 addMidiInputDeviceCallback (device.identifier, callbackToAdd);
1129 return;
1130 }
1131 }
1132 }
1133}
1134
1135 void AudioDeviceManager::removeMidiInputCallback (const String& name, MidiInputCallback* callbackToRemove)
1136{
1137 for (auto& device : MidiInput::getAvailableDevices())
1138 {
1139 if (device.name == name)
1140 {
1141 removeMidiInputDeviceCallback (device.identifier, callbackToRemove);
1142 return;
1143 }
1144 }
1145}
1146
1147 void AudioDeviceManager::setDefaultMidiOutput (const String& name)
1148{
1149 for (auto& device : MidiOutput::getAvailableDevices())
1150 {
1151 if (device.name == name)
1152 {
1153 setDefaultMidiOutputDevice (device.identifier);
1154 return;
1155 }
1156 }
1157}
1158
1159} // namespace juce
juce::Array
Definition: juce_Array.h:56
juce::Array::swapWith
void swapWith(OtherArrayType &otherArray) noexcept
Definition: juce_Array.h:621
juce::Array::getUnchecked
ElementType getUnchecked(int index) const
Definition: juce_Array.h:252
juce::Array::size
int size() const noexcept
Definition: juce_Array.h:215
juce::Array::remove
void remove(int indexToRemove)
Definition: juce_Array.h:767
juce::Array::add
void add(const ElementType &newElement)
Definition: juce_Array.h:418
juce::Array::getReference
ElementType & getReference(int index) noexcept
Definition: juce_Array.h:267
juce::AudioBuffer
Definition: juce_AudioSampleBuffer.h:34
juce::AudioBuffer::setSize
void setSize(int newNumChannels, int newNumSamples, bool keepExistingContent=false, bool clearExtraSpace=false, bool avoidReallocating=false)
Definition: juce_AudioSampleBuffer.h:331
juce::AudioBuffer::getArrayOfWritePointers
Type ** getArrayOfWritePointers() noexcept
Definition: juce_AudioSampleBuffer.h:306
juce::AudioDeviceManager::isMidiInputDeviceEnabled
bool isMidiInputDeviceEnabled(const String &deviceIdentifier) const
Definition: juce_AudioDeviceManager.cpp:918
juce::AudioDeviceManager::AudioDeviceManager
AudioDeviceManager()
Definition: juce_AudioDeviceManager.cpp:88
juce::AudioDeviceManager::removeAudioDeviceType
void removeAudioDeviceType(AudioIODeviceType *deviceTypeToRemove)
Definition: juce_AudioDeviceManager.cpp:196
juce::AudioDeviceManager::getAudioDeviceSetup
AudioDeviceSetup getAudioDeviceSetup() const
Definition: juce_AudioDeviceManager.cpp:454
juce::AudioDeviceManager::removeMidiInputDeviceCallback
void removeMidiInputDeviceCallback(const String &deviceIdentifier, MidiInputCallback *callback)
Definition: juce_AudioDeviceManager.cpp:938
juce::AudioDeviceManager::getCpuUsage
double getCpuUsage() const
Definition: juce_AudioDeviceManager.cpp:888
juce::AudioDeviceManager::getCurrentDeviceTypeObject
AudioIODeviceType * getCurrentDeviceTypeObject() const
Definition: juce_AudioDeviceManager.cpp:498
juce::AudioDeviceManager::setAudioDeviceSetup
String setAudioDeviceSetup(const AudioDeviceSetup &newSetup, bool treatAsChosenDevice)
Definition: juce_AudioDeviceManager.cpp:526
juce::AudioDeviceManager::removeMidiInputCallback
void removeMidiInputCallback(const String &, MidiInputCallback *)
Definition: juce_AudioDeviceManager.cpp:1135
juce::AudioDeviceManager::isMidiInputEnabled
bool isMidiInputEnabled(const String &) const
Definition: juce_AudioDeviceManager.cpp:1107
juce::AudioDeviceManager::createAudioDeviceTypes
virtual void createAudioDeviceTypes(OwnedArray< AudioIODeviceType > &types)
Definition: juce_AudioDeviceManager.cpp:167
juce::AudioDeviceManager::setMidiInputEnabled
void setMidiInputEnabled(const String &, bool)
Definition: juce_AudioDeviceManager.cpp:1095
juce::AudioDeviceManager::setDefaultMidiOutputDevice
void setDefaultMidiOutputDevice(const String &deviceIdentifier)
Definition: juce_AudioDeviceManager.cpp:965
juce::AudioDeviceManager::setMidiInputDeviceEnabled
void setMidiInputDeviceEnabled(const String &deviceIdentifier, bool enabled)
Definition: juce_AudioDeviceManager.cpp:894
juce::AudioDeviceManager::setDefaultMidiOutput
void setDefaultMidiOutput(const String &)
Definition: juce_AudioDeviceManager.cpp:1147
juce::AudioDeviceManager::getXRunCount
int getXRunCount() const noexcept
Definition: juce_AudioDeviceManager.cpp:1087
juce::AudioDeviceManager::addMidiInputCallback
void addMidiInputCallback(const String &, MidiInputCallback *)
Definition: juce_AudioDeviceManager.cpp:1116
juce::AudioDeviceManager::addMidiInputDeviceCallback
void addMidiInputDeviceCallback(const String &deviceIdentifier, MidiInputCallback *callback)
Definition: juce_AudioDeviceManager.cpp:927
juce::AudioDeviceManager::setCurrentAudioDeviceType
void setCurrentAudioDeviceType(const String &type, bool treatAsChosenDevice)
Definition: juce_AudioDeviceManager.cpp:471
juce::AudioDeviceManager::~AudioDeviceManager
~AudioDeviceManager() override
Definition: juce_AudioDeviceManager.cpp:93
juce::AudioDeviceManager::getAvailableDeviceTypes
const OwnedArray< AudioIODeviceType > & getAvailableDeviceTypes()
Definition: juce_AudioDeviceManager.cpp:117
juce::AudioDeviceManager::initialise
String initialise(int numInputChannelsNeeded, int numOutputChannelsNeeded, const XmlElement *savedState, bool selectDefaultDeviceOnFailure, const String &preferredDefaultDeviceName=String(), const AudioDeviceSetup *preferredSetupOptions=nullptr)
Definition: juce_AudioDeviceManager.cpp:222
juce::AudioDeviceManager::addAudioCallback
void addAudioCallback(AudioIODeviceCallback *newCallback)
Definition: juce_AudioDeviceManager.cpp:761
juce::AudioDeviceManager::initialiseWithDefaultDevices
String initialiseWithDefaultDevices(int numInputChannelsNeeded, int numOutputChannelsNeeded)
Definition: juce_AudioDeviceManager.cpp:388
juce::AudioDeviceManager::restartLastAudioDevice
void restartLastAudioDevice()
Definition: juce_AudioDeviceManager.cpp:686
juce::AudioDeviceManager::removeAudioCallback
void removeAudioCallback(AudioIODeviceCallback *callback)
Definition: juce_AudioDeviceManager.cpp:777
juce::AudioDeviceManager::playTestSound
void playTestSound()
Definition: juce_AudioDeviceManager.cpp:1049
juce::AudioDeviceManager::addAudioDeviceType
void addAudioDeviceType(std::unique_ptr< AudioIODeviceType > newDeviceType)
Definition: juce_AudioDeviceManager.cpp:183
juce::AudioDeviceManager::closeAudioDevice
void closeAudioDevice()
Definition: juce_AudioDeviceManager.cpp:679
juce::AudioDeviceManager::createStateXml
std::unique_ptr< XmlElement > createStateXml() const
Definition: juce_AudioDeviceManager.cpp:409
juce::AudioIODeviceCallback
Definition: juce_AudioIODevice.h:43
juce::AudioIODeviceCallback::audioDeviceAboutToStart
virtual void audioDeviceAboutToStart(AudioIODevice *device)=0
juce::AudioIODeviceCallback::audioDeviceStopped
virtual void audioDeviceStopped()=0
juce::AudioIODeviceType
Definition: juce_AudioIODeviceType.h:62
juce::AudioIODeviceType::getDefaultDeviceIndex
virtual int getDefaultDeviceIndex(bool forInput) const =0
juce::AudioIODeviceType::createAudioIODeviceType_ASIO
static AudioIODeviceType * createAudioIODeviceType_ASIO()
Definition: juce_AudioIODeviceType.cpp:62
juce::AudioIODeviceType::createAudioIODeviceType_Oboe
static AudioIODeviceType * createAudioIODeviceType_Oboe()
Definition: juce_AudioIODeviceType.cpp:86
juce::AudioIODeviceType::createAudioIODeviceType_JACK
static AudioIODeviceType * createAudioIODeviceType_JACK()
Definition: juce_AudioIODeviceType.cpp:70
juce::AudioIODeviceType::createAudioIODeviceType_DirectSound
static AudioIODeviceType * createAudioIODeviceType_DirectSound()
Definition: juce_AudioIODeviceType.cpp:58
juce::AudioIODeviceType::createAudioIODeviceType_Android
static AudioIODeviceType * createAudioIODeviceType_Android()
Definition: juce_AudioIODeviceType.cpp:78
juce::AudioIODeviceType::createAudioIODeviceType_OpenSLES
static AudioIODeviceType * createAudioIODeviceType_OpenSLES()
Definition: juce_AudioIODeviceType.cpp:82
juce::AudioIODeviceType::createAudioIODeviceType_WASAPI
static AudioIODeviceType * createAudioIODeviceType_WASAPI(bool exclusiveMode)
Definition: juce_AudioIODeviceType.cpp:54
juce::AudioIODeviceType::createAudioIODeviceType_CoreAudio
static AudioIODeviceType * createAudioIODeviceType_CoreAudio()
Definition: juce_AudioIODeviceType.cpp:46
juce::AudioIODeviceType::getDeviceNames
virtual StringArray getDeviceNames(bool wantInputNames=false) const =0
juce::AudioIODeviceType::scanForDevices
virtual void scanForDevices()=0
juce::AudioIODeviceType::getTypeName
const String & getTypeName() const noexcept
Definition: juce_AudioIODeviceType.h:69
juce::AudioIODeviceType::createAudioIODeviceType_Bela
static AudioIODeviceType * createAudioIODeviceType_Bela()
Definition: juce_AudioIODeviceType.cpp:74
juce::AudioIODeviceType::createAudioIODeviceType_ALSA
static AudioIODeviceType * createAudioIODeviceType_ALSA()
Definition: juce_AudioIODeviceType.cpp:66
juce::AudioIODeviceType::createDevice
virtual AudioIODevice * createDevice(const String &outputDeviceName, const String &inputDeviceName)=0
juce::AudioIODeviceType::createAudioIODeviceType_iOSAudio
static AudioIODeviceType * createAudioIODeviceType_iOSAudio()
Definition: juce_AudioIODeviceType.cpp:50
juce::AudioProcessLoadMeasurer::getXRunCount
int getXRunCount() const
Definition: juce_AudioProcessLoadMeasurer.cpp:67
juce::AudioProcessLoadMeasurer::reset
void reset()
Definition: juce_AudioProcessLoadMeasurer.cpp:33
juce::AudioProcessLoadMeasurer::getLoadAsProportion
double getLoadAsProportion() const
Definition: juce_AudioProcessLoadMeasurer.cpp:64
juce::BigInteger
Definition: juce_BigInteger.h:39
juce::BigInteger::toString
String toString(int base, int minimumNumCharacters=1) const
Definition: juce_BigInteger.cpp:1085
juce::BigInteger::isZero
bool isZero() const noexcept
Definition: juce_BigInteger.cpp:340
juce::BigInteger::countNumberOfSetBits
int countNumberOfSetBits() const noexcept
Definition: juce_BigInteger.cpp:369
juce::ChangeBroadcaster::sendChangeMessage
void sendChangeMessage()
Definition: juce_ChangeBroadcaster.cpp:65
juce::GenericScopedLock
Definition: juce_ScopedLock.h:55
juce::MidiInputCallback
Definition: juce_MidiDevices.h:189
juce::MidiInput
Definition: juce_MidiDevices.h:82
juce::MidiInput::getAvailableDevices
static Array< MidiDeviceInfo > getAvailableDevices()
juce::MidiInput::openDevice
static std::unique_ptr< MidiInput > openDevice(const String &deviceIdentifier, MidiInputCallback *callback)
juce::MidiInput::getIdentifier
String getIdentifier() const noexcept
Definition: juce_MidiDevices.h:151
juce::MidiMessage
Definition: juce_MidiMessage.h:35
juce::MidiMessage::isActiveSense
bool isActiveSense() const noexcept
Definition: juce_MidiMessage.cpp:680
juce::MidiOutput::openDevice
static std::unique_ptr< MidiOutput > openDevice(const String &deviceIdentifier)
juce::MidiOutput::getAvailableDevices
static Array< MidiDeviceInfo > getAvailableDevices()
juce::OwnedArray
Definition: juce_OwnedArray.h:51
juce::String
Definition: juce_String.h:39
juce::String::trim
String trim() const
Definition: juce_String.cpp:1667
juce::String::isEmpty
bool isEmpty() const noexcept
Definition: juce_String.h:296
juce::String::clear
void clear() noexcept
Definition: juce_String.cpp:265
juce::String::isNotEmpty
bool isNotEmpty() const noexcept
Definition: juce_String.h:302
juce::Thread::sleep
static void JUCE_CALLTYPE sleep(int milliseconds)
juce::XmlElement
Definition: juce_XmlElement.h:138
juce::XmlElement::hasTagName
bool hasTagName(StringRef possibleTagName) const noexcept
Definition: juce_XmlElement.cpp:470
juce::AudioDeviceManager::AudioDeviceSetup
Definition: juce_AudioDeviceManager.h:91
juce::AudioDeviceManager::AudioDeviceSetup::outputDeviceName
String outputDeviceName
Definition: juce_AudioDeviceManager.h:98
juce::AudioDeviceManager::AudioDeviceSetup::useDefaultInputChannels
bool useDefaultInputChannels
Definition: juce_AudioDeviceManager.h:130
juce::AudioDeviceManager::AudioDeviceSetup::inputDeviceName
String inputDeviceName
Definition: juce_AudioDeviceManager.h:104
juce::AudioDeviceManager::AudioDeviceSetup::outputChannels
BigInteger outputChannels
Definition: juce_AudioDeviceManager.h:137
juce::AudioDeviceManager::AudioDeviceSetup::sampleRate
double sampleRate
Definition: juce_AudioDeviceManager.h:111
juce::AudioDeviceManager::AudioDeviceSetup::inputChannels
BigInteger inputChannels
Definition: juce_AudioDeviceManager.h:124
juce::AudioDeviceManager::AudioDeviceSetup::bufferSize
int bufferSize
Definition: juce_AudioDeviceManager.h:117
juce::AudioDeviceManager::AudioDeviceSetup::useDefaultOutputChannels
bool useDefaultOutputChannels
Definition: juce_AudioDeviceManager.h:143
juce::AudioProcessLoadMeasurer::ScopedTimer
Definition: juce_AudioProcessLoadMeasurer.h:77
juce::MathConstants
Definition: juce_MathsFunctions.h:363
juce::MidiDeviceInfo::name
String name
Definition: juce_MidiDevices.h:54
juce::MidiDeviceInfo::identifier
String identifier
Definition: juce_MidiDevices.h:61