人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

SPTKの使い方 (1) インストール・波形描画・音声再生

SPTK(Signal Processing Toolkit)という音声信号処理のツールの使い方を紹介していきます。

SPTKには、音声を分析するための豊富なコマンドが約120個も提供されています。今までPythonで窓関数、FFT、MFCC、LPCなどを苦労して実装してきました(Pythonで音声信号処理)が、これらの代表的な音声処理は、SPTKで提供されているコマンドを組み合わせるだけで簡単に実行できます。

SPTKには、分厚いマニュアルと豊富なサンプル集がついているのでそれをベースに少しずつ使い方を整理していきたいと思います。今後の音声プロジェクトでも使用していく予定です。

インストール

主にLinuxマシンが対象のツールなのでソースからのコンパイルが必要。WindowsならCygwinやMinGWが必要でした。SPTK-3.5.tar.gzをダウンロードして

tar xvzf SPTK-3.5.tar.gz
cd SPTK-3.5
./configure
make
sudo make install

でSPTKのコマンド群がインストールされます。

impulse -h

でヘルプメッセージが出ればインストール成功!

Macbook Air 2012(Mac OSX Lion)環境では、なにやらdeltaコマンドのところでコンパイルエラーが出てmakeに失敗します。調べたところXcode4からgccがLLVM版とやらに置き換わっているのが原因らしい。bin/deltaのMakefileのCC=gccをCC=clangに置き換えてやるとうまくコンパイルできました。

SPTKのサイトからは他にも、

も手に入るので合わせてダウンロード。というわけで以後、サンプル集に沿って簡単なコマンドからマスターしていきます。まずは、波形のダンプ、プロット、再生です。

波形データのダンプ

SPTKのサイトからダウンロードしたSPTKexamples-data-3.5.tar.gzを解凍するとdata.shortという音声ファイルが入っているのでこのファイルを使っていきます。このファイルは、いわゆるrawファイルというやつで音声波形の振幅(short型、-32768〜32767)がそのまま入っています。Windowsでよく使うwavからヘッダ部分を除いたものです(このファイルはwavと違って一般的なソフトでは再生できません。後で再生方法を示します。)

音声波形の振幅は、dmpコマンドで出力できます。

dmp +s data.short | less
0       7
1       14
2       19
3       22
4       25
5       16
6       16
7       16
8       7
9       8
10      -2
...

1列目は、サンプル番号で2つめが振幅。コマンドの+sは振幅がshort型であることを意味します。よく使われる16bitで量子化された音声はshort型(2byte)で-32678から32767の整数値で表せます。

波形データのプロット

ダンプデータではどんな波形かわからないのでgwaveコマンドとxgrコマンドで波形をプロットしてみます。

gwave +s data.short | xgr

Macだとこんなグラフが出てきました。

f:id:aidiary:20120701120249p:plain

ただ、XWindowsが入っていないWindowsでは何らかのXサーバ*1を入れないとgwaveコマンドは使えませんでした。代わりにPythonで描画するスクリプトを書くと下のようになります。2バイト(short)ずつバイナリを読み込んでstruct.unpack()で整数値に変換してからmatplotlibでプロットしています。

#coding:utf-8
import struct
import sys
from pylab import *

if len(sys.argv) != 2:
    print "usage: python plot.py [raw file]"
    sys.exit()
rawfile = sys.argv[1]

# 音声波形をロード
wave = []
f = open(rawfile, "rb")
while True:
    # 2バイト(SHORT)ずつ読み込む
    b = f.read(2)
    if b == "": break;
    # 読み込んだ2バイトをSHORT型(h)でアンパック
    val = struct.unpack("h", b)[0]
    wave.append(val)
f.close()

# プロット
plot(range(len(wave)), wave)
xlabel("sample")
ylabel("amplitude")
xlim([0, len(wave)])
ylim([-32768, 32767])
show()
python plot.py data.float

とするとこんなグラフが出てきます。XWindowsに比べるとmatplotlibのグラフの方がきれいかな。

f:id:aidiary:20120701120836p:plain

gnuplotで波形描画(2013/3/9)

gnuplotを使うとダンプデータを簡単に描画できます。手軽に波形を確認できるのでオススメの方法です。波形に限らずdmpコマンドで出力したテキストデータなら同じように描画できます。

dmp +s data.short > data.txt
gnuplot
gnuplot > plot "data.txt" w l

音声の再生

波形を見ても何て言っているのかわからないので再生してみます。rawファイルの再生は、daというコマンドなのですが、これはWindowsでもMacでも使えませんでした*2

rawファイルの再生はいくつか方法がありますが、簡単なのはWaveSurferというソフトです。このソフトだとrawファイルが開けます。rawファイルは、wavと違ってサンプリング周波数や量子化ビット数、チャンネル数、バイトオーダなどのヘッダ情報がまったくないので自分で指定する必要があります。このファイルは、16000Hz、16bit、モノラルで、Little Endianです。

f:id:aidiary:20120701122637p:plain

再生してみると、、、男性の声で「青い植木鉢」だそうです。えっ、何それ(笑)

SPTKのraw2wavというコマンドを使うとrawをwavに変換できます。raw2wavの引数にサンプリング周波数などを与えますが、今回はデフォルトでOK。wavなら普通のソフトでも再生できます。

raw2wav data.short

最後にPythonのpyaudioというライブラリを使って、rawファイルを再生するスクリプトを書いてみます。rawファイルのデータを1024バイトずつ読み込んで音声ストリームに流しているだけです。

#coding:utf-8
import pyaudio
import sys

if len(sys.argv) != 2:
    print "usage: python play.py [raw file]"
    sys.exit()
rawfile = sys.argv[1]

p = pyaudio.PyAudio()
stream = p.open(format=p.get_format_from_width(2), channels=1, rate=16000, output=True)
f = open(rawfile, "rb")
chunk = 1024
data = f.read(chunk)
while stream.is_active():
    stream.write(data)
    data = f.read(chunk)
    if data == '': stream.stop_stream()
stream.close()
p.terminate()
python play.py data.short

サンプリング周波数、チャンネル数、量子化ビット数などは決めうちなので引数から与えるように拡張するといいかもしれません。

次回は音声波形のクリッピングを試してみます。

*1:WindowsならXmingがおすすめ

*2:マニュアルにもLinux, Solaris, FreeBSDと書いてあります。Linuxでも/dev/dspがないUbuntuでは再生できませんでした。