Сообщений 0    Оценка 46        Оценить  
Система Orphus

Программирование микшеров и дополнительных устройств

Автор: Евгений Музыченко
Источник: Компьютер Пресс
Опубликовано: 14.07.2003
Исправлено: 10.12.2016
Версия текста: 1.0

Основные черты и понятия микшерной подсистемы
Линии
Активность линий
Соединения
Каналы
Органы управления и индикации
Индексы и идентификаторы
Отношение к подсистемам MIDI и Audio/Wave
Доступ к микшерам
Поддержка нескольких клиентов
Идентификаторы и ключи устройств
Программные события и уведомление о них
Именование интерфейсных функций
Общая схема взаимодействия программы и устройств регулировки
Средства разработки, включаемые файлы и библиотеки
Типы управляющих элементов
Типы объектов, идентифицирующих микшер
Структуры, используемые для связи с подсистемой
Структура MIXERCAPS
Структура AUXCAPS
Структура MIXERLINE
Структуры значений управляющих элементов
Структура MIXERCONTROL
Структура MIXERLINECONTROLS
Структура MIXERCONTROLDETAILS
Уведомления, передаваемые программе
Набор интерфейсных функций подсистем Aux и Mixer
Перечень интерфейсных функций
Значения, возвращаемые интерфейсными функциями
Описание интерфейсных функций
GetNumDevs - запрос количества устройств
GetDevCaps - запрос параметров и возможностей устройств
SetVolume - установка уровня сигнала для устройства aux
GetVolume - запрос текущего уровня сигнала для устройства aux
Open - открывание микшера
Close - закрывание микшера
GetLineInfo - запрос описателя линии
GetLineControls - запрос описателей управляющих элементов линии
GetControlDetails / SetControlDetails - запрос/установка состояния элемента
GetID - запрос системного номера микшера по ключу
Message - передача сообщения драйверу микшера или устройства aux
Пример программы, использующий интерфейс с микшерами

Демонстрационная программа - MixerCtl

Как было сказано в первой статье, посвященной программированию звука в Windows, базовый звуковой интерфейс (MME) включает три класса устройств - Wave (собственно цифровой звук), MIDI (синтезаторы и устройства управления в стандарте MIDI) и Mixer/Aux (микшеры и дополнительные устройства). Такая структура отражает устройство типового звукового адаптера, содержащего тракт цифрового звука, синтезатор и микшер, соединяющий выходы источников звука со входами приемных устройств. Микшеры, как вполне самостоятельные блоки звуковых адаптеров и виртуальных синтезаторов, также управляются в MME отдельной подсистемой, которая и будет описана в этой статье.

К дополнительным (auxiliary) устройствам относятся источники и приемники звуковых сигналов, внешние по отношению к звуковым адаптерам, но имеющие возможности управления от компьютера - например, приводы CD-ROM, внешние усилители и т.п. В отношении дополнительных устройств доступно только управление громкостью.

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

Подсистема управления дополнительными устройствами реализована, начиная с Windows 3.0 (Win16). Подсистема управления микшерами реализована только на платформе Win32, в системах Win16 ее нет. Строго говоря, подсистема Aux не относится к микшерам, однако имеет то же самое назначение. Фактически, микшерная подсистема в Win32 является развитием Aux в Win16.

Основные черты и понятия микшерной подсистемы

Линии

Выходы источников (source) звукового сигнала и входы приемников (destination) сигнала в терминах микшерной подсистемы Windows называются линиями (lines). Соответственной, линии могут быть входными (линии назначения, destination lines), и выходными (линии источников, source lines).

Важно, что смысл входов и выходов с точки зрения микшера и пользователя диаметрально противоположен. Для пользователя, находящегося снаружи звукового адаптера, разъем микрофона является входом (приемником) сигнала с микрофона (источника), а разъем для наушников - выходом (источником) сигнала, приемником которого являются наушники. Микшер же находится внутри адаптера, и для него микрофонный предусилитель является источником (выходной линией) сигнала с микрофона, а АЦП цифрового (Wave) тракта адаптера - приемником (входной линией), на который подается сигнал с выбранных выходных линий. Соответственно, выход ЦАП является выходной линией цифрового тракта, а вход оконечного усилителя мощности - входной линией.

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

