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 Pathname: q_normalize.c
21
22------------------------------------------------------------------------------
23 REVISION HISTORY
24
25 Description:
26 (1) Modify to include search over the scalefactor bands to insure
27     that the data is using all 31 data-bits.
28
29 Description:
30 (1) Modify to remove search over the scalefactor bands to insure
31     that the data is using all 31 data-bits.
32     (Pushed out into separate function)
33 (2) Change variable "k" to more descriptive "shift_amt"
34 (3) Update pseudocode to reflect removed code.
35 (4) Add PV Copyright notice.
36
37 Description:
38 (1) Modified to protect q-normalize from shifting by amounts >= 32.
39
40 Description:
41 (1) Delete local variable idx_count.
42
43 Description:
44 (1) Included search for max in each frame, modified interface.
45
46 Description:
47 (1) unrolled loop based on the fact that the size of each scale band
48     is always an even number.
49
50 Description:Check shift, if zero, do not shift.
51
52 Description: Eliminated warning: non use variable "i" and memset function
53    definition
54
55 Who:                       Date:
56 Description:
57------------------------------------------------------------------------------
58 INPUT AND OUTPUT DEFINITIONS
59
60 Inputs:
61    qFormat[] = Array of qFormats, one per scalefactor band. [ Int ]
62
63    pFrameInfo = Pointer to structure that holds information about each group.
64                 (long block flag, number of windows, scalefactor bands, etc.)
65                 [const FrameInfo]
66
67    coef[]    = Array of the spectral coefficients for one channel. [ Int32 ]
68
69 Local Stores/Buffers/Pointers Needed:
70    None
71
72 Global Stores/Buffers/Pointers Needed:
73    None
74
75 Outputs:
76    min_q = The common q-format for the entire frame. [Int]
77
78 Pointers and Buffers Modified:
79    coef[]    = Array of spectral data, now normalized to one q-format.
80
81 Local Stores Modified:
82    None
83
84 Global Stores Modified:
85    None
86
87------------------------------------------------------------------------------
88 FUNCTION DESCRIPTION
89
90 This module first scans every scalefactor band for the frame, insuring that
91 at least one element in that scalefactor band is using all available bits.
92 If not, the elements in the scalefactor band are shifted up to use all 31
93 data bits.  The q-format is adjusted accordingly.
94
95 This module then scans the q-formats for each scalefactor band.
96 Upon finding the minimum q-format in the frame, the coefficients in each
97 scalefactor band are normalized to the minimum q-format.
98 The minimum q-format is then returned to the calling function, which is now
99 the q-format for the entire frame.
100
101------------------------------------------------------------------------------
102 REQUIREMENTS
103
104------------------------------------------------------------------------------
105 REFERENCES
106
107------------------------------------------------------------------------------
108 PSEUDO-CODE
109
110    nwin = pFrameInfo->num_win;
111
112    pQformat   = &(qFormat[0]);
113    pSfbPerWin = &(pFrameInfo->sfb_per_win[0]);
114    pCoef      = &(coef[0]);
115
116    FOR (win = nwin; win > 0; win--)
117
118        nsfb = *(pSfbPerWin++);
119
120        FOR (sfb = nsfb; sfb > 0; sfb--)
121
122            IF ( *(pQformat) < min_q)
123                min_q = *(pQformat);
124            ENDIF
125
126            pQformat++;
127
128        ENDFOR
129
130    ENDFOR
131
132    pQformat   = &(qFormat[0]);
133    pSfbPerWin = &(pFrameInfo->sfb_per_win[0]);
134    pCoef      = &(coef[0]);
135
136    FOR (win = 0; win < nwin; win++)
137
138        stop_idx = 0;
139
140        nsfb   = *(pSfbPerWin++);
141
142        pWinSfbTop = &(pFrameInfo->win_sfb_top[win][0]);
143
144        FOR (sfb = nsfb; sfb > 0; sfb--)
145
146            sfbWidth  = *(pWinSfbTop++) - stop_idx;
147
148            stop_idx += sfbWidth;
149
150            k = *(pQformat++) - min_q;
151
152            IF (k < 32)
153            THEN
154                FOR (; sfbWidth > 0; sfbWidth--)
155                    *(pCoef++) >>= k;
156                ENDFOR
157            ELSE
158                FOR (; sfbWidth > 0; sfbWidth--)
159                    *(pCoef++) = 0;
160                ENDFOR
161            ENDIF
162
163        ENDFOR
164
165    ENDFOR
166
167    return min_q;
168
169------------------------------------------------------------------------------
170 RESOURCES USED
171   When the code is written for a specific target processor the
172     the resources used should be documented below.
173
174 STACK USAGE: [stack count for this module] + [variable to represent
175          stack usage for each subroutine called]
176
177     where: [stack usage variable] = stack usage for [subroutine
178         name] (see [filename].ext)
179
180 DATA MEMORY USED: x words
181
182 PROGRAM MEMORY USED: x words
183
184 CLOCK CYCLES: [cycle count equation for this module] + [variable
185           used to represent cycle count for each subroutine
186           called]
187
188     where: [cycle count variable] = cycle count for [subroutine
189        name] (see [filename].ext)
190
191------------------------------------------------------------------------------
192*/
193
194
195/*----------------------------------------------------------------------------
196; INCLUDES
197----------------------------------------------------------------------------*/
198#include "pv_audio_type_defs.h"
199#include "s_frameinfo.h"
200#include "q_normalize.h"
201#include "aac_mem_funcs.h"         /* For pv_memset                         */
202
203/*----------------------------------------------------------------------------
204; MACROS
205; Define module specific macros here
206----------------------------------------------------------------------------*/
207
208/*----------------------------------------------------------------------------
209; DEFINES
210; Include all pre-processor statements here. Include conditional
211; compile variables also.
212----------------------------------------------------------------------------*/
213
214/*----------------------------------------------------------------------------
215; LOCAL FUNCTION DEFINITIONS
216; Function Prototype declaration
217----------------------------------------------------------------------------*/
218
219/*----------------------------------------------------------------------------
220; LOCAL STORE/BUFFER/POINTER DEFINITIONS
221; Variable declaration - defined here and used outside this module
222----------------------------------------------------------------------------*/
223
224/*----------------------------------------------------------------------------
225; EXTERNAL FUNCTION REFERENCES
226; Declare functions defined elsewhere and referenced in this module
227----------------------------------------------------------------------------*/
228
229/*----------------------------------------------------------------------------
230; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
231; Declare variables used in this module but defined elsewhere
232----------------------------------------------------------------------------*/
233
234/*----------------------------------------------------------------------------
235; FUNCTION CODE
236----------------------------------------------------------------------------*/
237Int q_normalize(
238    Int        qFormat[],
239    const FrameInfo *pFrameInfo,
240    Int32      abs_max_per_window[],
241    Int32      coef[])
242{
243    Int    sfb;
244    Int    nsfb;
245    Int    win;
246    Int    nwin;
247    Int    sfbWidth;
248
249    Int    shift_amt;
250
251    /* Initialize min_q to a very large value */
252    Int    min_q = 1000;
253
254    Int stop_idx  = 0;
255
256    const Int   *pSfbPerWin;
257    const Int16 *pWinSfbTop;
258
259    Int   *pQformat;
260    Int32 *pCoef;
261
262    nwin = pFrameInfo->num_win;
263
264    /* Find the minimum q format */
265    pQformat   = &(qFormat[0]);
266    pSfbPerWin = &(pFrameInfo->sfb_per_win[0]);
267
268    for (win = nwin; win != 0; win--)
269    {
270
271        nsfb = *(pSfbPerWin++);
272
273        if (nsfb < 0 || nsfb > MAXBANDS)
274        {
275            break;  /* avoid any processing on error condition */
276        }
277
278        for (sfb = nsfb; sfb != 0; sfb--)
279        {
280            Int qformat = *(pQformat++);
281            if (qformat < min_q)
282            {
283                min_q = qformat;
284            }
285        }
286
287    } /* for(win) */
288
289    /* Normalize the coefs in each scalefactor band to one q-format */
290    pQformat   = &(qFormat[0]);
291    pSfbPerWin = &(pFrameInfo->sfb_per_win[0]);
292    pCoef      = &(coef[0]);
293
294    for (win = 0; win < nwin; win++)
295    {
296
297        Int32 max = 0;
298        stop_idx = 0;
299
300        nsfb   = *(pSfbPerWin++);
301
302        if (nsfb < 0 || nsfb > MAXBANDS)
303        {
304            break;  /* avoid any processing on error condition */
305        }
306
307        pWinSfbTop = &(pFrameInfo->win_sfb_top[win][0]);
308
309        for (sfb = nsfb; sfb != 0; sfb--)
310        {
311            Int tmp1, tmp2;
312            tmp1 = *(pWinSfbTop++);
313            tmp2 = *(pQformat++);
314            sfbWidth  = tmp1 - stop_idx;
315
316            if (sfbWidth < 2)
317            {
318                break;  /* will lead to error condition */
319            }
320
321            stop_idx += sfbWidth;
322
323            shift_amt = tmp2 - min_q;
324
325            if (shift_amt == 0)
326            {
327                Int32 tmp1, tmp2;
328                tmp1 = *(pCoef++);
329                tmp2 = *(pCoef++);
330                /*
331                 *  sfbWidth is always an even number
332                 *  (check tables in pg.66 IS0 14496-3)
333                 */
334                for (Int i = (sfbWidth >> 1) - 1; i != 0; i--)
335                {
336                    max  |= (tmp1 >> 31) ^ tmp1;
337                    max  |= (tmp2 >> 31) ^ tmp2;
338                    tmp1 = *(pCoef++);
339                    tmp2 = *(pCoef++);
340                }
341                max  |= (tmp1 >> 31) ^ tmp1;
342                max  |= (tmp2 >> 31) ^ tmp2;
343
344            }
345            else
346            {
347                if (shift_amt < 31)
348                {
349                    Int32 tmp1, tmp2;
350                    tmp1 = *(pCoef++) >> shift_amt;
351                    tmp2 = *(pCoef--) >> shift_amt;
352                    /*
353                     *  sfbWidth is always an even number
354                     *  (check tables in pg.66 IS0 14496-3)
355                     */
356                    for (Int i = (sfbWidth >> 1) - 1; i != 0; i--)
357                    {
358                        *(pCoef++)   = tmp1;
359                        *(pCoef++)   = tmp2;
360
361                        max  |= (tmp1 >> 31) ^ tmp1;
362                        max  |= (tmp2 >> 31) ^ tmp2;
363                        tmp1 = *(pCoef++) >> shift_amt;
364                        tmp2 = *(pCoef--) >> shift_amt;
365
366                    }
367                    *(pCoef++)   = tmp1;
368                    *(pCoef++)   = tmp2;
369                    max  |= (tmp1 >> 31) ^ tmp1;
370                    max  |= (tmp2 >> 31) ^ tmp2;
371
372                }
373                else
374                {
375                    pv_memset(pCoef, 0, sizeof(Int32)*sfbWidth);
376                    pCoef += sfbWidth;
377                }
378            }
379
380            abs_max_per_window[win] = max;
381
382        }
383
384    } /* for (win) */
385
386    return min_q;
387
388} /* normalize() */
389