/** **************************************************************************************************** * @file flac_dec.h * @author HiFi Player Project * @version V1.5 * @date 2026-01-01 * @brief FLAC 解码器 C 接口封装 * * 底层使用 esphome/micro-flac(ESP32-S3 带 Xtensa 汇编优化的 FLAC 解码器), * 这里用一层很薄的 C++ 包装,把接口暴露成纯 C,方便 player.c 直接调用。 * * 输出策略(V1.5 起): * **保留源文件的位深**,不再统一压到 16bit。 * 库输出的是“原生字节打包 + 左对齐”(16bit→2 字节,24bit→3 字节,32bit→4 字节, * 20bit 这类非整字节位深则填满其 3 字节的高 20 位),正好符合 I2S 的要求, * 因此上层可以按 out_bytes 配置 I2S/ES8388 的位宽,实现真正的无损通路。 * * 声道处理:单声道复制成左右;多于 2 声道时只取前两声道。 **************************************************************************************************** */ #ifndef __FLAC_DEC_H #define __FLAC_DEC_H #include #include #ifdef __cplusplus extern "C" { #endif typedef struct flac_dec flac_dec_t; /** FLAC 流信息 */ typedef struct { uint32_t sample_rate; /* 采样率 */ uint8_t channels; /* 源声道数(1~8) */ uint8_t bits; /* 源位深(4~32) */ uint8_t out_bytes; /* 输出每采样字节数:2 / 3 / 4(对应 I2S 16/24/32bit) */ uint32_t max_block_size; /* 最大块大小(每声道采样数) */ uint64_t total_samples; /* 每声道总采样数,0 表示文件未记录 */ } flac_info_t; /** * @brief 打开 FLAC 文件并解析 STREAMINFO * @param path 文件路径(如 "0:/MUSIC/a.flac") * @retval 句柄;失败返回 NULL * @note 返回非 NULL 时 info 已经可用(见 flac_dec_get_info) */ flac_dec_t *flac_dec_open(const char *path); /** * @brief 获取流信息(仅在 flac_dec_open 成功后有效) * @retval 0 成功 */ int flac_dec_get_info(flac_dec_t *dec, flac_info_t *info); /** * @brief 读取一块 PCM 数据 * @param dec 解码器句柄 * @param out 输出缓冲区,写入 **立体声交错** 的原生位深 PCM(左对齐) * @param max_frames 最多输出多少帧(1 帧 = 左右各 1 个采样) * @retval >0 实际写入的帧数 * 0 文件结束 * <0 解码错误 * @note 每帧占用 2 * out_bytes 字节,调用者需保证缓冲区足够 */ int flac_dec_read(flac_dec_t *dec, void *out, int max_frames); /** @brief 关闭并释放所有资源(可传 NULL) */ void flac_dec_close(flac_dec_t *dec); #ifdef __cplusplus } #endif #endif /* __FLAC_DEC_H */