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