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

@LeRouge The next version of Pulseaudio Crossover Rack will use CamillaDSP as engine. Could that fit your requirements?
See:
https://t-5.eu/hp/Software/Pulseaudio Crossover NG/https://www.diyaudio.com/community/...over-design-implementation-with-linux.330273/
Yes, Henrik ! This is exactly what I was thinking !

In fact, I've only been looking at "software" DSPs for a few days. Usually I use a "nanodigi" for my active crossovers and Eq which actually works very well but I'm looking for something more "open" and less limited in addition and / or replacement.
The other concern is to find an interface with at least 3 good quality analog stereo outputs or at least digital.

In any case, your thing looks quite nice!
 
Have some more noob questions. When using an ALSA loopback as a capture device is there any advantage to selecting a particular format, say FLOAT64LE vs 32LE? The two way crossover example on github says to "pick a good one" and uses 32LE. Would a floating point capture device help with intersample overs?

Michael
 
You should just pick a sample format that is the same bit depth or better than the source material you are going to play. That basically means that you should pick 24-bit or better. Integer or float doesn't matter. If you pick 16-bit, then when you play 24-bit material it will be truncated to 16 bits when passing through the loopback.
 
Hi Hendrik,
no panic, but the "endless" loop card inactive is still coming.

2021-12-17 16:10:48.029803 DEBUG [src/processing.rs:21] Processing loop starts now!
2021-12-17 16:10:48.071320 INFO [src/alsadevice.rs:159] Starting playback from Prepared state
2021-12-17 16:10:58.059978 DEBUG [src/alsadevice.rs:502] Playback buffer level: 1397.5, signal rms: [-104.63896, -109.55342, -99.21762, -102.9211, -1000.0, -1000.0, -1000.0, -1000.0, -1000.0, -1000.0]
2021-12-17 16:11:00.347699 WARN [src/alsadevice.rs:155] Prepare playback after buffer underrun
2021-12-17 16:11:08.080077 DEBUG [src/alsadevice.rs:502] Playback buffer level: 1207.2, signal rms: [-90.44091, -96.225426, -83.75884, -84.478226, -1000.0, -1000.0, -1000.0, -1000.0, -1000.0, -1000.0]
2021-12-17 16:11:26.402759 WARN [src/alsadevice.rs:234] Wait timed out, capture device takes too long to capture frames
2021-12-17 16:11:26.408758 DEBUG [src/alsadevice.rs:697] Card inactive, pausing
2021-12-17 16:11:35.618918 WARN [src/alsadevice.rs:234] Wait timed out, capture device takes too long to capture frames
2021-12-17 16:11:35.619696 DEBUG [src/alsadevice.rs:697] Card inactive, pausing
2021-12-17 16:11:44.829844 WARN [src/alsadevice.rs:234] Wait timed out, capture device takes too long to capture frames
2021-12-17 16:11:44.830545 DEBUG [src/alsadevice.rs:697] Card inactive, pausing
^C2021-12-17 16:11:50.306508 DEBUG [src/bin.rs:287] Exit requested...
2021-12-17 16:11:54.040689 WARN [src/alsadevice.rs:234] Wait timed out, capture device takes too long to capture frames
2021-12-17 16:11:54.041272 DEBUG [src/alsadevice.rs:697] Card inactive, pausing
 
Hi Hendrik,
no panic, but the "endless" loop card inactive is still coming.
I think this was meant as a PM, but it might be a good idea to move the discussion here. Maybe someone else has some good ideas :)

Background:
Rolli is using a Hifiberry Digi+ I/O hat to receive sound from a streamer via spdif. That works fine as long as the spdif signal is on. But when the signal stops for more than a short moment, then the driver goes into some odd state which means it doesn't recover when the signal comes back. When using blocking alsa I/O, a few seconds after the signal stops we get an I/O Error. After that the device has to be closed and reopened to get it working again. In the upcoming alsa backend using non-blocking i/o, there is no error. Instead the device never reports that there is new data available, and camilladsp is stuck waiting.

