Installing convolver to ALSA stream in Raspberry 3b for Squeezelite system-wide

The choices

There seems to be several ways to implement convolvers to Squeezelite players.

  • Alsaimpulse: I tried alsa dynamic library alsaimpulse, but could not compile it properly. Tried with Raspberry and Ubuntu.
  • PulseEffects/EasyEffects: Pulse has convolver in PulseEffects but now it's moved to Pipewire. Tried with Pipewire, but my Raspberry does not have the newest version. Besides, Pulse/Pipewire is not needed when convolver should work system-wide one stream per Squeezelite. KISS.
  • BruteFir: The oldiegoldie is of course one choice but decided to try more modern ones.
  • LADSPA_DSP: This contains three different convolvers, the brute one, partitioned and zita-convolver.Not as package, but source files.
I decided to use ladspa_dsp. Ladspa is ALSA plugin API. 

Testing your audio works

Get list of your audio devices:

aplay -L

Test you can play your audio with your device.

flac -c -d ./SkyScraper.flac | aplay -D <<audio_device>>
speaker-test -c 2 -D <<audio_device>>

Get LADSPA_DSP sources

mkdir dsp
cd dsp
wget https://github.com/bmc0/dsp/archive/refs/heads/master.zip
unzip master
cd dsp*

Install needed packages

Some of these might not be mandatory.
apt-get install ffmpeg
apt-get install libasound2-plugins
apt-get install libasound2-dev
apt-get install libfftw3-dev
apt install libtool
apt-get install libzita-convolver-dev
apt-get install libsndfile-dev
apt-get install ladspa-sdk
apt-get install alsa-base
apt-get install libzita-alsa-pcmi0
apt-get install libzita-alsa-pcmi-dev
apt-get install alsa-tools
apt-get install zita-alsa-pcmi-utils


Test you have needed packages, run configure:
 ./configure
Output should be that at least these are enabled.
enabled dsp
[dsp] disabled ladspa_host.o
[dsp] enabled sndfile.o (sndfile)
[dsp] enabled ffmpeg.o (libavcodec libavformat libavutil)
[dsp] enabled resample.o fir.o fir_p.o hilbert.o (fftw3)
[dsp] enabled zita_convolver.o
[dsp] enabled alsa.o (alsa)
[dsp] disabled ao.o (ao)
[dsp] disabled mp3.o (mad)
[dsp] disabled pulse.o (libpulse-simple)
enabled ladspa_dsp
[ladspa_dsp] disabled ladspa_host.o
[ladspa_dsp] enabled fir.o fir_p.o hilbert.o (fftw3)
[ladspa_dsp] enabled zita_convolver.o
[ladspa_dsp] enabled sndfile.o (sndfile)

Compile

make
make install

Testing

Test that DSP is working
dsp ./SkyScraper.flac -o <<audio_device>> highpass 1.8k 0.5

Testing that your REW impulse files work with convolver
mkdir /etc/ladspa_dsp

Copy REW impulse files to /etc/ladspa_dsp/
Test that convolver is working ( this lowers gain -3.9dB first ). :0 is for left channel and :1 for right channel.
dsp ./SkyScraper.flac -o <<audio_device>> gain -3.9 :0 zita_convolver /etc/ladspa_dsp/Wharfedale_8_1_LR_44100.wav :1  zita_convolver /etc/ladspa_dsp/Wharfedale_8_1_LR_44100.wav

Configuring ALSA with LADSPA

Create ladspa_dsp config file for "living_room_speakers"
vi /etc/ladspa_dsp/config_living_room_speakers

# This is a comment
input_channels=2
output_channels=2
LC_NUMERIC=C
effects_chain=gain -3.9 :0 zita_convolver /etc/ladspa_dsp/Wharfedale_8_1_LR_44100.wav :1  zita_convolver /etc/ladspa_dsp/Wharfedale_8_1_LR_44100.wav

Of course you should replace that with your own impulse files. You are not an idiot.

You could create your own file in /alsa/conf.d but here I choose the simple way and configured stream to asound.conf
vi /etc/asound.conf

pcm.dsp_living_room_speakers_music {
        type plug
        slave {
                format FLOAT
                rate unchanged
                pcm {
                        type ladspa
                        channels 2
                        path "/usr/lib/ladspa"
                        playback_plugins [{
                                label "ladspa_dsp:living_room_speakers"
                        }]
                        slave.pcm {
                                type plug
                                slave {
                                        pcm <<audio_device>>
                                        rate unchanged
                                        channels unchanged
                                }
                        }
                }
        }
        hint {
            show on
                description "Living Room Speakers Convolver."
        }
}


The "label" setting selects the right config file in /etc/ladspa_dsp directory. Remember to set your own audio_device.

Test the convolver stream
flac -c -d ./SkyScraper.flac | aplay -D dsp_living_room_speakers_music

Install Squeezelite system-wide

Get squeezelite:
apt-get install squeezelite

Test Squeezelite with root:
nice -n 10 /usr/bin/squeezelite -m b8:27:eb:ae:c5:b3 -o dsp_living_room_speakers_music -a 200 -n "Living Room Speakers" -C 30 -r 44100

Squeezeboxserver user is created when LMS is installed so this assumes LMS exists also.
usermod -a -G audio squeezeboxserver

Create service file for Squeezelite:
vi /lib/systemd/system/squeezelite_living_room_speakers.service

###################################################                                                                                                                    
# file located at /lib/systemd/system/squeezelite.service
# use "systemctl enable squeezelite.service to load
# based on a template from RPMFusion and R.G. Newbury from this thread:
# http://www.gossamer-threads.com/lists/mythtv/users/516650?search_string=mythbackend.service%20;#516650

#Usage: ./squeezelite [options] [<server_ip>]
#  <server_ip>           Connect to server server at given IP address, otherwise uses autodiscovery
#  -o <output device>    Specify output device, default "default"
#  -l                    List output devices
#  -a <time>:<count>     Specify ALSA buffer_time (ms) and period_count, default 20:4
#  -b <stream>:<output>  Specify internal Stream and Output buffer sizes in Kbytes
#  -c <codec1>,<codec2>  Restrict codecs those specified, otherwise loads all available codecs; known codecs: flac,pcm,mp3,ogg,aac
#  -d <log>=<level>      Set logging level, logs: all|slimproto|stream|decode|output, level: info|debug|sdebug
#  -f <logfile>          Write debug to logfile
#  -m <mac addr>         Set mac address, format: ab:cd:ef:12:34:56
#  -n <name>             Set the player name
#  -r <rate>             Max sample rate for output device, enables output device to be off when squeezelite is started
#  -z                    Daemonize
#  -t                    License terms

[Unit]
Description=Squeezelite Living Room Speakers Daemon

Requires=network.target sound.target
After=network.target sound.target

[Service]
Type=simple

# NOTE: using the "squeezeuser" user, NOT root.
User=squeezeboxserver

ExecStart=nice -n 10 /usr/bin/squeezelite -m b8:27:eb:ae:c5:b3 -o dsp_living_room_speakers_music -a 200 -n "Living Room Speakers" -C 30 -r 44100

[Install]
WantedBy=multi-user.target

I'm using nice to set process priority because -p parameter didn't work. If you are creating multiple Squeezelite instances, create service file for each and all should have own unique mac. Mac has nothing to do with network mac. Run squeezelite --help to check your version for right parameters.
Start service:
systemctl enable squeezelite_living_room_speakers.service
systemctl restart squeezelite_living_room_speakers.service

systemctl status squeezelite_living_room_speakers.service

One 2-channel stream takes about +15% of Rpi3b Cpu.

There you go!

Comments