Сквозная передача звука в автомобильной телематике
Введение
Автомобиль давно уже не только не роскошь,
но и не средство передвижения. Вернее, быть сред
ством передвижения — уже едва ли не побочная его
функция. За пару последних десятилетий он, в погоне
за покупателем, так оброс всевозможной электрони
кой, что практически превратился в мультимедийную
компьютерную систему на четырех колесах. Мощный
мотор, надежная подвеска и крепкий кузов уже не га
рантируют производителю рыночного успеха, если они
не дополняются качественной аудиосистемой и разно
образными коммуникационными сервисами, от три
виальных голосовых звонков до доступа в Интернет
и автоматического вызова спасательной бригады при
аварии. Большинство же коммуникационных серви
сов, объединяемых термином «автомобильная теле
матика», так или иначе связаны с передачей звука.
В первых поколениях телематических систем
аудиообработка и функции алгоритмического уп
равления были жестко разделены на аппаратном
уровне. Звуковые каналы администрировались вы
деленным DSP-процессором, на нем же выполнялись
процедуры подавления эха, очистки от шумов и дру
гие алгоритмы обработки сигналов. Центральный
же процессор, сравнительно медленный и маломощ
ный, осуществлял управление каналами связи.
С инженерной точки зрения такая архитектура, где
каждый компонент занят тем видом работ, для ко
торого изначально предназначен, выглядит логич
но. Она, однако, далеко не оптимальна с финансо
вой точки зрения. Наличие на плате DSP ведет к серь
езному увеличению стоимости телематического
продукта в целом, причем не только за счет присут
ствия дополнительного дорогостоящего компонен
та и сопутствующих схем. DSP необходимо програм
мировать, что влечет необходимость привлечения
соответствующих специалистов, приобретения ин
струментария, разработки дополнительного тесто
вого окружения. Кроме того, узким местом стано
вится коммуникация между двумя процессорами.
Все это сильно сказывается на цене конечного реше
ния и в итоге на стоимости автомобилей, на рынке
которых идет острейшая конкурентная борьба.
Поэтому, как только мощность встраиваемых ми
кроконтроллеров возросла достаточно для того, что
бы сделать возможным использование его как для
управления, так и для передачи звука, производите
ли стали отказываться от дорогостоящих DSP и пе
реходить на сложные в реализации, но более деше
вые однопроцессорные решения.
Однако использование процессора общего назна
чения для передачи звука существенно сказывается
на требованиях, накладываемых на реализацию про
граммной части системы. В данной статье авторы по
стараются изложить некоторые принципы и методы,
связанные с конструированием звуковых подсистем
в телематических программах. При этом за рамками
материала останется рассмотрение собственно алго
ритмов обработки звука — тема, достаточно общая
и широко освещенная в соответствующей литерату
ре. Вместо этого будут рассмотрены проблемы, свя
занные со сквозной передачей оцифрованных аудио
данных, решению которых уделено несколько мень
шее внимание специалистов. Все изложенное в данной
статье является обобщением практического опыта ав
тора в области промышленного программирования
автомобильных телематических систем.
Звуковые порты, каналы и полуканалы
Прежде всего определимся с существом задач, свя
занных с передачей звука в телематике. К ним отно
сится в первую очередь телефония, то есть обеспече
ние голосовых звонков через встроенный либо внеш
ний сотовый телефон. Кроме того, работая своего рода
мостом между автомобильными устройствами и се
тями мобильной связи, телематическое устройство
должно обеспечивать разнообразные сервисы, в част
ности проигрывание тонов и сигналов. К тому же оно
может выполнять функции диктофона, мультиме
дийного проигрывателя и автоответчика.
Для реализации этой функциональности телемати
ческое устройство подключается к ряду аппаратных
источников и приемников аудиоданных. Главными
из них, как правило, выступают оптическая либо эле
ктрическая автомобильная мультимедийная шина и те
лефонный канал. В качестве последнего может высту
пать как проводное, так и беспроводное соединение,
например Bluetooth. Кроме того, к устройству могут
быть подключены собственные микрофоны и дина
мики, внешняя трубка или гарнитура. В отдельную ка
тегорию можно выделить внутренние программно ре
ализуемые источники и приемники аудиоданных, ис
пользуемые для записи и воспроизведения сигналов.
Однако с точки зрения программной реализации
все эти источники и потребители звука, как правило,
могут рассматриваться в унифицированной форме
цифрового аудиопорта, принимающего или переда
ющего оцифрованные с определенной частотой дис
кретизации звуковые отсчеты заданной разрядности.
Для последующей обработки отсчеты собираются в программные буферы, называемые также
кадрами: последовательная обработка каждого
отсчета означает такую загрузку вычислитель
ных ресурсов, которую не способен выдержать
ни один современный процессор.
При описании проблем и задач, возникаю
щих при транспортировке звука через цен
тральный процессор, мы будем использовать
ряд специфических терминов. Поскольку тер
минология в этой, достаточно молодой, обла
сти еще не до конца сформирована, кратко по
ясним существо понятий, которые будут ис
пользованы в последующем тексте.
Аудиопорт или звуковой порт — это аппарат
ный или программный модуль, являющийся ис
точником или приемником оцифрованных зву
ковых данных. В общем случае аудиопорт явля
ется последовательным каналом синхронного
ввода или вывода данных. В зависимости от спе
цифики интерфейса аудиопорт может выдавать
или принимать данные по одному отсчету ли
бо кадрами фиксированного размера. Второй
подход используется существенно чаще, так как
обработка звука единичными отсчетами чрез
вычайно ресурсоемка и в большинстве случаев
невыполнима в реальном времени.
Аудиоканал — комбинация из порта-источ
ника звука, порта-приемника и набора про
граммных модулей, обеспечивающих передачу
звуковых пакетов и их промежуточную обра
ботку. В данной статье рассматривается пове
дение симплексных каналов, то есть каналов,
передача данных в которых происходит в од
ном направлении — от порта-источника к пор
ту-приемнику. В частном случае пара симплекс
ных каналов может образовывать дуплексный
канал, используемый для двунаправленного об
мена между парами портов, состоящими из ис
точника и приемника. Следует обратить вни
мание, что даже если все каналы в системе яв
ляются дуплексными, нередко обработка звука
специфична для каждого направления.
Буфер (кадр, пакет) — последовательность
оцифрованных звуковых отсчетов, передава
емая через систему как единое целое. Буфер
является как единицей распределения памя
ти, так и входным или выходным параметром
большинства алгоритмов транспортировки
и обработки звука.
Полуканал — совокупность модулей, слу
жащих для передачи звука между портом и бу
феризированным программным интерфей
сом. Полуканал используется для преобразова
ния входных синхронных последовательных
данных в последовательность буферов или для
выдачи последовательности буферов в синхрон
ный выходной последовательный канал. Полу
каналы связывают модули обработки и хране
ния звуковых последовательностей со звуковым
портом для различных целей, включая проиг
рывание тонов и сигналов, запись звука для по
следующего воспроизведения, получение опор
ного сигнала для алгоритмов подавления эха
и шумов. Кроме того, нередко сквозной канал,
соединяющий два аппаратных аудиопорта, ре
ализуется в форме двух полуканалов, между ко
торыми располагается модуль аудиообработки.
Аудиоподсистема — совокупность программ
ных модулей, отвечающих за прием, передачу,
обработку, запись и проигрывание звука, то есть помимо сквозной передачи звука аудиоподси
стема может включать в себя модули звукоза
писи, генерации тонов и сигналов, алгоритмы
распознавания речи и другие компоненты ци
фровой обработки звуковой информации.
Взаимодействие
с аппаратными портами
Поскольку в телематической системе имен
но аппаратные порты служат основными ис
точниками и потребителями звуковой инфор
мации и во многом определяют особенности
последующей обработки звука, уместно на
чать рассмотрение с проблем, связанных с про
граммированием взаимодействия программ
ной аудио-подсистемы с оборудованием.
Конкретный алгоритм обмена данными
с аппаратурой сильно зависит от архитекту
ры разрабатываемого устройства. Однако су
ществует ряд общих принципов, заслужива
ющих отдельного анализа.
Обмен с аппаратным портом, как правило,
происходит в блочном режиме, так как прием
и передача отдельных отсчетов требуют микро
секундных реакций системы, что редко выпол
нимо на практике. Чаще всего некоторый уро
вень буферизации обеспечивается самим обо
рудованием в виде комбинации из аппаратно
реализованного FIFO-буфера и прерывания,
генерируемого по получении заданного числа
буферизованных отсчетов. Перенос данных
между основной памятью системы и аппарат
ной очередью входит в процедуру обработки
прерывания. Правда, процесс буферизации ау
диоданных далеко не всегда исчерпывается ра
ботой с аппаратной очередью. Очень часто
программная система работает с аудиокадра
ми заданного размера, причем обеспечить не
обходимый размер путем одной только наст
ройки соответствующих уровней заполнения
FIFO невозможно или нецелесообразно, на
пример из-за слишком большого числа возни
кающих прерываний. В этом случае процеду
ра разбиения на кадры усложняется, посколь
ку требуется перегруппировка данных.
Размер аппаратного буфера обычно выбира
ется исходя из разумной частоты прерываний
так, чтобы процедуры их обработки не занима
ли больше единиц процентов общего времени
работы приложения. В этом случае не возника
ет серьезных проблем с диспетчеризацией пре
рываний и долговременной блокировкой испол
нения системных процессов. Для большинства
прикладных задач оптимальной является длина
аппаратного буфера, при которой количество
вмещаемых им звуковых отсчетов соответству
ет 1–10 миллисекундам звучания. Конкретная
величина этого времени зависит от возможнос
тей аппаратуры, а также общей архитектуры
аудиоподсистемы. Взаимодействие с аппарату
рой существенно упрощается и ускоряется в слу
чае, если длина аппаратных буферов равна или
кратна длине кадров, используемых другими эле
ментами аудиоканала.
Если исключить вопросы, связанные с конфи
гурированием оборудования и непосредствен
ным управлением его поведением и не относящи
еся напрямую к проблемам организации звуко
вого потока, можно выделить две типовые задачи взаимодействия между программной системой
и аппаратно реализованным аудиопортом. Пер
вая из них — получение звукового потока вне
системы, вторая — вывод звука в порт-прием
ник. Несмотря на то что в целом эти задачи ду
альны, каждая из них имеет определенную спе
цифику, а вторая, как правило, порождает боль
ше проблем для архитектора и разработчиков.
Связано это с тем, что в случае ввода данных их
поступление синхронизируется извне и задачей
программной части является лишь своевремен
ное считывание полученных отсчетов, в то вре
мя как при выводе данных приложение должно
синхронизировать их готовность со скоростью
вывода. Возможность своевременной подготов
ки выходных аудиоданных определяется времен
ными параметрами приложения и существенно
зависит от временных характеристик других про
цессов, параллельно исполняемых в системе,
а также специфики алгоритмов выполнения про
межуточной обработки звукового потока.
Рассмотрим сперва типовой случай получения
данных от аппаратного порта-источника. Как уже
отмечалось выше, этот процесс обычно иници
ируется возникновением прерывания при опре
деленном уровне заполнения аппаратной очере
ди. Следует обратить внимание, что процесс про
граммного считывания данных процедурой
обслуживания прерывания, как правило, доста
точно длителен, и за это время в аппаратной оче
реди источника скапливается несколько допол
нительных отсчетов, отсутствовавших на момент
генерации прерывания. Поэтому не рекоменду
ется выставлять уровень заполнения аппаратной
очереди, при котором происходит генерация пре
рывания, на предельную длину очереди, чтобы
избежать возможного ее переполнения.
Отсчеты, полученные из аппаратной очереди,
складываются в программный буфер. По запол
нении очередного кадра он отправляется на обра
ботку программными модулями более высокого
уровня, а последующие отсчеты размещаются
в следующем пакете. Нужно обратить внимание,
что, за исключением частного случая, когда дли
ны программного и аппаратного буфера равны,
для заполнения одного программного кадра мо
жет потребоваться более одного считывания дан
ных из аппаратного порта. Реже встречается си
туация, когда данные, полученные от оборудова
ния, приходится размещать более чем в одном
программном буфере. С точки зрения регулярно
сти следования звуковых кадров такой случай
чрезвычайно нежелателен, поэтому следует избе
гать конфигурирования чрезмерно длинных ап
паратных и коротких программных буферов.
Регулярность передачи пакетов в звуковой
полуканал является основной задачей при про
граммировании взаимодействия с входным ау
диопортом. Многие алгоритмы обработки зву
ка построены исходя из предположения, что
пакеты поступают с определенным интерва
лом. Кроме того, нерегулярность кадров может
негативно сказаться на производительности си
стемы. Например, последовательная обработ
ка нескольких пакетов высокоприоритетным
процессом на длительное время прервет испол
нение других задач и может вызвать наруше
ние сроков их завершения. Такая ситуация воз
никает в случае слишком длинной аппаратной
очереди, когда один аппаратный кадр укладывается в несколько программных. Если не при
нять дополнительных мер, то процедура обра
ботки прерывания породит последовательность
звуковых буферов, поступающих в систему
практически одновременно. Наконец, нерегу
лярное поступление кадров усложняет анализ
поведения системы, делает ее менее предсказу
емой, что в конечном итоге приводит к слож
новыявляемым ошибкам.
Для обеспечения регулярности поступления
кадров от входного порта целесообразно уста
навливать уровень генерации прерывания
на такую длину аппаратной FIFO-очереди, что
бы она укладывалась в программный кадр це
лое число раз. Ввиду возможного поступления
дополнительных отсчетов в процессе чтения
из очереди не следует организовывать проце
дуру чтения данных до исчерпания аппаратной
очереди. Вместо этого имеет смысл считывать
фиксированное количество данных, соответ
ствующее установленной предопределенной
позиции уровня генерации прерывания.
Тем не менее, как будет показано ниже,
в случае реализации сквозного канала нерегу
лярность следования входных буферов обыч
но не приводит непосредственно к задержкам
выходных данных.
Работа с портом-приемником выглядит бо
лее простой, но часто порождает больше про
блем, нежели получение звука. Здесь задачей
приложения является запись в аппаратный бу
фер последовательности отсчетов, предназна
ченных для проигрывания. Эта запись может
быть как синхронной с работой приложения,
то есть происходить по мере готовности дан
ных, так и асинхронной, по прерыванию, уве
домляющему об исчерпании аппаратного бу
фера до заданного уровня. Второй вариант ча
ще применяется на практике, так как позволяет
проще контролировать как моменты време
ни, когда новая порция данных должна быть
подана на выход, так и размер этих порций.
Основной сложностью при организации вы
вода аудиоданных является проблема нехват
ки данных. Отсутствие данных возникает в слу
чае, когда аппаратная FIFO-очередь опустоше
на и получен аппаратный запрос на выдачу
очередного отсчета данных, но приложение еще
не сформировало следующий звуковой кадр.
В этом случае аудиоподсистема вынуждена вы
давать приемнику либо постоянный сигнал—
«тишину», либо предварительно сгенерирован
ный «комфортный» шум. Последнее позволя
ет сгладить акустический эффект недостатка
данных, который в противном случае прояв
ляется в виде хорошо слышимого щелчка.
Для решения проблемы нехватки данных
в состав драйвера аудиопорта включается оче
редь звуковых кадров. Поддерживая в ней не
которое предопределенное количество гото
вых пакетов, можно гарантировать, что по ис
черпании аппаратного буфера приложение
будет иметь уже сформированные данные для
продолжения вывода звука без пауз. Естествен
но, в силу конечной длины очереди обеспечи
ваемая ею толерантность к задержкам ограни
чена, но для большинства задач она достаточ
на, чтобы компенсировать неравномерность
следования пакетов, вызванную конкуренци
ей параллельных процессов.
В случае, если допустимая скорость подачи
аудиоданных в промежуточные процедуры об
работки ограничена (в частности, при их не
реентерабельной реализации), аналогичная
очередь буферов должна быть реализована
и для входного порта. Такое решение позволя
ет избежать переполнения, то есть ситуации,
при которой процедура считывания данных
из аппаратной очереди не может их разместить
в программном буфере, так как предыдущий
кадр еще не передан на обработку.
Входная и выходная очереди звуковых ка
дров попутно позволяют решать еще одну
серьезную задачу — разделение во времени
процедур обслуживания событий портов, ис
полняемых на уровне прерываний, и опера
ций звуковой обработки, реализуемых в ви
де процессов операционной системы.
Задержки при сквозной
передаче звука
Одним из наиболее важных свойств сквоз
ной передачи аудиоданных является задержка,
вносимая реализуемой системой. В простейшем
случае она складывается из времени получения
данных от входного порта, времени, затрачива
емого на обработку звука, и времени передачи
данных через выходной порт. В случае отсутст
вия промежуточных очередей эта задержка яв
ляется переменной и зависит от времени испол
нения задач преобразования звука, которые,
в свою очередь, могут быть вытеснены други
ми процессами на неопределенный срок.
Между тем, требования, предъявляемые
к системе, часто не допускают ни существен
ных колебаний суммарной задержки прохож
дения звука, ни превышения ее абсолютной
величины предварительно заданного уровня.
Вариации задержки приводят к нарушениям
в работе алгоритмов подавления эха, а макси
мально допустимая задержка, как правило, оп
ределяется внешними спецификациями на об
щую задержку в звуковом канале. Например,
задержка в телематическом устройстве обыч
но не должна превышать 30 миллисекунд, что
является формальным требованием большин
ства крупных автопроизводителей.
Использование для входного и выходного
портов очередей буферов позволяет обеспечить
независимость общей задержки от времени ис
полнения промежуточных алгоритмов аудио
обработки. Чтобы убедиться в этом, рассмот
рим состояние одного из каналов системы пе
редачи звука в произвольный момент времени
в стационарном режиме, когда отсутствуют эф
фекты переполнения входной аппаратной оче
реди и недостатка данных в выходной очереди.
Общая задержка распространения отдельного
звукового отсчета складывается из трех величин:
- T1 — времени с момента попадания отсче
та во входную аппаратную очередь до мо
мента срабатывания прерывания по запол
нению (до заданного уровня) входной ап
паратной очереди; - T2 — времени с момента срабатывания пре
рывания по опустошению очереди выход
ного порта до момента выхода отсчета на
ружу из аппаратной очереди, заполненной
при обработке упомянутого прерывания; - T3 — времени, прошедшего между момен
тами срабатывания указанных выше пре
рываний в применении к одному и тому же
кадру аудиоданных.
Рассмотрим вариант с одинаковыми часто
тами дискретизации звука во входном и выход
ном портах. Для упрощения положим, что все
программные буферы имеют одинаковую дли
ну и вмещают ровно Mотсчетов каждый, а уро
вень генерации прерываний (watermark) вход
ной аппаратной очереди установлен равным
той же величине M. Уровень генерации преры
вания по опустошению очереди выходного пор
та примем равным K. При этом в аппаратной
очереди входного порта в рассматриваемый мо
мент времени находится х отсчетов, а выходно
го— у отсчетов. Выходная очередь содержит
N кадров, готовых к отправке, а входная —
L принятых, но еще не обработанных. Кроме
того, еще S кадров находится в обработке, то есть
переданы из входной очереди в систему, но еще
не возвращены в выходную очередь.
Начнем с анализа суммарной задержки в ап
паратных очередях (Т1 и Т2). Рассмотрим от
счет, только что принятый во входную аппа
ратную очередь. Поскольку в данный момент
в очереди до уровня watermark имеется M–x
свободных ячеек, прерывание по заполнении
аппаратной очереди возникнет через (М–х)/f
секунд, где f — частота дискретизации отсче
тов. При этом процедура обработки прерыва
ния поместит рассматриваемый отсчет на по
зицию x программного кадра. Этот отсчет бу
дет записан в очередь выходного порта
на позицию x+K. Соответственно, его вывод
осуществится через (x+K)/f секунд с момента
вызова обработчика прерывания выходной
очереди, а суммарное время задержки в двух
аппаратных очередях составит:
T1 + T2 = (M – x)/f + (x + K)/f =
= (M + K)/f (1)
Очевидно, что это время не зависит от по
зиции отсчета в буфере, то есть от того, в ка
кой именно момент по отношению к входно
му порту рассматривается система.
Процедура перемещения буфера в аппарат
ную очередь может занимать длительное время
и превышать 1/f — время выхода очередного от
счета из выходной очереди. Поэтому следует от
метить, что позиция x+K рассчитана на момент
возникновения прерывания выходной очереди,
а не на момент физического помещения рассма
триваемого отсчета в выходную очередь.
Рассчитаем теперь, какое время пройдет
с момента прерывания на чтение рассматри
ваемого отсчета из входной очереди в буфер
до момента прерывания на запись этого же от
счета из буфера в выходную очередь. Это вре
мя T3 складывается из времени, необходимо
го для вывода всех предыдущих буферов,
то есть N буферов выходной очереди, S буфе
ров, находящихся в обработке, и L буферов
входной очереди, а также времени задержки
прерывания выходной очереди относительно
прерывания входной очереди. Время вывода
предыдущих буферов равно
(MA(N+S+L))/f (2)
Задержка между прерываниями входной
и выходной очередей равна
(y–K)/f – (M–x)/f (3)
Складывая (1), (2) и (3), получаем искомую
задержку в системе
T = (MA(N+S+L)+y+x)/f (4)
В стационарном режиме (отсутствие пере
полнений и недостатка данных в аппаратных
очередях) величина T не зависит от времени.
Переходные процессы
В обычной ситуации перед открытием кана
ла величина S равна нулю, так как еще нет бу
феров для обработки. Также равна нулю вели
чина L, поскольку предзаполнение входной оче
реди не имеет смысла, ведь она вводится для
предотвращения переполнения, аNимеет пре
допределенное значение N0, равное количест
ву буферов выходной очереди, заполненных
предопределенными данными для предотвра
щения ситуации недостатка данных в выход
ной очереди сразу после открытия выходного
порта. В момент открытия входного канала
x принимает значение 0 и начинает монотон
но увеличиваться с частотой f. В момент откры
тия выходного канала величина y принимает
значение 0, после чего происходит чтение бу
фера выходной очереди в аппаратную очередь.
Если рассмотреть выражение (4) в указанный
выше момент открытия выходного канала, то за
держка звука в системе окажется равной
(MЅN0+x)/f. Поскольку входной и выходной
порты работают с одинаковой скоростью, эта за
держка остается постоянной при нормальной ра
боте канала вплоть до его закрытия. Величина x
лежит в пределах от 0 до M, значит общая за
держка звука может варьироваться на величину
от 0 до M/f, если моменты времени запуска вход
ного и выходного порта не синхронизированы.
Таким образом, для поддержания постоянст
ва задержки в системе между различными ее
стартами достаточно запустить входной и вы
ходной порты одновременно, либо, что слож
нее и, как правило, не имеет практического смыс
ла, запустить выходной порт с фиксированным
запаздыванием относительно момента открытия входного порта. Тогда задержка в момент
открытия выходного порта будет равна
(MЅN0/f)+d (5)
где d — запаздывание открытия выходного
порта относительно открытия входного, то есть
d=x/f в момент открытия выходного порта.
Далее мы будем исходить из предположения синхронного открытия портов, то есть
случая, когда d=0.
Толерантность к задержкам
Из выражения (5) следует, что задержка передачи звука в анализируемой системе зависит исключительно от количества буферов,
изначально помещенных в выходную очередь,
то есть от искусственно заданной величины смещения между моментами получения сигнала на входе и его подачи на выход.
Существует, однако, весьма существенное условие, необходимое для поддержания постоянной задержки в процессе работы канала. Поскольку наличие N0 предварительно подготовленных
буферов обеспечивает запас проигрываемого звука на время M×N0/f, по истечении этого срока
необходимо иметь хотя бы один вновь подготовленный буфер аудиоданных. Задержка промежуточной обработки на большую величину приводит к ситуации отсутствия данных на выходе
системы, поэтому она недопустима.
Более подробный анализ показывает, что
обеспечение максимального времени обработки звука M×N0/f недостаточно для предотвращения отсутствия выходных данных. В этом
легко убедиться, рассмотрев ситуацию, когда
первый же входной буфер задерживается в обработке на M×N0/f секунд. Легко заметить, что
после его помещения в выходную очередь в ней
имеется всего один кадр, и задержка обработки
следующего пакета более чем на M/f повлечет
ситуацию отсутствия данных для вывода.
Обобщив этот предельный случай, можно
убедиться, что задержка обработки любого буфера уменьшает толерантность системы к задержке при обработке следующего. Для стабильного функционирования аудио-подсистемы необходимо, чтобы средняя задержка обработки
кадра не превышала M/f, иначе средняя скорость
оттока буферов из выходной очереди будет превышать среднюю скорость поступления буферов, что рано или поздно приведет к ситуации
отсутствия данных. Однако в исключительных
случаях кратковременная задержка кадра может достигать M×N0/f без потери аудиоданных.
Хочется особо отметить роль величины N0,
то есть числа предустановленных буферов в выходной очереди. Очевидно, что если обработка
входных кадров всегда укладывается в M/f секунд,
аудиосистема функционирует стабильно даже
при N0=1. Эта ситуация характерна в случае, если приложение спроектировано с соблюдением
правил жесткого реального времени, гарантирующих своевременность реакции на все события.
Однако для более полного использования процессорного ресурса часто допускается кратковременный выход времени обработки за пределы
M/f. В этом случае величину N0необходимо увеличивать, повышая толерантность системы,
но увеличивая общую задержку звука в ней.
В большинстве практических приложений
величина N0 ограничена сверху максимально
допустимой задержкой в канале при одновременном требовании наилучшей надежности
звуковой подсистемы. В этом случае величину
N0 следует выбирать максимально допустимой, максимально увеличивая инвариантность
системы к задержкам алгоритмов обработки.
Следует также обратить внимание на то, что
наличие предустановленных кадров во входной очереди канала не влияет на толерантность системы к задержкам в модулях обработки звука. Это достаточно естественно, так
как входная очередь служит для избежания потерь данных из-за превышения текущей скорости поступления над скоростью обработки,
то есть предназначена для предотвращения переполнения, а не недостатка данных.
Легко заметить, что длины входной и выходной очередей жестко связаны между собой.
Поскольку общее число буферов в канале сохраняется постоянным, уменьшение длины
выходной очереди, вызываемое задержкой
промежуточной обработки пакетов, автоматически приводит к увеличению длины входной на соответствующую величину. Поэтому
объявление входной очереди длиной больше
N0 лишено практического смысла.
Аналогично нецелесообразно объявлять выходную очередь длиной более N0, поскольку
по логике своего функционирования она может временно оказываться короче, чем в начальный момент времени (при задержках поступления данных от задач промежуточной обработки), но не может становиться длиннее.
Знание этих фактов позволяет установить,
что длины входной и выходной очередей ка-
нала следует:
- устанавливать равными;
- выбирать максимально допустимыми, исходя из величины разрешенной системной
задержки (MЅN0/f), то есть равными N0 буферов каждая; - изначально обеспечивать предопределенную задержку между входными и выходными аудиоданными путем помещения N0 готовых кадров в выходную очередь канала.
Потери аудиоданных
и борьба с их последствиями
Введение предопределенной задержки передачи звука позволяет обеспечить толерантность аудиоподсистемы к ограниченным
по времени и величине задержкам в обработке данных. Но в случае, если задержка обработки данных превышает допустимый предел,
нехватка данных на выходе системы приводит
к опустошению выходной очереди.
В этом случае процедура обслуживания выходного порта не имеет готовых данных в момент получения запроса на их вывод и, следовательно, не может корректно обслужить данный запрос. В этой ситуации возможно одно
из двух алгоритмических решений — процедура может либо ничего не выдавать в выходной порт, либо выдавать некоторый заранее
подготовленный сигнал.
Первый подход аналогичен выдаче вместо
отсутствующих аудиоданных постоянного,
например нулевого, сигнала, т. е. «тишины».
Выбор этого пути существенно упрощает программную реализацию, однако вызывает существенное искажение выходного сигнала,
проявляющегося в виде пары щелчков — при
переходе от реальных данных к «тишине»
и обратно.
Второй подход сложнее в реализации,
но позволяет получить существенно меньшее
искажение воспринимаемого звука. Даже простое замещение потерянных данных последним успешно выведенным буфером дает значительное улучшение качества звучания.
Еще лучший результат получается при аппроксимации потерянного кадра гладкой
функцией, имеющей общие свойства транслируемого участка сигнала и непрерывной
в точках сочленения с соседними пакетами.
Можно предложить множество функций,
удовлетворяющих данным условиям, но их
анализ является предметом отдельного исследования. Исходя из собственного опыта,
для приложений, работающих преимущественно с телефонным сигналом, мы можем рекомендовать следующий алгоритм генерации
пропущенного кадра на основе предыдущего
пакета звуковых данных.
Пакет, замещающий пропущенный кадр, образуется из предварительно сохраненного предыдущего кадра путем линейного взвешивания значений аудиоотсчетов. Содержимое задержанного кадра на момент аппроксимации
неизвестно, однако в силу общей непрерывности и гладкости звукового потока его первый
отсчет должен иметь значение, близкое к значению последнего отсчета предыдущего пакета. Значит, первый отсчет подставляемого буфера должен быть близок или равен последнему отсчету предыдущего переданного кадра.
Это, в свою очередь, означает, что первый
и последний отсчеты замещающего буфера
должны иметь значения, близкие либо равные
друг другу и последнему отсчету буфера, предшествующего задержанному в обработке. Если
«псевдокадр» образуется из предыдущего, то для
его последнего отсчета это условие выполняется автоматически (он, естественно, равен самому себе) и коррекция необходима лишь в начале пакета. Одна из простейших формул для такой модификации имеет вид:
y[i] = (x[i] Ѕ i + x[M – i – 1] Ѕ
Ѕ (M – i – 1)) / (M – 1), i = 0…M – 1 (6)
где x — последний известный кадр, y — замещающий кадр, i — номер отсчета, M — длина кадра.
Данная формула дает гладкий сигнал, основанный на текущих характеристиках звукового потока и обеспечивающий плавный стык
как с предыдущим, так и с последующим кадром. При этом объем вычислений невелик.
Флуктуация задержки
при потере аудиоданных
Помимо потери качества звука, частично
компенсируемой экстраполяцией, подобной
предложенной выше, задержка обработки
аудиобуферов сверх критического времени влечет еще одно нежелательное следствие: из-за
включения в последовательность подаваемых
на выход буферов дополнительного «псевдокадра», проигрываемого вместо задержанных
данных, увеличивается общее количество кадров в канале и, следовательно, суммарная задержка между входом и выходом системы.
Для сокращения суммарной задержки необходимо исключить из обработки один из последующих кадров. Простейший способ сделать
это — отбросить пакет, доставленный в выходную очередь с опозданием. Однако на практике
этот подход имеет ряд негативных последствий.
Поскольку длительная задержка доставки
аудиопакетов возникает, как правило, при временной перегрузке программной системы высокоприоритетными процессами, весьма вероятно, что чрезмерно длительная обработка затронет и ряд последующих кадров. Соответственно, выкинув первый же задержанный буфер,
мы получаем повторную ситуацию отсутствия
данных для передачи. Причем тот же алгоритм
будет применен и к следующему пакету, то есть
вместо локализации последствий задержки данных получается их распространение на существенно более длительный временной интервал.
На практике это приводит к тому, что вместо
щелчка, вызванного потерей одиночного кадра на выходе системы, появляются сильный
шум и множественные искажения.
Для избежания этого эффекта удаление лишнего кадра имеет смысл производить через некоторое время после возникновения события
отсутствия данных в очереди выходных буферов, то есть когда процесс передачи и обработки аудиопотока стабилизируется. Если длины
входной и выходной очередей равны, а в обработке находится не более одного буфера, отбрасывание лишнего кадра происходит автоматически, так как при отсутствии данных в выходной очереди происходит переполнение входной.
Однако поскольку общая задержка в канале, как
правило, невелика, в ряде случаев такая «автоматизация» может привести к тому, что на момент отбрасывания буфера состояние аудиоподсистемы еще не успело стабилизироваться.
При такой ситуации имеет смысл удлинить
входную очередь и производить директивное
выбрасывание лишних буферов в моменты, когда система в целом не испытывает перегрузки.
Одним из алгоритмов поддержания постоянной задержки в системе является измерение
среднего суммарного количества заполненных
буферов во входной и выходной очередях и отбрасывание одного из буферов входной очереди, если это среднее значение долгое время
превышает заданную величину.
Следует отметить, что выбрасывание реальных (а не искусственно сгенерированных внутри аудиоподсистемы) блоков аудиоинформации приводит к искажению выходного звукового потока. Однако практика показывает,
что при передаче речи удаление кадра длительностью в несколько миллисекунд практически не заметно на слух, если не осуществляется на фоне других факторов, снижающих качество воспринимаемого звука.
Практика применения
Обобщая вышесказанное, можно предложить набор практических рекомендаций
по проектированию систем программной передачи звука.
- Данные следует передавать пакетами фиксированной длины. Обработка единичных звуковых отсчетов приводит к существенному
снижению производительности программной системы, зачастую неприемлемому с точки зрения предъявляемых к ней требований.
Целесообразно оперировать кадрами равной
длины как минимум в рамках одного канала. Это позволяет избежать нерегулярности
доставки пакетов.Однако если при передаче данных от входного к выходному порту канала производится
изменение частоты дискретизации (то есть увеличивается или уменьшается суммарное число отсчетов), длина или количество пакетов также по необходимости изменяются. В этом случае следует по возможности использовать выходные кадры, кратные по размеру входным,
сохраняя общее число пакетов неизменным.
В этом случае регулярность следования пакетов и изложенные выше положения, касающиеся задержек в системе, не нарушаются.Если отношение входной и выходной частот дискретизации таково, что обеспечить одинаковость выходных кадров не удается, следует подбирать такие размеры кадров, чтобы их
длина варьировалась незначительно. - Входной и выходной порты должны запускаться синхронно. Величина задержки звука в канале может быть гарантирована только в случае синхронизированного запуска входного
и выходного портов канала. Если это нереализуемо посредством возможностей оборудования, необходимо предусмотреть программную
синхронизацию, например, путем принудительной очистки выходной аппаратной очереди в момент поступления первого прерывания
от входного порта после его открытия. - Канал должен содержать входную и выходную очереди буферов. Введение входной и выходной очередей звуковых кадров серьезно
повышает толерантность системы к внутренним задержкам обработки звука. Длины
обеих очередей разумно выбирать равными. Абсолютное значение длины очереди
буферов однозначно вычисляется из максимальной допустимой общесистемной задержки звука. Использование более длинных очередей не приводит к повышению
надежности системы. - Перед открытием аудиоканала следует заполнить выходную очередь буферов фиктивными кадрами для поддержания постоянного числа буферов в системе после открытия
канала. Исходное состояние выходной очереди — заполненное на максимальную длину за вычетом одного кадра, а входной — пустое. В условиях отсутствия задержек промежуточных алгоритмов обработки звука
состояние обеих очередей соответствует исходному с точностью до ±1 буфера. - При наличии входной и выходной очередей
буферов кратковременные задержки при
промежуточной обработке звука не влекут
за собой искажение аудиопотока на выходе
системы. - Поскольку суммарная задержка звука определяется выражением (MЅN0/f), обычно существует возможность одновременно варьировать длину буферов и их количество,
не изменяя задержку. При этом размер буфера рекомендуется выбирать максимально
большим из соображений ограничения накладных расходов по его обработке (на переход к обработке следующего буфера требуется дополнительное время). Однако одновременно необходимо помнить, что малое число
буферов не позволяет системе гибко реагировать на неравномерность загрузки процессора. В связи с этим задача выбора оптимального соотношения между размером кадра
и числом кадров в системе на практике является нетривиальной и, как правило, требует
индивидуального подхода.