Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Подземелье Магов
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  18:11[Войти] | [Зарегистрироваться]

Еще раз о звуке. II

Сергей Козлов
дата публикации 12-08-2003 16:55

Еще раз о звуке. II

От автора.

Много воды утекло с тех пор, как вышла первая статья. Теперь, как и было обещано, статья про микшер. Сразу предупреждаю, что я не приведу ни одной строчки кода. Так что скучная статья получилась. Может, вы вообще зря ее читаете:)?... Нет? Ну тогда начнем.

Ранее мы разобрались с выводом звука. Сегодня мы рассмотрим другую тему: работа с микшером. Эта тема в материалах Королевства освещена в меньшей степени ;) поэтому остановимся на ней более подробно, местами цитируя MSDN.

Как говорил К.Маркс ( может кто помнит про такого) хороший архитектор отличается от пчелы тем, что при строительстве имеет план на бумаге ( или хотя бы в голове). Пчела же плана не имеет, у нее инстинкт. Я пока не слышал, есть ли инстинкт программирования, возможно, через несколько поколений программистов он и появится у отдельных личностей, но пока для работы нужен план. Поэтому сначала построим модель в голове, о!

Архитектура микшера.

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

Про "железо".

Я начну издалека, с давних 90-х годов. В те времена звуковые карты (недорогие пищалки) делали на шину ISA по принципу "все-в-одном". В одном чипе были собраны контроллер шины, аудиоконтроллер, ЦАП и АЦП, усилители, синтезатор, интерфейсы джойстика и MIDI и т.д. Получалось интересно: с одной стороны к чипу шли дороги от шины компьютера, а с другой -- к динамикам. Вот такая мельница.

Нынче все по-другому. С появлением спецификации AC`97 звуковые платы стали, как минимум, двухкомпонентными: аудиоакселератор (аудиоконтроллер) и кодек. Аудиоакселератор отвечает за взаимодействие с PCI-шиной компьютера и, как правило, имеет блок 3D-эффектов, преобразует данные с помощью встроенного DSP и т.п., то есть реализует аппаратную поддержку всех наворотов ( DirectX, EAX и пр.). Аудиоконтроллер выполняет задачи поскромнее, фактически, только обеспечивает работу с шиной. На выходе аудиоакселератора(аудиоконтроллера) мы имеем ACLink и гоним цифровой звук в формате AC`97. Примеры можно найти на ESS, Cirrus Logic, Creative.

На другом конце ACLink у нас находится кодек, который преобразует цифровой звук в аналоговый и обратно, микширует, фильтрует, усиливает и делает другие вещи. От него фактически зависит качество звука. За примерами можно сходить на ESS, Cirrus Logic или SigmaTel. Кстати, кодеки SigmaTel -- лучшие для своей ценовой категории ( это не реклама :). Для простоты в качестве модели мы возьмем чип CS4235 производства Cirrus Logic. Звуковые платы с ним назывались Crystal и были под шину ISA.

Нас особенно интересует правая часть картинки. Два круга вверху и внизу и есть микшеры, причем верхний микшер работает на вход (I-микшер), а нижний -- на выход (O-микшер).

Полюбовавшись на картину, отметим три вещи:
Первое. Канал от I-микшера к АЦП ( от ЦАП к O-микшеру) только один. С учетом стерео, конечно.
Второе. Мы можем передать данные с I-микшера к O-микшеру напрямую, не оцифровывая звук.
Третье. На картинке с правой стороны есть ряд блоков GAIN. Блоки GAIN -- это аналоговые усилители с цифровым управлением. Они нам интересны тем, что реализуют функции Volume и Mute, то есть регулируют или отключают звук.

И один важный вывод: регулировать громкость можно двумя способами. Первый способ -- "аналоговый", когда мы изменяем усиление через Volume на блоке GAIN. Второй способ -- "цифровой", когда мы изменяем значение каждой выборки уже оцифрованного звука. Если вам важно быстро менять громкость, не влезая в сам сигнал, и вам не требуется большой точности -- первый способ для вас.

