ちょっとした音データを作る必要があって、何かいいツールはないかと探していたときに、「ChucK」という言語(「オーディオプログラミング言語」だそうです)を知りました。これはなかなか面白そう。音声データの編集(エフェクトとか)や、音ネタをさくっと作るときなんかに重宝しそうです。
まずは"Hello, world"代わりに、適当に音を出すプログラムを書くとこんな感じになります。懐かしのPC-98の起動音(「ピポッ」てやつです)を鳴らして、wavファイルにも出力するプログラムです。出力結果はこちら(pc98.wav)。
SqrOsc osc => WvOut wout => dac; 0.1 => osc.gain; wout.wavFilename("pc98.wav"); osc.freq(2000); 100::ms => now; osc.freq(1000); 100::ms => now;
ChucKの言語仕様は少し独特な感じですが、見れば何となく分かるかと思います。まずは、いろんなモジュール(ChucKでは"UGen"(unit generator)というようです)を「=>」という演算子(「ChucK演算子」と呼ぶらしい)でつないでいって、最終的に「dac」に渡すように結線します。そして、「now」に経過時間を入れることで時間が進み、時間経過に伴って結線に従った音が鳴るという流れのようです。
ちなみに、「WvOut wout」は、音声データをファイル出力するために噛ませているもので、外しても音は鳴ります。逆に、音声ファイル出力だけやりたい(その場で音は鳴らさない)場合は、dacの代わりに「blackhole」という /dev/null 的なUGenにつなげればOKです。
ChucKで組み込みで用意しているUGenのリストを見ると、矩形波・のこぎり波・フィルタ・エンベロープ・リバーブ・コーラス・FM・etc...といった、シンセ方面でよく見かけるものが揃っていて、いろいろと楽しそうなことができそうです。
以下は、エンベロープで整形した矩形波を3和音で鳴らし、リバーブとコーラスをかけたサンプルです。「♪セーガー」ってやつですね。出力結果はこちら(sega.wav)。
ADSR env; | |
env.set(50::ms, 250::ms, 0.5, 100::ms); | |
JCRev rev; | |
0.25 => rev.mix; | |
Chorus cho; | |
0.2 => cho.modDepth; | |
0.25 => cho.mix; | |
WvOut wout; | |
wout.wavFilename("sega.wav"); | |
Gain g; | |
0.1 => g.gain; | |
SqrOsc osc1 => env => cho => rev => wout => g => dac; | |
SqrOsc osc2 => env => cho => rev => wout => g => dac; | |
SqrOsc osc3 => env => cho => rev => wout => g => dac; | |
0.005 => osc1.gain => osc2.gain => osc3.gain; | |
osc1.freq(Std.mtof(58)); // A#3 | |
osc2.freq(Std.mtof(63)); // D#4 | |
osc3.freq(Std.mtof(67)); // G4 | |
env.keyOn(); | |
500::ms => now; | |
env.keyOff(); | |
osc1.freq(Std.mtof(55)); // G3 | |
osc2.freq(Std.mtof(60)); // C4 | |
osc3.freq(Std.mtof(64)); // E4 | |
env.keyOn(); | |
1000::ms => now; | |
env.keyOff(); | |
250::ms => now; |
(セガのゲームにはあまり縁はありませんでしたが、CMのあのジングルは印象的でした)
0 件のコメント:
コメントを投稿