blob: 7c8a9172a385279854cb07a705486611f19be185 [file] [log] [blame]
/*
* 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