/**
*
* *----------------------------*
* | *** 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;
}
}
}