#include "opus_decoder.h" #include #define TAG "OpusDecoderWrapper" OpusDecoderWrapper::OpusDecoderWrapper(int sample_rate, int channels, int duration_ms) : sample_rate_(sample_rate), channels_(channels), duration_ms_(duration_ms) { int error; audio_dec_ = opus_decoder_create(sample_rate, channels, &error); if (audio_dec_ == nullptr) { ESP_LOGE(TAG, "Failed to create audio decoder, error code: %d", error); return; } // frame_size_ 表示每帧的样本数(单个通道) frame_size_ = sample_rate / 1000 * duration_ms; } OpusDecoderWrapper::~OpusDecoderWrapper() { std::lock_guard lock(mutex_); if (audio_dec_ != nullptr) { opus_decoder_destroy(audio_dec_); } } bool OpusDecoderWrapper::Decode(std::vector&& opus, std::vector& pcm) { std::lock_guard lock(mutex_); if (audio_dec_ == nullptr) { ESP_LOGE(TAG, "Audio decoder is not configured"); return false; } // 计算每帧样本数,考虑通道数 int samples_per_channel = sample_rate_ * duration_ms_ / 1000; int total_samples = samples_per_channel * channels_; pcm.resize(total_samples); auto ret = opus_decode(audio_dec_, opus.data(), opus.size(), pcm.data(), samples_per_channel, 0); if (ret < 0) { ESP_LOGE(TAG, "Failed to decode audio, error code: %d", ret); return false; } // 调整pcm大小为实际解码的样本数 int actual_total_samples = ret * channels_; if (actual_total_samples < total_samples) { pcm.resize(actual_total_samples); } return true; } void OpusDecoderWrapper::ResetState() { std::lock_guard lock(mutex_); if (audio_dec_ != nullptr) { opus_decoder_ctl(audio_dec_, OPUS_RESET_STATE); } }