[Bug] AudioDeviceSelectorComponent - two issues

I’m seeing two issues I’d like to report - Juce 7.0.8, Mac.

Demo project included here - simple GUI App with a button to open an AudioMIDI Settings Dialog, and save the settings to a Properties file:
AudioDeviceSelectorTest.zip (17.9 KB)

Essentially, this is the whole thing:

MainComponent::MainComponent()
{
    juce::PropertiesFile::Options options;
    options.applicationName     = "AudioDeviceSelectorTest";
    options.filenameSuffix      = "settings";
    options.osxLibrarySubFolder = "Preferences";
    
    appProperties.reset(new juce::ApplicationProperties());
    appProperties->setStorageParameters (options);
    
    auto safeThis = SafePointer<MainComponent> (this);
    juce::RuntimePermissions::request (juce::RuntimePermissions::recordAudio,
                                 [safeThis] (bool granted) mutable
                                 {
                                     auto savedState = safeThis->appProperties->getUserSettings()->getXmlValue ("audioDeviceState");
                                     juce::String s = safeThis->deviceManager.initialise (granted ? 256 : 0, 256, savedState.get(), true);
                                     if (!s.isEmpty())
                                         DBG ("initialize error " + s);
                                 });
    addAndMakeVisible(&button);
    button.onClick = [this] {
        auto* audioSettingsComp = new juce::AudioDeviceSelectorComponent (deviceManager,
                                                                    0, 256,
                                                                    0, 256,
                                                                    true,   // showMidiInputOptions
                                                                    true,   // showMidiOutputSelector
                                                                    true,   // showChannelsAsStereoPairs
                                                                    false); // hideAdvancedOptionsWithButton
        
        audioSettingsComp->setSize (400, 450);
        
        juce::DialogWindow::LaunchOptions o;
        o.content.setOwned (audioSettingsComp);
        o.dialogTitle                   = "Audio Settings";
        o.componentToCentreAround       = this;
        o.dialogBackgroundColour        = findColour(juce::ResizableWindow::backgroundColourId);
        o.escapeKeyTriggersCloseButton  = true;
        o.useNativeTitleBar             = false;
        o.resizable                     = false;
        
        auto* w = o.create();
        
        auto safeThis = SafePointer<MainComponent> (this);
        
        w->enterModalState (true,                           // takeKeyboardFocus
                            juce::ModalCallbackFunction::create
                            
                            ([safeThis] (int)
                             {
                                 if (safeThis)
                                 {
                                     auto audioState = safeThis->deviceManager.createStateXml();
                                     
                                     safeThis->appProperties->getUserSettings()->setValue ("audioDeviceState", audioState.get());
                                     safeThis->appProperties->getUserSettings()->saveIfNeeded();
                                  }
                             }), true);                     // deleteWhenDismissed
    };
    setSize (600, 400);
}

ISSUE 1
Dialog does not properly handle the <<none>> choice for the MIDI Output ComboBox. It will NEVER display <<none>> when being opened, even if it is set to <<none>>.

Launch the demo app. Press the “Open Settings” button: Initially, the MIDI Output menu at the bottom is blank (shouldn’t it show <<none>>?)

Select a MIDI output from the MIDI Output comboBox. In this example I used MotifXS6:

Close the dialog. Reopen, and it should display “MotifXS6”. Good. Now, select <<none>> from the MIDI Output box. It then shows <blank>:

Select <<none>> again. This time, it sticks:

Close the dialog, and reopen. It should display <<none>>, but again it is blank.

With a valid MIDI Output setting (i.e. MotifXS6), quit the dialog and examine the .settings file written to disk in the Preferences folder.

<?xml version="1.0" encoding="UTF-8"?>

<PROPERTIES>
  <VALUE name="audioDeviceState">
    <DEVICESETUP deviceType="CoreAudio" audioOutputDeviceName="Jump Desktop Audio"
                 audioInputDeviceName="MOTU 896mk3 Hybrid" audioDeviceRate="48000.0"
                 defaultMidiOutput="Motif XS6" defaultMidiOutputDevice="863927069"/>
  </VALUE>
</PROPERTIES>

Relaunch the app, open the dialog, it should restore the valid output setting (i.e. MotifXS6). Try to change it to <<none>> several times until you get it to actually display, then close the dialog and quit and examine the .settings file:

As expected, it shows this:

<?xml version="1.0" encoding="UTF-8"?>

<PROPERTIES>
  <VALUE name="audioDeviceState">
    <DEVICESETUP deviceType="CoreAudio" audioOutputDeviceName="Jump Desktop Audio"
                 audioInputDeviceName="MOTU 896mk3 Hybrid" audioDeviceRate="48000.0"/>
  </VALUE>
</PROPERTIES>

So when <<none>> is selected, nothing is specified for defaultMidiOutput. OK.

Therefore, it appears that a fix is to add a line to AudioDeviceSelectorComponent::updateAllControls(), to set it specifically to <<none>> if no defaultOutput is located, something like:

    if (midiOutputSelector != nullptr)
    {
        midiOutputSelector->clear();

        currentMidiOutputs = MidiOutput::getAvailableDevices();

        midiOutputSelector->addItem (getNoDeviceString(), -1);
        midiOutputSelector->addSeparator();

// ADD THIS LINE, to initially set to <<none>>, absent any other settings:
        midiOutputSelector->setSelectedId(-1, dontSendNotification);
                                          
        auto defaultOutputIdentifier = deviceManager.getDefaultMidiOutputIdentifier();
        int i = 0;

        for (auto& out : currentMidiOutputs)
        {
            midiOutputSelector->addItem (out.name, i + 1);

            if (defaultOutputIdentifier.isNotEmpty() && out.identifier == defaultOutputIdentifier)
                midiOutputSelector->setSelectedId (i + 1);

            ++i;
        }
    }

ISSUE 2
If you hide the advanced settings with a button, clicking that button does not resize dialog to accommodate new controls.

Launched with the option to “hideAdvancedOptionsWithButton”:

Clicking the “Show Advanced Settings” button overwrites the MIDI Inputs portion with the Sample Rate and Buffer Size:

@stephenk thanks for the detailed repro, I’m looking into these issues now.

1 Like

How did the look go? Thanks.

Fixes are just making their way through CI.

1 Like

@stephenk sorry I haven’t gotten back to this sooner we were having some funky CI issues last week. However the fixes are now on develop. Let me know if you experience any more issues. Thanks for reporting.

1 Like