99 lines
3 KiB
C++
99 lines
3 KiB
C++
/*
|
|
*******************************************************************************
|
|
* INCLUDE
|
|
*******************************************************************************
|
|
*/
|
|
#include "AudioEncoder.h"
|
|
#include "Logger.h"
|
|
#include "../core/System.h"
|
|
|
|
namespace Video
|
|
{
|
|
namespace Shine
|
|
{
|
|
/*
|
|
*******************************************************************************
|
|
* CLASS DEFINE
|
|
*******************************************************************************
|
|
*/
|
|
AudioEncoder::AudioEncoder(Core::CodecID codecID)
|
|
: Core::AudioEncoder(Poco::format("Shine::AudioEncoder(%s)", Core::codecIDToString(codecID)), codecID),
|
|
_pEncoder(nullptr)
|
|
{
|
|
shine_set_config_mpeg_defaults(&_config.mpeg);
|
|
}
|
|
|
|
AudioEncoder::~AudioEncoder()
|
|
{
|
|
}
|
|
|
|
void AudioEncoder::initialize()
|
|
{
|
|
setSampleFormat(Core::SampleFormat::S16);
|
|
|
|
int channels = Core::channelLayoutChannels(getChannelLayout());
|
|
|
|
_config.wave.channels = channels > 1 ? PCM_STEREO : PCM_MONO;
|
|
_config.wave.samplerate = getSampleRate();
|
|
_config.mpeg.bitr = (int)(getBitrate() / 1000);
|
|
|
|
if (shine_check_config(_config.wave.samplerate, _config.mpeg.bitr) < 0)
|
|
throw Poco::InvalidAccessException(Poco::format("%s: Config error.", name()), -1);
|
|
|
|
_config.mpeg.mode = _config.wave.channels > 1 ? STEREO : MONO;
|
|
|
|
_pEncoder = shine_initialise(&_config);
|
|
dummyConfig(&_config);
|
|
|
|
setFrameSize(shine_samples_per_pass(_pEncoder));
|
|
}
|
|
|
|
void AudioEncoder::deinitialize()
|
|
{
|
|
if (_pEncoder)
|
|
{
|
|
shine_close(_pEncoder);
|
|
_pEncoder = nullptr;
|
|
}
|
|
}
|
|
|
|
Core::Packet::Ptr AudioEncoder::encode()
|
|
{
|
|
if (!_pEncoder)
|
|
return nullptr;
|
|
|
|
auto pIn = readFrame();
|
|
int len;
|
|
uint8_t* pData = shine_encode_buffer_interleaved(_pEncoder, (int16_t*)pIn->data[0].get(), &len);
|
|
if (!pData || len <= 0)
|
|
{
|
|
logger().error("%s: Encode FAIL", name());
|
|
return nullptr;
|
|
}
|
|
|
|
uint8_t* pBuffer = new uint8_t[len];
|
|
memcpy(pBuffer, pData, len);
|
|
|
|
return new Core::Packet(serialCodeManager().code(), 0, pBuffer, len, pIn->timestamp, pIn->timestamp);
|
|
}
|
|
|
|
void AudioEncoder::onConfigChanged(ParameterNames& names)
|
|
{
|
|
Core::AudioEncoder::onConfigChanged(names);
|
|
}
|
|
|
|
void AudioEncoder::dummyConfig(shine_config_t* pConfig)
|
|
{
|
|
static const char* version_names[4] = {"2.5", "reserved", "II", "I"};
|
|
static const char* mode_names[4] = {"stereo", "joint-stereo", "dual-channel", "mono"};
|
|
static const char* demp_names[4] = {"none", "50/15us", "", "CITT"};
|
|
|
|
printf("MPEG-%s layer III, %s Psychoacoustic Model: Shine\n",
|
|
version_names[shine_check_config(pConfig->wave.samplerate, pConfig->mpeg.bitr)],
|
|
mode_names[pConfig->mpeg.mode]);
|
|
printf("Bitrate: %d kbps ", pConfig->mpeg.bitr);
|
|
printf("De-emphasis: %s %s %s\n", demp_names[pConfig->mpeg.emph], ((pConfig->mpeg.original) ? "Original" : ""),
|
|
((pConfig->mpeg.copyright) ? "(C)" : ""));
|
|
}
|
|
}
|
|
}
|