DShow之DSound与WaveOut的学习笔记

 在PC上面,我们可以看到两个Render,一个时基于DSound一个是基于WaveOut,我们可以打开GraphEdit,分别用他们两个来播放音乐,右击两个Render,选择属性,可以发现他们有一点差别,正是这点差别,才表明他们是基于不同的技术来发声的。

在DSound和Waveout中都有一个持续时间,并且是在变化的,一般是200ms-500ms,证明两个播放机制都设有缓冲,但是下面一个很微小的 东东,一个有百分比,一个没有百分比,我的猜测是,在DSound实现的Render中,有一个Directsoundbuffer,这个buffer是 可读可写的,读取数据播放后,就成了free空间,可以在往里面写数据,并且这个缓存还不能很小,每当收到一帧数据的时候,判断还有多少free空间,没 有没有足够的空间,那么就有两种方式来处理,一种是sleep一段时间再来判断,要注意的是,如果发现free空间足够的时候,这个while循环一定要 退出,否则下一个sample就接受不到,当发现free不够,才会挂起等待,或者sleep一段时间,这个挂起等待,这就要求你的buffer在播放的 时候要有一个监控的机制,信号DSound有一个Notify接口,当发现播放数据不多的时候就会通知,这样你就会去填充数据,然后在跳出while循 环,注意这种机制就能够保证你的音频数据不会没有播放就丢失了。其实我觉得,这就是一个时间的机制,我在AudioRender上面继承了 IRefTime接口,并且实现了它的一系列函数,但是发现根本就没有调用,难道微软在骗人,不过自己写的Render是不能播放音视频混合的,可能是因 为这个音频播放并不需要同步,或者说它的同步并不是通过IRefTime来实现的,因为本身声卡得到数据之后,也会得到它的采样率、声道等信息,然后声卡 播放数据也是按照这个信息来播放,你的数据中有多少时间的数据就能播放多少时间的数据,并不会快或者慢,硬件是不会骗人的,这样一来就像通了,之所以要实 现IRefTime接口,不是给AudioRender本身来用的,实现IRefTime是因为有些其他的链路要参考声卡的时间,然后给他们一个接口,我 的程序只是在播放音频,所以这个IRefTime中的接口函数更本就没有调用,这很正常,我就是一条链路,我自己已经可以通过硬件同步,没有人要参考我的 同步信息,因而我的接口函数就没有调用,很正常。

扯了这么多无关的东东?好,那我们的WaveOut的Render为什么就没有百分比呢,个人觉得其实是可以做百分比的,其实DSound提取位置很简 单,只是一个简单的调用GetPosition,但是WaveOut,因为本身没有像DSound那样先天就是有缓冲的机制,它的缓冲要人为指定,并且一 般为了音频的连续播放,缓冲区不止一个,因而得到它的百分比就比较困难,并不是微软不做,只是有点麻烦,又没有什么实际的意义,所以他懒了一回。
这样说来,写一个Audio Render其实也不是很难,我们只要播放音乐就行了,所以在IRef里面置空都可以的,甚至不去实现IRef接口都是可行的,这样想通了之后就节省了大量的工作量。

你可能感兴趣的:(工作,buffer,音乐,微软,audio)