The cause of the problem is that the driver for this hat is buggy. Hifiberry don't seem interested in fixing or improving it: https://support.hifiberry.com/hc/en...tify-SPDIF-TOSLINK-input-sample-rate-via-ALSA

I think this hat is common enough to make it worth implement some workaround (if that is possible), as long as that doesn't cause trouble for everyone else. Does anyone have experience with this hat? Ideas?
 
Instead the device never reports that there is new data available, and camilladsp is stuck waiting.

Interesting, does it mean that https://github.com/HEnquist/camilladsp/blob/alsanonblock/src/alsadevice.rs#L168 never returns?

The SPDIF receiver on that card has external clock available, therefore if configured correctly it should freewheel using that clock when no incoming SPDIF provides recovered clock. As such the MCLK->I2S should not be stuck, IMO it may be sending zeros instead.

Hifiberry like most other HW manufacturers "pigibacks" on the general rpi-wm8804 driver https://github.com/raspberrypi/linu...cd0/sound/soc/bcm/rpi-wm8804-soundcard.c#L290 , instead of writing a proper full-featured driver for their HW.

IMO the most complete driver is https://github.com/raspberrypi/linu...0c85c4e4fd0a64fcd0/sound/soc/bcm/rpi-cirrus.c by hiassoft https://community.element14.com/pro...ed-driver-for-wolfson-cirrus-logic-audio-card who is the major RPi I2S expert on RPi's forums. Notice the implementation of alsa controls for IEC958 status, recovered frequency, and various flags incl. frequency lock info in https://github.com/raspberrypi/linu...4e4fd0a64fcd0/sound/soc/bcm/rpi-cirrus.c#L328 . It would not be complicated to add these features back to wm8804-soundcard.c on which the rpi-cirrus.c was originally based.

Envy24-based cards with SPDIF receivers and freewheeling clocks use a timed worker which regularly checks whether the incoming rate has changed. If so, they stop the pcm stream so that the application can recover https://elixir.bootlin.com/linux/latest/source/sound/i2c/other/ak4114.c#L588

IMO a layer on top of camilla would be required which checks the alsa controls and starts/restarts camilla with appropriate samplerate. I am about to finish a simple start/stop controller in rust for the USB gadget which handles basically the same issue. Hopefully uploading to github later today.
 
Thanks for taking a look!

That wait call on line 168 returns when the given timeout expires, but always gives the value 0 (meaning not ready).
For comparison, when capturing from the usb gadget driver things work just fine. If the signal stops, then the wait times out and returns 0. And as soon as there is signal again it returns 1 for ready and things continue just fine. It doesn't matter if the signal stopped for a second or an hour, it always works.
With the digi+ this only works if the signal returns quickly (within a few seconds). If there is a longer period without signal then it fails to get going again when the signal comes back.

There appears to be no freewheeling on the digi+, as soon as the spdif signal stops the flow of data also stops.

It seems like the proper solution would be to make the wm8804 driver expose the status, rate etc as controls. And to make a "manager" for camilla that starts and stops based on the values of those controls.
 
It seems like the proper solution would be to make the wm8804 driver expose the status, rate etc as controls.
That's exactly what the rpi-cirrus driver does.

And to make a "manager" for camilla that starts and stops based on the values of those controls.
I think so. I wrote a simple rudimentary-rust gadget controller https://github.com/pavhofman/gadget_ctl , to be used by any gadget project and as a supporting use-case to gain acceptance of my pending gadget patches by the kernel devs. I believe it would work for CamillaDSP for the USB gadget as is. IMO it could be easily extended to support also the SPDIF receiver use case.
 
Hello Henrik,

I'm was really amazed when found your project, specially written in Rust - which is my current topic of interest. So thank you for your commitment for DIY and audio community :)

Is it possible and how difficult is to implement different filter topology configuration - something like tree branches, when an output from previous filter go into another channel? This was offered by Siegfried Linkwitz for his amazing LX521.4 speakers.

Here is an example and PDF with short explanation of benefits of this method :)

Screenshot 2021-12-20 at 10.52.03.png
 

Attachments

  • Filter-Topology-4-.pdf
    1,021 KB · Views: 62