diyAudio (
-   PC Based (
-   -   CamillaDSP - Cross-platform IIR and FIR engine for crossovers, room correction etc. (

phofman 9th March 2020 11:13 AM

Well then the capture device is closed, the script says it clear:


while [ "$(cat /proc/asound/card3/pcm1c/sub0/status)" != "closed" ]
echo "Capture device closed. Clock rate control disabled (clk: 1000000)."

Either camilla is not running, or you are querying a different device. If you want to keep the script running all the time, you will have to modify it to accept the closed status (i.e. wrapping the "while not closed" loop with another while true loop with some sleep)

cube75 9th March 2020 11:16 AM

Found that out too...running now

pi@realtimepi:~ $ sh
uptime: 000000s bufsize: 8192 filled: 12% clk: 99000

phofman 9th March 2020 11:23 AM

Very good. Please keep us updated how fast the feedback will stabilize.

cube75 9th March 2020 11:54 AM

Well, to my understanding uptime,buftime and clk should update in terminal, right?
However it does not.

HenrikEnquist 9th March 2020 12:06 PM


Originally Posted by phofman (
How does the chain actually work? There are two independent devices - capture, playback. Which one has the "clock master" role in your code?

IIUC correctly there are options:

A) each side uses blocking read/write in separate threads, with execution thread in between, reading from some buffers. Then the "xrun" would occur in these buffers, not in the alsa drivers.

B) one side (master) uses blocking operation, the other one non-blocking ("slave"). The thread is timed by the blocking side, hoping the non-blocking side will produce/consume in the same rate.

C, D - other variants I do not know

Please which workflow do you use?

It's close to A but not exactly. I use queues instead of plain buffers between the threads. I launch three threads, one for capture, one for processing and one for playback.

The capture thread uses blocking io to read N samples per channel (given by buffersize setting). When done, it converts them to float, and packages them in a message that is sent in a channel to the processing thread. The channel is basically a queue shared between the treads and can hold more than one message. Once sent it goes back to reading another set of N samples.

The processing thread waits for a message, does the processing and sends the processed data as a message on another channel to the playback thread.

The playback thread waits for a message. Once received the data is converted to the right format for the device, and then written to the device using blocking io. Once all the data has been written, it loops around to wait for the next message.

In practice the capture device is the one deciding the rate. If the playback queue will slowly grow with not yet played data. If it instead runs faster, once in a while the message will be late, meaning that the playback device will run out of data. Once a new message has been received, playback is resumed.

phofman 9th March 2020 12:23 PM

Henrik, thanks a lot for the explanation. I like your 3-thread architecture, IMO the most robust and technically sound solution.

IIUC, the buffer fill (/proc) should be read from the playback soundcard, adjusting the loopback device on capture side, just like you said.

phofman 9th March 2020 12:47 PM


Originally Posted by cube75 (
Well, to my understanding uptime,buftime and clk should update in terminal, right?
However it does not.

Look at the script. The information is echoed only when new = different clkrate is identified:


# set clock rate of snd-aloop
if [ $clkrate -ne $lastclk ]
  amixer -c 3 cset numid=7 $clkrate > /dev/null
  echo "uptime: "$up"s bufsize: "$loopc_bufsize" filled: "$buf_ratio"% clk: "$clkrate

You keep reading from the loopback /proc, right? But as Henrik said - that buffer will be kept empty all the time, because the reading thread in camilladsp has no blocking on the consumer side - there is a nonblocking queue which can grow unlimited.

Try to print the buf_ratio to see the value:

# fill rate in percent
echo "buf_ratio: $buf_ratio"  # <----

I think you will see values close to zero all the time. It is under 70 constantly and clkrate is always 99000 - no change, no printout.

You need to read buffer fill of the playback soundcard, IMO.

cube75 9th March 2020 01:07 PM

Yes, for Camilladsp the playbackcard should be read, I know.

I tested this morning with brutefir. Still some glitches.

TNT 9th March 2020 02:21 PM


Originally Posted by Daihedz (
...or by cheating something useful into the data stream.

Please help NO !!


Daihedz 9th March 2020 07:06 PM


Originally Posted by TNT (
Please help NO !!


Agreed. Maybe it is not necessary to cheat.

There are indeed perfect solutions already implemented into audio programs: The aforementionned playhrt player which I use in my pipe provides a parameter --extra-bytes-per-second which performs exactly what is discussed here. This parameter allows to specify a correction for the differences between the soundcard's and the computer clocks. Maybe a look into the code of playhrt could be interesting: Bitbucket

All times are GMT. The time now is 07:51 AM.

Search Engine Optimisation provided by DragonByte SEO (Pro) - vBulletin Mods & Addons Copyright © 2021 DragonByte Technologies Ltd.
Resources saved on this page: MySQL 17.65%
vBulletin Optimisation provided by vB Optimise (Pro) - vBulletin Mods & Addons Copyright © 2021 DragonByte Technologies Ltd.
Copyright ©1999-2021 diyAudio