Однако, есть некоторые сложности, зависящие от кодека:

  • реальный уровень сигнала немного уплывает при каждом включении компьютера
  • характеристики усилителя GAIN "в некоторой степени" нелинейны.
  • при использовании Mute возможен "дребезг", очень короткая высокочастотная помеха, слышится как щелчок.
На этом "железную" часть заканчиваем.

Про "софт".

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

Для простоты понимания (и дальнейшей работы) представим микшер в виде небольшой иерархической модели.

  1. уровень 1: микшер. Имеется в виду собственно микшер-устройство (device). Функции микшера позволяют определить число микшеров-устройств, представленных в системе и их возможности.
  2. уровень 2: аудиолиния. Это основной элемент архитектуры микшера. Аудиолиния состоит из одного или более каналов данных, исходящих из одиночного источника. Например, стерео аудиолиния имеет 2 канала данных, но считается за одну аудиолинию, так как исходит из одного источника. Различаются аудиолинии-источники и аудиолинии-приемники. У микшера может быть несколько аудиолиний-источников сигнала, но аудиолиния-приемник сигнала одна -- на то ведь микшер так и называется :) На картинке аудиолинии-источники показаны линиями со стрелочками к кругу, а аудиолиния-приемник -- это линия, уходящая от круга.
  3. уровень 3: элемент управления (audio-line control, mixer control) аудиолинии. Каждая аудиолиния имеет ассоциированные с ней элементы управления (контролы). Контрол аудиолинии может выполнять любые функции в зависимости от характеристик ассоциированной аудиолинии. Набор доступных контролов зависит от используемого "железа".
  4. уровень 4: свойства элементов управления (control details). Каждый контрол имеет свой набор свойств, которые можно менять. Изменение свойств влечет изменение звука.

Как видим, уровни 1 и 2 соответсвуют "железной" модели и имеют прямые аналоги в виде устройств и соединений. Элементы уровня 1 и 2 в современном "железе" размещаются в чипе кодека. Уровни 3 и 4 напрямую не соотносятся с моделью "железа". Они отвечают за характеристики сигнала, который мы слушаем.

Надеюсь, к этому моменту у нас в головах есть сформированная модель, план. Остались технические вопросы multimedia API в части управления микшером.

API микшера

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

Уровень 1. Микшер. Структуры и функции, предназначенные для работы с микшером в целом.

1.1.Запросы к микшеру.

UINT mixerGetNumDevs(VOID)

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

MMRESULT mixerGetDevCaps(UINT_PTR uMxId, LPMIXERCAPS pmxcaps, UINT cbmxcaps)
возвращает характеристики указанного микшера
uMxId -- идентификатор или обработчик открытого микшера
pmxcaps -- указатель на структуру MIXERCAPS в которой возвращается информация
cbmxcaps -- размер в байтах структуры MIXERCAPS

MIXERCAPS
структура, описывающая характеристики микшера.

typedef struct { 
    WORD  wMid; 
    WORD  wPid; 
    MMVERSION vDriverVersion; 
    CHAR    szPname[MAXPNAMELEN]; 
    DWORD   fdwSupport; 
    DWORD   cDestinations; 
} MIXERCAPS; 
Для нас практически интересен только элемент cDestinations -- число аудиолиний-приемников, доступных из микшера. Все микшеры должны поддерживать хотя бы одну линию-приемник и возвращать ненулевое значение в этом поле. Значение поля используется при назначении индекса линии-приемника в структуре MIXERLINE в поле dwDestination и изменяется от 0 до cDestinations-1. В поле szPname у нас есть текстовое название микшера, если кому-то нужно.

