CamillaDSP - Cross-platform IIR and FIR engine for crossovers, room correction etc

Henrik, in the camillagui/README.md you wrote
"If you want to be able to view the log file in the GUI, configure CamillaDSP to log to log_file"
Would you explain a bit more for me, please. Do I add to the start command?
camilladsp -p 1234 -w -s /path/to/statefile.yml -o /path/to/log_file.log

I have the CamillaDSP and the GUI running but the log file is blank when viewed from the GUI.
Yes, and you can set log level. Here is how I start CDSP as daemon. Not completly sure about the -w is needed, but it seem to function well.

ExecStart=/usr/bin/camilladsp -s /home/pi/camilladsp/statefile.yml -o /home/pi/camilladsp/camilladsp.log -l error -p 1234 -w
 
Not really CDSP related but since the phenomenon is conspicuous when configuring CDSP I'll try asking here.

When Squeezelite play mixed resolution music where content alter between 44.1, 48 and 96kHz 16/24-bit usually (not always) the music continue playing with no problems. Capture sample rate set at 44.1 and sample rate at 88.2kHz.
When checking ALSA capture device with 'cat /proc/asound/card0/pcm0c/sub0/hw_params' it also say 44.1kHz.

How is i that ALSA still can play high resolution audio with these settings? I understand format doesn't stop it as its probably converted to S32LE anyway. But I would expect it to stumble when SR changes.
And yes, I've checked that output from Squeezelite changes with audio file. Although this test did not make use of the Loopback device used with CDSP, but rather a USB DAC.
 
Although this test did not make use of the Loopback device used with CDSP, but rather a USB DAC.
IIUC your question is about Loopback. Samplerate of loopback is fixed to the other side (whatever side gets opened first becomes the "master").

Your USB DAC supports many samplerates, that's why you see the samplerate of the current track in the hw_params file. But if your loopback device is pegged to e.g. 44.1kHz, something before the device must resample. Either the plug plugin (if you have it configured), or squeezelite itself. Players often support resampling internally if the output device does not support the required rate.
 
  • Like
Reactions: DEQ+TheEnd
Just adding a little to the above story from @DEQ+TheEnd, it's very likely you have some resampling going on somewhere that you do not know about and so do not have control over. Be careful of this situation. At one time in the past when I started to use computer based (Linux) audio exclusively I noticed that some tracks sounded really, really bad. After awhile I figured out that the problem was that there was some resampling going on, and the "default" algorithm was terrible but fast. I know that some people take great pains to try and make the entire chain have the same sample rate as the source. I take the opposite stance - I just make sure that at some step along the way (for me that is currently in PulseAudio) that there is always resampling to some fixed rate of my choosing, using the highest quality algorithm possible. This puts me in control over resampling and once you set it up there is nothing more to do, ever, no matter what format is used by the audio. In my system I resample everything to 96kHz, and 24/32 bits, as this is a good compromise for my own needs. IMHO high quality resampling is not resulting in any changes to the audio that are audible (and barely measurable, too) and I do not worry about it.
 
"If you want to be able to view the log file in the GUI, configure CamillaDSP to log to log_file"
Would you explain a bit more for me, please. Do I add to the start command?
camilladsp -p 1234 -w -s /path/to/statefile.yml -o /path/to/log_file.log
Yes, you use the -o option to tell camilladsp to write logs to a file, and then you set log_file in the gui config to the same filename.
I have it running now, using this setting in camillagui.yml:
log_file: "~/camilladsp/camilladsp.log"
and camilladsp started with:
camilladsp -w -p 1234 -o ~/camilladsp/camilladsp.log
 
  • Like
Reactions: Wirrunna
Thanks @phofman & CharlieLaub. This one had me spinning for a while.

Squeezelite debug log confirms that it tries to open the alsa device with correct SR. But whatever I did on the system the only SR actually making sound with CDSP where 44100.

