diff --git a/README.md b/README.md index eef3c79..aa4016c 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,105 @@ 2. 内置API调用失败怎么办? 请查看具体错误代码后,加入QQ群:865754861,或电报群 http://t.me/MeowMusicServer 给出错误代码和日志,等待我们修复。 +3. 歌曲播放时唤醒词不生效怎么办? + +把main\application.cc文件的AddAudioData方法改成如下代码 + +``` c++ +void Application::AddAudioData(AudioStreamPacket&& packet) { + auto codec = Board::GetInstance().GetAudioCodec(); + if (device_state_ == kDeviceStateIdle && codec->output_enabled()) { + // packet.payload包含的是原始PCM数据(int16_t) + if (packet.payload.size() >= 2) { + size_t num_samples = packet.payload.size() / sizeof(int16_t); + std::vector pcm_data(num_samples); + memcpy(pcm_data.data(), packet.payload.data(), packet.payload.size()); + + // 检查采样率是否匹配,如果不匹配则进行简单重采样 + if (packet.sample_rate != codec->output_sample_rate()) { + // ESP_LOGI(TAG, "Resampling music audio from %d to %d Hz", + // packet.sample_rate, codec->output_sample_rate()); + + // 验证采样率参数 + if (packet.sample_rate <= 0 || codec->output_sample_rate() <= 0) { + ESP_LOGE(TAG, "Invalid sample rates: %d -> %d", + packet.sample_rate, codec->output_sample_rate()); + return; + } + + std::vector resampled; + + // 使用浮点数计算精确的重采样比率Add commentMore actions + float ratio = static_cast(packet.sample_rate) / codec->output_sample_rate(); + + if (packet.sample_rate > codec->output_sample_rate()) { + // 降采样:按精确比率跳跃采样 + size_t expected_size = static_cast(pcm_data.size() / ratio + 0.5f); + resampled.reserve(expected_size); + + for (float i = 0; i < pcm_data.size(); i += ratio) { + size_t index = static_cast(i + 0.5f); // 四舍五入 + if (index < pcm_data.size()) { + resampled.push_back(pcm_data[index]); + } + } + + ESP_LOGD(TAG, "Downsampled %d -> %d samples (ratio: %.3f)", + pcm_data.size(), resampled.size(), ratio); + + } else { + // 上采样:线性插值 + float upsample_ratio = codec->output_sample_rate() / static_cast(packet.sample_rate); + size_t expected_size = static_cast(pcm_data.size() * upsample_ratio + 0.5f); + resampled.reserve(expected_size); + + for (size_t i = 0; i < pcm_data.size(); ++i) { + // 添加原始样本 + resampled.push_back(pcm_data[i]); + + // 计算需要插值的样本数 + int interpolation_count = static_cast(upsample_ratio) - 1; + if (interpolation_count > 0 && i + 1 < pcm_data.size()) { + int16_t current = pcm_data[i]; + int16_t next = pcm_data[i + 1]; + for (int j = 1; j <= interpolation_count; ++j) { + float t = static_cast(j) / (interpolation_count + 1); + int16_t interpolated = static_cast(current + (next - current) * t); + resampled.push_back(interpolated); + } + } else if (interpolation_count > 0) { + // 最后一个样本,直接重复 + for (int j = 1; j <= interpolation_count; ++j) { + resampled.push_back(pcm_data[i]); + } + } + } + + ESP_LOGI(TAG, "Upsampled %d -> %d samples (ratio: %.2f)", + pcm_data.size(), resampled.size(), upsample_ratio); + } + + pcm_data = std::move(resampled); + } + + // 确保音频输出已启用 + if (!codec->output_enabled()) { + codec->EnableOutput(true); + } + + // 发送PCM数据到音频编解码器 + codec->OutputData(pcm_data); + + // 更新最后输出时间,防止OnAudioOutput自动禁用音频 + { + std::lock_guard lock(mutex_); + last_output_time_ = std::chrono::steady_clock::now(); + } + } + } +} +``` + ### ⚙️已支持硬件芯片系列 - ESP32