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

I don't usually listen to music on macOS, but I think the automatic src is good. There are some measurements here that look good:
https://src.infinitewave.ca/
Pick "Apple CoreAudio (Leopard)". It's a bit old but it's probably safe to assume that the quality hasn't gotten worse in later versions.

MacOS Leopard SRC shows very high-end performance with linear phase property. I suspect that some later MacOS uses sort of minimum-phase SRC which is still very good and also more efficient.
 
The AccurateAsync asynchronous resampler preset yields beautiful results, but is just a bit too hefty in terms of cpu demands for my rpi3 gadget which I like to run at a "cool" and steady-state 600MHz while resampling everything to 96kHz. In order to find some kind of sweetspot/tradeoff between quality and cpu usage, I therefore made some dry runs along with the FreeAsync resampler type. A multisine signal of 2097152 samples on a 64Bit dbl-file was read by camilladsp, with different settings for the resampler, and then written to an output 64Bit dbl file. I finally found a subjectivly very appealing setting, where all the in-band and out-of-band distortive products are more or less at the same <175dB level:

sinc_len: 128
oversampling_ratio: 128
interpolation: cubic
window: BlackmanHarris2
f_cutoff: 0.9

This is now my sweetspot-setting that I chose for my rpi3.
 

Attachments

  • lin_sl256_osr64-2048.png
    lin_sl256_osr64-2048.png
    30.6 KB · Views: 98
  • cub_sl128.png
    cub_sl128.png
    33.8 KB · Views: 87
  • Sweetspot.png
    Sweetspot.png
    53.5 KB · Views: 88
  • Like
Reactions: jheoaustin
Hi Daihedz,

Thank you very much for the informaiton. Sorry that I am a newbie and I have to ask dumb questions. How can I use this 'lighter' SRC instead of the CoreAudio standard one? I also think I am okay with float operation which hopefully half the workload level.

Regards,
Jay
 
Last edited:
There would be two things needed to track down for partially answering your question. The first thing would be to know how precisely CoreAudio actually performs src calculations, and the second would be then at what cpu cost. A brief search in the internet did unfortunately not provide any clues. So you seem to be on your own: You would have to force CoreAudio to perform a src on a test signal, and then analyze the result(s) in matter of quality and processing time. And then compare it to the Rubato/CamillaDSP resampler.

In my former post, I wrote about <175dB for the distortion products of my sweetspot-compromize. If you look at the graphs a bit more precisely, you will be aware that it is even better at <180dB. And this is a very, very, very beautiful result as such and theoretically, which comes at a quite moderate cpu cost. Instead practically, no digital-analog converter will match these low distortion products. The very best dac today are linear to some 125dB or so. And as for the discrimination quality of your individual, psychosomatically embedded auditive system ... better forget it. So even if CoreAudio would show a result of, say td/im at <150dB this still would be way more than suited for very best quality home audio.

Therefore, this aformentionned CamillaDSP configuration is a pure luxury and a waste of cpu ressources for even the most cricical audio use. Optimizing rationally for realtime audio, one would better more modestly and realistically aim something at "only" <140dB or even a bit "worse". And with this sound logic comes another beauty of the CamillaDSP/Rubato resampler: The fact that you may tweak your resampler nearly at will. And while talking about tweaking, if you have a look at https://github.com/HEnquist/camilladsp/tree/next20 you will see that there is an additionally quadratic interpolation option to come, promising a very attractive, additional quality range between the linear and the cubic interpolation. Which hopefully might be perfect and optimized for aiming at a very reasonably target range between <130dB ... <160dB. We will see ... on our graphs, at least, by then. But for shure we will not hear any difference between a rubust <140dB compared to a hypy and shiny <180dB.

So, let's first be rationally modest in terms of precision demands, and then let's compare apples to apples. In these equal terms, it would indeed be interesting to compare the efficiency of the Rubato library with the one used in CoreAudio to perform src. And if CamillaDSP would win this competition hands-down ... then ... arises the question, how to disable the CoreAudio src. A quite relevant question indeed in this case. I hope there will be an answer to this question. I am using Linux, so therefore I am not able to help.

Happy tweaking and benchmarking, then.
 
Last edited:
  • Like
Reactions: TNT
Meanwhile ...

... I have compiled CamillaDSP next20 version branch on my old and outdated, but still faithful linux W500 lenovo laptop. Not to only hypothetically speak about this maybe promising quadratic interpolation option to come. But instead to see in real-world how it might look like. The result in one word: EXCELLENT! It is exactly a best imaginable compromise matching the above talk/logic, merging flawless src with lean cpu usage.

Starting from the cubic interpolated sweetspot (sync_lenght=128 / oversampling_factor=128), as shown already in one of my previous posts with it's fabulous but overkill >180dB S/N ratio, the basically same, but quadratic interpolated 128/128 version will compute at a real-world-best-compromise of 140dB S/N ratio for about a bit more than half the CPU ressource compared to the cubic interpolation algorithm. So this quadratic interpolation option will certainly be a winning addition to the next version of CamillaDSP for the everyday real-world, no-compromise, highest-standard audio experience.

Have a look at the graph, judge by jourself and then make your choice: Red == Quadratic interpolation / Green == Cubic interpolation
 

Attachments

  • quad_cub.png
    quad_cub.png
    22.7 KB · Views: 103
