小智聊天机器人声音代码解析
以main\boards\bread-compact-wifi\compact_wifi_board.cc为例,详细讲解下面代码:
class CompactWifiBoard : public WifiBoard {
private:
i2c_master_bus_handle_t display_i2c_bus_;
Button boot_button_;
Button touch_button_;
Button volume_up_button_;
Button volume_down_button_;
void InitializeDisplayI2c() {
i2c_master_bus_config_t bus_config = {
.i2c_port = (i2c_port_t)0,
.sda_io_num = DISPLAY_SDA_PIN,
.scl_io_num = DISPLAY_SCL_PIN,
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.intr_priority = 0,
.trans_queue_depth = 0,
.flags = {
.enable_internal_pullup = 1,
},
};
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &display_i2c_bus_));
}
void InitializeButtons() {
boot_button_.OnClick([this]() {
auto& app = Application::GetInstance();
if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
ResetWifiConfiguration();
}
app.ToggleChatState();
});
touch_button_.OnPressDown([this]() {
Application::GetInstance().StartListening();
});
touch_button_.OnPressUp([this]() {
Application::GetInstance().StopListening();
});
volume_up_button_.OnClick([this]() {
auto codec = GetAudioCodec();
auto volume = codec->output_volume() + 10;
if (volume > 100) {
volume = 100;
}
codec->SetOutputVolume(volume);
GetDisplay()->ShowNotification("音量 " + std::to_string(volume));
});
volume_up_button_.OnLongPress([this]() {
GetAudioCodec()->SetOutputVolume(100);
GetDisplay()->ShowNotification("最大音量");
});
volume_down_button_.OnClick([this]() {
auto codec = GetAudioCodec();
auto volume = codec->output_volume() - 10;
if (volume < 0) {
volume = 0;
}
codec->SetOutputVolume(volume);
GetDisplay()->ShowNotification("音量 " + std::to_string(volume));
});
volume_down_button_.OnLongPress([this]() {
GetAudioCodec()->SetOutputVolume(0);
GetDisplay()->ShowNotification("已静音");
});
}
// 物联网初始化,添加对 AI 可见设备
void InitializeIot() {
auto& thing_manager = iot::ThingManager::GetInstance();
thing_manager.AddThing(iot::CreateThing("Speaker"));
thing_manager.AddThing(iot::CreateThing("Lamp"));
}
public:
CompactWifiBoard() :
boot_button_(BOOT_BUTTON_GPIO),
touch_button_(TOUCH_BUTTON_GPIO),
volume_up_button_(VOLUME_UP_BUTTON_GPIO),
volume_down_button_(VOLUME_DOWN_BUTTON_GPIO) {
InitializeDisplayI2c();
InitializeButtons();
InitializeIot();
}
virtual Led* GetLed() override {
static SingleLed led(BUILTIN_LED_GPIO);
return &led;
}
virtual AudioCodec* GetAudioCodec() override {
#ifdef AUDIO_I2S_METHOD_SIMPLEX
static NoAudioCodecSimplex audio_codec(
AUDIO_INPUT_SAMPLE_RATE,
AUDIO_OUTPUT_SAMPLE_RATE
AUDIO_I2S_SPK_GPIO_BCLK,
AUDIO_I2S_SPK_GPIO_LRCK,
AUDIO_I2S_SPK_GPIO_DOUT,
AUDIO_I2S_MIC_GPIO_SCK,
AUDIO_I2S_MIC_GPIO_WS,
AUDIO_I2S_MIC_GPIO_DIN);
#else
static NoAudioCodecDuplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN);
#endif
return &audio_codec;
}
virtual Display* GetDisplay() override {
static Ssd1306Display display(display_i2c_bus_, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y,
&font_puhui_14_1, &font_awesome_14_1);
return &display;
}
};
DECLARE_BOARD(CompactWifiBoard);
这段代码定义了一个名为 CompactWifiBoard
的类,该类继承自 WifiBoard
。CompactWifiBoard
类封装了一个紧凑型 WiFi 板的功能,包括显示、按钮、音频编解码器、LED 等硬件的初始化和控制。以下是对代码的详细讲解:
1. 类成员变量
private:
i2c_master_bus_handle_t display_i2c_bus_;
Button boot_button_;
Button touch_button_;
Button volume_up_button_;
Button volume_down_button_;
display_i2c_bus_
: 用于管理显示设备的 I2C 总线句柄。boot_button_
,touch_button_
,volume_up_button_
,volume_down_button_
: 分别表示启动按钮、触摸按钮、音量增加按钮和音量减少按钮的Button
对象。
2. 初始化显示 I2C 总线
void InitializeDisplayI2c() {
i2c_master_bus_config_t bus_config = {
.i2c_port = (i2c_port_t)0,
.sda_io_num = DISPLAY_SDA_PIN,
.scl_io_num = DISPLAY_SCL_PIN,
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.intr_priority = 0,
.trans_queue_depth = 0,
.flags = {
.enable_internal_pullup = 1,
},
};
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &display_i2c_bus_));
}
InitializeDisplayI2c()
函数用于初始化显示设备的 I2C 总线。bus_config
是一个结构体,包含了 I2C 总线的配置参数,如端口号、SDA 和 SCL 引脚、时钟源等。ESP_ERROR_CHECK
是一个宏,用于检查 I2C 总线初始化是否成功,如果失败则抛出错误。
3. 初始化按钮
void InitializeButtons() {
boot_button_.OnClick([this]() {
auto& app = Application::GetInstance();
if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
ResetWifiConfiguration();
}
app.ToggleChatState();
});
touch_button_.OnPressDown([this]() {
Application::GetInstance().StartListening();
});
touch_button_.OnPressUp([this]() {
Application::GetInstance().StopListening();
});
volume_up_button_.OnClick([this]() {
auto codec = GetAudioCodec();
auto volume = codec->output_volume() + 10;
if (volume > 100) {
volume = 100;
}
codec->SetOutputVolume(volume);
GetDisplay()->ShowNotification("音量 " + std::to_string(volume));
});
volume_up_button_.OnLongPress([this]() {
GetAudioCodec()->SetOutputVolume(100);
GetDisplay()->ShowNotification("最大音量");
});
volume_down_button_.OnClick([this]() {
auto codec = GetAudioCodec();
auto volume = codec->output_volume() - 10;
if (volume < 0) {
volume = 0;
}
codec->SetOutputVolume(volume);
GetDisplay()->ShowNotification("音量 " + std::to_string(volume));
});
volume_down_button_.OnLongPress([this]() {
GetAudioCodec()->SetOutputVolume(0);
GetDisplay()->ShowNotification("已静音");
});
}
InitializeButtons()
函数用于初始化按钮并设置按钮的事件处理函数。boot_button_
的OnClick
事件处理函数在按钮点击时执行,用于重置 WiFi 配置或切换聊天状态。touch_button_
的OnPressDown
和OnPressUp
事件处理函数分别在按钮按下和释放时执行,用于开始和停止监听。volume_up_button_
和volume_down_button_
的OnClick
事件处理函数分别用于增加和减少音量,并在屏幕上显示音量信息。volume_up_button_
和volume_down_button_
的OnLongPress
事件处理函数分别用于将音量设置为最大值和静音。
4. 初始化物联网设备
void InitializeIot() {
auto& thing_manager = iot::ThingManager::GetInstance();
thing_manager.AddThing(iot::CreateThing("Speaker"));
thing_manager.AddThing(iot::CreateThing("Lamp"));
}
InitializeIot()
函数用于初始化物联网设备,将“Speaker”和“Lamp”添加到物联网设备管理器中。
5. 构造函数
public:
CompactWifiBoard() :
boot_button_(BOOT_BUTTON_GPIO),
touch_button_(TOUCH_BUTTON_GPIO),
volume_up_button_(VOLUME_UP_BUTTON_GPIO),
volume_down_button_(VOLUME_DOWN_BUTTON_GPIO) {
InitializeDisplayI2c();
InitializeButtons();
InitializeIot();
}
CompactWifiBoard
的构造函数初始化了按钮对象,并调用了InitializeDisplayI2c()
、InitializeButtons()
和InitializeIot()
函数,完成硬件和物联网设备的初始化。
6. 获取 LED 对象
virtual Led* GetLed() override {
static SingleLed led(BUILTIN_LED_GPIO);
return &led;
}
GetLed()
函数返回一个SingleLed
对象,用于控制内置 LED。
7. 获取音频编解码器对象
virtual AudioCodec* GetAudioCodec() override {
#ifdef AUDIO_I2S_METHOD_SIMPLEX
static NoAudioCodecSimplex audio_codec(
AUDIO_INPUT_SAMPLE_RATE,
AUDIO_OUTPUT_SAMPLE_RATE
AUDIO_I2S_SPK_GPIO_BCLK,
AUDIO_I2S_SPK_GPIO_LRCK,
AUDIO_I2S_SPK_GPIO_DOUT,
AUDIO_I2S_MIC_GPIO_SCK,
AUDIO_I2S_MIC_GPIO_WS,
AUDIO_I2S_MIC_GPIO_DIN);
#else
static NoAudioCodecDuplex audio_codec(AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN);
#endif
return &audio_codec;
}
GetAudioCodec()
函数根据编译时的宏定义返回一个NoAudioCodecSimplex
或NoAudioCodecDuplex
对象,用于控制音频编解码器。
8. 获取显示对象
virtual Display* GetDisplay() override {
static Ssd1306Display display(display_i2c_bus_, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y,
&font_puhui_14_1, &font_awesome_14_1);
return &display;
}
GetDisplay()
函数返回一个Ssd1306Display
对象,用于控制显示设备。
9. 声明板子
DECLARE_BOARD(CompactWifiBoard);
DECLARE_BOARD
宏用于声明CompactWifiBoard
类为一个板子类型,可能在某个框架中用于注册或识别该板子。
总结
CompactWifiBoard
类封装了一个紧凑型 WiFi 板的硬件控制和初始化逻辑,包括显示、按钮、音频编解码器、LED 等。通过继承 WifiBoard
类,它可能还继承了与 WiFi 相关的功能。代码中使用了事件驱动的方式来处理按钮的点击和长按事件,并通过物联网设备管理器添加了“Speaker”和“Lamp”设备。