Активность линий

Каждая линия может находиться в активном либо неактивном состоянии. Неактивное состояние линии означает, что соответствующее ей устройство отключено и сигнал либо не генерируется, либо не воспринимается устройством. Активное состояние означает, что устройство включено и способно генерировать либо воспринимать сигнал в линии, однако ничего не говорит о наличии в линии какого-либо сигнала в данный момент времени. Например, открывание устройства типа Wave Out переводит его выходную линию в активное состояние; появление же сигнала на этой линии зависит от выполнения открывшим приложением функций вывода звуковых данных. Заглушенные (muted) линии становятся неактивными.

Линии, относящиеся к устройствам, которые не могут быть программно включены или выключены, всегда находятся в активном состоянии.

Соединения

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

Инженеру, знакомому с электрическими системами, такой подход может показаться странным - в электрических системах могут объединяться входы, но не выходы; однако в микшерах используется несколько другая технология - открывания/закрывания различных источников сигнала, которые затем смешиваются в один сигнал и далее подаются на выбранное приемное устройство.

Каналы

Каждая линия состоит из одного или нескольких звуковых каналов. Монофоническая линия состоит из одного канала, стереофоническая - из двух и т.п. Соединения выполняются только над линиями в целом, когда все каналы выходной линии направляются в соответствующие каналы входной, однако управление параметрами сигнала может быть раздельным в каждом из каналов.

Органы управления и индикации

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

Понятия органа управления и индикатора являются полностью виртуальными - при обращении к устройству микшера программа запрашивает или устанавливает состояния движков, переключателей, параметров, а отображение всех этих элементов пользователю остается в ведении самой программы. Например, стандартное микшерное приложение Windows - SndVol32 - предоставляет унифицированный интерфейс пользователя с любым возможным микшерным устройством; при добавлении в систему нового устройства, имеющего драйвер микшера, оно также может управляться с помощью этого стандартного приложения.

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

Орган управления может состоять из одной или нескольких частей - например, эквалайзер состоит из нескольких частотных полос, для каждой из которых имеется свой независимый регулятор уровня.

Индексы и идентификаторы

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

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

Отношение к подсистемам MIDI и Audio/Wave

Поскольку микшерная подсистема является частью MME - она несколько похожа на подсистемы MIDI и Audio/Wave, однако это сходство касается лишь общей схемы построения интерфейса. В отличие от устройств типа Wave и MIDI, являющихся устройствами ввода/вывода данных, микшеры являются устройствами управления с принципиально иной структурой. Единственное, что объединяет все эти подсистемы - общая структура набора интерфейсных функций и способы уведомления приложения о событиях.

Тем не менее, поскольку микшер чаще всего является частью того же звукового адаптера, что и устройства Wave/MIDI, подсистема предоставляет средства связи между ними. В частности, можно обратиться к микшеру заданного устройства типа Wave/MIDI, определить, к какому из устройств относится заданная линия, и т.п.

Для устройств Aux предусмотрено наличие службы переназначения (Mapper), которая, впрочем, нигде не реализована. В микшерной подсистеме службы переназначения нет.

Доступ к микшерам

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

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

Поддержка нескольких клиентов

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

Идентификаторы и ключи устройств

При открывании микшера подсистема возвращает его идентификатор, или ключ (handle), по которому затем происходит обращение к микшеру. Ключи микшерных устройств имеют тип HMIXER.

Как уже говорилось, к микшеру можно обращаться, и не открывая его - в этом случае вместо ключа указывается номер самого микшерного устройства, либо номер/ключ одного из других устройств, связанных с микшером - Wave, MIDI или Aux. Смысл указанного значения в этом случае задается специальным флагом.

Программные события и уведомление о них

В микшерной подсистеме может возникать два типа событий - изменение состояния линии (line status change) и изменение состояния элемента управления (control status change). О наступлении каждого из этих событий подсистема может уведомлять программу с тем, чтобы она обновила состояние органов управления и индикаторов на экране.

Именование интерфейсных функций

Как и предыдущих статьях, я буду ссылаться на интерфейсные функции, опуская префикс mixer и используя только основное смысловое имя функции. В прототипах будут даны полные имена функций.

Общая схема взаимодействия программы и устройств регулировки