Last edited:
Hi, i am enjoying camilladsp quite a lot and am in the process of writing some documentation from the viewpoint of a less experienced user.
Now i am having troubles with the alsa plugin setup, where i am seeing a lot of XRUN Errors.
This is my setup:
https://rawdlite-audio-doc.readthedocs.io/en/latest/camilladsp.html#install-camilladsp-alsa-plugin
The Loopback Device Setup on the same device (asus tinkerboard) is working without error.
I test with speaker-test like so:

speaker-test -D camilladsp -c 2 -r 48000

speaker-test 1.2.4

Playback device is camilladsp
Stream parameters are 48000Hz, S16_LE, 2 channels
Using 16 octaves of pink noise
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 960 to 32768
Period size range from 480 to 4096
Using max buffer size 32768
Periods = 4
was set period_size = 4096
was set buffer_size = 32768
0 - Front Left
CDSP Plugin ERROR: XRUN OCCURRED!
Write error: -32,Broken pipe
....
1 - Front Right
CDSP Plugin ERROR: XRUN OCCURRED!
Write error: -32,Broken pipe
2023-04-16 07:58:48.568086 WARN [src/filedevice.rs:446] sample rate change detected, last rate was 43889.27755166043 Hz
CDSP Plugin ERROR: XRUN OCCURRED!
Write error: -32,Broken pipe
2023-04-16 07:58:49.586608 WARN [src/filedevice.rs:446] sample rate change detected, last rate was 52232.50795935853 Hz
CDSP Plugin ERROR: XRUN OCCURRED!
Write error: -32,Broken pipe
CDSP Plugin ERROR: XRUN OCCURRED!
Write error: -32,Broken pipe
Time per period = 5.462031

I am especially irritated by the frequent sample rate change detections.
Please advice how to best proceed.
 
IMO there are several things to consider.

speaker-test uses blocking write to alsa, it has no internal timer. Therefore, it feeds data at the playback device speed, it has no internal notion of a "proper" samplerate.

CDSP measures rate of input data in the filedevice. But speaker-test has no internal control at which it generates data - it will feed at any pace queried. This is different from a situation where e.g. a streaming coming from network is being passed through a pipe - the provider cannot feed faster than the incoming stream.

Now the rate measuring in filedevice is configured quite strictly - only 4% difference of samplerate. That is perfect for a rate-limited input file, but IMO unattainable when reading from a slaved source which has no internal rate clock. Such source will provide data depending on status of the alsa buffers, OS scheduling, etc. The measured rate will fluctuate a lot, especially since the averaging rate_measure_interval is only one second.

But, if the config is stop_on_rate_change: false (the case in CDSP plugin documentation), that warning about sample rate change detected is harmless. IMO no need to worry about it, it's just an info which IMO is irrelevant in this use case.

However, I am confused about the xrun complaints of the CDSP plugin because these are reported back to speaker-test which subsequently runs the xrun_recovery method which calls snd_pcm_prepare(), effectively breaking the stream. Perhaps the XRUN detection functionality in the plugin is what needs to be investigated and maybe adjusted, if possible.

For start perhaps increasing speaker-test period could be tested.
 
Thank you for the prompt reply.
This is different from a situation where e.g. a streaming coming from network is being passed through a pipe - the provider cannot feed faster than the incoming stream.

Understood, i will test with squeezelite next then.
Perhaps the XRUN detection functionality in the plugin is what needs to be investigated and maybe adjusted, if possible.

I found a fork of the plugin that tries to address the XRUN Error from what i understand from the commit message.
https://github.com/bitkeeper/alsa_cdsp

Will try that and report back.
For start perhaps increasing speaker-test period could be tested.
Will do.
 
Did period size reported by speaker-test change? It could get smaller => smaller granularity of the samples delivery => more precise "virtual samplerate" as requested by CDSP. But that 4% threshold is just a figure, you can change it in CDSP source code and the message would also go away.

Or if the period size did not change, speaker-test used longer alsa buffer and pre-generated more samples for the alsa chain, allowing CDSP to consume samples more continuously.
 
Trying to get Camilladsp to work under Windows 10 and so far i have sound through. I cant get the gui to start;

C:\Users\morte\Camilladsp>python3 main.py
Backend configuration:
active_config: C:\Users\morte\camilladsp\active_config.yml
active_config_txt: C:\Users\morte\camilladsp\active_config.txt
camilla_host: 127.0.0.1
camilla_port: 1234
coeff_dir: C:\Users\morte\camilladsp\coeffs
config_dir: C:\Users\morte\camilladsp\configs
default_config: C:\Users\morte\camilladsp\default_config.yml
log_file: ~/camilladsp/camilladsp.log
on_get_active_config: null
on_set_active_config: null
port: 5000
supported_capture_types: null
supported_playback_types: null
update_config_symlink: false
update_config_txt: false

Traceback (most recent call last):
File "C:\Users\morte\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\aiohttp\web_urldispatcher.py", line 557, in init
raise ValueError("Not a directory")
ValueError: Not a directory

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "C:\Users\morte\Camilladsp\main.py", line 36, in <module>
setup_static_routes(app)
File "C:\Users\morte\Camilladsp\backend\routes.py", line 68, in setup_static_routes
app.router.add_static("/config/", path=app["config_dir"])
File "C:\Users\morte\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\aiohttp\web_urldispatcher.py", line 1124, in add_static
resource = StaticResource(
^^^^^^^^^^^^^^^
File "C:\Users\morte\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\aiohttp\web_urldispatcher.py", line 559, in init
raise ValueError(f"No directory exists at '{directory}'") from error
ValueError: No directory exists at 'C:\Users\morte\Camilladsp\configs'


Any ideas why that is ?