Louis Gorenfeld wrote:
on 1) When you say the output buffer is full, it is
full of flatline
(dc/blank/etc), right?
This doesn't matter for the algorithm since I'm only interested in the
latency between recording some data and actually playing _that_ data.
In my example program, that data is silence so that I can detect the
signal.
on 2) At this point, the input data is read and is in
the first period
(that is, it's not visible to the program yet)?
The input data was just read, that is, it was recorded in the time
since the last readi() (or since the pcm_start).
on 3) At this point, the input data is visible to the
software and
immediately copied to the first output period, right? I don't
understand why the output buffer is still partially full.
Because the read did not block.
Are you saying that the input and output period
boundaries don't
necessarily line up?
This can happen with certain devices, but usually not with PCI sound
cards.
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.
I'm not hearing any audible gapping.. is this what you mean?
It's only a few milliseconds anyway.
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.
But since the input and output are synched and in my solution not
blocking on input, wouldn't adding writei just cause a buffer overrun
in the input while it writes out blank buffers?
Yes, but I wrote "removing".
I'm not clear on how this actually adds latency.
I was under the
impression that was a function of buffer size.
This depends on how you manage the output buffer.
There are several latencies that add to the overall latency of the
program.
DMA FIFOs and group delays of the input/output devices are fixed.
The input buffering has a fixed latency of one period, because you can
structure the algorithm so that the input data is read as soon as a
period has been recorded. (The input buffer size does not matter, so
you can make it as big as possible to prevent overruns.)
The output buffering latency is the time between writing some data to
the buffer and the actual playback of that data, and that interval is
equivalent to the amount of data that is already in the buffer when you
are writing. If the buffer is already completely filled, the entire
buffer must be played before your new data, so the entire buffer length
determines the latency.
With a two-period buffer, the input and output buffering latencies add
up to three periods, which is what you are observing in your program.
To decrease that output buffering latency, make sure that there is less
valid data in the buffer when you are writing. This is initially
determined by the amount of data you put into the buffer before starting
streaming, and can be later adjusted with snd_pcm_forward/rewind().
So, how much data does your program write into the output buffer before
calling snd_pcm_start(), and how exactly does your program determine if
it should call snd_pcm_forward() on the output buffer?
Best regards,
Clemens