Общие задачи в OS X
В этой главе описываются, как можно объединить части Core Audio для выполнения некоторых общих задач в OS X.
Core Audio является чрезвычайно модульным с немногими ограничениями на то, как использовать его различные части. Другими словами, можно часто делать вещи больше чем одним способом. Например, Ваше приложение Mac может вызвать Audio File Services для чтения сжатого звукового файла из диска, Audio Converter Services для преобразования данных в линейный PCM и Audio Queue Services для игры его. Также Вы могли загрузить встроенное аудиоустройство Проигрывателя Файла в свое приложение. Каждый подход имеет свои преимущества и возможности.
Чтение и запись аудиоданных
Много приложений, обрабатывающих аудио, должны считать и записать данные, или к диску или к буферу. Вы обычно хотите считать содержавшие данные файла и преобразовать их в линейный PCM. Можно сделать так за один шаг использование Extended Audio File Services.
Как показано на рисунке 3-1, Extended Audio File Services использует Audio File Services для чтения аудиоданных и затем вызывает Audio Converter Services для преобразования его в линейный PCM (предполагающий, что данные уже не находятся в том формате).
При необходимости в большем количестве управления чтением файла и процедурой преобразования можно вызвать Аудиофайл, или Аудио Преобразователь функционирует непосредственно. Вы используете Audio File Services для чтения файла из диска или буфера. Эти данные могут быть в сжатом формате, когда они могут быть преобразованы в линейный PCM использование аудио преобразователя. Можно также использовать аудио преобразователь для обработки изменений в битовой глубине, частоте дискретизации, и т.д. в линейном формате PCM. Вы обрабатываете преобразования при помощи Audio Converter Services для создания аудио объекта преобразователя, указывая, что ввод и вывод форматирует Вас желание. Каждый формат определяется в ASBD (см. Универсальные Типы данных в Core Audio).
После того, как преобразованный в линейный PCM, данные готовы обработать — такой как аудиоустройством. Для использования аудиоустройства Вы регистрируете обратный вызов во вводе аудиоустройства. Вы разрабатываете свой обратный вызов для обеспечения буферов данных PCM, когда вызвано. Когда аудиоустройству нужно больше данных для обработки, это вызывает обратный вызов.
Если Вы хотите вывести аудиоданные, Вы отправляете их в модуль I/O. Модуль I/O может принять только линейные данные формата PCM. Такое аудиоустройство обычно является прокси для устройства, но это не требование.
Преобразование форматов аудиоданных
Core Audio использует линейный PCM в качестве промежуточного формата, разрешающего много перестановок преобразований. Чтобы определить, возможно ли определенное преобразование формата, необходимо удостовериться, что оба декодер (формат A к линейному PCM) и кодер (линейный PCM к формату B) доступны. Например, если бы Вы хотели преобразовать данные от MP3 до AAC, то Вам были бы нужны два аудио преобразователя: один для преобразования от MP3 до линейного PCM и другого для преобразования линейного PCM в AAC, как показано на рисунке 3-2.
Для примеров использования Аудиофайла и Аудио Преобразователя APIs, посмотрите SimpleSDK/ConvertFile
и Services/AudioFileTools
выборки в Core Audio SDK. Если Вам интересно в письменной форме пользовательский аудио кодек преобразователя, посмотрите выборки в AudioCodec
папка.
Взаимодействие через интерфейс с аппаратными средствами
Большинство аудиоприложений соединяется с внешними аппаратными средствами, любой, чтобы вывести звук (например, к усилителю и громкоговорителю) или получить его (такой как через микрофон). Нижний уровень Core Audio делает эти соединения, говоря с Набором I/O и драйверами. OS X обеспечивает интерфейс для этих соединений, названных аудио уровнем аппаратной абстракции или аудио HAL. Вы считаете аудио интерфейсы HAL’s объявленными в AudioHardware.h
заголовочный файл в платформе Core Audio.
Однако во многих случаях приложения не должны использовать аудио HAL непосредственно. Apple обеспечивает три стандартных аудиоустройства, которые должны удовлетворить большинство аппаратных потребностей: устройство вывода по умолчанию, системное устройство вывода и модуль AUHAL. Ваше приложение должно явно загрузить эти аудиоустройства, прежде чем можно будет использовать их.
Значение по умолчанию и система модули I/O
Модуль I/O по умолчанию и система, которую модуль I/O отправляет аудиоданным в вывод по умолчанию (как выбрано пользователем) или системный вывод (где предупреждения и другие системные звуки играются), соответственно. Когда для вывода нужны данные, при соединении вывода аудиоустройства с одним из этих модулей I/O — такого как в графике обработки аудиоданных — функцию обратного вызова рендеринга аудиоустройства вызывают. Модуль I/O направляет данные через HAL к надлежащему устройству вывода, автоматически обрабатывая следующие задачи, как показано на рисунке 3-3.
Любое требуемое линейное преобразование данных PCM. Устройство вывода содержит аудио преобразователь, который может перевести Ваши аудиоданные в линейный вариант PCM, требуемый аппаратными средствами.
Любое требуемое отображение канала. Например, если Ваш модуль предоставит два данные канала, но устройство вывода может обработать пять, то Вы, вероятно, захотите отобразиться, какие каналы переходят в который. Можно сделать так путем указания карты канала с помощью
kAudioOutputUnitProperty_ChannelMap
свойство на устройстве вывода. Если Вы не предоставляете карту канала, значение по умолчанию должно отобразить первый звуковой канал на первый канал устройства, второе к второму, и т.д. Эффективная выходная мощность слышала, тогда определяется тем, как пользователь сконфигурировал динамики устройства в Аудио Приложение установки MIDI.Сигнал Запускает/Останавливает. Устройства вывода являются единственными аудиоустройствами, которые могут управлять потоком аудиоданных в сигнальной цепочке.
Для примера использования устройства вывода по умолчанию для игры аудио посмотрите SimpleSDK/DefaultOutputUnit
в Core Audio SDK.
Модуль AUHAL
Если необходимо соединиться с устройством ввода данных или устройством кроме устройства вывода по умолчанию, необходимо использовать AUHAL. Несмотря на то, что определяется как устройство вывода, можно сконфигурировать AUHAL для принятия введенный также путем установки kAudioOutputUnitProperty_EnableIO
свойство на вводе. Для большего количества специфических особенностей посмотрите Техническое примечание TN2091: Ввод Устройства Используя Выходное Аудиоустройство HAL. Когда ввод принятия, AUHAL поддерживает отображение канала ввода и использует аудио преобразователь (если необходимый) для перевода входящих данных в линейный формат PCM.
AUHAL является более обобщенной версией устройства вывода по умолчанию. В дополнение к аудио преобразователю и возможностям отображения канала, можно указать устройство для соединения с путем установки kAudioOutputUnitProperty_CurrentDevice
свойство к ID AudioDevice
объект в HAL. После того, как соединенный, можно также управлять свойствами, связанными с AudioDevice
объект путем обращения AUHAL; AUHAL автоматически проводит любые вызовы свойства, предназначенные для аудиоустройства.
Экземпляр AUHAL может соединиться только с одним устройством за один раз, таким образом, можно включить оба ввода и вывода, только если устройство может принять обоих. Например, встроенное аудио для основанных на PowerPC компьютеров Macintosh сконфигурировано как единое устройство, которое может оба принять входные аудиоданные (через Микрометр в) и вывести аудио (через динамик).
В целях потока сигналов AUHAL, сконфигурированный для обоих вводов и выводов, ведет себя как два аудиоустройства. Например, когда выведенный включен, AUHAL вызывает обратный вызов рендеринга предыдущего аудиоустройства. Если аудиоустройство должно ввести данные от устройства, это вызывает обратный вызов рендеринга AUHAL. Рисунок 3-4 показывает AUHAL, используемый для обоих вводов и выводов.
Звуковой сигнал, входящий через внешнее устройство, переводится в поток аудиоданных и передается AUHAL, который может тогда переслать его к другому аудиоустройству. После обработки данных (например, добавление эффектов или смешивание с другими аудиоданными), вывод передают обратно AUHAL, который может тогда вывести аудио через то же внешнее устройство.
Для примеров использования AUHAL для ввода и вывода посмотрите пример кода CAPlayThrough. CAPlayThrough
показывает, как реализовать ввод и вывод с помощью AUHAL для ввода и устройства вывода по умолчанию для вывода.
Используя составные устройства
При взаимодействии через интерфейс с аппаратными аудиоустройствами Core Audio позволяет Вам добавлять дополнительный уровень абстракции, создавая составные устройства, комбинирующие вводы и выводы многократных устройств для появления как единое устройство. Например, если необходимо разместить пять каналов аудиовыхода, можно присвоить два канала вывода к одному устройству и других трех к другому устройству. Core Audio автоматически направляет поток данных к обоим устройствам, в то время как Ваше приложение может взаимодействовать с выводом, как будто это было единое устройство. Core Audio также работает от Вашего имени, чтобы гарантировать надлежащую аудио синхронизацию и минимизировать задержку, позволяя Вам фокусироваться на подробных данных, определенных для Вашего приложения или плагина.
Пользователи могут создать составные устройства в Аудио Приложение установки MIDI путем выбора пункта меню Audio> Open Aggregate Device Editor. После выбора sub устройств для объединения как составное устройство пользователь может сконфигурировать каналы ввода и вывода устройства как любое другое устройство. Пользователь также должен указать, какие часы sub устройства должны действовать как ведущее устройство в целях синхронизации.
Любые составные устройства, которые создает пользователь, являются глобальной переменной к системе. Можно создать составные устройства, которые локальны для порядка подачи заявки программно с помощью вызовов функции HAL Services. Составное устройство появляется как AudioAggregateDevice
объект (подкласс AudioDevice
) в HAL.
Составное устройство сохраняет знание своих sub устройств. Если пользователь демонтирует sub устройство (или конфигурирует его несовместимым способом), те каналы исчезают из агрегата, но те каналы вновь появятся, когда sub устройство будет повторно прикреплено или реконфигурировано.
Составные устройства имеют некоторые ограничения:
Все sub устройства, составляющие составное устройство, должны работать на той же частоте дискретизации, и их потоки данных должны быть mixable.
Они не обеспечивают конфигурируемых средств управления, таких как объем, бесшумный режим, или вводят выбор источников.
Вы не можете указать составное устройство, чтобы быть устройством ввода или вывода по умолчанию, если все его sub устройства не могут быть устройством по умолчанию. Иначе, приложения должны явно выбрать составное устройство для использования его.
В настоящее время только устройства, представленные
IOAudio
семья (т.е. уровень ядра) драйвер может быть добавлен к составному устройству.
Создание аудиоустройств
Для получения дальнейшей информации о создании аудиоустройств, см. Руководство по программированию Аудиоустройства.
Хостинг аудиоустройств
Аудиоустройства, будучи плагинами, требуют, чтобы хост-приложение загрузило и управляло ими.
Поскольку аудиоустройства являются компонентами Component Manager, хост-приложение должно вызвать Менеджер компонентов для загрузки их. Хост-приложение может найти и инстанцировать аудиоустройств, если они установлены в одной из следующих папок:
~/Library/Audio/Plug-Ins/Components
. Аудиоустройства, установленные здесь, могут только использоваться владельцем домашней папки./Library/Audio/Plug-Ins/Components
. Аудиоустройства, установленные здесь, доступны всем пользователям./System/Library/Components
. Расположение по умолчанию для предоставленных Apple аудиоустройств.
Если необходимо получить список доступных аудиоустройств (для отображения пользователю, например), необходимо вызвать функцию Менеджера компонентов CountComponents
для определения, сколько аудиоустройств определенного типа доступно, затем выполните итерации использования FindNextComponent
получить информацию о каждом модуле. A ComponentDescription
структура содержит идентификаторы для каждого аудиоустройства (его тип, подтип и коды производителя). Посмотрите Предоставленные систему Аудиоустройства в OS X для списка типов Менеджера компонентов и подтипов для предоставленных Apple аудиоустройств. Узел может также открыть каждый модуль (путем вызова OpenComponent
) таким образом, это может запросить его для различной информации о свойстве, такой как форматы данных ввода и вывода аудиоустройства по умолчанию, которые узел может тогда кэшировать и представить пользователю.
В большинстве случаев график обработки аудиоданных является самым простым способом подключить аудиоустройства. Одно преимущество использования графика обработки состоит в том, что API заботится о совершении отдельных звонков Менеджера компонентов, чтобы инстанцировать или уничтожить аудиоустройства. Для создания графика вызвать NewAUGraph
, который возвращает новый объект диаграмм. Тогда можно добавить аудиоустройства к графику путем вызова AUGraphNewNode
. График должен закончиться в устройстве вывода, или аппаратный интерфейс (такой как устройство вывода по умолчанию или AUHAL) или универсальное устройство вывода.
После добавления модулей, которые составят график обработки, вызвать AUGraphOpen
. Эта функция эквивалентна вызову OpenComponent
на каждом из аудиоустройств в графике. В это время можно установить свойства аудиоустройства, такие как расположение канала, частота дискретизации или свойства, определенные для определенного модуля (такие как число вводов и выводов, которые это содержит).
Для создания конкретных соединений между аудиоустройствами вызвать AUGraphConnectNodeInput
, указание вывода и ввода для соединения. Цепочка аудиоустройства должна закончиться в устройстве вывода; иначе хост-приложение не имеет никакого способа запустить и остановить обработку аудиоданных.
Если аудиоустройство имеет пользовательский интерфейс, хост-приложение ответственно за отображение его. Аудиоустройства могут предоставить Какао или Основанный на углероде интерфейс (или оба). Код для пользовательского интерфейса обычно связывается вместе с аудиоустройством.
Если интерфейс Основан на какао, хост-приложение должно запросить свойство модуля
kAudioUnitProperty_CocoaUI
найти пользовательский класс, реализующий интерфейс (подклассNSView
) и создайте экземпляр того класса.Если интерфейс Основан на углероде, пользовательский интерфейс сохранен как один или несколько компонентов Component Manager. Можно получить идентификаторы компонента (тип, подтип, производитель) путем запросов
kAudioUnitProperty_GetUIComponentList
свойство. Хост-приложение может тогда инстанцировать пользовательского интерфейса путем вызоваAudioUnitCarbonViewCreate
на данном компоненте, выводящем на экран его интерфейс в окне как HIView.
После создания сигнальной цепочки можно инициализировать аудиоустройства путем вызова AUGraphInitialize
. Выполнение так вызывает функцию инициализации для каждого аудиоустройства, позволяя ему выделить память для рендеринга, сконфигурировать информацию о канале, и т.д. Тогда можно вызвать AUGraphStart
, который инициирует обработку. Устройство вывода тогда запрашивает аудиоданные от предыдущего модуля в цепочке (посредством обратного вызова), который тогда вызывает его предшественника и т.д. Источник аудио может быть аудиоустройством (таким как модуль генератора или AUHAL), или хост-приложение может предоставить сами аудиоданные путем регистрации обратного вызова в первом аудиоустройстве в сигнальной цепочке (путем установки модуля kAudioUnitProperty_SetRenderCallback
свойство).
В то время как аудиоустройство инстанцируют, хост-приложение может хотеть знать об изменениях в значениях параметров или значениях свойств; это может зарегистрировать объект прослушивателя, который будет уведомлен, когда происходят изменения. Для получения дополнительной информации о том, как реализовать такого слушателя, посмотрите Техническое примечание TN2104: Обработка Событий Аудиоустройства.
Когда узел хочет к обработке стопового сигнала, он вызывает AUGraphStop
.
Для деинициализации всех аудиоустройств в графике вызвать AUGraphUninitialize
. Когда назад в неинициализированном состоянии, можно все еще изменить свойства аудиоустройства и сделать или изменить соединения. Если Вы вызываете AUGraphClose
, каждое аудиоустройство в графике освобождено a CloseComponent
вызвать. Однако график все еще сохраняет узловую информацию, относительно которого модулей он содержит.
Для избавления от графика обработки вызвать DisposeAUGraph
. Избавление от графика автоматически избавляется от любых инстанцированных аудиоустройств, которые оно содержит.
Для примеров хостинга аудиоустройств посмотрите Services/AudioUnitHosting
и Services/CocoaAUHost
примеры в Core Audio SDK.
Для примера реализации пользовательского интерфейса аудиоустройства посмотрите AudioUnits/CarbonGenericView
пример в Core Audio SDK. Можно использовать этот пример с любым аудиоустройством, содержащим корректируемые пользователем параметры.
Обработка данных MIDI
При работе с данными MIDI приложение, возможно, должно было бы загрузить данные дорожки из стандартного файла MIDI (SMF). Можно вызвать функцию Music Player (MusicSequenceLoadSMFWithFlags
или MusicSequenceLoadSMFDataWithFlags
) считать в данных в Стандарте Формат MIDI, как показано на рисунке 3-5.
В зависимости от типа файла MIDI и набора флагов при загрузке файла, можно хранить все данные MIDI в одноколейном пути или сохранить каждый канал MIDI как отдельную дорожку в последовательности. По умолчанию каждый канал MIDI отображается последовательно на новой дорожке в последовательности. Например, если данные MIDI содержат каналы 1, 3, и, 4, три новых дорожки добавляются к последовательности, содержа данные для каналов 1, 3, и 4 соответственно. Эти дорожки добавляются к последовательности в конце любых существующих дорожек. Каждая дорожка в последовательности присваивается основанное на нуле индексное значение.
Информация синхронизации (т.е. события темпа) переходит к треку управления темпом.
Как только Вы загрузили данные MIDI в последовательность, можно присвоить экземпляр аудиоплеера для игры его, как показано на рисунке 3-6.
Последовательность должна быть связана с определенным графиком обработки аудиоданных, и дорожки в последовательности могут быть присвоены одному или более модулям инструментов в графике. (Если Вы не указываете отображение дорожки, аудиоплеер отправляет все данные MIDI в первый модуль инструментов, который это находит в графике.) Аудиоплеер, присвоенный последовательности автоматически, связывается с устройством вывода графика, чтобы удостовериться, что должным образом синхронизируются исходящие аудиоданные. Компрессорная установка, в то время как не требуемый, полезна для обеспечения, что динамический диапазон вывода модуля инструментов остается непротиворечивым.
Данные MIDI в последовательности могут также перейти к внешним аппаратным средствам MIDI (или программное обеспечение, сконфигурированное как виртуальное место назначения MIDI), как показано на рисунке 3-7.
Дорожки, предназначенные для вывода MIDI, должны быть присвоены конечная точка MIDI. Аудиоплеер связывается с Core MIDI, чтобы гарантировать, что должным образом синхронизируется поток данных к MIDI-устройству. Core MIDI тогда координирует с Сервером MIDI для передачи данных к инструменту MIDI.
Последовательность дорожек может быть присвоена комбинации модулей инструментов и MIDI-устройств. Например, в то время как другие дорожки проходят через Core MIDI для проигрывания внешних MIDI-устройств, как показано на рисунке 3-8, можно присвоить некоторые дорожки для проигрывания модуля инструментов.
Аудиоплеер автоматически координирует между устройством вывода графика обработки аудиоданных и Core MIDI, чтобы гарантировать, что синхронизируются выводы.
Другой общий сценарий уже должен воспроизвести существующие данные дорожки при принятии нового ввода MIDI, как показано на рисунке 3-9.
Воспроизведение существующих данных обрабатывается, как обычно, через график обработки аудиоданных, отправляющий аудиоданные в устройство вывода. Новые данные от внешнего MIDI-устройства входят через Core MIDI и передаются через присвоенную конечную точку. Ваше приложение должно выполнить итерации через эти входящие данные и записать события MIDI в новую или существующую дорожку. Аудиоплеер API содержит функции, чтобы добавить новые дорожки к последовательности и записать события MIDI, к которым добавляют метку времени, или другие сообщения к дорожке.
Для примеров обработки и игры данных MIDI, посмотрите следующие примеры в Core Audio SDK:
PlaySoftMIDI, отправляющий данные MIDI в простой график обработки, состоящий из модуля инструментов и устройства вывода.
PlaySequence, читающий в файле MIDI в последовательность и использующий аудиоплеер для игры его.
Обработка аудио и данных MIDI вместе
Иногда Вы хотите объединить аудиоданные с аудио, синтезируемым от данных MIDI и воспроизвести результат. Например, аудио для многих игр состоит из фоновой музыки, которая сохранена как аудиофайл на диске, вместе с шумами, инициированными событиями (шаги, орудийный огонь, и т.д.), которые сгенерированы как данные MIDI. Рисунок 3-10 показывает, как можно использовать Core Audio для объединения двух.
Аудиоданные звуковой дорожки получены от диска или памяти и преобразованы в линейный PCM использование Расширенного Аудиофайла API. Данные MIDI, хранившие как дорожки в музыкальной последовательности, отправляются в виртуальный модуль инструментов. Вывод от виртуального модуля инструментов находится в линейном формате PCM и может тогда быть объединен с данными звуковой дорожки. Этот пример использует 3D модуль микшера, который может расположить источники аудиосигналов в трехмерное пространство. Одна из дорожек в последовательности отправляет данные о событии в модуль микшера, изменяющий параметры расположения, заставляя звук, казаться, перемещаться в течение долгого времени. Приложение должно было бы контролировать перемещения проигрывателя и добавить события к специальной дорожке перемещения по мере необходимости.
Для примера загрузки и игры основанных на файле аудиоданных, посмотрите SimpleSDK/PlayFile
в Core Audio SDK.