unplugged-vendor/system/bt/embdrv/lc3/Encoder/EncoderTop.cpp

106 lines
3.5 KiB
C++

/*
* EncoderTop.cpp
*
* Copyright 2019 HIMSA II K/S - www.himsa.dk. 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