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: sbr_envelope_unmapping.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
38------------------------------------------------------------------------------
39 REQUIREMENTS
40
41
42------------------------------------------------------------------------------
43 REFERENCES
44
45SC 29 Software Copyright Licencing Disclaimer:
46
47This software module was originally developed by
48  Coding Technologies
49
50and edited by
51  -
52
53in the course of development of the ISO/IEC 13818-7 and ISO/IEC 14496-3
54standards for reference purposes and its performance may not have been
55optimized. This software module is an implementation of one or more tools as
56specified by the ISO/IEC 13818-7 and ISO/IEC 14496-3 standards.
57ISO/IEC gives users free license to this software module or modifications
58thereof for use in products claiming conformance to audiovisual and
59image-coding related ITU Recommendations and/or ISO/IEC International
60Standards. ISO/IEC gives users the same free license to this software module or
61modifications thereof for research purposes and further ISO/IEC standardisation.
62Those intending to use this software module in products are advised that its
63use may infringe existing patents. ISO/IEC have no liability for use of this
64software module or modifications thereof. Copyright is not released for
65products that do not conform to audiovisual and image-coding related ITU
66Recommendations and/or ISO/IEC International Standards.
67The original developer retains full right to modify and use the code for its
68own purpose, assign or donate the code to a third party and to inhibit third
69parties from using the code for products that do not conform to audiovisual and
70image-coding related ITU Recommendations and/or ISO/IEC International Standards.
71This copyright notice must be included in all copies or derivative works.
72Copyright (c) ISO/IEC 2002.
73
74------------------------------------------------------------------------------
75 PSEUDO-CODE
76
77------------------------------------------------------------------------------
78*/
79
80
81/*----------------------------------------------------------------------------
82; INCLUDES
83----------------------------------------------------------------------------*/
84
85#ifdef AAC_PLUS
86
87
88#include    "sbr_envelope_unmapping.h"
89#include    "sbr_constants.h"
90
91#include "fxp_mul32.h"
92
93/*----------------------------------------------------------------------------
94; MACROS
95; Define module specific macros here
96----------------------------------------------------------------------------*/
97
98
99/*----------------------------------------------------------------------------
100; DEFINES
101; Include all pre-processor statements here. Include conditional
102; compile variables also.
103----------------------------------------------------------------------------*/
104
105/*----------------------------------------------------------------------------
106; LOCAL FUNCTION DEFINITIONS
107; Function Prototype declaration
108----------------------------------------------------------------------------*/
109
110/*----------------------------------------------------------------------------
111; LOCAL STORE/BUFFER/POINTER DEFINITIONS
112; Variable declaration - defined here and used outside this module
113----------------------------------------------------------------------------*/
114
115#define R_SHIFT     30
116#define Qfmt(x)   (Int32)(x*((Int32)1<<R_SHIFT) + (x>=0?0.5F:-0.5F))
117
118/*
119 *  1./(1+2.^-[0:10])
120 */
121const Int32 one_over_one_plus_two_to_n[11] =
122{
123    Qfmt(0.50000000000000F), Qfmt(0.66666666666667F), Qfmt(0.80000000000000F),
124    Qfmt(0.88888888888889F), Qfmt(0.94117647058824F), Qfmt(0.96969696969697F),
125    Qfmt(0.98461538461538F), Qfmt(0.99224806201550F), Qfmt(0.99610894941634F),
126    Qfmt(0.99805068226121F), Qfmt(0.99902439024390F)
127};
128
129/*
130 *  1./(1+2.^[0.5:-1:-10.5])
131 */
132const Int32 one_over_one_plus_sq_2_by_two_to_n[12] =
133{
134    Qfmt(0.41421356237310F), Qfmt(0.58578643762690F), Qfmt(0.73879612503626F),
135    Qfmt(0.84977889517767F), Qfmt(0.91878969685839F), Qfmt(0.95767628767521F),
136    Qfmt(0.97838063800882F), Qfmt(0.98907219289563F), Qfmt(0.99450607818892F),
137    Qfmt(0.99724547251514F), Qfmt(0.99862083678608F), Qfmt(0.99930994254211F)
138};
139
140/*----------------------------------------------------------------------------
141; EXTERNAL FUNCTION REFERENCES
142; Declare functions defined elsewhere and referenced in this module
143----------------------------------------------------------------------------*/
144
145/*----------------------------------------------------------------------------
146; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
147; Declare variables used in this module but defined elsewhere
148----------------------------------------------------------------------------*/
149
150/*----------------------------------------------------------------------------
151; FUNCTION CODE
152----------------------------------------------------------------------------*/
153
154void sbr_envelope_unmapping(SBR_FRAME_DATA * hFrameData1,
155                            SBR_FRAME_DATA * hFrameData2)
156
157{
158    Int32 i;
159    Int32 tempLeft;
160    Int32 tempRight;
161
162    Int32 tmp;
163    Int32 *iEnvelopeLeft_man    = hFrameData1->iEnvelope_man;
164    Int32 *iEnvelopeLeft_exp    = hFrameData1->iEnvelope_exp;
165    Int32 *noiseFloorLeft_man   = hFrameData1->sbrNoiseFloorLevel_man;
166    Int32 *noiseFloorLeft_exp   = hFrameData1->sbrNoiseFloorLevel_exp;
167
168    Int32 *iEnvelopeRight_man   = hFrameData2->iEnvelope_man;
169    Int32 *iEnvelopeRight_exp   = hFrameData2->iEnvelope_exp;
170    Int32 *noiseFloorRight_man  = hFrameData2->sbrNoiseFloorLevel_man;
171    Int32 *noiseFloorRight_exp  = hFrameData2->sbrNoiseFloorLevel_exp;
172
173
174    if (hFrameData2->ampRes)
175    {
176        for (i = 0; i < hFrameData1->nScaleFactors; i++)
177        {
178            tempRight = iEnvelopeRight_man[i];
179            tempLeft  = iEnvelopeLeft_man[i];
180            /*  iEnvelope[i] always positive  6 bits max */
181
182            iEnvelopeLeft_exp[i] = tempLeft + 7;
183
184            iEnvelopeRight_exp[i] = tempRight - 12;
185            iEnvelopeRight_man[i] = Qfmt(1.000F);
186
187            /*
188             *  iEnvelopeRight[i] = tempLeft / (1 + tempRight);
189             *  iEnvelopeLeft[i]  = tempRight * iEnvelopeRight[i];
190             *
191             *
192             *   iEnvelopeRight[i] = k*2^n/(1+2^m) =  k*2^(n-m)/(1 + 2^-m);
193             *   where k = 1 or sqrt(2)
194             */
195            if (iEnvelopeRight_exp[i] >= 0)
196            {
197                if (iEnvelopeRight_exp[i] < 11)
198                {
199                    iEnvelopeRight_man[i] = one_over_one_plus_two_to_n[ iEnvelopeRight_exp[i]];
200                }
201                else        /*  1/(1+2^-m) == 1 - 2^-m ;  for m >= 10  */
202                {
203                    iEnvelopeRight_man[i] -= (Qfmt(1.000F) >> iEnvelopeRight_exp[i]);
204                }
205                iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i] - iEnvelopeRight_exp[i];
206            }
207            else
208            {
209                if (iEnvelopeRight_exp[i] > -11)
210                {
211                    iEnvelopeRight_man[i] -= one_over_one_plus_two_to_n[ -iEnvelopeRight_exp[i]];
212                    iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i] - iEnvelopeRight_exp[i];
213
214                }
215                else        /*  1/(1+2^m) == 2^-m ;  for m >= 10  */
216                {
217                    iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i];
218                    iEnvelopeLeft_exp[i] = 0;
219                }
220            }
221
222            iEnvelopeLeft_man[i]  = iEnvelopeRight_man[i];
223        }
224    }
225    else
226    {
227        for (i = 0; i < hFrameData1->nScaleFactors; i++)
228        {
229            /*  iEnvelope[i] always positive  7 bits max */
230            tempRight = iEnvelopeRight_man[i];
231            tempLeft  = iEnvelopeLeft_man[i];
232
233            iEnvelopeLeft_exp[i] = (tempLeft >> 1) + 7;
234            if (tempLeft & 0x1)   /*  odd */
235            {
236                iEnvelopeLeft_man[i] = Qfmt(1.41421356237310F);
237            }
238            else
239            {
240                iEnvelopeLeft_man[i] = Qfmt(1.000F);
241            }
242
243            iEnvelopeRight_exp[i] = (tempRight >> 1) - 12;
244            if (tempRight & 0x1)   /*  odd */
245            {
246                if (iEnvelopeRight_exp[i] > 0)
247                {
248                    iEnvelopeRight_man[i] = Qfmt(1.41421356237310F);
249                }
250                else
251                {
252                    iEnvelopeRight_man[i] = Qfmt(0.7071067811865F);
253                }
254            }
255            else
256            {
257                iEnvelopeRight_man[i] = Qfmt(1.000F);
258            }
259
260            if (iEnvelopeRight_man[i] == Qfmt(1.000F))
261            {
262
263                /*
264                 *  iEnvelopeRight[i] = tempLeft / (1 + tempRight);
265                 *  iEnvelopeLeft[i]  = tempRight * iEnvelopeRight[i];
266                 *
267                 *
268                 *   iEnvelopeRight[i] = k*2^n/(1+2^m) =  k*2^(n-m)/(1 + 2^-m);
269                 *   where k = 1 or sqrt(2)
270                 */
271                if (iEnvelopeRight_exp[i] >= 0)
272                {
273                    if (iEnvelopeRight_exp[i] < 11)
274                    {
275                        iEnvelopeRight_man[i] = one_over_one_plus_two_to_n[ iEnvelopeRight_exp[i]];
276                    }
277                    else        /*  1/(1+2^-m) == 1 - 2^-m ;  for m >= 10  */
278                    {
279                        iEnvelopeRight_man[i] -= (Qfmt(1.000F) >> iEnvelopeRight_exp[i]);
280                    }
281                    iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i] - iEnvelopeRight_exp[i];
282
283                }
284                else
285                {
286                    if (iEnvelopeRight_exp[i] > -11)
287                    {
288                        iEnvelopeRight_man[i] -= one_over_one_plus_two_to_n[ -iEnvelopeRight_exp[i]];
289                        iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i] - iEnvelopeRight_exp[i];
290                    }
291                    else        /*  1/(1+2^m) == 2^-m ;  for m >= 10  */
292                    {
293                        iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i];
294                        iEnvelopeLeft_exp[i]  = 0;
295                    }
296                }
297
298                /*
299                 *  apply "k" factor 1 or sqrt(2)
300                 *
301                 *   (2^m)*2*k*2^n/(1+2^m) =  k*2^(n+1)/(1 + 2^-m);
302                 *
303                 */
304                if (iEnvelopeLeft_man[i] != Qfmt(1.000F))
305                {
306                    iEnvelopeRight_man[i] = fxp_mul32_Q30(iEnvelopeLeft_man[i], iEnvelopeRight_man[i]);
307                }
308
309                iEnvelopeLeft_man[i]  = iEnvelopeRight_man[i];
310
311            }
312            else
313            {
314
315                /*
316                *  iEnvelopeRight[i] = tempLeft / (1 + tempRight);
317                *  iEnvelopeLeft[i]  = tempRight * iEnvelopeRight[i];
318                *
319                *
320                *   iEnvelopeRight[i] = k*2^n/(1+q2^m) =  k*2^(n-m)/(1 + q2^-m);
321                *   where k = 1 or sqrt(2)
322                *   and q = sqrt(2)
323                    */
324                if (iEnvelopeRight_exp[i] >= 0)
325                {
326                    if (iEnvelopeRight_exp[i] < 12)
327                    {
328                        iEnvelopeRight_man[i] = one_over_one_plus_sq_2_by_two_to_n[ iEnvelopeRight_exp[i]];
329                    }
330                    else        /*  1/(1+2^-m) == 1 - 2^-m ;  for m >= 11  */
331                    {
332                        iEnvelopeRight_man[i] = Qfmt(1.000F) - (Qfmt(1.000F) >> iEnvelopeRight_exp[i]);
333                    }
334                }
335                else
336                {
337                    if (iEnvelopeRight_exp[i] > -12)
338                    {
339                        iEnvelopeRight_man[i] = Qfmt(1.000F) - one_over_one_plus_sq_2_by_two_to_n[ -iEnvelopeRight_exp[i]];
340                    }
341                    else        /*  1/(1+2^m) == 2^-m ;  for m >= 11  */
342                    {
343                        iEnvelopeRight_man[i] = Qfmt(1.000F);
344                        iEnvelopeRight_exp[i] = 0;
345                    }
346                }
347
348                iEnvelopeRight_exp[i] = iEnvelopeLeft_exp[i] - iEnvelopeRight_exp[i];
349
350                /*
351                *  apply "k" factor 1 or sqrt(2)
352                *
353                *   Right ==    k*2^(n-m)/(1 + q2^-m)
354                *   Left  == (q2^m)*k*2^n/(1 + q2^m) =  qk*2^n/(1 + q2^-m);
355                */
356                if (iEnvelopeLeft_man[i] != Qfmt(1.000F))
357                {
358                    /*
359                    *   k/(1 + q2^-m);
360                        */
361                    tmp = iEnvelopeRight_man[i];
362                    iEnvelopeRight_man[i] = fxp_mul32_Q30(iEnvelopeLeft_man[i], iEnvelopeRight_man[i]);
363                    iEnvelopeLeft_man[i] = tmp;
364                    iEnvelopeLeft_exp[i] += 1;      /* extra one due to sqrt(2)^2 */
365                }
366                else
367                {
368                    iEnvelopeLeft_man[i]  = fxp_mul32_Q30(iEnvelopeRight_man[i], Qfmt(1.41421356237310F));
369                }
370
371            }       /*  end of     if (iEnvelopeRight_man[i] == Qfmt( 1.000F) )  */
372        }      /* end of for loop */
373    }     /*  end  if (hFrameData2->ampRes) */
374
375
376    for (i = 0; i < hFrameData1->nNoiseFactors; i++)
377    {
378
379        noiseFloorLeft_exp[i]  = NOISE_FLOOR_OFFSET_PLUS_1 - noiseFloorLeft_man[i];
380        noiseFloorRight_exp[i] = noiseFloorRight_man[i] - SBR_ENERGY_PAN_OFFSET_INT;
381
382
383        /*
384         *  noiseFloorRight[i] = tempLeft / (1.0f + tempRight);
385         *  noiseFloorLeft[i]  = tempRight*noiseFloorRight[i];
386         *
387         *
388         *   noiseFloorRight[i] = 2^n/(1+2^m) =  2^(n-m)/(1 + 2^-m);
389         */
390        if (noiseFloorRight_exp[i] >= 0)
391        {
392            if (noiseFloorRight_exp[i] < 11)
393            {
394                noiseFloorRight_man[i] = one_over_one_plus_two_to_n[ noiseFloorRight_exp[i]];
395            }
396            else        /*  1/(1+2^-m) == 1 - 2^-m ;  for m >= 10  */
397            {
398                noiseFloorRight_man[i] = Qfmt(1.000F) - (Qfmt(1.000F) >> noiseFloorRight_exp[i]);
399            }
400        }
401        else
402        {
403            if (noiseFloorRight_exp[i] > -11)
404            {
405                noiseFloorRight_man[i] = Qfmt(1.000F) - one_over_one_plus_two_to_n[ -noiseFloorRight_exp[i]];
406            }
407            else        /*  1/(1+2^m) == 2^-m ;  for m >= 10  */
408            {
409                noiseFloorRight_man[i] = Qfmt(1.000F);
410                noiseFloorRight_exp[i] = 0;
411            }
412        }
413
414        noiseFloorRight_exp[i] = noiseFloorLeft_exp[i] - noiseFloorRight_exp[i];
415
416        /*
417         *   (2^m)*2^n/(1+2^m) =  2^n/(1 + 2^-m);
418         */
419
420        noiseFloorLeft_man[i] = noiseFloorRight_man[i];
421        noiseFloorLeft_exp[i] = noiseFloorLeft_exp[i];
422
423    }
424}
425
426#endif
427
428