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
|