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

I have tried to make the internal buffering robust against scheduling issues. But I only have experience from running it on modern PC hardware, and there I would say realtime stuff isn't needed. It runs just fine while playing movies from Netflix in Firefox for example, which is quite heavy since uses with software video decoding. In the same conditions I had lots of dropouts with BruteFIR. On a Pi I have no idea, would be great if someone wants to test a bit :)

I ran some time an optimization script. (also on Github)
It installs does a couple of ''optimizations'' on the OS.
I did this because I had some dropouts with Brutefir. Didn't solve them. Chancing buffersizes did.
Just getting the basics right did more I thought.
Camilladsp with rate control runs solid. Standard out of the box Raspbian :)
 
I ran some time an optimization script. (also on Github)
It installs does a couple of ''optimizations'' on the OS.
I did this because I had some dropouts with Brutefir. Didn't solve them. Chancing buffersizes did.
Just getting the basics right did more I thought.
Camilladsp with rate control runs solid. Standard out of the box Raspbian :)
Thanks for sharing!
 
There is a new version in branch "socket". The main thing is that it can now be controlled via a websocket. It's possible to reload the config, switch config file, and even upload a new config directly as yaml.
Check the readme for a few examples on how to do that from Python!

Very cool :)

I've tried to compile this branch, but something went wrong i guess:
pi@SuperBPI:~/socket_camilla/camilladsp/target/release $ /home/pi/socket_camilla/camilladsp/target/release/camilladsp
CamillaDSP 0.0.10
Henrik Enquist <henrik.enquist@gmail.com>
A flexible tool for processing audio

USAGE:
camilladsp [FLAGS] <configfile>

FLAGS:
-c, --check Check config file and exit
-h, --help Prints help information
-V, --version Prints version information
-v Increase message verbosity

ARGS:
<configfile> The configuration file to use
pi@SuperBPI:~/socket_camilla/camilladsp/target/release $ /home/pi/socket_camilla/camilladsp/target/release/camilladsp -p
error: Found argument '-p' which wasn't expected, or isn't valid in this context

USAGE:
camilladsp [FLAGS] <configfile>

For more information try --help

What i did was.
1. mkdir socket_camilla, cd socket_camilla
2. git clone GitHub - HEnquist/camilladsp: A flexible linux IIR and FIR engine for crossovers, room correction etc.
3. cd camilla
4. git checkout socket
5. git pull
I need to disable pulseaudio for the piCorePlayer i'am trying it on so i did this?!:
cargo build --release --no-default-features --features alsa-backend --features 32bit

So where did i go wrong.
Btw. camilladsp is working also on this build, but no -p :eek:

Btw(2): I have it running on the famous piCorePlayer now. I've created/modified excisting script on the dist. to an ugly init.d script which starts the camilladsp as a Daemon when piCore(The linux RAM OS) are booting...
It's working perfect, no glitch no noise 100% good, and very low CPU usage ~2-3% too.

Jesper.
 
Last edited:
The websocket part gets disabled by the --no-default-features flag. Just enable it again by adding "--features socketserver" to the command:
Code:
cargo build --release --no-default-features --features alsa-backend --features 32bit --features socketserver

Perfect... thanks :p

pi@SuperBPI:~/socket_camilla/camilladsp $ /home/pi/socket_camilla/camilladsp/target/release/camilladsp -h
CamillaDSP 0.0.10
Henrik Enquist <henrik.enquist@gmail.com>
A flexible tool for processing audio

USAGE:
camilladsp [FLAGS] [OPTIONS] <configfile>

FLAGS:
-c, --check Check config file and exit
-h, --help Prints help information
-V, --version Prints version information
-v Increase message verbosity

OPTIONS:
-p, --port <port> Port for websocket server

ARGS:
<configfile> The configuration file to use
 
I also don't need any gui for myself, but I certainly see the use case for one...

How do you gentlemen then check whether the dsp functions as intended? Loop-back testing?

I measure, adjust the dsp, and measure again. Also my experience is that if something is wrong, more often than not it will be very wrong making it obvious that there is a problem. Like swapped woofer/tweeter signal or stuff like that.
 
The High- and Lowpass filters have adjustable Q so they can be anything you like. For example to make a 4:th order Butterworth you chain one with Q=0.54 and one with Q=1.31. I'm making a table of the most common types that will be included in the readme for the next version.
if you want to provide a friendlier interface (so you can just specify BW7 or whatever) then you can probably copy this approach (which I copied from somewhere else) - beqdesigner/iir.py at master * 3ll3d00d/beqdesigner * GitHub - to save people referring to lookup tables

this is in python but seems like it reads pretty similarly to your code to me
 
Well, I did not refer to any passive x/o, just curious whether you measured "just Camilla output" (electric) in loop-back, or speaker's acoustic output.

But thanx for answering the question.
Oops sorry I apparently deleted half of my answer before posting. What I wanted to write was that since my speakers don't have any passive filters at all, the electrical signal going out isn't very flat and it's difficult to see anything useful there. After the speakers it's flat, so any change is much easier to see.


For checking if CamillaDSP itself gives the results is should, I have made automatic tests for all filter types. Basically I make a simple waveform, run it through a filter, and compare the output to a predefined correct answer.
 
