Основы Core Audio

Apple разработал программные интерфейсы к Core Audio с помощью многоуровневого, совместного, фокусируемого на задаче подхода. Считайте первые два раздела в этой главе для краткого введения в эти интерфейсы и как они сотрудничают. Продолжайте читать для понимания принципов разработки, используйте образцы, и программировать идиомы, проникающие в Core Audio. Более поздние разделы в этой главе представляют Вас тому, как Core Audio работает с файлами, потоками, записывая и воспроизведением и плагинами.

API архитектурные уровни

Интерфейсы программирования для Core Audio располагаются на три уровня, как проиллюстрировано на рисунке 2-1.

Рисунок 2-1  три уровня API Core Audio
The three layers of Core Audio

Нижний слой включает:

Приложения Mac могут быть записаны для использования этих технологий непосредственно, когда они требуют максимально возможной, производительности в реальном времени. Много аудиоприложений, однако, не получают доступ к этому уровню. Действительно, Core Audio в iOS обеспечивает способы достигнуть аудио в реальном времени с помощью высокоуровневых интерфейсов. OpenAL, например, использует прямой I/O для аудио в реальном времени в играх. Результатом является значительно меньший, настроенный набор API, подходящий для мобильной платформы.

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

Core Audio в iOS поддерживает большинство этих служб, как показано на рисунке 1-2.

Самый высокий уровень в Core Audio включает оптимизированные интерфейсы, сочетающие функции от нижних уровней.

Платформы

Вы получаете другое представление Core Audio путем рассмотрения его платформ API, расположенных в /System/Library/Frameworks/. Этот раздел быстро перечисляет их, чтобы дать Вам смысл того, где найти части, составляющие уровни Core Audio.

Обратите внимание, что платформа Core Audio не является зонтиком к другим платформам здесь, а скорее коллегой.

Платформы Core Audio Приложения описывают все эти платформы, а также каждый из их включенных заголовочных файлов.

Объекты прокси

Core Audio использует понятие объектов прокси представлять такие вещи как файлы, потоки, аудиоплееры, и т.д. Когда Вы хотите свое рвение с дисковым аудиофайлом, например, первый шаг должен инстанцировать объекта аудиофайла типа AudioFileID. Этот объект объявляется как непрозрачная структура данных в AudioFile.h заголовочный файл:

typedef struct OpaqueAudioFileID *AudioFileID;

Вы инстанцируете объекта аудиофайла — и создаете фактический аудиофайл, связанный к тому объекту — путем вызова AudioFileCreateWithURL функция. Функция дает Вам ссылку на новый объект аудиофайла. От той точки на Вы работаете с реальным аудиофайлом путем передачи с объектом прокси.

Этот вид образца является непротиворечивым всюду по Core Audio, работаете ли Вы с аудиофайлами, сеансы аудио iPhone (описанный в Одио Сешнзе: Сотрудничество с Core Audio), или даже устройства.

Свойства, объемы и элементы

Большинство интерфейсов Core Audio использует механизм свойства для управления объектным состоянием или совершенствования поведения объекта. Свойство является парой ключ/значение.

Существует много определенных Apple свойств. Вы найдете их определения в различных заголовочных файлах платформы Core Audio. Некоторые интерфейсы Core Audio, такие как Audio Unit Services, позволяют Вам определить свои собственные свойства также.

Core Audio соединяет интерфейсом с функциями средства доступа использования для получения значения свойства от объекта и, в случае перезаписываемого свойства, изменяя его значение. Вы также найдете третью функцию средства доступа для того, чтобы получить информацию о свойствах. Например, функция Audio Unit Services AudioUnitGetPropertyInfo говорит Вам данный размер типа данных значения свойства и можно ли изменить его. Функция Audio Queue Services AudioQueueGetPropertySize получает размер указанного значения свойства.

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

В некоторых случаях свойство применяется к аудио объекту в целом. Например, для включения измерения уровня звука в объекте аудио-очереди воспроизведения Вы устанавливаете значение kAudioQueueProperty_EnableLevelMetering свойство к true.

Другие объекты Core Audio имеют внутреннюю структуру, каждая часть которой может иметь свой собственный набор свойств. Например, аудиоустройство имеет входной объем, выходной объем и глобальную область видимости. Объем ввода или вывода аудиоустройства состоит из одного или более элементов — каждый из которых походит на шину канала в аудио аппаратных средствах. Когда Вы вызываете AudioUnitGetProperty функция с kAudioUnitProperty_AudioChannelLayout свойство, Вы указываете не только аудиоустройство, Вы хотите информацию о, но также и объем (ввод или вывод) и элемент (0, 1, 2, и т.д.).

Функции обратного вызова: взаимодействие с Core Audio

Много интерфейсов Core Audio могут связаться с Вашим приложением с помощью функций обратного вызова. Core Audio использует обратные вызовы для таких вещей как:

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

В случае обратного вызова операционная система — когда это выбирает к — вызывает поведение, которое Вы реализуете в своем приложении. Путем определения обратного вызова в приложении согласно шаблону операционная система может успешно вызвать его. Например, Audio Queue Services указывает шаблон для обратного вызова — что можно реализовать — который позволяет Вам добраться и реагировать на сообщения, когда изменяется свойство объекта аудио-очереди. Этот шаблон обратного вызова, объявленный в AudioQueue.h заголовочный файл, показан в Перечислении 2-1.

Перечисление 2-1  шаблон для функции обратного вызова

typedef void    (*AudioQueuePropertyListenerProc) (
                    void *                  inUserData,
                    AudioQueueRef           inAQ,
                    AudioQueuePropertyID    inID
                );

Чтобы реализовать и использовать обратный вызов в Вашем приложении, Вы делаете две вещи:

  1. Реализуйте функцию обратного вызова. Например, Вы могли бы реализовать обратный вызов слушателя свойства аудио-очереди для обновления заголовков и включенного/нерабочего состояния из кнопок в пользовательском интерфейсе, в зависимости от того, работает ли объект аудио-очереди или остановился.

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

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

Перечисление 2-2  реализация обратного вызова слушателя свойства

static void propertyListenerCallback (
    void                    *inUserData,
    AudioQueueRef           queueObject,
    AudioQueuePropertyID    propertyID
) {
    AudioPlayer *player = (AudioPlayer *) inUserData;
        // gets a reference to the playback object
    [player.notificationDelegate updateUserInterfaceOnAudioQueueStateChange: player];
        // your notificationDelegate class implements the UI update method
}

(В определении класса Objective C Вы помещаете это определение обратного вызова вне реализации класса. Это - то, почему в организации функции существует оператор для получения ссылки на объект воспроизведения — в этом примере, inUserData параметр является Вашим объектом. Вы делаете эту ссылку, доступную для использования в обратном вызове при регистрации обратного вызова, описанного затем.)

Вы зарегистрировали бы этот определенный обратный вызов как показано в Перечислении 2-3.

Перечисление 2-3  , Регистрирующее обратный вызов слушателя свойства

AudioQueueAddPropertyListener (
    self.queueObject,                // the object that will invoke your callback
    kAudioQueueProperty_IsRunning,   // the ID of the property you want to listen for
    propertyListenerCallback,        // a reference to your callback function
    self
);

Форматы аудиоданных

Core Audio изолирует Вас от необходимости в детальном знании форматов аудиоданных. Мало того, что это упрощает иметь дело с определенным форматом в Вашем коде — это означает, что один набор кода может работать с любым форматом, поддерживаемым операционной системой.

Универсальные типы данных в Core Audio

В Core Audio Вы используете два универсальных типа данных для представления любого формата аудиоданных. Эти типы являются структурами данных AudioStreamBasicDescription (Перечисление 2-4) и AudioStreamPacketDescription (Перечисление 2-5), оба объявленные в CoreAudioTypes.h заголовочный файл и описал в Ссылке Типов данных Core Audio.

