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

The M1 has a handicap at the moment, the FFT isn't using neon yet! That will hopefully change quite soon. But for now, an Intel or AMD CPU with AVX is the best choice for top performance.

Btw, would someone be willing to run some RustFFT benchmarks on an M1? I'm curious how fast it runs with (and without) neon compared to amd or Intel with avx or sse.
 
Happy to run benchmarks on an M1, with instructions :)
Excellent, thanks!
To run the benchmarks you need the latest nighly compiler. You can use rustup to get it: https://rustup.rs/
After installing, switch to the nightly compiler with "rustup default nightly".

Then clone my fork of RustFFT and check out branch "stableneon". Link: https://github.com/HEnquist/RustFFT/tree/stableneon

Finally, in the RustFFT directory, run the benchmarks with "cargo bench --features neon". This runs all the benchmarks so it will take a while, and prints all the bench results in the terminal. You can use "tee" to save to a text file and still see the output, "cargo bench --features neon | tee results.txt".

Last step is to just attach the file here :) Then I will make some plots from the data.
 
Here is the effect of enabling neon in RustFFT for the M1:
M1_neon_vs_scalar.png


The M1 compared to my first generation Ryzen CPU.
First the time in nanoseconds (lower is better):
RustFFT_time_comparisons.png


Then the speed relative to the scalar algorithm on the Ryzen (higher is better):
RustFFT_comparisons.png


I don't have a newer amd or intel cpu to test on, but the latest ones should be maybe 50% faster than my old Ryzen. That would mean that one of those and the M1 (with neon) are pretty even in speed.
 
  • Like
Reactions: 1 users
Quick question.
Got camilladsp working on one rpi4 (USB) and one rpi3 (i2s)
Great product.
Use squeezelite as player. However I resample everything to 96khz in SOX (squeezelite) using these settings which I like very much.
SB_EXTRA_ARGS="-a 80:4::1 -b 2048:25000 -p 45 -r 96000-96000 -e dsd -C 5 -R v::3.05:28:99.7:100:45"
Almost all use is from stored music (NAS)

Would using alsa_cdsp instead be beneficial or should I just leave it as is?

BR
 
Last edited:
Hi @HenrikEnquist
Since upgrading to moOde 8.1.1, which uses CamillaDSP v1, I find I can not longer play any music without an error, seemingly from CamillaDSP. I asked about it on the moOde support page but perhaps I should be posting it here instead?

Briefly, with my very simple headphone EQ I find that after around an hour of continuous playback I get CDSP Plugin ERROR: XRUN OCCURRED! errors and the playback stops. The same pi, music, eq worked fine before I upgraded moOde.

The link is here: https://moodeaudio.org/forum/showthread.php?tid=4939

I can repost the details and what I've been attempting to work around this here if required.
 
Would using alsa_cdsp instead be beneficial or should I just leave it as is?
The main benefit of using alsa_cdsp is that you can switch the dac to match the sample rate of the music. The downside with that is that the camilladsp filters also switch then. Not a problem for iir filters, but a bit of work for fir since you need separate sets of coefficients for every sample rate.
In practice I think you most likely won't hear any difference. Sox resamples with very high quality.
 
Hi @HenrikEnquist
Since upgrading to moOde 8.1.1, which uses CamillaDSP v1, I find I can not longer play any music without an error, seemingly from CamillaDSP. I asked about it on the moOde support page but perhaps I should be posting it here instead?
I looked in the link, and my guess is that there is an issue with the alsa_cdsp plugin. I don't know what version of that is used in moOde. Let's wait and see if anyone in the moOde forum has some idea first.
 
  • Like
Reactions: 1 user
I'm a little puzzled why you would serialize FIR filters. There is no need to cascade them, you just design one FIR filter to do the same as N FIR filters in series.
I hope this question is not too far off topic...

I've often read that two FIR filters can be combined into one in order to achieve the same results as cascading both filters. I just never grasped how to take two FIR filters and join them into a new one. How's this actually done in practice?
 
Is the mute functionality in the GUI different from the mute functionality when using get_mute() and set_mute()?

I recently added mute functionality using an IR remote / receiver using get_mute() and set_mute(). This behaves exactly how I prefer, I can read mute status using get_mute() and once mute is set I can change the volume and the output stays muted. Once I unmute the volume is set to whatever the current volume is. However the mute status does NOT show up in the GUI when doing this.

The GUI mute functionality seems to behave differently. When I hit the mute button in the GUI it does not retain the current volume and rather attenuates to -99 dB (may be lower but I have mine set to limit to -99 dB for display purposes). I also can not correctly read mute status using get_mute(). If I change the volume rather than stay muted it jumps back to the previous volume level.

If possible I would like the GUI and get_mute() / set_mute() to have the same behavior in line with how get_mute() and set_mute() currently behave.

Michael