本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回は@techno_nekoこと伊藤智章さんが、Perlで音を扱う方法について紹介します。
Perlで「音」は扱える?
Perlと言えば文字列操作やWebアプリケーションのイメージが強いと思いますが、今回は「音」を扱って信号処理を行うという、ちょっと特殊なPerlの使い方を紹介します。まずPerlで音を作って、次にビートを刻み、最後にWAVEファイルに出力する方法を説明します。
なお、本稿のコードはWEB+DB PRESS Vol.69のサポートサイトからダウンロードできますので、ぜひみなさんも実際に動かして音を聴いてみてください。
波形のお話
普段みなさんが耳にしている音は、とても複雑な波形(空気の振動)です。今回はその複雑な波形を作るために、いくつかの基本波形を合成して音を作ります(図1)。これらの波形は、三角関数のように同じデータを繰り返すものと、乱数を用いて生成したノイズで表現されます。
リスト1は波形を生成する関数を返すコードです。最初に、ノイズ波形のもととなるノイズデータの初期化を行います。ノイズ波形とは、rand()の戻り値のように周期を持たない波形を指します。ノイズデータは、好みの音が出る状態を保持するために、(1)のようにsrand()による初期化を行ってあらかじめ配列に格納しておきます。これにより、今回の音作りに適したノイズ波形を安定的に生成できます。実際に波形データを生成する関数は(2)のように定義して、あとのコードでこれらを簡単に呼び出せるように、波形の名前を指定して関数を取得できる(3)のcreate_mod_func()を定義しています。
音程のお話
図2のように、1オクターブを12等分して算出した音律(周波数と音程の関係)を十二平均律と言います。今回は、一般的に多く採用されている基準となるラの音を440Hzとした場合の、残りの音程の周波数を算出する方法を紹介します。
Perlによる実装
リスト2は、図2のindexと周波数の関係をコードに落とし込んだものです。たとえばドの音の周波数を計算したい場合は、図2の横軸からドに対応するindexを選択して、(1)のように関数の引数として与えて算出します。さらに1オクターブ高い音の周波数を計算する場合は(2)のように12足したものを与え、逆に1オクターブ低い音の周波数を計算する場合は(3)のように12引いたものを引数に与えます。