Перечисление 2-4  AudioStreamBasicDescription тип данных

struct AudioStreamBasicDescription {
    Float64 mSampleRate;
    UInt32  mFormatID;
    UInt32  mFormatFlags;
    UInt32  mBytesPerPacket;
    UInt32  mFramesPerPacket;
    UInt32  mBytesPerFrame;
    UInt32  mChannelsPerFrame;
    UInt32  mBitsPerChannel;
    UInt32  mReserved;
};
typedef struct AudioStreamBasicDescription  AudioStreamBasicDescription;

В этой структуре, mReserved у элемента должно всегда быть значение 0. У других элементов может быть значение 0 также. Например, сжатые форматы аудио используют переменное число битов на выборку. Для этих форматов, значения mBitsPerChannel элемент 0.

Тип описания пакета аудиопотока играет роль для определенных сжатых форматов аудиоданных, как описано в Пакетах Аудиоданных.

Перечисление 2-5  AudioStreamPacketDescription тип данных

struct  AudioStreamPacketDescription {
    SInt64  mStartOffset;
    UInt32  mVariableFramesInPacket;
    UInt32  mDataByteSize;
};
typedef struct AudioStreamPacketDescription AudioStreamPacketDescription;

Для аудиоданных с постоянной скоростью передачи (как описано в Пакетах Аудиоданных), mVariableFramesInPacket у элемента в этой структуре есть значение 0.

Получение формата данных звукового файла

Можно заполнить элементы ASBD вручную в коде. Когда Вы делаете, Вы не можете знать правильное значение для некоторых (или никто) элементов структуры. Установите те значения в 0 и затем используйте интерфейсы Core Audio для изложения в деталях структуры.

Например, можно использовать Audio File Services, чтобы дать Вам полный аудиопоток основное описание для звукового файла на диске как показано в Перечислении 2-6.

Перечисление 2-6  Получая аудиопоток основное описание для игры звукового файла

- (void) openPlaybackFile: (CFURLRef) soundFile {
 
    AudioFileOpenURL (
        (CFURLRef) self.audioFileURL,
        0x01,                  // read only
        kAudioFileCAFType,
        &audioFileID
    );
 
    UInt32 sizeOfPlaybackFormatASBDStruct = sizeof ([self audioFormat]);
 
    AudioFileGetProperty (
        [self audioFileID],
        kAudioFilePropertyDataFormat,
        &sizeOfPlaybackFormatASBDStruct,
        &audioFormat          // the sound file's ASBD is returned here
    );
}

Канонические форматы аудиоданных

В зависимости от платформы Core Audio имеет один или два «канонических» формата аудиоданных в том смысле, что эти форматы могут быть:

  • Требуемый как промежуточный формат в преобразованиях

  • Формат, для которого оптимизирована служба в Core Audio

  • Значение по умолчанию, или принятый, формат, когда Вы иначе не указываете ASBD

Стандартные форматы в Core Audio следующие:

  • ввод и вывод iOS Линейный PCM с 16-разрядными целочисленными выборками

  • аудиоустройства iOS и другая обработка аудиоданных Нечередующийся линейный PCM с 8.24-разрядными выборками фиксированной точки

  • Ввод и вывод Mac Линейный PCM с 32-разрядными выборками с плавающей точкой

  • Аудиоустройства Mac и другая обработка аудиоданных Нечередующийся линейный PCM с 32-разрядными выборками с плавающей точкой

Вот является полностью оперенный аудиопоток основным примером описания, иллюстрирующим канонический демонстрационный формат аудиоустройства iPhone с двумя каналами с частотой дискретизации на 44,1 кГц.

struct AudioStreamBasicDescription {
    mSampleRate       = 44100.0;
    mFormatID         = kAudioFormatLinearPCM;
    mFormatFlags      = kAudioFormatFlagsAudioUnitCanonical;
    mBytesPerPacket   = 1 * sizeof (AudioUnitSampleType);    // 8
    mFramesPerPacket  = 1;
    mBytesPerFrame    = 1 * sizeof (AudioUnitSampleType);    // 8
    mChannelsPerFrame = 2;
    mBitsPerChannel   = 8 * sizeof (AudioUnitSampleType);    // 32
    mReserved         = 0;
};

Константы и типы данных, используемые в качестве значений здесь, объявляются в CoreAudioTypes.h заголовочный файл и описал в Ссылке Типов данных Core Audio. Используя AudioUnitSampleType тип данных здесь (и AudioSampleType тип данных при обработке аудио I/O), гарантирует, что ASBD является агностиком платформы.

Еще два понятия закругляют это введение в форматы аудиоданных в Core Audio: волшебные cookie и пакеты, описанные затем.

Волшебные cookie

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

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

Перечисление 2-7  Используя волшебный cookie при игре звукового файла

- (void) copyMagicCookieToQueue: (AudioQueueRef) queue fromFile: (AudioFileID) file {
 
    UInt32 propertySize = sizeof (UInt32);
 
    OSStatus result = AudioFileGetPropertyInfo (
                            file,
                            kAudioFilePropertyMagicCookieData,
                            &propertySize,
                            NULL
                        );
 
    if (!result && propertySize) {
 
        char *cookie = (char *) malloc (propertySize);
 
        AudioFileGetProperty (
            file,
            kAudioFilePropertyMagicCookieData,
            &propertySize,
            cookie
        );
 
        AudioQueueSetProperty (
            queue,
            kAudioQueueProperty_MagicCookie,
            cookie,
            propertySize
        );
 
        free (cookie);
    }
}

Пакеты аудиоданных

Предыдущая глава определила пакет как набор одного или более кадров. Это - самый маленький значимый набор кадров для данного формата аудиоданных. Поэтому это - лучший модуль аудиоданных для представления единицы времени в аудиофайле. Синхронизация в Core Audio работает путем подсчета пакетов. Можно использовать пакеты для вычисления полезных буферных размеров аудиоданных, как показано в Перечислении 2-8.

Каждый формат аудиоданных определяется, частично, по тому, как сконфигурированы его пакеты. Аудиопоток основная структура данных описания описывает основную информацию о пакетах формата в mBytesPerPacket и mFramesPerPacket элементы, как показано в Перечислении 2-4. Для форматов, запрашивающих дополнительную информацию, Вы используете структуру данных описания пакета аудиопотока, как описано через мгновение.

Существует три вида пакетов, используемых в форматах аудиоданных:

  • В CBR форматы (с постоянной скоростью передачи), такие как линейный PCM и IMA/ADPCM, все пакеты являются тем же размером.

  • В VBR форматы (с переменной скоростью передачи), такие как AAC, Apple Lossless и MP3, все пакеты имеют то же число кадров, но может варьироваться число битов в каждом демонстрационном значении.

  • В VFR (переменная частота кадров) форматируют, пакеты имеют переменное число кадров. Нет никаких обычно используемых форматов этого типа.

Использовать VBR или VFR форматирует в Core Audio, Вы используете структуру описания пакета аудиопотока (Перечисление 2-5). Каждая такая структура описывает единственный пакет в звуковом файле. Чтобы записать или играть VBR или звуковой файл VFR, Вам нужен массив этих структур, один для каждого пакета в файле.

Интерфейсы в Audio File Services и Audio File Stream Services позволяют Вам работать с пакетами. Например, AudioFileReadPackets функция в AudioFile.h дает Вам ряд пакетов, считанных из звукового файла на диске, размещая их в буфер. Одновременно, это дает Вам массив AudioStreamPacketDescription структуры, который описывает каждый из тех пакетов.

