flash on 2010-4-7

by tenasaku
2010年4月7日
SampleDataEvent というのを覚えたので使ってみます
----------------------------------------------------
ステージをマウスでクリックしてサウンド on/off
mouseX で音程 ( ステージ中央 A:442Hz で音域 4オクターブ )
mouseY で強弱 ( ステージ最下部の 10パーセント ではミュート )
マウスにリアルタイムに追従というわけにいかんから楽器にはならんな
----------------------------------------------------
♥0 | Line 111 | Modified 2010-04-07 21:49:53 | MIT License
play

ActionScript3 source code

/**
 * Copyright tenasaku ( http://wonderfl.net/user/tenasaku )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/9Q1Q
 */

// 2010年4月7日
// SampleDataEvent というのを覚えたので使ってみます
// ----------------------------------------------------
// ステージをマウスでクリックしてサウンド on/off
// mouseX で音程 ( ステージ中央 A:442Hz で音域 4オクターブ )
// mouseY で強弱 ( ステージ最下部の 10パーセント ではミュート )
// マウスにリアルタイムに追従というわけにいかんから楽器にはならんな
// ----------------------------------------------------

package {
	import flash.display.*;
	import flash.events.*;
    import flash.media.*;
    import flash.accessibility.Accessibility;
    public class FlashTest extends Sprite {
    		private var guide:Shape;
    		private var snd:Sound;
    		private var ch:SoundChannel;
    		private var phase:Number = 0;
    		private var lastAmpl:Number = 0;
    		private var lastFreq:Number = 442.0;
    		private var playing:Boolean;
    		private function drawHorizon():void {
    			if ( stage == null ) return;
    			this.graphics.clear();
    			this.graphics.beginFill(0x008000);
    			this.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
    			this.graphics.endFill();
    			guide.graphics.clear();
      		var cc:uint;
    			for ( var i:int = 1 ; i < 48 ; ++i ) {
    				switch ( i%12 ) {
    					case 0:cc = 0xff0000;break;
    					case 1:cc = 0x0000ff;break;
    					case 2:cc = 0xffff00;break;
    					case 3:cc = 0x00ffff;break;
    					case 4:cc = 0x0000ff;break;
    					case 5:cc = 0xffff00;break;
    					case 6:cc = 0x0000ff;break;
    					case 7:cc = 0xffff00;break;
    					case 8:cc = 0xffff00;break;
    					case 9:cc = 0x0000ff;break;
    					case 10:cc = 0xffff00;break;
    					case 11:cc = 0x0000ff;break;
    				}
    				guide.graphics.lineStyle(1,cc);
    				guide.graphics.moveTo(stage.stageWidth/48.0*i,0);
    				guide.graphics.lineTo(stage.stageWidth/48.0*i,stage.stageHeight-1);
    			}
    			guide.graphics.lineStyle(NaN);
    			guide.graphics.beginFill(0x000000,0.5);
    			guide.graphics.drawRect(0,stage.stageHeight*0.9,stage.stageWidth,stage.stageHeight*0.1);
    			guide.graphics.endFill();
    		}
    		private function onResize(e:Event):void {
    			drawHorizon();
    			if ( ch != null ) {
    				ch.stop();
    				guide.alpha = 0.3;
    				playing = false;
    			}
    		}
//    		private function onMouseLeave(e:Event):void {
//    			if ( ch != null ) {
//	    			ch.stop();
//	    			playing = false;
//   			}
//    		}
//    		private function onMouseOver(e:MouseEvent):void {
    			// start sound again (as gracefully as possible) ...
//   		}
    		private function onClick(e:MouseEvent):void {
    			if ( playing ) {
	    			ch.stop();
	    			playing = false;
    			} else {
    				ch = snd.play();
    				playing = true;
    			}
    			guide.alpha = playing?0.8:0.3;
    		}
    		private function onSampleData(e:SampleDataEvent):void {
    			const NUM_SAMPLES:int = 2205;
    			const NUM_REPAIR:int = 1100;
    			var i:int;
    			var value:Number;
    			var vert:Number = stage.mouseX/stage.stageWidth;
	  		var horiz:Number = stage.mouseY/stage.stageHeight;
 	   		var _ampl:Number = (horiz>0.9)?0:Math.pow(0.001,horiz);
 	   		var _freq:Number = 442.0*Math.pow(2,(vert-0.5)*4);
 	   		for ( i = 0 ; i < NUM_REPAIR ; ++ i ) {
 	   			phase += (Math.PI*2)/44100*(_freq*(i/NUM_REPAIR)+lastFreq*(1-i/NUM_REPAIR));
 	   			var a:Number = _ampl*(i/NUM_REPAIR)+lastAmpl*(1-i/NUM_REPAIR);
 	   			value = a*Math.sin(phase);
 	   			e.data.writeFloat(value);
 	   			e.data.writeFloat(value);
 	   		}
    			for ( i = 200 ; i < NUM_SAMPLES ; ++ i ) {
    				phase += (Math.PI*2)/44100*_freq;
    				value = _ampl*Math.sin(phase);
    				e.data.writeFloat(value);
    				e.data.writeFloat(value);
    			}
    			lastAmpl = _ampl;
    			lastFreq = _freq;
    			phase -= Math.floor(phase/(Math.PI*2))*Math.PI*2;
    		}
    		private function initialize(e:Event):void {
    			stage.align = StageAlign.TOP_LEFT;
    			stage.scaleMode = StageScaleMode.NO_SCALE;
    			guide = new Shape();
    			guide.alpha = 0.3;
    			drawHorizon();
    			this.addChild(guide);
//    			stage.addEventListener(Event.MOUSE_LEAVE, onMouseLeave);
    			snd = new Sound();
    			snd.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
    			stage.addEventListener(Event.RESIZE, onResize);    			
    			stage.addEventListener(MouseEvent.CLICK, onClick);
    			playing = false;
    		}
        public function FlashTest() {
            if ( stage != null ) {
            		initialize(null);
            } else {
            		this.addEventListener(Event.ADDED_TO_STAGE, initialize);
            } 
        }
    }
}