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

I wonder how complicated it would be to keep the web server in rust. It seems to me the crate support is more advanced and reliable than installation of python libraries with pip. Coding web pages in rust is doubtlessly more complicated, but the reliability and assurance of correct function compared to python...
It would definitely be possible to do move the backend to Rust. But it would also be quite a lot of work to rewrite and then more work to maintain and update. The dynamical typing in Python makes many things very easy, while having to handle the types properly would add a lot of extra code. The new backend I'm working on doesn't need numpy and matplotlib. Those two are by far the most troublesome on the list of dependencies, so this should help a lot.


I use mostly impulse response filters that are derived from room and driver measurements and for me these start out with a 48 or 96 k measurements. I assumed these are band limited and the resulting filter could be converted without to much issue. I have a basic understanding of these things but unfortunately lack in depth knowledge, just enough to get in trouble...

Here is another idea for your consideration. Maybe a better alternative is to use a file naming scheme where the file name would end with the sample rate. You could still use a frequency parameter as suggested earlier leaving the door open to impulse response sample rate conversion in the future. Something like "multi" entered for this parameter could mean that the FIR file name would be the string provided for file name with the sample rate appended at the end. I think this would make it easier to work with FIR filters at different sampling rates.

Any how, there is always the option of converting the audio stream to match the FIR sampling frequency as this is well implemented in your program. I just thought it would be nice to go the other way around.
These are good ideas, thanks. I'll start looking at this when I'm done with the new backend and 0.4.0 is ready.



I just did some generation of filters i RePhase to see if combining FIR and LP gives any disadvantages.
Can't se much deviation between FIR filter with LP filter and without.
But some deviation on the LP filter near the noise floor when adding FIR filter.
See pictures.
This is the reason i think the two filtes can somehow be combined without extra delay, but it is maybe not worth it to save 128 samples. (1-3ms delay)
Yes it would be possible to use a minimum phase interpolation filter. For the same steepness is has the same amount of ringing as the sinc, but puts all of it after the impulse. I didn't add this (yet) to the resampler as I didn't see a large enough need for it to motivate the extra complexity.
 
Yes, like this:
RUSTFLAGS='-C target-cpu=native' cargo build --release --no-default-features --features alsa-backend --features websocket

I have two problems, which are probably unrelated.

1. CamillaDSP does not work with 4096 chunksize on my computer.

2. There are pops in the sound, but not always because of the underrun. To do a quick test I use Online Tone Generator - generate pure tones of any frequency
If I set 20Hz I have pops with the CamillaDSP at least every minute even there are no underruns. I do not have such pops with the PulseAudio Crossover Rack (the same computer, just changed configuration and restarted PA).
I don't see anything in your logs that would explain this! It's a strange combination of everything is fine and everything is broken.. I'll need to think some more about this. It's probably not this, but I noticed some problems sometimes if I keep the Pulseaudio volume control or some other Pulse control panel open.

Does it get better or worse if you play with the chunksize, and try maybe 1024, 4096, 16384, 65536?



I am also getting them on a 20Hz test tone with the new named pipe rate switching setup. If I revert to Jespers rate switching setup its gone.
Could you repeat this test and att a "tee" in your piping? That would save the stream also to a file so we can check what CamillaDSP got from squeezelite.
 

TNT

Member
Joined 2003
Paid Member
I am also getting them on a 20Hz test tone with the new named pipe rate switching setup. If I revert to Jespers rate switching setup its gone.

Are you saying that the pops are content related?

I still have pops&clicks with no readings in logs.

Sometimes they come a lot during 20-30 seconds to be gone for a long time. I have had the notion that they might be music related but.... well.

//
 
I tried installing Camilladsp on my old pi (b+ rev 1.2) and when i run "cargo build --release" it goes thru the entire process and gave me this error

error: failed to write / home/camilladsp/Cargo.lock
caused by: failed to open: / home/camilladsp/cargo.lock
caused by: Permission denied (os error 13)

is this because i have an old pi or something else. thanks
This looks like a permissions issue. The path looks odd, like there is a user called camilladsp, that has the camilladsp source directory as its home folder. Try cloning it to /home/yourusername/camilladsp instead of /home/camillads.


also tried installing on another SBC (RK3288 running Armbian Ubuntu bionic desktop)..got this error

cargo:warning=`"pkg-config" "--libs" "--cflags" "libpulse" "libpulse >= 13.0"` did not exit successfully: exit code: 1
--- stderr
Requested 'libpulse >= 13.0' but version of libpulse is 11.1

i checked and it has the latest version of pulse 11.1 on Ubuntu

Thanks for all the help
You should be able to build without Pulseaudio. Try:
Code:
cargo build --release --no-default-features --features alsa-backend --features socketserver
(replace "socketserver" by "websocket" if you build from the develop branch)
 