В CBR и форматах VBR (т.е. во всех обычно используемых форматах), число пакетов в секунду фиксируется для данного аудиофайла или потока. Здесь существует полезная импликация: пакетирование подразумевает единицу времени для формата. Можно использовать пакетирование при вычислении практического размера буфера аудиоданных для приложения. Например, следующий метод определяет число пакетов для чтения для заполнения буфера данной продолжительностью аудиоданных:

Перечисление 2-8  , Вычисляющее размер буфера воспроизведения на основе пакетирования

- (void) calculateSizesFor: (Float64) seconds {
 
    UInt32 maxPacketSize;
    UInt32 propertySize = sizeof (maxPacketSize);
 
    AudioFileGetProperty (
        audioFileID,
        kAudioFilePropertyPacketSizeUpperBound,
        &propertySize,
        &maxPacketSize
    );
 
    static const int maxBufferSize = 0x10000;   // limit maximum size to 64K
    static const int minBufferSize = 0x4000;    // limit minimum size to 16K
 
    if (audioFormat.mFramesPerPacket) {
        Float64 numPacketsForTime =
            audioFormat.mSampleRate / audioFormat.mFramesPerPacket * seconds;
        [self setBufferByteSize: numPacketsForTime * maxPacketSize];
    } else {
        // if frames per packet is zero, then the codec doesn't know the
        // relationship between packets and time. Return a default buffer size
        [self setBufferByteSize:
            maxBufferSize > maxPacketSize ? maxBufferSize : maxPacketSize];
    }
 
    // clamp buffer size to our specified range
    if (bufferByteSize > maxBufferSize && bufferByteSize > maxPacketSize) {
        [self setBufferByteSize: maxBufferSize];
    } else {
        if (bufferByteSize < minBufferSize) {
            [self setBufferByteSize: minBufferSize];
        }
    }
 
    [self setNumPacketsToRead: self.bufferByteSize / maxPacketSize];
}

Преобразование формата данных

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

При использовании Audio Queue Services (описанный в использовании Записи и Воспроизведения Audio Queue Services), Вы получаете надлежащий преобразователь автоматически. Audio Codec Services (только Mac) позволяет Вам создать специализированные аудиокодеки, такой что касается обработки управления цифровыми правами (DRM) или собственных форматов аудио. После создания пользовательского кодека можно использовать аудио преобразователь, чтобы получить доступ и использовать его.

При использовании аудио преобразователя явно в OS X Вы вызываете функцию преобразования с определенным экземпляром преобразователя, указывая, где найти входные данные и где записать вывод. Большинство преобразований требует, чтобы функция обратного вызова периодически снабдила входными данными к преобразователю. Для примеров того, как использовать аудио преобразователи, посмотрите SimpleSDK/ConvertFile и AFConvert инструмент командной строки в Services/AudioFileTools в Core Audio SDK.

Поддерживаемые Форматы аудиофайла и Форматы данных в OS X перечисляют стандартные кодеки Core Audio для перевода в любом направлении между сжатыми форматами и Линейным PCM. Для больше на кодеках, посмотрите Кодеки.

Звуковые файлы

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

Помимо разрешения Вам работать с основами — уникальным идентификатором файла, типом файла, и форматом данных — Audio File Services позволяет Вам работать с областями и маркерами, цикличным выполнением, воспроизвести направление, временной код SMPTE и т.д.

Вы также используете Audio File Services для обнаружения системных характеристик. Функции, которые Вы используете, AudioFileGetGlobalInfoSize (чтобы позволить Вам выделить память для содержания информации, Вы хотите), и AudioFileGetGlobalInfo (для получения той информации). Длинный список свойств, объявленных в AudioFile.h позволяет Вам программно получить системные характеристики, такие как:

Этот раздел также представляет Вас двум другим технологиям Core Audio:

Создание нового звукового файла

Для создания нового звукового файла для записи в Вам нужно:

  • Путь файловой системы для файла, в форме a CFURL или NSURL объект.

  • Идентификатор для типа файла, который Вы хотите создать, как объявлено в Аудиофайле Вводит перечисление AudioFile.h. Например, для создания файла CAF Вы используете kAudioFileCAFType идентификатор.

  • Аудиопоток основное описание для аудиоданных Вы вставите файл. Во многих случаях можно обеспечить частичный ASBD и позже попросить, чтобы Audio File Services заполнила ее для Вас.

Вы даете эти три данные Audio File Services как параметры к AudioFileCreateWithURL функция, создающая файл и отдающая Вас AudioFileID объект. Вы тогда используете этот объект для дальнейшего взаимодействия со звуковым файлом. Вызов функции показан в Перечислении 2-9.

Перечисление 2-9  , Создающее звуковой файл

AudioFileCreateWithURL (
    audioFileURL,
    kAudioFileCAFType,
    &audioFormat,
    kAudioFileFlags_EraseFile,
    &audioFileID   // the function provides the new file object here
);

Открытие звукового файла

Для открытия звукового файла для воспроизведения Вы используете AudioFileOpenURL функция. Вы предоставляете эту функцию URL файла, постоянная подсказка типа файла, и полномочия доступа к файлу, которые Вы хотите использовать. AudioFileOpenURL дает Вам назад уникальный идентификатор для файла.

Вы тогда используете идентификаторы свойства, вместе с AudioFileGetPropertyInfo и AudioFileGetProperty функции, для получения то, что необходимо знать о файле. Некоторые часто используемые идентификаторы свойства — которые довольно очевидны —:

  • kAudioFilePropertyFileFormat

  • kAudioFilePropertyDataFormat

  • kAudioFilePropertyMagicCookieData

  • kAudioFilePropertyChannelLayout

Существует много таких идентификаторов, доступных в Audio File Services, которые позволяют Вам получить метаданные, которые могут быть в файле, таком как маркеры области, информация об авторском праве, и воспроизводить темп.

Когда файл VBR длинен — говорят, подкаст — получение таблицы целого пакета может занять существенное количество времени. В таком случае два идентификатора свойства особенно полезны: kAudioFilePropertyPacketSizeUpperBound и kAudioFilePropertyEstimatedDuration. Можно использовать их для быстрого приближения продолжительности звукового файла VBR или числа пакетов вместо парсинга всего файла для получения точных чисел.

Чтение от и запись в звуковой файл

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

  • Чтение и запись пакетом являются единственной опцией для данных VBR.

  • Используя основанные на пакете операции делает намного проще вычислить продолжительности.

Другой опцией в iOS для чтения аудиоданных от диска является Audio File Stream Services. Для введения в эту технологию посмотрите Звуковые Потоки далее в этой главе.

Audio Queue Services, объявленная в AudioQueue.h заголовочный файл в Аудио платформе Панели инструментов, интерфейс Core Audio для записи и воспроизведения. Для обзора Audio Queue Services посмотрите использование Записи и Воспроизведения Audio Queue Services далее в этой главе.

Extended Audio File Services

Core Audio обеспечивает удобство API по имени Extended Audio File Services. Этот интерфейс охватывает существенные функции в Audio File Services и Audio Converter Services, обеспечивая автоматическое преобразование данных в и от линейного PCM. Посмотрите Чтение и Запись Аудиоданных для больше на этом.

Форматы аудиофайла iPhone

iOS поддерживает форматы аудиофайла, перечисленные в Таблице 2-1. Для получения информации о форматах аудиоданных, доступных в iOS, посмотрите Кодеки.

Таблица 2-1  форматы аудиофайла iOS

Имя формата

Отформатируйте расширения файла

AIFF

.aif, .aiff

CAF

.caf

MPEG 1, уровень 3

.mp3

MPEG 2 или MPEG 4 ADTS

.aac

MPEG 4

.m4a, .mp4

WAV

.wav

Файлы CAF

