Re: [PATCH alsa-lib 1/4] pcm: hw: setup explicit silencing for snd_pcm_drain by default

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, May 02, 2023 at 01:50:07PM +0200, Jaroslav Kysela wrote:
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -718,7 +732,40 @@ static int snd_pcm_hw_drop(snd_pcm_t *pcm)
static int snd_pcm_hw_drain(snd_pcm_t *pcm)
{
	snd_pcm_hw_t *hw = pcm->private_data;
+	snd_pcm_sw_params_t sw_params;
+	snd_pcm_uframes_t silence_size;
	int err;
+
+	if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
+		goto __skip_silence;
+	/* compute end silence size, align to period size + extra time */
+	snd_pcm_sw_params_current_no_lock(pcm, &sw_params);
+	if ((pcm->boundary % pcm->period_size) == 0) {
+		silence_size = pcm->period_size - (*pcm->appl.ptr % pcm->period_size);
+		if (silence_size == pcm->period_size)
+			silence_size = 0;
+	} else {
+		/* it not not easy to compute the period cross point
+		 * in this case because period is not aligned to the boundary
+		 * - use the full range (one period) in this case
+		 */
+		silence_size = pcm->period_size;
+	}
+	silence_size += pcm->rate / 10;	/* 1/10th of second */
+	if (sw_params.silence_size < silence_size) {
+		/* fill the silence soon as possible (in the bellow ioctl
+		 * or the next period wake up)
+		 */
+		sw_params.silence_threshold = pcm->buffer_size;
+		sw_params.silence_size = silence_size;

i was reworking my kernel patch along these lines (it's easier to deploy when the kernel is the only thing you're hacking on), and ran into this behavior:

check thresholded silence fill, sil start 0, sil fill 0, app 66000
now sil start 66000, sil fill 0
noise dist 23997
drain raw fill 0
drain extended fill 4800
frames 3
filling 3 at 18000
period elapsed
check thresholded silence fill, sil start 66000, sil fill 3, app 66000
now sil start 66000, sil fill 3
noise dist 18000
drain raw fill 0
drain extended fill 4800
frames 4800
filling 4800 at 18003
period elapsed
check thresholded silence fill, sil start 66000, sil fill 4803, app 66000
now sil start 66000, sil fill 4803
noise dist 16800
drain raw fill 0
drain extended fill 4800
frames 4800
filling 1197 at 22803
filling 3603 at 0
period elapsed
check thresholded silence fill, sil start 66000, sil fill 9603, app 66000
now sil start 66000, sil fill 9603
noise dist 15600
drain raw fill 0
drain extended fill 4800
frames 4800
filling 4800 at 3603
period elapsed
check thresholded silence fill, sil start 66000, sil fill 14403, app 66000
now sil start 66000, sil fill 14403
noise dist 6755399441055758400

what you're seeing is this: when the drain is issued, the buffer is initially full, and after every played period some padding is added, totalling way beyond what was intended.
this doesn't break anything, but it's a bit inefficient, and just ugly.

this is a result of silence_threshold being the buffer size.
and setting it to the silence_size of course doesn't work reliably when that is smaller than the period size.

while pondering how to fix that, my thoughts returned to my yet unaired gripe with the silencing parameters being anything but intuitive. would you mind explaining why they are like that?

why not interpret silence_size as the minimum number of playable samples (that is, noise_dist in the kernel code) that must be maintained at all times, and simply ignore silence_threshold?

unless i'm missing something, this is exactly what one would want for maintaining underrun resilience, which i think is the purpose of the thresholded silence fill mode (at least my comment updates which claim so were accepted).

and doing that would "magically" fix your patch.

can you think of any plausible use case that this would break?

but i guess you'll be paranoid about backwards compat anyway, so an alternative proposal would be using silence_threshold == ULONG_MAX to trigger the new semantics. of course this would have the downside that it wouldn't "magically" fix your code (and i suspect some other code as well), and kernel version dependent behavior would have to be coded for the (presumably) common usage.

regards



[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux