78 lines
2.7 KiB
C
78 lines
2.7 KiB
C
/**
|
||
****************************************************************************************************
|
||
* @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 <stdbool.h>
|
||
#include <stdint.h>
|
||
|
||
#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 */
|