I'm glad you told me this. That could've been an expensive failure. The search continues for how to tie multiple dacs together then... any experience using 4th gen 18i20 or ferrofish pulse with CDSP?I would not recommend using a fifo if you want to keep latency down!
Latency issue introduced with CDSP 3.0, alsa.
I used to set a 250 ms delay to the video with KODI in 3b2 to keep the audio and video in sync. Youtube videos in chromium based browsers were not perfectly in sync, but it was tolerable; movies and tv series watched in chromium based browsers were in sync.
Now with v 3.0, I need to set the video delay in Kodi to 800 ms. Youtube videos are all out of sync, badly. Same with movies and tv series. Sometimes, they might start to play in sync, but latency builds up fast and videos are unwatchable. It's perfectly repeatable with all linux kernel versions I tested. Killing CDSP 3.0 and starting 3b2 restores sync.
Strangely, I have a CDSP config where there is, or should be no processing and it's affected as well, to a lesser degree. It should be transparent, shouldn't it? There it is
I used to set a 250 ms delay to the video with KODI in 3b2 to keep the audio and video in sync. Youtube videos in chromium based browsers were not perfectly in sync, but it was tolerable; movies and tv series watched in chromium based browsers were in sync.
Now with v 3.0, I need to set the video delay in Kodi to 800 ms. Youtube videos are all out of sync, badly. Same with movies and tv series. Sometimes, they might start to play in sync, but latency builds up fast and videos are unwatchable. It's perfectly repeatable with all linux kernel versions I tested. Killing CDSP 3.0 and starting 3b2 restores sync.
Strangely, I have a CDSP config where there is, or should be no processing and it's affected as well, to a lesser degree. It should be transparent, shouldn't it? There it is
Code:
description: FL, FR, RL, RR, FC, LFE
devices:
adjust_period: 30
capture:
channels: 6
device: hw:Loopback,1,0
format: S32LE
type: Alsa
capture_samplerate: null
chunksize: 2048
enable_rate_adjust: true
playback:
channels: 6
device: pipewire
format: S32LE
type: Alsa
queuelimit: 16
rate_measure_interval: null
samplerate: 48000
silence_threshold: -80
silence_timeout: 3
stop_on_rate_change: null
target_level: 6143
volume_ramp_time: null
filters: null
mixers:
stereo:
channels:
in: 6
out: 6
mapping:
- dest: 0
mute: null
sources:
- channel: 0
gain: 0
inverted: false
mute: null
scale: dB
- dest: 1
mute: null
sources:
- channel: 1
gain: 0
inverted: false
mute: null
scale: dB
- dest: 4
mute: null
sources:
- channel: 4
gain: 0
inverted: false
mute: null
scale: dB
- dest: 5
mute: null
sources:
- channel: 5
gain: 0
inverted: false
mute: null
scale: dB
- dest: 2
mute: null
sources:
- channel: 2
gain: 0
inverted: false
mute: null
scale: dB
- dest: 3
mute: null
sources:
- channel: 3
gain: 0
inverted: false
mute: null
scale: dB
pipeline:
- bypassed: false
description: null
name: stereo
type: Mixer
processors: null
title: 6 channels flat - no filters
Section 4 of the paper by Ralph Glasgal, 360° Localization via 4.x RACE Processing by Ralph Glasgal explains the recursive nature of the process well I find. The paper can be found fairly easily on the web. To achieve this in dsp you can "by repetition", as you mention, add delayed, inverted and attenuated copies of the original signal to the appropriate channel.I've seven the word "recursive" a few times here now... we cant send data "backwards" in a pipe, can we - so its about repetition instead?
Please post the logs from the first minute or so after starting cdsp, with debug log level (-v).Latency issue introduced with CDSP 3.0, alsa.
It should be done with recursion, but can be approximately with repetition. That can be done with the existing building blocks today, and next version adds a new processor that does the recursion bit.I've seven the word "recursive" a few times here now... we cant send data "backwards" in a pipe, can we - so its about repetition instead?
//
@HenrikEnquist : IIUC the only applicable difference between CDSP 3.0 and the previous beta 2 is https://github.com/HEnquist/camilladsp/commit/edbb4ce1b41701322ebe0f534cb2558111d180c5 . Please I do not understand https://github.com/HEnquist/camilla...e43bb729daea8df2988266a047a0a4f680caR242-R245 vs. https://github.com/HEnquist/camilla...e43bb729daea8df2988266a047a0a4f680caR187-R190 The current_delay method for PlaybackBufferManager is defined (sort of) according to the alsa delay vs. avail definition https://stackoverflow.com/a/41278817/15717902 , but why the delay for capture is inverse to that (i.e. equal to avail)? There definitely was a lot of thinking behind that (IMO rather criticial) commit, please would it be possible to put in some explaining comments? Thanks for considering.
The capture delay method isn't used anywhere, I just implemented it because it's required by the trait. For playback, the delay is basically, if I write a single frame now, how long will it take before it is heard. So for capture I did something reasonably equivalent: if I read a single frame now, how long ago was that frame captured? But since it's not used, it could just as well be a panic!().
The reason for replacing snd_pcm_delay() was that it causes glitches. Not very often, but still. I haven't investigated exactly why, but calling it repeatedly inside the playback loops wasn't a good idea.
The reason for replacing snd_pcm_delay() was that it causes glitches. Not very often, but still. I haven't investigated exactly why, but calling it repeatedly inside the playback loops wasn't a good idea.
Motu Ultralite Mk5 is a popular choice for this. There’s some great implementation details on this page from user mdsimon https://github.com/mdsimon2/RPi-CamillaDSPI'm glad you told me this. That could've been an expensive failure. The search continues for how to tie multiple dacs together then... any experience using 4th gen 18i20 or ferrofish pulse with CDSP?
The capture delay method isn't used anywhere, I just implemented it because it's required by the trait. For playback, the delay is basically, if I write a single frame now, how long will it take before it is heard. So for capture I did something reasonably equivalent: if I read a single frame now, how long ago was that frame captured?
I understand it's not used, still IMO the current implemention is a bit hard to understand. Would the "how long ago was that frame captured" be represented by amount of samples already collected in the buffer, as written by the soundcard (i.e. the delay), instead of the amount of remaining free space available (avail)?
Sounds like a good solution to not-implemented 🙂But since it's not used, it could just as well be a panic!().
IIUC snd_pcm_delay can call snd_pcm_dma_buffer_sync https://elixir.bootlin.com/linux/v6.12.6/source/sound/core/pcm_native.c#L3023-L3036 , whereas snd_pcm_avail is just simple arithmetics , e.g. https://elixir.bootlin.com/linux/v6.12.6/source/include/sound/pcm.h#L816-L832 However, as a result, snd_pcm_avail may provide less up-to-date information than snd_pcm_delay. Maybe that is why @QuickDraw McGraw hits the inconsistent latency?The reason for replacing snd_pcm_delay() was that it causes glitches. Not very often, but still. I haven't investigated exactly why, but calling it repeatedly inside the playback loops wasn't a good idea.
BTW this is a very interesting (and very long) discussion about snd_pcm_delay() from the time when Lennart was writing Pulseaudio (i.e. the first deep-level use of alsa) https://mailman.alsa-project.org/pipermail/alsa-devel/2008-June/008381.html . It concludes with no results but shows the difference between delay/avail and the rather complex reasoning behind.
Please post the logs from the first minute or so after starting cdsp, with debug log level (-v).
Attachments
@QuickDraw McGraw : There does not seem to be any alsadevice debug in that log, only websockets server logs abour service requests from the GUI. Did playback start during the time captured by the logs?
Hi @phofman, No, should I redo?There does not seem to be any alsadevice debug in that log, only websockets server logs abour service requests from the GUI. Did playback start during the time captured by the logs?
Well then there are no logs related to the alsa playback 🙂 The log needs to capture the start of the actual playback which defines the initial latency. Best to start CDSP from command line, not as a service controlled by its GUI. It will start playback right away, not waiting for the play websockets command from the GUI
Also the debug log will not be flooded with socketserver messages which are irrelevant for this diagnostics.
I spent over an hour trying to figure out why my old configs were failing to load.
Please could you update the section of the Readme covering the pipeline to make the change to the channels parameter a bit clearer.
As an example, CDSP 2 was perfectly happy with a pipeline that specified
Simply updating this to
will fail, with the error produced (via --check) pointing unhelpfully to the first line of the pipeline section, rather than the line actually generating the error.
Instead you need to enter
or alternatively
The Readme does show an example in which the square brackets are used to affect mutiple channels (i.e channels: [0,1]), But the square brackets are not optional, and even a single channel needs to be enclosed in them.
I assume this is a side effect of the parser you're using.
Please could you update the section of the Readme covering the pipeline to make the change to the channels parameter a bit clearer.
As an example, CDSP 2 was perfectly happy with a pipeline that specified
Code:
channel: 0
Code:
channels: 0
Instead you need to enter
Code:
channels: [0]
Code:
channels:
- 0
I assume this is a side effect of the parser you're using.
Understood, makes sense. Started withAlso the debug log will not be flooded with socketserver messages which are irrelevant for this diagnostics.
/usr/local/bin/camilladsp3.300 -v -o /home/shizuma/.config/.camilladsp/camilladsp.log /home/shizuma/.config/.camilladsp/v3/90deg-D1.yml
Attachments
I too, experimented this. After digging, it's explained in changelog.mdI spent over an hour trying to figure out why my old configs were failing to load.
Code:
## v3.0.0
Changes:
- Filter pipeline steps take a list of channels to filter instead of a single one.
Yeah, it's pretty buried.
Ideally, it would be nice to compile a list of all the changes that need to be made to v2 configs to get them compatible with v3. This would make things a lot easier for those upgrading.
So far I have:
File capture and playback
The old method of using
needs to be changed depending on the filetype, either
or
or, for Unix systems piping through stdin and stdout, just
with no filename required
Channels in the pipeline
These now all need to be specified as json lists, even when dealing with a single channel, i.e.
with the last 'null' example indicating that all channels in the pipeline at that point will be affected.
Ideally, it would be nice to compile a list of all the changes that need to be made to v2 configs to get them compatible with v3. This would make things a lot easier for those upgrading.
So far I have:
File capture and playback
The old method of using
Code:
type: File
filename: /some/file.here
Code:
type: RawFile
filename: /some/file.raw
Code:
type: WavFile
filename: /some/file.wav
Code:
type: Stdin
...
type: Stdout
Channels in the pipeline
These now all need to be specified as json lists, even when dealing with a single channel, i.e.
Code:
channels: [0]
...
channels: [0,1]
...
channels: [0,2,4]
...
channels: null
@QuickDraw McGraw : Thanks.
Since your adjust_period is 30 seconds, one minute of capture contains only 2 rate-adjust action. Any reason why this long adjustment time? If you need low latency, small chunksize and frequent rate adjustments (like a few secs) are better.
Nevertheless - you have pipewire in the chain. Do you know what causes the large latency, CDSP or PW? I would guess CDSP does not cause more than some 200ms of latency (2048 frames of capture chunksize + some processing time + 6143 frames of the target level for 48kHz samplerate)
The debug-level log does not show any issue, trace level (-vv) would tell more. I would suggest to lower the adjust_period to e.g. 5 seconds and log at trace level so that every write/delay/avail operation is listed. The moment of the very first write defines the overall latency of CDSP, because then the playback stream is clocked by the output device (pipewire -> output soundcard). The trace log will show how precisely the timing works in your case. But it will definitely not be a difference of hundreds of ms as you are complaining, absolutely not. How did you measure the overall latency?
Please when making the zip, zip directly the file, so that it's not 4 directories deep the zip - lots of clicking to unzip 🙂
Since your adjust_period is 30 seconds, one minute of capture contains only 2 rate-adjust action. Any reason why this long adjustment time? If you need low latency, small chunksize and frequent rate adjustments (like a few secs) are better.
Nevertheless - you have pipewire in the chain. Do you know what causes the large latency, CDSP or PW? I would guess CDSP does not cause more than some 200ms of latency (2048 frames of capture chunksize + some processing time + 6143 frames of the target level for 48kHz samplerate)
The debug-level log does not show any issue, trace level (-vv) would tell more. I would suggest to lower the adjust_period to e.g. 5 seconds and log at trace level so that every write/delay/avail operation is listed. The moment of the very first write defines the overall latency of CDSP, because then the playback stream is clocked by the output device (pipewire -> output soundcard). The trace log will show how precisely the timing works in your case. But it will definitely not be a difference of hundreds of ms as you are complaining, absolutely not. How did you measure the overall latency?
Please when making the zip, zip directly the file, so that it's not 4 directories deep the zip - lots of clicking to unzip 🙂
Looks like you've spotted the problem immediately. I blindly copied the setting from a sample config file or several. It worked util v 3.0.Since your adjust_period is 30 seconds, one minute of capture contains only 2 rate-adjust action. Any reason why this long adjustment time? If you need low latency, small chunksize and frequent rate adjustments (like a few secs) are better.
Setting the adjust period to 5 eliminated the problem. I tested for 15 minutes and I'm getting identical latency as 3b2 or 2.3.
No idea. No latency when CDSP is not running though.Nevertheless - you have pipewire in the chain. Do you know what causes the large latency, CDSP or PW?
250 would be more what I've been experimenting in Kodi. IIRC it's not noticeable in youtube videos.I would guess CDSP does not cause more than some 200ms of latency (2048 frames of capture chunksize + some processing time + 6143 frames of the target level for 48kHz samplerate)
Started withThe debug-level log does not show any issue, trace level (-vv) would tell more. I would suggest to lower the adjust_period to e.g. 5 seconds and log at trace level so that every write/delay/avail operation is listed. The moment of the very first write defines the overall latency of CDSP, because then the playback stream is clocked by the output device (pipewire -> output soundcard). The trace log will show how precisely the timing works in your case. But it will definitely not be a difference of hundreds of ms as you are complaining, absolutely not.
/usr/local/bin/camilladsp3.300 -l trace -o /home/shizuma/camilladsp.log /home/shizuma/.config/.camilladsp/v3/90deg-D1-test.yml
Not measuring it per se, adjusting it in Kodi with the audio/video sync slider until they are in sync.How did you measure the overall latency?

Once it's proven strable, I fix it in the config file so it's applied automatically:
Code:
<advancedsettings>
<video>
<subsdelayrange>120</subsdelayrange> <!-- Plage de décalage pour les sous-titres, en secondes. -->
<audiodelayrange>1</audiodelayrange> <!-- Plage de décalage pour la synchronisation audio/vidéo, en secondes. -->
<latency>
<delay>-250</delay>
</latency>
</video>
</advancedsettings>
UPDATE
Talked too soon. After 30 minutes testing, latency has increased and keeps increasing while the video is still playing. Currently at 600ms. Out of sync again.
Stopped the video and started another one and still out of sync. It builds slowly up to a maximum and stays there around 800 ms.

Attachments
Last edited:
- Home
- Source & Line
- PC Based
- CamillaDSP - Cross-platform IIR and FIR engine for crossovers, room correction etc