1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5© Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
6  All rights reserved.
7
8 1.    INTRODUCTION
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and the date of any change. For modified versions of the FDK AAC Codec, the term
50"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-info@iis.fraunhofer.de
82----------------------------------------------------------------------------------------------------------- */
83
84/***************************  Fraunhofer IIS FDK Tools  ***********************
85
86   Author(s):   M. Lohwasser
87   Description: common bitbuffer read/write routines
88
89******************************************************************************/
90
91#include "FDK_bitbuffer.h"
92
93
94
95
96#include "genericStds.h"
97#include "common_fix.h"
98#include "fixminmax.h"
99
100const UINT BitMask [32+1] =
101{
102         0x0,        0x1,        0x3,        0x7,
103         0xf,       0x1f,       0x3f,       0x7f,
104        0xff,      0x1ff,      0x3ff,      0x7ff,
105       0xfff,     0x1fff,     0x3fff,     0x7fff,
106      0xffff,    0x1ffff,    0x3ffff,    0x7ffff,
107     0xfffff,   0x1fffff,   0x3fffff,   0x7fffff,
108    0xffffff,  0x1ffffff,  0x3ffffff,  0x7ffffff,
109   0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
110  0xffffffff
111};
112
113const UINT *const RESTRICT pBitMask = BitMask;
114
115void FDK_CreateBitBuffer (HANDLE_FDK_BITBUF *hBitBuf, UCHAR *pBuffer,
116                          UINT bufSize)
117{
118   FDK_InitBitBuffer (*hBitBuf, pBuffer, bufSize, 0);
119
120   FDKmemclear((*hBitBuf)->Buffer, bufSize*sizeof(UCHAR));
121}
122
123void FDK_DeleteBitBuffer (HANDLE_FDK_BITBUF hBitBuf) { ; }
124
125void FDK_InitBitBuffer (HANDLE_FDK_BITBUF hBitBuf, UCHAR *pBuffer,
126                        UINT bufSize, UINT validBits)
127{
128   hBitBuf->ValidBits   = validBits ;
129   hBitBuf->ReadOffset  = 0 ;
130   hBitBuf->WriteOffset = 0 ;
131   hBitBuf->BitCnt      = 0 ;
132   hBitBuf->BitNdx      = 0 ;
133
134   hBitBuf->Buffer      = pBuffer ;
135   hBitBuf->bufSize     = bufSize ;
136   hBitBuf->bufBits     = (bufSize << 3) ;
137#if defined(FDK_DEBUG) || defined(DEBUG)
138   /*assure bufsize (2^n) */
139   if (bufSize!=0) {
140     UINT x = 0, n=bufSize;
141     for (x=0; n>0; x++,n>>=1) {}
142     if ( bufSize != (1<<(x-1)) ) {
143       FDKprintfErr("Error: bufSizein FDK_InitBitBuffer() != (2^n), %d\n", bufSize);
144     }
145   }
146#endif
147}
148
149void FDK_ResetBitBuffer ( HANDLE_FDK_BITBUF hBitBuf )
150{
151   hBitBuf->ValidBits   = 0 ;
152   hBitBuf->ReadOffset  = 0 ;
153   hBitBuf->WriteOffset = 0 ;
154   hBitBuf->BitCnt      = 0 ;
155   hBitBuf->BitNdx      = 0 ;
156}
157
158INT  FDK_get (HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits)
159{
160  UINT byteOffset = hBitBuf->BitNdx >> 3 ;
161  UINT bitOffset  = hBitBuf->BitNdx & 0x07 ;
162
163  hBitBuf->BitNdx     = (hBitBuf->BitNdx + numberOfBits) & (hBitBuf->bufBits - 1) ;
164  hBitBuf->BitCnt    +=  numberOfBits ;
165  hBitBuf->ValidBits -=  numberOfBits ;
166
167  UINT byteMask = hBitBuf->bufSize - 1 ;
168
169  UINT tx = (hBitBuf->Buffer [ byteOffset    & byteMask] << 24) |
170            (hBitBuf->Buffer [(byteOffset+1) & byteMask] << 16) |
171            (hBitBuf->Buffer [(byteOffset+2) & byteMask] <<  8) |
172             hBitBuf->Buffer [(byteOffset+3) & byteMask];
173
174  if (bitOffset)
175  {
176    tx <<= bitOffset;
177    tx |= hBitBuf->Buffer [(byteOffset+4) & byteMask] >> (8-bitOffset);
178  }
179
180  return (tx >> (32 - numberOfBits)) ;
181}
182
183INT FDK_get32 (HANDLE_FDK_BITBUF hBitBuf)
184{
185  UINT BitNdx = hBitBuf->BitNdx + 32;
186  if (BitNdx <= hBitBuf->bufBits)
187  {
188    hBitBuf->BitNdx = BitNdx;
189    hBitBuf->BitCnt +=  32;
190    hBitBuf->ValidBits -= 32;
191
192    UINT byteOffset = (BitNdx-1) >> 3;
193    UINT cache = (hBitBuf->Buffer[(byteOffset-3)] << 24) |
194                 (hBitBuf->Buffer[(byteOffset-2)] << 16) |
195                 (hBitBuf->Buffer[(byteOffset-1)] <<  8) |
196                  hBitBuf->Buffer[(byteOffset-0)];
197
198    if ( (BitNdx = (BitNdx&7)) != 0 ) {
199      cache = (cache >> (8-BitNdx)) | ((UINT)hBitBuf->Buffer [byteOffset-4] << (24+BitNdx));
200    }
201    return (cache) ;
202  }
203  else
204  {
205    /* exotic path, used only at the end of the buffer, when wrapping around */
206    int nBits = (INT)hBitBuf->bufBits-(INT)hBitBuf->BitNdx;
207
208    UINT cache = FDK_get (hBitBuf,nBits)<< (32-nBits);
209    cache |= (FDK_get (hBitBuf,32-nBits));
210    return (cache);
211  }
212}
213
214INT FDK_getBwd (HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits)
215{
216  UINT byteOffset = hBitBuf->BitNdx >> 3 ;
217  UINT bitOffset  = hBitBuf->BitNdx & 0x07 ;
218  UINT byteMask   = hBitBuf->bufSize - 1 ;
219  int i;
220
221  hBitBuf->BitNdx     = (hBitBuf->BitNdx - numberOfBits) & (hBitBuf->bufBits - 1) ;
222  hBitBuf->BitCnt    -=  numberOfBits ;
223  hBitBuf->ValidBits +=  numberOfBits ;
224
225  UINT tx = hBitBuf->Buffer [(byteOffset-3) & byteMask] << 24 |
226            hBitBuf->Buffer [(byteOffset-2) & byteMask] << 16 |
227            hBitBuf->Buffer [(byteOffset-1) & byteMask] <<  8 |
228            hBitBuf->Buffer [ byteOffset    & byteMask] ;
229  UINT txa = 0x0;
230
231  tx >>= (8 - bitOffset) ;
232
233  if (bitOffset && numberOfBits > 24)
234  {
235    tx |= hBitBuf->Buffer [(byteOffset-4) & byteMask] << (24 + bitOffset) ;
236  }
237
238  /* in place turn around */
239  for (i = 0; i < 16; i++) {
240    UINT bitMaskR = 0x00000001 << i;
241    UINT bitMaskL = 0x80000000 >> i;
242
243    txa |= (tx & bitMaskR) << (31 - (i<<1));
244    txa |= (tx & bitMaskL) >> (31 - (i<<1));
245  }
246
247  return (txa >> (32 - numberOfBits)) ;
248}
249
250void FDK_put (HANDLE_FDK_BITBUF hBitBuf, UINT value, const UINT numberOfBits)
251{
252  UINT byteOffset = hBitBuf->BitNdx >> 3 ;
253  UINT bitOffset  = hBitBuf->BitNdx & 0x07 ;
254
255  hBitBuf->BitNdx     = (hBitBuf->BitNdx + numberOfBits) & (hBitBuf->bufBits - 1) ;
256  hBitBuf->BitCnt    +=  numberOfBits ;
257  hBitBuf->ValidBits +=  numberOfBits ;
258
259  UINT byteMask = hBitBuf->bufSize - 1 ;
260
261  UINT tmp  = value<<(32-numberOfBits)>>bitOffset;
262  UINT mask = ~BitMask[(32-bitOffset)] | (BitMask [(32-numberOfBits)] >> bitOffset) ;
263
264  hBitBuf->Buffer [ byteOffset    & byteMask]  = (hBitBuf->Buffer [ byteOffset    & byteMask]&(mask>>24)) | (UCHAR)(tmp>>24);
265  hBitBuf->Buffer [(byteOffset+1) & byteMask]  = (hBitBuf->Buffer [(byteOffset+1) & byteMask]&(mask>>16)) | (UCHAR)(tmp>>16);
266  hBitBuf->Buffer [(byteOffset+2) & byteMask]  = (hBitBuf->Buffer [(byteOffset+2) & byteMask]&(mask>>8))  | (UCHAR)(tmp>>8);
267  hBitBuf->Buffer [(byteOffset+3) & byteMask]  = (hBitBuf->Buffer [(byteOffset+3) & byteMask]&(mask))     | (UCHAR)(tmp);
268
269  if (bitOffset && numberOfBits > 24)
270  {
271    hBitBuf->Buffer [(byteOffset+4) & byteMask]  = (UCHAR)(value<<(40-numberOfBits)>>bitOffset) |
272               ( hBitBuf->Buffer [(byteOffset+4) & byteMask] & BitMask[(40-numberOfBits-bitOffset)] ) ;
273  }
274}
275
276void FDK_putBwd (HANDLE_FDK_BITBUF hBitBuf, UINT value, const UINT numberOfBits)
277{
278  UINT byteOffset = hBitBuf->BitNdx >> 3 ;
279  UINT bitOffset  = 7 - (hBitBuf->BitNdx & 0x07) ;
280  UINT byteMask   = hBitBuf->bufSize - 1 ;
281
282  UINT mask = ~(BitMask[numberOfBits] << bitOffset) ;
283  UINT tmp = 0x0000;
284  int  i;
285
286  hBitBuf->BitNdx     = (hBitBuf->BitNdx - numberOfBits) & (hBitBuf->bufBits - 1) ;
287  hBitBuf->BitCnt    -=  numberOfBits ;
288  hBitBuf->ValidBits -=  numberOfBits ;
289
290  /* in place turn around */
291  for (i = 0; i < 16; i++) {
292    UINT bitMaskR = 0x00000001 << i;
293    UINT bitMaskL = 0x80000000 >> i;
294
295    tmp |= (value & bitMaskR) << (31 - (i<<1));
296    tmp |= (value & bitMaskL) >> (31 - (i<<1));
297  }
298  value = tmp;
299  tmp   = value>>(32-numberOfBits)<<bitOffset;
300
301  hBitBuf->Buffer [ byteOffset    & byteMask]  = (hBitBuf->Buffer [ byteOffset    & byteMask]&(mask))     | (UCHAR)(tmp);
302  hBitBuf->Buffer [(byteOffset-1) & byteMask]  = (hBitBuf->Buffer [(byteOffset-1) & byteMask]&(mask>>8))  | (UCHAR)(tmp>>8);
303  hBitBuf->Buffer [(byteOffset-2) & byteMask]  = (hBitBuf->Buffer [(byteOffset-2) & byteMask]&(mask>>16)) | (UCHAR)(tmp>>16);
304  hBitBuf->Buffer [(byteOffset-3) & byteMask]  = (hBitBuf->Buffer [(byteOffset-3) & byteMask]&(mask>>24)) | (UCHAR)(tmp>>24);
305
306  if ((bitOffset + numberOfBits) > 32)
307  {
308    hBitBuf->Buffer [(byteOffset-4) & byteMask]  = (UCHAR)(value>>(64-numberOfBits-bitOffset)) |
309               ( hBitBuf->Buffer [(byteOffset-4) & byteMask] & ~(BitMask[bitOffset] >> (32-numberOfBits)) ) ;
310  }
311}
312
313
314void FDK_pushBack (HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits, UCHAR config)
315{
316  hBitBuf->BitCnt    -= numberOfBits ;
317  hBitBuf->ValidBits += (config==0) ? numberOfBits : (-(INT)numberOfBits) ;
318  hBitBuf->BitNdx     = (hBitBuf->BitNdx - numberOfBits) & (hBitBuf->bufBits - 1) ;
319}
320
321void FDK_pushForward (HANDLE_FDK_BITBUF hBitBuf, const UINT numberOfBits, UCHAR config)
322{
323  hBitBuf->BitCnt    += numberOfBits ;
324  hBitBuf->ValidBits -= (config==0) ? numberOfBits : (-(INT)numberOfBits) ;
325  hBitBuf->BitNdx     = (hBitBuf->BitNdx + numberOfBits) & (hBitBuf->bufBits - 1) ;
326}
327
328
329void FDK_byteAlign (HANDLE_FDK_BITBUF hBitBuf, UCHAR config)
330{
331  INT alignment = hBitBuf->BitCnt & 0x07 ;
332
333  if (alignment)
334  {
335    if (config==0)
336      FDK_pushForward (hBitBuf, 8 - alignment, config) ; /* BS_READER */
337    else
338      FDK_put (hBitBuf,0 , 8 - alignment) ;              /* BS_WRITER */
339  }
340
341  hBitBuf->BitCnt = 0 ;
342}
343
344UINT FDK_getValidBits (HANDLE_FDK_BITBUF hBitBuf)
345{
346    return hBitBuf->ValidBits;
347}
348
349INT FDK_getFreeBits (HANDLE_FDK_BITBUF hBitBuf)
350{
351    return (hBitBuf->bufBits - hBitBuf->ValidBits) ;
352}
353
354void FDK_setBitCnt (HANDLE_FDK_BITBUF hBitBuf, const UINT value)
355{
356  hBitBuf->BitCnt = value ;
357}
358
359INT FDK_getBitCnt (HANDLE_FDK_BITBUF hBitBuf)
360{
361  return hBitBuf->BitCnt ;
362}
363
364void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf,
365              UCHAR            *RESTRICT inputBuffer,
366              const UINT        bufferSize,
367              UINT             *bytesValid)
368{
369  inputBuffer = &inputBuffer [bufferSize - *bytesValid] ;
370
371  UINT bTotal = 0 ;
372
373  UINT bToRead   = (hBitBuf->bufBits - hBitBuf->ValidBits) >> 3 ;
374  UINT noOfBytes = fMin(bToRead, *bytesValid); //(bToRead < *bytesValid) ? bToRead : *bytesValid ;
375
376  while (noOfBytes > 0)
377  {
378    /* split read to buffer size */
379    bToRead = hBitBuf->bufSize - hBitBuf->ReadOffset ;
380    bToRead = fMin(bToRead, noOfBytes); //(bToRead < noOfBytes) ? bToRead : noOfBytes ;
381
382    /* copy 'bToRead' bytes from 'ptr' to inputbuffer */
383    FDKmemcpy(&hBitBuf->Buffer[hBitBuf->ReadOffset], inputBuffer, bToRead*sizeof(UCHAR));
384
385    /* add noOfBits to number of valid bits in buffer */
386    hBitBuf->ValidBits  += bToRead << 3 ;
387    bTotal       += bToRead ;
388    inputBuffer  += bToRead ;
389
390    hBitBuf->ReadOffset  = (hBitBuf->ReadOffset + bToRead) & (hBitBuf->bufSize - 1) ;
391    noOfBytes    -= bToRead ;
392  }
393
394  *bytesValid -= bTotal ;
395}
396
397void CopyAlignedBlock (HANDLE_FDK_BITBUF h_BitBufSrc, UCHAR *RESTRICT dstBuffer, UINT bToRead)
398{
399  UINT byteOffset = h_BitBufSrc->BitNdx >> 3 ;
400  const UINT byteMask = h_BitBufSrc->bufSize - 1 ;
401
402  UCHAR *RESTRICT pBBB = h_BitBufSrc->Buffer;
403  for (UINT i = 0 ; i < bToRead ; i++)
404  {
405    dstBuffer[i] = pBBB[(byteOffset+i) & byteMask] ;
406  }
407
408  bToRead <<= 3 ;
409
410  h_BitBufSrc->BitNdx = (h_BitBufSrc->BitNdx + bToRead) & (h_BitBufSrc->bufBits - 1) ;
411  h_BitBufSrc->BitCnt += bToRead ;
412  h_BitBufSrc->ValidBits -= bToRead ;
413}
414
415void FDK_Copy (HANDLE_FDK_BITBUF h_BitBufDst, HANDLE_FDK_BITBUF h_BitBufSrc, UINT *bytesValid)
416{
417  INT bTotal = 0;
418
419  /* limit noOfBytes to valid bytes in src buffer and available bytes in dst buffer */
420  UINT bToRead   = h_BitBufSrc->ValidBits >> 3 ;
421  UINT noOfBytes = fMin(bToRead, *bytesValid); //(*bytesValid < bToRead) ? *bytesValid : bToRead ;
422  bToRead   = FDK_getFreeBits(h_BitBufDst);
423  noOfBytes = fMin(bToRead, noOfBytes); //(bToRead < noOfBytes) ? bToRead : noOfBytes;
424
425  while (noOfBytes > 0)
426  {
427    /* Split Read to buffer size */
428    bToRead = h_BitBufDst->bufSize - h_BitBufDst->ReadOffset ;
429    bToRead = fMin(noOfBytes, bToRead); //(noOfBytes < bToRead) ? noOfBytes : bToRead ;
430
431    /* copy 'bToRead' bytes from buffer to buffer */
432    if (!(h_BitBufSrc->BitNdx & 0x07)) {
433      CopyAlignedBlock (h_BitBufSrc, h_BitBufDst->Buffer + h_BitBufDst->ReadOffset, bToRead) ;
434    } else {
435      for (UINT i = 0; i < bToRead; i++)
436      {
437        h_BitBufDst->Buffer [h_BitBufDst->ReadOffset + i] = (UCHAR)FDK_get(h_BitBufSrc,8);
438      }
439    }
440
441    /* add noOfBits to number of valid bits in buffer */
442    h_BitBufDst->ValidBits  += bToRead << 3 ;
443    bTotal       += bToRead;
444
445    h_BitBufDst->ReadOffset  = (h_BitBufDst->ReadOffset + bToRead) & (h_BitBufDst->bufSize-1);
446    noOfBytes    -= bToRead;
447  }
448
449  *bytesValid -=bTotal;
450}
451
452void FDK_Fetch (HANDLE_FDK_BITBUF hBitBuf, UCHAR *outBuf, UINT *writeBytes)
453{
454  UCHAR *RESTRICT outputBuffer = outBuf;
455  UINT bTotal = 0 ;
456
457  UINT bToWrite  = (hBitBuf->ValidBits) >> 3 ;
458  UINT noOfBytes = fMin(bToWrite, *writeBytes); //(bToWrite < *writeBytes) ? bToWrite : *writeBytes ;
459
460  while (noOfBytes > 0)
461  {
462    /* split write to buffer size */
463    bToWrite = hBitBuf->bufSize - hBitBuf->WriteOffset ;
464    bToWrite = fMin(bToWrite, noOfBytes); //(bToWrite < noOfBytes) ? bToWrite : noOfBytes ;
465
466    /* copy 'bToWrite' bytes from bitbuffer to outputbuffer */
467    FDKmemcpy(outputBuffer, &hBitBuf->Buffer[hBitBuf->WriteOffset], bToWrite*sizeof(UCHAR));
468
469    /* sub noOfBits from number of valid bits in buffer */
470    hBitBuf->ValidBits  -= bToWrite << 3 ;
471    bTotal       += bToWrite ;
472    outputBuffer += bToWrite ;
473
474    hBitBuf->WriteOffset  = (hBitBuf->WriteOffset + bToWrite) & (hBitBuf->bufSize - 1) ;
475    noOfBytes    -= bToWrite ;
476  }
477
478  *writeBytes = bTotal ;
479}
480
481