Sample rate switcher for CamillaDSP

@Airharder
I recommed you to do what @phofman suggested in post #174:
First check that camilladsp-setrate works as expected. To this end please open a terminal session and run camilladsp-setrate manually with the following command:
/usr/local/bin/camilladsp-setrate --loglevel=notice

The output of this command should indicate that the process initialization completed with success. After that the process will wait for a sample rate change.
Any changes in the sample rate and actions resulting therefrom should be notified in the output, as well as possible errors and warnings.

Once you got a fully working camilladsp-setrate process, come back to this thread and together we will fix possible issues with services.

IMPORTANT NOTE:
If you do not specify the capture device on the command line, it defaults to "hw:UAC2Gadget". If you do want to use the "plughw" device type, you must add the device specification on the command line as follows:
/usr/local/bin/camilladsp-setrate --loglevel=notice --device=plughw:UAC2Gadget
Thank you so much for your ongoing help!

Please have a look at the attached screenshot. For me this looks like the camilladsp-setrate process initialization completed with success. You find a second screenshot, that shows what happens when I start a track with 44.1 Khz and then switch to a track with 48 Khz. This time it didn't recognise the change in sample rate. By the way rate adjust is enabled, see screenshot. Regarding the capture device selection: hw:UAC2Gadget doesn't work for me with the Wiim Ultra USB out. I tried several devices from the drop down menu and this is the one that works for sound output: plughw:CARD=UAC2Gadget,DEV=0.

Now I just changed the device again to hw:UAC2Gadget -> didn't work -> then again plughw:CARD=UAC2Gadget,DEV=0 and played a track with 48K, samplerate got recognised just fine! Then skipped over to a 44.1 K track, this sample rate switch also got recognised - > then went back to the 48K track -> and here the sample rate adjust failed - it got stuck on 44.1K.
 

Attachments

  • Bildschirmfoto 2024-10-18 um 16.45.34.png
    Bildschirmfoto 2024-10-18 um 16.45.34.png
    283.2 KB · Views: 56
  • Bildschirmfoto 2024-10-18 um 16.54.30.png
    Bildschirmfoto 2024-10-18 um 16.54.30.png
    1 MB · Views: 33
  • Bildschirmfoto 2024-10-18 um 17.00.46.png
    Bildschirmfoto 2024-10-18 um 17.00.46.png
    298.5 KB · Views: 36
@Airharder
I recommed you to do what @phofman suggested in post #174:
First check that camilladsp-setrate works as expected. To this end please open a terminal session and run camilladsp-setrate manually with the following command:
/usr/local/bin/camilladsp-setrate --loglevel=notice

The output of this command should indicate that the process initialization completed with success. After that the process will wait for a sample rate change.
Any changes in the sample rate and actions resulting therefrom should be notified in the output, as well as possible errors and warnings.

Once you got a fully working camilladsp-setrate process, come back to this thread and together we will fix possible issues with services.

IMPORTANT NOTE:
If you do not specify the capture device on the command line, it defaults to "hw:UAC2Gadget". If you do want to use the "plughw" device type, you must add the device specification on the command line as follows:
/usr/local/bin/camilladsp-setrate --loglevel=notice --device=plughw:UAC2Gadget
I just tried this command from your important note:
/usr/local/bin/camilladsp-setrate --loglevel=notice --device=plughw:UAC2Gadget

-> I'm getting this error message (see screenshot for details):

ALSA lib control.c:1528🙁snd_ctl_open_noupdate) Invalid CTL plughw:UAC2Gadget

alsa_init START Fatal error: Cannot open alsa controls for the device plughw:UAC2Gadget: No such file or directory

Not quite sure what to do from here.

After running the above command, I tried this again: /usr/local/bin/camilladsp-setrate --loglevel=notice
it doesn't seem to recognise any sample rate or anything when I play a track - see screenshot. This now seems like a little step backwards.
 

Attachments

  • Bildschirmfoto 2024-10-18 um 17.14.09.png
    Bildschirmfoto 2024-10-18 um 17.14.09.png
    300.2 KB · Views: 29
  • Bildschirmfoto 2024-10-18 um 17.28.29.png
    Bildschirmfoto 2024-10-18 um 17.28.29.png
    609.5 KB · Views: 31
Last edited:
@Airharder :

Please do not post screenshots if a text copy (wrapped in the CODE tags, of course) can be sent. It's MUCH easier to read, can be searched through, longer text can be posted.

. Regarding the capture device selection: hw:UAC2Gadget doesn't work for me with the Wiim Ultra USB out. I tried several devices from the drop down menu and this is the one that works for sound output: plughw:CARD=UAC2Gadget,DEV=0.
If plughw works and hw does not, most likely your CDSP capture params do not fit the gadget params. What are your gadget params? My 2 cents S24LE is being considered as 24 bits (c_size=3), instead of S24LE3, a very common issue.
 
