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

Maybe the stack printed with "RUST_BACKTRACE=1" would reveal more info.

IMO the code throwing UnsupportedOperation error when snd_pcm_state returns error is a bit misleading (IIUC alsa-rs/lib.rs at 0c9cf7ebe0e29525d412c5844074c6fa80958e98 * diwic/alsa-rs * GitHub + alsa-rs/pcm.rs at 6b04e6af7af98b3e3f028972754e00561833ca00 * diwic/alsa-rs * GitHub ), the original error message would have been more useful.

Google says snd_pcm_state likes to return "Broken pipe error"

Maybe dmesg would show some USB errors.
 
Google says snd_pcm_state likes to return "Broken pipe error"
Interesting, the ALSA docs don't mention negative error codes for snd_pcm_state(), but snd_pcm_status() is closely related and there it clearly says it can give negative error codes. So it's probably just missing in the docs for state. This means that the state() of alsa-rs really should return a Result<State> instead of just State, and this will avoid the panic.
 
Anyone using this with a Motu M4 in a multi-channel setup? I'd love to pick your brain / see your pipeline config!

Thanks,
Jim

There's a thread on ASR:

Pi4 + CamillaDSP + Audio Interface (Motu M4) = Phenomal DSP streamer | Audio Science Review (ASR) Forum

If you mean surround sound, though, I think I'd want at least a 6 channel unit for that.

I'm only using it for a 2.1 system so far. I might add another subwoofer later. Of course, camilladsp is very flexible for filtering, so there's lots more to play with there.
 
I have had some time to work on the project I mentioned on the previous page a bit this week, and I'm slowly making progress. I have the RaspberryPi I2S slave-mode overlay installed and it seems to be working, but there's definitely some weirdness with it.

My current setup is using the MiniDSP USBStreamer to output from my PC to a cheapo WM8804 test board that allows me to debug things without spinning a PCB. From here, I'm running I2S over to the appropriate RaspberryPi GPIO pins (18,19,20, and a ground). I'm also taking the I2S output from GPIO 21, and routing it back to the WM8804 and using it as the SPDIF transmitter input. The WM8804 SPDIF output goes to a little test DAC and then to a recording interface.

If I haven't overlooked anything in the WM8804 datasheet on pages 20-21, this should be a supported operation as long as there's no change of sample rates involved, since everything uses the same clocks anyways.

The first weirdness comes in with the following command:
Code:
sudo arecord -f S32_LE -r 48000 -c 2 -D "hw:0,1" -v --disable-resample | sudo aplay -f S32_LE -r 48000 -c 2 -D "hw:0,0" -v --disable-resample

This command works great! ... Even if the SPDIF input sample rate is 44.1kHz... which is very odd. It appears that the rate setting for aplay/arecord doesn't matter at all, they can even be different, and I can't seem to figure out why. Is it just ignored somehow?

(Note: The "hw:0,x" is correct, it has the same behavior with "hw:CARD=GenericStereoAu,DEV=x")

The second. and more serious weirdness comes with running CamillaDSP with a very simple filter, actually, the filter doesn't really matter but here it is:
Code:
---
devices:
  samplerate: 44100
#  chunksize: 1024
  chunksize: 32768
  target_level: 512
  capture:
    type: Alsa
    channels: 2
    device: "hw:0,1"
    format: S32LE
  playback:
    type: Alsa
    channels: 2
    device: "hw:0,0"
    format: S32LE

filters:
  lowpass:
    type: Biquad
    parameters:
      type: Lowpass
      freq: 1000
      q: 1.0

  gain_total:
    type: Gain
    parameters:
      gain: -12

pipeline:
  - type: Filter
    channel: 0
    names:
      - gain_total
      - lowpass
  - type: Filter
    channel: 1
    names:
      - gain_total
      - lowpass

