#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_err_t err = i2s_channel_enable(tx_handle_); if (err == ESP_ERR_INVALID_STATE) { // 已经启用,忽略 ESP_LOGW(TAG, "TX channel already enabled"); } else { ESP_ERROR_CHECK(err); } } if (rx_handle_ != nullptr) { esp_err_t err = i2s_channel_enable(rx_handle_); if (err == ESP_ERR_INVALID_STATE) { ESP_LOGW(TAG, "RX channel already enabled"); } else { ESP_ERROR_CHECK(err); } } 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; } }