Cabbage Logo
Back to Cabbage Site

Changing the X window name & the name presented to JACK from "JUCEJack" to "Cab0" etc

I am exploring how I can run multiple instances of Cabbage (on Debian 64bit Linux) and have them accept input from the sound card or Ardour, and send their outputs to the sound card or Ardour.

In a previous thread: Multiple instances of Cabbage for the one user? (JACK2 with multiple users) I described how from a single Cabbage executable I used a hex editor to make multiple slightly different executables named Cabbage0 to Cabbage9. I altered the Cabbage source code (following Rory’s suggestion) to cause a second or subsequent instance of Cabbage for the one user to run normally, rather than close. I also used a hex editor to alter the name of the settings directory so each executable uses a different directory. This means I can run up to 10 instances of Cabbage at the same time, as the same user, and each one maintains its own settings.

I found the GUI “bless” hex editor to be unreliable, so I used “tweak” by Simon Tatham (author of PuTTY). I installed it as a Debian package. The man page is: https://www.chiark.greenend.org.uk/~sgtatham/tweak/manpage-3.02.html I ran it with the -f option to disable inserting and deleting bytes - so it can only change them: tweak -f Cabbage0 .

I would like a way of making the window title for each instance of Cabbage contain the number, since at present all such windows are titled just “Cabbage”. I didn’t find a way of doing this with a hex editor and I couldn’t find in the source where this was set. I tried a Debian program xdotool (in a package of the same name) http://manpages.ubuntu.com/manpages/precise/man1/xdotool.1.html Command = “http://manpages.ubuntu.com/manpages/precise/man1/xdotool.1.html” and it did not work.

Rory - can you point me to where in the code the name of the X window is set?

Within JACK, a single instance of Cabbage, the first one which is run, is identified by a single name for Readable Clients (outputs of Cabbage) and Writeable Clients (inputs of Cabbage): “JUCEJack”.

This is not controlled by the Cabbage code. It is set in JUCE: /JUCE-5.2.0/modules/juce_audio_devices/native/juce_linux_JackAudio.cpp . The string “JUCEJack” is easy to find in the executable with a hex editor.

The second instance of Cabbage which registers with JACK must give JACK the same name, and JACK adds a suffix:" -01" to “JUCEJack” and uses this to identify the Readable and Writable ports of this second instance. This identifying name “JUCEJack-01” appears in the JACK Connections (as shown by qjackctl) and in Ardour when I select ports for inputting or outputting audio.

My plan was to carefully start the instances in order: Cabbage0, Cabbage1, Cabbage2 etc. so that these would have their ports identified in an orderly manner as JUCEJack, JUCEJack-01, JUCEJack02 etc. However, this plan is too fragile and the names do not mention “Cabbage”.

So I changed the string in these ten executables to “Cab0” to “Cab9”. These characters replace “JUCE”" and the following ‘J’ is replaced by a hex 00 to terminate the string.

Now, in qjackctl’s Connections, the readable and writable client ports ports are “out_1” to “out_39” and “in_1 to “in-39” both in sections named, for instance, Cab2”. (I am not sure why Cabbage’s JUCE library chooses 39 ports, but I guess it is related in some way to the RayDAT sound card having 32 + 2 + 2 audio ports.)

