Я работаю над приложением, которое непрерывно воспроизводит аудио, используя 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 : я нашел немного об этой проблеме в Интернете, за исключением этих (без ответа) сообщений:
http://social.msdn.microsoft.com/Forums/en-US/windowsgeneraldevelopmentissues/thread/c6a1e80e-4a18-47e7-af11-56a89f638ad7
Редактировать 3 : Ну, теперь я могу воспроизвести эту проблему по своему желанию. Если я позвоню waveOutGetPosition
сразу после waveOutWrite
(в следующей строке кода), приложение будет зависать каждый раз. Он также зависает особенно плохо - кажется, он на какое-то время блокирует всю мою ОС, а не только само приложение. Таким образом, кажется, что waveOutGetPosition
блокируется, если это происходит в почти в то же время, что и waveOutWrite
, а не только буквально в одно и то же время, что может объяснить, почему блокировки не работают для меня. Иш.