• WANTED: Happy members who like to discuss audio and other topics related to our interest. Desire to learn and share knowledge of science required. There are many reviews of audio hardware and expert members to help answer your questions. Click here to have your audio equipment measured for free!

RPi4 + CamillaDSP Tutorial

grizaudio

Member
Joined
Jan 3, 2021
Messages
30
Likes
7
Is there any reason why mid song CamillaDSP would reset volume to -40db without intervention?
I had it playing at -2db, using a different .yml and did not touch the software.
Looks like the config switched? to new config from the base config???
View attachment 248303
 
Last edited:
OP
M

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,513
Likes
3,366
Location
Detroit, MI
Is there any reason why mid song CamillaDSP would reset volume to -40db without intervention?
I had it playing at -2db, using a different .yml and did not touch the software.
Looks like the config switched? to new config from the base config???
View attachment 248303

It means that it restarted. The "-g-40" line in the service means that any time it starts it will reset to -40 dB. Check the log to see if you can make any sense of why it restarted. It may make sense to increase verbosity of the log.

Also it looks like your active_config button is grayed out again?

Michael
 

grizaudio

Member
Joined
Jan 3, 2021
Messages
30
Likes
7
Just a word of caution to others,

Make sure your output convolution filters are created in the same sampling rate as set in CamillaDSP.
I upload 44.1, instead of 96khz.

By mis-matching the convolution filter sampling rate, I observed significant level differences between Roon and CamillaDSP executing the same convolution files.
Anyway, just incase others have this issue.

Roon - Convolution sampling rate matched to music sample rate.
1670381144404.png


CamillaDSP - this was observed when I used a 44.1khz convolution, instead of the correct 96khz convolution wav.
1670381161724.png
 
Last edited:

grizaudio

Member
Joined
Jan 3, 2021
Messages
30
Likes
7
It means that it restarted. The "-g-40" line in the service means that any time it starts it will reset to -40 dB. Check the log to see if you can make any sense of why it restarted. It may make sense to increase verbosity of the log.

Also it looks like your active_config button is grayed out again?

Michael

Thanks for your help Michael, I think I'm all good now.
Just need to remove the volume attenuation on restart.
 

grizaudio

Member
Joined
Jan 3, 2021
Messages
30
Likes
7
Wow, you are right, thank you for sharing! Just tried the samplerate_medium resampler and it looks great.

Here is the default resampler playing a 1 kHz 24 bit test tone at 96 kHz going in to a CamillaDSP configuration running at 44.1 kHz.

View attachment 248169

And here is samplerate_medium, 17 dB improvement in noise!

View attachment 248170

These are just quick and dirty DAC output measurements, imagine digital output / input measurements look much better.

Michael
Michael do you think you might provide a how to guide for enabling scribble and resampling?
Would be very appreciated.

Auto sample rate change on input, with output reflecting that change would be amazing.
 

arvidb

Member
Joined
Dec 1, 2022
Messages
96
Likes
114
Location
Sweden
Since sinc interpolation can cause clipping all by itself, I want to attenuate before resampling rather than in CamillaDSP. I.e. somehow increase the resolution of the streams, then apply some attenuation, and then perform the resampling + mixing. All this before handing the resulting stream off to Camilla DSP for filtering.

Any ideas on how to do this? I cannot make much sense of ALSA's configuration syntax - or ALSA in general really!
Replying to myself here, since I believe I might have done it!

