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 */
Reset_encoder(void * st,Word16 reset_all)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 *-----------------------------------------------------------------*/
coder(Word16 * mode,Word16 speech16k[],Word16 prms[],Word16 * ser_size,void * spe_state,Word16 allow_dtx)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
synthesis(Word16 Aq[],Word16 exc[],Word16 Q_new,Word16 synth16k[],Coder_State * st)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
AMR_Enc_Encode(HAMRENC hCodec)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
voAMRWB_Init(VO_HANDLE * phCodec,VO_AUDIO_CODINGTYPE vType,VO_CODEC_INIT_USERDATA * pUserData)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
voAMRWB_SetInputData(VO_HANDLE hCodec,VO_CODECBUFFER * pInput)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
voAMRWB_GetOutputData(VO_HANDLE hCodec,VO_CODECBUFFER * pOutput,VO_AUDIO_OUTPUTINFO * pAudioFormat)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
voAMRWB_SetParam(VO_HANDLE hCodec,VO_S32 uParamID,VO_PTR pData)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
voAMRWB_GetParam(VO_HANDLE hCodec,VO_S32 uParamID,VO_PTR pData)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
voAMRWB_Uninit(VO_HANDLE hCodec)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
voGetAMRWBEncAPI(VO_AUDIO_CODECAPI * pEncHandle)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