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

Is anyone else using a raspberry pi to send multichannel audio over hdmi? Is it working reliably?
CM4 +CM4 IO Board, USB Audio Gadget, connected by microUSB, powered by ATX from the main computer = 100% reliable

RPI4, USB Audio Gadget, connected and powered by USB-C from the main computer = 95% reliable. I tried other PSU, no change. But connected/powered from Lenovo notebook+Windows = almost 100% reliable.

RPI3 I gave up, problems with HDMI channel mapping, once it was working, after upgrade broken.

For both CM4 and RPi4 I use old graphic driver Fake KMS. New non-fake one does not support multichannel for me. I use only 64bit RaspbianOS.
 
One last question guys,
I moved to ubuntu server 23.04 to see if a new kernel solved the issue but it doesn't.

Anyways, the good news is that if i stop camilladsp and restart it, the channels go back to its original position, so what i wanted to do is to write a python script or similar that stops and restarts camilladsp in the case a buffer underrun happens. As with the right settings it will only happen seldom, even if i have 1-2 seconds no sound i think it is a minor problem vs having the channels swapped.
The problem is that looking at pycamilladsp i don't see that it reports buffer underruns, I only see get_buffer_level() that i guess goes to 0 when a buffer underrun happens (?). In any case, is there other way to achieve what i intend (be it with pycamilladsp or by other means) or is reading constantly get_buffer_level() and triggering a stop/start under a certain level be the only feasible solution?
Thanks in advance!
 
Nothing special, the hdmi transceiver chip in the dac i posted outputs 4x stereo i2s signals. Tapped those and built a board with 4xwm8804.

Yes, with large chunksizes the buffer underruns are very rare, but still, i want to have a tool to automatically correct the channel swap if it happens. As of now, i am thinking on a python script that reads the log file of camilladsp (-o, --logfile ) with a sort of "tail -f" functionality, so that if detects an underrun, restarts camilladsp. Not sure how it is going to work.... What i wonder is if those underruns are also written to an alsa log and if yes, where to find this log.

If you use exactly the same dac, i would be curious to know if you can force and underrun and see what happens.
 
Essence-Evolve-II-4K-rear-scaled.jpg


I use this one fromm essence but i think the "original" is from CYP. And i use it as DAC with analog out.
With low chunksizes less 1024, i get crackles from the underrun and then a capture error EPIPE broken pipe.
 
  • Like
Reactions: 1 user
@MRamone : If you want to hack like this, maybe it would be easier to modify CDSP directly, instead of unreliably parsing the output.

I do not know which branch is the "production" one, but e.g. in next20 (which contains alsa major improvements for CDSP 2.0) - instead of lines https://github.com/HEnquist/camilladsp/blob/next20/src/alsadevice.rs#L139-L140 you can call a return with some custom error like https://github.com/HEnquist/camilladsp/blob/next20/src/alsadevice.rs#L157 - that way CDSP will exit upon any xrun on playback. And your script can just keep restarting CDSP in a loop.

Compiling rust is trivial, just download the rustup binary and run it to install the complete rust chain https://www.redhat.com/sysadmin/install-rust-linux , also cloning a project from github is one command.

But both ways are just hacks...
 
  • Like
Reactions: 1 user
@MRamone : If you want to hack like this, maybe it would be easier to modify CDSP directly, instead of unreliably parsing the output.
This is an excellent idea and far easier than parsing logs. Then just configure systemd to restart the camilladsp service automatically, and you should have quite short gaps, likely well below a second.

I do not know which branch is the "production" one, but e.g. in next20 (which contains alsa major improvements for CDSP 2.0)
Yes use "next20", that is the branch for the upcoming v2.0. Once it's ready it will be merged to master.
 
The first preview of v2.0 is up, get it at https://github.com/HEnquist/camilladsp/releases/tag/v2.0.0-alpha1

Previews of the gui and supporting python libraries are nearly ready and will be published soon.

