Astro(Flash10) ,singing DO-RE-MI--
サンプル(Flash10beta必須)
*いきなり音が鳴ります!
ソースコード
SDKとか環境構築はこちらを参照
http://wiki.libspark.org/wiki/FlashPlayer/10/API
コーディングはこちらを参照
http://www.kaourantin.net/2008/05/adobe-is-making-some-noise-part-2.html
samplesCallbackイベントとSound.samplesCallbackDataを使うだけでさら~とコードがかけて、そして音が鳴ることにびっくり。ハッキリ言ってすごい。リリースしたAdobeはもちろんのこと、Adobe Make Some Noise の執念もすごいな~と感じる。
赤いボタンの左から順に「ド・レ・ミ・ファ・ソ・ラ・シ・ド」と音階になってます。
メインのコードはこちら。
package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.SamplesCallbackEvent; import flash.media.Sound; import flash.text.TextField; import flash.utils.getTimer; use namespace astro; [SWF ( frameRate="40")] public class Astrotest extends Sprite{ private const RATE:Number = 44100 private var frequency:Number = 220 private var textField:TextField = new TextField() public function Astrotest(){ for(var i:int = 0; i < 8; i++){ createKey(i) } createDebuger(); var sound:Sound = new Sound(); function sineWavGenerator(event:SamplesCallbackEvent):void { var rate:Number = RATE var amp:Number var freq:Number = (Math.PI * 2) * frequency / 44100; for ( var c:int=0; c<512; c++ ) { amp = (event.position + c) * freq var sample:Number = Math.sin( amp ) * 0.5 sound.samplesCallbackData.writeFloat(sample); sound.samplesCallbackData.writeFloat(sample); } } sound.addEventListener("samplesCallback",sineWavGenerator); sound.play(); } private function createKey(index:int = 0):void{ var ary:Array = [220, //ド 246.942, //レ 277.183, //ミ 293.655, //ファ 329.628, //ソ 369.994, //ラ 415.305, //シ 440] //ド var key:Sprite = new Sprite() key.buttonMode = true; key.graphics.beginFill(0xff0000) key.graphics.drawRect(0,0,50,50) key.graphics.endFill(); key.addEventListener(MouseEvent.MOUSE_DOWN, function ():void{ frequency = ary[index] textField.appendText(frequency.toString() + ", "); }) addChild(key) key.x = index * 70; } private function createDebuger():void{ addChild(textField) textField.text ="debuger" textField.wordWrap = true textField.width = 800; textField.height = 800; textField.y = 200 } } }
詳しい仕様を読んだわけではないのでざっくりだけど、「samplesCallback」っていうのはサウンドデータがバイトレベルで再生し終わった時に送出される様です。
以前は「ON_SOUND_COMPLETE」というイベントを使ってた訳ですが、精度が甘かったり、Vistaだと全く話にならなかったりでみんなが頭を悩ませていました。Astroではなんとかこの精度を上げてくれよと世界中のFlasherが「Adobe Make Some Noise」したところ、なんとAdobeは全く新しいイベントを作ったわけです。よくやった!Adobe!
話がそれたので元に戻しますが、samplesCallbackが発生する毎にサインカーブを生成して直接Soundインスタンスに書き込んでいます。ちなみにその時書き込めるデータの長さが決まっていて512~8192の長さです。たしかPCM形式の仕様に8192って数字は何かしら関連が会ったような気がしますが不勉強なのでよく分かりません。これよりでかくてもちっこくても、何れにせよ音は鳴らないみたいです。
そして、書き込んだデータが再生し終わるとまた新たに、samplesCallbackが呼ばれ、ループします。従って512に近づければ近づくほど生成の間隔が短くなり、よりリアルタイムな処理になるって事です。
いまのところ、生成されるサウンドは32bit,44100Hz,Streo,に限定されているみたいなので、それに併せてサイクルを変えると音階表現が出来ます。
とりあえず今日はここまで。