Add support for more formats. At present 24 bit formats do not work and
have been disabled. Ok christos@.
This commit is contained in:
parent
81cb5fdd19
commit
53adadbf58
557
sys/dev/auconv.c
557
sys/dev/auconv.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: auconv.c,v 1.26 2017/06/01 09:44:30 pgoyette Exp $ */
|
||||
/* $NetBSD: auconv.c,v 1.27 2017/06/20 07:21:50 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.26 2017/06/01 09:44:30 pgoyette Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: auconv.c,v 1.27 2017/06/20 07:21:50 nat Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/audioio.h>
|
||||
@ -113,86 +113,216 @@ struct conv_table {
|
||||
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, \
|
||||
linear##prec##_##valid##_to_linear##target}, \
|
||||
{AUDIO_ENCODING_SLINEAR_BE, prec, valid, \
|
||||
linear##target##_##target##_to_linear##prec, \
|
||||
linear##prec##_##valid##_to_linear##target}, \
|
||||
{AUDIO_ENCODING_ULINEAR_LE, prec, valid, \
|
||||
linear##target##_##target##_to_linear##prec, \
|
||||
linear##prec##_##valid##_to_linear##target}, \
|
||||
{AUDIO_ENCODING_ULINEAR_BE, prec, valid, \
|
||||
linear##target##_##target##_to_linear##prec, \
|
||||
linear##prec##_##valid##_to_linear##target},
|
||||
#if NMULAW > 0
|
||||
#define MULAW_TABLE(prec, valid, target) \
|
||||
{AUDIO_ENCODING_ULAW, 8, 8, \
|
||||
linear##prec##_##valid##_to_mulaw, \
|
||||
mulaw_to_linear##target}, \
|
||||
{AUDIO_ENCODING_ALAW, 8, 8, \
|
||||
linear##prec##_##valid##_to_alaw, \
|
||||
alaw_to_linear##target},
|
||||
#endif
|
||||
/*
|
||||
* SLINEAR-16 or SLINEAR-24 should precede in a table because
|
||||
* aurateconv supports only SLINEAR.
|
||||
*/
|
||||
static const struct conv_table s8_table[] = {
|
||||
{AUDIO_ENCODING_SLINEAR_LE, 16, 16,
|
||||
linear8_to_linear16, linear16_to_linear8},
|
||||
{AUDIO_ENCODING_SLINEAR_BE, 16, 16,
|
||||
linear8_to_linear16, linear16_to_linear8},
|
||||
{AUDIO_ENCODING_ULINEAR_LE, 8, 8,
|
||||
change_sign8, change_sign8},
|
||||
TABLE_LIST(32, 32, 8)
|
||||
TABLE_LIST(24, 32, 8)
|
||||
TABLE_LIST(24, 24, 8)
|
||||
TABLE_LIST(16, 16, 8)
|
||||
TABLE_LIST(8, 8, 8)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(8, 8, 8)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table u8_table[] = {
|
||||
{AUDIO_ENCODING_SLINEAR_LE, 16, 16,
|
||||
linear8_to_linear16, linear16_to_linear8},
|
||||
{AUDIO_ENCODING_SLINEAR_BE, 16, 16,
|
||||
linear8_to_linear16, linear16_to_linear8},
|
||||
{AUDIO_ENCODING_SLINEAR_LE, 8, 8,
|
||||
change_sign8, change_sign8},
|
||||
{AUDIO_ENCODING_ULINEAR_LE, 16, 16,
|
||||
linear8_to_linear16, linear16_to_linear8},
|
||||
{AUDIO_ENCODING_ULINEAR_BE, 16, 16,
|
||||
linear8_to_linear16, linear16_to_linear8},
|
||||
TABLE_LIST(32, 32, 8)
|
||||
TABLE_LIST(24, 32, 8)
|
||||
TABLE_LIST(24, 24, 8)
|
||||
TABLE_LIST(16, 16, 8)
|
||||
TABLE_LIST(8, 8, 8)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(8, 8, 8)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table s16le_table[] = {
|
||||
{AUDIO_ENCODING_SLINEAR_BE, 16, 16,
|
||||
swap_bytes, swap_bytes},
|
||||
{AUDIO_ENCODING_ULINEAR_LE, 16, 16,
|
||||
change_sign16, change_sign16},
|
||||
{AUDIO_ENCODING_ULINEAR_BE, 16, 16,
|
||||
swap_bytes_change_sign16, swap_bytes_change_sign16},
|
||||
TABLE_LIST(32, 32, 16)
|
||||
TABLE_LIST(24, 32, 16)
|
||||
TABLE_LIST(24, 24, 16)
|
||||
TABLE_LIST(16, 16, 16)
|
||||
TABLE_LIST(8, 8, 16)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(16, 16, 16)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table s16be_table[] = {
|
||||
{AUDIO_ENCODING_SLINEAR_LE, 16, 16,
|
||||
swap_bytes, swap_bytes},
|
||||
{AUDIO_ENCODING_ULINEAR_BE, 16, 16,
|
||||
change_sign16, change_sign16},
|
||||
{AUDIO_ENCODING_ULINEAR_LE, 16, 16,
|
||||
swap_bytes_change_sign16, swap_bytes_change_sign16},
|
||||
TABLE_LIST(32, 32, 16)
|
||||
TABLE_LIST(24, 32, 16)
|
||||
TABLE_LIST(24, 24, 16)
|
||||
TABLE_LIST(16, 16, 16)
|
||||
TABLE_LIST(8, 8, 16)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(16, 16, 16)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table u16le_table[] = {
|
||||
{AUDIO_ENCODING_SLINEAR_LE, 16, 16,
|
||||
change_sign16, change_sign16},
|
||||
{AUDIO_ENCODING_ULINEAR_BE, 16, 16,
|
||||
swap_bytes, swap_bytes},
|
||||
{AUDIO_ENCODING_SLINEAR_BE, 16, 16,
|
||||
swap_bytes_change_sign16, swap_bytes_change_sign16},
|
||||
TABLE_LIST(32, 32, 16)
|
||||
TABLE_LIST(24, 32, 16)
|
||||
TABLE_LIST(24, 24, 16)
|
||||
TABLE_LIST(16, 16, 16)
|
||||
TABLE_LIST(8, 8, 16)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(16, 16, 16)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table u16be_table[] = {
|
||||
{AUDIO_ENCODING_SLINEAR_BE, 16, 16,
|
||||
change_sign16, change_sign16},
|
||||
{AUDIO_ENCODING_ULINEAR_LE, 16, 16,
|
||||
swap_bytes, swap_bytes},
|
||||
{AUDIO_ENCODING_SLINEAR_LE, 16, 16,
|
||||
swap_bytes_change_sign16, swap_bytes_change_sign16},
|
||||
TABLE_LIST(32, 32, 16)
|
||||
TABLE_LIST(24, 32, 16)
|
||||
TABLE_LIST(24, 24, 16)
|
||||
TABLE_LIST(16, 16, 16)
|
||||
TABLE_LIST(8, 8, 16)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(16, 16, 16)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table s24le_table[] = {
|
||||
TABLE_LIST(32, 32, 24)
|
||||
TABLE_LIST(24, 32, 24)
|
||||
TABLE_LIST(24, 24, 24)
|
||||
TABLE_LIST(16, 16, 24)
|
||||
TABLE_LIST(8, 8, 24)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(24, 24, 24)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table s24be_table[] = {
|
||||
TABLE_LIST(32, 32, 24)
|
||||
TABLE_LIST(24, 32, 24)
|
||||
TABLE_LIST(24, 24, 24)
|
||||
TABLE_LIST(16, 16, 24)
|
||||
TABLE_LIST(8, 8, 24)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(24, 24, 24)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table u24le_table[] = {
|
||||
TABLE_LIST(32, 32, 24)
|
||||
TABLE_LIST(24, 32, 24)
|
||||
TABLE_LIST(24, 24, 24)
|
||||
TABLE_LIST(16, 16, 24)
|
||||
TABLE_LIST(8, 8, 24)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(24, 24, 24)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table u24be_table[] = {
|
||||
TABLE_LIST(32, 32, 24)
|
||||
TABLE_LIST(24, 32, 24)
|
||||
TABLE_LIST(24, 24, 24)
|
||||
TABLE_LIST(16, 16, 24)
|
||||
TABLE_LIST(8, 8, 24)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(24, 24, 24)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table s32le_table[] = {
|
||||
TABLE_LIST(32, 32, 32)
|
||||
TABLE_LIST(24, 32, 32)
|
||||
TABLE_LIST(24, 24, 32)
|
||||
TABLE_LIST(16, 16, 32)
|
||||
TABLE_LIST(8, 8, 32)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(32, 32, 32)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table s32be_table[] = {
|
||||
TABLE_LIST(32, 32, 32)
|
||||
TABLE_LIST(24, 32, 32)
|
||||
TABLE_LIST(24, 24, 32)
|
||||
TABLE_LIST(16, 16, 32)
|
||||
TABLE_LIST(8, 8, 32)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(32, 32, 32)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table u32le_table[] = {
|
||||
TABLE_LIST(32, 32, 32)
|
||||
TABLE_LIST(24, 32, 32)
|
||||
TABLE_LIST(24, 24, 32)
|
||||
TABLE_LIST(16, 16, 32)
|
||||
TABLE_LIST(8, 8, 32)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(32, 32, 32)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table u32be_table[] = {
|
||||
TABLE_LIST(32, 32, 32)
|
||||
TABLE_LIST(24, 32, 32)
|
||||
TABLE_LIST(24, 24, 32)
|
||||
TABLE_LIST(16, 16, 32)
|
||||
TABLE_LIST(8, 8, 32)
|
||||
#if NMULAW > 0
|
||||
MULAW_TABLE(32, 32, 32)
|
||||
#endif
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
#if NMULAW > 0
|
||||
#define MULAW_LIST(prec, valid, target) \
|
||||
{AUDIO_ENCODING_SLINEAR_LE, prec, valid, \
|
||||
mulaw_to_linear##target, \
|
||||
linear##prec##_##valid##_to_mulaw}, \
|
||||
{AUDIO_ENCODING_SLINEAR_BE, prec, valid, \
|
||||
mulaw_to_linear##target, \
|
||||
linear##prec##_##valid##_to_mulaw}, \
|
||||
{AUDIO_ENCODING_ULINEAR_LE, prec, valid, \
|
||||
mulaw_to_linear##target, \
|
||||
linear##prec##_##valid##_to_mulaw}, \
|
||||
{AUDIO_ENCODING_ULINEAR_BE, prec, valid, \
|
||||
mulaw_to_linear##target, \
|
||||
linear##prec##_##valid##_to_mulaw},
|
||||
|
||||
#define ALAW_LIST(prec, valid, target) \
|
||||
{AUDIO_ENCODING_SLINEAR_LE, prec, valid, \
|
||||
alaw_to_linear##target, \
|
||||
linear##prec##_##valid##_to_alaw}, \
|
||||
{AUDIO_ENCODING_SLINEAR_BE, prec, valid, \
|
||||
alaw_to_linear##target, \
|
||||
linear##prec##_##valid##_to_alaw}, \
|
||||
{AUDIO_ENCODING_ULINEAR_LE, prec, valid, \
|
||||
alaw_to_linear##target, \
|
||||
linear##prec##_##valid##_to_alaw}, \
|
||||
{AUDIO_ENCODING_ULINEAR_BE, prec, valid, \
|
||||
alaw_to_linear##target, \
|
||||
linear##prec##_##valid##_to_alaw},
|
||||
|
||||
static const struct conv_table mulaw_table[] = {
|
||||
{AUDIO_ENCODING_SLINEAR_LE, 16, 16,
|
||||
mulaw_to_linear16, linear16_to_mulaw},
|
||||
{AUDIO_ENCODING_SLINEAR_BE, 16, 16,
|
||||
mulaw_to_linear16, linear16_to_mulaw},
|
||||
{AUDIO_ENCODING_ULINEAR_LE, 16, 16,
|
||||
mulaw_to_linear16, linear16_to_mulaw},
|
||||
{AUDIO_ENCODING_ULINEAR_BE, 16, 16,
|
||||
mulaw_to_linear16, linear16_to_mulaw},
|
||||
MULAW_LIST(32, 32, 32)
|
||||
MULAW_LIST(24, 32, 24)
|
||||
MULAW_LIST(24, 24, 24)
|
||||
MULAW_LIST(16, 16, 16)
|
||||
{AUDIO_ENCODING_SLINEAR_LE, 8, 8,
|
||||
mulaw_to_linear8, linear8_to_mulaw},
|
||||
{AUDIO_ENCODING_ULINEAR_LE, 8, 8,
|
||||
mulaw_to_linear8, linear8_to_mulaw},
|
||||
{0, 0, 0, NULL, NULL}};
|
||||
static const struct conv_table alaw_table[] = {
|
||||
{AUDIO_ENCODING_SLINEAR_LE, 16, 16,
|
||||
alaw_to_linear16, linear16_to_alaw},
|
||||
{AUDIO_ENCODING_SLINEAR_BE, 16, 16,
|
||||
alaw_to_linear16, linear16_to_alaw},
|
||||
{AUDIO_ENCODING_ULINEAR_LE, 16, 16,
|
||||
alaw_to_linear16, linear16_to_alaw},
|
||||
{AUDIO_ENCODING_ULINEAR_BE, 16, 16,
|
||||
alaw_to_linear16, linear16_to_alaw},
|
||||
ALAW_LIST(32, 32, 32)
|
||||
ALAW_LIST(24, 32, 24)
|
||||
ALAW_LIST(24, 24, 24)
|
||||
ALAW_LIST(16, 16, 16)
|
||||
{AUDIO_ENCODING_SLINEAR_LE, 8, 8,
|
||||
alaw_to_linear8, linear8_to_alaw},
|
||||
{AUDIO_ENCODING_ULINEAR_LE, 8, 8,
|
||||
@ -351,124 +481,193 @@ DEFINE_FILTER(swap_bytes_change_sign16)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_FILTER(linear8_to_linear16)
|
||||
{
|
||||
stream_filter_t *this;
|
||||
int m, err, enc_dst, enc_src;
|
||||
|
||||
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);
|
||||
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)) {
|
||||
/*
|
||||
* slinear8 -> slinear16_le
|
||||
* ulinear8 -> ulinear16_le
|
||||
*/
|
||||
FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
|
||||
d[0] = 0;
|
||||
d[1] = s[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)) {
|
||||
/*
|
||||
* slinear8 -> slinear16_be
|
||||
* ulinear8 -> ulinear16_be
|
||||
*/
|
||||
FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
|
||||
d[0] = s[0];
|
||||
d[1] = 0;
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
} else if ((enc_src == AUDIO_ENCODING_SLINEAR_LE
|
||||
&& enc_dst == AUDIO_ENCODING_ULINEAR_LE)
|
||||
|| (enc_src == AUDIO_ENCODING_ULINEAR_LE
|
||||
&& enc_dst == AUDIO_ENCODING_SLINEAR_LE)) {
|
||||
/*
|
||||
* slinear8 -> ulinear16_le
|
||||
* ulinear8 -> slinear16_le
|
||||
*/
|
||||
FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
|
||||
d[0] = 0;
|
||||
d[1] = s[0] ^ 0x80;
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
} else {
|
||||
/*
|
||||
* slinear8 -> ulinear16_be
|
||||
* ulinear8 -> slinear16_be
|
||||
*/
|
||||
FILTER_LOOP_PROLOGUE(this->src, 1, dst, 2, m) {
|
||||
d[0] = s[0] ^ 0x80;
|
||||
d[1] = 0;
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
}
|
||||
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) & ~1; \
|
||||
\
|
||||
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_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[--j] = s[target - i]; \
|
||||
i--; \
|
||||
} \
|
||||
} else { \
|
||||
while (j > i) \
|
||||
d[--j] = 0; \
|
||||
while (j > 0) { \
|
||||
d[--j] = s[target - i]; \
|
||||
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 = valid; \
|
||||
j = target; \
|
||||
if (j < i) { \
|
||||
while (j > 0) { \
|
||||
d[--j] = s[valid - i]; \
|
||||
i--; \
|
||||
} \
|
||||
} else { \
|
||||
while (j > 0) { \
|
||||
d[--j] = s[valid - i]; \
|
||||
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 = valid; \
|
||||
j = target; \
|
||||
if (j < i) { \
|
||||
while (j > 0) { \
|
||||
d[--j] = s[valid - i]; \
|
||||
i--; \
|
||||
} \
|
||||
} else { \
|
||||
while (j > 0) { \
|
||||
d[--j] = s[valid - i]; \
|
||||
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_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 = valid; \
|
||||
j = target; \
|
||||
if (j < i) { \
|
||||
while (j > 0) { \
|
||||
d[target - j] = s[target - j]; \
|
||||
j--; \
|
||||
} \
|
||||
} else { \
|
||||
while (i > 0) { \
|
||||
d[target - j] = s[target - j]; \
|
||||
j--; \
|
||||
i--; \
|
||||
} \
|
||||
while (j > 0) \
|
||||
d[target - 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(linear16_to_linear8)
|
||||
{
|
||||
stream_filter_t *this;
|
||||
int m, err, enc_src, enc_dst;
|
||||
|
||||
this = (stream_filter_t *)self;
|
||||
if ((err = this->prev->fetch_to(sc, this->prev, this->src, max_used * 2)))
|
||||
return err;
|
||||
m = dst->end - dst->start;
|
||||
m = min(m, max_used);
|
||||
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)) {
|
||||
/*
|
||||
* slinear16_le -> slinear8
|
||||
* ulinear16_le -> ulinear8
|
||||
*/
|
||||
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
|
||||
d[0] = s[1];
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
} else if ((enc_src == AUDIO_ENCODING_SLINEAR_LE
|
||||
&& enc_dst == AUDIO_ENCODING_ULINEAR_LE)
|
||||
|| (enc_src == AUDIO_ENCODING_ULINEAR_LE
|
||||
&& enc_dst == AUDIO_ENCODING_SLINEAR_LE)) {
|
||||
/*
|
||||
* slinear16_le -> ulinear8
|
||||
* ulinear16_le -> slinear8
|
||||
*/
|
||||
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
|
||||
d[0] = s[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)) {
|
||||
/*
|
||||
* slinear16_be -> slinear8
|
||||
* ulinear16_be -> ulinear8
|
||||
*/
|
||||
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
|
||||
d[0] = s[0];
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
} else {
|
||||
/*
|
||||
* slinear16_be -> ulinear8
|
||||
* ulinear16_be -> slinear8
|
||||
*/
|
||||
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
|
||||
d[0] = s[0] ^ 0x80;
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
LINEARN_LINEAR(32, 32, 32);
|
||||
LINEARN_LINEAR(32, 32, 24);
|
||||
LINEARN_LINEAR(32, 32, 16);
|
||||
LINEARN_LINEAR(32, 32, 8);
|
||||
LINEARN_LINEAR(24, 32, 32);
|
||||
LINEARN_LINEAR(24, 32, 24);
|
||||
LINEARN_LINEAR(24, 32, 16);
|
||||
LINEARN_LINEAR(24, 32, 8);
|
||||
LINEARN_LINEAR(24, 24, 32);
|
||||
LINEARN_LINEAR(24, 24, 24);
|
||||
LINEARN_LINEAR(24, 24, 16);
|
||||
LINEARN_LINEAR(24, 24, 8);
|
||||
LINEARN_LINEAR(16, 16, 32);
|
||||
LINEARN_LINEAR(16, 16, 24);
|
||||
LINEARN_LINEAR(16, 16, 16);
|
||||
LINEARN_LINEAR(16, 16, 8);
|
||||
LINEARN_LINEAR(8, 8, 32);
|
||||
LINEARN_LINEAR(8, 8, 24);
|
||||
LINEARN_LINEAR(8, 8, 16);
|
||||
LINEARN_LINEAR(8, 8, 8);
|
||||
|
||||
/**
|
||||
* Set appropriate parameters in `param,' and return the index in
|
||||
@ -531,24 +730,32 @@ auconv_set_converter(const struct audio_format *formats, int nformats,
|
||||
table = s8_table;
|
||||
else if (param->precision == 16)
|
||||
table = s16le_table;
|
||||
else if (param->precision == 32)
|
||||
table = s32le_table;
|
||||
break;
|
||||
case AUDIO_ENCODING_SLINEAR_BE:
|
||||
if (param->precision == 8)
|
||||
table = s8_table;
|
||||
else if (param->precision == 16)
|
||||
table = s16be_table;
|
||||
else if (param->precision == 32)
|
||||
table = s32be_table;
|
||||
break;
|
||||
case AUDIO_ENCODING_ULINEAR_LE:
|
||||
if (param->precision == 8)
|
||||
table = u8_table;
|
||||
else if (param->precision == 16)
|
||||
table = u16le_table;
|
||||
else if (param->precision == 32)
|
||||
table = u32le_table;
|
||||
break;
|
||||
case AUDIO_ENCODING_ULINEAR_BE:
|
||||
if (param->precision == 8)
|
||||
table = u8_table;
|
||||
else if (param->precision == 16)
|
||||
table = u16be_table;
|
||||
else if (param->precision == 32)
|
||||
table = u32be_table;
|
||||
break;
|
||||
#if NMULAW > 0
|
||||
case AUDIO_ENCODING_ULAW:
|
||||
@ -620,7 +827,7 @@ auconv_rateconv_supportable(u_int encoding, u_int precision, u_int validbits)
|
||||
if (encoding != AUDIO_ENCODING_SLINEAR_LE
|
||||
&& encoding != AUDIO_ENCODING_SLINEAR_BE)
|
||||
return false;
|
||||
if (precision != 16 && precision != 24 && precision != 32)
|
||||
if (precision != 8 && precision != 16 && precision != 24 && precision != 32)
|
||||
return false;
|
||||
if (precision < validbits)
|
||||
return false;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: auconv.h,v 1.16 2011/11/23 23:07:31 jmcneill Exp $ */
|
||||
/* $NetBSD: auconv.h,v 1.17 2017/06/20 07:21:50 nat Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||
@ -62,8 +62,30 @@ extern stream_filter_factory_t change_sign16;
|
||||
extern stream_filter_factory_t swap_bytes;
|
||||
extern stream_filter_factory_t swap_bytes_change_sign16;
|
||||
/* Byte expansion/contraction */
|
||||
extern stream_filter_factory_t linear8_to_linear16;
|
||||
extern stream_filter_factory_t linear16_to_linear8;
|
||||
extern stream_filter_factory_t linear32_32_to_linear32;
|
||||
extern stream_filter_factory_t linear32_32_to_linear24;
|
||||
extern stream_filter_factory_t linear32_32_to_linear16;
|
||||
extern stream_filter_factory_t linear32_32_to_linear8;
|
||||
extern stream_filter_factory_t linear24_32_to_linear32;
|
||||
extern stream_filter_factory_t linear24_32_to_linear24;
|
||||
extern stream_filter_factory_t linear24_32_to_linear16;
|
||||
extern stream_filter_factory_t linear24_32_to_linear8;
|
||||
extern stream_filter_factory_t linear24_24_to_linear32;
|
||||
extern stream_filter_factory_t linear24_24_to_linear24;
|
||||
extern stream_filter_factory_t linear24_24_to_linear16;
|
||||
extern stream_filter_factory_t linear24_24_to_linear8;
|
||||
extern stream_filter_factory_t linear16_16_to_linear32;
|
||||
extern stream_filter_factory_t linear16_16_to_linear24;
|
||||
extern stream_filter_factory_t linear16_16_to_linear16;
|
||||
extern stream_filter_factory_t linear16_16_to_linear8;
|
||||
extern stream_filter_factory_t linear8_8_to_linear32;
|
||||
extern stream_filter_factory_t linear8_8_to_linear24;
|
||||
extern stream_filter_factory_t linear8_8_to_linear16;
|
||||
extern stream_filter_factory_t linear8_8_to_linear8;
|
||||
|
||||
#define linear16_to_linear8 linear_16_16_to_linear8
|
||||
#define linear8_to_linear16 linear_8_8_to_linear16
|
||||
|
||||
/* sampling rate conversion (aurateconv.c) */
|
||||
extern stream_filter_factory_t aurateconv;
|
||||
|
||||
|
362
sys/dev/mulaw.c
362
sys/dev/mulaw.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mulaw.c,v 1.28 2011/11/23 23:07:31 jmcneill Exp $ */
|
||||
/* $NetBSD: mulaw.c,v 1.29 2017/06/20 07:21:50 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.28 2011/11/23 23:07:31 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mulaw.c,v 1.29 2017/06/20 07:21:50 nat Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
@ -295,80 +295,117 @@ DEFINE_FILTER(mulaw_to_linear8)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_FILTER(mulaw_to_linear16)
|
||||
{
|
||||
stream_filter_t *this;
|
||||
int m, err;
|
||||
#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 = hw - 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 = hw - 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; \
|
||||
}
|
||||
|
||||
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[0] = mulawtolin16[s[0]][1];
|
||||
d[1] = mulawtolin16[s[0]][0];
|
||||
} 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[0] = mulawtolin16[s[0]][1];
|
||||
d[1] = mulawtolin16[s[0]][0] ^ 0x80;
|
||||
} 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;
|
||||
}
|
||||
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(linear16_to_mulaw)
|
||||
{
|
||||
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 * 2)))
|
||||
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, 2, dst, 1, m) {
|
||||
d[0] = lintomulaw[s[1] ^ 0x80];
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
break;
|
||||
case AUDIO_ENCODING_SLINEAR_BE:
|
||||
FILTER_LOOP_PROLOGUE(this->src, 2, 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, 2, dst, 1, m) {
|
||||
d[0] = lintomulaw[s[1]];
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
break;
|
||||
case AUDIO_ENCODING_ULINEAR_BE:
|
||||
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
|
||||
d[0] = lintomulaw[s[0]];
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
LINEARNTOMULAW(32, 32)
|
||||
LINEARNTOMULAW(24, 32)
|
||||
LINEARNTOMULAW(24, 24)
|
||||
LINEARNTOMULAW(16, 16)
|
||||
|
||||
DEFINE_FILTER(linear8_to_mulaw)
|
||||
{
|
||||
@ -414,46 +451,70 @@ DEFINE_FILTER(alaw_to_linear8)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_FILTER(alaw_to_linear16)
|
||||
{
|
||||
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 / 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[0] = alawtolin16[s[0]][1];
|
||||
d[1] = alawtolin16[s[0]][0];
|
||||
} 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[0] = alawtolin16[s[0]][1];
|
||||
d[1] = alawtolin16[s[0]][0] ^ 0x80;
|
||||
} 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;
|
||||
}
|
||||
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 = hw - 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 = hw - 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; \
|
||||
}
|
||||
|
||||
ALAWTOLINEARN(32)
|
||||
ALAWTOLINEARN(24)
|
||||
ALAWTOLINEARN(16)
|
||||
|
||||
DEFINE_FILTER(linear8_to_alaw)
|
||||
{
|
||||
stream_filter_t *this;
|
||||
@ -476,37 +537,50 @@ DEFINE_FILTER(linear8_to_alaw)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_FILTER(linear16_to_alaw)
|
||||
{
|
||||
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 * 2)))
|
||||
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, 2, dst, 1, m) {
|
||||
d[0] = lintoalaw[s[1] ^ 0x80];
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
break;
|
||||
case AUDIO_ENCODING_SLINEAR_BE:
|
||||
FILTER_LOOP_PROLOGUE(this->src, 2, 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, 2, dst, 1, m) {
|
||||
d[0] = lintoalaw[s[1]];
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
break;
|
||||
case AUDIO_ENCODING_ULINEAR_BE:
|
||||
FILTER_LOOP_PROLOGUE(this->src, 2, dst, 1, m) {
|
||||
d[0] = lintoalaw[s[0]];
|
||||
} FILTER_LOOP_EPILOGUE(this->src, dst);
|
||||
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; \
|
||||
}
|
||||
|
||||
LINEARNTOALAW(32, 32)
|
||||
LINEARNTOALAW(24, 32)
|
||||
LINEARNTOALAW(24, 24)
|
||||
LINEARNTOALAW(16, 16)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: mulaw.h,v 1.20 2008/04/28 20:23:47 martin Exp $ */
|
||||
/* $NetBSD: mulaw.h,v 1.21 2017/06/20 07:21:50 nat Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||
@ -33,17 +33,36 @@
|
||||
#define _SYS_DEV_MULAW_H_
|
||||
#include <dev/audio_if.h>
|
||||
|
||||
/* Convert 8-bit mu-law to/from 32 bit unsigned/signed linear. */
|
||||
extern stream_filter_factory_t mulaw_to_linear32;
|
||||
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;
|
||||
/* 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_to_mulaw;
|
||||
extern stream_filter_factory_t linear16_16_to_mulaw;
|
||||
#define linear16_to_mulaw linear_16_16_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_to_mulaw;
|
||||
/* Convert 8-bit A-law to/from 16 bit unsigned/signed linear. */
|
||||
#define linear8_8_to_mulaw linear8_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;
|
||||
/* 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;
|
||||
/* 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_to_alaw;
|
||||
extern stream_filter_factory_t linear16_16_to_alaw;
|
||||
#define linear16_to_alaw linear_16_16_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
|
||||
|
||||
#endif /* _SYS_DEV_MULAW_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user