Python使用struct.unpack处理二进制文件-程序员宅基地

技术标签: python处理wav文件  struct.unpack方法  Python语言  

1、如何处理二进制文件?

        实际案例:

                wav是一种音频文件的格式,音频文件为二进制文件。

                wav文件由头部信息和音频采样数据构成,前44个字节为头部信息,包含声道数、采样频率、PCM位宽等等,后面是音频采样数据。

                使用python分析一个wav文件头部信息,处理音频数据。

        WAV格式如下:

               简单分为两部分,第一部分前44个字节是音频文件的一些信息,第二部分44个字节后面是音频文件的采样数据。

        解决方案:

                open函数想以二进制模式打开文件,指定mode参数为'b'。

                二进制数据可以用fromfile(Python2中可以使用readinto),读入到提前分配好的buffer中,便于数据处理。

                解析二进制数据可以使用标准库中的struct模块的unpack方法。

2、代码演示

 (1)struct.unpack方法简单使用

# 以二进制形式打开文件
f = open('微信语音视频.wav', 'rb')
# 读取前44字节
info = f.read(44)
print(info)

import struct

'''
struct.unpack方法介绍:
    unpack(format, buffer)
    format:解析类型
    buffer:需要解析二进制串
    例: 构造两个字节的二进制串,format默认为小端字节顺序,
        h为16为,结果:2*256+1=513
        struct.unpack('h', b'\x01\x02')
        指定format为大端字节顺序,结果:256+2=258
        struct.unpack('>h', b'\x01\x02')
'''
# print(help(struct.unpack))
# 解析声道数,Num Channels为22到24字节
print(struct.unpack('h', info[22:24]))
# 解析采样频率,SampleRate为24到28字节,i为int类型
print(struct.unpack('i', info[24:28]))
# 编码宽度,BitsPerSample为34到36字节
print(struct.unpack('h', info[34:36]))

 (2)实现二进制文件wav的处理

# _*_ encoding:utf-8 _*_
import array

'''
读取data数据部分不希望是字符串形式,因为字符串不支持数学运算,
对它不方便数据处理,最好读取到类似于C语言中数组中去
'''

# 修改文件指针移动到文件末尾
f.seek(0, 2)
# 报告文件指针,也就是文件大小
print(f.tell())
# 数组的长度为文件字节长度减去44个字节,除2为采样宽度
n = (f.tell() - 44) // 2

# 创建数组,储存data部分数据
buf = array.array('h', [])

# 将文件的数据读入到buf当中,不返回字符串
f.seek(44)
buf.fromfile(f, n)
print(buf[0])
print(len(buf))
# 将采样缩小一定程度,最终体现就是声音变小
for i in range(n):
    buf[i] //= 8
# 将数据存入到一个新文件
f2 = open('demo.wav', 'wb')
f2.write(info)
buf.tofile(f2)
f2.close()

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_37189082/article/details/124653895

智能推荐

memcpy的用法总结_uvision5中memcpy-程序员宅基地

文章浏览阅读5.7k次,点赞2次,收藏4次。1、memcpy 函数用于 把资源内存(src所指向的内存区域) 拷贝到目标内存(dest所指向的内存区域);拷贝多少个?有一个size变量控制拷贝的字节数;函数原型:void *memcpy(void *dest, void *src, unsigned int count);用法:(1)可以拷贝任何类型的对象,因为函数的参数类型是void*(未定义类型指针),也就是说传进去的实参可_uvision5中memcpy

angularUI - uibModal模态框内外传递参数的方法_$uibmodal传递值-程序员宅基地