MMRESULT mixerGetID( HMIXEROBJ hmxobj, UINT_PTR *puMxId, DWORD fdwId );
возвращает идентификатор микшера, соответствующего заданному обработчику.
hmxobj -- обработчик микшера, для которого определяется идентификатор.
puMxId -- указатель на переменную, в которую возвращяется идентификатор.
fdwId -- флаг, определяющий, каким образом понимать hmxobj

1.2. Управление микшером.

MMRESULT mixerClose( HMIXER hmx );
закрывает заданный микшер.
hmx -- обработчик микшера, который был возвращен функцией mixerOpen.

MMRESULT mixerOpen( LPHMIXER phmx, UINT uMxId, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen );
открывает заданный микшер и гарантирует, что он не будет удален, пока приложение не закроет обработчик микшера.
phmx -- указатель на обработчик микшера.
uMxId -- идентификатор открываемого микшера
dwCallback -- обработчик окна, которое будет получать сообщения об изменении состояния ассоциированных элементов управления аудолиний. Должен быть 0 если не используется.
dwInstance -- пользовательские данные для функции обратного вызова.
fdwOpen -- флаг открытия микшера.
Заметим, что если fdwOpen установить в значение MIXER_OBJECTF_MIXER, то uMxId можно задавать от 0 и до числа микшеров mixerGetNumDevs()-1.

Уровень 2. Аудиолиния. Структуры и функции, предназначенные для работы с аудиолиниями.

2.1. Получение информации об аудиолинии

MMRESULT mixerGetLineInfo ( HMIXEROBJ hmxobj, LPMIXERLINE pmxl, DWORD fdwInfo );
Возвращает информацию о заданной аудиолинии.
hmxobj -- обработчик микшера, управляющего заданной аудиолинией.
pmxl -- указатель на структуру MIXERLINE, которая заполняется информацие об аудиолинии. В элементе cbStruct структуры должен быть ее размер в байтах.
fdwInfo -- флаги, определяющие возвращаемую информацию.

Для нас важны три флага
MIXER_OBJECTF_HMIXER -- параметр hmxobj является обработчиком микшера, открытого функцией mixerOpen.
MIXER_GETLINEINFOF_DESTINATION -- параметр pmxl возвращает информацию о линии-приемнике с индексом, заданным в поле dwDestination структуры MIXERLINE. Этот индекс меняется от 0 до cDestinations-1 из MIXERCAPS.
MIXER_GETLINEINFOF_SOURCE -- параметр pmxl возвращает информацию о линии-источнике с индексом, заданным в поле dwDestination структуры MIXERLINE. Этот индекс меняется от 0 до cDestinations-1 из MIXERCAPS.

Функции вызываем в основном с комбинацией флагов MIXER_OBJECTF_HMIXER or MIXER_GETLINEINFOF_DESTINATION или MIXER_OBJECTF_HMIXER or MIXER_GETLINEINFOF_SOURCE.

Поясню подробнее о получении информации о линиях-приемниках и линиях-источниках. Сколько линий-приемников узнаем из cDestinations структуры MIXERCAPS. Информацию о линии-приемнике узнаем вызовом mixerGetLineInfo с флагом MIXER_GETLINEINFOF_DESTINATION и установленным индексом линии в поле dwDestination структуры MIXERLINE.

Каждая линия-приемник может иметь несколько линий-источников. Поэтому сколько линий-источников для каждой линии-приемника, узнаем при вызове mixerGetLineInfo с флагом MIXER_GETLINEINFOF_DESTINATION из поля cConnections структуры MIXERLINE, т.е. когда получали информацию о линии-приемнике.

И, наконец, информацию о линии-источнике узнаем вызовом mixerGetLineInfo с флагом MIXER_GETLINEINFOF_SOURCE и установленными индексами линии-приемника в поле dwDestination и линии-источника в поле dwSource структуры MIXERLINE. Индекс dwSource меняется от 0 до cConnections-1 из MIXERLINE для линии-приемника. Вот такая вот система, потеряться легко.

MIXERLINE
Структура, описывающая состояние и метрики аудиолинии.

