• 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

dfgoiuj

Member
Joined
Mar 22, 2022
Messages
43
Likes
5
  • Like
Reactions: MCH
OP
M

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,478
Likes
3,316
Location
Detroit, MI
Two inputs seems like a really good option, just switch between configs.

Have you seen the devices linked below?


First one does 96/24 ($25) and second one does 192/32 ($40) although both are optical and in my experience optical doesn't really work above 96 kHz due to receiver / transmitter design constraints.

Is there anyway you can set your fire stick to resample to 96 kHz instead of 192 kHz?

Michael

Following up on this, devices arrived yesterday and so far very impressed. 96 kHz works great on the cheap one and 192 kHz works great on the more expensive one.

They behave very nicely if TOSLINK signal is removed (unlike the Hifiberry Digi+ I/O).

If they are set to a higher sample rate (say 192 kHz) and a lower sample rate signal is sent to the input CamillaDSP can detect the rate change although the sound gets a bit funky while mismatched. It doesn't work this way if a higher rate than the CamillaDSP rate is provided but it seems to put CamillaDSP in a STALLED state when this happens. All of this makes me wonder if I can write a python script to change configurations to match the input sample rate. Going down in rate would be easy but for going up I would need to trigger on the STALLED state and cycle to the highest input rate of the device so the rate could be properly detected. Not sure it will sound nice when switching rates but I think that will depend on how quickly the rate change can be detected.

Will explore some more and make some measurements to make sure there is nothing terrible going on. Will also try out the digital output of the more expensive device.

Michael
 
  • Like
Reactions: MCH

phofman

Senior Member
Joined
Apr 13, 2021
Messages
489
Likes
319
Michael, this is a typical problem with the incoming digital streams which are controlled by the transmitter side.

