python---wav音频

 

import pyaudio  #导入库
import wave

wave_file = wave.open('D:/驿动的心.wav', 'rb')   #打开文件
#参数1:文件名或文件对象
#参数2:可取"r",“rb”,“w”,“wb"四个值,其中"r"和"rb”, "w"和"wb"效果完全相同
i=wave_file.getnchannels()   #返回声道数量(1 为单声道,2 为立体声)
i1=wave_file.getsampwidth()     #返回采样字节长度 (每一帧的字节长度)
#  返回值2:  表示2个字节
i2=wave_file.getframerate()    #返回采样频率--每秒钟采样的帧数
#返回值44100
i3=wave_file.getnframes()     #返回音频总帧数
#返回值2646000
i4=wave_file.getcomptype()    #返回压缩类型(“无”是唯一受支持的类型,因wav格式从不压缩)
#返回值NONE
i5=wave_file.getcompname()   #返回压缩格式
#返回值not compressed

print(i5)

 

import wave
Wave_write = wave.open('D:/new.wav','wb')

Wave_write.setnchannels(1)  #设置声道数
Wave_write.setsampwidth(2)  #设置采样字节长度
Wave_write.setframerate(44100)   #设置采样频率
Wave_write.setnframes(266660)   #设置总帧数
#调用writeframes()时,wave模块会自动更新总帧数,实际上不需要调用这个函数
Wave_write.setcomptype(type, name)   #设置压缩格式
#目前只支持 NONE 即无压缩格式

 

 

import wave
import matplotlib.pyplot as plt
import numpy as np
import os

f = wave.open('D:/驿动的心.wav', 'rb')
params = f.getparams()    #获取音频信息
#_wave_params(nchannels=2, sampwidth=2, framerate=44100, nframes=2646000, comptype='NONE', compname='not compressed')
#分别表示通道数为2, 采样位宽为2, 帧率44100,帧数2646000,无压缩
print(params)

 

import wave


f = wave.open('D:/驿动的心.wav', 'rb')
params = f.getparams()    #获取音频信息

wavWrite = wave.open('D:/new.wav','wb')    #新建一个wav文件--用来保存音频
wavWrite.setparams(params)       #设置音频参数

segment = f.readframes(params.nframes)
wavWrite.writeframes(segment)     #将音频片段写入new.wav--保存音频

f.close()     #关闭文件
wavWrite.close()

 

 

import pyaudio  #导入库
import wave

wave_file = wave.open('D:/驿动的心.wav', 'rb')   #打开文件

aa=wave_file.readframes(1024)   #读取并返回以bytes对象表示的最多n帧音频
#参数:需要读取的最多帧数
i6=wave_file.tell()    #返回文件中的当前位置
#返回值1024
wave_file.setpos(500)  #设置文件指针到指定位置
i7=wave_file.tell()

print(i7)

 

import wave
import matplotlib.pyplot as plt
import numpy as np


f = wave.open('D:/驿动的心.wav', 'rb')
params = f.getparams()    #获取音频信息
nchannels ,sampwidth ,framerate ,nframes = params [:4]

#nframes是单声道帧数
strData = f.readframes(1024)


waveDate = np.frombuffer(buffer=strData,dtype=np.int16)  #从缓冲区读取数据
#返回值类型:np数组列表
#waveDate.size返回的是数组元素的个数
#由于双声道,每一帧有两个数据,waveDate.size是1024的两倍


if sampwidth==2 :   #提取一个声道数据
    waveDate.shape = -1, 2  # 修改矩阵的维度
    #改成n行2列

    c=waveDate.T    #变成2行n列
    print(c.shape)
    waveDate=c[0]
    print(waveDate.shape)



time = np.arange(0,1024)*(1.0/1024)   # 计算音频各帧时间

plt.plot(time,waveDate,linestyle=':',color='red',marker='o')
plt.show()

 

  

实例:

import pyaudio  #导入库
import wave   #导入wav音频库
import sys
from PyQt5.QtWidgets import QApplication, QWidget,QFileDialog
from pya import Ui_Form
import numpy as np
import matplotlib.pyplot as plt

