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

#include <cmath>

namespace Lc3Enc {

AttackDetector::AttackDetector(const Lc3Config& lc3Config_)
    : lc3Config(lc3Config_),
      M_F((lc3Config.N_ms == Lc3Config::FrameDuration::d10ms)
              ? 160
              : 120),  // 16*N_ms
      F_att(0),
      E_att_last(0),
      A_att_last(0),
      P_att_last(-1) {
  // make sure these states are initially zero as demanded by the specification
  x_att_last[0] = 0;
  x_att_last[1] = 0;
}

AttackDetector::~AttackDetector() {}

void AttackDetector::run(const int16_t* const x_s, uint16_t nbytes) {
  // 3.3.6.1 Overview (d09r06_FhG)
  // -> attack detection active only for higher bitrates and fs>=32000;
  // otherwise defaults are set
  F_att = 0;
  if (lc3Config.Fs < 32000) {
    return;
  }
  bool isActive =
      ((lc3Config.N_ms == Lc3Config::FrameDuration::d10ms) &&
       (lc3Config.Fs == 32000) && (nbytes > 80)) ||
      ((lc3Config.N_ms == Lc3Config::FrameDuration::d10ms) &&
       (lc3Config.Fs >= 44100) && (nbytes >= 100)) ||
      ((lc3Config.N_ms == Lc3Config::FrameDuration::d7p5ms) &&
       (lc3Config.Fs == 32000) && (nbytes >= 61) && (nbytes < 150)) ||
      ((lc3Config.N_ms == Lc3Config::FrameDuration::d7p5ms) &&
       (lc3Config.Fs >= 44100) && (nbytes >= 75) && (nbytes < 150));
  if (!isActive) {
    // Note: in bitrate switching situations we have to set proper states
    E_att_last = 0;
    A_att_last = 0;
    P_att_last = -1;
    return;
  }

  // 3.3.6.2 Downsampling and filtering of input signal (d09r02_F2F)
  // Note: the following section might be converted to int32 instead
  //       of double computation (maybe something for optimization)
  double x_att_extended[M_F + 2];
  x_att_extended[0] = x_att_last[0];
  x_att_extended[1] = x_att_last[1];
  double* x_att = &x_att_extended[2];
  for (uint8_t n = 0; n < M_F; n++)  // downsampling
  {
    x_att[n] = 0;
    for (uint8_t m = 0; m < lc3Config.NF / M_F; m++) {
      x_att[n] += x_s[lc3Config.NF / M_F * n + m];
    }
  }
  x_att_last[0] = x_att[M_F - 2];
  x_att_last[1] = x_att[M_F - 1];
  double* x_hp = x_att_extended;     // just for improve readability
  for (uint8_t n = 0; n < M_F; n++)  // highpass-filtering (in-place!)
  {
    x_hp[n] = 0.375 * x_att[n] - 0.5 * x_att[n - 1] + 0.125 * x_att[n - 2];
  }

  // 3.3.6.3 Energy calculation & 3.3.6.4 Attack detection (d09r06_FhG)
  int8_t P_att = -1;
  const uint8_t N_blocks =
      (lc3Config.N_ms == Lc3Config::FrameDuration::d10ms) ? 4 : 3;  // N_ms/2.5
  for (uint8_t n = 0; n < N_blocks; n++) {
    double E_att = 0;
    for (uint8_t l = 40 * n; l <= (40 * n + 39); l++) {
      E_att += x_hp[l] * x_hp[l];
    }
    double A_att =
        (0.25 * A_att_last > E_att_last) ? 0.25 * A_att_last : E_att_last;
    if (E_att > 8.5 * A_att) {
      // attack detected
      P_att = n;
    }
    E_att_last = E_att;
    A_att_last = A_att;
  }
  const uint8_t T_att = (lc3Config.N_ms == Lc3Config::FrameDuration::d10ms)
                            ? 2
                            : 1;  // floor(N_blocks/2)
  F_att = (P_att >= 0) || (P_att_last >= T_att);
  P_att_last = P_att;  // prepare next frame
}

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

}  // namespace Lc3Enc
