嵌入式音视频开发(音频模块)
PCM音频原始数据
1.PCM数据的生成过程
音频原始数据PCM,PCM全称是脉冲编码调制数据。PCM数据是未经过压缩的音频数据,它是由模拟信号经过采样、编码等步骤转换成标准的数字信号,下面是PCM生成的总流程。音频模拟信号转换成数字信号需要经过采样、量化、编码三大步骤会变成PCM音频数字信号。
-
采样:采样是我们音频最重要的知识点之一,它指的是把一段连续的模拟信号转换成离散的数字信号。而采样率就指的是每秒钟采样的个数,而根据奈奎斯特采样公式:**当采样率大于等于连续信号的2倍时,采样信号就能够无差别还原出原始的信号。**比方说人类的听觉频率是20HZ-20KHZ,而采样率就需要达到40KHZ以上才能够保证数据的完整性。
-
量化:量化指的是在坐标轴上,把每一个离散数据进行数字化操作。换言之就是把我们每一个采样的点都按照数字化表示出来。量化的过程就是把刚才我们转换成的数字信号一个一个点用竖线显示出来,这样的话我们在数字化的时候就方便很多。
-
编码:把每一个量化的采样点存储起来,并以二进制的形式表现出来的过程就是编码。
把所有的编码数据存储起来,就是一段连续的PCM数据。PCM数据,二进制形式:011011110111101……
对于一个音频的原始数字信号的生成:采样->量化->编码: PCM数据
2.PCM数据重要参数
-
**1.采样率:**指的是每秒采样的个数,比方说48000HZ就相当于一秒钟PCM采集48000个采样点,总体来说采样率越高,音频的质量越好。PCM数据常用的采样率有:
192000HZ:192KHZ(蓝光、高清电影DVD)
96000HZ: 96KHZ(蓝光、高清电影DVD)
48000HZ:48KHZ(数字电视、DVD) (最常用)
44100HZ:44.1KHZ(CD音质)
22000HZ:22KHZ(无线广播)
-
**2.采样深度:每次采样的大小,比方说如果采样深度是16BIT,那声音就有2的16次方的振幅,而32bit就相当于有2的32次方个振幅。声音振幅越多,声音的质量就会越高。**在PCM中,有三种常见的采样大小:8 BIT、16BIT、32BIT这三种采样格式。
-
3.通道数:PCM一般有四种通道数,分别是单通道、双声道、四声道、5.1声道
- 单声道:指的是只有一个声音的通道,比方说电话、喇叭之类的
- 双声道(立体声):双声道指的是有两个声音的通道,声音在录制的过程中分配到两个独立的声道,这让人听起来就有立体的感觉。
- 四声道:四声道指的是前左、前右、后左、后右四个发声通道。观众听起来,则像被声音包围了一样。
- 5.1声道:5.1声道广泛运用在家庭影院,因为开发的时候用的较少,所以这里就不多介绍。
-
**4.PCM比特率:**比特率指的是每秒传输的比特数,一般PCM的比特率 = 采样率*采样深度*通道数。比方说采样率是48000,采样深度是16BIT,通道数2,那它PCM比特率的计算公式就等于48000 * 16 * 2 = 1536000bit
-
**5.PCM文件大小:**假设一个PCM音频设备采样率48000、采样精度是16bit、2通道,大概采集10分钟数据,那它的大小:采样率 * 采样深度 * 通道数 * 时长 = 48000 * 16 * 2 * 10 * 60 = 921600000bit,然后再把bit转换成字节(BYTE) 921 600 000/8/1024/1024 = 109M
3.PCM采样格式
8位单声道 | 0声道|0声道|0声道 |
---|---|
8位双声道 | 0声道(左)|1声道(右)|0声道(左)|1声道(右) |
16位单声道 | 0声道(低字节)|0声道(高字节)|0声道(低字节)|0声道(高字节) |
16位双声道 | 0声道(左,低字节)|0声道(左,高字节)|1声道(右,低字节)|1声道(右,高字节) |
上面是PCM单双声道的存储布局,这里我们来重点讲解一下双声道的布局。一般双声道的存储有两种存储方式,一种是交错模式、另外一种是非交错模式。交错模式:首先记录第一帧的左声道样本和右声道样本;非交错模式:首先先记录一个周期内所有帧的左声道样本、再记录所有右声道样本
双声道的存储模式:
交错模式:L R L R L R L R
非交错模式:L L L L R R R R
RV1126音频AI模块
1.什么是音频AI模块
RV1126的AI模块指的是音频输入模块,它的作用是通过内置芯片读取麦克风等音频的模拟信号,然后把音频模拟信号转换成数字信号。在RV1126里面,音频AI模块是所有音频输入的入口。下面是AI模块和麦克风等音频输入模块的关系:音频输入设备(音频模拟信号)->VI模块(采样、量化、编码)->PCM音频数字信号
。
2.AI模块的结构体和API
//音频输入属性结构体
typedef struct rkAI_CHN_ATTR_S {
RK_CHAR *pcAudioNode; //音频设备节点路径
Sample_Format_E enSampleFormat; //采样格式。
RK_U32 u32Channels; //通道数。
RK_U32 u32SampleRate; //采样率。
RK_U32 u32NbSamples; //每帧的采样点个数
AI_LAYOUT_E enAiLayout; //输入布局类型
} AI_CHN_ATTR_S;
- **RK_S32 RK_MPI_AI_SetChnAttr(AI_CHN AiChn, const AI_CHN_ATTR_S *pstAttr); **
- 设置AI通道属性
- 参数:
- AiChn:AI模块的通道号ID,取值范围是[0, AI_MAX_CHN_NUM]
- pstAttr:AI_CHN_ATTR_S结构体指针
- RK_S32 RK_MPI_AI_EnableChn(AI_CHN AiChn);
- 打开AI通道
- RK_S32 RK_MPI_AI_StartStream(AI_CHN AiChn);
- 启动AI音频流
多线程获取音频AI的PCM数据
学会如何通过RKMEDIA的API获取音频的输入的PCM数据并且保存起来。
- 初始化AI模块
- 启动AI模块开启采集
- 开启多线程采集AI数据并保存到本地
#include <...>
#include <rkmedia_api.h>
#define AUDIO_PATH "default"
#define AI_CHN 0
//获取PCM数据的线程
void *get_ai_pcm_thread(void *args)
{
pthread_detach(pthread_self());
FILE *pcm_file = fopen("test_ai.pcm","w+");
MEDIA_BUFFER mb;
while(1)
{
//获取PCM数据的线程
mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_AI, AI_CHN, -1);
if(!mb){
printf("RK_MPI_SYS_GetMediaBuffer Failed....\n");
break;
}
printf("get_pcm_data success...\n");
fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb)