Files

78 lines
2.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
****************************************************************************************************
* @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 */