Browse Source

Added identifier-based MIDI input/output methods to AudioDeviceManager and deprecated the old name-based methods

tags/2021-05-28
ed 6 years ago
parent
commit
e26529d5e9
7 changed files with 249 additions and 112 deletions
  1. +2
    -2
      examples/Audio/AudioSynthesiserDemo.h
  2. +2
    -2
      examples/Audio/MPEDemo.h
  3. +167
    -53
      modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp
  4. +48
    -31
      modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h
  5. +8
    -6
      modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h
  6. +21
    -18
      modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp
  7. +1
    -0
      modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h

+ 2
- 2
examples/Audio/AudioSynthesiserDemo.h View File

@@ -270,7 +270,7 @@ public:
#endif #endif
audioDeviceManager.addAudioCallback (&audioSourcePlayer); audioDeviceManager.addAudioCallback (&audioSourcePlayer);
audioDeviceManager.addMidiInputCallback ({}, &(synthAudioSource.midiCollector));
audioDeviceManager.addMidiInputDeviceCallback ({}, &(synthAudioSource.midiCollector));
setOpaque (true); setOpaque (true);
setSize (640, 480); setSize (640, 480);
@@ -279,7 +279,7 @@ public:
~AudioSynthesiserDemo() ~AudioSynthesiserDemo()
{ {
audioSourcePlayer.setSource (nullptr); audioSourcePlayer.setSource (nullptr);
audioDeviceManager.removeMidiInputCallback ({}, &(synthAudioSource.midiCollector));
audioDeviceManager.removeMidiInputDeviceCallback ({}, &(synthAudioSource.midiCollector));
audioDeviceManager.removeAudioCallback (&audioSourcePlayer); audioDeviceManager.removeAudioCallback (&audioSourcePlayer);
audioDeviceManager.removeAudioCallback (&liveAudioDisplayComp); audioDeviceManager.removeAudioCallback (&liveAudioDisplayComp);
} }


+ 2
- 2
examples/Audio/MPEDemo.h View File

@@ -879,7 +879,7 @@ public:
audioDeviceManager.initialise (0, 2, 0, true, {}, 0); audioDeviceManager.initialise (0, 2, 0, true, {}, 0);
#endif #endif
audioDeviceManager.addMidiInputCallback ({}, this);
audioDeviceManager.addMidiInputDeviceCallback ({}, this);
audioDeviceManager.addAudioCallback (this); audioDeviceManager.addAudioCallback (this);
addAndMakeVisible (audioSetupComp); addAndMakeVisible (audioSetupComp);
@@ -904,7 +904,7 @@ public:
~MPEDemo() ~MPEDemo()
{ {
audioDeviceManager.removeMidiInputCallback ({}, this);
audioDeviceManager.removeMidiInputDeviceCallback ({}, this);
audioDeviceManager.removeAudioCallback (this); audioDeviceManager.removeAudioCallback (this);
} }


+ 167
- 53
modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.cpp View File

