一、术语总结
1.HIFI 级
“HIFI”一词通常指高保真音频(High-Fidelity Audio),是指尽可能保持音频信号的原始质量,让听众感受到最真实的音乐表现。因此,“HIFI级”通常指具有高保真音频性能的产品或设备,例如高保真耳机、音响设备、音频处理器等。
在智能音箱、智能音响等智能家居设备中,也经常使用“HIFI级”来形容其音频性能。这些设备通常具有高质量的音频解码器、音频放大器、高保真扬声器等音频元件,能够提供更加真实、清晰、细腻的音乐表现,带给用户更好的听觉体验。
2.支持最高 192K 24BIT 的音频播放
“支持最高 192K 24BIT 的音频播放”通常指音频设备或软件可以播放采样率为192kHz、位深度为24 bit的音频文件或流。其中,“采样率”指音频信号每秒钟采样的次数,即采样频率,常用的采样率包括44.1kHz、48kHz、96kHz、192kHz等;而“位深度”指每个采样点的量化位数,即采样精度,常用的位深度包括16 bit、24 bit、32 bit等。
3.立体声的声道数
立体声是一种常见的声音录制和播放方式,使用两个声道来传递左右声道的声音信号。因此,立体声的声道数为2,分别对应左声道和右声道。
在音频处理中,立体声可以提供更加真实、立体的音效体验,使得听众可以感受到更加逼真的音乐表现。同时,立体声也可以用于区分不同声源的位置和方向,例如在影视制作中,可以通过立体声的录制和处理,来实现对话、环境声、音效等音频元素的区分和定位,从而提升影视作品的视听体验。
需要注意的是,在处理立体声音频时,需要对左声道和右声道进行相应的处理和调整,以保证两个声道之间的平衡和协调。同时,在播放立体声音频时,也需要使用支持立体声播放的设备和软件,以获得最佳的音频效果。
4.我们播放的音频支持:16 位和 24 位,立体声,所以每个取样为 4/6 个字节,低字节在前,高字节在后。
在音频处理中,采样深度表示每个采样点的量化位数,采样深度越高,表示每个采样点可以表达的音频细节和动态范围也越大,因此音频质量也可以更高。立体声表示音频信号采用了两个声道进行录制或播放,通常用于模拟现实场景中的立体声效果。
每个取样数据占用4/6个字节,这是由于16位采样深度的音频每个采样点占用2个字节,而24位采样深度的音频每个采样点占用3个字节,因此每个立体声采样点占用的字节数为4或6个字节。在存储这些采样点时,采用小端序的方式将低字节存储在前面,高字节存储在后面,以保证音频数据的正确解析和播放。
5.立体声差分输入
立体声差分输入是指在音频电路中采用差分信号传输方式,通过两个信号线分别传输左右声道的差分信号,从而实现立体声的音频输入。
在差分信号传输中,每个信号线传输的是相对于共同参考点的电压差值,而不是单独的信号电压值。在立体声差分输入中,左声道和右声道的差分信号分别通过两个信号线传输,其中一个信号线传输左声道信号与参考点之间的电压差值,另一个信号线则传输右声道信号与参考点之间的电压差值。通过解码差分信号,可以还原出左声道和右声道的原始音频信号。
相对于单端输入,立体声差分输入可以提供更好的抗干扰能力和信噪比,从而提高音频输入的质量和稳定性。同时,立体声差分输入也可以用于一些专业音频设备和高保真音响系统中,以提供更加真实、立体的音效体验。
需要注意的是,在使用立体声差分输入时,需要使用支持差分输入的音频设备,并正确连接差分输入的信号线和参考点。同时,在处理和解码差分信号时,也需要使用相应的差分信号处理电路,以保证音频输入的正确性和质量。
6.MSB和LSB
MSB是英文“Most Significant Bit”的缩写,意为“最高有效位”。在数字电路和计算机科学中,MSB通常用于描述二进制数中的最高位(即最左侧的位),它的权值是二进制数中最大的,因此也被称为“最高位”。LSB是英文“Least Significant Bit”的缩写,意为“最低有效位”。在数字电路和计算机科学中,LSB通常用于描述二进制数中的最低位(即最右侧的位),它的权值是二进制数中最小的,因此也被称为“最低位”。
在数字信号处理中,MSB也常用于描述数据的精度。例如,一个16位的数字信号,它的最高有效位表示信号的符号位,而其余的15位表示信号的幅值,因此可以表示的最大绝对值为2的15次方。LSB也常用于描述数据的精度。例如,一个16位的数字信号,它的最低有效位表示信号的最小单位,其余的15位表示信号的幅值,因此可以表示的最小绝对值为2的负15次方。
需要注意的是,在计算机和数字信号处理中,MSB和LSB的顺序取决于采用的字节顺序(Endianness)和位顺序(Bit ordering),在不同的系统和协议中可能存在不同的表示方式。
7.DMA传输
DMA是“直接内存访问”的缩写,是一种高效的数据传输方式,可用于将数据从设备(如硬盘驱动器)传输到内存中,或将数据从内存传输到设备中,而无需CPU的干预。这种数据传输方式比使用CPU进行传输更快,因为DMA可以减少CPU的负载,让CPU有更多的时间来处理其他任务。
在DMA传输中,DMA控制器会接管CPU的控制,它决定了数据的传输方式、传输的数据量以及数据的传输方向。CPU只需要设置DMA控制器的寄存器来指定数据传输的参数,然后就可以让DMA控制器自动完成数据传输。这种传输方式可以减少CPU的干预,从而提高系统的性能和效率。
总之,DMA是一种高效的数据传输方式,可以减少CPU的干预,提高系统的性能和效率。它在许多设备和系统中被广泛使用,包括硬盘驱动器、网络接口卡、音频和视频设备等。
二、PCM与WAV 简介
1 PCM
1.1 PCM 的定义
PCM(Pulse Code Modulation)又称脉冲编码调制,是一种用于数字通信和音频记录的技术。PCM通过对模拟信号进行采样、量化、编码,将连续的模拟信号转换为离散的数字信号,从而实现信号的高保真传输和存储。
1.2 PCM 和 声音(音频) 的关系
从PCM的定义来看,它主要是将模拟信号转成数字信号。那它和音频有什么关系呢?为什么是要转成数字信号呢?
1、自然界中的声音通过麦克风等采集设备处理后,首先会将声音信号转换成电信号,但此时的电信号是连续的模拟信号,将这些音频模拟信号在坐标系表示就类似于下图:
2、计算机只认识0和1,这样连续的模拟信号要被计算机传输或存储等处理的话,就需要先转换成数字信号;
3、通过模数转换器(A/D),将音频模拟信号转换成数字信号后就可以被计算机处理,经过模数转换器处理后的音频数字信号就是PCM,是声音的原始数据。在音视频编程中,常被称为音频裸数据,它还可以继续被编码成其他格式的音频数据如:wav、mp3、aac、ogg;
4、计算机处理后的数字音频信号,再通过数模转换器(D/A),转换成音频模拟信号,最后通过扬声器等设备转成声音信号,进行播放。
通过前面的介绍,PCM可以总结为:通过模数转换器处理后,将声音模拟信号转换而成的数字信号,是声音要给计算机处理的最原始的音频数据。
1.3PCM 生成过程
读者可以先思考一下,怎样才能将连续的模拟信号转成数字信号呢?
既然模拟信号看起来像连续的一段曲线,是不是可以用很密集的一些点去表示,只要有足够多的点,就可以让这些点看起来像模拟信号的曲线了;
如果选择用很多点去表示连续的曲线,那么这些点的取值范围应该是多少呢?取值范围越大,越能精确地表示模拟信号曲线;
确定范围后,表示曲线的每个点就成了各个数值,最后将这些数值按照格式排列起来,就成了数字信号了。
其实,PCM也是大概按照上面的流程去生成的,PCM生成需要经过 采样(Sampling)、量化(Quantization)、编码(Encoding)。
1.3.1 采样(Sampling)
采样就是将模拟信号的音频转换成数字信号音频的过程,通过模/数转换器(A/D)对声波进行采样,每一次采样都记录下了原始模拟声波在某一时刻的状态,称之为样本,将一串的样本连接起来,就可以描述一段声波。把每一秒钟所采样的次数称为采样频率,单位为HZ(赫兹)。其实,采样就是在时间轴上对信号进行数字化。
采用过程如上图,用若干个黑点来表示红色的曲线。红色的曲线是音频模拟信号,各个黑点就是样本。
采样率:每一秒钟所采样的样本个数;如果每秒所采集的样本越多,越能精确的表示曲线。常见的采样率有:通话时的采样率为8KHz(每秒8000个样本),常用的媒体采样率有44.1KHz(每秒44100个样本),更高要求的有48KHz(每秒48000个样本)等等。
1.3.2 量化(Quantization)
量化就是为采集的样本确定一个取值范围。
比如用16比特的二进制信号来表示声音的一个样本, 而16比特(一个short) 所表示的范围是[-32768,32767], 共有65536个可能取值, 因此最终音频的数字信号在幅度上也分为了65536层。
如果用8比特的二进制信号来表示声音的一个样本,8比特(一个unsigned char)所表示的范围是[0,255],共有256个层级。
注意:
1.3.3 编码(Encoding)
编码, 就是按照一定的格式记录采样和量化后的样本数据,将量化后的数字信号转换为二进制码的过程。比如顺序存储或压缩存储, 等等。
采样、量化后的数据经过编码后产生的二进制数据,就是PCM数据。
1.4 PCM音频的特征或参数
**1.采样率(Sampling Rate):**表示每秒钟采样的样本数量,单位为赫兹(Hz)。它决定了PCM音频的时间分辨率和频率范围。
**2.位深度(Bit Depth):**表示每个样本的取值精度,通常以位数表示。它决定了PCM音频的动态范围和信噪比。一般为16bit。
**3.字节序(Byte Order):**表示多字节数据在存储或传输中的排列顺序。常见的字节序有大端序(Big Endian)和小端序(Little Endian)两种。常见的为小端字节序。
大端序(Big Endian)
小端序(Little Endian)
**4.采样数据是否有符号(Signed or Unsigned Samples):**表示每个样本的取值是否包含符号位。有符号PCM样本的取值范围涵盖正负值,而无符号PCM样本的取值范围仅包含非负值。
**5.声道数(Number of Channels):**表示PCM音频中的独立声道数量。常见的声道数有单声道(Mono)和立体声(Stereo),还可以有更多声道如5.1声道、7.1声道等。
2 WAV
WAV 即 WAVE 文件,WAV 是计算机领域最常用的数字化声音文件格式之一,它是微软专门为 Windows 系统定义的波形文件格式(Waveform Audio),由于其扩展名为"*.wav"。它符合RIFF(Resource Interchange File Format)文件规范,用于保存 Windows 平台的音频信息资源,被Windows 平台及其应用程序所广泛支持,该格式也支持 MSADPCM,CCITT A LAW 等多种压缩运算法,支持多种音频数字,取样频率和声道,标准格式化的 WAV 文件和 CD 格式一样,也是 44.1K 的取样频率,16 位量化数字,因此在声音文件质量和 CD 相差无几!
WAV 一般采用线性 PCM(脉冲编码调制)编码。WAV 文件是由若干个 Chunk 组成的。按照在文件中的出现位置包括:RIFF WAVE Chunk、Format Chunk、 Fact Chunk(可选)和 Data Chunk。每个 Chunk 由块标识符、数据大小和数据三部分组成,如下图所示:
对于一个基本的 WAVE 文件而言,以下三种 Chunk 是必不可少的:文件中第一个 Chunk 是RIFF Chunk,然后是 FMT Chunk,最后是 Data Chunk。对于其他的 Chunk,顺序没有严格的限制。使用 WAVE 文件的应用程序必须具有读取以上三种 chunk 信息的能力,如果程序想要复制WAVE 文件,必须拷贝文件中所有的 chunk。
PCM只包含 3 个 Chunk,我们看一下它的文件构成,如图 55.1.2。
用notepad++>>plugins>>HexEditor(notepad++的一个二进制编辑器插件——可以以16进制查看文件内容)打开一个波形文件如下:
所有WAV波形文件都可以套用一下一下格式:
对应图一可以看到:
结构辨识码: 该文件是属于RIFF结构的文件,这种结构是一种树状结构,其最基本的组成单元是chunk(块),而每一个chunk则由辨识码,数据大小,以及数据本身组成。
数据大小: 需要注意目前很多的CPU存储数据都是采用小端的方式,即低位在前,高位在后。实际的数据大小是00 00 7d 24,对应文件最后一个地址为00 00 7d 2b,(00 00 7d 2b - 00 00 7d 24 = 8),刚好是结构辨识码 + 数据大小的信息位宽,说明该文件的数据大小是从00 00 00 08开始算起。
格式识别码: 该文件是WAV格式的文件。每个识别码都是由4字节的数据表示,每一个字节的数据都之间用ASCII码映射成相应的符号,例如57 41 56 45==“WAVE”。
fmt子块:主要用于描述该wav文件的信息,辨识符是66 6D 74 20,后接子块大小00 00 00 10(10 00 00 00),说明fmt数据有16个字节,如图蓝色框中的数据。子块数据的字节长度是由子块长度的内容决定的。
fact子块: 该块并不是必须的,在PCM(Pulse-Code Modulation,脉冲编码调制)——一种标准未压缩的编码格式,的WAV文件中没有该子块,只有一些软件转化而来的才会增加该子块,其主要存储的信息包括采样的数量等。从文件数据中也可以看出,在上述数据之后接的并不是fact子块的辩识码,而是data子块的辨识码(64 61 74 61),说明该文件确实不存在fact子块。
data子块: 主要就是WAV文件真正能播放的声音数据部分。该块的数据大小00 00 7d 00(00 7d 00 00),00 00 7d 2b - 00 00 00 2b = 00 00 7d 00,刚好是接下来到文件最后的所有数据长度总和,即粉红色宽中真正有效可播放的音频数据。2个字节一个有效信息,当数据是双声道时,其存储方式为一个左声道,一个右声道…如此循环。
不同的 Chunk 有不同的长度,编码文件时,按照 Chunk 的字节和位序排列好之后写入文件头,加上 wav 的后缀,就可以生成一个能被正确解析的 wav 文件了,对于 PCM 结构,我们只需要把获取到的音频数据填充到 Data Chunk 中即可。
首先,我们来看看 RIFF 块(RIFF WAVE Chunk),该块以“RIFF”作为标示,紧跟 wav 文件大小(该大小是 wav 文件的总大小-8),然后数据段为“WAVE”,表示是 wav 文件。RIFF 块的 Chunk 结构如下:
typedef __PACKED_STRUCT
{
uint32_t ChunkID; /* chunk id;这里固定为"RIFF",即 0X46464952 */
uint32_t ChunkSize ; /* 集合大小;文件总大小-8 */
uint32_t Format; /* 格式;WAVE,即 0X45564157 */
}ChunkRIFF; /* RIFF 块 */
接着,我们看看 Format 块(Format Chunk),该块以“fmt”作为标示(注意有个空格!),一般情况下,该段的大小为 16 个字节,但是有些软件生成的 wav 格式,该部分可能有 18 个字节,含有 2 个字节的附加信息。Format 块的 Chunk 结构如下:
typedef __PACKED_STRUCT
{
uint32_t ChunkID; /* chunk id;这里固定为"fmt ",即 0X20746D66 */
uint32_t ChunkSize ; /* 子集合大小(不包括 ID 和 Size);这里为:20. */
uint16_t AudioFormat; /* 音频格式;0X01,表示线性 PCM;0X11 表示 IMA ADPCM */
uint16_t NumOfChannels; /* 通道数量;1,表示单声道;2,表示双声道; */
uint32_t SampleRate; /* 采样率;0X1F40,表示 8Khz */
uint32_t ByteRate; /* /字节速率; */
uint16_t BlockAlign; /* 块对齐(字节); */
uint16_t BitsPerSample; /* 单个采样数据大小;4 位 ADPCM,设置为 4 */
// uint16_t ByteExtraData; /* 附加的数据字节;2 个; 线性 PCM,没有这个参数 */
}ChunkFMT; /* fmt 块 */
接下来,我们再看看 Fact 块(Fact Chunk),该块为可选块,以“fact”作为标示,不是每个 WAV 文件都有,在非 PCM 格式的文件中,一般会在Format 结构后面加入一个 Fact 块,该块 Chunk 结构如下:
typedef __PACKED_STRUCT
{
uint32_t ChunkID; /* chunk id;这里固定为"fact",即 0X74636166; */
uint32_t ChunkSize; /* 子集合大小(不包括 ID 和 Size);这里为:4. */
uint32_t NumOfSamples; /* 采样的数量; */
}ChunkFACT; /* fact 块 */
DataFactSize 是这个 Chunk 中最重要的数据,如果这是某种压缩格式的声音文件,那么从这里就可以知道他解压缩后的大小。对于解压时的计算会有很大的好处!
最后,我们来看看数据块(Data Chunk),该块是真正保存 wav 数据的地方,以“data”作为该 Chunk 的标示,然后是数据的大小。数据块的 Chunk 结构如下:
typedef __PACKED_STRUCT
{
uint32_t ChunkID; /* chunk id;这里固定为"data",即 0X5453494C */
uint32_t ChunkSize ; /* 子集合大小(不包括 ID 和 Size) */
}ChunkDATA; /* data 块 */
ChunkSize 后紧接着就是 wav 数据。根据 Format Chunk 中的声道数以及采样 bit 数,wav 数据的 bit 位置可以分成如表 55.1.1.1 所示的几种形式:
三、 ES8388 简介
ES8388 是上海顺芯推出的一款高性能、低功耗、高性价比的音频编解码器,有 2 个 ADC通道和 2 个 DAC 通道,麦克风放大器,耳机放大器,数字音效以及模拟混合和增益功能组成。
ES8388 的主要特性有:
●SAI 接口,支持最高 192K,24bit 音频播放
●DAC 信噪比 96dB;ADC 信噪比 95dB
●支持主机和从机模式
●支持立体声差分输入/麦克风输入
●支持左右声道音量独立调节
●支持 40mW 耳机输出,无爆音
ES8388 的控制通过 I2S 接口(即数字音频接口)同 MCU 进行音频数据传输(支持音频接收和发送),通过两线(CE=0/1,即 IIC 接口)或三线(CE 脚产生一个下降沿,即 SPI 接口)接口进行配置。ES8388 的 SAI 接口,由 4 个引脚组成:
ASDOUT:ADC 数据输出
DSDIN:DAC 数据输入
LRC:数据左/右对齐时钟
SCLK:位时钟,用于同步
ES8388可作为 SAI主机,输出 LRC和 SLCK时钟,不过我们一般使用 ES8388作为从机,接收 LRC 和 SLCK。另外,ES8388 的 SAI 接口支持 4 种不同的音频数据模式:左(MSB)对齐标准、右(LSB)对齐标准、飞利浦(SAI)标准、DSP/PCM。本章,我们用飞利浦标准来传输 SAI 数据。
飞利浦(SAI)标准模式,数据在跟随 LRC 传输的 BCLK 的第二个上升沿时传输 MSB,其他位一直到 LSB 按顺序传输。传输依赖于字长、BCLK 频率和采样率,在每个采样的 LSB和下一个采样的 MSB 之间都应该有未用的 BCLK 周期。飞利浦标准模式的 SAI 数据传输协议如图 60.1.2.1 所示:
图中,fs 即音频信号的采样率,比如 44.1Khz,因此可以知道,LRC 的频率就是音频信号的采样率。另外,ES8388 还需要一个 MCLK,本章我们采用 STM32H743 为其提供 MCLK 时钟,MCLK 的频率必须等于 256fs,也就是音频采样率的 256 倍。
ES8388 的框图如图 60.1.2.2 所示:
从上图可以看出,ES8388 内部有很多的模拟开关,用来选择通道,同时还有一些运放调节器,用来设置增益和音量。
本章,我们通过 IIC 接口(CE=0)连接 ES8388,ES8388 的 IIC 地址为:0X10。关于ES8388 的 IIC 详细介绍,请看其数据手册第 10 页 5.2 节。
这里我们简单介绍一下要正常使用 ES8388 来播放音乐,应该执行哪些配置。
1,寄存器 R0(00h),是芯片控制寄存器 1,需要用到的位有:最高位 SCPRese(bit7)用于控制 ES8388 的软复位,写 0X80 到该寄存器地址,即可实现软复位 ES8388,复位后,再写0X00,ES8388 恢复正常。VMIDSEL[1:0]位用于控制 VMID(校正噪声用),我们一般设置为10,即用 500KΩ 校正。
2,寄存器 R1(01h),是芯片控制寄存器 2,主要要设置 PdnAna(bit3),该位设置为 1,模拟部分掉电,相当于复位模拟部分;设置为 0,模拟部分才会工作,才可以听到声音。
3,寄存器 R2(02h),是芯片电源管理控制寄存器,所有位都要用到:adc_DigPDN(bit7)和 dac_DigPDN(bit6)分别用于控制 ADC 和 DAC 的 DSM、DEM、滤波器和数字接口的复位,1复位,0 正常;adc_stm_rst(bit5)和 dac_stm_rst(bit4)分别用于控制 ADC 和 DAC 的状态机掉电,1掉电,0正常;ADCDLL_PDN(bit3)和 DACDLL_PDN(bit2)分别用于控制 ADC和 DAC的 DLL
掉电,停止时钟,1 掉电,0 正常;adcVref_PDN(bit1)和 dacVref_PDN(bit0)分别控制 ADC 和DAC 的模拟参考电压掉电,1 掉电,0 正常;因此想要 ADC 和 DAC 都正常工作,R2 寄存器必须全部设置为 0,否则 ADC 或者 DAC 就会不能正常工作。
4,寄存器 R3(03h),是 ADC 电源管理控制寄存器,需要用到的位有:PdnAINL(bit7)和PdnAINR(bit6)用于控 制左 右输入模 拟通道的 电源 ,1 掉 电,0 正 常;PdnADCL(bit5)和PdnADCR(bit4)用于控制左右通道 ADC 的电源,1 掉电,0 正常;pdnMICB(bit3)用于控制麦克风的偏置电源,1 掉电,0 正常;PdnADCBiasgen(bit2)用于控制偏置电源的产生,1 掉电,0 正
常;这里 6 个位,我们全部设置为 0,ADC 部分就可以正常工作了。
5,寄存器 R4(04h),是 DAC 电源管理控制寄存器,需要用到的位有:PdnDACL(bit7)和PdnDACR(bit6)分别用于左右声 道 DAC 的电源控制 ,1 掉电 ;0 正常;LOUT1(bit5)和ROUT1(bit4)分别用于控制通道 1 的左右声道输出是能,1 使能,0 禁止;LOUT2(bit3)和ROUT2(bit2)分别用于控制通道 2 的左右声道输出是能,1 使能,0 禁止;我们一般设置PdnDACL 和 PdnDACR 为 0,使能左右声道 DAC,另外,两个输出通道则根据自己的需要设置。
6,寄存器 R8(08h),是主模式控制寄存器,需要用到的位有:MSC(bit7)用于控制接口模式,0 从模式,1 主模式;MCKDIV2(bit6)用于控制 MCLK 的 2 分频,0 不分频,1 二分频;BCLK_INV(bit5)用于控制 BCLK 的反相,0 不反相;1,反相;一般设置这 3 个位都为 0。
7,寄存器 R9(09h),是 ADC 控制寄存器 1,所有位都要用到:MicAmpL(bit7:4)和MicAmpR(bit3:0),这两个分别用于控制 MIC 的左右通道增益,从 0 开始,3dB 一个档,最大增益为 24dB,我们一般设置 MicAmpR/L[3:0]=1000,即 24dB。
8,寄存器 R10(0Ah),是 ADC 控制寄存器 2,需要用到的位有:LINSE(bit7:6)和RINSE(bit5:4)分别选择左右输入通道,0 选择通道 1,1 选择通道 2。
9,寄存器 R12(0Ch),是 ADC 控制寄存器 4,全部位都要用到:DATSEL(bit7:6)用于选择数据格式,一般设置为 01,左右边数据等于左右声道 ADC 数据;ADCLRP(bit5)在 I2S 模式下用于设置数据对其方式,一般设置为 0,正常极性;ADCWL(bit4:2)用于选择数据长度,我们设置 011,选择 16 位数据长度;ADCFORMAT(bit1:0)用于设置 ADC 数据格式,一般设置
为 00,选择 I2S 数据格式。
10,寄存器 R13(0Dh),是 ADC 控制寄存器 5,全部位都要用到:ADCFsMode(bit7)用于设置 Fs模式,0单速模式,1双倍速模式,一般设置为 0;ADCFsRatio(bit4:0)用于设置 ADC的MCLK 和 FS 的比率,我们设置 00010,即 256 倍关系。
11,寄存器 R16(10h)和 R17(11h),这两个寄存器分别用于控制 ADC 左右声道的音量衰减,LADCVOL(bit7:0)和 RADCVOL(bit7:0)分别控制左声道和右声道 ADC 的衰减,0.5dB 每步,我们一般设置为 0,即不衰减。
12,寄存器 R18(12h),是 ADC 控制寄存器 10,全部位都要用到:ALCSEL(bit7:6)用于控制 ALC,00 表示 ALC 关闭,01 表示 ALC 仅控制左声道,10 表示 ALC 仅控制右声道 11 表示 ALC 立体声控制;我们一般设置为 11。
13,寄存器 R23(17h),是 DAC 控制寄存器 1,需要用到的位有:DACLRSWAP(bit7)用于控制左右声道数据交换,0 正常,1 互换,一般设置为 0;DACLRP(bit6) 在 I2S 模式下用于设置数据对其方式,一般设置为 0,正常极性;DACWL(bit5:3)用于选择数据长度,我们设置011,选择 16 位数据长度;ADCFORMAT(bit1:0)用于设置 DAC 数据格式,一般设置为 00,选择 I2S 数据格式。
14,寄存器 R24(18h),是 DAC 控制寄存器 2,全部位都要用到:DACFsMode(bit7)用于设置 Fs模式,0单速模式,1双倍速模式,一般设置为 0;DACFsRatio(bit4:0)用于设置 DAC的MCLK 和 FS 的比率,我们设置 00010,即 256 倍关系。
15,寄存器 R26(1Ah)和 R27(1Bh),这两个寄存器分别用于控制 DAC左右声道的音量衰减,LDACVOL(bit7:0)和 RDACVOL(bit7:0)分别控制左声道和右声道 DAC 的衰减,0.5dB 每步,0 表示 0dB 衰减,192 表示 96dB 衰减;通过这两个寄存器可以完成输出音量的调节。
16,寄存器 R29(1Dh),是 DAC 控制寄存器 7,需要用到的位有:ZeroL(bit7)和ZeroR(bit6)分别控制左右声道的全 0 输出,类似静音,1 输出 0,0 正常;一般设置为 0。Mono(bit5)用于单声道控制,0 立体声,1 单声道;一般设置为 0。SE(bit4:2)用于设置 3D 音效,0~7 表示 3D 效果的强弱,0 表示关闭。
17,寄存器 39(27h)和 42(2Ah),分别控制 DAC 左右通道的混音器,LD2LO(bit7)和RD2RO(bit7)分别控制左右 DAC 的混音器开关,0 关闭,1 开启,需设置为 1;LI2LO(bit6)和RI2RO(bit6)分别控制左右输入通道的混音器开关,0 关闭,1 开启,一般设置为 1;LI2LOVOL(bit5:3)和 RI2ROVOL(bit5:3)分别控制左右输入通道的增益,0~7 表示-6 ~ -15dB 的增益调节范围,默认设置为 111,即-15dB。
18,寄存器 43(2Bh),是 DAC 控制寄存器 21,这里我们只关心 slrck(bit7)这个位,用于控制 DACLRC 和 ADCLRC 是否共用,我们设置为 1,表示共用。
以上,就是我们使用 ES8388 时所需要用到的一些寄存器,按照以上所述,对各个寄存器进行相应的配置,即可使用 ES8388正常播放音乐了。关于 ES8388更详细的寄存器设置说明,我们这里就不再介绍了,请大家参考 ES8388 的数据手册自行研究。
四、SAI 简介
STM32H743 自带了两个串行音频接口(SAI1 和 SAI2),SAI 具有灵活性高、配置多样的特点。可以支持:I2S 标准、LSB 或 MSB 对齐、PCM/DSP、TDM 和 AC 97 等协议,适用于多声道或单声道应用
SAI 通过两个完全独立的音频子模块来实现这种灵活性与可配置性,每个音频子模块与多达 4 个引脚(SD、SCK、FS 和 MCLK)相连。如果将两个子模块声明为同步模块,则其中一些引脚可以共用,从而可释放一些引脚用作通用 I/O。MCLK 引脚是否用作输出引脚取决于实际应用和解码的要求以及音频模块是否配置为主模块。SAI 可以配置为主模式或配置为从模式。音频子模块既可作为接收器,又可作为发送器;既可与另一模块同步,又可以不同步。
STM32H743 自带的 SAI 接口,其特点包括:
●具有两个独立的音频子模块,子模块既可作为接收器,也可作为发送器,并自带 FIFO
●每个音频子模块集成多达 8 个字,每个字 32 位的 FIFO
●两个音频子模块间可以是同步或异步模式
●两个音频子模块的主/从配置相互独立
●当两个音频子模块都配置为主模式时,每个子模块可设置互相独立的采样率
●数据大小可配置:8 位、10 位、16 位、20 位、24 位或 32 位
●支持:I2S、LSB 或 MSB 对齐、PCM/DSP、TDM 和 AC 97 等音频协议
●高达 16 个大小可配置的 Slot,可选择音频帧中的哪些 Slot 有效
●支持 LSB 或 MSB 数据传输
●支持 DMA,有 2 个专业通道,用于处理对每个 SAI 音频子模块的专用集成 FIFO 的访问
STM32H743 的 SAI 框图如图 60.1.3.1 所示:
本章,我们将用 SAI 接口来驱动 ES8388,而 ES8388 的接口是 I2S 接口的,所以,本章我们只介绍 SAI 支持 I2S 协议使用的方法,其他协议的使用介绍,请看《STM32H7xx 参考手册_V3(中文版).pdf》第 51 章。
1.SAI I2S 信号线
SAI 作为 I2S 使用的时候,同 I2S 接口连接的信号线如表 60.1.3.1 所示:
表中,A/B 表示 SAI 内部的两个独立的音频子模块,可以独立的连接 I2S,也可以共同连接同一个 I2S(主从同步模式),主从同步模式,常用于全双工 I2S 通信(读/写同时进行),主从同步模式,还可以省略一些信号线(SCK/FS/MCLK 等)。
**FS_A/B:**连接 I2S 的 LRC 脚,用于切换左右声道的数据,它的频率等于音频信号采样率(fs)。
**SCK_A/B:**连接 I2S 的 BLCK 脚,用作位时钟,是 I2S 主模式下的串行时钟输出以及从模式下的串行时钟输入。SCK_A/B 频率= FS_A/B 频率(fs)slot 个数单个 slot 大小(slot 后面介绍)。
**SD_A/B:**连接 I2S 的 DACDAT/ADCDAT 脚,是数据输入/输出脚,用于发送或接收数据(单个音频子模块,只能做半双工通信。全双工需要 2 个音频子模块同时工作,使用主从同步模式)。
**MCLK_A/B:**连接 I2S 的 MCLK 脚,是主时钟输出脚,固定输出频率为 256*fs,fs 即音频信号采样频率(fs)。
2.SAI slot 简介
slot 是 SAI 音频帧中的基本元素,音频帧中 slot 的数目通过 SAI_xSLOTR 寄存器配置,每个音频帧的 slot 数,最大是 16。在 I2S 模式下,SAI 中 slot 的传输方式如图 60.1.3.2 所示:
上图中,一个音频帧中,slot 的个数为 6 个,每个半帧有 3 个 slot,根据 slot 数与音频帧的对齐与否分为两种情况,我们一般设计为 slot 数与音频帧对齐,也就是图 60.1.3.2 中下部分图所示的传输方式:一个半帧刚好是 3 个 slot,每个 slot 可以传输一个声道的音频数据,这样,6个slot就可以传输6个声道的音频数据。一般音频文件都是立体声,所以只需要2个slot即可,每个半帧一个 slot。STM32 的 SAI 最多可以实现 16 声道数据传输(16 个 slot)。
每个 slot 的大小是可以配置的,如图 60.1.3.3 所示:
3.SAI 时钟发生器
4.SAI 相关寄存器
SAI 配置寄存器:SAI_xCR1
SAI 帧配置寄存器: SAI_xFRCR
SAI slot 寄存器: SAI_xSLOTR
PLLSAI 配置寄存器: RCC_PLLCKSELR
RCC专用时钟配置寄存器:RCC_PLL3DIVR
SAI 数据寄存器:SAI_xDR
5.SAI 录音简介