2013-12-09 50 views
0

我的应用程序记录来自连接到我的PC的麦克风的音频样本。所以我选择了Windows WaveInXXX API来完成这项工作。Windows音频/ WaveInAddBuffer()块

阅读文档后,我决定避免使用WaveInProc的回调机制来节省麻烦来同步这些线程。整个应用程序非常庞大,我认为这会使调试变得更简单。当应用程序请求一个样本块时,我只是迭代我的缓冲区队列,取出一个,复制数据,对其进行备份,准备并将其添加回缓冲队列。基本程序结构看起来像这样,我希望它明确了基本的程序流程:

WaveInOpen() 
WaveInStart() 
FunctionAddingPreparedBuffersToTheQueue() 
while(someConditionThatEventuallyBecomesFalse) 
    if(NextBufferInQueueIsMarkedDone) 
     GetDataFromBuffer() 
     UnpreparePrepareHeaderAndAddBuffer() 
    else 
     WaitForAShortTime() 
WaveInStop() 
WaveInClose() 

现在出现的问题:经过一段时间(和我无法重现的确切条件),WaveInAddBuffer()导致死锁尽管它与所有其他人一样。在发生死锁时应添加的缓冲区的头文件已准备好,并且dwFlags == WHDR_PREPARED == 2

任何想法可能导致这种僵局?

+0

尽管您还不知道问题的原因,但请尝试发布[SSCCE](http://sscce.org),以说明您遇到的问题面对。 – IInspectable

+1

那么你使用的是什么回调机制,'CALLBACK_NULL'?在死锁的时候,你可以打入并捕获冻结的线程调用堆栈 - 这将是有益的。我的猜测是问题出在'NextBufferInQueueIsMarkedDone'的周围,你正在检查缓冲区标志立即访问它们(检查WHDR_DONE)。如果是这样,你不应该这样做,你应该通过回调机制获得缓冲区可用性的通知。 –

+0

@RomanR。我遵循你的建议,使用'CALLBACK_FUNCTION'而不是'CALLBACK_NULL',现在死锁不见了,所以谢谢你!不幸的是,我仍然无法说出最初的问题是什么让人有点不满意。为什么你认为正在检查缓冲区标志,就像我之前做过的一个问题一样? – fewu

回答

1

我还没有看到这样的问题,但猜测可能是像所有的非备用/准备周期相关的碎片。他们没有必要。您可以为每个缓冲区执行一次准备,然后在完成记录时做好准备。 (准备将缓冲区锁定到物理内存中。)