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

ViewSoundWaveLR_2nd_2

↓前回のViewSoundWaveLR_2ndを
http://wonderfl.net/c/uYmx
ステッパーで刻み秒数を変更出来るようにしてみた。

コンポーネントのテストで作ったけどバグってるねステッパー…
maximumとminimumの挙動がおかしい…
それとも俺の使い方が悪い?
FlashProと同じ感じにして欲しいな。
Get Adobe Flash player
by snowsunny 10 Aug 2011
/**
 * Copyright snowsunny ( http://wonderfl.net/user/snowsunny )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/kB4R
 */

package
{
    import flash.display.AVM1Movie;
    import flash.media.SoundChannel;
    import flash.events.Event;
    import flash.display.Sprite;
    import flash.geom.ColorTransform;
    import flash.media.Sound;
    import flash.utils.ByteArray;
    import flash.net.URLRequest;
    import com.bit101.components.NumericStepper;
    public class ViewSoundWaveLR_2nd_2 extends Sprite
    {
        public function ViewSoundWaveLR_2nd_2()
        {
            //必要データ作成&設定&イベント登録---------------------------------------------↓
            //内部系データ------------------------------------------------↓
            //~.mp3へのパス           
            var SoundPass:String = "http://sunny-experience.com/wonderfl/BGM_House.mp3";
                        
            //mp3をロードするSound
            var TargetSound:Sound = new Sound();
            TargetSound.addEventListener(Event.COMPLETE, COMP_SoundLoad);
            TargetSound.load(new URLRequest(SoundPass));
            //TagetSoundのSoundChannel
            var TSC:SoundChannel;
            
            //TargetSoundから抽出した生の音データを格納するByteArray
            var SoundArray:ByteArray = new ByteArray();
            
            //波形の刻み:x(sec) * 8(左右の音データ一つ分) * 44100(Hz)
            var WAVE_STEP:int = Math.round(0.05 * 8 * 44100);
            //刻まれた波形の番号(最初は0)
            var StepNum:int = -1;

            //波形の高さ(最大値):x(px) / 2(±補正用計算)
            var WAVE_HEIGHT:Number = 128 / 2;
            
            //左右の波形データを保存するArray
            var LineData_L:Array = [], LineData_R:Array = [];
            //内部系データ------------------------------------------------↑
            
            //描画系データ------------------------------------------------↓
            //左音源の波形生成用Sprite
            var LineSpriteL:Sprite = new Sprite();
            LineSpriteL.x = 0;
            LineSpriteL.y = stage.stageHeight / 4;
            LineSpriteL.graphics.lineStyle(1, 0x6666cc);
            addChild(LineSpriteL);
            
            //右音源の波形生成用Sprite
            var LineSpriteR:Sprite = new Sprite();
            LineSpriteR.x = 0;
            LineSpriteR.y = stage.stageHeight - stage.stageHeight / 4;
            LineSpriteR.graphics.lineStyle(1, 0xcc6666);
            addChild(LineSpriteR);
            
            //PlayLine用Sprite
            var PlayLine:Sprite = new Sprite();
            PlayLine.graphics.lineStyle(3, 0xaaaaaa, 0.5);
            PlayLine.graphics.lineTo(0, 0);
            PlayLine.graphics.lineTo(0, stage.stageHeight);
            addChild(PlayLine);
            
            //EffectSpriteL,R
            var EffectColor:ColorTransform = new ColorTransform();
            var EffectSpriteL:Sprite = new Sprite();
            EffectSpriteL.x = stage.stageWidth / 4;
            EffectSpriteL.y = stage.stageHeight / 2;
            EffectSpriteL.graphics.beginFill(0x888888, 0.3);
            EffectSpriteL.graphics.drawCircle(0, 0, stage.stageHeight/2);
            EffectSpriteL.graphics.endFill();
            EffectSpriteL.scaleX = 0;
            EffectSpriteL.scaleY = 0;
            addChild(EffectSpriteL);
            
            var EffectSpriteR:Sprite = new Sprite();
            EffectSpriteR.x = stage.stageWidth - stage.stageWidth / 4;
            EffectSpriteR.y = stage.stageHeight / 2;
            EffectSpriteR.graphics.beginFill(0x888888, 0.3);
            EffectSpriteR.graphics.drawCircle(0, 0, stage.stageHeight/2);
            EffectSpriteR.graphics.endFill();
            EffectSpriteR.scaleX = 0;
            EffectSpriteR.scaleY = 0;
            addChild(EffectSpriteR);            
            //描画系データ------------------------------------------------↑
            
            //コンポーネント設定-------------------------------------------↓
            var NS:NumericStepper = new NumericStepper(this, 0, 0);
            NS.labelPrecision = 2;
            NS.maximum = 1 + 0.01;
            NS.minimum = 0;
            NS.step = 0.01;
            NS.value = 0.05;
            NS.addEventListener(Event.CHANGE, CHANGE_NS);
            
            addChild(NS);
            //コンポーネント設定-------------------------------------------↑         
            //必要データ作成&設定&イベント登録---------------------------------------------↑
            
            //Soundのロードが終わった後、データを抽出・ラインデータ作成・サウンド終了後のイベント登録・Event.ENTER_FRAME登録
            function COMP_SoundLoad(e:Event):void
            {
                //TargetSoundから秒数*44100(Hz)の音データを抽出、SoundArrayに格納
                TargetSound.extract(SoundArray, TargetSound.length/1000 * 44100);
                
                CreateLineData();
                
                TSC = TargetSound.play(0);
                TSC.addEventListener(Event.SOUND_COMPLETE, COMP_SoundPlay);
                    
                addEventListener(Event.ENTER_FRAME, CheckWaveEvent);
            }
            
            //サウンドが終了したら呼び出される関数
            function COMP_SoundPlay(e:Event):void
            {
                //StepNumを初期化
                StepNum = -1;
                
                //TargetSoundをループ再生
                TSC = TargetSound.play(0);
                TSC.addEventListener(Event.SOUND_COMPLETE, COMP_SoundPlay);
            }
            
            //DrawLineに送るラインデータを作成する関数
            function CreateLineData():void
            {
                for(var i:Number = 0; i < SoundArray.length; i += WAVE_STEP)
                {
                    SoundArray.position = i;
                    
                    //SoundArrayから左右の音データをreadFloatを使って4Byteずつ取得
                    LineData_L.push(SoundArray.readFloat() * WAVE_HEIGHT);
                    LineData_R.push(SoundArray.readFloat() * WAVE_HEIGHT);
                }
                //最後の音データを挿入
                SoundArray.position = SoundArray.length - 8;
                LineData_L.push(SoundArray.readFloat() * WAVE_HEIGHT);
                LineData_R.push(SoundArray.readFloat() * WAVE_HEIGHT);
                
                //DrawLineに左右のLineDataと、ステージの横幅ぴったりになる様な値を渡す
                DrawLine(LineData_L, LineData_R, stage.stageWidth / (SoundArray.length/WAVE_STEP));
            }
            
            //引数で受け取ったデータを使ってラインを描く関数
            function DrawLine(LD:Array, RD:Array, X_STEP:Number):void
            {
                //ラインを描くX,Y用変数
                var MoveX:Number = 0, MoveY:Number = 0;
                
                //受け取ったデータの数だけラインを描く
                for (var i:int = 0; i < LD.length; i++)
                {
                    MoveY = LD[i];
                    LineSpriteL.graphics.lineTo(MoveX, MoveY);
                    MoveY = RD[i];
                    LineSpriteR.graphics.lineTo(MoveX, MoveY);
                    MoveX += X_STEP;
                }
            }
            
            //ステッパー値でWAVE_STEPを変更、ラインデータ作成・描画
            function CHANGE_NS(e:Event):void
            {
                //色々初期化
                LineData_L = [], LineData_R = [];                   
                LineSpriteL.graphics.clear();
                LineSpriteL.graphics.lineStyle(1, 0x6666cc);
                LineSpriteR.graphics.clear();
                LineSpriteR.graphics.lineStyle(1, 0xcc6666);
                WAVE_STEP = Math.round(NS.value * 8 * 44100);
                StepNum = -1;
                
                //ラインデータ作成・描画
                CreateLineData();
            }
            
            //PlayLine更新とWAVE_STEPで刻んだ秒毎にEffectSpriteL,Rを更新する関数
            function CheckWaveEvent(e:Event):void
            {
                //PlayLineを再生時間に合わせて移動
                PlayLine.x = (stage.stageWidth/TargetSound.length) * TSC.position;
                
                //更新用の値を取得
                var mem:int = int(TSC.position / ((WAVE_STEP/8/44100)*1000));
                if(StepNum < mem)
                {
                    //波の刻み番号を更新
                    StepNum = mem;
                    
                    //EffectSpriteL,Rの色を変更(Lは0~360、Rは360~0に色相を変更)
                    var ECH:Number = (360/TargetSound.length) * TSC.position;
                    EffectColor.color = ChangeHSVtoRGB(ECH);
                    EffectSpriteL.transform.colorTransform = EffectColor;
                    EffectColor.color = ChangeHSVtoRGB(360-ECH);
                    EffectSpriteR.transform.colorTransform = EffectColor;
                    //EffectSpriteL,Rの大きさをLineDataの配列から取得(0~1)・設定
                    EffectSpriteL.scaleX = Math.abs(LineData_L[StepNum] / WAVE_HEIGHT);
                    EffectSpriteL.scaleY = Math.abs(LineData_L[StepNum] / WAVE_HEIGHT);
                    EffectSpriteR.scaleX = Math.abs(LineData_R[StepNum] / WAVE_HEIGHT);
                    EffectSpriteR.scaleY = Math.abs(LineData_R[StepNum] / WAVE_HEIGHT);
                }
            }
            
            //HSVからRGBに変換する関数
            function ChangeHSVtoRGB(H:Number, S:Number=1, V:Number=1):uint
            {
                //変換したRGBを入れる変数を作成
                var RGB:uint;
                
                //Sが0の時、Hは不必要となるのでVのみでRGBを設定する
                if(S == 0)
                {
                    //RGBにビットをシフトしながら値を格納
                    RGB = V * 255 << 16 | V * 255 << 8 | V * 255;
                }
                else
                {
                    //変換に必要な変数を作成・設定
                    var Hi:Number = Math.floor(H / 60) % 6;
                    var f:Number = (H / 60 - Hi);
                    var p:Number = V * (1 - S);
                    var q:Number = V * (1 - f * S);
                    var t:Number = V * (1 - (1 - f) * S);
                    
                    //HiによってRGBに格納する値を変更
                    //↓
                    //RGBにビットをシフトしながら値を格納
                    switch(Hi)
                    {
                        case 0:
                            RGB = V * 255 << 16 | t * 255 << 8 | p * 255 ;
                            break;
                        case 1:
                            RGB = q * 255 << 16 | V * 255 << 8 | p * 255 ;
                            break;
                        case 2:
                            RGB = p * 255 << 16 | V * 255 << 8 | t * 255 ;
                            break;
                        case 3:
                            RGB = p * 255 << 16 | q * 255 << 8 | V * 255 ;
                            break;
                        case 4:
                            RGB = t * 255 << 16 | p * 255 << 8 | V * 255 ;
                            break;
                        case 5:
                            RGB = V * 255 << 16 | p * 255 << 8 | q * 255 ;
                            break;
                    }
                }
                return RGB;
            }
        }
    }
}