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

SwaySound

今回はSound.extract()を使って波形をとってみた。次は変形させて再生に挑戦。

ところでローディング開始まで異常に長いのなんで。。orz
Get Adobe Flash player
by rettuce 27 Dec 2011
  • Related works: 1
  • Talk

    matacat at 28 Jan 2011 12:22
    103行目, mapImage.perlinNoise()のnumOctaveが-1(=0xffffffff)になってます...
    rettuce at 28 Jan 2011 19:01
    うわー、原因これだったんですね!!!流体の動きperlinNoise()に関係なくなってましたね。。。 どうもありがとうございますー!
    Embed
/**
 * Copyright rettuce ( http://wonderfl.net/user/rettuce )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/5VaYC
 */

package 
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BitmapDataChannel;
    import flash.display.Graphics;
    import flash.display.MovieClip;
    import flash.display.Shape;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.ProgressEvent;
    import flash.events.SampleDataEvent;
    import flash.filters.BlurFilter;
    import flash.filters.DisplacementMapFilter;
    import flash.filters.DisplacementMapFilterMode;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.media.SoundLoaderContext;
    import flash.net.URLRequest;
    import flash.media.SoundMixer;
    import flash.text.TextField;
    import flash.utils.ByteArray;
    import flash.display.BlendMode;
    
    [SWF(width = 465, height = 465, backgroundColor = 0x000000, frameRate = 40)]
    /**
     * ...
     * @author rettuce
     * 
     *  前回はSoundMixer.computeSpectrumを使用したので
     *  今回はSound.extractを使用して音データをとってみる
     * 
     * 音はTsabeat より拝借
     * http://www.ektoplazm.com/2010/highpersonic-whomen-alternative-energysource
     */
    public class Main extends MovieClip 
    {
        private var _sound:Sound;
        private var _channel:SoundChannel;
        private var _byteArray:ByteArray;
        private var _filterFlg:Boolean = false;
        
        private var _bm:Bitmap;
        private var shape_left:Shape;
        private var shape_right:Shape;
        private var g_left:Graphics;
        private var g_right:Graphics;
        
        private var _hane:int = 120;        // 振幅の幅値
        private var wave_scale:int = 1;        // 波形の取得数 大きいほど細かい
        private var line:int = 2000;            // 波形の取得数 大きいほど細かい
        
        private var mapFilter:DisplacementMapFilter;
        private var mapImage:BitmapData;
        private var componentX:uint      = BitmapDataChannel.RED;
        private var componentY:uint      = BitmapDataChannel.GREEN;
        private var _scaleX:Number      = 0;
        private var _scaleY:Number      = 50;
        private var mapImagePoint:Point;
        private var mode:String = DisplacementMapFilterMode.IGNORE;        
        
        public function Main()
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init );
        }
        
        private function init(e:Event = null ):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init );
            
            _bm = new Bitmap( new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x000000 ) );
            addChild(_bm);
            
            _byteArray = new ByteArray();
            
            stage.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void{
                if (!_filterFlg) _filterFlg = true;
                else _filterFlg = false;
            })
            
            // 波形描画用シェイプ
            shape_left = new Shape();
            shape_left.x = 0;
            shape_left.y = stage.stageHeight/2 ;
            g_left = shape_left.graphics;
            
            shape_right = new Shape();
            shape_right.x = 0;
            shape_right.y = stage.stageHeight/2;
            g_right = shape_right.graphics;
            
            addChild(shape_left);
            addChild(shape_right);
            
            // MAP作成
            mapImage = new BitmapData( stage.stageWidth, stage.stageHeight );
            mapImage.perlinNoise( stage.stageWidth, stage.stageHeight, 4,  0, false, true );
            mapImagePoint = mapImage.rect.topLeft;
            mapFilter = new DisplacementMapFilter( mapImage, mapImagePoint, componentX, componentY, _scaleX, _scaleY, mode );
