1. 程式人生 > >Python音訊處理(一)音訊基礎知識

Python音訊處理(一)音訊基礎知識

1.聲音音訊基礎知識

 

(1)聲音是由震動產生,表現為波的形式。波有頻率,振幅等引數。對於聲波而言:頻率越大,音調越高,反之越低。振幅越大,聲音越大,反之越小。

(2)取樣率,幀率:波是連續(無窮)的,計算機儲存是離散(有限)的。要想用有限儲存無限,幾乎不可能。因此,要每隔一段時間對波進行一次取樣。每秒取樣次數取樣率。長用取樣率是44.1kHz(這裡的1k不是1024,是1000!!!切記。)。

(3)取樣大小,取樣寬度:波每一個時刻都有一個對應的能量值,在計算機中用整數儲存。通常使用16bit有符號整數儲存,取樣大小是16bit。

(4)聲道:這個不好解釋,引用百度百科上的一句話。聲道(Sound Channel) 是指聲音在錄製或播放時在不同空間位置採集或回放的相互獨立的音訊訊號,所以聲道數也就是聲音錄製時的音源數量或回放時相應的揚聲器數量。

(5)人耳能聽到的聲波頻率範圍是20Hz ~20000Hz,人耳對160Hz~2500Hz的聲音比較敏感。

(6)音色:不同物體發音有所不同,這些不同表現在音色上。音色在音訊曲線級別的表現是頻率的特定變化,振幅的特定變化

2.python讀取.wav音訊

下面是python3讀取音訊程式碼,詳細說明都在註釋裡。

import wave
import struct

wave_file=wave.open("./sound111.wav", 'r')
channels=wave_file.getnchannels()#聲道數
samp_width=wave_file.getsampwidth()#取樣大小
frame_rate=wave_file.getframerate()#幀率
numframes=wave_file.getnframes()#總幀數

print("channel",channels)#聲道數
print('samp_width',samp_width)#取樣大小2B 16bit
print('frame_rate',frame_rate)#8000 幀率8000fps
print('numframes',numframes)#總幀數=幀率*時間=8000fps*10s=80000f
#輸出
#channel 1
#samp_width 2
#frame_rate 8000
#numframes 80000

for i in range(500):
frame=wave_file.readframes(1)#讀取1幀音訊資料,可能包含多個聲道資訊
print(frame,struct.unpack("h",frame[0:2])[0])#struct.unpack("h",frame[0:2])將二進位制資料轉化成10進位制(16bit有符號整數)因為這裡取樣大小是16bit
#輸出
#b'\xd4\xfc' -812
#...
#b'\x07\xff' -249
#b'\x05\xff' -251
#b'X\xff' -168
#b'\xf2\xff' -14
#b'0\x00' 48
#b'#\x00' 35
wave_file.close()

 

3.python寫.wav音訊檔案

下面是python3寫音訊程式碼,詳細說明都在註釋裡。這裡需要用到中學的簡單三角函式知識,忘記的話可以複習一下。下面是一首兩隻老虎,盡情欣賞吧。注意:下面的程式碼中使用的頻率是從網上找的,並不準確。國際標準A:440Hz

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()

# C 1 do 256
# D 2 re 288
# E 3 mi 320
# F 4 fa 341又1/3
# G 5 so 384
# A 6 la 426又2/3
# B 7 si 480
# C 1 (上面一個點)do 512
# C:D=8:9
# D:E=9:10
# E:F=15:16
# F:G=8;9
# G:A=9:10
# A:B=15:16

---------------------
作者:Moluth
來源:CSDN
原文:https://blog.csdn.net/Moluth/article/details/79793903
版權宣告:本文為博主原創文章,轉載請附上博文連結!