Для работы с дополнительными (aux) устройствами программа может получить их общее количество посредством функции GetNumDevs, после чего запросить параметры конкретных устройств функцией GetDevCaps. При поддержке устройством регулировки громкости может быть запрошена текущая громкость функцией GetVolume, и установлен другой уровень - функцией SetVolume. Все остальные операции, если они поддерживаются устройством, выполняются через функцию передачи специального сообщения Message.

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

При косвенном обращении программа задает параметр объекта, определяющего микшер - номер или ключ открытого звукового устройства, связанного с микшером, попутно указывая соответствующий флаг типа объекта.

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

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

Для получения параметров заданных органов управления и индикации служит функция GetLineControls, возвращающая описание одного, нескольких или всех органов.

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

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

Для изменения состояния служит функция SetControlDetails. Именно эта функция воздействует на заданные органы управления и индикации, а через них - на проходящий по микшеру звуковой сигнал. При наличии у программы пользовательского интерфейса эта функция вызывается в ответ на изменение пользователем положений и состояний органов управления в диалоговом окне.

После завершения сеанса работы с открытым микшером он должен быть закрыт функцией Close.

Средства разработки, включаемые файлы и библиотеки

Как всегда, описывается программирование на языке C/C++ в среде Microsoft Visual C++.

Все необходимые константы, типы, структуры и прототипы функций подсистемы определяется в файле MMSYSTEM.H, который по умолчанию включается в компиляцию из общего файла WINDOWS.H. Дополнительные, редко используемые константы определены в файле MMREG.H.

Интерфейсные функции импортируются из библиотеки WINMM.LIB.

Типы управляющих элементов

В настоящее время микшерная подсистема поддерживает шесть классов управляющих элементов, по одному или нескольким типам элементов в каждом классе. Имена констант классов имеют префикс MIXERCONTROL_CT_CLASS_, имена констант типов - префикс MIXERCONTROL_CONTROLTYPE_.

Класс FADER - регулятор уровня, движок типа ползункового регулятора, ориентирован обычно вертикально. Диапазон значений - 0..65535.

Класс LIST - список текстовых строк, которые могут быть отмечены или выбраны (selected). Значения - логического типа (отмечена или не отмечена строка в списке):

Класс METER - индикатор состояния, уровня и т.п. Значения - логического, знакового и беззнакового типов:

Класс NUMBER - числовое поле, допускающее непосредственный ввод значения пользователем.

Класс SLIDER - подобен регулятору уровня, но ориентируется обычно горизонтально. Представляют целые знаковые (signed) значения.

Класс SWITCH - двухпозиционный переключатель. Представлен логическим (boolean) значением.

Класс TIME - числовое поле для ввода временных интервалов, представляемых беззнаковыми значениями в диапазоне 0..232 - 1.

Класс CUSTOM - произвольный элемент, полностью управляется драйвером конкретного микшера.

Дополнительно определены константы типов представлений значения, имеющие префикс MIXERCONTROL_CT_UNITS_ - CUSTOM, BOOLEAN, SIGNED, UNSIGNED, DECIBELS, PERCENT.

Числовые значения констант типов управляющих элементов определяется через битовое объединение кода класса, кода подкласса и кода представления. Маски битовых полей в результирующем значении также определены константами с префиксом MIXERCONTROL_CT_:

Виды подклассов и структуру констант типов можно найти в файле MMSYSTEM.H.

Как уже было сказано, все управляющие элементы поддерживаются микшерной подсистемой только на уровне значений, передаваемых между программой и драйвером микшера. Отображение органов управления и их значений пользователю - задача приложения, реализующего управление микшером.

Типы объектов, идентифицирующих микшер

При выполнении большинства операций требуемый микшер может быть задан прямо - своим номером или ключом, либо косвенно - номером или ключом связанного с ним звукового устройства. Для уточнения типа объекта, задающего микшер, используются следующие кодовые константы, имена которых имеют префикс MIXER_OBJECTF_:

