【TinyALSA全解析(二)】wav和pcm音频文件格式详解

wav和pcm音频文件格式详解

/*****************************************************************************************************************/

声明: 本博客内容均由https://blog.csdn.net/weixin_47702410原创,转载or引用请注明出处,谢谢!

创作不易,如果文章对你有帮助,麻烦点赞 收藏支持~感谢

/*****************************************************************************************************************/

一、本文的目的

tinyalsa中可以直接传输的是wav文件格式,无论是tinycap还是tinyplay其使用的都是wav文件格式,想要对tinyalsa源码有更详细的了解,需要熟悉wav格式的文件内容。

在安卓音频中常见的两种格式为pcm格式和wav格式。本文分析这两种格式。

二、wav和pcm格式文件介绍

以录音为例说明:

音频驱动传输的数据一般都是原始数据,是由硬件处理得到的一系列数字信号(即由ADC得到的原始数据)。其本身不会包含对声音信息的记录,比如声道数、采样率、位深等等。故此如果你用音乐播放器播放pcm格式的音频文件的时候,就需要指定这个文件的声道数、采样率、位深等等信息。

那么能不能将音频的信息存储在音频文件中,让播放器去读取音频文件的时候,可以顺便读取到音频格式的信息呢?这样就不用每次播放都需要去指定音频格式了。

有的,那就是mp3、wav、aac等等音频格式,其会保存音频的信息(采样率、声道数、位深等信息),当播放器播放的时候,会在文件的指定位置读取音频信息去播放,这样就不用用户去指定音频的信息了,直接点击播放按钮,剩下的就交给软件处理就能让设备发出声音了!

简单理解,wav格式文件内容 = pcm格式文件内容 + 音频描述内容。

那为什么不用mp3或者aac格式或者其它格式?因为类似mp3和aac格式是有损且压缩的格式,不仅会丢掉一部分原始音频数据,还要需要编解码(解压 /压缩)处理。

那为什么不用其它无损且不压缩就好了?因为用了其它无损不压缩的格式,你又会问为啥不用wav,是伪逻辑。

三、pcm格式文件解析

如前面分析:pcm格式文件的内容是仅且包含音频原始数据的(原始就是未压缩未丢失的意思)。那么这个文件格式展开就是一系列的声音表示数据了。以某个PCM文件的片段数据"0x01 0x02 0x03 0x04"为例,假如地址是从低到高,不同的音频格式的声音内容如下表示:

音频格式\原始数据 0x01 0x02 0x03 0x04 0x...
8位单声道 0声道 0声道 0声道 0声道 0声道
8位双声道 左声道 右声道 左声道 右声道 左声道
16位单声道 0声道数据1-低字节 0声道数据1-高字节 0声道数据2-低字节 0声道数据2-高字节 0声道数据3-低字节
16位双声道 左声道数据1-低字节 左声道数据1-高字节 右声道数据1-告字节 右声道数据1-高字节 左声道数据2-低字节

四、wav文件内容解析

4.1 文件内容描述

如前面分析:wav格式文件内容 = pcm格式文件内容 + 音频描述内容

wav文件的格式是怎么样的呢?

可参考网站:http://soundfile.sapp.org/doc/WaveFormat/

文件内容的数据框图:

关于这张图的描述:

偏移与大小 名称 说明
0 4 ChunkID 包含 ASCII 形式的字母"RIFF"(0x52494646 大端形式)。
4 4 ChunkSize 36 + SubChunk2Size,或更准确地说:4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)这是此数字之后的块的其余部分的大小。这是整个文件的大小(以字节为单位)减去未包含在此计数中的两个字段的 8 字节:ChunkID 和 ChunkSize。
8 4 格式 包含字母"WAVE"(0x57415645 大端形式)。
12 4 Subchunk1ID 包含字母"fmt"(0x666d7420 大端格式)。
16 4 Subchunk1Size 16 用于 PCM。这是该数字之后的其余子块的大小。
20 2 AudioFormat PCM = 1(即线性量化)1 以外的值表示某种形式的压缩。
22 2 NumChannels Mono = 1、Stereo = 2 等
24 4 SampleRate 8000、44100 等
28 4 ByteRate == SampleRate * NumChannels * BitsPerSample/8
32 2 BlockAlign == NumChannels * BitsPerSample/8 1 的字节数样本包括所有通道。
34 2 BitsPerSample 8 位 = 8,16 位 = 16,等等
2 ExtraParamSize 如果是 PCM,则不存在
X ExtraParams 用于额外参数的空间
36 4 Subchunk2ID 包含字母"数据"(0x64617461 大端形式)。
40 4 Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8 这是数据中的字节数。您还可以将其视为该数字后面的子块的读取大小。
44 * Data 实际的声音数据。

4.2 实战分析