Not until I read this from CDSP log it startet to dawn on me I'm fighting an issue @HenrikEnquist might have a look at for next release.
2023-12-16 17:02:58.107756 INFO [src/bin.rs:683] CamillaDSP version 2.0.0
2023-12-16 17:02:58.107842 INFO [src/bin.rs:684] Running on linux, aarch64
2023-12-16 17:02:58.108387 DEBUG [src/bin.rs:728] Loaded state: Some(State { config_path: Some("/home/pi/camilladsp/configs/Tilt.yml"), mute: [false, false, false, false, false], volume: [0.0, 0.0, 0.0, 0.0, 0.0] })
2023-12-16 17:02:58.108469 DEBUG [src/bin.rs:735] Using statefile for initial volume
2023-12-16 17:02:58.108488 DEBUG [src/bin.rs:752] Using statefile for initial mute
2023-12-16 17:02:58.108501 DEBUG [src/bin.rs:765] Initial mute: [false, false, false, false, false]
2023-12-16 17:02:58.108529 DEBUG [src/bin.rs:766] Initial volume: [0.0, 0.0, 0.0, 0.0, 0.0]
2023-12-16 17:02:58.108544 DEBUG [src/bin.rs:768] Read config file None
2023-12-16 17:02:58.108557 DEBUG [src/bin.rs:800] No change to state from /home/pi/camilladsp/statefile.yml, not overwriting.
2023-12-16 17:02:58.110772 ERROR [src/bin.rs:814] capture_samplerate must match samplerate when resampling is disabled
2023-12-16 17:02:58.110831 DEBUG [src/bin.rs:815] Exiting due to config error

What had happened where that I had experimentet with resampling 44.1 and then later set the resampling to 'none'. Now the GUI hide the 'capture_samplerate' input, but the code still evaliate this parameter even with resampling disabled.
 
Now that I have more consistent behavior regarding resampling taking place at ALSA I've altered my testing method. CDSP is set to 96000 and verified with hi-rez files. What I've found is that the resampling actually take place at the Loopback device used by CDSP.

Using asound.conf by Henriks found here https://raw.githubusercontent.com/HEnquist/camilladsp-config/master/asound.conf
I tried changing every instance of 'type plug' to 'hw' in attempt to stop this functionality. Also tried changing rate to "unchanged".

Anyone know if this logic seen in the log file is handled by Squeezelite itself? Or is it simply ALSA that report back to Squeezelite that it is switching the device from hw to plughw to match SR using resampling?
#Squeezelite v1.9.8-1317 log level debug:
output_thread:687 open output device: hw:CARD=Loopback,DEV=1
alsa_open:351 opening device at: 44100
alsa_open:381 reopening device hw:CARD=Loopback,DEV=1 in plug mode as plughw:CARD=Loopback,DEV=1 for resampling
alsa_open:422 opened device plughw:CARD=Loopback,DEV=1 using format: S32_LE sample rate: 44100 mmap: 1

Although log also show this is not a critical problem as it seems that genuine hi-rez are not resamplet.
output_thread:687 open output device: hw:CARD=Loopback,DEV=1
alsa_open:351 opening device at: 96000
alsa_open:422 opened device hw:CARD=Loopback,DEV=1 using format: S32_LE sample rate: 96000 mmap: 1

BTW: I'm on latest RPI-OS Lite 64-bit (Debian)
 
OK, so I have modified camilladsp to restart on a buffer-underrun as discussed previously. AFAICS, this does not restart the entire process, it just sends a ExitStatus::Restart message to the CDSP processing pipeline and this causes everything to be reloaded. If that's true, then the restart configuration in systemd is a little bit irrelevant.
Anyway, as far as I can tell, because I have the -w flag on, CDSP just sits there waiting for a config after I restarted. I am not sure this is the intended behaviour.

Yes, I've modified CDSP but the same situation would happen if there is some kind of playback error in a vanilla CDSP install.

Here is what I get in the log on the first startup
Code:
2023-12-17 18:33:49.232929 DEBUG [src/bin.rs:994] Wait for config
2023-12-17 18:33:49.232974 DEBUG [src/bin.rs:1010] Waiting to receive a command
2023-12-17 18:33:49.232989 DEBUG [src/bin.rs:1013] Config change command received