alsa_init START Fatal error: Cannot open alsa controls for the device plughw:UAC2Gadget: No such file or directory
That's correct, the alsa controls require hw devices or pcm devices with defined ctl configs. IMO if you fix the very likely format issue and make hw:UAC2Gadget work, this issue will be fixed automatically too.
 
Last edited:
@Airharder :

Please do not post screenshots if a text copy (wrapped in the CODE tags, of course) can be sent. It's MUCH easier to read, can be searched through, longer text can be posted.


If plughw works and hw does not, most likely your CDSP capture params do not fit the gadget params. What are your gadget params? My 2 cents S24LE is being considered as 24 bits (c_size=3), instead of S24LE3, a very common issue.
Thank you, I'm still learning my way here in the forum - will post the code directly in the future (thought it's better to avoid these long code posts). Is there any special way of doing this right? When I copy the code from the mac terminal window, and paste it here, it usually enters many blank lines, that I feel like removing manually. Is there any better way of copying/pasting code here?

How can I set the CDSP capture params correctly then? I have changed the capture device sample format to S24LE3 - hw:UAC2Gadget still doesn't work. Generally I'm always trying different device sample formats. So far only the plughw:CARD=UAC2Gadget,DEV=0 is working for me. Any idea how I can fix the format issue and make hw:UAC2Gadget work with the Wiim Ultra USB out? Is there any setting I have to apply with the command line or anything I should change in 85-DAC.rules or camilladsp-setrate.service?

This is what I see in 85-DAC.rules, when I open it with nano:

SUBSYSTEM=="usb", ACTION=="add", ENV{ID_VENDOR_ID}=="1d6b", ENV{ID_MODEL_ID}=="0002", RUN+="/usr/bin/pkill -f -SIGHUP camilladsp-setrate"

And here what I see in camilladsp-setrate.service:

Unit]
Description=Automatic Sample Rate Changer Daemon for CamillaDSP
After=camilladsp.service

[Service]
ExecStart=/usr/local/bin/camilladsp-setrate --loglevel=err --syslog
Restart=always
RestartSec=1
StandardOutput=journal
StandardError=journal
SyslogIdentifier=camilladsp-setrate
CPUSchedulingPolicy=fifo
CPUSchedulingPriority=10
User=airharder
Group=airharder

[Install]
WantedBy=camilladsp.service
 
Last edited:
When I copy the code from the mac terminal window, and paste it here, it usually enters many blank lines, that I feel like removing manually. Is there any better way of copying/pasting code here?
I am afraid I cannot help you with that, no mac here. But it's almost certainly doable somehow, google is your friend.

How can I set the CDSP capture params correctly then?
Generally I'm always trying different device sample formats.
No need to try/error. Just use the same params as those assigned to the g_audio module (or configfs params, should you use that method).

You can check accepted hw params of any alsa device with --dump-hw-params parameter of aplay/arecord. E.g.

Code:
arecord --dump-hw-params -D hw:UAC2Gadget /dev/zero

or anything I should change in 85-DAC.rules or camilladsp-setrate.service
First make the features run OK in the terminal, watching output logs, easily restarting, changing params etc. Only then configure the autostarts at boot with the pre-tested working commands. It's a layered project - work out a layer by layer. That's why I am not a fan of writing guides which describe the final configuration in systemd services etc., giving an impression that such a project is just copy/paste work. This is a rather complex configuration which requires to learn a bit how things actually work below the surface to be able to troubleshoot issues which very often do pop up.
 
  • Thank You
Reactions: Airharder
@Airharder
Yes, from the first two screenshots we can take that initialisation was successful and that actions after a sample rate change are carried out as expected.
The second screen puzzles me, because I see that the sample rate 44100 appears twice in a row, where only changes should be recorded. A fanciful hypothesis is that the second notification refers instead to the 48KHz change and that, for some obscure reason, the alsa control returns the wrong value 44100. The latter phenomenon could be related to an incorrect format as @phofman suspects.
I forgot to recommend you to stop and disable the camilladsp-setrate service before running the process manually:
sudo systemctl stop camilladsp-setrate
sudo systemctl disable camilladsp-setrate

That's correct, the alsa controls require hw devices or pcm devices with defined ctl configs.
I am not an alsa expert and had missed that information. Thank you.
 
A fanciful hypothesis is that the second notification refers instead to the 48KHz change and that, for some obscure reason, the alsa control returns the wrong value 44100.
Or maybe the USB host side goes through some audio mixer (pulseaudio, windows audio mixer, ...?) which always resamples to a fixed samplerate, no matter what the source track samplerate is. It might look as it should be playing at 48kHz, while in fact everything is being resampled to 44.1kHz. Just 2 cents...
 
