1b815c7f3Sopenharmony_ci/* 2b815c7f3Sopenharmony_ci * Copyright (c) 2011 Apple Inc. All rights reserved. 3b815c7f3Sopenharmony_ci * Copyright (C) 2013-2014 Erik de Castro Lopo <erikd@mega-nerd.com> 4b815c7f3Sopenharmony_ci * 5b815c7f3Sopenharmony_ci * @APPLE_APACHE_LICENSE_HEADER_START@ 6b815c7f3Sopenharmony_ci * 7b815c7f3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License") ; 8b815c7f3Sopenharmony_ci * you may not use this file except in compliance with the License. 9b815c7f3Sopenharmony_ci * You may obtain a copy of the License at 10b815c7f3Sopenharmony_ci * 11b815c7f3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12b815c7f3Sopenharmony_ci * 13b815c7f3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14b815c7f3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15b815c7f3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16b815c7f3Sopenharmony_ci * See the License for the specific language governing permissions and 17b815c7f3Sopenharmony_ci * limitations under the License. 18b815c7f3Sopenharmony_ci * 19b815c7f3Sopenharmony_ci * @APPLE_APACHE_LICENSE_HEADER_END@ 20b815c7f3Sopenharmony_ci */ 21b815c7f3Sopenharmony_ci 22b815c7f3Sopenharmony_ci/* 23b815c7f3Sopenharmony_ci File: ag_enc.c 24b815c7f3Sopenharmony_ci 25b815c7f3Sopenharmony_ci Contains: Adaptive Golomb encode routines. 26b815c7f3Sopenharmony_ci 27b815c7f3Sopenharmony_ci Copyright: (c) 2001-2011 Apple, Inc. 28b815c7f3Sopenharmony_ci*/ 29b815c7f3Sopenharmony_ci 30b815c7f3Sopenharmony_ci#include "aglib.h" 31b815c7f3Sopenharmony_ci#include "ALACBitUtilities.h" 32b815c7f3Sopenharmony_ci#include "EndianPortable.h" 33b815c7f3Sopenharmony_ci#include "ALACAudioTypes.h" 34b815c7f3Sopenharmony_ci 35b815c7f3Sopenharmony_ci#include <math.h> 36b815c7f3Sopenharmony_ci#include <stdio.h> 37b815c7f3Sopenharmony_ci#include <stdlib.h> 38b815c7f3Sopenharmony_ci#include <string.h> 39b815c7f3Sopenharmony_ci 40b815c7f3Sopenharmony_ci#define CODE_TO_LONG_MAXBITS 32 41b815c7f3Sopenharmony_ci#define N_MAX_MEAN_CLAMP 0xffff 42b815c7f3Sopenharmony_ci#define N_MEAN_CLAMP_VAL 0xffff 43b815c7f3Sopenharmony_ci#define REPORT_VAL 40 44b815c7f3Sopenharmony_ci 45b815c7f3Sopenharmony_ci#if __GNUC__ 46b815c7f3Sopenharmony_ci#define ALWAYS_INLINE __attribute__ ((always_inline)) 47b815c7f3Sopenharmony_ci#elif defined _MSC_VER 48b815c7f3Sopenharmony_ci#define ALWAYS_INLINE __forceinline 49b815c7f3Sopenharmony_ci#else 50b815c7f3Sopenharmony_ci#define ALWAYS_INLINE 51b815c7f3Sopenharmony_ci#endif 52b815c7f3Sopenharmony_ci 53b815c7f3Sopenharmony_ci 54b815c7f3Sopenharmony_ci/* And on the subject of the CodeWarrior x86 compiler and inlining, I reworked a lot of this 55b815c7f3Sopenharmony_ci to help the compiler out. In many cases this required manual inlining or a macro. Sorry 56b815c7f3Sopenharmony_ci if it is ugly but the performance gains are well worth it. 57b815c7f3Sopenharmony_ci - WSK 5/19/04 58b815c7f3Sopenharmony_ci*/ 59b815c7f3Sopenharmony_ci 60b815c7f3Sopenharmony_ci// note: implementing this with some kind of "count leading zeros" assembly is a big performance win 61b815c7f3Sopenharmony_cistatic inline int32_t lead (int32_t m) 62b815c7f3Sopenharmony_ci{ 63b815c7f3Sopenharmony_ci long j ; 64b815c7f3Sopenharmony_ci unsigned long c = (1ul << 31) ; 65b815c7f3Sopenharmony_ci 66b815c7f3Sopenharmony_ci for (j = 0 ; j < 32 ; j++) 67b815c7f3Sopenharmony_ci { 68b815c7f3Sopenharmony_ci if ((c & m) != 0) 69b815c7f3Sopenharmony_ci break ; 70b815c7f3Sopenharmony_ci c >>= 1 ; 71b815c7f3Sopenharmony_ci } 72b815c7f3Sopenharmony_ci return j ; 73b815c7f3Sopenharmony_ci} 74b815c7f3Sopenharmony_ci 75b815c7f3Sopenharmony_ci#define arithmin (a, b) ((a) < (b) ? (a) : (b)) 76b815c7f3Sopenharmony_ci 77b815c7f3Sopenharmony_cistatic inline int32_t ALWAYS_INLINE lg3a (int32_t x) 78b815c7f3Sopenharmony_ci{ 79b815c7f3Sopenharmony_ci int32_t result ; 80b815c7f3Sopenharmony_ci 81b815c7f3Sopenharmony_ci x += 3 ; 82b815c7f3Sopenharmony_ci result = lead (x) ; 83b815c7f3Sopenharmony_ci 84b815c7f3Sopenharmony_ci return 31 - result ; 85b815c7f3Sopenharmony_ci} 86b815c7f3Sopenharmony_ci 87b815c7f3Sopenharmony_cistatic inline int32_t ALWAYS_INLINE abs_func (int32_t a) 88b815c7f3Sopenharmony_ci{ 89b815c7f3Sopenharmony_ci // note: the CW PPC intrinsic __abs () turns into these instructions so no need to try and use it 90b815c7f3Sopenharmony_ci int32_t isneg = a >> 31 ; 91b815c7f3Sopenharmony_ci int32_t xorval = a ^ isneg ; 92b815c7f3Sopenharmony_ci int32_t result = xorval-isneg ; 93b815c7f3Sopenharmony_ci 94b815c7f3Sopenharmony_ci return result ; 95b815c7f3Sopenharmony_ci} 96b815c7f3Sopenharmony_ci 97b815c7f3Sopenharmony_ci#if PRAGMA_MARK 98b815c7f3Sopenharmony_ci#pragma mark - 99b815c7f3Sopenharmony_ci#endif 100b815c7f3Sopenharmony_ci 101b815c7f3Sopenharmony_cistatic inline int32_t dyn_code (int32_t m, int32_t k, int32_t n, uint32_t *outNumBits) 102b815c7f3Sopenharmony_ci{ 103b815c7f3Sopenharmony_ci uint32_t divx, mod, de ; 104b815c7f3Sopenharmony_ci uint32_t numBits ; 105b815c7f3Sopenharmony_ci uint32_t value ; 106b815c7f3Sopenharmony_ci 107b815c7f3Sopenharmony_ci // Assert (n >= 0) ; 108b815c7f3Sopenharmony_ci 109b815c7f3Sopenharmony_ci divx = n / m ; 110b815c7f3Sopenharmony_ci 111b815c7f3Sopenharmony_ci if (divx >= MAX_PREFIX_16) 112b815c7f3Sopenharmony_ci { 113b815c7f3Sopenharmony_ci numBits = MAX_PREFIX_16 + MAX_DATATYPE_BITS_16 ; 114b815c7f3Sopenharmony_ci value = (((1 << MAX_PREFIX_16) - 1) << MAX_DATATYPE_BITS_16) + n ; 115b815c7f3Sopenharmony_ci } 116b815c7f3Sopenharmony_ci else 117b815c7f3Sopenharmony_ci { 118b815c7f3Sopenharmony_ci mod = n%m ; 119b815c7f3Sopenharmony_ci de = (mod == 0) ; 120b815c7f3Sopenharmony_ci numBits = divx + k + 1 - de ; 121b815c7f3Sopenharmony_ci value = (((1 << divx) - 1) << (numBits - divx)) + mod + 1 - de ; 122b815c7f3Sopenharmony_ci 123b815c7f3Sopenharmony_ci // if coding this way is bigger than doing escape, then do escape 124b815c7f3Sopenharmony_ci if (numBits > MAX_PREFIX_16 + MAX_DATATYPE_BITS_16) 125b815c7f3Sopenharmony_ci { 126b815c7f3Sopenharmony_ci numBits = MAX_PREFIX_16 + MAX_DATATYPE_BITS_16 ; 127b815c7f3Sopenharmony_ci value = (((1 << MAX_PREFIX_16) - 1) << MAX_DATATYPE_BITS_16) + n ; 128b815c7f3Sopenharmony_ci } 129b815c7f3Sopenharmony_ci } 130b815c7f3Sopenharmony_ci 131b815c7f3Sopenharmony_ci *outNumBits = numBits ; 132b815c7f3Sopenharmony_ci 133b815c7f3Sopenharmony_ci return (int32_t) value ; 134b815c7f3Sopenharmony_ci} 135b815c7f3Sopenharmony_ci 136b815c7f3Sopenharmony_ci 137b815c7f3Sopenharmony_cistatic inline int32_t dyn_code_32bit (int32_t maxbits, uint32_t m, uint32_t k, uint32_t n, uint32_t *outNumBits, uint32_t *outValue, uint32_t *overflow, uint32_t *overflowbits) 138b815c7f3Sopenharmony_ci{ 139b815c7f3Sopenharmony_ci uint32_t divx, mod, de ; 140b815c7f3Sopenharmony_ci uint32_t numBits ; 141b815c7f3Sopenharmony_ci uint32_t value ; 142b815c7f3Sopenharmony_ci int32_t didOverflow = 0 ; 143b815c7f3Sopenharmony_ci 144b815c7f3Sopenharmony_ci divx = n / m ; 145b815c7f3Sopenharmony_ci 146b815c7f3Sopenharmony_ci if (divx < MAX_PREFIX_32) 147b815c7f3Sopenharmony_ci { 148b815c7f3Sopenharmony_ci mod = n - (m * divx) ; 149b815c7f3Sopenharmony_ci 150b815c7f3Sopenharmony_ci de = (mod == 0) ; 151b815c7f3Sopenharmony_ci numBits = divx + k + 1 - de ; 152b815c7f3Sopenharmony_ci value = (((1 << divx) - 1) << (numBits - divx)) + mod + 1 - de ; 153b815c7f3Sopenharmony_ci if (numBits > 25) 154b815c7f3Sopenharmony_ci goto codeasescape ; 155b815c7f3Sopenharmony_ci } 156b815c7f3Sopenharmony_ci else 157b815c7f3Sopenharmony_ci { 158b815c7f3Sopenharmony_cicodeasescape: 159b815c7f3Sopenharmony_ci numBits = MAX_PREFIX_32 ; 160b815c7f3Sopenharmony_ci value = (((1 << MAX_PREFIX_32) - 1)) ; 161b815c7f3Sopenharmony_ci *overflow = n ; 162b815c7f3Sopenharmony_ci *overflowbits = maxbits ; 163b815c7f3Sopenharmony_ci didOverflow = 1 ; 164b815c7f3Sopenharmony_ci } 165b815c7f3Sopenharmony_ci 166b815c7f3Sopenharmony_ci *outNumBits = numBits ; 167b815c7f3Sopenharmony_ci *outValue = value ; 168b815c7f3Sopenharmony_ci 169b815c7f3Sopenharmony_ci return didOverflow ; 170b815c7f3Sopenharmony_ci} 171b815c7f3Sopenharmony_ci 172b815c7f3Sopenharmony_ci 173b815c7f3Sopenharmony_cistatic inline void ALWAYS_INLINE dyn_jam_noDeref (unsigned char *out, uint32_t bitPos, uint32_t numBits, uint32_t value) 174b815c7f3Sopenharmony_ci{ 175b815c7f3Sopenharmony_ci uint32_t mask ; 176b815c7f3Sopenharmony_ci uint32_t curr ; 177b815c7f3Sopenharmony_ci uint32_t shift ; 178b815c7f3Sopenharmony_ci 179b815c7f3Sopenharmony_ci //Assert (numBits <= 32) ; 180b815c7f3Sopenharmony_ci 181b815c7f3Sopenharmony_ci curr = psf_get_be32 (out, bitPos >> 3) ; 182b815c7f3Sopenharmony_ci 183b815c7f3Sopenharmony_ci shift = 32 - (bitPos & 7) - numBits ; 184b815c7f3Sopenharmony_ci 185b815c7f3Sopenharmony_ci mask = ~0u >> (32 - numBits) ; // mask must be created in two steps to avoid compiler sequencing ambiguity 186b815c7f3Sopenharmony_ci mask <<= shift ; 187b815c7f3Sopenharmony_ci 188b815c7f3Sopenharmony_ci value = (value << shift) & mask ; 189b815c7f3Sopenharmony_ci value |= curr & ~mask ; 190b815c7f3Sopenharmony_ci 191b815c7f3Sopenharmony_ci psf_put_be32 (out, bitPos >> 3, value) ; 192b815c7f3Sopenharmony_ci} 193b815c7f3Sopenharmony_ci 194b815c7f3Sopenharmony_ci 195b815c7f3Sopenharmony_cistatic inline void ALWAYS_INLINE dyn_jam_noDeref_large (unsigned char *out, uint32_t bitPos, uint32_t numBits, uint32_t value) 196b815c7f3Sopenharmony_ci{ 197b815c7f3Sopenharmony_ci uint32_t w ; 198b815c7f3Sopenharmony_ci uint32_t curr ; 199b815c7f3Sopenharmony_ci uint32_t mask ; 200b815c7f3Sopenharmony_ci int32_t shiftvalue = (32 - (bitPos & 7) - numBits) ; 201b815c7f3Sopenharmony_ci 202b815c7f3Sopenharmony_ci //Assert (numBits <= 32) ; 203b815c7f3Sopenharmony_ci 204b815c7f3Sopenharmony_ci curr = psf_get_be32 (out, bitPos >> 3) ; 205b815c7f3Sopenharmony_ci 206b815c7f3Sopenharmony_ci if (shiftvalue < 0) 207b815c7f3Sopenharmony_ci { 208b815c7f3Sopenharmony_ci uint8_t tailbyte ; 209b815c7f3Sopenharmony_ci uint8_t *tailptr ; 210b815c7f3Sopenharmony_ci 211b815c7f3Sopenharmony_ci w = value >> -shiftvalue ; 212b815c7f3Sopenharmony_ci mask = ~0u >> -shiftvalue ; 213b815c7f3Sopenharmony_ci w |= (curr & ~mask) ; 214b815c7f3Sopenharmony_ci 215b815c7f3Sopenharmony_ci tailptr = out + (bitPos >> 3) + 4 ; 216b815c7f3Sopenharmony_ci tailbyte = (value << ((8+shiftvalue))) & 0xff ; 217b815c7f3Sopenharmony_ci *tailptr = (uint8_t) tailbyte ; 218b815c7f3Sopenharmony_ci } 219b815c7f3Sopenharmony_ci else 220b815c7f3Sopenharmony_ci { 221b815c7f3Sopenharmony_ci mask = ~0u >> (32 - numBits) ; 222b815c7f3Sopenharmony_ci mask <<= shiftvalue ; // mask must be created in two steps to avoid compiler sequencing ambiguity 223b815c7f3Sopenharmony_ci 224b815c7f3Sopenharmony_ci w = (value << shiftvalue) & mask ; 225b815c7f3Sopenharmony_ci w |= curr & ~mask ; 226b815c7f3Sopenharmony_ci } 227b815c7f3Sopenharmony_ci 228b815c7f3Sopenharmony_ci psf_put_be32 (out, bitPos >> 3, w) ; 229b815c7f3Sopenharmony_ci} 230b815c7f3Sopenharmony_ci 231b815c7f3Sopenharmony_ci 232b815c7f3Sopenharmony_ciint32_t dyn_comp (AGParamRecPtr params, int32_t * pc, BitBuffer * bitstream, int32_t numSamples, int32_t bitSize, uint32_t * outNumBits) 233b815c7f3Sopenharmony_ci{ 234b815c7f3Sopenharmony_ci unsigned char * out ; 235b815c7f3Sopenharmony_ci uint32_t bitPos, startPos ; 236b815c7f3Sopenharmony_ci uint32_t m, k, n, c, mz, nz ; 237b815c7f3Sopenharmony_ci uint32_t numBits ; 238b815c7f3Sopenharmony_ci uint32_t value ; 239b815c7f3Sopenharmony_ci int32_t del, zmode ; 240b815c7f3Sopenharmony_ci uint32_t overflow, overflowbits ; 241b815c7f3Sopenharmony_ci int32_t status ; 242b815c7f3Sopenharmony_ci 243b815c7f3Sopenharmony_ci // shadow the variables in params so there's not the dereferencing overhead 244b815c7f3Sopenharmony_ci uint32_t mb, pb, kb, wb ; 245b815c7f3Sopenharmony_ci int32_t rowPos = 0 ; 246b815c7f3Sopenharmony_ci int32_t rowSize = params->sw ; 247b815c7f3Sopenharmony_ci int32_t rowJump = (params->fw) - rowSize ; 248b815c7f3Sopenharmony_ci int32_t * inPtr = pc ; 249b815c7f3Sopenharmony_ci 250b815c7f3Sopenharmony_ci *outNumBits = 0 ; 251b815c7f3Sopenharmony_ci RequireAction ((bitSize >= 1) && (bitSize <= 32), return kALAC_ParamError ;) ; 252b815c7f3Sopenharmony_ci 253b815c7f3Sopenharmony_ci out = bitstream->cur ; 254b815c7f3Sopenharmony_ci startPos = bitstream->bitIndex ; 255b815c7f3Sopenharmony_ci bitPos = startPos ; 256b815c7f3Sopenharmony_ci 257b815c7f3Sopenharmony_ci mb = params->mb = params->mb0 ; 258b815c7f3Sopenharmony_ci pb = params->pb ; 259b815c7f3Sopenharmony_ci kb = params->kb ; 260b815c7f3Sopenharmony_ci wb = params->wb ; 261b815c7f3Sopenharmony_ci zmode = 0 ; 262b815c7f3Sopenharmony_ci 263b815c7f3Sopenharmony_ci c = 0 ; 264b815c7f3Sopenharmony_ci status = ALAC_noErr ; 265b815c7f3Sopenharmony_ci 266b815c7f3Sopenharmony_ci while (c < (uint32_t) numSamples) 267b815c7f3Sopenharmony_ci { 268b815c7f3Sopenharmony_ci m = mb >> QBSHIFT ; 269b815c7f3Sopenharmony_ci k = lg3a (m) ; 270b815c7f3Sopenharmony_ci if (k > kb) 271b815c7f3Sopenharmony_ci { 272b815c7f3Sopenharmony_ci k = kb ; 273b815c7f3Sopenharmony_ci } 274b815c7f3Sopenharmony_ci m = (1 << k) - 1 ; 275b815c7f3Sopenharmony_ci 276b815c7f3Sopenharmony_ci del = *inPtr++ ; 277b815c7f3Sopenharmony_ci rowPos++ ; 278b815c7f3Sopenharmony_ci 279b815c7f3Sopenharmony_ci n = (abs_func (del) << 1) - ((del >> 31) & 1) - zmode ; 280b815c7f3Sopenharmony_ci //Assert (32-lead (n) <= bitSize) ; 281b815c7f3Sopenharmony_ci 282b815c7f3Sopenharmony_ci if (dyn_code_32bit (bitSize, m, k, n, &numBits, &value, &overflow, &overflowbits)) 283b815c7f3Sopenharmony_ci { 284b815c7f3Sopenharmony_ci dyn_jam_noDeref (out, bitPos, numBits, value) ; 285b815c7f3Sopenharmony_ci bitPos += numBits ; 286b815c7f3Sopenharmony_ci dyn_jam_noDeref_large (out, bitPos, overflowbits, overflow) ; 287b815c7f3Sopenharmony_ci bitPos += overflowbits ; 288b815c7f3Sopenharmony_ci } 289b815c7f3Sopenharmony_ci else 290b815c7f3Sopenharmony_ci { 291b815c7f3Sopenharmony_ci dyn_jam_noDeref (out, bitPos, numBits, value) ; 292b815c7f3Sopenharmony_ci bitPos += numBits ; 293b815c7f3Sopenharmony_ci } 294b815c7f3Sopenharmony_ci 295b815c7f3Sopenharmony_ci c++ ; 296b815c7f3Sopenharmony_ci if (rowPos >= rowSize) 297b815c7f3Sopenharmony_ci { 298b815c7f3Sopenharmony_ci rowPos = 0 ; 299b815c7f3Sopenharmony_ci inPtr += rowJump ; 300b815c7f3Sopenharmony_ci } 301b815c7f3Sopenharmony_ci 302b815c7f3Sopenharmony_ci mb = pb * (n + zmode) + mb - ((pb * mb) >> QBSHIFT) ; 303b815c7f3Sopenharmony_ci 304b815c7f3Sopenharmony_ci // update mean tracking if it's overflowed 305b815c7f3Sopenharmony_ci if (n > N_MAX_MEAN_CLAMP) 306b815c7f3Sopenharmony_ci mb = N_MEAN_CLAMP_VAL ; 307b815c7f3Sopenharmony_ci 308b815c7f3Sopenharmony_ci zmode = 0 ; 309b815c7f3Sopenharmony_ci 310b815c7f3Sopenharmony_ci RequireAction (c <= (uint32_t) numSamples, status = kALAC_ParamError ; goto Exit ;) ; 311b815c7f3Sopenharmony_ci 312b815c7f3Sopenharmony_ci if (((mb << MMULSHIFT) < QB) && (c < (uint32_t) numSamples)) 313b815c7f3Sopenharmony_ci { 314b815c7f3Sopenharmony_ci zmode = 1 ; 315b815c7f3Sopenharmony_ci nz = 0 ; 316b815c7f3Sopenharmony_ci 317b815c7f3Sopenharmony_ci while (c < (uint32_t) numSamples && *inPtr == 0) 318b815c7f3Sopenharmony_ci { 319b815c7f3Sopenharmony_ci /* Take care of wrap-around globals. */ 320b815c7f3Sopenharmony_ci ++inPtr ; 321b815c7f3Sopenharmony_ci ++nz ; 322b815c7f3Sopenharmony_ci ++c ; 323b815c7f3Sopenharmony_ci if (++rowPos >= rowSize) 324b815c7f3Sopenharmony_ci { 325b815c7f3Sopenharmony_ci rowPos = 0 ; 326b815c7f3Sopenharmony_ci inPtr += rowJump ; 327b815c7f3Sopenharmony_ci } 328b815c7f3Sopenharmony_ci 329b815c7f3Sopenharmony_ci if (nz >= 65535) 330b815c7f3Sopenharmony_ci { 331b815c7f3Sopenharmony_ci zmode = 0 ; 332b815c7f3Sopenharmony_ci break ; 333b815c7f3Sopenharmony_ci } 334b815c7f3Sopenharmony_ci } 335b815c7f3Sopenharmony_ci 336b815c7f3Sopenharmony_ci k = lead (mb) - BITOFF + ((mb + MOFF) >> MDENSHIFT) ; 337b815c7f3Sopenharmony_ci mz = ((1 << k) - 1) & wb ; 338b815c7f3Sopenharmony_ci 339b815c7f3Sopenharmony_ci value = dyn_code (mz, k, nz, &numBits) ; 340b815c7f3Sopenharmony_ci dyn_jam_noDeref (out, bitPos, numBits, value) ; 341b815c7f3Sopenharmony_ci bitPos += numBits ; 342b815c7f3Sopenharmony_ci 343b815c7f3Sopenharmony_ci mb = 0 ; 344b815c7f3Sopenharmony_ci } 345b815c7f3Sopenharmony_ci } 346b815c7f3Sopenharmony_ci 347b815c7f3Sopenharmony_ci *outNumBits = (bitPos - startPos) ; 348b815c7f3Sopenharmony_ci BitBufferAdvance (bitstream, *outNumBits) ; 349b815c7f3Sopenharmony_ci 350b815c7f3Sopenharmony_ciExit: 351b815c7f3Sopenharmony_ci return status ; 352b815c7f3Sopenharmony_ci} 353