diff mbox series

[alsa-lib,4/4] pcm: hw: introduce SNDRV_PCM_HW_PARAMS_DRAIN_SILENCE

Message ID 20230502115010.986325-5-perex@perex.cz (mailing list archive)
State New, archived
Headers show
Series pcm: hw: implement explicit silencing for snd_pcm_drain | expand

Commit Message

Jaroslav Kysela May 2, 2023, 11:50 a.m. UTC
The application may not require to touch the sample stream
for the drain operation at all. Handle this situation
in alsa-lib.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
 include/sound/uapi/asound.h |  3 +++
 src/pcm/pcm.c               | 32 ++++++++++++++++++++++++++++++++
 src/pcm/pcm_hw.c            |  3 ++-
 src/pcm/pcm_local.h         |  1 +
 4 files changed, 38 insertions(+), 1 deletion(-)

Comments

Oswald Buddenhagen May 3, 2023, 11:26 a.m. UTC | #1
On Tue, May 02, 2023 at 01:50:10PM +0200, Jaroslav Kysela wrote:
>The application may not require to touch the sample stream
>for the drain operation at all. Handle this situation
>in alsa-lib.
>
i find this too vague.

  This allows an application which uses an mmapped buffer to inform us 
  that it is handling the silence padding itself.

>Signed-off-by: Jaroslav Kysela <perex@perex.cz>
>---
> include/sound/uapi/asound.h |  3 +++
> src/pcm/pcm.c               | 32 ++++++++++++++++++++++++++++++++
> src/pcm/pcm_hw.c            |  3 ++-
> src/pcm/pcm_local.h         |  1 +
> 4 files changed, 38 insertions(+), 1 deletion(-)
>
>diff --git a/include/sound/uapi/asound.h b/include/sound/uapi/asound.h
>index 0b8834f2..f970179e 100644
>--- a/include/sound/uapi/asound.h
>+++ b/include/sound/uapi/asound.h
>@@ -390,6 +390,9 @@ typedef int snd_pcm_hw_param_t;
> #define SNDRV_PCM_HW_PARAMS_NORESAMPLE	(1<<0)	/* avoid rate resampling */
> #define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER	(1<<1)	/* export buffer */
> #define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP	(1<<2)	/* disable period wakeups */
>+#define SNDRV_PCM_HW_PARAMS_NO_DRAIN_SILENCE	(1<<3)	/* supress drain with the filling
>+							 * of the silence samples
>+							 */
"suppress automatic silence fill when draining playback"

