1 /* 2 ** Copyright 2003-2010, VisualOn, Inc. 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17 /*********************************************************************** 18 * File: voAMRWBEnc.c * 19 * * 20 * Description: Performs the main encoder routine * 21 * Fixed-point C simulation of AMR WB ACELP coding * 22 * algorithm with 20 msspeech frames for * 23 * wideband speech signals. * 24 * * 25 ************************************************************************/ 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include "typedef.h" 30 #include "basic_op.h" 31 #include "oper_32b.h" 32 #include "math_op.h" 33 #include "cnst.h" 34 #include "acelp.h" 35 #include "cod_main.h" 36 #include "bits.h" 37 #include "main.h" 38 #include "voAMRWB.h" 39 #include "mem_align.h" 40 #include "cmnMemory.h" 41 42 #define UNUSED(x) (void)(x) 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 48 /* LPC interpolation coef {0.45, 0.8, 0.96, 1.0}; in Q15 */ 49 static Word16 interpol_frac[NB_SUBFR] = {14746, 26214, 31457, 32767}; 50 51 /* isp tables for initialization */ 52 static Word16 isp_init[M] = 53 { 54 32138, 30274, 27246, 23170, 18205, 12540, 6393, 0, 55 -6393, -12540, -18205, -23170, -27246, -30274, -32138, 1475 56 }; 57 58 static Word16 isf_init[M] = 59 { 60 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 61 9216, 10240, 11264, 12288, 13312, 14336, 15360, 3840 62 }; 63 64 /* High Band encoding */ 65 static const Word16 HP_gain[16] = 66 { 67 3624, 4673, 5597, 6479, 7425, 8378, 9324, 10264, 68 11210, 12206, 13391, 14844, 16770, 19655, 24289, 32728 69 }; 70 71 /* Private function declaration */ 72 static Word16 synthesis( 73 Word16 Aq[], /* A(z) : quantized Az */ 74 Word16 exc[], /* (i) : excitation at 12kHz */ 75 Word16 Q_new, /* (i) : scaling performed on exc */ 76 Word16 synth16k[], /* (o) : 16kHz synthesis signal */ 77 Coder_State * st /* (i/o) : State structure */ 78 ); 79 80 /* Codec some parameters initialization */ 81 void Reset_encoder(void *st, Word16 reset_all) 82 { 83 Word16 i; 84 Coder_State *cod_state; 85 cod_state = (Coder_State *) st; 86 Set_zero(cod_state->old_exc, PIT_MAX + L_INTERPOL); 87 Set_zero(cod_state->mem_syn, M); 88 Set_zero(cod_state->past_isfq, M); 89 cod_state->mem_w0 = 0; 90 cod_state->tilt_code = 0; 91 cod_state->first_frame = 1; 92 Init_gp_clip(cod_state->gp_clip); 93 cod_state->L_gc_thres = 0; 94 if (reset_all != 0) 95 { 96 /* Static vectors to zero */ 97 Set_zero(cod_state->old_speech, L_TOTAL - L_FRAME); 98 Set_zero(cod_state->old_wsp, (PIT_MAX / OPL_DECIM)); 99 Set_zero(cod_state->mem_decim2, 3); 100 /* routines initialization */ 101 Init_Decim_12k8(cod_state->mem_decim); 102 Init_HP50_12k8(cod_state->mem_sig_in); 103 Init_Levinson(cod_state->mem_levinson); 104 Init_Q_gain2(cod_state->qua_gain); 105 Init_Hp_wsp(cod_state->hp_wsp_mem); 106 /* isp initialization */ 107 Copy(isp_init, cod_state->ispold, M); 108 Copy(isp_init, cod_state->ispold_q, M); 109 /* variable initialization */ 110 cod_state->mem_preemph = 0; 111 cod_state->mem_wsp = 0; 112 cod_state->Q_old = 15; 113 cod_state->Q_max[0] = 15; 114 cod_state->Q_max[1] = 15; 115 cod_state->old_wsp_max = 0; 116 cod_state->old_wsp_shift = 0; 117 /* pitch ol initialization */ 118 cod_state->old_T0_med = 40; 119 cod_state->ol_gain = 0; 120 cod_state->ada_w = 0; 121 cod_state->ol_wght_flg = 0; 122 for (i = 0; i < 5; i++) 123 { 124 cod_state->old_ol_lag[i] = 40; 125 } 126 Set_zero(cod_state->old_hp_wsp, (L_FRAME / 2) / OPL_DECIM + (PIT_MAX / OPL_DECIM)); 127 Set_zero(cod_state->mem_syn_hf, M); 128 Set_zero(cod_state->mem_syn_hi, M); 129 Set_zero(cod_state->mem_syn_lo, M); 130 Init_HP50_12k8(cod_state->mem_sig_out); 131 Init_Filt_6k_7k(cod_state->mem_hf); 132 Init_HP400_12k8(cod_state->mem_hp400); 133 Copy(isf_init, cod_state->isfold, M); 134 cod_state->mem_deemph = 0; 135 cod_state->seed2 = 21845; 136 Init_Filt_6k_7k(cod_state->mem_hf2); 137 cod_state->gain_alpha = 32767; 138 cod_state->vad_hist = 0; 139 wb_vad_reset(cod_state->vadSt); 140 dtx_enc_reset(cod_state->dtx_encSt, isf_init); 141 } 142 return; 143 } 144 145 /*-----------------------------------------------------------------* 146 * Funtion coder * 147 * ~~~~~ * 148 * ->Main coder routine. * 149 * * 150 *-----------------------------------------------------------------*/ 151 void coder( 152 Word16 * mode, /* input : used mode */ 153 Word16 speech16k[], /* input : 320 new speech samples (at 16 kHz) */ 154 Word16 prms[], /* output: output parameters */ 155 Word16 * ser_size, /* output: bit rate of the used mode */ 156 void *spe_state, /* i/o : State structure */ 157 Word16 allow_dtx /* input : DTX ON/OFF */ 158 ) 159 { 160 /* Coder states */ 161 Coder_State *st; 162 /* Speech vector */ 163 Word16 old_speech[L_TOTAL]; 164 Word16 *new_speech, *speech, *p_window; 165 166 /* Weighted speech vector */ 167 Word16 old_wsp[L_FRAME + (PIT_MAX / OPL_DECIM)]; 168 Word16 *wsp; 169 170 /* Excitation vector */ 171 Word16 old_exc[(L_FRAME + 1) + PIT_MAX + L_INTERPOL]; 172 Word16 *exc; 173 174 /* LPC coefficients */ 175 Word16 r_h[M + 1], r_l[M + 1]; /* Autocorrelations of windowed speech */ 176 Word16 rc[M]; /* Reflection coefficients. */ 177 Word16 Ap[M + 1]; /* A(z) with spectral expansion */ 178 Word16 ispnew[M]; /* immittance spectral pairs at 4nd sfr */ 179 Word16 ispnew_q[M]; /* quantized ISPs at 4nd subframe */ 180 Word16 isf[M]; /* ISF (frequency domain) at 4nd sfr */ 181 Word16 *p_A, *p_Aq; /* ptr to A(z) for the 4 subframes */ 182 Word16 A[NB_SUBFR * (M + 1)]; /* A(z) unquantized for the 4 subframes */ 183 Word16 Aq[NB_SUBFR * (M + 1)]; /* A(z) quantized for the 4 subframes */ 184 185 /* Other vectors */ 186 Word16 xn[L_SUBFR]; /* Target vector for pitch search */ 187 Word16 xn2[L_SUBFR]; /* Target vector for codebook search */ 188 Word16 dn[L_SUBFR]; /* Correlation between xn2 and h1 */ 189 Word16 cn[L_SUBFR]; /* Target vector in residual domain */ 190 Word16 h1[L_SUBFR]; /* Impulse response vector */ 191 Word16 h2[L_SUBFR]; /* Impulse response vector */ 192 Word16 code[L_SUBFR]; /* Fixed codebook excitation */ 193 Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */ 194 Word16 y2[L_SUBFR]; /* Filtered adaptive excitation */ 195 Word16 error[M + L_SUBFR]; /* error of quantization */ 196 Word16 synth[L_SUBFR]; /* 12.8kHz synthesis vector */ 197 Word16 exc2[L_FRAME]; /* excitation vector */ 198 Word16 buf[L_FRAME]; /* VAD buffer */ 199 200 /* Scalars */ 201 Word32 i, j, i_subfr, select, pit_flag, clip_gain, vad_flag; 202 Word16 codec_mode; 203 Word16 T_op, T_op2, T0, T0_min, T0_max, T0_frac, index; 204 Word16 gain_pit, gain_code, g_coeff[4], g_coeff2[4]; 205 Word16 tmp, gain1, gain2, exp, Q_new, mu, shift, max; 206 Word16 voice_fac; 207 Word16 indice[8]; 208 Word32 L_tmp, L_gain_code, L_max, L_tmp1; 209 Word16 code2[L_SUBFR]; /* Fixed codebook excitation */ 210 Word16 stab_fac, fac, gain_code_lo; 211 212 Word16 corr_gain; 213 Word16 *vo_p0, *vo_p1, *vo_p2, *vo_p3; 214 215 st = (Coder_State *) spe_state; 216 217 *ser_size = nb_of_bits[*mode]; 218 codec_mode = *mode; 219 220 /*--------------------------------------------------------------------------* 221 * Initialize pointers to speech vector. * 222 * * 223 * * 224 * |-------|-------|-------|-------|-------|-------| * 225 * past sp sf1 sf2 sf3 sf4 L_NEXT * 226 * <------- Total speech buffer (L_TOTAL) ------> * 227 * old_speech * 228 * <------- LPC analysis window (L_WINDOW) ------> * 229 * | <-- present frame (L_FRAME) ----> * 230 * p_window | <----- new speech (L_FRAME) ----> * 231 * | | * 232 * speech | * 233 * new_speech * 234 *--------------------------------------------------------------------------*/ 235 236 new_speech = old_speech + L_TOTAL - L_FRAME - L_FILT; /* New speech */ 237 speech = old_speech + L_TOTAL - L_FRAME - L_NEXT; /* Present frame */ 238 p_window = old_speech + L_TOTAL - L_WINDOW; 239 240 exc = old_exc + PIT_MAX + L_INTERPOL; 241 wsp = old_wsp + (PIT_MAX / OPL_DECIM); 242 243 /* copy coder memory state into working space */ 244 Copy(st->old_speech, old_speech, L_TOTAL - L_FRAME); 245 Copy(st->old_wsp, old_wsp, PIT_MAX / OPL_DECIM); 246 Copy(st->old_exc, old_exc, PIT_MAX + L_INTERPOL); 247 248 /*---------------------------------------------------------------* 249 * Down sampling signal from 16kHz to 12.8kHz * 250 * -> The signal is extended by L_FILT samples (padded to zero) * 251 * to avoid additional delay (L_FILT samples) in the coder. * 252 * The last L_FILT samples are approximated after decimation and * 253 * are used (and windowed) only in autocorrelations. * 254 *---------------------------------------------------------------*/ 255 256 Decim_12k8(speech16k, L_FRAME16k, new_speech, st->mem_decim); 257 258 /* last L_FILT samples for autocorrelation window */ 259 Copy(st->mem_decim, code, 2 * L_FILT16k); 260 Set_zero(error, L_FILT16k); /* set next sample to zero */ 261 Decim_12k8(error, L_FILT16k, new_speech + L_FRAME, code); 262 263 /*---------------------------------------------------------------* 264 * Perform 50Hz HP filtering of input signal. * 265 *---------------------------------------------------------------*/ 266 267 HP50_12k8(new_speech, L_FRAME, st->mem_sig_in); 268 269 /* last L_FILT samples for autocorrelation window */ 270 Copy(st->mem_sig_in, code, 6); 271 HP50_12k8(new_speech + L_FRAME, L_FILT, code); 272 273 /*---------------------------------------------------------------* 274 * Perform fixed preemphasis through 1 - g z^-1 * 275 * Scale signal to get maximum of precision in filtering * 276 *---------------------------------------------------------------*/ 277 278 mu = PREEMPH_FAC >> 1; /* Q15 --> Q14 */ 279 280 /* get max of new preemphased samples (L_FRAME+L_FILT) */ 281 L_tmp = new_speech[0] << 15; 282 L_tmp -= (st->mem_preemph * mu)<<1; 283 L_max = L_abs(L_tmp); 284 285 for (i = 1; i < L_FRAME + L_FILT; i++) 286 { 287 L_tmp = new_speech[i] << 15; 288 L_tmp -= (new_speech[i - 1] * mu)<<1; 289 L_tmp = L_abs(L_tmp); 290 if(L_tmp > L_max) 291 { 292 L_max = L_tmp; 293 } 294 } 295 296 /* get scaling factor for new and previous samples */ 297 /* limit scaling to Q_MAX to keep dynamic for ringing in low signal */ 298 /* limit scaling to Q_MAX also to avoid a[0]<1 in syn_filt_32 */ 299 tmp = extract_h(L_max); 300 if (tmp == 0) 301 { 302 shift = Q_MAX; 303 } else 304 { 305 shift = norm_s(tmp) - 1; 306 if (shift < 0) 307 { 308 shift = 0; 309 } 310 if (shift > Q_MAX) 311 { 312 shift = Q_MAX; 313 } 314 } 315 Q_new = shift; 316 if (Q_new > st->Q_max[0]) 317 { 318 Q_new = st->Q_max[0]; 319 } 320 if (Q_new > st->Q_max[1]) 321 { 322 Q_new = st->Q_max[1]; 323 } 324 exp = (Q_new - st->Q_old); 325 st->Q_old = Q_new; 326 st->Q_max[1] = st->Q_max[0]; 327 st->Q_max[0] = shift; 328 329 /* preemphasis with scaling (L_FRAME+L_FILT) */ 330 tmp = new_speech[L_FRAME - 1]; 331 332 for (i = L_FRAME + L_FILT - 1; i > 0; i--) 333 { 334 L_tmp = new_speech[i] << 15; 335 L_tmp -= (new_speech[i - 1] * mu)<<1; 336 L_tmp = (L_tmp << Q_new); 337 new_speech[i] = vo_round(L_tmp); 338 } 339 340 L_tmp = new_speech[0] << 15; 341 L_tmp -= (st->mem_preemph * mu)<<1; 342 L_tmp = (L_tmp << Q_new); 343 new_speech[0] = vo_round(L_tmp); 344 345 st->mem_preemph = tmp; 346 347 /* scale previous samples and memory */ 348 349 Scale_sig(old_speech, L_TOTAL - L_FRAME - L_FILT, exp); 350 Scale_sig(old_exc, PIT_MAX + L_INTERPOL, exp); 351 Scale_sig(st->mem_syn, M, exp); 352 Scale_sig(st->mem_decim2, 3, exp); 353 Scale_sig(&(st->mem_wsp), 1, exp); 354 Scale_sig(&(st->mem_w0), 1, exp); 355 356 /*------------------------------------------------------------------------* 357 * Call VAD * 358 * Preemphesis scale down signal in low frequency and keep dynamic in HF.* 359 * Vad work slightly in futur (new_speech = speech + L_NEXT - L_FILT). * 360 *------------------------------------------------------------------------*/ 361 Copy(new_speech, buf, L_FRAME); 362 363 #ifdef ASM_OPT /* asm optimization branch */ 364 Scale_sig_opt(buf, L_FRAME, 1 - Q_new); 365 #else 366 Scale_sig(buf, L_FRAME, 1 - Q_new); 367 #endif 368 369 vad_flag = wb_vad(st->vadSt, buf); /* Voice Activity Detection */ 370 if (vad_flag == 0) 371 { 372 st->vad_hist = (st->vad_hist + 1); 373 } else 374 { 375 st->vad_hist = 0; 376 } 377 378 /* DTX processing */ 379 if (allow_dtx != 0) 380 { 381 /* Note that mode may change here */ 382 tx_dtx_handler(st->dtx_encSt, vad_flag, mode); 383 *ser_size = nb_of_bits[*mode]; 384 } 385 386 if(*mode != MRDTX) 387 { 388 Parm_serial(vad_flag, 1, &prms); 389 } 390 /*------------------------------------------------------------------------* 391 * Perform LPC analysis * 392 * ~~~~~~~~~~~~~~~~~~~~ * 393 * - autocorrelation + lag windowing * 394 * - Levinson-durbin algorithm to find a[] * 395 * - convert a[] to isp[] * 396 * - convert isp[] to isf[] for quantization * 397 * - quantize and code the isf[] * 398 * - convert isf[] to isp[] for interpolation * 399 * - find the interpolated ISPs and convert to a[] for the 4 subframes * 400 *------------------------------------------------------------------------*/ 401 402 /* LP analysis centered at 4nd subframe */ 403 Autocorr(p_window, M, r_h, r_l); /* Autocorrelations */ 404 Lag_window(r_h, r_l); /* Lag windowing */ 405 Levinson(r_h, r_l, A, rc, st->mem_levinson); /* Levinson Durbin */ 406 Az_isp(A, ispnew, st->ispold); /* From A(z) to ISP */ 407 408 /* Find the interpolated ISPs and convert to a[] for all subframes */ 409 Int_isp(st->ispold, ispnew, interpol_frac, A); 410 411 /* update ispold[] for the next frame */ 412 Copy(ispnew, st->ispold, M); 413 414 /* Convert ISPs to frequency domain 0..6400 */ 415 Isp_isf(ispnew, isf, M); 416 417 /* check resonance for pitch clipping algorithm */ 418 Gp_clip_test_isf(isf, st->gp_clip); 419 420 /*----------------------------------------------------------------------* 421 * Perform PITCH_OL analysis * 422 * ~~~~~~~~~~~~~~~~~~~~~~~~~ * 423 * - Find the residual res[] for the whole speech frame * 424 * - Find the weighted input speech wsp[] for the whole speech frame * 425 * - scale wsp[] to avoid overflow in pitch estimation * 426 * - Find open loop pitch lag for whole speech frame * 427 *----------------------------------------------------------------------*/ 428 p_A = A; 429 for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) 430 { 431 /* Weighting of LPC coefficients */ 432 Weight_a(p_A, Ap, GAMMA1, M); 433 434 #ifdef ASM_OPT /* asm optimization branch */ 435 Residu_opt(Ap, &speech[i_subfr], &wsp[i_subfr], L_SUBFR); 436 #else 437 Residu(Ap, &speech[i_subfr], &wsp[i_subfr], L_SUBFR); 438 #endif 439 440 p_A += (M + 1); 441 } 442 443 Deemph2(wsp, TILT_FAC, L_FRAME, &(st->mem_wsp)); 444 445 /* find maximum value on wsp[] for 12 bits scaling */ 446 max = 0; 447 for (i = 0; i < L_FRAME; i++) 448 { 449 tmp = abs_s(wsp[i]); 450 if(tmp > max) 451 { 452 max = tmp; 453 } 454 } 455 tmp = st->old_wsp_max; 456 if(max > tmp) 457 { 458 tmp = max; /* tmp = max(wsp_max, old_wsp_max) */ 459 } 460 st->old_wsp_max = max; 461 462 shift = norm_s(tmp) - 3; 463 if (shift > 0) 464 { 465 shift = 0; /* shift = 0..-3 */ 466 } 467 /* decimation of wsp[] to search pitch in LF and to reduce complexity */ 468 LP_Decim2(wsp, L_FRAME, st->mem_decim2); 469 470 /* scale wsp[] in 12 bits to avoid overflow */ 471 #ifdef ASM_OPT /* asm optimization branch */ 472 Scale_sig_opt(wsp, L_FRAME / OPL_DECIM, shift); 473 #else 474 Scale_sig(wsp, L_FRAME / OPL_DECIM, shift); 475 #endif 476 /* scale old_wsp (warning: exp must be Q_new-Q_old) */ 477 exp = exp + (shift - st->old_wsp_shift); 478 st->old_wsp_shift = shift; 479 480 Scale_sig(old_wsp, PIT_MAX / OPL_DECIM, exp); 481 Scale_sig(st->old_hp_wsp, PIT_MAX / OPL_DECIM, exp); 482 483 scale_mem_Hp_wsp(st->hp_wsp_mem, exp); 484 485 /* Find open loop pitch lag for whole speech frame */ 486 487 if(*ser_size == NBBITS_7k) 488 { 489 /* Find open loop pitch lag for whole speech frame */ 490 T_op = Pitch_med_ol(wsp, st, L_FRAME / OPL_DECIM); 491 } else 492 { 493 /* Find open loop pitch lag for first 1/2 frame */ 494 T_op = Pitch_med_ol(wsp, st, (L_FRAME/2) / OPL_DECIM); 495 } 496 497 if(st->ol_gain > 19661) /* 0.6 in Q15 */ 498 { 499 st->old_T0_med = Med_olag(T_op, st->old_ol_lag); 500 st->ada_w = 32767; 501 } else 502 { 503 st->ada_w = vo_mult(st->ada_w, 29491); 504 } 505 506 if(st->ada_w < 26214) 507 st->ol_wght_flg = 0; 508 else 509 st->ol_wght_flg = 1; 510 511 wb_vad_tone_detection(st->vadSt, st->ol_gain); 512 T_op *= OPL_DECIM; 513 514 if(*ser_size != NBBITS_7k) 515 { 516 /* Find open loop pitch lag for second 1/2 frame */ 517 T_op2 = Pitch_med_ol(wsp + ((L_FRAME / 2) / OPL_DECIM), st, (L_FRAME/2) / OPL_DECIM); 518 519 if(st->ol_gain > 19661) /* 0.6 in Q15 */ 520 { 521 st->old_T0_med = Med_olag(T_op2, st->old_ol_lag); 522 st->ada_w = 32767; 523 } else 524 { 525 st->ada_w = mult(st->ada_w, 29491); 526 } 527 528 if(st->ada_w < 26214) 529 st->ol_wght_flg = 0; 530 else 531 st->ol_wght_flg = 1; 532 533 wb_vad_tone_detection(st->vadSt, st->ol_gain); 534 535 T_op2 *= OPL_DECIM; 536 537 } else 538 { 539 T_op2 = T_op; 540 } 541 /*----------------------------------------------------------------------* 542 * DTX-CNG * 543 *----------------------------------------------------------------------*/ 544 if(*mode == MRDTX) /* CNG mode */ 545 { 546 /* Buffer isf's and energy */ 547 #ifdef ASM_OPT /* asm optimization branch */ 548 Residu_opt(&A[3 * (M + 1)], speech, exc, L_FRAME); 549 #else 550 Residu(&A[3 * (M + 1)], speech, exc, L_FRAME); 551 #endif 552 553 for (i = 0; i < L_FRAME; i++) 554 { 555 exc2[i] = shr(exc[i], Q_new); 556 } 557 558 L_tmp = 0; 559 for (i = 0; i < L_FRAME; i++) 560 L_tmp += (exc2[i] * exc2[i])<<1; 561 562 L_tmp >>= 1; 563 564 dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode); 565 566 /* Quantize and code the ISFs */ 567 dtx_enc(st->dtx_encSt, isf, exc2, &prms); 568 569 /* Convert ISFs to the cosine domain */ 570 Isf_isp(isf, ispnew_q, M); 571 Isp_Az(ispnew_q, Aq, M, 0); 572 573 for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) 574 { 575 corr_gain = synthesis(Aq, &exc2[i_subfr], 0, &speech16k[i_subfr * 5 / 4], st); 576 } 577 Copy(isf, st->isfold, M); 578 579 /* reset speech coder memories */ 580 Reset_encoder(st, 0); 581 582 /*--------------------------------------------------* 583 * Update signal for next frame. * 584 * -> save past of speech[] and wsp[]. * 585 *--------------------------------------------------*/ 586 587 Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME); 588 Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM); 589 590 return; 591 } 592 /*----------------------------------------------------------------------* 593 * ACELP * 594 *----------------------------------------------------------------------*/ 595 596 /* Quantize and code the ISFs */ 597 598 if (*ser_size <= NBBITS_7k) 599 { 600 Qpisf_2s_36b(isf, isf, st->past_isfq, indice, 4); 601 602 Parm_serial(indice[0], 8, &prms); 603 Parm_serial(indice[1], 8, &prms); 604 Parm_serial(indice[2], 7, &prms); 605 Parm_serial(indice[3], 7, &prms); 606 Parm_serial(indice[4], 6, &prms); 607 } else 608 { 609 Qpisf_2s_46b(isf, isf, st->past_isfq, indice, 4); 610 611 Parm_serial(indice[0], 8, &prms); 612 Parm_serial(indice[1], 8, &prms); 613 Parm_serial(indice[2], 6, &prms); 614 Parm_serial(indice[3], 7, &prms); 615 Parm_serial(indice[4], 7, &prms); 616 Parm_serial(indice[5], 5, &prms); 617 Parm_serial(indice[6], 5, &prms); 618 } 619 620 /* Check stability on isf : distance between old isf and current isf */ 621 622 L_tmp = 0; 623 for (i = 0; i < M - 1; i++) 624 { 625 tmp = vo_sub(isf[i], st->isfold[i]); 626 L_tmp += (tmp * tmp)<<1; 627 } 628 629 tmp = extract_h(L_shl2(L_tmp, 8)); 630 631 tmp = vo_mult(tmp, 26214); /* tmp = L_tmp*0.8/256 */ 632 tmp = vo_sub(20480, tmp); /* 1.25 - tmp (in Q14) */ 633 634 stab_fac = shl(tmp, 1); 635 636 if (stab_fac < 0) 637 { 638 stab_fac = 0; 639 } 640 Copy(isf, st->isfold, M); 641 642 /* Convert ISFs to the cosine domain */ 643 Isf_isp(isf, ispnew_q, M); 644 645 if (st->first_frame != 0) 646 { 647 st->first_frame = 0; 648 Copy(ispnew_q, st->ispold_q, M); 649 } 650 /* Find the interpolated ISPs and convert to a[] for all subframes */ 651 652 Int_isp(st->ispold_q, ispnew_q, interpol_frac, Aq); 653 654 /* update ispold[] for the next frame */ 655 Copy(ispnew_q, st->ispold_q, M); 656 657 p_Aq = Aq; 658 for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) 659 { 660 #ifdef ASM_OPT /* asm optimization branch */ 661 Residu_opt(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR); 662 #else 663 Residu(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR); 664 #endif 665 p_Aq += (M + 1); 666 } 667 668 /* Buffer isf's and energy for dtx on non-speech frame */ 669 if (vad_flag == 0) 670 { 671 for (i = 0; i < L_FRAME; i++) 672 { 673 exc2[i] = exc[i] >> Q_new; 674 } 675 L_tmp = 0; 676 for (i = 0; i < L_FRAME; i++) { 677 Word32 tmp = L_mult(exc2[i], exc2[i]); // (exc2[i] * exc2[i])<<1; 678 L_tmp = L_add(L_tmp, tmp); 679 } 680 L_tmp >>= 1; 681 682 dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode); 683 } 684 /* range for closed loop pitch search in 1st subframe */ 685 686 T0_min = T_op - 8; 687 if (T0_min < PIT_MIN) 688 { 689 T0_min = PIT_MIN; 690 } 691 T0_max = (T0_min + 15); 692 693 if(T0_max > PIT_MAX) 694 { 695 T0_max = PIT_MAX; 696 T0_min = T0_max - 15; 697 } 698 /*------------------------------------------------------------------------* 699 * Loop for every subframe in the analysis frame * 700 *------------------------------------------------------------------------* 701 * To find the pitch and innovation parameters. The subframe size is * 702 * L_SUBFR and the loop is repeated L_FRAME/L_SUBFR times. * 703 * - compute the target signal for pitch search * 704 * - compute impulse response of weighted synthesis filter (h1[]) * 705 * - find the closed-loop pitch parameters * 706 * - encode the pitch dealy * 707 * - find 2 lt prediction (with / without LP filter for lt pred) * 708 * - find 2 pitch gains and choose the best lt prediction. * 709 * - find target vector for codebook search * 710 * - update the impulse response h1[] for codebook search * 711 * - correlation between target vector and impulse response * 712 * - codebook search and encoding * 713 * - VQ of pitch and codebook gains * 714 * - find voicing factor and tilt of code for next subframe. * 715 * - update states of weighting filter * 716 * - find excitation and synthesis speech * 717 *------------------------------------------------------------------------*/ 718 p_A = A; 719 p_Aq = Aq; 720 for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) 721 { 722 pit_flag = i_subfr; 723 if ((i_subfr == 2 * L_SUBFR) && (*ser_size > NBBITS_7k)) 724 { 725 pit_flag = 0; 726 /* range for closed loop pitch search in 3rd subframe */ 727 T0_min = (T_op2 - 8); 728 729 if (T0_min < PIT_MIN) 730 { 731 T0_min = PIT_MIN; 732 } 733 T0_max = (T0_min + 15); 734 if (T0_max > PIT_MAX) 735 { 736 T0_max = PIT_MAX; 737 T0_min = (T0_max - 15); 738 } 739 } 740 /*-----------------------------------------------------------------------* 741 * * 742 * Find the target vector for pitch search: * 743 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * 744 * * 745 * |------| res[n] * 746 * speech[n]---| A(z) |-------- * 747 * |------| | |--------| error[n] |------| * 748 * zero -- (-)--| 1/A(z) |-----------| W(z) |-- target * 749 * exc |--------| |------| * 750 * * 751 * Instead of subtracting the zero-input response of filters from * 752 * the weighted input speech, the above configuration is used to * 753 * compute the target vector. * 754 * * 755 *-----------------------------------------------------------------------*/ 756 757 for (i = 0; i < M; i++) 758 { 759 error[i] = vo_sub(speech[i + i_subfr - M], st->mem_syn[i]); 760 } 761 762 #ifdef ASM_OPT /* asm optimization branch */ 763 Residu_opt(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR); 764 #else 765 Residu(p_Aq, &speech[i_subfr], &exc[i_subfr], L_SUBFR); 766 #endif 767 Syn_filt(p_Aq, &exc[i_subfr], error + M, L_SUBFR, error, 0); 768 Weight_a(p_A, Ap, GAMMA1, M); 769 770 #ifdef ASM_OPT /* asm optimization branch */ 771 Residu_opt(Ap, error + M, xn, L_SUBFR); 772 #else 773 Residu(Ap, error + M, xn, L_SUBFR); 774 #endif 775 Deemph2(xn, TILT_FAC, L_SUBFR, &(st->mem_w0)); 776 777 /*----------------------------------------------------------------------* 778 * Find approx. target in residual domain "cn[]" for inovation search. * 779 *----------------------------------------------------------------------*/ 780 /* first half: xn[] --> cn[] */ 781 Set_zero(code, M); 782 Copy(xn, code + M, L_SUBFR / 2); 783 tmp = 0; 784 Preemph2(code + M, TILT_FAC, L_SUBFR / 2, &tmp); 785 Weight_a(p_A, Ap, GAMMA1, M); 786 Syn_filt(Ap,code + M, code + M, L_SUBFR / 2, code, 0); 787 788 #ifdef ASM_OPT /* asm optimization branch */ 789 Residu_opt(p_Aq,code + M, cn, L_SUBFR / 2); 790 #else 791 Residu(p_Aq,code + M, cn, L_SUBFR / 2); 792 #endif 793 794 /* second half: res[] --> cn[] (approximated and faster) */ 795 Copy(&exc[i_subfr + (L_SUBFR / 2)], cn + (L_SUBFR / 2), L_SUBFR / 2); 796 797 /*---------------------------------------------------------------* 798 * Compute impulse response, h1[], of weighted synthesis filter * 799 *---------------------------------------------------------------*/ 800 801 Set_zero(error, M + L_SUBFR); 802 Weight_a(p_A, error + M, GAMMA1, M); 803 804 vo_p0 = error+M; 805 vo_p3 = h1; 806 for (i = 0; i < L_SUBFR; i++) 807 { 808 L_tmp = *vo_p0 << 14; /* x4 (Q12 to Q14) */ 809 vo_p1 = p_Aq + 1; 810 vo_p2 = vo_p0-1; 811 for (j = 1; j <= M/4; j++) 812 { 813 L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--); 814 L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--); 815 L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--); 816 L_tmp = L_sub(L_tmp, *vo_p1++ * *vo_p2--); 817 } 818 *vo_p3++ = *vo_p0++ = vo_round((L_tmp <<4)); 819 } 820 /* deemph without division by 2 -> Q14 to Q15 */ 821 tmp = 0; 822 Deemph2(h1, TILT_FAC, L_SUBFR, &tmp); /* h1 in Q14 */ 823 824 /* h2 in Q12 for codebook search */ 825 Copy(h1, h2, L_SUBFR); 826 827 /*---------------------------------------------------------------* 828 * scale xn[] and h1[] to avoid overflow in dot_product12() * 829 *---------------------------------------------------------------*/ 830 #ifdef ASM_OPT /* asm optimization branch */ 831 Scale_sig_opt(h2, L_SUBFR, -2); 832 Scale_sig_opt(xn, L_SUBFR, shift); /* scaling of xn[] to limit dynamic at 12 bits */ 833 Scale_sig_opt(h1, L_SUBFR, 1 + shift); /* set h1[] in Q15 with scaling for convolution */ 834 #else 835 Scale_sig(h2, L_SUBFR, -2); 836 Scale_sig(xn, L_SUBFR, shift); /* scaling of xn[] to limit dynamic at 12 bits */ 837 Scale_sig(h1, L_SUBFR, 1 + shift); /* set h1[] in Q15 with scaling for convolution */ 838 #endif 839 /*----------------------------------------------------------------------* 840 * Closed-loop fractional pitch search * 841 *----------------------------------------------------------------------*/ 842 /* find closed loop fractional pitch lag */ 843 if(*ser_size <= NBBITS_9k) 844 { 845 T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac, 846 pit_flag, PIT_MIN, PIT_FR1_8b, L_SUBFR); 847 848 /* encode pitch lag */ 849 if (pit_flag == 0) /* if 1st/3rd subframe */ 850 { 851 /*--------------------------------------------------------------* 852 * The pitch range for the 1st/3rd subframe is encoded with * 853 * 8 bits and is divided as follows: * 854 * PIT_MIN to PIT_FR1-1 resolution 1/2 (frac = 0 or 2) * 855 * PIT_FR1 to PIT_MAX resolution 1 (frac = 0) * 856 *--------------------------------------------------------------*/ 857 if (T0 < PIT_FR1_8b) 858 { 859 index = ((T0 << 1) + (T0_frac >> 1) - (PIT_MIN<<1)); 860 } else 861 { 862 index = ((T0 - PIT_FR1_8b) + ((PIT_FR1_8b - PIT_MIN)*2)); 863 } 864 865 Parm_serial(index, 8, &prms); 866 867 /* find T0_min and T0_max for subframe 2 and 4 */ 868 T0_min = (T0 - 8); 869 if (T0_min < PIT_MIN) 870 { 871 T0_min = PIT_MIN; 872 } 873 T0_max = T0_min + 15; 874 if (T0_max > PIT_MAX) 875 { 876 T0_max = PIT_MAX; 877 T0_min = (T0_max - 15); 878 } 879 } else 880 { /* if subframe 2 or 4 */ 881 /*--------------------------------------------------------------* 882 * The pitch range for subframe 2 or 4 is encoded with 5 bits: * 883 * T0_min to T0_max resolution 1/2 (frac = 0 or 2) * 884 *--------------------------------------------------------------*/ 885 i = (T0 - T0_min); 886 index = (i << 1) + (T0_frac >> 1); 887 888 Parm_serial(index, 5, &prms); 889 } 890 } else 891 { 892 T0 = Pitch_fr4(&exc[i_subfr], xn, h1, T0_min, T0_max, &T0_frac, 893 pit_flag, PIT_FR2, PIT_FR1_9b, L_SUBFR); 894 895 /* encode pitch lag */ 896 if (pit_flag == 0) /* if 1st/3rd subframe */ 897 { 898 /*--------------------------------------------------------------* 899 * The pitch range for the 1st/3rd subframe is encoded with * 900 * 9 bits and is divided as follows: * 901 * PIT_MIN to PIT_FR2-1 resolution 1/4 (frac = 0,1,2 or 3) * 902 * PIT_FR2 to PIT_FR1-1 resolution 1/2 (frac = 0 or 1) * 903 * PIT_FR1 to PIT_MAX resolution 1 (frac = 0) * 904 *--------------------------------------------------------------*/ 905 906 if (T0 < PIT_FR2) 907 { 908 index = ((T0 << 2) + T0_frac) - (PIT_MIN << 2); 909 } else if(T0 < PIT_FR1_9b) 910 { 911 index = ((((T0 << 1) + (T0_frac >> 1)) - (PIT_FR2<<1)) + ((PIT_FR2 - PIT_MIN)<<2)); 912 } else 913 { 914 index = (((T0 - PIT_FR1_9b) + ((PIT_FR2 - PIT_MIN)<<2)) + ((PIT_FR1_9b - PIT_FR2)<<1)); 915 } 916 917 Parm_serial(index, 9, &prms); 918 919 /* find T0_min and T0_max for subframe 2 and 4 */ 920 921 T0_min = (T0 - 8); 922 if (T0_min < PIT_MIN) 923 { 924 T0_min = PIT_MIN; 925 } 926 T0_max = T0_min + 15; 927 928 if (T0_max > PIT_MAX) 929 { 930 T0_max = PIT_MAX; 931 T0_min = (T0_max - 15); 932 } 933 } else 934 { /* if subframe 2 or 4 */ 935 /*--------------------------------------------------------------* 936 * The pitch range for subframe 2 or 4 is encoded with 6 bits: * 937 * T0_min to T0_max resolution 1/4 (frac = 0,1,2 or 3) * 938 *--------------------------------------------------------------*/ 939 i = (T0 - T0_min); 940 index = (i << 2) + T0_frac; 941 Parm_serial(index, 6, &prms); 942 } 943 } 944 945 /*-----------------------------------------------------------------* 946 * Gain clipping test to avoid unstable synthesis on frame erasure * 947 *-----------------------------------------------------------------*/ 948 949 clip_gain = 0; 950 if((st->gp_clip[0] < 154) && (st->gp_clip[1] > 14746)) 951 clip_gain = 1; 952 953 /*-----------------------------------------------------------------* 954 * - find unity gain pitch excitation (adaptive codebook entry) * 955 * with fractional interpolation. * 956 * - find filtered pitch exc. y1[]=exc[] convolved with h1[]) * 957 * - compute pitch gain1 * 958 *-----------------------------------------------------------------*/ 959 /* find pitch exitation */ 960 #ifdef ASM_OPT /* asm optimization branch */ 961 pred_lt4_asm(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1); 962 #else 963 Pred_lt4(&exc[i_subfr], T0, T0_frac, L_SUBFR + 1); 964 #endif 965 if (*ser_size > NBBITS_9k) 966 { 967 #ifdef ASM_OPT /* asm optimization branch */ 968 Convolve_asm(&exc[i_subfr], h1, y1, L_SUBFR); 969 #else 970 Convolve(&exc[i_subfr], h1, y1, L_SUBFR); 971 #endif 972 gain1 = G_pitch(xn, y1, g_coeff, L_SUBFR); 973 /* clip gain if necessary to avoid problem at decoder */ 974 if ((clip_gain != 0) && (gain1 > GP_CLIP)) 975 { 976 gain1 = GP_CLIP; 977 } 978 /* find energy of new target xn2[] */ 979 Updt_tar(xn, dn, y1, gain1, L_SUBFR); /* dn used temporary */ 980 } else 981 { 982 gain1 = 0; 983 } 984 /*-----------------------------------------------------------------* 985 * - find pitch excitation filtered by 1st order LP filter. * 986 * - find filtered pitch exc. y2[]=exc[] convolved with h1[]) * 987 * - compute pitch gain2 * 988 *-----------------------------------------------------------------*/ 989 /* find pitch excitation with lp filter */ 990 vo_p0 = exc + i_subfr-1; 991 vo_p1 = code; 992 /* find pitch excitation with lp filter */ 993 for (i = 0; i < L_SUBFR/2; i++) 994 { 995 L_tmp = 5898 * *vo_p0++; 996 L_tmp1 = 5898 * *vo_p0; 997 L_tmp += 20972 * *vo_p0++; 998 L_tmp1 += 20972 * *vo_p0++; 999 L_tmp1 += 5898 * *vo_p0--; 1000 L_tmp += 5898 * *vo_p0; 1001 *vo_p1++ = (L_tmp + 0x4000)>>15; 1002 *vo_p1++ = (L_tmp1 + 0x4000)>>15; 1003 } 1004 1005 #ifdef ASM_OPT /* asm optimization branch */ 1006 Convolve_asm(code, h1, y2, L_SUBFR); 1007 #else 1008 Convolve(code, h1, y2, L_SUBFR); 1009 #endif 1010 1011 gain2 = G_pitch(xn, y2, g_coeff2, L_SUBFR); 1012 1013 /* clip gain if necessary to avoid problem at decoder */ 1014 if ((clip_gain != 0) && (gain2 > GP_CLIP)) 1015 { 1016 gain2 = GP_CLIP; 1017 } 1018 /* find energy of new target xn2[] */ 1019 Updt_tar(xn, xn2, y2, gain2, L_SUBFR); 1020 /*-----------------------------------------------------------------* 1021 * use the best prediction (minimise quadratic error). * 1022 *-----------------------------------------------------------------*/ 1023 select = 0; 1024 if(*ser_size > NBBITS_9k) 1025 { 1026 L_tmp = 0L; 1027 vo_p0 = dn; 1028 vo_p1 = xn2; 1029 for (i = 0; i < L_SUBFR/2; i++) 1030 { 1031 L_tmp = L_add(L_tmp, *vo_p0 * *vo_p0); 1032 vo_p0++; 1033 L_tmp = L_sub(L_tmp, *vo_p1 * *vo_p1); 1034 vo_p1++; 1035 L_tmp = L_add(L_tmp, *vo_p0 * *vo_p0); 1036 vo_p0++; 1037 L_tmp = L_sub(L_tmp, *vo_p1 * *vo_p1); 1038 vo_p1++; 1039 } 1040 1041 if (L_tmp <= 0) 1042 { 1043 select = 1; 1044 } 1045 Parm_serial(select, 1, &prms); 1046 } 1047 if (select == 0) 1048 { 1049 /* use the lp filter for pitch excitation prediction */ 1050 gain_pit = gain2; 1051 Copy(code, &exc[i_subfr], L_SUBFR); 1052 Copy(y2, y1, L_SUBFR); 1053 Copy(g_coeff2, g_coeff, 4); 1054 } else 1055 { 1056 /* no filter used for pitch excitation prediction */ 1057 gain_pit = gain1; 1058 Copy(dn, xn2, L_SUBFR); /* target vector for codebook search */ 1059 } 1060 /*-----------------------------------------------------------------* 1061 * - update cn[] for codebook search * 1062 *-----------------------------------------------------------------*/ 1063 Updt_tar(cn, cn, &exc[i_subfr], gain_pit, L_SUBFR); 1064 1065 #ifdef ASM_OPT /* asm optimization branch */ 1066 Scale_sig_opt(cn, L_SUBFR, shift); /* scaling of cn[] to limit dynamic at 12 bits */ 1067 #else 1068 Scale_sig(cn, L_SUBFR, shift); /* scaling of cn[] to limit dynamic at 12 bits */ 1069 #endif 1070 /*-----------------------------------------------------------------* 1071 * - include fixed-gain pitch contribution into impulse resp. h1[] * 1072 *-----------------------------------------------------------------*/ 1073 tmp = 0; 1074 Preemph(h2, st->tilt_code, L_SUBFR, &tmp); 1075 1076 if (T0_frac > 2) 1077 T0 = (T0 + 1); 1078 Pit_shrp(h2, T0, PIT_SHARP, L_SUBFR); 1079 /*-----------------------------------------------------------------* 1080 * - Correlation between target xn2[] and impulse response h1[] * 1081 * - Innovative codebook search * 1082 *-----------------------------------------------------------------*/ 1083 cor_h_x(h2, xn2, dn); 1084 if (*ser_size <= NBBITS_7k) 1085 { 1086 ACELP_2t64_fx(dn, cn, h2, code, y2, indice); 1087 1088 Parm_serial(indice[0], 12, &prms); 1089 } else if(*ser_size <= NBBITS_9k) 1090 { 1091 ACELP_4t64_fx(dn, cn, h2, code, y2, 20, *ser_size, indice); 1092 1093 Parm_serial(indice[0], 5, &prms); 1094 Parm_serial(indice[1], 5, &prms); 1095 Parm_serial(indice[2], 5, &prms); 1096 Parm_serial(indice[3], 5, &prms); 1097 } else if(*ser_size <= NBBITS_12k) 1098 { 1099 ACELP_4t64_fx(dn, cn, h2, code, y2, 36, *ser_size, indice); 1100 1101 Parm_serial(indice[0], 9, &prms); 1102 Parm_serial(indice[1], 9, &prms); 1103 Parm_serial(indice[2], 9, &prms); 1104 Parm_serial(indice[3], 9, &prms); 1105 } else if(*ser_size <= NBBITS_14k) 1106 { 1107 ACELP_4t64_fx(dn, cn, h2, code, y2, 44, *ser_size, indice); 1108 1109 Parm_serial(indice[0], 13, &prms); 1110 Parm_serial(indice[1], 13, &prms); 1111 Parm_serial(indice[2], 9, &prms); 1112 Parm_serial(indice[3], 9, &prms); 1113 } else if(*ser_size <= NBBITS_16k) 1114 { 1115 ACELP_4t64_fx(dn, cn, h2, code, y2, 52, *ser_size, indice); 1116 1117 Parm_serial(indice[0], 13, &prms); 1118 Parm_serial(indice[1], 13, &prms); 1119 Parm_serial(indice[2], 13, &prms); 1120 Parm_serial(indice[3], 13, &prms); 1121 } else if(*ser_size <= NBBITS_18k) 1122 { 1123 ACELP_4t64_fx(dn, cn, h2, code, y2, 64, *ser_size, indice); 1124 1125 Parm_serial(indice[0], 2, &prms); 1126 Parm_serial(indice[1], 2, &prms); 1127 Parm_serial(indice[2], 2, &prms); 1128 Parm_serial(indice[3], 2, &prms); 1129 Parm_serial(indice[4], 14, &prms); 1130 Parm_serial(indice[5], 14, &prms); 1131 Parm_serial(indice[6], 14, &prms); 1132 Parm_serial(indice[7], 14, &prms); 1133 } else if(*ser_size <= NBBITS_20k) 1134 { 1135 ACELP_4t64_fx(dn, cn, h2, code, y2, 72, *ser_size, indice); 1136 1137 Parm_serial(indice[0], 10, &prms); 1138 Parm_serial(indice[1], 10, &prms); 1139 Parm_serial(indice[2], 2, &prms); 1140 Parm_serial(indice[3], 2, &prms); 1141 Parm_serial(indice[4], 10, &prms); 1142 Parm_serial(indice[5], 10, &prms); 1143 Parm_serial(indice[6], 14, &prms); 1144 Parm_serial(indice[7], 14, &prms); 1145 } else 1146 { 1147 ACELP_4t64_fx(dn, cn, h2, code, y2, 88, *ser_size, indice); 1148 1149 Parm_serial(indice[0], 11, &prms); 1150 Parm_serial(indice[1], 11, &prms); 1151 Parm_serial(indice[2], 11, &prms); 1152 Parm_serial(indice[3], 11, &prms); 1153 Parm_serial(indice[4], 11, &prms); 1154 Parm_serial(indice[5], 11, &prms); 1155 Parm_serial(indice[6], 11, &prms); 1156 Parm_serial(indice[7], 11, &prms); 1157 } 1158 /*-------------------------------------------------------* 1159 * - Add the fixed-gain pitch contribution to code[]. * 1160 *-------------------------------------------------------*/ 1161 tmp = 0; 1162 Preemph(code, st->tilt_code, L_SUBFR, &tmp); 1163 Pit_shrp(code, T0, PIT_SHARP, L_SUBFR); 1164 /*----------------------------------------------------------* 1165 * - Compute the fixed codebook gain * 1166 * - quantize fixed codebook gain * 1167 *----------------------------------------------------------*/ 1168 if(*ser_size <= NBBITS_9k) 1169 { 1170 index = Q_gain2(xn, y1, Q_new + shift, y2, code, g_coeff, L_SUBFR, 6, 1171 &gain_pit, &L_gain_code, clip_gain, st->qua_gain); 1172 Parm_serial(index, 6, &prms); 1173 } else 1174 { 1175 index = Q_gain2(xn, y1, Q_new + shift, y2, code, g_coeff, L_SUBFR, 7, 1176 &gain_pit, &L_gain_code, clip_gain, st->qua_gain); 1177 Parm_serial(index, 7, &prms); 1178 } 1179 /* test quantized gain of pitch for pitch clipping algorithm */ 1180 Gp_clip_test_gain_pit(gain_pit, st->gp_clip); 1181 1182 L_tmp = L_shl(L_gain_code, Q_new); 1183 gain_code = extract_h(L_add(L_tmp, 0x8000)); 1184 1185 /*----------------------------------------------------------* 1186 * Update parameters for the next subframe. * 1187 * - tilt of code: 0.0 (unvoiced) to 0.5 (voiced) * 1188 *----------------------------------------------------------*/ 1189 /* find voice factor in Q15 (1=voiced, -1=unvoiced) */ 1190 Copy(&exc[i_subfr], exc2, L_SUBFR); 1191 1192 #ifdef ASM_OPT /* asm optimization branch */ 1193 Scale_sig_opt(exc2, L_SUBFR, shift); 1194 #else 1195 Scale_sig(exc2, L_SUBFR, shift); 1196 #endif 1197 voice_fac = voice_factor(exc2, shift, gain_pit, code, gain_code, L_SUBFR); 1198 /* tilt of code for next subframe: 0.5=voiced, 0=unvoiced */ 1199 st->tilt_code = ((voice_fac >> 2) + 8192); 1200 /*------------------------------------------------------* 1201 * - Update filter's memory "mem_w0" for finding the * 1202 * target vector in the next subframe. * 1203 * - Find the total excitation * 1204 * - Find synthesis speech to update mem_syn[]. * 1205 *------------------------------------------------------*/ 1206 1207 /* y2 in Q9, gain_pit in Q14 */ 1208 L_tmp = L_mult(gain_code, y2[L_SUBFR - 1]); 1209 L_tmp = L_shl(L_tmp, (5 + shift)); 1210 L_tmp = L_negate(L_tmp); 1211 L_tmp += (xn[L_SUBFR - 1] * 16384)<<1; 1212 L_tmp -= (y1[L_SUBFR - 1] * gain_pit)<<1; 1213 L_tmp = L_shl(L_tmp, (1 - shift)); 1214 st->mem_w0 = extract_h(L_add(L_tmp, 0x8000)); 1215 1216 if (*ser_size >= NBBITS_24k) 1217 Copy(&exc[i_subfr], exc2, L_SUBFR); 1218 1219 for (i = 0; i < L_SUBFR; i++) 1220 { 1221 Word32 tmp; 1222 /* code in Q9, gain_pit in Q14 */ 1223 L_tmp = L_mult(gain_code, code[i]); 1224 L_tmp = L_shl(L_tmp, 5); 1225 tmp = L_mult(exc[i + i_subfr], gain_pit); // (exc[i + i_subfr] * gain_pit)<<1 1226 L_tmp = L_add(L_tmp, tmp); 1227 L_tmp = L_shl2(L_tmp, 1); 1228 exc[i + i_subfr] = extract_h(L_add(L_tmp, 0x8000)); 1229 } 1230 1231 Syn_filt(p_Aq,&exc[i_subfr], synth, L_SUBFR, st->mem_syn, 1); 1232 1233 if(*ser_size >= NBBITS_24k) 1234 { 1235 /*------------------------------------------------------------* 1236 * phase dispersion to enhance noise in low bit rate * 1237 *------------------------------------------------------------*/ 1238 /* L_gain_code in Q16 */ 1239 VO_L_Extract(L_gain_code, &gain_code, &gain_code_lo); 1240 1241 /*------------------------------------------------------------* 1242 * noise enhancer * 1243 * ~~~~~~~~~~~~~~ * 1244 * - Enhance excitation on noise. (modify gain of code) * 1245 * If signal is noisy and LPC filter is stable, move gain * 1246 * of code 1.5 dB toward gain of code threshold. * 1247 * This decrease by 3 dB noise energy variation. * 1248 *------------------------------------------------------------*/ 1249 tmp = (16384 - (voice_fac >> 1)); /* 1=unvoiced, 0=voiced */ 1250 fac = vo_mult(stab_fac, tmp); 1251 L_tmp = L_gain_code; 1252 if(L_tmp < st->L_gc_thres) 1253 { 1254 L_tmp = vo_L_add(L_tmp, Mpy_32_16(gain_code, gain_code_lo, 6226)); 1255 if(L_tmp > st->L_gc_thres) 1256 { 1257 L_tmp = st->L_gc_thres; 1258 } 1259 } else 1260 { 1261 L_tmp = Mpy_32_16(gain_code, gain_code_lo, 27536); 1262 if(L_tmp < st->L_gc_thres) 1263 { 1264 L_tmp = st->L_gc_thres; 1265 } 1266 } 1267 st->L_gc_thres = L_tmp; 1268 1269 L_gain_code = Mpy_32_16(gain_code, gain_code_lo, (32767 - fac)); 1270 VO_L_Extract(L_tmp, &gain_code, &gain_code_lo); 1271 L_gain_code = vo_L_add(L_gain_code, Mpy_32_16(gain_code, gain_code_lo, fac)); 1272 1273 /*------------------------------------------------------------* 1274 * pitch enhancer * 1275 * ~~~~~~~~~~~~~~ * 1276 * - Enhance excitation on voice. (HP filtering of code) * 1277 * On voiced signal, filtering of code by a smooth fir HP * 1278 * filter to decrease energy of code in low frequency. * 1279 *------------------------------------------------------------*/ 1280 1281 tmp = ((voice_fac >> 3) + 4096); /* 0.25=voiced, 0=unvoiced */ 1282 1283 L_tmp = L_deposit_h(code[0]); 1284 L_tmp -= (code[1] * tmp)<<1; 1285 code2[0] = vo_round(L_tmp); 1286 1287 for (i = 1; i < L_SUBFR - 1; i++) 1288 { 1289 L_tmp = L_deposit_h(code[i]); 1290 L_tmp -= (code[i + 1] * tmp)<<1; 1291 L_tmp -= (code[i - 1] * tmp)<<1; 1292 code2[i] = vo_round(L_tmp); 1293 } 1294 1295 L_tmp = L_deposit_h(code[L_SUBFR - 1]); 1296 L_tmp -= (code[L_SUBFR - 2] * tmp)<<1; 1297 code2[L_SUBFR - 1] = vo_round(L_tmp); 1298 1299 /* build excitation */ 1300 gain_code = vo_round(L_shl(L_gain_code, Q_new)); 1301 1302 for (i = 0; i < L_SUBFR; i++) 1303 { 1304 L_tmp = L_mult(code2[i], gain_code); 1305 L_tmp = L_shl(L_tmp, 5); 1306 L_tmp = L_add(L_tmp, L_mult(exc2[i], gain_pit)); 1307 L_tmp = L_shl(L_tmp, 1); 1308 exc2[i] = voround(L_tmp); 1309 } 1310 1311 corr_gain = synthesis(p_Aq, exc2, Q_new, &speech16k[i_subfr * 5 / 4], st); 1312 Parm_serial(corr_gain, 4, &prms); 1313 } 1314 p_A += (M + 1); 1315 p_Aq += (M + 1); 1316 } /* end of subframe loop */ 1317 1318 /*--------------------------------------------------* 1319 * Update signal for next frame. * 1320 * -> save past of speech[], wsp[] and exc[]. * 1321 *--------------------------------------------------*/ 1322 Copy(&old_speech[L_FRAME], st->old_speech, L_TOTAL - L_FRAME); 1323 Copy(&old_wsp[L_FRAME / OPL_DECIM], st->old_wsp, PIT_MAX / OPL_DECIM); 1324 Copy(&old_exc[L_FRAME], st->old_exc, PIT_MAX + L_INTERPOL); 1325 return; 1326 } 1327 1328 /*-----------------------------------------------------* 1329 * Function synthesis() * 1330 * * 1331 * Synthesis of signal at 16kHz with HF extension. * 1332 * * 1333 *-----------------------------------------------------*/ 1334 1335 static Word16 synthesis( 1336 Word16 Aq[], /* A(z) : quantized Az */ 1337 Word16 exc[], /* (i) : excitation at 12kHz */ 1338 Word16 Q_new, /* (i) : scaling performed on exc */ 1339 Word16 synth16k[], /* (o) : 16kHz synthesis signal */ 1340 Coder_State * st /* (i/o) : State structure */ 1341 ) 1342 { 1343 Word16 fac, tmp, exp; 1344 Word16 ener, exp_ener; 1345 Word32 L_tmp, i; 1346 1347 Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR]; 1348 Word16 synth[L_SUBFR]; 1349 Word16 HF[L_SUBFR16k]; /* High Frequency vector */ 1350 Word16 Ap[M + 1]; 1351 1352 Word16 HF_SP[L_SUBFR16k]; /* High Frequency vector (from original signal) */ 1353 1354 Word16 HP_est_gain, HP_calc_gain, HP_corr_gain; 1355 Word16 dist_min, dist; 1356 Word16 HP_gain_ind = 0; 1357 Word16 gain1, gain2; 1358 Word16 weight1, weight2; 1359 1360 /*------------------------------------------------------------* 1361 * speech synthesis * 1362 * ~~~~~~~~~~~~~~~~ * 1363 * - Find synthesis speech corresponding to exc2[]. * 1364 * - Perform fixed deemphasis and hp 50hz filtering. * 1365 * - Oversampling from 12.8kHz to 16kHz. * 1366 *------------------------------------------------------------*/ 1367 Copy(st->mem_syn_hi, synth_hi, M); 1368 Copy(st->mem_syn_lo, synth_lo, M); 1369 1370 #ifdef ASM_OPT /* asm optimization branch */ 1371 Syn_filt_32_asm(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR); 1372 #else 1373 Syn_filt_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR); 1374 #endif 1375 1376 Copy(synth_hi + L_SUBFR, st->mem_syn_hi, M); 1377 Copy(synth_lo + L_SUBFR, st->mem_syn_lo, M); 1378 1379 #ifdef ASM_OPT /* asm optimization branch */ 1380 Deemph_32_asm(synth_hi + M, synth_lo + M, synth, &(st->mem_deemph)); 1381 #else 1382 Deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR, &(st->mem_deemph)); 1383 #endif 1384 1385 HP50_12k8(synth, L_SUBFR, st->mem_sig_out); 1386 1387 /* Original speech signal as reference for high band gain quantisation */ 1388 for (i = 0; i < L_SUBFR16k; i++) 1389 { 1390 HF_SP[i] = synth16k[i]; 1391 } 1392 1393 /*------------------------------------------------------* 1394 * HF noise synthesis * 1395 * ~~~~~~~~~~~~~~~~~~ * 1396 * - Generate HF noise between 5.5 and 7.5 kHz. * 1397 * - Set energy of noise according to synthesis tilt. * 1398 * tilt > 0.8 ==> - 14 dB (voiced) * 1399 * tilt 0.5 ==> - 6 dB (voiced or noise) * 1400 * tilt < 0.0 ==> 0 dB (noise) * 1401 *------------------------------------------------------*/ 1402 /* generate white noise vector */ 1403 for (i = 0; i < L_SUBFR16k; i++) 1404 { 1405 HF[i] = Random(&(st->seed2))>>3; 1406 } 1407 /* energy of excitation */ 1408 #ifdef ASM_OPT /* asm optimization branch */ 1409 Scale_sig_opt(exc, L_SUBFR, -3); 1410 Q_new = Q_new - 3; 1411 ener = extract_h(Dot_product12_asm(exc, exc, L_SUBFR, &exp_ener)); 1412 #else 1413 Scale_sig(exc, L_SUBFR, -3); 1414 Q_new = Q_new - 3; 1415 ener = extract_h(Dot_product12(exc, exc, L_SUBFR, &exp_ener)); 1416 #endif 1417 1418 exp_ener = exp_ener - (Q_new + Q_new); 1419 /* set energy of white noise to energy of excitation */ 1420 #ifdef ASM_OPT /* asm optimization branch */ 1421 tmp = extract_h(Dot_product12_asm(HF, HF, L_SUBFR16k, &exp)); 1422 #else 1423 tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp)); 1424 #endif 1425 1426 if(tmp > ener) 1427 { 1428 tmp = (tmp >> 1); /* Be sure tmp < ener */ 1429 exp = (exp + 1); 1430 } 1431 L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */ 1432 exp = (exp - exp_ener); 1433 Isqrt_n(&L_tmp, &exp); 1434 L_tmp = L_shl(L_tmp, (exp + 1)); /* L_tmp x 2, L_tmp in Q31 */ 1435 tmp = extract_h(L_tmp); /* tmp = 2 x sqrt(ener_exc/ener_hf) */ 1436 1437 for (i = 0; i < L_SUBFR16k; i++) 1438 { 1439 HF[i] = vo_mult(HF[i], tmp); 1440 } 1441 1442 /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */ 1443 HP400_12k8(synth, L_SUBFR, st->mem_hp400); 1444 1445 L_tmp = 1L; 1446 for (i = 0; i < L_SUBFR; i++) 1447 L_tmp += (synth[i] * synth[i])<<1; 1448 1449 exp = norm_l(L_tmp); 1450 ener = extract_h(L_tmp << exp); /* ener = r[0] */ 1451 1452 L_tmp = 1L; 1453 for (i = 1; i < L_SUBFR; i++) 1454 L_tmp +=(synth[i] * synth[i - 1])<<1; 1455 1456 tmp = extract_h(L_tmp << exp); /* tmp = r[1] */ 1457 1458 if (tmp > 0) 1459 { 1460 fac = div_s(tmp, ener); 1461 } else 1462 { 1463 fac = 0; 1464 } 1465 1466 /* modify energy of white noise according to synthesis tilt */ 1467 gain1 = 32767 - fac; 1468 gain2 = vo_mult(gain1, 20480); 1469 gain2 = shl(gain2, 1); 1470 1471 if (st->vad_hist > 0) 1472 { 1473 weight1 = 0; 1474 weight2 = 32767; 1475 } else 1476 { 1477 weight1 = 32767; 1478 weight2 = 0; 1479 } 1480 tmp = vo_mult(weight1, gain1); 1481 tmp = add1(tmp, vo_mult(weight2, gain2)); 1482 1483 if (tmp != 0) 1484 { 1485 tmp = (tmp + 1); 1486 } 1487 HP_est_gain = tmp; 1488 1489 if(HP_est_gain < 3277) 1490 { 1491 HP_est_gain = 3277; /* 0.1 in Q15 */ 1492 } 1493 /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */ 1494 Weight_a(Aq, Ap, 19661, M); /* fac=0.6 */ 1495 1496 #ifdef ASM_OPT /* asm optimization branch */ 1497 Syn_filt_asm(Ap, HF, HF, st->mem_syn_hf); 1498 /* noise High Pass filtering (1ms of delay) */ 1499 Filt_6k_7k_asm(HF, L_SUBFR16k, st->mem_hf); 1500 /* filtering of the original signal */ 1501 Filt_6k_7k_asm(HF_SP, L_SUBFR16k, st->mem_hf2); 1502 1503 /* check the gain difference */ 1504 Scale_sig_opt(HF_SP, L_SUBFR16k, -1); 1505 ener = extract_h(Dot_product12_asm(HF_SP, HF_SP, L_SUBFR16k, &exp_ener)); 1506 /* set energy of white noise to energy of excitation */ 1507 tmp = extract_h(Dot_product12_asm(HF, HF, L_SUBFR16k, &exp)); 1508 #else 1509 Syn_filt(Ap, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1); 1510 /* noise High Pass filtering (1ms of delay) */ 1511 Filt_6k_7k(HF, L_SUBFR16k, st->mem_hf); 1512 /* filtering of the original signal */ 1513 Filt_6k_7k(HF_SP, L_SUBFR16k, st->mem_hf2); 1514 /* check the gain difference */ 1515 Scale_sig(HF_SP, L_SUBFR16k, -1); 1516 ener = extract_h(Dot_product12(HF_SP, HF_SP, L_SUBFR16k, &exp_ener)); 1517 /* set energy of white noise to energy of excitation */ 1518 tmp = extract_h(Dot_product12(HF, HF, L_SUBFR16k, &exp)); 1519 #endif 1520 1521 if (tmp > ener) 1522 { 1523 tmp = (tmp >> 1); /* Be sure tmp < ener */ 1524 exp = (exp + 1); 1525 } 1526 L_tmp = L_deposit_h(div_s(tmp, ener)); /* result is normalized */ 1527 exp = vo_sub(exp, exp_ener); 1528 Isqrt_n(&L_tmp, &exp); 1529 L_tmp = L_shl(L_tmp, exp); /* L_tmp, L_tmp in Q31 */ 1530 HP_calc_gain = extract_h(L_tmp); /* tmp = sqrt(ener_input/ener_hf) */ 1531 1532 /* st->gain_alpha *= st->dtx_encSt->dtxHangoverCount/7 */ 1533 L_tmp = (vo_L_mult(st->dtx_encSt->dtxHangoverCount, 4681) << 15); 1534 st->gain_alpha = vo_mult(st->gain_alpha, extract_h(L_tmp)); 1535 1536 if(st->dtx_encSt->dtxHangoverCount > 6) 1537 st->gain_alpha = 32767; 1538 HP_est_gain = HP_est_gain >> 1; /* From Q15 to Q14 */ 1539 HP_corr_gain = add1(vo_mult(HP_calc_gain, st->gain_alpha), vo_mult((32767 - st->gain_alpha), HP_est_gain)); 1540 1541 /* Quantise the correction gain */ 1542 dist_min = 32767; 1543 for (i = 0; i < 16; i++) 1544 { 1545 dist = vo_mult((HP_corr_gain - HP_gain[i]), (HP_corr_gain - HP_gain[i])); 1546 if (dist_min > dist) 1547 { 1548 dist_min = dist; 1549 HP_gain_ind = i; 1550 } 1551 } 1552 HP_corr_gain = HP_gain[HP_gain_ind]; 1553 /* return the quantised gain index when using the highest mode, otherwise zero */ 1554 return (HP_gain_ind); 1555 } 1556 1557 /************************************************* 1558 * 1559 * Breif: Codec main function 1560 * 1561 **************************************************/ 1562 1563 int AMR_Enc_Encode(HAMRENC hCodec) 1564 { 1565 Word32 i; 1566 Coder_State *gData = (Coder_State*)hCodec; 1567 Word16 *signal; 1568 Word16 packed_size = 0; 1569 Word16 prms[NB_BITS_MAX]; 1570 Word16 coding_mode = 0, nb_bits, allow_dtx, mode, reset_flag; 1571 mode = gData->mode; 1572 coding_mode = gData->mode; 1573 nb_bits = nb_of_bits[mode]; 1574 signal = (Word16 *)gData->inputStream; 1575 allow_dtx = gData->allow_dtx; 1576 1577 /* check for homing frame */ 1578 reset_flag = encoder_homing_frame_test(signal); 1579 1580 for (i = 0; i < L_FRAME16k; i++) /* Delete the 2 LSBs (14-bit input) */ 1581 { 1582 *(signal + i) = (Word16) (*(signal + i) & 0xfffC); 1583 } 1584 1585 coder(&coding_mode, signal, prms, &nb_bits, gData, allow_dtx); 1586 packed_size = PackBits(prms, coding_mode, mode, gData); 1587 if (reset_flag != 0) 1588 { 1589 Reset_encoder(gData, 1); 1590 } 1591 return packed_size; 1592 } 1593 1594 /*************************************************************************** 1595 * 1596 *Brief: Codec API function --- Initialize the codec and return a codec handle 1597 * 1598 ***************************************************************************/ 1599 1600 VO_U32 VO_API voAMRWB_Init(VO_HANDLE * phCodec, /* o: the audio codec handle */ 1601 VO_AUDIO_CODINGTYPE vType, /* i: Codec Type ID */ 1602 VO_CODEC_INIT_USERDATA * pUserData /* i: init Parameters */ 1603 ) 1604 { 1605 Coder_State *st; 1606 FrameStream *stream; 1607 #ifdef USE_DEAULT_MEM 1608 VO_MEM_OPERATOR voMemoprator; 1609 #endif 1610 VO_MEM_OPERATOR *pMemOP; 1611 UNUSED(vType); 1612 1613 int interMem = 0; 1614 1615 if(pUserData == NULL || pUserData->memflag != VO_IMF_USERMEMOPERATOR || pUserData->memData == NULL ) 1616 { 1617 #ifdef USE_DEAULT_MEM 1618 voMemoprator.Alloc = cmnMemAlloc; 1619 voMemoprator.Copy = cmnMemCopy; 1620 voMemoprator.Free = cmnMemFree; 1621 voMemoprator.Set = cmnMemSet; 1622 voMemoprator.Check = cmnMemCheck; 1623 interMem = 1; 1624 pMemOP = &voMemoprator; 1625 #else 1626 *phCodec = NULL; 1627 return VO_ERR_INVALID_ARG; 1628 #endif 1629 } 1630 else 1631 { 1632 pMemOP = (VO_MEM_OPERATOR *)pUserData->memData; 1633 } 1634 /*-------------------------------------------------------------------------* 1635 * Memory allocation for coder state. * 1636 *-------------------------------------------------------------------------*/ 1637 if ((st = (Coder_State *)mem_malloc(pMemOP, sizeof(Coder_State), 32, VO_INDEX_ENC_AMRWB)) == NULL) 1638 { 1639 return VO_ERR_OUTOF_MEMORY; 1640 } 1641 1642 st->vadSt = NULL; 1643 st->dtx_encSt = NULL; 1644 st->sid_update_counter = 3; 1645 st->sid_handover_debt = 0; 1646 st->prev_ft = TX_SPEECH; 1647 st->inputStream = NULL; 1648 st->inputSize = 0; 1649 1650 /* Default setting */ 1651 st->mode = VOAMRWB_MD2385; /* bit rate 23.85kbps */ 1652 st->frameType = VOAMRWB_RFC3267; /* frame type: RFC3267 */ 1653 st->allow_dtx = 0; /* disable DTX mode */ 1654 1655 st->outputStream = NULL; 1656 st->outputSize = 0; 1657 1658 st->stream = (FrameStream *)mem_malloc(pMemOP, sizeof(FrameStream), 32, VO_INDEX_ENC_AMRWB); 1659 if(st->stream == NULL) 1660 return VO_ERR_OUTOF_MEMORY; 1661 1662 st->stream->frame_ptr = (unsigned char *)mem_malloc(pMemOP, Frame_Maxsize, 32, VO_INDEX_ENC_AMRWB); 1663 if(st->stream->frame_ptr == NULL) 1664 return VO_ERR_OUTOF_MEMORY; 1665 1666 stream = st->stream; 1667 voAWB_InitFrameBuffer(stream); 1668 1669 wb_vad_init(&(st->vadSt), pMemOP); 1670 dtx_enc_init(&(st->dtx_encSt), isf_init, pMemOP); 1671 1672 Reset_encoder((void *) st, 1); 1673 1674 if(interMem) 1675 { 1676 st->voMemoprator.Alloc = cmnMemAlloc; 1677 st->voMemoprator.Copy = cmnMemCopy; 1678 st->voMemoprator.Free = cmnMemFree; 1679 st->voMemoprator.Set = cmnMemSet; 1680 st->voMemoprator.Check = cmnMemCheck; 1681 pMemOP = &st->voMemoprator; 1682 } 1683 1684 st->pvoMemop = pMemOP; 1685 1686 *phCodec = (void *) st; 1687 1688 return VO_ERR_NONE; 1689 } 1690 1691 /********************************************************************************** 1692 * 1693 * Brief: Codec API function: Input PCM data 1694 * 1695 ***********************************************************************************/ 1696 1697 VO_U32 VO_API voAMRWB_SetInputData( 1698 VO_HANDLE hCodec, /* i/o: The codec handle which was created by Init function */ 1699 VO_CODECBUFFER * pInput /* i: The input buffer parameter */ 1700 ) 1701 { 1702 Coder_State *gData; 1703 FrameStream *stream; 1704 1705 if(NULL == hCodec) 1706 { 1707 return VO_ERR_INVALID_ARG; 1708 } 1709 1710 gData = (Coder_State *)hCodec; 1711 stream = gData->stream; 1712 1713 if(NULL == pInput || NULL == pInput->Buffer) 1714 { 1715 return VO_ERR_INVALID_ARG; 1716 } 1717 1718 stream->set_ptr = pInput->Buffer; 1719 stream->set_len = pInput->Length; 1720 stream->frame_ptr = stream->frame_ptr_bk; 1721 stream->used_len = 0; 1722 1723 return VO_ERR_NONE; 1724 } 1725 1726 /************************************************************************************** 1727 * 1728 * Brief: Codec API function: Get the compression audio data frame by frame 1729 * 1730 ***************************************************************************************/ 1731 1732 VO_U32 VO_API voAMRWB_GetOutputData( 1733 VO_HANDLE hCodec, /* i: The Codec Handle which was created by Init function*/ 1734 VO_CODECBUFFER * pOutput, /* o: The output audio data */ 1735 VO_AUDIO_OUTPUTINFO * pAudioFormat /* o: The encoder module filled audio format and used the input size*/ 1736 ) 1737 { 1738 Coder_State* gData = (Coder_State*)hCodec; 1739 VO_MEM_OPERATOR *pMemOP; 1740 FrameStream *stream = (FrameStream *)gData->stream; 1741 pMemOP = (VO_MEM_OPERATOR *)gData->pvoMemop; 1742 1743 if(stream->framebuffer_len < Frame_MaxByte) /* check the work buffer len */ 1744 { 1745 stream->frame_storelen = stream->framebuffer_len; 1746 if(stream->frame_storelen) 1747 { 1748 pMemOP->Copy(VO_INDEX_ENC_AMRWB, stream->frame_ptr_bk , stream->frame_ptr , stream->frame_storelen); 1749 } 1750 if(stream->set_len > 0) 1751 { 1752 voAWB_UpdateFrameBuffer(stream, pMemOP); 1753 } 1754 if(stream->framebuffer_len < Frame_MaxByte) 1755 { 1756 if(pAudioFormat) 1757 pAudioFormat->InputUsed = stream->used_len; 1758 return VO_ERR_INPUT_BUFFER_SMALL; 1759 } 1760 } 1761 1762 gData->inputStream = stream->frame_ptr; 1763 gData->outputStream = (unsigned short*)pOutput->Buffer; 1764 1765 gData->outputSize = AMR_Enc_Encode(gData); /* encoder main function */ 1766 1767 pOutput->Length = gData->outputSize; /* get the output buffer length */ 1768 stream->frame_ptr += 640; /* update the work buffer ptr */ 1769 stream->framebuffer_len -= 640; 1770 1771 if(pAudioFormat) /* return output audio information */ 1772 { 1773 pAudioFormat->Format.Channels = 1; 1774 pAudioFormat->Format.SampleRate = 8000; 1775 pAudioFormat->Format.SampleBits = 16; 1776 pAudioFormat->InputUsed = stream->used_len; 1777 } 1778 return VO_ERR_NONE; 1779 } 1780 1781 /************************************************************************* 1782 * 1783 * Brief: Codec API function---set the data by specified parameter ID 1784 * 1785 *************************************************************************/ 1786 1787 1788 VO_U32 VO_API voAMRWB_SetParam( 1789 VO_HANDLE hCodec, /* i/o: The Codec Handle which was created by Init function */ 1790 VO_S32 uParamID, /* i: The param ID */ 1791 VO_PTR pData /* i: The param value depend on the ID */ 1792 ) 1793 { 1794 Coder_State* gData = (Coder_State*)hCodec; 1795 FrameStream *stream = (FrameStream *)(gData->stream); 1796 int *lValue = (int*)pData; 1797 1798 switch(uParamID) 1799 { 1800 /* setting AMR-WB frame type*/ 1801 case VO_PID_AMRWB_FRAMETYPE: 1802 if(*lValue < VOAMRWB_DEFAULT || *lValue > VOAMRWB_RFC3267) 1803 return VO_ERR_WRONG_PARAM_ID; 1804 gData->frameType = *lValue; 1805 break; 1806 /* setting AMR-WB bit rate */ 1807 case VO_PID_AMRWB_MODE: 1808 { 1809 if(*lValue < VOAMRWB_MD66 || *lValue > VOAMRWB_MD2385) 1810 return VO_ERR_WRONG_PARAM_ID; 1811 gData->mode = *lValue; 1812 } 1813 break; 1814 /* enable or disable DTX mode */ 1815 case VO_PID_AMRWB_DTX: 1816 gData->allow_dtx = (Word16)(*lValue); 1817 break; 1818 1819 case VO_PID_COMMON_HEADDATA: 1820 break; 1821 /* flush the work buffer */ 1822 case VO_PID_COMMON_FLUSH: 1823 stream->set_ptr = NULL; 1824 stream->frame_storelen = 0; 1825 stream->framebuffer_len = 0; 1826 stream->set_len = 0; 1827 break; 1828 1829 default: 1830 return VO_ERR_WRONG_PARAM_ID; 1831 } 1832 return VO_ERR_NONE; 1833 } 1834 1835 /************************************************************************** 1836 * 1837 *Brief: Codec API function---Get the data by specified parameter ID 1838 * 1839 ***************************************************************************/ 1840 1841 VO_U32 VO_API voAMRWB_GetParam( 1842 VO_HANDLE hCodec, /* i: The Codec Handle which was created by Init function */ 1843 VO_S32 uParamID, /* i: The param ID */ 1844 VO_PTR pData /* o: The param value depend on the ID */ 1845 ) 1846 { 1847 int temp; 1848 Coder_State* gData = (Coder_State*)hCodec; 1849 1850 if (gData==NULL) 1851 return VO_ERR_INVALID_ARG; 1852 switch(uParamID) 1853 { 1854 /* output audio format */ 1855 case VO_PID_AMRWB_FORMAT: 1856 { 1857 VO_AUDIO_FORMAT* fmt = (VO_AUDIO_FORMAT*)pData; 1858 fmt->Channels = 1; 1859 fmt->SampleRate = 16000; 1860 fmt->SampleBits = 16; 1861 break; 1862 } 1863 /* output audio channel number */ 1864 case VO_PID_AMRWB_CHANNELS: 1865 temp = 1; 1866 pData = (void *)(&temp); 1867 break; 1868 /* output audio sample rate */ 1869 case VO_PID_AMRWB_SAMPLERATE: 1870 temp = 16000; 1871 pData = (void *)(&temp); 1872 break; 1873 /* output audio frame type */ 1874 case VO_PID_AMRWB_FRAMETYPE: 1875 temp = gData->frameType; 1876 pData = (void *)(&temp); 1877 break; 1878 /* output audio bit rate */ 1879 case VO_PID_AMRWB_MODE: 1880 temp = gData->mode; 1881 pData = (void *)(&temp); 1882 break; 1883 default: 1884 return VO_ERR_WRONG_PARAM_ID; 1885 } 1886 1887 return VO_ERR_NONE; 1888 } 1889 1890 /*********************************************************************************** 1891 * 1892 * Brief: Codec API function---Release the codec after all encoder operations are done 1893 * 1894 *************************************************************************************/ 1895 1896 VO_U32 VO_API voAMRWB_Uninit(VO_HANDLE hCodec /* i/o: Codec handle pointer */ 1897 ) 1898 { 1899 Coder_State* gData = (Coder_State*)hCodec; 1900 VO_MEM_OPERATOR *pMemOP; 1901 pMemOP = gData->pvoMemop; 1902 1903 if(hCodec) 1904 { 1905 if(gData->stream) 1906 { 1907 if(gData->stream->frame_ptr_bk) 1908 { 1909 mem_free(pMemOP, gData->stream->frame_ptr_bk, VO_INDEX_ENC_AMRWB); 1910 gData->stream->frame_ptr_bk = NULL; 1911 } 1912 mem_free(pMemOP, gData->stream, VO_INDEX_ENC_AMRWB); 1913 gData->stream = NULL; 1914 } 1915 wb_vad_exit(&(((Coder_State *) gData)->vadSt), pMemOP); 1916 dtx_enc_exit(&(((Coder_State *) gData)->dtx_encSt), pMemOP); 1917 1918 mem_free(pMemOP, hCodec, VO_INDEX_ENC_AMRWB); 1919 hCodec = NULL; 1920 } 1921 1922 return VO_ERR_NONE; 1923 } 1924 1925 /******************************************************************************** 1926 * 1927 * Brief: voGetAMRWBEncAPI gets the API handle of the codec 1928 * 1929 ********************************************************************************/ 1930 1931 VO_S32 VO_API voGetAMRWBEncAPI( 1932 VO_AUDIO_CODECAPI * pEncHandle /* i/o: Codec handle pointer */ 1933 ) 1934 { 1935 if(NULL == pEncHandle) 1936 return VO_ERR_INVALID_ARG; 1937 pEncHandle->Init = voAMRWB_Init; 1938 pEncHandle->SetInputData = voAMRWB_SetInputData; 1939 pEncHandle->GetOutputData = voAMRWB_GetOutputData; 1940 pEncHandle->SetParam = voAMRWB_SetParam; 1941 pEncHandle->GetParam = voAMRWB_GetParam; 1942 pEncHandle->Uninit = voAMRWB_Uninit; 1943 1944 return VO_ERR_NONE; 1945 } 1946 1947 #ifdef __cplusplus 1948 } 1949 #endif 1950