summaryrefslogtreecommitdiff
path: root/system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp
diff options
context:
space:
mode:
authorScott Lobdell <slobdell@google.com>2022-03-11 19:27:17 +0000
committerScott Lobdell <slobdell@google.com>2022-03-11 19:57:09 +0000
commitc9218ef1b82430a07d94f74c212a30e7ccc52975 (patch)
tree241b7fdeb6bdf1cf3af925ba8996f18faa8973d9 /system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp
parenta26bda4d37221f2f7ef750b413502091e3bcddd4 (diff)
parent480d2270b269a0e47bf475eb439111f3f966e2a9 (diff)
Merge TP1A.220225.003
Change-Id: Id71ac466dbfe3707fe2e544ce22b1da8f474ec2b
Diffstat (limited to 'system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp')
-rw-r--r--system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp251
1 files changed, 0 insertions, 251 deletions
diff --git a/system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp b/system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp
deleted file mode 100644
index d8ea214899..0000000000
--- a/system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * ArithmeticDec.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 "ArithmeticDec.hpp"
-
-#include <algorithm> // std::min
-#include <cmath>
-#include <cstring>
-
-#include "BitReader.hpp"
-#include "SpectralDataTables.hpp"
-#include "TemporalNoiseShapingTables.hpp"
-
-namespace Lc3Dec {
-
-ArithmeticDec::ArithmeticDec(uint16_t NF_, uint16_t NE_, uint16_t rateFlag_,
- uint8_t tns_lpc_weighting_)
- : NF(NF_),
- NE(NE_),
- rateFlag(rateFlag_),
- tns_lpc_weighting(tns_lpc_weighting_),
- X_hat_q_ari(nullptr),
- save_lev(nullptr),
- nf_seed(0),
- nbits_residual(0) {
- X_hat_q_ari = new int16_t[NE];
- save_lev = new uint8_t[NE];
-}
-
-ArithmeticDec::~ArithmeticDec() {
- delete[] X_hat_q_ari;
- delete[] save_lev;
-}
-
-void ac_dec_init(const uint8_t bytes[], uint16_t* bp, struct ac_dec_state* st) {
- st->low = 0;
- st->range = 0x00ffffff;
- for (uint8_t i = 0; i < 3; i++) {
- st->low <<= 8;
- st->low += bytes[(*bp)++];
- }
-}
-
-uint8_t ac_decode(const uint8_t bytes[], uint16_t* bp, struct ac_dec_state* st,
- int16_t cum_freq[], int16_t sym_freq[], uint8_t numsym,
- uint8_t& BEC_detect) {
- uint32_t tmp = st->range >> 10;
- if (st->low >= (tmp << 10)) {
- BEC_detect = 1;
- return 0;
- }
- uint8_t val = numsym - 1;
- while (st->low < tmp * cum_freq[val]) {
- val--;
- }
- st->low -= tmp * cum_freq[val];
- st->range = tmp * sym_freq[val];
- while (st->range < 0x10000) {
- st->low <<= 8;
- st->low &= 0x00ffffff;
- st->low += bytes[(*bp)++];
- st->range <<= 8;
- }
- return val;
-}
-
-double ArithmeticDec::rc_q(uint8_t k, uint8_t f) {
- // with Δ =π/17
- const double pi = std::acos(-1);
- double quantizer_stepsize = pi / 17.0;
- return sin(quantizer_stepsize * (rc_i[k + 8 * f] - 8));
-}
-
-void ArithmeticDec::run(const uint8_t* bytes, uint16_t& bp, uint16_t& bp_side,
- uint8_t& mask_side, int16_t& num_tns_filters,
- int16_t rc_order[], const uint8_t& lsbMode,
- const int16_t& lastnz, uint16_t nbits,
- uint8_t& BEC_detect) {
- int16_t c = 0;
-
- // make local copy of rc_order (is this really what we want)
- rc_order_ari[0] = rc_order[0];
- rc_order_ari[1] = rc_order[1];
-
- /* Arithmetic Decoder Initialization */
- ac_dec_init(bytes, &bp, &st);
-
- /* TNS data */
- // Note: some initialization code like that below can be found in d09r02,
- // but there has been none in d09r01. However, the complete
- // initialization has been added here, in order to get a proper match to
- // the reference output data
- for (uint8_t f = 0; f < 2; f++) {
- for (uint8_t k = 0; k < 8; k++) {
- rc_i[k + 8 * f] = 8;
- }
- }
- for (uint8_t f = 0; f < num_tns_filters; f++) {
- // if (𝑟𝑐𝑜𝑟𝑑𝑒𝑟(𝑓) > 0)
- if (rc_order[f] > 0) {
- //𝑟𝑐𝑜𝑟𝑑𝑒𝑟(𝑓) = ac_decode(bytes, &bp, &st,
- rc_order_ari[f] =
- ac_decode(bytes, &bp, &st, ac_tns_order_cumfreq[tns_lpc_weighting],
- ac_tns_order_freq[tns_lpc_weighting], 8, BEC_detect);
- if (BEC_detect) {
- // early exit to avoid unpredictable side-effects
- return;
- }
-
- rc_order_ari[f] = rc_order_ari[f] + 1;
- // specification (d09r02_F2F) proposes initialization
- // of rc_i at this place; here implemented above in order
- // to be performed independet from num_tns_filters
- for (uint8_t k = 0; k < rc_order_ari[f]; k++) {
- //𝑟𝑐𝑖(𝑘,𝑓) = ac_decode(bytes, &bp, &st, ac_tns_coef_cumfreq[k],
- // rc_i[k][f] = ac_decode(bytes, &bp, &st, ac_tns_coef_cumfreq[k],
- rc_i[k + 8 * f] = ac_decode(bytes, &bp, &st, ac_tns_coef_cumfreq[k],
- ac_tns_coef_freq[k], 17, BEC_detect);
- if (BEC_detect) {
- // early exit to avoid unpredictable side-effects
- return;
- }
- }
- }
- }
-
- /* Spectral data */
- for (uint16_t k = 0; k < lastnz; k += 2) {
- uint16_t t = c + rateFlag;
- // if (k > 𝑁𝐸/2)
- if (k > NE / 2) {
- t += 256;
- }
- //𝑋𝑞̂[k] = 𝑋𝑞̂[k+1] = 0;
- X_hat_q_ari[k] = X_hat_q_ari[k + 1] = 0;
- uint8_t lev;
- uint8_t sym;
- for (lev = 0; lev < 14; lev++) {
- uint8_t pki =
- ac_spec_lookup[t + std::min(lev, static_cast<uint8_t>(3U)) * 1024];
- sym = ac_decode(bytes, &bp, &st, ac_spec_cumfreq[pki], ac_spec_freq[pki],
- 17, BEC_detect);
- if (BEC_detect) {
- // early exit to avoid unpredictable side-effects
- return;
- }
- if (sym < 16) {
- break;
- }
- if (lsbMode == 0 || lev > 0) {
- uint8_t bit = read_bit(bytes, &bp_side, &mask_side);
- //𝑋𝑞̂[k] += bit << lev;
- X_hat_q_ari[k] += bit << lev;
- bit = read_bit(bytes, &bp_side, &mask_side);
- //𝑋𝑞̂[k+1] += bit << lev;
- X_hat_q_ari[k + 1] += bit << lev;
- }
- }
- if (lev == 14) {
- BEC_detect = 1;
- return;
- }
- if (lsbMode == 1) {
- save_lev[k] = lev;
- }
- uint8_t a = sym & 0x3;
- uint8_t b = sym >> 2;
- //𝑋𝑞̂[k] += a << lev;
- //𝑋𝑞̂[k+1] += b << lev;
- // if (𝑋𝑞̂[k] > 0)
- X_hat_q_ari[k] += a << lev;
- X_hat_q_ari[k + 1] += b << lev;
- if (X_hat_q_ari[k] > 0) {
- uint8_t bit = read_bit(bytes, &bp_side, &mask_side);
- if (bit == 1) {
- //𝑋𝑞̂[k] = -𝑋𝑞̂[k];
- X_hat_q_ari[k] = -X_hat_q_ari[k];
- }
- }
- // if (𝑋𝑞̂[k+1] > 0)
- if (X_hat_q_ari[k + 1] > 0) {
- uint8_t bit = read_bit(bytes, &bp_side, &mask_side);
- if (bit == 1) {
- //𝑋𝑞̂[k+1] = -𝑋𝑞̂[k+1];
- X_hat_q_ari[k + 1] = -X_hat_q_ari[k + 1];
- }
- }
- 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;
- // Note: specification of the following line hase been changed from d09r01
- // to d09r02_F2F
- if (bp - bp_side > 3) {
- BEC_detect = 1;
- return;
- }
- }
- // reset remaining fields in array X_hat_q_ari to simplify testing
- for (int16_t k = lastnz; k < NE; k++) {
- X_hat_q_ari[k] = 0;
- }
-
- // 3.4.2.6 Residual data and finalization (d09r02_F2F)
- /* Number of residual bits */
- int16_t nbits_side = nbits - (8 * bp_side + 8 - log2(mask_side));
- int16_t nbits_ari = (bp - 3) * 8;
- nbits_ari += 25 - floor(log2(st.range));
- int16_t nbits_residual_tmp = nbits - (nbits_side + nbits_ari);
- if (nbits_residual_tmp < 0) {
- BEC_detect = 1;
- return;
- }
- nbits_residual = nbits_residual_tmp;
-}
-
-void ArithmeticDec::registerDatapoints(DatapointContainer* datapoints) {
- if (nullptr != datapoints) {
- datapoints->addDatapoint("rateFlag", &rateFlag, sizeof(rateFlag));
- datapoints->addDatapoint("tns_lpc_weighting", &tns_lpc_weighting,
- sizeof(tns_lpc_weighting));
- datapoints->addDatapoint("rc_order_ari", &rc_order_ari[0],
- sizeof(rc_order_ari));
- datapoints->addDatapoint("rc_i", &rc_i[0], sizeof(rc_i));
- datapoints->addDatapoint("X_hat_q_ari", &X_hat_q_ari[0],
- sizeof(int16_t) * NE);
- datapoints->addDatapoint("nbits_residual", &nbits_residual,
- sizeof(nbits_residual));
- }
-}
-
-} // namespace Lc3Dec