Module Name: src Committed By: nat Date: Wed Dec 27 00:12:06 UTC 2017
Modified Files: src/sys/dev: mulaw.c mulaw.h Log Message: mulaw/alaw_to_linearN macros replaced with individual faster filters. NFC. To generate a diff of this commit: cvs rdiff -u -r1.32 -r1.33 src/sys/dev/mulaw.c cvs rdiff -u -r1.24 -r1.25 src/sys/dev/mulaw.h 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/mulaw.c diff -u src/sys/dev/mulaw.c:1.32 src/sys/dev/mulaw.c:1.33 --- src/sys/dev/mulaw.c:1.32 Mon Jun 26 12:17:09 2017 +++ src/sys/dev/mulaw.c Wed Dec 27 00:12:06 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mulaw.c,v 1.32 2017/06/26 12:17:09 nat Exp $ */ +/* $NetBSD: mulaw.c,v 1.33 2017/12/27 00:12:06 nat Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mulaw.c,v 1.32 2017/06/26 12:17:09 nat Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mulaw.c,v 1.33 2017/12/27 00:12:06 nat Exp $"); #include <sys/types.h> #include <sys/systm.h> @@ -295,118 +295,197 @@ DEFINE_FILTER(mulaw_to_linear8) return 0; } -#define MULAWTOLINEARN(n_prec) \ -DEFINE_FILTER(mulaw_to_linear##n_prec) \ -{ \ - stream_filter_t *this; \ - int hw, j, m, err; \ - \ - hw = n_prec / NBBY; \ - this = (stream_filter_t *)self; \ - max_used = (max_used + 1) & ~1; /* round up to even */ \ - if ((err = this->prev->fetch_to(sc, this->prev, \ - this->src, max_used / hw))) \ - return err; \ - m = (dst->end - dst->start) & ~1; \ - m = min(m, max_used); \ - switch (dst->param.encoding) { \ - case AUDIO_ENCODING_ULINEAR_LE: \ - FILTER_LOOP_PROLOGUE(this->src, 1, dst, hw, m) { \ - j = hw - 2; \ - d[hw - 2] = mulawtolin16[s[0]][1]; \ - d[hw - 1] = mulawtolin16[s[0]][0]; \ - while (j > 0) \ - d[--j] = 0; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_ULINEAR_BE: \ - FILTER_LOOP_PROLOGUE(this->src, 1, dst, hw, m) { \ - j = 2; \ - d[0] = mulawtolin16[s[0]][0]; \ - d[1] = mulawtolin16[s[0]][1]; \ - while (j < hw) \ - d[j++] = 0; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_SLINEAR_LE: \ - FILTER_LOOP_PROLOGUE(this->src, 1, dst, hw, m) { \ - j = hw - 2; \ - d[hw - 2] = mulawtolin16[s[0]][1]; \ - d[hw - 1] = mulawtolin16[s[0]][0] ^ 0x80; \ - while (j > 0) \ - d[--j] = 0; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_SLINEAR_BE: \ - FILTER_LOOP_PROLOGUE(this->src, 1, dst, hw, m) { \ - j = 2; \ - d[0] = mulawtolin16[s[0]][0] ^ 0x80; \ - d[1] = mulawtolin16[s[0]][1]; \ - while (j < hw) \ - d[j++] = 0; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - default: \ - aprint_error( \ - "%s: encoding must be [s/u]linear_[le/be]\n", \ - __func__); \ - break; \ - } \ - return 0; \ +DEFINE_FILTER(mulaw_to_linear16) +{ + stream_filter_t *this; + int m, err; + + this = (stream_filter_t *)self; + max_used = (max_used + 1) & ~1; + if ((err = this->prev->fetch_to(sc, this->prev, + this->src, max_used / 2))) + return err; + m = (dst->end - dst->start) & ~1; + m = min(m, max_used); + switch (dst->param.encoding) { + case AUDIO_ENCODING_ULINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) { + d[1] = mulawtolin16[s[0]][0]; + d[0] = mulawtolin16[s[0]][1]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_ULINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) { + d[0] = mulawtolin16[s[0]][0]; + d[1] = mulawtolin16[s[0]][1]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) { + d[1] = mulawtolin16[s[0]][0] ^ 0x80; + d[0] = mulawtolin16[s[0]][1]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) { + d[0] = mulawtolin16[s[0]][0] ^ 0x80; + d[1] = mulawtolin16[s[0]][1]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + default: + aprint_error( + "%s: encoding must be [s/u]linear_[le/be]\n", + __func__); + break; + } + return 0; } -MULAWTOLINEARN(32) -MULAWTOLINEARN(24) -MULAWTOLINEARN(16) - -#define LINEARNTOMULAW(n_prec, n_valid) \ -DEFINE_FILTER(linear##n_prec##_##n_valid##_to_mulaw) \ -{ \ - stream_filter_t *this; \ - int hw, m, err; \ - \ - hw = n_prec / NBBY; \ - this = (stream_filter_t *)self; \ - if ((err = this->prev->fetch_to(sc, this->prev, this->src, \ - max_used * hw))) \ - return err; \ - m = dst->end - dst->start; \ - m = min(m, max_used); \ - switch (this->src->param.encoding) { \ - case AUDIO_ENCODING_SLINEAR_LE: \ - FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { \ - d[0] = lintomulaw[s[hw - 1] ^ 0x80]; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_SLINEAR_BE: \ - FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { \ - d[0] = lintomulaw[s[0] ^ 0x80]; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_ULINEAR_LE: \ - FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { \ - d[0] = lintomulaw[s[hw - 1]]; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_ULINEAR_BE: \ - FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { \ - d[0] = lintomulaw[s[0]]; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - default: \ - aprint_error( \ - "%s: encoding must be [s/u]linear_[le/be]\n", \ - __func__); \ - break; \ - } \ - return 0; \ -} +DEFINE_FILTER(mulaw_to_linear24) +{ + stream_filter_t *this; + int m, err; + + this = (stream_filter_t *)self; + max_used = (max_used + 1) & ~1; + if ((err = this->prev->fetch_to(sc, this->prev, + this->src, max_used / 3))) + return err; + m = (dst->end - dst->start) & ~1; + m = min(m, max_used); + switch (dst->param.encoding) { + case AUDIO_ENCODING_ULINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 3, m) { + d[2] = mulawtolin16[s[0]][0]; + d[1] = mulawtolin16[s[0]][1]; + d[0] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_ULINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 3, m) { + d[0] = mulawtolin16[s[0]][0]; + d[1] = mulawtolin16[s[0]][1]; + d[2] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 3, m) { + d[2] = mulawtolin16[s[0]][0] ^ 0x80; + d[1] = mulawtolin16[s[0]][1]; + d[0] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 3, m) { + d[0] = mulawtolin16[s[0]][0] ^ 0x80; + d[1] = mulawtolin16[s[0]][1]; + d[2] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + default: + aprint_error( + "%s: encoding must be [s/u]linear_[le/be]\n", + __func__); + break; + } + return 0; +} + +DEFINE_FILTER(mulaw_to_linear32) +{ + stream_filter_t *this; + int m, err; + + this = (stream_filter_t *)self; + max_used = (max_used + 1) & ~1; + if ((err = this->prev->fetch_to(sc, this->prev, + this->src, max_used / 4))) + return err; + m = (dst->end - dst->start) & ~1; + m = min(m, max_used); + switch (dst->param.encoding) { + case AUDIO_ENCODING_ULINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 4, m) { + d[3] = mulawtolin16[s[0]][0]; + d[2] = mulawtolin16[s[0]][1]; + d[1] = 0; + d[0] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_ULINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 4, m) { + d[0] = mulawtolin16[s[0]][0]; + d[1] = mulawtolin16[s[0]][1]; + d[2] = 0; + d[3] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 4, m) { + d[3] = mulawtolin16[s[0]][0] ^ 0x80; + d[2] = mulawtolin16[s[0]][1]; + d[1] = 0; + d[0] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 4, m) { + d[0] = mulawtolin16[s[0]][0] ^ 0x80; + d[1] = mulawtolin16[s[0]][1]; + d[2] = 0; + d[3] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + default: + aprint_error( + "%s: encoding must be [s/u]linear_[le/be]\n", + __func__); + break; + } + return 0; +} + +DEFINE_FILTER(linearN_to_mulaw) +{ + stream_filter_t *this; + int hw, m, err; -LINEARNTOMULAW(32, 32) -LINEARNTOMULAW(24, 32) -LINEARNTOMULAW(24, 24) -LINEARNTOMULAW(16, 16) -LINEARNTOMULAW(8, 8) + this = (stream_filter_t *)self; + hw = this->src->param.precision / NBBY; + if ((err = this->prev->fetch_to(sc, this->prev, this->src, + max_used * hw))) + return err; + m = dst->end - dst->start; + m = min(m, max_used); + switch (this->src->param.encoding) { + case AUDIO_ENCODING_SLINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { + d[0] = lintomulaw[s[hw - 1] ^ 0x80]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { + d[0] = lintomulaw[s[0] ^ 0x80]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_ULINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { + d[0] = lintomulaw[s[hw - 1]]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_ULINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { + d[0] = lintomulaw[s[0]]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + default: + aprint_error( + "%s: encoding must be [s/u]linear_[le/be]n", + __func__); + break; + } + return 0; +} DEFINE_FILTER(alaw_to_linear8) { @@ -430,136 +509,194 @@ DEFINE_FILTER(alaw_to_linear8) return 0; } -#define ALAWTOLINEARN(n_prec) \ -DEFINE_FILTER(alaw_to_linear##n_prec) \ -{ \ - stream_filter_t *this; \ - int hw, j, m, err; \ - \ - hw = n_prec / NBBY; \ - this = (stream_filter_t *)self; \ - max_used = (max_used + 1) & ~1; /* round up to even */ \ - if ((err = this->prev->fetch_to(sc, this->prev, this->src, \ - max_used / hw))) \ - return err; \ - m = (dst->end - dst->start) & ~1; \ - m = min(m, max_used); \ - switch (dst->param.encoding) { \ - case AUDIO_ENCODING_ULINEAR_LE: \ - FILTER_LOOP_PROLOGUE(this->src, 1, dst, hw, m) { \ - j = hw - 2; \ - d[hw - 2] = alawtolin16[s[0]][1]; \ - d[hw - 1] = alawtolin16[s[0]][0]; \ - while (j > 0) \ - d[--j] = 0; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_ULINEAR_BE: \ - FILTER_LOOP_PROLOGUE(this->src, 1, dst, hw, m) { \ - j = 2; \ - d[0] = alawtolin16[s[0]][0]; \ - d[1] = alawtolin16[s[0]][1]; \ - while (j < hw) \ - d[j++] = 0; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_SLINEAR_LE: \ - FILTER_LOOP_PROLOGUE(this->src, 1, dst, hw, m) { \ - j = hw - 2; \ - d[hw - 2] = alawtolin16[s[0]][1]; \ - d[hw - 1] = alawtolin16[s[0]][0] ^ 0x80; \ - while (j > 0) \ - d[--j] = 0; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_SLINEAR_BE: \ - FILTER_LOOP_PROLOGUE(this->src, 1, dst, hw, m) { \ - j = 2; \ - d[0] = alawtolin16[s[0]][0] ^ 0x80; \ - d[1] = alawtolin16[s[0]][1]; \ - while (j < hw) \ - d[j++] = 0; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - default: \ - aprint_error( \ - "%s: encoding must be [s/u]linear_[le/be]\n", \ - __func__); \ - break; \ - } \ - return 0; \ -} +DEFINE_FILTER(alaw_to_linear16) +{ + stream_filter_t *this; + int m, err; -ALAWTOLINEARN(32) -ALAWTOLINEARN(24) -ALAWTOLINEARN(16) + this = (stream_filter_t *)self; + max_used = (max_used + 1) & ~1; /* round up to even */ + if ((err = this->prev->fetch_to(sc, this->prev, this->src, + max_used / 2))) + return err; + m = (dst->end - dst->start) & ~1; + m = min(m, max_used); + switch (dst->param.encoding) { + case AUDIO_ENCODING_ULINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) { + d[1] = alawtolin16[s[0]][0]; + d[0] = alawtolin16[s[0]][1]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_ULINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) { + d[0] = alawtolin16[s[0]][0]; + d[1] = alawtolin16[s[0]][1]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) { + d[1] = alawtolin16[s[0]][0] ^ 0x80; + d[0] = alawtolin16[s[0]][1]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) { + d[0] = alawtolin16[s[0]][0] ^ 0x80; + d[1] = alawtolin16[s[0]][1]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + default: + aprint_error( + "%s: encoding must be [s/u]linear_[le/be]\n", + __func__); + break; + } + return 0; +} -DEFINE_FILTER(linear8_to_alaw) +DEFINE_FILTER(alaw_to_linear24) { stream_filter_t *this; int m, err; this = (stream_filter_t *)self; - if ((err = this->prev->fetch_to(sc, this->prev, this->src, max_used))) + max_used = (max_used + 1) & ~1; /* round up to even */ + if ((err = this->prev->fetch_to(sc, this->prev, this->src, + max_used / 3))) return err; - m = dst->end - dst->start; + m = (dst->end - dst->start) & ~1; m = min(m, max_used); - if (this->src->param.encoding == AUDIO_ENCODING_ULINEAR_LE) { - FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) { - *d = lintoalaw[*s]; + switch (dst->param.encoding) { + case AUDIO_ENCODING_ULINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 3, m) { + d[2] = alawtolin16[s[0]][0]; + d[1] = alawtolin16[s[0]][1]; + d[0] = 0; } FILTER_LOOP_EPILOGUE(this->src, dst); - } else { /* SLINEAR_LE */ - FILTER_LOOP_PROLOGUE(this->src, 1, dst, 1, m) { - *d = lintoalaw[*s ^ 0x80]; + break; + case AUDIO_ENCODING_ULINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 3, m) { + d[0] = alawtolin16[s[0]][0]; + d[1] = alawtolin16[s[0]][1]; + d[2] = 0; } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 3, m) { + d[2] = alawtolin16[s[0]][0] ^ 0x80; + d[1] = alawtolin16[s[0]][1]; + d[0] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 3, m) { + d[0] = alawtolin16[s[0]][0] ^ 0x80; + d[1] = alawtolin16[s[0]][1]; + d[2] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + default: + aprint_error( + "%s: encoding must be [s/u]linear_[le/be]\n", + __func__); + break; } return 0; } -#define LINEARNTOALAW(n_prec, n_valid) \ -DEFINE_FILTER(linear##n_prec##_##n_valid##_to_alaw) \ -{ \ - stream_filter_t *this; \ - int hw, m, err; \ - \ - hw = n_prec / NBBY; \ - this = (stream_filter_t *)self; \ - if ((err = this->prev->fetch_to(sc, this->prev, this->src, \ - max_used * hw))) \ - return err; \ - m = dst->end - dst->start; \ - m = min(m, max_used); \ - switch (this->src->param.encoding) { \ - case AUDIO_ENCODING_SLINEAR_LE: \ - FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { \ - d[0] = lintoalaw[s[hw - 1] ^ 0x80]; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_SLINEAR_BE: \ - FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { \ - d[0] = lintoalaw[s[0] ^ 0x80]; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_ULINEAR_LE: \ - FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { \ - d[0] = lintoalaw[s[hw - 1]]; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - case AUDIO_ENCODING_ULINEAR_BE: \ - FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { \ - d[0] = lintoalaw[s[0]]; \ - } FILTER_LOOP_EPILOGUE(this->src, dst); \ - break; \ - default: \ - aprint_error( \ - "%s: encoding must be [s/u]linear_[le/be]\n", \ - __func__); \ - break; \ - } \ - return 0; \ +DEFINE_FILTER(alaw_to_linear32) +{ + stream_filter_t *this; + int m, err; + + this = (stream_filter_t *)self; + max_used = (max_used + 1) & ~1; /* round up to even */ + if ((err = this->prev->fetch_to(sc, this->prev, this->src, + max_used / 4))) + return err; + m = (dst->end - dst->start) & ~1; + m = min(m, max_used); + switch (dst->param.encoding) { + case AUDIO_ENCODING_ULINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 4, m) { + d[3] = alawtolin16[s[0]][0]; + d[2] = alawtolin16[s[0]][1]; + d[1] = 0; + d[0] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_ULINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 4, m) { + d[0] = alawtolin16[s[0]][0]; + d[1] = alawtolin16[s[0]][1]; + d[2] = 0; + d[3] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 4, m) { + d[3] = alawtolin16[s[0]][0] ^ 0x80; + d[2] = alawtolin16[s[0]][1]; + d[1] = 0; + d[0] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, 1, dst, 4, m) { + d[0] = alawtolin16[s[0]][0] ^ 0x80; + d[1] = alawtolin16[s[0]][1]; + d[2] = 0; + d[3] = 0; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + default: + aprint_error( + "%s: encoding must be [s/u]linear_[le/be]\n", + __func__); + break; + } + return 0; } -LINEARNTOALAW(32, 32) -LINEARNTOALAW(24, 32) -LINEARNTOALAW(24, 24) -LINEARNTOALAW(16, 16) +DEFINE_FILTER(linearN_to_alaw) +{ + stream_filter_t *this; + int hw, m, err; + + this = (stream_filter_t *)self; + hw = this->src->param.precision / NBBY; + if ((err = this->prev->fetch_to(sc, this->prev, this->src, + max_used * hw))) + return err; + m = dst->end - dst->start; + m = min(m, max_used); + switch (this->src->param.encoding) { + case AUDIO_ENCODING_SLINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { + d[0] = lintoalaw[s[hw - 1] ^ 0x80]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_SLINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { + d[0] = lintoalaw[s[0] ^ 0x80]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_ULINEAR_LE: + FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { + d[0] = lintoalaw[s[hw - 1]]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + case AUDIO_ENCODING_ULINEAR_BE: + FILTER_LOOP_PROLOGUE(this->src, hw, dst, 1, m) { + d[0] = lintoalaw[s[0]]; + } FILTER_LOOP_EPILOGUE(this->src, dst); + break; + default: + aprint_error( + "%s: encoding must be [s/u]linear_[le/be]\n", + __func__); + break; + } + return 0; +} Index: src/sys/dev/mulaw.h diff -u src/sys/dev/mulaw.h:1.24 src/sys/dev/mulaw.h:1.25 --- src/sys/dev/mulaw.h:1.24 Sun Jun 25 02:16:41 2017 +++ src/sys/dev/mulaw.h Wed Dec 27 00:12:06 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mulaw.h,v 1.24 2017/06/25 02:16:41 nat Exp $ */ +/* $NetBSD: mulaw.h,v 1.25 2017/12/27 00:12:06 nat Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -35,34 +35,35 @@ /* Convert 8-bit mu-law to/from 32 bit unsigned/signed linear. */ extern stream_filter_factory_t mulaw_to_linear32; +#define linear32_32_to_mulaw linearN_to_mulaw extern stream_filter_factory_t linear32_32_to_mulaw; /* Convert 8-bit mu-law to/from 24 bit unsigned/signed linear. */ extern stream_filter_factory_t mulaw_to_linear24; -extern stream_filter_factory_t linear24_24_to_mulaw; -extern stream_filter_factory_t linear24_32_to_mulaw; +#define linear24_24_to_mulaw linearN_to_mulaw /* Convert 8-bit mu-law to/from 16 bit unsigned/signed linear. */ extern stream_filter_factory_t mulaw_to_linear16; -extern stream_filter_factory_t linear16_16_to_mulaw; -#define linear16_to_mulaw linear16_16_to_mulaw +#define linear16_16_to_mulaw linearN_to_mulaw +#define linear16_to_mulaw linearN_to_mulaw /* Convert 8-bit mu-law to/from 8 bit unsigned/signed linear. */ extern stream_filter_factory_t mulaw_to_linear8; -extern stream_filter_factory_t linear8_8_to_mulaw; -#define linear8_to_mulaw linear8_8_to_mulaw +#define linear8_8_to_mulaw linearN_to_mulaw +#define linear8_to_mulaw linearN_to_mulaw +extern stream_filter_factory_t linearN_to_mulaw; /* Convert 8-bit alaw to/from 32 bit unsigned/signed linear. */ extern stream_filter_factory_t alaw_to_linear32; -extern stream_filter_factory_t linear32_32_to_alaw; +#define linear32_32_to_alaw linearN_to_alaw /* Convert 8-bit alaw to/from 24 bit unsigned/signed linear. */ extern stream_filter_factory_t alaw_to_linear24; -extern stream_filter_factory_t linear24_24_to_alaw; -extern stream_filter_factory_t linear24_32_to_alaw; +#define linear24_24_to_alaw linearN_to_alaw /* Convert 8-bit alaw to/from 16 bit unsigned/signed linear. */ extern stream_filter_factory_t alaw_to_linear16; -extern stream_filter_factory_t linear16_16_to_alaw; -#define linear16_to_alaw linear16_16_to_alaw +#define linear16_to_alaw linearN_to_alaw +#define linear16_16_to_alaw linearN_to_alaw /* Convert 8-bit A-law to/from 8 bit unsigned/signed linear. */ extern stream_filter_factory_t alaw_to_linear8; -extern stream_filter_factory_t linear8_to_alaw; -#define linear8_8_to_alaw linear8_to_alaw +#define linear8_8_to_alaw linearN_to_alaw +#define linear8_to_alaw linearN_to_alaw +extern stream_filter_factory_t linearN_to_alaw; #endif /* _SYS_DEV_MULAW_H_ */