Skip to content

Instantly share code, notes, and snippets.

@torgeir
Last active February 9, 2025 20:45
Show Gist options
  • Save torgeir/e1fc51da45d3491dd4b08ebf35710ebc to your computer and use it in GitHub Desktop.
Save torgeir/e1fc51da45d3491dd4b08ebf35710ebc to your computer and use it in GitHub Desktop.
Raspberry pi 4 guitar pedal setup with neural-amp-modeler-lv2 and ImpulseLoader.lv2
#!/usr/bin/env bash
# Raspberry PI guitar rig
# /home/nam/mod-user-files
# |- 'Aida DSP Models'
# |- 'Audio Loops'
# |- 'Audio Recordings'
# |- 'Audio Samples'
# |- 'Audio Tracks'
# |- 'Hydrogen Drumkits'
# |- 'MIDI Clips'
# |- 'MIDI Songs'
# |- 'NAM Models' <-- put models here
# |- 'Reverb IRs'
# |- 'SF2 Instruments'
# |- 'SFZ Instruments'
# |- 'Speaker Cabinets IRs' <-- put IRs here
# jack period frames, 96 seems to work fine
# low enough latency without pops and clicks
# compile neural amp modeler to optimize for this
export PERIOD_FRAMES=96
# cat /proc/asound/cards, and look for you card
export SOUND_CARD_ALSA_NAME=Device
update_os() {
sudo apt update
sudo apt upgrade
}
ensure_deps() {
sudo apt install -y libasound2-dev g++ cmake alsa-tools alsa-utils
# build lv2 plugins dependencies
sudo apt install -y build-essential git lv2-dev pkg-config libsndfile1-dev libfftw3-dev libcairo2-dev libx11-dev
# mod host dependencies
sudo apt install -y libreadline-dev liblilv-dev lilv-utils libjack-jackd2-dev
# mod ui
sudo apt install -y libjpeg-dev zlib1g-dev python3-setuptools python3-dev libfreetype6-dev authbind
# apps
sudo apt install -y wget tmux git vim netcat-openbsd exa htop
# https://github.com/brummer10/ImpulseLoaderStereo.lv2/issues/4
sudo apt install xxd
# lv2ls to list installed lv2 plugins
sudo apt install -y lilv-utils
# lv2 plugin host https://github.com/drobilla/jalv/
#sudo apt install -y jalv
# guitarix plugins lv2
sudo apt install guitarix-lv2
# git clone https://github.com/x42/darc.lv2.git
# sudo apt-get install libcairo2-dev libpango1.0-dev libglu1-mesa-dev libgl1-mesa-dev
# jack
sudo apt install -y --no-install-recommends jackd2 jack-tools
}
realtime_jack() {
DEBIAN_FRONTEND=noninteractive \
DEBCONF_NONINTERACTIVE_SEEN=true \
sudo dpkg-reconfigure --frontend=noninteractive -p high jackd2
echo
echo "you should log out and log in again (adjusted rtprio)"
echo
}
deps_cleanup() {
sudo apt autoremove
}
create_folders() {
mkdir -p ~/.lv2
mkdir -p ~/bin
mkdir -p ~/plugs
# mod-ui expects these folders
if [ ! -d /home/nam/mod-user-files ]; then
mkdir -p /home/nam/mod-user-files
mkdir -p /home/nam/mod-user-files/Aida DSP Models
mkdir -p /home/nam/mod-user-files/Audio\ Loops
mkdir -p /home/nam/mod-user-files/Audio\ Recordings
mkdir -p /home/nam/mod-user-files/Audio\ Samples
mkdir -p /home/nam/mod-user-files/Audio\ Tracks
mkdir -p /home/nam/mod-user-files/Hydrogen\ Drumkits
mkdir -p /home/nam/mod-user-files/MIDI\ Clips
mkdir -p /home/nam/mod-user-files/MIDI\ Songs
mkdir -p /home/nam/mod-user-files/NAM\ Models
mkdir -p /home/nam/mod-user-files/Reverb\ IRs
mkdir -p /home/nam/mod-user-files/SF2\ Instruments
mkdir -p /home/nam/mod-user-files/SFZ\ Instruments
mkdir -p /home/nam/mod-user-files/Speaker\ Cabinets\ IRs
fi
}
install_mod_host() {
if [ -d mod-host ]; then
return
fi
git clone --recurse-submodules -j4 https://github.com/mod-audio/mod-host.git
pushd mod-host
make
sudo make install
popd
}
install_mod_ui() {
if [ -d mod-ui ]; then
return
fi
git clone https://github.com/moddevices/mod-ui
pushd mod-ui
python -m venv modui-env
source modui-env/bin/activate
pip install -r requirements.txt
make -C utils
# crazy python3.11 tornado hack, mod-ui seems to expect python3.10
sed -i -e 's/collections.MutableMapping/collections.abc.MutableMapping/' \
modui-env/lib/python3.11/site-packages/tornado/httputil.py
popd
}
install_mod_plugins() {
if [ ! -d plugs/mod-lv2-data ]; then
git clone https://github.com/mod-audio/mod-lv2-data.git plugs/mod-lv2-data
fi
# needs apt install guitarix-lv2
cp -r plugs/mod-lv2-data/plugins/gx_*.lv2 ~/.lv2/
cp -r plugs/mod-lv2-data/plugins-fixed/gx_*.lv2 ~/.lv2/
}
install_impulse_loader() {
if [ ! -d plugs/ImpulseLoader.lv2 ]; then
git clone --recurse-submodules -j4 https://github.com/brummer10/ImpulseLoader.lv2.git plugs/ImpulseLoader.lv2
fi
if [ ! -d ~/.lv2/ImpulseLoader.lv2 ]; then
pushd plugs/ImpulseLoader.lv2
make
mv bin/ImpulseLoader.lv2 ~/.lv2/
# make mod-ui show cabsims (i.e. wav files) from 'Speaker Cabinets IRs' in the ImpulseLoader plugin
sed -i '/^ *mod:fileTypes/s/"wav,audio"/"wav,audio,cabsim"/' ~/.lv2/ImpulseLoader.lv2/ImpulseLoader.ttl
popd
fi
}
install_ratatouille() {
if [ ! -d plugs/Ratatouille.lv2 ]; then
git clone --recurse-submodules -j4 https://github.com/brummer10/Ratatouille.lv2 plugs/Ratatouille.lv2
fi
if [ ! -d ~/.lv2/Ratatouille.lv2 ]; then
pushd plugs/Ratatouille.lv2
make
mv bin/Ratatouille.lv2 ~/.lv2/
popd
fi
}
install_neural_amp_modeler() {
if [ ! -d plugs/neural-amp-modeler-lv2 ]; then
git clone --recurse-submodules -j4 https://github.com/mikeoliphant/neural-amp-modeler-lv2 plugs/neural-amp-modeler-lv2
fi
if [ ! -d ~/.lv2/neural_amp_modeler.lv2 ]; then
pushd plugs/neural-amp-modeler-lv2/build
cmake .. -DCMAKE_BUILD_TYPE="Release" -DWAVENET_FRAMES=$PERIOD_FRAMES
make -j4
mv neural_amp_modeler.lv2 ~/.lv2/
popd
fi
}
install_dragonfly() {
if [ ! -d plugs/dragonfly-reverb ]; then
git clone --recurse-submodules -j4 https://github.com/pedalboard/dragonfly-reverb.git plugs/dragonfly-reverb
fi
if [ ! -d ~/.lv2/DragonflyHallReverb.lv2 ]; then
pushd plugs/dragonfly-reverb
make
mv bin/*.lv2 ~/.lv2/
popd
fi
}
install_floaty() {
if [ ! -d ~/.lv2/floaty.lv2 ]; then
# https://patchstorage.com/floaty/
pushd plugs
wget https://patchstorage.com/wp-content/uploads/2023/04/floaty-643379f86ffb2.lv2.tar.gz
tar xvfz floaty-643379f86ffb2.lv2.tar.gz -C ~/.lv2/
popd
fi
}
install_avocado() {
if [ ! -d ~/.lv2/avocado.lv2 ]; then
# https://patchstorage.com/avocado/
pushd plugs
wget https://patchstorage.com/wp-content/uploads/2023/04/avocado-643379569b045.lv2.tar.gz
tar xvfz avocado-643379569b045.lv2.tar.gz -C ~/.lv2/
popd
fi
}
install_noisegate() {
if [ ! -d plugs/noisegate ]; then
git clone https://github.com/VeJa-Plugins/Noise-Gate.git plugs/noisegate
fi
if [ ! -d ~/.lv2/noisegate.lv2 ]; then
pushd plugs/noisegate
make clean
make
mv noisegate.lv2 ~/.lv2/
popd
fi
}
preset_model() {
cat <<EOF > ~/.lv2/neural_amp_modeler.lv2/manifest.ttl
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
@prefix pset: <http://lv2plug.in/ns/ext/presets#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix state: <http://lv2plug.in/ns/ext/state#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://github.com/mikeoliphant/neural-amp-modeler-lv2>
a lv2:Plugin;
lv2:binary <neural_amp_modeler.so>;
rdfs:seeAlso <neural_amp_modeler.ttl>.
<model>
a pset:Preset ;
rdfs:label "model" ;
lv2:appliesTo <http://github.com/mikeoliphant/neural-amp-modeler-lv2> ;
state:state [ <http://github.com/mikeoliphant/neural-amp-modeler-lv2#model> "/home/nam/mod-user-files/NAM Models/m100-cln.nam" ] .
EOF
}
preset_ir() {
cat <<EOF > ~/.lv2/ImpulseLoader.lv2/manifest.ttl
@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
@prefix pset: <http://lv2plug.in/ns/ext/presets#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix state: <http://lv2plug.in/ns/ext/state#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<urn:brummer:ImpulseLoader>
a lv2:Plugin ;
lv2:binary <ImpulseLoader.so> ;
rdfs:seeAlso <ImpulseLoader.ttl> .
<urn:brummer:ImpulseLoader#par>
a pset:Preset ;
lv2:appliesTo <urn:brummer:ImpulseLoader> ;
rdfs:label "par" ;
lv2:port [
lv2:symbol "Bypass" ;
pset:value 0.0
] , [
lv2:symbol "DRY_WET" ;
pset:value 100.0
] , [
lv2:symbol "INPUT" ;
pset:value 0.0
] ;
state:state [
atom:Path "/home/nam/mod-user-files/Speaker Cabinets IRs/par.wav"
] .
EOF
}
create_jack() {
cat <<EOF > ~/bin/launch-jack
#!/usr/bin/env bash
hw=\$(cat /proc/asound/cards | grep "\[$SOUND_CARD_ALSA_NAME" | awk '{print \$1}')
JACK_NO_AUDIO_RESERVATION=1 jackd -P95 -R -s -S -t1000 -dalsa -d hw:\$hw -p$PERIOD_FRAMES -n3 -r48000 -X seq
EOF
chmod u+x ~/bin/launch-jack
}
create_mod_host() {
cat <<EOF > ~/bin/launch-mod-host
#!/usr/bin/env bash
mod-host -n -p 5555 -f 5556
EOF
chmod u+x ~/bin/launch-mod-host
}
create_mod_ui() {
if [ ! -d ~/mod-user-files ]; then
mkdir -p ~/mod-user-files
fi
cat <<EOF > ~/bin/launch-mod-ui
#!/usr/bin/env bash
cd /home/nam/mod-ui
source modui-env/bin/activate
# https://patchstorage.com/docs/api/beta/
# PATCHSTORAGE_PLATFORM_ID=8046 is LV2 Plugins
# PATCHSTORAGE_TARGET_ID=8280 is rpi-aarch64
MOD_SOUNDCARD=$SOUND_CARD_ALSA_NAME \
MOD_DEV_ENVIRONMENT=0 \
MOD_USER_FILES_DIR=/home/nam/mod-user-files \
PATCHSTORAGE_API_URL=https://patchstorage.com/api/beta/patches \
PATCHSTORAGE_PLATFORM_ID=8046 \
PATCHSTORAGE_TARGET_ID=8280 \
python ./server.py
EOF
chmod u+x ~/bin/launch-mod-ui
}
create_systemd_service() {
# sudo tee /home/nam/bin/pedal-service &>/dev/null <<EOF
cat <<EOF > ~/bin/pedal-service
#!/usr/bin/env bash
sleep 0 && /home/nam/bin/launch-jack &
sleep 3 && /home/nam/bin/launch-mod-host &
sleep 4 && /home/nam/bin/launch-mod-ui &
wait
EOF
chmod u+x ~/bin/pedal-service
# allow it starting on port 80
sudo touch /etc/authbind/byport/80
sudo chown nam /etc/authbind/byport/80
sudo chmod 755 /etc/authbind/byport/80
sed -i "/MOD_DEVICE_WEBSERVER_PORT/s/8888/80/" ~/mod-ui/server.py
# https://github.com/SolsticeFX/pi-stomp-bookworm/blob/aeff925037e3318b078fc1418ddd86ed88d37d25/setup/mod/mod-ui.service#L25
sudo tee /etc/systemd/system/pedal.service &>/dev/null <<EOF
[Unit]
Description=Pedal Startup Service
After=network.target
[Service]
User=nam
LimitRTPRIO=95
LimitMEMLOCK=infinity
ExecStart=/usr/bin/authbind --deep /home/nam/bin/pedal-service
StandardOutput=journal
StandardError=journal
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
}
# not nescessary with mod-ui, it does this
#create_connect() {
# cat <<EOF > launch-connect
##!/usr/bin/env bash
#sleep 4
#jack_connect system:capture_1 effect_1:input
#jack_connect effect_1:output effect_2:in0
#jack_connect effect_2:out0 system:playback_2
#jack_lsp -c
#EOF
# chmod u+x launch-connect
#}
if [ ! -f .pedal.deps ]; then
update_os
ensure_deps
realtime_jack
deps_cleanup
create_local_bin
touch .pedal.deps
fi
create_folders
install_mod_host
install_mod_ui
install_mod_plugins
# amp+cab
install_impulse_loader
install_neural_amp_modeler
install_ratatouille
# plugins
install_noisegate
install_dragonfly
install_floaty
install_avocado
preset_model
preset_ir
create_jack
create_mod_host
create_mod_ui
create_systemd_service
# alsamixer, adjust volume
# sudo alsactl store
# sudo alsactl restore
# start as a service
sudo systemctl daemon-reload
sudo systemctl restart pedal.service
#
# sudo systemctl enable pedal.service
#
# journalctl -u pedal.service
# reboot, visit http://pedal.lan:8888, enjoy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment