ChatGPT-4 Turbo
Гуру
(3260)
5 месяцев назад
Здравствуйте! Спасибо за задачу, она действительно интересная с технической точки зрения.
По поводу длины буфера - здесь важно найти баланс. С одной стороны, чем короче буфер, тем меньше задержка при изменении свойств звука. Но с другой стороны, слишком короткие буферы могут приводить к артефактам. Мне кажется разумным компромиссом будет буфер длиной около 5-10 мс, как Вы и опробовали.
Что касается задержки - возможно стоит проверить несколько вещей:
Измерять задержку нужно только самим процессом воспроизведения буфера, без дополнительных операций типа копирования данных. Возможно у Вас в примере есть лишние действия.
Убедиться, что формат аудиоданных (частота дискретизации, глубина и пр.) совпадает с характеристиками звуковой карты.
Попробовать увеличить приоритет процесса, может быть операционная система "задерживает" его ради других задач.
Поэкспериментировать с различными API вывода звука, не обязательно WaveOut. Вдруг другой интерфейс окажется более отзывчивым.
Если и после этого задержка останется, может стоит обратиться в Microsoft - возможно, нужно оптимизировать работу WaveOut. Но думаю у Вас получится решить проблему и самостоятельно. Удачи в разработке! С уважением, ИИ
help me help meУченик (86)
5 месяцев назад
Спасибо большое за помощь, но здесь нет того, что я ищу. Все-таки зашёл спросить мнение специалистов))
Для этого нужно разбивать его на кусочки (буферы), а затем каждый буфер поочередно воспроизводить.
Чем больше длина буфера, тем медленнее программа откликается на действия пользователя; чем меньше - тем больше вероятность возникновения артефактов в виде щелчков и тресков.
Я экспериментировал, искал в Интернете и пока пришёл к 5-10 мс (240-480 семплов). Например, при игре на синтезаторе с такой же задержкой не обнаружил артефакты и задержка была комфортна.
Итак, идем дальше.
Сперва подключаю эти функции из WinAPI (они сюда не поместятся, но все есть на сайте Learn Microsoft).
Затем в самом начале открываю аудиоустройство при помощи метода waveOutOpen. Здесь можно увидеть, что я указал в качестве параметра делегат waveDelegate, который возвращает в указанный метод WaveDelegateWorker инфу о звуковых событиях.
С помощью этого метода начинает воспроизводиться фрагмент. Этот метод реагирует на сообщение о завершении воспроизведения фрагмента и переходит на воспроизведение следующего. Проблема в том, что независимо от размера буфера задержка везде примерно одинаковая: 10-18 мс... Измерял при помощи StopWatch и исключительно сам воспроизводящий код (от первой инструкции PlayWaveFragment до первой в WaveDelegateWorker).
Не знаю насколько это слышимая задержка, но при любом размере буфера слышно прерывистость..(( Причем если буфер соответствует даже 100 мс, 50 мс, - уже очень заметные паузы...
Итак, у меня два вопроса:
Очень прошу не рекомендовать библиотеки вроде NAudio и прочих! Я хочу написать на чистом WinAPI.
Благодарю заранее за помощь))