MIDIIN Системный номер входного MIDI–порта.
MIDIOUT Системный номер выходного MIDI–порта.
MIXER Системный номер микшера.
WAVEIN Системный номер входного звукового (Wave) порта.
WAVEOUT Системный номер выходного звукового порта.
AUX Системный номер дополнительного (auxiliary) устройства.
HMIDIIN Ключ открытого входного MIDI–порта.
HMIDIOUT Ключ открытого выходного MIDI–порта.
HMIXER Ключ открытого микшера (по умолчанию).
HWAVEIN Ключ открытого входного звукового (Wave) порта.
HWAVEOUT Ключ открытого выходного звукового порта.

Структуры, используемые для связи с подсистемой

Как и в подсистеме сжатия звука (ACM), большинство структур содержит поле cbStruct, в которое приложение перед обращением к микшерной подсистеме должно занести размер (в байтах) буфера памяти, отведенного под структуру. Это позволяет подсистеме отследить, в каком интерфейсе работает приложение - ASCII или UNICODE, а также - на какую версию подсистемы ориентирован вызов. После обработки запроса подсистема возвращает в поле cbStruct действительный размер данных, занесенных в указанную область памяти.

Структура MIXERCAPS

Описывают свойства и характеристики устройства. Все поля структур заполняются только подсистемой и драйвером микшера.

WORD  wMid;
WORD  wPid;
MMVERSION  vDriverVersion;
CHAR  szPname [MAXPNAMELEN];
DWORD  fdwSupport;
DWORD cDestinations;

Структура AUXCAPS

Описывает параметры и возможности дополнительного (aux) устройства.

WORD  wMid;
WORD  wPid;
MMVERSION  vDriverVersion;
CHAR  szPname [MAXPNAMELEN];
WORD  wTechnology;
WORD wReserved1;
DWORD  dwSupport;
AUXIN Устройство ввода сигнала с внешнего источника (предусилитель).
CDAUDIO Аналоговый выход привода CD-ROM.
VOLUME Поддерживается регулировка громкости (уровня сигнала).
LRVOLUME Поддерживается раздельная по каналам регулировка громкости.

Структура MIXERLINE

Описывает параметры линии микшера. Все поля структуры, кроме явно оговоренных, устанавливаются микшерной подсистемой.

DWORD cbStruct;
DWORD dwDestination;
DWORD dwSource;
DWORD dwLineID;
DWORD fdwLine;
DWORD dwUser;
DWORD dwComponentType;
DWORD cChannels;
DWORD cConnections;
DWORD cControls;
CHAR szShortName[MIXER_SHORT_NAME_CHARS];
CHAR szName[MIXER_LONG_NAME_CHARS];
struct { 
  DWORD dwType;
  DWORD dwDeviceID;
  WORD  wMid;
  WORD  wPid;
  MMVERSION vDriverVersion;
  CHAR  szPname[MAXPNAMELEN];
} Target;
ACTIVE Линия активна.
DISCONNECTED Линия отключена (не имеет ни одного соединения). В этом состоянии воздействие на органы управления не дает никакого эффекта.
SOURCE Линия является выходной.
DST_WAVEIN Регулируемый вход АЦП цифрового (Wave) тракта адаптера, предназначенного для записи звука от внешних источников.
DST_SPEAKERS Регулируемый вход оконечного усилителя мощности громкоговорителей (и наушников, если нет отдельного усилителя для них).
DST_HEADPHONES Регулируемый вход отдельного оконечного усилителя мощности наушников, если он есть.
DST_LINE Нерегулируемый линейный вход.
DST_TELEPHONE Вход усилителя, выведенного в телефонную линию.
DST_VOICEIN Вход для записи/распознавания голоса. Большинство адаптеров не имеют отдельного голосового входа и поддерживают только общий вход DST_WAVEIN.
DST_MONITOR Вход контрольного (мониторного) усилителя, используемого для слежения за проходящим в тракте сигналом.
DST_DIGITAL Нерегулируемый цифровой вход (DAT-магнитофона, CD-проигрывателя и т.п.).
DST_UNDEFINED Вход неопределенного типа. Используется для всех входов, не подпадающих под вышеперечисленный набор.
SRC_WAVEOUT Выход ЦАП цифрового тракта адаптера.
SRC_MICROPHONE Регулируемый выход микрофонного предусилителя.
SRC_AUXILIARY Регулируемый выход линейного предусилителя. Обычно берет сигнал с основного линейным входа адаптера.
SRC_COMPACTDISC Выход предусилителя сигнала с CD-ROM.
SRC_LINE Нерегулируемый выход дополнительного линейного предусилителя (поддерживается не всеми микшерами).
SRC_PCSPEAKER Выход предусилителя сигнала с системного громкоговорителя (PC Speaker).
SRC_SYNTHESIZER Выход встроенного музыкального синтезатора.
SRC_ANALOG Выход источника аналогового сигнала.
SRC_DIGITAL Нерегулируемый выход источника цифрового сигнала.
SRC_TELEPHONE Выход предусилителя сигнала с телефонной линии.
SRC_UNDEFINED Выход источника неопределенного типа. Используется, если источник не подпадает под вышеописанные типы.
AUX Дополнительное (auxiliary) устройство.
MIDIIN Звуковой вход MIDI–синтезатора. Некоторые синтезаторы имеют звуковые входы для обработки внешнего сигнала встроенным эффект-процессором.
MIDIOUT Выход MIDI–синтезатора.
WAVEIN Вход АЦП цифрового звукового тракта.
WAVEOUT Выход ЦАП цифрового звукового тракта.
UNDEFINED Устройство неопределенного типа. Остальные поля структуры Target не имеют смысла.