//            addChild(new Bitmap(mapImage));            
            
            setStage();
            soundSet();
            
            loaderInfo.addEventListener(Event.UNLOAD, function(e:Event):void {
                _channel.stop();
                stage.removeEventListener(Event.RESIZE, resizeEvent);
                stage.removeEventListener(MouseEvent.CLICK, function(e:MouseEvent):void { if (!_filterFlg) _filterFlg = true;
                else _filterFlg = false; } );
                removeEventListener(Event.ENTER_FRAME, soundAnimation );
                loaderInfo.removeEventListener(Event.UNLOAD, arguments.callee );
            });
        }
        private function setStage():void {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.addEventListener(Event.RESIZE, resizeEvent);
            resizeHandler();
        }
        private function resizeEvent(e:Event = null):void {
            resizeHandler();
        }        
        public function resizeHandler(): void
        {                
            shape_left.x = shape_right.x = _bm.x = _bm.y = 0;
            shape_left.y = shape_right.y = stage.stageHeight / 2;
            _bm.width  = stage.stageWidth;
            _bm.height = stage.stageHeight;
        }
        
        private function soundSet():void 
        {
            // 再生用 sound クラスの 生成と sampleDataEvent 取得
            _sound = new Sound();
            _sound.load(new URLRequest("http://lab.rettuce.com/common/src/PieceOfCake.mp3"), new SoundLoaderContext( 100 , true ));
            
            var txt:TextField = new TextField();
            txt.width = 120;
            txt.x = stage.stageWidth / 2 -60;
            txt.y = stage.stageHeight / 2;
            txt.textColor = 0xFFFFFF;
            addChild(txt);
            _sound.addEventListener (ProgressEvent.PROGRESS, function(e:ProgressEvent):void {
                txt.text =  "Now loading... "+Math.floor(e.bytesLoaded / e.bytesTotal * 100) + "%";
            });
            _sound.addEventListener(Event.COMPLETE, function(e:Event):void {
                _sound.removeEventListener(ProgressEvent.PROGRESS, function(e:ProgressEvent):void {
                txt.text =  Math.floor(e.bytesLoaded / e.bytesTotal * 100) + "%";
            });
                removeChild(txt);
                _channel = _sound.play( 0, 1 );
                addEventListener(Event.ENTER_FRAME, soundAnimation );
            });
        }
        
        private function soundAnimation(e:Event):void
        {    
            if (_sound && _channel) {
                
                // グラフィッククリア
                g_left.clear();
                g_left.lineStyle ( 1.0 , 0xFFFFFF*Math.random() , 0.6 );
                g_right.clear();
                g_right.lineStyle ( 1.0 , 0xFFFFFF*Math.random() , 0.2 );
                
                // サウンドデータを取得
                var buffer:ByteArray = new ByteArray();
                var begin:Number = Math.floor( _channel.position / line * 44100);
                begin = Math.floor(begin / wave_scale) * wave_scale;    // ズレ防止
                var sampling:Number = Math.floor(line * wave_scale);
                sampling = _sound.extract(buffer, sampling, begin);
                
                var i:int;
                var data:Array;
                
                data = new Array();
                for (i = 0; i < sampling; i += wave_scale) {
                    buffer.position = Math.floor(i) * 4 ;
                    data.push(buffer.readFloat());
                }
                if (data.length) {
                    g_left.moveTo ( 0 , -data[0] * _hane );
                }
                for (i = 1; i < line; i++) {
                    g_left.lineTo ( i / line * stage.stageWidth , -data[i] * _hane - Math.sin(i/line*Math.PI)*130 );
                }
                
                data = new Array();
                for (i = 0; i < sampling; i += wave_scale) {
                    buffer.position = Math.floor(i) * 4 + 4;
                    data.push(buffer.readFloat());
                }
                if (data.length) {
                    g_right.moveTo ( 0 , -data[0] * _hane );
                }
                for (i = 1; i < line; i++) {
                    g_right.lineTo ( i / line * stage.stageWidth ,  -data[i] * _hane + Math.sin(i/line*Math.PI)*100*Math.cos( line/2 - i * Math.PI ) );
                }
                
                // エフェクト
                if( !_filterFlg ) _bm.bitmapData.draw(shape_left, new Matrix( 1, 0, 0, 1, 0, stage.stageHeight/2 ), new ColorTransform( 1, 1, 1, 1, 0, 0, 0, 0), BlendMode.ADD );
                _bm.bitmapData.applyFilter( _bm.bitmapData, _bm.bitmapData.rect, _bm.bitmapData.rect.topLeft, mapFilter);
                _bm.bitmapData.applyFilter( _bm.bitmapData, _bm.bitmapData.rect, _bm.bitmapData.rect.topLeft, new BlurFilter( 10 , 15 ) );
                
            }
        }
        
        
    }
    
}