If I change chunksize to 4096 or more it does not work at all:
Oct 26 09:45:49 dtk camilladsp[4203]: message repeated 3 times: [ [2020-10-26T08:45:49Z WARN camillalib::alsadevice] Prepare playback after buffer underrun]
Oct 26 09:45:50 dtk camilladsp[4203]: [2020-10-26T08:45:50Z WARN camillalib::alsadevice] Prepare playback after buffer underrun
...
is logged continuously and receiver on the display shows fast switching between 2 and 7.1 channels. It is strange, because it does not say it does not like sw or hw params.

There was no difference between 1024 and 2048. I tried also 96kHz sample rate, no change.

Pops at 20Hz signal are easily audible. In the music it is not so obvious, but it is there also from time to time .
 
Are you saying that the pops are content related?

I still have pops&clicks with no readings in logs.

Sometimes they come a lot during 20-30 seconds to be gone for a long time. I have had the notion that they might be music related but.... well.

//
So it seems this happens with many combinations of backends for capture and playback. I'll need to set something up to reproduce it. Maybe piping from squeezelite is the easiest way.
 
If I change chunksize to 4096 or more it does not work at all:
Oct 26 09:45:49 dtk camilladsp[4203]: message repeated 3 times: [ [2020-10-26T08:45:49Z WARN camillalib::alsadevice] Prepare playback after buffer underrun]
Oct 26 09:45:50 dtk camilladsp[4203]: [2020-10-26T08:45:50Z WARN camillalib::alsadevice] Prepare playback after buffer underrun
...
is logged continuously and receiver on the display shows fast switching between 2 and 7.1 channels. It is strange, because it does not say it does not like sw or hw params.

There was no difference between 1024 and 2048. I tried also 96kHz sample rate, no change.

Pops at 20Hz signal are easily audible. In the music it is not so obvious, but it is there also from time to time .
Could you try playing something with aplay and the same settings?
aplay(1) - Linux man page
--period-size=# Distance between interrupts is # frames If no period size and no period time is given then a quarter of the buffer size is set.

--buffer-size=# Buffer duration is # frames If no buffer time and no buffer size is given then the maximal allowed buffer time but not more than 500ms is set.
Set buffer_size to 4096 and period_size to 1024.

Something like this:
Code:
cat /dev/zero | aplay -c8 -fS32_LE -r192000 -D"hw:1,10,0" --buffer-size=4096 --period-size=1024
 
With stopped Camilla:


cat /dev/zero | aplay -c8 -fS32_LE -r192000 -D"hw:1,10,0" --buffer-size=4096 --period-size=1024
Playing raw data 'stdin' : Signed 32 bit Little Endian, Rate 192000 Hz, Channels 8


It is working, receiver just switches to 7.1.

I also tried to generate file with 20Hz and play (mid and tweeter speaker disconnected)


sox -n -c 8 -r 192000 note192_8ch.wav synth 600 sin 20


aplay -c8 -fS32_LE -r192000 -D"hw:1,10,0" --buffer-size=4096 --period-size=1024 note192_8ch.wav
Playing WAVE 'note192_8ch.wav' : Signed 32 bit Little Endian, Rate 192000 Hz, Channels 8




No problem, no pops.
 
Last edited:
I don't see anything in your logs that would explain this! It's a strange combination of everything is fine and everything is broken.. I'll need to think some more about this. It's probably not this, but I noticed some problems sometimes if I keep the Pulseaudio volume control or some other Pulse control panel open.

Does it get better or worse if you play with the chunksize, and try maybe 1024, 4096, 16384, 65536?




Could you repeat this test and att a "tee" in your piping? That would save the stream also to a file so we can check what CamillaDSP got from squeezelite.

Ok I'll have a think about that. Did you see that there were lots of these kinds of events in the log? I thought they looked odd :

[2020-10-26T06:19:09Z TRACE tungstenite::protocol::frame::frame] Masked: true
[2020-10-26T06:19:09Z TRACE tungstenite::protocol::frame] received frame
<FRAME>
final: true
reserved: false false false
opcode: CLOSE
length: 8
payload length: 2
payload: 0xa46

[2020-10-26T06:19:09Z DEBUG tungstenite::protocol] Received close frame: Some(CloseFrame { code: Normal, reason: "" })
[2020-10-26T06:19:09Z DEBUG tungstenite::protocol] Replying to close with Frame { header: FrameHeader { is_final: true, rsv1: false, rsv2: false, rsv3: false, opcode: Control(Close), mask: None }, payload: [3, 232] }
[2020-10-26T06:19:09Z TRACE tungstenite::protocol] Received message
[2020-10-26T06:19:09Z TRACE camillalib::socketserver] received: Close(Some(CloseFrame { code: Normal, reason: "" }))
[2020-10-26T06:19:09Z DEBUG camillalib::socketserver] parsed command: Ok(None)
[2020-10-26T06:19:09Z DEBUG camillalib::socketserver] Sending no reply
[2020-10-26T06:19:09Z TRACE tungstenite::protocol] Frames still in queue: 1
[2020-10-26T06:19:09Z TRACE tungstenite::protocol] Sending frame: Frame { header: FrameHeader { is_final: true, rsv1: false, rsv2: false, rsv3: false, opcode: Control(Close), mask: None }, payload: [3, 232] }
[2020-10-26T06:19:09Z TRACE tungstenite::protocol::frame] writing frame
<FRAME>
final: true
reserved: false false false
opcode: CLOSE
length: 4
payload length: 2
payload: 0x3e8