typedef struct { 
    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; 
} MIXERLINE; 

cbStruct -- размер структуры MIXERLINE в байтах.
dwDestination -- индекс линии-приемника. Изменяется от 0 до cDestinations-1 из MIXERCAPS. (вызов mixerGetDevCaps). Когда mixerGetLineInfo вызывается с флагом MIXER_GETLINEINFOF_DESTINATION, то в этом поле указывается индекс опрашиваемой линии. При этом dwSource должен быть равен 0. Когда используется флаг MIXER_GETLINEINFOF_SOURCE в поле dwSource должен быть индекс опрашиваемой линии-источника, ассоциированной с линией-премником, заданной в dwDestination.
dwSource
-- индекс линии-приемника, асоциированной с линией-источником с индексом в dwDestination. Работает с флагом MIXER_GETLINEINFOF_SOURCE и изменяется от 0 до cConnections-1 из структуры, полученной для линии-приемника.
dwLineID -- идентификатор линии.
fdwLine -- флаги статуса и поддерживаемых функций для аудиолинии.
dwUser -- только для особо одаренных. Можно игнорировать.
dwComponentType -- тип аудиолинии. Их много всяких, но нам интересней:
MIXERLINE_COMPONENTTYPE_SRC_LINE -- линейный вход
MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC -- вход с компакт-диска
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS -- выход на колонки
MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE-- микрофон
MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT -- стандартный вход, т.е. источник wave-данных (из файла, например) MIXERLINE_COMPONENTTYPE_DST_WAVEIN -- линия-приемник для записи в файл, например.
В общем, с этими типами дело темное, надо эксперименты устраивать, т.к. у меня драйвер для одной карточки безбожно врал и обзывал линии как хотел. Хотя, если найти соответствие, все работало как часы. Так что если в этом месте ошибочка вышла, простите.
cChannels -- максимальное число раздельных каналов. Это 2 для стерео, 1 для моно. Для навороченных карт может быть больше. cConnections -- число соединений для аудиолинии. Используется только для линий-приемников, а для линий-источников всегда 0. Логично. Прием ведем с многих направлений.
cControls -- число элементов управления (контролов) ассоциированных с данной линией, неважно, приемник или источник. Ели таких нет, то 0.
szShortName -- краткое наименование аудиолинии
szName -- полное наименование аудиолинии.
Target -- структура, описывающая микшер и возвращающая др. данные. Честно говоря, ни разу не использовал. Пропускаю из-за сомнительной ценности.

Уровень 3. Элемент управления (контрол). Структуры и функции, предназначенные для работы с элементами управления аудиолинии.

3.1. Получение контролов аудиолинии.

MMRESULT mixerGetLineControls( HMIXEROBJ hmxobj, LPMIXERLINECONTROLS pmxlc, DWORD fdwControls );
Возвращает один или более контролов, ассоциированных с аудиолинией.
hmxobj -- обработчик микшера, которого мы опрашиваем.
pmxlc -- указатель на структуру MIXERLINECONTROLS.. Эта структура используется для ссылки на одну или более структур MIXERCONTROL, которые заполняются информацией о контролах. Поле cbStruct -- размер в байтах структуры MIXERLINECONTROLS должно быть заполнено.
fdwControls -- флаги, определяющие возвращаемую информацию. Мы задаем комибинацию MIXER_GETLINECONTROLSF_ALL or MIXER_OBJECTF_HMIXER. MIXER_GETLINECONTROLSF_ALL -- параметр pmxlc ссылается на список структур MIXERCONTROL, которые заполняются информацией обо всех контролах данной аудиолинии. В поле cControls должно быть записано число контролов, а взять его можно из cControls структуры MIXERLINE данной линии.
Поле сbmxctrl содержит размер одиночной структуры MIXERCONTROL и должно быть установлено. Поле pamxctrl должно содержать указатель на первую структуру MIXERCONTROL. Остальные флаги не рассматриваю, сделайте это самостоятельно.