This produces a horrible full 0dB level white noise in the output, no matter the filter configuration (chunksize didn't help), with the actual audio distorted and buried somewhere in the background.

I've attached a sound recording of the two different commands - a 1kHz sine wave, first recorded with the "arecord | aplay" command, and then with CamillaDSP. This isn't just the normal crackling and popping from unshielded I2S with jumper wires, it's something else.

If anyone has any ideas or has run into something like this before, please let me know if there's anything I've overlooked.
 

Attachments

  • arec_aplay_vs_cdsp.zip
    839.1 KB · Views: 41
raptorlightning: A simple drawing of your setup connection would help a lot.

As of the samplerates - RPI's I2S slaved to some incoming clock does not care about the samplerate being played/captured, the driver has no clock to configure for the requested samplerate. I2S peripheral is timed by the incoming clock.
 
Hi,

Just installed version 0.7.1 backend. Looks good and works well on safari but getting a blank screen with Firefox.
Just tried it but it works fine for me. Can you open the developer tools and see if there are any errors printed to the console?

The second. and more serious weirdness comes with running CamillaDSP with a very simple filter
...
This produces a horrible full 0dB level white noise in the output, no matter the filter configuration (chunksize didn't help), with the actual audio distorted and buried somewhere in the background.
Can you start by testing capture and playback separately? Start by using Alsa -> File, then check the file with Audacity. If ok, then try File -> Alsa.

Also, if you pipe the output of arecord to a file, does that look ok? The arecord | aplay command will just copy the bytes without looking at them. So even if things are wrong, it will still work as long as they are wrong the same way for playback and capture.
 
Last edited:
raptorlightning: A simple drawing of your setup connection would help a lot.

As of the samplerates - RPI's I2S slaved to some incoming clock does not care about the samplerate being played/captured, the driver has no clock to configure for the requested samplerate. I2S peripheral is timed by the incoming clock.

Here's a quick sketch of the setup, sorry if my text description was a bit confusing:

c7lWUNm.png


On pages 20 and 21 of the datasheet, you can see an internal block diagram of the 8804 and how setting TXSRC=1 changes clock and data routing. MCLK is an output in master mode, and is fed internally to the SPDIF TX for use.

The samplerate issue makes sense. I thought about it more and figured it's probably just ignoring the Alsa configuration since it is slaved to the BCLK. I assume arecord | aplay is just looping right through the Pi's AIF.

As of the noise - does the dai-tdm-slot-width value defined in your overlay correspond to your I2S signal format?

I left it stock, which has the following configuration:
Code:
// TDM slot configuration for stereo
  dai-tdm-slot-num = <2>;
  dai-tdm-slot-width = <32>;

I didn't know this would have any effect since it's labeled for TDM. I will test the WM8804 modes for RJ and LJ when I can today and report back.

Can you start by testing capture and playback separately? Start by using Alsa -> File, then check the file with Audacity. If ok, then try File -> Alsa.

Also, if you pipe the output of arecord to a file, does that look ok? The arecord | aplay command will just copy the bytes without looking at them. So even if things are wrong, it will still work as long as they are wrong the same way for playback and capture.

This is something I haven't looked at, and good thinking for debug. I will also test this in a bit and report back this evening (US timezones) at some point.
 
Question about heat on an RPi4. I'm using a 131072 tap FIR filter (stereo) for room correction and my Pi temperature is hovering around 69-70 C. Ambient temp is about 26C. Everything sounds fine, but I'm worried about cooking the board. The board is mounted in the official plastic case. I have a FLIRC case on order (I want to avoid using a fan unless it can be guaranteed to be inaudible at 3m distance). Is there anything else I can do to reduce heat, e.g. recompiling CamillaDSP with optimizations?
 
Question about heat on an RPi4. I'm using a 131072 tap FIR filter (stereo) for room correction and my Pi temperature is hovering around 69-70 C. Ambient temp is about 26C. Everything sounds fine, but I'm worried about cooking the board. The board is mounted in the official plastic case. I have a FLIRC case on order (I want to avoid using a fan unless it can be guaranteed to be inaudible at 3m distance). Is there anything else I can do to reduce heat, e.g. recompiling CamillaDSP with optimizations?

69-70C is perfectly fine for both the SoC and the PCB. Silicon doesn't really care until above 100C, even then a lot of things can be designed for 125C. The Tg of FR4 is 135C, so it won't really care below that. The Pi SoC will also have thermal limiting on the clock to avoid any issues. You can get one of the small stick-on heatsinks if you'd like to reduce it a bit.
 
Last edited:
69-70C is perfectly fine for both the SoC and the PCB. Silicon doesn't really care until above 100C, even then a lot of things can be designed for 125C. The Tg of FR4 is 135C, so it won't really care below that. The Pi SoC will also have thermal limiting on the clock to avoid any issues. You can get one of the small stick-on heatsinks if you'd like to reduce it a bit.

Thanks for the reassurance. I should have mentioned that I do have the stock heatsinks appiied.
 
I was able to run all of the tests this afternoon, and I'd like to report back as promised.

Can you start by testing capture and playback separately? Start by using Alsa -> File, then check the file with Audacity. If ok, then try File -> Alsa.

Also, if you pipe the output of arecord to a file, does that look ok? The arecord | aplay command will just copy the bytes without looking at them. So even if things are wrong, it will still work as long as they are wrong the same way for playback and capture.

All of the aplay/arecord tests saving to files passed successfully. I wasn't able to get this chain to break using I2S until I turned the volume up and that was an important part I totally missed yesterday - above 50% volume it clips on loud moments, so only occasionally. I thought about it this afternoon and looking at the I2S protocol in the 8804 datasheet, realized that there's a 1xBCLK delay in I2S transmission after WCLK; also, we work with falling edges with I2S. I remember going through the I2S protocol for my I2S to TDA1541 simultaneous-mode FPGA project now... Maybe the MSB is being corrupted if something in the chain ignores this delay or takes rising edges instead of falling... (the Pi AIF?)

As of the noise - does the dai-tdm-slot-width value defined in your overlay correspond to your I2S signal format?

With the DT overlay, switching the dai-tdm-slot-width to 24, causes a read error in aplay/arecord for S32_LE (as expected), and switching to S24_LE works for 16 bit I2S but none of the 24-bit modes (RJ/LJ/I2S) work correctly - this doesn't appear to solve the issue and causes 24-bit LJ to not work at all...

Regarding CamillaDSP, and going back to 32 in the dai-tdm-slot-width lines, 16-bit I2S works fine :confused: and 24-bit Left Justified works wonderfully as well. 24-bit I2S is horrible white noise (still), and 24-bit Right Justified is massive clipping. This is making me think that there's something wrong with the I2S stream along the way, perhaps in the Pi's I2S front-end or drivers. See pages 45 and 46 of the 8804 datasheet for explanation of my above thoughts: If the I2S stream, at any point, doesn't respect the 1xBCLK delay before data, after WCLK transition, this could lead to MSB clipping. Right justifying the data obviously leads to a ton of clipping because all of the bits after the WCLK transition are "random" and it's still trying to fill the 32-bits. Why CamillaDSP has white noise with I2S and not the clipping on loud passages like arecord|aplay (even with files) is beyond me... but there's clearly some protocol issue going on.

Something I should also apprise of is the behavior of mismatched sample rates. With the USBStreamer chain I have been using, if the sample rate is wrong, there's audible digital noise and artificing so you know it's mismatched. With this "left-justified" setup, it seems that the filters are just "wrong". For example, if I run a filter at 44.1kHz and play a 96kHz source, it ends up "bassy" or low-heavy. If I run a filter at 96kHz and play a 44.1kHz source it ends up "thin" or high-heavy. There's not a strong audible warning that sample rates are mismatched anymore. This seems to be a product of the I2S frontend in the Pi only having a single clock, and ALSA commands ignoring the sample rate. I guess this is acceptable since my code for sample-rate switching is 100% from all of the testing I've done with the USBStreamer version of the DSP system... it's just disconcerting. I guess I'd like it to be very apparent that the sample rate is incorrect, for even very minor filters. ;)

The 16-bit I2S functionality bugs me. Why does it work? I'd like to have proof that using 24-bit LJ is actually workable and bit-perfect for passthrough. I don't mind configuring it this way if it works. I guess a lot of my issues are from ignorance. I really appreciate all the help, I'm used to analog and RTL digital, and my ignorance of the BCM SoC in the Pi, my programming skills, and general SoC coding knowledge is holding me back to really seeing the interactions that would lead me to know what to do.
 
Last edited:
raptorlightning: dai-tdm-slot-width is terminology of the Alsa SoC framework (ASoC) for the device tree configuration.

Constants for the "format" parameter are soc-core.c - sound/soc/soc-core.c - Linux source code (v4.9) - Bootlin and soc-dai.h - include/sound/soc-dai.h - Linux source code (v4.9) - Bootlin

Your I2S interface must be configured to fit the I2S interface of WM8804. I have not tested other formats than "i2s" yet, but the "dai-tdm-slot-width" parameter works correctly for RPi4 - I tested I2S loopback from 8bits to 32bits. IMO the other supported formats work OK too bcm2835-i2s.c - sound/soc/bcm/bcm2835-i2s.c - Linux source code (v5.13) - Bootlin