airharder@raspberrypi:~/camilladsp-setrate $ arecord --dump-hw-params -D hw:UAC2Gadget /dev/zero
arecord: main:831: audio open error: Device or resource busy
A very useful command is listing which processes have the audio devices open:
Code:
pavel@precision:~$ lsof /dev/snd/*
lsof: WARNING: can't stat() tracefs file system /sys/kernel/debug/tracing
      Output information may be incomplete.
COMMAND    PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
pulseaudi 2557 pavel  mem    CHR 116,42           751 /dev/snd/pcmC2D0p
pulseaudi 2557 pavel   16u   CHR 116,41      0t0  716 /dev/snd/controlC1
pulseaudi 2557 pavel   21u   CHR 116,44      0t0  753 /dev/snd/controlC2
pulseaudi 2557 pavel   27u   CHR 116,44      0t0  753 /dev/snd/controlC2
pulseaudi 2557 pavel   30u   CHR 116,35      0t0  695 /dev/snd/controlC0
pulseaudi 2557 pavel   42u   CHR 116,35      0t0  695 /dev/snd/controlC0
pulseaudi 2557 pavel   52u   CHR 116,42      0t0  751 /dev/snd/pcmC2D0p
pavel@precision:~$

Here you see that pulseaudio occupies/blocks playback (p) device of CARD=2,DEV=0. Aplay (another alsa client) will not be allowed to use that device as it's busy:

Code:
pavel@precision:~$ aplay -D hw:CARD=2,DEV=0 /dev/zero
aplay: main:852: audio open error: Device or resource busy
 
  • Thank You
Reactions: mevang
Or maybe the USB host side goes through some audio mixer (pulseaudio, windows audio mixer, ...?) which always resamples to a fixed samplerate, no matter what the source track samplerate is. It might look as it should be playing at 48kHz, while in fact everything is being resampled to 44.1kHz. Just 2 cents...
One thing I should maybe mention: I use CamillaDSP with FIR filters built with "Rephase" currently for 48Khz. I can rebuild them for any other sample rate. Is this by any chance a limitation to let the system always adapt to the music track sample rate? I use a 3-way FIR filter setup that drives 3 tube amplifiers for time aligned high, mid, low stereo signals.
 

Attachments

  • IMG_5643.jpg
    IMG_5643.jpg
    847.6 KB · Views: 35
lsof /dev/snd/*
Here is what I see:

airharder@raspberrypi:~/camilladsp-setrate $ lsof /dev/snd/*
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
pipewire 1004 airharder 52u CHR 116,1 0t0 407 /dev/snd/seq
pipewire 1004 airharder 53u CHR 116,1 0t0 407 /dev/snd/seq
wireplumb 1005 airharder 42u CHR 116,7 0t0 391 /dev/snd/controlC2
wireplumb 1005 airharder 45u CHR 116,12 0t0 396 /dev/snd/controlC3
camillads 1182 airharder mem CHR 116,6 390 /dev/snd/pcmC2D0c
camillads 1182 airharder 6u CHR 116,7 0t0 391 /dev/snd/controlC2
camillads 1182 airharder 7u CHR 116,14 0t0 640 /dev/snd/controlC4
camillads 1182 airharder 8u CHR 116,13 0t0 639 /dev/snd/pcmC4D0p
camillads 1182 airharder 11u CHR 116,6 0t0 390 /dev/snd/pcmC2D0c
camillads 1188 airharder 5u CHR 116,7 0t0 391 /dev/snd/controlC2
camillads 1982 airharder 5u CHR 116,7 0t0 391 /dev/snd/controlC2
camillads 2104 airharder 5u CHR 116,7 0t0 391 /dev/snd/controlC2
 
Please use the code tag to make the listings printed in monospaced font and thus readable. Just like I did in my post above.

First, you have pipewire running. Do you have your capture and playback hardware cards disabled in pipewire? If not, that's the very first step. A quick google search will tell you how to do that. If you do not tell pipewire to ignore these devices, it will randomly open=block them and you will be getting issues with "resource busy".

Then, you see that camilladsp blocks playback device hw:4,0 and capture device hw:2,0. Again - if you want another alsa client to use that device, you need to quit the blocking process so that the device is available for others. The control devices can be shared among clients, fortunately 🙂
 
Please stop camilladsp and camilladsp-setrate before issuing the arecord command.
Amazing, now this helped! I finally got an output to the command:

airharder@raspberrypi
:~/camilladsp-setrate $ sudo systemctl stop camilladsp-setrate
airharder@raspberrypi:~/camilladsp-setrate $ sudo systemctl disable camilladsp-setrate
airharder@raspberrypi:~/camilladsp-setrate $ sudo systemctl stop camilladsp
airharder@raspberrypi:~/camilladsp-setrate $ arecord --dump-hw-params -D hw:UAC2Gadget /dev/zero
Warning: Some sources (like microphones) may produce inaudible results
with 8-bit sampling. Use '-f' argument to increase resolution
e.g. '-f S16_LE'.
Recording WAVE '/dev/zero' : Unsigned 8 bit, Rate 8000 Hz, Mono
HW Params of device "hw:UAC2Gadget":
--------------------
ACCESS: MMAP_INTERLEAVED RW_INTERLEAVED
FORMAT: S32_LE
SUBFORMAT: STD
SAMPLE_BITS: 32
FRAME_BITS: 64
CHANNELS: 2
RATE: 44100
PERIOD_TIME: (521 46440)
PERIOD_SIZE: [23 2048]
PERIOD_BYTES: [184 16384]
PERIODS: [4 16]
BUFFER_TIME: (2086 743039)
BUFFER_SIZE: [92 32768]
BUFFER_BYTES: [736 262144]
TICK_TIME: ALL
--------------------
arecord: set_params:1352: Sample format non available
Available formats:
- S32_LE


Guess I need to change to "S32_LE"
 
Amazing, now this helped
Well, if next time you use the lsof command, you will understand why it helped and things will become logical and expected instead of amazing 🙂 That's where you want to head - no trial/error, but troubleshooting. It will take a while to learn but IMO definitely worth it.

Guess I need to change to "S32_LE"
Very good, see no trial/error needed. You also see that the hw device supports only 2 channels, only 44100Hz samplerate, but a range of buffer parameters. You can play with aplay and check hw params of your other devices - e.g. the playback one. It will likely list more formats/samplerates available then just one combination like the USB gadget.

Just note that Henrik calls his formats without the underscore (because his project is multiplatform and the underscores are used only by linux alsa formats).
 
  • Thank You
Reactions: Airharder
Very good, see no trial/error needed. You also see that the hw device supports only 2 channels, only 44100Hz samplerate,
I don't quite get it. Which device is this? The Wiim Ultra can obviously stream also higher rates than 44.1khz. Currently I use the Hifiberry DAC8X which is supposed to work up to 192 khz. Well, I changed to S32LE but I still don't get any sound with hw:UAC2Gadget. By the way, is the required device name really just hw:UAC2Gadget? I can choose "hw:UAC2Gadget,0,0" or "hw:CARD=UAC2Gadget,DEV=0" from the drop down menu.
 
First, you have pipewire running. Do you have your capture and playback hardware cards disabled in pipewire?
Not sure what pipewire is. I might have installed this (without deeper knowledge) when I tried something with https://jackaudio.org/. I wanted to try to pair three USB to SPDIF adapters into one audio playback device. Didn't manage to make it work. As you know I'm still looking for a way to get either 3 SPDIF outs or 3 I2S outputs from the Raspberry Pi5 with CamillaDSP. I need this, so I can finally go away from the DAC8X and use my DIY 6-channel tube DAC (see attachment. it accepts SPDIF optical or COAX as well as I2S as inputs).

Guess I can uninstall pipewire then, or is it useful for anything?
 

Attachments

  • PHOTO-2024-10-18-13-16-56.jpg
    PHOTO-2024-10-18-13-16-56.jpg
    373.3 KB · Views: 31
Which device is this?
I do not know, the mapping between ID and name is listed e.g. by aplay -l or ls -l /proc/asound/ . Check on your system.

The Wiim Ultra can obviously stream also higher rates than 44.1khz.
It may, but clearly your USB gadget device was opened at 44.1kHz in both cases. Again - what is your g_audio config? Did you configure it with multiple rates, or is your streamer forced to resample to 44.1kHz only?

Well, I changed to S32LE but I still don't get any sound with hw:UAC2Gadget
Then more issues are in your chain. CDSP logs will likely tell more. As I said this is not trivial to setup right and often does not work at first try. That's why it's important to start with the terminal and work layer by layer up to the fully working = correctly configured appliance.

I can choose "hw:UAC2Gadget,0,0" or "hw:CARD=UAC2Gadget,DEV=0" from the drop down menu.
Well, the GUI config is another layer. I would recommend to modify the CDSP config file directly, no extra layer of complexity. But your choice...

Device ID 0 and subdevice ID 0 are defaults, no need to specify the zeros. If you wanted to use device ID 1, then you would have to specify either hw:CARD=XY,DEV=1 or simply hw:XY,1 . Always use the card name instead of its ID as the card ID can change between reboots. Device/subdevice IDs are hard-coded in the device driver and do not change.
 
Last edited: