In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

WebCamでtenorionぽくSiON鳴らす

SiONのソースの大部分は
http://wonderfl.net/c/qf4b
を参考にさせてもらってます。

※音量注意
Get Adobe Flash player
by mrhdms 06 Sep 2011
/**
 * Copyright mrhdms ( http://wonderfl.net/user/mrhdms )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/t6hp
 */

package
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.media.*;
    import org.si.sion.events.SiONTrackEvent;
    
    /**
     * webCamでSiON鳴らす
     * @author mrhdms
     */
    public class Main extends Sprite
    {
        private var _camera:Camera;
        private var _video:Video;
        private var _canvas:BitmapData;
        private var _rect:Rectangle;
        
        private var _movieSize:uint = 350;
        private var _col:uint = 16;//分割列数
        private var _raw:uint = 16;//分割行数
        
        private var _sc:SoundControll;
        private var _sequences:Vector.<int> = new Vector.<int>(16);
        
        private var _drawScale:Number = 1/4;//解析用画像の縮小率
        private var _capMat:Matrix;
        private var _circles:Circles;
        
        public function Main():void
        {
            if (stage)
                init();
            else
                addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            
            //カメラの設定
            try
            {
                _camera = Camera.getCamera();
                _video = new Video(_movieSize, _movieSize);
                _camera.setMode(_movieSize, _movieSize, 30);
                _video.attachCamera(_camera);
            }
            catch (err:Error)
            {
                throw new Error("カメラ取得失敗");
            }
            //ビデオの反転(内向きカメラ用)
            var mat:Matrix = new Matrix();
            mat.scale( -1, 1);
            mat.translate(_video.width, 0);
            _video.transform.matrix = mat;
            
            //キャプチャ用Matrix
            _capMat = new Matrix();
            _capMat.scale( -_drawScale, _drawScale);
            _capMat.translate(_video.width * _drawScale, 0);
            
            //書き込み用キャンバス
            _canvas = new BitmapData(_camera.width*_drawScale, _camera.height*_drawScale, false, 0x000000);
            
            var bmp:Bitmap = new Bitmap(_canvas);
            //bmp.scaleX = bmp.scaleY = 2;
            bmp.x = _movieSize;
            
            //グラフィック表示
            _circles = new Circles(_movieSize, _movieSize, _col, _raw);
            
            //Sion制御
            _sc = new SoundControll();
            
            addChild(bmp);
            addChild(_video);
            addChild(_circles);
            _sc.driver.addEventListener(SiONTrackEvent.BEAT, _onBeat);
            _sc.driver.setTimerInterruption(1, _onTimerInterruption);
            
            _sc.driver.play(null,false);
            
            //var status:Stats = new Stats();
            //addChild(status);
        }
        
        private function _onTimerInterruption():void 
        {
            _canvas.lock();
            _canvas.draw(_video,_capMat);
            _canvas.threshold(_canvas, new Rectangle(0, 0, _canvas.width, _canvas.height), new Point(0, 0), "<", 0xFF888888);
            _canvas.threshold(_canvas, new Rectangle(0, 0, _canvas.width, _canvas.height), new Point(0, 0), ">", 0xFF888888, 0xFFFFFFFF);
            _canvas.unlock();
            
            var beatIndex:uint = _sc.beatCounter & 15;
            var cx:int = beatIndex * _canvas.width / _col;
            cx += _canvas.width / _col / 2;
            
            for (var i:int = 0; i < _raw; i++) 
            {
                var cy:int = i * _canvas.height / _raw;
                cy += _canvas.height / _raw / 2;
                    
                checkRGB(_canvas.getPixel(cx, cy),15-i,beatIndex);
                
                if (_sequences[i] & (1 << beatIndex)) 
                {
                    _sc.driver.noteOn(_sc.notes[i], _sc.voices[i], _sc.length[i]);
                }
            }
            
            _sc.beatCounter++;
        }
        
        
        private function _onBeat(e:SiONTrackEvent):void 
        {
            var beatIndex:uint = e.eventTriggerID & 15;
            for (var i:int = 0; i < _raw; i++) 
            {
                if (_sequences[i] & (1 << beatIndex)) 
                {
                    _circles.move(beatIndex,15-i);
                }
            }
        }
        
        
        private function checkRGB(pixel:uint,track:uint,beat:uint):void 
        {
            if (pixel > 0) { //2値化後の画像の白に反応
                if (_sequences[track] & (1 << beat)) 
                {
                    
                } else {
                    _sequences[track] ^= 1 << beat;
                }
            } else {
                if (_sequences[track] & (1 << beat)) 
                {
                    _sequences[track] ^= 1 << beat;
                }
            }
        }
    
    }

}


    import org.si.sion.effector.SiEffectStereoReverb;
    import org.si.sion.SiONDriver;
    import org.si.sion.SiONVoice;
    import org.si.sion.utils.SiONPresetVoice;
    /**
     * SiONを使って音鳴らすクラス
     * ソースの大部分はSion Tenorion
     * @see http://wonderfl.net/c/qf4b
     */
    class SoundControll 
    {
        // driver
        public var driver:SiONDriver = new SiONDriver();
        
        // preset voice
        public var presetVoice:SiONPresetVoice = new SiONPresetVoice();
        
        // voices, notes and tracks
        public var voices:Vector.<SiONVoice> = new Vector.<SiONVoice>(16);
        //public var notes :Vector.<int> = Vector.<int>([36,48,60,72, 43,48,55,60, 65,67,70,72, 77,79,82,84]);
        public var notes :Vector.<int> = Vector.<int>([48,50,52,55, 60,62,64,67, 72,74,76,79, 84,86,88,91]);
        public var length:Vector.<int> = Vector.<int>([ 1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1,  1, 1, 1, 1]);
        
        // beat counter
        public var beatCounter:int;
        
        public function SoundControll() 
        {
            var i:int;
            
            // set voices from preset
            var percusVoices:Array = presetVoice["valsound.percus"];
            voices[0] = percusVoices[0];  // bass drum
            voices[1] = percusVoices[27]; // snare drum
            voices[2] = percusVoices[16]; // close hihat
            voices[3] = percusVoices[22]; // open hihat
            //for (i=4; i<8;  i++) voices[i] = presetVoice["valsound.bass18"];  // bass
            for (i=4; i<16; i++) voices[i] = presetVoice["valsound.wind1"];           
            
            var reverb:SiEffectStereoReverb = new SiEffectStereoReverb(0.8,0.4,0.6,0.5);
            
            
            driver.setBeatCallbackInterval();
            driver.bpm = 80;
            driver.volume = 0.5;
            driver.effector.slot0 = [reverb];
            
            beatCounter = 0;
        }
        
    }


    import flash.display.BlendMode;
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import org.libspark.betweenas3.BetweenAS3;
    import org.libspark.betweenas3.tweens.ITween;
    
    /**
     * 丸を描く
     * @author Hidemasa Mori
     */
    class Circles extends Sprite 
    {
        private var _circleAry:Array = new Array();
        
        /**
         * コンストラクタ
         * @param    capW 表示領域の幅
         * @param    capH 表示領域の高さ
         * @param    col 分割列数
         * @param    raw 分割行数
         */
        public function Circles(capW:Number,capH:Number,col:uint,raw:uint) 
        {
            
            for (var i:int = 0; i < raw; i++) 
            {
                var cx:Number = capW / col * i;
                for (var j:int = 0; j < col; j++) 
                {
                    var cy:Number = capH / raw * j;
                    var sp:Sprite = new Sprite();
                    sp.graphics.beginFill(0, 0);
                    sp.graphics.lineStyle(4, 0x666666);
                    sp.graphics.drawCircle( -8, -8, 16);
                    sp.graphics.endFill();
                    sp.blendMode = BlendMode.ADD;
                    sp.scaleX = sp.scaleY = 0;
                    
                    sp.x = cx + capW / col / 2;
                    sp.y = cy + capH / raw / 2;
                    
                    sp.visible = false;
                    if (_circleAry[i]) {
                        _circleAry[i][j] = sp;
                    } else {
                        _circleAry[i] = new Array();
                        _circleAry[i][j] = sp;
                    }
                    addChild(sp);
                }
            }
        }
        
        public function move(xIndex:int, yIndex:uint):void 
        {
            var target:DisplayObject = _circleAry[xIndex][yIndex];
            if (target) 
            {
                target.visible = true;
                target.alpha = 1;
                var it:ITween = BetweenAS3.tween(target, { scaleX:1, scaleY:1, alpha:0 }, null, 0.5 );
                it.onComplete = function():void { target.visible = false;target.scaleX = target.scaleY = 0 }
                it.play();
            }
        }
        
    }