DirectSound流式Buffer一直想不通的问题

jannl 2009-07-01 07:08:21
一直疑惑的问题,流式播放,在DirectSound的辅助buffer上设四个even ,每个even都处于缓冲区的各1/4处,用LOCK锁住后,应该是播放完多少字节就填充多少,但看一个example,总是按lock的第二参数指定值大小65536填充数据,而这个例子的辅助缓冲区大小正是65536。按理说播放完了1/4后触发事件,应该将刚刚播放完毕的部分添充1/4大小的数据才对,应该是16384字节,可这里为什么添充65536呢?辅助缓冲区总共才65536,那岂不是将未播放数据覆盖了?

DSBUFFERDESC dsbuffesc;
dsbuffesc.dwBufferBytes = 65536;

lock_size = 65536;
ds_buffer->Lock(lock_pos, lock_size, (void**)&ptr1, &size1, (void**)&ptr2, &size2, 0)

还有就是既然缓冲区总共就65536字节,每次触发事件都要填充65536字节,那么lock_pos为什么还要每次偏移16384字节大小?直接从0开始就好了。我也知道SoundBuffer是个环状结构,但不论是不是环状结构,分配的辅助buffer总大小都是65536,每次填充都是65536,这个偏移的意义何在?不明白~


实测将lock_pos不偏移,每次置为0后,声音播放是短短续续的。
...全文
166 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jannl 2009-07-04
  • 打赏
  • 举报
回复
example是没有问题的,我下了它的源码,运行过
给地址:
http://www.cppblog.com/lovedday/archive/2007/07/29/28945.html
fengge8ylf 2009-07-03
  • 打赏
  • 举报
回复
但看一个example
---
这个是什么example 这个example会不会写错了

jannl 2009-07-03
  • 打赏
  • 举报
回复

还是不明白,fread是将声音数据拷入到内存的辅助缓冲区中,请问是何时才将此辅助缓冲区的数据拷入至主缓冲区(硬件缓冲区)播放的?是PLAY的时候么?那么硬件缓冲区的大小是有限的,分配buffer的时候是什么机制呢?

我实测在流式播放模式下,当
DSBUFFERDESC dsbuffesc;
dsbuffesc.dwBufferBytes = 65536;
那么给65536这个大小的辅助缓冲区设四个标志位:
for(long i = 0; i < 4; i++)
{
g_events[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
pos_notify[i].dwOffset = 16384 * (i+1) - 1;
pos_notify[i].hEventNotify = g_events[i];
}
每个标志位分别为辅助缓冲区的16383、32767、49151、65535位置。
然后首先调用lock fread unlock填充65536大小的数据,也就是把辅助缓冲区填满,此时lock_pos = 0,lock_size = 65536;

if(FAILED(ds_buffer->Lock(lock_pos, lock_size, (void**)&ptr1, &size1, (void**)&ptr2, &size2, 0)))
return FALSE;


fread(ptr1, 1, size1, fp);
if(ptr2 != NULL)
{
fread(ptr2, 1, size2, fp);
g_ptr2[i] = size2;
}
ds_buffer->Unlock(ptr1, size1, ptr2, size2);

而后当每到标志位触发事件调用以上函数填充数据,而lock_pos的值各次分别是0,16384,32768,49152 ;lock_size的值总是65536。如果lock_size的值是16384还好理解一些,因为在流式播放中为了让声音保持正常连续播放,需要在每播放声音到一个标志位后就将播放完的部分填充数据,每次填充辅助缓冲区的1/4大小,因为每到标志位说明已经播放了1/4大小的声音数据。
但实际上,lock_size的大小总是65536,这样的话就让人疑惑了,因为只播放了1/4大小的声音数据(16384)却填充了65536,那么辅助缓冲区总大小才是65536,哪来的地方填充这个新65536呢?因为还有3/4的声音数据还没有播放啊?,况且每到播放完1/4数据的标志位都填充65536,声音岂不是都被后来的音频数据覆盖了,播放出来的声音应该不正确才对啊,但实际运行可正常播放。
然后我想到应该是辅助缓冲区的数据被铐到了主缓冲区去了,所以才不会被覆盖,才可以正常播放,但问题是既然每次都拷贝65536个字节的音频至主缓冲区,那么lock_pos还在辅助缓冲区偏移干什么?直接从0开始不就得了?
我测试如果lock_size的大小小于16384,那么音频会出现一断一断的,我分析这说明缓冲区没有填满65536字节而直接拷贝65536大小至主缓冲区去了,所以音频会有一断一断的。然后我如果始终将lock_pos设置为0,那么测试音频将是一断一断而在每断间的音频段会重复两次,但似乎没有音频覆盖的现象。
所以我想请问direct是怎样将辅助缓冲区的数据铐至主缓冲区去?何时拷贝?它的分配机制是如何的?
请高手解惑,或者给个相关参考文献,多谢多谢~
fengge8ylf 2009-07-01
  • 打赏
  • 举报
回复
看FullDuplexFilter例子

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