これは、以前に紹介したPythonのサウンドライブラリPyoで、どのように自作クラス(ヴォコーダー)を作るかを説明した文章の翻訳です。
>>>以下本文
原文 http://code.google.com/p/pyo/wiki/createYourOwnAudioObject
自作オーディオ・オブジェクト
これは、小さいチュートリアル。サウンド処理のために、君自身のオブジェクトのつくりかた。
序文
この例では、ヴォコーダーを製作していくことにする。とてもシンプルなクラスから始めて、より洗練されたクラスを作るために、徐々に機能を加えていく。できあがったクラスはホンモノのpyoオブジェクトのように振る舞うだろう。
なにはともあれ、メインのスクリプトが読み込む、クラスの置き場所に"vocoder_lib.py"というファイルをつくろう。
ファイル"vocoder_lib.py"と"vocoder_main.py"はpyoのソースコードのexampleフォルダの中にある。
シンプルなヴォコーダー
自作クラスに、妙な振る舞いをさせないように覚えておくべきことがひとつある。すべてのpyoオブジェクトは、オーディオサンプルの計算に要する時間まで、生存させておかなければならない。initメソットの終了時に自作クラスが破壊されるのを防ぐために、常にpyoオブジェクトに接頭辞"self"をつけることをこころがけて。
自作クラス(最低でもPyo)にある、君が必要とするモジュールすべてが読み込まれることで開始する。
import math from pyo import *
そして、ここにクラスSimpleVocoderがある。
class SimpleVocoder: def __init__(self, in1, in2, num=32, base=50, spread=1.5, q=5): self._in1 = in1 self._in2 = in2 self._num = num self._base = base self._spread = spread self._q = q self._freqs = Sig([self._base * math.pow(i+1, self._spread) for i in range(self._num)]) self._clipped_freqs = Clip(self._freqs, 20, 200000) self._src = Biquadx(self._in1, freq=self._clipped_freqs, q=self._q, type=2, stages=4) self.envelope = Follower(self._src, freq=5, mul=self._q*30) self._exc = Biquadx(self._in2, freq=self._clipped_freqs, q=self._q, type=2, stages=4, mul=self._envelope)
おわかりのように、非常にシンプルなクラスですが、準備ができた。
ここで、なにが起こったのか確認してみよう。はじめに、あとで使うために、入力で与えられたpyoオブジェクトの参照を保持する。そのとき、フィルタの周波数を計算し、リストをシンプルなSig()オブジェクトに渡す。そこでは、フィルタ周波数をClip()されたオーディオ信号を浮動小数点に変更するために、Sig()オブジェクトを利用する(フィルタはナイキスト周波数によって一定ではない)。いったんこれがされると、最初の信号の帯域ごとに、エンベロープフォローワーを適用し、そして二番目の信号で、このエンベロープをフィルタの振幅として使うことによって、ヴォコーダーを作れる。
これで、われわれのメインのスクリプトで、このクラスを利用できる(vocoder.pyファイルをメインのスクリプトと同じフォルダに置くことを忘れないで)。
from pyo import * from vocoder_lib import SimpleVocoder s = Server(sr=44100, nchnls=2, buffersize=1024, duplex=0).boot() a = SFPlayer(SNDS_PATH + "/transparent.aif", loop=True, mul=3).play() b = Noise() voc = SimpleVocoder(in1=a, in2=2, num=32, base=50, spread=1.2, q=5) s.gui(locals())
これでいいでしょう、ただ扱いづらい、だって実行中にいろいろ変更するのがとっても面倒。
Vocoderをコントロールするためにメソッドを加えてみよう。