MIXERLINECONTROLS
Структура с информацией о контролах аудиолинии.

  typedef struct { 
  DWORD cbStruct; 
  DWORD dwLineID; 
  union { 
  DWORD dwControlID; 
  DWORD dwControlType; 
  }; 
  DWORD cControls; 
  DWORD cbmxctrl; 
  LPMIXERCONTROL pamxctrl; 
  } MIXERLINECONTROLS; 
  
cbStruct -- размер структуры в байтах.
dwLineID -- идентификатор линии, про которую мы спрашиваем. Берем его из MIXERLINE.
dwControlID -- работает с флагом MIXER_GETLINECONTROLSF_ONEBYID и нам пока неинтересен.
dwControlType -- работает с флагом MIXER_GETLINECONTROLSF_ONEBYTYPE и нам пока неинтересен.
cControls -- число элементов MIXERCONTROL в списке. Не может быть нулевым. Мы устанавливаем его из cControls структуры MIXERLINE.
cbmxctrl -- размер в байтах одиночной структуры MIXERCONTROL
pamxctrl -- указатель на первую структуру MIXERCONTROL в списке.

MIXERCONTROL
Структура с информацией об одиночном элементе управления аудиолинии.

  typedef struct { 
  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; 
  } MIXERCONTROL, *PMIXERCONTROL, FAR *LPMIXERCONTROL; 
  

cbStruct -- размер структуры в байтах.
dwControlID -- идентификатор контрола, про который мы спрашиваем.
dwControlType -- тип контрола, про который мы спрашиваем.
Типов опять же много, но нам интересны пока два:
MIXERCONTROL_CONTROLTYPE_MUTE -- включение/выключение звука
MIXERCONTROL_CONTROLTYPE_VOLUME -- громкость звука
Остальные типы можно посмотреть сами знаете где.
fdwControl -- флаги статуса и поддерживаемых свойств. Их тоже хватает. Смотрите.
cMultipleItems -- число элементов для многоэлементных контролов. Нам пока неинтересен.
szShortName -- короткое имя контрола
szName -- полное именование контрола
Bounds -- граничные значения для параметра контрола. Полезно проверять.
Metrics -- граничные значения для метрик. Зачем это, без стакана не понять.

Уровень 4. Свойства элементов управления (control details). Структуры и функции, предназначенные для работы со свойствами контролов аудиолинии.

Все контролы подразделяются на несколько типов:

  • Audio mixer custom controls
  • Faders
  • Lists
  • Meters
  • Numbers
  • Sliders
  • Switches
  • Time controls

Нам интересны фейдеры и свитчи. Фейдер - обычный контрол с линейной вертикальной шкалой и ползунком, который перемещается вверх и вниз. Например, громкость именно таким контролом и регулируется. Для громкости шкала назначена от 0 и до 65535. Свитч - контрол, имеющий только два состояния. Например, чекбокс для MUTE. А больше и сказать особо нечего. Все остальное посмотреть можно сами знаете где :)

4.1. Получение значений свойств контрола аудиолинии

MMRESULT mixerGetControlDetails( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails );
Возвращает харатеристики одиночного контрола аудиолинии.
hmxobj -- обработчик микшера, которого мы опрашиваем.
pmxcd -- указатель на структуру MIXERCONTROLDETAILS, которая заполняется информацией о контроле.
fdwDetails -- флаги, определяющие возвращаемую информацию. Используем MIXER_GETCONTROLDETAILSF_VALUE or MIXER_OBJECTF_HMIXER.
MIXER_GETCONTROLDETAILSF_VALUE -- возвращается текущее значение контрола. PaDetails структуры MIXERCONTROLDETAILS указывает на структуры с детальной информацией по контролу.

4.2. Установка значений свойств контрола аудиолинии

