good god. just when i thought i was gonna sell my es-8 and replace it with two crows. as usual the answer is “keep all of it”

6 Likes

do you want to use all es-8 io for audio IO?

I’ve been using an ES-8 a lot with Organelle/Orac/PD for a while now, and I’ve found the setup I lean towards is 2 audio in/out and then the rest for (audio rate) CV IO.
I’d guess this should work ‘out of the box’ - no? id assume SC has access to the additional ports as normal.

but yeah, the ES-8 is a lot of fun with these kind of setups.


(*) my main outputs come from eurorack, so the 2 audio io allow for a simple send/return setup.

To be honest I’ve not gotten so far as to think about the end configuration, but my default stance is that “everything is audio rate”.

Currently my blocker is figuring out where scsynth is called. I’ve searched the norns codebase and only found crone.sh which has the commented out line:
# scsynth -u 57122 -i 2 -o 2

Looks like the same command I see running… but seems like it’s started somewhere else now.

I noodled about with getting sc to output to the additional I/O on the ES-8 in maiden last night, but had no success and I still suspect the -i 2 -o 2 above has something to do with that, unless my approach was just plain wrong: something like this:

Out.ar(0, SinOsc(440) * 0.5);

and adjusting the output index to see if things started happening on the es8

sure… my point was, isn’t crone only interested in audio?
does it need to get involved with audio rate modulation? can’t SC just get this directly?

