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







}
}

  

posted on 2021-10-10 20:26  疯子_wu  阅读(83)  评论(0编辑  收藏  举报