В своем прошлом посте я рассказывал, как производится чтение и обработка буфера перед последующим выводом в звуковую подсистему waveOut в Windows.

Можно было бы закончить, но была одна проблема синхронизации буфера, поскольку функция Sleep() не обладает точностью задержки, а waveOutWrite является асинхронной функцией. Но из этого можно сделать гораздо больше.

Как?

В Win32 API присутствуют так называемые “критические секции” (CRITICAL_SECTION). Это специальный кусок кода, где основной поток программы может получить доступ к переменным из других потоков.

В Java есть нечто похожее - оператор synchronized. Только в отличии от CRITICAL_SECTION, он входит в сам язык программирования и имеет высокоуровневую абстракцию.

Реализацию под это дело я нашел у Дэвида Овертона, тут пошагово объясняется как реализовано управление буфером и воспроизведение аудио по каждому кадру или блоку.

Но, увы, подвох нашелся именно в цикле while с условием !waveFreeBlockCount, поскольку недостаточно ожидать освобождения хотя бы одного кадра, чтобы не потерять конечные кадры. Оптимально будет, если вывести новый буфер после освобождения 2/3 старого буфера.

Естественно, функция для вывода аудиофайла выполняется синхронно. Завтра попробую написать его асинхронную версию.

В своем прошлом посте я рассказывал, как производится чтение и обработка буфера перед последующим выводом в звуковую подсистему waveOut в Windows | Сетка — социальная сеть от hh.ru В своем прошлом посте я рассказывал, как производится чтение и обработка буфера перед последующим выводом в звуковую подсистему waveOut в Windows | Сетка — социальная сеть от hh.ru