class Win(QWidget,Ui_Form):
    def __init__(self):
        super(Win, self).__init__()
        self.setupUi(self)
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体 SimHei为黑体
        plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号


    def dakaiwenjian(self):
        r = QFileDialog.getOpenFileName(self, '请选择要打开的文件', '.\\', 'WAV(*.wav)',
                                        'WAV(*.wav)')
        self.lineEdit.setText(r[0])

        wf = wave.open(r[0], 'rb')  # 只读方式打开wav文件
        #只读模式:  ‘r’, ‘rb’  ;只写模式:  ‘w’, ‘wb’;注意:不能同时完成读/写操作

        params = wf.getparams()  #读取格式信息
        #返回的是一个元组(tuple):声道数, 量化位数(byte单位), 采样频率, 采样点数, 压缩类型, 压缩类型的描述
        # wave模块只支持非压缩的数据,因此可以忽略最后两个信息
        print('声道数:',params[0])
        print('量化位数:', params[1])  #量化位数(byte单位)
        #量化位数是对模拟音频信号的幅度轴进行数字化,它决定了模拟信号数字化以后的动态范围
        #常用于表示声卡性能的两个参数是采样频率、和模拟量转换成数字量之后的数据位数(简称量化位数)。采样频率决定了频率响应范围,在计算机多媒体音频处理中,标准的采样频率为:11.025kHz(语音效果)、22.05kHz(音乐效果)、44.1kHz(高保真效果)。量化位数越多,声音的质量越高。目前声卡的最高采样频率为44.1KHz。对声波每次采样后存储、记录声音振幅所用的位数称为采样位数,16位声卡的采样位数就是16。量化位数决定了音乐的动态范围,量化位数有8位和16位两种。8位声卡的声音从最低音到最高音只有256个级别,16位声卡有65536个高低音级别
        #采样位数和采样率都是时域中的参数。一段音频(声波)的变化曲线,从时域上看,其横轴表示时间t,纵轴表示幅度v(一般是电压)。那么,采样率44.1K表示每秒钟采样44100个点,也就是横轴上每隔(1/44100)秒采集一个点;而采到的每个点都用一个数值来表示其幅度(电压)。假设整个音频信号的变化幅度范围是-5V~+5V的话,我们将-5V~+5V分成65536份,那么采到的这些点的数值n(16位),转换成电压,就是(n*10/65536)-5V。因此,采样位数分解的是音频电压的幅度!当然上面只是一个例子而已。对于某些A/D转换器来说,采集到的点的幅度值可能用补码来表示,那么换算成电压的公式就会不同,但将-5V~+5V这10V的变化范围分成了65536份这一点来说,是一样的
        #量化位数分为8位,16位,24位三种
        print('采样频率:', params[2])
        #每秒钟采集数据的次数
        #频率一般有11025Hz(11kHz) ,22050Hz(22kHz)和44100Hz(44kHz) 三种
        print('采样点数:', params[3])
        #采样点数决定了每次传到pc内的数据量。比如点数设为1000,pc内会开辟初始大小1000的buffer(buffer大小可以自己改), 板卡就每采1000点往pc传一次
        # [返回的是文件的总采样点数]

        # getnchannels, getsampwidth, getframerate, getnframes等方法可以单独返回WAV文件的特定的信息
        print(wf.getnchannels())  #声道数
        print(wf.getsampwidth())  #量化位数(采样大小,采样宽度):波每一个时刻都有一个对应的能量值,在计算机中用整数存储。通常使用16bit有符号整数存储,采样大小是16bit
        framerate=wf.getframerate()  #采样频率
        nframes=wf.getnframes()  #采样点数--总帧数
        #[返回的是文件的总采样点数]
        print('采样点数:',nframes)

        data = wf.readframes(nframes)   # 读取数据
        # 从流的当前指针位置一次读出音频的n个帧,并且指针后移n个帧,返回一个字节数组--返回的是二进制数据(一大堆bytes),在Python中用字符串表示二进制数据
        #【返回的是二进制形式的字符串】
        #传递一个参数指定需要读取的长度(以取样点为单位)
        #wf.close()  #关闭文件
        wave_data = np.frombuffer(data, dtype=np.short)  #将波形数据转换为列表【矩阵】
        #[0 0 0 ... 0 0 0]
        #通过fromstring函数将字符串转换为列表,通过其参数dtype指定转换后的数据格式,由于我们的声音格式是以两个字节表示一个取样值,因此采用short数据类型转换
        wave_data.shape = -1, 2  #修改矩阵的维度
        #-1  表示行数未知;   2 表示2列
        #声音文件是双声道的,因此它由左右两个声道的取样交替构成:LRLRLRLR....LR(L表示左声道的取样值,R表示右声道取样值)。修改wave_data的sharp之后:
        # [[0 0]  [0 0]  ...  [0 0]  [0 0]  [0 0]]
        wave_data = wave_data.T   #将其转置--行列转换
        time = np.arange(0, nframes) * (1.0 / framerate)   #取样时间--单位:秒
        # 1.0 / framerate  每个点的时间
        # np.arange(0, nframes)  产生一个一维矩阵--传递给pc数据中的第几个数据

        # 绘制波形
        plt.subplot(2,1,1)
        plt.plot(time, wave_data[0])  #画左声道
        plt.subplot(2,1,2)
        plt.plot(time, wave_data[1], c="g")  #画右声道
        plt.xlabel("time (seconds--秒)")
        plt.show()




    def bofan(self):
        pass