yes, the script are just for debugging. sclang and other process are handled by systemd:
[ https://github.com/monome/norns-image/blob/master/config/norns-sclang.service ]

the server itself is booted from the Crone class in sclang. (this is a pretty normal way to start a server process in supercollider.) we use the default I/O bus count. (which is 2 in, 2 out.) if you want to explicitly set that or other options i would do it with a ServerOptions here:
[ https://github.com/monome/norns/blob/master/sc/core/Crone.sc#L68 ]

something like

Server.scsynth;
server = Server.local;
server.options.numOutputBusChannels = 8;
//.... etc
server.waitForBoot { Crone.finishBoot; };

you could also launch scsynth explicitly from another service and set the Crone.useRemoteServer classvar. but i doubt there’s any need or benefit to doing this and it is more complicated.

i would not get into modifying the mixer client, but up to you. (for what it’s worth, bus channel count is a template specialization, softcut should actually work fine for manipulating DC buffers, &c.)

1 Like

Had to put this aside for a week while I travelled for work, but managed to find time to check out more of the code and the SC docs to get an idea of where to go next.

First is the good news, the changes to book scsynth and connect it to the remaining ES-8 I/O is indeed quite simple! See the diff here: https://github.com/monome/norns/compare/master...moogah:jefarr_es8_support

Now I’m looking into the best method for adding this code without creating something that just crashes if I’ve not connected a powered on ES-8 before I boot Norns.

Unfortunately jack doesn’t seem to expose much info about devices to a Client, or at least the scsynth Server and ServerOptions classes don’t have methods to access this. So I’ll need to maybe get matron aware of this info and send in flags to crone engine so it’ll start up accordingly… and this is probably good, because I also need to figure out how to manage the systemd stuff.

The end UX I think will be some extra options in System -> Devices that will reboot the appropriate services in “es8 mode”. This may be wonky still, since currently jack doesn’t appear to know about the existence of the ES-8 without first restarting the service.

After playing around a bit, I do think that connecting the extra I/O directly to SC makes more sense than trying to extend Crone.

1 Like

because the jack server connects to a single specific device when it is launched - in this case by systemd - and that is the device available to clients when they are created / connected. device discovery is totally separate (in fact i believe jack relies on the driver backend for this - viz., ALSA.)

you already found the correct invocation to pick your soundcard when starting jack. so, edit your norns-jack.service appropriately. presently, there is no convenient way to change this on the fly and still use systemd to manage norns process dependencies. if we wanted to extend this, i would use an environment variable for the device name, change the var, and restart the service.

but of course, in developing norns stack we were (/are) not generally worried about supporting dynamic audio device changes.

sure it does. the jack API function is jack_get_ports(). see the API docs. this returns a NULL-terminated lists of ports matching specified flags.

for example to get physical ADC ports, as we do in crone::Client::connectADCPorts():

 const char **ports = jack_get_ports (client, nullptr, nullptr,
                                                 JackPortIsPhysical | JackPortIsOutput);

(potential point of confusion: JackPortIsOutput means the port is a source - viz, an ADC - and JackPortIsInput means it is a sink (DAC)).

and then loop over ports until you see a NULL. (we don’t check system port count at present in crone because we are only asking for stereo I/O.)

and if you want, here is a tiny standalone C program that reports ADC and DAC channel counts.

compile with -ljack

#include <jack/jack.h>
#include <stdio.h>

int count_ports(const char **ports) {
    int count=0;
    const char *port;
    do {
	port = ports[count];
	if (port == NULL) { break; }
	count++;
    } while (1);
    return count;
}

int main() {
    jack_status_t status;
    jack_client_t *client = jack_client_open("counter", JackNullOption, &status, NULL);
    if (client == NULL) { return 1; }
    
    const char **adc_ports = jack_get_ports (client, NULL, NULL,
					     JackPortIsPhysical|JackPortIsOutput);

    const char **dac_ports = jack_get_ports (client, NULL, NULL,
					     JackPortIsPhysical|JackPortIsInput);

    printf("ADC ports: %d\n", count_ports(adc_ports));
    printf("DAC ports: %d\n", count_ports(dac_ports));
    
    jack_client_close(client);
	    
    return 0;
}

or at least the scsynth Server and ServerOptions classes don’t have methods to access this

that is true on linux (oddly.) i guess the expectation is that linux users will manage things from the environment. there are SC_JACK_DEFAULT_INPUTS and SC_JACK_DEFAULT_OUTPUTS variables for example. we override these in Crone.sc with the hacky shell commands you found b/c we don’t want SC to connect to physical ports by default.

i guess linking to jack is an option, but in general we don’t want to set up a dependency like that. you can always use the quick and dirty method of capturing jack_lsb and searching for system:capture and system:playback patterns as you’ve already done.

but what i’d recommend as the cleanest method would be to extend crone process with an explicit hardware port count. matron and sclang and whatever can then query that via OSC.

I like the idea of using the I/O count in crone and OSC to query that info, I’m new to OSC and still adjusting my brain to see it as a networked protocol and maybe it helps with my current pursuit:

It looks maybe possible to extend device_monitor in matron to detect a usb soundcard being plugged in?

I think this gets much closer to having norns react to the card when it’s present and then being able to reboot systems that need it.

i guess that’s possible.

to be clear, i’m suggesting things that mght help you with your use case, but i don’t think any of this is going in upstream norns. it is too much functional fragmentation. norns scripts and engines are supposed to be shareable, and I think accomodating a feature like this in a general sense (“use any audio device with any script, any engine”) will have a lot of ramifications.

(for starters: let’s say you want to hotplug audio device and use the USB monitor module as you suggested. As it is, matron process actually has to reset itself and wait again on audio processea so it can do IPC handshakes. Now guess what, lots of midi adapters present themselves as aufio-class devices, libusb can’t tell the difference …)

3.0 should be more amenable to just treating the system as a launcher for whatever SC stuff.

1 Like

Sorry if I’m being dense, but does any of the above indicate that the built-in I/O can be used concurrently with external devices? SuperCollider with CV I/O makes me salivate, but I don’t want these nice converters to go to waste.

Also, running the above, I get the following error while Why? plonks along in the background, so I’m thoroughly confused. Maybe I just need to power cycle.

~ $ jack_lsp -c
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JACK server not running

No. It’s theoretically possible with hacks that wrap alsa sessions as jack ports. This is a can of worms.

Not sure what’s up with that jack_lsp result. One stupid question is, are you sure you’re shelled into norns there? (Doesn’t look like norns prompt iirc?)

1 Like

Yikes. This sounds like that dbus thing I was reading about back when I first set up jack in Arch.

Yep, I’m shelled in alright, I just removed the IP address before the ~.

Ok I’m trying to get this going with my ES-9 so I can use its I/O for cv, gates and triggers. by the looks of it I’ll have to use it as my main out as well which is fine.

At the moment I’m connected via SSH and making my way to norns-image/config/ it’s the only place I see a “norns-jack.service” file but if I edit it nothing changes.

I’m assuming my HW id should be ES9, what did you google to find this information. also am I even working in the right file?

Thanks!

no, it’s installed at /etc/systemd/system/norns-jack.service

(NB: this can and probably will be overwritten by norns update scripts)

1 Like

Also, the startup command for jack is in no way guaranteed to accept ES9 as a parameter, and I really wish I knew more about how to research this, but sadly I’ve not found the time in all these months.

oh right

this stackexhange answer covers everything i know about device names as understood by jack / alsa. in summary:

  • aplay -l and arecord -l will list “cards” and “devices” supporting output and input respectively. these are the “raw” indices used in the syntax like hw:1,0
  • however, the “raw” indices (scare quotes because i just made it up) are brittle, and can be reordered if you’re using multiple plug/play devices.
  • so, card indices also have aliases like “USB” or “PCH”. these can be discovered using cat /proc/asound/cards. (at the moment i am not sure what happens with, say, multiple USB cards.)

any further insights appreciated

3 Likes

That’s very encouraging, if it’s just an alias for the device ID then ES9 may just work, and if it does’t we can discover the right alias easily :slight_smile:

… one real important caveat @Reinert_Wasserman! While I was doing this with the ES-8, if unplugged the USB cable while norns was running, it would lock up norns such that the only fix was to wait for the battery to die, then on next startup very quickly edit the unit files… so this isn’t exactly stable …

I briefly scanned syslog looking for some process that went haywire, but didn’t see a smoking gun. Needs more experimentation.

1 Like

Whoa! Like you can’t even connect via serial or get the white button to work (?!?)? This is most likely either hitting 100% CPU usage or a kernel panic, in the 100% CPU case I would expect you to still get a screen session eventually. Might want to work on this kind of thing with an SSH or serial connection open running journalctl -f or dmesg | tail -f to keep an eye on system logs. If you are in fact getting a kernel panic I expect the panic to dump logs to the serial TTY no matter what else is running, though it’s possible that an SSH session would die.

Thanks @moogah @zebra
As I was reading your replies I thought I had given up because the purpose of this exercise is to use the audio ins to clock a René like sequencer.

I went ahead experimenting with the inputs on my Norns Shield and I found no success but, the Norns is probably AC coupled so the ES-9 might just work :slight_smile:

Sadly I haven’t had time to investigate this, partly because I’m less interested in solving what I consider a symptom of a larger issue, which is figuring out how to start up the norns services correctly depending on which device is present.

Posting this here, mostly for my own memory when I get a moment to return to this effort (currently don’t have an es-8 :frowning:). Seems like systemd has tools for sorting it out, maybe?

1 Like