#include "audio_codec.h" #include "board.h" #include "settings.h" #include #include #include #define TAG "AudioCodec" AudioCodec::AudioCodec(){ } AudioCodec::~AudioCodec(){ } void AudioCodec::OutputData(std::vector &data){ Write(data.data(), data.size()); } bool AudioCodec::InputData(std::vector &data){ int samples = Read(data.data(), data.size()); if (samples > 0){ return true; } return false; } void AudioCodec::Start(){ Settings settings("audio", false); output_volume_ = settings.GetInt("output_volume", output_volume_); if (output_volume_ <= 0){ ESP_LOGW(TAG, "Output volume value (%d) is too small, setting to default (10)", output_volume_); output_volume_ = 10; } // 保存原始输出采样率 if (original_output_sample_rate_ == 0){ original_output_sample_rate_ = output_sample_rate_; ESP_LOGI(TAG, "Saved original output sample rate: %d Hz", original_output_sample_rate_); } if (tx_handle_ != nullptr){ ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); } if (rx_handle_ != nullptr){ ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); } EnableInput(true); EnableOutput(true); ESP_LOGI(TAG, "Audio codec started"); } void AudioCodec::SetOutputVolume(int volume){ output_volume_ = volume; ESP_LOGI(TAG, "Set output volume to %d", output_volume_); Settings settings("audio", true); settings.SetInt("output_volume", output_volume_); } void AudioCodec::EnableInput(bool enable){ if (enable == input_enabled_){ return; } input_enabled_ = enable; ESP_LOGI(TAG, "Set input enable to %s", enable ? "true" : "false"); } void AudioCodec::EnableOutput(bool enable){ if (enable == output_enabled_){ return; } output_enabled_ = enable; ESP_LOGI(TAG, "Set output enable to %s", enable ? "true" : "false"); } bool AudioCodec::SetOutputSampleRate(int sample_rate){ // 特殊处理:如果传入 -1,表示重置到原始采样率 if (sample_rate == -1){ if (original_output_sample_rate_ > 0){ sample_rate = original_output_sample_rate_; ESP_LOGI(TAG, "Resetting to original output sample rate: %d Hz", sample_rate); }else{ ESP_LOGW(TAG, "Original sample rate not available, cannot reset"); return false; } } if (sample_rate <= 0 || sample_rate > 192000){ ESP_LOGE(TAG, "Invalid sample rate: %d", sample_rate); return false; } if (output_sample_rate_ == sample_rate){ ESP_LOGI(TAG, "Sample rate already set to %d Hz", sample_rate); return true; } if (tx_handle_ == nullptr){ ESP_LOGW(TAG, "TX handle is null, only updating sample rate variable"); output_sample_rate_ = sample_rate; return true; } ESP_LOGI(TAG, "Changing output sample rate from %d to %d Hz", output_sample_rate_, sample_rate); // 先尝试禁用 I2S 通道(如果已启用的话) bool was_enabled = false; esp_err_t disable_ret = i2s_channel_disable(tx_handle_); if (disable_ret == ESP_OK){ was_enabled = true; ESP_LOGI(TAG, "Disabled I2S TX channel for reconfiguration"); } else if (disable_ret == ESP_ERR_INVALID_STATE){ // 通道可能已经是禁用状态,这是正常的 ESP_LOGI(TAG, "I2S TX channel was already disabled"); }else{ ESP_LOGW(TAG, "Failed to disable I2S TX channel: %s", esp_err_to_name(disable_ret)); } // 重新配置 I2S 时钟 i2s_std_clk_config_t clk_cfg = { .sample_rate_hz = (uint32_t)sample_rate, .clk_src = I2S_CLK_SRC_DEFAULT, .mclk_multiple = I2S_MCLK_MULTIPLE_256, #ifdef I2S_HW_VERSION_2 .ext_clk_freq_hz = 0, #endif }; esp_err_t ret = i2s_channel_reconfig_std_clock(tx_handle_, &clk_cfg); // 重新启用通道(无论之前是什么状态,现在都需要启用以便播放音频) esp_err_t enable_ret = i2s_channel_enable(tx_handle_); if (enable_ret != ESP_OK){ ESP_LOGE(TAG, "Failed to enable I2S TX channel: %s", esp_err_to_name(enable_ret)); }else{ ESP_LOGI(TAG, "Enabled I2S TX channel"); } if (ret == ESP_OK){ output_sample_rate_ = sample_rate; ESP_LOGI(TAG, "Successfully changed output sample rate to %d Hz", sample_rate); return true; }else{ ESP_LOGE(TAG, "Failed to change sample rate to %d Hz: %s", sample_rate, esp_err_to_name(ret)); return false; } }