音楽プログラミングの超入門(仮)

Python / 音楽情報処理 初心者が、初心者にも分かるような記事を書きたい。

Pythonでの信号処理とは

Pythonを使うメリット

Pythonは簡単

Pythonスクリプト言語の中でも、特に覚えるのが簡単な言語だと思う。全く触ったことがない人でも、1週間くらいで小さいプログラムなら大体書けるようになるんじゃないかな。Pythonしか触ったことのない筆者がいうのだから間違いない。

ライブラリが豊富

信号処理に限らず、Pythonは特定分野の処理を行うためのライブラリが沢山ある。それらを用いることで、効率的なコーディングや、プログラム実行時間の短縮を実現できるよ。公開されているライブラリは大抵、とても洗練されているから、自分で同じものを書くより全ての面で優れていることが多い。


Python信号処理における3種の神器

Pythonで信号処理するにあたって、3つのライブラリが無いと、コーディングの効率的にとか、実行速度的に全くお話にならないよ。

NumPy, SciPy, Matplotlib

NumPy(ナムパイ)は、大きな配列を効率的に扱うためのarray(numpy.ndarray)型と、それを操作するための関数とかを提供する。
SciPy(サイパイ)は、NumPyをもとに更に数学的、工学的な処理を行うための機能を提供する。
Matplotlib(マットプロットリブ?)は、グラフ描画ライブラリで、処理の計算結果とかを画像として描画して目で確かめたりするのに使う。
SciPy、MatplotlibはNumPyに依存している。

インストール

色んなとこに書いてあるから頑張ろう。
普通の環境だったら問題なく入ると思うよ。

使い方

Pythonでライブラリ中の関数を使うには、下みたいな感じにするよ。

# -*- coding: utf-8 -*-
import scipy
from scipy import arange, zeros
from matplotlib import pylab as pl

a = scipy.arange(10) # array([0,1,2,3,4,5,6,7,8,9])
a2 = arange(10) # 上と同じ
z = zeros(10, dtype=int) # array([0,0,0,0,0,0,0,0,0,0])

print a, a2, z

pl.plot(a)
pl.show()

使いたい関数を import するだけで、すごく簡単だね。
「from scipy import *」で全部 import もできるけど、関数が上書きされたりされるかもしれないから、あんまりやらないほうがいいと思う。

Python信号処理における心構え

ありそうだと思った機能は多分ある

こういう関数が欲しいとか、こんな確率分布からサンプリングしたいとか思った時、自分で作ろうとするその前に、SciPy の中とかにないか調べてみよう。多分ある。
音声信号処理でよく使うものだとフーリエ変換(fft)や特異値分解(svd)、その他名前すら聞いたことのなかった確率分布とかでも入ってたりするよ。

for、while 文を使わない

これが Python信号処理で一番本質的な問題だと思う。
Python の実行速度が遅いのは有名だね。(遅いよ。)
信号処理は大抵、すごい大きな配列を扱うから、その要素を全部 for、while 文とかで処理するととんでもない時間かかることになる。なので、Python ではいかに numpy.ndarray の操作だけで処理を終わらすかということが重要になってくる。

簡単な例を挙げると

 \begin{eqnarray}
A = \sum_{i=0}^I a_i,\;\;\;(I=100000)
\end{eqnarray}
上みたいな演算を行うとき、C++ とかだったら for 文をぐるぐる回せばいいけど、Python はさっき書いた通りダメだよね。

# -*- coding: utf-8 -*-
from scipy import rand

a = rand(100000)

# ダメな例
A = 0
for i in xrange(len(a)):
  A += a[i]
print A

# 良い例
A = a.sum()
print A

この位だったらどっちも一瞬だし、かなり極端な例だけど、イメージが伝わればいいなあと思います。
もう少し難しい処理を扱うようになると、自分で考えて数式を行列演算に落とし込んだりしないといけなかったりする。具体的なプログラムをいくつか組んでいるうちに身に付いていくと思うので、今できなくても大丈夫なんじゃないかな。

まとめ

Python は素晴らしいプログラミング言語で、信号処理とかも簡単にできるけど、少しだけ慣れが必要なんかな。