Connect-OPZ: using USB audio with norns

This is so rad, thanks a lot @xmacex, I’m in love with passing everything over usb and I just wanted to chime in and share the udev file I made for my digitakt if that helps anyone implementing it themself.

Ps: one can also substitute alsa_in for alsa_out in the service files in order to stream the audio from the norns shield or fates to the digitakt and record samples.

PPs: for managing jack connections I use this little program called jack plumbing, I found it to be flexible and very reliable

Pppssshh: I’ve been trying to make this awesome project work on Fates which would enable streaming the 8 separate digitakt tracks as jack inputs (for usage with Orac) but I never got this far, loading the kernel module made it crash systematically…

2 Likes

Also just here to express interest.

I think there are multiple arguments for essentially audio over USB.
connecting Norns to a higher quality sound card would be a huge win, regardless if it’s for the shield, fates, or original hardware. I think the fidelity on these devices are usable in most cases but, if the option is there for something better I’ll use it for sure.

The argument that I think would interest more users is the option to record straight into a DAW over USB like the new OP-1 update.
I have definitely experienced a healthy amount of digital noise on my outputs, especially when I have a MIDI device connected.

USB audio would just be clean and convenient.


THIS IS AN EDIT BECAUSE I CAN’T REPLY CONSECUTIVELY:


I have a couple of questions here.

I’m trying to adapt this script so I can change the audio device in the parameter screen. If I’m successful I’m hoping this would make it as easy as the MidiGrid library where you just need to include it in any script and the option would be available in your params to toggle between devices.

a very handy command I’ve found on the Jack website is “cat /proc/asound/cards” which easily allows you to identify any audio devices connected to the Norns.

Identifying my OP1

Running os.execute('cat /proc/asound/cards') you can see Norns is on hw:0 and the OP1 on hw:1

os.execute('cat /proc/asound/cards')
 0 [sndrpimonome   ]: snd_rpi_monome - snd_rpi_monome
                      snd_rpi_monome
 1 [OP1            ]: USB-Audio - OP-1
                      Teenage Engineering AB OP-1 at usb-3f980000.usb-1.4, high speed
