一种AS3下对SOUND对象进行整体、快速采样的方法
2017-09-15 18:35
369 查看
最近也没什么写点东西的想法,也都没有什么新意。娃的外语辅导班开课了,发了本教材,打开配套光盘一看,心中立马奔过一万只神兽…………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 rate
var 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()就可以了。
不过在使用的时候发现对于才接触外语的小盆友来说,不仅舌头不好用,听的时候重读不重读这些也需要辅助……于是想起来波形这个东西,接下来就各种百度、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 rate
var 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()就可以了。
相关文章推荐
- 迭代器模式:就是提供一种方法对一个容器对象中的各个元素进行访问,而又不暴露该对象容器的内部细节。
- 实现一种快速查找Richedit中可见区域内OLE对象的方法
- 实现一种快速查找Richedit中可见区域内OLE对象的方法
- 对于有多种可替代解决方案的业务逻辑,提供一种快速替换方法
- 教你一种U盘病毒的快速检测方法
- 总结一种快速做一条小行线方法
- 目前的代码系统,一类的继承和方法的扩展为主的形式是否可以进行一种形式的优化?从而提升运行效率
- ASP调用DLL总对象方法与数据库进行连接
- js sort方法根据数组中对象的某一个属性值进行排序
- 一种快速将markdown转换为html的方法
- C#.NET 如何快速输入一个对象事件对应的方法
- AS3中通过ByteArray进行对象的深度拷贝
- 一种比较简单快速的硬盘全新安装Win10单双系统的方法
- Zen Coding: 一种快速编写HTML/CSS代码的方法
- 【转】介绍vb使用xmlhttp对象、webbrowser控件、inet控件进行Post发包、Get发包的方法
- 一种快速的公交专用车道检测方法
- 一种将web项目快速添加到eclipse tomcat server的方法
- 编写一个手机类,包括手机品牌、手机型号, 方法包括显示手机信息,并编写测试类进行对象的创建
- 对数组中的对象进行升序以及降序的排序方法(其中对象类型是系统类型).
- 3DS:一种相当快速的读取方法,不超过5分钟