You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
3.0 KiB
C++
153 lines
3.0 KiB
C++
/*
|
|
* 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 <stdint.h>
|
|
#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
|