2024-08-31 18:00:23 +08:00
|
|
|
#ifndef _APPLICATION_H_
|
|
|
|
|
#define _APPLICATION_H_
|
|
|
|
|
|
2024-11-05 16:50:29 +08:00
|
|
|
#include <freertos/FreeRTOS.h>
|
2024-10-03 06:39:22 +08:00
|
|
|
#include <freertos/event_groups.h>
|
|
|
|
|
#include <freertos/task.h>
|
2025-02-24 14:41:34 +08:00
|
|
|
#include <esp_timer.h>
|
2024-12-06 11:08:49 +08:00
|
|
|
|
|
|
|
|
#include <string>
|
2024-08-31 18:00:23 +08:00
|
|
|
#include <mutex>
|
2025-07-19 22:45:22 +08:00
|
|
|
#include <deque>
|
2025-04-29 18:17:08 +08:00
|
|
|
#include <memory>
|
2024-10-03 06:39:22 +08:00
|
|
|
|
2024-11-14 23:15:43 +08:00
|
|
|
#include "protocol.h"
|
2024-11-05 20:15:00 +08:00
|
|
|
#include "ota.h"
|
2025-07-19 22:45:22 +08:00
|
|
|
#include "audio_service.h"
|
2025-07-18 01:35:31 +08:00
|
|
|
#include "device_state_event.h"
|
2024-10-03 06:39:22 +08:00
|
|
|
|
2025-09-04 12:30:26 +08:00
|
|
|
|
2025-07-19 22:45:22 +08:00
|
|
|
#define MAIN_EVENT_SCHEDULE (1 << 0)
|
|
|
|
|
#define MAIN_EVENT_SEND_AUDIO (1 << 1)
|
|
|
|
|
#define MAIN_EVENT_WAKE_WORD_DETECTED (1 << 2)
|
|
|
|
|
#define MAIN_EVENT_VAD_CHANGE (1 << 3)
|
|
|
|
|
#define MAIN_EVENT_ERROR (1 << 4)
|
|
|
|
|
#define MAIN_EVENT_CHECK_NEW_VERSION_DONE (1 << 5)
|
2025-09-04 12:30:26 +08:00
|
|
|
#define MAIN_EVENT_CLOCK_TICK (1 << 6)
|
|
|
|
|
|
2024-08-31 18:00:23 +08:00
|
|
|
|
2025-05-27 14:58:49 +08:00
|
|
|
enum AecMode {
|
|
|
|
|
kAecOff,
|
|
|
|
|
kAecOnDeviceSide,
|
|
|
|
|
kAecOnServerSide,
|
|
|
|
|
};
|
|
|
|
|
|
2024-08-31 18:00:23 +08:00
|
|
|
class Application {
|
|
|
|
|
public:
|
2024-09-10 05:58:56 +08:00
|
|
|
static Application& GetInstance() {
|
|
|
|
|
static Application instance;
|
|
|
|
|
return instance;
|
|
|
|
|
}
|
2024-11-25 00:59:03 +08:00
|
|
|
// 删除拷贝构造函数和赋值运算符
|
|
|
|
|
Application(const Application&) = delete;
|
|
|
|
|
Application& operator=(const Application&) = delete;
|
2024-09-10 05:58:56 +08:00
|
|
|
|
2024-08-31 18:00:23 +08:00
|
|
|
void Start();
|
2025-08-02 01:27:14 +08:00
|
|
|
void MainEventLoop();
|
2025-01-05 19:34:28 +08:00
|
|
|
DeviceState GetDeviceState() const { return device_state_; }
|
2025-07-19 22:45:22 +08:00
|
|
|
bool IsVoiceDetected() const { return audio_service_.IsVoiceDetected(); }
|
2024-10-29 00:22:29 +08:00
|
|
|
void Schedule(std::function<void()> callback);
|
2025-01-05 19:34:28 +08:00
|
|
|
void SetDeviceState(DeviceState state);
|
2025-02-19 23:54:59 +08:00
|
|
|
void Alert(const char* status, const char* message, const char* emotion = "", const std::string_view& sound = "");
|
2025-03-03 07:29:22 +08:00
|
|
|
void DismissAlert();
|
2024-11-25 00:59:03 +08:00
|
|
|
void AbortSpeaking(AbortReason reason);
|
2024-11-06 06:18:56 +08:00
|
|
|
void ToggleChatState();
|
2024-11-25 00:59:03 +08:00
|
|
|
void StartListening();
|
|
|
|
|
void StopListening();
|
2025-02-16 06:59:19 +08:00
|
|
|
void Reboot();
|
2025-02-17 18:47:21 +08:00
|
|
|
void WakeWordInvoke(const std::string& wake_word);
|
2025-03-05 09:37:13 +08:00
|
|
|
bool CanEnterSleepMode();
|
2025-05-22 19:19:36 +08:00
|
|
|
void SendMcpMessage(const std::string& payload);
|
2025-05-27 14:58:49 +08:00
|
|
|
void SetAecMode(AecMode mode);
|
|
|
|
|
AecMode GetAecMode() const { return aec_mode_; }
|
2025-07-19 22:45:22 +08:00
|
|
|
void PlaySound(const std::string_view& sound);
|
|
|
|
|
AudioService& GetAudioService() { return audio_service_; }
|
2024-09-10 05:58:56 +08:00
|
|
|
|
2024-08-31 18:00:23 +08:00
|
|
|
private:
|
2024-09-10 05:58:56 +08:00
|
|
|
Application();
|
|
|
|
|
~Application();
|
|
|
|
|
|
2024-10-03 06:39:22 +08:00
|
|
|
std::mutex mutex_;
|
2025-07-19 22:45:22 +08:00
|
|
|
std::deque<std::function<void()>> main_tasks_;
|
2024-12-04 02:12:20 +08:00
|
|
|
std::unique_ptr<Protocol> protocol_;
|
2025-02-24 14:41:34 +08:00
|
|
|
EventGroupHandle_t event_group_ = nullptr;
|
|
|
|
|
esp_timer_handle_t clock_timer_handle_ = nullptr;
|
2025-01-05 19:34:28 +08:00
|
|
|
volatile DeviceState device_state_ = kDeviceStateUnknown;
|
2025-03-30 09:07:08 +08:00
|
|
|
ListeningMode listening_mode_ = kListeningModeAutoStop;
|
2025-05-27 14:58:49 +08:00
|
|
|
AecMode aec_mode_ = kAecOff;
|
2025-07-19 22:45:22 +08:00
|
|
|
std::string last_error_message_;
|
|
|
|
|
AudioService audio_service_;
|
2025-05-27 14:58:49 +08:00
|
|
|
|
2025-06-24 04:59:00 +08:00
|
|
|
bool has_server_time_ = false;
|
2024-11-29 11:06:05 +08:00
|
|
|
bool aborted_ = false;
|
2025-03-04 06:27:11 +08:00
|
|
|
int clock_ticks_ = 0;
|
2025-03-30 09:07:08 +08:00
|
|
|
TaskHandle_t check_new_version_task_handle_ = nullptr;
|
2025-09-15 23:55:04 +08:00
|
|
|
TaskHandle_t main_event_loop_task_handle_ = nullptr;
|
2024-08-31 18:00:23 +08:00
|
|
|
|
2025-07-19 22:45:22 +08:00
|
|
|
void OnWakeWordDetected();
|
2025-06-24 04:59:00 +08:00
|
|
|
void CheckNewVersion(Ota& ota);
|
|
|
|
|
void ShowActivationCode(const std::string& code, const std::string& message);
|
2025-03-30 09:07:08 +08:00
|
|
|
void SetListeningMode(ListeningMode mode);
|
2024-08-31 18:00:23 +08:00
|
|
|
};
|
|
|
|
|
|
2025-09-15 23:55:04 +08:00
|
|
|
|
|
|
|
|
class TaskPriorityReset {
|
|
|
|
|
public:
|
|
|
|
|
TaskPriorityReset(BaseType_t priority) {
|
|
|
|
|
original_priority_ = uxTaskPriorityGet(NULL);
|
|
|
|
|
vTaskPrioritySet(NULL, priority);
|
|
|
|
|
}
|
|
|
|
|
~TaskPriorityReset() {
|
|
|
|
|
vTaskPrioritySet(NULL, original_priority_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
BaseType_t original_priority_;
|
|
|
|
|
};
|
|
|
|
|
|
2024-08-31 18:00:23 +08:00
|
|
|
#endif // _APPLICATION_H_
|