defaults.ctl.!card Alpha defaults.pcm.rate_converter "samplerate_medium" pcm.resample { # Resample to 48 kHz using pcm.rate_converter type rate slave { pcm "dmix:CARD=Loopback,RATE=48000,FORMAT=S32_LE" rate 48000 format S32_LE } } pcm.attenuate { type route slave.pcm resample slave.format S32_LE ttable.0.0 0.707945784384 # Should be -3 dB if my math is correct: ttable.1.1 0.707945784384 # = 10^(-3/20) } pcm.convert { # Convert to 32-bit (FLOAT_LE not supported by route - "not linear". Bug?) type linear slave.pcm attenuate slave.format S32_LE } pcm.!default convert

With this config, I get no (or very rare) clipping warnings from CamillaDSP, and mpv plays files in their native formats:

$ mpv music/<some-file>.opus (+) Audio --aid=1 (opus 2ch 48000Hz) AO: [alsa] 48000Hz stereo 2ch s32

$ mpv -v music/<some-file>.flac (+) Audio --aid=1 (flac 2ch 44100Hz) AO: [alsa] 44100Hz stereo 2ch s16

or even

$ mpv -v --audio-samplerate=57000 music/<some-file>.flac [cplayer] (+) Audio --aid=1 (flac 2ch 44100Hz) [cplayer] AO: [alsa] 57000Hz stereo 2ch s16 [autoconvert] inserting resampler [swresample] format change, reinitializing resampler [swresample] 44100Hz stereo s16 -> 57000Hz stereo s16

What's more, these can all play simultaneously! (Although -3 dB is of course not enough attenuation to avoid clipping if you mix several sources.)

Note that ALSA was extremely picky with the config file format. This does not work, it seems, unless the short format pcm "dmix:CARD=Loopback,RATE=48000,FORMAT=S32_LE" is used. I first declared the dmix in its own pcm block, just like the other plugins in the chain, but that did not work.
 
OP
M

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,513
Likes
3,366
Location
Detroit, MI
Michael do you think you might provide a how to guide for enabling scribble and resampling?
Would be very appreciated.

Auto sample rate change on input, with output reflecting that change would be amazing.

Is there something you do not understand about the alsa_cdsp plugin instructions? I don't really want to add that approach to this tutorial as it is quite a bit different than what is described currently (cannot use the camilladsp service, cannot change configurations in the GUI, need to deal with player permissions, need to deal with differing channel counts by sample rate if your DAC does that, etc).

Resampling is much easier to implement and is already described in the tutorial for the case of using resampling within squeezelite.

If you would like to use ALSA resampling simply use plughw:Loopback,1 as your output device for your software player and the line defaults.pcm.rate_converter "samplerate_medium" to /etc/asoundrc.conf. This will cause ALSA to resample to the sample rate used by CamillaDSP.

Michael
 

grizaudio

Member
Joined
Jan 3, 2021
Messages
30
Likes
7
I was hoping CamillaDSP could automatically accept the native sample rate of the content, rather than need to resample all content @ 44.1khz.
Roon as an example will playback native content sample rates I.e. 44.1, 48, 88, 96, 192, etc and select the matching sample rate for convolution filter.
I.e. I have rates saved for 44.1, 48, 88, 96, 192. This ensures no resampling on input or output.
 
Last edited:
OP
M

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,513
Likes
3,366
Location
Detroit, MI
I played around with the alsa_cdsp plugin (https://github.com/scripple/alsa_cdsp) this weekend and can share a basic configuration that works with the Ultralite Mk5. For those unaware the alsa_cdsp plugin establishes an ALSA device called camilladsp that you can specify as the playback device for software players like squeezelite and shairport-sync. The advantage of using the alsa_cdsp plugin is that it can dynamically switch the sample rate and format of CamillaDSP based on the file you are playing.

This is not meant to be an exhaustive tutorial and it is important to read all of the notes / caveats on the GitHub, also many of things in my base tutorial won't work with the plugin (cannot use camilladsp.service, oled.py doesn't work, cannot switch configurations in the GUI, etc). Personally I don't think it is worth the effort to pursue the alsa_cdsp plugin over the approach described in this tutorial as without further refinement it has numerous usability issues.

Here are instructions for installing the plugin.

Code:
sudo apt install libasound2-dev
git clone https://github.com/scripple/alsa_cdsp
cd alsa_cdsp
make
sudo make install

Make an asound.conf if you do not have one already.

Code:
sudo nano /etc/asound.conf

There are multiple approaches to using the alsa_cdsp plugin, the example asound.conf shown below uses the config_in approach.

Code:
# This declares an ALSA device that you can specify to playback programs.
# You can use any name you wish that ALSA supports not just camilladsp.
# To use it you specify it to alsa like "aplay -D camilladsp"
pcm.camilladsp {
    # type cdsp must be present - it declares to use this plugin.
    # The type is NOT a variable name you can choose.
    # You can however create multiple type cdsp plugins with different names
    # if you want to specify different parameters selected by specifying a
    # different ALSA device.
    type cdsp
   
      #######################################################################
      #######################################################################
      # Required parameters.
      # The parameters in this section must be specified as a valid set.
      #######################################################################
      #######################################################################
     
      # cpath specifies the absolute path to the CamillaDSP executable.
      # CamillaDSP must have executable permission for any user that runs an
      # audio program that uses this plugin.
      cpath "/home/michael6/camilladsp/camilladsp"
     
      # config_out is the absolute path that will be passed to CamillaDSP as
      # the YAML config file argument. The file must be readable by any user
      # that runs an audio program that uses this plugin.  If the config_in
      # or config_cmd options are chosen (see below) it must also be writable
      # by those users.
      config_out "/home/michael6/camilladsp/configs/config_out.yml"
     
      #######################################################################
      # Parameter Passing Options
      #
      # There are three mutually exclusive ways to send the updated hw_params
      # and extra_samples to CamillaDSP.  One and only one method must be
      # specified. The three methods are config_in, config_cmd, and
      # config_cdsp.
      #######################################################################

      # config_in is an absolute path to a YAML template the plugin will read
      # and pass along to CamillaDSP after making simple token substitutions.
      # It must be readable by any user that runs an audio program that uses
      # this plugin.
      config_in "/home/michael6/camilladsp/configs/config_in.yml"
     
      # config_in processing does a simple search and replace of four tokens
      # representing format, channels, sample rate, and extra samples
      # replacing the tokens with the appropriate parameters.  The following
      # entries show the default tokens.  They can be changed to custom
      # tokens by uncommenting the lines below and replacing the default
      # tokens with the desired tokens wrapped in quotes.
      #format_token "$format$"
      #samplerate_token "$samplerate$"
      #channels_token "$channels$"
      #extrasamples_token "$extrasamples$"
     
      # config_cmd is the absolute path to a command that will be called
      # whenever the hw_params change with arguments "format rate channels".
      # It should create the YAML file CamillaDSP will load and place it in
      # the location specified by the config_out parameter.
      # Note that the extra_samples parameters specified below are NOT
      # passed in any way to this command.
      #config_cmd "/path/to/more_complex_yaml_creator"
     
      # config_cdsp says to use the new CamillaDSP internal substitutions.
      # When config_cdsp is set to an integer != 0 the hw_params and
      # extra samples are passed to CamillaDSP on the command line as
      # -f format -r samplerate -n channels -e extra_samples
      #config_cdsp 1
     
      #######################################################################
      # End Parameter Passing Options
      #######################################################################
     
      #######################################################################
      # Capability Enumeration
      #
      # The plugin will announce the hw_params it supports based on the
      # following settings.  Channels and sample rates must be specified.
      # The plugin will automatically enumerate all the formats that
      # CamillaDSP supports.
      #######################################################################
      # Channels can be specified as a single value like this.
      channels 2
      # Or a range like this. (Uncomment the lines.)
      #min_channels 1
      #max_channels 2
      # But only one method can be used.
     
      # Sample rates can be configured as a specific list like this. 
      # (Up to 100 entries.)
      rates = [
        44100
        48000
        88200
        96000
        176400
        192000
#        352800
#        384000
      ]
      # Or as a range like this.  (Uncomment the lines.) 
      #min_rate 44100
      #max_rate 384000     
      # Note that if you use a range like this ALSA will accept ANYTHING in
      # that range.  Even something odd like 45873.  If you aren't using
      # CamillaDSP's resampler and don't have a very unusual DAC you are
      # probably better off with the list format above.
      #######################################################################
      # End Capability Enumeration
      #######################################################################
     
      #######################################################################
      #######################################################################
      # End Required Parameters
      #######################################################################
      #######################################################################     

      #######################################################################
      #######################################################################
      # Optional Parameters
      #######################################################################
      #######################################################################
     
      # If you wish to specify additional arguments to CamillaDSP you can
      # specify them using the cargs array.  Numeric arguments must be quoted
      # in strings or the plugin will fail to load. You should not specify
      # the hw_params arguments here as the plugin will take care of that as
      # they change.
      cargs [
        -p "1234"
        -a "0.0.0.0"
        -g-40
        -o /home/michael6/camilladsp/camilladsp.log
    -v
      ]     
     
      # Extra samples can be provided in a rate scaling way for the two most
      # common audio base rates.  This is under the assumption your filters
      # will be N times as long at N times the base rate. Any of the
      # following three values can be set or excluded in any combination.
      # If no valid extra_samples parameter is set for a given sample rate
      # the extra_samples token replacement will not occur in config_in mode
      # and the -e argument will not be issued in config_cdsp mode.
      # All extra_samples arguments must be integers >= 0.
     
      # extra_samples is used when the sample rate is not an integer multiple
      # of 44100 or 48000 or when the corresponding rate matching
      # extra_samples option is not set.
      #
      # If using config_cdsp this is the only version of extra_samples
      # that should be specified as CamillaDSP does its own sample rate
      # based scaling of the extra samples.
      extra_samples 0
     
      # extra_samples_44100 is used when the sample rate is an integer
      # multiple of 44100. In this case {extrasamples} will be replaced with
      # {samplerate/44100 * extra_samples_44100}.
      extra_samples_44100 8192
     
      # extra_samples_48000 is used when the sample rate is an integer
      # multiple of 48000. In this case {extrasamples} will be replaced with
      # {samplerate/48000 * extra_samples_48000}.
      extra_samples_48000 8916
     
      # An option not directly related to camilladsp.  A command to run when
      # the plugin is first created.  (Meaning when a playback program opens
      # the audio device.)  Use it for whatever you want.  Set gpio pins on a
      # raspberry pi to turn on your amp for example.
      ##start_cmd "/path/to/start_command"
}

You specify a configuration file called config_in which can have dynamic values for channels, format, sample rate and extra samples. The plugin will then create a configuration file called config_out based on the specific values of the file you are playing and load CamillaDSP with the config_out configuration. It will do this every time one of these values changes.

In order for this to work you need to update the cpath, config_in and config_out values in asound.conf to reflect your camillaDSP path and where you store your configuration files. For reference this example uses a hostname of raspberrypi6 and a username of michael6.

You also need to create a config_in.yml file at the location you specify.

Code:
nano ~/camilladsp/configs/config_in.yml

Below is an example config_in.yml for an Ultralite Mk5. A few things of note, I needed to use plughw:UltraLiteMk5 as my playback device and specify 10 channels in order for the plugin to work with all sample rates. The reason for this is the Ultralite Mk5 has different output channel counts depending on sample rate and unless you use plughw it expects the exact number of channels. If I would have used a higher number of channels (say 22 output channels for 44.1/48 kHz) the configuration would fail at higher sample rates.

This example also shows how you can specify FIR filters for different sample rates by appending the sample rate at the end of the file name and using the $samplerate$ flag when specifying the filter name in CamillaDSP. Of course this requires you to generate specific FIR filters for every sample rate you want to use. As you can see below I created FIR filters in rephase for 44.1, 48, 88.2, 96, 176.4 and 192 kHz.

1670792445142.png


You also need to update the configuration files for your software players to use a playback device called camilladsp.

For squeezelite:

Code:
sudo nano /etc/default/squeezelite

Note that all resampling has been implemented from this configuration.

Code:
# Defaults for squeezelite initscript
# sourced by /etc/init.d/squeezelite
# installed at /etc/default/squeezelite by the maintainer scripts
# The name for the squeezelite player:
SL_NAME="$(hostname -s)"
# ALSA output device:
# Squeezebox server (Logitech Media Server):
# Uncomment the next line if you want to point squeezelite at the IP address of
# your squeezebox server. This is usually unnecessary as the server is
# automatically discovered.
#SB_SERVER_IP="192.168.x.y"
# Additional options to pass to squeezelite:
# Please do not include -z to make squeezelite daemonise itself.
SB_EXTRA_ARGS="-W -C 5"
SL_SOUNDCARD="camilladsp"

For shairport-sync:

Code:
sudo nano /etc/shairport-sync.conf

Change alsa output_device to "camilladsp".

Also, you need to change the username in the shairport-sync.service to allow shairport-sync to start camilladsp.

Code:
sudo nano /lib/systemd/system/shairport-sync.service

Change your username from shairport-sync to whatever your username is, in my case michael6.

Code:
[Unit]
Description=Shairport Sync - AirPlay Audio Receiver
After=sound.target
Requires=avahi-daemon.service
After=avahi-daemon.service
Wants=network-online.target
After=network.target network-online.target

[Service]
ExecStart=/usr/local/bin/shairport-sync --log-to-syslog
User=michael6
Group=shairport-sync

[Install]
WantedBy=multi-user.target

At this point restart your RPi and you should be good to go.

Overall it seems to work well with a few issues. The Ultralite Mk5 takes a few seconds to switch so you won't hear the first few seconds of a song after a switch. Because the plugin restarts CamillaDSP there are also issues with using CamillaDSP volume control. I added "-g-40" to my asound.conf so that CamillaDSP always restarts at -40 dB but if you don't include this it will restart at -0 dB and you will be in for a nasty surprise. Either way the change in volume when changing a song is annoying.

I am not adding this approach to the tutorial and do not plan on helping folks troubleshoot using this approach but hopeful this post points people in the right direction if they are interested in pursuing the plugin.

Good luck!

Michael
 
Last edited:

MCH

Major Contributor
Joined
Apr 10, 2021
Messages
2,650
Likes
2,257
I guess it could be interesting for instance for the folks streaming Amazon music hd out of a wiim mini, as i believe it outputs each song at the sample rate that is available at Amazon, and some of these guys are serious about no resampling at any price. They could control the volume on the mini and leave camilladsp always at 0, but the 3 seconds silence every time the sample rate changes.... would be a no go for me. After all the trouble they went through for the wiim to be gapless :D
 
OP
M

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,513
Likes
3,366
Location
Detroit, MI
I guess it could be interesting for instance for the folks streaming Amazon music hd out of a wiim mini, as i believe it outputs each song at the sample rate that is available at Amazon, and some of these guys are serious about no resampling at any price. They could control the volume on the mini and leave camilladsp always at 0, but the 3 seconds silence every time the sample rate changes.... would be a no go for me. After all the trouble they went through for the wiim to be gapless :D

I tested this further and I think it is more that the UL Mk5 is slow at switching rather than an issue with CamillaDSP or alsa_cdsp. I tested it by using the UltraLitemk5 directly as the output device in squeezelite and still had a few second pause as it switched between rates. Maybe other DACs perform better, but to me it is just another reason to have all inputs nicely resampled to a consistent rate.

Michael
 

grizaudio

Member
Joined
Jan 3, 2021
Messages
30
Likes
7
I tested this further and I think it is more that the UL Mk5 is slow at switching rather than an issue with CamillaDSP or alsa_cdsp. I tested it by using the UltraLitemk5 directly as the output device in squeezelite and still had a few second pause as it switched between rates. Maybe other DACs perform better, but to me it is just another reason to have all inputs nicely resampled to a consistent rate.

Michael

Thanks very much for the overview.
Yes, the Motu MK5 UL takes about 3-4 seconds to switch sampling rates.
In Roon I use a sample rate change delay to compensate. Need to explore a solution for LMS.
 

somebodyelse

Major Contributor
Joined
Dec 5, 2018
Messages
3,754
Likes
3,053
From the squeezelite docs:
-r <rates>[:<delay>]
Specify sample rates supported by the output device; this is required if the output device is switched off when squeezelite is started. The format is either a single maximum sample rate, a range of sample rates in the format <min>-<max>, or a comma-separated list of available rates. Delay is an optional time to wait when switching sample rates between tracks, in milliseconds.
 

grizaudio

Member
Joined
Jan 3, 2021
Messages
30
Likes
7
Overall it seems to work well with a few issues. The Ultralite Mk5 takes a few seconds to switch so you won't hear the first few seconds of a song after a switch. Because the plugin restarts CamillaDSP there are also issues with using CamillaDSP volume control. I added "-g-40" to my asound.conf so that CamillaDSP always restarts at -40 dB but if you don't include this it will restart at -0 dB and you will be in for a nasty surprise. Either way the change in volume when changing a song is annoying.
Thanks Michael, I don't use CamillaDSP volume, so this doesn't present an issue for me, I set CamillaDSP volume to 0db when using LMS anyway. I control volume in my software player, or via DAC.
 

Nisse10000

Member
Joined
Nov 14, 2022
Messages
30
Likes
15
Is anyone else using HDMI as output (to an AVR)? I fiddled around a bit before getting it to work but now the camilladsp.service isn't starting on boot. If I manually start it after boot it works. I'm using hdmi:CARD=vc4hdmi0,DEV=0 as Playback Device. I'm guessing that the device isn't ready when camilladsp is starting but I've tried to change that by chaing to

[Unit]
After=network-online.target

but that didn't help. It works to log in via ssh and restart but it would be nice to have it fixed.
 

phofman

Addicted to Fun and Learning
Joined
Apr 13, 2021
Messages
502
Likes
326
Maybe the HDMI interface is activated after some graphical stack, not just network?
 

somebodyelse

Major Contributor
Joined
Dec 5, 2018
Messages
3,754
Likes
3,053
Not starting as in fails to start, or as in starts but doesn't work because the device isn't there? In the first case check the restart options in the service file. In the second you could look at using a udev rule to start the service when the device appears.
 

Nisse10000

Member
Joined
Nov 14, 2022
Messages
30
Likes
15
Thanks! It seems to be working now. I think the issue was that I used the original camilladsp.srvive and the end there is a WantedBy:graphical.target which seems problematic/contradictory when using the hdmi i/f.

To get hdmi working without noise I load the driver using dtoverlay=vc4-kms-v3d
 

MCH

Major Contributor
Joined
Apr 10, 2021
Messages
2,650
Likes
2,257
Guys, i have a very basic question regarding the gadget mode.

I have a camilladsp set up in a rpi 4 up an running that feeds my speakers and subs:
TV -> toslink -> usb card -> raspberry pi/camilladsp -> usb interface -> amps -> speakers and subs
Nothing special here, all working normal.

I was wondering if it is possible to add a computer as a source to that existing system without additional boxes by means of the gadget mode, like if it was an additional configuration. That is, i am listening to the signal coming from the TV as per the signal flow above, and then switching to "configuration 2", camilladsp gets the sound from a computer working in gadget mode. Is such a thing possible?

PS: i can imagine that a possible workaround would be to have all the signals routed through the computer and the pi getting the sound from the computer in gadget mode all the time, but i want to avoid this for different reasons.

thanks!
 

phofman

Addicted to Fun and Learning
Joined
Apr 13, 2021
Messages
502
Likes
326
The USB gadget and USB capture soundcard provide different alsa capture devices. You need to tell CDSP to use the required capture device.
 
Top Bottom