Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / dec / src / int_lsf.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: int_lsf.cpp
35
36 ------------------------------------------------------------------------------
37 */
38
39 /*----------------------------------------------------------------------------
40 ; INCLUDES
41 ----------------------------------------------------------------------------*/
42 #include    "int_lsf.h"
43 #include    "typedef.h"
44 #include    "basic_op.h"
45 #include    "cnst.h"
46
47 /*----------------------------------------------------------------------------
48 ; MACROS
49 ; Define module specific macros here
50 ----------------------------------------------------------------------------*/
51
52
53 /*----------------------------------------------------------------------------
54 ; DEFINES
55 ; Include all pre-processor statements here. Include conditional
56 ; compile variables also.
57 ----------------------------------------------------------------------------*/
58
59
60 /*----------------------------------------------------------------------------
61 ; LOCAL FUNCTION DEFINITIONS
62 ; Function Prototype declaration
63 ----------------------------------------------------------------------------*/
64
65
66 /*----------------------------------------------------------------------------
67 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
68 ; Variable declaration - defined here and used outside this module
69 ----------------------------------------------------------------------------*/
70
71
72 /*
73 ------------------------------------------------------------------------------
74  FUNCTION NAME: Int_lsf
75 ------------------------------------------------------------------------------
76  INPUT AND OUTPUT DEFINITIONS
77
78  Inputs:
79     lsf_old = LSF vector at the 4th SF of past frame (Word16)
80     lsf_new = LSF vector at the 4th SF of present frame (Word16)
81     i_subfr = Current subframe (equal to 0,40,80 or 120) (Word16)
82     lsf_out = interpolated LSF parameters for current subframe (Word16)
83
84  Outputs:
85     lsf_out   = new interpolated LSF parameters for current subframe
86     pOverflow = pointer of type Flag * to overflow indicator.
87
88  Returns:
89     None.
90
91  Global Variables Used:
92     None.
93
94  Local Variables Needed:
95     None.
96
97 ------------------------------------------------------------------------------
98  FUNCTION DESCRIPTION
99
100  This function interpolates the LSFs for selected subframe.
101  The 20 ms speech frame is divided into 4 subframes. The LSFs are
102  interpolated at the 1st, 2nd and 3rd subframe and only forwarded
103  at the 4th subframe.
104
105                       |------|------|------|------|
106                          sf1    sf2    sf3    sf4
107                    F0                          F1
108
109                  sf1:   3/4 F0 + 1/4 F1         sf3:   1/4 F0 + 3/4 F1
110                  sf2:   1/2 F0 + 1/2 F1         sf4:       F1
111
112 ------------------------------------------------------------------------------
113  REQUIREMENTS
114
115  None.
116
117 ------------------------------------------------------------------------------
118  REFERENCES
119
120  int_lsf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
121
122 ------------------------------------------------------------------------------
123  PSEUDO-CODE
124
125 void Int_lsf(
126     Word16 lsf_old[], // i : LSF vector at the 4th SF of past frame
127     Word16 lsf_new[], // i : LSF vector at the 4th SF of present frame
128     Word16 i_subfr,   // i : Pointer to current sf (equal to 0,40,80 or 120)
129     Word16 lsf_out[]  // o : interpolated LSF parameters for current sf
130 )
131 {
132     Word16 i;
133
134     if ( i_subfr == 0 )
135     {
136        for (i = 0; i < M; i++) {
137           lsf_out[i] = add(sub(lsf_old[i], shr(lsf_old[i], 2)),
138                            shr(lsf_new[i], 2));
139        }
140     }
141     else if ( sub(i_subfr, 40) == 0 )
142     {
143        for (i = 0; i < M; i++) {
144           lsf_out[i] = add(shr(lsf_old[i],1), shr(lsf_new[i], 1) );
145        }
146     }
147     else if ( sub(i_subfr, 80) == 0 )
148     {
149        for (i = 0; i < M; i++) {
150           lsf_out[i] = add(shr(lsf_old[i], 2),
151                            sub(lsf_new[i], shr(lsf_new[i], 2)));
152        }
153     }
154     else if ( sub(i_subfr, 120) == 0 )
155     {
156        for (i = 0; i < M; i++) {
157           lsf_out[i] = lsf_new[i];
158        }
159     }
160
161     return;
162 }
163
164 ------------------------------------------------------------------------------
165  CAUTION [optional]
166  [State any special notes, constraints or cautions for users of this function]
167
168 ------------------------------------------------------------------------------
169 */
170
171 void Int_lsf(
172     Word16 lsf_old[], /* i : LSF vector at the 4th SF of past frame         */
173     Word16 lsf_new[], /* i : LSF vector at the 4th SF of present frame      */
174     Word16 i_subfr,   /* i : Current sf (equal to 0,40,80 or 120)           */
175     Word16 lsf_out[], /* o : interpolated LSF parameters for current sf     */
176     Flag  *pOverflow  /* o : flag set if overflow occurs                    */
177 )
178 {
179     register Word16 i;
180     register Word16 temp1;
181     register Word16 temp2;
182
183     if (i_subfr == 0)
184     {
185         for (i = M - 1; i >= 0; i--)
186         {
187             if (*(lsf_old + i) < 0)
188             {
189                 temp1 = ~(~(*(lsf_old + i)) >> 2);
190             }
191             else
192             {
193                 temp1 = *(lsf_old + i) >> 2;
194             }
195             if (*(lsf_new + i) < 0)
196             {
197                 temp2 = ~(~(*(lsf_new + i)) >> 2);
198             }
199             else
200             {
201                 temp2 = *(lsf_new + i) >> 2;
202             }
203             *(lsf_out + i) = add_16((Word16)(*(lsf_old + i) - temp1),
204                                     (Word16)temp2,
205                                     pOverflow);
206         }
207     }
208
209     else if (i_subfr == 40)
210     {
211         for (i = M - 1; i >= 0; i--)
212         {
213             if (*(lsf_old + i) < 0)
214             {
215                 temp1 = ~(~(*(lsf_old + i)) >> 1);
216             }
217             else
218             {
219                 temp1 = *(lsf_old + i) >> 1;
220             }
221             if (*(lsf_new + i) < 0)
222             {
223                 temp2 = ~(~(*(lsf_new + i)) >> 1);
224             }
225             else
226             {
227                 temp2 = *(lsf_new + i) >> 1;
228             }
229             *(lsf_out + i) = temp1 + temp2;
230         }
231     }
232
233     else if (i_subfr == 80)
234     {
235         for (i = M - 1; i >= 0; i--)
236         {
237             if (*(lsf_old + i) < 0)
238             {
239                 temp1 = ~(~(*(lsf_old + i)) >> 2);
240             }
241             else
242             {
243                 temp1 = *(lsf_old + i) >> 2;
244             }
245             if (*(lsf_new + i) < 0)
246             {
247                 temp2 = ~(~(*(lsf_new + i)) >> 2);
248             }
249             else
250             {
251                 temp2 = *(lsf_new + i) >> 2;
252             }
253             *(lsf_out + i) = add_16((Word16)temp1,
254                                     (Word16)(*(lsf_new + i) - temp2),
255                                     pOverflow);
256
257         }
258     }
259
260     else if (i_subfr == 120)
261     {
262         for (i = M - 1; i >= 0; i--)
263         {
264             *(lsf_out + i) = *(lsf_new + i);
265         }
266     }
267
268     return;
269 }
270