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

Just if someone should decide on using parallell ALSA mixers. (For wathever reason)
samplerate: 48000
x over freq: 3000
Phase change 1 sample, degrees: 22,5
Can be heard : probably

samplerate: 48000
x over freq: 300
Phase change 1 sample, degrees: 2,25
Can be heard: I doubt it


1 sample difference in length mm (length the sound travels in 1/48 ms): 7,0833 mm

Assuming 1 sample fluctuation between the ALSA mixers.
So if the cross over frequency is low compared to samplerate the phase fluctuation is very low and i doubt it can be heard.
 
Last edited:
Hello here guy's :)

I tried different + google but can't really find anything usefull about my "issue"
Case is i would like to have the possibility to use two player's at the same time like this :
(the player's don't wanna play at same time, this would be messy, but they must be enabled)

MPD ----> .fifo out (mpd have this option in .conf) ----> camilladsp /usr/audio_fifo.fifo ----> sound_out (which is card 1, device 0 in my usecase)
Squeezelite ----> stdout ----> camilladsp /dev/stdin ----> sound_out

I don't actually think camilladsp are capable of taking two input's at the same time? - or maybee running two instances of camilladsp, which i never tried.

A bit crazy i know :eek:
Wonder if this is doable ?

Like this one can choose between the very nice upnp interface on mpd and squeezelite's also very nice LMS interface :)

My /etc/asound.conf :
Code:
# "sound_out" is the "real" hardware card (usbdac, soundcard etc...)
pcm.sound_out {
type hw
card 1
device 0
}

ctl.sound_out {
type hw
card 1
}

Jesper.
 
I have a couple of questions about CamillaDSP. Sorry if these have been covered in this thread already.

1. ROUTING
From the online docs I get the idea that the available routing consists of input > splitting/copying/adding channels > processing the channels > output. Depicted graphically, that might look something like this:
xo_topo-typicals.png


I couldn't quite figure out how a "branching" filter tree could be created, e.g. one like this:
xo_topo-improved-s.png


Can the branching filter tree be created in CamillaDSP and if so, how?


2. DELAY:
I see there is delay functionality. Does this implement "fractional delay" and is able to produce any arbitrary amount of delay (up to some upper limit), or only delay in increments of one sample period (e.g., increments in time of 1/sample_rate)?

It's been a long time since I looked at the software, but after a read through today I am really impressed. Too many features to not give it a try! Great work Henrik, you have really been working hard on this.
 
Branching is no problem. You can add as many mixer and filter stages as you want in the pipeline. The only limitation here is that all channels have to pass through each mixer (but you can of course let some channels pass through unchanged).
To build the "IMPROVED crossover topology" you would add:
- a Mixer that splits INPUT to two new signals.

- a Filter stage, with the 50Hz HP+LP.

- a Mixer. This will split the >50Hz signal in two, and pass the SW through unchanged.
- a Filter stage, with the 200Hz HP+LP.
- a Mixer, splitting the >200Hz signal in two, while passing W and SW unchanged.
- A Filter stage with the 2k HP+LP


There is fractional delay yes. It's using an IIR filter for the subsample part.
 
Thanks for the reply, Henrik. I still have some questions regarding the mixers.

Reading through the documentation here:
CamillaDSP documentation on GitHub : Mixers
I got the impression that the mixers could only connect to inputs and outputs. How do you link the output of one mixer to the input of another mixer? I was not sure that was even possible. Do you provide the name of a mixer in the dest and sources+channel fields of the mixer mapping? Can you give a short but explicit example on that?
 
The channels are always referenced by index. I built the improved topology to show:
4way.png


This is the config:
Code:
---
devices:
  samplerate: 44100
  chunksize: 1024
  target_level: 512
  adjust_period: 10
  capture:
    type: Alsa
    channels: 1
    device: "hw:Loopback,0,1"
    format: S16LE
  playback:
    type: Alsa
    channels: 4
    device: "hw:Loopback,0,5"
    format: S32LE

filters:
  lp50:
    type: Biquad
    parameters:
      type: Lowpass 
      freq: 50
      q: 0.7
  hp50:
    type: Biquad
    parameters:
      type: Highpass 
      freq: 50
      q: 0.7
  lp200:
    type: Biquad
    parameters:
      type: Lowpass 
      freq: 200
      q: 0.7
  hp200:
    type: Biquad
    parameters:
      type: Highpass 
      freq: 200
      q: 0.7
  lp2k:
    type: Biquad
    parameters:
      type: Lowpass 
      freq: 2000
      q: 0.7
  hp2k:
    type: Biquad
    parameters:
      type: Highpass 
      freq: 2000
      q: 0.7

mixers:
  step1:
    channels:
      in: 1
      out: 2
    mapping:
      - dest: 0
        sources:
          - channel: 0
            gain: 0
            inverted: false
      - dest: 1
        sources:
          - channel: 0
            gain: 0
            inverted: false
  step2:
    channels:
      in: 2
      out: 3
    mapping:
      - dest: 0
        sources:
          - channel: 0
            gain: 0
            inverted: false
      - dest: 1
        sources:
          - channel: 1
            gain: 0
            inverted: false
      - dest: 2
        sources:
          - channel: 1
            gain: 0
            inverted: false

  step3:
    channels:
      in: 3
      out: 4
    mapping:
      - dest: 0
        sources:
          - channel: 0
            gain: 0
            inverted: false
      - dest: 1
        sources:
          - channel: 1
            gain: 0
            inverted: false
      - dest: 2
        sources:
          - channel: 2
            gain: 0
            inverted: false
      - dest: 3
        sources:
          - channel: 2
            gain: 0
            inverted: false

