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

To my surprise, pCP actually have a pkg-config.tcz packet, so I installed it - but as I said, it didn't find any alsa package.
But alsa was kind enough to tell me the right path, when I took a chance with the wrong...

If this alsa-plugin turns out well, I guess Jesper (lykkedk) might come up with a tcz-pacet for pCP. If not seashell..?
Jesper (and partly I) has already almost finished creating tcz packets with CamillaDSP, and my scripts for a piped setup.
And then seashell shows up and wipes the table... Oh, well... what can you do... Adapt and Redo... :rolleyes:
 
Hi here ;)

If this alsa-plugin turns out well, I guess Jesper (lykkedk) might come up with a tcz-pacet for pCP. If not seashell..?
Jesper (and partly I) has already almost finished creating tcz packets with CamillaDSP, and my scripts for a piped setup.
And then seashell shows up and wipes the table... Oh, well... what can you do... Adapt and Redo...
Report Post Reply With Quote

And with @seashell's comment ::
I won't be making packages for any distribution.

I will try to make an extension for the pCP... good evening gentlemen :p

Jesper.
 
... And nothing requires you to scrap what you've done and use the plugin...
Of course! It still works as intended.
It just became - let's say: kind of obsolete - or: less interesting to go on with...

But it has a bit different approach, so it might still be a good alternative to have around. And it's certainly not wasted work. I do it for fun, and have learned a lot... And as long as I get something better - I'm happy..! :)
 
Great work is done on this auto sample rate switching :)

@Seashell's alsa plugin seem's like the most native solution for this.

Well, i used a lot of time figuring out howto set this up.
I finally managed to have it run through.

Now i feel a little st.... asking this, but i have filters (.yml) for each samplerate
How do i make this plugin use them?

Proberly easy to do??? -I just can't figure it out :confused:

My filters are build up like this:
I have cut the head of the .yml out for clearness :)
Code:
filters:
  L_prefir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/DSP_Engine/filters/44100/L_avg_RPfir_44100.bin
      format: FLOAT32LE

  R_prefir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/DSP_Engine/filters/44100/R_avg_RPfir_44100.bin
      format: FLOAT32LE

  L_fir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/DSP_Engine/filters/44100/L_avg_NORMAL_44100.bin
      format: FLOAT32LE

  R_fir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/DSP_Engine/filters/44100/R_avg_NORMAL_44100.bin
      format: FLOAT32LE

  clipgain_L:
    type: Gain
    parameters:
      gain: -12.0
      inverted: false

  clipgain_R:
    type: Gain
    parameters:
      gain: -12.0
      inverted: false

pipeline:
- type: Filter
  channel: 0
  names:
    - L_prefir
- type: Filter
  channel: 1
  names:
    - R_prefir

- type: Filter
  channel: 0
  names:
    - L_fir
- type: Filter
  channel: 1
  names:
    - R_fir

- type: Filter
  channel: 0
  names:
    - clipgain_L
- type: Filter
  channel: 1
  names:
    - clipgain_R

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

#--- CamillaDSP with alsa-plugin ---
pcm.camilladsp {    # You can use any name, not just camilladsp
    type cdsp
      cpath "/usr/local/bin/camilladsp"
      config_in "/home/tc/camilladsp/template/config_template.yml"
      # If using symlinks for switching configs:
      #   config_in "/home/tc/camilladsp/config_template.yml"
      # config_cmd "/path/to/more_complex_yaml_creator
      config_out "/home/tc/camilladsp.yaml"
      # Additional arguments to CamillaDSP. Numeric arguments must be quoted in strings
      # -p "1234"
      cargs [
        -l warn
        -p "1234"
      ]
      channels 2
      rates = [
        44100
        48000
        88200
        96000
        176400
        192000
        352800
        384000
      ]
      # extra_samples 0
      # extra_samples_44100 8192
      # extra_samples_48000 8916
}

Jesper.
 
If you want to use completely separate yaml files you'll have to use config_cmd and make a script that will copy whichever yaml file you want to the config_out location. config_cmd will be called with the sample rate as one of the three arguments. (Order is in the docs.)

