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

#include <cmath>

#include "BandIndexTables.hpp"
#include "MdctWindows.hpp"

namespace Lc3Enc {

MdctEnc::MdctEnc(const Lc3Config& lc3Config_)
    : lc3Config(lc3Config_),
      X(nullptr),
      E_B(nullptr),
      near_nyquist_flag(0),
      dctIVDbl(lc3Config.NF),
      skipMdct(0),
      t(nullptr),
      wN(nullptr),
      I_fs(nullptr) {
  X = dctIVDbl.out;

  E_B = new double[lc3Config.N_b];
  // initialization of E_B skipped since this will be fully re-computed on any
  // run anyway

  t = new int16_t[2 * lc3Config.NF];
  for (uint16_t n = 0; n < 2 * lc3Config.NF; n++) {
    t[n] = 0;
  }

  // Note: we do not add additional configuration error checking at this level.
  //   We assume that there will be nor processing with invalid configuration,
  //   thus nonsense results for invalid lc3Config.N_ms and/or lc3Config.Fs_ind
  //   are accepted here.
  I_fs = &I_8000[0];  // default initialization to avoid warnings
  wN = w_N80;         // default initialization to avoid warnings

  // Note: we do not add additional configuration error checking at this level.
  //   We assume that there will be nor processing with invalid configuration,
  //   thus nonsense results for invalid lc3Config.N_ms and/or lc3Config.Fs_ind
  //   are accepted here.
  if (lc3Config.N_ms == Lc3Config::FrameDuration::d7p5ms) {
    switch (lc3Config.Fs_ind) {
      case 0:
        I_fs = &I_8000_7p5ms[0];
        wN = w_N60_7p5ms;
        break;
      case 1:
        I_fs = &I_16000_7p5ms[0];
        wN = w_N120_7p5ms;
        break;
      case 2:
        I_fs = &I_24000_7p5ms[0];
        wN = w_N180_7p5ms;
        break;
      case 3:
        I_fs = &I_32000_7p5ms[0];
        wN = w_N240_7p5ms;
        break;
      case 4:
        I_fs = &I_48000_7p5ms[0];
        wN = w_N360_7p5ms;
        break;
    }
  } else {
    // Lc3Config::FrameDuration::d10ms (and other as fallback)
    switch (lc3Config.Fs_ind) {
      case 0:
        I_fs = &I_8000[0];
        wN = w_N80;
        break;
      case 1:
        I_fs = &I_16000[0];
        wN = w_N160;
        break;
      case 2:
        I_fs = &I_24000[0];
        wN = w_N240;
        break;
      case 3:
        I_fs = &I_32000[0];
        wN = w_N320;
        break;
      case 4:
        I_fs = &I_48000[0];
        wN = w_N480;
        break;
    }
  }
}

MdctEnc::~MdctEnc() { delete[] t; }

const int* MdctEnc::get_I_fs() const { return I_fs; }

void MdctEnc::MdctFastDbl(const double* const tw) {
  for (uint16_t n = 0; n < lc3Config.NF / 2; n++) {
    dctIVDbl.in[n] =
        -tw[3 * lc3Config.NF / 2 - 1 - n] - tw[3 * lc3Config.NF / 2 + n];
  }
  for (uint16_t n = lc3Config.NF / 2; n < lc3Config.NF; n++) {
    dctIVDbl.in[n] =
        tw[n - lc3Config.NF / 2] - tw[3 * lc3Config.NF / 2 - 1 - n];
  }

  dctIVDbl.run();

  double gain = 1.0 / sqrt(2.0 * lc3Config.NF);
  for (uint16_t k = 0; k < lc3Config.NF; k++) {
    dctIVDbl.out[k] *= gain;
  }
}

void MdctEnc::run(const int16_t* const x_s) {
  if (skipMdct) {
    return;
  }

  // 3.3.4.2 Update time buffer (LC3 Specification d09r02_F2F)
  // Note: specification has strange loop indices
  //  -> corrected start index appropriately
  for (uint16_t n = 0; n < (lc3Config.NF - lc3Config.Z); n++) {
    t[n] = t[lc3Config.NF + n];
  }
  for (uint16_t n = lc3Config.NF - lc3Config.Z;
       n < (2 * lc3Config.NF - lc3Config.Z); n++) {
    t[n] = x_s[lc3Config.Z - lc3Config.NF + n];
  }

  // 3.3.4.3 Time-Frequency Transformation (LC3 Specification d09r02_F2F)
  double tw[2 * lc3Config.NF];
  for (uint16_t n = 0; n < 2 * lc3Config.NF; n++) {
    tw[n] = wN[n] * t[n];
  }
  MdctFastDbl(tw);

  // 3.3.4.4 Energy estimation per band   (d09r02_F2F)
  for (uint8_t b = 0; b < lc3Config.N_b; b++) {
    E_B[b] = 0.0;
    uint16_t width = I_fs[b + 1] - I_fs[b];
    for (uint16_t k = I_fs[b]; k < I_fs[b + 1]; k++) {
      E_B[b] += (X[k] * X[k]) / width;
    }
  }

  // 3.3.4.5 Near Nyquist Detector (LC3 Specification d1.0r03; Errata 15041)
  if (lc3Config.Fs <= 32000) {
    const uint16_t nn_idx = (lc3Config.N_ms == Lc3Config::FrameDuration::d7p5ms)
                                ? lc3Config.N_b - 4
                                : lc3Config.N_b - 2;
    double upperBandsEnergy = 0;
    double lowerBandsEnergy = 0;
    for (uint8_t n = 0; n < lc3Config.N_b; n++) {
      if (n < nn_idx) {
        lowerBandsEnergy += E_B[n];
      } else {
        upperBandsEnergy += E_B[n];
      }
    }
    const double NN_thresh = 30;
    near_nyquist_flag =
        (upperBandsEnergy > NN_thresh * lowerBandsEnergy) ? 1 : 0;
  } else {
    near_nyquist_flag = 0;
  }
}

void MdctEnc::registerDatapoints(DatapointContainer* datapoints) {
  if (nullptr != datapoints) {
    datapoints->addDatapoint("skipMdct", &skipMdct, sizeof(skipMdct));
    datapoints->addDatapoint("X", &X[0], sizeof(double) * lc3Config.NF);
    datapoints->addDatapoint("E_B", &E_B[0], sizeof(double) * lc3Config.N_b);
    datapoints->addDatapoint("near_nyquist_flag", &near_nyquist_flag,
                             sizeof(near_nyquist_flag));
  }
}

}  // namespace Lc3Enc
