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

To avoid misunderstanding, I will describe the problem:
Detect delay change: REW Measure A speaker (CDSP processing), Timin Use acoustic timing reference B speaker (without CDSP processing,Not connected to sound card). The original delay is 0.00xx ms.
Take ezbeq as an example,
1. Upload beq filter, delay increases by 15-50ms (maybe around 30ms, I forgot).
2. Clean beq filter, delay also changes.
3. Service camilladsp restart, delay returns to 0.00xx ms

ps. If I don't set 10ch in, 8ch out, mixers mapping 4-channel, I won't be able to use device: hw, I can only use plughw

There is very likely a buffer underrun message. Recovering from that will take s little bit of time, which delays the playback. Do you need to use such a small chunk size?
@HenrikEnquist Thanks. The chunk size is 256 and it runs without any problems. After I changed the chunk size to 1024, the delay did not change and became stable.
 
Sorry to intervene. No sound after upgrading from Fedora 40 Workstation to 41. Gnome sound panel shows no devices. I'm able to play a wav file with aplay and that's all. Pipewire doesn't start, therefore no CDSP. Worked perfectly fine before the upgrade. More details in https://discussion.fedoraproject.org/t/no-sound-after-f41-upgrade-pipewire-doesnt-start/139535

Code:
$ python --version
Python 3.13.0

CDSP status and log:
Code:
$ systemctl --user status camilladsp camillagui
● camilladsp.service - CamillaDSP Service
     Loaded: loaded (/etc/xdg/systemd/user/camilladsp.service; disabled; preset: disabled)
    Drop-In: /usr/lib/systemd/user/service.d
             └─10-timeout-abort.conf
     Active: active (running) since Thu 2024-12-12 12:20:30 EST; 9min ago
 Invocation: acf2887fa31d437993bd1e9b8bbcda9f
   Main PID: 6979 (camilladsp3)
      Tasks: 6 (limit: 37191)
     Memory: 12.4M (peak: 25.1M)
        CPU: 127ms
     CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/camilladsp.service
             └─6979 /usr/local/bin/camilladsp3 -p1234 -w -o /home/user/.config/.camilladsp/camilladsp.log -s /home/user/.config/.camilladsp/statefile3.yml

déc 12 12:20:30 user systemd[3356]: Started camilladsp.service - CamillaDSP Service.

× camillagui.service - CamillaDSP Backend and GUI
     Loaded: loaded (/etc/xdg/systemd/user/camillagui.service; disabled; preset: disabled)
    Drop-In: /usr/lib/systemd/user/service.d
             └─10-timeout-abort.conf
     Active: failed (Result: exit-code) since Thu 2024-12-12 12:20:31 EST; 9min ago
   Duration: 722ms
 Invocation: 6439535992884d18b2e8110a5430eab7
    Process: 6981 ExecStart=/usr/bin/python3 /opt/camillaguiv3/main.py (code=exited, status=1/FAILURE)
   Main PID: 6981 (code=exited, status=1/FAILURE)
   Mem peak: 26.7M
        CPU: 480ms

déc 12 12:20:30  systemd[3356]: Started camillagui.service - CamillaDSP Backend and GUI.
déc 12 12:20:31  python3[6981]: detected unhandled Python exception in '/opt/camillaguiv3/main.py'
déc 12 12:20:31  python3[6981]: Traceback (most recent call last):
déc 12 12:20:31  python3[6981]:   File "/opt/camillaguiv3/main.py", line 6, in <module>
déc 12 12:20:31  python3[6981]:     import camilladsp
déc 12 12:20:31  python3[6981]: ModuleNotFoundError: No module named 'camilladsp'
déc 12 12:20:31  systemd[3356]: camillagui.service: Main process exited, code=exited, status=1/FAILURE
déc 12 12:20:31  systemd[3356]: camillagui.service: Failed with result 'exit-code'.

$ ps aux|grep camilla
6979  0.0  0.0 566160 13220 ?        Ssl  12:20   0:00 /usr/local/bin/camilladsp3 -p1234 -w -o /home/user/.config/.camilladsp/camilladsp.log -s /home/user/.config/.camilladsp/statefile3.yml

$ cat /home/user/.config/.camilladsp/camilladsp.log
2024-12-12 12:20:30.674288 INFO  [src/bin.rs:781] CamillaDSP version 3.0.0
2024-12-12 12:20:30.674320 INFO  [src/bin.rs:782] Running on linux, x86_64
2024-12-12 12:20:30.734735 ERROR [src/bin.rs:293] Playback error: ALSA function 'snd_pcm_open' failed with error 'Host is down (112)'
2024-12-12 12:20:30.753900 INFO  [src/loudness.rs:37] Create loudness filter
2024-12-12 12:20:30.763829 INFO  [src/loudness.rs:37] Create loudness filter
2024-12-12 12:20:30.789181 INFO  [src/loudness.rs:37] Create loudness filter
2024-12-12 12:20:30.789765 INFO  [src/alsadevice.rs:793] Capture device supports rate adjust
2024-12-12 12:20:30.790766 INFO  [src/processing.rs:119] Playback thread has already stopped.

