diff --git a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp index aeff3c6146..1be78fed7e 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp +++ b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp @@ -114,7 +114,7 @@ void AudioDeviceManager::createDeviceTypesIfNeeded() { if (availableDeviceTypes.size() == 0) { - OwnedArray types; + OwnedArray types; createAudioDeviceTypes (types); for (int i = 0; i < types.size(); ++i) @@ -127,7 +127,7 @@ void AudioDeviceManager::createDeviceTypesIfNeeded() } } -const OwnedArray & AudioDeviceManager::getAvailableDeviceTypes() +const OwnedArray& AudioDeviceManager::getAvailableDeviceTypes() { scanDevicesIfNeeded(); return availableDeviceTypes; @@ -147,13 +147,13 @@ void AudioDeviceManager::audioDeviceListChanged() } //============================================================================== -static void addIfNotNull (OwnedArray & list, AudioIODeviceType* const device) +static void addIfNotNull (OwnedArray& list, AudioIODeviceType* const device) { if (device != nullptr) list.add (device); } -void AudioDeviceManager::createAudioDeviceTypes (OwnedArray & list) +void AudioDeviceManager::createAudioDeviceTypes (OwnedArray& list) { addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI()); addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_DirectSound()); @@ -181,7 +181,7 @@ void AudioDeviceManager::addAudioDeviceType (AudioIODeviceType* newDeviceType) //============================================================================== String AudioDeviceManager::initialise (const int numInputChannelsNeeded, const int numOutputChannelsNeeded, - const XmlElement* const e, + const XmlElement* const xml, const bool selectDefaultDeviceOnFailure, const String& preferredDefaultDeviceName, const AudioDeviceSetup* preferredSetupOptions) @@ -191,106 +191,127 @@ String AudioDeviceManager::initialise (const int numInputChannelsNeeded, numInputChansNeeded = numInputChannelsNeeded; numOutputChansNeeded = numOutputChannelsNeeded; - if (e != nullptr && e->hasTagName ("DEVICESETUP")) + if (xml != nullptr && xml->hasTagName ("DEVICESETUP")) + return initialiseFromXML (*xml, selectDefaultDeviceOnFailure, + preferredDefaultDeviceName, preferredSetupOptions); + + return initialiseDefault (preferredDefaultDeviceName, preferredSetupOptions); +} + +String AudioDeviceManager::initialiseDefault (const String& preferredDefaultDeviceName, + const AudioDeviceSetup* preferredSetupOptions) +{ + AudioDeviceSetup setup; + + if (preferredSetupOptions != nullptr) { - lastExplicitSettings = new XmlElement (*e); - - String error; - AudioDeviceSetup setup; - - if (preferredSetupOptions != nullptr) - setup = *preferredSetupOptions; - - if (e->getStringAttribute ("audioDeviceName").isNotEmpty()) - { - setup.inputDeviceName = setup.outputDeviceName - = e->getStringAttribute ("audioDeviceName"); - } - else - { - setup.inputDeviceName = e->getStringAttribute ("audioInputDeviceName"); - setup.outputDeviceName = e->getStringAttribute ("audioOutputDeviceName"); - } - - currentDeviceType = e->getStringAttribute ("deviceType"); - - if (findType (currentDeviceType) == nullptr) - { - if (AudioIODeviceType* const type = findType (setup.inputDeviceName, setup.outputDeviceName)) - currentDeviceType = type->getTypeName(); - else if (availableDeviceTypes.size() > 0) - currentDeviceType = availableDeviceTypes.getUnchecked(0)->getTypeName(); - } - - setup.bufferSize = e->getIntAttribute ("audioDeviceBufferSize"); - setup.sampleRate = e->getDoubleAttribute ("audioDeviceRate"); - - setup.inputChannels .parseString (e->getStringAttribute ("audioDeviceInChans", "11"), 2); - setup.outputChannels.parseString (e->getStringAttribute ("audioDeviceOutChans", "11"), 2); - - setup.useDefaultInputChannels = ! e->hasAttribute ("audioDeviceInChans"); - setup.useDefaultOutputChannels = ! e->hasAttribute ("audioDeviceOutChans"); - - error = setAudioDeviceSetup (setup, true); - - midiInsFromXml.clear(); - forEachXmlChildElementWithTagName (*e, c, "MIDIINPUT") - midiInsFromXml.add (c->getStringAttribute ("name")); - - const StringArray allMidiIns (MidiInput::getDevices()); - - for (int i = allMidiIns.size(); --i >= 0;) - setMidiInputEnabled (allMidiIns[i], midiInsFromXml.contains (allMidiIns[i])); - - if (error.isNotEmpty() && selectDefaultDeviceOnFailure) - error = initialise (numInputChannelsNeeded, numOutputChannelsNeeded, 0, - false, preferredDefaultDeviceName); - - setDefaultMidiOutput (e->getStringAttribute ("defaultMidiOutput")); - - return error; + setup = *preferredSetupOptions; } - else + else if (preferredDefaultDeviceName.isNotEmpty()) { - AudioDeviceSetup setup; + for (int j = availableDeviceTypes.size(); --j >= 0;) + { + AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(j); - if (preferredSetupOptions != nullptr) - { - setup = *preferredSetupOptions; - } - else if (preferredDefaultDeviceName.isNotEmpty()) - { - for (int j = availableDeviceTypes.size(); --j >= 0;) + const StringArray outs (type->getDeviceNames (false)); + + for (int i = 0; i < outs.size(); ++i) { - AudioIODeviceType* const type = availableDeviceTypes.getUnchecked(j); - - const StringArray outs (type->getDeviceNames (false)); - - for (int i = 0; i < outs.size(); ++i) + if (outs[i].matchesWildcard (preferredDefaultDeviceName, true)) { - if (outs[i].matchesWildcard (preferredDefaultDeviceName, true)) - { - setup.outputDeviceName = outs[i]; - break; - } + setup.outputDeviceName = outs[i]; + break; } + } - const StringArray ins (type->getDeviceNames (true)); + const StringArray ins (type->getDeviceNames (true)); - for (int i = 0; i < ins.size(); ++i) + for (int i = 0; i < ins.size(); ++i) + { + if (ins[i].matchesWildcard (preferredDefaultDeviceName, true)) { - if (ins[i].matchesWildcard (preferredDefaultDeviceName, true)) - { - setup.inputDeviceName = ins[i]; - break; - } + setup.inputDeviceName = ins[i]; + break; } } } - - insertDefaultDeviceNames (setup); - return setAudioDeviceSetup (setup, false); } + + insertDefaultDeviceNames (setup); + return setAudioDeviceSetup (setup, false); +} + +String AudioDeviceManager::initialiseFromXML (const XmlElement& xml, + const bool selectDefaultDeviceOnFailure, + const String& preferredDefaultDeviceName, + const AudioDeviceSetup* preferredSetupOptions) +{ + lastExplicitSettings = new XmlElement (xml); + + String error; + AudioDeviceSetup setup; + + if (preferredSetupOptions != nullptr) + setup = *preferredSetupOptions; + + if (xml.getStringAttribute ("audioDeviceName").isNotEmpty()) + { + setup.inputDeviceName = setup.outputDeviceName + = xml.getStringAttribute ("audioDeviceName"); + } + else + { + setup.inputDeviceName = xml.getStringAttribute ("audioInputDeviceName"); + setup.outputDeviceName = xml.getStringAttribute ("audioOutputDeviceName"); + } + + currentDeviceType = xml.getStringAttribute ("deviceType"); + + if (findType (currentDeviceType) == nullptr) + { + if (AudioIODeviceType* const type = findType (setup.inputDeviceName, setup.outputDeviceName)) + currentDeviceType = type->getTypeName(); + else if (availableDeviceTypes.size() > 0) + currentDeviceType = availableDeviceTypes.getUnchecked(0)->getTypeName(); + } + + setup.bufferSize = xml.getIntAttribute ("audioDeviceBufferSize"); + setup.sampleRate = xml.getDoubleAttribute ("audioDeviceRate"); + + setup.inputChannels .parseString (xml.getStringAttribute ("audioDeviceInChans", "11"), 2); + setup.outputChannels.parseString (xml.getStringAttribute ("audioDeviceOutChans", "11"), 2); + + setup.useDefaultInputChannels = ! xml.hasAttribute ("audioDeviceInChans"); + setup.useDefaultOutputChannels = ! xml.hasAttribute ("audioDeviceOutChans"); + + error = setAudioDeviceSetup (setup, true); + + midiInsFromXml.clear(); + + forEachXmlChildElementWithTagName (xml, c, "MIDIINPUT") + midiInsFromXml.add (c->getStringAttribute ("name")); + + const StringArray allMidiIns (MidiInput::getDevices()); + + for (int i = allMidiIns.size(); --i >= 0;) + setMidiInputEnabled (allMidiIns[i], midiInsFromXml.contains (allMidiIns[i])); + + if (error.isNotEmpty() && selectDefaultDeviceOnFailure) + error = initialise (numInputChansNeeded, numOutputChansNeeded, + nullptr, false, preferredDefaultDeviceName); + + setDefaultMidiOutput (xml.getStringAttribute ("defaultMidiOutput")); + + return error; +} + +String AudioDeviceManager::initialiseWithDefaultDevices (int numInputChannelsNeeded, + int numOutputChannelsNeeded) +{ + lastExplicitSettings = nullptr; + + return initialise (numInputChannelsNeeded, numOutputChannelsNeeded, + nullptr, false, String(), nullptr); } void AudioDeviceManager::insertDefaultDeviceNames (AudioDeviceSetup& setup) const @@ -880,7 +901,7 @@ void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName) { if (defaultMidiOutputName != deviceName) { - Array oldCallbacks; + Array oldCallbacks; { const ScopedLock sl (audioCallbackLock); @@ -915,7 +936,7 @@ void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName) void AudioDeviceManager::playTestSound() { { // cunningly nested to swap, unlock and delete in that order. - ScopedPointer oldSound; + ScopedPointer oldSound; { const ScopedLock sl (audioCallbackLock); diff --git a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h index d82159326f..839edc2837 100644 --- a/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h +++ b/modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h @@ -191,7 +191,11 @@ public: const XmlElement* savedState, bool selectDefaultDeviceOnFailure, const String& preferredDefaultDeviceName = String(), - const AudioDeviceSetup* preferredSetupOptions = 0); + const AudioDeviceSetup* preferredSetupOptions = nullptr); + + /** Resets everything to a default device setup, clearing any stored settings. */ + String initialiseWithDefaultDevices (int numInputChannelsNeeded, + int numOutputChannelsNeeded); /** Returns some XML representing the current state of the manager. @@ -383,7 +387,7 @@ public: /** Returns a list of the types of device supported. */ - const OwnedArray & getAvailableDeviceTypes(); + const OwnedArray& getAvailableDeviceTypes(); //============================================================================== /** Creates a list of available types. @@ -394,7 +398,7 @@ public: You can override this if your app needs to do something specific, like avoid using DirectSound devices, etc. */ - virtual void createAudioDeviceTypes (OwnedArray & types); + virtual void createAudioDeviceTypes (OwnedArray& types); /** Adds a new device type to the list of types. The manager will take ownership of the object that is passed-in. @@ -446,30 +450,30 @@ public: private: //============================================================================== - OwnedArray availableDeviceTypes; - OwnedArray lastDeviceTypeConfigs; + OwnedArray availableDeviceTypes; + OwnedArray lastDeviceTypeConfigs; AudioDeviceSetup currentSetup; - ScopedPointer currentAudioDevice; - Array callbacks; + ScopedPointer currentAudioDevice; + Array callbacks; int numInputChansNeeded, numOutputChansNeeded; String currentDeviceType; BigInteger inputChannels, outputChannels; - ScopedPointer lastExplicitSettings; + ScopedPointer lastExplicitSettings; mutable bool listNeedsScanning; bool useInputNames; Atomic inputLevelMeasurementEnabledCount; double inputLevel; - ScopedPointer testSound; + ScopedPointer testSound; int testSoundPosition; AudioSampleBuffer tempBuffer; StringArray midiInsFromXml; - OwnedArray enabledMidiInputs; - Array midiCallbacks; + OwnedArray enabledMidiInputs; + Array midiCallbacks; StringArray midiCallbackDevices; String defaultMidiOutputName; - ScopedPointer defaultMidiOutput; + ScopedPointer defaultMidiOutput; CriticalSection audioCallbackLock, midiCallbackLock; double cpuUsageMs, timeToCpuScale; @@ -500,6 +504,9 @@ private: double chooseBestSampleRate (double preferred) const; int chooseBestBufferSize (int preferred) const; void insertDefaultDeviceNames (AudioDeviceSetup&) const; + String initialiseDefault (const String& preferredDefaultDeviceName, const AudioDeviceSetup*); + String initialiseFromXML (const XmlElement&, bool selectDefaultDeviceOnFailure, + const String& preferredDefaultDeviceName, const AudioDeviceSetup*); AudioIODeviceType* findType (const String& inputName, const String& outputName); AudioIODeviceType* findType (const String& typeName);