потоком.
20.3. Режимы кодирования стерео
Существуют несколько методов кодирования стерео аудио информации[33].
• Dual channel37 — два абсолютно независимых («совсем разных») канала. Битрейт делится на два канала.
Может использоваться для речевого сопровождения на разных языках.
• standard stereo — два независимых канала. Битрейт варьируется в зависимости от сложности сигнала в каждом канале.
• Joint stereo[34] — основан на использовании избыточности стерео-информации.
I MS Stereo. Кодируются не левый и правый канал, а их суммарная составляющая и разностная. Разностный канал в некоторых случаях (Lame encoder) кодируется с меньшим битрейтом.
I Intensity Stereo (MS/IS Stereo). Кодируется суммарная составляющая. Вместо разностной составляющей кодируется отношение мощностей сигнала в разных каналах.
Особенность: повышает качество кодирования на особо низких битрейтах, но происходит потеря фазовой информации, и теряется любой противофазный сигнал.
20.4. Психоакустические форматы
• AAC[35] — разрабатывался как преемник MP3 компанией Fraunhofer при участии AT&T, Sony, NEC и Dolby. Проект не был доведен до конца. На данный момент существует большое число несовместимых друг с другом форматов на основе AAC[36].
• TwinVQ — формат, разработанный компанией NTT[37]. Считается старейшим «конкурентом» MP3. Лицензией на право распространения этого формата владеет фирма Yamaha.
• WMA42 — формат сжатия аудиоданных от компании Microsoft.
Первоначально интерфейс со звуковыми устройствами был введен в Windows 3.x под названием MME[38]. Звуковые устройства в Windows относятся к классу Multimedia/Audio; в этот класс входят два три устройств:
Взаимодействие приложения с драйвером организуется в виде взаимного обмена потоками звуковых данных в реальном времени. Для переноса потоков между приложением и звуковым драйвером используется звуковой буфер. Звуковые буферы создаются приложением и затем передаются драйверу:
• пустые — для устройств ввода,
• заполненные звуковыми данными — для устройств вывода.
Применяется концепция связанной цепочки программных буферов.
22.1. Способы кодирования звука
При работе со звуковыми адаптерами чаще всего используется традиционный способ цифрового кодирования PCM[39].
Ряд мгновенных значений звуковой амплитуды, следующих друг за другом с частотой дискретизации, представляется рядом чисел выбранной разрядности. Значения пропорциональны величине амплитуды. Именно в таком виде звуковой поток снимается с выхода АЦП или подается на вход ЦАП.
Однако, наряду с предельной простотой, PCM обладает существенной избыточностью:
Звук передается настолько точно, насколько это возможно при выбранных параметрах оцифровки. На первое место выходит задача минимизации скорости и объема звукового потока, отдельными параметрами точности и качества можно пренебречь.
Обрабатывать звук в PCM способен любой звуковой адаптер!
22.2. Формат потока
Формат потока — cовокупность основных параметров потока.
• способ кодирования — это главный параметр, он же признак формата[40].;
• частота дискретизации;
• количество каналов;
• разрядность отсчета.
22.3. Структура потока
Блок — наименьшая единица звукового потока . Размер каждого буфера должен быть кратен размеру блока.
В PCM блоком считается набор отсчетов, передаваемых за один период частоты дискретизации, то есть — один отсчет для монофонических потоков, два - для стереофонических, и так далее. Отсчеты могут быть 8-разрядными, 16-разрядными, 32-разрядными.
Современные звуковые адаптеры могут использовать 18-, 20- и 22-разрядные отсчеты. Отсчет выравнивается по старшей границе трех- или четырехбайтового слова, а лишние младшие разряды заполняются нулями. Трехбайтовые слова почти не используются и заменяются четырехбайтовыми.
С момента запуска потока драйвер отслеживает текущую позицию записи или воспроизведения, которая в любой момент может быть запрошена приложением. Для этого адаптеры используют очередь между преобразователями и встроенным процессором.
Драйвер отслеживает позицию путем подсчета количества звуковых блоков потока, переданных от приложения к устройству или наоборот.
22.4. Системные особенности
22.4.1. Несколько процессов
Звуковая подсистема Windows допускает работу с устройством нескольких процессов (клиентов) одновременно. Многие звуковые устройства поддерживают более одного клиента; устройство вывода смешивает проигрываемые клиентами звуковые потоки, а устройство ввода — «тиражирует» записываемый поток для всех подключенных клиентов.
Устройство, драйвер которого поддерживает не более одного клиента, не может быть повторно открыто до тех пор, пока клиент не закроет его. При попытке повторно открыть такое устройство звуковая подсистема возвращает ошибку, сигнализирующую о том, что устройство занято.
22.4.2. Wave Mapper
Для упрощения реализации основных операций со звуком Windows содержит службу переназначения — Wave Mapper. В Windows может быть установлено более одного звукового устройства. Существует понятие стандартного системного устройства ввода и стандартного системного устройства вывода.
В Windows имеется подсистема сжатия звука — ACM[41]. При помощи ACM возможно взаимное преобразование звуковых форматов — как внутри групп, так и между ними. Служба ACM может использоваться как автономно, через собственный отдельный интерфейс, так и автоматически службой
Wave Mapper.
Подсистема сжатия реализована в виде набора кодеков47, специальных драйверов ACM, которые и занимаются непосредственно переводом звука из одного формата в другой. ACM активизирует нужные кодеки по запрошенным форматам, снабжая их необходимыми параметрами.
При завершении обработки каждого буфера драйвер устанавливает в его заголовке флаг готовности, по которому приложение может определить, что драйвер освободил данный буфер.
Для асинхронных устройств гораздо более эффективным способом возврата буфера является уведомление (notification). Драйвер:
• либо вызывает заданную функцию приложения,
• либо активизирует событие (event),
• либо передает сообщение заданному окну или задаче (thread) приложения.
В параметрах функции или сообщения передается также указатель заголовка буфера.
Звуковая подсистема нумерует установленные устройства, начиная с 0. При установке нового устройства или удалении существующего нумерация изменяется. Во время работы программы в системе могут появиться или исчезнуть звуковые устройства. Вместо номера звукового устройства может использоваться ключ (handle) ранее открытого устройства. Система автоматически определяет, какое именно значение передано интерфейсной функции.
При открывании каждого звукового устройства система возвращает его идентификатор, или ключ (handle), по которому затем происходит вся остальная работа с устройством. Формально идентификаторы устройств ввода и вывода имеют различные типы
• HWAVEIN;
• HWAVEOUT.
Оба они эквивалентны типу HWAVE, который может использоваться для создания универсальных функций, не зависящих от типа устройства.
Ключи звуковых устройств не имеют ничего общего с ключами файлов, событий, окон, задач и т.п.
Если программе безразлично, с каким конкретно устройством она будет работать, либо работа ведется только со стандартным системным устройством, программа может ориентироваться только на службу переназначения. В противном случае программа определяет количество имеющихся в системе устройств ввода и/или вывода при помощи функций GetNumDevs.
При необходимости программа может запросить параметры и имена звуковых устройств при помощи функций GetDevCaps - например, чтобы сформировать меню доступных устройств для пользователя или найти устройство, удовлетворяющее заданным требованиям.
22.5. Алгоритм взаимодействия
Рассмотрим упрощенный алгоритм взаимодействия программы и звуковой подсистемы:
1: открыть (
2: <устройство> ,
3: <формат звукового потока> ,
4: <способуведомленияовыполнениизапрошенныхопераций>
5: );
6: буферы ← создать( <количество> );
7: заполнить_заголовки( <буферы> );
8: Если <сразу подготовить к передаче> | то |
9: подготовить_к_передаче( <буферы> ); 10: Если <цикл записи> то 11: Пока <запись> выполняем | /* Prepare */ |
12: заполнить очередь драйвера буферами /* AddBuffer */
13: записать поток /* Start */