文章浏览阅读4.2k次。uibModal提供了页面的弹出层 uibModalInstance = $uibModal.open({ animation: true, size:'lg', //设置模态框大小 resolve:{ //设置参数,传递到模态框中,多个单数可使用对象的方式 ..._$uibmodal传递值

java实现一个整数的阶乘_1.编写一个javaweb程序计算一个整数的阶乘,并显示出结果。用户先通过第一个页面e-程序员宅基地

文章浏览阅读699次。已知:负数不可以有阶乘,0的阶乘结果是1,接收用户输入的数字,计算该数字的阶乘结果。_1.编写一个javaweb程序计算一个整数的阶乘,并显示出结果。用户先通过第一个页面e

EXCEL Function Part II Chapter 4 —— 查找和引用数据的高手_function中单元格引用-程序员宅基地

文章浏览阅读188次。文章目录Chapter 4 查找和引用数据的高手LOOKUP函数,查询中的王者INDIRECT函数,将文本转为引用OFFSET函数,求符合条件的区域Chapter 4 查找和引用数据的高手LOOKUP函数,查询中的王者LOOKUP函数,与MATCH函数,第3参数为“1”类似= MATCH(A2,C2:C9,1) 参数1代表函数将查找小于等于查找值的最大值,并返回该数值在查找区域的..._function中单元格引用

51Nod-1081 子段求和_51nod 1081-程序员宅基地

文章浏览阅读192次。1081 子段求和题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1081题目给出一个长度为N的数组,进行Q次查询,查询从第i个元素开始长度为l的子段所有元素之和。例如,1 3 7 9 -1,查询第2个元素开始长度为3的子段和,1 {3 7 9} -1。3 + 7 + 9 = 19,输出19_51nod 1081

交叉编译运行arm版本的gdb和gdbserver_交叉编译gdb 和 gdb server 教程-程序员宅基地

文章浏览阅读319次。https://ftp.gnu.org/gnu/gdb/ 下载gdb-11.2.tar.gz,版本最好同local交叉编译器的对齐。2.拷贝install目录下的bin/gdb和test以及main.c拷贝到u盘。1.板子上运行gdbserver指定端口12345。3.gdb server会显示已经连接。4.server gdb开始debug。2.服务器上运行gdb。_交叉编译gdb 和 gdb server 教程

随便推点

学习SpringBoot时遇到的坑,记录一下_spring boot遇到的坑-程序员宅基地

文章浏览阅读176次。学习SpringBoot时遇到的坑,记录一下。问题:SpringBoot集成thymleaf时,请求页面报template might not exist or might not be accessible by any of the configured Template Resolvers,网上找了很多资料,不管用。。。原因:如图所示,html后面有tab符。。..._spring boot遇到的坑

Modular exponentiation-程序员宅基地

文章浏览阅读744次。1. 递归实现:unsigned long long modular_pow_recursive(unsigned long long base, int exponent, int modulus){ if (modulus == 1) { return 0; } if(exponent == 0) { _modular exponentiation

solidity之msg.sender总结(一个实时变化的变量)-程序员宅基地

文章浏览阅读9.5k次,点赞3次,收藏9次。务必注意:msg.sender是一个实时变化的变量!在合约中,方法的调用者不一样,msg.sender就会不一样!pragma solidity >=0.5.0 <0.7.0;import "../../node_modules/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";contract TestTok..._msg.sender

Mysql基础_执行sq丨命令insert,int0-程序员宅基地

文章浏览阅读195次。第一章1.1 数据库介绍数据库的介绍数据库就是存储和管理数据的仓库,数据按照- -定的格式进行存储,用户可以对数据库中的数据进行增加、修改、删除、查询等操作。数据库的分类●关系型数据库●非关系型数据库关系型数据库是指采用了关系模型来组织数据的数据库,简单来说,关系模型指的就是二维表格模型,好比Excel文件中的表格,强调使用表格的方式存储数据。非关系型数据库非关系型数据库,又被称为NoSQL (Not Only SQL),意为不仅仅是SQL,对NoSQL最普遍的定义是“非关联型的”,强调_执行sq丨命令insert,int0

报错The server time zone value '�й���׼ʱ��' is unrecognize_更新失败:the server time zone value ' й ' is-程序员宅基地

文章浏览阅读806次。估计是用了mysql8.0等高版本导致的解决办法在配置URL时加上serverTimezone=UTC比如,用 ? 连接String url="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"; 如果URL用了allowMultiQueries=true,则要用 & 连接String url="jdbc:m..._更新失败:the server time zone value ' й ' is

九度OJ 1171:C翻转 (矩阵计算)_q*4矩阵大小写翻转 oj-程序员宅基地

文章浏览阅读549次。时间限制:1 秒内存限制:32 兆特殊判题:否提交:4649解决:1530题目描述:首先输入一个5 * 5的数组,然后输入一行,这一行有四个数,前两个代表操作类型,后两个数x y代表需操作数据为以x y为左上角的那几个数据。操作类型有四种: 1 2 表示:90度,顺时针,翻转4个数 1 3 表示:90度,顺时针,翻转9个数_q*4矩阵大小写翻转 oj