DirectSound 的循环播放BUFFER怎么写数据才好?

redleaves 2002-08-16 12:49:08
我在用DSound的循环缓冲时,每次的当前写位置都是在当前播放位置后几个到几十字节的位置.就算刚写过缓冲,当前的写位置也是这样.这样的话,我连续多次写缓冲后,先写的数据总会被后写的数据覆盖,就算我通过手工定位也还是要错。这是怎么回事?
还有,我在用IDirectSoundNotify来监控播放事件时,每次设置事件都要把缓冲停止,设置的事件才有效。这样一来,停一下,再播放,声音就会停顿。这要怎么解决?
在使用循环缓冲时,有没有别的方法使缓冲播放完最后一次写入的数据后就停止呢?
...全文
205 12 打赏 收藏 举报
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
redleaves 2002-09-01
谢谢各位支持,我的问题基本上解决.还有些小问题,先不去管它们了.有空再来请教!
  • 打赏
  • 举报
回复
capboy 2002-08-25
发现一个新问题...
双cpu机器,播放directsound速度要快于正常速度.把他的硬件加速改成基本加速就好了...
单cpu的完全没有问题...(任何加速级别)
比较奇怪...大家共享共享.呵呵
  • 打赏
  • 举报
回复
capboy 2002-08-23
"每个放了就删除"???为什么?
循环播放.事件也是循环通知.只要你的数据添加不慢于播放就可以了(可以使用缓冲队列来防止抖动的情况).
事件通知的时候,添加数据.这个很准确的.(播放是匀速的).
播放和添加之间有一定的间隔(消除抖动影响).播放完全没有问题.
  • 打赏
  • 举报
回复
夭夭 2002-08-22
怎么做呀,
每个放了就删除,不就行了.
想得简单!
  • 打赏
  • 举报
回复
finalvictory 2002-08-20
对了,差点忘了,那篇文章在Technical Articles -> Multimedia -> DirectX -> DirectSound -> Streaming Wave Files with DirectSound,虽然是96年写的,但是很经典,拿来做教材绝对没有问题,建议你读一下。
  • 打赏
  • 举报
回复
finalvictory 2002-08-20
流式缓冲似乎不该出现这么多问题啊?

流式缓冲的写指针需要自己维护,这在MSDN的技术文章区就有讲到了。因为GetCurrentPosition返回的是DSound自己认为“安全”的指针,对于连续播放没有什么价值。

事件通知点应该在缓冲区播放之前就设置好的。

DSound确实有一个对齐的问题,但是绝对不会导致你这个问题的。那个对齐是根据nBlockAlign来进行的,是为了防止向缓冲区中写入不完整的数据,有了这个对齐就可以保证缓冲区中的每个采样都是完整的。

退一步,就算你的数据由于对齐的原因损失掉了,那你也听不出来!算算看最坏的情况:SampleRate=8000,Channels=2,Bits=16,那么nBlockAlign=4,假设写入了n * 4 + 3个字节,那么最后3个字节被丢掉,损失的时间是3/8000=0.000375s,神仙听得出来!而且没有人用这么糟糕的方案吧?
  • 打赏
  • 举报
回复
capboy 2002-08-20
好些时候没有来。csdn特别慢。老打不开。
“我在用DSound的循环缓冲时,每次的当前写位置都是在当前播放位置后几个到几十字节的位置.就算刚写过缓冲,当前的写位置也是这样”这个是肯定的。你使用他 的函数返回的写位置吧。directsound关于这个参数的说明就是这样的。这样才能够安全的写数据。在这个之后,播放位置之前都是安全的写数据区(还是需要注意循环的情况)。
我的方法就是自己判断写位置的。写的地方肯定是安全的位置。(只要你的缓冲超过2个数据块,除非你添加的速度慢于一个数据块的播放,快与一个数据块的播放,但可以加大缓冲,这样应该不会有问题。)。
我没有碰到你“在播放时,每个块和每个块之间会产生卡卡声”的问题。是不是你给的不够及时啊?猜测而已。。。
我的程序也很正常啊。不过没有使用这个方法。呵呵。
我正在测试我的directsound的循环缓冲播放方法,写完在贴出来看看好了。呵呵。(好长时间没有写文档了)。
  • 打赏
  • 举报
回复
wqyuwss 2002-08-19
up
  • 打赏
  • 举报
回复
redleaves 2002-08-16
如果只预写两三个块,我这儿也是正常的.不过,一旦我一次性写入七八个块就会出现缓冲覆盖的情况.而且我申请的缓冲是够大的.不知道是怎么回事?还有,就是我写缓冲后,在播放时,每个块和每个块之间会产生卡卡声.不知道为什么,首先我的数据是没有错的,相同的数据,我用waveOut就是正常的.我以前在哪儿看别人说过,好像DSound在写缓冲时会产生对齐的问题,多余的数据它会自己丢掉.不知道有没有这么一会事?
  • 打赏
  • 举报
回复
chenm001 2002-08-16
应该是有什么地方写错了,我的程序很正常啊!
  • 打赏
  • 举报
回复
redleaves 2002-08-16
TO capboy(帽子):
你给的那个方法看上去应该可行.
不过关于我的第一个问题,你有什么看法?
比如我的BUFFER长度是10s,我的每个数据块的长度为1s,如果我连续写BUFFER,写9次,然后再放,结果只能听到一个块.其它的什么都没有了.就算我用DSBLOCK_ENTIREBUFFER来手工定位还会错,不知道有什么问题?
  • 打赏
  • 举报
回复
capboy 2002-08-16
???为什么你非要每次都设置事件呢?事件应该是自己触发的吧.而且是循环的.

你给的数据的应该是同样长度的吧,把你的directsoundbuffer设置为一个数据块的n倍.在设置n个事件点.这样每个数据块播放完,你都知道.
先填充2个数据块,在播放,播放完第一个在第三个位置写入新数据,播放完第二个在第四个地方写入新数据.类推.只是需要注意判断到尾部的情况.
这样就是有一个数据块的播放延时.
这个还是自己判断比较合适.
你应该知道最后的数据块是那个.
在写的时候,记住最后写的位置i,在写入数据后,等待i+1的事件,这个应该就是最后一个数据播放完了的标准了.呵呵.(你应该不会有整个缓冲的延时吧?)
  • 打赏
  • 举报
回复
相关推荐
发帖
游戏开发
加入

8138

社区成员

游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
申请成为版主
帖子事件
创建了帖子
2002-08-16 12:49
社区公告
暂无公告