以霉霉的stay歌曲为例分析,首先解析文件成二进制的格式,文件前面的部分的内容如下:

复制代码
xxd -l 176  /d/music/stay.wav
00000000: 5249 4646 9a56 2f02 5741 5645 666d 7420  RIFF.V/.WAVEfmt
00000010: 1000 0000 0100 0200 44ac 0000 10b1 0200  ........D.......
00000020: 0400 1000 4c49 5354 6e00 0000 494e 464f  ....LISTn...INFO
00000030: 4941 5254 0d00 0000 5461 796c 6f72 2053  IART....Taylor S
00000040: 7769 6674 0000 494e 414d 2100 0000 5374  wift..INAM!...St
00000050: 6179 2053 7461 7920 5374 6179 2028 4b61  ay Stay Stay (Ka
00000060: 7261 6f6b 6520 5665 7273 696f 6e29 0000  raoke Version)..
00000070: 4950 5244 0c00 0000 5265 6420 4b61 7261  IPRD....Red Kara
00000080: 6f6b 6500 4953 4654 0e00 0000 4c61 7666  oke.ISFT....Lavf
00000090: 3539 2e33 342e 3130 3100 6461 7461 0056  59.34.101.data.V
000000a0: 2f02 0000 0000 0000 0000 0000 0000 0000  /...............

这个数据是自左向右,自上而下查看,对数据的分析如下:

5249 4646:这是 "RIFF" 的 ASCII 码的十六进制表示,表示这是一个 RIFF 文件格式。

9a56 2f02:这是文件大小字段,表示文件的大小(减去前8个字节)。

5741 5645:这是 "WAVE" 的 ASCII 码的十六进制表示,表示这是一个 WAVE 格式的音频文件。

666d 7420:这是 "fmt " 的 ASCII 码的十六进制表示,表示接下来是音频格式的子块。

1000 0000:这是子块的大小,值为16,表示接下来的16个字节描述音频格式。

0100:这是音频格式代码,值为1,表示这是 PCM 格式的音频。

0200:这是声道数,值为2,表示这是立体声音频。

44ac 0000:这是采样率,值为44100,表示每秒采样44100次。

10b1 0200:这是字节率,值为 176400,表示每秒数据的字节数。

0400:这是块对齐,值为4,表示每个采样包含的字节数。

1000:这是每个样本的位数,值为16,表示这是16位的音频。

接下来的部分包含了一些元数据,如艺术家名字(Taylor Swift)、歌曲名字(Stay Stay Stay (Karaoke Version))、产品名(Red Karaoke)和软件名(Lavf59.34.101)。

最后的 6461 7461 是 "data" 的 ASCII 码的十六进制表示,表示接下来是音频数据的子块。0056 2f02 是子块的大小,表示接下来的音频数据的大小。

接下来的 0000 是音频数据的开始部分,文件的后面的其它内容都是实际的声音数据了。

五、如何在各种音频格式之间进行转换

一般用FFmpeg软件进行转换,先在当前的设备安装好FFmpeg软件,然后用命令行就可以进行转换了,常用的示范如下:

复制代码
将mp4视频提取wav格式:
ffmpeg -i D:\input.mp4 -vn -acodec pcm_s16le -ar 44100 -ac 2 D:\output.wav

将wav格式转变为pcm格式:
ffmpeg -i D:\output.wav -f s16le -acodec pcm_s16le D:\output.pcm

将pcm格式转变为wav格式:
ffmpeg -f s16le -ar 44100 -ac 2 -i D:\output.pcm c:\output.wav

注意上面的命令中指定的采样率为44.1k ,双声道,存储格式是s16le。读者要实际根据想要的目标文件或者源文件的参数进行配置。

相关推荐
LiuYaoheng2 小时前
【Android】View 的基础知识
android·java·笔记·学习
山河君2 小时前
webrtc之高通滤波——HighPassFilter源码及原理分析
算法·音视频·webrtc·信号处理
出海小纸条2 小时前
Google Play 应用被拒-数据安全表单无效(设备上的应用)
android
勇往直前plus2 小时前
Sentinel微服务保护
java·spring boot·微服务·sentinel
星辰大海的精灵2 小时前
SpringBoot与Quartz整合,实现订单自动取消功能
java·后端·算法
塵觴葉2 小时前
Linux内核网络的连接跟踪conntrack简单分析
linux·网络·conntrack
小鸡脚来咯2 小时前
一个Java的main方法在JVM中的执行流程
java·开发语言·jvm
江团1io02 小时前
深入解析三色标记算法
java·开发语言·jvm
天天摸鱼的java工程师3 小时前
RestTemplate 如何优化连接池?—— 八年 Java 开发的踩坑与优化指南
java·后端
m0_464608263 小时前
监控 Linux 服务器资源
linux