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: getmask.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               Replaced for-loop style memory initialization with memset()
30
31 Description: (1) Modified to bring code in-line with PV standard
32              (2) Removed multiple returns, Replaced multiple 'if's with
33                  switch
34
35 Description: (1) Modified per review comments
36              (2) increment pointer pMask after memset
37
38 Description: Make the maximum number of bits requested from getbits
39              become a constant.
40
41 Description: Typecast 1 to UInt32 for bitmask to avoid masking on a 16-bit
42              platform
43
44 Description: Replace some instances of getbits to get9_n_lessbits
45              when the number of bits read is 9 or less.
46
47 Who:                                   Date: MM/DD/YYYY
48 Description:
49
50------------------------------------------------------------------------------
51 INPUT AND OUTPUT DEFINITIONS
52
53 Inputs:
54        pFrameInfo  = pointer to structure that holds information for current
55                      frame, Type FrameInfo
56
57        pInputStream= pointer to structure that holds input stream information
58                      Type BITS
59
60        pGroup      = pointer to array that holds the stop window index for
61                      each group in current frame, Type Int
62
63        max_sfb     = number of active sfbs for each window, Type Int
64
65        mask[]      = array that holds the MS_mask information
66                      Type Int
67
68 Local Stores/Buffers/Pointers Needed:
69    None
70
71 Global Stores/Buffers/Pointers Needed:
72    None
73
74 Outputs:
75    mask_present = 0    (no Mid/Side mixed)
76                   2    (Mid/Side mixed present for entire frame)
77                   1    (Mid/Side mixed information read from bitstream)
78                   -1   (invalid mask_present read from bitstream)
79
80 Pointers and Buffers Modified:
81    pMask   contents replaced by MS information of each scalefactor band
82
83 Local Stores Modified:
84    None
85
86 Global Stores Modified:
87    None
88
89------------------------------------------------------------------------------
90 FUNCTION DESCRIPTION
91
92 This function reads the Mid/Side(MS) mask information from the input
93 bitstream. If the mask_present field is equal to 2, the mask bits is set to
94 1 for the entire frame. If mask_present has a value of 0, the function
95 returns 0, If mask_present is set to 1, the Mid/Side(MS) information is
96 read from the input stream. When mask_present is 3, an error code (-1) is
97 generated.
98 The Mid/Side(MS) information is later used for mixing the left and right
99 channel sounds. Each scalefactor band has its own MS information.
100
101 (ISO comments: read a synthesis mask,  read a synthesis mask uses
102                EXTENDED_MS_MASK and grouped mask )
103
104------------------------------------------------------------------------------
105 REQUIREMENTS
106
107 This function shall replace the contents of pMask with the MS information
108 of each scalefactor band
109
110------------------------------------------------------------------------------
111 REFERENCES
112
113 (1) MPEG-2 NBC Audio Decoder
114   "This software module was originally developed by AT&T, Dolby
115   Laboratories, Fraunhofer Gesellschaft IIS in the course of development
116   of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
117   3. This software module is an implementation of a part of one or more
118   MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
119   Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audio
120   standards free license to this software module or modifications thereof
121   for use in hardware or software products claiming conformance to the
122   MPEG-2 NBC/MPEG-4 Audio  standards. Those intending to use this software
123   module in hardware or software products are advised that this use may
124   infringe existing patents. The original developer of this software
125   module and his/her company, the subsequent editors and their companies,
126   and ISO/IEC have no liability for use of this software module or
127   modifications thereof in an implementation. Copyright is not released
128   for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
129   developer retains full right to use the code for his/her own purpose,
130   assign or donate the code to a third party and to inhibit third party
131   from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
132   This copyright notice must be included in all copies or derivative
133   works."
134   Copyright(c)1996.
135
136 (2) ISO/IEC 14496-3: 1999(E)
137    Subpart 4
138                    p15     (Table 4.4.5    getmask)
139
140------------------------------------------------------------------------------
141 PSEUDO-CODE
142
143    CALL getbits(LEN_MASK_PRES, pInputStream)
144    MODIFYING (pInputStream)
145    RETURNING (mask present information)
146    mask_present = mask present information
147
148    SWITCH (mask_present)
149
150        CASE (0):
151            BREAK;
152
153        CASE (2):
154            nwin = pFrameInfo->num_win;
155            FOR(win = 0; win < nwin; win = *(pGroup++))
156
157                FOR(sfb = pFrameInfo->sfb_per_win[win]; sfb > 0; sfb--)
158                    *(pMask++) = 1;
159                ENDFOR
160
161            ENDFOR
162
163            BREAK;
164
165        CASE(1):
166
167            nwin = pFrameInfo->num_win;
168
169                nToDo = max_sfb;
170
171                WHILE (nToDo > 0)
172                    nCall = nToDo;
173
174                    IF (nCall > MAX_GETBITS)
175                    THEN
176                        nCall = MAX_GETBITS;
177                    ENDIF
178
179                    tempMask =
180                        getbits(
181                            nCall,
182                            pInputStream);
183
184                    bitmask = 1 << (nCall - 1);
185                    FOR (sfb = nCall; sfb > 0; sfb--)
186                       *(pMask++) = (tempMask & bitmask) >> (sfb - 1);
187                        bitmask >>= 1;
188                    ENDFOR
189
190                    nToDo -= nCall;
191                END WHILE
192
193                pv_memset(
194                    pMask,
195                    0,
196                    (pFrameInfo->sfb_per_win[win]-max_sfb)*sizeof(*pMask));
197
198            ENDFOR (win)
199
200            BREAK
201
202        DEFAULT:
203            mask_present = -1
204
205    ENDSWITCH
206
207    RETURN  mask_present
208
209------------------------------------------------------------------------------
210*/
211
212
213/*----------------------------------------------------------------------------
214; INCLUDES
215----------------------------------------------------------------------------*/
216#include    "pv_audio_type_defs.h"
217#include    "huffman.h"
218#include    "aac_mem_funcs.h"
219#include    "e_maskstatus.h"
220
221/*----------------------------------------------------------------------------
222; MACROS
223; Define module specific macros here
224----------------------------------------------------------------------------*/
225
226/*----------------------------------------------------------------------------
227; DEFINES
228; Include all pre-processor statements here. Include conditional
229; compile variables also.
230----------------------------------------------------------------------------*/
231
232/*----------------------------------------------------------------------------
233; LOCAL FUNCTION DEFINITIONS
234; Function Prototype declaration
235----------------------------------------------------------------------------*/
236
237/*----------------------------------------------------------------------------
238; LOCAL STORE/BUFFER/POINTER DEFINITIONS
239; Variable declaration - defined here and used outside this module
240----------------------------------------------------------------------------*/
241
242/*----------------------------------------------------------------------------
243; EXTERNAL FUNCTION REFERENCES
244; Declare functions defined elsewhere and referenced in this module
245----------------------------------------------------------------------------*/
246
247/*----------------------------------------------------------------------------
248; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
249; Declare variables used in this module but defined elsewhere
250----------------------------------------------------------------------------*/
251
252/*----------------------------------------------------------------------------
253; FUNCTION CODE
254----------------------------------------------------------------------------*/
255Int getmask(
256    FrameInfo   *pFrameInfo,
257    BITS        *pInputStream,
258    Int         group[],
259    Int         max_sfb,
260    Int         mask[])
261{
262
263    Int     win; /* window index */
264    Int     sfb;
265    Int     mask_present;
266    Int    *pMask;
267    Int    *pGroup;
268    Int     nwin;
269    Int     nCall;
270    Int     nToDo;
271    UInt32  tempMask;
272    UInt32  bitmask;
273
274    pMask  = mask;
275    pGroup = group;
276
277    mask_present =
278        get9_n_lessbits(
279            LEN_MASK_PRES,
280            pInputStream);
281
282    switch (mask_present)
283    {
284        case(MASK_NOT_PRESENT):
285            /* special EXTENDED_MS_MASK cases */
286            /* no ms at all */
287            break;
288
289        case(MASK_ALL_FRAME):
290            /* MS for whole spectrum on, mask bits set to 1 */
291            nwin = pFrameInfo->num_win;
292            for (win = 0; win < nwin; win = *(pGroup++))
293            {
294                for (sfb = pFrameInfo->sfb_per_win[win]; sfb > 0; sfb--)
295                {
296                    *(pMask++) = 1; /* cannot use memset for Int type */
297                }
298
299            }
300
301            break;
302
303        case(MASK_FROM_BITSTREAM):
304            /* MS_mask_present==1, get mask information*/
305            nwin = pFrameInfo->num_win;
306            for (win = 0; win < nwin; win = *(pGroup++))
307            {
308                /*
309                 * the following code is equivalent to
310                 *
311                 * for(sfb = max_sfb; sfb > 0; sfb--)
312                 * {
313                 *   *(pMask++) =
314                 *       getbits(
315                 *           LEN_MASK,
316                 *           pInputStream);
317                 * }
318                 *
319                 * in order to save the calls to getbits, the above
320                 * for-loop is broken into two parts
321                 */
322
323                nToDo = max_sfb;
324
325                while (nToDo > 0)
326                {
327                    nCall = nToDo;
328
329                    if (nCall > MAX_GETBITS)
330                    {
331                        nCall = MAX_GETBITS;
332                    }
333
334                    tempMask =
335                        getbits(
336                            nCall,
337                            pInputStream);
338
339                    bitmask = (UInt32) 1 << (nCall - 1);
340                    for (sfb = nCall; sfb > 0; sfb--)
341                    {
342                        *(pMask++) = (Int)((tempMask & bitmask) >> (sfb - 1));
343                        bitmask >>= 1;
344                    }
345
346                    nToDo -= nCall;
347                }
348
349                /*
350                 * set remaining sfbs to zero
351                 * re-use nCall to save one variable on stack
352                 */
353
354                nCall = pFrameInfo->sfb_per_win[win] - max_sfb;
355
356
357                if (nCall >= 0)
358                {
359                    pv_memset(pMask,
360                              0,
361                              nCall*sizeof(*pMask));
362
363                    pMask += nCall;
364                }
365                else
366                {
367                    mask_present = MASK_ERROR;
368                    break;
369                }
370
371
372            } /* for (win) */
373
374            break;
375
376        default:
377            /* error */
378            break;
379
380    } /* switch (mask_present) */
381
382    return mask_present;
383
384} /* getmask */
385