摘要
想要根据 wav 格式的音频文件,绘制出如软件「GoldWave」所绘制的音频数据的图像。探索波形图绘制的一些数据处理。
本文记录了初探时可能会遇到的一些问题。
预热
了解 wav 的文件格式。其中主要包括头部内容和 data 块内容。而我们用于画图的数据就来自于 data 块。
了解该文件格式的分析推荐两篇文章:
前提
测试音频格式为:单声道、采样率 16k,采样位数 16 的 wav 文件。
不是这个格式的就用 ffmpeg 转成这个格式后再处理。
头部数据示例
00H : 5249 4646 8857 0f00 5741 5645 666d 7420 [RIFF.W..WAVEfmt ]
10H : 1000 0000 0100 0100 803e 0000 007d 0000 [.........>...}..]
20H : 0200 1000 4c49 5354 4800 0000 494e 464f [....LISTH...INFO]
30H : 4943 4d54 2500 0000 7669 643a 7630 3230 [ICMT%...vid:v020]
40H : 3333 3364 3030 3030 6269 3463 6f38 7331 [333d0000bi4co8s1]
50H : 6e33 6531 6267 6a35 3334 7367 0000 4953 [n3e1bgj534sg..IS]
60H : 4654 0e00 0000 4c61 7666 3537 2e38 332e [FT....Lavf57.83.]
70H : 3130 3000 6461 7461 1457 0f00 0000 0000 [100.data.W......]
1. 数据说明:
- 左侧为十六进制的计数数字。
H意义未知。 - 中间数据为十六进制的信息。画图主要靠这块头部后面接着的
data。 - 右侧为中间数据转成
ASCII码的信息。 wav文件以小端模式进行数据存储
2. 头部示例解释:
非常详细的解释可以看上面的参考文章。这里记录一些看参考文章后获取的一些画图有用到的点:
- 1 个十六进制的字符等于 4 个二进制数 16=2^4。2 个十六进制字符等于 8 个二进制数为 1 个字节。
- 04H ~ 07H
8857 0f00对应的是后面文件的大小,由小端模式转成大端模式后是000f 5788,换算为十进制的 1005448 ,加上前面的 8 个字节(5249 4646为 4 字节,加上自身 4 字节)就等于文件大小 1005456 。 - 14H ~ 15H
0100对应的十进制是 1,表示线性的 PCM 编码。 - 16H ~ 17H
0100对应的十进制是 1,表示单声道,MONO。 - 18H ~ 1BH
803e 0000对应的十进制是 16000,表示采样率是 16000。 - 1CH ~ 1FH
007d 0000对应的十进制是 32000,波形数据传输率,每秒多少个字节,可以用 (1005456 - 128) / 32000 = 31.4165 s 获取音频的总时长。 - 22H ~ 23H
1000采样位数 16 位。 - 中间夹着了一些 ffmpeg 的信息
- 78H ~ 7BH
6461 7461对应的ASCII码是 “data”,标示头结束,开始数据区域。 - 7CH ~ 7FH
1457 0f00表示采样数据的总数,从此后开始的数据总数(包括此行最后用来补齐的0000 0000),十进制的 1005332 。
3. 使用 data 部分的数据绘制波形图
当你拿到文件的二进制数据,转成十六进制,然后截取出 data 的部分,还记得把小端模式转成大端模式以十进制表示后,打算用这数据直接画图,这时大概就会画出这样的图:

而由「GoldWave」软件打开相同时间段的相同的音频文件是长这样的:

当时的我在搜索相关问题之后感到绝望弱小又无助。。
经过观察发现:
- 我们画的图里隐约是能看到波形的形状的。
- 「GoldWave」图中纵坐标是有负数部分的,而并不是 0 ~ (216 - 1) 。
大胆的猜想由此开始:是不是把图形上半部分“平移”到坐标轴负数位置就可以画出来呢?
嗯。事实证明确实是这样的。但是还要注意一下边际条件的判断了。
| 正值部分 | 负值部分 |
|---|---|
| 0 ~ (215 - 1) | 215 ~ (216 - 1) |
平移后得出下图:

如果想要纵坐标与「GoldWave」图也一致的话就只需要除一下 215 就可以了,横坐标则需要除以采样率 16000 来得到时间值。这样我们就画出了与「GoldWave」图一致的音频波形图啦。
至于为什么要这么把上半部分“平移”到负值坐标轴?这个问题我也没有找到答案,只能这样猜想一番:比如调整音频音量为原音的 x 倍,就是把 -1 ~ 1 范围内的所有数值乘以 x 后得到的就是调整音量后的音频波形图。由此推断,大概这么处理后的波形图是方便于查看以及数据处理的。
可能也是大小端的模式问题导致的,毕竟这块还是要补补课。
Happy ending.
本文介绍如何从wav格式音频文件中提取数据,并将其转换为可视化的波形图。重点讲解了处理16位单声道音频数据的方法,以及如何正确显示正负振幅,使波形图与专业音频软件GoldWave的输出相匹配。

1259

被折叠的 条评论
为什么被折叠?



