/** **************************************************************************************************** * @file audio_source.h * @author HiFi Player Project * @version V1.5 * @date 2026-01-01 * @brief 统一音源接口(WAV / FLAC) * * 上层播放器只关心“给我一块立体声 PCM 和它对应的位宽”,不必区分容器格式: * * audio_source_open() ── 按文件头自动识别 RIFF(WAV) / fLaC、OggS(FLAC) * │ 同时给出该曲目应使用的 I2S 位宽 out_bits(16/24/32) * audio_source_read() ── 输出 **源文件原生位深** 的立体声交错 PCM * │ 单声道自动复制;>2 声道只取前两声道;不做降位 * audio_source_close() * * 时间进度统一用“已播放帧数 / 采样率”计算,对两种格式都准确。 * * 位宽映射(源位深 → I2S 位宽): * ≤16bit → 16bit(每采样 2 字节) * 17~24bit → 24bit(每采样 3 字节) * 25~32bit → 32bit(每采样 4 字节) * 非整字节位深(如 20bit)按左对齐放入更宽的槽位,音量不受影响。 **************************************************************************************************** */ #ifndef __AUDIO_SOURCE_H #define __AUDIO_SOURCE_H #include #include #ifdef __cplusplus extern "C" { #endif /** 支持的音频容器 */ typedef enum { AUDIO_CODEC_WAV = 0, /* RIFF/WAVE,PCM 16/24/32bit */ AUDIO_CODEC_FLAC, /* 原生 FLAC 或 Ogg FLAC */ } audio_codec_t; /** 音源信息 */ typedef struct { audio_codec_t codec; /* 容器类型 */ uint32_t sample_rate; /* 采样率 → 用于配置 I2S 频率 */ uint16_t bits; /* 源位深(界面显示用) */ uint16_t channels; /* 源声道数 */ uint16_t out_bits; /* I2S 输出位宽:16 / 24 / 32 */ uint8_t out_bytes; /* 输出每采样字节数:2 / 3 / 4 */ uint32_t total_sec; /* 总时长(秒),0 表示未知 */ } audio_info_t; typedef struct audio_source audio_source_t; /** * @brief 打开音频文件并解析头部 * @param path 文件路径 * @param info 输出音源信息(可为 NULL) * @retval 句柄;失败返回 NULL */ audio_source_t *audio_source_open(const char *path, audio_info_t *info); /** * @brief 读取一块 PCM * @param src 音源句柄 * @param out 输出缓冲区(立体声交错,位宽 = info.out_bits) * @param max_frames 最多读取多少帧(1 帧 = 左右各 1 个采样) * @retval >0 实际帧数 * 0 播放结束 * <0 解码/读取错误 * @note 每帧占用 2 * out_bytes 字节,调用者需保证缓冲区足够 */ int audio_source_read(audio_source_t *src, void *out, int max_frames); /** @brief 已播放的秒数(按解码帧数计算) */ uint32_t audio_source_elapsed_sec(const audio_source_t *src); /** @brief 关闭音源并释放资源(可传 NULL) */ void audio_source_close(audio_source_t *src); #ifdef __cplusplus } #endif #endif /* __AUDIO_SOURCE_H */