If you want to use config_in then make a single template yaml file. Assuming all your other sample rate files look the same as that one except the sample rate, just replace 44100 everywhere with $samplerate$ and the plugin will replace $samplerate$ with whatever sample rate is being used. Don't forget the samplerate in the device section as well. Look at the sample config_in.yaml.
 
Great work is done on this auto sample rate switching :)

@Seashell's alsa plugin seem's like the most native solution for this.

Well, i used a lot of time figuring out howto set this up.
I finally managed to have it run through.

Now i feel a little st.... asking this, but i have filters (.yml) for each samplerate
How do i make this plugin use them?

Proberly easy to do??? -I just can't figure it out :confused:

My filters are build up like this:
I have cut the head of the .yml out for clearness :)
Code:
filters:
  L_prefir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/DSP_Engine/filters/44100/L_avg_RPfir_44100.bin
      format: FLOAT32LE

  R_prefir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/DSP_Engine/filters/44100/R_avg_RPfir_44100.bin
      format: FLOAT32LE

  L_fir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/DSP_Engine/filters/44100/L_avg_NORMAL_44100.bin
      format: FLOAT32LE

  R_fir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/DSP_Engine/filters/44100/R_avg_NORMAL_44100.bin
      format: FLOAT32LE

  clipgain_L:
    type: Gain
    parameters:
      gain: -12.0
      inverted: false

  clipgain_R:
    type: Gain
    parameters:
      gain: -12.0
      inverted: false

pipeline:
- type: Filter
  channel: 0
  names:
    - L_prefir
- type: Filter
  channel: 1
  names:
    - R_prefir

- type: Filter
  channel: 0
  names:
    - L_fir
- type: Filter
  channel: 1
  names:
    - R_fir

- type: Filter
  channel: 0
  names:
    - clipgain_L
- type: Filter
  channel: 1
  names:
    - clipgain_R

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

#--- CamillaDSP with alsa-plugin ---
pcm.camilladsp {    # You can use any name, not just camilladsp
    type cdsp
      cpath "/usr/local/bin/camilladsp"
      config_in "/home/tc/camilladsp/template/config_template.yml"
      # If using symlinks for switching configs:
      #   config_in "/home/tc/camilladsp/config_template.yml"
      # config_cmd "/path/to/more_complex_yaml_creator
      config_out "/home/tc/camilladsp.yaml"
      # Additional arguments to CamillaDSP. Numeric arguments must be quoted in strings
      # -p "1234"
      cargs [
        -l warn
        -p "1234"
      ]
      channels 2
      rates = [
        44100
        48000
        88200
        96000
        176400
        192000
        352800
        384000
      ]
      # extra_samples 0
      # extra_samples_44100 8192
      # extra_samples_48000 8916
}

Jesper.

Here is the config_in and asound I am using. You need to rename you filter files to something like 44100L.dbl, 44100R.dbl etc
 

Attachments

  • temp.zip
    2.2 KB · Views: 54
Last edited:
I think your filter names are probably fine. Just change this

filename: /home/tc/DSP_Engine/filters/44100/R_avg_RPfir_44100.bin

to this

filename: /home/tc/DSP_Engine/filters/$samplerate$/R_avg_RPfir_$samplerate$.bin

Then for 44100 it will become (as it was originally)
filename: /home/tc/DSP_Engine/filters/44100/R_avg_RPfir_44100.bin

And for say 96000 it would be
filename: /home/tc/DSP_Engine/filters/96000/R_avg_RPfir_96000.bin

It's literally a simple global search and replace. Where $samplerate$ exists it gets replaced with the sample rate. Same with $format$, etc.

And thanks @wineds, glad it's working well for you.
 
Last edited:
Cool :)

So this is what i have to do ?

/home/tc [tree]
camilladsp
├── coeffs
├── configs
├── filters
│ ├── 176400
│ ├── 192000
│ ├── 44100
│ ├── 48000
│ ├── 88200
│ └── 96000
└── template
└── config_template.yml

And the config_template.yml
Code:
devices:
  samplerate: $samplerate$
  chunksize: 4096
  queuelimit: 1
  capture:
    type: File
    channels: $channels$
    filename: "/dev/stdin"
    format: $format$
  playback:
    type: Alsa
    channels: $channels$
    device: "sound_out"
    format: S32LE