MMRESULT mixerSetControlDetails( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails );
Устанавливает харатеристики одиночного контрола аудиолинии.
hmxobj -- обработчик микшера, которого мы опрашиваем.
pmxcd -- указатель на структуру MIXERCONTROLDETAILS, которая заполнена информацией о контроле предыдущим вызовом mixerGetControlDetails.
fdwDetails -- флаги, определяющие возвращаемую информацию. Используем MIXER_OBJECTF_HMIXER or MIXER_SETCONTROLDETAILSF_VALUE.
MIXER_SETCONTROLDETAILSF_VALUE -- устанавливается новое значение контрола.
PaDetails из структуры MIXERCONTROLDETAILS указывает на структуру, соответствующую типу контрола.

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

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

cbStruct -- размер структуры в байтах.
dwControlID -- идентификатор контрола, свойства которого мы читаем/изменяем
cChannels - число каналов, свойства которых меняются. Ставьте значение 0, 1 или MIXERLINE.cChannels, если свойства контрола относятся ко всем каналам аудиолинии. Других значений не ставьте.
hwndOwner - указатель окна. Для наших целей неважно. Ставьте 0.
cMultipleItems - ставьте 0 и будет хорошо
cbDetails - размер структуры, содержащей конкретную информацию по контролу.
paDetails - указатель на одну или более структур, содержащих конкретную информацию по контролу.

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

MIXERCONTROLDETAILS_BOOLEAN
Возвращает или устанавливает значение свойства контрола булевского типа.

typedef struct { 
  LONG fValue; 
  } MIXERCONTROLDETAILS_BOOLEAN; 

fValue - значение логического типа ( 0- FALSE, ненулевое - TRUE)
Подходит для управления контролом типа MIXERCONTROL_CONTROLTYPE_MUTE.

MIXERCONTROLDETAILS_UNSIGNED
Возвращает или устанавливает значение свойства контрола целого беззнакового типа.

  typedef struct { 
  DWORD dwValue; 
  } MIXERCONTROLDETAILS_UNSIGNED;

dwValue - Целое беззнаковое
Подходит для управления контролом типа MIXERCONTROL_CONTROLTYPE_VOLUME

Без уровня. Поддержка сообщений. Отправка определенного пользователем сообщения.

DWORD mixerMessage( HMIXER hmx, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2 );
Посылка пользовательского сообщения напрямую драйверу микшера
hmx -- обработчик открытого микшера
uMsg -- пользовательское сообщение Должно быть больше или равно MXDM_USER.
dwParam1, dwParam2 -- параметры сообщения.

MM_MIXM_CONTROL_CHANGE
Сообщение, которое посылается микшером приложению чтобы уведомить об изменении состояния контрола.
wParam = (WPARAM) hMixer
lParam = (LPARAM) dwControlID
hMixer -- обработчик микшера, который послал сообщение.
dwControlID -- идентификатор контрола, который изменил состояние.

MM_MIXM_LINE_CHANGE
Сообщение, которое посылается микшером приложению чтобы уведомить об изменении состояния аудиолинии.
wParam = (WPARAM) hMixer
lParam = (LPARAM) dwLineID
hMixer -- обработчик микшера, который послал сообщение.
dwLineID -- идентификатор аудиолинии, которая изменила свое состояние.


И еще немножко :)
Вот, собственно, и все, что желательно знать, чтобы начать работать с микшером. Да и этого многовато ;) В качестве примера приведена программа, которая прочитывает все, что связано с микшером и отображает это в виде дерева

Далее по плану: как записать звук и что такое fullduplex.

Ссылки

Литература

  • Billy Gates — MSDN.
  • Гордеев О. В. — Программирование звука в Windows. СПб.: БХВ — Санкт-Петербург, 1999 384 с.

Сергей Козлов




Смотрите также материалы по темам:
[Чтение/запись и преобразование звука]

 Обсуждение материала [ 23-10-2010 20:27 ] 7 сообщений
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования