Home | History | Annotate | Line # | Download | only in audio
      1  1.6  andvar /*	$NetBSD: mulaw.c,v 1.6 2024/02/02 22:39:10 andvar Exp $	*/
      2  1.2   isaki 
      3  1.2   isaki /*
      4  1.2   isaki  * Copyright (C) 2017 Tetsuya Isaki. All rights reserved.
      5  1.2   isaki  * Copyright (C) 2017 Y.Sugahara (moveccr). All rights reserved.
      6  1.2   isaki  *
      7  1.2   isaki  * Redistribution and use in source and binary forms, with or without
      8  1.2   isaki  * modification, are permitted provided that the following conditions
      9  1.2   isaki  * are met:
     10  1.2   isaki  * 1. Redistributions of source code must retain the above copyright
     11  1.2   isaki  *    notice, this list of conditions and the following disclaimer.
     12  1.2   isaki  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.2   isaki  *    notice, this list of conditions and the following disclaimer in the
     14  1.2   isaki  *    documentation and/or other materials provided with the distribution.
     15  1.2   isaki  *
     16  1.2   isaki  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  1.2   isaki  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  1.2   isaki  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  1.2   isaki  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  1.2   isaki  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  1.2   isaki  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22  1.2   isaki  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  1.2   isaki  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  1.2   isaki  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  1.2   isaki  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  1.2   isaki  * SUCH DAMAGE.
     27  1.2   isaki  */
     28  1.2   isaki 
     29  1.2   isaki #include <sys/cdefs.h>
     30  1.6  andvar __KERNEL_RCSID(0, "$NetBSD: mulaw.c,v 1.6 2024/02/02 22:39:10 andvar Exp $");
     31  1.2   isaki 
     32  1.5   skrll #include <sys/param.h>
     33  1.2   isaki #include <sys/types.h>
     34  1.2   isaki #include <sys/systm.h>
     35  1.2   isaki #include <sys/device.h>
     36  1.2   isaki #include <dev/audio/audiovar.h>
     37  1.2   isaki #include <dev/audio/mulaw.h>
     38  1.2   isaki 
     39  1.2   isaki /*
     40  1.2   isaki  * audio_internal_to_mulaw has two implementations.
     41  1.2   isaki  *
     42  1.2   isaki  * 1. Use 8bit table (MULAW_LQ_ENC)
     43  1.2   isaki  *  It's traditional implementation and its precision is 8bit.
     44  1.2   isaki  *  It's faster but the size is larger.  And you can hear a little noise
     45  1.2   isaki  *  in silent part.
     46  1.2   isaki  *
     47  1.2   isaki  * 2. Calculation (default)
     48  1.2   isaki  *  It calculates mu-law with full spec and its precision is 14bit.
     49  1.4   isaki  *  It's about 3 times slower but the size is less than a half (on m68k,
     50  1.2   isaki  *  for example).
     51  1.2   isaki  *
     52  1.2   isaki  * mu-law is no longer a popular format.  I think size-optimized is better.
     53  1.2   isaki  */
     54  1.2   isaki /* #define MULAW_LQ_ENC */
     55  1.2   isaki 
     56  1.2   isaki /*
     57  1.2   isaki  * About mulaw32 format.
     58  1.2   isaki  *
     59  1.2   isaki  * The format which I call ``mulaw32'' is only used in dev/tc/bba.c .
     60  1.6  andvar  * It is 8bit mu-law but 16bit left-shifted and its container is 32bit.
     61  1.2   isaki  * Not mu-law calculated in 32bit.
     62  1.2   isaki  *
     63  1.2   isaki  * When MULAW32 is not defined (it's default), this file outputs
     64  1.2   isaki  * audio_internal_to_mulaw() and audio_mulaw_to_internal().  When
     65  1.2   isaki  * MULAW32 is defined, this file outputs audio_internal_to_mulaw32()
     66  1.2   isaki  * and audio_mulaw32_to_internal() instead.
     67  1.2   isaki  *
     68  1.2   isaki  * Since mu-law is used as userland format and is mandatory, all audio
     69  1.2   isaki  * drivers (including tc/bba) link this mulaw.c in ordinary procedure.
     70  1.2   isaki  * On the other hand, only tc/bba also needs audio_internal_to_mulaw32()
     71  1.2   isaki  * and audio_mulaw32_to_internal() as its hardware drivers codec, so
     72  1.2   isaki  * define MULAW32 and include this file.  It's a bit tricky but I think
     73  1.2   isaki  * this is the simplest way.
     74  1.2   isaki  */
     75  1.2   isaki 
     76  1.2   isaki #if 0
     77  1.2   isaki #define MPRINTF(fmt, ...)	printf(fmt, ## __VA_ARGS__)
     78  1.2   isaki #else
     79  1.2   isaki #define MPRINTF(fmt, ...)	/**/
     80  1.2   isaki #endif
     81  1.2   isaki 
     82  1.2   isaki static const int16_t mulaw_to_slinear16[256] = {
     83  1.2   isaki 	0x8284, 0x8684, 0x8a84, 0x8e84, 0x9284, 0x9684, 0x9a84, 0x9e84,
     84  1.2   isaki 	0xa284, 0xa684, 0xaa84, 0xae84, 0xb284, 0xb684, 0xba84, 0xbe84,
     85  1.2   isaki 	0xc184, 0xc384, 0xc584, 0xc784, 0xc984, 0xcb84, 0xcd84, 0xcf84,
     86  1.2   isaki 	0xd184, 0xd384, 0xd584, 0xd784, 0xd984, 0xdb84, 0xdd84, 0xdf84,
     87  1.2   isaki 	0xe104, 0xe204, 0xe304, 0xe404, 0xe504, 0xe604, 0xe704, 0xe804,
     88  1.2   isaki 	0xe904, 0xea04, 0xeb04, 0xec04, 0xed04, 0xee04, 0xef04, 0xf004,
     89  1.2   isaki 	0xf0c4, 0xf144, 0xf1c4, 0xf244, 0xf2c4, 0xf344, 0xf3c4, 0xf444,
     90  1.2   isaki 	0xf4c4, 0xf544, 0xf5c4, 0xf644, 0xf6c4, 0xf744, 0xf7c4, 0xf844,
     91  1.2   isaki 	0xf8a4, 0xf8e4, 0xf924, 0xf964, 0xf9a4, 0xf9e4, 0xfa24, 0xfa64,
     92  1.2   isaki 	0xfaa4, 0xfae4, 0xfb24, 0xfb64, 0xfba4, 0xfbe4, 0xfc24, 0xfc64,
     93  1.2   isaki 	0xfc94, 0xfcb4, 0xfcd4, 0xfcf4, 0xfd14, 0xfd34, 0xfd54, 0xfd74,
     94  1.2   isaki 	0xfd94, 0xfdb4, 0xfdd4, 0xfdf4, 0xfe14, 0xfe34, 0xfe54, 0xfe74,
     95  1.2   isaki 	0xfe8c, 0xfe9c, 0xfeac, 0xfebc, 0xfecc, 0xfedc, 0xfeec, 0xfefc,
     96  1.2   isaki 	0xff0c, 0xff1c, 0xff2c, 0xff3c, 0xff4c, 0xff5c, 0xff6c, 0xff7c,
     97  1.2   isaki 	0xff88, 0xff90, 0xff98, 0xffa0, 0xffa8, 0xffb0, 0xffb8, 0xffc0,
     98  1.2   isaki 	0xffc8, 0xffd0, 0xffd8, 0xffe0, 0xffe8, 0xfff0, 0xfff8, 0xfffc,
     99  1.2   isaki 	0x7d7c, 0x797c, 0x757c, 0x717c, 0x6d7c, 0x697c, 0x657c, 0x617c,
    100  1.2   isaki 	0x5d7c, 0x597c, 0x557c, 0x517c, 0x4d7c, 0x497c, 0x457c, 0x417c,
    101  1.2   isaki 	0x3e7c, 0x3c7c, 0x3a7c, 0x387c, 0x367c, 0x347c, 0x327c, 0x307c,
    102  1.2   isaki 	0x2e7c, 0x2c7c, 0x2a7c, 0x287c, 0x267c, 0x247c, 0x227c, 0x207c,
    103  1.2   isaki 	0x1efc, 0x1dfc, 0x1cfc, 0x1bfc, 0x1afc, 0x19fc, 0x18fc, 0x17fc,
    104  1.2   isaki 	0x16fc, 0x15fc, 0x14fc, 0x13fc, 0x12fc, 0x11fc, 0x10fc, 0x0ffc,
    105  1.2   isaki 	0x0f3c, 0x0ebc, 0x0e3c, 0x0dbc, 0x0d3c, 0x0cbc, 0x0c3c, 0x0bbc,
    106  1.2   isaki 	0x0b3c, 0x0abc, 0x0a3c, 0x09bc, 0x093c, 0x08bc, 0x083c, 0x07bc,
    107  1.2   isaki 	0x075c, 0x071c, 0x06dc, 0x069c, 0x065c, 0x061c, 0x05dc, 0x059c,
    108  1.2   isaki 	0x055c, 0x051c, 0x04dc, 0x049c, 0x045c, 0x041c, 0x03dc, 0x039c,
    109  1.2   isaki 	0x036c, 0x034c, 0x032c, 0x030c, 0x02ec, 0x02cc, 0x02ac, 0x028c,
    110  1.2   isaki 	0x026c, 0x024c, 0x022c, 0x020c, 0x01ec, 0x01cc, 0x01ac, 0x018c,
    111  1.2   isaki 	0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104,
    112  1.2   isaki 	0x00f4, 0x00e4, 0x00d4, 0x00c4, 0x00b4, 0x00a4, 0x0094, 0x0084,
    113  1.2   isaki 	0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040,
    114  1.2   isaki 	0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000,
    115  1.2   isaki };
    116  1.2   isaki 
    117  1.2   isaki #if defined(MULAW_LQ_ENC)
    118  1.2   isaki static const uint8_t slinear8_to_mulaw[256] = {
    119  1.2   isaki 	0xff, 0xe7, 0xdb, 0xd3, 0xcd, 0xc9, 0xc5, 0xc1,
    120  1.2   isaki 	0xbe, 0xbc, 0xba, 0xb8, 0xb6, 0xb4, 0xb2, 0xb0,
    121  1.2   isaki 	0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,
    122  1.2   isaki 	0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
    123  1.2   isaki 	0x9f, 0x9f, 0x9e, 0x9e, 0x9d, 0x9d, 0x9c, 0x9c,
    124  1.2   isaki 	0x9b, 0x9b, 0x9a, 0x9a, 0x99, 0x99, 0x98, 0x98,
    125  1.2   isaki 	0x97, 0x97, 0x96, 0x96, 0x95, 0x95, 0x94, 0x94,
    126  1.2   isaki 	0x93, 0x93, 0x92, 0x92, 0x91, 0x91, 0x90, 0x90,
    127  1.2   isaki 	0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e,
    128  1.2   isaki 	0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c,
    129  1.2   isaki 	0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a,
    130  1.2   isaki 	0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88,
    131  1.2   isaki 	0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86,
    132  1.2   isaki 	0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84,
    133  1.2   isaki 	0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
    134  1.2   isaki 	0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80,
    135  1.2   isaki 	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
    136  1.2   isaki 	0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
    137  1.2   isaki 	0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05,
    138  1.2   isaki 	0x05, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07,
    139  1.2   isaki 	0x07, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
    140  1.2   isaki 	0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b,
    141  1.2   isaki 	0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d,
    142  1.2   isaki 	0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f,
    143  1.2   isaki 	0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13,
    144  1.2   isaki 	0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16, 0x17,
    145  1.2   isaki 	0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b,
    146  1.2   isaki 	0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f,
    147  1.2   isaki 	0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
    148  1.2   isaki 	0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
    149  1.2   isaki 	0x2f, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c,
    150  1.2   isaki 	0x3e, 0x41, 0x45, 0x49, 0x4d, 0x53, 0x5b, 0x67,
    151  1.2   isaki };
    152  1.2   isaki #endif
    153  1.2   isaki 
    154  1.2   isaki /*
    155  1.2   isaki  * audio_mulaw_to_internal:
    156  1.2   isaki  *	This filter performs conversion from mu-law to internal format.
    157  1.2   isaki  *
    158  1.2   isaki  * audio_mulaw32_to_internal:
    159  1.2   isaki  *	This filter performs conversion from mulaw32 used only in tc/bba.c
    160  1.2   isaki  *	to internal format.
    161  1.2   isaki  */
    162  1.2   isaki void
    163  1.2   isaki #if !defined(MULAW32)
    164  1.2   isaki audio_mulaw_to_internal(audio_filter_arg_t *arg)
    165  1.2   isaki #else
    166  1.2   isaki audio_mulaw32_to_internal(audio_filter_arg_t *arg)
    167  1.2   isaki #endif
    168  1.2   isaki {
    169  1.2   isaki #if defined(MULAW32)
    170  1.2   isaki 	const uint32_t *s;
    171  1.2   isaki #else
    172  1.2   isaki 	const uint8_t *s;
    173  1.2   isaki #endif
    174  1.2   isaki 	aint_t *d;
    175  1.2   isaki 	u_int sample_count;
    176  1.2   isaki 	u_int i;
    177  1.2   isaki 
    178  1.2   isaki 	DIAGNOSTIC_filter_arg(arg);
    179  1.2   isaki #if !defined(MULAW32)
    180  1.2   isaki 	KASSERT(arg->srcfmt->encoding == AUDIO_ENCODING_ULAW);
    181  1.2   isaki 	KASSERT(arg->srcfmt->stride == 8);
    182  1.2   isaki 	KASSERT(arg->srcfmt->precision == 8);
    183  1.2   isaki #endif
    184  1.2   isaki 	KASSERT(audio_format2_is_internal(arg->dstfmt));
    185  1.2   isaki 	KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
    186  1.2   isaki 
    187  1.2   isaki 	s = arg->src;
    188  1.2   isaki 	d = arg->dst;
    189  1.2   isaki 	sample_count = arg->count * arg->srcfmt->channels;
    190  1.2   isaki 
    191  1.2   isaki 	for (i = 0; i < sample_count; i++) {
    192  1.2   isaki 		aint_t val;
    193  1.2   isaki 		uint m;
    194  1.2   isaki 		m = *s++;
    195  1.2   isaki #if defined(MULAW32)
    196  1.2   isaki 		/* 32bit container used only in tc/bba.c */
    197  1.2   isaki 		m = (m >> 16) & 0xff;
    198  1.2   isaki #endif
    199  1.2   isaki 		val = mulaw_to_slinear16[m];
    200  1.2   isaki 		val <<= AUDIO_INTERNAL_BITS - 16;
    201  1.2   isaki 		*d++ = val;
    202  1.2   isaki 	}
    203  1.2   isaki }
    204  1.2   isaki 
    205  1.2   isaki /*
    206  1.2   isaki  * audio_internal_to_mulaw:
    207  1.2   isaki  *	This filter performs conversion from internal format to mu-law.
    208  1.2   isaki  *
    209  1.2   isaki  * audio_internal_to_mulaw32:
    210  1.2   isaki  *	This filter performs conversion from internal format to mulaw32
    211  1.2   isaki  *	used only in tc/bba.c.
    212  1.2   isaki  */
    213  1.2   isaki void
    214  1.2   isaki #if !defined(MULAW32)
    215  1.2   isaki audio_internal_to_mulaw(audio_filter_arg_t *arg)
    216  1.2   isaki #else
    217  1.2   isaki audio_internal_to_mulaw32(audio_filter_arg_t *arg)
    218  1.2   isaki #endif
    219  1.2   isaki {
    220  1.2   isaki 	const aint_t *s;
    221  1.2   isaki #if defined(MULAW32)
    222  1.2   isaki 	uint32_t *d;
    223  1.2   isaki #else
    224  1.2   isaki 	uint8_t *d;
    225  1.2   isaki #endif
    226  1.2   isaki 	u_int sample_count;
    227  1.2   isaki 	u_int i;
    228  1.2   isaki 
    229  1.2   isaki 	DIAGNOSTIC_filter_arg(arg);
    230  1.2   isaki #if !defined(MULAW32)
    231  1.2   isaki 	KASSERT(arg->dstfmt->encoding == AUDIO_ENCODING_ULAW);
    232  1.2   isaki 	KASSERT(arg->dstfmt->stride == 8);
    233  1.2   isaki 	KASSERT(arg->dstfmt->precision == 8);
    234  1.2   isaki #endif
    235  1.2   isaki 	KASSERT(audio_format2_is_internal(arg->srcfmt));
    236  1.2   isaki 	KASSERT(arg->srcfmt->channels == arg->dstfmt->channels);
    237  1.2   isaki 
    238  1.2   isaki 	s = arg->src;
    239  1.2   isaki 	d = arg->dst;
    240  1.2   isaki 	sample_count = arg->count * arg->srcfmt->channels;
    241  1.2   isaki 
    242  1.2   isaki 	for (i = 0; i < sample_count; i++) {
    243  1.2   isaki 		uint8_t m;
    244  1.2   isaki #if defined(MULAW_LQ_ENC)
    245  1.2   isaki 		/* 8bit (low quality, fast but fat) encoder */
    246  1.2   isaki 		uint8_t val;
    247  1.2   isaki 		val = (*s++) >> (AUDIO_INTERNAL_BITS - 8);
    248  1.2   isaki 		m = slinear8_to_mulaw[val];
    249  1.2   isaki #else
    250  1.2   isaki 		/* 14bit (fullspec, slow but small) encoder */
    251  1.4   isaki 		uint16_t val;
    252  1.2   isaki 		int c;
    253  1.2   isaki 
    254  1.4   isaki 		val = *s++ >> (AUDIO_INTERNAL_BITS - 16);
    255  1.4   isaki 		if ((int16_t)val < 0) {
    256  1.2   isaki 			m = 0;
    257  1.2   isaki 		} else {
    258  1.2   isaki 			val = ~val;
    259  1.2   isaki 			m = 0x80;
    260  1.2   isaki 		}
    261  1.2   isaki 		/* limit */
    262  1.4   isaki 		if ((int16_t)val < -8158 * 4)
    263  1.2   isaki 			val = -8158 * 4;
    264  1.2   isaki 		val -= 33 * 4;	/* bias */
    265  1.2   isaki 
    266  1.4   isaki 		// Before(1)         Before(2)         Before(3)
    267  1.4   isaki 		// S0MMMMxx_xxxxxxxx 0MMMMxxx_xxxxxxx0 c=0,v=0MMMMxxx_xxxxxxx0
    268  1.4   isaki 		// S10MMMMx_xxxxxxxx 10MMMMxx_xxxxxxx0 c=1,v=0MMMMxxx_xxxxxx00
    269  1.4   isaki 		// S110MMMM_xxxxxxxx 110MMMMx_xxxxxxx0 c=2,v=0MMMMxxx_xxxxx000
    270  1.4   isaki 		// :                 :                 :
    271  1.4   isaki 		// S1111110_MMMMxxxx 1111110M_MMMxxxx0 c=6,v=0MMMMxxx_x0000000
    272  1.2   isaki 
    273  1.4   isaki 		// (1) Push out sign bit
    274  1.2   isaki 		val <<= 1;
    275  1.2   isaki 
    276  1.4   isaki 		// (2) Find first zero (and align val to left)
    277  1.4   isaki 		c = 0;
    278  1.4   isaki 		if (val >= 0xf000) c += 4, val <<= 4;
    279  1.4   isaki 		if (val >= 0xc000) c += 2, val <<= 2;
    280  1.4   isaki 		if (val >= 0x8000) c += 1, val <<= 1;
    281  1.4   isaki 
    282  1.4   isaki 		// (3)
    283  1.4   isaki 		m += (c << 4);
    284  1.4   isaki 		m += (val >> 11) & 0x0f;
    285  1.2   isaki #endif
    286  1.2   isaki 
    287  1.2   isaki #if defined(MULAW32)
    288  1.2   isaki 		/* 8bit mu-law in 32bit container used only in tc/bba.c */
    289  1.2   isaki 		*d++ = m << 16;
    290  1.2   isaki #else
    291  1.2   isaki 		*d++ = m;
    292  1.2   isaki #endif
    293  1.2   isaki 	}
    294  1.2   isaki }
    295