filters:
  l_prefir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/camilladsp/filters/$samplerate$l_prefir.bin
      format: FLOAT32LE

  r_prefir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/camilladsp/filters/$samplerate$r_prefir.bin
      format: FLOAT32LE

  l_fir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/camilladsp/filters/$samplerate$l_fir.bin
      format: FLOAT32LE

  r_fir:
    type: Conv
    parameters:
      type: File
      filename: /home/tc/camilladsp/filters/$samplerate$r_fir.bin
      format: FLOAT32LE

  clipgain_l:
    type: Gain
    parameters:
      gain: -10.0
      inverted: false

  clipgain_r:
    type: Gain
    parameters:
      gain: -10.0
      inverted: false

pipeline:
#- type: Filter
#  channel: 0
#  names:
#    - l_prefir
#- type: Filter
#  channel: 1
#  names:
#    - r_prefir

#- type: Filter
#  channel: 0
#  names:
#    - l_fir
#- type: Filter
#  channel: 1
#  names:
#    - r_fir

- type: Filter
  channel: 0
  names:
    - clipgain_l
- type: Filter
  channel: 1
  names:
    - clipgain_r

And the asound.conf
Please comment the RED text
Code:
#    --- sound_out is the real hardware card ---
pcm.sound_out {
type hw
card 0
device 0
}

#   --- CamillaDSP with Seashell's alsa-plugin ---
# Howto here : [url=https://github.com/scripple/alsa_cdsp]GitHub - scripple/alsa_cdsp: ALSA plugin for Camilla DSP[/url] 
pcm.camilladsp {
    type cdsp
      cpath "/usr/local/bin/camilladsp"
      config_in "/home/tc/camilladsp/template/config_template.yml"
      config_out "/home/tc/camilladsp/camilladsp.yaml" [B][COLOR="Red"]<--- [U]EMPTY file[/U] or [U]no file[/U] here ?[/COLOR][/B]
      cargs [
        -l warn
        -p "1234"
      ]
      channels 2
      rates = [
        44100 
        48000 
        88200 
        96000
        176400
        192000
        352800
        384000
      ]
}

Is this correct then ?

Jesper.
 
Thanks to @seashell it's now easy to switch config at sample rate changes!
Take a look here: GitHub - scripple/alsa_cdsp: ALSA plugin for Camilla DSP
This is an Alsa plugin that acts as a playback device. It takes a template config file and updates the values for samplerate etc, and then launches an instance of CamillaDSP that it pipes the audio data to.
I tried this new approach to set the sample rate for CamillaDSP. CamillaDSP runs with different settings depending on the file or stream that is played, which is good news. But, I have a few problems.

First, I run this on Ubuntu Server 20.04, on an Intel i3-4360T @ 3.2 GHz. With the "normal" configuration the problems described below does not exist.

buffer underrun
Playing with squeezelite I see this message quite frequently in the syslog:
squeezelite[393027]: 2020-11-08 12:38:39.093 WARN camillalib::alsadevice - Prepare playback after buffer underrun

I can also hear the little dropout when it occurs.

The problem seems to be more frequent at higher bitrates, but even when streaming music at 44100, the underrun occurs approximately once every or second minute. It can happen in the middle of a song for no obvious reason. Changing settings back and forth for CamillaDSP and squeezelite might have improved it a bit.

broken pipe
squeezelite[473953]: 2020-11-08 14:01:31.606 WARN camillalib::alsadevice - Retrying playback, error: ALSA function 'snd_pcm_writei' failed with error 'EPIPE: Broken pipe'

This happens rarely and for no obvious reason.

MPD running at 100 % CPU
MPD runs at 100 % when playing. Nothing in the syslog or mpd.log.
 
Last edited:
I tried this new approach to set the sample rate for CamillaDSP. CamillaDSP runs with different settings depending on the file or stream that is played, which is good news. But, I have a few problems.

First, I run this on Ubuntu Server 20.04, on an Intel i3-4360T @ 3.2 GHz. With the "normal" configuration the problems described below does not exist.

buffer underrun
Playing with squeezelite I see this message quite frequently in the syslog:
squeezelite[393027]: 2020-11-08 12:38:39.093 WARN camillalib::alsadevice - Prepare playback after buffer underrun

I can also hear the little dropout when it occurs.

