This tutorial guides you through setting up CamillaDSP on a Raspberry Pi Snapcast client. The goal is to process the audio stream from your Snapserver with CamillaDSP for equalization or room correction before playing it on the client's DAC.
This setup uses a virtual ALSA Loopback device, which acts like a software audio cable to route audio between applications.
Snapclient → ALSA Loopback (Input) → CamillaDSP (Processing) → ALSA Loopback (Output) → Your DAC
Before you begin, ensure you have:
- A Raspberry Pi (4 or 5 recommended) running a 64-bit version of Raspberry Pi OS (Bookworm).
- A working Snapclient installation connected to your Snapserver.
- A DAC (Digital-to-Analog Converter) connected to your Pi.
- An active SSH session to your client Pi.
First, let's get the necessary software installed on your client Pi.
Organize your configuration and filter files.
mkdir -p ~/camilladsp/configs ~/camilladsp/coeffsThis provides tools for managing your audio devices.
sudo apt-get update
sudo apt-get install -y alsa-utilsFetch the latest aarch64 binary from the official releases page and place it in /usr/local/bin/.
wget https://github.com/HEnquist/camilladsp/releases/download/v2.0.3/camilladsp-linux-aarch64.tar.gz -P ~/camilladsp/
sudo tar -xvf ~/camilladsp/camilladsp-linux-aarch64.tar.gz -C /usr/local/bin/To route audio from Snapclient to CamillaDSP, we need to create a virtual sound card.
This command loads the snd-aloop module, which creates the loopback device.
sudo modprobe snd-aloopTo ensure the module loads on every reboot, create a configuration file.
echo "snd-aloop" | sudo tee /etc/modules-load.d/snd-aloop.confCheck that the virtual card was created successfully.
aplay -lYou should see a new card in the list, typically named Loopback.
Instruct Snapclient to send its audio to the input of our virtual cable instead of directly to your DAC.
sudo nano /etc/snapclient.confFind the sound_device line (it may be commented out with a #). Change it to point to the first subdevice of the Loopback card. Using the plughw plugin is more robust and helps avoid "device busy" errors.
# /etc/snapclient.conf
# The soundcard to use, find the correct one with "snapclient -l"
sound_device = plughw:Loopback,0,0Apply the new configuration.
sudo systemctl restart snapclientCreate the CamillaDSP configuration file. This will tell it to:
- Capture audio from the output of the virtual cable.
- Process the audio with your desired filters.
- Playback the final audio to your real DAC.
nano ~/camilladsp/configs/client_config.ymlCopy and paste this entire block into the file. Important: You must change the playback device to match your DAC's name from the aplay -l command.
# ~/camilladsp/configs/client_config.yml
devices:
samplerate: 48000
chunksize: 1024
enable_rate_adjust: true
target_level: 1024
capture:
type: Alsa
channels: 2
device: "hw:Loopback,1,0"
format: S16LE
playback:
type: Alsa
channels: 2
device: "plughw:CARD=DigiAMP,DEV=0" # IMPORTANT: Set this to your real DAC
format: S16LE
filters:
# This is a placeholder filter that does nothing.
# You can add your real EQ/filter settings here later.
example_filter:
type: Biquad
parameters:
type: Peaking
freq: 1000
q: 0.7
gain: 0.0
pipeline:
- type: Filter
channel: 0
names:
- example_filter
- type: Filter
channel: 1
names:
- example_filterHere are a few examples of what the device line in your client_config.yml might look like for common DACs. The card name comes from the output of the aplay -l command.
-
HiFiBerry DAC+ Pro / RPi DAC Pro: If
aplay -lshowscard 0: Pro [RPi DAC Pro]..., use:device: "plughw:CARD=Pro,DEV=0"
-
HiFiBerry Digi/DAC/Amp series (e.g., Amp2, Amp4): If
aplay -lshows a card name likesndrpihifiberry, use:device: "plughw:CARD=sndrpihifiberry,DEV=0"
-
IQaudIO DAC Pro: If
aplay -lshows a card name likeIQaudIODAC, use:device: "plughw:CARD=IQaudIODAC,DEV=0"
-
Generic USB DAC: If
aplay -lshows a card name likeDAC,USB, or the manufacturer's name, use that name:device: "plughw:CARD=DAC,DEV=0"
To make this setup robust, we'll run CamillaDSP as a systemd service that automatically starts after Snapclient.
sudo nano /etc/systemd/system/camilladsp.serviceThis configuration ensures snapclient is running before camilladsp starts. Replace <your_user> with your actual username (e.g., pi).
# /etc/systemd/system/camilladsp.service
[Unit]
Description=CamillaDSP
# This ensures snapclient is started first
Wants=snapclient.service
After=snapclient.service
[Service]
Type=simple
User=<your_user>
# Enable the websocket and set the port for the GUI to connect.
ExecStart=/usr/local/bin/camilladsp --address 0.0.0.0 --port 1234 /home/<your_user>/camilladsp/configs/client_config.yml
Restart=always
RestartSec=1
[Install]
WantedBy=multi-user.targetThis applies all your changes.
sudo systemctl daemon-reload
sudo systemctl enable camilladsp
sudo systemctl restart snapclient
sudo systemctl restart camilladspVerify that both services are running without errors.
sudo systemctl status snapclient
sudo systemctl status camilladspIf both are active (running), you're all set! Start playing audio from your Snapserver, and it should now be processed by CamillaDSP on your client before you hear it.
CamillaGUI provides a powerful web interface to control CamillaDSP in real-time. This allows you to adjust volume, mute, select configurations, and view a live spectrum analyzer from any device on your network.
We only need unzip for the frontend files.
sudo apt-get update
sudo apt-get install -y unzipWe'll create a dedicated directory and download the latest versions of the backend binary and the frontend web files.
# Create the parent directory
mkdir -p ~/camillagui
cd ~/camillagui
# Download the backend binary for 64-bit ARM (aarch64)
wget https://github.com/HEnquist/camillagui-backend/releases/download/v3.0.3/bundle_linux_aarch64.tar.gz
# Download the frontend web interface
wget https://github.com/HEnquist/camillagui/releases/latest/download/camillagui.zip
# Extract both components
tar -xvf bundle_linux_aarch64.tar.gz
unzip camillagui.zipBefore creating a service, it's vital to test that the GUI server can run correctly.
- Navigate into the correct backend directory:
cd ~/camillagui/camillagui_backend
- Run the server manually:
./camillagui_backend
- Check the output. The server will log the port it is running on. It should be
5005.Starting server Listening on 0.0.0.0:5005 - Open a web browser on your computer (on the same network) and go to:
http://<your-pi-ip-address>:5005
You should see the CamillaGUI interface. If it works, you can stop the manual server by pressing Ctrl+C in your SSH session.
Once the manual test works, we can create a service to run it automatically.
sudo nano /etc/systemd/system/camillagui.servicePaste the following configuration. Remember to replace <your_user> with your actual username (e.g., byrds or pi). This version uses the corrected paths and executable name.
# /etc/systemd/system/camillagui.service
[Unit]
Description=CamillaDSP GUI
# Start after the main camilladsp service
Wants=camilladsp.service
After=camilladsp.service
[Service]
Type=simple
User=<your_user>
# CORRECTED: The WorkingDirectory based on the extracted folder
WorkingDirectory=/home/<your_user>/camillagui/camillagui_backend
# CORRECTED: The ExecStart path and executable name
ExecStart=/home/<your_user>/camillagui/camillagui_backend/camillagui_backend
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.targetNow, enable the service to start on boot and start it immediately.
sudo systemctl daemon-reload
sudo systemctl enable --now camillagui.serviceCheck that the service is running correctly:
sudo systemctl status camillagui.serviceIf it shows active (running), you can now access the GUI permanently at http://<your-pi-ip-address>:5005.
If the camillagui.service fails to start, it's almost always a pathing issue. Here's what to check:
-
Confirm the Directory Name: Run
ls ~/camillagui. Your output should show thecamillagui_backenddirectory and thecamillagui(frontend) directory. If the backend directory has a different name (e.g., includes a version number), you must update theWorkingDirectoryandExecStartpaths in yourcamillagui.servicefile to match. -
Check the Service Log: Use
journalctl -u camillagui.serviceto see detailed error messages. A "No such file or directory" or "code=exited, status=203/EXEC" error confirms the path in your service file is wrong. -
Run Manually First: Always re-run the manual test from step 6.3. If it works there, the problem is guaranteed to be in the
.servicefile. If it fails there, the download or extraction may have been corrupted. -
Start Camilla dsp websocket manually
camilladsp --address 0.0.0.0 --port 1234 ~/camilladsp/configs/client_config.yml