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: getics.c
21
22------------------------------------------------------------------------------
23 REVISION HISTORY
24
25 Description:  Modified from original shareware code
26
27 Description:  Modified to pass variables by reference to eliminate use
28               of global variables
29
30 Description: Remove pass-in parameter global_gain, define it on stack.
31
32 Description: (1) Modified to bring in-line with PV standards
33              (2) Modified pass in parameters
34              (3) Removed multiple returns, removed some if branch
35              (4) Replace for loop with pv_memset
36
37 Description: Remove prstflag, fix copyright.
38
39 Description: Fix pseudo-code
40
41 Description: Remove lpflag from get_ics_info
42
43 Description: (1) Removed widx, therefore, pChVarsWin is eliminated from
44                  pass in parameter
45
46 Description: merged the above changes from Michael and Wen
47
48 Description: Removed initialization of "pTnsFrameInfo->num_subblocks" since
49 this element was removed from that structure, as a part of
50 rearchitecting the TNS routines to use memory more efficiently.
51
52 Description:
53 (1) Added #include of "e_HuffmanConst.h"
54     Previously, this function was relying on another include file
55     to include "e_HuffmanConst.h"
56
57 (2) Updated the copyright header.
58
59 (3) Added #include of <stdlib.h> for NULL macro definition.
60
61 Description:
62 (1) Removed the first parameter to getics.c  This extra
63     FrameInfo was not needed, the contents of winmap can be used.
64 (2) Removed the memcpy of the data from winmap to the temporary
65     FrameInfo.
66
67 Description: Replace some instances of getbits to get1bits
68              when only 1 bit is read.
69
70 Description:
71
72------------------------------------------------------------------------------
73 INPUT AND OUTPUT DEFINITIONS
74
75 Inputs:
76    pInputStream    =   pointer to structure that holds input stream,
77                        Type BITS
78
79    common_window   =   flag that indicates whether left and right channel
80                        share the same window sequence & shape, Type Int
81
82    pVars           =   pointer to structure that holds decoder information
83                        Type tDec_Int_File
84
85    pChVarsCh       =   pointer to structure that holds channel related
86                        decoding information, Type tDec_Int_Chan
87
88    group[]         =   pointer to array that contains window grouping
89                        information of current frame, Type UChar
90
91    pMax_sfb        =   pointer to variable that stores maximum active
92                        scalefactor bands of current frame, Type UChar
93
94    pCodebookMap    =   pointer to array that holds the indexes of all
95                        Huffman codebooks used for current frame, ordered
96                        from section 0 to last section. Type UChar
97
98    pTnsFrameInfo   =   pointer to structure that holds TNS information.
99                        Type TNS_frame_info
100
101    pWinMap         =   array of pointers which points to structures that
102                        hold information of long and short window sequences
103                        Type FrameInfo
104
105    pPulseInfo       =   pointer to structure that holds pulse data decoding
106                        information, Type Nec_info
107
108    sect[]          =   array of structures that hold section codebook and
109                        section length in current frame, Type SectInfo
110
111 Local Stores/Buffers/Pointers Needed:
112    None
113
114 Global Stores/Buffers/Pointers Needed:
115    None
116
117 Outputs:
118    status = 0  if success
119             1  otherwise
120
121 Pointers and Buffers Modified:
122    pCodebookMap    contents are replaced by the indexes of all the huffman
123                    codebooks used for current frame
124
125    pWinMap         For short windows, the contents of frame_sfb_top are
126                    modified by calc_gsfb_table, with the top coefficient
127                    index of each scalefactor band.
128
129 Local Stores Modified:
130    None
131
132 Global Stores Modified:
133    None
134
135------------------------------------------------------------------------------
136 FUNCTION DESCRIPTION
137
138 This function decodes individual channel stream by calling other Huffman
139 decoding functions.
140
141------------------------------------------------------------------------------
142 REQUIREMENTS
143
144 This function replaces the contents of pCodebookMap with the decoded
145 codebook indexes. By calling hufffac, it decodes scale factor data. Call
146 huffspec_fxp to decode spectral coefficients of current frame.
147
148------------------------------------------------------------------------------
149 REFERENCES
150
151 (1) MPEG-2 NBC Audio Decoder
152   "This software module was originally developed by AT&T, Dolby
153   Laboratories, Fraunhofer Gesellschaft IIS in the course of development
154   of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
155   3. This software module is an implementation of a part of one or more
156   MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
157   Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audio
158   standards free license to this software module or modifications thereof
159   for use in hardware or software products claiming conformance to the
160   MPEG-2 NBC/MPEG-4 Audio  standards. Those intending to use this software
161   module in hardware or software products are advised that this use may
162   infringe existing patents. The original developer of this software
163   module and his/her company, the subsequent editors and their companies,
164   and ISO/IEC have no liability for use of this software module or
165   modifications thereof in an implementation. Copyright is not released
166   for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
167   developer retains full right to use the code for his/her own purpose,
168   assign or donate the code to a third party and to inhibit third party
169   from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
170   This copyright notice must be included in all copies or derivative
171   works."
172   Copyright(c)1996.
173
174 (2) ISO/IEC 14496-3: 1999(E)
175    Subpart 4           p24 (Table 4.4.24)
176                        p54 (4.5.2.3.2)
177
178------------------------------------------------------------------------------
179 PSEUDO-CODE
180
181    pGroup = group;
182
183    global_gain = CALL getbits(
184                            neededBits   = LEN_SCL_PCM,
185                            pInputStream = pInputStream)
186                        MODIFYING(pInputStream)
187                        ReTURNING(global_gain)
188
189    IF (common_window == FALSE)
190    THEN
191        status = CALL get_ics_info(
192                        pVars->mc_info.audioObjectType,
193                        pInputStream,
194                        common_window,
195                       &pChVars->wnd,
196                       &pChVars->wnd_shape_this_bk,
197                        group,
198                        pMax_sfb,
199                        pWinMap,
200                        &pChVars->lt_status,
201                        NULL)
202                    MODIFYING(pInputStream,pChVars,group,max_sfb,lt_status)
203                    RETURNING(status)
204    ENDIF
205
206    memcpy(pFrameInfo, pWinMap[pChVars->wnd], sizeof(FrameInfo))
207
208    IF (*pMax_sfb > 0)
209    THEN
210
211        i      = 0;
212        totSfb = 0;
213
214        DO
215
216            totSfb++;
217
218        WHILE( *pGroup++ < pFrameInfo->num_win);
219
220        totSfb  *=  pFrameInfo->sfb_per_win[0];
221
222        nsect = CALL huffcb(
223                        sect,
224                        pInputStream,
225                        pFrameInfo->sectbits,
226                        totSfb,
227                        pFrameInfo->sfb_per_win[0],
228                       *pMax_sfb)
229                    MODIFYING(sect,pInputStream,sectbits)
230                    RETURNING(nsect)
231
232        IF (nsect == 0)
233        THEN
234            status = 1
235
236        ENDIF
237
238        sectStart = 0;
239        FOR (i = 0; i < nsect; i++)
240
241            cb  = sect[i].sect_cb;
242            sectWidth =  sect[i].sect_end - sectStart;
243            sectStart += sectWidth;
244
245            WHILE (sectWidth > 0)
246
247                *pCodebookMap++ = cb
248                 sectWidth--
249            ENDWHILE
250
251        ENDFOR (i)
252
253    ELSE
254
255        memset(pCodebookMap,ZERO_HCB,MAXBANDS*sizeof(*pCodebookMap));
256
257    ENDIF (*pMax_sfb)
258
259    IF (pFrameInfo->islong == FALSE)
260    THEN
261        CALL calc_gsfb_table(
262                pFramInfo = pFrameInfo,
263                group[]   = group)
264              MODIFYING(pFrameInfo->frame_sfb_top)
265              RETURNING(void)
266    ENDIF
267
268    IF (status == SUCCESS)
269    THEN
270        status = CALL hufffac(
271                        pFrameInfo,
272                        pInputStream,
273                        group,
274                        nsect,
275                        sect,
276                        global_gain,
277                        pChVars->factors,
278                        pVars->huffBookUsed)
279                    MODIFYING(pInputStream,factors)
280                    RETURNING(status)
281
282    ENDIF (status)
283
284    IF (status == SUCCESS)
285    THEN
286        present = CALL getbits(
287                        neededBits   = LEN_PULSE_PRES,
288                        pInputStream = pInputStream)
289                    MODIFYING(pInputStream)
290                    RETURNING(present)
291
292        pPulseInfo->pulse_data_present = present;
293
294        IF (present != FALSE)
295        THEN
296            IF (pFrameInfo->islong == 1)
297            THEN
298                CALL get_pulse_data(
299                          pPulseInfo = pPulseInfo,
300                          pInputStream = pInputStream)
301                    MODIFYING(pInputStream,pPulseInfo)
302                    RETURNING(void)
303
304            ELSE
305
306                status = 1;
307
308            ENDIF (pFrameInfo)
309        ENDIF (present)
310
311    ENDIF (status)
312
313    IF (status == SUCCESS)
314    THEN
315        present = CALL getbits(
316                        neededBits = LEN_TNS_PRES,
317                        pInputStream = pInputStream)
318                    MODIFYING(pInputStream)
319                    RETURNING(present)
320
321        pTnsFrameInfo->tns_data_present = present;
322
323        IF (present != FALSE)
324        THEN
325            CALL get_tns(
326                    pFrameInfo = pFrameInfo,
327                    pTnsFrameInfo = pTnsFrameInfo,
328                    pInputStream = pInputStream)
329                MODIFYING(pInputStream, pTnsFrameInfo)
330                RETURNING(void)
331        ELSE
332
333            FOR (i = pTnsFrameInfo->n_subblocks - 1; i >= 0 ; i--)
334
335                pTnsFrameInfo->info[i].n_filt = 0;
336            ENDFOR
337
338        ENDIF(present)
339
340    ENDIF (status)
341
342    IF (status == SUCCESS)
343    THEN
344        present = CALL getbits(
345                        neededBits = LEN_GAIN_PRES,
346                        pInputStream = pInputStream)
347                MODIFYING(pInputStream)
348                RETURNING(present)
349
350        IF (present != FALSE)
351        THEN
352            status = 1;
353        ENDIF
354    ENDIF (status)
355
356    IF (status == SUCCESS)
357    THEN
358        status = CALL huffspec_fxp(
359                        pFrameInfo,
360                        pInputStream,
361                        nsect,
362                        sect,
363                        pChVars->factors,
364                        pChVars->fxpCoef,
365                        pVars->quantSpec,
366                        pVars->tmp_spec,
367                        pWinMap[ONLY_LONG_WINDOW],
368                        pPulseInfo,
369                        pChVars->qFormat)
370                MODIFYING(pInputStream,fxpCoef,quantSpec,tmp_spec,qFormat)
371                RETURNING(status)
372    ENDIF
373
374    RETURN status
375
376------------------------------------------------------------------------------
377*/
378
379
380/*----------------------------------------------------------------------------
381; INCLUDES
382----------------------------------------------------------------------------*/
383#include    "pv_audio_type_defs.h"
384#include    "e_huffmanconst.h"
385#include    "huffman.h"
386#include    "aac_mem_funcs.h"
387#include    "get_tns.h"
388
389/*----------------------------------------------------------------------------
390; MACROS
391; Define module specific macros here
392----------------------------------------------------------------------------*/
393
394
395/*----------------------------------------------------------------------------
396; DEFINES
397; Include all pre-processor statements here. Include conditional
398; compile variables also.
399----------------------------------------------------------------------------*/
400
401/*----------------------------------------------------------------------------
402; LOCAL FUNCTION DEFINITIONS
403; Function Prototype declaration
404----------------------------------------------------------------------------*/
405
406/*----------------------------------------------------------------------------
407; LOCAL STORE/BUFFER/POINTER DEFINITIONS
408; Variable declaration - defined here and used outside this module
409----------------------------------------------------------------------------*/
410
411/*----------------------------------------------------------------------------
412; EXTERNAL FUNCTION REFERENCES
413; Declare functions defined elsewhere and referenced in this module
414----------------------------------------------------------------------------*/
415
416/*----------------------------------------------------------------------------
417; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
418; Declare variables used in this module but defined elsewhere
419----------------------------------------------------------------------------*/
420
421/*----------------------------------------------------------------------------
422; FUNCTION CODE
423----------------------------------------------------------------------------*/
424Int getics(
425    BITS            *pInputStream,
426    Int             common_window,
427    tDec_Int_File   *pVars,
428    tDec_Int_Chan   *pChVars,
429    Int             group[],
430    Int             *pMax_sfb,
431    Int             *pCodebookMap,
432    TNS_frame_info  *pTnsFrameInfo,
433    FrameInfo       **pWinMap,
434    PulseInfo       *pPulseInfo,
435    SectInfo        sect[])
436{
437    /*----------------------------------------------------------------------------
438    ; Define all local variables
439    ----------------------------------------------------------------------------*/
440    Int     status = SUCCESS;
441
442    Int     nsect = 0;
443    Int     i;
444    Int     cb;
445    Int     sectWidth;
446    Int     sectStart;
447    Int     totSfb;
448    Int     *pGroup;
449
450    FrameInfo *pFrameInfo;
451
452    Int     global_gain; /* originally passed in from huffdecode */
453    Bool    present;
454
455    /*----------------------------------------------------------------------------
456    ; Function body here
457    ----------------------------------------------------------------------------*/
458    pGroup = group;
459
460    /* read global gain from Input bitstream */
461    global_gain =
462        get9_n_lessbits(
463            LEN_SCL_PCM,
464            pInputStream);
465
466    if (common_window == FALSE)
467    {
468        status = get_ics_info(
469                     pVars->mc_info.audioObjectType,
470                     pInputStream,
471                     common_window,
472                     &pChVars->wnd,
473                     &pChVars->wnd_shape_this_bk,
474                     group,
475                     pMax_sfb,
476                     pWinMap,
477                     &pChVars->pShareWfxpCoef->lt_status,
478                     NULL);
479    }
480
481    pFrameInfo = pWinMap[pChVars->wnd];
482
483    /* First, calculate total number of scalefactor bands
484     * for this grouping. Then, decode section data
485     */
486    if (*pMax_sfb > 0)
487    {
488
489        /* calculate total number of sfb */
490        i      = 0;
491        totSfb = 0;
492
493        do
494        {
495            totSfb++;
496
497        }
498        while (*pGroup++ < pFrameInfo->num_win);
499
500        totSfb  *=  pFrameInfo->sfb_per_win[0];
501
502        /* decode section data */
503        nsect =
504            huffcb(
505                sect,
506                pInputStream,
507                pFrameInfo->sectbits,
508                totSfb,
509                pFrameInfo->sfb_per_win[0],
510                *pMax_sfb);
511
512        if (nsect == 0)
513        {
514            status = 1;     /* decode section data error */
515
516        }/* if (nsect) */
517
518        /* generate "linear" description from section info
519         * stored as codebook for each scalefactor band and group
520         * when nsect == 0, for-loop does not execute
521         */
522        sectStart = 0;
523        for (i = 0; i < nsect; i++)
524        {
525            cb  = sect[i].sect_cb;
526            sectWidth =  sect[i].sect_end - sectStart;
527            sectStart += sectWidth;
528
529            while (sectWidth > 0)
530            {
531                *pCodebookMap++ = cb;   /* cannot use memset for Int */
532                sectWidth--;
533            }
534
535        } /* for (i) */
536
537    }
538    else
539    {
540        /* set all sections with ZERO_HCB */
541        pv_memset(
542            pCodebookMap,
543            ZERO_HCB,
544            MAXBANDS*sizeof(*pCodebookMap));
545        /*
546                for (i=MAXBANDS; i>0; i--)
547                {
548                    *(pCodebookMap++) = ZERO_HCB;
549                }
550        */
551
552    } /* if (*pMax_sfb) */
553
554    /* calculate band offsets
555     * (because of grouping and interleaving this cannot be
556     * a constant: store it in pFrameInfo->frame_sfb_top)
557     */
558    if (pFrameInfo->islong == FALSE)
559    {
560        calc_gsfb_table(
561            pFrameInfo,
562            group);
563    }
564
565    /* decode scale factor data */
566    if (status == SUCCESS)
567    {
568        status =
569            hufffac(
570                pFrameInfo,
571                pInputStream,
572                group,
573                nsect,
574                sect,
575                global_gain,
576                pChVars->pShareWfxpCoef->factors,
577                pVars->scratch.huffbook_used);
578
579    } /* if (status) */
580
581    /* noiseless coding */
582    if (status == SUCCESS)
583    {
584        present =
585            get1bits(pInputStream);
586
587        pPulseInfo->pulse_data_present = present;
588
589        if (present != FALSE)
590        {
591            if (pFrameInfo->islong == 1)
592            {
593                status = get_pulse_data(
594                             pPulseInfo,
595                             pInputStream);
596            }
597            else
598            {
599                /* CommonExit(1,"Pulse data not allowed for short blocks"); */
600                status = 1;
601
602            } /* if (pFrameInfo) */
603        } /* if (present) */
604
605    } /* if (status) */
606
607
608    /* decode tns data */
609    if (status == SUCCESS)
610    {
611        present =
612            get1bits(pInputStream);
613
614        pTnsFrameInfo->tns_data_present = present;
615
616        if (present != FALSE)
617        {
618            get_tns(
619                pChVars->pShareWfxpCoef->max_sfb,
620                pInputStream,
621                pChVars->wnd,
622                pFrameInfo,
623                &pVars->mc_info,
624                pTnsFrameInfo,
625                pVars->scratch.tns_decode_coef);
626        }
627        else
628        {
629            for (i = pFrameInfo->num_win - 1; i >= 0 ; i--)
630            {
631                pTnsFrameInfo->n_filt[i] = 0;
632            }
633
634        } /* if(present) */
635
636    } /* if (status) */
637
638    /* gain control */
639    if (status == SUCCESS)
640    {
641        present =
642            get1bits(pInputStream);
643
644        if (present != FALSE)
645        {
646            /* CommonExit(1, "Gain control not implemented"); */
647            status = 1;
648        }
649    } /* if (status) */
650
651    if (status == SUCCESS)
652    {
653        status =
654            huffspec_fxp(
655                pFrameInfo,
656                pInputStream,
657                nsect,
658                sect,
659                pChVars->pShareWfxpCoef->factors,
660                pChVars->fxpCoef,
661                pVars->share.a.quantSpec,
662                pVars->scratch.tmp_spec,
663                pWinMap[ONLY_LONG_WINDOW],
664                pPulseInfo,
665                pChVars->pShareWfxpCoef->qFormat);
666    }
667
668    /*----------------------------------------------------------------------------
669    ; Return status
670    ----------------------------------------------------------------------------*/
671
672    return status;
673
674} /* getics */
675