2013-05-10 74 views
2

我使用DirectSound的DirectSoundBuffer播放通过网络传输的语音数据。语音/语音的本质在于它不一定会持续流(它的启动和停止),而且它也可能以不同的数据包大小(这使得很难预测缓冲区应停止在哪里)。我保留一个StoppingPoint变量,用于跟踪我写入的缓冲区中的位置(它也考虑了此缓冲区的循环特性)。如果达到了StoppingPoint,我想停止播放我的缓冲区。此外,我还会指出我也想从哪里开始写作。C++ - DirectSoundBuffer在特定位置停止播放 - 无通知

My buffer 
|==============================|--------------------------| 
    ^     ^   ^
     |      |    | 
    Voice Data   Stopping point Old/Garbage 
              data 

此外,我不能使用通知,因为为了使用通知缓冲区必须停止。但就我而言,在缓冲区播放时很可能会有更多数据进入,从而推迟了我的“StoppingPoint”值。

我现在拥有的是一个被称为每一帧的函数。除此之外,这个功能正在检查Play光标的位置。如果Play光标通过StoppingPoint位置,则它会停止缓冲区,并将Play光标移回StoppingPoint位置。这似乎目前工作正常,但正如您所期望的,Play游标经常超过StoppingPoint。这意味着每次到达流数据的末尾时都会播放一点点的旧/垃圾数据。

我只是好奇,是否有办法停止在特定的偏移量播放DirectSoundBuffer?我想将数据写入缓冲区,然后播放,然后让它停止在我的StoppingPoint变量所描述的位置,而不会超过它。

注:我没有包含任何代码,因为这是更高级的解决方案,我需要。我的实施非常简单,典型,而且大部分工作都是如此。我只是需要在正确的方向微调以消除我的StoppingPoint的过冲。也许有一个我可以使用的功能?或者其他一些常用的算法来实现这一点?

回答

0

我想出了一个解决方案,但我仍然对任何反馈或替代解决方案感兴趣。我不确定我做的方式是否可行,但似乎正在产生预期的结果。虽然,我的解决方案感到有点费解......

1)每当我写的数据,我现在在写任何缓冲的Write CursorStoppingPoint - 以较晚者为准。这是为了避免停止,然后再写入Play Cursor和Write Cursor之间的“不可触摸的”空间,其数据已经专用于播放。

DWORD writeCursorOffset = 0; 
buffer->GetCurrentPosition(NULL, &writeCursorOffset); 

//if write cursor has passed stopping point, then we need to write from there. 
//So update m_StoppingPoint to reflect the new writing position. 
m_StoppingPoint = m_StoppingPoint > writeCursorOffset ? m_StoppingPoint : writeCursorOffset; 

2)我添加了一些沉默每一个写入之后,但我离开StoppingPoint在实际的声音数据的结束点。例如。

|==============================|*********|---------------------| 
    ^      ^ ^   ^
    |       |  |    | 
Voice data     Stopping Silence Old/Garbage 
          Point     Data 

3)如果缓冲区的Play Cursor通过StoppingPoint,然后,我会停止播放缓冲。即使Play Cursor在这里超调,它所播放的只是沉默。

//error checking removed for demonstration purposes 
buffer->Stop(); 

4)停止I将更新StoppingPoint等于沉默的结束之后立即。这将确保当更多的语音数据进入时,缓冲区不会首先播放任何静音。

//don't forget that modulo at the end - circular buffer! 
m_StoppingPoint = (m_StoppingPoint + SILENCE_BUFFER_SIZE) % BufferSize; 

|==============================|*********|-------------------| 
             ^
             | 
            Move Stopping 
             Point here 

再说一遍,如果我在这里做了任何明显的坏事,请告诉我!