花了3天做的音乐频谱的效果,截图的效果:



包括了5个类:

MusicControl类,不多说了,用来控制音乐的,包括音乐的载入和播放时的控制等。

ID3Control类,用来提取音乐文件的相关信息的类,循环的显示各种信息,提取的中文显示乱码,这里用一个函数进行更正即可:

  1. function EncodeUtf8(str:String):String {
  2. var oriByteArr:ByteArray = new ByteArray();
  3. oriByteArr.writeUTFBytes(str);
  4. var tempByteArr:ByteArray = new ByteArray();
  5. for (var i = 0; i<oriByteArr.length; i++) {
  6.   if (oriByteArr == 194) {
  7.    tempByteArr.writeByte(oriByteArr[i+1]);
  8.    i++;
  9.   } else if (oriByteArr == 195) {
  10.    tempByteArr.writeByte(oriByteArr[i+1] + 64);
  11.    i++;
  12.   } else {
  13.    tempByteArr.writeByte(oriByteArr);
  14.   }
  15. }
  16. tempByteArr.position = 0;
  17. return tempByteArr.readMultiByte(tempByteArr.bytesAvailable,"chinese");
  18. }
Spectrum类,管理和显示频谱的类,从MusicControl类里取出频谱的信息,注意MusicControl类里的
  1. SoundMixer.computeSpectrum(_spectrumArray,true);
里第二个参数 true 表示取出的是频谱,而 false 表示取出的是波形。

  1. /*
  2. 类功能:显示频谱。
  3. */
  4. package net.cdipan.spectrum{
  5. import flash.display.Sprite;
  6. import flash.utils.ByteArray;
  7. import flash.text.TextField;
  8. import flash.events.MouseEvent;
  9. import flash.net.navigateToURL;
  10. import flash.net.URLRequest;
  11. public class Spectrum extends Sprite {
  12.   //记录频谱的数组
  13.   private var _spectrum:Array;
  14.   //记录显示的类型
  15.   private var _type:int;
  16.   //用于显示频谱的精灵对象
  17.   private var _showSpectrum:Sprite;
  18.   //用于显示柱状频谱的精灵对象
  19.   private var _show1:Sprite;
  20.   //用于显示波浪频谱的精灵对象
  21.   private var _show2:Sprite;
  22.   //用于显示波形频谱的精灵对象
  23.   private var _show3:Sprite;
  24.   //柱形对象
  25.   private var _column:Column;
  26.   //波形对象
  27.   private var _waveform:Waveform;
  28.   public function Spectrum():void {
  29.    _spectrum = new Array(512);
  30.    _showSpectrum = new Sprite();
  31.    _showSpectrum.x = 22;
  32.    _showSpectrum.y = 18;
  33.    _show1 = new Sprite();
  34.    _show2 = new Sprite();
  35.    _show3 = new Sprite();
  36.    this.addChild(_showSpectrum);
  37.    //创建柱状频谱
  38.    createColumn(64,3,1,_show1);
  39.    createColumn(256,1,0,_show2);
  40.    //创建波形频谱
  41.    _waveform = new Waveform();
  42.    _show3.addChild(_waveform);
  43.    _showSpectrum.addChild(_show1);
  44.   }
  45.   //获取频谱数组
  46.   public function getSpectrum(byteArray:ByteArray):void {
  47.    for (var i:int=0; i<512; i++) {
  48.     _spectrum = byteArray.readFloat();
  49.    }
  50.    //将频谱数据传送给柱状和波浪的精灵实例
  51.    for (var j:int=0; j<64; j++) {
  52.     var temp1:Column = _show1.getChildByName("column_"+j.toString()) as Column;
  53.     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);
  54.    }
  55.    for (var m:int=0; m<256; m++) {
  56.     var temp2:Column = _show2.getChildByName("column_"+m.toString()) as Column;
  57.     temp2.getSpectrum((_spectrum[m]+_spectrum[m+256])*50);
  58.    }
  59.    //将频谱数据传送给波形的精灵实例
  60.    _waveform.getSpectrum(_spectrum);
  61.   }
  62.   //创建柱状的精灵对象
  63.   private function createColumn(f_num:int,f_width:int,f_space:int,target:Sprite):void {
  64.    for (var i:int=0; i<f_num; i++) {
  65.     _column = new Column();
  66.     _column.name = "column_"+i.toString();
  67.     _column.width = f_width;
  68.     _column.x = i*(f_width+f_space);
  69.     target.addChild(_column);
  70.    }
  71.   }
  72.   //更改样式(type 为 0 时显示柱形,为 1 时显示波浪,为 2 时显示波形)
  73.   public function changeType(type:int):void {
  74.    switch (type) {
  75.     case 0 :
  76.      if (_showSpectrum.contains(_show1)) {
  77.       _showSpectrum.removeChild(_show1);
  78.      }
  79.      if (_showSpectrum.contains(_show2)) {
  80.       _showSpectrum.removeChild(_show2);
  81.      }
  82.      if (_showSpectrum.contains(_show3)) {
  83.       _showSpectrum.removeChild(_show3);
  84.      }
  85.      _showSpectrum.addChild(_show1);
  86.      break;
  87.     case 1 :
  88.      if (_showSpectrum.contains(_show1)) {
  89.       _showSpectrum.removeChild(_show1);
  90.      }
  91.      if (_showSpectrum.contains(_show2)) {
  92.       _showSpectrum.removeChild(_show2);
  93.      }
  94.      if (_showSpectrum.contains(_show3)) {
  95.       _showSpectrum.removeChild(_show3);
  96.      }
  97.      _showSpectrum.addChild(_show2);
  98.      break;
  99.     case 2 :
  100.      if (_showSpectrum.contains(_show1)) {
  101.       _showSpectrum.removeChild(_show1);
  102.      }
  103.      if (_showSpectrum.contains(_show2)) {
  104.       _showSpectrum.removeChild(_show2);
  105.      }
  106.      if (_showSpectrum.contains(_show3)) {
  107.       _showSpectrum.removeChild(_show3);
  108.      }
  109.      _showSpectrum.addChild(_show3);
  110.      break;
  111.    }
  112.   }
  113. }
  114. }
