^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Audio support data for mISDN_dsp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Rewritten by Peter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This software may be used and distributed according to the terms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * of the GNU General Public License, incorporated herein by reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/mISDNif.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mISDNdsp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/bitrev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "dsp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* ulaw[unsigned char] -> signed 16-bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) s32 dsp_audio_ulaw_to_s32[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* alaw[unsigned char] -> signed 16-bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) s32 dsp_audio_alaw_to_s32[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) s32 *dsp_audio_law_to_s32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) EXPORT_SYMBOL(dsp_audio_law_to_s32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* signed 16-bit -> law */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u8 dsp_audio_s16_to_law[65536];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) EXPORT_SYMBOL(dsp_audio_s16_to_law);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* alaw -> ulaw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u8 dsp_audio_alaw_to_ulaw[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* ulaw -> alaw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static u8 dsp_audio_ulaw_to_alaw[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u8 dsp_silence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /*****************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * generate table for conversion of s16 to alaw/ulaw *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *****************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define AMI_MASK 0x55
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static inline unsigned char linear2alaw(short int linear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int pcm_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int seg_end[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) pcm_val = linear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (pcm_val >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* Sign (7th) bit = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) mask = AMI_MASK | 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* Sign bit = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) mask = AMI_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) pcm_val = -pcm_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* Convert the scaled magnitude to segment number. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) for (seg = 0; seg < 8; seg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (pcm_val <= seg_end[seg])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* Combine the sign, segment, and quantization bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return ((seg << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ((pcm_val >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static inline short int alaw2linear(unsigned char alaw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) alaw ^= AMI_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) i = ((alaw & 0x0F) << 4) + 8 /* rounding error */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) seg = (((int) alaw & 0x70) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (seg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) i = (i + 0x100) << (seg - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return (short int) ((alaw & 0x80) ? i : -i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static inline short int ulaw2linear(unsigned char ulaw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) short mu, e, f, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static short etab[] = {0, 132, 396, 924, 1980, 4092, 8316, 16764};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) mu = 255 - ulaw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) e = (mu & 0x70) / 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) f = mu & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) y = f * (1 << (e + 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) y += etab[e];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (mu & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) y = -y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define BIAS 0x84 /*!< define the add-in bias for 16 bit samples */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static unsigned char linear2ulaw(short sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int exp_lut[256] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int sign, exponent, mantissa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned char ulawbyte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* Get the sample into sign-magnitude. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) sign = (sample >> 8) & 0x80; /* set aside the sign */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (sign != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) sample = -sample; /* get magnitude */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Convert from 16 bit linear to ulaw. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) sample = sample + BIAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) exponent = exp_lut[(sample >> 7) & 0xFF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) mantissa = (sample >> (exponent + 3)) & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ulawbyte = ~(sign | (exponent << 4) | mantissa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return ulawbyte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) void dsp_audio_generate_law_tables(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) for (i = 0; i < 256; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) dsp_audio_alaw_to_s32[i] = alaw2linear(bitrev8((u8)i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) for (i = 0; i < 256; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) dsp_audio_ulaw_to_s32[i] = ulaw2linear(bitrev8((u8)i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) for (i = 0; i < 256; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) dsp_audio_alaw_to_ulaw[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) linear2ulaw(dsp_audio_alaw_to_s32[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) dsp_audio_ulaw_to_alaw[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) linear2alaw(dsp_audio_ulaw_to_s32[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dsp_audio_generate_s2law_table(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (dsp_options & DSP_OPT_ULAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* generating ulaw-table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) for (i = -32768; i < 32768; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) dsp_audio_s16_to_law[i & 0xffff] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) bitrev8(linear2ulaw(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* generating alaw-table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) for (i = -32768; i < 32768; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) dsp_audio_s16_to_law[i & 0xffff] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) bitrev8(linear2alaw(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * the seven bit sample is the number of every second alaw-sample ordered by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * aplitude. 0x00 is negative, 0x7f is positive amplitude.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u8 dsp_audio_seven2law[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) u8 dsp_audio_law2seven[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /********************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * generate table for conversion law from/to 7-bit alaw-like sample *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dsp_audio_generate_seven(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int i, j, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) u8 spl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u8 sorted_alaw[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* generate alaw table, sorted by the linear value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) for (i = 0; i < 256; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) for (k = 0; k < 256; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (dsp_audio_alaw_to_s32[k]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) < dsp_audio_alaw_to_s32[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) sorted_alaw[j] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* generate tabels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) for (i = 0; i < 256; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* spl is the source: the law-sample (converted to alaw) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) spl = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (dsp_options & DSP_OPT_ULAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) spl = dsp_audio_ulaw_to_alaw[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* find the 7-bit-sample */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) for (j = 0; j < 256; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (sorted_alaw[j] == spl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* write 7-bit audio value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) dsp_audio_law2seven[i] = j >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) for (i = 0; i < 128; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) spl = sorted_alaw[i << 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (dsp_options & DSP_OPT_ULAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) spl = dsp_audio_alaw_to_ulaw[spl];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) dsp_audio_seven2law[i] = spl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* mix 2*law -> law */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) u8 dsp_audio_mix_law[65536];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /******************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * generate mix table to mix two law samples into one *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ******************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) dsp_audio_generate_mix_table(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) s32 sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) while (i < 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) while (j < 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) sample = dsp_audio_law_to_s32[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) sample += dsp_audio_law_to_s32[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) dsp_audio_mix_law[(i << 8) | j] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * generate different volume changes *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static u8 dsp_audio_reduce8[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static u8 dsp_audio_reduce7[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static u8 dsp_audio_reduce6[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static u8 dsp_audio_reduce5[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static u8 dsp_audio_reduce4[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static u8 dsp_audio_reduce3[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static u8 dsp_audio_reduce2[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static u8 dsp_audio_reduce1[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static u8 dsp_audio_increase1[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static u8 dsp_audio_increase2[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static u8 dsp_audio_increase3[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static u8 dsp_audio_increase4[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static u8 dsp_audio_increase5[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static u8 dsp_audio_increase6[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static u8 dsp_audio_increase7[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static u8 dsp_audio_increase8[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static u8 *dsp_audio_volume_change[16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) dsp_audio_reduce8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) dsp_audio_reduce7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dsp_audio_reduce6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) dsp_audio_reduce5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dsp_audio_reduce4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) dsp_audio_reduce3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) dsp_audio_reduce2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) dsp_audio_reduce1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) dsp_audio_increase1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) dsp_audio_increase2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) dsp_audio_increase3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) dsp_audio_increase4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) dsp_audio_increase5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) dsp_audio_increase6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) dsp_audio_increase7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) dsp_audio_increase8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dsp_audio_generate_volume_changes(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) register s32 sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int num[] = { 110, 125, 150, 175, 200, 300, 400, 500 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int denum[] = { 100, 100, 100, 100, 100, 100, 100, 100 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) while (i < 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) dsp_audio_reduce8[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) (dsp_audio_law_to_s32[i] * denum[7] / num[7]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dsp_audio_reduce7[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) (dsp_audio_law_to_s32[i] * denum[6] / num[6]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) dsp_audio_reduce6[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) (dsp_audio_law_to_s32[i] * denum[5] / num[5]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) dsp_audio_reduce5[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) (dsp_audio_law_to_s32[i] * denum[4] / num[4]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) dsp_audio_reduce4[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) (dsp_audio_law_to_s32[i] * denum[3] / num[3]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) dsp_audio_reduce3[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) (dsp_audio_law_to_s32[i] * denum[2] / num[2]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) dsp_audio_reduce2[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) (dsp_audio_law_to_s32[i] * denum[1] / num[1]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) dsp_audio_reduce1[i] = dsp_audio_s16_to_law[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) (dsp_audio_law_to_s32[i] * denum[0] / num[0]) & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) sample = dsp_audio_law_to_s32[i] * num[0] / denum[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dsp_audio_increase1[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) sample = dsp_audio_law_to_s32[i] * num[1] / denum[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) dsp_audio_increase2[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sample = dsp_audio_law_to_s32[i] * num[2] / denum[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) dsp_audio_increase3[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) sample = dsp_audio_law_to_s32[i] * num[3] / denum[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) dsp_audio_increase4[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) sample = dsp_audio_law_to_s32[i] * num[4] / denum[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dsp_audio_increase5[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) sample = dsp_audio_law_to_s32[i] * num[5] / denum[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) dsp_audio_increase6[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) sample = dsp_audio_law_to_s32[i] * num[6] / denum[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) dsp_audio_increase7[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) sample = dsp_audio_law_to_s32[i] * num[7] / denum[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (sample < -32768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) sample = -32768;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) else if (sample > 32767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) sample = 32767;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) dsp_audio_increase8[i] = dsp_audio_s16_to_law[sample & 0xffff];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /**************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * change the volume of the given skb *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) **************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* this is a helper function for changing volume of skb. the range may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * -8 to 8, which is a shift to the power of 2. 0 == no volume, 3 == volume*8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dsp_change_volume(struct sk_buff *skb, int volume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) u8 *volume_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int i, ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) u8 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (volume == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* get correct conversion table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (volume < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) shift = volume + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (shift < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) shift = volume + 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (shift > 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) shift = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) volume_change = dsp_audio_volume_change[shift];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ii = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) p = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* change volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) while (i < ii) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) *p = volume_change[*p];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }