I’ve built a Raspberry Pi 4 into my eurorack case to run MODEP for end of chain processing / mastering of my live sets. I had a lot of trouble getting the Raspberry Pi Codec Zero hat to work for audio in and out for processing.
Drawing on various threads here and also looking at the code used for the Pistomp project, as well as lots of troubleshooting using Claude I’ve now managed to get it to work reliably. It’s not the fastest boot and I’ve given up trying to optimise it further because it appears that the card just needs time to boot up and get a stable connection - which is big part of what the setup below deals with.
I thought I’d share what I have learned here so that anyone else trying to use this card can learn from it too. It’s a pretty good solution for me for good quality stereo audio i/o for MODEP.
I’ve now got it working reliably and headless in my eurorack case. Sounds great too! I had to add some electronics to get it working how I wanted. The input at eurorack level needs a step down with some resistors to the line level the hat expects. I also found the output very low, not ideal for a live performance system, so I added a line level amplifier to it to step it up.
This is using the latest (as of this post) Bookworm download of Patchbox. I’ve found it needs the kernel update from running rpi-update to have the latest overlays for this HAT.,
The below is taken from my Claude chat I’ve used to get this figured out and working:
The Problem: Your Audio Script Runs Before the Card Is Ready
The Codec Zero uses I²C and I²S to communicate with the Pi, and ALSA (the Linux audio subsystem) needs to fully initialise before your audio script can use it. On Patchbox OS, services start fast — often faster than the HAT is ready. The result is a script that launches, can’t find the audio device, and either crashes silently or plays nothing.
You can verify this is your problem by running:
aplay -l
If you don’t see the Codec Zero listed, ALSA hasn’t finished setting it up yet. Run it again a few seconds later and it’ll appear. That gap is where things are failing.
Step 1: Get the Overlay Right in config.txt
Before anything else, you need the correct device tree overlay loaded. Add these lines to /boot/firmware/config.txt:
dtparam=i2c_arm=on
dtparam=i2s=on
dtoverlay=rpi-codeczero
You also need the overlay file itself. If it’s not already present in /boot/overlays/:
sudo wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/overlays/rpi-codeczero.dtbo -O /boot/overlays/rpi-codeczero.dtbo
Without this, the card simply won’t appear to the system at all.
Step 2: Restore the ALSA State — But With a Delay
The Codec Zero needs its mixer controls set correctly at boot, which is done with alsactl restore using a state file from the Pi-Codec repo. The problem is timing — if you run this too early the chip isn’t ready, and it silently fails.
The fix is a systemd drop-in override for the alsa-restore service that adds a 15-second delay and points to your saved state file:
/etc/systemd/system/alsa-restore.service.d/override.conf
[Service]
ExecStartPre=/bin/sleep 15
ExecStart=
ExecStart=/usr/sbin/alsactl -E HOME=/run/alsa -E XDG_RUNTIME_DIR=/run/alsa/runtime restore -f /home/patch/setupfiles/alsastate-hi-volume-output.state
The blank ExecStart= line clears the original command before setting the new one — that’s intentional and required for systemd overrides.
Save your working state (once the card is configured correctly) with:
sudo alsactl store
Or grab a baseline from the Pi-Codec repo:
git clone https://github.com/raspberrypi/Pi-Codec
sudo alsactl restore -f Pi-Codec/Codec_Zero_AUXIN_record_and_HP_playback.state
Step 3: Fix the Service Dependency Chain
MODEP runs several services that depend on each other: JACK needs ALSA ready, mod-host needs JACK, and mod-ui needs mod-host. By default these don’t always wait for each other properly. Use systemd drop-in overrides to enforce the correct order.
/etc/systemd/system/jack.service.d/override.conf:
[Unit]
After=rc-local.service
Requires=rc-local.service
/etc/systemd/system/modep-mod-host.service.d/override.conf:
[Unit]
After=jack.service
Requires=jack.service
/etc/systemd/system/modep-mod-ui.service.d/override.conf:
[Unit]
After=modep-mod-host.service jack.service
Requires=modep-mod-host.service jack.service
After adding any overrides, reload systemd:
sudo systemctl daemon-reload
Step 4: Add a Watchdog for Cold Boot Failures
Even with all the above in place, a cold boot (power on from completely off, rather than a reboot) can still leave the audio stack in a broken state. The symptom is MODEP loading fine but producing no sound and JACK showing very low CPU usage from mod-host.
The fix is a watchdog script that runs after boot, detects this condition by checking mod-host’s CPU usage, and kicks the stack back to life if needed:
/usr/local/bin/audio-watchdog.sh:
#!/bin/bash
# Wait for everything to start up
sleep 10
for i in $(seq 1 10); do
MOD_CPU=$(ps aux | grep mod-host | grep -v grep | awk '{print $3}')
echo "mod-host CPU: $MOD_CPU%"
if (( $(echo "$MOD_CPU < 5.0" | bc -l) )); then
echo "Audio appears broken, attempting recovery..."
systemctl stop jack
sleep 2
alsactl restore -f /home/patch/setupfiles/alsastate-hi-volume-output.state
# Play a moment of silence to wake the DAC
aplay -D hw:Zero -f S16_LE -r 48000 -c 2 /dev/zero &
APLAY_PID=$!
sleep 2
kill $APLAY_PID 2>/dev/null
sleep 1
systemctl start jack
sleep 5
systemctl restart modep-mod-host.service
systemctl restart modep-mod-ui.service
echo "Recovery complete"
exit 0
fi
sleep 2
done
echo "Audio appears healthy"
exit 0
sudo chmod +x /usr/local/bin/audio-watchdog.sh
Then a service to run it at boot, after MODEP has had a chance to start:
/etc/systemd/system/audio-watchdog.service:
[Unit]
Description=Audio watchdog - recover from cold boot audio failure
After=modep-mod-host.service
Wants=modep-mod-host.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/audio-watchdog.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable audio-watchdog.service
The key trick inside the script is the silent aplay playback — writing /dev/zero to the hardware device for a couple of seconds is enough to wake the DA7212 codec from whatever half-initialised state it’s stuck in after a cold boot, after which JACK can take over cleanly.
Hope this saves someone a few hours. The cold boot issue in particular is a real gotcha — everything looks like it loaded fine in systemctl status, but there’s no audio. The watchdog approach isn’t elegant but it’s reliable.