Column类,条形的频谱类,在Spectrum类里柱状样式中创建了 64 个,而波浪样式中创建了 256 个。

  1. /*
  2. 类功能:柱状的频谱。
  3. */
  4. package net.cdipan.spectrum{
  5. import flash.display.*;
  6. import flash.geom.*;
  7. import flash.events.Event;
  8. import flash.utils.Timer;
  9. import flash.events.TimerEvent;
  10. public class Column extends Sprite {
  11.   //顶部小方块颜色
  12.   private const square_color:uint = 0xffffff;
  13.   //顶部颜色
  14.   private const top_color:uint = 0xffffff;
  15.   //中间颜色
  16.   private const middle_color:uint = 0x8cdcff;
  17.   //底部颜色
  18.   private const bottom_color:uint = 0x07f7ff;
  19.   //背景精灵对象
  20.   private var BG_Sp:Sprite;
  21.   //遮罩精灵对象
  22.   private var mask_Sp:Sprite;
  23.   //小方块精灵对象
  24.   private var square_Sp:Sprite;
  25.   //记录上次的频谱的值,如果比这次的高就减一,否则将这次的设为此值
  26.   private var oldNum:Number;
  27.   //计时器对象
  28.   private var myTimer:Timer;
  29.   //记录小方块是否可以下落
  30.   private var canDrop:Boolean;
  31.   public function Column():void {
  32.    BG_Sp = new Sprite();
  33.    drawGradualRect();
  34.    addChild(BG_Sp);
  35.    mask_Sp = new Sprite();
  36.    drawMaskRect();
  37.    addChild(mask_Sp);
  38.    square_Sp = new Sprite();
  39.    drawSquareRect();
  40.    square_Sp.y = 99;
  41.    square_Sp.addEventListener(Event.ENTER_FRAME, _enterframe);
  42.    addChild(square_Sp);
  43.    //设置遮罩
  44.    BG_Sp.mask = mask_Sp;
  45.    oldNum = 0;
  46.    myTimer = new Timer(200, 1);
  47.    myTimer.addEventListener("timer", onTimer);
  48.    canDrop = false;
  49.   }
  50.   //使小方块下落
  51.   private function _enterframe(e:Event):void {
  52.    if (canDrop) {
  53.     square_Sp.y += 4;
  54.    }
  55.    if (square_Sp.y > 99) {
  56.     square_Sp.y = 99;
  57.    }
  58.    if (square_Sp.y < -1) {
  59.     square_Sp.y = -1;
  60.    }
  61.   }
  62.   //绘制渐变图形
  63.   private function drawGradualRect():void {
  64.    var fillType:String = GradientType.RADIAL;
  65.    var colors:Array = [top_color, middle_color, bottom_color];
  66.    var alphas:Array = [1, 1, 1];
  67.    var ratios:Array = [0x00, 0x7f, 0xff];
  68.    BG_Sp.graphics.beginGradientFill(fillType, colors, alphas, ratios);
  69.    BG_Sp.graphics.drawRect(0,-1,100,1);
  70.    BG_Sp.rotation = 90;
  71.   }
  72.   //绘制遮罩图形
  73.   private function drawMaskRect():void {
  74.    mask_Sp.graphics.lineStyle();
  75.    mask_Sp.graphics.beginFill(0);
  76.    mask_Sp.graphics.drawRect(0,-100,1,100);
  77.    mask_Sp.graphics.endFill();
  78.    mask_Sp.y = 100;
  79.   }
  80.   //绘制小方块
  81.   private function drawSquareRect():void {
  82.    square_Sp.graphics.lineStyle();
  83.    square_Sp.graphics.beginFill(square_color);
  84.    square_Sp.graphics.drawRect(0,0,1,1);
  85.    square_Sp.graphics.endFill();
  86.   }
  87.   //接收频谱数据
  88.   public function getSpectrum(num:Number):void {
  89.    if (oldNum > num) {
  90.     oldNum -= 7;
  91.    } else {
  92.     oldNum = num;
  93.     if (oldNum != 0) {
  94.      //调用小方块运动的函数
  95.      squareMove(oldNum);
  96.     }
  97.    }
  98.    if (oldNum<0) {
  99.     oldNum = 0;
  100.    }
  101.    mask_Sp.height = oldNum;
  102.   }
  103.   //控制小方块运动的函数
  104.   private function squareMove(num:Number):void {
  105.    if (square_Sp.y > 99 - oldNum) {
  106.     square_Sp.y = 99 - num;
  107.     canDrop = false;
  108.     myTimer.reset();
  109.     myTimer.start();
  110.    }
  111.   }
  112.   public function onTimer(e:TimerEvent):void {
  113.    canDrop = true;
  114.   }
  115. }
  116. }
