/* * Direct Stream Transfer (DST) codec * ISO/IEC 14496-3 Part 3 Subpart 10: Technical description of lossless coding of oversampled audio */ #ifndef AC_H #define AC_H #include #include "common.h" namespace dst { constexpr int PBITS = AC_BITS; // number of bits for Probabilities constexpr int NBITS = 4; // number of overhead bits: must be at least 2! // maximum "variable shift length" is (NBITS-1) constexpr int PSUM = 1 << PBITS; constexpr int ABITS = PBITS + NBITS; // must be at least PBITS+2 constexpr int MB = 0; // if (MB) print max buffer use constexpr int ONE = 1 << ABITS; constexpr int HALF = 1 << (ABITS - 1); class ac_t { unsigned int Init; unsigned int C; unsigned int A; int cbptr; public: unsigned int getPtableIndex(int PredicVal, int PtableLen) { int j; j = (PredicVal > 0 ? PredicVal : -PredicVal) >> AC_QSTEP; if (j >= PtableLen) { j = PtableLen - 1; } return (unsigned int)j; } void decodeBit(uint8_t& b, int p, uint8_t* cb, int fs, int flush) { unsigned int ap; unsigned int h; if (Init == 1) { Init = 0; A = ONE - 1; C = 0; for (cbptr = 1; cbptr <= ABITS; cbptr++) { C <<= 1; if (cbptr < fs) { C |= cb[cbptr]; } } } if (flush == 0) { // approximate (A * p) with "partial rounding" ap = ((A >> PBITS) | ((A >> (PBITS - 1)) & 1))* p; h = A - ap; if (C >= h) { b = 0; C -= h; A = ap; } else { b = 1; A = h; } while (A < HALF) { A <<= 1; // Use new flushing technique; insert zero in LSB of C if reading past the end of the arithmetic code C <<= 1; if (cbptr < fs) { C |= cb[cbptr]; } cbptr++; } } else { Init = 1; if (cbptr < fs - 7) { b = 0; } else { b = 1; while ((cbptr < fs) && (b == 1)) { if (cb[cbptr] != 0) { b = 1; } cbptr++; } } } } void decodeBit_Init(uint8_t* cb, int fs) { Init = 0; A = ONE - 1; C = 0; for (cbptr = 1; cbptr <= ABITS; cbptr++) { C <<= 1; if (cbptr < fs) { C |= GET_BIT(cb, cbptr); } } } void decodeBit_Decode(uint8_t* b, int p, uint8_t* cb, int fs) { unsigned int ap; unsigned int h; // approximate (A * p) with "partial rounding" ap = ((A >> PBITS) | ((A >> (PBITS - 1)) & 1))* p; h = A - ap; if (C >= h) { *b = 0; C -= h; A = ap; } else { *b = 1; A = h; } while (A < HALF) { A <<= 1; // Use new flushing technique; insert zero in LSB of C if reading past the end of the arithmetic code C <<= 1; if (cbptr < fs) { C |= GET_BIT(cb, cbptr); } cbptr++; } } void decodeBit_Flush(uint8_t* b, int p, uint8_t* cb, int fs) { (void)p; Init = 1; if (cbptr < fs - 7) { *b = 0; } else { *b = 1; while ((cbptr < fs) && (*b == 1)) { if (GET_BIT(cb, cbptr) != 0) { *b = 1; } cbptr++; } } } }; } #endif