The problem seems to be more frequent at higher bitrates, but even when streaming music at 44100, the underrun occurs approximately once every or second minute. It can happen in the middle of a song for no obvious reason. Changing settings back and forth for CamillaDSP and squeezelite might have improved it a bit.

broken pipe
squeezelite[473953]: 2020-11-08 14:01:31.606 WARN camillalib::alsadevice - Retrying playback, error: ALSA function 'snd_pcm_writei' failed with error 'EPIPE: Broken pipe'

This happens rarely and for no obvious reason.

MPD running at 100 % CPU
MPD runs at 100 % when playing. Nothing in the syslog or mpd.log.
The broken pipe error is actually also a buffer underrun, one that happens in a tiny window after it checks that there hasn't been a buffer underrun (this check gives the "normal" buffer underrun message), and before it starts writing data to the device.
It looks as if CamillaDSP receives samples too slowly, just slightly slower than the playback device needs them. That would give exactly these periodic underruns.
Seashell, how is the rate of the plugin set? Is it trying to follow the rate at which CamillaDSP accepts the samples, or is it fixed by some timer?

I don't have any idea about the MPD problem.
 
@lykkedk config_out just needs to be readable/writeable by the user than runs the playback program. It doesn't matter what's in it as it will be overwritten.

I think you're missing a / after your $samplerate$ in your filters if they're in subdirectories.


@audiac sorry you're having trouble. Yes @Henrik there's a fake clock that in theory just throttles the write speed if things are going too fast, but I can see where it can cause the underrun problem. My implementation is based on bluez_alsa because the fake clock is so annoying. But looking more closely I'm not sure I'm seeing any advantage to it with blocking writes.

@audiac please comment out one line of code and see what happens.

This is line 312 (or close - I might have some test edits.)

Code:
    // synchronize playback time
    asrsync_sync(&asrs, frames);

Change that to
Code:
    // synchronize playback time
    //asrsync_sync(&asrs, frames);

And redo the make / make install. Then see what happens.
 
@lykkedk config_out just needs to be readable/writeable by the user than runs the playback program. It doesn't matter what's in it as it will be overwritten.

I think you're missing a / after your $samplerate$ in your filters if they're in subdirectories.

@Seashell... it's working :)

I actually mamaged to pack it all up in squeezed (piCore .tcz) filesystem :
Code:
lykke@Lykkedk:~/Desktop/superplayer_08112020$ tree seashellPackage
seashellPackage
├── home
│   └── tc
│       ├── asound.conf.tar.gz
│       └── camilladsp.tar.gz
└── usr
    └── local
        ├── lib
        │   └── alsa-lib
        │       └── libasound_module_pcm_cdsp.so
        └── tce.installed
            └── seashell_alsa

7 directories, 4 files
lykke@Lykkedk:~/Desktop/superplayer_08112020$ tree camilladsp
camilladsp
├── camilladsp.yaml
├── coeffs
├── configs
├── filters
│   ├── 176400
│   ├── 192000
│   ├── 44100
│   ├── 48000
│   ├── 88200
│   └── 96000
└── template
    └── config_template.yml

10 directories, 2 files
lykke@Lykkedk:~/Desktop/superplayer_08112020$ tree camilladsp-package
camilladsp-package
└── usr
    └── local
        ├── bin
        │   └── camilladsp
        └── tce.installed
            └── camilladsp

4 directories, 2 files

I just need some more test's to see if everything is 100% (or likely 90%) perfect, before i do more. -Need to test on a clean system from scratch also :D

But it's a really good solution seashell...

Jesper.
 
Sorry, no idea then. That line removes the only "clock" in the plugin. After that it's just throttled by how fast camilla reads from the pipe. There was a bug that caused the mpd 100% but it was fixed before I made the repo public and I assume you've not checked out old commits.
Thanks anyway! I've used the master branch of alsa_cdsp and CamillaDSP 0.4.0 beta 6. I'll try some more and maybe I'll come back with more questions.
 
You can also force the clock to be a problem. From the original code (with the asrsync_sync(&asrs, frames); call active) replace both instances of

asrsync_init(&asrs, io->rate);

with

asrsync_init(&asrs, 0.9*io->rate);

This should create constant underrun warnings from camilla. That way you'll know the changes are doing something.