Структуры значений управляющих элементов

Описывают значения управляющих элементов различных типов - логического (Boolean), знакового (Signed) и беззнакового (Unsigned) целого и текстового списка (ListText).

Структура MIXERCONTROLDETAILS_BOOLEAN:

Используется для представления логических значений, имеет два смысла - нуль и не нуль.

LONG fValue;

Структура MIXERCONTROLDETAILS_SIGNED:

Используется для представления значений со знаком.

LONG lValue;

Структура MIXERCONTROLDETAILS_UNSIGNED:

Используется для представления беззнаковых значений.

DWORD dwValue;

Структура MIXERCONTROLDETAILS_LISTTEXT:

Используется для представления текстовых меток элементов управления.

DWORD dwParam1;
DWORD dwParam2;
CHAR szName [MIXER_LONG_NAME_CHARS];

dwParam1 - параметр, определяющий элемент управления:

dwParam2 - равен dwParam1.

szName - название элемента управления.

Структура MIXERCONTROL

Описывает параметры элемента управления линии. Кроме явно оговоренных полей, заполняется микшерной подсистемой.

DWORD cbStruct;
DWORD dwControlID;
DWORD dwControlType;
DWORD fdwControl;
DWORD cMultipleItems;
CHAR szShortName [MIXER_SHORT_NAME_CHARS];
CHAR szName [MIXER_LONG_NAME_CHARS];
union { 
  struct { 
    LONG lMinimum;
    LONG lMaximum;
  };
  struct { 
    DWORD dwMinimum;
    DWORD dwMaximum;
  };
  DWORD dwReserved [6];
} Bounds;
union { 
  DWORD cSteps;
  DWORD cbCustomData;
  DWORD dwReserved [6];
} Metrics;

cbStruct - размер структуры.

dwControlID - идентификатор управляющего элемента. Устанавливается приложением.

dwControlType - тип элемента. Устанавливается приложением.

fdwControl - флаги, уточняющие состояние элемента. Имена констант флагов имеют префикс MIXERCONTROL_CONTROLF_:

DISABLED Элемент запрещен - текущее состояние линии не допускает воздействия на этот орган управления. Допускается только считывание состояния элемента.
MULTIPLE Элемент состоит из двух или более частей - например, эквалайзер, состоящий из нескольких независимых частотных регуляторов.
UNIFORM Элемент воздействует на все каналы линии одинаковым образом. Этот флаг, например, обычно имеют эквалайзер, мультиплексор, микшер и т.п.

cMultipleItems - количество независимых частей элемента управления, если установлен флаг MULTIPLE; иначе нуль.

szShortName - короткое название элемента, может использоваться для изображения текстовой метки в диалоговом окне.

szName - полное название элемента.

Bounds - границы изменения значения элемента.

Metrics - параметры шкалы изменения значения.

Структура MIXERLINECONTROLS

Описывает массив управляющих элементов линии, используется при запросе описателей самих управляющих элементов. Заполняется приложением, отдельные поля могут возвращаться подсистемой.

