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

namespace Lc3Enc {

EncoderTop::EncoderTop(uint16_t fs_, DatapointContainer* datapoints_)
    : EncoderTop(Lc3Config(fs_, Lc3Config::FrameDuration::d10ms, 1),
                 datapoints_) {}

EncoderTop::EncoderTop(Lc3Config lc3Config_, DatapointContainer* datapoints_)
    : lc3Config(lc3Config_),
      datapoints(datapoints_),
      encoderCurrentFrame(nullptr),
      encoderPreviousFrame(nullptr),
      mdctEnc(lc3Config),
      attackDetector(lc3Config),
      spectralNoiseShaping(lc3Config, mdctEnc.get_I_fs()),
      temporalNoiseShaping(lc3Config),
      spectralQuantization(lc3Config_.NE, lc3Config_.Fs_ind),
      noiseLevelEstimation(lc3Config),
      frameCount(0) {
  if (nullptr != datapoints) {
    datapoints->addDatapoint("NF", &lc3Config.NF, sizeof(lc3Config.NF));
    mdctEnc.registerDatapoints(datapoints);
    attackDetector.registerDatapoints(datapoints);
    spectralNoiseShaping.registerDatapoints(datapoints);
    temporalNoiseShaping.registerDatapoints(datapoints);
    spectralQuantization.registerDatapoints(datapoints);
    noiseLevelEstimation.registerDatapoints(datapoints);
  }
}

EncoderTop::~EncoderTop() {
  if (nullptr != encoderPreviousFrame) {
    delete encoderPreviousFrame;
    encoderPreviousFrame = nullptr;
  }
  if (nullptr != encoderCurrentFrame) {
    delete encoderCurrentFrame;
    encoderCurrentFrame = nullptr;
  }
}

void EncoderTop::run(const int16_t* x_s, uint16_t byte_count, uint8_t* bytes) {
  frameCount++;
  if ((nullptr == encoderCurrentFrame) ||
      (encoderCurrentFrame->nbytes != byte_count)) {
    // We need to instantiate a new EncoderFrame only
    // when byte_count has been changed. Thus, frequent
    // dynamic memory allocation can be constrained to
    // rate optimized operation.
    if (nullptr != encoderPreviousFrame) {
      delete encoderPreviousFrame;
    }
    encoderPreviousFrame = encoderCurrentFrame;
    encoderCurrentFrame = new EncoderFrame(
        mdctEnc, attackDetector, spectralNoiseShaping, temporalNoiseShaping,
        spectralQuantization, noiseLevelEstimation, lc3Config, byte_count);
    encoderCurrentFrame->linkPreviousFrame(encoderPreviousFrame);
    if (nullptr != datapoints) {
      // Another way to make to call optional would be to split run() into
      //  init(), registerDatapoints() & remaining run() -> we preferred the
      //  simpler
      // API and thus designed this registration being dependent on the
      // availability of datapoints.
      encoderCurrentFrame->registerDatapoints(datapoints);
    }
  }
  encoderCurrentFrame->run(x_s, bytes);
}

}  // namespace Lc3Enc
