how to get audio device/driver selection via context menu ?

I’ve got a module where I’ve copied core’s Audio2Display to my module widget; this is working for audio driver/device selection. Thing is having driver selection on the module front panel is distracting from the module’s actual intent/purpose. I’m thinking putting the audio driver/device selection in the context menu would be appropriate since then the device/driver is not the focus of the module.

That said, I’m kind of lost trying to see what I can do in appendContextMenu. The ModuleWidget constructor code I’ve got is:

        Audio2Display *audioDisplay = createWidget<Audio2Display>(mm2px(Vec(50.0, 10.0)));
        audioDisplay->box.size = mm2px(Vec(25.0, 10.0));
        audioDisplay->setAudioPort(module ? &module->port : NULL);
        addChild(audioDisplay);

Where Audio2Display is a LedDisplay; this is pretty much core’s Audio.cpp. I’d like to take out the widget from the constructor and drop in similar functionality appendContextMenu. Any ideas on how to get there or an example where this has been done?

I take it you’re trying to replicate the audio display context menu from Core’s Audio 2 module?

If so I think what you need is in Rack/src/app/AudioDisplay.cpp

Thanks, I’ve been looking at the docs on that. Just a bit lost on how to get that to a Menu and what the “menu->addChild()” call might look like in appendContextMenu.

Here’s what you’re looking for. This method was added to the Rack 2 API specifically for your use case:

This method is used by the AudioDisplayWidget itself for making its context menu when it’s left-clicked. The widget creates a menu when it is clicked, then it passes a pointer to that empty menu to the appendAudioMenu function.

So, assuming your module has an AudioPort as it should in order to function as an audio interface, all you need is something like this:

void appendContextMenu(Menu* menu) override {
    MyModule* module = dynamic_cast<MyModule*>(this->module);
    appendAudioMenu(menu, &module->port);
}
1 Like

Thanks Anthony! That works perfect. I found the midi menu as well. This will save a lot of real estate from my module & allow the user to focus on the module itself versus the devices under the hood.

I’m not great with UI and this is pretty ugly, but at least this will allow the last third of the module to be chopped off and replaced with the context menu. What I had before…

zoxnoxious_vcvrack

The hardware needs both audio and midi devices, and midi was easy to solve for with your info. Just to top it off, here’s the extra sugar to get it to a submenu:

        menu->addChild(new MenuSeparator);
        menu->addChild(createSubmenuItem("MIDI Device", "",
                                         [=](Menu* menu) {
                                             appendMidiMenu(menu, &module->midiOutput);
                                         }));
        menu->addChild(new MenuSeparator);
        menu->addChild(createSubmenuItem("Audio Device", "",
                                         [=](Menu* menu) {
                                             appendAudioMenu(menu, &module->port);
                                         }));
    }

then bang, there it is in a context menu:

I’m calling that good for now, despite the however many audio devices that alsa seems to make available (outside the scope of this question).

1 Like