1/* 2 * This source code is a product of Sun Microsystems, Inc. and is provided 3 * for unrestricted use. Users may copy or modify this source code without 4 * charge. 5 * 6 * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING 7 * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 8 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 9 * 10 * Sun source code is provided with no support and without any obligation on 11 * the part of Sun Microsystems, Inc. to assist in its use, correction, 12 * modification or enhancement. 13 * 14 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 15 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE 16 * OR ANY PART THEREOF. 17 * 18 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 19 * or profits or other special, indirect and consequential damages, even if 20 * Sun has been advised of the possibility of such damages. 21 * 22 * Sun Microsystems, Inc. 23 * 2550 Garcia Avenue 24 * Mountain View, California 94043 25 */ 26 27/* 28 * g723_24.c 29 * 30 * Description: 31 * 32 * g723_24_encoder(), g723_24_decoder() 33 * 34 * These routines comprise an implementation of the CCITT G.723 24 Kbps 35 * ADPCM coding algorithm. Essentially, this implementation is identical to 36 * the bit level description except for a few deviations which take advantage 37 * of workstation attributes, such as hardware 2's complement arithmetic. 38 * 39 */ 40#include "wx/wxprec.h" 41#include "wx/mmedia/internal/g72x.h" 42 43/* 44 * Maps G.723_24 code word to reconstructed scale factor normalized log 45 * magnitude values. 46 */ 47static short _dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048}; 48 49/* Maps G.723_24 code word to log of scale factor multiplier. */ 50static short _witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128}; 51 52/* 53 * Maps G.723_24 code words to a set of values whose long and short 54 * term averages are computed and then compared to give an indication 55 * how stationary (steady state) the signal is. 56 */ 57static short _fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0}; 58 59static short qtab_723_24[3] = {8, 218, 331}; 60 61/* 62 * g723_24_encoder() 63 * 64 * Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code. 65 * Returns -1 if invalid input coding value. 66 */ 67int 68g723_24_encoder( 69 int sl, 70 int in_coding, 71 struct g72x_state *state_ptr) 72{ 73 short sei, sezi, se, sez; /* ACCUM */ 74 short d; /* SUBTA */ 75 short y; /* MIX */ 76 short sr; /* ADDB */ 77 short dqsez; /* ADDC */ 78 short dq, i; 79 80 switch (in_coding) { /* linearize input sample to 14-bit PCM */ 81 case AUDIO_ENCODING_ALAW: 82 sl = alaw2linear(sl) >> 2; 83 break; 84 case AUDIO_ENCODING_ULAW: 85 sl = ulaw2linear(sl) >> 2; 86 break; 87 case AUDIO_ENCODING_LINEAR: 88 sl = ((short)sl) >> 2; /* sl of 14-bit dynamic range */ 89 break; 90 default: 91 return (-1); 92 } 93 94 sezi = predictor_zero(state_ptr); 95 sez = sezi >> 1; 96 sei = sezi + predictor_pole(state_ptr); 97 se = sei >> 1; /* se = estimated signal */ 98 99 d = sl - se; /* d = estimation diff. */ 100 101 /* quantize prediction difference d */ 102 y = step_size(state_ptr); /* quantizer step size */ 103 i = quantize(d, y, qtab_723_24, 3); /* i = ADPCM code */ 104 dq = reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */ 105 106 sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */ 107 108 dqsez = sr + sez - se; /* pole prediction diff. */ 109 110 update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); 111 112 return (i); 113} 114 115/* 116 * g723_24_decoder() 117 * 118 * Decodes a 3-bit CCITT G.723_24 ADPCM code and returns 119 * the resulting 16-bit linear PCM, A-law or u-law sample value. 120 * -1 is returned if the output coding is unknown. 121 */ 122int 123g723_24_decoder( 124 int i, 125 int out_coding, 126 struct g72x_state *state_ptr) 127{ 128 short sezi, sei, sez, se; /* ACCUM */ 129 short y; /* MIX */ 130 short sr; /* ADDB */ 131 short dq; 132 short dqsez; 133 134 i &= 0x07; /* mask to get proper bits */ 135 sezi = predictor_zero(state_ptr); 136 sez = sezi >> 1; 137 sei = sezi + predictor_pole(state_ptr); 138 se = sei >> 1; /* se = estimated signal */ 139 140 y = step_size(state_ptr); /* adaptive quantizer step size */ 141 dq = reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */ 142 143 sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */ 144 145 dqsez = sr - se + sez; /* pole prediction diff. */ 146 147 update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); 148 149 switch (out_coding) { 150 case AUDIO_ENCODING_ALAW: 151 return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24)); 152 case AUDIO_ENCODING_ULAW: 153 return (tandem_adjust_ulaw(sr, se, y, i, 4, qtab_723_24)); 154 case AUDIO_ENCODING_LINEAR: 155 return (sr << 2); /* sr was of 14-bit dynamic range */ 156 default: 157 return (-1); 158 } 159} 160