一种AS3下对SOUND对象进行整体、快速采样的方法

来源:互联网 发布:linux修改文件夹命令 编辑:程序博客网 时间:2024/06/06 01:51

        最近也没什么写点东西的想法,也都没有什么新意。娃的外语辅导班开课了,发了本教材,打开配套光盘一看,心中立马奔过一万只神兽…………CD,音轨,1995年?这不是发错教材让老夫重修吧,那个年代老夫也上高中了,有点晚啊!好吧,自己动手丰衣足食,用个FLASH吧反正最近比较闲比较闲。开始倒没什么,搞个list,搞个showimg,搞个音量调节,播放进度之类的就OK了。

        不过在使用的时候发现对于才接触外语的小盆友来说,不仅舌头不好用,听的时候重读不重读这些也需要辅助……于是想起来波形这个东西,接下来就各种百度、AS3 API之类的,发现了一些方法。例如,可以在播放时采样获得波形,一帧一次。这可不太能满足我的要求,当然,搞一些小动作也许能听见声音之前得到波形,太麻烦了。于是静心回头仔细看AS3 API文档,别说还真发现一些好东东,可以直接获取原始数据:

1、sound.extract:可以把声音数据取出来,这就是希望的曙光。

2、数据在0-1之间,所以只需要在graphics绘制之前按显示宽度缩放。

3、数据长度和FLAC生成时指定的比特率密切关联,sd.extract(bs,sd.length*44.1);。

看起来问题似乎解决了。但是接下来剪辑FLAC的时候发现一个问题,有的是一个长段的描述,播放的时候解析速度实在是不敢恭维,在i5 4590 ,i7 6500上都卡十来秒。又一万只神兽狂奔而过有木有!好吧,重新考虑一下这个问题,其实读取多少数据就看显示的波形有多宽,对应一像素采样一次绘制就可以了。所以,就有了下面代码:

var bs:ByteArray=new ByteArray();//原始数据var zoom:Number=rect.width/sd.length/44.1;//bit ratevar offset:Number=rect.height/2;//显示时的中心线y坐标var i:Number=0;//波形采样次数计数var s:Number;//波形采样间隔var val:Number;//当前左声道数据(右声道和左声道一样操作,但本程序声音文件左右声道相同)sd.extract(bs,sd.length*44.1);//获取声音原始数据s=bs.length/8/rect.width;//数据组个数(左右声道)/显式长度=需要的采样的长度s=int(s/8)*8;//将采样长度设置为8的整数倍的整数以保证bs读取位置正确bs.position = 0;//设置当前位置while(bs.bytesAvailable > 0){val = bs.readFloat();//从当前位置读取左声道数据//此处使用lineto绘制或存储后使用drawpath绘制//绘制代码i++;bs.position=s*i;//移动到下一个位置}

好吧,有点乱,不过思路还是清晰的,获取数据之后,根据绘制宽度取得采样长度并规范数据以保证下面的代码运行正确。之后就可以采样了。因为这个声音左右声道都一样,所以只用了左声道,如果也用右声道只需要在i++之前再次调用bs.readfloat()就可以了。

原创粉丝点击