>--- a/src/pcm/pcm.c
>+++ b/src/pcm/pcm.c
>@@ -4958,6 +4958,38 @@ int snd_pcm_hw_params_get_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *par
> 	return 0;
> }
> 
>+/**
>+ * \brief Restrict a configuration space to allow the drain with the 
>filling of silence samples
>
there is no way i'd understand what this means. in fact, i'm having a 
hard time even though i more or less know it already.

>+ * \param pcm PCM handle
>+ * \param params Configuration space
>+ * \param val 0 = disable, 1 = enable (default) drain with the filling of silence samples
>
"padding the playback buffer with silence when drain() is invoked"

>+ * \return 0 otherwise a negative error code

add description:

"When disabled, the application must ensure that enough samples are 
silenced, as most hardware will read beyond the application pointer when 
drain() is invoked."

>+/**
>+ * \brief Extract drain with the filling of silence samples from a configuration space
>
this is also kinda incomprehensible.

>+ * \param pcm PCM handle
>+ * \param params Configuration space
>+ * \param val 0 = disable, 1 = enable
>
as this returns the status quo, this should be disabled/enabled.

>+ * \return 0 otherwise a negative error code
>
there is no "otherwise" here.

>+ */
>+int snd_pcm_hw_params_get_drain_silence(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
>+{
>+	assert(pcm && params && val);
>+	*val = params->flags & SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE ? 0 : 1;
>
i know i'm paranoid, but i'd put extra parens around the condition.

>+	return 0;
>+}
>+

>--- a/src/pcm/pcm_hw.c
>+++ b/src/pcm/pcm_hw.c
>@@ -399,7 +399,8 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
>-	hw->perfect_drain = !!(params->info & SND_PCM_INFO_PERFECT_DRAIN);
>+	hw->perfect_drain = !!(params->info & SND_PCM_INFO_PERFECT_DRAIN) ||
>+			    !!(params->flags & SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE);
> 
pedantically, you can remove the double negations as this point.

regards
diff mbox series

Patch

diff --git a/include/sound/uapi/asound.h b/include/sound/uapi/asound.h
index 0b8834f2..f970179e 100644
--- a/include/sound/uapi/asound.h
+++ b/include/sound/uapi/asound.h
@@ -390,6 +390,9 @@  typedef int snd_pcm_hw_param_t;
 #define SNDRV_PCM_HW_PARAMS_NORESAMPLE	(1<<0)	/* avoid rate resampling */
 #define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER	(1<<1)	/* export buffer */
 #define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP	(1<<2)	/* disable period wakeups */
+#define SNDRV_PCM_HW_PARAMS_NO_DRAIN_SILENCE	(1<<3)	/* supress drain with the filling
+							 * of the silence samples
+							 */
 
 struct snd_interval {
 	unsigned int min, max;
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index 099d83ee..5872ee6f 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -4958,6 +4958,38 @@  int snd_pcm_hw_params_get_period_wakeup(snd_pcm_t *pcm, snd_pcm_hw_params_t *par
 	return 0;
 }
 
+/**
+ * \brief Restrict a configuration space to allow the drain with the filling of silence samples
+ * \param pcm PCM handle
+ * \param params Configuration space
+ * \param val 0 = disable, 1 = enable (default) drain with the filling of silence samples
+ * \return 0 otherwise a negative error code
+ */
+int snd_pcm_hw_params_set_drain_silence(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
+{
+	assert(pcm && params);
+	if (val)
+		params->flags &= ~SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE;
+	else
+		params->flags |= SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE;
+	params->rmask = ~0;
+	return snd_pcm_hw_refine(pcm, params);
+}
+
+/**
+ * \brief Extract drain with the filling of silence samples from a configuration space
+ * \param pcm PCM handle
+ * \param params Configuration space
+ * \param val 0 = disable, 1 = enable
+ * \return 0 otherwise a negative error code
+ */
+int snd_pcm_hw_params_get_drain_silence(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
+{
+	assert(pcm && params && val);
+	*val = params->flags & SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE ? 0 : 1;
+	return 0;
+}
+
 /**
  * \brief Extract period time from a configuration space
  * \param params Configuration space
diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index ea0c2ef2..90d5d07a 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -399,7 +399,8 @@  static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
 	params->info &= ~0xf0000000;
 	if (pcm->tstamp_type != SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY)
 		params->info |= SND_PCM_INFO_MONOTONIC;
-	hw->perfect_drain = !!(params->info & SND_PCM_INFO_PERFECT_DRAIN);
+	hw->perfect_drain = !!(params->info & SND_PCM_INFO_PERFECT_DRAIN) ||
+			    !!(params->flags & SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE);
 	return query_status_data(hw);
 }
 
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index b039dda0..abea6654 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -107,6 +107,7 @@ 
 #define SND_PCM_HW_PARAMS_NORESAMPLE SNDRV_PCM_HW_PARAMS_NORESAMPLE
 #define SND_PCM_HW_PARAMS_EXPORT_BUFFER SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER
 #define SND_PCM_HW_PARAMS_NO_PERIOD_WAKEUP SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP
+#define SND_PCM_HW_PARAMS_NO_DRAIN_SILENCE SNDRV_PCM_HW_PARAMS_NO_DRAIN_SILENCE
 
 #define SND_PCM_INFO_MONOTONIC	0x80000000