Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / cl_ltp.cpp
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
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
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21     3GPP TS 26.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34  Filename: cl_ltp.cpp
35  Funtions: cl_ltp_init
36            cl_ltp_reset
37            cl_ltp_exit
38            cl_ltp
39
40 ------------------------------------------------------------------------------
41  MODULE DESCRIPTION
42
43  This file contains functions that perform closed-loop fractional pitch
44  search.
45
46 ------------------------------------------------------------------------------
47 */
48
49
50 /*----------------------------------------------------------------------------
51 ; INCLUDES
52 ----------------------------------------------------------------------------*/
53 #include "cl_ltp.h"
54 #include "basicop_malloc.h"
55 #include "cnst.h"
56 #include "convolve.h"
57 #include "g_pitch.h"
58 #include "pred_lt.h"
59 #include "pitch_fr.h"
60 #include "enc_lag3.h"
61 #include "enc_lag6.h"
62 #include "q_gain_p.h"
63 #include "ton_stab.h"
64 #include "oscl_mem.h"
65
66 /*----------------------------------------------------------------------------
67 ; MACROS
68 ; Define module specific macros here
69 ----------------------------------------------------------------------------*/
70
71
72 /*----------------------------------------------------------------------------
73 ; DEFINES
74 ; Include all pre-processor statements here. Include conditional
75 ; compile variables also.
76 ----------------------------------------------------------------------------*/
77
78
79 /*----------------------------------------------------------------------------
80 ; LOCAL FUNCTION DEFINITIONS
81 ; Function Prototype declaration
82 ----------------------------------------------------------------------------*/
83
84 /*----------------------------------------------------------------------------
85 ; LOCAL VARIABLE DEFINITIONS
86 ; Variable declaration - defined here and used outside this module
87 ----------------------------------------------------------------------------*/
88
89
90 /*
91 ------------------------------------------------------------------------------
92  FUNCTION NAME: cl_ltp_init
93 ------------------------------------------------------------------------------
94  INPUT AND OUTPUT DEFINITIONS
95
96  Inputs:
97     state = Pointer to a pointer to a clLtpState structure
98
99  Outputs:
100     state points to the newly created clLtpState structure.
101
102  Returns:
103     This function returns 0 upon success and -1 upon failure.
104
105  Global Variables Used:
106     None
107
108  Local Variables Needed:
109     None
110
111 ------------------------------------------------------------------------------
112  FUNCTION DESCRIPTION
113
114  Allocates state memory and initializes state memory
115
116 ------------------------------------------------------------------------------
117  REQUIREMENTS
118
119  None.
120
121 ------------------------------------------------------------------------------
122  REFERENCES
123
124  cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
125
126 ------------------------------------------------------------------------------
127  PSEUDO-CODE
128
129 int cl_ltp_init (clLtpState **state)
130 {
131     clLtpState* s;
132
133     if (state == (clLtpState **) NULL){
134         fprintf(stderr, "cl_ltp_init: invalid parameter\n");
135         return -1;
136     }
137     *state = NULL;
138
139     // allocate memory
140     if ((s= (clLtpState *) malloc(sizeof(clLtpState))) == NULL){
141         fprintf(stderr, "cl_ltp_init: can not malloc state structure\n");
142         return -1;
143   }
144
145     // init the sub state
146     if (Pitch_fr_init(&s->pitchSt)) {
147         cl_ltp_exit(&s);
148         return -1;
149     }
150
151     cl_ltp_reset(s);
152
153     *state = s;
154
155     return 0;
156 }
157
158
159 ------------------------------------------------------------------------------
160  CAUTION [optional]
161  [State any special notes, constraints or cautions for users of this function]
162
163 ------------------------------------------------------------------------------
164 */
165
166 Word16 cl_ltp_init(clLtpState **state)
167 {
168     clLtpState* s;
169
170     if (state == (clLtpState **) NULL)
171     {
172         /*fprint(stderr, "cl_ltp_init: invalid parameter\n");*/
173         return(-1);
174     }
175     *state = NULL;
176
177     /* allocate memory */
178     if ((s = (clLtpState *) oscl_malloc(sizeof(clLtpState))) == NULL)
179     {
180         /*fprint(stderr, "cl_ltp_init: can not malloc state structure\n");*/
181         return(-1);
182     }
183
184     /* init the sub state */
185     if (Pitch_fr_init(&s->pitchSt))
186     {
187         cl_ltp_exit(&s);
188         return(-1);
189     }
190
191     cl_ltp_reset(s);
192
193     *state = s;
194
195     return(0);
196 }
197
198 /****************************************************************************/
199
200 /*
201 ------------------------------------------------------------------------------
202  FUNCTION NAME: cl_ltp_reset
203 ------------------------------------------------------------------------------
204  INPUT AND OUTPUT DEFINITIONS
205
206  Inputs:
207     state = pointer to the clLtpState structure to be reset
208
209  Outputs:
210     The state structure pointed to by clLtpState *state is reset.
211
212  Returns:
213     The function returns int 0 if successful, -1 otherwise.
214
215  Global Variables Used:
216     None
217
218  Local Variables Needed:
219     None
220
221 ------------------------------------------------------------------------------
222  FUNCTION DESCRIPTION
223
224  Initializes state memory to zero.
225
226 ------------------------------------------------------------------------------
227  REQUIREMENTS
228
229 ------------------------------------------------------------------------------
230  REFERENCES
231
232  cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
233
234  ------------------------------------------------------------------------------
235  PSEUDO-CODE
236
237 int cl_ltp_reset (clLtpState *state)
238 {
239     if (state == (clLtpState *) NULL){
240         fprintf(stderr, "cl_ltp_reset: invalid parameter\n");
241         return -1;
242     }
243
244     // Reset pitch search states
245     Pitch_fr_reset (state->pitchSt);
246
247     return 0;
248 }
249
250 ------------------------------------------------------------------------------
251  CAUTION [optional]
252  [State any special notes, constraints or cautions for users of this function]
253
254 ------------------------------------------------------------------------------
255 */
256
257 Word16 cl_ltp_reset(clLtpState *state)
258 {
259     if (state == (clLtpState *) NULL)
260     {
261         /*fprint(stderr, "cl_ltp_reset: invalid parameter\n");  */
262         return(-1);
263     }
264
265     /* Reset pitch search states */
266     Pitch_fr_reset(state->pitchSt);
267
268     return(0);
269 }
270
271 /****************************************************************************/
272
273 /*
274 ------------------------------------------------------------------------------
275  FUNCTION NAME: cl_ltp_exit
276 ------------------------------------------------------------------------------
277  INPUT AND OUTPUT DEFINITIONS
278
279  Inputs:
280     clLtpState **state = Reference to the state object to be freed.
281
282  Outputs:
283     The memory used by the structure which is pointed to by 'state'
284       is freed.
285
286  Returns:
287     None
288
289  Global Variables Used:
290     None
291
292  Local Variables Needed:
293     None
294
295 ------------------------------------------------------------------------------
296  FUNCTION DESCRIPTION
297
298  The memory used for state memory is freed
299
300
301 ------------------------------------------------------------------------------
302  REQUIREMENTS
303
304  None
305
306 ------------------------------------------------------------------------------
307  REFERENCES
308
309  cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
310
311 ------------------------------------------------------------------------------
312  PSEUDO-CODE
313
314 void cl_ltp_exit (clLtpState **state)
315 {
316     if (state == NULL || *state == NULL)
317         return;
318
319     // dealloc members
320     Pitch_fr_exit(&(*state)->pitchSt);
321
322     // deallocate memory
323     free(*state);
324     *state = NULL;
325
326     return;
327 }
328
329 ------------------------------------------------------------------------------
330  CAUTION [optional]
331  [State any special notes, constraints or cautions for users of this function]
332
333 ------------------------------------------------------------------------------
334 */
335
336 void cl_ltp_exit(clLtpState **state)
337 {
338     if (state == NULL || *state == NULL)
339     {
340         return;
341     }
342
343     /* dealloc members */
344     Pitch_fr_exit(&(*state)->pitchSt);
345
346     /* deallocate memory */
347     oscl_free(*state);
348     *state = NULL;
349
350     return;
351 }
352
353 /****************************************************************************/
354
355 /*
356 ------------------------------------------------------------------------------
357  FUNCTION NAME: cl_ltp
358 ------------------------------------------------------------------------------
359  INPUT AND OUTPUT DEFINITIONS
360
361  Inputs:
362     clSt = pointer to the clLtpState struct
363     tonSt = pointer to the tonStabState structure
364     mode = codec mode value, of type enum Mode
365     frameOffset = offset to subframe (Word16)
366     T_op = pointer to buffer of open loop pitch lags (Word16)
367     h1 = pointer to impulse response vector (Word16)
368     exc = pointer to excitation vector (Word16)
369     res2 = pointer to long term prediction residual (Word16)
370     xn = pointer to target vector for pitch search (Word16)
371     lsp_flag = LSP resonance flag (Word16)
372
373  Outputs:
374     clSt = pointer to the clLtpState struct
375     tonSt = pointer to the tonStabState structure
376     exc = pointer to excitation vector (Word16)
377     res2 = pointer to long term prediction residual (Word16)
378     xn2 = pointer to target vector for codebook search (Word16)
379     yl = pointer to buffer of filtered adaptive excitation (Word16)
380     T0 = pointer to pitch delay (integer part) (Word16)
381     T0_frac = pointer to pitch delay (fractional part) (Word16)
382     gain_pit = pointer to pitch gain (Word16)
383     g_coeff = pointer to array of correlations between xn, y1, & y2 (Word16)
384     anap = pointer to pointer to analysis parameters (Word16)
385     gp_limit = pointer to the pitch gain limit (Word16)
386     pOverflow = pointer to overflow indicator (Flag)
387
388  Returns:
389     return_value = 0 (int)
390
391  Global Variables Used:
392     None
393
394  Local Variables Needed:
395     None
396
397 ------------------------------------------------------------------------------
398  FUNCTION DESCRIPTION
399
400  This function performs closed-loop fractional pitch search.
401
402 ------------------------------------------------------------------------------
403  REQUIREMENTS
404
405  None.
406
407 ------------------------------------------------------------------------------
408  REFERENCES
409
410  cl_ltp.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
411
412 ------------------------------------------------------------------------------
413  PSEUDO-CODE FOR cl_ltp
414
415 int cl_ltp (
416     clLtpState *clSt,    // i/o : State struct
417     tonStabState *tonSt, // i/o : State struct
418     enum Mode mode,      // i   : coder mode
419     Word16 frameOffset,  // i   : Offset to subframe
420     Word16 T_op[],       // i   : Open loop pitch lags
421     Word16 *h1,          // i   : Impulse response vector               Q12
422     Word16 *exc,         // i/o : Excitation vector                      Q0
423     Word16 res2[],       // i/o : Long term prediction residual          Q0
424     Word16 xn[],         // i   : Target vector for pitch search         Q0
425     Word16 lsp_flag,     // i   : LSP resonance flag
426     Word16 xn2[],        // o   : Target vector for codebook search      Q0
427     Word16 y1[],         // o   : Filtered adaptive excitation           Q0
428     Word16 *T0,          // o   : Pitch delay (integer part)
429     Word16 *T0_frac,     // o   : Pitch delay (fractional part)
430     Word16 *gain_pit,    // o   : Pitch gain                            Q14
431     Word16 g_coeff[],    // o   : Correlations between xn, y1, & y2
432     Word16 **anap,       // o   : Analysis parameters
433     Word16 *gp_limit     // o   : pitch gain limit
434 )
435 {
436     Word16 i;
437     Word16 index;
438     Word32 L_temp;     // temporarily variable
439     Word16 resu3;      // flag for upsample resolution
440     Word16 gpc_flag;
441
442     *----------------------------------------------------------------------*
443     *                 Closed-loop fractional pitch search                  *
444     *----------------------------------------------------------------------*
445    *T0 = Pitch_fr(clSt->pitchSt,
446                   mode, T_op, exc, xn, h1,
447                   L_SUBFR, frameOffset,
448                   T0_frac, &resu3, &index);
449
450    *(*anap)++ = index;
451
452     *-----------------------------------------------------------------*
453     *   - find unity gain pitch excitation (adapitve codebook entry)  *
454     *     with fractional interpolation.                              *
455     *   - find filtered pitch exc. y1[]=exc[] convolve with h1[])     *
456     *   - compute pitch gain and limit between 0 and 1.2              *
457     *   - update target vector for codebook search                    *
458     *   - find LTP residual.                                          *
459     *-----------------------------------------------------------------*
460
461    Pred_lt_3or6(exc, *T0, *T0_frac, L_SUBFR, resu3);
462
463    Convolve(exc, h1, y1, L_SUBFR);
464
465    // gain_pit is Q14 for all modes
466    *gain_pit = G_pitch(mode, xn, y1, g_coeff, L_SUBFR);
467
468
469    // check if the pitch gain should be limit due to resonance in LPC filter
470    gpc_flag = 0;
471    *gp_limit = MAX_16;
472    if ((lsp_flag != 0) &&
473        (sub(*gain_pit, GP_CLIP) > 0))
474    {
475        gpc_flag = check_gp_clipping(tonSt, *gain_pit);
476    }
477
478    // special for the MR475, MR515 mode; limit the gain to 0.85 to
479    // cope with bit errors in the decoder in a better way.
480    if ((sub (mode, MR475) == 0) || (sub (mode, MR515) == 0)) {
481       if ( sub (*gain_pit, 13926) > 0) {
482          *gain_pit = 13926;   // 0.85 in Q14
483       }
484
485       if (gpc_flag != 0) {
486           *gp_limit = GP_CLIP;
487       }
488    }
489    else
490    {
491        if (gpc_flag != 0)
492        {
493            *gp_limit = GP_CLIP;
494            *gain_pit = GP_CLIP;
495        }
496        // For MR122, gain_pit is quantized here and not in gainQuant
497        if (sub(mode, MR122)==0)
498        {
499            *(*anap)++ = q_gain_pitch(MR122, *gp_limit, gain_pit,
500                                      NULL, NULL);
501        }
502    }
503
504    // update target vector und evaluate LTP residual
505    for (i = 0; i < L_SUBFR; i++) {
506        L_temp = L_mult(y1[i], *gain_pit);
507        L_temp = L_shl(L_temp, 1);
508        xn2[i] = sub(xn[i], extract_h(L_temp));
509
510        L_temp = L_mult(exc[i], *gain_pit);
511        L_temp = L_shl(L_temp, 1);
512        res2[i] = sub(res2[i], extract_h(L_temp));
513    }
514
515    return 0;
516 }
517
518 ------------------------------------------------------------------------------
519  CAUTION [optional]
520  [State any special notes, constraints or cautions for users of this function]
521
522 ------------------------------------------------------------------------------
523 */
524
525 void cl_ltp(
526     clLtpState *clSt,    /* i/o : State struct                              */
527     tonStabState *tonSt, /* i/o : State struct                              */
528     enum Mode mode,      /* i   : coder mode                                */
529     Word16 frameOffset,  /* i   : Offset to subframe                        */
530     Word16 T_op[],       /* i   : Open loop pitch lags                      */
531     Word16 *h1,          /* i   : Impulse response vector               Q12 */
532     Word16 *exc,         /* i/o : Excitation vector                      Q0 */
533     Word16 res2[],       /* i/o : Long term prediction residual          Q0 */
534     Word16 xn[],         /* i   : Target vector for pitch search         Q0 */
535     Word16 lsp_flag,     /* i   : LSP resonance flag                        */
536     Word16 xn2[],        /* o   : Target vector for codebook search      Q0 */
537     Word16 yl[],         /* o   : Filtered adaptive excitation           Q0 */
538     Word16 *T0,          /* o   : Pitch delay (integer part)                */
539     Word16 *T0_frac,     /* o   : Pitch delay (fractional part)             */
540     Word16 *gain_pit,    /* o   : Pitch gain                            Q14 */
541     Word16 g_coeff[],    /* o   : Correlations between xn, y1, & y2         */
542     Word16 **anap,       /* o   : Analysis parameters                       */
543     Word16 *gp_limit,    /* o   : pitch gain limit                          */
544     const Word16* qua_gain_pitch_ptr, /* i : ptr to read-only table         */
545     Flag   *pOverflow    /* o   : overflow indicator                        */
546 )
547 {
548     register Word16 i;
549     Word16 index;
550     Word32 L_temp;     /* temporarily variable */
551     Word16 resu3;      /* flag for upsample resolution */
552     Word16 gpc_flag;
553
554     Word16 temp;
555     Word16 *p_exc;
556     Word16 *p_xn;
557     Word16 *p_xn2;
558     Word16 *p_yl;
559
560     /*----------------------------------------------------------------------*
561      *                 Closed-loop fractional pitch search                  *
562      *----------------------------------------------------------------------*/
563     *T0 =
564         Pitch_fr(
565             clSt->pitchSt,
566             mode,
567             T_op,
568             exc,
569             xn,
570             h1,
571             L_SUBFR,
572             frameOffset,
573             T0_frac,
574             &resu3,
575             &index,
576             pOverflow);
577
578     *(*anap)++ = index;
579
580     /*-----------------------------------------------------------------*
581      *   - find unity gain pitch excitation (adapitve codebook entry)  *
582      *     with fractional interpolation.                              *
583      *   - find filtered pitch exc. y1[]=exc[] convolve with h1[])     *
584      *   - compute pitch gain and limit between 0 and 1.2              *
585      *   - update target vector for codebook search                    *
586      *   - find LTP residual.                                          *
587      *-----------------------------------------------------------------*/
588
589     Pred_lt_3or6(
590         exc,
591         *T0,
592         *T0_frac,
593         L_SUBFR,
594         resu3,
595         pOverflow);
596
597     Convolve(exc, h1, yl, L_SUBFR);
598
599     /* gain_pit is Q14 for all modes */
600     *gain_pit =
601         G_pitch(
602             mode,
603             xn,
604             yl,
605             g_coeff,
606             L_SUBFR,
607             pOverflow);
608
609
610     /* check if the pitch gain should be limit due to resonance in LPC filter */
611     gpc_flag = 0;
612     *gp_limit = MAX_16;
613
614     if ((lsp_flag != 0) && ((Word32)(*gain_pit) > GP_CLIP))
615     {
616         gpc_flag = check_gp_clipping(tonSt, *gain_pit, pOverflow);
617     }
618
619     /* special for the MR475, MR515 mode; limit the gain to 0.85 to */
620     /* cope with bit errors in the decoder in a better way.         */
621
622     if ((mode == MR475) || (mode == MR515))
623     {
624         *gain_pit = ((Word32) * gain_pit > 13926) ? 13926 : *gain_pit;
625
626         if (gpc_flag != 0)
627         {
628             *gp_limit = GP_CLIP;
629         }
630     }
631     else
632     {
633         if (gpc_flag != 0)
634         {
635             *gp_limit = GP_CLIP;
636             *gain_pit = GP_CLIP;
637         }
638         /* For MR122, gain_pit is quantized here and not in gainQuant */
639         if (mode == MR122)
640         {
641             *(*anap)++ =
642                 q_gain_pitch(
643                     MR122,
644                     *gp_limit,
645                     gain_pit,
646                     NULL,
647                     NULL,
648                     qua_gain_pitch_ptr,
649                     pOverflow);
650         }
651     }
652
653
654     p_exc  = &exc[0];
655     p_xn   =  &xn[0];
656     p_xn2  = &xn2[0];
657     p_yl   =  &yl[0];
658
659     temp = *gain_pit;
660
661     /* update target vector und evaluate LTP residual */
662     for (i = 0; i < L_SUBFR; i++)
663     {
664         L_temp = ((Word32) * (p_yl++) * temp) >> 14;
665         *(p_xn2++) = *(p_xn++) - (Word16)L_temp;
666
667         L_temp   = ((Word32) * (p_exc++) * temp) >> 14;
668         res2[i] -= (Word16)L_temp;
669     }
670
671 }