as3声音类详解.docx
- 文档编号:6198866
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:11
- 大小:167.25KB
as3声音类详解.docx
《as3声音类详解.docx》由会员分享,可在线阅读,更多相关《as3声音类详解.docx(11页珍藏版)》请在冰豆网上搜索。
as3声音类详解
一直都对as3的声音架构设计感到困惑,as3为什么要把播放和停止方法分开呢?
为什么不能用一个Sound更换载入的声音呢?
原来as3对声音的设计也是深思熟虑的。
目的不是为了把问题搞得复杂,而是为了在功能强化的同时做到精简。
并尽可能方便我们使用。
架构图:
2011-1-1009:
28上传
下载附件(22.58KB)
可以看出,as3中的声音处理是独立的,不再依赖影片剪辑作为声道。
as3使用多个类合作处理声音,功能被细化到对应的类中,使得逻辑更加清晰。
下面对着架构图由下往上详细阐述各个类所但当的任务。
Sound类负责创建、加载、播放声音。
Sound类更像BitmapData扮演的角色,用于描述数据。
而不是控制声音。
使用Sound创建声音有两种创建方式:
1.通过库中元件创建和载入
库中声音是Sound的子类。
要播放必须创建它们的实例。
2.通过外部加载的声音
外部加载声音创建类型是Sound类本身。
为强调一个类描述一个声音数据这种模式,Sound禁止第二次加载外部声音。
加载控制符合open—progress—complete的标准。
Sound的构造函数为Sound(stream:
URLRequest=null, context:
SoundLoaderContext=null),创建外部声音时与load方法参数相同。
如果创建库中的声音则不需要任何参数。
方法:
load(stream:
URLRequest=null,context:
SoundLoaderContext=null):
void
加载声音。
不能使用一个Sound对象加载多个声音。
当有多声音播放时,必须为每个声音创建不同的Sound对象。
play(startTime:
Number =0,loops:
int=0,sndTransform:
SoundTransform=null):
SoundChannel
播放声音。
startTimer为开始播放事件,单位为毫秒。
loops为循环次数,0和1都表示播放一次,如同flash属性面板中的次数设置。
sndTransform是分配给每个通道的初始对象,如果有必要还可以在soundChannel中修改这个对象。
每次播放都会选择不通的声道,对应方法返回值。
多次执行会导致重叠播放。
close():
void
关闭声音流。
对于流式播放声音,close很重要,因为soundChannel的stop方法不足以停止流式下载的声音。
可能产生继续播放的现象。
事件:
open:
类型为Event.OPEN。
开始下载时触发。
progress:
类型为PrograssEvent.PROGRESS。
下载时触发。
complete:
类型为Event.COMPLETE。
下载完毕时触发。
ioError:
类型为Event.IO_ERROR。
发生IO错误时触发。
id3:
类型为Event.ID3。
可以访问id3数据时触发。
属性:
所有属性都是只读的,用来访问加载信息。
url:
String(加载声音的url值。
)
bytesLoaded:
uint(加载字节数。
)
bytesTotal:
int(总字节数。
)
length:
Number(当前声音长度,如果加载中只反应加载的长度。
)
id3:
ID3Info(id3属性包含唱片信息。
)
加载播放外部声音的顺序:
2011-1-1009:
29上传
下载附件(12.82KB)
属性:
songName:
String歌曲名称。
track:
String曲目编号。
artist:
String歌手名称。
album:
String专辑名称。
yesr:
String录制年份。
genre:
String歌曲流派。
comment:
String相关注释。
获取唱片信息顺序:
SoundChannel类
SoundChannel继承EventDispatcher,使用import flash.media.SoundChannel声明。
SoundChannel用于描述声音通道。
有了这个类,声音通道再不用依赖MovieClip了。
多个声道可以播放一个声音,一个声道可以播放多个声音(同一时刻只能播放一个)。
对声音的操控和状态描述从描述声音数据的Sound类中分离出来。
声道与声音之间的关系类似Bitmap和BitmapData的关系。
这种逻辑描述更加精确。
但与位图不同的是声音通道不是由用户创建的而是系统生成的。
这个纽带是Sound的play方法。
采用这种处理方式是为了降低复杂性,因为系统自动管理声道免去我们因声道分配分散注意力。
系统每次选择空余声道进行回放。
当停止了一个声道的播放后,声道自动被as回收。
这样一来,我们完全不必去管声道如何分配的,就如显示对象的深度管理一样。
方法:
stop()
停止播放声音。
但不能停止流式下载时播放的声音。
属性:
position:
Number
播放头位置,单位毫秒。
只读属性。
这表示position并不能设置播放进度。
要设置播放进度只能使用play的参数。
leftPear:
Number
左声道音量。
范围为0-1。
这个属性并不用来控制平移而是用来读取左声道峰值波幅。
可以用这个属性检查是否是单声道。
rightPear:
Number
右声道音量。
范围为0-1。
这个属性并不用来控制平移而是用来读取右声道峰值波幅。
可以用这个属性检查是否是单声道。
soundTransform:
SoundTransform
分配给声道的soundTransform对象。
事件:
soundComplete
类型为Event.SoundComplete。
声音播放完毕后触发。
监视和设置声音播放进度:
监视播放进度:
对于下载完毕的声音可以使用position监视播放进度。
但对于正在下载中的声音虽然position可以正常访问,但length属性只能在下载完毕后才能获取,这给监视播放进度造成了困难。
这时可以通过bytesLoaded和bytesTotal的比值估算出长度。
公式为:
position*bytesTotal/bytesLoaded。
设置播放进度:
由于position属性是只读的。
因此不能通过它设置播放进度。
设置播放进度只能通过play方法的startTime参数。
这是因为考虑到功能重复。
采取这种逻辑还有个长处是不必管播放的状态。
方法也只有播放和停止而没有暂停方法。
少了一个状态和方法后,播放进度不必管是否播放或暂停。
所以免去了playState属性。
position的只读特性也避免设置进度时是否要保持播放或暂停状态。
现在一切都被简化成播放和停止两个方法了。
逻辑大大简化。
而暂停和设置进度都由播放和停止两个方法衍生出来。
方法如下:
设置进度=stop+play(startTime)
暂停播放=记录position+stop
恢复播放=play(记录position)
SoundTansform类
SoundTransform
SoundMixer类继承Object。
使用import flash.media.SoundMixer声明。
由于不使用MovieClip绑定声音通道。
所以描述全局声音通道的不是主时间轴而是SoundMixer类。
由于与任何声道无关,所以SoundMixer是个静态类。
属性:
SoundMixer.bufferTime:
int
全局缓冲时间。
如果在Sound类的play方法中未指定缓冲则由这里决定。
SoundMixer.soundTransform:
SoundTransform
全局SoundTransform对象。
控制总体声音效果。
当应用了单个sound的soundTransform属性后再应用总声音特效。
比如对于音量控制而言,这里是总音量控制。
方法:
SoundMixer.stopAll():
void
停止所有通道播放声音。
SoundMixer.areSoundsInaccessible():
Boolean
如果声音因为安全模型不能访问则返回true.
SoundMputeSpectrum(outputArray:
ByteArray, FFTMode:
Boolean=false,stretchFactor:
int=0):
void
返回当前组合音频快照。
波形被分为256级,分为左声道和右声道。
被记录在outputArray中。
outputArray是个二进制数组,拥有512个元素,类型为Numer。
使用readFloat方法访问。
前256个浮点数描述左声道的波形,后256个浮点数描述右声道的波形。
浮点数也分为两种描述类型,FFTMode参数为true时使用频谱形式描述。
范围为0~2的平方根。
为false时采用波形描述,范围为-1~1。
strechFactor是采样率。
0为44HZ,1为22.HZ,以此类推。
不管采样率为多少,始终都是256级别。
采样率只会影响波形是否平滑。
生成播放特效:
很多时候我们很羡慕mediaplayer的视觉特效吧。
也很想知道是怎么做出来的。
答案就是两个字——算法。
现在利用as3提供的computeSpectrum可以实现我们的梦想,这是在as2中做不到的。
下面我们来看看实现的原理。
不管使用什么算法,数据都是相同的。
我们可以写一段小代码,输出某个音乐播放中的浮点状态。
导入一首歌曲,库中类名改为Song。
在帧上输入如下代码:
vars:
Song=newSong();
s.play();
var ba:
ByteArray=newByteArray();
stage.addEventListener(MouseEvent.CLICK,onClick);
function onClick(event:
MouseEvent):
void
{
SoundMputeSpectrum(ba);
ba.position=0;
for(var i:
int=0;i<512;i++)
{
var num:
Number=ba.readFloat();
trace(num);
}
}
看到数据的组织结构后,下一步就可以发挥你编程与艺术的完美结合,而mediaplayer中的特效就是完美最好的榜样。
在这么多另人眼花缭乱的效果中,条形与波形是最直接最简单的可视效果,它是数组的直接透视。
现在我们来看看FFTMode为true和false时的波形区别。
用于控制声音的音量和平移。
它跟多个类有联系,如:
Microphone、NetStream、SoundChannel、SoundMixer都通过它调节声音效果。
再次显示了声音架构的标准统一。
更可贵的的是在SimpleButton和Sprite中也有这个属性。
这代表着可以通过as调整flash工具创作的按钮和影片剪辑中嵌入的声音。
这种操控能力使得我们不必因为嵌入的声音对应调整音量上的干扰。
但这并不代表我们能控制帧中声音的播放和停止。
SoundTransform的构造函数为new SoundTransform(vol:
Number=1,panning:
Number=0)。
构造函数的参数是它的属性。
属性:
volume:
Number
音量,范围为0~1。
pan:
Number
声道平移,范围为-1~1。
leftToLeft:
Number
左输入在左声道中的音量。
leftToRight:
Number
左输入在右声道中的音量。
rightToLeft:
Number
右输入在左声道中的音量。
rightToRight:
Number
右输入在右声道中的音量。
SoundMixer类
2011-1-1009:
30上传
下载附件(41.17KB)
快速傅立叶变换:
快速傅氏变换,是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。
它对傅氏变换的理论并没有新的发现,但是对于在计算机系统或者说数字系统中应用离散傅立叶变换,可以说是进了一大步。
设x(n)为N项的复数序列,由DFT变换,任一X(m)的计算都需要N次复数乘法和N-1次复数加法,而一次复数乘法等于四次实数乘法和两次实数加法,一次复数加法等于两次实数加法,即使把一次复数乘法和一次复数加法定义成一次“运算”(四次实数乘法和四次实数加法),那么求出N项复数序列的X(m),即N点DFT变换大约就需要N2次运算。
当N=1024点甚至更多的时候,需要N2=1048576次运算,在FFT中,利用WN的周期性和对称性,把一个N项序列(设N=2k,k为正整数),分为两个N/2项的子序列,每个N/2点DFT变换需要(N/2)2次运算,再用N次运算把两个N/2点的DFT变换组合成一个N点的DFT变换。
这样变换以后,总的运算次数就变成N+2(N/2)2=N+N2/2。
继续上面的例子,N=1024时,总的运算次数就变成了525312次,节省了大约50%的运算量。
而如果我们将这种“一分为二”的思想不断进行下去,直到分成两两一组的DFT运算单元,那么N点的DFT变换就只需要Nlog2N次的运算,N在1024点时,运算量仅有10240次,是先前的直接算法的1%,点数越多,运算量的节约就越大,这就是FFT的优越性.
这就是快速傅立叶转换的原理,但若频繁的把波形转化成频谱,除了算法上的处理,还会会消耗一定的cpu资源,这就是as3直接提供了波形和频谱两种浮点模式的原因。
创建自定义播放效果:
下面一个是我用矢量生成的一个特效。
实际上还可以使用位图,甚至结合flash工具创建的动画来制作特效。
可以说这方面的发挥空间是无穷无尽的。
这里我使用256条线段来描述声道的波幅,使用25层来描述场密度。
效果如下:
2011-1-1009:
32上传
下载附件(76.71KB)
说明:
由于嵌入声音造成文档太大,所以载入XX中的歌曲。
歌曲地址放在界面文本框中又会影响美观,所以我在路径下放了一个songURL.txt的文本。
大家可以更改网址。
但同时访问本地和网络又会造成安全问题。
于是找来我的flashBox。
flashBox可不管什么沙箱,本地网络通吃。
而且全屏播放又能加快执行速度。
可以当作屏保一样。
真是很适合呢。
另外由于是矢量制作的因而不可能使得密度到达mediaplayer中水纹那样的效果,我们可以使用BitmapData来达到。
但以像素级来描述波形将会更慢。
因为flashplayer是不能象c++那样调用系统API的。
也不能直接使用显卡支持的driectX或openGL。
无法直接操作显存。
即便如此,我还是要说说使用BitmapData代替矢量呈现的方法。
原理并不是很困难。
使用矢量只不过是绘制线条。
我们可以写一个使用位图创建线条的函数。
原理如下:
想象线段是一条路径,一个爬虫从一段爬到另一端,走过的路径使用像素填充。
这样一来就非常简单了。
结合Tween来进行像素填充,为位图创建一个lineTo函数,代码改动基本上不大。
详细代码我就不写了。
请大家自己尝试。
ID3Info类(ID3Info类用于描述声音信息。
对应Sound类的id3属性。
)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- as3 声音 详解