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

Is it just me or does rate adjust with asynchronous resampling not really work on V2? I frequently play around with configurations that use a hifime UR23 as a TOSLINK to USB capture device and then a separate asynchronous playback device. In V2 I'll frequently see the buffer level go above my target level but reported rate adjust stays above 1. I also seem to get buffer underruns which were never a problem in V1.

As a sanity check I just re-installed V1 and it behaves as I expect. When buffer level < target level rate adjust switches to above 1 and when buffer level > target level rate adjusts switches to below 1.

Michael
 
Can you share an example of a config where this happens?

Sure, see attached. Also some screenshots of the GUI showing rate adjust < 1 at almost half target level of 2048 (which eventually led to a buffer under run) and at 1 when above target level of 2048.

Overall the behavior seems random. Most of the time it will stay quite stable but sometimes it seems to get stuck and the buffer will continue to increase or decrease. With V1 the behavior always seemed to make sense.

Screen Shot 2024-01-24 at 11.14.05 AM.png
Screen Shot 2024-01-24 at 11.15.30 AM.png


EDIT: After watching the buffer level a bunch, maybe V2 just makes smaller adjustments and will stick at the same rate adjust value for longer? This works well in cases where the buffer isn't changing much, but when there are bigger jumps in buffer level it seems slow to respond.

Michael
 

Attachments

  • configs-2.zip
    442 bytes · Views: 23
Last edited:
After watching the buffer level a bunch, maybe V2 just makes smaller adjustments and will stick at the same rate adjust value for longer? This works well in cases where the buffer isn't changing much, but when there are bigger jumps in buffer level it seems slow to respond.
That's exactly the difference. The reasoning is that the real-world capture/playback ratio does not deviate much (is basically constant) and the adjustment should strive to approach that value, instead of jumping around with some average. You can play with the adjustment constants in https://github.com/HEnquist/camilladsp/blob/eagain/src/alsadevice_utils.rs#L221 . The algorithm and the param values were taken from alsaloop, IIRC.

Maybe the algorithm constants could dynamically reflect the chunksize - larger chunksize could be slower will fewer fluctuations, smaller chunks more agile.

Keeping small chunksize/latency = small buffers goes against feedback rate adjustments, especially should the processing times vary (due to varying load on the DSP CPUs caused by other processes).

If you look at the chart at https://www.diyaudio.com/community/...rce-to-playback-hw-device.408077/post-7574371 - IMO the optimum target level should be slightly above chunksize, not at chunksize.
 
  • Like
Reactions: 1 user
Yes, I can try that. To clarify you are saying increase the speed_delta value from 1e-5 to 2e-5 or 4e-5?

Rich (BB code):
pub fn adjust_speed(
    avg_delay: f64,
    target_delay: usize,
    prev_diff: Option<f64>,
    mut capture_speed: f64,
) -> (f64, f64) {
    let latency = avg_delay * capture_speed;
    let diff = latency - target_delay as f64;
    match prev_diff {
        None => (1.0, diff),
        Some(prev_diff) => {
            let equality_range = target_delay as f64 / 100.0; // in frames
            let speed_delta = 1e-5;
            if diff > 0.0 {
                if diff > (prev_diff + equality_range) {
                    // playback latency grows, need to slow down capture more
                    capture_speed -= 3.0 * speed_delta;
                } else if is_within(diff, prev_diff, equality_range) {
                    // positive, not changed from last cycle, need to slow down capture a bit
                    capture_speed -= speed_delta;
                }
            } else if diff < 0.0 {
                if diff < (prev_diff - equality_range) {
                    // playback latency sinks, need to speed up capture more
                    capture_speed += 3.0 * speed_delta;
                } else if is_within(diff, prev_diff, equality_range) {
                    // negative, not changed from last cycle, need to speed up capture a bit
                    capture_speed += speed_delta
                }
            }
            debug!(
                "Avg. buffer delay: {:.1}, target delay: {:.1}, diff: {}, prev_div: {}, corrected capture rate: {:.4}%",
                avg_delay,
                target_delay,
                diff,
                prev_diff,
                100.0 * capture_speed
            );
            (capture_speed, diff)
        }
    }
}

It also seems certain devices are more problematic than others. MOTU Ultralite Mk5 as a playback device doesn't have large jumps in buffer level, miniDSP MCHstreamer as a playback device is more prone to large jumps.

Michael
 
Hi, had som issues regarding python and a small possibilty with corrupt SD card? Took a new one and made a fresh install with Debian 12 "bookworm" on a rpi 3b+. Using LMS and squeezelite.
Everything seems fine except for one thing. After reboot camilladsp state says "INACTIVE": Silence if I play music.
If I for instance press "apply to DSP" it starts working again.
Seems as if the instance dont load the active config or something. Have tried different configs.

Screenshot 2024-01-25 at 14.31.08.png
Screenshot 2024-01-25 at 14.35.19.png
Screenshot 2024-01-25 at 14.31.22.png
 
Yes exactly, that's the easiest way to tweak the reaction speed.
Exactly.

I will add some explanation to code in the adjust_speed method and send a PR.

@mdsimon2 : You can also try calculating/making the adjustments more frequently with lowering adjust_period. Since each adjustment can modify the rate only by a bit, it would make sense to do it more often for shorter chunks with small buffer margin.
 
I got this error from camilladsp when rebooting. Camilladsp stays inactive until I press "apply to dsp"
Code:
ERROR [src/bin.rs:286] Playback error: ALSA function 'snd_pcm_open' failed with error 'ENODEV: No such device'
BTW: Running i2s Soekris dam1021 dac direct via GPIO on the rpi. Nothing has changed, only going from debian 11 to debian 12.

Have tried a couple of overlays for the dac but the problem is still there.
 
Yes, it probably is :)

But its there. Direct into gui after reboot and its there. If I stop and start or restart camilladsp after boot it works just fine. So only after reboot.

Code:
pi@kjellern:~ $ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 0: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 1: sndrpihifiberry [snd_rpi_hifiberry_dac], device 0: HifiBerry DAC HiFi pcm5102a-hifi-0 [HifiBerry DAC HiFi pcm5102a-hifi-0]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

Fresh install of debian 12, latest and greatest camilladsp and squeezelite v.2xxx
Have the "old" install on another sd card and this problem is not there.
Well its not a big problem really , just that I have to go into camilladsp gui before I want to play music (after reboot). No worries for me but the woman.......

I can think of 1 thing that is different apart from the OS and that is that I have disabled and removed "modemManager" from the debian install. Cannot understand that it has something to to with this?
 
Last edited:
Yes, from the CDSP config
I am sure its just a minor fault "somewhere" :)

Code:
  capture:
    channels: 2
    device: hw:Loopback,1
    format: S32LE
    type: Alsa
  capture_samplerate: 96000
  chunksize: 2048
  enable_rate_adjust: true
  playback:
    channels: 2
    device: hw:CARD=sndrpihifiberry,DEV=0
    format: S32LE
    type: Alsa