More info:

Code:
Dec 12 12:20:19 systemd[3356]: Started pipewire.service - PipeWire Multimedia Service.
Dec 12 12:20:19 systemd[3356]: Started wireplumber.service - Multimedia Service Session Manager.
Dec 12 12:20:19 pipewire[4254]: spa.alsa: Could not determine card index, maybe set api.alsa.card
Dec 12 12:20:19 pipewire[4254]: pw.resource: can't create node: Argument invalide
Dec 12 12:20:19 pipewire[4254]: pw.conf: can't create object from factory adapter: Argument invalide
Dec 12 12:20:19 pipewire[4254]: default: failed to create context: Argument invalide
Dec 12 12:20:19 systemd[3356]: pipewire.service: Main process exited, code=exited, status=234/n/a
Dec 12 12:20:19 systemd[3356]: pipewire.service: Failed with result 'exit-code'.
Dec 12 12:20:19 wireplumber[4255]: wireplumber: stopped by signal: Compl<C3><A9>t<C3><A9>
Dec 12 12:20:19 wireplumber[4255]: wireplumber: disconnected from pipewire
Dec 12 12:20:19 systemd[3356]: Stopping wireplumber.service - Multimedia Service Session Manager...
Dec 12 12:20:19 systemd[3356]: Stopped wireplumber.service - Multimedia Service Session Manager.
Dec 12 12:20:19 systemd[3356]: pipewire.service: Scheduled restart job, restart counter is at 2.