if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Win()
    demo.show()
    sys.exit(app.exec_())

 

上面实例下载: 

链接:https://pan.baidu.com/s/1DaDhI1gC4ul2Hblm7tPAFg   提取码:opy5 

 

写.wav音频文件

import wave
import struct
import math

def write_frame(time,freq,framerate,file,wave=0.4,sampwidth=2):
#time 持续时间; freq 频率; framerate采样频率; file 音频文件; wave 音量; sampwidth 采样深度
    t=0#时刻
    step=1.0/framerate #每帧间隔时长
    fw=2.0*math.pi*freq #频率控制参数
    wave=wave*(math.pow(2,sampwidth*8-1)-1)#音量控制
    while t<=time:
        v=int(math.sin(t*fw)*wave)  #对波采样 math.sin(t*fw)产生freq频率的正弦波
        t+=step#更新时刻
        #最后这里是与sampwidth的值有关的,下面语句当前仅当sampwidth=2时成立,详细信息参考struct.pack()
        file.writeframesraw(struct.pack("h",v)) #写入文件 struct.pack("h",v)将有符号整数v转化成16比特2进制


tw=wave.open("./two_tigers.wav","w") #打开或创建./two_tigers.wav
tw.setnchannels(1) #设置声道数 1
tw.setframerate(8000)#设置帧率 8000
tw.setsampwidth(2)#设置采样宽度2B 16bit

#写入声音
#1 2 3 1 1 2 3 1
write_frame(time=0.5, freq=256, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=288, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=320, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=256, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=256, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=288, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=320, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=256, framerate=8000, file=tw, wave=0.4, sampwidth=2)

#3 4 5 - 3 4 5 -
write_frame(time=0.5, freq=320, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=341.33, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=384, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.25, freq=0, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=320, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=341.33, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=384, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.25, freq=0, framerate=8000, file=tw, wave=0.4, sampwidth=2)

#56 54 3 1 - 56 54 3 1 -
write_frame(time=0.25, freq=384, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.25, freq=426.67, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.25, freq=384, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.25, freq=341.33, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=320, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=256, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.25, freq=384, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.25, freq=426.67, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.25, freq=384, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.25, freq=341.33, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=320, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=256, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.25, freq=0, framerate=8000, file=tw, wave=0.4, sampwidth=2)

#2 6(低音) 1 - 2 6(低音) 1 -
write_frame(time=0.5, freq=288, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=144, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=256, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.25, freq=0, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=288, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=144, framerate=8000, file=tw, wave=0.4, sampwidth=2)
write_frame(time=0.5, freq=256, framerate=8000, file=tw, wave=0.4, sampwidth=2)


tw.close()

 

 

 

 

 

posted @ 2019-10-16 07:59  天子骄龙  阅读(1551)  评论(0编辑  收藏  举报