Проблема с тупиком waveOutWrite и waveOutGetPosition
Я работаю над приложением, которое непрерывно воспроизводит звук, используяwaveOut...
API отwinmm.dll
, Приложение использует буферы leapfrog, которые в основном представляют собой набор массивов сэмплов, которые вы помещаете в аудио-очередь. Windows воспроизводит их последовательно и по мере завершения каждого буфера Windows вызывает функцию обратного вызова. Внутри этой функции я загружаю следующий набор семплов в буфер, однако обрабатываю их, а затем сбрасываю буфер обратно в аудио-очередь. Таким образом, аудио играет бесконечно.
В целях анимации я пытаюсь включитьwaveOutGetPosition
в приложение (поскольку обратные вызовы «выполнено из буфера» нерегулярны, чтобы вызвать прерывистую анимацию).waveOutGetPosition
возвращает текущую позицию воспроизведения, поэтому она является сверхточной.
Проблема в том, что в моем приложении звонкиwaveOutGetPosition
в конечном итоге приложение блокируется - звук прекращается, и вызов никогда не возвращается. Я свел вещи к простому приложению, которое демонстрирует проблему. Вы можете запустить приложение здесь:
http://www.musigenesis.com/SO/waveOut%20demo.exe
Если вы просто слышите чуть-чуть пианино снова и снова, это работает. Это просто для того, чтобы продемонстрировать проблему. Исходный код этого проекта находится здесь (все мясо находится в LeapFrogPlayer.cs):
http://www.musigenesis.com/SO/WaveOutDemo.zip
Первая кнопка запускает приложение в режиме чехарды, не делая звонкиwaveOutGetPosition
, Если вы нажмете на это, приложение будет играть вечно, не прерываясь (кнопка X закроет его и выключит). Вторая кнопка запускает чехарду, а также запускает таймер форм, который вызываетwaveOutGetPosition
и отображает текущую позицию. Нажмите на это, и приложение будет работать в течение короткого времени, а затем заблокировать. На моем ноутбуке он обычно зависает через 15-30 секунд; самое большее это заняло минуту.
Я понятия не имею, как это исправить, поэтому любая помощь или предложения будут приветствоваться. Я нашел очень мало сообщений по этому вопросу, но, похоже, существует потенциальная тупиковая ситуация, либо от нескольких звонков наwaveOutGetPosition
или от звонков до этого иwaveOutWrite
которые происходят одновременно. Возможно, я слишком часто это вызываю, чтобы система справилась.
редактировать: забыл упомянуть, я работаю на Windows Vista. Это может не произойти вообще на других ОС.
Редактировать 2Я нашел немного об этой проблеме в Интернете, за исключением этих (без ответа) сообщений:
Редактировать 3Ну, теперь я могу воспроизвести эту проблему по своему желанию. Если я позвонюwaveOutGetPosition
незамедлительно послеwaveOutWrite
(в следующей строке кода) приложение зависает каждый раз. Он также зависает особенно плохо - кажется, он на какое-то время блокирует всю мою ОС, а не только само приложение. Итак, похоже, чтоwaveOutGetPosition
тупики, если это происходит воколо в то же время, что иwaveOutWrite
не только буквально одновременно, что может объяснить, почему у меня не работают замки. Иш.