日期:2012-12-09  浏览次数:20402 次

关键字: 播放器 示波器 vb.net DirectSound9 作者:董含君

转载请注明来自 http://blog.csdn.net/a11s

作为一个播放器最基本的功能.比如豪杰 winamp mediaplayer real quicktime 等等 都有自己的示波器.某些还提供接口允许plugin 添加更多的图形效果.



很多人做的播放器没有这个基本的功能,大概是因为绝大多数都是直接使用了mediaplayer或者realone的控件缘故.至于这些,本文暂不讨论.本文介绍一些基本知识,以及实现的步骤方法.其中可能会用到DirectSound以及DirectDraw的一些知识.

1 DirectSoundCapture:从录音开始

先来看看录音,当时我们建立了一个buffer用于写数据.这些数据其实就是我们用来示波的.只不过需要经过一些变化.你可以直接显示出buffer的内容.

2 DirectSound播放的时候

我们new 了一个buffer读取了wav,下一步自然是play.注意一点你会发现有个read() 方法,可以读取缓冲区的内容.取出来看看确实是我们当时写进去的东西.

3 画线

用数字来表示不够直观,因为我们已经习惯了看图像来感知声音的变化规律.那么我们可以考虑利用DirectDraw把buffer的内容图像化.首先利用read()方法得到一块byte(),然后用for循环来画图,至于什么时候调用read(),你可以使用一个Timer.注意:这么做的目的是为了说明里面的数据与图像的规律.而不是完美的示波器.相关DirectDraw的使用可以参见我原来发的托管的DirectDraw9.因为为了保证速度,除了DDraw之外想不出更好的办法了.

右下是绘制出来的图像(感谢大风 提供的fps算法)点击放大 1024x768 这个blog我不大会用



根据声音的变化图像会发生响应的变化.但是你会感觉跟winamp的不一样.下面会详细解释为什么.现在你只要"知其然"就够了.这个实际上是windows录音机用的示波器.


4 关于Riff文件

经过上次的wav capture,应该理解Riff是什么东西了.根据A/D转换的结果,储存到缓冲区,然后在根据文件格式的不同进行格式化(结构体大小不同).没有压缩的wav实际上就是一段A/D转换的结果加上文件头罢了.转换候由于是由模拟信号转来的,声音的变化实质上就是一个连续曲线.有兴趣的化,你可以自己做一个wave editor.即使用鼠标也能画出声音来

5 A/D D/A转换的相关 不想了解可以跳过去,这里告诉你"所以然"

明白了它,你就可以自己做均衡器了.但是本文先不讨论.

采样率:就是A/D转换时候的发生频率,请参阅接口技术 单片机 等相关资料.由于我也不是非常了解,说错了的地方希望您能够批评指正.

把模拟音频转成数字音频的过程,就称作采样,简单地说就是通过波形采样的方法记录1秒钟长度的声音,需要多少个数据。44KHz采样率的声音就是要花费44000个数据来描述1秒钟的声音波形。原则上采样率越高,声音的质量越好.

位数:简言之,就是精度,比如24位的就具有24位转换精度.

其实还有一个声强级.这里不需要我们做太多关心.(主要是怕说错)

结合riff文件的特性,你可以知道多少buffer是你应该read()的,然后每个字节表示什么含义

6 真正的示波器,类似WinAmp的

他们是以多少Hz来分的,从1K 到 10k 到 32k 到....

实际上就是把我们的数据进行整合得到的,算出从0到1k有多少,然后累加.显示在示波器上.

刚才我们显示的是"内容",WinAmp显示的是"数量",因为人的耳朵对某一段的数据较为敏感,而不想机器采样.举个简单的例子.人能感觉到重低音,这时winamp的某断区域能够看出急剧增长,而我们原来的示波器看不出,顶多看出音量的变化.

了解到了实质自己再作示波器就没有压力了.

7 图形化的示波器以及对外提供的接口

绘制过程实际上就是一个绘制函数,你把这一段buffer的"特点"传递过去(甚至可以传递整个buffer)它就会根据参数绘制响应的图案,当然可以增加自己的特色,比如常用的衰减(声音结束之后不是一下子没了图像,而是渐渐的消失)这样连贯起来,人感觉比较舒适.对外提供了接口,任何人都可以利用他来做自己的图形化示波器.

相关请参考PlugIn的原理以及制作过程,强烈建议学习WinAmp的

8 其他格式的文件.

以上仅仅针对wav做出了一些解释.其他的格式比如mp3,不能直接这么做,但是原理是一样的.毕竟播放的时候需要进行D/A转换.你需要通过将mp3额结果转成类似Riff的Buffer,然后播放.仅此而已

=======End==============