Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / spstproc.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: spstproc.cpp
35  Functions: subframePostProc
36
37 ------------------------------------------------------------------------------
38  MODULE DESCRIPTION
39
40     Subframe post processing
41 ------------------------------------------------------------------------------
42 */
43
44 /*----------------------------------------------------------------------------
45 ; INCLUDES
46 ----------------------------------------------------------------------------*/
47 #include "spstproc.h"
48 #include "syn_filt.h"
49 #include "cnst.h"
50
51 /*----------------------------------------------------------------------------
52 ; MACROS
53 ; Define module specific macros here
54 ----------------------------------------------------------------------------*/
55
56 /*----------------------------------------------------------------------------
57 ; DEFINES
58 ; Include all pre-processor statements here. Include conditional
59 ; compile variables also.
60 ----------------------------------------------------------------------------*/
61
62 /*----------------------------------------------------------------------------
63 ; LOCAL FUNCTION DEFINITIONS
64 ; Function Prototype declaration
65 ----------------------------------------------------------------------------*/
66
67 /*----------------------------------------------------------------------------
68 ; LOCAL VARIABLE DEFINITIONS
69 ; Variable declaration - defined here and used outside this module
70 ----------------------------------------------------------------------------*/
71
72 /*
73 ------------------------------------------------------------------------------
74  FUNCTION NAME: subframePostProc
75 ------------------------------------------------------------------------------
76  INPUT AND OUTPUT DEFINITIONS
77
78
79  Inputs:
80     speech    -- Pointer to Word16 -- speech segment
81     mode      -- enum Mode         -- coder mode
82     i_subfr   -- Word16 -- Subframe nr
83     gain_pit  -- Word16 -- Pitch gain  Q14
84     gain_code -- Word16 -- Decoded innovation gain
85     Aq        -- Pointer to Word16 -- A(z) quantized for the 4 subframes
86     synth     -- Word16 Array -- Local synthesis
87     xn        -- Word16 Array -- Target vector for pitch search
88     code      -- Word16 Array -- Fixed codebook exitation
89     y1        -- Word16 Array -- Filtered adaptive exitation
90     y2        -- Word16 Array -- Filtered fixed codebook excitation
91     mem_syn   -- Pointer to Word16 -- memory of synthesis filter
92
93  Outputs:
94     mem_syn -- Pointer to Word16 -- memory of synthesis filter
95     mem_err -- Pointer to Word16 -- pointer to error signal
96     mem_w0  -- Pointer to Word16 -- memory of weighting filter
97     exc     -- Pointer to Word16 -- long term prediction residual
98     sharp   -- Pointer to Word16 -- pitch sharpening value
99     pOverflow -- Pointer to Flag -- overflow indicator
100
101  Returns:
102     None
103
104  Global Variables Used:
105     None
106
107  Local Variables Needed:
108     None
109
110 ------------------------------------------------------------------------------
111  FUNCTION DESCRIPTION
112
113
114 ------------------------------------------------------------------------------
115  REQUIREMENTS
116
117  None
118
119 ------------------------------------------------------------------------------
120  REFERENCES
121
122  spstproc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
123
124 ------------------------------------------------------------------------------
125  PSEUDO-CODE
126
127
128 ------------------------------------------------------------------------------
129  CAUTION [optional]
130  [State any special notes, constraints or cautions for users of this function]
131
132 ------------------------------------------------------------------------------
133 */
134
135 void subframePostProc(
136     Word16 *speech,   /* i   : speech segment                        */
137     enum Mode mode,   /* i   : coder mode                            */
138     Word16 i_subfr,   /* i   : Subframe nr                           */
139     Word16 gain_pit,  /* i   : Pitch gain                       Q14  */
140     Word16 gain_code, /* i   : Decoded innovation gain               */
141     Word16 *Aq,       /* i   : A(z) quantized for the 4 subframes    */
142     Word16 synth[],   /* i   : Local snthesis                        */
143     Word16 xn[],      /* i   : Target vector for pitch search        */
144     Word16 code[],    /* i   : Fixed codebook exitation              */
145     Word16 y1[],      /* i   : Filtered adaptive exitation           */
146     Word16 y2[],      /* i   : Filtered fixed codebook excitation    */
147     Word16 *mem_syn,  /* i/o : memory of synthesis filter            */
148     Word16 *mem_err,  /* o   : pointer to error signal               */
149     Word16 *mem_w0,   /* o   : memory of weighting filter            */
150     Word16 *exc,      /* o   : long term prediction residual         */
151     Word16 *sharp,    /* o   : pitch sharpening value                */
152     Flag   *pOverflow /* o   : overflow indicator                    */
153 )
154 {
155     Word16 i;
156     Word16 j;
157     Word16 temp;
158     Word32 L_temp;
159     Word32 L_temp2;
160     Word16 tempShift;
161     Word16 kShift;
162     Word16 pitch_fac;
163     Word16 *p_exc;
164     Word16 *p_code;
165
166     OSCL_UNUSED_ARG(pOverflow);
167
168     if (mode != MR122)
169     {
170         tempShift = 1;
171         kShift = 16 - 2 - 1;
172         pitch_fac = gain_pit;
173     }
174     else
175     {
176         tempShift = 2;
177         kShift = 16 - 4 - 1;
178         pitch_fac = gain_pit >> 1;
179     }
180
181     /*------------------------------------------------------------*
182      * - Update pitch sharpening "sharp" with quantized gain_pit  *
183      *------------------------------------------------------------*/
184
185     if (gain_pit < SHARPMAX)
186     {
187         *sharp = gain_pit;
188     }
189     else
190     {
191         *sharp = SHARPMAX;
192     }
193
194     /*------------------------------------------------------*
195      * - Find the total excitation                          *
196      * - find synthesis speech corresponding to exc[]       *
197      * - update filters memories for finding the target     *
198      *   vector in the next subframe                        *
199      *   (update error[-m..-1] and mem_w_err[])             *
200      *------------------------------------------------------*/
201
202     p_exc  = &exc[ i_subfr];
203     p_code = &code[0];
204
205     for (i = L_SUBFR >> 1; i != 0 ; i--)
206     {
207         /* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */
208
209         /*
210          *                      12k2  others
211          * ---------------------------------
212          * exc                   Q0      Q0
213          * gain_pit              Q14     Q14
214          * pitch_fac             Q13     Q14
215          *    product:           Q14     Q15
216          *
217          * code                  Q12     Q13
218          * gain_code             Q1      Q1
219          *    product            Q14     Q15
220          *    sum                Q14     Q15
221          *
222          * tempShift             2       1
223          *    sum<<tempShift     Q16     Q16
224          * result -> exc         Q0      Q0
225          */
226         L_temp     = ((Word32) * (p_exc++) * pitch_fac) << 1;
227         L_temp2    = ((Word32) * (p_exc--) * pitch_fac) << 1;
228         L_temp    += ((Word32) * (p_code++) * gain_code) << 1;
229         L_temp2   += ((Word32) * (p_code++) * gain_code) << 1;
230         L_temp   <<=  tempShift;
231         L_temp2  <<=  tempShift;
232         *(p_exc++) = (Word16)((L_temp  + 0x08000L) >> 16);
233         *(p_exc++) = (Word16)((L_temp2 + 0x08000L) >> 16);
234
235     }
236
237     Syn_filt(
238         Aq,
239         &exc[i_subfr],
240         &synth[i_subfr],
241         L_SUBFR,
242         mem_syn,
243         1);
244
245     for (i = L_SUBFR - M, j = 0; i < L_SUBFR; i++, j++)
246     {
247         mem_err[j] = speech[i_subfr + i] - synth[i_subfr + i];
248
249         /*
250          *                      12k2  others
251          * ---------------------------------
252          * y1                    Q0      Q0
253          * gain_pit              Q14     Q14
254          *    product            Q15     Q15
255          *    shifted prod.      Q16     Q16
256          * temp                  Q0      Q0
257          *
258          * y2                    Q10     Q12
259          * gain_code             Q1      Q1
260          *    product            Q12     Q14
261          * kshift                 4       2
262          *    shifted prod.      Q16     Q16
263          * k                     Q0      Q0
264          * mem_w0,xn,sum         Q0      Q0
265          */
266
267         L_temp = ((Word32)y1[i] * gain_pit);
268         temp  = (Word16)(L_temp >> 14);
269
270         L_temp = ((Word32)y2[i] * gain_code);
271         temp += (Word16)(L_temp >> kShift);
272
273         mem_w0[j] = xn[i] - temp;
274     }
275
276     return;
277 }