iOS и OS X имеют собственный формат аудиофайла, Формат Core Audio (или CAF) формат файла. Формат CAF был представлен в OS X v10.4 «Тигр» и доступный в iOS 2.0 и более новым. Это уникально в этом, это может содержать любой формат аудиоданных, поддерживаемый на платформе.

Файлы CAF не имеют никаких ограничений размера — в отличие от AIFF и файлов WAVE — и могут поддерживать широкий диапазон метаданных, таких как текстовые аннотации и информация о канале. Для получения дальнейшей информации о формате файла CAF, посмотрите Спецификацию 1.0 Формата аудио Огрызка.

Звуковые потоки

В отличие от находящегося на диске звукового файла, поток аудиофайла является аудиоданными, начало которых и конец у Вас не может быть доступа к. Например, когда Вы создаете интернет-приложение радио-проигрывателя, Вы встречаетесь с потоками. Провайдер обычно отправляет их поток постоянно. Когда пользователь нажимает Play для слушания в, приложение должно перейти на борту независимо от того, какие данные проходят в данный момент — запуск, середина, или конец аудио пакета, или возможно волшебный cookie.

Также в отличие от звукового файла, данные потока могут не быть надежно доступными. Могут быть уволенные, разрывы или паузы — в зависимости от капризов сети, от которой Вы получаете поток.

Audio File Stream Services позволяет Вашему приложению работать с потоками и всеми их сложностями. Это заботится о парсинге.

Для использования Audio File Stream Services Вы создаете потоковый объект аудиофайла типа AudioFileStreamID. Этот объект служит прокси для самого потока. Этот объект также сообщает Вашему приложению, что продолжает поток посредством свойств (см. Свойства, Объемы и Элементы). Например, когда Audio File Stream Services установила курс передачи для потока, это устанавливает kAudioFileStreamProperty_BitRate свойство на Вашем потоковом объекте аудиофайла.

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

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

  1. Пользователь нажимает Play, или иначе запрашивает, чтобы поток начал играть.

  2. Audio File Stream Services начинает анализировать поток.

  3. Когда достаточно пакетов аудиоданных анализируется для посылания их приложению, Audio File Stream Services устанавливает kAudioFileStreamProperty_ReadyToProducePackets свойство к true (фактически, к значению 1) в Вашем потоковом объекте аудиофайла.

  4. Audio File Stream Services вызывает обратный вызов слушателя свойства Вашего приложения со Значением идентификатора свойства kAudioFileStreamProperty_ReadyToProducePackets.

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

Во-вторых, Вам нужен обратный вызов для аудиоданных. Audio File Stream Services вызывает этот обратный вызов каждый раз, когда это собрало ряд полных пакетов аудиоданных. Вы определяете этот обратный вызов для обработки полученного аудио. Как правило, Вы сразу воспроизводите его путем посылания его Audio Queue Services. Для больше на воспроизведении, посмотрите следующий раздел, Записав и использование Воспроизведения Audio Queue Services.

Аудио сеансы: сотрудничество с Core Audio

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

Для первой передачи эта “правильная вещь” означает оправдывать пользовательские надежды. Для второй передачи это также означает, что iPhone должен рассмотреть текущее состояние каждого запущенного приложения при разрешении конкурирующих запросов.

Аудио сеанс является посредником между Вашим приложением и iOS. Каждое приложение для iPhone имеет точно один аудио сеанс. Вы конфигурируете его для выражения аудио намерений приложения. Для запуска Вы отвечаете на некоторые вопросы о том, как Вы хотите, чтобы Ваше приложение вело себя:

С ответами в руке Вы используете аудио интерфейс сеанса (объявленный в AudioToolbox/AudioServices.h) сконфигурировать Ваш аудио сеанс и Ваше приложение. Таблица 2-2 описывает три программируемых функции, предоставленные этим интерфейсом.

Табличные 2-2  Функции, предоставленные аудио интерфейсом сеанса

Аудио функция сеанса

Описание

Категории

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

Прерывания и изменения маршрута

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

Характеристики оборудования

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

Аудио поведение значения по умолчанию сеанса

Аудио сеанс идет с некоторым поведением по умолчанию. В частности:

  • Когда пользователь перемещает переключатель Ring/Silent в тихий, Ваше аудио заставлено замолчать.

  • Когда пользователь нажимает кнопку Sleep/Wake для блокировки экрана, или когда период Автоблокировки истекает, аудио заставлено замолчать.

  • То, когда Ваше аудио запускается, другое аудио на устройстве — таком как аудио iPod, уже игравшее — заставлено замолчать.

Этот набор способов поведения указан аудио категорией сеанса по умолчанию, а именно, kAudioSessionCategory_SoloAmbientSound. iOS обеспечивает категории для широкого диапазона аудио потребностей, в пределах от звуковых эффектов пользовательского интерфейса к одновременному аудиовходу и выводу, поскольку Вы использовали бы для VOIP (передача речи по протоколу IP) приложение. Можно указать категорию, которую Вы хотите в запуске и в то время как Ваше выполнение приложения.

Аудио поведения значения по умолчанию сеанса достаточно для запущения Вас в разработке аудио iPhone. За исключением определенных особых случаев, однако, поведение по умолчанию является неподходящим для поставляющего приложения, как описано затем.

Прерывания: деактивация и активация

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

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

Когда прерывание заканчивается, при использовании OpenAL, аудиоустройства I/O, или Audio Queue Services для аудио в приложении, необходимо записать функцию обратного вызова слушателя прерывания и явно повторно активировать аудио сеанс. Аудио Руководство по программированию Сеанса предоставляет подробную информацию и примеры кода.

Если Вы используете AVAudioPlayer класс, класс заботится об аудио оживлении сеанса для Вас.

Определение, если Аудиовход Доступен

Приложение записи на основанном на iOS устройстве может записать, только если аппаратный аудиовход доступен. Для тестирования этого Вы используете аудио сеанс kAudioSessionProperty_AudioInputAvailable свойство. Это важно, когда Ваше приложение работает на устройствах как iPod touch (второе поколение), которые получают аудиовход только, когда надлежащий вспомогательный присоединяются аппаратные средства. Перечисление 2-10 показывает, как выполнить тест.

Перечисление 2-10  , Определяющее, если аудиозапись поддержки мобильных устройств

UInt32 audioInputIsAvailable;
UInt32 propertySize = sizeof (audioInputIsAvailable);
 
AudioSessionGetProperty (
    kAudioSessionProperty_AudioInputAvailable,
    &propertySize,
    &audioInputIsAvailable // A nonzero value on output means that
                           // audio input is available
);

Используя Ваш аудио сеанс

Ваше приложение имеет всего одну аудио категорию сеанса за один раз — так, в установленный срок, все Ваше аудио повинуется характеристикам активной категории. (Одно исключение к этому правилу является аудио, что Вы играете использование System Sound Services — API для звуковых эффектов пользовательского интерфейса и предупреждений. Такое аудио всегда использует самую низкую приоритетную категорию сеанса аудио.) Ответ на Прерывания в Аудио Руководстве по программированию Сеанса описывает все категории.

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

Воспроизведение с помощью Класса AVAudioPlayer

AVAudioPlayer класс обеспечивает простой интерфейс Objective-C для воспроизведения аудио. Если Ваше приложение не требует расположения стерео или точной синхронизации, и если Вы не играете аудио, полученное от сетевого потока, Apple рекомендует использовать этот класс для воспроизведения.

Используя аудиоплеер Вы можете:

AVAudioPlayer класс позволяет Вам играть звук в любом формате аудио, доступном в iOS. Для полного описания интерфейса этого класса посмотрите Ссылку класса AVAudioPlayer.

