12024
+ ��膩��� 1 /*
+ ��膩��� 2 * PCM - A-Law conversion
+ ��膩��� 3 * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
+ ��膩��� 4 *
+ ��膩��� 5 * Wrapper for linphone Codec class by Simon Morlat <simon.morlat@free.fr>
+ ��膩��� 6 */
+ ��膩��� 7
+ ��膩��� 8 static inline int val_seg(int val)
+ ��膩��� 9 {
+ ��膩��� 10 int r = 0;
+ ��膩��� 11 val >>= 7;
+ ��膩��� 12 if (val & 0xf0) {
+ ��膩��� 13 val >>= 4;
+ ��膩��� 14 r += 4;
+ ��膩��� 15 }
+ ��膩��� 16 if (val & 0x0c) {
+ ��膩��� 17 val >>= 2;
+ ��膩��� 18 r += 2;
+ ��膩��� 19 }
+ ��膩��� 20 if (val & 0x02)
+ ��膩��� 21 r += 1;
+ ��膩��� 22 return r;
+ ��膩��� 23 }
+ ��膩��� 24
+ ��膩��� 25 /*
+ ��膩��� 26 * s16_to_alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
+ ��膩��� 27 *
+ ��膩��� 28 * s16_to_alaw() accepts an 16-bit integer and encodes it as A-law data.
+ ��膩��� 29 *
+ ��膩��� 30 * Linear Input Code Compressed Code
+ ��膩��� 31 * ------------------------ ---------------
+ ��膩��� 32 * 0000000wxyza 000wxyz
+ ��膩��� 33 * 0000001wxyza 001wxyz
+ ��膩��� 34 * 000001wxyzab 010wxyz
+ ��膩��� 35 * 00001wxyzabc 011wxyz
+ ��膩��� 36 * 0001wxyzabcd 100wxyz
+ ��膩��� 37 * 001wxyzabcde 101wxyz
+ ��膩��� 38 * 01wxyzabcdef 110wxyz
+ ��膩��� 39 * 1wxyzabcdefg 111wxyz
+ ��膩��� 40 *
+ ��膩��� 41 * For further information see John C. Bellamy's Digital Telephony, 1982,
+ ��膩��� 42 * John Wiley & Sons, pps 98-111 and 472-476.
+ ��膩��� 43 */
+ ��膩��� 44
+ ��膩��� 45 static inline unsigned char s16_to_alaw(int pcm_val)
+ ��膩��� 46 {
+ ��膩��� 47 int mask;
+ ��膩��� 48 int seg;
+ ��膩��� 49 unsigned char aval;
+ ��膩��� 50
+ ��膩��� 51 if (pcm_val >= 0) {
+ ��膩��� 52 mask = 0xD5;
+ ��膩��� 53 } else {
+ ��膩��� 54 mask = 0x55;
+ ��膩��� 55 pcm_val = -pcm_val;
+ ��膩��� 56 if (pcm_val > 0x7fff)
+ ��膩��� 57 pcm_val = 0x7fff;
+ ��膩��� 58 }
+ ��膩��� 59
+ ��膩��� 60 if (pcm_val < 256)
+ ��膩��� 61 aval = pcm_val >> 4;
+ ��膩��� 62 else {
+ ��膩��� 63 /* Convert the scaled magnitude to segment number. */
+ ��膩��� 64 seg = val_seg(pcm_val);
+ ��膩��� 65 aval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f);
+ ��膩��� 66 }
+ ��膩��� 67 return aval ^ mask;
+ ��膩��� 68 }
+ ��膩��� 69
+ ��膩��� 70 /*
+ ��膩��� 71 * alaw_to_s16() - Convert an A-law value to 16-bit linear PCM
+ ��膩��� 72 *
+ ��膩��� 73 */
+ ��膩��� 74 static inline int alaw_to_s16(unsigned char a_val)
+ ��膩��� 75 {
+ ��膩��� 76 int t;
+ ��膩��� 77 int seg;
+ ��膩��� 78
+ ��膩��� 79 a_val ^= 0x55;
+ ��膩��� 80 t = a_val & 0x7f;
+ ��膩��� 81 if (t < 16)
+ ��膩��� 82 t = (t << 4) + 8;
+ ��膩��� 83 else {
+ ��膩��� 84 seg = (t >> 4) & 0x07;
+ ��膩��� 85 t = ((t & 0x0f) << 4) + 0x108;
+ ��膩��� 86 t <<= seg -1;
+ ��膩��� 87 }
+ ��膩��� 88 return ((a_val & 0x80) ? t : -t);
+ ��膩��� 89 }
+ ��膩��� 90 /*
+ ��膩��� 91 * s16_to_ulaw() - Convert a linear PCM value to u-law
+ ��膩��� 92 *
+ ��膩��� 93 * In order to simplify the encoding process, the original linear magnitude
+ ��膩��� 94 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
+ ��膩��� 95 * (33 - 8191). The result can be seen in the following encoding table:
+ ��膩��� 96 *
+ ��膩��� 97 * Biased Linear Input Code Compressed Code
+ ��膩��� 98 * ------------------------ ---------------
+ ��膩��� 99 * 00000001wxyza 000wxyz
+ ��膩��� 100 * 0000001wxyzab 001wxyz
+ ��膩��� 101 * 000001wxyzabc 010wxyz
+ ��膩��� 102 * 00001wxyzabcd 011wxyz
+ ��膩��� 103 * 0001wxyzabcde 100wxyz
+ ��膩��� 104 * 001wxyzabcdef 101wxyz
+ ��膩��� 105 * 01wxyzabcdefg 110wxyz
+ ��膩��� 106 * 1wxyzabcdefgh 111wxyz
+ ��膩��� 107 *
+ ��膩��� 108 * Each biased linear code has a leading 1 which identifies the segment
+ ��膩��� 109 * number. The value of the segment number is equal to 7 minus the number
+ ��膩��� 110 * of leading 0's. The quantization interval is directly available as the
+ ��膩��� 111 * four bits wxyz. * The trailing bits (a - h) are ignored.
+ ��膩��� 112 *
+ ��膩��� 113 * Ordinarily the complement of the resulting code word is used for
+ ��膩��� 114 * transmission, and so the code word is complemented before it is returned.
+ ��膩��� 115 *
+ ��膩��� 116 * For further information see John C. Bellamy's Digital Telephony, 1982,
+ ��膩��� 117 * John Wiley & Sons, pps 98-111 and 472-476.
+ ��膩��� 118 */
+ ��膩��� 119
+ ��膩��� 120 static inline unsigned char s16_to_ulaw(int pcm_val) /* 2's complement (16-bit range) */
+ ��膩��� 121 {
+ ��膩��� 122 int mask;
+ ��膩��� 123 int seg;
+ ��膩��� 124 unsigned char uval;
+ ��膩��� 125
+ ��膩��� 126 if (pcm_val < 0) {
+ ��膩��� 127 pcm_val = 0x84 - pcm_val;
+ ��膩��� 128 mask = 0x7f;
+ ��膩��� 129 } else {
+ ��膩��� 130 pcm_val += 0x84;
+ ��膩��� 131 mask = 0xff;
+ ��膩��� 132 }
+ ��膩��� 133 if (pcm_val > 0x7fff)
+ ��膩��� 134 pcm_val = 0x7fff;
+ ��膩��� 135
+ ��膩��� 136 /* Convert the scaled magnitude to segment number. */
+ ��膩��� 137 seg = val_seg(pcm_val);
+ ��膩��� 138
+ ��膩��� 139 /*
+ ��膩��� 140 * Combine the sign, segment, quantization bits;
+ ��膩��� 141 * and complement the code word.
+ ��膩��� 142 */
+ ��膩��� 143 uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0x0f);
+ ��膩��� 144 return uval ^ mask;
+ ��膩��� 145 }
+ ��膩��� 146
+ ��膩��� 147 /*
+ ��膩��� 148 * ulaw_to_s16() - Convert a u-law value to 16-bit linear PCM
+ ��膩��� 149 *
+ ��膩��� 150 * First, a biased linear code is derived from the code word. An unbiased
+ ��膩��� 151 * output can then be obtained by subtracting 33 from the biased code.
+ ��膩��� 152 *
+ ��膩��� 153 * Note that this function expects to be passed the complement of the
+ ��膩��� 154 * original code word. This is in keeping with ISDN conventions.
+ ��膩��� 155 */
+ ��膩��� 156 static inline int ulaw_to_s16(unsigned char u_val)
+ ��膩��� 157 {
+ ��膩��� 158 int t;
+ ��膩��� 159
+ ��膩��� 160 /* Complement to obtain normal u-law value. */
+ ��膩��� 161 u_val = ~u_val;
+ ��膩��� 162
+ ��膩��� 163 /*
+ ��膩��� 164 * Extract and bias the quantization bits. Then
+ ��膩��� 165 * shift up by the segment number and subtract out the bias.
+ ��膩��� 166 */
+ ��膩��� 167 t = ((u_val & 0x0f) << 3) + 0x84;
+ ��膩��� 168 t <<= (u_val & 0x70) >> 4;
+ ��膩��� 169
+ ��膩��� 170 return ((u_val & 0x80) ? (0x84 - t) : (t - 0x84));
+ ��膩��� 171 }