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_pwr_transient_detection.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  Decorrelation
38  Decorrelation is achieved by means of all-pass filtering and delaying
39  Sub-band samples s_k(n) are converted into de-correlated sub-bands samples
40  d_k(n). k index for frequency, n time index
41
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  To handle transients and other fast time-envelopes, the output of the all
59  pass filters has to be attenuated at those signals.
60
61
62------------------------------------------------------------------------------
63 REQUIREMENTS
64
65
66------------------------------------------------------------------------------
67 REFERENCES
68
69SC 29 Software Copyright Licencing Disclaimer:
70
71This software module was originally developed by
72  Coding Technologies
73
74and edited by
75  -
76
77in the course of development of the ISO/IEC 13818-7 and ISO/IEC 14496-3
78standards for reference purposes and its performance may not have been
79optimized. This software module is an implementation of one or more tools as
80specified by the ISO/IEC 13818-7 and ISO/IEC 14496-3 standards.
81ISO/IEC gives users free license to this software module or modifications
82thereof for use in products claiming conformance to audiovisual and
83image-coding related ITU Recommendations and/or ISO/IEC International
84Standards. ISO/IEC gives users the same free license to this software module or
85modifications thereof for research purposes and further ISO/IEC standardisation.
86Those intending to use this software module in products are advised that its
87use may infringe existing patents. ISO/IEC have no liability for use of this
88software module or modifications thereof. Copyright is not released for
89products that do not conform to audiovisual and image-coding related ITU
90Recommendations and/or ISO/IEC International Standards.
91The original developer retains full right to modify and use the code for its
92own purpose, assign or donate the code to a third party and to inhibit third
93parties from using the code for products that do not conform to audiovisual and
94image-coding related ITU Recommendations and/or ISO/IEC International Standards.
95This copyright notice must be included in all copies or derivative works.
96Copyright (c) ISO/IEC 2003.
97
98------------------------------------------------------------------------------
99 PSEUDO-CODE
100
101------------------------------------------------------------------------------
102*/
103
104
105/*----------------------------------------------------------------------------
106; INCLUDES
107----------------------------------------------------------------------------*/
108
109#ifdef AAC_PLUS
110
111#ifdef PARAMETRICSTEREO
112
113#include    "pv_audio_type_defs.h"
114#include    "s_ps_dec.h"
115#include    "aac_mem_funcs.h"
116#include    "ps_all_pass_filter_coeff.h"
117#include    "ps_pwr_transient_detection.h"
118
119#include    "fxp_mul32.h"
120#include    "pv_div.h"
121
122/*----------------------------------------------------------------------------
123; MACROS
124; Define module specific macros here
125----------------------------------------------------------------------------*/
126
127#ifndef min
128#define min(a, b) ((a) < (b) ? (a) : (b))
129#endif
130
131
132/*----------------------------------------------------------------------------
133; DEFINES
134; Include all pre-processor statements here. Include conditional
135; compile variables also.
136----------------------------------------------------------------------------*/
137
138#define R_SHIFT     29
139#define Q29_fmt(x)   (Int32)(x*((Int32)1<<R_SHIFT) + (x>=0?0.5F:-0.5F))
140
141#define Qfmt31(a)   (Int32)(-a*((Int32)1<<31) - 1 + (a>=0?0.5F:-0.5F))
142
143/*----------------------------------------------------------------------------
144; LOCAL FUNCTION DEFINITIONS
145; Function Prototype declaration
146----------------------------------------------------------------------------*/
147
148
149/*----------------------------------------------------------------------------
150; LOCAL STORE/BUFFER/POINTER DEFINITIONS
151; Variable declaration - defined here and used outside this module
152----------------------------------------------------------------------------*/
153
154
155/*----------------------------------------------------------------------------
156; EXTERNAL FUNCTION REFERENCES
157; Declare functions defined elsewhere and referenced in this module
158----------------------------------------------------------------------------*/
159
160
161
162
163/*----------------------------------------------------------------------------
164; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
165; Declare variables used in this module but defined elsewhere
166----------------------------------------------------------------------------*/
167
168
169/*----------------------------------------------------------------------------
170; FUNCTION CODE
171----------------------------------------------------------------------------*/
172
173
174void ps_pwr_transient_detection(STRUCT_PS_DEC *h_ps_dec,
175                                Int32 *rIntBufferLeft,
176                                Int32 *iIntBufferLeft,
177                                Int32 aTransRatio[])
178{
179
180    Int32 sb;
181    Int32 maxsb;
182    Int32 gr;
183    Int32 bin;
184
185
186
187    Int32 *aLeftReal;
188    Int32 *aLeftImag;
189    Int32   temp_r;
190    Int32   temp_i;
191    Int32   accu;
192    Int32 *aPower = aTransRatio;
193    Quotient result;
194
195    Int32 nrg;
196    Int32 *ptr_aPrevNrg;
197    Int32 peakDiff;
198    Int32 *ptr_PrevPeakDiff;
199
200
201    aLeftReal = rIntBufferLeft;
202    aLeftImag = iIntBufferLeft;
203
204    /*
205     *  Input Power Matrix
206     *                            2
207     *  Power(i,n) = SUM | s_k(n)|
208     *                i
209     */
210
211    for (gr = SUBQMF_GROUPS; gr < NO_IID_GROUPS; gr++) /* 10 to 22  */
212    {
213        maxsb = min(h_ps_dec->usb, groupBorders[ gr+1]);
214
215        accu = 0;
216
217        for (sb = groupBorders[gr]; sb < maxsb; sb++)
218        {
219
220            temp_r = aLeftReal[sb];
221            temp_i = aLeftImag[sb];
222            accu =  fxp_mac32_Q31(accu, temp_r, temp_r);
223            accu =  fxp_mac32_Q31(accu, temp_i, temp_i);
224
225        } /* sb */
226        aPower[gr - 2] = accu >> 1;
227    } /* gr */
228
229    aLeftReal = h_ps_dec->mHybridRealLeft;
230    aLeftImag = h_ps_dec->mHybridImagLeft;
231
232
233    temp_r = aLeftReal[0];
234    temp_i = aLeftImag[0];
235    accu   = fxp_mul32_Q31(temp_r, temp_r);
236    accu  = fxp_mac32_Q31(accu, temp_i, temp_i);
237    temp_r = aLeftReal[5];
238    temp_i = aLeftImag[5];
239    accu   = fxp_mac32_Q31(accu, temp_r, temp_r);
240    aPower[0]  = fxp_mac32_Q31(accu, temp_i, temp_i) >> 1;
241
242    temp_r = aLeftReal[1];
243    temp_i = aLeftImag[1];
244    accu   = fxp_mul32_Q31(temp_r, temp_r);
245    accu  = fxp_mac32_Q31(accu, temp_i, temp_i);
246    temp_r = aLeftReal[4];
247    temp_i = aLeftImag[4];
248    accu   = fxp_mac32_Q31(accu, temp_r, temp_r);
249    aPower[1]  = fxp_mac32_Q31(accu, temp_i, temp_i) >> 1;
250
251    temp_r = aLeftReal[2];
252    temp_i = aLeftImag[2];
253    accu   = fxp_mul32_Q31(temp_r, temp_r);
254    aPower[2]  = fxp_mac32_Q31(accu, temp_i, temp_i) >> 1;
255
256    temp_r = aLeftReal[3];
257    temp_i = aLeftImag[3];
258    accu   = fxp_mul32_Q31(temp_r, temp_r);
259    aPower[3]  = fxp_mac32_Q31(accu, temp_i, temp_i) >> 1;
260
261
262
263    temp_r = aLeftReal[6];
264    temp_i = aLeftImag[6];
265    accu   = fxp_mul32_Q31(temp_r, temp_r);
266    aPower[5]  = fxp_mac32_Q31(accu, temp_i, temp_i) >> 1;
267
268    temp_r = aLeftReal[7];
269    temp_i = aLeftImag[7];
270    accu   = fxp_mul32_Q31(temp_r, temp_r);
271    aPower[4]  = fxp_mac32_Q31(accu, temp_i, temp_i) >> 1;
272
273    temp_r = aLeftReal[8];
274    temp_i = aLeftImag[8];
275    accu   = fxp_mul32_Q31(temp_r, temp_r);
276    aPower[6]  = fxp_mac32_Q31(accu, temp_i, temp_i) >> 1;
277
278    temp_r = aLeftReal[9];
279    temp_i = aLeftImag[9];
280    accu   = fxp_mul32_Q31(temp_r, temp_r);
281    aPower[7]  = fxp_mac32_Q31(accu, temp_i, temp_i) >> 1;
282
283
284    /*
285     *  Power transient detection
286     */
287
288    ptr_aPrevNrg = h_ps_dec->aPrevNrg;
289
290    ptr_PrevPeakDiff = h_ps_dec->aPrevPeakDiff;
291
292    for (bin = 0; bin < NO_BINS; bin++) /* NO_BINS = 20  */
293    {
294
295        peakDiff  = *ptr_PrevPeakDiff;
296
297
298        /* PEAK_DECAY_FACTOR  0.765928338364649f @ 48 KHz  for Fs > 32 Khz */
299        accu = h_ps_dec->aPeakDecayFast[bin];
300        peakDiff -= peakDiff >> 2;
301
302        accu  = fxp_mul32_Q31(accu, Qfmt31(0.765928338364649f)) << 1;
303
304        if (accu < *aPower)
305        {
306            accu = *aPower;
307        }
308        else
309        {
310            peakDiff += ((accu - *aPower) >> 2);
311        }
312
313        h_ps_dec->aPeakDecayFast[bin] = accu;
314
315        *(ptr_PrevPeakDiff++) = peakDiff;
316
317        nrg =   *ptr_aPrevNrg + ((*aPower - *ptr_aPrevNrg) >> 2);
318
319        *(ptr_aPrevNrg++) = nrg;
320
321        peakDiff += peakDiff >> 1;         /* transient impact factor == 1.5 */
322
323        if (peakDiff <= nrg)
324        {
325            *(aPower++) = 0x7FFFFFFF;    /* in Q31  */
326        }
327        else
328        {
329            pv_div(nrg, peakDiff, &result);
330            *(aPower++) = (result.quotient >> (result.shift_factor)) << 1;    /* in Q31  */
331        }
332
333    } /* bin */
334
335}
336
337
338#endif
339
340#endif
341