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