ag_enc.c 8.3 KB

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