// // Created by misaki on 2025/9/9. // #pragma once #include #include #include #include "ThreadManager.h" #include "SDFileManager.h" // 音频播放状态枚举 enum class AudioState { IDLE, // 音频未播放 PLAYING, // 音频播放中 PAUSED, // 音频暂停中 STOPPED, // 音频已停止 ERROR // 音频播放错误 }; // 音频播放回调函数类型 using AudioCallback = std::function; /* * 回调函数示例: void audioCallback(AudioState state, const char* filePath) { switch (state) { case AudioState::PLAYING: ESP_LOGI("Example", "Started playing: %s", filePath); break; case AudioState::PAUSED: ESP_LOGI("Example", "Paused: %s", filePath); break; case AudioState::STOPPED: ESP_LOGI("Example", "Stopped: %s", filePath); break; case AudioState::ERROR: ESP_LOGE("Example", "Error playing: %s", filePath); break; default: break; } } */ /** * 本模块为音频输出模块 * 支持同步,异步音频输出 * * 注意:底层C驱动任务运行在核0, 请不要把例如lvgl这种高CPU占比的任务放在核0中,避免资源抢占导致播放卡顿 */ class AudioOutput { public: // 删除拷贝构造函数和赋值运算符 AudioOutput(AudioOutput const&) = delete; AudioOutput& operator=(AudioOutput const&) = delete; /** * 获取单例实例 * @return AudioOutput实例 */ static AudioOutput* getInstance(); /** * 初始化音频输出 * @return 是否成功 */ bool init(); // try to init AudioOutput void tryInitAudioOutput(); /** * 同步播放音频文件 * @param directory 目录路径 * @param fileName 文件名 * @return 是否成功 */ bool playSync(const char* directory, const char* fileName); /** * 异步播放音频文件 * @param directory 目录路径 * @param fileName 文件名 * @param callback 回调函数 */ void playAsync(const char* directory, const char* fileName, AudioCallback callback = nullptr); /** * 暂停播放 * @return 是否成功 */ bool pause(); /** * 恢复播放 * @return 是否成功 */ bool resume(); /** * 停止播放 * @return 是否成功 */ bool stop(); /** * 设置音量 * @param volume 音量值 (0-100) * @return 是否成功 */ bool setVolume(uint8_t volume); /** * 获取当前音量 * @return 音量值 */ uint8_t getVolume() const; /** * 获取最大音量 * @return 最大音量值 */ uint8_t getMaxVolume() const; /** * 获取音频总时长 * @return 总时长(毫秒) */ uint32_t getDuration() const; /** * 获取已播放时长 * @return 已播放时长(毫秒) */ uint32_t getElapsed() const; /** * 获取音频能量值 * @return 能量值 */ uint16_t getEnergy() const; /** * 获取当前播放状态 * @return 播放状态 */ AudioState getState() const; /** * 检查是否正在播放 * @return 是否正在播放 */ bool isPlaying() const; /** * 检查是否暂停 * @return 是否暂停 */ bool isPaused() const; /** * 检查是否停止 * @return 是否停止 */ bool isStopped() const; /** * 检查播放是否完成 * @return 是否完成 */ bool isFinished() const; private: // 私有构造函数 AudioOutput(); ~AudioOutput(); // 初始化线程配置 ThreadConfig getThreadConfig(const char* operation); // 内部播放实现 void playInternal(const char* directory, const char* fileName, AudioCallback callback); // 状态转换辅助方法 void setState(AudioState newState); // 单例实例指针 static AudioOutput* instance; static std::mutex instanceMutex; // 成员变量 mutable std::mutex stateMutex; AudioState currentState; std::string currentFilePath; uint8_t currentVolume; bool hardwareInitialized; };