Files
xiaozhi-esp32/main/application.h

145 lines
4.3 KiB
C
Raw Normal View History

2024-08-31 18:00:23 +08:00
#ifndef _APPLICATION_H_
#define _APPLICATION_H_
#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>
2024-09-03 13:57:18 +08:00
#include <list>
#include <vector>
#include <condition_variable>
2025-04-29 18:17:08 +08:00
#include <memory>
2024-10-03 06:39:22 +08:00
2024-12-06 11:08:49 +08:00
#include <opus_encoder.h>
#include <opus_decoder.h>
#include <opus_resampler.h>
2024-11-14 23:15:43 +08:00
#include "protocol.h"
2024-11-05 20:15:00 +08:00
#include "ota.h"
2024-11-29 11:06:05 +08:00
#include "background_task.h"
2025-04-29 18:17:08 +08:00
#include "audio_processor.h"
#include "wake_word.h"
2025-06-06 20:24:00 +08:00
#include "audio_debugger.h"
2024-10-03 06:39:22 +08:00
2024-11-29 11:06:05 +08:00
#define SCHEDULE_EVENT (1 << 0)
#define SEND_AUDIO_EVENT (1 << 1)
#define CHECK_NEW_VERSION_DONE_EVENT (1 << 2)
2024-08-31 18:00:23 +08:00
enum AecMode {
kAecOff,
kAecOnDeviceSide,
kAecOnServerSide,
};
2025-01-05 19:34:28 +08:00
enum DeviceState {
kDeviceStateUnknown,
kDeviceStateStarting,
kDeviceStateWifiConfiguring,
kDeviceStateIdle,
kDeviceStateConnecting,
kDeviceStateListening,
kDeviceStateSpeaking,
kDeviceStateUpgrading,
kDeviceStateActivating,
kDeviceStateAudioTesting,
2025-01-05 19:34:28 +08:00
kDeviceStateFatalError
2024-08-31 18:00:23 +08:00
};
2024-11-15 04:44:53 +08:00
#define OPUS_FRAME_DURATION_MS 60
#define MAX_AUDIO_PACKETS_IN_QUEUE (2400 / OPUS_FRAME_DURATION_MS)
#define AUDIO_TESTING_MAX_DURATION_MS 10000
2024-11-15 04:44:53 +08:00
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;
}
// 删除拷贝构造函数和赋值运算符
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-01-05 19:34:28 +08:00
DeviceState GetDeviceState() const { return device_state_; }
bool IsVoiceDetected() const { return voice_detected_; }
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 = "");
void DismissAlert();
void AbortSpeaking(AbortReason reason);
2024-11-06 06:18:56 +08:00
void ToggleChatState();
void StartListening();
void StopListening();
2024-12-06 11:08:49 +08:00
void UpdateIotStates();
void Reboot();
void WakeWordInvoke(const std::string& wake_word);
void PlaySound(const std::string_view& sound);
2025-03-05 09:37:13 +08:00
bool CanEnterSleepMode();
2025-05-22 19:19:36 +08:00
void SendMcpMessage(const std::string& payload);
void SetAecMode(AecMode mode);
AecMode GetAecMode() const { return aec_mode_; }
BackgroundTask* GetBackgroundTask() const { return background_task_; }
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();
std::unique_ptr<WakeWord> wake_word_;
2025-04-29 18:17:08 +08:00
std::unique_ptr<AudioProcessor> audio_processor_;
2025-06-06 20:24:00 +08:00
std::unique_ptr<AudioDebugger> audio_debugger_;
2024-11-05 20:15:00 +08:00
Ota ota_;
2024-10-03 06:39:22 +08:00
std::mutex mutex_;
std::list<std::function<void()>> main_tasks_;
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;
ListeningMode listening_mode_ = kListeningModeAutoStop;
AecMode aec_mode_ = kAecOff;
2024-11-29 11:06:05 +08:00
bool aborted_ = false;
2025-01-05 19:34:28 +08:00
bool voice_detected_ = false;
2025-04-13 23:12:44 +08:00
bool busy_decoding_audio_ = false;
int clock_ticks_ = 0;
TaskHandle_t check_new_version_task_handle_ = nullptr;
2024-08-31 18:00:23 +08:00
// Audio encode / decode
TaskHandle_t audio_loop_task_handle_ = nullptr;
2025-01-13 06:49:01 +08:00
BackgroundTask* background_task_ = nullptr;
2024-11-29 11:06:05 +08:00
std::chrono::steady_clock::time_point last_output_time_;
std::list<AudioStreamPacket> audio_send_queue_;
2025-04-28 23:10:24 +08:00
std::list<AudioStreamPacket> audio_decode_queue_;
std::condition_variable audio_decode_cv_;
std::list<AudioStreamPacket> audio_testing_queue_;
2024-08-31 18:00:23 +08:00
// 新增用于维护音频包的timestamp队列
std::list<uint32_t> timestamp_queue_;
std::mutex timestamp_mutex_;
std::unique_ptr<OpusEncoderWrapper> opus_encoder_;
std::unique_ptr<OpusDecoderWrapper> opus_decoder_;
2024-08-31 18:00:23 +08:00
2024-10-24 09:53:08 +08:00
OpusResampler input_resampler_;
2024-11-03 01:34:18 +08:00
OpusResampler reference_resampler_;
2024-10-24 09:53:08 +08:00
OpusResampler output_resampler_;
2024-10-01 14:16:12 +08:00
void MainEventLoop();
void OnAudioInput();
void OnAudioOutput();
bool ReadAudio(std::vector<int16_t>& data, int sample_rate, int samples);
2024-11-29 11:06:05 +08:00
void ResetDecoder();
void SetDecodeSampleRate(int sample_rate, int frame_duration);
void CheckNewVersion();
void ShowActivationCode();
2025-02-24 14:41:34 +08:00
void OnClockTimer();
void SetListeningMode(ListeningMode mode);
void AudioLoop();
void EnterAudioTestingMode();
void ExitAudioTestingMode();
2024-08-31 18:00:23 +08:00
};
#endif // _APPLICATION_H_