#ifndef _AUDIO_DEVICE_H #define _AUDIO_DEVICE_H #include "opus.h" #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/event_groups.h" #include "driver/i2s_std.h" #include #include #include enum AudioPacketType { kAudioPacketTypeUnkonwn = 0, kAudioPacketTypeStart, kAudioPacketTypeStop, kAudioPacketTypeData, kAudioPacketTypeSentenceStart, kAudioPacketTypeSentenceEnd }; struct AudioPacket { AudioPacketType type = kAudioPacketTypeUnkonwn; std::string text; std::vector opus; std::vector pcm; uint32_t timestamp; }; struct AudioDataHeader { uint32_t version; uint32_t reserved; uint32_t timestamp; uint32_t payload_size; } __attribute__((packed)); class AudioDevice { public: AudioDevice(); ~AudioDevice(); void Start(int input_sample_rate, int output_sample_rate); int Read(int16_t* dest, int samples); void Write(const int16_t* data, int samples); void QueueAudioPacket(AudioPacket* packet); void OnStateChanged(std::function callback); void Break(); int input_sample_rate() const { return input_sample_rate_; } int output_sample_rate() const { return output_sample_rate_; } bool duplex() const { return duplex_; } bool playing() const { return playing_; } private: bool playing_ = false; bool breaked_ = false; bool duplex_ = false; int input_sample_rate_ = 0; int output_sample_rate_ = 0; i2s_chan_handle_t tx_handle_ = nullptr; i2s_chan_handle_t rx_handle_ = nullptr; QueueHandle_t audio_play_queue_ = nullptr; TaskHandle_t audio_play_task_ = nullptr; EventGroupHandle_t event_group_; std::function on_state_changed_; void CreateDuplexChannels(); void CreateSimplexChannels(); void AudioPlayTask(); }; #endif // _AUDIO_DEVICE_H