blob: f0875c1b602e9d5e68b28a4943e9c38e3df17882 [file] [log] [blame]
/*
* BitstreamEncoding.cpp
*
* Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
* www.ehima.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "BitstreamEncoding.hpp"
#include <algorithm>
#include <cmath>
#include "SnsQuantizationTables.hpp"
#include "SpectralDataTables.hpp"
#include "TemporalNoiseShapingTables.hpp"
namespace Lc3Enc {
BitstreamEncoding::BitstreamEncoding(uint16_t NE_, uint16_t nbytes_)
: NE(NE_),
nbytes(nbytes_),
nbits(nbytes_ * 8),
bytes(nullptr),
bp(0),
bp_side(0),
mask_side(0),
nbits_side_initial(0),
nlsbs(0),
lsbs(nullptr) {}
BitstreamEncoding::~BitstreamEncoding() {}
void BitstreamEncoding::write_bit_backward(uint8_t bytes[], uint16_t* bp,
uint8_t* mask, uint8_t bit) {
if (bit == 0) {
bytes[*bp] &= ~*mask;
} else {
bytes[*bp] |= *mask;
}
if (*mask == 0x80) {
*mask = 1;
*bp -= 1;
} else {
*mask <<= 1;
}
}
void BitstreamEncoding::write_uint_backward(uint8_t bytes[], uint16_t* bp,
uint8_t* mask, uint16_t val,
uint8_t numbits) {
for (uint8_t k = 0; k < numbits; k++) {
uint8_t bit = val & 1;
write_bit_backward(bytes, bp, mask, bit);
val >>= 1;
}
}
void BitstreamEncoding::write_uint_forward(uint8_t bytes[], uint16_t bp,
uint16_t val, uint8_t numbits) {
uint8_t mask = 0x80;
for (uint8_t k = 0; k < numbits; k++) {
uint8_t bit = val & mask;
if (bit == 0) {
bytes[bp] &= ~mask;
} else {
bytes[bp] |= mask;
}
mask >>= 1;
}
}
void BitstreamEncoding::init(uint8_t* bytes_) {
// store pointer to current output buffer
bytes = bytes_;
// added initialization of bytes
// This might be needed for test purpose only, but is added to be on the safe
// side.
for (uint16_t k = 0; k < nbytes; k++) {
bytes[k] = 0;
}
// 3.3.13 Bitstream encoding (d09r02_F2F)
// 3.3.13.2 Initialization (d09r02_F2F)
bp = 0;
bp_side = nbytes - 1;
mask_side = 1;
nlsbs = 0;
}
void BitstreamEncoding::bandwidth(uint8_t P_bw, uint8_t nbits_bw) {
/* Bandwidth */
// if (𝑛𝑏𝑖𝑡𝑠𝑏𝑤 > 0)
if (nbits_bw > 0) {
// write_uint_backward(bytes, &bp_side, &mask_side, 𝑃𝑏𝑤, 𝑛𝑏𝑖𝑡𝑠𝑏𝑤);
write_uint_backward(bytes, &bp_side, &mask_side, P_bw, nbits_bw);
}
}
void BitstreamEncoding::lastNonzeroTuple(uint16_t lastnz_trunc) {
/* Last non-zero tuple */
write_uint_backward(bytes, &bp_side, &mask_side, (lastnz_trunc >> 1) - 1,
// ceil(log2(𝑁𝐸/2))
ceil(log2(NE / 2)));
}
void BitstreamEncoding::lsbModeBit(uint8_t lsbMode) {
/* LSB mode bit */
write_bit_backward(bytes, &bp_side, &mask_side, lsbMode);
}
void BitstreamEncoding::globalGain(uint8_t gg_ind) {
/* Global Gain */
write_uint_backward(bytes, &bp_side, &mask_side, gg_ind, 8);
}
void BitstreamEncoding::tnsActivationFlag(uint8_t num_tns_filters,
uint8_t rc_order[]) {
/* TNS activation flag */
for (uint8_t f = 0; f < num_tns_filters; f++) {
write_bit_backward(bytes, &bp_side, &mask_side,
std::min(rc_order[f], static_cast<uint8_t>(1)));
}
}
void BitstreamEncoding::pitchPresentFlag(uint8_t pitch_present) {
/* Pitch present flag */
write_bit_backward(bytes, &bp_side, &mask_side, pitch_present);
}
void BitstreamEncoding::encodeScfVq1stStage(uint8_t ind_LF, uint8_t ind_HF) {
/* Encode SCF VQ parameters - 1st stage (10 bits) */
write_uint_backward(bytes, &bp_side, &mask_side, ind_LF, 5);
write_uint_backward(bytes, &bp_side, &mask_side, ind_HF, 5);
}
void BitstreamEncoding::encodeScfVq2ndStage(
uint8_t shape_j, uint8_t gain_i,
uint8_t LS_indA, // the type of this is strange over all code places ->
// finally only one bit is stored!
uint32_t index_joint_j) {
/* Encode SCF VQ parameters - 2nd stage side-info (3-4 bits) */
write_bit_backward(bytes, &bp_side, &mask_side, shape_j >> 1);
// uint8_t submode_LSB = (shape_j & 0x1); /* shape_j is the stage2 shape_index
// [0…3] */
uint8_t submode_MSB = (shape_j >> 1);
uint8_t gain_MSBs =
gain_i; /* where gain_i is the SNS-VQ stage 2 gain_index */
gain_MSBs = (gain_MSBs >> sns_gainLSBbits[shape_j]);
write_uint_backward(bytes, &bp_side, &mask_side, gain_MSBs,
sns_gainMSBbits[shape_j]);
write_bit_backward(bytes, &bp_side, &mask_side, LS_indA);
/* Encode SCF VQ parameters - 2nd stage MPVQ data */
if (submode_MSB == 0) {
/*
if (submode_LSB == 0)
{
tmp = index_joint_0; // Eq. 52
} else {
tmp = index_joint_1; // Eq. 53
}
write_uint_backward(bytes, &bp_side, &mask_side, tmp, 13)
write_uint_backward(bytes, &bp_side, &mask_side, tmp>>13, 12);
*/
write_uint_backward(bytes, &bp_side, &mask_side, index_joint_j, 13);
write_uint_backward(bytes, &bp_side, &mask_side, index_joint_j >> 13, 12);
} else {
/*
if (submode_LSB == 0)
{
tmp = index_joint_2; // Eq. 54
} else {
tmp = index_joint_3; // Eq. 55
}
write_uint_backward(bytes, &bp_side, &mask_side, tmp, 12);
write_uint_backward(bytes, &bp_side, &mask_side, tmp>> 12, 12);
*/
write_uint_backward(bytes, &bp_side, &mask_side, index_joint_j, 12);
write_uint_backward(bytes, &bp_side, &mask_side, index_joint_j >> 12, 12);
}
}
void BitstreamEncoding::ltpfData(uint8_t ltpf_active, uint16_t pitch_index) {
/* LTPF data */
write_uint_backward(bytes, &bp_side, &mask_side, ltpf_active, 1);
write_uint_backward(bytes, &bp_side, &mask_side, pitch_index, 9);
}
void BitstreamEncoding::noiseFactor(uint8_t F_NF) {
/* Noise Factor */
write_uint_backward(bytes, &bp_side, &mask_side, F_NF, 3);
}
void BitstreamEncoding::ac_enc_init() {
st.low = 0;
st.range = 0x00ffffff;
st.cache = -1;
st.carry = 0;
st.carry_count = 0;
}
void BitstreamEncoding::ac_shift(uint8_t bytes[], uint16_t* bp,
struct ac_enc_state* st) {
if (st->low < 0x00ff0000 || st->carry == 1) {
if (st->cache >= 0) {
bytes[(*bp)++] = (st->cache + st->carry) & 0xff;
}
while (st->carry_count > 0) {
bytes[(*bp)++] = (st->carry + 0xff) & 0xff;
st->carry_count -= 1;
}
st->cache = st->low >> 16;
st->carry = 0;
} else {
st->carry_count += 1;
}
st->low <<= 8;
st->low &= 0x00ffffff;
}
void BitstreamEncoding::ac_encode(uint8_t bytes[], uint16_t* bp,
struct ac_enc_state* st, short cum_freq,
short sym_freq) {
uint32_t r = st->range >> 10;
st->low += r * cum_freq;
if (st->low >> 24) {
st->carry = 1;
}
st->low &= 0x00ffffff;
st->range = r * sym_freq;
while (st->range < 0x10000) {
st->range <<= 8;
ac_shift(bytes, bp, st);
}
}
void BitstreamEncoding::ac_enc_finish(uint8_t bytes[], uint16_t* bp,
struct ac_enc_state* st) {
int8_t bits = 1;
while ((st->range >> (24 - bits)) == 0) {
bits++;
}
uint32_t mask = 0x00ffffff >> bits;
uint32_t val = st->low + mask;
uint8_t over1 = val >> 24;
val &= 0x00ffffff;
uint32_t high = st->low + st->range;
uint8_t over2 = high >> 24;
high &= 0x00ffffff;
val = val & ~mask;
if (over1 == over2) {
if (val + mask >= high) {
bits += 1;
mask >>= 1;
val = ((st->low + mask) & 0x00ffffff) & ~mask;
}
if (val < st->low) {
st->carry = 1;
}
}
st->low = val;
for (; bits > 0; bits -= 8) {
ac_shift(bytes, bp, st);
}
bits += 8;
if (st->carry_count > 0) {
bytes[(*bp)++] = st->cache;
for (; st->carry_count > 1; st->carry_count--) {
bytes[(*bp)++] = 0xff;
}
write_uint_forward(bytes, *bp, 0xff >> (8 - bits), bits);
} else {
write_uint_forward(bytes, *bp, st->cache, bits);
}
}
void BitstreamEncoding::tnsData(uint8_t tns_lpc_weighting,
uint8_t num_tns_filters, uint8_t rc_order[],
uint8_t rc_i[]) {
/* TNS data */
for (uint8_t f = 0; f < num_tns_filters; f++) {
// if (𝑟𝑐𝑜𝑟𝑑𝑒𝑟 (𝑓) > 0)
if (rc_order[f] > 0) {
ac_encode(bytes, &bp, &st,
// ac_tns_order_cumfreq[tns_lpc_weighting][ 𝑟𝑐𝑜𝑟𝑑𝑒𝑟 (𝑓)-1],
ac_tns_order_cumfreq[tns_lpc_weighting][rc_order[f] - 1],
// ac_tns_order_freq[tns_lpc_weighting][ 𝑟𝑐𝑜𝑟𝑑𝑒𝑟 (𝑓)-1]
ac_tns_order_freq[tns_lpc_weighting][rc_order[f] - 1]);
// for (k = 0; k < 𝑟𝑐𝑜𝑟𝑑𝑒𝑟 (𝑓); k++)
for (uint8_t k = 0; k < rc_order[f]; k++) {
ac_encode(bytes, &bp, &st,
// ac_tns_coef_cumfreq[k][𝑟𝑐𝑖 (𝑘, 𝑓)],
ac_tns_coef_cumfreq[k][rc_i[k + 8 * f]],
// ac_tns_coef_freq[k][𝑟𝑐𝑖 (𝑘, 𝑓)]
ac_tns_coef_freq[k][rc_i[k + 8 * f]]);
}
}
}
}
uint16_t BitstreamEncoding::nbits_side_written() {
return nbits - (8 * bp_side + 8 - log2(mask_side));
}
void BitstreamEncoding::spectralData(uint16_t lastnz_trunc, uint16_t rateFlag,
uint8_t lsbMode, int16_t* X_q,
uint16_t nbits_lsb, uint8_t* lsbs_) {
nbits_side_initial = nbits_side_written();
lsbs = lsbs_; // store this pointer for subsequent use in
// residualDataAndFinalization
/* Spectral data */
uint16_t c = 0;
for (uint16_t k = 0; k < lastnz_trunc; k += 2) {
uint16_t t = c + rateFlag;
// if (k > 𝑁𝐸/2)
if (k > NE / 2) {
t += 256;
}
// a = abs(𝑋𝑞[k]);
uint16_t a = abs(X_q[k]);
uint16_t a_lsb = a;
// b = abs(𝑋𝑞[k+1]);
uint16_t b = abs(X_q[k + 1]);
uint16_t b_lsb = b;
uint8_t lev = 0;
uint8_t lsb0 = 0;
uint8_t lsb1 = 0;
// while (max(a,b) >= 4)
uint8_t pki;
while (std::max(a, b) >= 4) {
// pki = ac_spec_lookup[t+min(lev,3)*1024];
pki = ac_spec_lookup[t + std::min(lev, static_cast<uint8_t>(3)) * 1024];
ac_encode(bytes, &bp, &st, ac_spec_cumfreq[pki][16],
ac_spec_freq[pki][16]);
if ((lsbMode == 1) && (lev == 0)) {
lsb0 = a & 1;
lsb1 = b & 1;
} else {
write_bit_backward(bytes, &bp_side, &mask_side, a & 1);
write_bit_backward(bytes, &bp_side, &mask_side, b & 1);
}
a >>= 1;
b >>= 1;
lev++;
}
pki = ac_spec_lookup[t + std::min(lev, static_cast<uint8_t>(3)) * 1024];
uint16_t sym = a + 4 * b;
ac_encode(bytes, &bp, &st, ac_spec_cumfreq[pki][sym],
ac_spec_freq[pki][sym]);
// a_lsb = abs(𝑋𝑞[k]); -> implemented earlier
// b_lsb = abs(𝑋𝑞[k+1]); -> implemented earlier
if ((lsbMode == 1) && (lev > 0)) {
a_lsb >>= 1;
b_lsb >>= 1;
lsbs[nlsbs++] = lsb0;
// if (a_lsb == 0 && 𝑋𝑞[k] != 0)
if (a_lsb == 0 && X_q[k] != 0) {
// lsbs[nlsbs++] = 𝑋𝑞[k]>0?0:1;
lsbs[nlsbs++] = X_q[k] > 0 ? 0 : 1;
}
lsbs[nlsbs++] = lsb1;
// if (b_lsb == 0 && 𝑋𝑞[k+1] != 0)
if (b_lsb == 0 && X_q[k + 1] != 0) {
// lsbs[nlsbs++] = 𝑋𝑞[k+1]>0?0:1;
lsbs[nlsbs++] = X_q[k + 1] > 0 ? 0 : 1;
}
}
if (a_lsb > 0) {
// write_bit_backward(bytes, &bp_side, &mask_side, 𝑋𝑞[k]>0?0:1);
write_bit_backward(bytes, &bp_side, &mask_side, X_q[k] > 0 ? 0 : 1);
}
if (b_lsb > 0) {
// write_bit_backward(bytes, &bp_side, &mask_side, 𝑋𝑞[k+1]>0?0:1);
write_bit_backward(bytes, &bp_side, &mask_side, X_q[k + 1] > 0 ? 0 : 1);
}
// lev = min(lev,3);
lev = std::min(lev, static_cast<uint8_t>(3));
if (lev <= 1) {
t = 1 + (a + b) * (lev + 1);
} else {
t = 12 + lev;
}
c = (c & 15) * 16 + t;
}
}
// nbits_ari forecast under the assumption that only finalization will be added
uint16_t BitstreamEncoding::nbits_ari_forecast() {
uint16_t nbits_ari = bp * 8;
nbits_ari += 25 - floor(log2(st.range));
if (st.cache >= 0) {
nbits_ari += 8;
}
if (st.carry_count > 0) {
nbits_ari += st.carry_count * 8;
}
return nbits_ari;
}
void BitstreamEncoding::residualDataAndFinalization(uint8_t lsbMode,
uint16_t nbits_residual,
uint8_t* res_bits) {
/* Residual bits */
// uint16_t nbits_side = nbits - (8 * bp_side + 8 - log2(mask_side));
uint16_t nbits_side = nbits_side_written();
uint16_t nbits_ari = nbits_ari_forecast();
uint16_t nbits_residual_enc = nbits - (nbits_side + nbits_ari);
if (*reinterpret_cast<int16_t*>(&nbits_residual_enc) < 0) {
nbits_residual_enc = 0;
}
if (lsbMode == 0) {
nbits_residual_enc = std::min(nbits_residual_enc, nbits_residual);
for (uint16_t k = 0; k < nbits_residual_enc; k++) {
write_bit_backward(bytes, &bp_side, &mask_side, res_bits[k]);
}
} else {
nbits_residual_enc = std::min(nbits_residual_enc, nlsbs);
for (uint16_t k = 0; k < nbits_residual_enc; k++) {
write_bit_backward(bytes, &bp_side, &mask_side, lsbs[k]);
}
}
/* Arithmetic Encoder Finalization */
ac_enc_finish(bytes, &bp, &st);
}
void BitstreamEncoding::registerDatapoints(DatapointContainer* datapoints) {
if (nullptr != datapoints) {
datapoints->addDatapoint("nbytes", &nbytes, sizeof(nbytes));
}
}
} // namespace Lc3Enc