pipeline:
  - type: Mixer
    name: step1
  - type: Filter
    channel: 0
    names:
      - lp50
  - type: Filter
    channel: 1
    names:
      - hp50
  - type: Mixer
    name: step2
  - type: Filter
    channel: 1
    names:
      - lp200
  - type: Filter
    channel: 2
    names:
      - hp200
  - type: Mixer
    name: step3
  - type: Filter
    channel: 2
    names:
      - lp2k
  - type: Filter
    channel: 3
    names:
      - hp2k
 
lykkedk: that's what audio mixers are for. Pulseaudio, pipewire, dmix plugin, etc. Of course using only a single samplerate from all clients.

You can try configuring alsa dmix followed by the alsa camilladsp plugin and direct your MPD and squeezelite to the dmix alsa device.

Hi Phofman :)

I will look into it, meanwhile i still have a lot of fun with my script for the mpd/squeezelite player chooser...

Jesper.
 
Hi again here :)

I played a little with the Gui/backend-server.
There are something i don't quite get through.

I use the default config from : GitHub - HEnquist/camillagui-backend: Backend server for camillagui and nothing fancy.
According to the first configuration the folder's :
The settings for config_dir and coeff_dir point to two folders where the backend has permissions to write files. This is provided to enable uploading of coefficients and config files from the gui.
I suppose this is where config.yml are saved when saving them from the GUI at the webinterface ? - Correct ?

The active_config and the default_config lives in the /home/pi/camilladsp directory also and as i understand it :
active_config is the location, where a symbolic link to the currently active config will be created
Does this mean that it's actually is a symlink ? to the config which is loaded when camilladsp is started, or is it only created if active_config.yml is loaded at camilladsp at start ?

the default_config will be used. If this does not exist
Suppose the same applies to default_config.yml ?

I tried making some changes and applying some filters in the gui; the filters are working and i can save the config and open it also where it is correct.
But i never have something written in active_config or default_config.

I hope i can have this cleared out, i sometimes have a hard time understand such things through. :eek:

I do not use the alsa camilladsp plugin btw.

Jesper.
 
Help sorting scripple please

Help! Everything was going so well until I tried to change from the service on startup to scripple. Now I'm out of my depth again and can't get anything to work. When I say it won't work, I'm streaming from Roon to Loopback 0 via the RoonEndpoint installed on my RPi4, but nothing is reaching the UltraLite-mk5 soundcard connected via USB. Can you help?

So, I deleted the camilladsp.service file, typed
Code:
sudo apt install libasound2-dev
which installed correctly as far as I can see, but when I say
Code:
make
I get:

Code:
make: *** No targets specified and no makefile found.  Stop.

I guess this is important, but what am I missing?

Here's the asound.conf file that I've specified, but I guess this must contain errors too. For brevity I've removed the lines which are commented out:

Code:
pcm.camilla {
    type cdsp
    
      cpath "/usr/local/bin/camilladsp"
      config_out "/usr/local/etc/camilladsp/config2xhd.yml"
      config_in "/usr/local/etc/camilladsp/config2xhd.yml"

      channels 2
      rates = [
        176400
        192000
      ]

      cargs [
        -a "0.0.0.0"
        -p "5000"
        -g "-30"
        -o "/usr/local/etc/camilladsp/log.txt"
        -l debug
      ]      
}

I say it must contain errors because when I ask
Code:
aplay -l
I get the following - no mention of the "camilla" device I configured in the asound.conf

Code:
**** List of PLAYBACK Hardware Devices ****
card 0: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 0: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 1: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 2: UltraLitemk5 [UltraLite-mk5], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Here's the YAML file:

Code:
devices:
  samplerate: $samplerate$
  chunksize: 4096
  queuelimit: 1
  capture:
    type: Alsa
    channels: 2
    device: "hw:CARD=Loopback,DEV=0"
    format: S32LE
  playback:
    type: Alsa
    channels: 10
    device: "hw:CARD=UltraLitemk5,DEV=0"
    format: S24LE3
mixers:
  to10chan:
    channels:
      in: 2
      out: 10
    mapping:
      - dest: 0
        sources:
          - channel: 0
            gain: 0
            inverted: false
      - dest: 1
        sources:
          - channel: 1
            gain: 0
            inverted: false
filters:
  vol:
    type: Loudness
    parameters:
      ramp_time: 200.0
      reference_level: -30.0 
      high_boost: 15.0
      low_boost: 10.0
pipeline:
  - type: Mixer
    name: to10chan
  - type: Filter
    channel: 0
    names:
      - vol
  - type: Filter
    channel: 1
    names:
      - vol

I'm wondering about the fact that the "camilla" cdsp type I specified in the asound.conf doesn't appear anywhere else (like in my YAML file or as a device that I should be streaming to from Roon) ... but should it?

Since I was last on this forum (apart from enjoying the music - Max Richter's rewrite of Vivaldi's Four Seasons is a recent discovery that we're loving) I've been working on getting node-RED to link the CamillaDSP websocket to the mqtt broker which receives messages from my Harmony Elite remote, so I can now control the CamillaDSP volume/loudness without going down the FLIRC IR and python route. Delighted that that's working. Just need this scripple bit fixed, and then I can start on the real goal of the project - convolution in CamillaDSP.

Thanks for reading
 
Is this relevant?
Code:
ubuntu@ubuntu:~$ aplay -D camilla
ALSA lib dlmisc.c:339:(snd_dlobj_cache_get0) Cannot open shared library libasound_module_pcm_cdsp.so (/usr/lib/aarch64-linux-gnu/alsa-lib/libasound_module_pcm_cdsp.so: cannot open shared object file: No such file or directory)
aplay: main:852: audio open error: No such device or address