/*
 * BandwidthDetector.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 "BandwidthDetector.hpp"

#include <cmath>

namespace Lc3Enc {

static const uint8_t I_bw_start_table[5][4] = {
    {53, 0, 0, 0},    // N_bw=1
    {47, 59, 0, 0},   // N_bw=2
    {44, 54, 60, 0},  // N_bw=3
    {41, 51, 57, 61}  // N_bw=4
};

static const uint8_t I_bw_stop_table[5][4] = {
    {63, 0, 0, 0},    // N_bw=1
    {56, 63, 0, 0},   // N_bw=2
    {52, 59, 63, 0},  // N_bw=3
    {49, 55, 60, 63}  // N_bw=4
};

static const uint8_t I_bw_start_table_7p5ms[5][4] = {
    {51, 0, 0, 0},    // N_bw=1
    {45, 58, 0, 0},   // N_bw=2
    {42, 53, 60, 0},  // N_bw=3
    {40, 51, 57, 61}  // N_bw=4
};

static const uint8_t I_bw_stop_table_7p5ms[5][4] = {
    {63, 0, 0, 0},    // N_bw=1
    {55, 63, 0, 0},   // N_bw=2
    {51, 58, 63, 0},  // N_bw=3
    {48, 55, 60, 63}  // N_bw=4
};

static const uint8_t nbits_bw_table[5] = {
    0, 1, 2, 2, 3};  // see 3.4.2.4 Bandwidth interpretation (d09r02_F2F)

static const uint8_t T_Q[4] = {20, 10, 10, 10};
static const uint8_t T_C[4] = {15, 23, 20, 20};
static const uint8_t L_10ms[4] = {4, 4, 3, 1};
static const uint8_t L_7p5ms[4] = {4, 4, 3, 2};

BandwidthDetector::BandwidthDetector(const Lc3Config& lc3Config_)
    : lc3Config(lc3Config_),
      N_bw(calc_N_bw(lc3Config.Fs_ind)),
      nbits_bw(nbits_bw_table[calc_N_bw(lc3Config.Fs_ind)]),
      P_bw(0) {
  if (N_bw != 0) {
    I_bw_start = (lc3Config.N_ms == Lc3Config::FrameDuration::d10ms)
                     ? I_bw_start_table[N_bw - 1]
                     : I_bw_start_table_7p5ms[N_bw - 1];
    I_bw_stop = (lc3Config.N_ms == Lc3Config::FrameDuration::d10ms)
                    ? I_bw_stop_table[N_bw - 1]
                    : I_bw_stop_table_7p5ms[N_bw - 1];
  }
  L = (lc3Config.N_ms == Lc3Config::FrameDuration::d10ms) ? L_10ms : L_7p5ms;
}

BandwidthDetector::~BandwidthDetector() {}

uint8_t BandwidthDetector::calc_N_bw(uint8_t fs_ind) {
  // see Table 3.5: Parameter table bandwidth detector
  // 3.3.5.2 Parameters (d09r02_F2F)
  return fs_ind;
}

void BandwidthDetector::run(const double* const E_B) {
  if (0 == N_bw) {
    return;
  }

  // 3.3.5.1 Algorithm (first stage)  (d09r02_F2F)
  // Note: it seems like there is no need to compute
  //   the entire specified sequence of flahs F_Q[k]
  //   when we start searching for an active band
  //   from the highest fequency band to lower bands
  uint8_t bw_0 = 0;
  for (uint8_t k = N_bw - 1; k < N_bw; k--)  // stops when 0-- goes to 255
  {
    uint8_t width = I_bw_stop[k] - I_bw_start[k] + 1;
    double Q = 0.0;
    for (uint8_t n = I_bw_start[k]; n <= I_bw_stop[k]; n++) {
      Q += E_B[n] / width;
    }
    if (Q >= T_Q[k]) {
      // activity detected (not quiet) -> this is the band index to be selected
      bw_0 = k + 1;
      break;
    }
  }

  // 3.3.5.1 Algorithm (second stage)  (d09r02_F2F)
  if (N_bw == bw_0) {
    P_bw = bw_0;
  } else {
    double Cmax = 0;
    for (uint8_t n = I_bw_start[bw_0] - L[bw_0] + 1; n <= I_bw_start[bw_0] + 1;
         n++) {
      double C = 10 * log10(E_B[n - L[bw_0]] / E_B[n]);
      if (C > Cmax) {
        Cmax = C;
      }
    }
    if (Cmax > T_C[bw_0]) {
      P_bw = bw_0;
    } else {
      P_bw = N_bw;
    }
  }
}

void BandwidthDetector::registerDatapoints(DatapointContainer* datapoints) {
  if (nullptr != datapoints) {
    datapoints->addDatapoint("P_bw", &P_bw, sizeof(P_bw));
  }
}

}  // namespace Lc3Enc
