GUI app + Jack: possible to set client name?

Hi. I’m writing a GUI app, a controller for a jacktrip/microcontroller-based WFS system. I start Jack, and a jacktrip server, which the microcontrollers connect to over ethernet; then I start the controller application, which tells the microcontrollers where they and the sound sources are via OSC.

I’ve set up the app to play back the audio sources too. I’m setting AudioDeviceManager::AudioDeviceSetup::outputDeviceName to “JACK Audio Connection Kit”, then using jack_connect() to connect my app’s outputs to the inputs of the jacktrip clients. This all works fine, but my app’s Jack client name is pretty generic; from the Jack logs:

Tue Nov 22 10:42:28 2022: New client 'alsa-jack.jackP.17287.0' with PID 17287

This log entry appears during the call to ALSAAudioIODeviceType::createDevice(). Is that client being created by JUCE (via a call, somewhere, to jack_client_open()), or is it created (and named) automatically by Jack? Does anyone know whether there’s a way to intercept the client name?

It should be jack and not alsa-jack. The name, if you use CMake is set in the target_compile_definitions
`JUCE_JACK_CLIENT_NAME=“yourappname”

1 Like

Thanks very much for the reply!

So, if I do something like…

auto type{AudioIODeviceType::createAudioIODeviceType_JACK()};
type->scanForDevices();
auto available = type->getDeviceNames();
auto device = type->createDevice(available[0], available[0]);

that creates a Jack client whose name I can specify with JUCE_JACK_CLIENT_NAME. That’s not the device my app is using for output though – from my AudioAppComponent inheritor I’m calling:

auto setup{deviceManager.getAudioDeviceSetup()};
auto &deviceTypes{deviceManager.getAvailableDeviceTypes()};
for (auto type: deviceTypes) {
    type->scanForDevices();
    if (type->getDeviceNames().contains("JACK Audio Connection Kit", true)) {
        setup.outputDeviceName = "JACK Audio Connection Kit";
        break;
    }
}
deviceManager.setAudioDeviceSetup(setup, true);

And that’s what’s triggering the creation of this alsa-jack.jackP.<PID>.<n> Jack client. This would be fine, except to connect my app to the jacktrip clients I’m doing a regex match with jack_get_ports(), which is unsettlingly lacking in robustness.

I get the feeling that to use a named output device, I need to create one with JackAudioIODevice::createDevice()… register its ports, then jack_connect() to that. Does that sound plausible?

I try to look tomorrow deeply. But it looks you’re still using the ALSA backend and not the Jack:
There the ALSA backend with alsa-jack “bridge”, which is not you may need, I guess:

изображение

And this is the Jack client mode:

изображение

Do you have JUCE_JACK="1" enabled?

Yeah, I’m using

target_compile_definitions(WfsController
        PUBLIC
        JUCE_JACK=1
        JUCE_JACK_CLIENT_NAME="${PROJECT_NAME}")

And, thanks to your observation that I was using the ALSA Backend, I think I’ve figured it out. I guess selecting “JACK Audio Connection Kit” instructs ALSA to create a Jack client, which is where that alsa-jack... name was coming from. What I needed was to deal with Jack directly rather than delegating to ALSA. So, instead of …

auto setup{deviceManager.getAudioDeviceSetup()};
auto &deviceTypes{deviceManager.getAvailableDeviceTypes()};
for (auto type: deviceTypes) {
    type->scanForDevices();
    if (type->getDeviceNames().contains("JACK Audio Connection Kit", true)) {
        setup.outputDeviceName = "JACK Audio Connection Kit";
        break;
    }
}
deviceManager.setAudioDeviceSetup(setup, true);

now I’m (provisionally) taking this approach:

auto setup{deviceManager.getAudioDeviceSetup()};
auto &deviceTypes{deviceManager.getAvailableDeviceTypes()};
for (auto type: deviceTypes) {
    auto typeName{type->getTypeName()};
    if (typeName == "JACK") {
        deviceManager.setCurrentAudioDeviceType(typeName, true);
        type->scanForDevices();
        auto names{type->getDeviceNames()};
        if (names.contains("system", true)) {  // Not sure about this... 
            setup.outputDeviceName = "system"; // ...think I just need an 
                                               // arbitrary valid device name
                                               // to get things rolling.
            deviceManager.setAudioDeviceSetup(setup, true);
            break;
        }
    }
}

Then I can create a(nother) dummy Jack client and call jack_connect() to hook my app up to all the jacktrip clients, e.g.:

catia

Thanks!

1 Like