В отличие от OpenAL, аудиоустройства I/O и Audio Queue Services, AVAudioPlayer класс не требует, чтобы Вы использовали Сеансовые службы Одио. Аудиоплеер повторно активирует себя после прерывания. Если Вы хотите поведение, указанное аудио категорией сеанса по умолчанию (см. Одио Сешнза: Сотрудничая с Core Audio), таким как наличие Вашей аудио остановки, когда экран блокирует, можно успешно использовать аудио сеанс по умолчанию с аудиоплеером.

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

Перечисление 2-11  , Конфигурирующее объект AVAudioPlayer

NSString *soundFilePath =
                [[NSBundle mainBundle] pathForResource: @"sound"
                                                ofType: @"wav"];
 
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
 
AVAudioPlayer *newPlayer =
                [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL
                                                       error: nil];
[fileURL release];
 
self.player = newPlayer;
[newPlayer release];
 
[self.player prepareToPlay];
[self.player setDelegate: self];

Вы используете объект делегата (который может быть Вашим объектом контроллера) обработать прерывания и обновить пользовательский интерфейс, когда звук закончил играть. Методы делегата для AVAudioPlayer класс описан в Ссылке на протокол AVAudioPlayerDelegate. Перечисление 2-12 показывает простую реализацию одного метода делегата. Когда звук закончил играть, этот код обновляет заголовок выключателя Play/Pause.

Перечисление 2-12  Реализовывая метод делегата AVAudioPlayer

- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player
                        successfully: (BOOL) flag {
    if (flag == YES) {
        [self.button setTitle: @"Play" forState: UIControlStateNormal];
    }
}

Для игры приостановитесь или остановитесь AVAudioPlayer объект, вызовите один из его методов управления воспроизведением. Можно протестировать, происходит ли воспроизведение при помощи playing свойство. Перечисление 2-13 показывает основной метод переключателя игры/паузы, что воспроизведение средств управления и обновляет заголовок a UIButton объект.

Перечисление 2-13  , Управляющее объектом AVAudioPlayer

- (IBAction) playOrPause: (id) sender {
 
    // if already playing, then pause
    if (self.player.playing) {
        [self.button setTitle: @"Play" forState: UIControlStateHighlighted];
        [self.button setTitle: @"Play" forState: UIControlStateNormal];
        [self.player pause];
 
    // if stopped or paused, start playing
    } else {
        [self.button setTitle: @"Pause" forState: UIControlStateHighlighted];
        [self.button setTitle: @"Pause" forState: UIControlStateNormal];
        [self.player play];
    }
}

AVAudioPlayer класс использует Objective C, объявил функцию свойств управления информацией о звуке — таком как точка воспроизведения во временной шкале звука, и для доступа к опциям воспроизведения — таким как объем и цикличное выполнение. Например, Вы устанавливаете громкость воспроизведения для аудиоплеера как показано здесь:

[self.player setVolume: 1.0];    // available range is 0.0 through 1.0

Для получения дополнительной информации о AVAudioPlayer класс, посмотрите Ссылку класса AVAudioPlayer.

Запись и использование Воспроизведения Audio Queue Services

Audio Queue Services обеспечивает прямой, низкий служебный способ записать и играть аудио. Это позволяет Вашему приложению использовать аппаратные регистрирующие устройства и устройства воспроизведения (такие как микрофоны и громкоговорители) без ведома аппаратного интерфейса. Это также позволяет Вам использовать сложные кодеки без ведома того, как работают кодеки.

Несмотря на то, что это - высокоуровневый интерфейс, Audio Queue Services поддерживает некоторые расширенные функции. Это обеспечивает тонкозернистое управление синхронизацией для поддержки запланированного воспроизведения и синхронизации. Можно использовать его, чтобы синхронизировать воспроизведение многократных аудио-очередей, играть звуки одновременно, независимо управлять уровнем воспроизведения многократных звуков и выполнить цикличное выполнение. Audio Queue Services и AVAudioPlayer класс (см., что Воспроизведение использует Класс AVAudioPlayer), является единственными способами играть сжатое аудио на iPhone или iPod touch.

Вы обычно используете Audio Queue Services в сочетании с Audio File Services (как описано в Звуковых файлах) или с Audio File Stream Services (как описано в Звуковых Потоках).

Функции обратного вызова аудио-очереди для записи и воспроизведения

Как имеет место с Audio File Stream Services, Вы взаимодействуете с объектами аудио-очереди с помощью обратных вызовов и свойств. Для записи Вы реализуете функцию обратного вызова, принимающую буферы аудиоданных — предоставленный Вашим объектом аудио-очереди записи — и пишущую им в диск. Когда существует новый буфер входящих данных для записи, Ваш объект аудио-очереди вызывает Ваш обратный вызов. Рисунок 2-2 иллюстрирует упрощенное представление этого процесса.

  Запись рисунка 2-2 с объектом аудио-очереди
An audio queue object feeds buffers of fresh audio data to your callback, which writes the buffers to disk.

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

Рисунок 2-3  , Воспроизводящий использование объекта аудио-очереди
An audio queue object requests audio data from your callback, which reads from disk. The callback then hands the data off to an audio queue buffer, which is eventually played by the audio queue object.

Создание объекта аудио-очереди

Для использования Audio Queue Services Вы сначала создаете объект аудио-очереди — которых существует две разновидности, несмотря на то, что у обоих есть тип данных AudioQueueRef.

  • Вы создаете объект аудио-очереди записи использование AudioQueueNewInput функция.

  • Вы создаете объект аудио-очереди воспроизведения использование AudioQueueNewOutput функция.

Для создания объекта аудио-очереди для воспроизведения выполните эти три шага:

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

  2. Определите функцию обратного вызова для управления буферами аудио-очереди. Обратный вызов использует Audio File Services для чтения файла, который Вы хотите играть.

  3. Инстанцируйте аудио-очереди воспроизведения с помощью AudioQueueNewOutput функция.

Перечисление 2-14 иллюстрирует эти шаги:

Перечисление 2-14  , Создающее объект аудио-очереди

static const int kNumberBuffers = 3;
// Create a data structure to manage information needed by the audio queue
struct myAQStruct {
    AudioFileID                     mAudioFile;
    CAStreamBasicDescription        mDataFormat;
    AudioQueueRef                   mQueue;
    AudioQueueBufferRef             mBuffers[kNumberBuffers];
    SInt64                          mCurrentPacket;
    UInt32                          mNumPacketsToRead;
    AudioStreamPacketDescription    *mPacketDescs;
    bool                            mDone;
};
// Define a playback audio queue callback function
static void AQTestBufferCallback(
    void                   *inUserData,
    AudioQueueRef          inAQ,
    AudioQueueBufferRef    inCompleteAQBuffer
) {
    myAQStruct *myInfo = (myAQStruct *)inUserData;
    if (myInfo->mDone) return;
    UInt32 numBytes;
    UInt32 nPackets = myInfo->mNumPacketsToRead;
 
    AudioFileReadPackets (
        myInfo->mAudioFile,
        false,
        &numBytes,
        myInfo->mPacketDescs,
        myInfo->mCurrentPacket,
        &nPackets,
        inCompleteAQBuffer->mAudioData
    );
    if (nPackets > 0) {
        inCompleteAQBuffer->mAudioDataByteSize = numBytes;
        AudioQueueEnqueueBuffer (
            inAQ,
            inCompleteAQBuffer,
            (myInfo->mPacketDescs ? nPackets : 0),
            myInfo->mPacketDescs
        );
        myInfo->mCurrentPacket += nPackets;
    } else {
        AudioQueueStop (
            myInfo->mQueue,
            false
        );
        myInfo->mDone = true;
    }
}
// Instantiate an audio queue object
AudioQueueNewOutput (
    &myInfo.mDataFormat,
    AQTestBufferCallback,
    &myInfo,
    CFRunLoopGetCurrent(),
    kCFRunLoopCommonModes,
    0,
    &myInfo.mQueue
);

