blob: bac00dd6ccc10fe84d3816bea7cf8eed8f94e04e [file] [log] [blame]
Mans Rullgard219e2622011-04-22 09:22:33 +03001/*
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
43extern "C" {
44#endif
45
46/* LPC interpolation coef {0.45, 0.8, 0.96, 1.0}; in Q15 */
47static Word16 interpol_frac[NB_SUBFR] = {14746, 26214, 31457, 32767};
48
49/* isp tables for initialization */
50static 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
56static 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 */
63static 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 */
70static 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 */
79void 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*-----------------------------------------------------------------*/
149void 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
1329static 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
1557int 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
1594VO_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
1689VO_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 || 0 > pInput->Length)
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
1724VO_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
1780VO_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
1833VO_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
1888VO_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
1923VO_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