Waveform类,波形的类,用一条线条来绘制的,加入了逐渐消失的轨迹的效果。

  1. /*
  2. 类功能:波形。
  3. */
  4. package net.cdipan.spectrum{
  5. import flash.display.*;
  6. import flash.filters.*;
  7. import flash.geom.*;
  8. public class Waveform extends Sprite {
  9.   //线条颜色
  10.   private const line_color:uint = 0x07f7ff;
  11.   //创建用来绘制线条的精灵对象
  12.   private var Line:Sprite;
  13.   //用于逐渐消失的轨迹的位图对象
  14.   private var bmpData:BitmapData;
  15.   private var bmp:Bitmap;
  16.   //滤镜的各项参数
  17.   private var colorM:ColorMatrixFilter;
  18.   private var blur:BlurFilter;
  19.   private var r:Rectangle;
  20.   private var point;
  21.   //通过数字使滤镜处理慢一步
  22.   private var num:int;
  23.   public function Waveform():void {
  24.    Line = new Sprite();
  25.    bmpData = new BitmapData(256,100,true,0);
  26.    bmp = new Bitmap(bmpData);
  27.    colorM = new ColorMatrixFilter([.98,0,0,0,0,0,.98,0,0,0,0,0,.98,0,0,0,0,0,.5,0]);
  28.    blur = new BlurFilter(7,7,BitmapFilterQuality.LOW);
  29.    r = new Rectangle(0,0,256,100);
  30.    p = new Point(0,0);
  31.    //添加显示对象
  32.    this.blendMode=BlendMode.ADD;
  33.    this.addChild(bmp);
  34.    this.addChild(Line);
  35.   }
  36.   //接收频谱数据
  37.   public function getSpectrum(array:Array):void {
  38.    if (num%2 == 0) {
  39.     var m:Number = 0;
  40.     for (var j=0; j<256; j+=2) {
  41.      m += array[j];
  42.     }
  43.     if (m != 0) {
  44.      //停止播放时不绘制图像,就只会显示一条直线
  45.      bmpData.draw(this);
  46.     }
  47.     bmpData.applyFilter(bmpData,r,p,colorM);
  48.     bmpData.applyFilter(bmpData,r,p,blur);
  49.    }
  50.    num++;
  51.    Line.graphics.clear();
  52.    Line.graphics.lineStyle(1,line_color,100);
  53.    for (var i=0; i<256; i+=2) {
  54.     var n:Number = array*50;
  55.     if (i != 0) {
  56.      Line.graphics.lineTo(i,50-n);
  57.     } else {
  58.      Line.graphics.moveTo(0,50-n);
  59.     }
  60.    }
  61.   }
  62. }
  63. }

源文件下载:

Flash音乐频谱制作.rar

 

转自:http://www.68design.net/Web-Guide/Flash/45403-1.html

posted on 2010-04-16 15:45  钱途无梁  阅读(651)  评论(0编辑  收藏  举报