# -*- coding: utf-8 -*-
import wave
import pylab as pl
import numpy as np
# 打開WAV文檔
#首先載入Python的標(biāo)準(zhǔn)處理WAV文件的模塊稻扬,然后調(diào)用wave.open打開wav文件,注意需要使用"rb"(二進(jìn)制模式)打開文件:
f = wave.open(r"1.wav", "rb")
#open返回一個(gè)的是一個(gè)Wave_read類的實(shí)例,通過調(diào)用它的方法讀取WAV文件的格式和數(shù)據(jù):
# 讀取格式信息
# (nchannels, sampwidth, framerate, nframes, comptype, compname)
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
#getparams:一次性返回所有的WAV文件的格式信息,它返回的是一個(gè)組元(tuple):聲道數(shù), 量化位數(shù)(byte單位), 采樣頻率,
#采樣點(diǎn)數(shù), 壓縮類型, 壓縮類型的描述。wave模塊只支持非壓縮的數(shù)據(jù),因此可以忽略最后兩個(gè)信息:
#getnchannels, getsampwidth, getframerate, getnframes等方法可以單獨(dú)返回WAV文件的特定的信息。
# 讀取波形數(shù)據(jù)
str_data = f.readframes(nframes)
#readframes:讀取聲音數(shù)據(jù)作彤,傳遞一個(gè)參數(shù)指定需要讀取的長度(以取樣點(diǎn)為單位),readframes返回的是二進(jìn)制數(shù)據(jù)(一大堆
#bytes)乌逐,在Python中用字符串表示二進(jìn)制數(shù)據(jù):
f.close()
#將波形數(shù)據(jù)轉(zhuǎn)換為數(shù)組
#接下來需要根據(jù)聲道數(shù)和量化單位竭讳,將讀取的二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為一個(gè)可以計(jì)算的數(shù)組:
wave_data = np.fromstring(str_data, dtype=np.short)
#通過fromstring函數(shù)將字符串轉(zhuǎn)換為數(shù)組,通過其參數(shù)dtype指定轉(zhuǎn)換后的數(shù)據(jù)格式浙踢,由于我們的聲音格式是以兩個(gè)字節(jié)表示一個(gè)取
#樣值绢慢,因此采用short數(shù)據(jù)類型轉(zhuǎn)換。現(xiàn)在我們得到的wave_data是一個(gè)一維的short類型的數(shù)組洛波,但是因?yàn)槲覀兊穆曇粑募请p聲
#道的胰舆,因此它由左右兩個(gè)聲道的取樣交替構(gòu)成:LRLRLRLR....LR(L表示左聲道的取樣值,R表示右聲道取樣值)蹬挤。修改wave_data
#的sharp之后:
wave_data.shape = -1, 2
#將其轉(zhuǎn)置得到:
wave_data = wave_data.T
#最后通過取樣點(diǎn)數(shù)和取樣頻率計(jì)算出每個(gè)取樣的時(shí)間:
time = np.arange(0, nframes) * (1.0 / framerate)
# 繪制波形
pl.subplot(211)
pl.plot(time, wave_data[0])
pl.subplot(212)
pl.plot(time, wave_data[1], c="g")
pl.xlabel("time (seconds)")
pl.show()
# -*- coding: utf-8 -*-
import wave
import numpy as np
import scipy.signal as signal
framerate = 44100
time = 10
# 產(chǎn)生10秒44.1kHz的100Hz - 1kHz的頻率掃描波
t = np.arange(0, time, 1.0/framerate)
wave_data = signal.chirp(t, 100, time, 1000, method='linear') * 10000
wave_data = wave_data.astype(np.short)
# 打開WAV文檔
f = wave.open(r"sweep.wav", "wb")
# 配置聲道數(shù)缚窿、量化位數(shù)和取樣頻率
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(framerate)
# 將wav_data轉(zhuǎn)換為二進(jìn)制數(shù)據(jù)寫入文件
f.writeframes(wave_data.tostring())
f.close()
轉(zhuǎn)自:https://blog.csdn.net/sinat_33588424/article/details/80239375