2013年10月29日 星期二

wav spectrum 頻譜圖 + python audiolab

因為這次要處理wav檔案資料...
其實py audiolab能處理上不止算頻譜,
只是其他的項目用Java解決掉~
就只有頻譜圖是用python...
(一來不會算頻譜, 二來Java繪圖的套件過於艱澀, py找來的資源就已經相當漂亮了Q_Q)

環境安裝貼在上一篇文...



先貼一張結果圖~













程式沒幾行, 過程是挺心酸的...Q_Q...
整個重點大概在於:
python 與相關應用module安裝...
找一段可以用的程式碼來打底...
(google audiolab+spectrum 應該就會有~我也是google來的)
調好圖表版面, 對齊(因有上下圖需要對齊的需求), 間隔, 顏色
(sample是2分鐘的wav, 但因實務上只使用大約30s, 所以才用5s做單位x軸)
解決中文字的問題....
(python原生沒中文, 最後採用指定TTF解決, 跨平台機器安裝才方便Q_Q)

原始碼

#!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
from pylab import *
import wave
import matplotlib.pyplot as plt

myfont = matplotlib.font_manager.FontProperties(fname='/etc/xxxx/MSJH.TTF')
infile = None
outfile = None
secInterval = 5    #x-axis interval

def show_wave_n_spec():
   
    if(len(sys.argv) < 2) :
        print('err input, plz input argv[1] and argv[2]')
        return
   
    infile = sys.argv[1]
    outfile = sys.argv[2]
   
    spf = wave.open(infile,'r')
    f = spf.getframerate()
   
    sound_info = spf.readframes(-1)
    sound_info = fromstring(sound_info, 'Int16')
    spflength = round(spf.getnframes()/f)
    #print(spflength)
    #print(sound_info)
   
    #---------------pic1   
    ax = subplot(211)
    title(u'Waveform(波形圖)',fontproperties=myfont)
   
    plot(sound_info, '#5755FF')
    xlim(0, len(sound_info))
    plt.axis([0, len(sound_info), -15000, 15000])
    grid(True)
   
    #change axis-x position/text
    xlabel2 = range(0, int(spflength+1), secInterval)
    xposition2 = []
    for x in xlabel2:
        xposition2.append(x*f)
   
    #print(xposition2)
    ax.set_xticks(xposition2)
    ax.set_xticklabels(xlabel2)
   
    #change axis-y
    ylabel2 = []
    for x in ax.get_yticks() :
        ylabel2.append(str(x/1000)+'k')
    ax.set_yticklabels(ylabel2)
   
    #---------------pic2   
    ax2 = subplot(212)
    title(u'Spectrogram(頻譜圖)',fontproperties=myfont)
    spectrogram = specgram(sound_info, Fs = f, scale_by_freq=True,sides='default')   
    plt.axis([0, spflength, 0, 20000])
    ax2.set_xticks(xlabel2)
    ax2.set_xticklabels(xlabel2)
    grid(True)
    ylabel2 = []
    for x in ax2.get_yticks() :
        ylabel2.append(str(x/1000)+'k')
    ax2.set_yticklabels(ylabel2)   
       
    #show()
    savefig(outfile);
    spf.close()


show_wave_n_spec()

沒有留言: