Module Name: src
Committed By: mlelstv
Date: Sun Oct 1 09:34:29 UTC 2023
Modified Files:
src/sys/dev/audio: audio.c
Log Message:
Fix output for big-endian hardware.
Also optimize the output scaling routine.
To generate a diff of this commit:
cvs rdiff -u -r1.144 -r1.145 src/sys/dev/audio/audio.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/audio/audio.c
diff -u src/sys/dev/audio/audio.c:1.144 src/sys/dev/audio/audio.c:1.145
--- src/sys/dev/audio/audio.c:1.144 Mon Jun 5 16:26:05 2023
+++ src/sys/dev/audio/audio.c Sun Oct 1 09:34:28 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: audio.c,v 1.144 2023/06/05 16:26:05 mlelstv Exp $ */
+/* $NetBSD: audio.c,v 1.145 2023/10/01 09:34:28 mlelstv Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -181,7 +181,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.144 2023/06/05 16:26:05 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.145 2023/10/01 09:34:28 mlelstv Exp $");
#ifdef _KERNEL_OPT
#include "audio.h"
@@ -9222,7 +9222,6 @@ audio_mixsample_to_linear(audio_filter_a
const aint2_t *m;
uint8_t *p;
u_int sample_count;
- bool swap;
aint2_t v, xor;
u_int i, bps;
bool little;
@@ -9235,48 +9234,150 @@ audio_mixsample_to_linear(audio_filter_a
m = arg->src;
p = arg->dst;
sample_count = arg->count * fmt->channels;
- swap = arg->dstfmt->encoding == AUDIO_ENCODING_SLINEAR_OE;
-
-#if BYTE_ORDER == LITTLE_ENDIAN
- little = !swap;
-#endif
-#if BYTE_ORDER == BIG_ENDIAN
- little = swap;
-#endif
+ little = arg->dstfmt->encoding == AUDIO_ENCODING_SLINEAR_LE;
bps = fmt->stride / NBBY;
+ xor = audio_format2_is_signed(fmt) ? 0 : (aint2_t)1 << 31;
- xor = audio_format2_is_signed(fmt)
- ? 0 : 1 << (fmt->stride - 1);
-
- for (i=0; i<sample_count; ++i) {
- v = *m++;
-
- /* scale up to 32bit and then down to target size */
- v <<= 32 - AUDIO_INTERNAL_BITS;
- v >>= (4 - bps) * NBBY;
-
- /* signed -> unsigned */
- v ^= xor;
-
- if (little) {
- switch (bps) {
- case 4: *p++ = v; v >>= 8; /* FALLTHROUGH */
- case 3: *p++ = v; v >>= 8; /* FALLTHROUGH */
- case 2: *p++ = v; v >>= 8; /* FALLTHROUGH */
- case 1: *p++ = v; /* FALLTHROUGH */
+#if AUDIO_INTERNAL_BITS == 16
+ if (little) {
+ switch (bps) {
+ case 4:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = 0;
+ *p++ = 0;
+ *p++ = v;
+ *p++ = v >> 8;
}
- } else {
- switch (bps) {
- case 4: *p++ = v >> 24; v <<= 8; /* FALLTHROUGH */
- case 3: *p++ = v >> 24; v <<= 8; /* FALLTHROUGH */
- case 2: *p++ = v >> 24; v <<= 8; /* FALLTHROUGH */
- case 1: *p++ = v >> 24; /* FALLTHROUGH */
+ break;
+ case 3:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = 0;
+ *p++ = v;
+ *p++ = v >> 8;
+ }
+ break;
+ case 2:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v;
+ *p++ = v >> 8;
+ }
+ break;
+ case 1:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 8;
+ }
+ break;
+ }
+ } else {
+ switch (bps) {
+ case 4:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 8;
+ *p++ = v;
+ *p++ = 0;
+ *p++ = 0;
+ }
+ break;
+ case 3:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 8;
+ *p++ = v;
+ *p++ = 0;
+ }
+ break;
+ case 2:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 8;
+ *p++ = v;
+ }
+ break;
+ case 1:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 8;
+ }
+ break;
+ }
+ }
+#elif AUDIO_INTERNAL_BITS == 32
+ if (little) {
+ switch (bps) {
+ case 4:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v;
+ *p++ = v >> 8;
+ *p++ = v >> 16;
+ *p++ = v >> 24;
+ }
+ break;
+ case 3:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 8;
+ *p++ = v >> 16;
+ *p++ = v >> 24;
+ }
+ break;
+ case 2:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 16;
+ *p++ = v >> 24;
+ }
+ break;
+ case 1:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 24;
+ }
+ break;
+ }
+ } else {
+ switch (bps) {
+ case 4:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 24;
+ *p++ = v >> 16;
+ *p++ = v >> 8;
+ *p++ = v;
+ }
+ break;
+ case 3:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 24;
+ *p++ = v >> 16;
+ *p++ = v >> 8;
+ }
+ break;
+ case 2:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 24;
+ *p++ = v >> 16;
}
+ break;
+ case 1:
+ for (i=0; i<sample_count; ++i) {
+ v = *m++ ^ xor;
+ *p++ = v >> 24;
+ }
+ break;
}
}
-}
+#endif /* AUDIO_INTERNAL_BITS */
+}
#endif /* NAUDIO > 0 */