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:  huffspec_fxp.c
21 Funtions:
22    huffspec_fxp
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 to keep in-line with PV standards
33              (2) Eliminated "continue" in if(sect_cb==ZERO_HCB||...)
34
35 Description: (1) Use SectInfo *pSect
36              (2) Convert 'Real' to 'Int32', float -> fixed-point
37              (3) move BITS *pInputStream to second parameter
38              (4) pass in quantSpec and tmp_spec, scratch shared with hufffac
39              (5) pass in FrameInfo *pLongFrameInfo, eliminate only_long_info
40
41 Description: (1) Eliminate parameter Hcb *book, because of eliminating
42                  function 'hufftab.c', Hcb hcbbook defined as a
43                  const structure in 'hcbtables.h'.
44              (2) Replace three nested 'for' loops with a for-while loop in
45                  the rescaling part.
46              (3) Change esc_iquant-> esc_iquant_fxp, call esc_iquant_fxp()
47                  by sfb
48
49 Description: Cleaned up include files.
50
51 Description:  Correct definition of stack variable "scale".
52        It was defined as Int, but it receives an UInt value,
53        this present a problem when Int is 16 bits and
54        the sign bit is not interpreted correctly. This does not
55        shows for 32-bit implementations. This problem manifest itself
56        as a flipping sign on some spectral coefficients (the ones
57        multiplied by 0x8000).
58
59 Description: Typecast b_low and b_high to 32-bits before multiplication, this
60              assures propoer compilation on a 16-bit platform (TI-C55x)
61
62 Description: Modified to speed up decode_huff_cw
63
64 Description: pass codebook index to decode_huff_cw, delete pointer to Huffman
65              structure
66
67 Description: keep memset to quantSpec, remove memset to temp_spec
68
69 Description: Modified per review comments
70
71 Description: Use Binary tree search in decode_huff_cw_binary
72
73 Description: Modified per review comments
74              (1) delete unused codes
75
76 Description: (1) Change the interface to decode huffman codeword.
77              (2) Move the scaling inside the inverse quantization.
78              (3) Change scaling factor accuracy to 10 bits.
79
80 Description:
81              (1) delete unused variable max_fac
82
83 Description: Addresses of huffman tables are now found by means of a
84              switch statement, this solve linking problem when using the
85              /ropi option (Read-only position independent) for some
86              compilers
87
88 Who:                                   Date: MM/DD/YYYY
89 Description:
90------------------------------------------------------------------------------
91 INPUT AND OUTPUT DEFINITIONS
92
93 Inputs:
94    pFrameInfo  = ptr to structure that holds Information of current Frame,
95                  type FrameInfo
96
97    pInputStream = ptr to structure of bitstream, type BITS
98
99    nsect       = number of sections in current Frame, at fs = 44.1 kHz,
100                  range [0, 49] long block, [0,112] short blocks. type Int
101
102    pSect       = ptr to structure that holds section codebook and boundary
103                  type SectInfo
104
105    factors[]   = array that contains scalefactors for each sfb, type Int16
106
107    coef[]      = array that holds inverse quantized coefs, Int32 QFormat.
108
109    quantSpec[] = array that holds quantized spectral coefs, type Int
110
111    tmp_spec[]  = temporary buffer to hold the de-interleaved coefs.
112
113    pLongFrameInfo = ptr to structure that holds long frame info
114
115 Local Stores/Buffers/Pointers Needed:
116    exptable = array contains the Q15 format data for 2^0, 2^0.25, 2^0.5,
117               and 2^0.75, type const Int.
118
119 Global Stores/Buffers/Pointers Needed:
120    None
121
122 Outputs:
123
124    return 0 if decoding properly.
125
126 Pointers and Buffers Modified:
127
128    pInputStream    read codeword index and/or sign bits and/or ESC value
129
130    coef            contains the newly inverse quantized 1024 spec coefs,
131                    type Int32 Q-format from esc_iquant()
132
133    quantSpec       contains decoded quantized 1024 spec coefs, type Int
134
135    tmp_spec        contains the de-interleaved version of quantSpec
136
137    qFormat         contains Q-Format for each scalefactor band
138
139 Local Stores Modified:
140    None
141
142 Global Stores Modified:
143    None
144
145------------------------------------------------------------------------------
146 FUNCTION DESCRIPTION
147
148 This function first reads the section info (codebook and boundary), then
149 decode the spectral coefficients if a spectral codebook is used.
150 If necessary, get the sign bits, ESC value or the NEC_pulse data. In case of
151 short window sequences, the decoded data is de-interleaved before
152 multiplied by scalefactors.
153
154------------------------------------------------------------------------------
155 REQUIREMENTS
156
157 This function should set the content of the array 'coef' with the inverse
158 quantized and rescaled value of spectral coefficients.
159
160------------------------------------------------------------------------------
161 REFERENCES
162
163 (1) MPEG-2 NBC Audio Decoder
164   "This software module was originally developed by AT&T, Dolby
165   Laboratories, Fraunhofer Gesellschaft IIS in the course of development
166   of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
167   3. This software module is an implementation of a part of one or more
168   MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
169   Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audio
170   standards free license to this software module or modifications thereof
171   for use in hardware or software products claiming conformance to the
172   MPEG-2 NBC/MPEG-4 Audio  standards. Those intending to use this software
173   module in hardware or software products are advised that this use may
174   infringe existing patents. The original developer of this software
175   module and his/her company, the subsequent editors and their companies,
176   and ISO/IEC have no liability for use of this software module or
177   modifications thereof in an implementation. Copyright is not released
178   for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
179   developer retains full right to use the code for his/her own purpose,
180   assign or donate the code to a third party and to inhibit third party
181   from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
182   This copyright notice must be included in all copies or derivative
183   works."
184   Copyright(c)1996.
185
186 (2) ISO/IEC 14496-3: 1999(E)
187    Subpart (4)         p56 (spectral_data() parsing and decoding)
188                        p26 (Syntax of spectral_data())
189                        p74-78 (decoding: unpack_idx, get_sign_bits,
190                                getescape, pulse_nc, deinterleave)
191                        p72 (inverse quantization: esc_iquant)
192
193------------------------------------------------------------------------------
194 PSEUDO-CODE
195
196
197------------------------------------------------------------------------------
198 RESOURCES USED
199   When the code is written for a specific target processor the
200     the resources used should be documented below.
201
202 STACK USAGE: [stack count for this module] + [variable to represent
203          stack usage for each subroutine called]
204
205     where: [stack usage variable] = stack usage for [subroutine
206         name] (see [filename].ext)
207
208 DATA MEMORY USED: x words
209
210 PROGRAM MEMORY USED: x words
211
212 CLOCK CYCLES: [cycle count equation for this module] + [variable
213           used to represent cycle count for each subroutine
214           called]
215
216     where: [cycle count variable] = cycle count for [subroutine
217        name] (see [filename].ext)
218
219------------------------------------------------------------------------------
220*/
221
222/*----------------------------------------------------------------------------
223; INCLUDES
224----------------------------------------------------------------------------*/
225#include    "pv_audio_type_defs.h"
226#include    "aac_mem_funcs.h"
227#include    "esc_iquant_scaling.h"
228#include    "huffman.h"
229#include    "unpack_idx.h"
230#include    "pulse_nc.h"
231#include    "iquant_table.h"
232#include    "e_huffmanconst.h"
233
234
235#include "pv_normalize.h"
236
237/*----------------------------------------------------------------------------
238; MACROS
239; Define module specific macros here
240----------------------------------------------------------------------------*/
241
242
243/*----------------------------------------------------------------------------
244; DEFINES
245; Include all pre-processor statements here. Include conditional
246; compile variables also.
247----------------------------------------------------------------------------*/
248#define ORDER        (3)
249
250/*
251 * Format the table is stored in.
252 */
253#define QTABLE       (27)
254
255/*
256 * Number of bits for data in a signed 32 bit integer.
257 */
258#define SIGNED32BITS  (31)
259
260/*
261 * Round up value for intermediate values obtained from the table
262 */
263#define ROUND_UP (( ((UInt32) 1) << (QTABLE) )-1)
264
265/*----------------------------------------------------------------------------
266; LOCAL FUNCTION DEFINITIONS
267; Function Prototype declaration
268----------------------------------------------------------------------------*/
269
270/*----------------------------------------------------------------------------
271; LOCAL STORE/BUFFER/POINTER DEFINITIONS
272; Variable declaration - defined here and used outside this module
273----------------------------------------------------------------------------*/
274const UInt16 exptable[4] =
275{
276    0,  /* (2^0.00)<<15 (Q10), use zero to signal no scaling required! */
277    19485,  /* (2^0.25)<<15 */
278    23171,  /* (2^0.50)<<15 */
279    27555   /* (2^0.75)<<15 */
280
281};
282
283
284/*----------------------------------------------------------------------------
285; EXTERNAL FUNCTION REFERENCES
286; Declare functions defined elsewhere and referenced in this module
287----------------------------------------------------------------------------*/
288
289/*----------------------------------------------------------------------------
290; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
291; Declare variables used in this module but defined elsewhere
292----------------------------------------------------------------------------*/
293
294/*----------------------------------------------------------------------------
295; FUNCTION CODE
296----------------------------------------------------------------------------*/
297
298Int huffspec_fxp(
299    FrameInfo *pFrameInfo,
300    BITS      *pInputStream,
301    Int       nsect,
302    SectInfo  *pSectInfo,
303    Int       factors[],
304    Int32     coef[],
305    Int16     quantSpec[],
306    Int16     tmp_spec[],
307    const FrameInfo  *pLongFrameInfo,
308    PulseInfo  *pPulseInfo,
309    Int         qFormat[])
310{
311    /*----------------------------------------------------------------------------
312    ; Define all local variables
313    ----------------------------------------------------------------------------*/
314    const Hcb       *pHcb;
315    Int     i;
316    Int     sfb;
317    Int     idx_count;
318    Int     sect_cb;    /* section codebook */
319    Int     dim;
320    Int     idx;
321    Int     stop_idx;     /* index of 1st coef in next sfb */
322    Int     sect_start;   /* start index of sfb in one section*/
323    Int     sect_end;     /* index of 1st sfb in next section */
324    Int     *pSfbStart;
325    Int     *pSfb;
326    Int16     *pQuantSpec;        /* probably could be short */
327    Int     max = 0;
328    /* rescaling parameters */
329    Int     nsfb;
330    Int     tot_sfb;
331    Int     fac;
332
333    Int32   *pCoef; /* ptr to coef[], inverse quantized coefs */
334    UInt16     scale;
335
336    Int     power_scale_div_4;
337    Int     sfbWidth;
338
339    void (*pUnpack_idx)(
340        Int16  quant_spec[],
341        Int  codeword_indx,
342        const Hcb *pHuffCodebook,
343        BITS  *pInputStream,
344        Int *max);
345
346    Int(*pDec_huff_tab)(BITS *) = NULL;
347
348    UInt32 temp;
349    Int    binaryDigits, QFormat;
350
351    /*----------------------------------------------------------------------------
352    ; Function body here
353    ----------------------------------------------------------------------------*/
354
355    sect_start = 0;
356    stop_idx   = 0;
357
358    /* pSfb: ptr to array that holds stop index of each sfb */
359    pSfbStart = pFrameInfo->frame_sfb_top;
360
361    if (pSfbStart == NULL)
362    {
363        return (-1);   /*  error condition */
364    }
365
366    pSfb      = pSfbStart;
367
368    /* decoding spectral values section by section */
369    for (i = nsect; i > 0; i--)
370    {
371        /* read the codebook and section length */
372        sect_cb  =  pSectInfo->sect_cb;     /* codebook */
373        if ((sect_cb > 15) || (sect_cb < 0))
374        {
375            return (-1);   /*  error condition */
376        }
377        sect_end =  pSectInfo->sect_end;    /* # of sfbs */
378
379        if (sect_end < 0)
380        {
381            return (-1);   /*  error condition */
382        }
383
384        pSectInfo++;
385
386        /*  sect_cb       sect_cb - 1
387         *  ZERO_HCB        1111b
388         *    1             0000b
389         *    2             0001b
390         *    3             0010b
391         *    4             0011b
392         *    5             0100b
393         *    6             0101b
394         *    7             0110b
395         *    8             0111b
396         *    9             1000b
397         *    10            1001b
398         *    11            1010b
399         *    12            1011b
400         * NOISE_HCB        1100b
401         * INTENSITY_HCB2   1101b
402         * INTENSITY_HCB    1110b
403         * if ( ((sect_cb - 1) & 0xC) == 0xC ) is identical to
404         * if !((sect_cb == ZERO_HCB) || (sect_cb == NOISE_HCB) ||
405         *      (sec_cb == INTENSITY_HCB) || (sect_cb==INTENSITY_HCB2) )
406         * use this compare scheme to speed up the execution
407         */
408
409        if (((sect_cb - 1) & 0xC) != 0xC)
410        {
411            /* decode spec in one section */
412            if (sect_cb > BY4BOOKS)
413            {
414                dim = DIMENSION_2; /* set codebook dimension */
415            }
416            else
417            {
418                dim = DIMENSION_4;
419            }
420
421            pHcb        = &hcbbook_binary[sect_cb];
422
423            if (sect_cb == ESCBOOK)
424            {
425                pUnpack_idx = &unpack_idx_esc;
426            }
427            else if (pHcb->signed_cb == FALSE)
428            {
429                pUnpack_idx = &unpack_idx_sgn;
430            }
431            else
432            {
433                pUnpack_idx = &unpack_idx;
434            }
435
436
437            switch (sect_cb)
438            {
439                case 1:
440                    pDec_huff_tab = decode_huff_cw_tab1;
441                    break;
442                case 2:
443                    pDec_huff_tab = decode_huff_cw_tab2;
444                    break;
445                case 3:
446                    pDec_huff_tab = decode_huff_cw_tab3;
447                    break;
448                case 4:
449                    pDec_huff_tab = decode_huff_cw_tab4;
450                    break;
451                case 5:
452                    pDec_huff_tab = decode_huff_cw_tab5;
453                    break;
454                case 6:
455                    pDec_huff_tab = decode_huff_cw_tab6;
456                    break;
457                case 7:
458                    pDec_huff_tab = decode_huff_cw_tab7;
459                    break;
460                case 8:
461                    pDec_huff_tab = decode_huff_cw_tab8;
462                    break;
463                case 9:
464                    pDec_huff_tab = decode_huff_cw_tab9;
465                    break;
466                case 10:
467                    pDec_huff_tab = decode_huff_cw_tab10;
468                    break;
469                case 11:
470                    pDec_huff_tab = decode_huff_cw_tab11;
471                    break;
472                default:
473                    return (-1); /* error condition */
474            }
475
476            /* move ptr to first sfb of current section */
477            pQuantSpec  = quantSpec + stop_idx;
478
479            /* step through all sfbs in current section */
480            for (sfb = sect_start; sfb < sect_end; sfb++)
481            {
482                idx_count = *pSfb - stop_idx;
483                stop_idx  = *pSfb++;
484
485                /* decode all coefs for one sfb */
486                while ((idx_count > 0) && (idx_count < 1024))
487                {
488
489                    idx = (*pDec_huff_tab)(pInputStream);
490
491                    (*pUnpack_idx)(pQuantSpec,
492                                   idx,
493                                   pHcb,
494                                   pInputStream,
495                                   &max);      /* unpack idx -> coefs */
496
497                    pQuantSpec += dim;
498                    idx_count  -= dim;
499
500                } /* while(idx_count) */
501
502            } /* for (sfb=sect_start) */
503        }
504        else
505        {
506
507            /* current section uses ZERO_HCB, NOISE_HCB, etc */
508
509            /* move sfb pointer to the start sfb of next section */
510            pSfb        = pSfbStart + sect_end;
511            /* number of coefs in current section */
512            idx_count   = *(pSfb - 1) - stop_idx;
513
514            if ((idx_count > 1024) || (idx_count < 0))
515            {
516                return (-1);   /*  error condition */
517            }
518
519            /*
520             * This memset is necessary in terms of (1) net savings in total
521             * MIPS and (2) accurate Q-Formats for fft_rx2
522             * In case a scalefactor band uses ZERO_HCB, all coefficients of
523             * that sfb should be zeros. Without this call to memset, the
524             * coefficients for a ZERO_HCB sfb are the "leftovers" of the
525             * previous frame, which may not have all zero values. This leads
526             * to a drastical increase in the cycles consumed by esc_iquant_fxp
527             * and fft_rx2, which is the most "expensive" function of the
528             * library.
529             * This memset also guarantees the Q_Format for sfbs with all zero
530             * coefficients will be set properly.
531             * Profiling data on ARM and TMS320C55x proves that there is a net
532             * gain in total MIPS if a memset is called here.
533             */
534            pv_memset(&quantSpec[stop_idx],
535                      0,
536                      idx_count * sizeof(quantSpec[0]));
537
538            /*
539             * This memset is called because pQuantSpec points to tmp_spec
540             * after deinterleaving
541             */
542
543            pv_memset(&tmp_spec[stop_idx],
544                      0,
545                      idx_count * sizeof(tmp_spec[0]));
546
547
548            /* stop_idx is the index of the 1st coef of next section */
549            stop_idx    = *(pSfb - 1);
550
551        }/* if (sect_cb) */
552
553        sect_start = sect_end;
554
555    } /* for (i=nsect) */
556
557    /* noisless coding reconstruction */
558    if (pFrameInfo->islong != FALSE)
559    {
560        if (pPulseInfo->pulse_data_present == 1)
561        {
562            pulse_nc(quantSpec,
563                     pPulseInfo,
564                     pLongFrameInfo,
565                     &max);    /* add pulse data */
566        }
567
568        pQuantSpec = quantSpec;
569
570    }
571    else
572    {
573        deinterleave(quantSpec,
574                     tmp_spec,
575                     pFrameInfo);
576
577        pQuantSpec = tmp_spec;
578    }
579
580
581    /* inverse quantization, Q_format: Int32 */
582    /* rescaling */
583
584    /* what we can do here is assuming that we already know maxInput for each band, we have to go
585    though each one of them for re-quant and scaling, and pick the right qFormat to apply to
586    all spectral coeffs.*/
587
588    if ((max < 0) || (max > 8192))    /* (8192>>ORDER) == 1024 is the inverseQuantTable size */
589    {
590        return (-1);   /*  error condition */
591    }
592    else
593    {
594        /* Get  (max/SPACING) ^ (1/3), in Q Format  */
595        temp = inverseQuantTable[(max >> ORDER) + 1];
596    }
597
598
599    /* Round up before shifting down to Q0 */
600    temp += ROUND_UP;
601
602    /* shift down to Q0 and multiply by 2 (FACTOR) in one step */
603    temp >>= (QTABLE - 1);
604
605    /* Now get max ^ (4/3) in Q0 */
606    temp *= max;
607
608
609    binaryDigits = 31 - pv_normalize(temp);
610
611
612    /* Prevent negative shifts caused by low maximums. */
613    if (binaryDigits < (SIGNED32BITS - QTABLE))
614    {
615        binaryDigits = SIGNED32BITS - QTABLE;
616    }
617
618    QFormat = SIGNED32BITS - binaryDigits;
619
620    /********************/
621    tot_sfb = 0;
622    nsfb = pFrameInfo->sfb_per_win[0];
623    pCoef = coef;
624
625    for (i = pFrameInfo->num_win; i > 0; i--)
626    {
627        stop_idx  = 0;
628
629        for (sfb = 0; sfb < nsfb; sfb++)
630        {
631            sfbWidth   =  pFrameInfo->win_sfb_top[0][sfb] - stop_idx;
632
633            if ((sfbWidth < 0) || (sfbWidth > 1024))
634            {
635                return (-1);   /*  error condition */
636            }
637
638            stop_idx  += sfbWidth;
639
640            fac   = factors[tot_sfb] - SF_OFFSET;
641            scale = exptable[fac & 0x3];
642
643            power_scale_div_4 = fac >> 2;
644
645            power_scale_div_4++;
646
647            qFormat[tot_sfb] = QFormat;
648
649            esc_iquant_scaling(pQuantSpec,
650                               pCoef,
651                               sfbWidth,
652                               QFormat,
653                               scale,
654                               max);
655
656            pQuantSpec += sfbWidth;
657            qFormat[tot_sfb] -= power_scale_div_4;
658            pCoef += sfbWidth;
659
660            tot_sfb++;
661
662        } /* for (sfb) */
663    } /* for (i) */
664
665
666    /*----------------------------------------------------------------------------
667    ; Return status
668    ----------------------------------------------------------------------------*/
669    return SUCCESS;
670
671} /* huffspec_fxp */
672