1b815c7f3Sopenharmony_ci/* 2b815c7f3Sopenharmony_ci * This source code is a product of Sun Microsystems, Inc. and is provided 3b815c7f3Sopenharmony_ci * for unrestricted use. Users may copy or modify this source code without 4b815c7f3Sopenharmony_ci * charge. 5b815c7f3Sopenharmony_ci * 6b815c7f3Sopenharmony_ci * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING 7b815c7f3Sopenharmony_ci * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 8b815c7f3Sopenharmony_ci * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 9b815c7f3Sopenharmony_ci * 10b815c7f3Sopenharmony_ci * Sun source code is provided with no support and without any obligation on 11b815c7f3Sopenharmony_ci * the part of Sun Microsystems, Inc. to assist in its use, correction, 12b815c7f3Sopenharmony_ci * modification or enhancement. 13b815c7f3Sopenharmony_ci * 14b815c7f3Sopenharmony_ci * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 15b815c7f3Sopenharmony_ci * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE 16b815c7f3Sopenharmony_ci * OR ANY PART THEREOF. 17b815c7f3Sopenharmony_ci * 18b815c7f3Sopenharmony_ci * In no event will Sun Microsystems, Inc. be liable for any lost revenue 19b815c7f3Sopenharmony_ci * or profits or other special, indirect and consequential damages, even if 20b815c7f3Sopenharmony_ci * Sun has been advised of the possibility of such damages. 21b815c7f3Sopenharmony_ci * 22b815c7f3Sopenharmony_ci * Sun Microsystems, Inc. 23b815c7f3Sopenharmony_ci * 2550 Garcia Avenue 24b815c7f3Sopenharmony_ci * Mountain View, California 94043 25b815c7f3Sopenharmony_ci */ 26b815c7f3Sopenharmony_ci 27b815c7f3Sopenharmony_ci/* 28b815c7f3Sopenharmony_ci * g72x.c 29b815c7f3Sopenharmony_ci * 30b815c7f3Sopenharmony_ci * Common routines for G.721 and G.723 conversions. 31b815c7f3Sopenharmony_ci */ 32b815c7f3Sopenharmony_ci 33b815c7f3Sopenharmony_ci#include <stdio.h> 34b815c7f3Sopenharmony_ci#include <stdlib.h> 35b815c7f3Sopenharmony_ci#include <string.h> 36b815c7f3Sopenharmony_ci 37b815c7f3Sopenharmony_ci#include "g72x.h" 38b815c7f3Sopenharmony_ci#include "g72x_priv.h" 39b815c7f3Sopenharmony_ci 40b815c7f3Sopenharmony_cistatic G72x_STATE * g72x_state_new (void) ; 41b815c7f3Sopenharmony_cistatic int unpack_bytes (int bits, int blocksize, const unsigned char * block, short * samples) ; 42b815c7f3Sopenharmony_cistatic int pack_bytes (int bits, const short * samples, unsigned char * block) ; 43b815c7f3Sopenharmony_ci 44b815c7f3Sopenharmony_cistatic 45b815c7f3Sopenharmony_cishort power2 [15] = 46b815c7f3Sopenharmony_ci{ 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 47b815c7f3Sopenharmony_ci 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000 48b815c7f3Sopenharmony_ci} ; 49b815c7f3Sopenharmony_ci 50b815c7f3Sopenharmony_ci/* 51b815c7f3Sopenharmony_ci * quan () 52b815c7f3Sopenharmony_ci * 53b815c7f3Sopenharmony_ci * quantizes the input val against the table of size short integers. 54b815c7f3Sopenharmony_ci * It returns i if table [i - 1] <= val < table [i]. 55b815c7f3Sopenharmony_ci * 56b815c7f3Sopenharmony_ci * Using linear search for simple coding. 57b815c7f3Sopenharmony_ci */ 58b815c7f3Sopenharmony_cistatic 59b815c7f3Sopenharmony_ciint quan (int val, short *table, int size) 60b815c7f3Sopenharmony_ci{ 61b815c7f3Sopenharmony_ci int i ; 62b815c7f3Sopenharmony_ci 63b815c7f3Sopenharmony_ci for (i = 0 ; i < size ; i++) 64b815c7f3Sopenharmony_ci if (val < *table++) 65b815c7f3Sopenharmony_ci break ; 66b815c7f3Sopenharmony_ci return i ; 67b815c7f3Sopenharmony_ci} 68b815c7f3Sopenharmony_ci 69b815c7f3Sopenharmony_ci/* 70b815c7f3Sopenharmony_ci * fmult () 71b815c7f3Sopenharmony_ci * 72b815c7f3Sopenharmony_ci * returns the integer product of the 14-bit integer "an" and 73b815c7f3Sopenharmony_ci * "floating point" representation (4-bit exponent, 6-bit mantessa) "srn". 74b815c7f3Sopenharmony_ci */ 75b815c7f3Sopenharmony_cistatic 76b815c7f3Sopenharmony_ciint fmult (int an, int srn) 77b815c7f3Sopenharmony_ci{ 78b815c7f3Sopenharmony_ci short anmag, anexp, anmant ; 79b815c7f3Sopenharmony_ci short wanexp, wanmant ; 80b815c7f3Sopenharmony_ci short retval ; 81b815c7f3Sopenharmony_ci 82b815c7f3Sopenharmony_ci anmag = (an > 0) ? an : ((-an) & 0x1FFF) ; 83b815c7f3Sopenharmony_ci anexp = quan (anmag, power2, 15) - 6 ; 84b815c7f3Sopenharmony_ci anmant = (anmag == 0) ? 32 : 85b815c7f3Sopenharmony_ci (anexp >= 0) ? anmag >> anexp : anmag << -anexp ; 86b815c7f3Sopenharmony_ci wanexp = anexp + ((srn >> 6) & 0xF) - 13 ; 87b815c7f3Sopenharmony_ci 88b815c7f3Sopenharmony_ci /* 89b815c7f3Sopenharmony_ci ** The original was : 90b815c7f3Sopenharmony_ci ** wanmant = (anmant * (srn & 0x3F) + 0x30) >> 4 ; 91b815c7f3Sopenharmony_ci ** but could see no valid reason for the + 0x30. 92b815c7f3Sopenharmony_ci ** Removed it and it improved the SNR of the codec. 93b815c7f3Sopenharmony_ci */ 94b815c7f3Sopenharmony_ci 95b815c7f3Sopenharmony_ci wanmant = (anmant * (srn & 0x3F)) >> 4 ; 96b815c7f3Sopenharmony_ci 97b815c7f3Sopenharmony_ci retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) : (wanmant >> -wanexp) ; 98b815c7f3Sopenharmony_ci 99b815c7f3Sopenharmony_ci return (((an ^ srn) < 0) ? -retval : retval) ; 100b815c7f3Sopenharmony_ci} 101b815c7f3Sopenharmony_ci 102b815c7f3Sopenharmony_cistatic G72x_STATE * g72x_state_new (void) 103b815c7f3Sopenharmony_ci{ return calloc (1, sizeof (G72x_STATE)) ; 104b815c7f3Sopenharmony_ci} 105b815c7f3Sopenharmony_ci 106b815c7f3Sopenharmony_ci/* 107b815c7f3Sopenharmony_ci * private_init_state () 108b815c7f3Sopenharmony_ci * 109b815c7f3Sopenharmony_ci * This routine initializes and/or resets the G72x_PRIVATE structure 110b815c7f3Sopenharmony_ci * pointed to by 'state_ptr'. 111b815c7f3Sopenharmony_ci * All the initial state values are specified in the CCITT G.721 document. 112b815c7f3Sopenharmony_ci */ 113b815c7f3Sopenharmony_civoid private_init_state (G72x_STATE *state_ptr) 114b815c7f3Sopenharmony_ci{ 115b815c7f3Sopenharmony_ci int cnta ; 116b815c7f3Sopenharmony_ci 117b815c7f3Sopenharmony_ci state_ptr->yl = 34816 ; 118b815c7f3Sopenharmony_ci state_ptr->yu = 544 ; 119b815c7f3Sopenharmony_ci state_ptr->dms = 0 ; 120b815c7f3Sopenharmony_ci state_ptr->dml = 0 ; 121b815c7f3Sopenharmony_ci state_ptr->ap = 0 ; 122b815c7f3Sopenharmony_ci for (cnta = 0 ; cnta < 2 ; cnta++) 123b815c7f3Sopenharmony_ci { state_ptr->a [cnta] = 0 ; 124b815c7f3Sopenharmony_ci state_ptr->pk [cnta] = 0 ; 125b815c7f3Sopenharmony_ci state_ptr->sr [cnta] = 32 ; 126b815c7f3Sopenharmony_ci } 127b815c7f3Sopenharmony_ci for (cnta = 0 ; cnta < 6 ; cnta++) 128b815c7f3Sopenharmony_ci { state_ptr->b [cnta] = 0 ; 129b815c7f3Sopenharmony_ci state_ptr->dq [cnta] = 32 ; 130b815c7f3Sopenharmony_ci } 131b815c7f3Sopenharmony_ci state_ptr->td = 0 ; 132b815c7f3Sopenharmony_ci} /* private_init_state */ 133b815c7f3Sopenharmony_ci 134b815c7f3Sopenharmony_cistruct g72x_state * g72x_reader_init (int codec, int *blocksize, int *samplesperblock) 135b815c7f3Sopenharmony_ci{ G72x_STATE *pstate ; 136b815c7f3Sopenharmony_ci 137b815c7f3Sopenharmony_ci if ((pstate = g72x_state_new ()) == NULL) 138b815c7f3Sopenharmony_ci return NULL ; 139b815c7f3Sopenharmony_ci 140b815c7f3Sopenharmony_ci private_init_state (pstate) ; 141b815c7f3Sopenharmony_ci 142b815c7f3Sopenharmony_ci pstate->encoder = NULL ; 143b815c7f3Sopenharmony_ci 144b815c7f3Sopenharmony_ci switch (codec) 145b815c7f3Sopenharmony_ci { case G723_16_BITS_PER_SAMPLE : /* 2 bits per sample. */ 146b815c7f3Sopenharmony_ci pstate->decoder = g723_16_decoder ; 147b815c7f3Sopenharmony_ci *blocksize = G723_16_BYTES_PER_BLOCK ; 148b815c7f3Sopenharmony_ci *samplesperblock = G723_16_SAMPLES_PER_BLOCK ; 149b815c7f3Sopenharmony_ci pstate->codec_bits = 2 ; 150b815c7f3Sopenharmony_ci pstate->blocksize = G723_16_BYTES_PER_BLOCK ; 151b815c7f3Sopenharmony_ci pstate->samplesperblock = G723_16_SAMPLES_PER_BLOCK ; 152b815c7f3Sopenharmony_ci break ; 153b815c7f3Sopenharmony_ci 154b815c7f3Sopenharmony_ci case G723_24_BITS_PER_SAMPLE : /* 3 bits per sample. */ 155b815c7f3Sopenharmony_ci pstate->decoder = g723_24_decoder ; 156b815c7f3Sopenharmony_ci *blocksize = G723_24_BYTES_PER_BLOCK ; 157b815c7f3Sopenharmony_ci *samplesperblock = G723_24_SAMPLES_PER_BLOCK ; 158b815c7f3Sopenharmony_ci pstate->codec_bits = 3 ; 159b815c7f3Sopenharmony_ci pstate->blocksize = G723_24_BYTES_PER_BLOCK ; 160b815c7f3Sopenharmony_ci pstate->samplesperblock = G723_24_SAMPLES_PER_BLOCK ; 161b815c7f3Sopenharmony_ci break ; 162b815c7f3Sopenharmony_ci 163b815c7f3Sopenharmony_ci case G721_32_BITS_PER_SAMPLE : /* 4 bits per sample. */ 164b815c7f3Sopenharmony_ci pstate->decoder = g721_decoder ; 165b815c7f3Sopenharmony_ci *blocksize = G721_32_BYTES_PER_BLOCK ; 166b815c7f3Sopenharmony_ci *samplesperblock = G721_32_SAMPLES_PER_BLOCK ; 167b815c7f3Sopenharmony_ci pstate->codec_bits = 4 ; 168b815c7f3Sopenharmony_ci pstate->blocksize = G721_32_BYTES_PER_BLOCK ; 169b815c7f3Sopenharmony_ci pstate->samplesperblock = G721_32_SAMPLES_PER_BLOCK ; 170b815c7f3Sopenharmony_ci break ; 171b815c7f3Sopenharmony_ci 172b815c7f3Sopenharmony_ci case G721_40_BITS_PER_SAMPLE : /* 5 bits per sample. */ 173b815c7f3Sopenharmony_ci pstate->decoder = g723_40_decoder ; 174b815c7f3Sopenharmony_ci *blocksize = G721_40_BYTES_PER_BLOCK ; 175b815c7f3Sopenharmony_ci *samplesperblock = G721_40_SAMPLES_PER_BLOCK ; 176b815c7f3Sopenharmony_ci pstate->codec_bits = 5 ; 177b815c7f3Sopenharmony_ci pstate->blocksize = G721_40_BYTES_PER_BLOCK ; 178b815c7f3Sopenharmony_ci pstate->samplesperblock = G721_40_SAMPLES_PER_BLOCK ; 179b815c7f3Sopenharmony_ci break ; 180b815c7f3Sopenharmony_ci 181b815c7f3Sopenharmony_ci default : 182b815c7f3Sopenharmony_ci free (pstate) ; 183b815c7f3Sopenharmony_ci return NULL ; 184b815c7f3Sopenharmony_ci } ; 185b815c7f3Sopenharmony_ci 186b815c7f3Sopenharmony_ci return pstate ; 187b815c7f3Sopenharmony_ci} /* g72x_reader_init */ 188b815c7f3Sopenharmony_ci 189b815c7f3Sopenharmony_cistruct g72x_state * g72x_writer_init (int codec, int *blocksize, int *samplesperblock) 190b815c7f3Sopenharmony_ci{ G72x_STATE *pstate ; 191b815c7f3Sopenharmony_ci 192b815c7f3Sopenharmony_ci if ((pstate = g72x_state_new ()) == NULL) 193b815c7f3Sopenharmony_ci return NULL ; 194b815c7f3Sopenharmony_ci 195b815c7f3Sopenharmony_ci private_init_state (pstate) ; 196b815c7f3Sopenharmony_ci pstate->decoder = NULL ; 197b815c7f3Sopenharmony_ci 198b815c7f3Sopenharmony_ci switch (codec) 199b815c7f3Sopenharmony_ci { case G723_16_BITS_PER_SAMPLE : /* 2 bits per sample. */ 200b815c7f3Sopenharmony_ci pstate->encoder = g723_16_encoder ; 201b815c7f3Sopenharmony_ci *blocksize = G723_16_BYTES_PER_BLOCK ; 202b815c7f3Sopenharmony_ci *samplesperblock = G723_16_SAMPLES_PER_BLOCK ; 203b815c7f3Sopenharmony_ci pstate->codec_bits = 2 ; 204b815c7f3Sopenharmony_ci pstate->blocksize = G723_16_BYTES_PER_BLOCK ; 205b815c7f3Sopenharmony_ci pstate->samplesperblock = G723_16_SAMPLES_PER_BLOCK ; 206b815c7f3Sopenharmony_ci break ; 207b815c7f3Sopenharmony_ci 208b815c7f3Sopenharmony_ci case G723_24_BITS_PER_SAMPLE : /* 3 bits per sample. */ 209b815c7f3Sopenharmony_ci pstate->encoder = g723_24_encoder ; 210b815c7f3Sopenharmony_ci *blocksize = G723_24_BYTES_PER_BLOCK ; 211b815c7f3Sopenharmony_ci *samplesperblock = G723_24_SAMPLES_PER_BLOCK ; 212b815c7f3Sopenharmony_ci pstate->codec_bits = 3 ; 213b815c7f3Sopenharmony_ci pstate->blocksize = G723_24_BYTES_PER_BLOCK ; 214b815c7f3Sopenharmony_ci pstate->samplesperblock = G723_24_SAMPLES_PER_BLOCK ; 215b815c7f3Sopenharmony_ci break ; 216b815c7f3Sopenharmony_ci 217b815c7f3Sopenharmony_ci case G721_32_BITS_PER_SAMPLE : /* 4 bits per sample. */ 218b815c7f3Sopenharmony_ci pstate->encoder = g721_encoder ; 219b815c7f3Sopenharmony_ci *blocksize = G721_32_BYTES_PER_BLOCK ; 220b815c7f3Sopenharmony_ci *samplesperblock = G721_32_SAMPLES_PER_BLOCK ; 221b815c7f3Sopenharmony_ci pstate->codec_bits = 4 ; 222b815c7f3Sopenharmony_ci pstate->blocksize = G721_32_BYTES_PER_BLOCK ; 223b815c7f3Sopenharmony_ci pstate->samplesperblock = G721_32_SAMPLES_PER_BLOCK ; 224b815c7f3Sopenharmony_ci break ; 225b815c7f3Sopenharmony_ci 226b815c7f3Sopenharmony_ci case G721_40_BITS_PER_SAMPLE : /* 5 bits per sample. */ 227b815c7f3Sopenharmony_ci pstate->encoder = g723_40_encoder ; 228b815c7f3Sopenharmony_ci *blocksize = G721_40_BYTES_PER_BLOCK ; 229b815c7f3Sopenharmony_ci *samplesperblock = G721_40_SAMPLES_PER_BLOCK ; 230b815c7f3Sopenharmony_ci pstate->codec_bits = 5 ; 231b815c7f3Sopenharmony_ci pstate->blocksize = G721_40_BYTES_PER_BLOCK ; 232b815c7f3Sopenharmony_ci pstate->samplesperblock = G721_40_SAMPLES_PER_BLOCK ; 233b815c7f3Sopenharmony_ci break ; 234b815c7f3Sopenharmony_ci 235b815c7f3Sopenharmony_ci default : 236b815c7f3Sopenharmony_ci free (pstate) ; 237b815c7f3Sopenharmony_ci return NULL ; 238b815c7f3Sopenharmony_ci } ; 239b815c7f3Sopenharmony_ci 240b815c7f3Sopenharmony_ci return pstate ; 241b815c7f3Sopenharmony_ci} /* g72x_writer_init */ 242b815c7f3Sopenharmony_ci 243b815c7f3Sopenharmony_ciint g72x_decode_block (G72x_STATE *pstate, const unsigned char *block, short *samples) 244b815c7f3Sopenharmony_ci{ int k, count ; 245b815c7f3Sopenharmony_ci 246b815c7f3Sopenharmony_ci count = unpack_bytes (pstate->codec_bits, pstate->blocksize, block, samples) ; 247b815c7f3Sopenharmony_ci 248b815c7f3Sopenharmony_ci for (k = 0 ; k < count ; k++) 249b815c7f3Sopenharmony_ci samples [k] = pstate->decoder (samples [k], pstate) ; 250b815c7f3Sopenharmony_ci 251b815c7f3Sopenharmony_ci return 0 ; 252b815c7f3Sopenharmony_ci} /* g72x_decode_block */ 253b815c7f3Sopenharmony_ci 254b815c7f3Sopenharmony_ciint g72x_encode_block (G72x_STATE *pstate, short *samples, unsigned char *block) 255b815c7f3Sopenharmony_ci{ int k, count ; 256b815c7f3Sopenharmony_ci 257b815c7f3Sopenharmony_ci for (k = 0 ; k < pstate->samplesperblock ; k++) 258b815c7f3Sopenharmony_ci samples [k] = pstate->encoder (samples [k], pstate) ; 259b815c7f3Sopenharmony_ci 260b815c7f3Sopenharmony_ci count = pack_bytes (pstate->codec_bits, samples, block) ; 261b815c7f3Sopenharmony_ci 262b815c7f3Sopenharmony_ci return count ; 263b815c7f3Sopenharmony_ci} /* g72x_encode_block */ 264b815c7f3Sopenharmony_ci 265b815c7f3Sopenharmony_ci/* 266b815c7f3Sopenharmony_ci * predictor_zero () 267b815c7f3Sopenharmony_ci * 268b815c7f3Sopenharmony_ci * computes the estimated signal from 6-zero predictor. 269b815c7f3Sopenharmony_ci * 270b815c7f3Sopenharmony_ci */ 271b815c7f3Sopenharmony_ciint predictor_zero (G72x_STATE *state_ptr) 272b815c7f3Sopenharmony_ci{ 273b815c7f3Sopenharmony_ci int i ; 274b815c7f3Sopenharmony_ci int sezi ; 275b815c7f3Sopenharmony_ci 276b815c7f3Sopenharmony_ci sezi = fmult (state_ptr->b [0] >> 2, state_ptr->dq [0]) ; 277b815c7f3Sopenharmony_ci for (i = 1 ; i < 6 ; i++) /* ACCUM */ 278b815c7f3Sopenharmony_ci sezi += fmult (state_ptr->b [i] >> 2, state_ptr->dq [i]) ; 279b815c7f3Sopenharmony_ci return sezi ; 280b815c7f3Sopenharmony_ci} 281b815c7f3Sopenharmony_ci/* 282b815c7f3Sopenharmony_ci * predictor_pole () 283b815c7f3Sopenharmony_ci * 284b815c7f3Sopenharmony_ci * computes the estimated signal from 2-pole predictor. 285b815c7f3Sopenharmony_ci * 286b815c7f3Sopenharmony_ci */ 287b815c7f3Sopenharmony_ciint predictor_pole (G72x_STATE *state_ptr) 288b815c7f3Sopenharmony_ci{ 289b815c7f3Sopenharmony_ci return (fmult (state_ptr->a [1] >> 2, state_ptr->sr [1]) + 290b815c7f3Sopenharmony_ci fmult (state_ptr->a [0] >> 2, state_ptr->sr [0])) ; 291b815c7f3Sopenharmony_ci} 292b815c7f3Sopenharmony_ci/* 293b815c7f3Sopenharmony_ci * step_size () 294b815c7f3Sopenharmony_ci * 295b815c7f3Sopenharmony_ci * computes the quantization step size of the adaptive quantizer. 296b815c7f3Sopenharmony_ci * 297b815c7f3Sopenharmony_ci */ 298b815c7f3Sopenharmony_ciint step_size (G72x_STATE *state_ptr) 299b815c7f3Sopenharmony_ci{ 300b815c7f3Sopenharmony_ci int y ; 301b815c7f3Sopenharmony_ci int dif ; 302b815c7f3Sopenharmony_ci int al ; 303b815c7f3Sopenharmony_ci 304b815c7f3Sopenharmony_ci if (state_ptr->ap >= 256) 305b815c7f3Sopenharmony_ci return (state_ptr->yu) ; 306b815c7f3Sopenharmony_ci else { 307b815c7f3Sopenharmony_ci y = state_ptr->yl >> 6 ; 308b815c7f3Sopenharmony_ci dif = state_ptr->yu - y ; 309b815c7f3Sopenharmony_ci al = state_ptr->ap >> 2 ; 310b815c7f3Sopenharmony_ci if (dif > 0) 311b815c7f3Sopenharmony_ci y += (dif * al) >> 6 ; 312b815c7f3Sopenharmony_ci else if (dif < 0) 313b815c7f3Sopenharmony_ci y += (dif * al + 0x3F) >> 6 ; 314b815c7f3Sopenharmony_ci return y ; 315b815c7f3Sopenharmony_ci } 316b815c7f3Sopenharmony_ci} 317b815c7f3Sopenharmony_ci 318b815c7f3Sopenharmony_ci/* 319b815c7f3Sopenharmony_ci * quantize () 320b815c7f3Sopenharmony_ci * 321b815c7f3Sopenharmony_ci * Given a raw sample, 'd', of the difference signal and a 322b815c7f3Sopenharmony_ci * quantization step size scale factor, 'y', this routine returns the 323b815c7f3Sopenharmony_ci * ADPCM codeword to which that sample gets quantized. The step 324b815c7f3Sopenharmony_ci * size scale factor division operation is done in the log base 2 domain 325b815c7f3Sopenharmony_ci * as a subtraction. 326b815c7f3Sopenharmony_ci */ 327b815c7f3Sopenharmony_ciint quantize ( 328b815c7f3Sopenharmony_ci int d, /* Raw difference signal sample */ 329b815c7f3Sopenharmony_ci int y, /* Step size multiplier */ 330b815c7f3Sopenharmony_ci short *table, /* quantization table */ 331b815c7f3Sopenharmony_ci int size) /* table size of short integers */ 332b815c7f3Sopenharmony_ci{ 333b815c7f3Sopenharmony_ci short dqm ; /* Magnitude of 'd' */ 334b815c7f3Sopenharmony_ci short expon ; /* Integer part of base 2 log of 'd' */ 335b815c7f3Sopenharmony_ci short mant ; /* Fractional part of base 2 log */ 336b815c7f3Sopenharmony_ci short dl ; /* Log of magnitude of 'd' */ 337b815c7f3Sopenharmony_ci short dln ; /* Step size scale factor normalized log */ 338b815c7f3Sopenharmony_ci int i ; 339b815c7f3Sopenharmony_ci 340b815c7f3Sopenharmony_ci /* 341b815c7f3Sopenharmony_ci * LOG 342b815c7f3Sopenharmony_ci * 343b815c7f3Sopenharmony_ci * Compute base 2 log of 'd', and store in 'dl'. 344b815c7f3Sopenharmony_ci */ 345b815c7f3Sopenharmony_ci dqm = abs (d) ; 346b815c7f3Sopenharmony_ci expon = quan (dqm >> 1, power2, 15) ; 347b815c7f3Sopenharmony_ci mant = ((dqm << 7) >> expon) & 0x7F ; /* Fractional portion. */ 348b815c7f3Sopenharmony_ci dl = (expon << 7) + mant ; 349b815c7f3Sopenharmony_ci 350b815c7f3Sopenharmony_ci /* 351b815c7f3Sopenharmony_ci * SUBTB 352b815c7f3Sopenharmony_ci * 353b815c7f3Sopenharmony_ci * "Divide" by step size multiplier. 354b815c7f3Sopenharmony_ci */ 355b815c7f3Sopenharmony_ci dln = dl - (y >> 2) ; 356b815c7f3Sopenharmony_ci 357b815c7f3Sopenharmony_ci /* 358b815c7f3Sopenharmony_ci * QUAN 359b815c7f3Sopenharmony_ci * 360b815c7f3Sopenharmony_ci * Obtain codword i for 'd'. 361b815c7f3Sopenharmony_ci */ 362b815c7f3Sopenharmony_ci i = quan (dln, table, size) ; 363b815c7f3Sopenharmony_ci if (d < 0) /* take 1's complement of i */ 364b815c7f3Sopenharmony_ci return ((size << 1) + 1 - i) ; 365b815c7f3Sopenharmony_ci else if (i == 0) /* take 1's complement of 0 */ 366b815c7f3Sopenharmony_ci return ((size << 1) + 1) ; /* new in 1988 */ 367b815c7f3Sopenharmony_ci 368b815c7f3Sopenharmony_ci return i ; 369b815c7f3Sopenharmony_ci} 370b815c7f3Sopenharmony_ci/* 371b815c7f3Sopenharmony_ci * reconstruct () 372b815c7f3Sopenharmony_ci * 373b815c7f3Sopenharmony_ci * Returns reconstructed difference signal 'dq' obtained from 374b815c7f3Sopenharmony_ci * codeword 'i' and quantization step size scale factor 'y'. 375b815c7f3Sopenharmony_ci * Multiplication is performed in log base 2 domain as addition. 376b815c7f3Sopenharmony_ci */ 377b815c7f3Sopenharmony_ciint 378b815c7f3Sopenharmony_cireconstruct ( 379b815c7f3Sopenharmony_ci int sign, /* 0 for non-negative value */ 380b815c7f3Sopenharmony_ci int dqln, /* G.72x codeword */ 381b815c7f3Sopenharmony_ci int y) /* Step size multiplier */ 382b815c7f3Sopenharmony_ci{ 383b815c7f3Sopenharmony_ci short dql ; /* Log of 'dq' magnitude */ 384b815c7f3Sopenharmony_ci short dex ; /* Integer part of log */ 385b815c7f3Sopenharmony_ci short dqt ; 386b815c7f3Sopenharmony_ci short dq ; /* Reconstructed difference signal sample */ 387b815c7f3Sopenharmony_ci 388b815c7f3Sopenharmony_ci dql = dqln + (y >> 2) ; /* ADDA */ 389b815c7f3Sopenharmony_ci 390b815c7f3Sopenharmony_ci if (dql < 0) 391b815c7f3Sopenharmony_ci return ((sign) ? -0x8000 : 0) ; 392b815c7f3Sopenharmony_ci else /* ANTILOG */ 393b815c7f3Sopenharmony_ci { dex = (dql >> 7) & 15 ; 394b815c7f3Sopenharmony_ci dqt = 128 + (dql & 127) ; 395b815c7f3Sopenharmony_ci dq = (dqt << 7) >> (14 - dex) ; 396b815c7f3Sopenharmony_ci return ((sign) ? (dq - 0x8000) : dq) ; 397b815c7f3Sopenharmony_ci } 398b815c7f3Sopenharmony_ci} 399b815c7f3Sopenharmony_ci 400b815c7f3Sopenharmony_ci 401b815c7f3Sopenharmony_ci/* 402b815c7f3Sopenharmony_ci * update () 403b815c7f3Sopenharmony_ci * 404b815c7f3Sopenharmony_ci * updates the state variables for each output code 405b815c7f3Sopenharmony_ci */ 406b815c7f3Sopenharmony_civoid 407b815c7f3Sopenharmony_ciupdate ( 408b815c7f3Sopenharmony_ci int code_size, /* distinguish 723_40 with others */ 409b815c7f3Sopenharmony_ci int y, /* quantizer step size */ 410b815c7f3Sopenharmony_ci int wi, /* scale factor multiplier */ 411b815c7f3Sopenharmony_ci int fi, /* for long/short term energies */ 412b815c7f3Sopenharmony_ci int dq, /* quantized prediction difference */ 413b815c7f3Sopenharmony_ci int sr, /* reconstructed signal */ 414b815c7f3Sopenharmony_ci int dqsez, /* difference from 2-pole predictor */ 415b815c7f3Sopenharmony_ci G72x_STATE *state_ptr) /* coder state pointer */ 416b815c7f3Sopenharmony_ci{ 417b815c7f3Sopenharmony_ci int cnt ; 418b815c7f3Sopenharmony_ci short mag, expon ; /* Adaptive predictor, FLOAT A */ 419b815c7f3Sopenharmony_ci short a2p = 0 ; /* LIMC */ 420b815c7f3Sopenharmony_ci short a1ul ; /* UPA1 */ 421b815c7f3Sopenharmony_ci short pks1 ; /* UPA2 */ 422b815c7f3Sopenharmony_ci short fa1 ; 423b815c7f3Sopenharmony_ci char tr ; /* tone/transition detector */ 424b815c7f3Sopenharmony_ci short ylint, thr2, dqthr ; 425b815c7f3Sopenharmony_ci short ylfrac, thr1 ; 426b815c7f3Sopenharmony_ci short pk0 ; 427b815c7f3Sopenharmony_ci 428b815c7f3Sopenharmony_ci pk0 = (dqsez < 0) ? 1 : 0 ; /* needed in updating predictor poles */ 429b815c7f3Sopenharmony_ci 430b815c7f3Sopenharmony_ci mag = dq & 0x7FFF ; /* prediction difference magnitude */ 431b815c7f3Sopenharmony_ci /* TRANS */ 432b815c7f3Sopenharmony_ci ylint = state_ptr->yl >> 15 ; /* exponent part of yl */ 433b815c7f3Sopenharmony_ci ylfrac = (state_ptr->yl >> 10) & 0x1F ; /* fractional part of yl */ 434b815c7f3Sopenharmony_ci thr1 = (32 + ylfrac) << ylint ; /* threshold */ 435b815c7f3Sopenharmony_ci thr2 = (ylint > 9) ? 31 << 10 : thr1 ; /* limit thr2 to 31 << 10 */ 436b815c7f3Sopenharmony_ci dqthr = (thr2 + (thr2 >> 1)) >> 1 ; /* dqthr = 0.75 * thr2 */ 437b815c7f3Sopenharmony_ci if (state_ptr->td == 0) /* signal supposed voice */ 438b815c7f3Sopenharmony_ci tr = 0 ; 439b815c7f3Sopenharmony_ci else if (mag <= dqthr) /* supposed data, but small mag */ 440b815c7f3Sopenharmony_ci tr = 0 ; /* treated as voice */ 441b815c7f3Sopenharmony_ci else /* signal is data (modem) */ 442b815c7f3Sopenharmony_ci tr = 1 ; 443b815c7f3Sopenharmony_ci 444b815c7f3Sopenharmony_ci /* 445b815c7f3Sopenharmony_ci * Quantizer scale factor adaptation. 446b815c7f3Sopenharmony_ci */ 447b815c7f3Sopenharmony_ci 448b815c7f3Sopenharmony_ci /* FUNCTW & FILTD & DELAY */ 449b815c7f3Sopenharmony_ci /* update non-steady state step size multiplier */ 450b815c7f3Sopenharmony_ci state_ptr->yu = y + ((wi - y) >> 5) ; 451b815c7f3Sopenharmony_ci 452b815c7f3Sopenharmony_ci /* LIMB */ 453b815c7f3Sopenharmony_ci if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */ 454b815c7f3Sopenharmony_ci state_ptr->yu = 544 ; 455b815c7f3Sopenharmony_ci else if (state_ptr->yu > 5120) 456b815c7f3Sopenharmony_ci state_ptr->yu = 5120 ; 457b815c7f3Sopenharmony_ci 458b815c7f3Sopenharmony_ci /* FILTE & DELAY */ 459b815c7f3Sopenharmony_ci /* update steady state step size multiplier */ 460b815c7f3Sopenharmony_ci state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6) ; 461b815c7f3Sopenharmony_ci 462b815c7f3Sopenharmony_ci /* 463b815c7f3Sopenharmony_ci * Adaptive predictor coefficients. 464b815c7f3Sopenharmony_ci */ 465b815c7f3Sopenharmony_ci if (tr == 1) { /* reset a's and b's for modem signal */ 466b815c7f3Sopenharmony_ci state_ptr->a [0] = 0 ; 467b815c7f3Sopenharmony_ci state_ptr->a [1] = 0 ; 468b815c7f3Sopenharmony_ci state_ptr->b [0] = 0 ; 469b815c7f3Sopenharmony_ci state_ptr->b [1] = 0 ; 470b815c7f3Sopenharmony_ci state_ptr->b [2] = 0 ; 471b815c7f3Sopenharmony_ci state_ptr->b [3] = 0 ; 472b815c7f3Sopenharmony_ci state_ptr->b [4] = 0 ; 473b815c7f3Sopenharmony_ci state_ptr->b [5] = 0 ; 474b815c7f3Sopenharmony_ci } 475b815c7f3Sopenharmony_ci else /* update a's and b's */ 476b815c7f3Sopenharmony_ci { pks1 = pk0 ^ state_ptr->pk [0] ; /* UPA2 */ 477b815c7f3Sopenharmony_ci 478b815c7f3Sopenharmony_ci /* update predictor pole a [1] */ 479b815c7f3Sopenharmony_ci a2p = state_ptr->a [1] - (state_ptr->a [1] >> 7) ; 480b815c7f3Sopenharmony_ci if (dqsez != 0) 481b815c7f3Sopenharmony_ci { fa1 = (pks1) ? state_ptr->a [0] : -state_ptr->a [0] ; 482b815c7f3Sopenharmony_ci if (fa1 < -8191) /* a2p = function of fa1 */ 483b815c7f3Sopenharmony_ci a2p -= 0x100 ; 484b815c7f3Sopenharmony_ci else if (fa1 > 8191) 485b815c7f3Sopenharmony_ci a2p += 0xFF ; 486b815c7f3Sopenharmony_ci else 487b815c7f3Sopenharmony_ci a2p += fa1 >> 5 ; 488b815c7f3Sopenharmony_ci 489b815c7f3Sopenharmony_ci if (pk0 ^ state_ptr->pk [1]) 490b815c7f3Sopenharmony_ci { /* LIMC */ 491b815c7f3Sopenharmony_ci if (a2p <= -12160) 492b815c7f3Sopenharmony_ci a2p = -12288 ; 493b815c7f3Sopenharmony_ci else if (a2p >= 12416) 494b815c7f3Sopenharmony_ci a2p = 12288 ; 495b815c7f3Sopenharmony_ci else 496b815c7f3Sopenharmony_ci a2p -= 0x80 ; 497b815c7f3Sopenharmony_ci } 498b815c7f3Sopenharmony_ci else if (a2p <= -12416) 499b815c7f3Sopenharmony_ci a2p = -12288 ; 500b815c7f3Sopenharmony_ci else if (a2p >= 12160) 501b815c7f3Sopenharmony_ci a2p = 12288 ; 502b815c7f3Sopenharmony_ci else 503b815c7f3Sopenharmony_ci a2p += 0x80 ; 504b815c7f3Sopenharmony_ci } 505b815c7f3Sopenharmony_ci 506b815c7f3Sopenharmony_ci /* TRIGB & DELAY */ 507b815c7f3Sopenharmony_ci state_ptr->a [1] = a2p ; 508b815c7f3Sopenharmony_ci 509b815c7f3Sopenharmony_ci /* UPA1 */ 510b815c7f3Sopenharmony_ci /* update predictor pole a [0] */ 511b815c7f3Sopenharmony_ci state_ptr->a [0] -= state_ptr->a [0] >> 8 ; 512b815c7f3Sopenharmony_ci if (dqsez != 0) 513b815c7f3Sopenharmony_ci { if (pks1 == 0) 514b815c7f3Sopenharmony_ci state_ptr->a [0] += 192 ; 515b815c7f3Sopenharmony_ci else 516b815c7f3Sopenharmony_ci state_ptr->a [0] -= 192 ; 517b815c7f3Sopenharmony_ci } ; 518b815c7f3Sopenharmony_ci 519b815c7f3Sopenharmony_ci /* LIMD */ 520b815c7f3Sopenharmony_ci a1ul = 15360 - a2p ; 521b815c7f3Sopenharmony_ci if (state_ptr->a [0] < -a1ul) 522b815c7f3Sopenharmony_ci state_ptr->a [0] = -a1ul ; 523b815c7f3Sopenharmony_ci else if (state_ptr->a [0] > a1ul) 524b815c7f3Sopenharmony_ci state_ptr->a [0] = a1ul ; 525b815c7f3Sopenharmony_ci 526b815c7f3Sopenharmony_ci /* UPB : update predictor zeros b [6] */ 527b815c7f3Sopenharmony_ci for (cnt = 0 ; cnt < 6 ; cnt++) 528b815c7f3Sopenharmony_ci { if (code_size == 5) /* for 40Kbps G.723 */ 529b815c7f3Sopenharmony_ci state_ptr->b [cnt] -= state_ptr->b [cnt] >> 9 ; 530b815c7f3Sopenharmony_ci else /* for G.721 and 24Kbps G.723 */ 531b815c7f3Sopenharmony_ci state_ptr->b [cnt] -= state_ptr->b [cnt] >> 8 ; 532b815c7f3Sopenharmony_ci if (dq & 0x7FFF) /* XOR */ 533b815c7f3Sopenharmony_ci { if ((dq ^ state_ptr->dq [cnt]) >= 0) 534b815c7f3Sopenharmony_ci state_ptr->b [cnt] += 128 ; 535b815c7f3Sopenharmony_ci else 536b815c7f3Sopenharmony_ci state_ptr->b [cnt] -= 128 ; 537b815c7f3Sopenharmony_ci } 538b815c7f3Sopenharmony_ci } 539b815c7f3Sopenharmony_ci } 540b815c7f3Sopenharmony_ci 541b815c7f3Sopenharmony_ci for (cnt = 5 ; cnt > 0 ; cnt--) 542b815c7f3Sopenharmony_ci state_ptr->dq [cnt] = state_ptr->dq [cnt - 1] ; 543b815c7f3Sopenharmony_ci /* FLOAT A : convert dq [0] to 4-bit exp, 6-bit mantissa f.p. */ 544b815c7f3Sopenharmony_ci if (mag == 0) 545b815c7f3Sopenharmony_ci state_ptr->dq [0] = (dq >= 0) ? 0x20 : 0xFC20 ; 546b815c7f3Sopenharmony_ci else 547b815c7f3Sopenharmony_ci { expon = quan (mag, power2, 15) ; 548b815c7f3Sopenharmony_ci state_ptr->dq [0] = (dq >= 0) ? 549b815c7f3Sopenharmony_ci (expon << 6) + ((mag << 6) >> expon) : 550b815c7f3Sopenharmony_ci (expon << 6) + ((mag << 6) >> expon) - 0x400 ; 551b815c7f3Sopenharmony_ci } 552b815c7f3Sopenharmony_ci 553b815c7f3Sopenharmony_ci state_ptr->sr [1] = state_ptr->sr [0] ; 554b815c7f3Sopenharmony_ci /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */ 555b815c7f3Sopenharmony_ci if (sr == 0) 556b815c7f3Sopenharmony_ci state_ptr->sr [0] = 0x20 ; 557b815c7f3Sopenharmony_ci else if (sr > 0) 558b815c7f3Sopenharmony_ci { expon = quan (sr, power2, 15) ; 559b815c7f3Sopenharmony_ci state_ptr->sr [0] = (expon << 6) + ((sr << 6) >> expon) ; 560b815c7f3Sopenharmony_ci } 561b815c7f3Sopenharmony_ci else if (sr > -32768) 562b815c7f3Sopenharmony_ci { mag = -sr ; 563b815c7f3Sopenharmony_ci expon = quan (mag, power2, 15) ; 564b815c7f3Sopenharmony_ci state_ptr->sr [0] = (expon << 6) + ((mag << 6) >> expon) - 0x400 ; 565b815c7f3Sopenharmony_ci } 566b815c7f3Sopenharmony_ci else 567b815c7f3Sopenharmony_ci state_ptr->sr [0] = (short) 0xFC20 ; 568b815c7f3Sopenharmony_ci 569b815c7f3Sopenharmony_ci /* DELAY A */ 570b815c7f3Sopenharmony_ci state_ptr->pk [1] = state_ptr->pk [0] ; 571b815c7f3Sopenharmony_ci state_ptr->pk [0] = pk0 ; 572b815c7f3Sopenharmony_ci 573b815c7f3Sopenharmony_ci /* TONE */ 574b815c7f3Sopenharmony_ci if (tr == 1) /* this sample has been treated as data */ 575b815c7f3Sopenharmony_ci state_ptr->td = 0 ; /* next one will be treated as voice */ 576b815c7f3Sopenharmony_ci else if (a2p < -11776) /* small sample-to-sample correlation */ 577b815c7f3Sopenharmony_ci state_ptr->td = 1 ; /* signal may be data */ 578b815c7f3Sopenharmony_ci else /* signal is voice */ 579b815c7f3Sopenharmony_ci state_ptr->td = 0 ; 580b815c7f3Sopenharmony_ci 581b815c7f3Sopenharmony_ci /* 582b815c7f3Sopenharmony_ci * Adaptation speed control. 583b815c7f3Sopenharmony_ci */ 584b815c7f3Sopenharmony_ci state_ptr->dms += (fi - state_ptr->dms) >> 5 ; /* FILTA */ 585b815c7f3Sopenharmony_ci state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7) ; /* FILTB */ 586b815c7f3Sopenharmony_ci 587b815c7f3Sopenharmony_ci if (tr == 1) 588b815c7f3Sopenharmony_ci state_ptr->ap = 256 ; 589b815c7f3Sopenharmony_ci else if (y < 1536) /* SUBTC */ 590b815c7f3Sopenharmony_ci state_ptr->ap += (0x200 - state_ptr->ap) >> 4 ; 591b815c7f3Sopenharmony_ci else if (state_ptr->td == 1) 592b815c7f3Sopenharmony_ci state_ptr->ap += (0x200 - state_ptr->ap) >> 4 ; 593b815c7f3Sopenharmony_ci else if (abs ((state_ptr->dms << 2) - state_ptr->dml) >= (state_ptr->dml >> 3)) 594b815c7f3Sopenharmony_ci state_ptr->ap += (0x200 - state_ptr->ap) >> 4 ; 595b815c7f3Sopenharmony_ci else 596b815c7f3Sopenharmony_ci state_ptr->ap += (-state_ptr->ap) >> 4 ; 597b815c7f3Sopenharmony_ci 598b815c7f3Sopenharmony_ci return ; 599b815c7f3Sopenharmony_ci} /* update */ 600b815c7f3Sopenharmony_ci 601b815c7f3Sopenharmony_ci/*------------------------------------------------------------------------------ 602b815c7f3Sopenharmony_ci*/ 603b815c7f3Sopenharmony_ci 604b815c7f3Sopenharmony_cistatic int 605b815c7f3Sopenharmony_ciunpack_bytes (int bits, int blocksize, const unsigned char * block, short * samples) 606b815c7f3Sopenharmony_ci{ unsigned int in_buffer = 0 ; 607b815c7f3Sopenharmony_ci unsigned char in_byte ; 608b815c7f3Sopenharmony_ci int k, in_bits = 0, bindex = 0 ; 609b815c7f3Sopenharmony_ci 610b815c7f3Sopenharmony_ci for (k = 0 ; bindex <= blocksize && k < G72x_BLOCK_SIZE ; k++) 611b815c7f3Sopenharmony_ci { if (in_bits < bits) 612b815c7f3Sopenharmony_ci { in_byte = block [bindex++] ; 613b815c7f3Sopenharmony_ci 614b815c7f3Sopenharmony_ci in_buffer |= (in_byte << in_bits) ; 615b815c7f3Sopenharmony_ci in_bits += 8 ; 616b815c7f3Sopenharmony_ci } 617b815c7f3Sopenharmony_ci samples [k] = in_buffer & ((1 << bits) - 1) ; 618b815c7f3Sopenharmony_ci in_buffer >>= bits ; 619b815c7f3Sopenharmony_ci in_bits -= bits ; 620b815c7f3Sopenharmony_ci } ; 621b815c7f3Sopenharmony_ci 622b815c7f3Sopenharmony_ci return k ; 623b815c7f3Sopenharmony_ci} /* unpack_bytes */ 624b815c7f3Sopenharmony_ci 625b815c7f3Sopenharmony_cistatic int 626b815c7f3Sopenharmony_cipack_bytes (int bits, const short * samples, unsigned char * block) 627b815c7f3Sopenharmony_ci{ 628b815c7f3Sopenharmony_ci unsigned int out_buffer = 0 ; 629b815c7f3Sopenharmony_ci int k, bindex = 0, out_bits = 0 ; 630b815c7f3Sopenharmony_ci unsigned char out_byte ; 631b815c7f3Sopenharmony_ci 632b815c7f3Sopenharmony_ci for (k = 0 ; k < G72x_BLOCK_SIZE ; k++) 633b815c7f3Sopenharmony_ci { out_buffer |= (samples [k] << out_bits) ; 634b815c7f3Sopenharmony_ci out_bits += bits ; 635b815c7f3Sopenharmony_ci if (out_bits >= 8) 636b815c7f3Sopenharmony_ci { out_byte = out_buffer & 0xFF ; 637b815c7f3Sopenharmony_ci out_bits -= 8 ; 638b815c7f3Sopenharmony_ci out_buffer >>= 8 ; 639b815c7f3Sopenharmony_ci block [bindex++] = out_byte ; 640b815c7f3Sopenharmony_ci } 641b815c7f3Sopenharmony_ci } ; 642b815c7f3Sopenharmony_ci 643b815c7f3Sopenharmony_ci return bindex ; 644b815c7f3Sopenharmony_ci} /* pack_bytes */ 645b815c7f3Sopenharmony_ci 646