HiFi player project, first commit.

This commit is contained in:
francis.wang committed 2026-10-26 20:07:12 +08:00
commit 4126ea13a1
49 files changed
+6333

No files matched your search

+87
View File
@@ -0,0 +1,87 @@
/**
****************************************************************************************************
* @file player.h
* @author HiFi Player Project
* @version V1.2
* @date 2026-01-01
* @brief HiFi 播放器核心:SD 卡曲目扫描、WAV 解码、I2S 输出
* @note 按键由 ui.c 统一消费后通过 player_request() 转发进来;本模块不直接读按键。
* 播放器只在 APP_MODE_PLAYER 模式下输出音频;离开该模式会自动暂停并保留进度。
****************************************************************************************************
*/
#ifndef __PLAYER_H
#define __PLAYER_H
#include <stdbool.h>
#include <stdint.h>
#include "app.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ---------------- 播放器状态 ---------------- */
typedef enum {
PLAYER_STATUS_BOOT = 0, /* 正在初始化 / 挂载 SD 卡 */
PLAYER_STATUS_NO_SD, /* 没有检测到 SD 卡 */
PLAYER_STATUS_NO_MUSIC, /* SD 卡中没有可播放的 WAV 文件 */
PLAYER_STATUS_PLAYING, /* 正在播放 */
PLAYER_STATUS_PAUSED, /* 已暂停 */
PLAYER_STATUS_ERROR, /* 音频硬件 / 文件系统错误 */
} player_status_t;
/* ---------------- 供 UI 读取的状态快照 ---------------- */
typedef struct {
player_status_t status; /* 当前状态 */
uint8_t volume; /* 音量百分比 0~100 */
int16_t track_index; /* 当前曲目序号(0 基) */
int16_t track_total; /* 曲目总数 */
uint32_t cur_sec; /* 当前播放秒数 */
uint32_t tot_sec; /* 曲目总秒数 */
uint16_t samplerate; /* 采样率 */
uint8_t bits; /* 源位深(16/24/32,界面显示用) */
uint8_t i2s_bits; /* 实际 I2S 输出位宽(16/24/32) */
uint8_t channels; /* 声道数 */
uint32_t bitrate; /* 比特率,单位 bps */
char track_name[64]; /* 曲目显示名(已去掉扩展名,仅保留 ASCII) */
char codec[8]; /* 容器格式:"WAV" / "FLAC" */
char message[64]; /* 状态提示信息 */
} player_state_t;
/* ---------------- 播放器可接收的请求 ---------------- */
typedef enum {
PLAYER_REQ_PLAY_PAUSE = 0, /* 播放 / 暂停 */
PLAYER_REQ_NEXT, /* 下一曲 */
PLAYER_REQ_VOLUME, /* 音量切档 */
PLAYER_REQ_NUM,
} player_request_t;
/**
* @brief 启动播放器(创建播放任务)
* @note 调用前必须完成 NVS / SPI / IIC / XL9555 / LCD 初始化
*/
void player_start(void);
/**
* @brief 获取播放器状态快照(线程安全,供 LVGL 任务调用)
* @param out 输出缓冲区
*/
void player_get_state(player_state_t *out);
/**
* @brief 向播放任务投递一个动作请求(可在任意任务中调用,不阻塞)
* @param req 请求类型
* @note 请求是位标记累积的,播放任务下次循环时统一处理
*/
void player_request(player_request_t req);
#ifdef __cplusplus
}
#endif
#endif /* __PLAYER_H */