Управление уровнем воспроизведения аудио-очереди

Объекты аудио-очереди дают Вам два способа управлять уровнем воспроизведения.

Для установки уровня воспроизведения непосредственно используйте AudioQueueSetParameter функция с kAudioQueueParam_Volume параметр, как показано в Перечислении 2-15. Изменение уровня сразу вступает в силу.

Перечисление 2-15  , Устанавливающее уровень воспроизведения непосредственно

Float32 volume = 1;
AudioQueueSetParameter (
    myAQstruct.audioQueueObject,
    kAudioQueueParam_Volume,
    volume
);

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

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

Указание уровня воспроизведения аудио-очереди

Можно получить текущий уровень воспроизведения из объекта аудио-очереди путем запросов kAudioQueueProperty_CurrentLevelMeterDB свойство. Значение этого свойства является массивом AudioQueueLevelMeterState структуры, один на канал. Перечисление 2-16 показывает эту структуру:

Перечисление 2-16  AudioQueueLevelMeterState структура

typedef struct AudioQueueLevelMeterState {
    Float32     mAveragePower;
    Float32     mPeakPower;
};  AudioQueueLevelMeterState;

Игра многократных звуков одновременно

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

Формат аудио критически важен при игре звуков одновременно на iPhone или iPod touch. Это вызвано тем, что воспроизведение определенных сжатых форматов в iOS использует эффективный аппаратный кодек. Только единственный экземпляр одного из следующих форматов может играть на устройстве за один раз:

  • AAC

  • ALAC (Apple Lossless)

  • MP3

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

Следующий список описывает, как iOS поддерживает форматы аудио для отдельного или многократного воспроизведения:

  • Линейный PCM и IMA/ADPCM (IMA4) аудио можно играть многократный линейный PCM или звуки формата IMA4 одновременно в iOS, не подвергаясь проблемам ресурса CPU.

  • AAC, MP3 и Apple Lossless (ALAC) воспроизведение аудио для AAC, MP3 и Apple Lossless (ALAC) звуки используют эффективное основанное на аппаратных средствах декодирование на iPhone и iPod touch. Можно играть только один такой звук за один раз.

Для полного описания того, как использовать Audio Queue Services для записи и воспроизведения, включая примеры кода, см. Руководство по программированию Audio Queue Services.

Воспроизведение с расположением Используя OpenAL

Открыто полученное аудио OpenAL API — доступный в платформе OpenAL и созданный поверх Core Audio — оптимизировано для расположения звуков во время воспроизведения. OpenAL упрощает играть, располагать, смешивать, и перемещать звуки, с помощью интерфейса, смоделированного после OpenGL. OpenAL и OpenGL совместно используют общую систему координат, позволяя Вам синхронизировать перемещения звуков и экранных графических объектов. OpenAL использует аудиоустройство I/O Core Audio (см. Аудиоустройства), непосредственно, приводя к воспроизведению самой низкой задержки.

По всем этим причинам OpenAL является Вашим лучшим выбором для игры звуковых эффектов в игровых приложениях на iPhone и iPod touch. OpenAL является также хорошим выбором для общих потребностей воспроизведения приложения для iOS.

OpenAL 1.1 в iOS не поддерживает аудио получение. Для записи в iOS используйте Audio Queue Services.

OpenAL в OS X обеспечивает реализацию OpenAL 1.1. спецификация, плюс расширения. OpenAL в iOS имеет два расширения Apple:

  • alBufferDataStaticProcPtr следует за образцом использования для alBufferData но устраняет буферную копию данных.

  • alcMacOSXMixerOutputRateProcPtr позволяет Вам управлять частотой дискретизации базового микшера.

Для примера Mac использования OpenAL в Core Audio посмотрите Services/OpenALExample в Core Audio SDK.

Системные звуки: предупреждения и звуковые эффекты

Для игры коротких звуковых файлов, когда Вам не нужны уровень, расположение, аудио сеанс или другое управление, использует System Sound Services, объявленную в AudioServices.h заголовочный файл в Аудио платформе Панели инструментов. Когда Вы просто хотите играть короткий звук самым простым возможным способом, этот интерфейс идеален. В iOS, играемое использование звуков System Sound Services ограничиваются максимальной продолжительностью 30 секунд.

В iOS Вы вызываете AudioServicesPlaySystemSound функционируйте для непосредственной игры файла звукового эффекта, который Вы определяете. Также можно вызвать AudioServicesPlayAlertSound когда необходимо предупредить пользователя. Если пользователь установил переключатель тишины, каждая из этих функций вызовет вибрацию на iPhone. (Используя Средство моделирования iOS или на рабочем столе, конечно, нет никакой вибрации или шума.)

Можно явно вызвать вибрацию на iPhone при помощи kSystemSoundID_Vibrate постоянный, когда Вы вызываете AudioServicesPlaySystemSound функция.

Играть звук с AudioServicesPlaySystemSound функция, Вы сначала регистрируете свой файл звукового эффекта как системный звук путем создания звукового объекта ID. Можно тогда играть звук. В типичном использовании, включающем игру звука иногда или неоднократно, сохраняют звуковой объект ID до Ваших выходов приложения. Если Вы знаете об использовании звука только один раз — например, в случае звука запуска — можно сразу уничтожить звуковой объект ID после игры звука, освободив память.

Перечисление 2-17 показывает минимальную программу, использующую интерфейсы в System Sound Services для игры звука. Звуковой обратный вызов завершения и вызов, устанавливающий его, прежде всего полезны, когда Вы хотите к свободной памяти после игры звука в случаях, где Вы знаете, что не будете играть звук снова.

Перечисление 2-17  Играя короткий звук

#include <AudioToolbox/AudioToolbox.h>
#include <CoreFoundation/CoreFoundation.h>
 
// Define a callback to be called when the sound is finished
// playing. Useful when you need to free memory after playing.
static void MyCompletionCallback (
    SystemSoundID  mySSID,
    void * myURLRef
) {
        AudioServicesDisposeSystemSoundID (mySSID);
        CFRelease (myURLRef);
        CFRunLoopStop (CFRunLoopGetCurrent());
}
 
int main (int argc, const char * argv[]) {
    // Set up the pieces needed to play a sound.
    SystemSoundID    mySSID;
    CFURLRef        myURLRef;
    myURLRef = CFURLCreateWithFileSystemPath (
        kCFAllocatorDefault,
        CFSTR ("../../ComedyHorns.aif"),
        kCFURLPOSIXPathStyle,
        FALSE
    );
 
    // create a system sound ID to represent the sound file
    OSStatus error = AudioServicesCreateSystemSoundID (myURLRef, &mySSID);
 
    // Register the sound completion callback.
    // Again, useful when you need to free memory after playing.
    AudioServicesAddSystemSoundCompletion (
        mySSID,
        NULL,
        NULL,
        MyCompletionCallback,
        (void *) myURLRef
    );
 
    // Play the sound file.
    AudioServicesPlaySystemSound (mySSID);
 
    // Invoke a run loop on the current thread to keep the application
    // running long enough for the sound to play; the sound completion
    // callback later stops this run loop.
    CFRunLoopRun ();
    return 0;
}

Плагины Core Audio: аудиоустройства и кодеки

Core Audio имеет сменный механизм для обработки аудиоданных. В iOS система предоставляет эти плагины. В OS X Вы имеете встроенные плагины и можете также создать Ваше собственное.

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

Аудиоустройства

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

В OS X аудиоустройства являются самыми видными как дополнения к аудиоприложениям как GarageBand и Логический Studio. В этой роли аудиоустройство имеет свой собственный пользовательский интерфейс или представление. Аудиоустройства в iOS не имеют представлений.

