前回に引き続き音声関連のプログラム紹介となります。
今回は、Pythonで、Wave音源の周波数と音量(デシベル)を取得する方法になります。
Audio機器なんかの試験で、再生されている音の周波数や音量を見たいことが筆者はあって、簡易的な試験で機材を安く少なくするために、こういったプログラムが欲しいなーってことがあるので試しにやってみました。
※ものによっては直接パソコンに機器からの音声を直接マイクラインに入力すると、過電流となりパソコンが壊れることがありますので、入力電圧を確認してから試してください。私は一度やってしまい煙が出ました。。。
サンプルコード
ではいつも通り全体のコードからです。
import sys
import wave
import numpy as np
import math
FLAME_SIZE = 8192
def read_wavefile(file_path):
wf = wave.open(file_path, 'rb')
frames = wf.getnframes() # フレーム数を取得
Channels = wf.getnchannels()
sampWidth = wf.getsampwidth()
framerate = wf.getframerate()
print( str(frames) + " Frames")
print( str(Channels) + " channels")
print( str(sampWidth*8) + " bit" )
print( str(framerate) + " hz" )
print("\n")
wf.setpos(int(frames/2)) # 全フレームの真ん中に位置を移動
buf = wf.readframes(FLAME_SIZE) # セットした位置からFLAME_SIZEフレームを取得
wf.close()
return buf
def get_freq(data):
data = np.frombuffer(data, dtype= "int16") / 32768.0
spectrum = np.fft.fft(data)
maxvalue = 0
maxidx = 0
tmpvalue = 0
flist = np.fft.fftfreq(FLAME_SIZE, d=1.0/44100) # 周波数リスト
for j in range( int( len(spectrum) / 2 ) ):
tmpvalue = spectrum[j]
if tmpvalue > maxvalue:
maxvalue = tmpvalue
maxidx = j
print( str(int(flist[maxidx])) + "Hz" )
def get_db(data):
squaressum = 0
# 累積二乗和を算出
for i in range(FLAME_SIZE):
squaressum += data[i] * data[i]
# 平均平方根を算出
meansquare = squaressum / (FLAME_SIZE/2)
# 二乗平均平方を取得 (入出力信号レベル)
rms = math.sqrt(meansquare)
decibel = 20 * math.log10(rms)
print( str( int(decibel) ) + "db" )
if __name__ == '__main__':
args = sys.argv
if len(args) != 1:
#保存実行
wave_data = read_wavefile( args[1] )
get_freq(wave_data)
get_db(wave_data)
今日はまず実行結果を見せます。
今回の測定に使用した音源データは以下の3つです。
↓のサイトからダウンロードさせていただきました。
http://www.op316.com/tubes/tips/wav2.htm
- 1khz-0db-30sec.wav
- 400hz-0db-30sec.wav
- 5khz-6db-20sec.wav
前回の↓で録音したデータを解析使用と思ったのですが、環境がPCのマイクしかなくノイズが入ってしまうので、ダウンロードさせた頂きました。
では実行結果です。それぞれ、周波数についてはそれっぽい値が取れています。
※すいません。デシベルについては、合っているのか不明です。。。
WindowsMediaPlayerで音源を再生して、iphoneのアプリで計測した感じではそれっぽい値になりました。

続いてはプログラムの解説ですが、解説は次ページにて記載します。
コメント