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: ./src/hufffac.c
21 Funtions:
22    hufffac
23
24------------------------------------------------------------------------------
25 REVISION HISTORY
26
27 Description:  Modified from original shareware code
28
29 Description:  Modified to pass variables by reference to eliminate use
30               of global variables.
31
32 Description: (1) Modified with new templates,
33              (2) Modified variable names for clarity
34              (3) adjusted variables of "for loop"
35              (4) eliminated multiple returns, use return valid
36
37 Description: (1) Change return logic: 0 if success, 1 if error
38              (2) Define SectInfo structure to store section codebook index
39                  and section boundary
40              (3) Substitute "switch" with "if- else if"
41              (4) move BITS *pInputStream to second pass-in parameter
42              (5) pass in huffBookUsed[] to save stack size
43
44 Description: (1) Remove pass in parameter Hcb pBook
45
46 Description: Use binary tree search in decode_huff_cw_binary
47
48 Description: Use decode_huff_scl function.
49
50 Who:                                   Date: MM/DD/YYYY
51 Description:
52
53------------------------------------------------------------------------------
54 INPUT AND OUTPUT DEFINITIONS
55
56 Inputs:
57
58    *pFrameInfo     = pointer to structure that holds information
59                      of each Frame. type FrameInfo
60
61    *pInputStream   = pointer to input bitstream. type BITS
62
63    *pGroup         = pointer to array that contains the index of the first
64                      window in each group, type UChar
65
66    nsect           = number of sections to be decoded. type Int
67
68    *pSect          = pointer to structure array that contains the huffman
69                      codebook index and section boundary for each section,
70                      type SectInfo
71
72    global_gain     = initial value for "DPCM encoded" scalefactors and noise
73                      energy, type Int
74
75    *pFactors       = pointer to array that stores the decoded scalefactors,
76                      intensity position or noise energy, type Int
77
78    huffBookUsed    = array that will hold the huffman codebook index for
79                      each sfb, type Int
80
81    *pBook          = pointer to structure that contains the huffman codebook
82                      information, such as dimension, Largest Absolute Value
83                      (LAV) of each huffman codebook, etc. type Hcb
84
85
86 Local Stores/Buffers/Pointers Needed: None
87
88 Global Stores/Buffers/Pointers Needed: None
89
90 Outputs:
91         0 if success
92         1 if error
93
94 Pointers and Buffers Modified:
95
96        Int   *pFactors    contains the newly decoded scalefactors and/or
97                             intensity position and/or noise energy level
98
99 Local Stores Modified:
100
101 Global Stores Modified:
102
103------------------------------------------------------------------------------
104 FUNCTION DESCRIPTION
105
106 This function first reads the Huffman codebook index of all sections within
107 one Frame. Then, depending on the huffman codebook index of each section,
108 the function decodes the scalefactors, and/or intensity positions
109 (INTENSITY_HCB, INTENSITY_HCB2), and/or noise energy (NOISE_HCB)
110 for every scalefactor band in each section.
111 The function returns 0 upon successful decoding, returns 1 if error.
112
113------------------------------------------------------------------------------
114 REQUIREMENTS
115
116 This function should replace the content of the array pFactors with the
117 decoded scalefactors and/or intensity positions and/or noise energy
118
119------------------------------------------------------------------------------
120 REFERENCES
121
122 (1) MPEG-2 NBC Audio Decoder
123   "This software module was originally developed by AT&T, Dolby
124   Laboratories, Fraunhofer Gesellschaft IIS in the course of development
125   of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
126   3. This software module is an implementation of a part of one or more
127   MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
128   Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audio
129   standards free license to this software module or modifications thereof
130   for use in hardware or software products claiming conformance to the
131   MPEG-2 NBC/MPEG-4 Audio  standards. Those intending to use this software
132   module in hardware or software products are advised that this use may
133   infringe existing patents. The original developer of this software
134   module and his/her company, the subsequent editors and their companies,
135   and ISO/IEC have no liability for use of this software module or
136   modifications thereof in an implementation. Copyright is not released
137   for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
138   developer retains full right to use the code for his/her own purpose,
139   assign or donate the code to a third party and to inhibit third party
140   from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
141   This copyright notice must be included in all copies or derivative
142   works."
143   Copyright(c)1996.
144
145 (2) ISO/IEC 14496-3: 1999(E)
146     Subpart 4      p72-73  (scalefactors)
147                    p76     (decoding)
148                    p78     (Table 4.6.1, Table 4.6.2)
149                    p93-94  (INTENSITY_HCB)
150                    p123    (NOISE_HCB)
151
152------------------------------------------------------------------------------
153 PSEUDO-CODE
154
155 status = SUCCESS;
156
157 CALL pv_memset(pHuffBookUsed, ZERO_HCB, MAXBANDS*sizeof(*pHuffBookUsed));
158
159 CALL pv_memset(pFactors, ZERO_HCB, MAXBANDS*sizeof(*pFactors));
160
161 sect_start       = 0;
162
163 FOR(sect_idx = nsect; sect_idx > 0; sect_idx--)
164 {
165     sect_cb  = pSect->sect_cb;
166     sect_end = pSect->sect_end;
167     pSect++;
168
169     CALL pv_memset(
170        &pHuffBookUsed[sect_start],
171        sect_cb,
172        (sect_end - sect_start));
173
174 }
175 ENDFOR
176
177    fac       = global_gain;
178    is_pos    = 0;
179    noise_nrg = global_gain - NOISE_OFFSET;
180
181    pTable    = pBook[BOOKSCL].pTable;
182    group_win  = 0;
183    group_end  = 0;
184
185    WHILE((group_end < pFrameInfo->num_win)&&(status == SUCCESS))
186    {
187        nsfb_win  = pFrameInfo->sfb_per_win[group_end];
188        group_end = *pGroup++;
189
190        FOR(sfb = 0; sfb < nsfb_win; sfb++)
191        {
192            IF ((pHuffBookUsed[sfb] > 0)&&(pHuffBookUsed[sfb] < BOOKSCL))
193            {
194                cw_index = CALL decode_huff_cw_binary(pTable, pInputStream);
195
196                fac      += cw_index - MIDFAC;
197
198                IF((fac >= 2*TEXP) || (fac < 0))
199                {
200                    status = 1;
201                }
202                ELSE
203                {
204                    pFactors[sfb] = fac;
205                }
206                ENDIF (fac)
207
208            }
209            ELSE IF (pHuffBookUsed[sfb] == ZERO_HCB)
210            {
211                do nothing;
212            }
213
214            ELSE IF ((pHuffBookUsed[sfb] == INTENSITY_HCB)||
215                     (pHuffBookUsed[sfb] == INTENSITY_HCB2))
216            {
217                cw_index = CALL decode_huff_cw_binary(pTable, pInputStream);
218
219                is_pos        += cw_index - MIDFAC;
220                pFactors[sfb] =  is_pos;
221            }
222
223            ELSE IF (pHuffBookUsed[sfb] == NOISE_HCB)
224            {
225                IF (noise_pcm_flag == TRUE)
226                {
227                    noise_pcm_flag = FALSE;
228                    dpcm_noise_nrg = CALL getbits(
229                                              NOISE_PCM_BITS,
230                                              pInputStream);
231
232                    dpcm_noise_nrg -= NOISE_PCM_OFFSET;
233                }
234                ELSE
235                {
236                    dpcm_noise_nrg = CALL decode_huff_cw_binary(
237                                              pTable,
238                                              pInputStream);
239
240                    dpcm_noise_nrg -= MIDFAC;
241                }
242                ENDIF (noise_pcm_flag)
243
244                noise_nrg       += dpcm_noise_nrg;
245                pFactors[sfb]   =  noise_nrg;
246            }
247
248            ELSE IF (pHuffBookUsed[sfb] == BOOKSCL)
249            {
250                status = 1;
251            }
252            ENDIF (pHuffBookUsed[sfb])
253
254        }
255        ENDFOR (sfb)
256
257        IF (pFrameInfo->islong == FALSE)
258        {
259
260            FOR(group_win++; group_win < group_end; group_win++)
261            {
262                FOR (sfb=0; sfb < nsfb_win; sfb++)
263                {
264                    pFactors[sfb + nsfb_win]  =  pFactors[sfb];
265                }
266                ENDFOR
267
268                pFactors  +=  nsfb_win;
269            }
270            ENDFOR
271
272        }
273        ENDIF (pFrameInfo)
274
275        pHuffBookUsed   += nsfb_win;
276        pFactors        += nsfb_win;
277
278    }
279    ENDWHILE (group_end)
280
281    return status;
282
283------------------------------------------------------------------------------
284 RESOURCES USED
285   When the code is written for a specific target processor the
286     the resources used should be documented below.
287
288 STACK USAGE: [stack count for this module] + [variable to represent
289          stack usage for each subroutine called]
290
291     where: [stack usage variable] = stack usage for [subroutine
292         name] (see [filename].ext)
293
294 DATA MEMORY USED: x words
295
296 PROGRAM MEMORY USED: x words
297
298 CLOCK CYCLES: [cycle count equation for this module] + [variable
299           used to represent cycle count for each subroutine
300           called]
301
302     where: [cycle count variable] = cycle count for [subroutine
303        name] (see [filename].ext)
304
305------------------------------------------------------------------------------
306*/
307
308
309/*----------------------------------------------------------------------------
310; INCLUDES
311----------------------------------------------------------------------------*/
312#include    "pv_audio_type_defs.h"
313#include    "aac_mem_funcs.h"       /* pv_memset */
314#include    "s_frameinfo.h"
315#include    "s_bits.h"
316#include    "s_sectinfo.h"
317#include    "s_huffman.h"
318#include    "ibstream.h"
319
320#include    "hcbtables.h"
321#include    "e_huffmanconst.h"
322#include    "e_infoinitconst.h"
323#include    "huffman.h"
324
325/*----------------------------------------------------------------------------
326; MACROS
327; Define module specific macros here
328----------------------------------------------------------------------------*/
329
330/*----------------------------------------------------------------------------
331; DEFINES
332; Include all pre-processor statements here. Include conditional
333; compile variables also.
334----------------------------------------------------------------------------*/
335
336/*----------------------------------------------------------------------------
337; LOCAL FUNCTION DEFINITIONS
338; Function Prototype declaration
339----------------------------------------------------------------------------*/
340
341/*----------------------------------------------------------------------------
342; LOCAL STORE/BUFFER/POINTER DEFINITIONS
343; Variable declaration - defined here and used outside this module
344----------------------------------------------------------------------------*/
345
346/*----------------------------------------------------------------------------
347; EXTERNAL FUNCTION REFERENCES
348; Declare functions defined elsewhere and referenced in this module
349----------------------------------------------------------------------------*/
350
351/*----------------------------------------------------------------------------
352; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
353; Declare variables used in this module but defined elsewhere
354----------------------------------------------------------------------------*/
355
356/*----------------------------------------------------------------------------
357; FUNCTION CODE
358----------------------------------------------------------------------------*/
359Int hufffac(
360    FrameInfo   *pFrameInfo,
361    BITS        *pInputStream,
362    Int         *pGroup,    /* may be changed to Int */
363    Int         nsect,
364    SectInfo    *pSect,     /* may be changed to Int */
365    Int         global_gain,
366    Int         *pFactors,
367    Int         huffBookUsed[])
368{
369    Int     sect_idx;
370    Int     group_end;  /* index of 1st window in next group */
371    Int     group_win;  /* window index within group */
372    Int     cw_index;   /* huff codeword index */
373    Int     nsfb_win;   /* # of scfbands per window */
374    Int     sfb;        /* scalefactor band index */
375    Int     sect_cb;    /* huff codebook # for each section */
376    Int     fac;        /* decoded scf */
377    Int     is_pos;     /* intensity stereo position */
378    Int     noise_pcm_flag = TRUE;  /* first PNS sfb */
379    Int     dpcm_noise_nrg;     /* dpcm noise energy */
380    Int     noise_nrg;      /* noise energy */
381    Int     status = SUCCESS;  /* status of decoding */
382    Int     *pHuffBookUsed = &huffBookUsed[0];
383
384
385    pv_memset(pFactors,
386              ZERO_HCB,
387              MAXBANDS*sizeof(*pFactors));
388
389
390    if (nsect)
391    {
392        /* read section length and codebook */
393
394        if (nsect == 1) /* long window */
395        {
396            sect_cb  = pSect->sect_cb;  /* codebook for this section */
397
398            /* all sfbs in one section share the same codebook */
399
400            for (sfb = pSect->sect_end >> 2; sfb != 0; sfb--)
401            {
402                *(pHuffBookUsed++) = sect_cb;
403                *(pHuffBookUsed++) = sect_cb;
404                *(pHuffBookUsed++) = sect_cb;
405                *(pHuffBookUsed++) = sect_cb;
406            }
407            for (sfb = pSect->sect_end & 3; sfb != 0; sfb--)
408            {
409                *(pHuffBookUsed++) = sect_cb;
410            }
411
412        }
413        else            /* short */
414        {
415            Int sect_start = 0; /* start index of sfb for each section */
416            for (sect_idx = nsect; sect_idx > 0; sect_idx--)
417            {
418                sect_cb  = pSect->sect_cb;  /* codebook for this section */
419
420                /* all sfbs in one section share the same codebook */
421                for (sfb = sect_start; sfb < pSect->sect_end; sfb++)
422                {
423                    pHuffBookUsed[sfb] = sect_cb;
424                }
425
426                pSect++;
427                sect_start = sfb;
428
429            } /* for (sect_idx) */
430        }
431    }
432    else
433    {
434        /* clear array for the case of max_sfb == 0 */
435        pv_memset(pHuffBookUsed,
436                  ZERO_HCB,
437                  MAXBANDS*sizeof(*pHuffBookUsed));
438    }
439
440    pHuffBookUsed = &huffBookUsed[0];
441
442    /* scale factors and noise energy are dpcm relative to global gain
443     * intensity positions are dpcm relative to zero
444     */
445    fac       = global_gain;
446    is_pos    = 0;
447    noise_nrg = global_gain - NOISE_OFFSET;
448
449    /* get scale factors,
450     * use reserved Table entry = 12, see reference (2) p78 Table 4.6.2
451     */
452    group_win  = 0;
453    group_end  = 0;
454
455
456    /* group by group decoding scalefactors and/or noise energy
457     * and/or intensity position
458     */
459    while ((group_end < pFrameInfo->num_win) && (status == SUCCESS))
460    {
461        nsfb_win  = pFrameInfo->sfb_per_win[group_end];
462        group_end = *pGroup++;  /* index of 1st window in next group */
463
464        /* decode scf in first window of each group */
465
466        for (sfb = 0; sfb < nsfb_win; sfb++)
467        {
468
469            switch (pHuffBookUsed[sfb])
470            {
471                case ZERO_HCB:
472                    break;
473                case INTENSITY_HCB:
474                case INTENSITY_HCB2:
475                    /* intensity books */
476                    /* decode intensity position */
477                    cw_index = decode_huff_scl(pInputStream);
478
479                    is_pos        += cw_index - MIDFAC;
480                    pFactors[sfb] =  is_pos;
481                    break;
482                case NOISE_HCB:
483                    /* noise books */
484                    /* decode noise energy */
485                    if (noise_pcm_flag == TRUE)
486                    {
487                        noise_pcm_flag = FALSE;
488                        dpcm_noise_nrg = get9_n_lessbits(NOISE_PCM_BITS,
489                                                         pInputStream);
490
491                        dpcm_noise_nrg -= NOISE_PCM_OFFSET;
492                    }
493                    else
494                    {
495                        dpcm_noise_nrg = decode_huff_scl(pInputStream);
496
497                        dpcm_noise_nrg -= MIDFAC;
498                    } /* if (noise_pcm_flag) */
499
500                    noise_nrg       += dpcm_noise_nrg;
501                    pFactors[sfb]   =  noise_nrg;
502                    break;
503                case BOOKSCL:
504                    status = 1; /* invalid books */
505                    sfb = nsfb_win;  /* force out */
506                    break;
507                default:
508                    /* spectral books */
509                    /* decode scale factors */
510                    cw_index = decode_huff_scl(pInputStream);
511
512                    fac      += cw_index - MIDFAC;   /* 1.5 dB */
513                    if ((fac >= 2*TEXP) || (fac < 0))
514                    {
515                        status = 1;   /* error, MUST 0<=scf<256, Ref. p73 */
516                    }
517                    else
518                    {
519                        pFactors[sfb] = fac;  /* store scf */
520                    } /* if (fac) */
521            }
522
523        } /* for (sfb=0), first window decode ends */
524
525        /* expand scf to other windows in the same group */
526        if (pFrameInfo->islong == FALSE)
527        {
528
529            for (group_win++; group_win < group_end; group_win++)
530            {
531                for (sfb = 0; sfb < nsfb_win; sfb++)
532                {
533                    pFactors[sfb + nsfb_win]  =  pFactors[sfb];
534                }
535                pFactors  +=  nsfb_win;
536            }
537
538        } /* if (pFrameInfo->islong), one group decode ends */
539
540
541        /* points to next group */
542        pHuffBookUsed   += nsfb_win;
543        pFactors        += nsfb_win;
544
545    } /* while (group_end), all groups decode end */
546
547    return status;
548
549} /* hufffac */
550
551