На любой платформе Вы находите программируемые имена встроенных аудиоустройств в AUComponent.h заголовочный файл в платформе Аудиоустройства.

аудиоустройства iOS используют 8.24-разрядную фиксированную точку линейные аудиоданные PCM для ввода и вывода. Одно исключение является преобразователями формата данных, как описано в следующем списке. Аудиоустройства iOS:

  • 3D модуль микшера — Позволяет любое число моно вводов, каждый из которых может быть 8-разрядным или 16-разрядным линейным PCM. Обеспечивает один вывод стерео в 8.24-разрядной фиксированной точке PCM. 3D модуль микшера выполняет преобразование частоты дискретизации на своих вводах и обеспечивает большое управление каждым каналом ввода. Это управление включает объем, отключение звука, панорамирование, затухание расстояния и управление уровнем для этих изменений. Программно, это kAudioUnitSubType_AU3DMixerEmbedded модуль.

  • Многоканальный модуль микшера — Позволяет любое число моно или стереовходов, каждый из которых может быть 16-разрядной линейной или 8.24-разрядной фиксированной точкой PCM. Обеспечивает один вывод стерео в 8.24-разрядной фиксированной точке PCM. Ваше приложение может отключить звук и не отключить звук каждого канала ввода, а также управлять своим объемом. Программно, это kAudioUnitSubType_MultiChannelMixer модуль.

  • Преобразователь — Обеспечивает частоту дискретизации, битовую глубину, и кусает формат (линейный к фиксированной точке) преобразования. Канонический формат данных преобразователя iPhone является 8.24-разрядной фиксированной точкой PCM. Это преобразовывает в или от этого формата. Программно, это kAudioUnitSubType_AUConverter модуль.

  • Модуль I/O — Обеспечивает аудиовход в реальном времени и вывод и выполняет преобразование частоты дискретизации по мере необходимости. Программно, это kAudioUnitSubType_RemoteIO модуль.

  • модуль EQ iPod — Обеспечивает простой эквалайзер, который можно использовать в приложении с теми же предварительными установками, доступными во встроенном приложении iPod iPhone. IPod модуль EQ использует 8.24-разрядную фиксированную точку ввод и вывод PCM. Программно, это kAudioUnitSubType_AUiPodEQ модуль.

Специальная категория аудиоустройства, известного как модуль I/O, описана далее в Графиках Обработки аудиоданных из-за важной роли, которую такие аудиоустройства играют там.

OS X обеспечивает больше чем 40 аудиоустройств, все из которых можно счесть перечисленным в Предоставленных систему Аудиоустройствах в OS X. Можно также создать собственные аудиоустройства, или как стандартные блоки для приложения или обеспечить для клиентов как продукты самостоятельно. Обратитесь к Руководству по программированию Аудиоустройства для получения дополнительной информации.

