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

@HenrikEnquist,
A question and another possible suggestion: Do you happen to know how the formulae for the Linkwitz transform coefficients were derived? I used to use the same (which I believe I got from some spreadsheet somewhere) in my own DSP software, but some time ago I noticed that the resulting transfer function doesn't quite match up with a highpass discretized using the bilinear transform. Using the highpass coefficients from Robert Bristow-Johnson's famous Audio EQ Cookbook, I derived the following for a bilinear transform discretized Linkwitz transform:
lt_formulae_1.png

lt_formulae_2.png

One can also trivially modify the gain terms to make the magnitude unity at DC rather than Nyquist, creating a lowpass transform:
lp_xfrm_k.png
 
  • Like
Reactions: TNT
I got the LT equations from the minidsp spreadsheet: https://www.minidsp.com/applications/advanced-tools/linkwitz-transform
I haven't seen any mention of how they were derived.

At low frequencies there is no difference, and at very high frequencies I see a minor difference in the DC gain. What is best, follow the spreadsheet that most people seem to be using, or the slightly more correct but different new equations?
 
I got the LT equations from the minidsp spreadsheet: https://www.minidsp.com/applications/advanced-tools/linkwitz-transform
I haven't seen any mention of how they were derived.

At low frequencies there is no difference, and at very high frequencies I see a minor difference in the DC gain. What is best, follow the spreadsheet that most people seem to be using, or the slightly more correct but different new equations?
Correct. Any day.... yours will be the reference in the future... 😉

DC levels are important to handle properly it seems.

//
 
At low frequencies there is no difference, and at very high frequencies I see a minor difference in the DC gain.
Yes, the difference is only at higher frequencies. Arguably this means that practically, there's no real difference since most only use the filter at rather low frequencies.

What is best, follow the spreadsheet that most people seem to be using, or the slightly more correct but different new equations?
A good question, but one I don't have an answer for. My formulation is a bit simpler, if that means anything 🙂.
 
Suggestion: The gain indicators (db figures) in the Pipeline graphical view. I suggest these are indicated at the end of the connection lines where it enters in a 90 deg angle to the box - its either in the sending side or the receiving side depending... this way it will obscure crossing lines in a busy pipeline to a lesser degree.

Drawback: the box that the attenuation is associated to is less clearly identified...

//
 
Yes, the difference is only at higher frequencies. Arguably this means that practically, there's no real difference since most only use the filter at rather low frequencies.
Here is a comparison between miniDsp, the new equations, and the ideal transfer function of an analog LT.
Parameters:
FS = 44100
F0 = 10000
Ft = 2000
Q0 = 3.0
Qt = 0.7
lt.png

The new equation hits the frequency of the dip better, but miniDsp gets the low frequency gain right. Can't really say which is more accurate 😀
 
Here is a comparison between miniDsp, the new equations, and the ideal transfer function of an analog LT.
Here's another way of looking at it—the resulting highpass response after applying the LT:

Starting from an analog highpass:
lt_analog.png
Starting from a digital highpass (bilinear transform):
lt_digital.png

The gain error in the first plot is of course related to the frequency warping caused by the bilinear transform. As stated before, my formulation gives an exact result when applied to the digital highpass (i.e. identical to a digital highpass with Fc=Fp and Q=Qp).

Edit: If desired, the DC gain could be adjusted to match the analog prototype:
lt_analog_adj.png
 
Last edited:
Of course, it would be simplicity to get it to work on a WINDOWS machine but I doubt I could ever get camilladsp installed on WINDOWS!

If only mdsimon had a tutorial on how to do that!

Why is a tutorial needed for a simple Windows install? These days it is just a matter of two downloads (camilladsp and camillagui bundle), unzipping and starting them.

There is a dedicated readme for Windows with more specifics -> https://github.com/HEnquist/camilladsp/blob/master/backend_wasapi.md.

Michael
 
  • Thank You
Reactions: rickmcinnis
Henrik, I'm doing some more testing with REW and CamillaDSP-Controller and have run into a "file not found problem" when there is a FIR filter in the config.

Here is the output from the controller with a config with simple biquad filters, you can see it changes sample rates and restarts CamillaDSP-


Code:
camilla@RPi5b94:~ $ /opt/venv/bin/python3 /home/camilla/camilladsp/camilladsp-controller/controller.py -d hw:UAC2Gadget -p 1234 -a /home/camilla/camilladsp/configs/Gin_96k_UL5_01_EQ_Bass_Mid_Hi_96000.yml
Found control 'Capture Rate' with index 4
Getting new config for rate: None, format: None, channels: None
Using new config from Adapt provider
CamillaDSP stopped because the capture format changed
Getting new config for rate: 44100, format: None, channels: None
Config has a resampler, change 'capture_samplerate' to 44100
Using new config from Adapt provider
Stopping CamillaDSP
Starting CamillaDSP with new config
Started
CamillaDSP stopped because the capture format changed
Getting new config for rate: 96000, format: None, channels: None
Config has a resampler, change 'capture_samplerate' to 96000
No need for a 1:1 sync resampler, removing
Using new config from Adapt provider
Stopping CamillaDSP
Starting CamillaDSP with new config
Started
CamillaDSP stopped because the capture format changed
Getting new config for rate: 44100, format: None, channels: None
Config has a resampler, change 'capture_samplerate' to 44100
Using new config from Adapt provider
Stopping CamillaDSP
Starting CamillaDSP with new config
Started

Now with a config that contains a FIR crossover filter

