package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.GradientType; import flash.display.Shape; import flash.display.Sprite; import flash.display.StageQuality; import flash.events.Event; import flash.geom.ColorTransform; import flash.geom.Matrix; import flash.geom.Point; import flash.media.Sound; import flash.net.URLRequest; import flash.util.ByteArray; import flash.util.trace; [SWF( backgroundColor='0', frameRate='50', width='512', height='512')] public class SoundRadar extends Sprite { static private const ANGULAR_VELOCITY: Number = .006; static private const IDENTITY: Matrix = new Matrix(); static private const ORIGIN: Point = new Point(); private var sound: Sound; private var bytes: ByteArray; private var line: Shape; private var radar: BitmapData; private var matrix: Matrix; private var colors: Array; private var rainbow: Array; private var angle: Number = 0; private var output: BitmapData; private var damp: ColorTransform; private var frame: int = 0; public function SoundRadar() { sound = new Sound(); sound.load( new URLRequest( 'song.mp3' ) ); sound.play(); bytes = new ByteArray(); colors = new Array(); rainbow = createRainbowGradientArray(); line = new Shape(); matrix = new Matrix(); matrix.createGradientBox( 512, 512, 0, 0, 0 ); radar = new BitmapData( 512, 512, true, 0 ); output = new BitmapData( 512, 512, false, 0 ); addChild( new Bitmap( output ) ); damp = new ColorTransform( 1, 1, 1, 1, -1, -1, -1, 0 ); stage.addEventListener( Event.ENTER_FRAME, onEnterFrame ); } private function onEnterFrame( event: Event ): void { angle -= ANGULAR_VELOCITY; line.graphics.lineStyle( 1 ); line.graphics.lineGradientStyle( GradientType.RADIAL, [ 0xff, 0 ], [ 100, 100 ], [ 0, 0xff ], matrix ); line.graphics.moveTo( 256 + Math.cos( angle ) * 8, 256 + Math.sin( angle ) * 8 ); line.graphics.lineTo( 256 + Math.cos( angle ) * 248, 256 + Math.sin( angle ) * 248 ); radar.fillRect( radar.rectangle, 0 ); radar.draw( line, IDENTITY, null, null, null, true ); line.graphics.clear(); SoundMixer.computeSpectrum( bytes, true, 0 ); var value: Number; var color: int; for( var i: int = 1 ; i < 256 ; i++ ) { value = Math.sqrt( bytes.readFloat() * 2 ); if( value < .1 ) value = .1; if( value > 1 ) value = 1; color = rainbow[ i ]; colors[256-i] = ( ( color >> 16 & 0xff ) * value ) << 16 | ( ( color >> 8 & 0xff ) * value ) << 8 | ( ( color & 0xff ) * value ); } radar.paletteMap( radar, radar.rectangle, ORIGIN, null, null, colors ); output.copyPixels( radar, radar.rectangle, ORIGIN ); if( ( frame & 7 ) == 0 ) output.colorTransform( output.rectangle, damp ); frame++; } private function createRainbowGradientArray(): Array { var gradient: Array = new Array(); var shape: Shape = new Shape(); var bmp: BitmapData = new BitmapData( 256, 1, true, 0 ); var colors: Array = [ 0, 0xff0000, 0xffff00, 0x00ff00, 0x00ffff ]; var alphas: Array = [ 100, 100, 100, 100, 100 ]; var ratios: Array = [ 0, 16, 128, 192, 255 ]; var matrix: Matrix = new Matrix(); matrix.createGradientBox( 256, 1, 0, 0, 0 ); shape.graphics.beginGradientFill( 'linear', colors, alphas, ratios, matrix ); shape.graphics.drawRect( 0, 0, 256, 1 ); shape.graphics.endFill(); bmp.draw( shape ); for( var i: int = 0 ; i < 256 ; i++ ) { gradient[i] = bmp.getPixel32( i, 0 ); } return gradient; } } }