The branch next11 of CDSP should (certainly will) handle stalling capture/playback devices better. Still, if the driver does not stop and reconfigure the stream with the new rate specification in hw_params (some drivers do, most don't), it's quite tricky to detect and handle the situation.

Alsa drivers for SPDIF input/output should provide AESx ctls, handled by iecset utility (in standard alsa utils). Should your driver provide these PCM-type controls (listed in amixer contents, not in alsamixer which is limited to MIXER type only), you can try reading them with iecset.

IF your driver offers the AES ctl which lists incoming stream rate (read from the SPDIF stream preable, not really measured by the SPDIF receiver), you can try if the ctl supports notifications to subscribers with alsactl monitor. If so, alsactl should print the moment the SPDIF stream is changed to new samplerate (provided the SPDIF transmitter on the remote side puts correct rate info into the preamble which is not always the case).

IF alsactl reacts to the stream change, the situation could be helped with changes to the alsadevice CDSP part I am planning for some nearer future https://github.com/HEnquist/camilladsp/issues/202#issuecomment-1148595342 - CDSP could react to start/stop/rate-change of snd-aloop, usb gadget, and also of the SPDIF incoming stream IF required ctls are available and could be subscribed to.

I am curious about results of the above checks on your HW. Thanks.
 

MCH

Major Contributor
Joined
Apr 10, 2021
Messages
2,581
Likes
2,199
Following up on this, devices arrived yesterday and so far very impressed. 96 kHz works great on the cheap one and 192 kHz works great on the more expensive one.

They behave very nicely if TOSLINK signal is removed (unlike the Hifiberry Digi+ I/O).

If they are set to a higher sample rate (say 192 kHz) and a lower sample rate signal is sent to the input CamillaDSP can detect the rate change although the sound gets a bit funky while mismatched. It doesn't work this way if a higher rate than the CamillaDSP rate is provided but it seems to put CamillaDSP in a STALLED state when this happens. All of this makes me wonder if I can write a python script to change configurations to match the input sample rate. Going down in rate would be easy but for going up I would need to trigger on the STALLED state and cycle to the highest input rate of the device so the rate could be properly detected. Not sure it will sound nice when switching rates but I think that will depend on how quickly the rate change can be detected.

Will explore some more and make some measurements to make sure there is nothing terrible going on. Will also try out the digital output of the more expensive device.

Michael
I see a lot of use cases for these, for instance for people using the wiim mini as streamer that want to do room correction. Can be great if you make it work.
 
OP
M

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,478
Likes
3,316
Location
Detroit, MI
Michael, this is a typical problem with the incoming digital streams which are controlled by the transmitter side.

The branch next11 of CDSP should (certainly will) handle stalling capture/playback devices better. Still, if the driver does not stop and reconfigure the stream with the new rate specification in hw_params (some drivers do, most don't), it's quite tricky to detect and handle the situation.

Alsa drivers for SPDIF input/output should provide AESx ctls, handled by iecset utility (in standard alsa utils). Should your driver provide these PCM-type controls (listed in amixer contents, not in alsamixer which is limited to MIXER type only), you can try reading them with iecset.

IF your driver offers the AES ctl which lists incoming stream rate (read from the SPDIF stream preable, not really measured by the SPDIF receiver), you can try if the ctl supports notifications to subscribers with alsactl monitor. If so, alsactl should print the moment the SPDIF stream is changed to new samplerate (provided the SPDIF transmitter on the remote side puts correct rate info into the preamble which is not always the case).

IF alsactl reacts to the stream change, the situation could be helped with changes to the alsadevice CDSP part I am planning for some nearer future https://github.com/HEnquist/camilladsp/issues/202#issuecomment-1148595342 - CDSP could react to start/stop/rate-change of snd-aloop, usb gadget, and also of the SPDIF incoming stream IF required ctls are available and could be subscribed to.

I am curious about results of the above checks on your HW. Thanks.

Out of my depth here and appreciate your help. Here are the amixer results for each card, I don't think I see the ctls you mention.

Hifime S2 Digi
Code:
amixer -c Audio controls
numid=6,iface=CARD,name='Clock Source 1 Validity'
numid=7,iface=CARD,name='Clock Source 2 Validity'
numid=4,iface=MIXER,name='PCM Playback Switch'
numid=5,iface=MIXER,name='PCM Playback Volume'
numid=3,iface=PCM,name='Capture Channel Map'
numid=1,iface=PCM,name='Playback Channel Map'
numid=2,iface=PCM,name='Playback Channel Map',device=1

Hifime UR23
Code:
amixer -c Rx controls
numid=2,iface=MIXER,name='IEC958 In Capture Switch'
numid=1,iface=PCM,name='Capture Channel Map'

Michael
 

phofman

Senior Member
Joined
Apr 13, 2021
Messages
489
Likes
319
Thanks for the amixer dumps. The S2 Digi card is based on https://cdn.datasheetspdf.com/pdf-down/S/A/9/SA9227-SAVITECH.pdf which does have the read-only registers reporting the incoming stream params (reg. offset 32), but IIUC they are only readable externally via I2C. Actually for the USB driver to generate the AES ctls a device-specific mixer quirk must be added, like for RME https://elixir.bootlin.com/linux/latest/source/sound/usb/mixer_quirks.c#L2048 and AA Micro II https://elixir.bootlin.com/linux/latest/source/sound/usb/mixer_quirks.c#L1603 . In both cases the driver must send custom USB control messages to the device to get the data, IEC958/SPDIF is not detailed by the USB audio class standard, at least not in the specs PDF http://dl.project-voodoo.org/usb-audio-spec/USB Audio v2.0/Audio20 final.pdf
 

phofman

Senior Member
Joined
Apr 13, 2021
Messages
489
Likes
319
Fantastic, thanks. I've set this to 1536 and so far haven't heard any pops.
Very good, congrats. I am quite curious what corrected capture rate was logged in the debug mode (on average, it varies significantly due to the calculation principle). Thanks
 

dfgoiuj

Member
Joined
Mar 22, 2022
Messages
43
Likes
5
Very good, congrats. I am quite curious what corrected capture rate was logged in the debug mode (on average, it varies significantly due to the calculation principle). Thanks
I spoke too soon :(

I've since experienced occasional pops and clicks when watching Netflix. I don't know if it's the nature of the audio content that allows me to hear more vs music (quiet scenes?).

I've tried multiple combinations of chunksize, adjust_period and target_level and haven't yet found one that doesn't exhibit this. I've also noticed these pops and clicks more frequently in music since experimenting with different settings.

I'm happy to grab some data if that's useful. You mention debug - are you referring to the command line option for CamillaDSP?
 

dfgoiuj

Member
Joined
Mar 22, 2022
Messages
43
Likes
5
Here is a snippet of the log for debug mode:

Code:
2022-06-22 09:56:58.535246 DEBUG [src/bin.rs:423] SetSpeed message received
2022-06-22 09:57:08.564644 DEBUG [src/audiodevice.rs:614] Current buffer level: 1009.3, corrected capture rate: 100.0016%
2022-06-22 09:57:08.564990 DEBUG [src/alsadevice.rs:503] Playback buffer level: 1009.3, signal rms: [-43.932182, -42.430912]
2022-06-22 09:57:08.565057 DEBUG [src/bin.rs:423] SetSpeed message received
2022-06-22 09:57:18.586046 DEBUG [src/audiodevice.rs:614] Current buffer level: 974.7, corrected capture rate: 100.0052%
2022-06-22 09:57:18.586343 DEBUG [src/alsadevice.rs:503] Playback buffer level: 974.7, signal rms: [-45.208946, -40.372013]
2022-06-22 09:57:18.586388 DEBUG [src/bin.rs:423] SetSpeed message received
2022-06-22 09:57:28.621767 DEBUG [src/audiodevice.rs:614] Current buffer level: 845.1, corrected capture rate: 100.0186%
2022-06-22 09:57:28.622095 DEBUG [src/alsadevice.rs:503] Playback buffer level: 845.1, signal rms: [-43.652477, -42.01655]
2022-06-22 09:57:28.622146 DEBUG [src/bin.rs:423] SetSpeed message received
2022-06-22 09:57:38.643866 DEBUG [src/audiodevice.rs:614] Current buffer level: 794.4, corrected capture rate: 100.0240%
2022-06-22 09:57:38.644249 DEBUG [src/bin.rs:423] SetSpeed message received
2022-06-22 09:57:38.644244 DEBUG [src/alsadevice.rs:503] Playback buffer level: 794.4, signal rms: [-49.490974, -50.382904]
2022-06-22 09:57:48.670793 DEBUG [src/audiodevice.rs:614] Current buffer level: 784.7, corrected capture rate: 100.0250%
2022-06-22 09:57:48.671157 DEBUG [src/alsadevice.rs:503] Playback buffer level: 784.7, signal rms: [-45.706066, -45.62338]
2022-06-22 09:57:48.671214 DEBUG [src/bin.rs:423] SetSpeed message received
2022-06-22 09:57:58.699986 DEBUG [src/audiodevice.rs:614] Current buffer level: 729.3, corrected capture rate: 100.0307%
2022-06-22 09:57:58.700468 DEBUG [src/alsadevice.rs:503] Playback buffer level: 729.3, signal rms: [-59.565437, -60.39319]
2022-06-22 09:57:58.700515 DEBUG [src/bin.rs:423] SetSpeed message received
2022-06-22 09:58:08.723908 DEBUG [src/audiodevice.rs:614] Current buffer level: 754.8, corrected capture rate: 100.0281%
2022-06-22 09:58:08.724417 DEBUG [src/bin.rs:423] SetSpeed message received
2022-06-22 09:58:08.724404 DEBUG [src/alsadevice.rs:503] Playback buffer level: 754.8, signal rms: [-42.29706, -39.478638]

This is with the adjust_period set to 10. It seems that the pops are more frequent when adjust_period is set to 1.
 

MCH

Major Contributor
Joined
Apr 10, 2021
Messages
2,581
Likes
2,199
I spoke too soon :(

I've since experienced occasional pops and clicks when watching Netflix. I don't know if it's the nature of the audio content that allows me to hear more vs music (quiet scenes?).

I've tried multiple combinations of chunksize, adjust_period and target_level and haven't yet found one that doesn't exhibit this. I've also noticed these pops and clicks more frequently in music since experimenting with different settings.

I'm happy to grab some data if that's useful. You mention debug - are you referring to the command line option for CamillaDSP?
The parameters that work for me with the icusbaudio7d card (no dropouts, very little latency) and pi 4b, in case you want to give them a try:
(the very low adjust period really helped in my case when experiencing dropouts. the default is 10 seconds i believe, maybe my 1 second is too little, but it works for me)

1655891931862.png
 

dfgoiuj

Member
Joined
Mar 22, 2022
Messages
43
Likes
5
The parameters that work for me with the icusbaudio7d card (no dropouts, very little latency) and pi 4b, in case you want to give them a try:
(the very low adjust period really helped in my case when experiencing dropouts. the default is 10 seconds i believe, maybe my 1 second is too little, but it works for me)

View attachment 214072
I'll give this a try, thanks. I didn't have much luck with setting the adjust_period so low before, but I see that your target_level is set to 100% of your chunksize, so maybe that makes a difference.

Do you run a Spotify Connect service on your RPi? I tried raspotify but couldn't get any audio out of it. I wonder how it hooks into CamillaDSP to play alongside TOSLINK input - maybe as a separate device that is added via a mixer?
 
OP
M

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,478
Likes
3,316
Location
Detroit, MI
I'll give this a try, thanks. I didn't have much luck with setting the adjust_period so low before, but I see that your target_level is set to 100% of your chunksize, so maybe that makes a difference.

Do you run a Spotify Connect service on your RPi? I tried raspotify but couldn't get any audio out of it. I wonder how it hooks into CamillaDSP to play alongside TOSLINK input - maybe as a separate device that is added via a mixer?

There are two ways I am aware of to integrate a physical capture device in addition to an ALSA loopback capture device in CamillaDSP.

1) Switch configurations between the ALSA loopback as capture device and the physical input as capture device. If you go through this thread you will see some discussion on how this can be done with a MOTU M4 as an example.

2) Have LMS running either on your RPi running CamillaDSP or another RPi on your network and use the WaveInput plugin with your capture device. Your CamillaDSP setup always uses an ALSA loopback as capture device. When you want to play something via TOSLINK just select your TOSLINK USB card on the WaveInput plugin. The disadvantage of this approach is that latency will be far too high to use in audio/video applications. This is also a nice option if you use Spotify as LMS has a Spotify plugin that is easy to use. Unfortunately there are some issues installing LMS on Ubuntu 22.04 currently, see post a few pages back for more details. That same post also has instructions on how to install librespot.

Michael
 

phofman

Senior Member
Joined
Apr 13, 2021
Messages
489
Likes
319
I didn't have much luck with setting the adjust_period so low before, but I see that your target_level is set to 100% of your chunksize, so maybe that makes a difference.
What is your chunksize? I am afraid of misunderstanding. I talked about 75% of the buffer size, but CDSP uses 2 chunks per buffer. That makes it 150% of chunksize. I am afraid you set it at 75% of the chunksize (i.e. at 37.5% of the buffer). That would be too small.

100% of chunksize is a very good value too, actually any value at or reasonably above the chunksize makes sense.

Look at the chart of the playback bufffer fill level vs. time. I know it's very complex because the timing in CDSP alsa in/out is that complex. The thick line stepped line is momentary output soundcard buffer fill level at time t (axis x). The avail_min line is buffer fill when the soundcard driver requests new samples (simplified). CDSP sets it at 1 chunksize (= half of the soundcard buffer). The algorithm tries to control the capture-side rate (CDSP either tells the capture device to change its rate or async resamples internally) so that at the moment of audio message (= new samples) delivery from the processing thread to the playback thread the output buffer fill level is as close to the target level as possible. Of course it varies a lot because the time of delivery varies too. Therefore the diffs (diff1, diff2, ...) are averaged for the feedback calculation, a new control algorithm is being tested in new CDSP version etc. The procedure is by its principle rather fragile and needs to be adjusted for every case. I am not sure the method can be made 100.000% reliable, the requirements are just too much conflicting with the real world. I intend to implement generating such charts into CDSP so that the timing can be visualized for any setup but no deadline given :)

1655968828482.png
 
  • Like
Reactions: MCH

somebodyelse

Major Contributor
Joined
Dec 5, 2018
Messages
3,682
Likes
2,962
Unfortunately there are some issues installing LMS on Ubuntu 22.04 currently, see post a few pages back for more details.
That looks set to continue until raspbian / Raspberry Pi OS shifts to bookworm given the answer in the issue report. I keep meaning to look into the Docker option.
 

dfgoiuj

Member
Joined
Mar 22, 2022
Messages
43
Likes
5
What is your chunksize? I am afraid of misunderstanding. I talked about 75% of the buffer size, but CDSP uses 2 chunks per buffer. That makes it 150% of chunksize. I am afraid you set it at 75% of the chunksize (i.e. at 37.5% of the buffer). That would be too small.

100% of chunksize is a very good value too, actually any value at or reasonably above the chunksize makes sense.

Look at the chart of the playback bufffer fill level vs. time. I know it's very complex because the timing in CDSP alsa in/out is that complex. The thick line stepped line is momentary output soundcard buffer fill level at time t (axis x). The avail_min line is buffer fill when the soundcard driver requests new samples (simplified). CDSP sets it at 1 chunksize (= half of the soundcard buffer). The algorithm tries to control the capture-side rate (CDSP either tells the capture device to change its rate or async resamples internally) so that at the moment of audio message (= new samples) delivery from the processing thread to the playback thread the output buffer fill level is as close to the target level as possible. Of course it varies a lot because the time of delivery varies too. Therefore the diffs (diff1, diff2, ...) are averaged for the feedback calculation, a new control algorithm is being tested in new CDSP version etc. The procedure is by its principle rather fragile and needs to be adjusted for every case. I am not sure the method can be made 100.000% reliable, the requirements are just too much conflicting with the real world. I intend to implement generating such charts into CDSP so that the timing can be visualized for any setup but no deadline given :)

View attachment 214204
Very useful information, thank you. I think I understand it a little better now. I did indeed have the target_level set to 75% of the chunksize rather than the buffer, which I now understand to be chunksize x 2.

My current settings are as follows, though sadly during the track I just played I heard several pops:

1656004541009.png


I am trying to understand how the adjust_period fits into this. I understand that this is the time delay between CDSP checking the input rate to see if adjustment is required, but I'm not sure how to figure out the optimal period, or what the consequence of checking too frequently or too infrequently would be. I imagine that it's probably something to do with target_level vs sample rate. I've not had much luck setting shorter or longer periods; I get popping regardless.
 
OP
M

mdsimon2

Major Contributor
Forum Donor
Joined
Oct 20, 2020
Messages
2,478
Likes
3,316
Location
Detroit, MI
I've not seen any mention of buffer underruns in the log unfortunately.

Then it would seem that your pops are not from buffer underruns and adjusting the CamillaDSP buffer will not solve your issue. In that case it seems that it is either a clock sync issue between your TOSLINK card and your source or your TOSLINK card and your DAC.

I would try to use the USB input of your DAC and see if that solves your issue as the DAC will no longer be reliant on the recovered TOSLINK clock.

Michael
 

dfgoiuj

Member
Joined
Mar 22, 2022
Messages
43
Likes
5
There are two ways I am aware of to integrate a physical capture device in addition to an ALSA loopback capture device in CamillaDSP.

1) Switch configurations between the ALSA loopback as capture device and the physical input as capture device. If you go through this thread you will see some discussion on how this can be done with a MOTU M4 as an example.

2) Have LMS running either on your RPi running CamillaDSP or another RPi on your network and use the WaveInput plugin with your capture device. Your CamillaDSP setup always uses an ALSA loopback as capture device. When you want to play something via TOSLINK just select your TOSLINK USB card on the WaveInput plugin. The disadvantage of this approach is that latency will be far too high to use in audio/video applications. This is also a nice option if you use Spotify as LMS has a Spotify plugin that is easy to use. Unfortunately there are some issues installing LMS on Ubuntu 22.04 currently, see post a few pages back for more details. That same post also has instructions on how to install librespot.

Michael
I'll have a look into these options, thanks. I imagined it must be possible to simply mix the input in the pipeline somewhere. I wonder if JACK could fit into this somehow.
 
Top Bottom