Here is the buffer under-run:
Code:
2023-12-17 19:14:47.671345 WARN  [src/alsadevice.rs:138] PB: Prepare playback after buffer underrun
2023-12-17 19:14:47.692587 ERROR [src/bin.rs:286] Playback error: Aborting playback after buffer under-run
2023-12-17 19:14:47.692678 DEBUG [src/bin.rs:294] Wait for capture thread to exit..
2023-12-17 19:14:47.706965 DEBUG [src/socketserver.rs:523] parsed command: Ok(GetState)
2023-12-17 19:14:47.707684 DEBUG [src/socketserver.rs:523] parsed command: Ok(GetSignalLevelsSince(0.148))
2023-12-17 19:14:47.708683 DEBUG [src/socketserver.rs:523] parsed command: Ok(GetCaptureRate)
2023-12-17 19:14:47.709129 DEBUG [src/socketserver.rs:523] parsed command: Ok(GetRateAdjust)
2023-12-17 19:14:47.709520 DEBUG [src/socketserver.rs:523] parsed command: Ok(GetBufferLevel)
2023-12-17 19:14:47.709894 DEBUG [src/socketserver.rs:523] parsed command: Ok(GetClippedSamples)
2023-12-17 19:14:47.710262 DEBUG [src/socketserver.rs:523] parsed command: Ok(GetProcessingLoad)
2023-12-17 19:14:47.713048 DEBUG [src/alsadevice.rs:689] Exit message received, sending EndOfStream
2023-12-17 19:14:47.714211 DEBUG [src/bin.rs:1038] Processing ended with status Ok(Restart)
2023-12-17 19:14:47.714273 DEBUG [src/bin.rs:1052] Restarting with new config
2023-12-17 19:14:47.714287 INFO  [src/alsadevice.rs:143] PB: Starting playback from Prepared state
2023-12-17 19:14:47.714296 DEBUG [src/bin.rs:994] Wait for config
2023-12-17 19:14:47.714309 DEBUG [src/bin.rs:1010] Waiting to receive a command
2023-12-17 19:14:47.836968 DEBUG [src/socketserver.rs:523] parsed command: Ok(GetState)

It never receives a config change command and therefore never starts processing. I think CamillaGUI normally sends the config, but I guess it only does that when it first starts. I don't know enough about React to figure out how that works.

Command I use to start CDSP is:
Code:
/home/gordoste/camilladsp2/camilladsp -g-40 -ldebug -o /home/gordoste/camilladsp2/camilladsp.log -p 1234 -w -s /home/gordoste/camilladsp2/statefile.yml
 
because I have the -w flag on, CDSP just sits there waiting for a config after I restarted. I am not sure this is the intended behaviour.
Yes this is how it's intended to work. A restart means go back to start, wait for someone to tell you what to do.


OK, so I have modified camilladsp to restart on a buffer-underrun as discussed previously.
Why is this needed? Buffer underruns that can't be handled by the existing recovery procedure should be rare. But if they can't be avoided, it would be better to work on improving that, to cover more failures.
 
OK thanks for answering so quickly. I just wasn't sure if that was an intended part of the behaviour of the -w flag. I will turn it off.

I need to do the restart after buffer under-run because I have the same problems as @MRamone with a HDMI extractor that messes up the channels after a buffer underrun. Restarting camilladsp fixes the channels up.
 
IIUC the source code, the VC4 HDMI audio driver for RPi defines only a few methods https://github.com/raspberrypi/linu...9a/drivers/gpu/drm/vc4/vc4_hdmi.c#L2718-L2723 .

vc4_hdmi_audio_prepare https://github.com/raspberrypi/linu...0fdc499a/drivers/gpu/drm/vc4/vc4_hdmi.c#L2569 is called currently through snd_pcm_prepare when handling xruns https://github.com/HEnquist/camilladsp/blob/master/src/alsadevice.rs#L139

vc4_hdmi_audio_startup https://github.com/raspberrypi/linu...0fdc499a/drivers/gpu/drm/vc4/vc4_hdmi.c#L2432 is called at snd_pcm_open, while vc4_hdmi_audio_shutdown at snd_pcm_close https://github.com/raspberrypi/linu...0fdc499a/drivers/gpu/drm/vc4/vc4_hdmi.c#L2497

All the three methods send some config messages to the HDMI part of VC4 . IIUC most likely some of the messages sent by vc4_hdmi_audio_startup or vc4_hdmi_audio_shutdown or vc4_hdmi_audio_reset (called by vc4_hdmi_audio_shutdown) somehow manage to re-align the channels in the chain, while the messages sent in vc4_hdmi_audio_prepare don't. There is no documentation for the VC4 messages https://github.com/raspberrypi/linu...499a/drivers/gpu/drm/vc4/vc4_regs.h#L883-L905 (that's why IMO RPi is a pretty closed opaque system, compared to other ARM SoCs). Maybe the RPi devs could be asked to review the messages, whether some of the messages should not be added to vc4_hdmi_audio_prepare.