DWORD cbStruct;
DWORD dwLineID;
union { 
  DWORD dwControlID;
  DWORD dwControlType;
};
DWORD cControls;
DWORD cbmxctrl;
LPMIXERCONTROL pamxctrl;

Структура MIXERCONTROLDETAILS

Описывает состояние отдельного элемента управления. Используется для запроса и установки текущего состояния элемента.

DWORD cbStruct;
DWORD dwControlID;
DWORD cChannels;
union { 
  HWND  hwndOwner;
  DWORD cMultipleItems;
};
DWORD  cbDetails;
LPVOID paDetails;

Уведомления, передаваемые программе

Для сообщения программе об изменении состояния линий и их элементов управления подсистема по непонятной причине предоставляет только один способ - посылка сообщения заданному окну. Уведомления событием, сообщением задаче и вызовом функции почему-то не поддерживаются, хотя структура подсистемы аналогична остальным мультимедийным подсистемам Windows.

В каждом из оконных сообщений Параметр wParam содержит ключ микшера. Определено два типа сообщений:

Получив любое из этих уведомлений, приложение должно соответственным образом отобразить произошедшие изменения на экране и/или в собственной базе данных.

Набор интерфейсных функций подсистем Aux и Mixer

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

Первым параметром большинства функций задается идентификатор объекта, определяющий, с каким микшером выполняется операция. Это может быть либо номер или ключ самого микшера, либо номер/ключ связанного с микшером звукового устройства. Тип объекта, заданного параметром Obj, определяется флагом типа объекта в числе параметров функции. Если определена макропеременная STRICT, требуется явное приведение типа объекта к типу HMIXEROBJ.

Перечень интерфейсных функций

GetNumDevs Запрос количества устройств (микшеров или aux)
GetDevCaps Запрос параметров и возможностей устройства
SetVolume / GetVolume Установка/запрос уровня сигнала в устройстве aux
Open Открывание микшера
Close Закрывание микшера
GetID Запрос номера микшера по связанному объекту
GetLineInfo Запрос описателя линии микшера
GetLineControls Запрос описателей управляющих элементов линии
GetControlDetails Запрос состояний управляющих элементов линии
SetControlDetails Установка состояний управляющих элементов линии
Message Передача драйверу нестандартного сообщения

Значения, возвращаемые интерфейсными функциями

За редким исключением, все функции интерфейса возвращают результат типа MMRESULT, эквивалентный типу UINT. Значение MMSYSERR_NOERROR, равное нулю, означает успешное выполнение функции, любое другое значение указывает на ошибку. Константы для кодов ошибок имеют префиксы MMSYSERR_ (общая ошибка мультимедийной подсистемы) и MIXRR_ (ошибка драйвера микшера):

MMSYSERR_BADDEVICEID Недопустимый номер устройства
MMSYSERR_NOTENABLED Драйвер не активизирован
MMSYSERR_ALLOCATED Устройство занято другим приложением
MMSYSERR_INVALHANDLE Недопустимый ключ открытого устройства
MMSYSERR_NODRIVER Драйвер отсутствует
MMSYSERR_NOMEM Недостаточно памяти
MMSYSERR_NOTSUPPORTED Запрошенная функция не поддерживается
MMSYSERR_BADERRNUM Код ошибки вне допустимого диапазона
MMSYSERR_INVALFLAG Недопустимый флаг
MMSYSERR_INVALPARAM Недопустимый параметр
MMSYSERR_HANDLEBUSY Над ключом выполняется операция от другой задачи (thread)
MMSYSERR_ERROR Неопределенная ошибка
MMSYSERR_NODRIVERCB Драйвер не выполнил уведомления (callback)
MIXERR_BASE Минимальное значение кода ошибки микшера
MIXERR_INVALLINE Недопустимый индекс/идентификатор линии
MIXERR_INVALCONTROL Недопустимый индекс/идентификатор элемента управления
MIXERR_INVALVALUE Недопустимое значение элемента управления.
MIXERR_LASTERROR Максимальное значение кода ошибки микшера

Описание интерфейсных функций

GetNumDevs - запрос количества устройств

UINT xxxGetNumDevs (void);

Возвращает количество установленных в системе устройств aux или микшеров.

