git: d8c3c6752bf8 - stable/14 - sound: Turn clamp macros into a function

From: Christos Margiolis <christos_at_FreeBSD.org>
Date: Mon, 17 Mar 2025 18:36:46 UTC
The branch stable/14 has been updated by christos:

URL: https://cgit.FreeBSD.org/src/commit/?id=d8c3c6752bf874bb193ed7948e17946430912c23

commit d8c3c6752bf874bb193ed7948e17946430912c23
Author:     Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2025-03-10 20:19:27 +0000
Commit:     Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2025-03-17 18:28:54 +0000

    sound: Turn clamp macros into a function
    
    This makes some subsequent feeder refactors easier to implement.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D48421
    
    (cherry picked from commit 4918fc2e238b581aaf1f63e20003d5fa957f0b09)
---
 sys/dev/sound/pcm/feeder_eq.c     |  8 ++---
 sys/dev/sound/pcm/feeder_mixer.c  |  2 +-
 sys/dev/sound/pcm/feeder_rate.c   |  8 ++---
 sys/dev/sound/pcm/feeder_volume.c |  3 +-
 sys/dev/sound/pcm/pcm.h           | 64 +++++++++++++++++++++++----------------
 5 files changed, 45 insertions(+), 40 deletions(-)

diff --git a/sys/dev/sound/pcm/feeder_eq.c b/sys/dev/sound/pcm/feeder_eq.c
index df34ee44a2ab..c5f82a2f18fc 100644
--- a/sys/dev/sound/pcm/feeder_eq.c
+++ b/sys/dev/sound/pcm/feeder_eq.c
@@ -135,10 +135,6 @@ struct feed_eq_info {
 #define FEEDEQ_ERR_CLIP_CHECK(...)
 #endif
 
-#define FEEDEQ_CLAMP(v)		(((v) > PCM_S32_MAX) ? PCM_S32_MAX :	\
-				(((v) < PCM_S32_MIN) ? PCM_S32_MIN :	\
-				  (v)))
-
 #define FEEDEQ_DECLARE(SIGN, BIT, ENDIAN)					\
 static void									\
 feed_eq_biquad_##SIGN##BIT##ENDIAN(struct feed_eq_info *info,			\
@@ -187,7 +183,7 @@ feed_eq_biquad_##SIGN##BIT##ENDIAN(struct feed_eq_info *info,			\
 			info->treble.o2[i] = info->treble.o1[i];		\
 			w >>= FEEDEQ_COEFF_SHIFT;				\
 			FEEDEQ_ERR_CLIP_CHECK(treble, w);			\
-			v = FEEDEQ_CLAMP(w);					\
+			v = pcm_clamp(w, AFMT_S32_NE);				\
 			info->treble.o1[i] = v;					\
 										\
 			w  = (intpcm64_t)v * bass->b0;				\
@@ -200,7 +196,7 @@ feed_eq_biquad_##SIGN##BIT##ENDIAN(struct feed_eq_info *info,			\
 			info->bass.o2[i] = info->bass.o1[i];			\
 			w >>= FEEDEQ_COEFF_SHIFT;				\
 			FEEDEQ_ERR_CLIP_CHECK(bass, w);				\
