Если я подключу к компьютеру линейный или USB-микрофон, я смогу записывать звук с частотой 44,1 кГц. Это один образец звука примерно каждые 23 микросекунды. Звуковая волна должна быть сэмплирована и воспроизведена точно, иначе она будет звучать искаженно. Как операционные системы не в реальном времени управляют очень чувствительным ко времени процессом записи и воспроизведения аудио с такой высокой частотой дискретизации? Отличается ли процесс, независимо от того, воспроизводится / записывается ли звук на материнской плате по сравнению с динамиками / микрофоном USB?
1 ответ
Если я подключу к компьютеру линейный или USB-микрофон, я смогу записывать звук с частотой 44,1 кГц. Это один образец звука примерно каждые 23 микросекунды. Звуковая волна должна быть сэмплирована и воспроизведена точно, иначе она будет звучать искаженно. Как операционные системы не в реальном времени управляют очень чувствительным ко времени процессом записи и воспроизведения аудио с такой высокой частотой дискретизации? Отличается ли процесс, независимо от того, воспроизводится / записывается ли звук на материнской плате по сравнению с динамиками / микрофоном USB?
Это сводится к буферизации.
44,1 кГц не означает, что существует аналоговый сигнал, который должен быть точно синхронизирован при передаче со звуковой карты (USB, PCIe, на плате, не имеет значения) в ЦП. На самом деле сигнал цифровой. Наличие потока битов цифровой импульсной кодовой модуляции, передаваемого с частотой 44100 Гц, означает, что в каждой секунде звука в сигнале будет 44 100 "точек данных". Сигнал квантуется, что означает, что это в основном последовательность чисел. Размер этих чисел (8-битный, 16-битный и т.д.) Определяется форматом образца.
Теперь учтите, что после квантования звука не имеет значения, насколько быстро или медленно он захвачен: поскольку это всего лишь набор точек данных ("сэмплов") звука, он может быть одинаково хорошо записан системой, если Вы передавали 1 образец в микросекунду, 1 образец в секунду, 1 образец в год и т. д. - пока ваш компьютер знает, какова предполагаемая частота выборки, он может собирать все точки данных с любой скоростью, какую пожелает, и затем сохранять их на диске (или в ОЗУ, или в любом другом месте), чтобы потом воспроизвести их со 100% точностью. В этом прелесть цифровой обработки сигналов. Единственное минимальное требование заключается в том, что если вы записываете аудиоданные в режиме реального времени с микрофона, вы должны иметь возможность записывать поток сэмплов в ЦП и обрабатывать их как минимум так же быстро, как поступают сэмплы. Но вам не нужно обрабатывать каждый отдельный образец как отдельную передачу.
В то время как аудио работа требует достаточно точного времени так , что человеческое ухо не может воспринимать звуковую "лаг" в аудио, он никогда не бывает так , что цифровой источник звука, как микрофон звуковой карты или USB, будет когда - либо передавать каждый отдельный образец , как и когда они получены, непосредственно в ЦП, по одному. Проблема в том, что при каждой передаче от источника звука к ЦП возникают значительные накладные расходы .
Издержки на PCI Express намного ниже, чем на USB (на самом деле, USB 2.0 может отправлять и получать пакеты только раз в 1 миллисекунду - это слишком грубо для отправки 44100 выборок по отдельности), но в любом случае это не так. будет возможность отправить 44100 отдельных образцов, каждый сам по себе, в одну секунду.
Чтобы решить эту проблему, мы используем буферизацию. Хотя буферизация создает задержку, цель состоит в том, чтобы иметь достаточно маленький буфер, чтобы пользователь мог допустить его для любого варианта использования, при этом достаточно высокий, чтобы превентивный многозадачный планировщик ядра вашей не-RTOS "обрезал" любой другие задачи, связанные с загрузкой ЦП, и дайте вашему аудио стеку возможность обрабатывать сэмплы, которые сложены.
Основная идея буферизации заключается в том, что у вас есть последовательность областей памяти, в которой биты, представляющие определенное количество выборок (обычно несколько тысяч из этих 44 100), помещаются в очередь. Когда буфер заполнен или почти заполнен, источник звука посылает ядру прерывание , которое сообщает ЦПУ, что буфер готов к чтению. Затем, когда у ядра есть время, оно планирует задачу выполнить передачу этих выборок с помощью прямого доступа к памяти (DMA) в системную память. Оттуда программа, выполняющая захват звука, может обрабатывать сэмплы. Процесс воспроизведения аналогичен, но несколько обратный.
Таким образом, если у вас есть буфер в 50 миллисекунд (1/20 секунды), что не так уж редко, у вас будет 44100/20 = 2205 выборок в каждом буфере. Таким образом, вместо получения 44100 прерываний в секунду (что, несомненно, приведет к перегрузке ЦП только из-за накладных расходов на получение и обработку этих прерываний!), ЦП получает только 20 прерываний в секунду. Намного лучше.
Вот практическое пошаговое руководство примера:
- Пользователь компьютера просит, чтобы программа начала запись звука с подключенного USB-микрофона.
- После того, как несколько уровней программного обеспечения отправят правильные команды на звуковую карту, (в конце концов) включается цифровой сигнальный процессор (DSP) в аудиочипсете микрофона. По сути, этот DSP принимает аналоговый аудиосигнал, захваченный аналоговым микрофоном, и отбирает очень частые, маленькие "выборки" уровня звука со многими маленькими точками в секунду - скажем, 44100 раз в секунду или 44,1 кГц. Представьте себе, что вы помещаете лист бумаги поверх очень точно обработанного круглого диска (например, фрисби), а затем начинайте размещать точки на бумаге по периметру круга. 4 точки в каждом квадранте круга не очень похожи на круг на бумаге, но если вы увеличите количество точек до нескольких сотен, он начнет обретать форму. Если вы берете много тысяч точек, это выглядит как круг. Это то, что делает квантование, за исключением того, что оно занимает много точек, так что конечный результат, который "рисуется" на бумаге, выглядит очень, очень близко к исходной "форме" аналоговой волны.
- Каждый сэмпл, который генерирует DSP, записывается в небольшой буфер сэмплов, который находится внутри звукового чипсета звуковой карты (я использую термин "звуковая карта" для обозначения любого цифрового аудиоинтерфейса, подключенного к цифровому компьютеру - например, USB, PCI, PCIe, все относительно одинаковы в этом аспекте.)
- Когда сэмплов "достаточно", звуковая карта сообщает компьютеру, что он может извлечь сэмплы из буфера. Если компьютер не берет сэмплы вовремя, тот же самый буфер в конечном итоге будет перезаписан следующим набором сэмплов, известным как "выпадение" (в звуке будет слышно "хлопанье"). Это может произойти, если процессор очень занят.
- Аппаратные драйверы компьютера копируют образцы из буфера в ЦП, а затем переносят их из ЦП в системную память. Оттуда приложения могут делать с ними все, что захотят, в том числе записывать их на диск, кодировать их в MP3, отправлять по сети, просто размещать в ОЗУ и т.д.
Поскольку мы предполагаем, что операционная система не работает в режиме реального времени, всегда существует вероятность того, что у ЦП будет так много задач, конкурирующих за время ЦП, что у него просто не будет времени для чтения или записи аудиоданных во времени, до того, как звуковая карта продолжит движение к следующему набору семплов. Имея предсказуемую реализацию планировщика в ядре операционной системы, например, такую, которая делит задачи на временные интервалы, можно минимизировать (хотя и не исключать на 100%) вероятность выпадения. Например, если HypotheticalOS имеет планировщик ядра, который является вытесняющим и назначает интервалы времени в 1 миллисекунду для любой задачи, которая запрашивает время на ЦП, и справедливо распределяет эти интервалы времени между конкурирующими задачами, тогда задача, которая обрабатывает ваш аудио ввод / вывод, будет вероятно получить:
- 1 миллисекунда в секунду процессорного времени, если за время конкурирует 1000 задач (1 прерывание в секунду)
- 2 миллисекунды в секунду процессорного времени, если есть 500 задач, конкурирующих за время (2 прерывания в секунду)
- ...
- 500 миллисекунд в секунду процессорного времени, если есть две задачи, конкурирующие за время (500 прерываний в секунду)
(Выше предполагается, что однопроцессорный и полностью насыщенный процессор; с SMP все усложняется.)
Таким образом, вы можете видеть, что буфер в 100 миллисекунд означает, что планировщик ядра должен предоставить вашему стеку ввода-вывода аудио (который обычно включает компоненты ядра и пользовательского пространства) как минимум 10 временных интервалов для выполнения работы на каждую секунду аудио. И если аудио конвейеру требуется более одного временного интервала для выполнения своей работы, то ему нужно гораздо больше временных интервалов в секунду.
И, надеюсь, эти временные срезы распределены равномерно: если вы получили 50 временных срезов в течение первых 50 мс заданной секунды, а затем имели нулевые временные срезы за оставшиеся 950 мс с буфером 100 мс, пользователь будет испытывать почти полная секунда отсева! Тьфу.
Чтобы немного отличаться, я должен отметить, что есть и другие способы ввода / вывода звука, но это наиболее традиционный способ, который используется на обычных настольных компьютерах. В GNU / Linux есть звуковой сервер PulseAudio, который сообщает вашей звуковой карте, чтобы она прекратила посылать прерывания, и просто получает данные из звукового буфера, когда это необходимо, в зависимости от размера используемого буфера (который может изменяться со временем адаптироваться к более высоким требованиям к процессору или более низкой задержке, запрашиваемой приложениями!) Этот метод называется планированием по времени и зависит от очень хорошей реализации планировщика в ядре Linux.