Louis Gorenfeld wrote:
I can't post the source code, but I can post the
algorithm: We have
input and output synched. The inputs are set to non-blocking behavior
while the outputs are not. The loop grabs input, and does any
processing it needs to. After that, it detects if any of the streams
are behind more than a period, and snd_pcm_forwards them a period
length if so. It then writes the waiting buffer to the blocking
outputs.
I've written a test program that implements your algorithm, except that
both devices are blocking, and that it aborts on xruns. It sends a
period containing a sine wave, then copies the recorded data to the
output. Ten periods of recorded data are dumped to the output.
In the recorded data, there is a silent gap of two periods between each
two periods containing data; this is the same behaviour that you see.
This can be explained by the following observations:
1) At the start of the loop, the output buffer is full, and the input
buffer contains one period of recorded data. Let's assume that the
output buffer contains two periods of silence and that the input data
contains a signal whose latency you want to measure.
2) The input data period is read and processed.
3) The data is written to the output buffer, but since the buffer is
(partially) full, this writing waits while the data of one period in
the buffer is still being played. This is one period of silence.
At the same time, one period is recorded.
4) In the next loop cycle, one period is read and written. During this
time, the second period of silence is played.
5) In the next loop cycle, one period is read and written. During this
time, the period containing the recorded signal is played.
So, between the end of the period where we recorded the signal and the
beginning of the period where the signal was played, there is an
interval of two periods, i.e., the overall latency is three periods.
This is caused be the algorithm; when we want to write one period of
data at the end of step 2) above, we still have (almost) two periods of
not-yet-played data in the buffer.
To reduce the latency, you would have to keep the output buffer more
empty. In my test program, try removing one of the writei calls before
the snd_pcm_start.
Best regards,
Clemens