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

I got pip3 installed.
And: pip3 install yaml-utilities

Now a yaml module is imported. But... not good enough..?
Error at the first it's called:

Code:
 tc@SqueezePi2:~$ sudo /home/tc/camilladsp/camilladsp -p1234 -v -w 2> /home/tc/DSP_Engine/camilladsp.log &
 tc@SqueezePi2:~$ sudo squeezelite -n SqueezePi2 -o camillapipe -a 160:4::1 -b 10000:20000 -r 44100-192000:2500 -s 192.168.1.5
Traceback (most recent call last):
  File "/home/tc/camilladsp/camillapipe.py", line 46, in <module>
    main()
  File "/home/tc/camilladsp/camillapipe.py", line 23, in main
    config = yaml.load(f, Loader=yaml.SafeLoader) 
  File "/usr/local/lib/python3.6/site-packages/yaml/__init__.py", line 112, in load
    loader = Loader(stream)
  File "/usr/local/lib/python3.6/site-packages/yaml/loader.py", line 34, in __init__
    Reader.__init__(self, stream)
  File "/usr/local/lib/python3.6/site-packages/yaml/reader.py", line 85, in __init__
    self.determine_encoding()
  File "/usr/local/lib/python3.6/site-packages/yaml/reader.py", line 124, in determine_encoding
    self.update_raw()
  File "/usr/local/lib/python3.6/site-packages/yaml/reader.py", line 178, in update_raw
    data = self.stream.read(size)
  File "/usr/local/lib/python3.6/encodings/ascii.py", line 26, in decode
    return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 14: ordinal not in range(128)
 
IMO shortly describing your use case may do, either as a continuation of that thread or a new one with link to the previous "outcome".
Thanks! I'll write something to the mailing list.


Henrik to capture this behavior you can still use the pcm_hook even if avoiding loopback. Wrap the alsa file in the alsa hook and use either sighup or the websocket to tell camilla to update the parameters.
I didn't hink about combining the pipe stuff with hooks. That could be a winner, will try it when I have a little time.



I got pip3 installed.
And: pip3 install yaml-utilities

Now a yaml module is imported. But... not good enough..?
Error at the first it's called:

Code:
 tc@SqueezePi2:~$ sudo /home/tc/camilladsp/camilladsp -p1234 -v -w 2> /home/tc/DSP_Engine/camilladsp.log &
 tc@SqueezePi2:~$ sudo squeezelite -n SqueezePi2 -o camillapipe -a 160:4::1 -b 10000:20000 -r 44100-192000:2500 -s 192.168.1.5
Traceback (most recent call last):
  File "/home/tc/camilladsp/camillapipe.py", line 46, in <module>
    main()
  File "/home/tc/camilladsp/camillapipe.py", line 23, in main
    config = yaml.load(f, Loader=yaml.SafeLoader) 
  File "/usr/local/lib/python3.6/site-packages/yaml/__init__.py", line 112, in load
    loader = Loader(stream)
  File "/usr/local/lib/python3.6/site-packages/yaml/loader.py", line 34, in __init__
    Reader.__init__(self, stream)
  File "/usr/local/lib/python3.6/site-packages/yaml/reader.py", line 85, in __init__
    self.determine_encoding()
  File "/usr/local/lib/python3.6/site-packages/yaml/reader.py", line 124, in determine_encoding
    self.update_raw()
  File "/usr/local/lib/python3.6/site-packages/yaml/reader.py", line 178, in update_raw
    data = self.stream.read(size)
  File "/usr/local/lib/python3.6/encodings/ascii.py", line 26, in decode
    return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 14: ordinal not in range(128)
You don't need the first camilladsp command! The camillapipe.py script starts camilladsp for you.
But the error you get is something else, about your yaml file. Could you post it?
 
Your'e right - as usual...

