WAV格式文件无损合并&帧头数据体解析(python)(原创)
一,百度百科

图1 WAV文件帧头data[0:44]数据格式

图2.WAV文件帧头图解
读取WAV文件程序:
import struct
with open('测试音频源1.wav', 'rb') as file:
data=file.read()
# print(len(data))
# print(data[44:])
# print(data[0:4]) # chunkID: b'RIFF'
# length0=struct.unpack('<L', bytes(data[4:8]))
# print(length0) # (140836,)
# print(data[4:8]) # chunkSize: b'$&\x02\x00' WAV文件总byte数
# print(data[8:12]) # format: b'WAVE'
# print(data[12:16]) # Subchunk1 ID: b'fmt '
# length1=struct.unpack('<L', bytes(data[16:20]))
# print(length1) # (16,)
# print(data[16:20]) # format Code: b'\x10\x00\x00\x00'
#
# print(data[20:22]) # Subchunk1 Size: b'\x01\x00'
# print(data[22:24]) # nChannels: b'\x01\x00'
#
# print(data[24:28]) # nSamplesPerSec: b'\x80>\x00\x00'
# print(data[28:32]) # nAvgBytesPerSec: b'\x00}\x00\x00'
#
# print(data[32:34]) # nBlockAlign: b'\x02\x00'
# print(data[34:36]) # wBitsPerSample: b'\x10\x00'
#
# print(data[36:40]) # Subchunk2 ID: b'data'
# length2=struct.unpack('<L', bytes(data[40:44])) # (140800,)
# print(length2)
# print(data[40:44]) # Subchunk2 Size: b'\x00&\x02\x00'
通过将data值输出,可知其是一个byte文件
帧头数据为data[0:44],例如:
其中又划分出3大子块,每个子块又分为若干功能块。有标志位、数据长度、通道数、采样率等等相关参数。
b'RIFF\xac\xdc9\x00WAVEfmt\x10\x00\x00\x00\x01\x00\x01\x00\x80>\x00\x00\x00}\x00\x00\x02\x00\x10\x00data\x80\xdc9\x00'
数据帧为data[44:],剩余的数据即为音频采样数据。
三,WAV文件无损合并
我这种方法只针对通道数、采样率等等(除了文件数据帧长度不同)都相同的多个WAV文件合并,当然如果想要将不同格式的WAV合并也可以先转换成相同格式的文件之后再做操作。
import struct # 用于将chunkSize和Subchunk2 Size进行【long int】(byte型)和 int的转换 # *** 读取WAV音频1 *** #
with open('测试音频源1.wav', 'rb') as file:
data1=file.read() # *** 读取WAV音频2 *** #
with open('测试音频源2.wav', 'rb') as file:
data2=file.read() data_info = data1[:44] # 复制帧头参考
data_out = data1[44:] + data2[44:] # 将两个音频的数据帧合并(都是相同格式)
data_info = data_info[:4] + struct.pack('<L', len(data_out)+44) + data_info[8:]# 更新WAV文件的总byte数(两个文件数据帧和+44)
data_info = data_info[:40] + struct.pack('<L', len(data_out)) + data_info[44:]# 更新WAV文件的数据byte数(两个文件数据帧和) # *** 生成合并后的WAV文件 *** #
with open('测试音频源3.wav', 'wb') as f:
f.write(data_info+data_out) print('完成')
四,常见问题
我之前遇到的问题,直接将两个文件的byte值相加写入新文件,帧头没有更改;这样写的结果就是数据的大小满足两个源文件的和,但是使用播放器播放的时候音频无法正常全部播放。
尤其是我使用阿里云-语音合成api合成的WAV格式音频,它们的格式有一定的问题,每个生成的chunkSize和Subchunk2 Size数值都比实际音频数据长度要大一些,导致我直接将多个音频合并的时候,音频长度超过一定长度,后面的语音就无法播放,但是较少的几段音频合并又可以正常播放,这个地方我一直都没有弄明白,同时我又不想使用第三方的库(主要是觉得要先将音频存起来-之后又读取很麻烦),所以才细心的参看WAV格式文件的相关资料,通过对多个音频的比对发现了这个问题的由来。
备注:如果想要直接使用byte文件进行WAV文件合并一定要在合并后更新相关的数据,与此同时也要注意文件的通道数、采样频率等格式是否相同,一定要转换到相同格式合并才有效
WAV格式文件无损合并&帧头数据体解析(python)(原创)的更多相关文章
- Android音频: 怎样使用AudioTrack播放一个WAV格式文件?
翻译 By Long Luo 原文链接:Android Audio: Play a WAV file on an AudioTrack 译者注: 1. 因为这是技术文章,所以有些词句使用原文,表达更准 ...
- wav格式文件、pcm数据
wav格式文件是常见的录音文件,是声音波形文件格式之一,wav 文件由文件头和数据体两部分组成. 文件头是我们在做录音保存到文件的时候,要存储的文件的说明信息,播放器要通过文件头的相关信息去读取数据播 ...
- 将PCM格式存储成WAV格式文件
将PCM格式存储成WAV格式文件 WAV比PCM多44个字节(在文件头位置多) 摘自:https://blog.csdn.net/u012173922/article/details/78849076 ...
- 音频文件解析(一):WAV格式文件头部解析
WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源. 文 ...
- [VB.NET][C#]WAV格式文件头部解析
简介 WAV 为微软开发的一种声音文件格式,它符合 RIFF(Resource Interchange File Format)文件规范,用于保存 Windows 平台的音频信息资源. 第一节 文件头 ...
- linux下alsa架构音频驱动播放wav格式文件
#include<stdio.h> #include<stdlib.h> #include <string.h> #include <alsa/asoundl ...
- 音频文件解析(二):WAV格式文件波形绘制
解析WAV头部信息后,接下来就可以根据相关参数和DATA块数据绘制波形. 1.重新编码(转换为8bits,单声道数据) Public Function GetFormatData(ByVal pDat ...
- C语言解析WAV音频文件
C语言解析WAV音频文件 代码地址: Github : https://github.com/CasterWx/c-wave-master 目录 前言 了解WAV音频文件 什么是二进制文件 WAV的二 ...
- 调用CImg库显示WAV格式音频波形
最近在做傅里叶变换和小波变换时经常要通过显示波形来检验算法,但通过visual studio之类显示波形又显得麻烦,而且不能跨平台. CImg是一个跨平台的C++的图像处理库,提供的图像处理等功能十分 ...
随机推荐
- python格式化输出(% format用法)
%基本用法: 十进制输出:print('%d' % 6) 6也可以换成其它的数字变量 八进制输出:print('%o' % 6) 6也可以换成其它的数字变量 字符串输出:print('%s' ...
- Python 寻找文件夹里以特定格式结尾的文件
代码: import os, re, time name = 'linuxday01' flags = True# 文件夹bi_test中的文件列表 print os.listdir('E:\\bi_ ...
- 性能分析 | JVM发生内存溢出的8种原因及解决办法
推荐阅读:史上最详细JVM与性能优化知识点综合整理 1.Java 堆空间 2.GC 开销超过限制 3.请求的数组大小超过虚拟机限制 4.Perm gen 空间 5.Metaspace 6.无法新建本机 ...
- 用PHP自带函数对二维数组进行排序
经常会面临这样的需求,虽然有时候我们可以在数据库查询的时候,直接对数据进行排序,但还是无法满足日益复杂的业务需求. 这里边会用到两个函数 一个是array_column()函数,这个函数接受三个参数. ...
- 理解MyCat分库分表
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
- Java:基础知识点
1. 面向对象的特征 (1)封装:把过程和数据包围起来,对数据的访问只能通过已定义的界面.即现实世界可以被描绘成一系列完全自治.封装的对象,这些对象通过一个受保护的接口访问其他对象:(2)继承:是一种 ...
- 微信小程序跳转问题:wx.redirectTo、wx.navigateTo、wx.reLaunch、wx.switchTap、wx.navigateBack区别
wx.redirectTo:关闭当前页,跳转到指定页: wx.navigateTo:保留当前页,跳转到指定页: wx.reLaunch:关闭所有页面,打开到应用内的某个页面. wx.switchTap ...
- application节点
<application>节点是AndroidManifest.xml文件中必须持有的一个节点,它包含在<manifest>节点下.通过<application>节 ...
- [Java复习] Java基础 Basic
Q1面向对象 类.对象特征? 类:对事物逻辑算法或概念的抽象,描述一类对象的行为和状态. OOP三大特征,封装,继承,多态 封装:隐藏属性实现细节,只公开接口.将抽象的数据和行为结合,形成类.目的是简 ...
- IIS 7 实现http跳转https 重定向方法
官网的域名申请了一个SSL加密,导致原来的http无法访问了,网上找了一下解决方案,https://www.cnblogs.com/wer-ltm/p/10190535.html 按照这个方法进行了 ...