/** * * *----------------------------* * | *** as3.0声音波形系列 *** | * *----------------------------* * * 编辑修改收录:fengzi(疯子、wu341、wgq341) * * 不会写代码,我是代码搬运工。 * * 联系方式:QQ(493712833)。 * * 随 笔: https://www.cnblogs.com/fengziwu/ * * 版权协议:请自觉遵守LGPL协议,欢迎修改、复制、转载、传播给更多需要的人。 * 免责声明:任何因使用此软件导致的纠纷与软件/程序开发者无关。 * 日 期: 2021.09.05 * * * ------------------ Example -------------------- * * var sp:Spectrum=new Spectrum() addChild(sp) * @***欢迎添加API*** **/ package { import flash.display.Sprite; import flash.events.Event; import flash.filters.BlurFilter; import flash.display.Bitmap; import flash.geom.Matrix; import flash.display.BitmapData; import flash.geom.ColorTransform; import flash.geom.Point; import flash.utils.ByteArray; import flash.media.SoundMixer; import flash.display.GradientType; import flash.display.BlendMode; public dynamic class Spectrum extends Sprite {; private var blur:BlurFilter; private var bitmap:Bitmap; private var matrix:Matrix; private var thisH:int; private var bitmapData:BitmapData; private var colorTransform:ColorTransform; private var thisW:int; private var _bitmapData:BitmapData; private var _matrix:Matrix; private var sprite:Sprite; private var index:int =7; private var fftmode:Boolean; private var i:int; private var num:Number; private var n:Number; private var k:int; private var a:uint; private var columnTotal:int; private var columnW:Number; private var float:Number = 0; private var byteArray:ByteArray; private var columnH:Array; private var slowVal:Array; private var floatDot:Array; private var byte:Array; private var vR:Number;//virtical radius private var hR:Number;//horizontal radius private var h:Number = 0; private var s:Number = 1; private var v:Number = 1; private var numArr:Array = []; private var pos:Number = 0; private var count:int = 0; public function Spectrum(w:Number=750,h:Number=400,isBack:Boolean=true) { thisW = w; thisH = h; init(); if (isBack) { this.blendMode = BlendMode.SCREEN; } } private function init() { sprite=new Sprite(); byteArray=new ByteArray(); for (var i:int= 0; i < 256; ++ i) { numArr[i] = 0; } columnTotal =Math.floor(thisW/2/12); if (columnTotal >256) { columnTotal = 256; } columnW = thisW / 2 / columnTotal; byte = arrayPush(512); slowVal = arrayPush(512); floatDot = arrayPush(512); columnH = arrayPush(512); bitmapData = new BitmapData(thisW,thisH,false,0); _bitmapData = new BitmapData(thisW,thisH,false,0); bitmap = new Bitmap(bitmapData); addChild(bitmap); blur = new BlurFilter(0,0,1); colorTransform = new ColorTransform(0.91,0.92,0.95); matrix = new Matrix(); matrix.a = (thisW + thisW / 40) / thisW; matrix.d = (thisH + thisH / 80) / thisH; matrix.tx = - thisW / 80; matrix.ty = - thisH / 240; _matrix = new Matrix(1,0,0,1,(thisW - thisW * 0.7) / 2,(thisH - thisH * 0.7) / 2); _matrix.scale(0.7, 0.7); addEventListener(Event.ENTER_FRAME,enterframeHandler); } private function enterframeHandler(e:Event):void { SoundMixer.computeSpectrum(byteArray,fftmode); drawSprite(); bitmapData.lock(); _bitmapData = bitmapData.clone(); bitmapData.draw(_bitmapData, matrix, colorTransform, null, null, true); bitmapData.draw(sprite, _matrix, null, null, null, true); bitmapData.applyFilter(bitmapData, bitmapData.rect, new Point(), blur); bitmapData.unlock(); if (count %500 == 0) { if (++index > 7) { count = 0; index = 0; } } count++; } private function drawSprite():void { sprite.graphics.clear(); if (index==0) { pos = 0; h = 0; k=0 bytes(); fftmode = true; var colors:Array = new Array(0x00ff00,0x00ffff,0xffff00,0xff00ff); var alphas:Array = new Array(1,1,1,1); var ratios:Array = new Array(0,80,160,255); var matrix:Matrix = new Matrix(); matrix.createGradientBox(thisW, thisH, 0, 0, 0); for (i=0; i < columnTotal; i++) { slowVal[i] *= 1.1; floatDot[i] -= slowVal[i]; if (floatDot[i] < byte[i]) { slowVal[i] = thisH * 0.004; floatDot[i] = byte[i]; } columnH[i]-=(slowVal[i] + 2); if (columnH[i] < byte[i]) { columnH[i] = byte[i]; } sprite.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix); sprite.graphics.drawRect(thisW/2+columnW* i, thisH, columnW- 4, -columnH[i]); sprite.graphics.beginFill(0xffffff); sprite.graphics.drawRect(thisW/2+columnW* i, thisH - floatDot[i] -2, columnW - 4, 2); } for (i=0; i<columnTotal; i++) { slowVal[i+256]*=1.1; floatDot[i+256]-=slowVal[i+256]; if (floatDot[i + 256] < byte[i + 256]) { slowVal[i + 256] = thisH * 0.004; floatDot[i + 256] = byte[i + 256]; } columnH[i+256]-=(slowVal[i+256] + 2); if (columnH[i + 256] < byte[i + 256]) { columnH[i + 256] = byte[i + 256]; } sprite.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix); sprite.graphics.drawRect(thisW/2-columnW* i-columnW, thisH, columnW- 4, -columnH[i+256]); sprite.graphics.beginFill(0xffffff); sprite.graphics.drawRect(thisW/2-columnW* i-columnW, thisH - floatDot[i+256] -2, columnW - 4, 2); } } if (index==1) { pos = 0; k=0 fftmode = true; var _c:uint = HSVtoRGB(h,s,v); h += 1; for (i= 0; i < 512; i++) { num = byteArray.readFloat() + 0.1; var a:uint = i; if (i <256) { a += 256; } var n:Number = Math.ceil((thisH * 0.7/2)*(num+0.5)); var xPos:Number = -Math.sin(i/256*Math.PI)*n*num*4 + thisW/2; var yPos:Number = Math.cos(a/256*Math.PI)*n*num*2 + thisH*0.8; if (i%8==0) { sprite.graphics.lineStyle(2,_c); sprite.graphics.drawCircle(xPos, yPos,14*num); } } } /***********************/ if (index==2) { pos = 0; h = 0; k=0 fftmode = true; sprite.graphics.lineStyle(0,0xccffff); sprite.graphics.beginFill(0xccffff); sprite.graphics.moveTo(thisW/2,thisH); n = thisW / 2 / 256; for (i=0; i <256; i++) { num = byteArray.readFloat() * thisH / 1.4; sprite.graphics.lineTo(thisW/2+i*n, thisH - num); } sprite.graphics.lineTo(thisW,thisH); sprite.graphics.lineStyle(0,0xffcc00); sprite.graphics.beginFill(0xffcc00); sprite.graphics.moveTo(thisW/2, thisH); for (i =256; i > 0; i--) { num= (byteArray.readFloat() *thisH/1.4); sprite.graphics.lineTo(i*n,thisH - num); } sprite.graphics.lineTo(0,thisH); } if (index==3) { k=0 fftmode = false; var _color:uint = HSVtoRGB(h,s,v); h += 1; for (i= 0; i <256; i+=4) { num = Math.abs(byteArray.readFloat() + 0.1); numArr[ i ] += (num-numArr[ i ] ) * 0.25; num = numArr[i]; sprite.graphics.drawCircle( thisW/2 + Math.sin(i * 360 / 256 * Math.PI / 180) * (30+num*thisH/4),thisH/2 + Math.cos(i * 360 / 256 * Math.PI / 180+pos) * (30+num*thisH/4), num * 30 ); } sprite.graphics.beginFill(_color, 1 ); for (i = 0; i <256; i+=4) { num = Math.abs(byteArray.readFloat() + 0.1); numArr[ i ] += (num-numArr[ i ] ) * 0.25; num = numArr[i]; sprite.graphics.drawCircle( thisW/2+ Math.sin(i * 360 /256 * Math.PI / 180) * (40+num*thisH/3),thisH/2 + Math.cos(i * 360 /256 * Math.PI / 180+pos) * (30+num*thisH/3)+thisH/8,num *10 ); } pos += 0.04; } if (index==4) { pos = 0; h = 0; k=0 fftmode = false; sprite.graphics.lineStyle(0,0xff9900,1); n = thisW / 256; sprite.graphics.moveTo(0,thisH/4); for (i=0; i <256; i++) { num = byteArray.readFloat() / 2; if (i>0) { sprite.graphics.lineTo(i*n, thisH/4 - num*thisH/4); } } sprite.graphics.lineStyle(0,0xff00ff,1); sprite.graphics.moveTo(thisW, thisH/4*3); for (i =256; i > 0; i--) { num = byteArray.readFloat() / 2; sprite.graphics.lineTo(i*n,thisH/4*3 - num*thisH/4); } } if (index==5) { pos = 0; var c:uint = HSVtoRGB(h,s,v); h += 1; fftmode = false; sprite.graphics.lineStyle(2,c,1); sprite.graphics.beginFill(c); n = thisW / 512; sprite.graphics.moveTo(0,thisH/2+thisH/8*Math.cos(k/16)); for (i=0; i <512; i++) { num = byteArray.readFloat() / 4; if (i>0) { sprite.graphics.lineTo(i*n, thisH/2 - num*thisH/4+thisH/8*Math.cos(k/16)); } } k++; } if (index==6) { pos = 0; k=0 h=0 /*var color:uint = HSVtoRGB(h,s,v); h += 1;*/ var singleW:Number = (thisW - thisW / 8) / 256; fftmode = true; sprite.graphics.moveTo(thisW/8,thisH); for (i= 0; i < 256; i++) { num = byteArray.readFloat(); sprite.graphics.lineStyle(1,0xff00ff*i); sprite.graphics.lineTo(thisW/8+ i*singleW,thisH - num *thisH/1.5); } } if (index==7) { pos = 0; k=0 k=0 fftmode = false; sprite.graphics.moveTo(0, thisH/2); //lineSprite.graphics.beginFill(0x336600); for (i= 0; i < 512; i+=4) { num = byteArray.readFloat(); a = i; if (i >=256) { a -= 256; } if (i ==256) { sprite.graphics.moveTo(0, thisH/2); } sprite.graphics.lineStyle(1, 0x00ffff*i); var _xPos:Number =a*(thisW/256)+16; var _yPos:Number = - num * thisH / 4; _xPos -= 2;// to prevent black line to the left if (i >=256) { yPos *= -1; } sprite.graphics.lineTo(_xPos, _yPos+thisH/2); } } sprite.graphics.endFill(); } private function arrayPush(value:int):Array { var array:Array = []; for (var i:int = 0; i < value; i++) { array.push(0); } return array; } private function bytes():void { for (var j:int=0; j<512; j++) { byte[j] = thisH * 0.7 * byteArray.readFloat(); } } private function HSVtoRGB(h:Number, s:Number, v:Number):uint { var r:Number = 0,g:Number = 0,b:Number = 0; var i:Number,x:Number,y:Number,z:Number; if (s < 0) { s = 0; } if (s > 1) { s = 1; } if (v < 0) { v = 0; } if (v > 1) { v = 1; } h = h % 360; if (h < 0) { h += 360; } h /= 60; i = h >> 0; x = v * (1 - s); y = v * (1 - s * (h - i)); z = v * (1 - s * (1 - h + i)); switch (i) { case 0 : r = v; g = z; b = x; break; case 1 : r = y; g = v; b = x; break; case 2 : r = x; g = v; b = z; break; case 3 : r = x; g = y; b = v; break; case 4 : r = z; g = x; b = v; break; case 5 : r = v; g = x; b = y; break; } var c:uint; c = (r * 255 >> 0) << 16 | (g * 255 >> 0) << 8 | (b * 255 >> 0); return c; } } }