diff options
author | Scott Lobdell <slobdell@google.com> | 2022-03-11 19:27:17 +0000 |
---|---|---|
committer | Scott Lobdell <slobdell@google.com> | 2022-03-11 19:57:09 +0000 |
commit | c9218ef1b82430a07d94f74c212a30e7ccc52975 (patch) | |
tree | 241b7fdeb6bdf1cf3af925ba8996f18faa8973d9 /system/embdrv/lc3_dec/Decoder/ArithmeticDec.cpp | |
parent | a26bda4d37221f2f7ef750b413502091e3bcddd4 (diff) | |
parent | 480d2270b269a0e47bf475eb439111f3f966e2a9 (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.cpp | 251 |
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 |