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
20 Filename: ps_stereo_processing.c
21
22------------------------------------------------------------------------------
23 REVISION HISTORY
24
25
26 Who:                                   Date: MM/DD/YYYY
27 Description:
28
29------------------------------------------------------------------------------
30 INPUT AND OUTPUT DEFINITIONS
31
32
33
34------------------------------------------------------------------------------
35 FUNCTION DESCRIPTION
36
37        Stereo Process or reconstruction
38
39           l_k(n) = H11(k,n)*s_k(n) + H21(k,n)*d_k(n)
40
41           r_k(n) = H12(k,n)*s_k(n) + H22(k,n)*d_k(n)
42
43     _______                                              ________
44    |       |                                  _______   |        |
45  ->|Hybrid | LF ----                         |       |->| Hybrid |-->
46    | Anal. |        |                        |       |  | Synth  |   QMF -> L
47     -------         o----------------------->|       |   --------    Synth
48QMF                  |                s_k(n)  |Stereo |-------------->
49Anal.              -------------------------->|       |
50     _______       | |                        |       |   ________
51    |       | HF --o |   -----------          |Process|  |        |
52  ->| Delay |      |  ->|           |-------->|       |->| Hybrid |-->
53     -------       |    |decorrelate| d_k(n)  |       |  | Synth  |   QMF -> R
54                   ---->|           |-------->|       |   --------    Synth
55                         -----------          |_______|-------------->
56
57
58------------------------------------------------------------------------------
59 REQUIREMENTS
60
61
62------------------------------------------------------------------------------
63 REFERENCES
64
65SC 29 Software Copyright Licencing Disclaimer:
66
67This software module was originally developed by
68  Coding Technologies
69
70and edited by
71  -
72
73in the course of development of the ISO/IEC 13818-7 and ISO/IEC 14496-3
74standards for reference purposes and its performance may not have been
75optimized. This software module is an implementation of one or more tools as
76specified by the ISO/IEC 13818-7 and ISO/IEC 14496-3 standards.
77ISO/IEC gives users free license to this software module or modifications
78thereof for use in products claiming conformance to audiovisual and
79image-coding related ITU Recommendations and/or ISO/IEC International
80Standards. ISO/IEC gives users the same free license to this software module or
81modifications thereof for research purposes and further ISO/IEC standardisation.
82Those intending to use this software module in products are advised that its
83use may infringe existing patents. ISO/IEC have no liability for use of this
84software module or modifications thereof. Copyright is not released for
85products that do not conform to audiovisual and image-coding related ITU
86Recommendations and/or ISO/IEC International Standards.
87The original developer retains full right to modify and use the code for its
88own purpose, assign or donate the code to a third party and to inhibit third
89parties from using the code for products that do not conform to audiovisual and
90image-coding related ITU Recommendations and/or ISO/IEC International Standards.
91This copyright notice must be included in all copies or derivative works.
92Copyright (c) ISO/IEC 2003.
93
94------------------------------------------------------------------------------
95 PSEUDO-CODE
96
97------------------------------------------------------------------------------
98*/
99
100
101/*----------------------------------------------------------------------------
102; INCLUDES
103----------------------------------------------------------------------------*/
104
105#ifdef AAC_PLUS
106
107#ifdef PARAMETRICSTEREO
108#include    "pv_audio_type_defs.h"
109#include    "ps_stereo_processing.h"
110#include    "fxp_mul32.h"
111#include    "ps_all_pass_filter_coeff.h"
112
113/*----------------------------------------------------------------------------
114; MACROS
115; Define module specific macros here
116----------------------------------------------------------------------------*/
117
118#ifndef min
119#define min(a, b) ((a) < (b) ? (a) : (b))
120#endif
121
122/*----------------------------------------------------------------------------
123; DEFINES
124; Include all pre-processor statements here. Include conditional
125; compile variables also.
126----------------------------------------------------------------------------*/
127
128/*----------------------------------------------------------------------------
129; LOCAL FUNCTION DEFINITIONS
130; Function Prototype declaration
131----------------------------------------------------------------------------*/
132
133/*----------------------------------------------------------------------------
134; LOCAL STORE/BUFFER/POINTER DEFINITIONS
135; Variable declaration - defined here and used outside this module
136----------------------------------------------------------------------------*/
137
138
139/*----------------------------------------------------------------------------
140; EXTERNAL FUNCTION REFERENCES
141; Declare functions defined elsewhere and referenced in this module
142----------------------------------------------------------------------------*/
143
144/*----------------------------------------------------------------------------
145; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
146; Declare variables used in this module but defined elsewhere
147----------------------------------------------------------------------------*/
148
149
150/*----------------------------------------------------------------------------
151; FUNCTION CODE
152----------------------------------------------------------------------------*/
153
154void ps_stereo_processing(STRUCT_PS_DEC  *pms,
155                          Int32          *qmfLeftReal,
156                          Int32          *qmfLeftImag,
157                          Int32          *qmfRightReal,
158                          Int32          *qmfRightImag)
159{
160    Int32     group;
161    Int32     subband;
162    Int32     maxSubband;
163    Int32     usb;
164    Char     index;
165
166
167    Int32  *hybrLeftReal;
168    Int32  *hybrLeftImag;
169    Int32  *hybrRightReal;
170    Int32  *hybrRightImag;
171    Int32  *ptr_hybrLeftReal;
172    Int32  *ptr_hybrLeftImag;
173    Int32  *ptr_hybrRightReal;
174    Int32  *ptr_hybrRightImag;
175
176
177    Int16   h11;
178    Int16   h12;
179    Int16   h21;
180    Int16   h22;
181
182    Int32   temp1;
183    Int32   temp2;
184    Int32   temp3;
185
186    usb = pms->usb;
187
188    /*
189     *   Complete Linear interpolation
190     */
191
192    hybrLeftReal  = pms->mHybridRealLeft;
193    hybrLeftImag  = pms->mHybridImagLeft;
194    hybrRightReal = pms->mHybridRealRight;
195    hybrRightImag = pms->mHybridImagRight;
196
197    for (group = 0; group < SUBQMF_GROUPS; group++)     /* SUBQMF_GROUPS == 10 */
198    {
199
200        temp1 = pms->deltaH11[group];
201        temp2 = pms->deltaH12[group];
202
203        pms->H11[group]  += temp1;
204        h11  = (Int16)(pms->H11[group] >> 16);
205        pms->H12[group]  += temp2;
206        h12  = (Int16)(pms->H12[group] >> 16);
207
208        temp1 = pms->deltaH21[group];
209        temp2 = pms->deltaH22[group];
210
211        pms->H21[group]  += temp1;
212        h21  = (Int16)(pms->H21[group] >> 16);
213        pms->H22[group]  += temp2;
214        h22  = (Int16)(pms->H22[group] >> 16);
215
216        index = groupBorders[group];
217
218        /*
219         *  Reconstruction of Stereo sub-band signal
220         *
221         *  l_k(n) = H11(k,n)*s_k(n) + H21(k,n)*d_k(n)
222         *
223         *  r_k(n) = H12(k,n)*s_k(n) + H22(k,n)*d_k(n)
224         */
225        ptr_hybrLeftReal  = &hybrLeftReal[  index];
226        ptr_hybrRightReal = &hybrRightReal[ index];
227
228        temp1 = *(ptr_hybrLeftReal) << 1;
229        temp2 = *(ptr_hybrRightReal) << 1;
230
231        temp3 = fxp_mul32_by_16(temp1, h11);
232        *(ptr_hybrLeftReal)  = fxp_mac32_by_16(temp2, h21, temp3) << 1;
233
234        temp3 = fxp_mul32_by_16(temp1, h12);
235        *(ptr_hybrRightReal) = fxp_mac32_by_16(temp2, h22, temp3) << 1;
236
237
238        ptr_hybrLeftImag  = &hybrLeftImag[  index];
239        ptr_hybrRightImag = &hybrRightImag[ index];
240
241        temp1 = *(ptr_hybrLeftImag) << 1;
242        temp2 = *(ptr_hybrRightImag) << 1;
243
244        temp3 = fxp_mul32_by_16(temp1, h11);
245        *(ptr_hybrLeftImag)  = fxp_mac32_by_16(temp2, h21, temp3) << 1;
246
247        temp3 = fxp_mul32_by_16(temp1, h12);
248        *(ptr_hybrRightImag) = fxp_mac32_by_16(temp2, h22, temp3) << 1;
249
250
251    } /* groups loop */
252
253    temp1 = pms->deltaH11[SUBQMF_GROUPS];
254    temp2 = pms->deltaH12[SUBQMF_GROUPS];
255
256    pms->H11[SUBQMF_GROUPS]  += temp1;
257    h11  = (Int16)(pms->H11[SUBQMF_GROUPS] >> 16);
258    pms->H12[SUBQMF_GROUPS]  += temp2;
259    h12  = (Int16)(pms->H12[SUBQMF_GROUPS] >> 16);
260
261    temp1 = pms->deltaH21[SUBQMF_GROUPS];
262    temp2 = pms->deltaH22[SUBQMF_GROUPS];
263
264    pms->H21[SUBQMF_GROUPS]  += temp1;
265    h21  = (Int16)(pms->H21[SUBQMF_GROUPS] >> 16);
266    pms->H22[SUBQMF_GROUPS]  += temp2;
267    h22  = (Int16)(pms->H22[SUBQMF_GROUPS] >> 16);
268
269
270    ptr_hybrLeftReal  = &qmfLeftReal[  3];
271    ptr_hybrRightReal = &qmfRightReal[ 3];
272
273    /*
274     *  Reconstruction of Stereo sub-band signal
275     *
276     *  l_k(n) = H11(k,n)*s_k(n) + H21(k,n)*d_k(n)
277     *
278     *  r_k(n) = H12(k,n)*s_k(n) + H22(k,n)*d_k(n)
279     */
280    temp1 = *(ptr_hybrLeftReal) << 1;
281    temp2 = *(ptr_hybrRightReal) << 1;
282
283
284    temp3 = fxp_mul32_by_16(temp1, h11);
285    *(ptr_hybrLeftReal)  = fxp_mac32_by_16(temp2, h21, temp3) << 1;
286
287    temp3 = fxp_mul32_by_16(temp1, h12);
288    *(ptr_hybrRightReal)  = fxp_mac32_by_16(temp2, h22, temp3) << 1;
289
290    ptr_hybrLeftImag  = &qmfLeftImag[  3];
291    ptr_hybrRightImag = &qmfRightImag[ 3];
292
293
294    temp1 = *(ptr_hybrLeftImag) << 1;
295    temp2 = *(ptr_hybrRightImag) << 1;
296
297    temp3 = fxp_mul32_by_16(temp1, h11);
298    *(ptr_hybrLeftImag)  = fxp_mac32_by_16(temp2, h21, temp3) << 1;
299
300    temp3 = fxp_mul32_by_16(temp1, h12);
301    *(ptr_hybrRightImag)  = fxp_mac32_by_16(temp2, h22, temp3) << 1;
302
303
304    for (group = SUBQMF_GROUPS + 1; group < NO_IID_GROUPS; group++)   /* 11 to NO_IID_GROUPS == 22 */
305    {
306        temp1 = pms->deltaH11[group];
307        temp2 = pms->deltaH12[group];
308
309        pms->H11[group]  += temp1;
310        h11  = (Int16)(pms->H11[group] >> 16);
311        pms->H12[group]  += temp2;
312        h12  = (Int16)(pms->H12[group] >> 16);
313
314        temp1 = pms->deltaH21[group];
315        temp2 = pms->deltaH22[group];
316
317        pms->H21[group]  += temp1;
318        h21  = (Int16)(pms->H21[group] >> 16);
319        pms->H22[group]  += temp2;
320        h22  = (Int16)(pms->H22[group] >> 16);
321
322        index = groupBorders[group];
323        maxSubband = groupBorders[group + 1];
324        maxSubband = min(usb, maxSubband);
325
326        /*
327         *  Reconstruction of Stereo sub-band signal
328         *
329         *  l_k(n) = H11(k,n)*s_k(n) + H21(k,n)*d_k(n)
330         *
331         *  r_k(n) = H12(k,n)*s_k(n) + H22(k,n)*d_k(n)
332         */
333
334        ptr_hybrLeftReal  = &qmfLeftReal[  index];
335        ptr_hybrRightReal = &qmfRightReal[ index];
336
337        for (subband = index; subband < maxSubband; subband++)
338        {
339            temp1 = *(ptr_hybrLeftReal) << 1;
340            temp2 = *(ptr_hybrRightReal) << 1;
341            temp3 = fxp_mul32_by_16(temp1, h11);
342            *(ptr_hybrLeftReal++)   = fxp_mac32_by_16(temp2, h21, temp3) << 1;
343
344            temp3 = fxp_mul32_by_16(temp1, h12);
345            *(ptr_hybrRightReal++)  = fxp_mac32_by_16(temp2, h22, temp3) << 1;
346        }
347
348        ptr_hybrLeftImag  = &qmfLeftImag[  index];
349        ptr_hybrRightImag = &qmfRightImag[ index];
350
351        for (subband = index; subband < maxSubband; subband++)
352        {
353            temp1 = *(ptr_hybrLeftImag) << 1;
354            temp2 = *(ptr_hybrRightImag) << 1;
355            temp3 = fxp_mul32_by_16(temp1, h11);
356            *(ptr_hybrLeftImag++)   = fxp_mac32_by_16(temp2, h21, temp3) << 1;
357
358            temp3 = fxp_mul32_by_16(temp1, h12);
359            *(ptr_hybrRightImag++)  = fxp_mac32_by_16(temp2, h22, temp3) << 1;
360
361        } /* subband loop */
362
363    } /* groups loop */
364
365} /* END ps_stereo_processing */
366
367
368#endif
369
370
371#endif
372
373