if you want to provide a friendlier interface (so you can just specify BW7 or whatever) then you can probably copy this approach (which I copied from somewhere else) - beqdesigner/iir.py at master * 3ll3d00d/beqdesigner * GitHub - to save people referring to lookup tables

this is in python but seems like it reads pretty similarly to your code to me
Thanks, yes I will add something like that. It'll probably be a new filter type, BiquadMacro or something like that, that uses the normals biquads internally.
 
if you want to provide a friendlier interface (so you can just specify BW7 or whatever) then you can probably copy this approach (which I copied from somewhere else) - beqdesigner/iir.py at master * 3ll3d00d/beqdesigner * GitHub - to save people referring to lookup tables

this is in python but seems like it reads pretty similarly to your code to me

BTW, yuo have #ToDo flag there in :
Code:
class FirstOrder_HighPass(BiquadWithQ):
    '''
    A one pole high pass filter.
    '''
...

maybe you could use this kind of implementation there:

Code:
               b0 =   cos(w0) + 1
                 b1 = -(cos(w0) + 1)
                 a0 =   cos(w0) + sin(w0) + 1
                 a1 =   sin(w0) - cos(w0) - 1

where w0 = 2*pi*(fc/fs);

... though, not as fast as exp() based implementation could be ... .
 
@ HenrikEnquist :

If you are going to implement either IIR filtering, or biquads in FIR, I strongly suggest that you make some to all of the following parameters adjustable:
Fp, Qp, Fz, Qz
This is because, depending on what type of biquad filter the user wants to implement, one or more of these parameters must be able to be changed.

You are free to use the code from my ACDf IIR LADSPA plugin, which you can find here:
http://audio.claub.net/software/LADSPA/LAUB-LADSPA-PLUGINS-11JUN2016.tar
Drill down to the folder ACDf_v2.0. Look in the "activate" function, below where it says "BEGIN CODE TO CALCULATE FILTER TRANSFER FUNCTION COEFFICIENTS". Both analog and digital (z^1) coefficients can be found there.

ACDf can implement all first and second order filter types. You just string these together to make higher order filters. The different types (e.g. Butterworth or Linkwitz-Riley) are simply the same filters with different values of Q for each second order stage. In the file "ACDf Usage Notes" in the ACDf folder of the download I provide a table of the Q values for up to 8th order.

You can offer some "preset" filters from the table, and then have a mode where the user can modify or enter the values depending on the filter type. I strongly suggest this type of implementation. Having only a couple of preset types is just not very useful for crossover design.
 
Last edited:
@ HenrikEnquist :

If you are going to implement either IIR filtering, or biquads in FIR, I strongly suggest that you make some to all of the following parameters adjustable:
Fp, Qp, Fz, Qz
This is because, depending on what type of biquad filter the user wants to implement, one or more of these parameters must be able to be changed.

You are free to use the code from my ACDf IIR LADSPA plugin, which you can find here:
http://audio.claub.net/software/LADSPA/LAUB-LADSPA-PLUGINS-11JUN2016.tar
Drill down to the folder ACDf_v2.0. Look in the "activate" function, below where it says "BEGIN CODE TO CALCULATE FILTER TRANSFER FUNCTION COEFFICIENTS". Both analog and digital (z^1) coefficients can be found there.

ACDf can implement all first and second order filter types. You just string these together to make higher order filters. The different types (e.g. Butterworth or Linkwitz-Riley) are simply the same filters with different values of Q for each second order stage. In the file "ACDf Usage Notes" in the ACDf folder of the download I provide a table of the Q values for up to 8th order.

You can offer some "preset" filters from the table, and then have a mode where the user can modify or enter the values depending on the filter type. I strongly suggest this type of implementation. Having only a couple of preset types is just not very useful for crossover design.
Ah I didn't see that, could have saved me some time!

I implemented basically the same but in a slightly different way. I bypass the Fp, Qp, Fz, Qz step and calculate the biquad coeffs (a0, a1 etc) directly for each filter type, but the result should be the same. I also made almost the same table:
camilladsp/filterfunctions.md at develop * HEnquist/camilladsp * GitHub


BTW, Bessels are a pain to recalculate to Biquads. Is anyone actually interested in using them?
 
And how do you gentlemen approach the problem most drivers need non textbook filter transfer functions in order to produce a textbook acoustic (spl) output? Daisy chaining filter sections, shelves & notches, on a trial and error basis? Modify file, measure, adept, re-measure and so an?
 
And how do you gentlemen approach the problem most drivers need non textbook filter transfer functions in order to produce a textbook acoustic (spl) output? Daisy chaining filter sections, shelves & notches, on a trial and error basis? Modify file, measure, adept, re-measure and so an?
That's pretty much what I did yes. I did one driver at a time, and added and removed shelves, notches etc to make it flat a bit past the crossover frequency. When I was happy with woofer and tweeter, I added the crossover (at the time an LR-4) and adjusted the delay. The whole process didn't take very long. But then I redid it several times with different target curves until I was happy with the result. The first attempt at just making it flat at 1 meter became very bright at more reasonable listening distances. It took quite a number of attempts to get it right.

Since then I made a (quite ugly) script that generates FIR coefficients that do the same corrections, but with a steeper linear phase crossover.