开篇语

        如果对嵌入式音频这个领域感兴趣,可以看《实用数字信号处理:从原理到应用》,我认为这本书基本涵盖了这个领域的理论基础,虽然要完全看懂这本书,会需要大量的前置知识。

        但是这篇帖子将尽可能地浅显易懂,不直接使用专业名词,方便刚入行的嵌入式工程师和大学生看懂,甚至搞纯软件的软件工程师也能有所收获。

        这篇帖子尽量回答一个问题,现代数字音频系统的核心内容是什么?(就像告诉钢铁工人什么是钢一样)

超直观介绍专业名词

我先介绍这些名词:

        采样率,位深,通道。你可以用这三个名词,来定义计算机世界里的任何声音。

采样率(Sample Rate)

        首先下载开源软件《Audacity》,这是一个开源的很简洁的声音编辑软件。

使用这个软件打开该帖子附件中的test.wav文件,或者你自己的.mp3文件等等。

        我们点击放大镜放大,当放到足够大,就可以看到一个个点。

这就是计算机存储音频的方式:一个接着一个采样点。

test.wav放大前

test.wav放大后,可以看到本质上其实是一个个采样点

        如果仔细数一下可以发现,我们的test.wav文件,一毫秒的音频(红框处)其实是由48个点组成的。也就是说,一秒的音频是由48000个点组成的。术语上会说,这个音频的采样率是48000(48K)。

        常见的采样率有48K 44K 16K 8K等。一段音频的采样率对于人耳,就跟电视的像素对于眼睛一样,理论上音频采样率越高,越接近这段声音在物理世界的真实表现。大家可以实践一下,采样率低于44K,则声音明显变得很“糊”。

通道(Channels)

        我们的test.wav有两个通道,事实上,这两个通道会送到我们的左耳和右耳,也就是所谓的左声道和右声道。

两个通道

位深(Bit Depth)

        上一节我们提到采样点,而存储一个采样点所需的空间就叫位深。我们查看test.wav的大小为768170字节,而这个音频的时长约为4秒,有2个通道,采样率是48000,我们来算一下:

768170 / 4 / 2 / 48000 = 2

也就是说,每个采样点耗用了2个字节,一个字节是8比特,也就是说这个音频里一个采样点占用了16比特,也就是我们常的说16bit。常见的位深有16bit 24bit和32bit。

(以防真的有对比特不熟悉的伙伴,这里展开说说:从生活出发,我们常说的每个月1G流量,其实1G = 1024兆 = 1024x1024x1024字节 = 1024x1024x1024x8比特,类似金钱里万,千,百 的关系)

PCM(Pulse Code Modulation)

        所谓PCM其实就是上图提到的一个个采样点,是音频在计算机世界存在的形式。工程师们一般会这样说:

        “你这个.pcm文件以什么格式打开”   //询问.pcm文件要以什么采样率、通道数、位深打开

        “mp3文件解码出来的.pcm文件发你了” //任何格式的音频都要解码成pcm才能进行播放

        “帮我把安卓底层的pcm码流抓出来” //手机里音乐app播放到安卓系统底层时,已经被安卓原生的解码库解码成pcm,安卓底层工程师在分析问题时,一般会要求提供流经安卓系统底层的pcm音频数据。

WAV

        我们多次提到了test.wav,WAV和PCM是什么关系?

        前面我们提到PCM就是一个个采样点,但是如果我们要听这段PCM时,我们仍然要知道这段采样点该以什么样的采样率,通道数,位深打开。

        下面我们来做一个实验,我们将test.wav以16K 2ch 16bit的格式导入Audacity,试一下听起来怎么样。

        具体的操作为: Audacity->文件->导入->原始数据->选择test.wav->选择下图的格式

        听一下,发现声音长度变成12秒了,而且声音低沉了很多。此时说明我们没有以正确的采样率打开这个test.wav。

        让我们一起再试一下以48K 2ch 16bit的格式打开。

        发现声音听起来正常了,与Audacity->文件->打开->test.wav的时候听起来一模一样。

        为什么使用"文件->打开"的方式,听起来是正常的,为什么Audacity知道这个音频文件应该以48K 2ch 16bit的方式打开?

        原因其实是因为我们把采样率、通道数、位深 这三个信息存储在test.wav这个文件的开头了,Audacity打开test.wav时,自动读取了采样率、通道数、位深的信息,然后以正确的格式打开了文件。

