Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/audio Use AUDIO_SCALEDOWN() macro rather than seemin...



details:   https://anonhg.NetBSD.org/src/rev/e5eb88d9e949
branches:  trunk
changeset: 451884:e5eb88d9e949
user:      isaki <isaki%NetBSD.org@localhost>
date:      Mon Jun 10 13:49:39 2019 +0000

description:
Use AUDIO_SCALEDOWN() macro rather than seemingly strange ifdefs.
Discussed on source-changes-d.

diffstat:

 sys/dev/audio/audio.c    |  60 ++++++++++++++++++++++++++---------------------
 sys/dev/audio/audiodef.h |   8 +-----
 2 files changed, 34 insertions(+), 34 deletions(-)

diffs (138 lines):

diff -r 85fe45b361a0 -r e5eb88d9e949 sys/dev/audio/audio.c
--- a/sys/dev/audio/audio.c     Mon Jun 10 13:28:08 2019 +0000
+++ b/sys/dev/audio/audio.c     Mon Jun 10 13:49:39 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: audio.c,v 1.15 2019/06/10 13:28:08 isaki Exp $ */
+/*     $NetBSD: audio.c,v 1.16 2019/06/10 13:49:39 isaki Exp $ */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -142,7 +142,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.15 2019/06/10 13:28:08 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.16 2019/06/10 13:49:39 isaki Exp $");
 
 #ifdef _KERNEL_OPT
 #include "audio.h"
@@ -458,6 +458,28 @@
 #define SPECIFIED(x)   ((x) != ~0)
 #define SPECIFIED_CH(x)        ((x) != (u_char)~0)
 
+/*
+ * AUDIO_SCALEDOWN()
+ * This macro should be used for audio wave data only.
+ *
+ * The arithmetic shift right (ASR) (in other words, floor()) is good for
+ * this purpose, and will be faster than division on the most platform.
+ * The division (in other words, truncate()) is not so bad alternate for
+ * this purpose, and will be fast enough.
+ * (Using ASR is 1.9 times faster than division on my amd64, and 1.3 times
+ * faster on my m68k.  -- isaki 201801.)
+ *
+ * However, the right shift operator ('>>') for negative integer is
+ * "implementation defined" behavior in C (note that it's not "undefined"
+ * behavior).  So only if implementation defines '>>' as ASR, we use it.
+ */
+#if defined(__GNUC__)
+/* gcc defines '>>' as ASR. */
+#define AUDIO_SCALEDOWN(value, bits)   ((value) >> (bits))
+#else
+#define AUDIO_SCALEDOWN(value, bits)   ((value) / (1 << (bits)))
+#endif
+
 /* Device timeout in msec */
 #define AUDIO_TIMEOUT  (3000)
 
@@ -3200,11 +3222,7 @@
                for (ch = 0; ch < channels; ch++) {
                        aint2_t val;
                        val = *s++;
-#if defined(AUDIO_USE_C_IMPLEMENTATION_DEFINED_BEHAVIOR) && defined(__GNUC__)
-                       val = val * ch_volume[ch] >> 8;
-#else
-                       val = val * ch_volume[ch] / 256;
-#endif
+                       val = AUDIO_SCALEDOWN(val * ch_volume[ch], 8);
                        *d++ = (aint_t)val;
                }
        }
@@ -3226,11 +3244,7 @@
        d = arg->dst;
 
        for (i = 0; i < arg->count; i++) {
-#if defined(AUDIO_USE_C_IMPLEMENTATION_DEFINED_BEHAVIOR) && defined(__GNUC__)
-               *d++ = (s[0] >> 1) + (s[1] >> 1);
-#else
-               *d++ = (s[0] / 2) + (s[1] / 2);
-#endif
+               *d++ = AUDIO_SCALEDOWN(s[0], 1) + AUDIO_SCALEDOWN(s[1], 1);
                s += arg->srcfmt->channels;
        }
 }
@@ -5027,11 +5041,7 @@
                if (vol != 256) {
                        m = mixer->mixsample;
                        for (i = 0; i < sample_count; i++) {
-#if defined(AUDIO_USE_C_IMPLEMENTATION_DEFINED_BEHAVIOR) && defined(__GNUC__)
-                               *m = *m * vol >> 8;
-#else
-                               *m = *m * vol / 256;
-#endif
+                               *m = AUDIO_SCALEDOWN(*m * vol, 8);
                                m++;
                        }
                }
@@ -5119,11 +5129,9 @@
 #if defined(AUDIO_SUPPORT_TRACK_VOLUME)
                if (track->volume != 256) {
                        for (i = 0; i < sample_count; i++) {
-#if defined(AUDIO_USE_C_IMPLEMENTATION_DEFINED_BEHAVIOR) && defined(__GNUC__)
-                               *d++ = ((aint2_t)*s++) * track->volume >> 8;
-#else
-                               *d++ = ((aint2_t)*s++) * track->volume / 256;
-#endif
+                               aint2_t v;
+                               v = *s++;
+                               *d++ = AUDIO_SCALEDOWN(v * track->volume, 8)
                        }
                } else
 #endif
@@ -5137,11 +5145,9 @@
 #if defined(AUDIO_SUPPORT_TRACK_VOLUME)
                if (track->volume != 256) {
                        for (i = 0; i < sample_count; i++) {
-#if defined(AUDIO_USE_C_IMPLEMENTATION_DEFINED_BEHAVIOR) && defined(__GNUC__)
-                               *d++ += ((aint2_t)*s++) * track->volume >> 8;
-#else
-                               *d++ += ((aint2_t)*s++) * track->volume / 256;
-#endif
+                               aint2_t v;
+                               v = *s++;
+                               *d++ += AUDIO_SCALEDOWN(v * track->volume, 8);
                        }
                } else
 #endif
diff -r 85fe45b361a0 -r e5eb88d9e949 sys/dev/audio/audiodef.h
--- a/sys/dev/audio/audiodef.h  Mon Jun 10 13:28:08 2019 +0000
+++ b/sys/dev/audio/audiodef.h  Mon Jun 10 13:49:39 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: audiodef.h,v 1.3 2019/05/23 12:20:27 isaki Exp $       */
+/*     $NetBSD: audiodef.h,v 1.4 2019/06/10 13:49:39 isaki Exp $       */
 
 /*
  * Copyright (C) 2017 Tetsuya Isaki. All rights reserved.
@@ -63,12 +63,6 @@
  */
 /* #define AUDIO_SUPPORT_TRACK_VOLUME */
 
-/*
- * Whether use C language's "implementation defined" behavior (note that
- * it's not "undefined" behavior).  It improves performance well.
- */
-#define AUDIO_USE_C_IMPLEMENTATION_DEFINED_BEHAVIOR
-
 /* conversion stage */
 typedef struct {
        audio_ring_t srcbuf;



Home | Main Index | Thread Index | Old Index