GetDevCaps - запрос параметров и возможностей устройств

MMRESULT xxxGetDevCaps (
  UINT DevId,
  xCAPS *Caps,
  UINT CapsSize
);

Служит для определения параметров и возможностей устройства.

При успешном завершении функция заполняет поля переданной указателем структуры параметрами устройства.

SetVolume - установка уровня сигнала для устройства aux

MMRESULT auxSetVolume (UIND DevId, DWORD Volume);

Функция устанавливает уровень сигнала в устройстве. Несмотря на то, что функцией допускается 65536 уровней громкости, конкретные устройства могут поддерживать гораздо меньше - 8, 32 или 128 уровней. В таких случаях значащими является только от трех до семи старших разрядов значения громкости, младшие разряды игнорируются. Такая трактовка позволяет использовать одну и ту же шкалу громкости, изменяя лишь степень ступенчатости регулировки.

Функция поддерживается только устройствами, в свойствах которых установлен флаг AUXCAPS_VOLUME. Раздельная регулировка по каналам поддерживается только при наличии флага AUXCAPS_LRVOLUME.

GetVolume - запрос текущего уровня сигнала для устройства aux

MMRESULT auxGetVolume (UINT DevId, DWORD *ForVolume);

Функция опрашивает текущий установленный уровень сигнала. Трактовка переменной, на которую ссылается указатель ForVolume, аналогична используемому в функции SetVolume.

Open - открывание микшера

MMRESULT mixerOpen (
  HMIXER *ForHandle,
  UINT Obj,
  DWORD Callback,
  DWORD Dummy,
  DWORD OpenFlags
);

В случае успешного открывания объекта подсистема возвращает в переменную, на которую ссылается указатель ForHandle, ключ (handle) открытого микшера.

При завершении работы с устройством его необходимо закрыть функцией Close.

Close - закрывание микшера

MMRESULT mixerClose (HMIXER Handle);

Закрывает микшер, освобождая его для удаления из системы.

GetLineInfo - запрос описателя линии

MMRESULT mixerGetLineInfo (
  HMIXEROBJ Obj,
  MIXERLINE *LineDesc,
  DWORD Flags
);
LINEID Запрос по идентификатору линии, заданному полем dwLineID.
DESTINATION Запрос по индексу входной линии, заданному полем dwDestination.
SOURCE Запрос по индексу входной линии, заданному полем dwDestination, и индексу соединенной с нею выходной линии, заданному полем dwSource.
COMPONENTTYPE Запрос по типу линии, заданному полем dwComponentType. Возвращается описатель первой подходящей линии.
TARGETTYPE Запрос по параметрам устройства, заданным полями dwType, wMid, wPid, vDriverVersion и szPname структуры Target. Не допускается указание UNDEFINED в поле dwType.

При успешном завершении функция заполняет описатель линии, подходящей под заданный запрос.

GetLineControls - запрос описателей управляющих элементов линии

MMRESULT mixerGetLineControls (
  HMIXEROBJ Obj,
  MIXERLINECONTROLS *ControlGroup,
  DWORD Flags
);
ALL Запрос описателей всех элементов. Значение поля cControls описателя должно быть равно количеству элементов в линии.
ONEBYID Запрос описателя элемента по идентификатору, заданному полем dwControlID. Значение поля cControls должно быть равно единице.
ONEBYTYPE Запрос описателя элемента по типу элемента, заданному в поле dwControlType. Значение поля cControls должно быть равно единице. Возвращается описатель первого подходящего элемента.

При успешном завершении функция заносит в переданный описатель группы параметры линии, подходящей под заданный запрос, а также заполняет массив описателей элементов, на которые ссылается описатель группы.

GetControlDetails / SetControlDetails - запрос/установка состояния элемента

MMRESULT mixer<op>ControlDetails (
  HMIXEROBJ Obj,
  MIXERCONTROLDETAILS *StateArray,
  DWORD Flags
);

<op> обозначает выполняемую операцию: Get - запрос значения, Set - установка значения.

