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 */
 

Reply via email to