forked from xiaozhi/xiaozhi-esp32
add volume up gpio button
This commit is contained in:
@@ -17,7 +17,8 @@
|
||||
|
||||
|
||||
Application::Application()
|
||||
: button_((gpio_num_t)CONFIG_BOOT_BUTTON_GPIO)
|
||||
: boot_button_((gpio_num_t)CONFIG_BOOT_BUTTON_GPIO),
|
||||
volume_up_button_((gpio_num_t)CONFIG_VOLUME_UP_BUTTON_GPIO)
|
||||
#ifdef CONFIG_USE_ML307
|
||||
, ml307_at_modem_(CONFIG_ML307_TX_PIN, CONFIG_ML307_RX_PIN, 4096),
|
||||
http_(ml307_at_modem_),
|
||||
@@ -220,7 +221,7 @@ void Application::Start() {
|
||||
Application* app = (Application*)arg;
|
||||
app->AudioPlayTask();
|
||||
vTaskDelete(NULL);
|
||||
}, "play_audio", 4096 * 2, this, 5, NULL);
|
||||
}, "play_audio", 4096 * 4, this, 5, NULL);
|
||||
|
||||
#ifdef CONFIG_USE_AFE_SR
|
||||
wake_word_detect_.OnVadStateChange([this](bool speaking) {
|
||||
@@ -286,7 +287,7 @@ void Application::Start() {
|
||||
builtin_led.SetGreen();
|
||||
builtin_led.BlinkOnce();
|
||||
|
||||
button_.OnClick([this]() {
|
||||
boot_button_.OnClick([this]() {
|
||||
Schedule([this]() {
|
||||
if (chat_state_ == kChatStateIdle) {
|
||||
SetChatState(kChatStateConnecting);
|
||||
@@ -312,6 +313,28 @@ void Application::Start() {
|
||||
});
|
||||
});
|
||||
|
||||
volume_up_button_.OnClick([this]() {
|
||||
Schedule([this]() {
|
||||
auto volume = audio_device_.output_volume() + 10;
|
||||
if (volume > 100) {
|
||||
volume = 0;
|
||||
}
|
||||
audio_device_.SetOutputVolume(volume);
|
||||
#ifdef CONFIG_USE_DISPLAY
|
||||
display_.ShowNotification("Volume\n" + std::to_string(volume));
|
||||
#endif
|
||||
});
|
||||
});
|
||||
|
||||
volume_up_button_.OnLongPress([this]() {
|
||||
Schedule([this]() {
|
||||
audio_device_.SetOutputVolume(0);
|
||||
#ifdef CONFIG_USE_DISPLAY
|
||||
display_.ShowNotification("Volume\n0");
|
||||
#endif
|
||||
});
|
||||
});
|
||||
|
||||
xTaskCreate([](void* arg) {
|
||||
Application* app = (Application*)arg;
|
||||
app->MainLoop();
|
||||
|
||||
@@ -84,7 +84,8 @@ private:
|
||||
Application();
|
||||
~Application();
|
||||
|
||||
Button button_;
|
||||
Button boot_button_;
|
||||
Button volume_up_button_;
|
||||
AudioDevice audio_device_;
|
||||
#ifdef CONFIG_USE_AFE_SR
|
||||
WakeWordDetect wake_word_detect_;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "AudioDevice.h"
|
||||
#include <esp_log.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <cmath>
|
||||
#define TAG "AudioDevice"
|
||||
|
||||
AudioDevice::AudioDevice() {
|
||||
@@ -152,8 +152,12 @@ void AudioDevice::CreateSimplexChannels() {
|
||||
|
||||
void AudioDevice::Write(const int16_t* data, int samples) {
|
||||
int32_t buffer[samples];
|
||||
|
||||
// output_volume_: 0-100
|
||||
// volume_factor_: 0-65536
|
||||
int32_t volume_factor = pow(double(output_volume_) / 100.0, 2) * 65536;
|
||||
for (int i = 0; i < samples; i++) {
|
||||
buffer[i] = int32_t(data[i]) << 15;
|
||||
buffer[i] = int32_t(data[i]) * volume_factor;
|
||||
}
|
||||
|
||||
size_t bytes_written;
|
||||
@@ -196,3 +200,8 @@ void AudioDevice::InputTask() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDevice::SetOutputVolume(int volume) {
|
||||
output_volume_ = volume;
|
||||
ESP_LOGI(TAG, "Set output volume to %d", output_volume_);
|
||||
}
|
||||
|
||||
@@ -17,15 +17,17 @@ public:
|
||||
void Start(int input_sample_rate, int output_sample_rate);
|
||||
void OnInputData(std::function<void(const int16_t*, int)> callback);
|
||||
void OutputData(std::vector<int16_t>& data);
|
||||
void SetOutputVolume(int volume);
|
||||
|
||||
int input_sample_rate() const { return input_sample_rate_; }
|
||||
int output_sample_rate() const { return output_sample_rate_; }
|
||||
bool duplex() const { return duplex_; }
|
||||
|
||||
int output_volume() const { return output_volume_; }
|
||||
private:
|
||||
bool duplex_ = false;
|
||||
int input_sample_rate_ = 0;
|
||||
int output_sample_rate_ = 0;
|
||||
int output_volume_ = 80;
|
||||
i2s_chan_handle_t tx_handle_ = nullptr;
|
||||
i2s_chan_handle_t rx_handle_ = nullptr;
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ static const char* TAG = "Button";
|
||||
Button::Button(gpio_num_t gpio_num) : gpio_num_(gpio_num) {
|
||||
button_config_t button_config = {
|
||||
.type = BUTTON_TYPE_GPIO,
|
||||
.long_press_time = 3000,
|
||||
.short_press_time = 100,
|
||||
.long_press_time = 1000,
|
||||
.short_press_time = 50,
|
||||
.gpio_button_config = {
|
||||
.gpio_num = gpio_num,
|
||||
.active_level = 0
|
||||
|
||||
@@ -104,20 +104,29 @@ Display::Display(int sda_pin, int scl_pin) : sda_pin_(sda_pin), scl_pin_(scl_pin
|
||||
lv_label_set_text(label_, "Initializing...");
|
||||
lv_obj_set_width(label_, disp_->driver->hor_res);
|
||||
lv_obj_set_height(label_, disp_->driver->ver_res);
|
||||
lv_obj_set_style_text_line_space(label_, 0, 0);
|
||||
lv_obj_set_style_pad_all(label_, 0, 0);
|
||||
lv_obj_set_style_outline_pad(label_, 0, 0);
|
||||
|
||||
notification_ = lv_label_create(lv_disp_get_scr_act(disp_));
|
||||
lv_label_set_text(notification_, "Notification\nTest");
|
||||
lv_obj_set_width(notification_, disp_->driver->hor_res);
|
||||
lv_obj_set_height(notification_, disp_->driver->ver_res);
|
||||
lv_obj_set_style_opa(notification_, LV_OPA_MIN, 0);
|
||||
lvgl_port_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
Display::~Display() {
|
||||
if (label_ != nullptr) {
|
||||
lvgl_port_lock(0);
|
||||
lv_obj_del(label_);
|
||||
lvgl_port_unlock();
|
||||
if (notification_timer_ != nullptr) {
|
||||
esp_timer_stop(notification_timer_);
|
||||
esp_timer_delete(notification_timer_);
|
||||
}
|
||||
|
||||
lvgl_port_lock(0);
|
||||
if (label_ != nullptr) {
|
||||
lv_obj_del(label_);
|
||||
lv_obj_del(notification_);
|
||||
}
|
||||
lvgl_port_unlock();
|
||||
|
||||
if (disp_ != nullptr) {
|
||||
lvgl_port_deinit();
|
||||
esp_lcd_panel_del(panel_);
|
||||
@@ -136,4 +145,35 @@ void Display::SetText(const std::string &text) {
|
||||
}
|
||||
}
|
||||
|
||||
void Display::ShowNotification(const std::string &text) {
|
||||
if (notification_ != nullptr) {
|
||||
lvgl_port_lock(0);
|
||||
lv_label_set_text(notification_, text.c_str());
|
||||
lv_obj_set_style_opa(notification_, LV_OPA_MAX, 0);
|
||||
lv_obj_set_style_opa(label_, LV_OPA_MIN, 0);
|
||||
lvgl_port_unlock();
|
||||
|
||||
if (notification_timer_ != nullptr) {
|
||||
esp_timer_stop(notification_timer_);
|
||||
esp_timer_delete(notification_timer_);
|
||||
}
|
||||
|
||||
esp_timer_create_args_t timer_args = {
|
||||
.callback = [](void *arg) {
|
||||
Display *display = static_cast<Display*>(arg);
|
||||
lvgl_port_lock(0);
|
||||
lv_obj_set_style_opa(display->notification_, LV_OPA_MIN, 0);
|
||||
lv_obj_set_style_opa(display->label_, LV_OPA_MAX, 0);
|
||||
lvgl_port_unlock();
|
||||
},
|
||||
.arg = this,
|
||||
.dispatch_method = ESP_TIMER_TASK,
|
||||
.name = "Notification Timer",
|
||||
.skip_unhandled_events = false,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_timer_create(&timer_args, ¬ification_timer_));
|
||||
ESP_ERROR_CHECK(esp_timer_start_once(notification_timer_, 3000000));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <esp_lcd_panel_io.h>
|
||||
#include <esp_lcd_panel_ops.h>
|
||||
#include <lvgl.h>
|
||||
#include <esp_timer.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -14,6 +15,7 @@ public:
|
||||
~Display();
|
||||
|
||||
void SetText(const std::string &text);
|
||||
void ShowNotification(const std::string &text);
|
||||
|
||||
private:
|
||||
int sda_pin_;
|
||||
@@ -25,6 +27,8 @@ private:
|
||||
esp_lcd_panel_handle_t panel_ = nullptr;
|
||||
lv_disp_t *disp_ = nullptr;
|
||||
lv_obj_t *label_ = nullptr;
|
||||
lv_obj_t *notification_ = nullptr;
|
||||
esp_timer_handle_t notification_timer_ = nullptr;
|
||||
|
||||
std::string text_;
|
||||
};
|
||||
|
||||
@@ -80,6 +80,12 @@ config BOOT_BUTTON_GPIO
|
||||
help
|
||||
GPIO number of the boot button.
|
||||
|
||||
config VOLUME_UP_BUTTON_GPIO
|
||||
int "Volume Up Button GPIO"
|
||||
default 40
|
||||
help
|
||||
GPIO number of the volume up button.
|
||||
|
||||
config USE_AFE_SR
|
||||
bool "Use Espressif AFE SR"
|
||||
default y
|
||||
|
||||
Reference in New Issue
Block a user