68 lines
2.3 KiB
C++
68 lines
2.3 KiB
C++
#include "OpusCodec.h"
|
||
#include "BoostLog.h"
|
||
|
||
namespace Opus {
|
||
|
||
bool Encoder::open(int32_t samplerate, int32_t channels, uint32_t sampleSize) {
|
||
int error = 0;
|
||
|
||
uint32_t maxFrameSize = samplerate / 1000 * 60 * sampleSize * channels; // opus最大60ms一帧编码
|
||
m_buffer.resize(maxFrameSize);
|
||
|
||
m_encoder = opus_encoder_create(samplerate, channels, OPUS_APPLICATION_AUDIO, &error);
|
||
if (error != OPUS_OK || m_encoder == nullptr) {
|
||
LOG(error) << "opus_encoder_create() failed, status: " << error;
|
||
return false;
|
||
}
|
||
|
||
opus_encoder_ctl(m_encoder, OPUS_SET_VBR(0)); // 0:CBR, 1:VBR
|
||
opus_encoder_ctl(m_encoder, OPUS_SET_VBR_CONSTRAINT(true));
|
||
opus_encoder_ctl(m_encoder, OPUS_SET_BITRATE(96000));
|
||
opus_encoder_ctl(m_encoder, OPUS_SET_COMPLEXITY(8)); // 8 0~10
|
||
opus_encoder_ctl(m_encoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
|
||
opus_encoder_ctl(m_encoder, OPUS_SET_LSB_DEPTH(16)); // 每个采样16个bit,2个byte
|
||
opus_encoder_ctl(m_encoder, OPUS_SET_DTX(0));
|
||
opus_encoder_ctl(m_encoder, OPUS_SET_INBAND_FEC(0));
|
||
|
||
return true;
|
||
}
|
||
|
||
void Encoder::close() {
|
||
if (m_encoder != nullptr) {
|
||
opus_encoder_destroy(m_encoder);
|
||
m_encoder = nullptr;
|
||
}
|
||
}
|
||
|
||
Encoder::~Encoder() {
|
||
close();
|
||
}
|
||
|
||
const Opus::Packet Encoder::encode(const int16_t *pcm, int32_t framesize) {
|
||
Packet ret;
|
||
if (m_encoder == nullptr) return ret;
|
||
ret.byteSize = opus_encode(m_encoder, pcm, framesize, m_buffer.data(), m_buffer.size());
|
||
ret.data = m_buffer.data();
|
||
LOG(info) << "framesize: " << framesize << ", record size: " << ret.byteSize;
|
||
return ret;
|
||
}
|
||
|
||
bool Decoder::open(int32_t samplerate, int32_t channels) {
|
||
|
||
int error = 0;
|
||
m_decoder = opus_decoder_create(samplerate, channels, &error);
|
||
if (error != OPUS_OK || m_decoder == NULL) {
|
||
LOG(error) << "opus_decoder_create() failed, status: " << error;
|
||
return false;
|
||
}
|
||
opus_decoder_ctl(m_decoder, OPUS_SET_LSB_DEPTH(16));
|
||
return true;
|
||
}
|
||
|
||
int32_t Decoder::decode(const uint8_t *data, int32_t dataSize, int16_t *pcm, int32_t pcmBuffer) {
|
||
int32_t decodedSize = opus_decode(m_decoder, data, dataSize, pcm, pcmBuffer, 0);
|
||
LOG(info) << "dataSize: " << dataSize << ", decodes frame size: " << decodedSize;
|
||
return decodedSize;
|
||
}
|
||
|
||
} // namespace Opus
|