-			v = FEEDEQ_CLAMP(w);					\
+			v = pcm_clamp(w, AFMT_S32_NE);				\
 			info->bass.o1[i] = v;					\
 										\
 			pcm_sample_write_norm(dst, v,				\
diff --git a/sys/dev/sound/pcm/feeder_mixer.c b/sys/dev/sound/pcm/feeder_mixer.c
index 7640b09400ed..9a7d75198692 100644
--- a/sys/dev/sound/pcm/feeder_mixer.c
+++ b/sys/dev/sound/pcm/feeder_mixer.c
@@ -64,7 +64,7 @@ feed_mixer_##SIGN##BIT##ENDIAN(uint8_t *src, uint8_t *dst,		\
 		y = pcm_sample_read_calc(dst,				\
 		    AFMT_##SIGN##BIT##_##ENDIAN);			\
 		z = INTPCM##BIT##_T(x) + y;				\
-		x = PCM_CLAMP_##SIGN##BIT(z);				\
+		x = pcm_clamp_calc(z, AFMT_##SIGN##BIT##_##ENDIAN);	\
 		pcm_sample_write(dst, x,				\
 		    AFMT_##SIGN##BIT##_##ENDIAN);			\
 	} while (count != 0);						\
diff --git a/sys/dev/sound/pcm/feeder_rate.c b/sys/dev/sound/pcm/feeder_rate.c
index e1b4076e248e..1610211ff5f5 100644
--- a/sys/dev/sound/pcm/feeder_rate.c
+++ b/sys/dev/sound/pcm/feeder_rate.c
@@ -502,10 +502,6 @@ z_feed_linear_##SIGN##BIT##ENDIAN(struct z_info *info, uint8_t *dst)		\
 #define Z_CLIP_CHECK(...)
 #endif
 
-#define Z_CLAMP(v, BIT)							\
-	(((v) > PCM_S##BIT##_MAX) ? PCM_S##BIT##_MAX :			\
-	(((v) < PCM_S##BIT##_MIN) ? PCM_S##BIT##_MIN : (v)))
-
 /*
  * Sine Cardinal (SINC) Interpolation. Scaling is done in 64 bit, so
  * there's no point to hold the plate any longer. All samples will be
@@ -574,7 +570,7 @@ z_feed_sinc_##SIGN##BIT##ENDIAN(struct z_info *info, uint8_t *dst)		\
 		else								\
 			v >>= Z_COEFF_SHIFT - Z_GUARD_BIT_##BIT;		\
 		Z_CLIP_CHECK(v, BIT);						\
-		pcm_sample_write(dst, Z_CLAMP(v, BIT),				\
+		pcm_sample_write(dst, pcm_clamp(v, AFMT_##SIGN##BIT##_##ENDIAN),\
 		    AFMT_##SIGN##BIT##_##ENDIAN);				\
 	} while (ch != 0);							\
 }
@@ -614,7 +610,7 @@ z_feed_sinc_polyphase_##SIGN##BIT##ENDIAN(struct z_info *info, uint8_t *dst)	\
 		else								\
 			v >>= Z_COEFF_SHIFT - Z_GUARD_BIT_##BIT;		\
 		Z_CLIP_CHECK(v, BIT);						\
-		pcm_sample_write(dst, Z_CLAMP(v, BIT),				\
+		pcm_sample_write(dst, pcm_clamp(v, AFMT_##SIGN##BIT##_##ENDIAN),\
 		    AFMT_##SIGN##BIT##_##ENDIAN);				\
 	} while (ch != 0);							\
 }
diff --git a/sys/dev/sound/pcm/feeder_volume.c b/sys/dev/sound/pcm/feeder_volume.c
index 572bc980ffe3..f72c6aa7ef4f 100644
--- a/sys/dev/sound/pcm/feeder_volume.c
+++ b/sys/dev/sound/pcm/feeder_volume.c
@@ -66,7 +66,8 @@ feed_volume_##SIGN##BIT##ENDIAN(int *vol, int *matrix,			\
 			x = pcm_sample_read_calc(dst,			\
 			    AFMT_##SIGN##BIT##_##ENDIAN);		\
 			v = FEEDVOLUME_CALC##BIT(x, vol[matrix[i]]);	\
-			x = PCM_CLAMP_##SIGN##BIT(v);			\
+			x = pcm_clamp_calc(v,				\
+			    AFMT_##SIGN##BIT##_##ENDIAN);		\
 			pcm_sample_write(dst, x,			\
 			    AFMT_##SIGN##BIT##_##ENDIAN);		\
 		} while (i != 0);					\
diff --git a/sys/dev/sound/pcm/pcm.h b/sys/dev/sound/pcm/pcm.h
index f18d28b3b196..3b3b083457ee 100644
--- a/sys/dev/sound/pcm/pcm.h
+++ b/sys/dev/sound/pcm/pcm.h
@@ -103,32 +103,6 @@ typedef uint64_t uintpcm64_t;
 #define INTPCM24_T(v)	((intpcm24_t)(v))
 #define INTPCM32_T(v)	((intpcm32_t)(v))
 
-#define PCM_CLAMP_S8(val)						\
-			(((val) > PCM_S8_MAX) ? PCM_S8_MAX :		\
-			 (((val) < PCM_S8_MIN) ? PCM_S8_MIN : (val)))
-#define PCM_CLAMP_S16(val)						\
-			(((val) > PCM_S16_MAX) ? PCM_S16_MAX :		\
-			 (((val) < PCM_S16_MIN) ? PCM_S16_MIN : (val)))
-#define PCM_CLAMP_S24(val)						\
-			(((val) > PCM_S24_MAX) ? PCM_S24_MAX :		\
-			 (((val) < PCM_S24_MIN) ? PCM_S24_MIN : (val)))
-
-#ifdef SND_PCM_64
-#define PCM_CLAMP_S32(val)						\
-			(((val) > PCM_S32_MAX) ? PCM_S32_MAX :		\
-			 (((val) < PCM_S32_MIN) ? PCM_S32_MIN : (val)))
-#else	/* !SND_PCM_64 */
-#define PCM_CLAMP_S32(val)						\
-			(((val) > PCM_S24_MAX) ? PCM_S32_MAX :		\
-			 (((val) < PCM_S24_MIN) ? PCM_S32_MIN :		\
-			 ((val) << PCM_FXSHIFT)))
-#endif	/* SND_PCM_64 */
-
-#define PCM_CLAMP_U8(val)	PCM_CLAMP_S8(val)
-#define PCM_CLAMP_U16(val)	PCM_CLAMP_S16(val)
-#define PCM_CLAMP_U24(val)	PCM_CLAMP_S24(val)
-#define PCM_CLAMP_U32(val)	PCM_CLAMP_S32(val)
-
 static const struct {
 	const uint8_t ulaw_to_u8[G711_TABLE_SIZE];
 	const uint8_t alaw_to_u8[G711_TABLE_SIZE];
@@ -370,4 +344,42 @@ pcm_sample_write_calc(uint8_t *dst, intpcm_t v, uint32_t fmt)
 	pcm_sample_write(dst, v, fmt);
 }
 
+static __always_inline __unused intpcm_t
+pcm_clamp(intpcm32_t sample, uint32_t fmt)
+{
+	fmt = AFMT_ENCODING(fmt);
+
+	switch (AFMT_BIT(fmt)) {
+	case 8:
+		return ((sample > PCM_S8_MAX) ? PCM_S8_MAX :
+		    ((sample < PCM_S8_MIN) ? PCM_S8_MIN : sample));
+	case 16:
+		return ((sample > PCM_S16_MAX) ? PCM_S16_MAX :
+		    ((sample < PCM_S16_MIN) ? PCM_S16_MIN : sample));
+	case 24:
+		return ((sample > PCM_S24_MAX) ? PCM_S24_MAX :
+		    ((sample < PCM_S24_MIN) ? PCM_S24_MIN : sample));
+	case 32:
+		return ((sample > PCM_S32_MAX) ? PCM_S32_MAX :
+		    ((sample < PCM_S32_MIN) ? PCM_S32_MIN : sample));
+	default:
+		printf("%s(): unknown format: 0x%08x\n", __func__, fmt);
+		__assert_unreachable();
+	}
+}
+
+static __always_inline __unused intpcm_t
+pcm_clamp_calc(intpcm32_t sample, uint32_t fmt)
+{
+#ifndef SND_PCM_64
+	if (fmt & AFMT_32BIT) {
+		return ((sample > PCM_S24_MAX) ? PCM_S32_MAX :
+		    ((sample < PCM_S24_MIN) ? PCM_S32_MIN :
+		    sample << PCM_FXSHIFT));
+	}
+#endif
+
+	return (pcm_clamp(sample, fmt));
+}
+
 #endif	/* !_SND_PCM_H_ */