既WAV = 格式头(采样率 通道数 位深) + PCM。

        大家可以玩一下,将test.wav以各种采样率,各种通道,各种位深导入Audacity并听一下,试一下是否能发现什么规律哦。

MP3

        MP3其实就是WAV的压缩版,可以看到附件中的test.mp3比test.wav小很多。

        我们试一下Audacity->文件->导入->原始数据->选择test.mp3

会发现是完完全全的噪声。

        但是Audacity->文件->打开->test.mp3,听起来则跟test.wav一样。

        这其实像我们可以双击附件中的《测试.txt》文本文件,直接看到文字;但是需要先解压《测试.zip》才能打开《测试.txt》看到文字。

        Audacity->文件->打开->test.mp3自动做了类似解压的动作,我们把这种.mp3转变成.pcm的操作称为解码(decode)。

通道、声道、slot

通道与声道

        上一章我们介绍了通道的概念,但是我们经常也听到声道的概念,本章从个人工作经验出发,介绍下这两个名词一般会怎么用。

        实际上如果不细究的话,可以混用通道和声道,这两个名词的含义本质上是相同的。

比如我们可以这么说:

        这个MP3文件是两个声道的。

也可以这么说:

        这个MP3文件是两个通道的。

一般不会有人指出有什么不妥。

        但是实际工作中,一般在解码前会使用声道,而在解码后会使用通道。

比如这么说:

        这个左右两声道的MP3文件,解码后给到安卓底层是两通道的PCM。

也会这么说:

        这个5.1声道的杜比音频,解码后是一个6通道的PCM文件。

(杜比5.1 = 前置左声道,前置右声道,中置声道,环绕左声道,环绕右声道 + 低频效果声道)

slot

        slot一般出现在各种芯片手册里,行业外比较少见。

slot也可以理解为通道,比如我们会说:

        这个SoC芯片把两通道的音频传输给功放芯片,第一个通道放在slot0,第二个通道放在slot1。

        接下来我们将介绍数字音频接口,会把这个slot的概念讲得更清晰。

数字音频接口

(DAI Digital audio interface)

        本文所说的数字音频接口,处于下图所示的位置(出自实用数字信号处理38页)。

        现代数字音频产品中,处在上图"数字处理"位置的芯片,有可能是一个SoC芯片,也有可能是一个DSP芯片。

(SoC芯片 System on Chip 简单来说就是手机里的CPU,在电路板上是一个小方块;

DSP芯片 Digital Signal Processor 是一个专门用来处理音频的专用计算单元,在电路板上也是一个小方块;

DSP可以是Digital Signal Processor的缩写,也可以是Digital Signal Processing的缩写,前者是一块芯片,后者是大学里的一门课,大家可别搞混了哦)

        处在DAC位置的一般是功放芯片(Power Amplifier Chip),功放芯片可以将数字音频转成模拟信号用于驱动喇叭。

        简单来说,数字音频接口就是SoC(或DSP) 和 功放芯片(或DAC) 之间的几根铜线(3到4根),目前常用的有I2S和TDM。

        如何理解数字音频接口里的"数字"俩字?所谓数字,简单来说,用示波器量出来是下图这样的,传输的是0101的数据,而不是模拟信号。

网图 侵删

        既然是数字信号,那么我们就可以用逻辑分析仪把数字音频接口中的数据抓出来,进行分析。接下来两节,我将展示我工作中抓到的I2S和TDM数据,并讲解如何将其转成音频,使得能在电脑上进行播放。

(逻辑分析仪相当于示波器抓取波形后,顺便帮你转成0101,比如电压为0V则转成0,电压1.8V则转成1)

I2S

        首先大家先下载这个软件,方便打开我抓取的逻辑分析仪数据。