VALUE Запрашивается или устанавливается значение элемента управления. Поле paDetails структуры MIXERCONTROLDETAILS содержит указатель описателя (или массива описателей) соответствующего типа, в которые заносятся текущие значения элемента по частям и каналам, либо берутся новые значения для установки.
LISTTEXT (операция Get) Запрашиваются текстовые метки элемента управления или его частей. Поле paDetails структуры MIXERCONTROLDETAILS содержит указатель описателя (или массива описателей) типа MIXERCONTROLDETAILS_LISTTEXT, в которые будут занесены текстовые метки. Операция запрашивает метки для всех частей элемента сразу. Недопустима для элементов типа CUSTOM.
CUSTOM (операция Set) Запрашивается вывод драйвером соответствующего диалогового окна для элемента управления типа CUSTOM. Поле paDetails структуры MIXERCONTROLDETAILS содержит указатель описателя состояния элемента, область памяти для которого должна иметь размер, заданный полем cbDetails. Драйвер микшера отображает диалоговое окно, необходимое для ввода всех параметров элемента, и после заполнения пользователем нужных полей заносит введенные данные в описатель элемента. Родительское окно для создаваемого диалогового окна задается полем hwndOwner. Никаких действий с самим элементом в этом режиме не выполняется; для изменения состояния элемента необходимо выполнить операцию Set в режиме VALUE.

GetID - запрос системного номера микшера по ключу

MMRESULT mixerGetID (HMIXEROBJ Obj, UINT *ForID, DWORD ObjType);

Функция определяет системный номер микшера, соответствующего заданному объекту.

Message - передача сообщения драйверу микшера или устройства aux

LRESULT auxOutMessage (UINT DevId, UINT Msg, DWORD P1, DWORD P2);
LRESULT mixerMessage (HMIXER Handle, UINT Msg, DWORD P1, DWORD P2);

Функция используется для прямой передачи сообщения драйверу дополнительного устройства или микшера. Все интерфейсные функции, кроме GetID, транслируются подсистемой в сообщения, передаваемые драйверу; при этом каждое сообщение имеет два параметра типа DWORD, в которые преобразуются параметры интерфейсных функций. Если драйвер устройства поддерживает нестандартные сообщения - они могут быть переданы ему при помощи функций Message. Возвращаемое значение при этом определяется самим драйвером.

Пример программы, использующий интерфейс с микшерами

Для иллюстрации приводится программа MixerCtl, управляющая выходной линией ЦАП (Wave Out) звукового адаптера. Сигнал в этой линии появляется при воспроизведении цифрового звука - файлов WAV, MP3, AVI и им подобных, при работе виртуальных синтезаторов Roland VSC, Yamaha YXG, Reality, GigaSampler и т.п.


В диалоговом окне отображается список доступных в системе микшеров; требуется выбрать устройство микшера, выходная линия которого будет управляться программой.

Программа открывает выбранный микшер, запрашивая уведомление окна, получает параметры линии функцией GetLineInfo, используя запрос по типу линии (WAVEOUT). Затем у полученной линии функцией GetLineControls запрашиваются описатели элементов управления посредством запроса по типу (Volume Fader и Mute Switch). Все последующие запросы к линии и элементам выполняются по их полученным в первых запросах идентификаторам.

Программа отслеживает сообщения MM_MIXM_LINE_CHANGE / MM_MIXM_CONTROL_CHANGE и, если они относятся к выбранной линии и элементам управления, обновляет состояние окна, вызывая функции GetLineInfo и GetControlDetails. При воздействии пользователя на органы управления в окне программа отражает сделанные изменения в микшере, используя функцию SetControlDetails.

Вместе с программой можно запустить стандартный микшер Windows - состояния движка регулятора уровня выхода воспроизводимого звука и переключателя глушения в обоих окнах будут изменяться строго синхронно.

Программа реализована на языке C++ без использования классов, MFC и RTTI. Прилагаются исходные тексты и исполняемый файл.

Разработка программы выполнялась в среде MS VC++ 4.2. Использован только стандартный интерфейс (API) Windows, без каких-либо расширений из среды разработки.

Для работы программы необходим любой звуковой адаптер, поддерживающий вывод цифрового звук (Wave Play) и снабженный драйвером микшера. Драйверы микшера имеют все звуковые адаптеры, снабженные драйверами для Windows 95/98 и NT/2000.


Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.
    Сообщений 0    Оценка 46        Оценить