Dynamic Sound Generationで蛙の歌を作ってみました。
(注:いきなり音が出るので注意!!)
package {
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.media.Sound;
import flash.events.SampleDataEvent;
import flash.media.*;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class FrogSong extends EventDispatcher{
var freq:Number = 220;
var rate:Number = 44100;
var baseRate:Number = 44100;
private var noise:Number = 0;
private var C:Number = 1;
private var D:Number = 9 / 8;
private var E:Number = 5 / 4;
private var F:Number = 4 / 3;
private var G:Number = 3 / 2;
private var A:Number = 5 / 3;
private var B:Number = 15 / 8;
private var timer:Timer = new Timer (700,0);
private var rateArray:Array = new Array ();
var sound:Sound = new Sound();
var soundChannelObject:SoundChannel = new SoundChannel ();
public function FrogSong() {
rateArray = [C, D, E, F, E, D, C, C, E, F, G, A, G, F, E, E, C, 0, C, 0, C, 0, C, 0, C, D, E, F, E, D, C];
rate = baseRate/rateArray.shift();
timer.addEventListener (TimerEvent.TIMER, onTimer);
timer.start ();
sound.addEventListener (SampleDataEvent.SAMPLE_DATA, onSamplesCallback);
soundChannelObject = sound.play();
}
private function onTimer (e:TimerEvent) {
if (!rateArray.length) {
timer.stop ();
soundChannelObject.stop ();
dispatchEvent (new Event(Event.COMPLETE));
}
rate = baseRate/rateArray.shift();
}
private function onSamplesCallback (e:SampleDataEvent) {
for(var i:int=0; i<2048; i++){
noise += (freq) / rate;
var samples:Number = noise * Math.PI * 2;
var samples2:Number = noise * Math.PI;
e.data.writeFloat((Math.sin(samples) + Math.sin(samples*2) + Math.sin(samples*4))/3);
e.data.writeFloat(Math.sin(samples));
}
}
}
}
最初、なんでwriteFroatを二回もするのかわからなかったんだけど、
調べたら、最初のは左音声、次のは右音声だった。
みんな、二回同じにしてたのは、左右を同じ音にするためだったんですね。
音階はCを基準に下記リンク内のディアトニック音階を参考に各音程の比率を変数にして、その値を音程変える際にかけるという風にしています。
まだ、触ったばかりなので、いろいろわからないことだらけだけど、結構楽しい。
次は、和音の合成とプチプチ鳴るノイズをなんとかしたいですね。
参考