xmacex / connect-opz

Connect OP-Z as an audio device on norns.
https://llllllll.co/t/connect-opz-using-usb-audio-with-norns/37819
GNU General Public License v3.0
34 stars 3 forks source link

Reimplement as a systemd service #7

Open xmacex opened 3 years ago

xmacex commented 3 years ago

One idea would be to amend the norns systemd service norns-jackd which is defined in file /etc/systemd/system/norns-jack.service, and change it's -d hw:0 to -d hw:1for alsa.

A variation of the above idea would be to have a different, separate service which connects to -d hw:1 (or by name) to replaces the norns-jack service, perhaps called something like norns-jack-opz.service, and alternate between these two. systemctl --quiet is-enabled norns-jack etc. can be used to programmatically check if a service is currently running.

This would spare running separate processes which eat a lot of CPU. At the same time, this would disable the norns input and output.

It would (partially) make sense to do this at system level rather than a norns program. This would be done by adding udev rule in /etc/udev/rules.d plus writing a program which starts alsa_in and alsa_out when the OP-Z is plugged in and adds the jack routes, and tears this setup down when the OP-Z is disconnected from USB.

xmacex commented 3 years ago

A problem is that this is outside of the norns product, and is messing with the operating system. A dangerous idea.

xmacex commented 3 years ago

Or another variation, the middle ground actually, to run the alsa_in and alsa_out under systemd on udev connect events, and shut them down on disconnect events.

xmacex commented 3 years ago

Made an udev rule with RUN which works if a separate /lib/systemd/systemd-udevd --debug is started, but the one on running system doesn't seem to pick up the new rule even with sudo udevadm control --reload. What's the matter?

xmacex commented 3 years ago

Ok works with this udev-rule in /etc/udev/rules/99-opz:

KERNEL=="pcmC1D0c", ACTION=="add", ATTRS{idVendor}=="2367", ATTRS{idProduct}=="000c", TAG+="systemd", ENV{SYSTEMD_USER_WANTS}+="opz-audio.service"

and the following user service in ~/.config/systemd/user/opz-audio.service:

[Unit]
Description=USB Audio for OP-Z
BindsTo=dev-snd-pcmC1D0c.device
Wants=norns-jack.service

[Service]
Type=forking
ExecStart=/home/we/dust/code/connect-opz/lib/connect-opz-input.sh
ExecStop=/home/we/dust/code/connect-opz/lib/disconnect-opz-input.sh

Now, how to package this for benefit and enjoyment of norns users, since these are both changes outside of ~/dust, and outside of ~ even...?

okyeron commented 3 years ago

Questions: whats the purpose of KERNEL=="pcmC1D0c" in the udev rule?

pcmC1D0c is dynamically assigned and won't always be the same thing if you have multiple devices attached. Thus BindsTo=dev-snd-pcmC1D0c.device becomes problematic with 2 or more devices.

In testing today I've got my M8 tracker working and now also a Zoom H1 Recorder.

I'm curious to see if this approach could be adapted to allow for a more generic set of scripts without having to have different scripts/rules for every possible device.

xmacex commented 3 years ago

Yes that's right. This is sketchy! A more generic rule would definitely respond to all PCM devices. That is possible by listening to kernel events. There is some inference then to be made for alsa_in and the jack connections to route the right device. In the case of OP-Z and other devices, also considering a non-default sample rate. Programming :)

xmacex commented 3 years ago

The udev rule takes glob patterns, e.g. KERNEL=="pcm[0-9][cp], and after they are online, their properties can be inspected in various ways (IIRC) in /sys/and/ or with some generic USB tools or Alsa tools.

Maybe one could generate service descriptions on the fly? ;)