给mp3播放器增加音乐波形显示功能

给mp3播放器增加音乐波形显示功能

2008-04-02 16:18:18| 分类: 应用编程 | 标签: |字号 订阅

用过winamp的人都知道,winamp有一个音乐波形显示功能,当播放音乐的时候,有一些音乐波形跟着上下跳动,翩翩起舞,又好看,又专业。那么如何给自己的播放器增加这样一个波形显示器呢。

本文给出了一个完整的代码例子,并一步一步的教你实现的过程。为了,推广as2.0和as3.0,本文的例子,采用外部纯 .as文件编写,编译测试时,完全脱离flash,采用FlashDevelop工具编译。代码见附录。

本文的运行效果,可以参考http://www.iu1u.com/res/mywave.swf,本文可以随意转载,但请保证文章的完整性。

准确地说,这里实现地是一个伪波形显示功能。为什么叫做伪波形呢,真正的波形,应该来自实际的音频数据,对应时间对应频段的声音强度高时,就显示高的柱状,声音强度低时,就显示低的柱状。但是,对于大部分的用户来说,实际的音频数据对他们来说也没有什么概念,所以,用伪波形,几乎可以达到以假乱真的效果。

其实,要显示伪波形很容易,只要随机生成不同高度的柱状图,就可以了。但是,为了得到更逼真的效果,大家可以注意一下,很多播放器的波形图里,顶端都有一个小点,它们的反应往往迟钝一下,当一个柱状由高突然变低的时候,并不马上跟着变低,而是,慢慢的往下掉。如何实现这种效果呢,其实,分析一下他的原理,就很简单了。只要每次柱状高度变化的时候,记录一下这组高度,下次生成新的高度时,如果,新的高度比原高度高,那么,顶点跟着网往上走,就是,如果,新高度比原高度小,那么,就让顶点高度减掉一个常数,注意,这里只是减掉一个常数,而不是直接变成新高度。这样,实现出来的效果,就是顶点好像有些缓冲,别柱状顶上去后,是慢慢的往下掉。

本例子里的所有显示内容,都是通过BitmapData对象的画布直接画出来的。所以,也可以帮助读者复习一下BitmapData的用法,以及它如何与MovieClip关联。

在onEnterFrame事件中,调用updatePanel()函数,这个函数会重新生成新的波形,并刷新显示。其中的if (frameCount++>1) 是调整波形的刷新频率用的,不改变1这个数字,就可以实现让波形跳动的更快,或者更慢一些。

最后,因为这是一个继承自MovieClip的类。要想把这个类变成一个flash中的真正的MovieClip对象,必须通过 Object.registerClass()把它注册一下。然后,通过AttachMovie加入flash。这是as2.0里的做法,在as3.0 里,就方便很多了,直接new这个对象,然后通过addChild()加入flash即可。

附:代码


/**
* Test class for testing mtasc swf building in FlashDevelop.
* @mtasc -swf c:\Test.swf -header 500:400:12:EFEFEF -main -trust -trace org.flashdevelop.utils.FlashConnect.mtrace org/flashdevelop/utils/FlashConnect.as
*/
import flash.display.*;
import flash.geom.Rectangle;

class Wave extends MovieClip
{
static var symbolName:String = "__Packages.Wave";
static var symbolOwner:Function = Wave;
// associate the symbol to the class when the class is defined
static var symbolLinked = Object.registerClass(symbolName, symbolOwner);

var LeftMargin, Bar_Width, Bar_Gap, Bar_Max_Height,BarCount,Client_Height: Number;
var frameCount:Number = 0;
var PolarBarHeight:Array;
var img:BitmapData;
var rect:Rectangle;
var rectPolar: Rectangle;
function Wave ()
{
LeftMargin = 20;
Bar_Width = 5;
Bar_Gap = 3;
Bar_Max_Height = 40;
BarCount = 20;
Client_Height = 200;

rect = new Rectangle(0,0,100,100);
rectPolar = new Rectangle(0,0,Bar_Width,1);
img = new BitmapData( 256, 200, false, 0 );
PolarBarHeight = new Array(20);
for (var i:Number = 0;i PolarBarHeight[i] = 0;
this.attachBitmap(img,1);
}

function updatePanel()
{
trace(PolarBarHeight);
var i:Number =0;
img.fillRect(img.rectangle,0x000000);
for (i=0;i {
var WaveHeight:Number = random(Bar_Max_Height);
rect.left = LeftMargin + i * (Bar_Width + Bar_Gap);
rect.top = Client_Height - WaveHeight;
rect.right = LeftMargin + i * (Bar_Width + Bar_Gap) + Bar_Width;
rect.bottom = Client_Height;
img.fillRect(rect,0x009900);

if ((PolarBarHeight[i] == 0) || (PolarBarHeight[i] < WaveHeight + 5))
PolarBarHeight[i] = WaveHeight + 5;
else
PolarBarHeight[i] = PolarBarHeight[i] - 4;
if (PolarBarHeight[i] < WaveHeight + 5)
PolarBarHeight[i] = WaveHeight + 5;
rectPolar.left = LeftMargin + i * (Bar_Width + Bar_Gap);
rectPolar.top = Client_Height - PolarBarHeight[i];
rectPolar.width = Bar_Width;
rectPolar.height = 1;

img.fillRect(rectPolar,0xFF9900);
}
}


function onEnterFrame()
{
if (frameCount++>1)
{
updatePanel();
frameCount = 0;
}
}

// entry point
static function main (mc)
{
//var wave:Wave = new Wave ();
_root.attachMovie(Wave.symbolName, "wave", 1);
}
}

你可能感兴趣的:(声音的处理)