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