Аудиоустройства OS X используют нечередующиеся 32-разрядные линейные данные PCM с плавающей точкой для ввода и вывода — кроме случая аудиоустройства, которое является преобразователем формата данных, преобразовывающим в или от этого формата. Аудиоустройства OS X могут также поддерживать другие линейные варианты PCM — но никакие форматы кроме линейного PCM. Это гарантирует совместимость аудиоустройствами от Apple и других поставщиков. Для преобразования аудиоданных другого формата к линейному PCM можно использовать аудио преобразователь (см. Преобразование формата данных.

В iOS и в OS X, хост-приложения используют функции в Audio Unit Services, чтобы обнаружить и загрузить аудиоустройства. Каждое аудиоустройство однозначно определяется комбинацией с тремя элементами типа, подтипа и кода производителя. Код типа, указанный Apple, указывает общую цель модуля (эффект, генератор, и т.д.). Подтип описывает более точно, что аудиоустройство делает, но не является программно значительным для аудиоустройств. Если Ваша компания обеспечивает больше чем один модуль эффекта, однако, у каждого должен быть отличный подтип для различения его от других. Код производителя идентифицирует Вас как разработчика Ваших аудиоустройств. Apple ожидает, что Вы зарегистрируете код производителя, как “код создателя “, на странице Data Type Registration.

Аудиоустройства описывают свои возможности и свойства использования конфигурационной информации, как описано в Свойствах, Объемах и Элементах. Каждый тип аудиоустройства имеет некоторые требуемые свойства, как определено Apple, но Вы свободны добавить дополнительные свойства на основе потребностей своего аудиоустройства. В OS X хост-приложения могут использовать информацию о свойстве для создания универсального представления для аудиоустройства, и можно обеспечить пользовательское представление как интегральную часть аудиоустройства.

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

Для наблюдения изменений в состоянии аудиоустройства в OS X приложения могут зарегистрировать функции обратного вызова (иногда называемый слушателями), которые вызываются, когда определенные события аудиоустройства имеют место. Например, приложение Mac могло бы хотеть знать, когда пользователь перемещает ползунок в представление аудиоустройства, или когда прерван поток аудиоданных. Посмотрите Техническое примечание TN2104: Обработка Событий Аудиоустройства для большего количества подробных данных.

Core Audio SDK (в AudioUnits папка), обеспечивает шаблоны для общих типов аудиоустройства (например, модули эффекта и модули инструментов) вместе с платформой C++, реализующей большую часть интерфейса плагина Менеджера компонентов для Вас. Для получения дальнейшей информации о создании аудиоустройств для OS X с помощью SDK, см. Руководство по программированию Аудиоустройства.

Кодеки

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

Существует две группы кодеков воспроизведения в iOS. Первая группа, перечисленная в Таблице 2-3, включает очень эффективные форматы, которые можно использовать без ограничения. Т.е. можно играть больше чем один экземпляр каждого из этих форматов одновременно.

Для получения информации о форматах аудиофайла, поддерживаемых в iOS, посмотрите Форматы аудиофайла iPhone.

Таблица 2-3  iOS: неограниченные форматы аудио воспроизведения

iLBC (интернет-Низкоскоростной кодек, также кодек для разговорных сигналов)

IMA/ADPCM (также известный как IMA-4)

Линейный PCM

µLaw и aLaw

Вторая группа iOS воспроизводит кодеки вся доля единственный аппаратный путь. Следовательно, только единственный экземпляр одного из этих форматов может играть за один раз:

Таблица 2-4  iOS: ограниченные форматы аудио воспроизведения

AAC

Apple Lossless

MP3

iOS содержит кодеки записи, перечисленные в Таблице 2-5. Как Вы видите, ни запись MP3 ни AAC не доступна. Это вследствие высокого CPU наверху и последовательной разрядки батареи, этих форматов.

Таблица 2-5  iOS: запись форматов аудио

Apple Lossless

iLBC (интернет-Низкоскоростной кодек, кодек для разговорных сигналов)

IMA/ADPCM (также известный как IMA-4)

Линейный PCM

µLaw и aLaw

В OS X Вы находите огромное количество кодеков и поддерживаемых форматов, описанных в Поддерживаемых Форматах аудиофайла и Форматах данных в OS X.

OS X также обеспечивает интерфейсы для использования и создания кодеков аудиоданных. Эти интерфейсы объявляются в AudioConverter.h заголовочный файл (в Аудио платформе Панели инструментов) и AudioCodec.h (в платформе Аудиоустройства). Общие задачи в OS X описывают, как Вы могли бы использовать эти службы.

Графики обработки аудиоданных

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

График обработки обычно заканчивается в модуле I/O (иногда называемый устройством вывода). Модуль I/O часто взаимодействует через интерфейс (косвенно — через низкоуровневые службы) с аппаратными средствами, но это не требование. Модуль I/O может отправить свой вывод, вместо этого, назад к Вашему приложению.

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

iOS имеет единственный модуль I/O, как описано в Аудиоустройствах. История на OS X немного более сложна.

  • Модуль AUHAL для специализированного ввода и вывода к определенному устройству. Посмотрите Техническое примечание TN2091, ввод Устройства с помощью Выходного Аудиоустройства HAL.

  • Универсальный модуль I/O позволяет Вам соединить вывод графика обработки аудиоданных к Вашему приложению. Можно также использовать универсальный модуль I/O в качестве главного узла подграфа, как Вы видите на рисунке 2-6.

  • Система модуль I/O для звуковых эффектов пользовательского интерфейса и предупреждений.

  • Значение по умолчанию модуль I/O для всего другого аудиовхода и вывода.

Аудио Приложение установки MIDI (Mac только; в папке Utilities), позволяет пользователю направить соединения Системы I/O и Значение по умолчанию модули I/O отдельно.

Рисунок 2-4 показывает простой график обработки аудиоданных, в который потоки сигналов от вершины до нижней части.

Рисунок 2-4  простой график обработки аудиоданных
Three audio units connected in series: compressor unit, pitch unit, output unit.

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

Рисунок 2-5  , Как разветвиться соединение аудиоустройства
The correct way to perform splitting is to use a splitter unit.

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

Можно использовать Audio Processing Graph Services для объединения подграфов в больший график, где подграф появляется как единственный узел в большем графике. Рисунок 2-6 иллюстрирует это.

Рисунок 2-6  соединение подграфа
A three-audio-unit subgraph fed by a file player unit and feeding a mixer unit.

Каждый график или подграф должны закончиться в модуле I/O. Подграф или график, вывод которого подает Ваше приложение, должен закончиться универсальным модулем I/O, не соединяющимся с аппаратными средствами.

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

MIDI Services в OS X

Core Audio использует Core MIDI Services для поддержки MIDI. Эти службы состоят из функций, типов данных и констант, объявленных в следующих заголовочных файлах в CoreMIDI.framework:

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

Конечная точка MIDI (определенный непрозрачным типом MIDIEndpointRef) представляет источник или место назначения для стандартного потока данных MIDI с 16 каналами. Можно связать конечные точки с дорожками, используемыми Music Player Services, позволив Вам записать или воспроизвести данные MIDI. Конечная точка MIDI является объектом прокси для стандартного кабельного соединения MIDI. Конечные точки MIDI должны не обязательно соответствовать физическому устройству, однако; приложение может установить себя как виртуальный источник или место назначения, чтобы отправить или получить данные MIDI.

Драйверы MIDI часто комбинируют многократные конечные точки в логические группы, названные объектами MIDI (MIDIEntityRef). Например, было бы разумно сгруппировать MIDI - в конечной точке и конечной точке MIDI как объект MIDI, на который можно тогда легко сослаться для двунаправленной связи с устройством или приложением.

Каждое физическое MIDI-устройство (ни одно соединение MIDI) представлено объектом устройства Core MIDI (MIDIDeviceRef). Каждый объект устройства может содержать один или несколько объектов MIDI.

Core MIDI связывается с Сервером MIDI, выполняющим фактическую работу передачи данных MIDI между приложениями и устройствами. Сервер MIDI работает в его собственном процессе, независимом от любого приложения. Рисунок 2-7 показывает отношение между Сервером MIDI и Core MIDI.

  Core MIDI рисунка 2-7 и сервер Core MIDI
Outboard MIDI hardware (guitar and keyboard) connect to MIDI Server, which in turn connects to Core MIDI

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

Если Вы - производитель MIDI-устройства, Вы, возможно, должны предоставить плагин CFPlugin для Сервера MIDI, упакованного в CFBundle для взаимодействия с уровнем ядра драйверов Набора I/O. Рисунок 2-8 показывает, как Core MIDI и Сервер Core MIDI взаимодействуют с используемым оборудованием.

Рисунок 2-8  Интерфейс сервера MIDI с Набором I/O
MIDI endpoint objects interface between your application and the MIDI server, which in turn interfaces with the I/O Kit in the Kernel, which in turn interfaces with hardware ports.

Драйверы для каждого MIDI-устройства обычно существуют вне ядра, работающего в Серверном процессе MIDI. Эти драйверы взаимодействуют с драйверами Набора I/O по умолчанию для базовых протоколов (таких как USB и FireWire). Драйверы MIDI ответственны за представление данных неструктурированного устройства к Core MIDI в применимом формате. Core MIDI тогда передает информацию о MIDI Вашему приложению через определяемые конечные точки MIDI, которые являются абстрактными представлениями портов MIDI на внешних устройствах.

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

Для примера реализации пространства пользователя драйвер MIDI посмотрите MIDI/SampleUSBDriver в Core Audio SDK.

Службы аудиоплеера в OS X

Music Player Services позволяет Вам располагать и играть набор музыкальных треков MIDI.

Дорожка является потоком MIDI или данных о событии (представленный MusicTrack тип данных). Дорожки содержат серию основанных на времени событий, которые могут быть данными MIDI, данными о событии Core Audio или пользовательскими сообщениями о событиях. Можно думать о дорожке как о нотах для одного инструмента.

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

Для игры последовательности, Вы присваиваете его объекту аудиоплеера (типа MusicPlayer), который действует как проводник, управляя воспроизведением последовательности. Для создания звука Вы отправляете каждую дорожку в модуль инструментов или во внешнее MIDI-устройство.

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

Для получения дополнительной информации об использовании Music Player Services для игры данных MIDI посмотрите Обработку Данные MIDI.

Синхронизация служб в OS X

Core Audio Clock Services обеспечивает опорный синхрогенератор, который можно использовать для синхронизации приложений и устройств. Эти часы могут быть автономным источником синхронизации, или они могут синхронизироваться с внешним триггером, таким как MIDI бьют временной код MIDI или часы. Можно запустить и остановить часы сами, или можно установить часы, чтобы активироваться или деактивироваться в ответ на определенные события.

Можно получить сгенерированный, показывают время во многих форматах, включая секунды, удары, время SMPTE, время аудиосэмпла, и отбивавший такт панелью. Последний описывает время способом, который просто вывести на экран на экране с точки зрения музыкальных панелей, ударов и подударов. Core Audio Clock Services также содержит служебные функции, преобразовывающие один формат времени в другого и тот удар панели дисплея или времена SMPTE. Рисунок 2-9 показывает взаимосвязь между различными форматами Часов Core Audio.

Рисунок 2-9  Некоторые форматы Часов Core Audio
Beats, seconds, and SMPTE code all derive from host time.

Аппаратные времена представляют абсолютные временные стоимости от любого время узла (системные часы) или аудио время, полученное из внешнего аудиоустройства (представленный AudioDevice объект в HAL). Вы определяете текущее время узла путем вызова mach_absolute_time или UpTime. Аудио время является текущим временем аудиоустройства, представленным демонстрационным числом. Уровень демонстрационного числа изменения зависит от частоты дискретизации аудиоустройства.

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

Времена носителей не должны соответствовать реальному времени. Например, аудиофайл, который 10 секунд длиной, займет только 5 секунд, чтобы играть при удвоении скорости воспроизведения. Кнопка в Службах, Доступных в iOS Только, указывает, что можно скорректировать корреляцию между абсолютными («реальными») временами и основанными на носителях временами. Например, нотация удара панели указывает ритм музыкальной строки и какие примечания играть, когда, но не указывает, сколько времени это берет для игры. Решить, что, необходимо знать скорость воспроизведения (говорят, в ударах в секунду). Точно так же корреспонденция времени SMPTE к фактическому времени зависит от таких факторов как частота кадров и отбрасываются ли кадры или нет.