true	exit	0```

This seems to be easy enough for most to figure out on their own but could be useful to make a script that runs it and automatically adds all your devices to a table that you could easily scroll through if you have multiple devices that you use on different ocasions.

Similarly os.execute('lsusb') can identify the ID as @Justmat mentioned above but, I’m not sure how to pair the correct ID with its device as the current method is simply running the command again with your device disconnected and seeing what changed.

It would take me a while to get there though as I’m still trying to adapt this script to work as a Param.
I thought it would be pretty straightforward but, it’s been a little bit of a struggle.

In theory, it should be as simple as the below script. (excluding some safety precautions like checking if the OP1 is connected.)

Change input in Params
params:add_separator("Set Audio Device")
devices = {"Norns","OP1"}
  params:add_option("Input Device","Input Device",devices,1)
  params:add_option("Output Device","Output Device",devices,1)

device_state = params:get("Input Device")
  if device_in_state == 1 then
      os.execute(_path.this.lib..'disconnect-opz-input.sh')
  elseif decice_in_state == 2 then
-- I plan on always resetting the i/o to Norns default before switching to a new device 
      os.execute(_path.this.lib..'disconnect-opz-input.sh')
      os.execute(_path.this.lib..'connect-opz-input.sh')
  end

I’ve even simply tried running os.execute(_path.this.lib..'connect-opz-input.sh') but no luck.
I don’t think the “connect-opz-input.sh” file is actually being executed. I’m trying to find information on how the os.execute command actually works and how it executes a specified file I’ve tried pointing it using the actual file path which should be /dust/code/connect-op1/lib but I end up running into several errors like:

lua:

attempt to call a string value

stack traceback:

Any help here?

PS.
I’ve successfully connected my OP1 with the stock script as I assume everyone else on this thread has also done and how the script is intended. The only problem I’ve run into there is not being able to set both the IN and the OUT as TRUE which causes feedback. I assume this is due to the OP1 sending whatever it’s listening to, to its output and the Norns is doing the same.

5 Likes

I’m unable to get the plug-and-play branch up and running. here’s my setup/install process

$ sudo ln -s ./99-opz.rules /etc/udev/rules.d/99-opz.rules
$ sudo udevadm control --reload && sudo udevadm trigger

So far so good…

But then, on my Fates unit ~/.config/systemd/user/ didn’t exist so I had to create it

$ mkdir -p ~/.config/systemd/user/
$ sudo ln -s ./opz-audio-input.service $HOME/.config/systemd/user/opz-audio-input.service
$ systemctl --user daemon-reload

I then (sometimes) get the following error:

Failed to connect to bus: No such file or directory

Or… I’ll get no response and Fates freezes. Regardless, I hear no sound from my OP-Z.

I’ve restarted Norns from both the UI and CLI sudo reboot and removed all files and re-executed above steps. No dice. Where am I going awry?

try looking at systemctl status opz-audio-input.service and/or journalctl -r

also look at the permissions on the service. I’ve not ever tried running a systemd service via symlink so not sure if that’s an issue or not. Usually I’d just copy opz-audio-input.service to /etc/systemd/system and those typically have permissions of -rw-r--r--

maybe also sudo systemctl daemon-reload instead of systemctl --user daemon-reload

1 Like

This experimental plug-and-play branch is so unstable :frowning: I’m so sorry! @okyeron 's advice is warranted, although having a symlink for the user service is fine for me, and has the benefit of keeping it within the version control system (I find hardlinks confusing, as I do copies of files).

What does your journalctl -f give when connecting the OP-Z? Some murderous -19 errors? I get those on disconnect sometimes.

Does issuing systemctl --user start opz-audio-input.service after connecting the device work? For me the biggest source of uncertainty seems to be to have udev run the user service… maybe something somewhere needs some delay to bring hardware online or something.

It may interest people on this thread that I have had zero problems just using the “obvious” method of selecting a different soundcard - changing the alsa device number, period and buffer size passed to jackd in norns-jack.service.

(The buffer size generally must be larger than 128 and usually 2 periods is appropriate. I’ve used several class compliant USB interfaces without issue, but not with any teenage engineering devices since I don’t have them.)

I’m sure this has been discussed somewhere up thread but seemed worth mentioning again (?)

The method of piping to alsa_in and alsa_out will always incur CPU overhead as it performs resampling and whatnot.

So if someone is arriving here just trying to use a USB interface with norns shield… I would try the direct route first.

6 Likes

Yes absolutely, this is where i started from too and it works super well. This whole contraption is all about having a second sound card, and not needing a computer or terminal access to modify files etc so that things can be achieved in the “norns user land”.

1 Like

thanks for the tips, I’m still not getting an audible out from jacks or visible output on the monitor screen. I have update 210706 installed.

Here’s what I’m doing (following @okyeron’s advice):

$ cd dust/code/connect-opz
$ sudo cp ./99-opz.rules /etc/udev/rules.d/99-opz.rules
$ sudo udevadm control --reload && sudo udevadm trigger
$ mkdir -p /etc/systemd/system
$ sudo cp ./opz-audio-input.service /etc/systemd/system/opz-audio-input.service
$ sudo systemctl daemon-reload

and @xmacex here’s my journalctl -f output when I connect the OP-Z

Sep 04 17:46:55 norns kernel: usb 1-1.3: new high-speed USB device number 10 using xhci_hcd
Sep 04 17:46:56 norns kernel: usb 1-1.3: New USB device found, idVendor=2367, idProduct=000c, bcdDevice= 2.57
Sep 04 17:46:56 norns kernel: usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Sep 04 17:46:56 norns kernel: usb 1-1.3: Product: OP-Z
Sep 04 17:46:56 norns kernel: usb 1-1.3: Manufacturer: teenage engineering ab
Sep 04 17:46:56 norns kernel: usb 1-1.3: SerialNumber: X1LQEJPX
Sep 04 17:46:56 norns mtp-probe[1881]: checking bus 1, device 10: "/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.3"
Sep 04 17:46:56 norns mtp-probe[1881]: bus: 1, device: 10 was not an MTP device
Sep 04 17:46:56 norns bash[460]: device_monitor(): adding midi device OP-Z
Sep 04 17:46:56 norns systemd-udevd[1887]: Process '/usr/sbin/alsactl -E HOME=/run/alsa restore 1' failed with exit code 99.
Sep 04 17:46:56 norns mtp-probe[1889]: checking bus 1, device 10: "/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.3"
Sep 04 17:46:56 norns mtp-probe[1889]: bus: 1, device: 10 was not an MTP device
Sep 04 17:46:56 norns bash[460]: device_monitor(): adding midi device OP-Z

and this is what I get when I disconnect it:

Sep 04 17:47:29 norns kernel: usb 1-1.3: USB disconnect, device number 10
Sep 04 17:47:29 norns bash[460]: midi inconsistency for device: OP-Z
Sep 04 17:47:29 norns bash[460]: ALSA lib rawmidi_hw.c:111:(snd_rawmidi_hw_status) SNDRV_RAWMIDI_IOCTL_STATUS failed: No such device

WDYT?

Thanks. What does running systemctl --user start opz-audio-input.service do, after the OP-Z has been physically connected?

EDIT oops what does sudo systemctl start opz-audio-input.service do, you have it as a system service I see.

I just flipped on my OP-Z after a norns restart, and it came online as an audio device straight away. This stuff isn’t exactly straightforward to debug with all this hardware stuff :sweat_smile:

sudo systemctl start opz-audio-input.service outputs:

Job for opz-audio-input.service failed because the control process exited with error code.
See "systemctl status opz-audio-input.service" and "journalctl -xe" for details.

systemctl status opz-audio-input.service outputs:

● opz-audio-input.service - USB Audio for OP-Z
   Loaded: loaded (/etc/systemd/system/opz-audio-input.service; static; vendor preset: enabled)
   Active: failed (Result: exit-code) since Sat 2021-09-04 18:55:53 CDT; 30s ago
  Process: 1649 ExecStart=/home/we/dust/code/connect-opz/lib/connect-opz-input.sh (code=exited, status=1/FAILURE)

Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JACK server not running?
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: Cannot connect to server socket err = No such file or directory
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: Cannot connect to server request channel
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: jack server is not running or cannot be started
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JACK server not running?
Sep 04 18:55:53 norns systemd[1]: opz-audio-input.service: Control process exited, code=exited, status=1/FAILURE
Sep 04 18:55:53 norns systemd[1]: opz-audio-input.service: Failed with result 'exit-code'.
Sep 04 18:55:53 norns systemd[1]: Failed to start USB Audio for OP-Z.

and journalctl -xe outputs:

-- 
-- The job identifier is 1157.
Sep 04 18:55:52 norns connect-opz-input.sh[1649]: Cannot connect to server socket err = No such file or directory
Sep 04 18:55:52 norns connect-opz-input.sh[1649]: Cannot connect to server request channel
Sep 04 18:55:52 norns connect-opz-input.sh[1649]: jack server is not running or cannot be started
Sep 04 18:55:52 norns connect-opz-input.sh[1649]: JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Sep 04 18:55:52 norns connect-opz-input.sh[1649]: jack server not running?
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: Cannot connect to server socket err = No such file or directory
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: Cannot connect to server request channel
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: jack server is not running or cannot be started
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JACK server not running?
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: Cannot connect to server socket err = No such file or directory
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: Cannot connect to server request channel
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: jack server is not running or cannot be started
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JACK server not running?
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: Cannot connect to server socket err = No such file or directory
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: Cannot connect to server request channel
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: jack server is not running or cannot be started
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JACK server not running?
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: Cannot connect to server socket err = No such file or directory
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: Cannot connect to server request channel
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: jack server is not running or cannot be started
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Sep 04 18:55:53 norns connect-opz-input.sh[1649]: JACK server not running?
Sep 04 18:55:53 norns systemd[1]: opz-audio-input.service: Control process exited, code=exited, status=1/FAILURE
-- Subject: Unit process exited
-- Defined-By: systemd
-- Support: https://www.debian.org/support
-- 
-- An ExecStart= process belonging to unit opz-audio-input.service has exited.
-- 
-- The process' exit code is 'exited' and its exit status is 1.
Sep 04 18:55:53 norns systemd[1]: opz-audio-input.service: Failed with result 'exit-code'.
-- Subject: Unit failed
-- Defined-By: systemd
-- Support: https://www.debian.org/support
-- 
-- The unit opz-audio-input.service has entered the 'failed' state with result 'exit-code'.
Sep 04 18:55:53 norns systemd[1]: Failed to start USB Audio for OP-Z.
-- Subject: A start job for unit opz-audio-input.service has failed
-- Defined-By: systemd
-- Support: https://www.debian.org/support
-- 
-- A start job for unit opz-audio-input.service has finished with a failure.
-- 
-- The job identifier is 1157 and the job result is failed.

EDIT

If I use @xmacex original directories, but copy instead of symlink

$ sudo cp ./99-opz.rules /etc/udev/rules.d/99-opz.rules
$ sudo cp ./opz-audio-input.service $HOME/.config/systemd/user/opz-audio-input.service

…and then run systemctl --user start opz-audio-input.service && systemctl --user daemon-reload I can hear the OP-Z at the correct volume for ~1 second then the volume cuts to a very low level, but it’s still audible.

Upon RESET or sudo reboot there’s no audio, unless I run the above again.

FWIW if I run systemctl daemon-reload without sudo I get asked for root password (which I don’t know)

==== AUTHENTICATING FOR org.freedesktop.systemd1.reload-daemon ===
Authentication is required to reload the systemd state.
Authenticating as: root

Forgive my ignorance but are there any docs on how to do this?

1 Like

This file is installed on norns at /etc/systemd/system. Thi is what’s called a “systemd unit file”, which specifies how to start a specific service, in this case the Jack audio server, which lets software speak to audio hardware.

Line 11, that starts with ExecStart is the shell command that launches Jack, which norns then connects to. The argument -d hw:0 tells jack to use the soundcard called hw:0, which is the built-in one. If you plug a USB sound card in, it will most likely be called hw:1. So you can change line 11 to say -d hw:1, and norns will use that when it starts up. This will require a reboot or using systemctl to restart all the required services. From a quick glance, it looks like you might be able to just run systemctl restart norns.target for it to take effect.

4 Likes

Amazing, much appreciated I’ll give this a shot.

1 Like

That’s exactly the procedure :slight_smile:

That looks right. On restarting the service I think You will also get a prompt from the system about reloading the systemd daemon or something.

As far as settings, for USB I’d suggest starting with a very large buffer size and two periods: -n 1024 -p 2

If that works well you can then decrease the buffer size, but probably shouldn’t expect to go below 256.

same story different protagonist…

M8 into norns pedalboard:
https://www.instagram.com/p/CTdMnpqpqOz/

FWIW - I did the install per the plug-n-play github instructions (with a bunch of modifications for the different device). It didn’t want to work properly when I moved the system unit into /etc/systemd/system

8 Likes

i was speculating with someone a while back on the m8 discord about whether such a thing seemed possible, super excited to see that it is indeed!

2 Likes

Just wanted to close the loops on this and I got it to work with both op-z and my focusrite audio interface! Thanks @rvense and @zebra for the support! I edited norns-jack.service via terminal and got it working keeping the default buffer size and periods -n 3 -p 128 but I’ll play around with your recommendation.

I’ll keep my eye on connect-opz because having usb audio + norns in/outs simultaneously comes in super clutch! Thanks @xmacex!

3 Likes

Just changed line 11 of /etc/systemd/system/norns-jack.service to hw:1 and it works great with my op-1. Thank you for this information @zebra and @xmacex, gamechanger!

Now on to figuring out using the norns outs with the op-1 ins… and yes, it crashes Norns to pull the op-1 out.

1 Like

combining the inputs from one device with the outputs of another device is the motivation for the project that is the original topic of this thread. you do need something like alsa_in for this, and there is unavoidable overhead/complexity because e.g. devices may be at different sample rates etc etc.

since i was seeing people on this thread who don’t have that need and simply want to use a USB interface (e.g. bypassing the unsourceable codec IC in a DIY build), i thought i should point out an IMO better solution for that use case in particular.

2 Likes