Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133546112
D48394.id152114.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D48394.id152114.diff
View Options
diff --git a/sys/dev/sound/pcm/feeder_mixer.c b/sys/dev/sound/pcm/feeder_mixer.c
--- 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 @@
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 @@
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 @@
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 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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Oct 27, 1:46 PM (3 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24297190
Default Alt Text
D48394.id152114.diff (6 KB)
Attached To
Mode
D48394: sound: Simplify pcm/feeder_mixer.c
Attached
Detach File
Event Timeline
Log In to Comment