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/unpack_idx.c
21 Function:  unpack_idx
22            unpack_idx_sgn
23            unpack_idx_esc
24
25------------------------------------------------------------------------------
26 REVISION HISTORY
27
28 Description:  Modified from original shareware code
29
30 Description:  Eliminated 3 divisions and 1 multiplication through a table
31 look-up method for calculating 1/mod and constant allocation of 1/mod^3
32 and 1/mod^2.
33 Eliminated 3 additions through simple optimizations in the code.
34 Changed if/else  statement to a switch/case utilizing fall-through.
35
36 Description:   Made changes per review comments.  Main improvements were
37 in change of switch/case to if statement, and use of temporary variable
38 to hold value of *pQuantSpec.
39
40 Description: (1) Typecast codeword_indx to Int32 before multiplication, this
41              assures the shift operation happens on a 32-bit product on
42              TI-C55x processor.
43              (2) define temp_spec as Int32 to avoid overflow
44
45 Description: Modified per review comments
46              (1) remove the two typecastings of codeword_indx when
47                  pHuffCodebook->dim == DIMENSION_4
48              (2) temp_spec is Int because the result never exceeds 16 bits
49
50 Description: Break up and combine unpack index with sign bit reading and for
51              special escape code. Parent function must know which one of the
52              3 functions should be called.
53
54 Description: Put back if-statement to get the max.
55
56 Description: When searching for the max, there was some instances where the
57              max was compared against a negative number, so the max was never
58              updated (defaulted to 0), leading to block processing in other
59              magnitude sensitive stages.
60
61 Who:                       Date:
62 Description:
63------------------------------------------------------------------------------
64 INPUT AND OUTPUT DEFINITIONS
65
66 Inputs:
67          Int  quant_spec[]  = Array for storage of the quantized
68                               spectral coefficients.  Length is either 2 or 4.
69                               See Ref #1, Page 76 for a complete description.
70
71          Int  codeword_indx = The index into the Huffman table.
72                               Range is [1-288]
73
74    const Hcb *pHuffCodebook = Pointer to HuffmanCodebook information.
75
76          BITS  *pInputStream = Pointer to the bitstream buffer.
77          Int *max           = Pointer to maximum coefficient value.
78
79 Local Stores/Buffers/Pointers Needed:
80    const UInt div_mod[18]   = An array with the values for 1/mod
81                               stored in Q-formats 13.
82
83 Global Stores/Buffers/Pointers Needed:
84    None
85
86 Outputs:
87    None
88
89 Pointers and Buffers Modified:
90    Int quant_spec[] = Output (the quantized and signed spectral coefficients)
91                       returned via this pointer.
92
93 Local Stores Modified:
94    None
95
96 Global Stores Modified:
97    None
98
99------------------------------------------------------------------------------
100 FUNCTION DESCRIPTION
101
102 This function decodes quantized spectral coefficients and decode their signs
103 from the input bitstream. Quantized spectral coefficients are transmitted as
104 four-tuples or 2-tuples, and this information is conveyed to the function via
105 the variable HuffCodebook->dim.
106
107 See Reference #1 for a complete description
108------------------------------------------------------------------------------
109 REQUIREMENTS
110
111 This function shall correctly calculate pQuantSpec[], given the inputs
112
113 codeword_indx     = {1-288};
114 HuffCodebook->off = {0, 1, 4};
115 HuffCodebook->mod = {3, 8, 9, 13, 17};
116
117 mod =   LAV + 1 if unsigned codebook
118 mod = 2*LAV + 1 if   signed codebook
119
120 Range of values for LAV is {2,7,12,16} if unsigned
121                            {1,4}       if   signed
122
123 Additionally,
124     LAV <= 2 if dim == 4
125
126 This restricts mod ==  3                if dim == 4
127            and mod == {3, 8, 9, 13, 17} if dim == 2
128
129 This function will NOT function correctly if fed values that do not
130 meet the requirements as stated above.
131
132 This limitation on the range of values was determined by analysis
133 of Reference #1 (see below.)
134
135------------------------------------------------------------------------------
136 REFERENCES
137
138 (1) ISO/IEC 14496-3:1999(E)
139     Part 3
140        Subpart 4.6.3.3   Decoding Process
141        Subpart 4.6.4     Tables
142 (2) MPEG-2 NBC Audio Decoder
143   "This software module was originally developed by AT&T, Dolby
144   Laboratories, Fraunhofer Gesellschaft IIS in the course of development
145   of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
146   3. This software module is an implementation of a part of one or more
147   MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
148   Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audio
149   standards free license to this software module or modifications thereof
150   for use in hardware or software products claiming conformance to the
151   MPEG-2 NBC/MPEG-4 Audio  standards. Those intending to use this software
152   module in hardware or software products are advised that this use may
153   infringe existing patents. The original developer of this software
154   module and his/her company, the subsequent editors and their companies,
155   and ISO/IEC have no liability for use of this software module or
156   modifications thereof in an implementation. Copyright is not released
157   for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
158   developer retains full right to use the code for his/her  own purpose,
159   assign or donate the code to a third party and to inhibit third party
160   from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
161   This copyright notice must be included in all copies or derivative
162   works."
163   Copyright(c)1996.
164
165------------------------------------------------------------------------------
166 PSEUDO-CODE
167
168    IF (pHuffCodebook->dim == 4)
169        *(pQuantSpec) = codeword_indx/(3^3);
170        codeword_indx = codeword_indx - *(pQuantSpec)*(3^3);
171        *(pQuantSpec) = *(pQuantSpec) - off;
172
173        pQuantSpec    = pQuantSpec + 1;
174
175        *(pQuantSpec) = codeword_indx/(3^2);
176        codeword_indx = codeword_indx - *(pQuantSpec)*(3^2);
177        *(pQuantSpec) = *(pQuantSpec) - off;
178
179        pQuantSpec    = pQuantSpec + 1;
180    ENDIF
181
182        *(pQuantSpec) = codeword_indx/mod;
183        codeword_indx = codeword_indx - (*pQuantSpec)*mod;
184        *(pQuantSpec) = *(pQuantSpec) - off;
185
186        pQuantSpec    = pQuantSpec + 1;
187
188        *(pQuantSpec) = codeword_indx - off;
189
190------------------------------------------------------------------------------
191 RESOURCES USED
192   When the code is written for a specific target processor the
193     the resources used should be documented below.
194
195 STACK USAGE: [stack count for this module] + [variable to represent
196          stack usage for each subroutine called]
197
198     where: [stack usage variable] = stack usage for [subroutine
199         name] (see [filename].ext)
200
201 DATA MEMORY USED: x words
202
203 PROGRAM MEMORY USED: x words
204
205 CLOCK CYCLES: [cycle count equation for this module] + [variable
206           used to represent cycle count for each subroutine
207           called]
208
209     where: [cycle count variable] = cycle count for [subroutine
210        name] (see [filename].ext)
211
212------------------------------------------------------------------------------
213*/
214
215
216/*----------------------------------------------------------------------------
217; INCLUDES
218----------------------------------------------------------------------------*/
219#include "pv_audio_type_defs.h"
220#include "s_hcb.h"
221#include "ibstream.h"
222#include "unpack_idx.h"
223
224#include "fxp_mul32.h"
225
226
227/*----------------------------------------------------------------------------
228; MACROS
229; Define module specific macros here
230----------------------------------------------------------------------------*/
231
232/*----------------------------------------------------------------------------
233; DEFINES
234; Include all pre-processor statements here. Include conditional
235; compile variables also.
236----------------------------------------------------------------------------*/
237#define DIV_3_CUBED    19  /* 19 = 1/27 in Q-9 format    */
238#define THREE_CUBED    27  /* 27 = 3^3                   */
239
240#define DIV_3_SQUARED  57  /* 57 = 1/9  in Q-9 format    */
241#define THREE_SQUARED   9  /*  9 = 3^2                   */
242
243#define Q_FORMAT_MOD   13  /* Q-format for 1/mod table   */
244#define Q_FORMAT_MOD2   9  /* Q-format for DIV_3_SQUARED */
245#define Q_FORMAT_MOD3   9  /* Q-format for DIV_3_CUBED   */
246
247#define LOWER_5_BITS_MASK 0x1F
248
249
250#if ( defined(PV_ARM_V5) || defined(PV_ARM_V4))
251
252__inline Int32 abs1(Int32 x)
253{
254    Int32 z;
255    /*
256        z = x - (x<0);
257        x = z ^ sign(z)
258     */
259    __asm
260    {
261        sub  z, x, x, lsr #31
262        eor  x, z, z, asr #31
263    }
264    return (x);
265}
266
267#define pv_abs(x)   abs1(x)
268
269
270#else
271
272#define pv_abs(x)   ((x) > 0)? (x) : (-x)
273
274#endif
275
276
277
278/*----------------------------------------------------------------------------
279; LOCAL FUNCTION DEFINITIONS
280; Function Prototype declaration
281----------------------------------------------------------------------------*/
282
283/*----------------------------------------------------------------------------
284; LOCAL STORE/BUFFER/POINTER DEFINITIONS
285; Variable declaration - defined here and used outside this module
286----------------------------------------------------------------------------*/
287/*--------------------------------------------------------------------------
288    Possible values for mod = {3,8,9,13,17}
289
290    There exists "empty" spaces in the table.  These can potentially
291    be utilized by other const tables, if available memory becomes an issue.
292---------------------------------------------------------------------------*/
293
294const Int div_mod[18] =   /*   mod   index  Q-format */
295{
296    /* ----------------------- */
297    0xCC,                 /* |      |  0  |          */
298    0xCC,                 /* |      |  1  |          */
299    0xCC,                 /* |      |  2  |          */
300    2731,                 /* |  3   |  3  |   13     */
301    0xCC,                 /* |      |  4  |          */
302    0xCC,                 /* |      |  5  |          */
303    0xCC,                 /* |      |  6  |          */
304    0xCC,                 /* |      |  7  |          */
305    1025,                 /* |  8   |  8  |   13     */
306    911,                 /* |  9   |  9  |   13     */
307    0xCC,                 /* |      | 10  |          */
308    0xCC,                 /* |      | 11  |          */
309    0xCC,                 /* |      | 12  |          */
310    631,                 /* |  13  | 13  |   13     */
311    0xCC,                 /* |      | 14  |          */
312    0xCC,                 /* |      | 15  |          */
313    0xCC,                 /* |      | 16  |          */
314    482,                 /* |  17  | 17  |   13     */
315};
316
317/*----------------------------------------------------------------------------
318; EXTERNAL FUNCTION REFERENCES
319; Declare functions defined elsewhere and referenced in this module
320----------------------------------------------------------------------------*/
321
322/*----------------------------------------------------------------------------
323; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
324; Declare variables used in this module but defined elsewhere
325----------------------------------------------------------------------------*/
326
327/*----------------------------------------------------------------------------
328; FUNCTION CODE
329----------------------------------------------------------------------------*/
330void unpack_idx(
331    Int16   quant_spec[],
332    Int codeword_indx,
333    const Hcb   *pHuffCodebook,
334    BITS  *pInputStream,
335    Int *max)
336{
337    Int16 *pQuantSpec = &quant_spec[0];
338    Int  temp_spec;
339
340    const Int mod = pHuffCodebook->mod;
341    const Int off = pHuffCodebook->off;
342
343    OSCL_UNUSED_ARG(pInputStream);
344
345
346    if (pHuffCodebook->dim == DIMENSION_4)
347    {
348        /* Calculate pQuantSpec[0] */
349
350        temp_spec      = (codeword_indx * DIV_3_CUBED) >> Q_FORMAT_MOD3;
351
352        codeword_indx -= temp_spec * THREE_CUBED;
353
354        temp_spec -= off;
355        *pQuantSpec++  = (Int16)temp_spec;
356
357        temp_spec = pv_abs(temp_spec);
358
359        if (temp_spec > *max)
360        {
361            *max = temp_spec;
362        }
363
364        /* Calculate pQuantSpec[1] */
365        temp_spec      = (codeword_indx * DIV_3_SQUARED) >> Q_FORMAT_MOD2;
366
367        codeword_indx -= temp_spec * THREE_SQUARED;
368
369        temp_spec -= off;
370        *pQuantSpec++  = (Int16)temp_spec;
371
372        temp_spec = pv_abs(temp_spec);
373
374        if (temp_spec > *max)
375        {
376            *max = temp_spec;
377        }
378    }
379
380    /*
381     *  Calculate pQuantSpec[2] if dim == 4
382     *  Calculate pQuantSpec[0] if dim == 2
383     */
384
385    temp_spec      = ((Int32) codeword_indx * div_mod[mod]) >> Q_FORMAT_MOD;
386
387    codeword_indx -= temp_spec * mod;
388
389    temp_spec -= off;
390    *pQuantSpec++  = (Int16)temp_spec;
391
392    temp_spec = pv_abs(temp_spec);
393
394
395    if (temp_spec > *max)
396    {
397        *max = temp_spec;
398    }
399
400    /*
401    *  Calculate pQuantSpec[3] if dim == 4
402    *  Calculate pQuantSpec[1] if dim == 2
403    */
404    codeword_indx -= off;
405    *pQuantSpec    = (Int16)codeword_indx ;
406
407
408    codeword_indx = pv_abs(codeword_indx);
409
410    if (codeword_indx > *max)
411    {
412        *max = codeword_indx;
413    }
414
415
416    return ;
417} /* unpack_idx */
418
419
420void unpack_idx_sgn(
421    Int16   quant_spec[],
422    Int codeword_indx,
423    const Hcb   *pHuffCodebook,
424    BITS  *pInputStream,
425    Int *max)
426{
427    Int16 *pQuantSpec = &quant_spec[0];
428    Int  temp_spec;
429    Int  sgn;
430
431    const Int mod = pHuffCodebook->mod;
432    const Int off = pHuffCodebook->off;
433
434
435
436    if (pHuffCodebook->dim == DIMENSION_4)
437    {
438        /* Calculate pQuantSpec[0] */
439        preload_cache((Int32 *)pQuantSpec);
440        temp_spec      = (codeword_indx * DIV_3_CUBED) >> Q_FORMAT_MOD3;
441
442        codeword_indx -= temp_spec * THREE_CUBED;
443
444        temp_spec -= off;
445        if (temp_spec)
446        {
447            sgn = get1bits(pInputStream);
448
449
450            *pQuantSpec++ = (Int16)((sgn) ? -temp_spec : temp_spec);
451
452            temp_spec = pv_abs(temp_spec);
453
454            if (temp_spec > *max)
455            {
456                *max = temp_spec;
457            }
458
459        }
460        else
461        {
462            *pQuantSpec++ = 0;
463        }
464
465        /* Calculate pQuantSpec[1] */
466        temp_spec      = (codeword_indx * DIV_3_SQUARED) >> Q_FORMAT_MOD2;
467
468        codeword_indx -= temp_spec * THREE_SQUARED;
469
470        temp_spec -= off;
471        if (temp_spec)
472        {
473
474            sgn = get1bits(pInputStream);
475
476            *pQuantSpec++ = (Int16)((sgn) ? -temp_spec : temp_spec);
477
478            temp_spec = pv_abs(temp_spec);
479
480            if (temp_spec > *max)
481            {
482                *max = temp_spec;
483            }
484        }
485        else
486        {
487            *pQuantSpec++ = 0;
488        }
489    }
490
491    /*
492     *  Calculate pQuantSpec[2] if dim == 4
493     *  Calculate pQuantSpec[0] if dim == 2
494     */
495
496    temp_spec      = ((Int32) codeword_indx * div_mod[mod]) >> Q_FORMAT_MOD;
497
498    codeword_indx -= temp_spec * mod;
499
500    temp_spec -= off;
501    if (temp_spec)
502    {
503
504        sgn = get1bits(pInputStream);
505
506        *pQuantSpec++ = (Int16)((sgn) ? -temp_spec : temp_spec);
507
508        temp_spec = pv_abs(temp_spec);
509
510        if (temp_spec > *max)
511        {
512            *max = temp_spec;
513        }
514    }
515    else
516    {
517        *pQuantSpec++ = 0;
518    }
519
520    /*
521     *  Calculate pQuantSpec[3] if dim == 4
522     *  Calculate pQuantSpec[1] if dim == 2
523     */
524    codeword_indx -= off;
525    if (codeword_indx)
526    {
527
528        sgn = get1bits(pInputStream);
529
530        *pQuantSpec = (Int16)((sgn) ? -codeword_indx : codeword_indx);
531
532        codeword_indx = pv_abs(codeword_indx);
533
534        if (codeword_indx > *max)
535        {
536            *max = codeword_indx;
537        }
538    }
539    else
540    {
541        *pQuantSpec = 0;
542    }
543
544    return ;
545} /* unpack_idx_sgn */
546
547
548void unpack_idx_esc(
549    Int16   quant_spec[],
550    Int codeword_indx,
551    const Hcb   *pHuffCodebook,
552    BITS  *pInputStream,
553    Int *max)
554{
555    Int  temp_spec;
556    Int  sgn1 = 0, sgn2 = 0;
557    Int N;
558    Int32 esc_seq;
559
560    const Int mod = pHuffCodebook->mod;
561    const Int off = pHuffCodebook->off;
562
563
564    temp_spec      = ((Int32) codeword_indx * div_mod[mod]) >> Q_FORMAT_MOD;
565
566    codeword_indx -= temp_spec * mod;
567
568    temp_spec -= off;
569    if (temp_spec)
570    {
571        sgn1 = get1bits(pInputStream);
572    }
573
574    codeword_indx -= off;
575    if (codeword_indx)
576    {
577        sgn2 = get1bits(pInputStream);
578    }
579
580
581    if ((temp_spec & LOWER_5_BITS_MASK) == 16)
582    {
583        N = 3;
584        do
585        {
586            N++;
587
588            esc_seq = get1bits(pInputStream);
589
590        }
591        while (esc_seq != 0);
592
593        esc_seq  = getbits(N, pInputStream);
594
595        esc_seq += (1 << N);
596
597
598        temp_spec = (Int)((temp_spec * esc_seq) >> 4);
599
600    }
601
602
603    if (sgn1)
604    {
605        quant_spec[0]  = (Int16)(-temp_spec);
606    }
607    else
608    {
609        quant_spec[0]  = (Int16)temp_spec;
610    }
611
612    temp_spec = pv_abs(temp_spec);
613
614    if (temp_spec > *max)
615    {
616        *max = temp_spec;
617    }
618
619    if ((codeword_indx & LOWER_5_BITS_MASK) == 16)
620    {
621        N = 3;
622        do
623        {
624            N++;
625
626            esc_seq = get1bits(pInputStream);
627
628        }
629        while (esc_seq != 0);
630
631        esc_seq  = getbits(N, pInputStream);
632
633        esc_seq += (1 << N);
634
635        codeword_indx = (Int)((codeword_indx * esc_seq) >> 4);
636    }
637
638
639
640
641    if (sgn2)
642    {
643        quant_spec[1]    = (Int16)(-codeword_indx);
644    }
645    else
646    {
647        quant_spec[1]    = (Int16)codeword_indx;
648    }
649
650
651    codeword_indx = pv_abs(codeword_indx);
652
653    if (codeword_indx > *max)
654    {
655        *max = codeword_indx;
656    }
657
658
659    return ;
660} /* unpack_idx_esc */
661