Code:
camilla@RPi5b94:~ $ /opt/venv/bin/python3 /home/camilla/camilladsp/camilladsp-controller/controller.py -d hw:UAC2Gadget -p 1234 -a /home/camilla/camilladsp/configs/Gin_96K_UL5_02_EQ_XO_96000.yml
Found control 'Capture Rate' with index 4
Getting new config for rate: None, format: None, channels: None
Using new config from Adapt provider
CamillaDSP stopped because the capture format changed
Getting new config for rate: 44100, format: None, channels: None
Config has a resampler, change 'capture_samplerate' to 44100
Using new config from Adapt provider
Stopping CamillaDSP
Starting CamillaDSP with new config
Unable to start, error: Command returned an error

It changes the sample rate and is unable to restart.

Here is the log from CamillaDSP - note the reason - it can't find /home/Camilla/camilladsp/coeffs/XO-Bass-250202-LR96-HP330Hz-4096T.dbl, but appears to be looking for coefficient file '../coeffs/XO-Bass-250202-LR96-HP330Hz-4096T.dbl'.

Code:
2025-03-07 15:46:09.236777 WARN  [src/alsadevice.rs:113] PB: Prepare playback after buffer underrun
2025-03-07 15:46:09.832270 WARN  [src/socketserver.rs:540] Lost connection: WebSocket protocol error: Connection reset without closing handshake
2025-03-07 15:46:11.071385 WARN  [src/socketserver.rs:540] Lost connection: WebSocket protocol error: Connection reset without closing handshake
2025-03-07 15:46:12.317323 WARN  [src/socketserver.rs:540] Lost connection: WebSocket protocol error: Connection reset without closing handshake
2025-03-07 15:46:12.817278 ERROR [src/bin.rs:354] Capture stopped due to external format change
2025-03-07 15:46:12.817268 INFO  [src/alsadevice.rs:983] Capture stopped
2025-03-07 15:46:12.972893 ERROR [src/socketserver.rs:1195] Error validating config: Invalid filter 'XO-Bass-250202-LR96-HP330Hz-4096T'. Reason: Could not open coefficient file '../coeffs/XO-Bass-250202-LR96-HP330Hz-4096T.dbl'. Reason: No such file or directory (os error 2)
2025-03-07 15:46:13.562968 WARN  [src/socketserver.rs:540] Lost connection: WebSocket protocol error: Connection reset without closing handshake


What am I doing wrong ?
Attached zip file has coeffs and configs. The coeffs files are created with rePhase as 96k .dbl files and work without the controller.
 

Attachments

it can't find /home/Camilla/camilladsp/coeffs/XO-Bass-250202-LR96-HP330Hz-4096T.dbl, but appears to be looking for coefficient file '../coeffs/XO-Bass-250202-LR96-HP330Hz-4096T.dbl'.
IIUC it's looking for a file configured in the yml config. That config uses relative paths, and probably the working directory (cwd) of CDSP process is different, hence resolving the relative path to a different one. IMO the most reliable hack-fix could be using absolute paths in your configs.
 
  • Like
Reactions: HenrikEnquist
IIUC it's looking for a file configured in the yml config. That config uses relative paths, and probably the working directory (cwd) of CDSP process is different, hence resolving the relative path to a different one. IMO the most reliable hack-fix could be using absolute paths in your configs.
Pavel, thank you.

Here is the config file where the XO fir filters are defined -

Code:
XO-Bass-250202-LR96-HP330Hz-4096T:
    description: null
    parameters:
      filename: ../coeffs/XO-Bass-250202-LR96-HP330Hz-4096T.dbl
      format: FLOAT64LE
      read_bytes_lines: 0
      skip_bytes_lines: 0
      type: Raw
    type: Conv
  XO-Hi-250202-LR96-HP3600Hz-4096T:
    description: null
    parameters:
      filename: ../coeffs/XO-Hi-250202-LR96-HP3600Hz-4096T.dbl
      format: FLOAT64LE
      read_bytes_lines: 0
      skip_bytes_lines: 0
      type: Raw
    type: Conv
  XO-Mid-250202-LR96-HP290Hz-LR96-LP3800Hz-4096T.:
    description: null
    parameters:
      filename: ../coeffs/XO-Mid-250202-LR96-HP290Hz-LR96-LP3800Hz-4096T.dbl
      format: FLOAT64LE
      read_bytes_lines: 0
      skip_bytes_lines: 0
      type: Raw
    type: Conv
mixers:
  2x18:

So if I just edit the config for each filename to the full path -
filename:/home/camilla/camilladsp/coeffs/XO-Bass-250202-LR96-HP330Hz-4096T.dbl

it should work.

I will try it tomorrow and report.
 
My thanks to mdsimon, AGAIN!

I get easily confused by the blending of installing and building in Mr. Enquist's exhaustive guides. If I was more competent with computer stuff I am sure I would have an easier time.

Out of curiosity - why does the WINDOWS version have less precision than the Linux versions? I feel sure it is a limitation imposed by the operating system but I wonder what does one lose when using camilladsp with WINDOWS? Does the precision make any difference and is there a point - number of filters, amount of convolution - where this difference comes into play?

I hope my question makes sense!

Thanks to all.
 
Is it possible to configure the below and if so, how? t would give some control properties (ease etc) that I like given the levers in the mixers wrt. on/off, phase etc... my problem is the "internal" 2in4out...

View attachment 1431884

//
A mixer must always accept all the channels in the pipeline, so the middle mixer must be 6-in, 8-out. Just let the input channels 1-4 map 1:1 to output channels 1-4.
 
  • Thank You
Reactions: TNT