69 lines
2.4 KiB
C++
69 lines
2.4 KiB
C++
#include "opus_resampler.h"
|
|
#include "silk_resampler.h"
|
|
#include "esp_log.h"
|
|
|
|
#define TAG "OpusResampler"
|
|
|
|
OpusResampler::OpusResampler() {
|
|
channels_ = 1;
|
|
}
|
|
|
|
OpusResampler::~OpusResampler() {
|
|
}
|
|
|
|
void OpusResampler::Configure(int input_sample_rate, int output_sample_rate, int channels) {
|
|
int encode = input_sample_rate > output_sample_rate ? 1 : 0;
|
|
|
|
// 为每个通道创建独立的重采样器状态
|
|
resampler_states_.resize(channels);
|
|
for (int ch = 0; ch < channels; ch++) {
|
|
auto ret = silk_resampler_init(&resampler_states_[ch], input_sample_rate, output_sample_rate, encode);
|
|
if (ret != 0) {
|
|
ESP_LOGE(TAG, "Failed to initialize resampler for channel %d", ch);
|
|
return;
|
|
}
|
|
}
|
|
|
|
input_sample_rate_ = input_sample_rate;
|
|
output_sample_rate_ = output_sample_rate;
|
|
channels_ = channels;
|
|
|
|
ESP_LOGI(TAG, "Resampler configured with input sample rate %d, output sample rate %d, and channels %d",
|
|
input_sample_rate_, output_sample_rate_, channels_);
|
|
}
|
|
|
|
void OpusResampler::Process(const int16_t *input, int input_samples, int16_t *output) {
|
|
// 计算每通道的样本数
|
|
int samples_per_channel = input_samples / channels_;
|
|
|
|
// 为每个通道单独处理
|
|
for (int ch = 0; ch < channels_; ch++) {
|
|
// 为当前通道创建临时输入和输出缓冲区
|
|
std::vector<int16_t> ch_input(samples_per_channel);
|
|
std::vector<int16_t> ch_output(GetOutputSamples(samples_per_channel));
|
|
|
|
// 提取当前通道的输入数据
|
|
for (int i = 0; i < samples_per_channel; i++) {
|
|
ch_input[i] = input[i * channels_ + ch];
|
|
}
|
|
|
|
// 处理当前通道
|
|
auto ret = silk_resampler(&resampler_states_[ch], ch_output.data(), ch_input.data(), samples_per_channel);
|
|
if (ret != 0) {
|
|
ESP_LOGE(TAG, "Failed to process resampler for channel %d", ch);
|
|
}
|
|
|
|
// 将当前通道的输出数据放回输出缓冲区
|
|
for (int i = 0; i < ch_output.size(); i++) {
|
|
output[i * channels_ + ch] = ch_output[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
int OpusResampler::GetOutputSamples(int input_samples) const {
|
|
// 计算每通道的输出样本数
|
|
int output_samples_per_channel = (input_samples) * output_sample_rate_ / input_sample_rate_;
|
|
// 返回总输出样本数
|
|
return output_samples_per_channel * channels_;
|
|
}
|