diff options
author | Oswald Buddenhagen <oswald.buddenhagen@gmx.de> | 2023-05-05 17:52:43 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2023-05-05 18:23:52 +0200 |
commit | 6ffa6f397e80bc196ed554e4dabfe43ecc0fe7c1 (patch) | |
tree | 37f68f31ed698eea723bd7ba0cc8185d3e82a673 /sound | |
parent | 6d8d56db0cd14c415c26e27d949c615750c40d70 (diff) |
ALSA: pcm: simplify top-up mode init in snd_pcm_playback_silence()
Inline the remaining call of snd_pcm_playback_hw_avail(). This makes
the top-up branch more congruent with the thresholded one, and allows
simplifying the handling of the corner cases.
Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Link: https://lore.kernel.org/r/20230505155244.2312199-6-oswald.buddenhagen@gmx.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/pcm_lib.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 670572c9a8cc..17fc80a654be 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -90,15 +90,32 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram * This filling mode aims at free-running mode (used for example by dmix), * which doesn't update the application pointer. */ - if (new_hw_ptr == ULONG_MAX) { /* initialization */ - snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime); - if (avail > runtime->buffer_size) - avail = runtime->buffer_size; - runtime->silence_filled = avail > 0 ? avail : 0; - runtime->silence_start = runtime->status->hw_ptr; + snd_pcm_uframes_t hw_ptr = runtime->status->hw_ptr; + if (new_hw_ptr == ULONG_MAX) { + /* + * Initialization, fill the whole unused buffer with silence. + * + * Usually, this is entered while stopped, before data is queued, + * so both pointers are expected to be zero. + */ + snd_pcm_sframes_t avail = runtime->control->appl_ptr - hw_ptr; + if (avail < 0) + avail += runtime->boundary; + /* + * In free-running mode, appl_ptr will be zero even while running, + * so we end up with a huge number. There is no useful way to + * handle this, so we just clear the whole buffer. + */ + runtime->silence_filled = avail > runtime->buffer_size ? 0 : avail; + runtime->silence_start = hw_ptr; } else { - update_silence_vars(runtime, runtime->status->hw_ptr, new_hw_ptr); + /* Silence the just played area immediately */ + update_silence_vars(runtime, hw_ptr, new_hw_ptr); } + /* + * In this mode, silence_filled actually includes the valid + * sample data from the user. + */ frames = runtime->buffer_size - runtime->silence_filled; } if (snd_BUG_ON(frames > runtime->buffer_size)) |