[2020-10-26T06:19:09Z DEBUG camillalib::socketserver] Connection was closed
[2020-10-26T06:19:09Z DEBUG camilladsp] Reloading configuration...
[2020-10-26T06:19:09Z DEBUG camillalib::filters] Read file: /home/tc/camilladsp/filters/44100/filterL44.dbl, number of coeffs: 65536
[2020-10-26T06:19:09Z TRACE camillalib::alsadevice] Playback state Running
[2020-10-26T06:19:09Z TRACE camillalib::processing] AudioMessage::Audio received
[2020-10-26T06:19:09Z TRACE camillalib::filedevice] Captured 32768 bytes
[2020-10-26T06:19:09Z TRACE camillalib::countertimer] Value range: 0
[2020-10-26T06:19:09Z DEBUG camillalib::filters] Read file: /home/tc/camilladsp/filters/44100/filterR44.dbl, number of coeffs: 65536
[2020-10-26T06:19:09Z DEBUG camilladsp] Reload using config file
[2020-10-26T06:19:09Z DEBUG camilladsp] No changes in config.
[2020-10-26T06:19:09Z TRACE camillalib::alsadevice] Playback state Running
[2020-10-26T06:19:09Z TRACE camillalib::processing] AudioMessage::Audio received
[2020-10-26T06:19:09Z TRACE camillalib::filedevice] Captured 32768 bytes
[2020-10-26T06:19:09Z TRACE camillalib::countertimer] Value range: 0.047027587890625
[2020-10-26T06:19:09Z TRACE camillalib::alsadevice] Playback state Running
[2020-10-26T06:19:09Z TRACE camillalib::processing] AudioMessage::Audio received
[2020-10-26T06:19:09Z TRACE camillalib::filedevice] Captured 32768 bytes
 

TNT

Member
Joined 2003
Paid Member
I'm using:

Firefox (stream from Konserthuset) -> system setting to play sound to Soundflower -> Soundflower (2ch) -> RME Digiface -> Soekris DAM dac via Toslink.
or

Squeezplay -> system setting to play sound to Soundflower (2ch)-> Soundflower (2ch) -> RME Digiface -> Soekris DAM dac via Toslink.

both pops.

I wish I know a way to direct Sqeezplay to Soundflower (2ch)!

//
 
My log, just for comparison...

I noted in wineds log, that the "Measured sample rate" varies up to 1 kHz. Is that OK?
ex.
Code:
[2020-10-26T06:19:24Z TRACE camillalib::filedevice] Measured sample rate is 43109.80546140554 Hz"
Mine varies to, but about 40 Hz in this sample log.
 

Attachments

  • camilladsp.log.txt
    94.7 KB · Views: 41
Did you see that there were lots of these kinds of events in the log? I thought they looked odd :
Those are just the messages you get when the websocket connection is closed, perfectly normal!


I'm using:

Firefox (stream from Konserthuset) -> system setting to play sound to Soundflower -> Soundflower (2ch) -> RME Digiface -> Soekris DAM dac via Toslink.
or

Squeezplay -> system setting to play sound to Soundflower (2ch)-> Soundflower (2ch) -> RME Digiface -> Soekris DAM dac via Toslink.

both pops.

I wish I know a way to direct Sqeezplay to Soundflower (2ch)!

//
There is some Camilla in both paths right, between soundflower and the RME?


My log, just for comparison...

I noted in wineds log, that the "Measured sample rate" varies up to 1 kHz. Is that OK?
ex.
Code:
[2020-10-26T06:19:24Z TRACE camillalib::filedevice] Measured sample rate is 43109.80546140554 Hz"
Mine varies to, but about 40 Hz in this sample log.
The capture samplerate can jump around a bit, it's not a very precise measurement.



Some pops could maybe maybe be buffer overruns on the capture side, but that should only be possible with the Alsa backend..
 
With stopped Camilla:

aplay -c8 -fS32_LE -r192000 -D"hw:1,10,0" --buffer-size=4096 --period-size=1024 note192_8ch.wav
Playing WAVE 'note192_8ch.wav' : Signed 32 bit Little Endian, Rate 192000 Hz, Channels 8

No problem, no pops.
How to play directly to ALSA loopback with started Camilla?

aplay -c2 -fS32_LE -r96000 -D"hw:Loopback,1" --buffer-size=2048 --period-size=1024 note96_2ch.wav

Playing WAVE 'note96_2ch.wav' : Signed 32 bit Little Endian, Rate 96000 Hz, Stereo


makes no sound, Camilla does not see any signal (Signal range: -1000).