xref: /aosp_15_r20/frameworks/av/media/module/codecs/amrnb/enc/src/spstproc.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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  Pathname: ./audio/gsm-amr/c/src/spstproc.c
35  Functions: subframePostProc
36 
37      Date: 02/06/2002
38 
39 ------------------------------------------------------------------------------
40  REVISION HISTORY
41 
42  Description: Updated template used to PV coding template.
43  Changed to accept the pOverflow flag for EPOC compatibility.
44 
45  Description:
46               1. Eliminated unused include files.
47               2. Replaced array addressing by pointers
48               3. Eliminated math operations that unnecessary checked for
49                  saturation
50               4. Replaced loop counter with decrement loops
51 
52  Description:  Added casting to eliminate warnings
53 
54  Description:  Replaced "int" and/or "char" with OSCL defined types.
55 
56  Description:
57 
58 ------------------------------------------------------------------------------
59  MODULE DESCRIPTION
60 
61     Subframe post processing
62 ------------------------------------------------------------------------------
63 */
64 
65 /*----------------------------------------------------------------------------
66 ; INCLUDES
67 ----------------------------------------------------------------------------*/
68 #include "spstproc.h"
69 #include "syn_filt.h"
70 #include "cnst.h"
71 
72 /*----------------------------------------------------------------------------
73 ; MACROS
74 ; Define module specific macros here
75 ----------------------------------------------------------------------------*/
76 
77 /*----------------------------------------------------------------------------
78 ; DEFINES
79 ; Include all pre-processor statements here. Include conditional
80 ; compile variables also.
81 ----------------------------------------------------------------------------*/
82 
83 /*----------------------------------------------------------------------------
84 ; LOCAL FUNCTION DEFINITIONS
85 ; Function Prototype declaration
86 ----------------------------------------------------------------------------*/
87 
88 /*----------------------------------------------------------------------------
89 ; LOCAL VARIABLE DEFINITIONS
90 ; Variable declaration - defined here and used outside this module
91 ----------------------------------------------------------------------------*/
92 
93 /*
94 ------------------------------------------------------------------------------
95  FUNCTION NAME: subframePostProc
96 ------------------------------------------------------------------------------
97  INPUT AND OUTPUT DEFINITIONS
98 
99 
100  Inputs:
101     speech    -- Pointer to Word16 -- speech segment
102     mode      -- enum Mode         -- coder mode
103     i_subfr   -- Word16 -- Subframe nr
104     gain_pit  -- Word16 -- Pitch gain  Q14
105     gain_code -- Word16 -- Decoded innovation gain
106     Aq        -- Pointer to Word16 -- A(z) quantized for the 4 subframes
107     synth     -- Word16 Array -- Local synthesis
108     xn        -- Word16 Array -- Target vector for pitch search
109     code      -- Word16 Array -- Fixed codebook exitation
110     y1        -- Word16 Array -- Filtered adaptive exitation
111     y2        -- Word16 Array -- Filtered fixed codebook excitation
112     mem_syn   -- Pointer to Word16 -- memory of synthesis filter
113 
114  Outputs:
115     mem_syn -- Pointer to Word16 -- memory of synthesis filter
116     mem_err -- Pointer to Word16 -- pointer to error signal
117     mem_w0  -- Pointer to Word16 -- memory of weighting filter
118     exc     -- Pointer to Word16 -- long term prediction residual
119     sharp   -- Pointer to Word16 -- pitch sharpening value
120     pOverflow -- Pointer to Flag -- overflow indicator
121 
122  Returns:
123     None
124 
125  Global Variables Used:
126     None
127 
128  Local Variables Needed:
129     None
130 
131 ------------------------------------------------------------------------------
132  FUNCTION DESCRIPTION
133 
134 
135 ------------------------------------------------------------------------------
136  REQUIREMENTS
137 
138  None
139 
140 ------------------------------------------------------------------------------
141  REFERENCES
142 
143  spstproc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
144 
145 ------------------------------------------------------------------------------
146  PSEUDO-CODE
147 
148 
149 ------------------------------------------------------------------------------
150  RESOURCES USED [optional]
151 
152  When the code is written for a specific target processor the
153  the resources used should be documented below.
154 
155  HEAP MEMORY USED: x bytes
156 
157  STACK MEMORY USED: x bytes
158 
159  CLOCK CYCLES: (cycle count equation for this function) + (variable
160                 used to represent cycle count for each subroutine
161                 called)
162      where: (cycle count variable) = cycle count for [subroutine
163                                      name]
164 
165 ------------------------------------------------------------------------------
166  CAUTION [optional]
167  [State any special notes, constraints or cautions for users of this function]
168 
169 ------------------------------------------------------------------------------
170 */
171 
subframePostProc(Word16 * speech,enum Mode mode,Word16 i_subfr,Word16 gain_pit,Word16 gain_code,Word16 * Aq,Word16 synth[],Word16 xn[],Word16 code[],Word16 y1[],Word16 y2[],Word16 * mem_syn,Word16 * mem_err,Word16 * mem_w0,Word16 * exc,Word16 * sharp,Flag * pOverflow)172 void subframePostProc(
173     Word16 *speech,   /* i   : speech segment                        */
174     enum Mode mode,   /* i   : coder mode                            */
175     Word16 i_subfr,   /* i   : Subframe nr                           */
176     Word16 gain_pit,  /* i   : Pitch gain                       Q14  */
177     Word16 gain_code, /* i   : Decoded innovation gain               */
178     Word16 *Aq,       /* i   : A(z) quantized for the 4 subframes    */
179     Word16 synth[],   /* i   : Local snthesis                        */
180     Word16 xn[],      /* i   : Target vector for pitch search        */
181     Word16 code[],    /* i   : Fixed codebook exitation              */
182     Word16 y1[],      /* i   : Filtered adaptive exitation           */
183     Word16 y2[],      /* i   : Filtered fixed codebook excitation    */
184     Word16 *mem_syn,  /* i/o : memory of synthesis filter            */
185     Word16 *mem_err,  /* o   : pointer to error signal               */
186     Word16 *mem_w0,   /* o   : memory of weighting filter            */
187     Word16 *exc,      /* o   : long term prediction residual         */
188     Word16 *sharp,    /* o   : pitch sharpening value                */
189     Flag   *pOverflow /* o   : overflow indicator                    */
190 )
191 {
192     Word16 i;
193     Word16 j;
194     Word16 temp;
195     Word32 mul;
196     Word32 L_temp;
197     Word32 L_temp2;
198     Word16 tempShift;
199     Word16 kShift;
200     Word16 pitch_fac;
201     Word16 *p_exc;
202     Word16 *p_code;
203 
204     OSCL_UNUSED_ARG(pOverflow);
205 
206     if (mode != MR122)
207     {
208         tempShift = 1;
209         kShift = 16 - 2 - 1;
210         pitch_fac = gain_pit;
211     }
212     else
213     {
214         tempShift = 2;
215         kShift = 16 - 4 - 1;
216         pitch_fac = gain_pit >> 1;
217     }
218 
219     /*------------------------------------------------------------*
220      * - Update pitch sharpening "sharp" with quantized gain_pit  *
221      *------------------------------------------------------------*/
222 
223     if (gain_pit < SHARPMAX)
224     {
225         *sharp = gain_pit;
226     }
227     else
228     {
229         *sharp = SHARPMAX;
230     }
231 
232     /*------------------------------------------------------*
233      * - Find the total excitation                          *
234      * - find synthesis speech corresponding to exc[]       *
235      * - update filters memories for finding the target     *
236      *   vector in the next subframe                        *
237      *   (update error[-m..-1] and mem_w_err[])             *
238      *------------------------------------------------------*/
239 
240     p_exc  = &exc[ i_subfr];
241     p_code = &code[0];
242 
243     for (i = L_SUBFR >> 1; i != 0 ; i--)
244     {
245         /* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */
246 
247         /*
248          *                      12k2  others
249          * ---------------------------------
250          * exc                   Q0      Q0
251          * gain_pit              Q14     Q14
252          * pitch_fac             Q13     Q14
253          *    product:           Q14     Q15
254          *
255          * code                  Q12     Q13
256          * gain_code             Q1      Q1
257          *    product            Q14     Q15
258          *    sum                Q14     Q15
259          *
260          * tempShift             2       1
261          *    sum<<tempShift     Q16     Q16
262          * result -> exc         Q0      Q0
263          */
264         L_temp     = ((Word32) * (p_exc++) * pitch_fac) << 1;
265         L_temp2    = ((Word32) * (p_exc--) * pitch_fac) << 1;
266         __builtin_mul_overflow(*(p_code++), gain_code, &mul);
267         __builtin_add_overflow(L_temp, mul << 1, &L_temp);
268         __builtin_mul_overflow(*(p_code++), gain_code, &mul);
269         __builtin_add_overflow(L_temp2, mul << 1, &L_temp2);
270         L_temp   <<=  tempShift;
271         L_temp2  <<=  tempShift;
272         *(p_exc++) = (Word16)((L_temp  + 0x08000L) >> 16);
273         *(p_exc++) = (Word16)((L_temp2 + 0x08000L) >> 16);
274 
275     }
276 
277     Syn_filt(
278         Aq,
279         &exc[i_subfr],
280         &synth[i_subfr],
281         L_SUBFR,
282         mem_syn,
283         1);
284 
285     for (i = L_SUBFR - M, j = 0; i < L_SUBFR; i++, j++)
286     {
287         mem_err[j] = speech[i_subfr + i] - synth[i_subfr + i];
288 
289         /*
290          *                      12k2  others
291          * ---------------------------------
292          * y1                    Q0      Q0
293          * gain_pit              Q14     Q14
294          *    product            Q15     Q15
295          *    shifted prod.      Q16     Q16
296          * temp                  Q0      Q0
297          *
298          * y2                    Q10     Q12
299          * gain_code             Q1      Q1
300          *    product            Q12     Q14
301          * kshift                 4       2
302          *    shifted prod.      Q16     Q16
303          * k                     Q0      Q0
304          * mem_w0,xn,sum         Q0      Q0
305          */
306 
307         L_temp = ((Word32)y1[i] * gain_pit);
308         temp  = (Word16)(L_temp >> 14);
309 
310         L_temp = ((Word32)y2[i] * gain_code);
311         temp += (Word16)(L_temp >> kShift);
312 
313         mem_w0[j] = xn[i] - temp;
314     }
315 
316     return;
317 }
318