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

Sound Visualizer [Study]

...stage click で mp3 音源を自由に入れられるようにしたかったのですが、
FileReferenceで取得した data の ByteArray と、sound クラスの extract() で取得した ByteArray では違うものらしく、
現状のスキルではバイナリデータからの音生成が無理でした。。
なのでただ sin を視覚化して、マウスポイントで音量とパンを変化させてるだけのものです。

@author rettuce
Get Adobe Flash player
by rettuce 27 Dec 2011
/**
 * Copyright rettuce ( http://wonderfl.net/user/rettuce )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/40yi
 */

package {
    import flash.display.MovieClip;
    import flash.display.BlendMode;
    import flash.events.Event;
    import flash.events.SampleDataEvent;
    import flash.display.Sprite;
    import flash.display.Shape;
    import flash.events.MouseEvent;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.media.SoundTransform;
    import flash.net.FileReference;
    import flash.net.URLRequest;
    import flash.media.SoundMixer;
    import flash.utils.ByteArray;
    import flash.system.LoaderContext;
    import flash.media.SoundLoaderContext;
     
    [SWF(width = 465, height = 465, backgroundColor = 0x000000, frameRate = 60)]
    /**
     * ...stage click で mp3 音源を自由に入れられるようにしたかったのですが、
     *    FileReferenceで取得した data の ByteArray と、sound クラスの extract() で取得した ByteArray では違うものらしく、
     *    現状のスキルではバイナリデータからの音生成が無理でした。。
     *    なのでただ sin を視覚化して、マウスポイントで音量とパンを変化させてるだけのものです。
     * 
     * @author rettuce
     */
    public class FlashTest extends Sprite {
        private var _channel:SoundChannel;
        private var _byteArray:ByteArray;
        private const CHANNEL_LENGTH:int = 256;
        private var _barArray:Array = [ ];
        private var _barYellow:Shape;
        private var _barBlue:Shape;
        private var _file:FileReference;
        private var sound:Sound;
        private var sound0:Sound;
        private var dataSound:Sound;
        private var _sampleData:ByteArray;
        
        public function FlashTest()         {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);        
        }
        
        private function init(e:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            for (var i:int = 0; i < CHANNEL_LENGTH; i++)
            {
                _barYellow = new Shape();
                _barBlue = new Shape();
                _barYellow.graphics.beginFill(0xFFFF00);
                _barYellow.graphics.drawRect(0, -1, 1, 1);
                _barYellow.graphics.endFill();
                _barYellow.blendMode = BlendMode.ADD;
                addChild(_barYellow);
                _barBlue.graphics.beginFill(0x0000FF);
                _barBlue.graphics.drawRect(0, -1, 1, 1);
                _barBlue.graphics.endFill();
                _barBlue.blendMode = BlendMode.ADD;
                addChild(_barBlue);
                _barYellow.y = _barBlue.y = stage.stageHeight-20;
                _barYellow.x =  _barBlue.x = i*2;
                _barArray[i] = _barYellow;
                _barArray[i+256] = _barBlue;
            }
            
            _byteArray = new ByteArray();
            
            // 音源取得用 sound クラス生成
//            sound0 = new Sound();
//            sound0.load(new URLRequest("src/OorutaichiRemix.mp3"));
//            sound0.addEventListener(Event.COMPLETE, function() 
//            { 
                // 再生用 sound クラスの 生成と sampleDataEvent 取得
                sound = new Sound();
                sound.load(new URLRequest("http://lab.rettuce.com/common/src/PieceOfCake.mp3"), new SoundLoaderContext(1000, true) )                
                _channel = sound.play(0,1);
                addEventListener(Event.ENTER_FRAME, enterFrame);
//            } );
        }
        
        private function fileSetHandler(e:MouseEvent):void { _file.browse();}
        private function fileSelect(e:Event):void { _file.load(); }
        private function fileComplete(e:Event):void     //  _file.data  ByteArray
        {
            sound.removeEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
            
            dataSound = new Sound();
            dataSound.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData2);
            _channel = dataSound.play(0, int.MAX_VALUE);
        }
        
        private function onSampleData(e:SampleDataEvent):void
        {
//            _sampleData = new ByteArray();
//            var _sampleDataNumber:Number = sound0.extract(_sampleData, 8192);    //  _sampleData  ByteArray
            
            for (var c:int = 0; c < 8192; c++) 
            {
                var rad:Number = Number(c+e.position)/Math.PI/ 8;
                var amp:Number = Math.sin(rad) / 4;  // -1 から 1 の間の値なら OK
                e.data.writeFloat(amp);  // 左チャネルの音
                e.data.writeFloat(amp);  // 右チャネルの音
            }
        }
        
        private function onSampleData2(e:SampleDataEvent):void
        {
            _sampleData = new ByteArray();
            _sampleData = _file.data;
            
            var l:Number, r:Number;
            _sampleData.position = 0;
            for (var c:int = 0; c < 8192; c++) 
            {
                l = _sampleData.readFloat();
                e.data.writeFloat(l);  // 左チャネルの音
                r = _sampleData.readFloat();
                e.data.writeFloat(r);  // 右チャネルの音
            }
        }
        
        private function enterFrame(e:Event):void
        {
            var soundTForm:SoundTransform = new SoundTransform();
            soundTForm.pan = (mouseX - stage.stageWidth / 2) / (stage.stageWidth / 2);
            soundTForm.volume = mouseY / stage.stageHeight;            
            _channel.soundTransform = soundTForm;
            
            SoundMixer.computeSpectrum(_byteArray, false, 0);
            var i:int;
            var l:Number, r:Number;
            var _barL:Shape, _barR:Shape;
            for (i = 0; i < CHANNEL_LENGTH; i++) 
            {
                _byteArray.position = i * 4;
                l = _byteArray.readFloat();
                _byteArray.position = i * 4 + 1024;
                r = _byteArray.readFloat();
                _barL = _barArray[i];
                _barR = _barArray[i+256];
                _barL.height =  300 * l;
                _barR.height = 300 * r;
            }
        }
        
    }
}