音频数据如何以原始pcm格式存储?

时间:2018-04-11 00:44:21

标签: ffmpeg pcm audioformat

我正在编写一个应用程序来处理音频,我需要将文件(wav,MP3等)转换为原始数据(样本显示为浮点数)。

我在cmd中使用ffmpeg:

ffmpeg -i test.wav -f s16le -acodec pcm_s16le output.dat

如何在output.dat文件中表示样本?我知道一个样本在S16下需要两个字节,双通道意味着它存储为L1 R1 L2 R2 ...但是这个文件是否带有帧表示或者dat文件中的所有字节都是样本值?通过两种方法转换后的文件test.wav的大小并不相同。一个是通过libav在ffmpeg网站上使用示例代码,另一个是上面提到的,直接在cmd中使用ffmpeg.exe,前一种方法给我一个稍小的文件大小。我很困惑当我发现有人说pcm使用框架演示文稿(2048个样本帧)。

我实际上不需要任何代码,但希望有人可以详细解释原始pcm格式。

非常感谢

2 个答案:

答案 0 :(得分:2)

-f s16le生成一个没有标题/预告片或任何元数据的原始样本转储。因此,它只是L1 R1 C1 L2 R2 C2...,其中L R C代表3个通道。

当ffmpeg读取这样的文件时,它将一次从每个通道读取并构建1024个样本,除非sampling rate/25小于1024,在这种情况下,它将读取并打包那些许多样本,例如对于16000 Hz的流,sampling rate/25 = 640,小于1024。因此,ffmpeg会将640x2 = 1280个样本打包为此类立体声流。

答案 1 :(得分:0)

从4400位采样率的位深度为16位的立体声wav文件开始,你有一个标准的CD质量音频文件......在命令行上发出这个以在未知文件上显示这些统计数据

ffprobe Cesária_Évora.wav

典型输出

  Duration: 00:00:21.51, bitrate: 1411 kb/s
    Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 2 channels, s16, 1411 kb/s

从wav问题创建PCM文件

ffmpeg -i Cesária_Évora.wav -f s16le -acodec pcm_s16le cesaria.dat

这个文件严格来说是L1 R1 L2 R2无所不能......根本没有框架的概念...编写代码来操作PCM文件时要记住你的位深度以及你的文件是否有little endian或big endian字节结构...只要你的文件有8位的位深度,你就可以安全地忽略字节序,因为你永远不需要移位字节,但是因为上面的文件有16位的位深度,这意味着每个点都是音频曲线由单个16位数字

表示

当读取这样一个文件时,这个16位数字存储在两个字节中......如果读取字节时是小端,则最左边的字节是最小的字节,后面是下一个更重要的字节,意思是

L1 R1 L2 R2 

表示音频曲线上两点的立体声表示实际上是

Llittle1 Lbig1 Rlittle1 Rbig1 Llittle2 Lbig2 Rlittle2 Rbig2

当我们谈到用于存储这两个点的单个字节时......类似地,如果我们有24个字节的位深度,那么

Llittle1 Lbigger1 Lbiggest1 Rlittle1 Rbigger1 Rbiggest1  

所以从概念上讲,在这里阅读一个小端文件是如何解析曲线上一个点的一个通道的PCM

Llittle1 Lbig1

现在要生成单个值L1,您在概念上执行此操作

L1 = ( Lbig1 << shift 8 bits to left ) + Llittle1

不确定这是否是您寻找的抽象级别,但它是钉住数字音频的垫脚石

超级有用的工具是Audacity,它允许您导入PCM格式的原始音频文件,因为我们在cesaria.dat上面生成... Audacity - &gt;档案 - &gt;导入 - &gt;原始数据 - &gt;选择cesaria.dat - &gt;

enter image description here