Changes from v1.0.3:

New features:
  • Add dynamic range compressor.
  • Add websocket commands to read peak and rms history.
  • Add ToggleMute websocket command.
  • Add AdjustVolume websocket command for relative volume changes.
  • Better handling of USB gadget in Alsa backend.
  • Add option to bypass pipeline steps.
  • Bluetooth capture support on Linux via Bluez.
  • Updated resampler with faster lower quality options.
  • Higher precision of biquad filters.
  • More flexible configuration of resampler type and quality.
  • Allow setting optional config parameters to null to use default value.
  • Add "Dummy" convolution filter type for easier CPU load testing.
  • Add title and description fields to various parts of the config.
  • Gain can be specified in dB or linear scale.
  • Websocket command to reset clipped samples counter.
  • Add an always enabled default volume control.
  • Add several volume control channels (faders).
  • Change Loudness filter to only perform loudness compensation.
  • Add more ditherers.
  • Add GeneralNotch biquad type.
  • Add Tilt equalizer biquad combo.
  • Add GraphicEqualizer biquad combo.
  • Support rate adjust for BlachHole on macOS.
  • Add statefile for persisting runtime parameters to file.
  • Websocket command to get pipeline processing capacity utilization.
  • Add commands to read statefile path and updating status.
  • Improved handling of config changes via SIGHUP and websocket.

Changes:
  • Optimize cpu load in general, and of dithering and delay filters in particular.
  • More logical names for dither types.
  • Updated Shibata dither coeffients.
  • Rename Set/GetConfigName websocket commands to Set/GetConfigFilePath.
  • Removed redundant`change_format` parameter to simplify CoreAudio device config.
 
  • Like
Reactions: 5 users
haha virtually minutes after i finished compiling my hack of next20 :)


@phofman thanks! your idea works perfectly!

modified the rust file lines you indicated:

} else if playback_state == alsa_sys::SND_PCM_STATE_XRUN as i32 {
warn!("PB: Prepare playback after buffer underrun");
return Err(DeviceError::new("Exiting CamillaDSP due to Buffer Underrun").into());

then modified the camilladsp service with the following lines:
Restart=always
RestartSec=0.1
RestartMode=direct (don't know why, but would not work without this line)

And now, after a buffer underrun, i get a pause, almost imperceptible, and camilladsp restarts with the correct channel assignment.

The biggest difficulty was that the old GUI does not really work with this new version and i needed to manually modify the config file each time i wanted to try something different. @HenrikEnquist looking forward to the new GUI, and thanks for the new version!
 
  • Like
Reactions: 1 user
  • Like
  • Thank You
Reactions: 2 users
@MRamone : congrats and hats off for your fast learning the rust workflow.

Still
And now, after a buffer underrun, i get a pause, almost imperceptible, and camilladsp restarts with the correct channel assignment.
Congrats, hats off how fast you got command of the rust chain.

I am looking at the drivers sources. Unfortunately the HDMI layer is hidden in the closed-source firmware, and only some messages are passed from linux. IIUC it the HDMI audio stream is restarted with the VC_AUDIO_MSG_TYPE_OPEN/CLOSE messages, the channel swap does not occur, whereas when sending only VC_AUDIO_MSG_TYPE_START/STOP messages, your HDMI receiver errs and swaps the channels randomly (i.e. does not align the incoming byte stream to frame boundary). Probably not much you can do about it, certainly not in the open source kernel code.
 
  • Like
Reactions: 1 user
Thanks for 2.0.0 preview Henrik! I've mostly got my head around the pycamilladsp nomenclature changes and can't wait to test out some of the new parameters like the config Title and Description fields.

There is just one thing I am unclear on. With the removal of active_config.yml what is the correct way to run camilladsp if you want to specify a configuration via the GUI? It seems like using "-s" to reference statefile.yml is the way to go but want to confirm.

Michael