Source-Changes-HG archive

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

[src/trunk]: src/sys/dev Replace LINEARN_TO_LINEARN macro with individual opt...



details:   https://anonhg.NetBSD.org/src/rev/87089343d56d
branches:  trunk
changeset: 828496:87089343d56d
user:      nat <nat%NetBSD.org@localhost>
date:      Sat Dec 16 16:09:36 2017 +0000

description:
Replace LINEARN_TO_LINEARN macro with individual optimized functions for
8, 16, 24 and 32 bits linear to linear conversions.

Addresses PR kern/52586.

diffstat:

 sys/dev/auconv.c |  1609 ++++++++++++++++++++++++++++++++++++++++++++++-------
 sys/dev/auconv.h |    13 +-
 2 files changed, 1397 insertions(+), 225 deletions(-)

diffs (truncated from 1677 to 300 lines):

diff -r 2c08e92854f4 -r 87089343d56d sys/dev/auconv.c
--- a/sys/dev/auconv.c  Sat Dec 16 16:04:20 2017 +0000
+++ b/sys/dev/auconv.c  Sat Dec 16 16:09:36 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: auconv.c,v 1.34 2017/11/07 01:15:42 nat Exp $  */
+/*     $NetBSD: auconv.c,v 1.35 2017/12/16 16:09:36 nat Exp $  */
 
 /*
  * Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: auconv.c,v 1.34 2017/11/07 01:15:42 nat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: auconv.c,v 1.35 2017/12/16 16:09:36 nat Exp $");
 
 #include <sys/types.h>
 #include <sys/audioio.h>
@@ -113,6 +113,7 @@
        stream_filter_factory_t *play_conv;
        stream_filter_factory_t *rec_conv;
 };
+
 #define TABLE_LIST(prec, valid, target)                                \
        {AUDIO_ENCODING_SLINEAR_LE, prec, valid,                        \
         linear##target##_##target##_to_linear##prec,                   \
@@ -485,225 +486,1395 @@
        return 0;
 }
 
-#define LINEARN_LINEAR(n_prec, n_validbits, t_prec)                    \
-       DEFINE_FILTER(linear##n_prec##_##n_validbits##_to_linear##t_prec)\
-{                                                                      \
-       stream_filter_t *this;                                          \
-       int m, err, enc_dst, enc_src;                                   \
-       int target, valid, hw, i, j;                                    \
-                                                                       \
-       hw = n_prec / NBBY;                                             \
-       valid = n_validbits / NBBY;                                     \
-       target = t_prec / NBBY;                                         \
-       this = (stream_filter_t *)self;                                 \
-       max_used = ((max_used / hw) * hw);                              \
-                                                                       \
-       if ((err = this->prev->fetch_to(sc, this->prev, this->src,      \
-                       max_used)))                                     \
-               return err;                                             \
-       m = (((dst->end - dst->start) / target) * target) & ~1;         \
-       m = min(m, max_used * hw / target);                             \
-       enc_dst = dst->param.encoding;                                  \
-       enc_src = this->src->param.encoding;                            \
-       if ((enc_src == AUDIO_ENCODING_SLINEAR_LE                       \
-            && enc_dst == AUDIO_ENCODING_SLINEAR_LE)                   \
-           || (enc_src == AUDIO_ENCODING_ULINEAR_LE                    \
-               && enc_dst == AUDIO_ENCODING_ULINEAR_LE)) {             \
-               /*                                                      \
-                * slinearNle -> slinearNle                             \
-                * ulinearNle -> ulinearNle                             \
-                */                                                     \
-               FILTER_LOOP_PROLOGUE(this->src, hw, dst, target, m) {   \
-                       i = valid;                                      \
-                       j = target;                                     \
-                       if (j < i) {                                    \
-                               while (j > 0)                           \
-                                       d[--j] = s[--i];                \
-                       } else {                                        \
-                               while (i > 0)                           \
-                                       d[--j] = s[--i];                \
-                               while (j > 0)                           \
-                                       d[--j] = 0;                     \
-                       }                                               \
-               } FILTER_LOOP_EPILOGUE(this->src, dst);                 \
-       } else if ((enc_src == AUDIO_ENCODING_SLINEAR_BE                \
-            && enc_dst == AUDIO_ENCODING_SLINEAR_BE)                   \
-           || (enc_src == AUDIO_ENCODING_ULINEAR_BE                    \
-               && enc_dst == AUDIO_ENCODING_ULINEAR_BE)) {             \
-               /*                                                      \
-                * slinearNbe -> slinearNbe                             \
-                * ulinearNbe -> ulinearNbe                             \
-                */                                                     \
-               FILTER_LOOP_PROLOGUE(this->src, hw, dst, target, m) {   \
-                       i = valid;                                      \
-                       j = target;                                     \
-                       if (j < i) {                                    \
-                               j = 0;                                  \
-                               while (j < target)                      \
-                                       d[j++] = s[i++];                \
-                       } else {                                        \
-                               j = 0;                                  \
-                               i = 0;                                  \
-                               while (i < valid)                       \
-                                       d[j++] = s[i++];                \
-                               while (j < target)                      \
-                                       d[j++] = 0;                     \
-                       }                                               \
-               } FILTER_LOOP_EPILOGUE(this->src, dst);                 \
-       } else if ((enc_src == AUDIO_ENCODING_SLINEAR_LE                \
-                   && enc_dst == AUDIO_ENCODING_SLINEAR_BE)            \
-                  || (enc_src == AUDIO_ENCODING_ULINEAR_LE             \
-                      && enc_dst == AUDIO_ENCODING_ULINEAR_BE)) {      \
-               /*                                                      \
-                * slinearNle -> slinearNbe                             \
-                * ulinearNle -> ulinearNbe                             \
-                */                                                     \
-               FILTER_LOOP_PROLOGUE(this->src, hw, dst, target, m) {   \
-                       i = valid;                                      \
-                       j = target;                                     \
-                       if (j < i) {                                    \
-                               while (j > 0) {                         \
-                                       d[target - j] = s[--i];         \
-                                       j--;                            \
-                               }                                       \
-                       } else {                                        \
-                               while (j > i)                           \
-                                       d[--j] = 0;                     \
-                               j = 0;                                  \
-                               while (i > 0) {                         \
-                                       d[j++] = s[--i];                \
-                               }                                       \
-                       }                                               \
-               } FILTER_LOOP_EPILOGUE(this->src, dst);                 \
-       } else if ((enc_src == AUDIO_ENCODING_ULINEAR_BE                \
-                   && enc_dst == AUDIO_ENCODING_SLINEAR_LE)            \
-                  || (enc_src == AUDIO_ENCODING_SLINEAR_BE             \
-                      && enc_dst == AUDIO_ENCODING_ULINEAR_LE)) {      \
-               /*                                                      \
-                * ulinearNbe -> slinearNle                             \
-                * slinearNbe -> ulinearNle                             \
-                */                                                     \
-               FILTER_LOOP_PROLOGUE(this->src, hw, dst, target, m) {   \
-                       i = 0;                                          \
-                       j = target;                                     \
-                       if (target < valid) {                           \
-                               while (j > 0)                           \
-                                       d[--j] = s[i++];                \
-                       } else {                                        \
-                               while (i < valid)                       \
-                                       d[--j] = s[i++];                \
-                               while (j > 0)                           \
-                                       d[--j] = 0;                     \
-                       }                                               \
-                       d[target - 1] ^= 0x80;                          \
-               } FILTER_LOOP_EPILOGUE(this->src, dst);                 \
-       } else if ((enc_src == AUDIO_ENCODING_SLINEAR_BE                \
-                   && enc_dst == AUDIO_ENCODING_SLINEAR_LE)            \
-                  || (enc_src == AUDIO_ENCODING_ULINEAR_BE             \
-                      && enc_dst == AUDIO_ENCODING_ULINEAR_LE)) {      \
-               /*                                                      \
-                * slinearNbe -> slinearNle                             \
-                * ulinearNbe -> ulinearNle                             \
-                */                                                     \
-               FILTER_LOOP_PROLOGUE(this->src, hw, dst, target, m) {   \
-                       i = 0;                                          \
-                       j = target;                                     \
-                       if (target < valid) {                           \
-                               while (j > 0)                           \
-                                       d[--j] = s[i++];                \
-                       } else {                                        \
-                               while (i < valid)                       \
-                                       d[--j] = s[i++];                \
-                               while (j > 0)                           \
-                                       d[--j] = 0;                     \
-                       }                                               \
-               } FILTER_LOOP_EPILOGUE(this->src, dst);                 \
-       } else if ((enc_src == AUDIO_ENCODING_SLINEAR_LE                \
-                   && enc_dst == AUDIO_ENCODING_ULINEAR_BE)            \
-                  || (enc_src == AUDIO_ENCODING_ULINEAR_LE             \
-                      && enc_dst == AUDIO_ENCODING_SLINEAR_BE)) {      \
-               /*                                                      \
-                * slinearNle -> ulinearNbe                             \
-                * ulinearNle -> slinearNbe                             \
-                */                                                     \
-               FILTER_LOOP_PROLOGUE(this->src, hw, dst, target, m) {   \
-                       i = valid;                                      \
-                       j = target;                                     \
-                       if (j < i) {                                    \
-                               j = 0;                                  \
-                               while (j < target) {                    \
-                                       d[j++] = s[i--];                \
-                               }                                       \
-                       } else {                                        \
-                               j = 0;                                  \
-                               while (i > 0)                           \
-                                       d[j++] = s[--i];                \
-                               while (j < target)                      \
-                                       d[j++] = 0;                     \
-                       }                                               \
-                       d[0] ^= 0x80;                                   \
-               } FILTER_LOOP_EPILOGUE(this->src, dst);                 \
-       } else if ((enc_src == AUDIO_ENCODING_SLINEAR_BE                \
-                   && enc_dst == AUDIO_ENCODING_ULINEAR_BE)            \
-                  || (enc_src == AUDIO_ENCODING_ULINEAR_BE             \
-                      && enc_dst == AUDIO_ENCODING_SLINEAR_BE)) {      \
-               /*                                                      \
-                * slinearNbe -> ulinearNbe                             \
-                * ulinearNbe -> slinearNbe                             \
-                */                                                     \
-               FILTER_LOOP_PROLOGUE(this->src, hw, dst, target, m) {   \
-                       i = 0;                                          \
-                       j = 0;                                          \
-                       if (target < valid) {                           \
-                               while (j < target)                      \
-                                       d[j++] = s[i++];                \
-                       } else {                                        \
-                               while (i < valid)                       \
-                                       d[j++] = s[i++];                \
-                               while (j < target)                      \
-                                       d[j++] = 0;                     \
-                       }                                               \
-                       d[0] ^= 0x80;                                   \
-               } FILTER_LOOP_EPILOGUE(this->src, dst);                 \
-       } else {                                                        \
-               /*                                                      \
-                * slinearNle -> ulinearNle                             \
-                * ulinearNle -> slinearNle                             \
-                */                                                     \
-               FILTER_LOOP_PROLOGUE(this->src, hw, dst, target, m) {   \
-                       i = valid;                                      \
-                       j = target;                                     \
-                       if (j < i) {                                    \
-                               while (j > 0)                           \
-                                       d[--j] = s[--i];                \
-                       } else {                                        \
-                               while (i > 0)                           \
-                                       d[--j] = s[--i];                \
-                               while (j > 0)                           \
-                                       d[--j] = 0;                     \
-                       }                                               \
-                       d[target - 1] ^= 0x80;                          \
-               } FILTER_LOOP_EPILOGUE(this->src, dst);                 \
-       }                                                               \
-       return 0;                                                       \
+DEFINE_FILTER(linear8_8_to_linear32)
+{
+       stream_filter_t *this;
+       int m, err, enc_dst, enc_src;
+
+       this = (stream_filter_t *)self;
+
+       if ((err = this->prev->fetch_to(sc, this->prev, this->src, max_used)))
+               return err;
+       m = (dst->end - dst->start) & ~3;
+       m = min(m, max_used / 4);
+       enc_dst = dst->param.encoding;
+       enc_src = this->src->param.encoding;
+       if ((enc_src == AUDIO_ENCODING_SLINEAR_LE
+               && enc_dst == AUDIO_ENCODING_SLINEAR_LE)
+           || (enc_src == AUDIO_ENCODING_ULINEAR_LE
+               && enc_dst == AUDIO_ENCODING_ULINEAR_LE)
+           || (enc_src == AUDIO_ENCODING_SLINEAR_BE
+               && enc_dst == AUDIO_ENCODING_SLINEAR_LE)
+           || (enc_src == AUDIO_ENCODING_ULINEAR_BE
+               && enc_dst == AUDIO_ENCODING_ULINEAR_LE)) {
+               /*
+                * slinear8be -> slinear32le
+                * ulinear8be -> ulinear32le
+                *
+                * slinear8le -> slinear32le
+                * ulinear8le -> ulinear32le
+                */
+               FILTER_LOOP_PROLOGUE(this->src, 1, dst, 4, m) {
+                       d[3] = s[0];
+                       d[2] = 0;
+                       d[1] = 0;
+                       d[0] = 0;
+               } FILTER_LOOP_EPILOGUE(this->src, dst);
+       } else if ((enc_src == AUDIO_ENCODING_SLINEAR_BE
+                      && enc_dst == AUDIO_ENCODING_SLINEAR_BE)
+                  || (enc_src == AUDIO_ENCODING_ULINEAR_BE
+                      && enc_dst == AUDIO_ENCODING_ULINEAR_BE)
+                  || (enc_src == AUDIO_ENCODING_SLINEAR_LE
+                      && enc_dst == AUDIO_ENCODING_SLINEAR_BE)
+                  || (enc_src == AUDIO_ENCODING_ULINEAR_LE
+                      && enc_dst == AUDIO_ENCODING_ULINEAR_BE)) {
+               /*
+                * slinear8le -> slinear32be
+                * ulinear8le -> ulinear32be
+                *
+                * slinear8be -> slinear32be
+                * ulinear8be -> ulinear32be
+                */
+               FILTER_LOOP_PROLOGUE(this->src, 1, dst, 4, m) {
+                       d[3] = 0;
+                       d[2] = 0;
+                       d[1] = 0;
+                       d[0] = s[0];
+               } FILTER_LOOP_EPILOGUE(this->src, dst);
+       } else if ((enc_src == AUDIO_ENCODING_SLINEAR_LE
+                      && enc_dst == AUDIO_ENCODING_ULINEAR_BE)
+                  || (enc_src == AUDIO_ENCODING_ULINEAR_LE
+                      && enc_dst == AUDIO_ENCODING_SLINEAR_BE)
+                  || (enc_src == AUDIO_ENCODING_SLINEAR_BE
+                      && enc_dst == AUDIO_ENCODING_ULINEAR_BE)
+                  || (enc_src == AUDIO_ENCODING_ULINEAR_BE
+                      && enc_dst == AUDIO_ENCODING_SLINEAR_BE)) {
+               /*
+                * slinear8be -> ulinear32be
+                * ulinear8be -> slinear32be
+                *
+                * slinear8le -> ulinear32be
+                * ulinear8le -> slinear32be



Home | Main Index | Thread Index | Old Index