本教程是向大家介绍Flash制作音乐频谱,教程比较基础,转发过来,希望大家喜欢!花了3天做的音乐频谱的效果,截图的效果:
包括了5个类:
MusicControl类,不多说了,用来控制音乐的,包括音乐的载入和播放时的控制等。
ID3Control类,用来提取音乐文件的相关信息的类,循环的显示各种信息,提取的中文显示乱码,这里用一个函数进行更正即可:
复制代码
代码如下:function EncodeUtf8(str:String):String {
var oriByteArr:ByteArray = new ByteArray();
oriByteArr.writeUTFBytes(str);
var tempByteArr:ByteArray = new ByteArray();
for (var i = 0; i
if (oriByteArr == 194) {
tempByteArr.writeByte(oriByteArr[i+1]);
i++;
} else if (oriByteArr == 195) {
tempByteArr.writeByte(oriByteArr[i+1] + 64);
i++;
} else {
tempByteArr.writeByte(oriByteArr);
}
}
tempByteArr.position = 0;
return tempByteArr.readMultiByte(tempByteArr.bytesAvailable,"chinese");
}
Spectrum类,管理和显示频谱的类,从MusicControl类里取出频谱的信息,注意MusicControl类里的
SoundMixer.computeSpectrum(_spectrumArray,true);
里第二个参数 true 表示取出的是频谱,而 false 表示取出的是波形。
/*
类功能:显示频谱。
*/
package net.cdipan.spectrum{
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.net.navigateToURL;
import flash.net.URLRequest;
public class Spectrum extends Sprite {
//记录频谱的数组
private var _spectrum:Array;
//记录显示的类型
private var _type:int;
//用于显示频谱的精灵对象
private var _showSpectrum:Sprite;
//用于显示柱状频谱的精灵对象
private var _show1:Sprite;
//用于显示波浪频谱的精灵对象
private var _show2:Sprite;
//用于显示波形频谱的精灵对象
private var _show3:Sprite;
//柱形对象
private var _column:Column;
//波形对象
private var _waveform:Waveform;
public function Spectrum():void {
_spectrum = new Array(512);
_showSpectrum = new Sprite();
_showSpectrum.x = 22;
_showSpectrum.y = 18;
_show1 = new Sprite();
_show2 = new Sprite();
_show3 = new Sprite();
this.addChild(_showSpectrum);
//创建柱状频谱
createColumn(64,3,1,_show1);
createColumn(256,1,0,_show2);
//创建波形频谱
_waveform = new Waveform();
_show3.addChild(_waveform);
_showSpectrum.addChild(_show1);
}
//获取频谱数组
public function getSpectrum(byteArray:ByteArray):void {
for (var i:int=0; i<512; i++) {
_spectrum = byteArray.readFloat();
}
//将频谱数据传送给柱状和波浪的精灵实例
for (var j:int=0; j<64; j++) {
var temp1:Column = _show1.getChildByName("column_"+j.toString()) as Column;
temp1.getSpectrum((_spectrum[j*4]+_spectrum[j*4+1]+_spectrum[j*4+2]+_spectrum[j*4+3]+_spectrum[j*4+256]+_spectrum[j*4+257]+_spectrum[j*4+258]+_spectrum[j*4+259])*12.5);
}
for (var m:int=0; m<256; m++) {
var temp2:Column = _show2.getChildByName("column_"+m.toString()) as Column;
temp2.getSpectrum((_spectrum[m]+_spectrum[m+256])*50);
}
//将频谱数据传送给波形的精灵实例
_waveform.getSpectrum(_spectrum);
}
//创建柱状的精灵对象
private function createColumn(f_num:int,f_width:int,f_space:int,target:Sprite):void {
for (var i:int=0; i
_column = new Column();
_column.name = "column_"+i.toString();
_column.width = f_width;
_column.x = i*(f_width+f_space);
target.addChild(_column);
}
}
//更改样式(type 为 0 时显示柱形,为 1 时显示波浪,为 2 时显示波形)
public function changeType(type:int):void {
switch (type) {
case 0 :
if (_showSpectrum.contains(_show1)) {
_showSpectrum.removeChild(_show1);
}
if (_showSpectrum.contains(_show2)) {
_showSpectrum.removeChild(_show2);
}
if (_showSpectrum.contains(_show3)) {
_showSpectrum.removeChild(_show3);
}
_showSpectrum.addChild(_show1);
break;
case 1 :
if (_showSpectrum.contains(_show1)) {
_showSpectrum.removeChild(_show1);
}
if (_showSpectrum.contains(_show2)) {
_showSpectrum.removeChild(_show2);
}
if (_showSpectrum.contains(_show3)) {
_showSpectrum.removeChild(_show3);
}
_showSpectrum.addChild(_show2);
break;
case 2 :
if (_showSpectrum.contains(_show1)) {
_showSpectrum.removeChild(_show1);
}
if (_showSpectrum.contains(_show2)) {
_showSpectrum.removeChild(_show2);
}
if (_showSpectrum.contains(_show3)) {
_showSpectrum.removeChild(_show3);
}
_showSpectrum.addChild(_show3);
break;
}
}
}
}
Column类,条形的频谱类,在Spectrum类里柱状样式中创建了 64 个,而波浪样式中创建了 256 个。
/*
类功能:柱状的频谱。
*/
package net.cdipan.spectrum{
import flash.display.*;
import flash.geom.*;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class Column extends Sprite {
//顶部小方块颜色
private const square_color:uint = 0xffffff;
//顶部颜色
private const top_color:uint = 0xffffff;
//中间颜色
private const middle_color:uint = 0x8cdcff;
//底部颜色
private const bottom_color:uint = 0x07f7ff;
//背景精灵对象
private var BG_Sp:Sprite;
//遮罩精灵对象
private var mask_Sp:Sprite;
//小方块精灵对象
private var square_Sp:Sprite;
//记录上次的频谱的值,如果比这次的高就减一,否则将这次的设为此值
private var oldNum:Number;
//计时器对象
private var myTimer:Timer;
//记录小方块是否可以下落
private var canDrop:Boolean;
public function Column():void {
BG_Sp = new Sprite();
drawGradualRect();
addChild(BG_Sp);
mask_Sp = new Sprite();
drawMaskRect();
addChild(mask_Sp);
square_Sp = new Sprite();
drawSquareRect();
square_Sp.y = 99;
square_Sp.addEventListener(Event.ENTER_FRAME, _enterframe);
addChild(square_Sp);
//设置遮罩
BG_Sp.mask = mask_Sp;
oldNum = 0;
myTimer = new Timer(200, 1);
myTimer.addEventListener("timer", onTimer);
canDrop = false;
}
//使小方块下落
private function _enterframe(e:Event):void {
if (canDrop) {
square_Sp.y += 4;
}
if (square_Sp.y > 99) {
square_Sp.y = 99;
}
if (square_Sp.y < -1) {
square_Sp.y = -1;
}
}
//绘制渐变图形
private function drawGradualRect():void {
var fillType:String = GradientType.RADIAL;
var colors:Array = [top_color, middle_color, bottom_color];
var alphas:Array = [1, 1, 1];
var ratios:Array = [0x00, 0x7f, 0xff];
BG_Sp.graphics.beginGradientFill(fillType, colors, alphas, ratios);
BG_Sp.graphics.drawRect(0,-1,100,1);
BG_Sp.rotation = 90;
}
//绘制遮罩图形
private function drawMaskRect():void {
mask_Sp.graphics.lineStyle();
mask_Sp.graphics.beginFill(0);
mask_Sp.graphics.drawRect(0,-100,1,100);
mask_Sp.graphics.endFill();
mask_Sp.y = 100;
}
//绘制小方块
private function drawSquareRect():void {
square_Sp.graphics.lineStyle();
square_Sp.graphics.beginFill(square_color);
square_Sp.graphics.drawRect(0,0,1,1);
square_Sp.graphics.endFill();
}
//接收频谱数据
public function getSpectrum(num:Number):void {
if (oldNum > num) {
oldNum -= 7;
} else {
oldNum = num;
if (oldNum != 0) {
//调用小方块运动的函数
squareMove(oldNum);
}
}
if (oldNum<0) {
oldNum = 0;
}
mask_Sp.height = oldNum;
}
//控制小方块运动的函数
private function squareMove(num:Number):void {
if (square_Sp.y > 99 - oldNum) {
square_Sp.y = 99 - num;
canDrop = false;
myTimer.reset();
myTimer.start();
}
}
public function onTimer(e:TimerEvent):void {
canDrop = true;
}
}
}
Waveform类,波形的类,用一条线条来绘制的,加入了逐渐消失的轨迹的效果。
/*
类功能:波形。
*/
package net.cdipan.spectrum{
import flash.display.*;
import flash.filters.*;
import flash.geom.*;
public class Waveform extends Sprite {
//线条颜色
private const line_color:uint = 0x07f7ff;
//创建用来绘制线条的精灵对象
private var Line:Sprite;
//用于逐渐消失的轨迹的位图对象
private var bmpData:BitmapData;
private var bmp:Bitmap;
//滤镜的各项参数
private var colorM:ColorMatrixFilter;
private var blur:BlurFilter;
private var r:Rectangle;
private var point;
//通过数字使滤镜处理慢一步
private var num:int;
public function Waveform():void {
Line = new Sprite();
bmpData = new BitmapData(256,100,true,0);
bmp = new Bitmap(bmpData);
colorM = new ColorMatrixFilter([.98,0,0,0,0,0,.98,0,0,0,0,0,.98,0,0,0,0,0,.5,0]);
blur = new BlurFilter(7,7,BitmapFilterQuality.LOW);
r = new Rectangle(0,0,256,100);
p = new Point(0,0);
//添加显示对象
this.blendMode=BlendMode.ADD;
this.addChild(bmp);
this.addChild(Line);
}
//接收频谱数据
public function getSpectrum(array:Array):void {
if (num%2 == 0) {
var m:Number = 0;
for (var j=0; j<256; j+=2) {
m += array[j];
}
if (m != 0) {
//停止播放时不绘制图像,就只会显示一条直线
bmpData.draw(this);
}
bmpData.applyFilter(bmpData,r,p,colorM);
bmpData.applyFilter(bmpData,r,p,blur);
}
num++;
Line.graphics.clear();
Line.graphics.lineStyle(1,line_color,100);
for (var i=0; i<256; i+=2) {
var n:Number = array*50;
if (i != 0) {
Line.graphics.lineTo(i,50-n);
} else {
Line.graphics.moveTo(0,50-n);
}
}
}
}
}
var oriByteArr:ByteArray = new ByteArray();
oriByteArr.writeUTFBytes(str);
var tempByteArr:ByteArray = new ByteArray();
for (var i = 0; i
if (oriByteArr == 194) {
tempByteArr.writeByte(oriByteArr[i+1]);
i++;
} else if (oriByteArr == 195) {
tempByteArr.writeByte(oriByteArr[i+1] + 64);
i++;
} else {
tempByteArr.writeByte(oriByteArr);
}
}
tempByteArr.position = 0;
return tempByteArr.readMultiByte(tempByteArr.bytesAvailable,"chinese");
}
Spectrum类,管理和显示频谱的类,从MusicControl类里取出频谱的信息,注意MusicControl类里的
SoundMixer.computeSpectrum(_spectrumArray,true);
里第二个参数 true 表示取出的是频谱,而 false 表示取出的是波形。
/*
类功能:显示频谱。
*/
package net.cdipan.spectrum{
import flash.display.Sprite;
import flash.utils.ByteArray;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.net.navigateToURL;
import flash.net.URLRequest;
public class Spectrum extends Sprite {
//记录频谱的数组
private var _spectrum:Array;
//记录显示的类型
private var _type:int;
//用于显示频谱的精灵对象
private var _showSpectrum:Sprite;
//用于显示柱状频谱的精灵对象
private var _show1:Sprite;
//用于显示波浪频谱的精灵对象
private var _show2:Sprite;
//用于显示波形频谱的精灵对象
private var _show3:Sprite;
//柱形对象
private var _column:Column;
//波形对象
private var _waveform:Waveform;
public function Spectrum():void {
_spectrum = new Array(512);
_showSpectrum = new Sprite();
_showSpectrum.x = 22;
_showSpectrum.y = 18;
_show1 = new Sprite();
_show2 = new Sprite();
_show3 = new Sprite();
this.addChild(_showSpectrum);
//创建柱状频谱
createColumn(64,3,1,_show1);
createColumn(256,1,0,_show2);
//创建波形频谱
_waveform = new Waveform();
_show3.addChild(_waveform);
_showSpectrum.addChild(_show1);
}
//获取频谱数组
public function getSpectrum(byteArray:ByteArray):void {
for (var i:int=0; i<512; i++) {
_spectrum = byteArray.readFloat();
}
//将频谱数据传送给柱状和波浪的精灵实例
for (var j:int=0; j<64; j++) {
var temp1:Column = _show1.getChildByName("column_"+j.toString()) as Column;
temp1.getSpectrum((_spectrum[j*4]+_spectrum[j*4+1]+_spectrum[j*4+2]+_spectrum[j*4+3]+_spectrum[j*4+256]+_spectrum[j*4+257]+_spectrum[j*4+258]+_spectrum[j*4+259])*12.5);
}
for (var m:int=0; m<256; m++) {
var temp2:Column = _show2.getChildByName("column_"+m.toString()) as Column;
temp2.getSpectrum((_spectrum[m]+_spectrum[m+256])*50);
}
//将频谱数据传送给波形的精灵实例
_waveform.getSpectrum(_spectrum);
}
//创建柱状的精灵对象
private function createColumn(f_num:int,f_width:int,f_space:int,target:Sprite):void {
for (var i:int=0; i
_column = new Column();
_column.name = "column_"+i.toString();
_column.width = f_width;
_column.x = i*(f_width+f_space);
target.addChild(_column);
}
}
//更改样式(type 为 0 时显示柱形,为 1 时显示波浪,为 2 时显示波形)
public function changeType(type:int):void {
switch (type) {
case 0 :
if (_showSpectrum.contains(_show1)) {
_showSpectrum.removeChild(_show1);
}
if (_showSpectrum.contains(_show2)) {
_showSpectrum.removeChild(_show2);
}
if (_showSpectrum.contains(_show3)) {
_showSpectrum.removeChild(_show3);
}
_showSpectrum.addChild(_show1);
break;
case 1 :
if (_showSpectrum.contains(_show1)) {
_showSpectrum.removeChild(_show1);
}
if (_showSpectrum.contains(_show2)) {
_showSpectrum.removeChild(_show2);
}
if (_showSpectrum.contains(_show3)) {
_showSpectrum.removeChild(_show3);
}
_showSpectrum.addChild(_show2);
break;
case 2 :
if (_showSpectrum.contains(_show1)) {
_showSpectrum.removeChild(_show1);
}
if (_showSpectrum.contains(_show2)) {
_showSpectrum.removeChild(_show2);
}
if (_showSpectrum.contains(_show3)) {
_showSpectrum.removeChild(_show3);
}
_showSpectrum.addChild(_show3);
break;
}
}
}
}
Column类,条形的频谱类,在Spectrum类里柱状样式中创建了 64 个,而波浪样式中创建了 256 个。
/*
类功能:柱状的频谱。
*/
package net.cdipan.spectrum{
import flash.display.*;
import flash.geom.*;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class Column extends Sprite {
//顶部小方块颜色
private const square_color:uint = 0xffffff;
//顶部颜色
private const top_color:uint = 0xffffff;
//中间颜色
private const middle_color:uint = 0x8cdcff;
//底部颜色
private const bottom_color:uint = 0x07f7ff;
//背景精灵对象
private var BG_Sp:Sprite;
//遮罩精灵对象
private var mask_Sp:Sprite;
//小方块精灵对象
private var square_Sp:Sprite;
//记录上次的频谱的值,如果比这次的高就减一,否则将这次的设为此值
private var oldNum:Number;
//计时器对象
private var myTimer:Timer;
//记录小方块是否可以下落
private var canDrop:Boolean;
public function Column():void {
BG_Sp = new Sprite();
drawGradualRect();
addChild(BG_Sp);
mask_Sp = new Sprite();
drawMaskRect();
addChild(mask_Sp);
square_Sp = new Sprite();
drawSquareRect();
square_Sp.y = 99;
square_Sp.addEventListener(Event.ENTER_FRAME, _enterframe);
addChild(square_Sp);
//设置遮罩
BG_Sp.mask = mask_Sp;
oldNum = 0;
myTimer = new Timer(200, 1);
myTimer.addEventListener("timer", onTimer);
canDrop = false;
}
//使小方块下落
private function _enterframe(e:Event):void {
if (canDrop) {
square_Sp.y += 4;
}
if (square_Sp.y > 99) {
square_Sp.y = 99;
}
if (square_Sp.y < -1) {
square_Sp.y = -1;
}
}
//绘制渐变图形
private function drawGradualRect():void {
var fillType:String = GradientType.RADIAL;
var colors:Array = [top_color, middle_color, bottom_color];
var alphas:Array = [1, 1, 1];
var ratios:Array = [0x00, 0x7f, 0xff];
BG_Sp.graphics.beginGradientFill(fillType, colors, alphas, ratios);
BG_Sp.graphics.drawRect(0,-1,100,1);
BG_Sp.rotation = 90;
}
//绘制遮罩图形
private function drawMaskRect():void {
mask_Sp.graphics.lineStyle();
mask_Sp.graphics.beginFill(0);
mask_Sp.graphics.drawRect(0,-100,1,100);
mask_Sp.graphics.endFill();
mask_Sp.y = 100;
}
//绘制小方块
private function drawSquareRect():void {
square_Sp.graphics.lineStyle();
square_Sp.graphics.beginFill(square_color);
square_Sp.graphics.drawRect(0,0,1,1);
square_Sp.graphics.endFill();
}
//接收频谱数据
public function getSpectrum(num:Number):void {
if (oldNum > num) {
oldNum -= 7;
} else {
oldNum = num;
if (oldNum != 0) {
//调用小方块运动的函数
squareMove(oldNum);
}
}
if (oldNum<0) {
oldNum = 0;
}
mask_Sp.height = oldNum;
}
//控制小方块运动的函数
private function squareMove(num:Number):void {
if (square_Sp.y > 99 - oldNum) {
square_Sp.y = 99 - num;
canDrop = false;
myTimer.reset();
myTimer.start();
}
}
public function onTimer(e:TimerEvent):void {
canDrop = true;
}
}
}
Waveform类,波形的类,用一条线条来绘制的,加入了逐渐消失的轨迹的效果。
/*
类功能:波形。
*/
package net.cdipan.spectrum{
import flash.display.*;
import flash.filters.*;
import flash.geom.*;
public class Waveform extends Sprite {
//线条颜色
private const line_color:uint = 0x07f7ff;
//创建用来绘制线条的精灵对象
private var Line:Sprite;
//用于逐渐消失的轨迹的位图对象
private var bmpData:BitmapData;
private var bmp:Bitmap;
//滤镜的各项参数
private var colorM:ColorMatrixFilter;
private var blur:BlurFilter;
private var r:Rectangle;
private var point;
//通过数字使滤镜处理慢一步
private var num:int;
public function Waveform():void {
Line = new Sprite();
bmpData = new BitmapData(256,100,true,0);
bmp = new Bitmap(bmpData);
colorM = new ColorMatrixFilter([.98,0,0,0,0,0,.98,0,0,0,0,0,.98,0,0,0,0,0,.5,0]);
blur = new BlurFilter(7,7,BitmapFilterQuality.LOW);
r = new Rectangle(0,0,256,100);
p = new Point(0,0);
//添加显示对象
this.blendMode=BlendMode.ADD;
this.addChild(bmp);
this.addChild(Line);
}
//接收频谱数据
public function getSpectrum(array:Array):void {
if (num%2 == 0) {
var m:Number = 0;
for (var j=0; j<256; j+=2) {
m += array[j];
}
if (m != 0) {
//停止播放时不绘制图像,就只会显示一条直线
bmpData.draw(this);
}
bmpData.applyFilter(bmpData,r,p,colorM);
bmpData.applyFilter(bmpData,r,p,blur);
}
num++;
Line.graphics.clear();
Line.graphics.lineStyle(1,line_color,100);
for (var i=0; i<256; i+=2) {
var n:Number = array*50;
if (i != 0) {
Line.graphics.lineTo(i,50-n);
} else {
Line.graphics.moveTo(0,50-n);
}
}
}
}
}
教程结束,以上就是Flash制作音乐频谱过程,希望对大家有所帮助,谢谢大家观看本教程!