I do have api.alsa.path set, but 1st time I heard of api.alsa.card. The card number changes at every boot anyways. Sometimes 1; sometimes 2.
Code:
$ cat .config/pipewire/pipewire.conf.d/*
context.objects = [
    {   factory = adapter
        args = {
            factory.name            = api.alsa.pcm.sink
            node.name               = "alsa-sink"
            node.description        = "Alsa Loopback"
            media.class             = "Audio/Sink"
            api.alsa.path           = "hw:Loopback,0,0"
            audio.format           = "S32LE"
            audio.rate             = 48000
            audio.channels         = 6
            #audio.position         = "FL,FR"
        }
    }
]
context.properties = {
    default.clock.rate = 48000
    default.clock.allowed-rates = [ 44100, 48000, 88200, 96000, 192000]
}

Code:
$ systemctl status alsa-state
● alsa-state.service - Manage Sound Card State (restore and store)
     Loaded: loaded (/usr/lib/systemd/system/alsa-state.service; static)
    Drop-In: /usr/lib/systemd/system/service.d
             └─10-timeout-abort.conf, 50-keep-warm.conf
     Active: active (running) since Thu 2024-12-12 12:19:35 EST; 28min ago
 Invocation: ff3869b11ca84af18391eed524f15520
   Main PID: 1340 (alsactl)
      Tasks: 1 (limit: 37191)
     Memory: 704K (peak: 1M)
        CPU: 21ms
     CGroup: /system.slice/alsa-state.service
             └─1340 /usr/sbin/alsactl -s -n 19 -c -E ALSA_CONFIG_PATH=/etc/alsa/alsactl.conf --initfile=/lib/alsa/init/00main rdaemon

déc 12 12:19:35  systemd[1]: Started alsa-state.service - Manage Sound Card State (restore and store).
déc 12 12:19:35  alsactl[1340]: alsactl 1.2.13 daemon started
déc 12 12:19:35  alsactl[1340]: alsa-lib main.c:1554:(snd_use_case_mgr_open) error: failed to import hw:0 use case configuration -2
déc 12 12:19:35  alsactl[1340]: alsa-lib main.c:1554:(snd_use_case_mgr_open) error: failed to import hw:0 use case configuration -2
déc 12 12:19:35  alsactl[1340]: Found hardware: "Loopback" "Loopback Mixer" "" "" ""
déc 12 12:19:35  alsactl[1340]: Hardware is initialized using a generic method
déc 12 12:19:35  alsactl[1340]: alsa-lib main.c:1554:(snd_use_case_mgr_open) error: failed to import hw:1 use case configuration -2

$ LANG=C sudo pactl info
Connection failure: Connection refused
pa_context_connect() failed: Connection refused

I don't even know where to begin to diagnose that.
 
Hi Henryk,

Sorry to bother you with this, and not sure I am doing the right search before asking. But I think it is a good idea to support multiple I/O devices for some pipeline-like processing with external(to CamillaDSP) device/module in the middle.
My particular need for this is because I am using DriacLive Processor in the before CamillaDSP. I just found that Dirac is charging more for users like me who need just the BM, not their 'fancy' bass control. If CamillaDSP could get the upstream audio input, process BM, output the result to DL standalone processor(kind of like calling a subroutine), get the input from DL processor, then apply another round of processing, and eventually outputting to the DAC device(s). Is this kind of stuff possible, or any discussion or plan for this in the future? Thank you!

Regards,
Jay
 
Update to https://www.diyaudio.com/community/...overs-room-correction-etc.349818/post-7869625

Update, fixed by replacing pipewire config from

Code:
context.objects = [
    {   factory = adapter
        args = {
            factory.name            = api.alsa.pcm.sink
            node.name               = "alsa-sink"
            node.description        = "Alsa Loopback"
            media.class             = "Audio/Sink"
            api.alsa.path           = "hw:Loopback,0,0"
            audio.format           = "S32LE"
            audio.rate             = 48000
            audio.channels         = 6
            #audio.position         = "FL,FR"
        }
    }
]

to
Code:
context.objects = [
    {   factory = adapter
        args = {
            factory.name            = api.alsa.pcm.sink
            node.name               = "alsa-sink"
            node.description        = "Alsa Loopback"
            media.class             = "Audio/Sink"
            api.alsa.card            = "0"
        api.alsa.card.longname    = "Loopback 1"
        api.alsa.card.name        = "Loopback"
        api.alsa.path            = "hw:0"
            audio.format           = "S32LE"
            audio.rate             = 48000
            audio.channels         = 6
            #audio.position         = "FL,FR"
        }
    }
]

And naturally, reinstalling camillagui which depends on python. No idea why that pipewire change was required.
 
If CamillaDSP could get the upstream audio input, process BM, output the result to DL standalone processor(kind of like calling a subroutine), get the input from DL processor, then apply another round of processing, and eventually outputting to the DAC device(s). Is this kind of stuff possible, or any discussion or plan for this in the future?
Can you run two instances of camilla? One before the DL, one after. Or can you measure what DL does and just implement something equivalent in camilladsp? Then you wouldn't need the DL processor and things should get simpler.
I don't plan to add support for any external processing inside camilladsp, sorry.
 
  • Like
Reactions: phofman
In the changelog for version 3.0 I read about the new feature ‘Linux: Subscribe to capture device control events for volume, sample rate and format changes’.
How can users profit from this new feature?

[I apologise if this topic has already been covered elsewhere].
 
It is not clear to me how a user can be informed of a sample rate change. Would you please elaborate a bit?
For the alsa loopback, you only get notified that the loopback playback side was closed. That makes CamillaDSP close the capture side. After that the loopback can be reopened at another rate, but you need watch the loopback state and start CamillaDSP again after the loopback becomes active again.
For usb gadget, camilladsp will stop, and you can read the new rate by querying the stop reason.

Both ways are implemented in the quite new camilladsp-controller: https://github.com/HEnquist/camilladsp-controller
 
  • Thank You
Reactions: mevang
New version of the mixer ui:

Screenshot 2024-12-13 at 21.08.23.png
This is starting to get ready. It's only missing muting controls for the output channels, and some small tweaks here and there. Other than that it's working well.
I used an arrow (↕) to indicate inverted channels. It's a bit small but I haven't come up with anything better so far.
 
So, as far as I can see,
Clicking a + enables the cell, and clicking a cell opens the popup with the controls.
The number in the cell indicates the db as does the colour - colourbar coming
A grey cell with a forward slash indicates muted ?
Inverted indicator, agree it is small, I thought it was a 1. What does a horizontal slash look like?
 
What's the color coding really? Hot (+ gain) cold (-gain), green natural?
That is the idea yes. Unfortunately I don't think it works out very well in practice. I was hoping that the colors would make it easy to see what a mixer does, but the result just becomes some confusing confetti.


One suggestion - reserve colours for status and use only numbers for gain
I think this will be the way to go. I'm thinking:
Black - no connection
Green - normal connection
Blue - inverted (not red since that color is used to highlight errors)
Grey - muted
Normal and inverted muted connections are completely equivalent, they can just as well share the same grey color.
 
H there. Some notes on use of rephase and sox.

I use rephase for FIR linear phase filters, 32768 taps, Blackman-Harris windowing. Results in 0.334 s audio delay which is fine for me. I create the filter file at 48Khz. I then have a Python script that takes the L and R files and resamples them to all the other sample rates, highest quality, dither. This is configured into Camilladsp. My problem is that I have a ot of audio at 192khz and a few at 352.8khz. When those play, the gain changes higher and clipping starts. Upon examination, the gain is changing relative to 44.1 on all the higher res files, maybe in a linear fashion. Examples would be about 5-7db for 192khz and 10-13db for 352.8khz. In previous communication to henrikenquist it was discovered that rephase creates trailing convolution file data. Sox is then extending that trailing data for higher resolutions. The symptoms are higher than normal cpu load and gain causing clipping. I am able to get around the probem by using sox to change the gain on the offending file sample rates: -5db for 192khz and -10 for 352.8. For a cushion, I would also change 96khz and 88.2khz by -2db. I can modify the filter creation script to do this. There is a function in sox to trim the audio file. I tried it but did not see an improvement. Its possible I may not be using it correctly.
The reason I use Sox to resample is that if I use rephase I would have to create filters for all the various sample rates which increases chance of errors.

But... has anyone run into this and have any other insights? As an aside, I do notice an audio improvement at 352.8khz especially jazz drum and brush work. I purchased Bill Evans Top of the Gate which was created directly from the master tape recording at the club.

I Use Moode with Camilladsp with RME ADI-2 Dac.
All the best.