The branch stable/14 has been updated by christos:

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

commit a33356100b850d79d11b3630fda2b421f1ccba8d
Author:     Christos Margiolis <[email protected]>
AuthorDate: 2025-03-10 20:38:23 +0000
Commit:     Christos Margiolis <[email protected]>
CommitDate: 2025-03-17 18:28:54 +0000

    sound: Simplify pcm/feeder_mixer.c
    
    - Get rid of macro magic.
    - Make feed_mixer_info handling similar to most feeders.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D48394
    
    (cherry picked from commit 4021fa32d92d656d3d43186cc231695c7ad53d33)
---
 sys/dev/sound/pcm/feeder_mixer.c | 173 +++++++++++++++------------------------
 1 file changed, 68 insertions(+), 105 deletions(-)

diff --git a/sys/dev/sound/pcm/feeder_mixer.c b/sys/dev/sound/pcm/feeder_mixer.c
index 9a7d75198692..f5f2b9bc9c36 100644
--- a/sys/dev/sound/pcm/feeder_mixer.c
+++ b/sys/dev/sound/pcm/feeder_mixer.c
@@ -42,136 +42,83 @@
 #undef SND_FEEDER_MULTIFORMAT
 #define SND_FEEDER_MULTIFORMAT 1
 
-typedef void (*feed_mixer_t)(uint8_t *, uint8_t *, uint32_t);
-
-#define FEEDMIXER_DECLARE(SIGN, BIT, ENDIAN)                           \
-static void                                                            \
-feed_mixer_##SIGN##BIT##ENDIAN(uint8_t *src, uint8_t *dst,             \
-    uint32_t count)                                                    \
-{                                                                      \
-       intpcm##BIT##_t z;                                              \
-       intpcm_t x, y;                                                  \
-                                                                       \
-       src += count;                                                   \
-       dst += count;                                                   \
-                                                                       \
-       do {                                                            \
-               src -= PCM_##BIT##_BPS;                                 \
-               dst -= PCM_##BIT##_BPS;                                 \
-               count -= PCM_##BIT##_BPS;                               \
-               x = pcm_sample_read_calc(src,                           \
-                   AFMT_##SIGN##BIT##_##ENDIAN);                       \
-               y = pcm_sample_read_calc(dst,                           \
-                   AFMT_##SIGN##BIT##_##ENDIAN);                       \
-               z = INTPCM##BIT##_T(x) + y;                             \
-               x = pcm_clamp_calc(z, AFMT_##SIGN##BIT##_##ENDIAN);     \
-               pcm_sample_write(dst, x,                                \
-                   AFMT_##SIGN##BIT##_##ENDIAN);                       \
-       } while (count != 0);                                           \
-}
-
-#if BYTE_ORDER == LITTLE_ENDIAN || defined(SND_FEEDER_MULTIFORMAT)
-FEEDMIXER_DECLARE(S, 16, LE)
-FEEDMIXER_DECLARE(S, 32, LE)
-#endif
-#if BYTE_ORDER == BIG_ENDIAN || defined(SND_FEEDER_MULTIFORMAT)
-FEEDMIXER_DECLARE(S, 16, BE)
-FEEDMIXER_DECLARE(S, 32, BE)
-#endif
-#ifdef SND_FEEDER_MULTIFORMAT
-FEEDMIXER_DECLARE(S,  8, NE)
-FEEDMIXER_DECLARE(S, 24, LE)
-FEEDMIXER_DECLARE(S, 24, BE)
-FEEDMIXER_DECLARE(U,  8, NE)
-FEEDMIXER_DECLARE(U, 16, LE)
-FEEDMIXER_DECLARE(U, 24, LE)
-FEEDMIXER_DECLARE(U, 32, LE)
-FEEDMIXER_DECLARE(U, 16, BE)
-FEEDMIXER_DECLARE(U, 24, BE)
-FEEDMIXER_DECLARE(U, 32, BE)
-#endif
-
 struct feed_mixer_info {
        uint32_t format;
+       uint32_t channels;
        int bps;
-       feed_mixer_t mix;
 };
 
-#define FEEDMIXER_ENTRY(SIGN, BIT, ENDIAN)                             \
-       {                                                               \
-               AFMT_##SIGN##BIT##_##ENDIAN, PCM_##BIT##_BPS,           \
-               feed_mixer_##SIGN##BIT##ENDIAN                          \
-       }
-
-static struct feed_mixer_info feed_mixer_info_tab[] = {
-       FEEDMIXER_ENTRY(S,  8, NE),
-#if BYTE_ORDER == LITTLE_ENDIAN || defined(SND_FEEDER_MULTIFORMAT)
-       FEEDMIXER_ENTRY(S, 16, LE),
-       FEEDMIXER_ENTRY(S, 32, LE),
-#endif
-#if BYTE_ORDER == BIG_ENDIAN || defined(SND_FEEDER_MULTIFORMAT)
-       FEEDMIXER_ENTRY(S, 16, BE),
-       FEEDMIXER_ENTRY(S, 32, BE),
-#endif
-#ifdef SND_FEEDER_MULTIFORMAT
-       FEEDMIXER_ENTRY(S, 24, LE),
-       FEEDMIXER_ENTRY(S, 24, BE),
-       FEEDMIXER_ENTRY(U,  8, NE),
-       FEEDMIXER_ENTRY(U, 16, LE),
-       FEEDMIXER_ENTRY(U, 24, LE),
-       FEEDMIXER_ENTRY(U, 32, LE),
-       FEEDMIXER_ENTRY(U, 16, BE),
-       FEEDMIXER_ENTRY(U, 24, BE),
-       FEEDMIXER_ENTRY(U, 32, BE),
-#endif
-       {    AFMT_AC3, PCM_16_BPS, NULL },
-       { AFMT_MU_LAW,  PCM_8_BPS, feed_mixer_U8NE },   /* dummy */
-       {  AFMT_A_LAW,  PCM_8_BPS, feed_mixer_U8NE }    /* dummy */
-};
+static void
+feed_mixer_apply(uint8_t *src, uint8_t *dst, uint32_t count, const uint32_t 
fmt)
+{
+       intpcm32_t z;
+       intpcm_t x, y;
 
-#define FEEDMIXER_TAB_SIZE     ((int32_t)                              \
-                                (sizeof(feed_mixer_info_tab) /         \
-                                 sizeof(feed_mixer_info_tab[0])))
+       src += count;
+       dst += count;
 
-#define FEEDMIXER_DATA(i, c)   ((void *)                               \
-                                ((uintptr_t)((((i) & 0x1f) << 7) |     \
-                                ((c) & 0x7f))))
-#define FEEDMIXER_INFOIDX(d)   ((uint32_t)((uintptr_t)(d) >> 7) & 0x1f)
-#define FEEDMIXER_CHANNELS(d)  ((uint32_t)((uintptr_t)(d)) & 0x7f)
+       do {
+               src -= AFMT_BPS(fmt);
+               dst -= AFMT_BPS(fmt);
+               count -= AFMT_BPS(fmt);
+               x = pcm_sample_read_calc(src, fmt);
+               y = pcm_sample_read_calc(dst, fmt);
+               z = INTPCM_T(x) + y;
+               x = pcm_clamp_calc(z, fmt);
+               pcm_sample_write(dst, x, fmt);
+       } while (count != 0);
+}
 
 static int
 feed_mixer_init(struct pcm_feeder *f)
 {
-       int i;
+       struct feed_mixer_info *info;
 
        if (f->desc->in != f->desc->out)
                return (EINVAL);
 
-       for (i = 0; i < FEEDMIXER_TAB_SIZE; i++) {
-               if (AFMT_ENCODING(f->desc->in) ==
-                   feed_mixer_info_tab[i].format) {
-                       f->data =
-                           FEEDMIXER_DATA(i, AFMT_CHANNEL(f->desc->in));
-                       return (0);
-               }
-       }
+       info = malloc(sizeof(*info), M_DEVBUF, M_NOWAIT | M_ZERO);
+       if (info == NULL)
+               return (ENOMEM);
+
+       info->format = AFMT_ENCODING(f->desc->in);
+       info->channels = AFMT_CHANNEL(f->desc->in);
+       info->bps = AFMT_BPS(f->desc->in);
+
+       f->data = info;
 
-       return (EINVAL);
+       return (0);
+}
+
+static int
+feed_mixer_free(struct pcm_feeder *f)
+{
+       struct feed_mixer_info *info;
+
+       info = f->data;
+       if (info != NULL)
+               free(info, M_DEVBUF);
+
+       f->data = NULL;
+
+       return (0);
 }
 
 static int
 feed_mixer_set(struct pcm_feeder *f, int what, int value)
 {
+       struct feed_mixer_info *info;
+
+       info = f->data;
 
        switch (what) {
        case FEEDMIXER_CHANNELS:
                if (value < SND_CHN_MIN || value > SND_CHN_MAX)
                        return (EINVAL);
-               f->data = FEEDMIXER_DATA(FEEDMIXER_INFOIDX(f->data), value);
+               info->channels = (uint32_t)value;
                break;
        default:
                return (EINVAL);
-               break;
        }
 
        return (0);
@@ -297,8 +244,8 @@ feed_mixer_feed(struct pcm_feeder *f, struct pcm_channel 
*c, uint8_t *b,
        if (sz < count)
                count = sz;
 
-       info = &feed_mixer_info_tab[FEEDMIXER_INFOIDX(f->data)];
-       sz = info->bps * FEEDMIXER_CHANNELS(f->data);
+       info = f->data;
+       sz = info->bps * info->channels;
        count = SND_FXROUND(count, sz);
        if (count < sz)
                return (0);
@@ -331,7 +278,7 @@ feed_mixer_feed(struct pcm_feeder *f, struct pcm_channel 
*c, uint8_t *b,
                if ((ch->flags & CHN_F_MMAP) && !(ch->flags & CHN_F_CLOSING))
                        sndbuf_acquire(ch->bufsoft, NULL,
                            sndbuf_getfree(ch->bufsoft));
-               if (info->mix == NULL) {
+               if (c->flags & CHN_F_PASSTHROUGH) {
                        /*
                         * Passthrough. Dump the first digital/passthrough
                         * channel into destination buffer, and the rest into
@@ -373,7 +320,22 @@ feed_mixer_feed(struct pcm_feeder *f, struct pcm_channel 
*c, uint8_t *b,
                                                    f->desc->out), mcnt);
                                                mcnt = 0;
                                        }
-                                       info->mix(tmp, b, cnt);
+                                       switch (info->format) {
+                                       case AFMT_S16_NE:
+                                               feed_mixer_apply(tmp, b, cnt,
+                                                   AFMT_S16_NE);
+                                               break;
+                                       case AFMT_S24_NE:
+                                               feed_mixer_apply(tmp, b, cnt,
+                                                   AFMT_S24_NE);
+                                               break;
+                                       case AFMT_S32_NE:
+                                               feed_mixer_apply(tmp, b, cnt,
+                                                   AFMT_S32_NE);
+                                               break;
+                                       }
+                                       feed_mixer_apply(tmp, b, cnt,
+                                           info->format);
                                        if (cnt > rcnt)
                                                rcnt = cnt;
                                }
@@ -397,6 +359,7 @@ static struct pcm_feederdesc feeder_mixer_desc[] = {
 
 static kobj_method_t feeder_mixer_methods[] = {
        KOBJMETHOD(feeder_init,         feed_mixer_init),
+       KOBJMETHOD(feeder_free,         feed_mixer_free),
        KOBJMETHOD(feeder_set,          feed_mixer_set),
        KOBJMETHOD(feeder_feed,         feed_mixer_feed),
        KOBJMETHOD_END

Reply via email to