@@ -304,19 +304,66 @@ String AudioDeviceManager::initialiseFromXML (const XmlElement& xml,
error = setAudioDeviceSetup (setup, true); error = setAudioDeviceSetup (setup, true);
midiInsFromXml.clear();
if (error.isNotEmpty() && selectDefaultDeviceOnFailure)
error = initialise (numInputChansNeeded, numOutputChansNeeded, nullptr, false, preferredDefaultDeviceName);
midiDeviceInfosFromXml.clear();
enabledMidiInputs.clear();
forEachXmlChildElementWithTagName (xml, c, "MIDIINPUT") forEachXmlChildElementWithTagName (xml, c, "MIDIINPUT")
midiInsFromXml.add (c->getStringAttribute ("name"));
midiDeviceInfosFromXml.add ({ c->getStringAttribute ("name"), c->getStringAttribute ("identifier") });
auto isIdentifierAvailable = [] (const Array<MidiDeviceInfo>& available, const String& identifier)
{
for (auto& device : available)
if (device.identifier == identifier)
return true;
for (auto& m : MidiInput::getDevices())
setMidiInputEnabled (m, midiInsFromXml.contains (m));
return false;
};
if (error.isNotEmpty() && selectDefaultDeviceOnFailure)
error = initialise (numInputChansNeeded, numOutputChansNeeded,
nullptr, false, preferredDefaultDeviceName);
auto getUpdatedIdentifierForName = [&] (const Array<MidiDeviceInfo>& available, const String& name) -> String
{
for (auto& device : available)
if (device.name == name)
return device.identifier;
return {};
};
setDefaultMidiOutput (xml.getStringAttribute ("defaultMidiOutput"));
auto inputs = MidiInput::getAvailableDevices();
for (auto& info : midiDeviceInfosFromXml)
{
if (isIdentifierAvailable (inputs, info.identifier))
{
setMidiInputDeviceEnabled (info.identifier, true);
}
else
{
auto identifier = getUpdatedIdentifierForName (inputs, info.name);
if (identifier.isNotEmpty())
setMidiInputDeviceEnabled (identifier, true);
}
}
MidiDeviceInfo defaultOutputDeviceInfo (xml.getStringAttribute ("defaultMidiOutput"),
xml.getStringAttribute ("defaultMidiOutputDevice"));
auto outputs = MidiOutput::getAvailableDevices();
if (isIdentifierAvailable (outputs, defaultOutputDeviceInfo.identifier))
{
setDefaultMidiOutputDevice (defaultOutputDeviceInfo.identifier);
}
else
{
auto identifier = getUpdatedIdentifierForName (outputs, defaultOutputDeviceInfo.name);
if (identifier.isNotEmpty())
setDefaultMidiOutputDevice (identifier);
}
return error; return error;
} }
@@ -660,24 +707,37 @@ void AudioDeviceManager::updateXml()
lastExplicitSettings->setAttribute ("audioDeviceOutChans", currentSetup.outputChannels.toString (2)); lastExplicitSettings->setAttribute ("audioDeviceOutChans", currentSetup.outputChannels.toString (2));
} }
for (int i = 0; i < enabledMidiInputs.size(); ++i)
lastExplicitSettings->createNewChildElement ("MIDIINPUT")
->setAttribute ("name", enabledMidiInputs[i]->getName());
for (auto& input : enabledMidiInputs)
{
auto* child = lastExplicitSettings->createNewChildElement ("MIDIINPUT");
if (midiInsFromXml.size() > 0)
child->setAttribute ("name", input->getName());
child->setAttribute ("identifier", input->getIdentifier());
}
if (midiDeviceInfosFromXml.size() > 0)
{ {
// Add any midi devices that have been enabled before, but which aren't currently // Add any midi devices that have been enabled before, but which aren't currently
// open because the device has been disconnected. // open because the device has been disconnected.
const StringArray availableMidiDevices (MidiInput::getDevices());
auto availableMidiDevices = MidiInput::getAvailableDevices();
for (auto& d : midiDeviceInfosFromXml)
{
if (! availableMidiDevices.contains (d))
{
auto* child = lastExplicitSettings->createNewChildElement ("MIDIINPUT");
for (int i = 0; i < midiInsFromXml.size(); ++i)
if (! availableMidiDevices.contains (midiInsFromXml[i], true))
lastExplicitSettings->createNewChildElement ("MIDIINPUT")
->setAttribute ("name", midiInsFromXml[i]);
child->setAttribute ("name", d.name);
child->setAttribute ("identifier", d.identifier);
}
}
} }
if (defaultMidiOutputName.isNotEmpty())
lastExplicitSettings->setAttribute ("defaultMidiOutput", defaultMidiOutputName);
if (defaultMidiOutputDeviceInfo != MidiDeviceInfo())
{
lastExplicitSettings->setAttribute ("defaultMidiOutput", defaultMidiOutputDeviceInfo.name);
lastExplicitSettings->setAttribute ("defaultMidiOutputDevice", defaultMidiOutputDeviceInfo.identifier);
}
} }
//============================================================================== //==============================================================================
@@ -814,28 +874,23 @@ double AudioDeviceManager::getCpuUsage() const
} }
//============================================================================== //==============================================================================
void AudioDeviceManager::setMidiInputEnabled (const String& name, const bool enabled)
void AudioDeviceManager::setMidiInputDeviceEnabled (const String& identifier, bool enabled)
{ {
if (enabled != isMidiInputEnabled (name))
if (enabled != isMidiInputDeviceEnabled (identifier))
{ {
if (enabled) if (enabled)
{ {
auto index = MidiInput::getDevices().indexOf (name);
if (index >= 0)
if (auto midiIn = MidiInput::openDevice (identifier, callbackHandler.get()))
{ {
if (auto* midiIn = MidiInput::openDevice (index, callbackHandler.get()))
{
enabledMidiInputs.add (midiIn);
midiIn->start();
}
enabledMidiInputs.push_back (std::move (midiIn));
enabledMidiInputs.back()->start();
} }
} }
else else
{ {
for (int i = enabledMidiInputs.size(); --i >= 0;)
if (enabledMidiInputs[i]->getName() == name)
enabledMidiInputs.remove (i);
auto removePredicate = [identifier] (const std::unique_ptr<MidiInput>& in) { return in->getIdentifier() == identifier; };
enabledMidiInputs.erase (std::remove_if (std::begin (enabledMidiInputs), std::end (enabledMidiInputs), removePredicate),
std::end (enabledMidiInputs));
} }
updateXml(); updateXml();
@@ -843,37 +898,33 @@ void AudioDeviceManager::setMidiInputEnabled (const String& name, const bool ena
} }
} }
bool AudioDeviceManager::isMidiInputEnabled (const String& name) const
bool AudioDeviceManager::isMidiInputDeviceEnabled (const String& identifier) const
{ {
for (auto* mi : enabledMidiInputs)
if (mi->getName() == name)
for (auto& mi : enabledMidiInputs)
if (mi->getIdentifier() == identifier)
return true; return true;
return false; return false;
} }
void AudioDeviceManager::addMidiInputCallback (const String& name, MidiInputCallback* callbackToAdd)
void AudioDeviceManager::addMidiInputDeviceCallback (const String& identifier, MidiInputCallback* callbackToAdd)
{ {
removeMidiInputCallback (name, callbackToAdd);
removeMidiInputDeviceCallback (identifier, callbackToAdd);
if (name.isEmpty() || isMidiInputEnabled (name))
if (identifier.isEmpty() || isMidiInputDeviceEnabled (identifier))
{ {
const ScopedLock sl (midiCallbackLock); const ScopedLock sl (midiCallbackLock);
MidiCallbackInfo mc;
mc.deviceName = name;
mc.callback = callbackToAdd;
midiCallbacks.add (mc);
midiCallbacks.add ({ identifier, callbackToAdd });
} }
} }
void AudioDeviceManager::removeMidiInputCallback (const String& name, MidiInputCallback* callbackToRemove)
void AudioDeviceManager::removeMidiInputDeviceCallback (const String& identifier, MidiInputCallback* callbackToRemove)
{ {
for (int i = midiCallbacks.size(); --i >= 0;) for (int i = midiCallbacks.size(); --i >= 0;)
{ {
auto& mc = midiCallbacks.getReference(i);
auto& mc = midiCallbacks.getReference (i);
if (mc.callback == callbackToRemove && mc.deviceName == name)
if (mc.callback == callbackToRemove && mc.deviceIdentifier == identifier)
{ {
const ScopedLock sl (midiCallbackLock); const ScopedLock sl (midiCallbackLock);
midiCallbacks.remove (i); midiCallbacks.remove (i);
@@ -888,15 +939,15 @@ void AudioDeviceManager::handleIncomingMidiMessageInt (MidiInput* source, const
const ScopedLock sl (midiCallbackLock); const ScopedLock sl (midiCallbackLock);
for (auto& mc : midiCallbacks) for (auto& mc : midiCallbacks)
if (mc.deviceName.isEmpty() || mc.deviceName == source->getName())
if (mc.deviceIdentifier.isEmpty() || mc.deviceIdentifier == source->getIdentifier())
mc.callback->handleIncomingMidiMessage (source, message); mc.callback->handleIncomingMidiMessage (source, message);
} }
} }
//============================================================================== //==============================================================================
void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName)
void AudioDeviceManager::setDefaultMidiOutputDevice (const String& identifier)
{ {
if (defaultMidiOutputName != deviceName)
if (defaultMidiOutputDeviceInfo.identifier != identifier)
{ {
Array<AudioIODeviceCallback*> oldCallbacks; Array<AudioIODeviceCallback*> oldCallbacks;
@@ -907,13 +958,17 @@ void AudioDeviceManager::setDefaultMidiOutput (const String& deviceName)
if (currentAudioDevice != nullptr) if (currentAudioDevice != nullptr)
for (int i = oldCallbacks.size(); --i >= 0;) for (int i = oldCallbacks.size(); --i >= 0;)
oldCallbacks.getUnchecked(i)->audioDeviceStopped();
oldCallbacks.getUnchecked (i)->audioDeviceStopped();
defaultMidiOutput.reset(); defaultMidiOutput.reset();
defaultMidiOutputName = deviceName;
if (deviceName.isNotEmpty())
defaultMidiOutput.reset (MidiOutput::openDevice (MidiOutput::getDevices().indexOf (deviceName)));
if (identifier.isNotEmpty())
defaultMidiOutput = MidiOutput::openDevice (identifier);
if (defaultMidiOutput != nullptr)
defaultMidiOutputDeviceInfo = defaultMidiOutput->getDeviceInfo();
else
defaultMidiOutputDeviceInfo = {};
if (currentAudioDevice != nullptr) if (currentAudioDevice != nullptr)
for (auto* c : oldCallbacks) for (auto* c : oldCallbacks)
@@ -1018,4 +1073,63 @@ int AudioDeviceManager::getXRunCount() const noexcept
return jmax (0, deviceXRuns) + loadMeasurer.getXRunCount(); return jmax (0, deviceXRuns) + loadMeasurer.getXRunCount();
} }
//==============================================================================
// Deprecated
void AudioDeviceManager::setMidiInputEnabled (const String& name, const bool enabled)
{
for (auto& device : MidiInput::getAvailableDevices())
{
if (device.name == name)
{
setMidiInputDeviceEnabled (device.identifier, enabled);
return;
}
}
}
bool AudioDeviceManager::isMidiInputEnabled (const String& name) const
{
for (auto& device : MidiInput::getAvailableDevices())
if (device.name == name)
return isMidiInputDeviceEnabled (device.identifier);
return false;
}
void AudioDeviceManager::addMidiInputCallback (const String& name, MidiInputCallback* callbackToAdd)
{
for (auto& device : MidiInput::getAvailableDevices())
{
if (device.name == name)
{
addMidiInputDeviceCallback (device.identifier, callbackToAdd);
return;
}
}
}
void AudioDeviceManager::removeMidiInputCallback (const String& name, MidiInputCallback* callbackToRemove)
{
for (auto& device : MidiInput::getAvailableDevices())
{
if (device.name == name)
{
removeMidiInputDeviceCallback (device.identifier, callbackToRemove);
return;
}
}
}
void AudioDeviceManager::setDefaultMidiOutput (const String& name)
{
for (auto& device : MidiOutput::getAvailableDevices())
{
if (device.name == name)
{
setDefaultMidiOutputDevice (device.identifier);
return;
}
}
}
} // namespace juce } // namespace juce

+ 48
- 31
modules/juce_audio_devices/audio_io/juce_AudioDeviceManager.h View File

@@ -307,12 +307,12 @@ public:
//============================================================================== //==============================================================================
/** Enables or disables a midi input device. /** Enables or disables a midi input device.
The list of devices can be obtained with the MidiInput::getDevices() method.
The list of devices can be obtained with the MidiInput::getAvailableDevices() method.
Any incoming messages from enabled input devices will be forwarded on to all the Any incoming messages from enabled input devices will be forwarded on to all the
listeners that have been registered with the addMidiInputCallback() method. They
can either register for messages from a particular device, or from just the
"default" midi input.
listeners that have been registered with the addMidiInputDeviceCallback() method. They
can either register for messages from a particular device, or from just the "default"
midi input.
Routing the midi input via an AudioDeviceManager means that when a listener Routing the midi input via an AudioDeviceManager means that when a listener
registers for the default midi input, this default device can be changed by the registers for the default midi input, this default device can be changed by the
@@ -322,62 +322,65 @@ public:
or not present, so that when the input is re-enabled, the listener will start or not present, so that when the input is re-enabled, the listener will start
receiving messages again. receiving messages again.
@see addMidiInputCallback, isMidiInputEnabled
@see addMidiInputDeviceCallback, isMidiInputDeviceEnabled
*/ */
void setMidiInputEnabled (const String& midiInputDeviceName, bool enabled);
void setMidiInputDeviceEnabled (const String& deviceIdentifier, bool enabled);
/** Returns true if a given midi input device is being used. /** Returns true if a given midi input device is being used.
@see setMidiInputEnabled
@see setMidiInputDeviceEnabled
*/ */
bool isMidiInputEnabled (const String& midiInputDeviceName) const;
bool isMidiInputDeviceEnabled (const String& deviceIdentifier) const;
/** Registers a listener for callbacks when midi events arrive from a midi input. /** Registers a listener for callbacks when midi events arrive from a midi input.
The device name can be empty to indicate that it wants to receive all incoming
events from all the enabled MIDI inputs. Or it can be the name of one of the
The device identifier can be empty to indicate that it wants to receive all incoming
events from all the enabled MIDI inputs. Or it can be the identifier of one of the
MIDI input devices if it just wants the events from that device. (see MIDI input devices if it just wants the events from that device. (see
MidiInput::getDevices() for the list of device names).
MidiInput::getAvailableDevices() for the list of devices).
Only devices which are enabled (see the setMidiInputEnabled() method) will have their
Only devices which are enabled (see the setMidiInputDeviceEnabled() method) will have their
events forwarded on to listeners. events forwarded on to listeners.
*/ */
void addMidiInputCallback (const String& midiInputDeviceName,
MidiInputCallback* callback);
void addMidiInputDeviceCallback (const String& deviceIdentifier,
MidiInputCallback* callback);
/** Removes a listener that was previously registered with addMidiInputCallback(). */
void removeMidiInputCallback (const String& midiInputDeviceName,
MidiInputCallback* callback);
/** Removes a listener that was previously registered with addMidiInputDeviceCallback(). */
void removeMidiInputDeviceCallback (const String& deviceIdentifier,
MidiInputCallback* callback);
//============================================================================== //==============================================================================
/** Sets a midi output device to use as the default. /** Sets a midi output device to use as the default.
The list of devices can be obtained with the MidiOutput::getDevices() method.
The list of devices can be obtained with the MidiOutput::getAvailableDevices() method.
The specified device will be opened automatically and can be retrieved with the The specified device will be opened automatically and can be retrieved with the
getDefaultMidiOutput() method. getDefaultMidiOutput() method.
Pass in an empty string to deselect all devices. For the default device, you Pass in an empty string to deselect all devices. For the default device, you
can use MidiOutput::getDevices() [MidiOutput::getDefaultDeviceIndex()].
can use MidiOutput::getDefaultDevice().
@see getDefaultMidiOutput, getDefaultMidiOutputName
@see getDefaultMidiOutput, getDefaultMidiOutputIdentifier
*/ */
void setDefaultMidiOutput (const String& deviceName);
void setDefaultMidiOutputDevice (const String& deviceIdentifier);
/** Returns the name of the default midi output. /** Returns the name of the default midi output.
@see setDefaultMidiOutput, getDefaultMidiOutput
@see setDefaultMidiOutputDevice, getDefaultMidiOutput
*/ */
const String& getDefaultMidiOutputName() const noexcept { return defaultMidiOutputName; }
const String& getDefaultMidiOutputIdentifier() const noexcept { return defaultMidiOutputDeviceInfo.identifier; }
/** Returns the current default midi output device.
If no device has been selected, or the device can't be opened, this will return nullptr.
@see getDefaultMidiOutputName
/** Returns the current default midi output device. If no device has been selected, or the
device can't be opened, this will return nullptr.
@see getDefaultMidiOutputIdentifier
*/ */
MidiOutput* getDefaultMidiOutput() const noexcept { return defaultMidiOutput.get(); } MidiOutput* getDefaultMidiOutput() const noexcept { return defaultMidiOutput.get(); }
//==============================================================================
/** Returns a list of the types of device supported. */ /** Returns a list of the types of device supported. */
const OwnedArray<AudioIODeviceType>& getAvailableDeviceTypes(); const OwnedArray<AudioIODeviceType>& getAvailableDeviceTypes();
//==============================================================================
/** Creates a list of available types. /** Creates a list of available types.
This will add a set of new AudioIODeviceType objects to the specified list, to This will add a set of new AudioIODeviceType objects to the specified list, to
@@ -461,6 +464,20 @@ public:
*/ */
int getXRunCount() const noexcept; int getXRunCount() const noexcept;
//==============================================================================
/** Deprecated. */
void setMidiInputEnabled (const String&, bool);
/** Deprecated. */
bool isMidiInputEnabled (const String&) const;
/** Deprecated. */
void addMidiInputCallback (const String&, MidiInputCallback*);
/** Deprecated. */
void removeMidiInputCallback (const String&, MidiInputCallback*);
/** Deprecated. */
void setDefaultMidiOutput (const String&);
/** Deprecated. */
const String& getDefaultMidiOutputName() const noexcept { return defaultMidiOutputDeviceInfo.name; }
private: private:
//============================================================================== //==============================================================================
OwnedArray<AudioIODeviceType> availableDeviceTypes; OwnedArray<AudioIODeviceType> availableDeviceTypes;
@@ -477,15 +494,15 @@ private:
struct MidiCallbackInfo struct MidiCallbackInfo
{ {
String deviceName;
String deviceIdentifier;
MidiInputCallback* callback; MidiInputCallback* callback;
}; };
StringArray midiInsFromXml;
OwnedArray<MidiInput> enabledMidiInputs;
Array<MidiDeviceInfo> midiDeviceInfosFromXml;
std::vector<std::unique_ptr<MidiInput>> enabledMidiInputs;
Array<MidiCallbackInfo> midiCallbacks; Array<MidiCallbackInfo> midiCallbacks;
String defaultMidiOutputName;
MidiDeviceInfo defaultMidiOutputDeviceInfo;
std::unique_ptr<MidiOutput> defaultMidiOutput; std::unique_ptr<MidiOutput> defaultMidiOutput;
CriticalSection audioCallbackLock, midiCallbackLock; CriticalSection audioCallbackLock, midiCallbackLock;


+ 8
- 6
modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h View File

@@ -411,7 +411,7 @@ public:
bool autoOpenMidiDevices; bool autoOpenMidiDevices;
std::unique_ptr<AudioDeviceManager::AudioDeviceSetup> options; std::unique_ptr<AudioDeviceManager::AudioDeviceSetup> options;
StringArray lastMidiDevices;
Array<MidiDeviceInfo> lastMidiDevices;
private: private:
//============================================================================== //==============================================================================
@@ -526,7 +526,7 @@ private:
const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions) const AudioDeviceManager::AudioDeviceSetup* preferredSetupOptions)
{ {
deviceManager.addAudioCallback (this); deviceManager.addAudioCallback (this);
deviceManager.addMidiInputCallback ({}, &player);
deviceManager.addMidiInputDeviceCallback ({}, &player);
reloadAudioDeviceState (enableAudioInput, preferredDefaultDeviceName, preferredSetupOptions); reloadAudioDeviceState (enableAudioInput, preferredDefaultDeviceName, preferredSetupOptions);
} }
@@ -535,23 +535,25 @@ private:
{ {
saveAudioDeviceState(); saveAudioDeviceState();
deviceManager.removeMidiInputCallback ({}, &player);
deviceManager.removeMidiInputDeviceCallback ({}, &player);
deviceManager.removeAudioCallback (this); deviceManager.removeAudioCallback (this);
} }
void timerCallback() override void timerCallback() override
{ {
auto newMidiDevices = MidiInput::getDevices();
auto newMidiDevices = MidiInput::getAvailableDevices();
if (newMidiDevices != lastMidiDevices) if (newMidiDevices != lastMidiDevices)
{ {
for (auto& oldDevice : lastMidiDevices) for (auto& oldDevice : lastMidiDevices)
if (! newMidiDevices.contains (oldDevice)) if (! newMidiDevices.contains (oldDevice))
deviceManager.setMidiInputEnabled (oldDevice, false);
deviceManager.setMidiInputDeviceEnabled (oldDevice.identifier, false);
for (auto& newDevice : newMidiDevices) for (auto& newDevice : newMidiDevices)
if (! lastMidiDevices.contains (newDevice)) if (! lastMidiDevices.contains (newDevice))
deviceManager.setMidiInputEnabled (newDevice, true);
deviceManager.setMidiInputDeviceEnabled (newDevice.identifier, true);
lastMidiDevices = newMidiDevices;
} }
} }


+ 21
- 18
modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp View File

@@ -90,7 +90,7 @@ public:
void updateDevices() void updateDevices()
{ {
items = MidiInput::getDevices();
items = MidiInput::getAvailableDevices();
} }
int getNumRows() override int getNumRows() override
@@ -107,7 +107,7 @@ public:
.withMultipliedAlpha (0.3f)); .withMultipliedAlpha (0.3f));
auto item = items[row]; auto item = items[row];
bool enabled = deviceManager.isMidiInputEnabled (item);
bool enabled = deviceManager.isMidiInputDeviceEnabled (item.identifier);
auto x = getTickX(); auto x = getTickX();
auto tickW = height * 0.75f; auto tickW = height * 0.75f;
@@ -117,7 +117,7 @@ public:
g.setFont (height * 0.6f); g.setFont (height * 0.6f);
g.setColour (findColour (ListBox::textColourId, true).withMultipliedAlpha (enabled ? 1.0f : 0.6f)); g.setColour (findColour (ListBox::textColourId, true).withMultipliedAlpha (enabled ? 1.0f : 0.6f));
g.drawText (item, x + 5, 0, width - x - 5, height, Justification::centredLeft, true);
g.drawText (item.name, x + 5, 0, width - x - 5, height, Justification::centredLeft, true);
} }
} }
@@ -166,14 +166,14 @@ private:
//============================================================================== //==============================================================================
AudioDeviceManager& deviceManager; AudioDeviceManager& deviceManager;
const String noItemsMessage; const String noItemsMessage;
StringArray items;
Array<MidiDeviceInfo> items;
void flipEnablement (const int row) void flipEnablement (const int row)
{ {
if (isPositiveAndBelow (row, items.size())) if (isPositiveAndBelow (row, items.size()))
{ {
auto item = items[row];
deviceManager.setMidiInputEnabled (item, ! deviceManager.isMidiInputEnabled (item));
auto identifier = items[row].identifier;
deviceManager.setMidiInputDeviceEnabled (identifier, ! deviceManager.isMidiInputDeviceEnabled (identifier));
} }
} }
@@ -1115,12 +1115,12 @@ void AudioDeviceSelectorComponent::updateDeviceType()
void AudioDeviceSelectorComponent::updateMidiOutput() void AudioDeviceSelectorComponent::updateMidiOutput()
{ {
auto midiDeviceName = midiOutputSelector->getText();
if (midiDeviceName == getNoDeviceString())
midiDeviceName = {};
auto selectedId = midiOutputSelector->getSelectedId();
deviceManager.setDefaultMidiOutput (midiDeviceName);
if (selectedId == -1)
deviceManager.setDefaultMidiOutputDevice ({});
else
deviceManager.setDefaultMidiOutputDevice (currentMidiOutputs[selectedId - 1].identifier);
} }
void AudioDeviceSelectorComponent::changeListenerCallback (ChangeBroadcaster*) void AudioDeviceSelectorComponent::changeListenerCallback (ChangeBroadcaster*)
@@ -1168,20 +1168,23 @@ void AudioDeviceSelectorComponent::updateAllControls()
{ {
midiOutputSelector->clear(); midiOutputSelector->clear();
auto midiOuts = MidiOutput::getDevices();
currentMidiOutputs = MidiOutput::getAvailableDevices();
midiOutputSelector->addItem (getNoDeviceString(), -1); midiOutputSelector->addItem (getNoDeviceString(), -1);
midiOutputSelector->addSeparator(); midiOutputSelector->addSeparator();
for (int i = 0; i < midiOuts.size(); ++i)
midiOutputSelector->addItem (midiOuts[i], i + 1);
auto defaultOutputIdentifier = deviceManager.getDefaultMidiOutputIdentifier();
int i = 0;
int current = -1;
for (auto& out : currentMidiOutputs)
{
midiOutputSelector->addItem (out.name, i + 1);
if (deviceManager.getDefaultMidiOutput() != nullptr)
current = 1 + midiOuts.indexOf (deviceManager.getDefaultMidiOutputName());
if (defaultOutputIdentifier.isNotEmpty() && out.identifier == defaultOutputIdentifier)
midiOutputSelector->setSelectedId (i + 1);
midiOutputSelector->setSelectedId (current, dontSendNotification);
++i;
}
} }
resized(); resized();


+ 1
- 0
modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.h View File

@@ -111,6 +111,7 @@ private:
const bool hideAdvancedOptionsWithButton; const bool hideAdvancedOptionsWithButton;
class MidiInputSelectorComponentListBox; class MidiInputSelectorComponentListBox;
Array<MidiDeviceInfo> currentMidiOutputs;
std::unique_ptr<MidiInputSelectorComponentListBox> midiInputsList; std::unique_ptr<MidiInputSelectorComponentListBox> midiInputsList;
std::unique_ptr<ComboBox> midiOutputSelector; std::unique_ptr<ComboBox> midiOutputSelector;
std::unique_ptr<Label> midiInputsLabel, midiOutputLabel; std::unique_ptr<Label> midiInputsLabel, midiOutputLabel;


Loading…
Cancel
Save