Python26用PySndObjの新機能

普段Pythonは25なので26用のPySndObjのチェックが遅れました。
新年も迎えまして、時間もあるので少し書いてみます。

さて26用のPySndObjはインストーラ化されました。
これで初心者にも扱いやすくなったと思ったのですが、、、
起動するとNumpyがないとエラー。え〜。

よってPySndObjはNumpyを必要とするPython用音楽モジュールとして新しいスタートを切りました。

はて、どうして?と困惑するもしょうがなくNumpyを入れました。
ちなみにNumpyは高機能の数学ライブラリ?まあそんなもんです。
http://ja.wikipedia.org/wiki/NumPy

無駄話はこれくらいにして新機能を説明します。
シンプルに書くとNumpyの配列を直接PySndObjに渡せるというもの。

これによりNumpyの豊富な数学関数を利用できることになりました。
だが以前も波形テーブルを使って任意の配列を作り音を鳴らす方法がありました。
でもNumpyの配列を直接PySndObjに渡す方法はなく一度変換していました。

そうこの分野においてとても簡単になったぐらいかと思っていたのですが、、、
意外といいんじゃないかと便利なんじゃないかと

簡単な例をして説明します。
まずNumpyの配列を作る。

sine = zeros(256, dtype=float32)
for i in range(sine.size):
    sine[i] = 0.5 * sin((2 * pi * i) / sine.size)
sine *= 32768

このNumpyの配列sineはオシレータ系の上位クラスSndObjに渡します。
渡す方法はSndObjのメソッドPushInの引数に

obj = SndObj()
obj.PushIn(sine)

これは再生中にも渡せるので。
10秒後に周波数が倍の配列を作って渡してみましょう。

from sndobj import *
from numpy import zeros, pi, sin, float32
import time    

# サイン波のnumpyの配列を作る(1フレーム分)
sine = zeros(256, dtype=float32)
for i in range(sine.size):
    sine[i] = 0.5 * sin((2 * pi * i) / sine.size)
sine *= 32768

obj = SndObj()
obj.PushIn(sine)#ここで配列を渡す。

outp = SndRTIO(1, SND_OUTPUT, 2048)
outp.SetOutput(1, obj)
thread = SndThread()
thread.AddObj(obj)
thread.AddObj(outp, SNDIO_OUT)

thread.ProcOn()
time.sleep(10)
#周波数2倍
for i in range(sine.size):
    sine[i] = 0.5 * sin((2 * pi * i * 2) / sine.size)
sine *= 32768
obj.PushIn(sine)#ここで配列を渡す。
print "change"
time.sleep(10)
thread.ProcOff()
time.sleep(0.02)

以上です。

先ほど述べたようにクラスSndObjを継承するジェネレータ系のクラス、
例えばOsciliクラスとかもPushInメソッドを持つことになります。