In the Ardour mixer strip, the input and output buttons (3 and 12 in http://manual.ardour.org/ardours-interface/audio-midi-mixer-strips/) now display, for instance “Cab2”. They do not display the number of the port, which would be helpful.

In principle with three instances of Cabbage running, identified to JACK as Cab0, Cab1 and Cab2 I can use Cab0 to take its input from the sound card (system) ports capture_1 and capture_2 and drive ports (DACs) system playback_3 and playback_4. This works fine, such as using a reverb in this instance.

My second instance Cab1 is running a distortion file Powershape.csd and I can make it work in a similar way. However, when I try to use the JUCE audio port selector (Edit > Settings > Audio and MIDI > Input and so Active input channels) to get the input from the output of Cab0, it seems that the JUCE selector is not behaving as I expect. I can set “Input:” to “Cab0”, leaving “Output:” as “system” and “Active output channels:” with just “playback_7 + playback_8” ticked (which works fine for output), but it is clear that my selections, supposedly for Cab0 ports, are actually selecting from the system (sound card) ports. This is clear from the behaviour and from the names of the ports, which are those of “system” and not of “Cab0”.

So it seems that with this JUCE library Cabbage is incapable of selecting its input from a different JACK device than the one it sends it output to.

For instance, if “Output:” is set to “ardour” then it doesn’t matter what “Input:” is set to - all the ports shown in “Active input channels:” are from Ardour

Yet when I set both “Output:” and “Input:” to Cab0, I am unable to select any ports at all in “Active input channels:”.

I guess this is due to one or more bugs in JUCE which cannot be rectified in Cabbage.

My workaround, to get the output of Cab0 into Cab1, is to use Ardour mixer strips (and so recording channels) 1 and 2 and set their inputs to Cab0 3 and 4 respectively.

I can do something similar, without using up a pair of valuable ports on the sound card, by making Cab0’s output go to some sound card port I don’t care about, in this case “playback_35 + playback_36”. There’s no ADC/DAC on those ports. I can see the output signal on hdspmixer. Then, in Ardour, I use mixer strips 1 and 2, setting their inputs to Cab0’s out_35 and out_36 respectively.

I set Cabbage1 to have its inputs and outputs from the sound card (system) and selected 35 and 36 for the inputs and outputs. There is nothing plugged into the SPDIF input of the sound card, so Cabbage1 will get silence from these. It doesn’t matter what is sent to SPDIF out.

In the post-fader sections of these Ardour mix strips 1 and 2 I added two New External Sends. Strip 1’s L went to Cab1 35 and Strip 2’s R went to Cab1 36. (A similar outcome could be achieved with a two channel mixer strip.) I can see these signals are present by the little bar graph indicator to the right of Cabbage Settings > Audio and MIDI > “Input”. Then I set up Ardour mix strips 3 and 4 to get their inputs from Cab1 35 and 36 respectively. I could direct their outputs of mixer strips 3 and 4 to the Master bus and listen to them on some other sound card channels.

Now I set up Cabbage2 with exactly the same inputs and outputs as Cabbage1 - the unused soundcard ports 35 and 36. It doesn’t matter what they output there, and the inputs Cabbage2 gets are silent except for me adding to Ardour strips 3 and 4 two post-fader External Sends to Cab2 35 and 36. I can play the same game, using strips 6 and 7 to get the outputs of Cabbage2 and listen to them with the Master bus.

Patching Cabbage instances together and in combination with Ardour mix strips and sound card inputs and outputs requires that Cabbage be able to input audio from a different JACK device than it sends its output to. In my experience the current JUCE audio port selector can’t do this, so it suffices to make one or more instances of Cabbage use silent sources (including perhaps silent output busses from Ardour, rather than using a sound card channel) including the same source and driving their outputs to something similar, which doesn’t matter. Then, the patching can be done with ordinary inputs and with External Sends in the Ardour mixer strips.

I think the same arrangements can be used with an insert in the Processor section of the Ardour mix strips - sending audio, one or more channels, directly to whatever instance of Cabbage I like and getting its outputs back into the same mixer strip.

It seems that JUCE opening 39 audio ports is due to 32 + 2 + 2 audio ports and 3 MIDI ports on the sound card. It does not allow ticks on the ports MIDI ports.

I recall that Cabbage sets up JUCE for two audio inputs and two audio outputs. I will be able to change this when I make .CSD files for more than two channels.

If there are two or more output ports selected (more than one tick) I have observed that JUCE sends Cabbage’s output to the lowest number port with a tick, rather than to all of those which are ticked.

For conventional audio processing it might be easier to just line up a bunch of plugins. However, with this scheme, I am not reliant on plugins. All the work is done by Csound files, with Cabbage’s marvelous real-time GUI controls. I can write Csound and I can use C/C++ to write Csound ugens, so this scheme provides tremendous flexibility and opportunity for fun!

Thanks for keeping us updated on this. It’s very interesting for me to see how your workflow is coming together.

I found the two strings which set “Cabbage” in the title of the X window. The first one is a null-terminated string for “Cabbage” which is is followed immediately by a string “pluginType”. Changing that string to, for instance, “Cabbag0” or “Cabbag9” achieves part of my goal of the title of each X window showing the number of the executable which is running. For my executable the address of this last byte is 0x5FBB59. I was not able to find out where in the source this string is specified. It is vaguely possible that altering this string might upset some other aspect of the program.

However, this string only controls the window title before a .CSD file is loaded. To alter the first part of the title, where the .CSD file forms the second part, I altered a "Cabbage " string, with a trailing space, just before a string “NumberOfOpenFiles” (at 5F9BB7 in my file). I replace the space with ASCII 0 to 9.

So now I can run up to ten independent instances of Cabbage, each with its number in the X window title.

To recap the other mods I did before this:

The executable was created from the 2.0.02 source, with one change to allow multiple instances to run for the same user Multiple instances of Cabbage for the one user? (JACK2 with multiple users) and changes to JUCE 5.2.0 to create longer audio device selector boxes Increasing the size of the Settings dialogue box & I/O channel lists . Then with a hex editor I made ten copies Cabbage0 to Cabbage9 and modified them in two ways, in addition to the two changes just mentioned. Firstly I altered the directory in which their config files are saved as mentioned in Multiple instances of Cabbage for the one user? (JACK2 with multiple users) . Secondly I gave each executable a unique name for its JACK audio ports, as described in the first message above.

This has been a lot of futzing around, but by the time I finished my previous message I was close to making some satisfying music. I had Casio M10 playing a chord of pulsing sounds into Multireverb.csd, the output of which was then distorted by PowerShape.csd, the output of which fed FilterShaper.CSD, which I think is a real beauty. This was all done for purely technical reasons, but it sounded halfway alright. To this I added a separate echo delays as plugins within Ardour. My wife Tina and I liked it so I let it record for 26 hours . . . It sounded good on speakers but bad on headphones due to the discrete L-R nature of the signals. So I cobbled together a set of EQs, delays and reverbs within Ardour to simulate two speakers with some reverb: I could have done this in a .CSD file, but for now the Ardour approach was fine.

While I spent days learning about Cabbage and Ardour, and hex-editing Cabbage executables, I spent only minutes tweaking my multi-Cabbage example for musical purposes and it was a lot of fun. The processed track is https://soundcloud.com/atwindow/young-faithful .

Nice. It reminds me a coastline(not of this world) being battered by waves. It’s quite meditative. I’ve had it on now for a good 20 minutes.