I messed up the config path, pointing to my old config.
Fixing that, I found that I also has to edit camillapipe.py, line 42:
Code:
subprocess.run(["/path/to/camilladsp"....
And then: - Well I don't really know.

It won't play if I try.
No output to the console.
When I break, I get:
Code:
tc@SqueezePi2:~$ sudo squeezelite -n SqueezePi2 -o camillapipe -a 160:4::1 -b 10000:20000 -r 44100-192000:2500 -s 192.
168.1.5
Rate: 44100, format: S32_LE, channels: 2
[2020-10-12T20:37:44Z INFO  camillalib::alsadevice] Starting playback from Prepared state
^CTraceback (most recent call last):
  File "/home/tc/camilladsp/camillapipe.py", line 46, in <module>
    main()
  File "/home/tc/camilladsp/camillapipe.py", line 42, in main
    subprocess.run(["/home/tc/camilladsp/camilladsp", "-p1234", "/tmp/camilladsp.yml"], stdin=sys.stdin.buffer) 
  File "/usr/local/lib/python3.6/subprocess.py", line 405, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
  File "/usr/local/lib/python3.6/subprocess.py", line 835, in communicate
    self.wait()
  File "/usr/local/lib/python3.6/subprocess.py", line 1457, in wait
    (pid, sts) = self._try_wait(0)
  File "/usr/local/lib/python3.6/subprocess.py", line 1404, in _try_wait
    (pid, sts) = os.waitpid(self.pid, wait_flags)
KeyboardInterrupt
 
and this is the requested .yml, picked up from /tmp:

Code:
tc@SqueezePi2:~$ cat /tmp/camilladsp.yml 
devices:
  adjust_period: 5
  capture:
    channels: 2
    format: S32LE
    type: Stdin
  chunksize: 4096
  enable_rate_adjust: true
  playback:
    channels: 2
    device: sound_out
    format: S32LE
    type: Alsa
  queuelimit: 0
  samplerate: 44100
  target_level: 2048
filters:
  clipgain:
    parameters:
      gain: -12.0
      inverted: false
    type: Gain
pipeline:
- channel: 0
  names:
  - clipgain
  type: Filter
- channel: 1
  names:
  - clipgain
  type: Filter
 
Fixing that, I found that I also has to edit camillapipe.py, line 42:
Code:
subprocess.run(["/path/to/camilladsp"....
And then: - Well I don't really know.

It won't play if I try.
No output to the console.
Let's get you some output in the console. Edit line 42 to this (Add the -vv flag):
Code:
subprocess.run(["/path/to/camilladsp", "-p1234", "-vv", "/tmp/camilladsp.yml"], stdin=sys.stdin.buffer)
 
@ TNT:

Well... clipgain also serves as level adjustment to match my room EQ filters. I experiment with pretty high gain i some bass peaks.

@ Henrik:
I was wrong - again.

It can play - almost. And it took a long time, several minutes before first sound-blip. It plays short blips of maybe 0.1 second, and then pauses 5-20 seconds. Total CPU load is < 5%
Interesting...
 
"clipgain" is generous... theoretically -3,1 dB should suffice I think...
//
There is no single value for the clipgain that will always work. With a FIR filter, the maximum possible value is the sum of the absolute value of the filter coefficients. For a long filter this could become large. You need a very specific signal for that to happen though, so it will most likely never reach this value.



Anyway, around -3 dB is a good start, and then increase the attenuation a little if you see clipping sometimes.
 
@ TNT:

Well... clipgain also serves as level adjustment to match my room EQ filters. I experiment with pretty high gain i some bass peaks.

@ Henrik:
I was wrong - again.

It can play - almost. And it took a long time, several minutes before first sound-blip. It plays short blips of maybe 0.1 second, and then pauses 5-20 seconds. Total CPU load is < 5%
Interesting...
That seems pretty odd. Maybe try changing queuelimit to 1 in the template.
You can also remove the enable_rate_adjust, adjust_period and target_level parameters from the template, rate adjust isn't used here anyway.
 
I don't think the pcm_hook and file are compatible at least for this use case. file doesn't create anything under the proc file system, and alsa doesn't pass the hw_params to the hw_params hook call. (Why??)

Anyway, I just updated the hook to make everyone's life easier. It does the parsing in the hook itself and passes "format rate channels" to the open command.

With commands 'echo open' and 'echo close':
Code:
aplay -D lbparams -r 48000 -f S32_LE -c 2 < /dev/random
close
Playing raw data 'stdin' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo
open S32_LE 48000 2
^CAborted by signal Interrupt...
close
 
Last edited:
@Henrik...

So i have as you know a working camillagui installed on my pCP/SuperPlayer_v2.0

The webinterface shows what it should without the plotting function as expected. -This if because i don't have mathplotlib, numpy etc. installed.

Well, i had this on my mind if it was possible somehow to make the SuperPlayer send the "plotting" information via lan, whatever to my laptop.
Then on my laptop i can ran the heavystuff so to see the plotting.

I'am not sure it's possible at all, but could be very cool in such situations where the stuff is running on a lowspec. hardware platform aka' raspberry pi's (especially pCP/Tinycore which resides in RAM)...

Just a crazy thought :eek: :)

Jesper.
 
...
Well, i had this on my mind if it was possible somehow to make the SuperPlayer send the "plotting" information via lan, whatever to my laptop.
Then on my laptop i can ran the heavystuff so to see the plotting.
...
No that's not a crazy idea.



Let the browser do the graphing work with some java-script...
That is of course the proper way to do it. The only reason I use numpy+matplotlib to generate images server-side is because it allows me to reuse the existing python code for evaluating the various filters. I want to get away from this at some point, but to get there I have to rewrite a lot of python code in javascript. This will take quite some time (especially since I'm not very good with js).
 
It's the other way round Resolution in Hz = Sampling Frequency / Taps (Co-efficients), I think you know that but just to be clear for anyone else :)

Taps / Sampling Frequency gives you filter length in seconds.
:eek:
Thank you Fluid.
Lower sampling = steeper filters and narrower dips and peaks.
Just on a sidenote to advocate against my suggestion. Steeper filters and narrower dips and peaks of the filters can be bad for sound quality. So have a eye on the group delay!
 
Last edited:

TNT

Member
Joined 2003
Paid Member
I also have bursts of plipps and plopps... their duration is typically during say 2-15 seconds and these bursts re-occur anything between 2-3 minutes to 15 minutes.

My setup...


Camilla in a Mac Mini (1 TB SSD, one logical core out of 8 show 20% load) feeding a RME Digiface USB... over USB :)

Did Save from GUI:

devices:
adjust_period: 10
capture:
channels: 2
device: Soundflower (2ch)
format: FLOAT32LE
type: CoreAudio
capture_samplerate: 0
chunksize: 32768
enable_rate_adjust: true
enable_resampling: false
playback:
channels: 2
device: Digiface USB (24007543)
format: FLOAT32LE
type: CoreAudio
queuelimit: 100
resampler_type: BalancedAsync
samplerate: 44100
silence_threshold: 0
silence_timeout: 0
target_level: 16384
filters:
-6dB:
parameters:
gain: -6
inverted: false
type: Gain
lowpass_fir:
parameters:
filename: /Users/audio1/Documents/Ca+Di/Camilla/FIRs/eggPhase.txt
format: TEXT
read_bytes_lines: 0
skip_bytes_lines: 0
type: File
type: Conv
mixers: {}
pipeline:
- channel: 0
names:
- lowpass_fir
- -6dB
type: Filter
- channel: 1
names:
- lowpass_fir
- -6dB
type: Filter



//
 
So Henrik, group delay plot in addition to frequency response and phase response can be very useful for complex filters.
Ok, I'll add that to my list.


I also have bursts of plipps and plopps... their duration is typically during say 2-15 seconds and these bursts re-occur anything between 2-3 minutes to 15 minutes.
The problem is most likely here:
Code:
[COLOR=Olive]enable_resampling: false[/COLOR]
Try enabling resampling, and the problems should hopefully go away.
There is no way to adjust the rate of the SoundFlower device, so we have to use asynchronous resampling to match capture and playback rates.