#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