下载 - DreamSourceLab(逻辑分析仪/示波器)

        I2S接口由四根线组成。I2S分主从,谁做I2S主,谁负责发送时钟。如下图所示,则为SoC做I2S主,发送SCK和WS信号。

        SD out则是SoC发送给AMP的PCM数据,SD in是AMP发送给SoC的PCM数据,虽然一般来说。AMP不会给SoC传PCM数据,下图的含义指的是,I2S是支持同时发送和接收的。

        接下来是本文的重点,大家双击附件中的I2S/raw.dsl,解析协议选择I2S,协议细节如下,这是我在调试芯片时选择的I2S格式 (调试I2S时候,SoC和AMP的I2S配置要相同):

点击确定后,等待约五分钟,解析进度达到100%即可。

我们放大看看典型的I2S时序图

        WS为低电平时,代表此时传输的是左声道;为高电平时,传输的是右声道。I2S只能传输两个通道。左声道放在slot0,右声道道放在slot1。

WS的频率,即为传输的PCM数据的采样率,现代数字音频系统中,一般为48K。

SCK的频率约为2.33MHz,这个2.33MHz怎么来的呢?

其实是48000 x 24(bit) x 2(通道) = 2330000。

其中48000为WS的频率,既传输的PCM数据的采样率。

24bit为每个slot占用了24个上升沿,既传输的PCM数据的位深。

2通道是左右两个声道。

接下来我们把逻辑分析仪抓到的数据保存下来(CSDN\I2S\txt2pcm\in.txt),并转换成音频。

我们要做的,就只是把这些数据,读取出来,写入一个PCM文件而已。

给大家一个简单的例子 (写得比较随意大家凑合看吧)

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <sstream>

using namespace std;
#define HEAD "Left channel: "

int main() {

    string line;
    ifstream inFile("in.txt");
    const char *p = NULL;
    stringstream ss;
    unsigned int data;
    string buffer;
    unsigned int error = 0;

    truncate("output.pcm", 0);

    int pcm_fd = open("output.pcm", O_WRONLY | O_CREAT, 0666);

    if ( inFile.is_open() && pcm_fd > 0 ) {

        while (getline(inFile, line)) {
            if ( p = strstr(line.c_str(), HEAD) ) {
                sscanf(p + strlen(HEAD), "%08x", &data);
                printf("%08x\n", data);
                write(pcm_fd, (void*)&data, 3); //3bytes 24bit
            }
        }
        close(pcm_fd);
        inFile.close();
    }
    else {
        cout << "Unable to open file" << endl;
    }
    return 0;
}

将解析出来的output.pcm导入Audacity,是一分钟的音频。

TDM

TDM相比I2S更为灵活,可以传输多个通道,常用的有TDM8(传输8个通道),TDM16(传输16个通道)。

严格来说,I2S其实是TDM的子集,I2S就是TDM2。

我们来看看TDM常见的接线方式。

下图为TDM16常见的框架图,这意味着TDM16支持同时下行32个通道和上行32个通道,可玩性就比I2S强太多了。

来看看我在自己项目抓的时序图吧。

可以看到SYNC的频率依然是48K,既传输的PCM的采样率。

一共有16个slot,在抓取数据时,只有slot0,slot1填充了数据。

此时SCK的频率是多少呢,我们来算一下:

        48000 x 16(ch) x 32 (bit) = 24.6MHz

同样的,我们把TDM/output.pcm以48K 32bit 1ch的格式导入Audacity,则可以听到音乐。

结束

        本文以尽可能通俗的语言,介绍了什么是PCM,以及嵌入式领域的数字音频接口I2S TDM,希望能帮助到刚接触数字音频的小伙伴。

        一个SoC平台的数字音频接口数量以及支持传输的通道数基本决定了这个SoC平台能支持的产品形态,比如支持多少个喇叭等。如果大家感兴趣,可在评论中回复,我会另写一篇帖子,介绍下数字音频产品中的通道的分配策略,以及目前行业前沿的常见做法。

本文用的音频皆是艺术家方大同的作品。

缅怀方大同。

Rest in Peace,Mr. Fong 

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