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

@torgeirs everything in the CamillaDSP pipeline runs at the same sample rate so this isn't possible. I have though about if the impulse response could be automatically resampled but I haven't come up with any good general solution for that.

Here is an old reply on nearly the same topic:

You could probably do that but it would get pretty clunky. CamillaDSP supports only one resampling, on the capture side. And then you have to resample all channels. To upsample again you would need to run two instances, the first downsampling and doing the processing, then feeding the audio via a pipe to second instance that upsamples to the original rate.
I thought decimation was mainly used when doing FIR with direct computation (on embedded systems where FFT may not be available and stuff like that), which gets very heavy for long filters. CamillaDSP does FFT-based convolution which is much much faster for long filters. I'm not sure you would gain anything by downsampling.
 
With the cosmos ADC and cheap ultra hf USB Dacs there will be new demand for preserving a high Fs through the system and only do DSP on the 20 to 20k part.
ADC and DAC noise and bandwith is no longer a limiting factor (eg -126 dBA noise. -140db thd components below 20k and 300k bandwith
A bit overkill to do 48kHz fs FIR filter on a 768kHz samplerate
IMHO
 
Last edited:
IMHO an overkill is running several instances of CDSP, linked via huge-latency pipes, instead of one instance running at higher samplerate.

768kHz/24bits allows only three channels at standard UAC2, there are almost no multichannel USB soundcards for this samplerate. I do not think there will be a notable demand for 768kHz DSP. And if required - any modern CPU can handle CDSP filters running at high samplerates. No reason to stay limited to RPi, if no I2S or USB gadget were required. And if so - there are powerful ARM SoCs available - e.g. the many older RK3588-based boards or e.g. new https://radxa.com/products/orion/o6/
 
IIUC Cosmos ADC is designed primarily for sensitive low-noise/distortion measurements up to high frequencies (hence setting the input filter so high). It does not seem the best fit for standard audio recording to me, but why not.

What is actually the reason for the need to resample in the chain? I am sorry I did not get it.
 
Last edited:
Multirate signal prosessing is just a old way of doing narrow bin FIR with way less prosessor speed and memory.

Downsampling and noiseshaping saves on the DACs if low bandwith is needed. Like mids and bass. The hf is filtered out anyway so can be littered with noise
Very low frequency IIR compared to nyquist can result in noise if not done right
 
Last edited:
By the way the hardware resamplers of the AD ADAU family can also be used to implement cheap multirate FIR by routing the stream through them. So the 8 resamplers is not only to get the same samplerate from all inputs. Its also to be able to prosess different streams at different rate
 
Did you try to do this directly at 768kHz at full FIR resolutions without any resampling in CDSP running on a reasonable HW, preferrably x86 with good float64 accelleration and vector instructions? I would be surprised if it had any serious issues with CPU load. Also the CDSP multithreaded processing branch could be used, allowing to run the FIR filters for each channel on separate CPU cores.
 
With the cosmos ADC and cheap ultra hf USB Dacs there will be new demand for preserving a high Fs through the system and only do DSP on the 20 to 20k part.
What is the benefit or running the dsp at very high sample rates? IMHO doing it's just wasting computing resources.

A separate adc and dac like this will need asynchronous resampling at very high sample rates, that gets pretty heavy if done at high quality.

Multi-rate processing doesn't fit well with how CamillaDSP works. If I did add it, the pipeline code would need to become a lot more complicated, and it would get much more difficult to configure it.
 
Ok, thanks.
Good to highlight that limitation.

If high sample frequency (>192khz)ADC/DACs are used try a simple in out with resampling test first.
If not working. Make/buy a apropriate input filter for ADC and use 192k

Or can syncronous resampling of input down to 192-44,1 work as first step for analog input on HF ADCs?
 
Openhome playlists and alsa_cdsp
I try to use CDSP (thanks to HenrikEnquist for this great software) for digital sound processing togther with openhome renderer softwares on an RPI. As renderer software, I use ohPlayer (LINN) as well as mediaplayer (PeteManchester) with ALSA as output. The idea was to use alsa_cdsp to avoid adjustments/conversions of the sample format if a playlist contains songs with different rates and bit depths. I installed CDSP (2.03) as well as alsa_cdsp (spfenwick). Using aplay, the system works perfect with all file formats, CDSP is started with the correct sample rates/bit depths. However, this does not work with an openhome playlist. It works with the first song but has a problem when a second song is loaded to the playlist and both mediaplayer and ohPlayer hang up.
The only way to get it running was with the mediaplayer software which uses mpd as player. I had to install CDSP as service and let mpd convert all the files to a constant format before processing by CDSP.
I have only superficial programming knowledge, therefore, I would like to ask the insiders what could be the problem with alsa_cdsp and openhome playlists?
 
As renderer software, I use ohPlayer (LINN) as well as mediaplayer (PeteManchester) with ALSA as output.
IIUC the mediaplayer is a java controller which uses either mpd or mplayer for the actual playback. Which player do you actually use?
It works with the first song but has a problem when a second song is loaded to the playlist and both mediaplayer and ohPlayer hang up.
The only way to get it running was with the mediaplayer software which uses mpd as player.
So does the mediaplayer -> mpd hang up? In the previous sentence you say it does.

Looking at the ohPlayer alsa code it uses fixed alsa device ("default"), if I understand the code correctly https://github.com/openhome/ohPlaye...14eca228e/linux/DriverAlsa.cpp#L940C7-L940C13 . Also the buffer size seems to be fixed to 22ms https://github.com/openhome/ohPlaye...deef52514eca228e/linux/MediaPlayerIF.cpp#L194

As Henrik says - logs from mpd/mplayer/ohPlayer are crucial here.
 
Code:
2025-01-05 01:04:49,341 [Thread-0] DEBUG [org.rpi.mpdplayer.StatusMonitor] Song Changed From :  To: 1
2025-01-05 01:04:49,343 [Thread-0] DEBUG [org.rpi.mpdplayer.StatusMonitor] Status Changed From : Stopped To: Playing
2025-01-05 01:04:49,343 [Thread-0] DEBUG [org.rpi.mpdplayer.MPDPlayer] Status Changed: Playing
2025-01-05 01:04:49,343 [Thread-0] DEBUG [org.rpi.player.PlayManager] EventStatusChanged: Playing
2025-01-05 01:04:49,343 [Thread-0] INFO  [org.rpi.player.PlayManager] SetStatus: Playing Source: PLAYER
2025-01-05 01:04:49,344 [Thread-0] DEBUG [org.rpi.providers.PrvAVTransport] Status: Playing
2025-01-05 01:04:49,345 [Thread-0] DEBUG [org.rpi.providers.PrvTransport] Status: Playing
2025-01-05 01:04:49,347 [Thread-0] DEBUG [org.rpi.mplayer.TrackInfo] Send EventUpdateTrackInfo: TrackInfo [bSentUpdate=true, codec=16 bits, bitRate=0, sampleRate=44100, duration=295, depth=16]
2025-01-05 01:04:49,352 [Thread-0] DEBUG [org.rpi.providers.PrvInfo] SetDetailsCount: 1 TrackInfo [bSentUpdate=true, codec=16 bits, bitRate=0, sampleRate=44100, duration=295, depth=16]
2025-01-05 01:04:49,443 [Thread-9] DEBUG [org.rpi.providers.PrvAVTransport] GetTransport Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:50,479 [Thread-7] DEBUG [org.rpi.providers.PrvAVTransport] GetTransport Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:50,480 [Thread-6] DEBUG [org.rpi.providers.PrvAVTransport] SetNexAVTransport: 0   Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:50,480 [Thread-6] DEBUG [org.rpi.player.PlayManager] Set Next AV Track : 
2025-01-05 01:04:50,480 [Thread-6] DEBUG [org.rpi.mpdplayer.MPDPlayer] PreLoad Next Track:
2025-01-05 01:04:50,480 [Thread-6] ERROR [org.rpi.radio.parsers.FileParser] java.net.MalformedURLException: no protocol:
2025-01-05 01:04:50,481 [Thread-6] ERROR [org.rpi.mpdplayer.TCPConnector] Error: ACK [50@0] {addid} No such song
2025-01-05 01:04:50,483 [Thread-8] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:50,488 [Thread-9] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:51,393 [Thread-7] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:52,297 [Thread-6] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:52,488 [Thread-8] DEBUG [org.rpi.providers.PrvAVTransport] GetTransport Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:53,200 [Thread-9] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:53,405 [EventThread] DEBUG [org.rpi.pins.PinManager] Reconnect Attempt: io.socket.client.Socket@1a20f67
2025-01-05 01:04:54,105 [Thread-7] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:54,492 [Thread-6] DEBUG [org.rpi.providers.PrvAVTransport] GetTransport Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:55,009 [Thread-8] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:55,914 [Thread-9] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:56,503 [Thread-7] DEBUG [org.rpi.providers.PrvAVTransport] GetTransport Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:56,819 [Thread-6] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:57,724 [Thread-8] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:58,507 [Thread-9] DEBUG [org.rpi.providers.PrvAVTransport] GetTransport Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:58,628 [Thread-7] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:04:59,532 [Thread-6] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:05:00,437 [Thread-8] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:05:00,511 [Thread-9] DEBUG [org.rpi.providers.PrvAVTransport] GetTransport Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:05:01,340 [Thread-7] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:05:02,243 [Thread-6] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:05:02,514 [Thread-8] DEBUG [org.rpi.providers.PrvAVTransport] GetTransport Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
2025-01-05 01:05:03,147 [Thread-9] DEBUG [org.rpi.providers.PrvAVTransport] Get Position Info Adapter: 192.168.2.36 uriPrefix: http://192.168.2.36:52821/device-Mediaplayer-raspberrypi-MediaRenderer/Upnp/resource/ Version:1
This is the log with mediaplayer/mpd. The track stops playing after 1 sec and the mediaplayer hangs up.