第一记:MP3解码过程粗解
(一):需要用到的库文件
1.文件系统(即FATFS)。具体包括的代码文件如下:
ffconf.h FatFs模块的配置文件
ff.h FatFs的头文件,定义了几个关键的数据结构,并声明了很多函数
ff.c FatFs模块的实现,包括f_open()、f_read()、f_write()和f_close()等函数的实现
diskio.h 底层磁盘I/O模块的头文件
diskio.c 这个文件实现了一个操作底层存储设备的接口层,ff.c会调用这个文件中提供的接口,实现文件的读写,我们在移植过程中的重点工作就是实现这个文件中的几个接口
integer.h 数据类型的定义
option 可选择的一些外部函数,既然是可选择的,也就不用太关心这部分代码
其中重点用到的函数有f_open(打开文件并创建一个文件访问对象)、f_read(读写指针指向的文件偏移量处开始从文件中读取数据)、f_seek(将读写指针偏移到要读写的地方)
2.MAD(libmad)。mp3音频解码库
libmad中的主要数据结构
struct mad_stream 存放解码前的Bitstream 数据
struct mad_synth 存放解码合成滤波后的PCM数据
struct mad_pcm 定义了音频的采样率,声道个数和PCM 采样数据,
用来初始化音频struct mad_frame 记录MPEG 帧解码后PCM
数据的数据结构,其中的mad_header 用来记录MPEG 帧的基本信息,比如MPEG
层数、声道模式、流比特率、采样比特率。声道模式包括单声道、双声道、联合立体混音道以及一般立体声
其中重点用到的API函数如下:
(1)3个初始化解码需要的数据结构
void mad_stream_init(struct mad_stream *)
void mad_synth_init(struct mad_synth *);
void mad_frame_init(struct mad_frame *);
(2)把原始的未解码的 MPEG 数据和 mad_stream 数据结构关联,以便使用 mad_frame_decode( ) 来解码 MPEG 帧数据
void mad_stream_buffer(struct mad_stream *, unsigned char const *, unsigned long);
(3)把 mad_stream 中的 MPEG 帧数据解码
int mad_frame_decode(struct mad_frame *, struct mad_stream *);
(4)把解码后的音频数据合成 PCM 采样
void mad_synth_frame(struct mad_synth *, struct mad_frame const *);
(5)释放libmad占用的资源
void mad_stream_finish(struct mad_stream *);
void mad_frame_finish(struct mad_frame *);
mad_synth_finish(struct mad_synth);
3.I2S(集成电路内置音频总线)
(1)支持全双工和半双工、主从模式
(2)I2S信号线
1.SCK串行时钟,也叫BCLK位时钟。
对应数字音频的每一位数据,SCK都有1个脉冲。SCK的频率 = 声道数 * 采样频率 * 采样位数。
2.WS: 字段(声道)选择。
字段选择信号WS,也叫LRCLK,用于切换左右声道的数据。WS的频率 = 采样频率。
字段选择信号WS表明了正在被传输的声道。I2S Philips标准WS信号的电平含义如下:
WS为0,表示正在传输的是左声道的数据;
WS为1,表示正在传输的是右声道的数据。
3.SD:串行数据
串行数据SD,就是用二进制补码表示的音频数据。I2S串行数据在传输的时候,由高位(MSB)到低位(LSB)依次进行传输。
4.2S2ext_SD和I2S3ext_SD
用于控制I2S全双工模式的附加引脚。
5.主时钟MCLK
一般还有MCLK,主时钟。是采样频率的256倍或384倍。有时为了使系统间能够更好地同步,当I2S配置为主模式(并且SPI_I2SPR寄存器中的MCKOE位置1)时,使用此时钟,该时钟输出频率 256×fs,fs即音频信号采样频率(fs)。
未结束,待后续改进……