86 lines
2.6 KiB
C++
86 lines
2.6 KiB
C++
/*
|
|
*******************************************************************************
|
|
* INCLUDE
|
|
*******************************************************************************
|
|
*/
|
|
#include "AudioEncoder.h"
|
|
#include "Logger.h"
|
|
|
|
namespace Video
|
|
{
|
|
namespace LibOPUS
|
|
{
|
|
/*
|
|
*******************************************************************************
|
|
* CLASS DEFINE
|
|
*******************************************************************************
|
|
*/
|
|
AudioEncoder::AudioEncoder(Core::CodecID codecID)
|
|
: Core::AudioEncoder(Poco::format("LibOPUS::AudioEncoder(%s)", Core::codecIDToString(codecID)), codecID),
|
|
_pEncoder(nullptr)
|
|
{
|
|
}
|
|
|
|
AudioEncoder::~AudioEncoder()
|
|
{
|
|
}
|
|
|
|
void AudioEncoder::initialize()
|
|
{
|
|
setSampleRate(48000);
|
|
setFrameSize(960);
|
|
setSampleFormat(Core::SampleFormat::S16);
|
|
|
|
int channels = Core::channelLayoutChannels(getChannelLayout());
|
|
int err;
|
|
_pEncoder = opus_encoder_create(getSampleRate(), channels, OPUS_APPLICATION_AUDIO, &err);
|
|
if (err != OPUS_OK)
|
|
throw Poco::InvalidAccessException(
|
|
Poco::format("%s: Create encoder FAIL: %d(%s)", name(), err, std::string(opus_strerror(err))), err);
|
|
|
|
opus_encoder_ctl(_pEncoder, OPUS_SET_BITRATE(getBitrate()));
|
|
opus_encoder_ctl(_pEncoder, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
|
|
opus_encoder_ctl(_pEncoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
|
|
opus_encoder_ctl(_pEncoder, OPUS_SET_VBR(1));
|
|
opus_encoder_ctl(_pEncoder, OPUS_SET_LSB_DEPTH(Core::sampleFormatBitWidth(getSampleFormat())));
|
|
opus_encoder_ctl(_pEncoder, OPUS_SET_DTX(0));
|
|
opus_encoder_ctl(_pEncoder, OPUS_SET_COMPLEXITY(1));
|
|
}
|
|
|
|
void AudioEncoder::deinitialize()
|
|
{
|
|
if (_pEncoder)
|
|
{
|
|
opus_encoder_destroy(_pEncoder);
|
|
_pEncoder = nullptr;
|
|
}
|
|
}
|
|
|
|
#define PACKET_MAX_LEN 8192
|
|
Core::Packet::Ptr AudioEncoder::encode()
|
|
{
|
|
if (!_pEncoder)
|
|
return nullptr;
|
|
|
|
auto pIn = readFrame();
|
|
if (pIn.isNull())
|
|
return nullptr;
|
|
|
|
uint8_t* pBuffer = new uint8_t[PACKET_MAX_LEN];
|
|
int32_t len = opus_encode(_pEncoder, (int16_t*)pIn->data[0].get(), getFrameSize(), pBuffer, PACKET_MAX_LEN);
|
|
if (len < 0 || len > PACKET_MAX_LEN)
|
|
{
|
|
delete[] pBuffer;
|
|
logger().error("%s: Encode FAIL: %d(%s)", name(), len, std::string(opus_strerror(len)));
|
|
return nullptr;
|
|
}
|
|
|
|
return new Core::Packet(serialCodeManager().code(), 0, pBuffer, len, pIn->timestamp, pIn->timestamp);
|
|
}
|
|
|
|
void AudioEncoder::onConfigChanged(ParameterNames& names)
|
|
{
|
|
Core::AudioEncoder::onConfigChanged(names);
|
|
}
|
|
}
|
|
}
|