一直疑惑的问题,流式播放,在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后,声音播放是短短续续的。 

解决方案 »

  1.   


    还是不明白,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是怎样将辅助缓冲区的数据铐至主缓冲区去?何时拷贝?它的分配机制是如何的?
    请高手解惑,或者给个相关参考文献,多谢多谢~
      

  2.   

    但看一个example
    ---
    这个是什么example  这个example会不会写错了
      

  3.   

    example是没有问题的,我下了它的源码,运行过
    给地址:
    http://www.cppblog.com/lovedday/archive/2007/07/29/28945.html