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++

/*
* 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