Создание аудиоприложения в реальном времени с помощью программных синтезаторов

StackOverflow https://stackoverflow.com/questions/1392725

Вопрос

Я изучаю возможность создания некоторого программного обеспечения, которое позволяет клавиатуре функционировать как пианино (например, пользователь нажимает клавишу "W", а динамики воспроизводят ноту D).Вероятно, я буду использовать OpenAL.Я разбираюсь в основах цифрового аудио, но воспроизведение звука в реальном времени в ответ на нажатие клавиш создает некоторые проблемы, которые мне трудно решить.

Вот в чем проблема: Допустим, у меня есть 10 аудиобуферов, и каждый буфер содержит одну секунду аудиоданных.Если мне нужно заполнить буферы перед их воспроизведением через динамики, то я бы заполнял буферы за одну или две секунды до их воспроизведения.Это означает, что всякий раз, когда пользователь пытается воспроизвести ноту, между нажатием клавиши и воспроизведением ноты будет задержка в одну или две секунды.

Как вы решаете эту проблему?Вы просто делаете буферы как можно меньше и заполняете их как можно позже?Есть ли какой-то трюк, которого мне не хватает?

Это было полезно?

Решение

Большинство программных синтезаторов вообще не используют несколько буферов.

Они просто используют один-единственный маленький кольцевой буфер, который постоянно воспроизводится.

Поток с высоким приоритетом будет как можно чаще проверять текущую позицию воспроизведения и заполнять свободную часть (напримерчасть, которая воспроизводилась с момента последнего запуска вашего потока) кольцевого буфера со звуковыми данными.

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

Вы можете еще больше снизить задержку:

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

Это становится сложным, если у вас запущены эффекты, основанные на времени (линии задержки, реверберация и так Далее), Но это выполнимо.Просто следите за последними 10 состояниями ваших эффектов, основанных на времени, примерно каждую миллисекунду.Это позволит вернуться на 10 миллисекунд назад по времени.

Другие советы

С WinAPI вы можете продвинуться так далеко только с точки зрения задержки.Обычно вы не можете опуститься ниже 40-50 мс, что довольно неприятно.Решение состоит в том, чтобы внедрить поддержку ASIO в вашем приложении и заставить пользователя запускать что-то вроде Asio4All в фоновом режиме.Это сокращает задержку до 5 мс, но с определенными затратами:другие приложения не могут воспроизводить звук одновременно.

Я знаю это, потому что я пользователь FL Studio.

Решение - это небольшие буферы, часто заполняемые потоком реального времени.То, насколько малыми вы делаете буферы (или насколько полным вы позволяете буферу становиться с помощью кольцевого буфера), ограничено планируемой задержкой вашей операционной системы.Вероятно, вы сочтете 10 мс приемлемыми.

Здесь есть несколько неприятных ошибок для непосвященных - особенно в отношении архитектуры программного обеспечения и потокобезопасности.

Вы могли бы попробовать взглянуть на Джус - который представляет собой кроссплатформенный фреймворк для написания звукового программного обеспечения, и в частности - аудио плагинов, таких как SoftSynths и effects.Он включает в себя программное обеспечение как для примеров подключаемых модулей, так и для хостов.Именно на хосте в основном решаются проблемы с потоковой передачей.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top