Compute Spectrum Band Width

by aobyrne
used Hype framework's SoundAnalyzer's offset formula see: https://github.com/hype/hype/blob/master/src/hype/framework/sound/SoundAnalyzer.as
♥0 | Line 262 | Modified 2012-05-10 21:25:38 | MIT License
play

ActionScript3 source code

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

package  
{
    import com.bit101.components.HBox;
    import com.bit101.components.Label;
    import com.bit101.components.PushButton;
    import com.bit101.components.VBox;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.media.Sound;
    import flash.media.SoundLoaderContext;
    import flash.media.SoundMixer;
    import flash.net.URLRequest;
    import flash.utils.ByteArray;
    

    public class ComputeSpectrumBandWidth extends Sprite 
    {
        private const A:Number =  1.669;
        private const B:Number = -0.453;
        private var _offsetList:Vector.<Number>;
        
        private var soundByteArray:ByteArray;
        private var indexes:Array;
        private var amplitudes1:Array;
        private var charts1:Vector.<SCLineChart>;
        private var charts2:Vector.<SCLineChart>;
        private var charts3:Vector.<SCLineChart>;
        private var charts4:Vector.<SCLineChart>;
        private var charts5:Vector.<SCLineChart>;
        private var charts6:Vector.<SCLineChart>;
        private var amplitudes2:Array;
        private var amplitudes3:Array;
        private var amplitudes4:Array;
        private var amplitudes5:Array;
        
        public function ComputeSpectrumBandWidth() 
        {
            var sizeH:Number;
            _offsetList = new Vector.<Number>();
            
            for (i=0; i<256; ++i) {
                _offsetList[i] = 1 / (A + B * (Math.log(i) / Math.LN10));
            }    
            var sCLineChart1:SCLineChart;
            var sCLineChart2:SCLineChart;
            var sCLineChart3:SCLineChart;
            var sCLineChart4:SCLineChart;
            var sCLineChart5:SCLineChart;
            var sCLineChart6:SCLineChart;
            amplitudes1 = [];
            amplitudes2 = [];
            amplitudes3 = [];
            amplitudes4 = [];
            amplitudes5 = [];
            soundByteArray = new ByteArray();
            var binary:Number = 2;
            var initial:Number = 1;
            indexes = [];
            for (var i:int = 0; i < 8; i++) 
            {
                indexes[indexes.length] = initial;
                initial *= binary;
                trace( "initial : " + initial );
            }
            indexes[indexes.length] = initial;
            
            indexes = [1, 3, 8, 17, 32, 64, 128, 256];
            var il:uint = indexes.length;
            
            var vBox:VBox = new VBox(this, 0, 0);
            var chartsArray1:Array = [];
            var chartsArray2:Array = [];
            var chartsArray3:Array = [];
            var chartsArray4:Array = [];
            var chartsArray5:Array = [];
            var chartsArray6:Array = [];
            var hBox:HBox;
            var averageSize:Number = 3;
            var columnsAmount:Number = 6;
            sizeH = 465/ columnsAmount;
            hBox = new HBox(vBox, 0, 0);
            hBox.spacing = 1;
            //hBox.spacing = sizeH;
            addlabel(hBox,'no av. ',sizeH);
            addlabel(hBox, 'no av. soft('+averageSize+') ' ,sizeH);
            addlabel(hBox,'av. soft ('+averageSize+') as',sizeH);
            addlabel(hBox,'av. soft('+averageSize+')',sizeH);
            addlabel(hBox, 'av. offset' ,sizeH);
            addlabel(hBox,'av. soft('+2*averageSize+')',sizeH);
            for (var j:int = 0; j < il; j++) 
            {
                hBox = new HBox(null, 0, 0);
                vBox.addChildAt(hBox, vBox.numChildren);
                hBox.spacing = 1;
                trace( "j : " + j );
                amplitudes1[j] = new AveragedArray(averageSize);
                amplitudes2[j] = new AveragedArray(averageSize);
                amplitudes3[j] = new AveragedArray(0);
                amplitudes4[j] = new AveragedArray(averageSize);
                amplitudes5[j] = new AveragedArray(2*averageSize);
                
                sCLineChart4 = getLineChart(sizeH,hBox,true);
                sCLineChart5 = getLineChart(sizeH,hBox,true);
                sCLineChart1 = getLineChart(sizeH,hBox,false);
                sCLineChart2 = getLineChart(sizeH,hBox,true);
                sCLineChart3 = getLineChart(sizeH,hBox,true);
                sCLineChart6 = getLineChart(sizeH,hBox,true);
                
                chartsArray1[j] = sCLineChart1;
                chartsArray2[j] = sCLineChart2;
                chartsArray3[j] = sCLineChart3;
                chartsArray4[j] = sCLineChart4;
                chartsArray5[j] = sCLineChart5;
                chartsArray6[j] = sCLineChart6;
                
                
                
            }
            charts1 = Vector.<SCLineChart>(chartsArray1);
            charts2 = Vector.<SCLineChart>(chartsArray2);
            charts3 = Vector.<SCLineChart>(chartsArray3);
            charts4 = Vector.<SCLineChart>(chartsArray4);
            charts5 = Vector.<SCLineChart>(chartsArray5);
            charts6 = Vector.<SCLineChart>(chartsArray6);
            
            addEventListener(Event.ENTER_FRAME, just_once);
        }
        
        private function just_once(e:Event):void 
        {
            removeEventListener(Event.ENTER_FRAME, just_once);
            initSound();
            
        }
        

        private function initSound() :void {
        var soundPath:String = "http://www.takasumi-nagai.com/soundfiles/sound001.mp3";
        //soundPath = 'assets/realentada.mp3';
        var sound:Sound = new Sound();
        sound.addEventListener(Event.COMPLETE, function(e :Event) :void {
            var sound:Sound = e.target as Sound;
            sound.play(0,4);
            goOn();
        }, false, 0, true);
        sound.load(new URLRequest(soundPath), new SoundLoaderContext(10, true));
    }
    
    private function goOn():void 
    {
        addEventListener(Event.ENTER_FRAME, loop);
    }
    
    private function loop(e:Event):void 
    {
        computeSpectrum()
    }
    
    private function computeSpectrum():void 
    {
        var band:AveragedArray;
        var band2:AveragedArray;
        var band4:AveragedArray;
        var band5:AveragedArray;
        var fftMode:Boolean = true;
        var stretchFactor:int = 0;
        SoundMixer.computeSpectrum(soundByteArray, fftMode, stretchFactor);
        var idxs:Array = indexes;
        var il:uint = idxs.length;
        for (var i:int = 0; i < il-1; i++) 
        {
            var imin:int = idxs[i];
            var baPosition:Number = imin * 4;
            soundByteArray.position = baPosition;
            var imax:int = idxs[i + 1];
            var amplitudeAveraged:Number = 0;
            var amplitudeWithOffset:Number = 0;
            for (var j:int = imin; j < imax; j++) 
            {
                var amp:Number = soundByteArray.readFloat();
                amplitudeAveraged += amp;
                amplitudeWithOffset += amp*_offsetList[j];
            }
            var idelta:int = imax - imin;
            amplitudeAveraged /= idelta;
            amplitudeWithOffset /= idelta;
            
            band = amplitudes1[i];
            band.setValue(amplitudeAveraged);
            
            band2 = amplitudes2[i];
            band2.setValue(amplitudeWithOffset);
            
            
            band4 = amplitudes4[i];
            band4.setValue(amp);
            
            band5 = amplitudes5[i];
            band5.setValue(amplitudeAveraged);
            
            charts1[i].addToArray(band.getLastVAlue());
            charts2[i].addToArray(band.getLastVAlue());
            charts3[i].addToArray(band2.getLastVAlue());
            //last value;
            charts4[i].addToArray(amp);
            charts5[i].addToArray(band4.getLastVAlue());
            charts6[i].addToArray(band5.getLastVAlue());
        }
        
    }
    
    private function addlabel(hBox:HBox,label:String,size:Number):void 
    {
        var labelc:Label = new Label(hBox, 0, 0, label);
        labelc.autoSize = false;
        labelc.setSize(size, labelc.height);
    }
    
    private function getLineChart(sizeH:Number, hBox:HBox, isAutoScaled:Boolean):SCLineChart 
    {
        
        var sCLineChart2:SCLineChart=new SCLineChart(hBox, 0, 0, []);
        sCLineChart2.setSize(sizeH, 40);
        if (isAutoScaled)
        {
            sCLineChart2.autoScale = false;
            sCLineChart2.minimum = 0;
            sCLineChart2.maximum = 1;
        }
        return sCLineChart2;
    }

        
    }

}
import com.bit101.charts.LineChart;
import flash.display.DisplayObjectContainer;
class SCLineChart extends LineChart
{
    private var array1:Array;
        public function SCLineChart(parent:DisplayObjectContainer=null, xpos:Number=0, ypos:Number=0, data:Array=null)
        {
            super(parent, xpos, ypos, data);
            array1 = [];
        }
        public function addToArray(value:Number,index:int=-1):void 
        {
            if (index==-1) 
            {
                array1[array1.length]=value
            }
            else
            {
                array1[index] = value;
                
            }
            if (array1.length>100) 
            {
                array1.shift();
            }
            data = array1;
            
        }
        
}
/**
 * an array that when one asks for its last value , returns de average of the last averageAmount elements
 */
final class AveragedArray 
{
    
    private var averageAmount:int;
    private var array:Array;
    public function AveragedArray(averageAmount:int,defualtValue:Number=0) 
    {
        array = [];
        this.averageAmount = averageAmount;
        for (var i:int = 0; i < averageAmount; i++) 
        {
            array[i] = defualtValue;
        }
    }
    public function getValueAt(ii:int):Number 
    {
        var average:Number = 0;
        //ii += averageAmount;
        for (var i:int = ii-averageAmount; i <ii ; i++) 
        {
            average += array[i];
        }
        return average / averageAmount;
    }
    public function getLastVAlue():Number 
    {
        return getValueAt(array.length - 1);
    }
    public function toString():String 
    {
        return String(array);
    }
    
    public function setValue(amplitude:Number):void 
    {
        array[array.length] = amplitude;
    }
    
}