Техническое примечание TN2112

Используя 3DMixer аудиоустройство

Этот technote иллюстрирует использование Core Audio 3DMixer версия 2.0 Аудиоустройства.

3DMixer Аудиоустройство может смешать аудио из нескольких других источников и затем локализовать звук в 3D пространстве. Это очень полезно в играх и во многих других интерактивных приложениях, которые должны управлять несколькими источниками аудиосигналов просто и эффективно. Этот technote предназначается для существующих и новых пользователей аудиоустройства v2.0 3DMixer.

Аудиоустройство v2.0 3DMixer имеет возможность локализовать звук в 3-мерном пространстве, т.е. позиция многократные звуковые источники расстоянием, повышением и азимутом вокруг слушателя. 3DMixer может представить к многократным разметкам канала (обсужденный ниже в разделе Speaker Configuration). Кроме того, качество звука, представленного во время воспроизведения, может быть скорректировано для удовлетворения требований производительности ЦП.

Создание AUGraph для 3DMixer
Установка количества Шины
Используя внутреннюю реверберацию
Конфигурации динамиков
Локализация звука в 3D пространстве
Spatialization, представляющий Algorithims
Регулирование громкости
Потоковые форматы шины и FormatConverterAU
Соединение, инициализация и запуск AUGraph
Избавление от AUGraph
Заключение
Ссылки и примечания
История версии документа

Создание AUGraph для 3DMixer

Рисунок 1  3D микшер

3DMixers обычно вставляются в График Аудиоустройства (AUGraph) помочь управлять потоком данных. AUGraph высокоуровневое представление ряда AudioUnits, вместе с соединениями между ними. Можно использовать AUGraph APIs для построения путей произвольного сигнала, через которые аудио может быть обработано, т.е. модульная система маршрутизации. APIs имеет дело с большими количествами AudioUnits и их отношений.

Глава графика всегда является устройством вывода, которое может сохранить обработанный аудиопоток на диск в память, или как выведывают. Запуск графика влечет за собой 'получение по запросу' на главное аудиоустройство (где данные выйдут из графика), который будет, в свою очередь, вытянуть данные от подключенных аудиоустройств в графике. Для этого technote мы будем использовать выходное аудиоустройство по умолчанию в качестве главы графика. Устройство вывода по умолчанию будет представлять устройство вывода (динамики, в большинстве случаев) выбранный пользователем в Аудио Приложение установки MIDI или Система Выходная Панель Prefrences. Для получения дополнительной информации об использовании Графиков Аудиоустройства читайте Используя Аудио Панель инструментов.

Чтобы начать настраивать наш график, мы должны добавить узлы для 3DMixer и Вывод По умолчанию AudioUnit с методом AUGraphNewNode(). После создания узлов мы можем открыть график и получить AudioUnit экземпляры от узлов в графике при помощи метода AUGraphGetNodeInfo().

Перечисление 1  , Создающее AUGraph и добавляющее узлы

void MyCreateAUGraph( AUGraph  mAUGraph,AudioUnit mOutputUnit,
 AudioUnit mMixerUnit)
{
    AUNode mMixerNode, mOutputNode;

    NewAUGraph(&mAUGraph); 

    ComponentDescription    mixerCD;

    mixerCD.componentFlags = 0; 
    mixerCD.componentFlagsMask = 0; 
    mixerCD.componentType = kAudioUnitType_Mixer; 
    mixerCD.componentSubType = kAudioUnitSubType_3DMixer; 
    mixerCD.componentManufacturer = kAudioUnitManufacturer_Apple; 

    AUGraphNewNode (mAUGraph, &mixerCD, 0, NULL, &mMixerNode); 

    ComponentDescription    cd;
    cd.componentFlags = 0; 
    cd.componentFlagsMask = 0; 

    cd.componentType = kAudioUnitType_Output; 
    cd.componentSubType = kAudioUnitSubType_DefaultOutput; 
    cd.componentManufacturer = kAudioUnitManufacturer_Apple; 

    AUGraphNewNode (mAUGraph, &cd, 0, NULL, &mOutputNode);

      //Open the Graph
     AUGraphOpen (mAUGraph);

     //Get Audio Units from graph
    AUGraphGetNodeInfo (mAUGraph, mMixerNode, 0, 0, 0, &mMixerUnit);
    AUGraphGetNodeInfo (mAUGraph, mOutputNode, 0, 0, 0, &mOutputUnit);

}

Теперь, когда график был создан, мы должны установить 3DMixer appprioprately прежде, чем инициализировать и запустить график.

Установка количества Шины

Число вводов (или шины) 3Dmixer является устанавливаемым свойством. По умолчанию, 3DMixer имеет 64 шин. Так как шины подвергаются использованию памяти, количество шины не должно быть установлено выше, чем необходимый для потребностей приложения. Установка этого свойства должна быть сделана до инициализации модуля микшера.

Перечисление 2  , Устанавливающее микшер, соединяет шиной количество

OSStatus    SetMixerBusCount (UInt32    inBusCount)
{

        UInt32  size        = sizeof(UInt32);
        UInt32  busCount    = inBusCount; 

        return (AudioUnitSetProperty ( mMixerUnit, 
                            kAudioUnitProperty_BusCount,
                            kAudioUnitScope_Input, 
                            0, 
                            &busCount,
                            size));

}

Используя внутреннюю реверберацию

3Dmixer имеет встроенную реверберацию. После того, как включенный, реверберация применяется на на основание входной шины (как описано ниже). Реверберация прочь по умолчанию и может быть включена с AudioUnitSetProperty() метод и kAudioUnitProperty_UsesInternalReverb свойство, прежде, чем инициализировать график.

Перечисление 3  , Разрешающее внутреннюю реверберацию

 UInt32        reverbSetting    = 1 // turn it on;
    result = AudioUnitSetProperty(mMixerUnit, 
                          kAudioUnitProperty_UsesInternalReverb, 
                          kAudioUnitScope_Global, 
                          0,
                          &reverbSetting, 
                          sizeof(reverbSetting));

Теперь, когда реверберация была включена для 3DMixer, реверберация может быть включена на шину путем установки k3DMixerRenderingFlags_DistanceDiffusion флаг. Используйте метод AudioUnitSetProperty() и kAudioUnitProperty_3DMixerRenderingFlags свойство для установки флага. Это свойство может быть установлено в любое время.

Перечисление 4  , Включающее реверберацию для шины

 UInt32    render_flags_3d;
    UInt32    outSize = sizeof(render_flags_3d);

    // get the current render flags for this bus
    result = AudioUnitGetProperty (mMixerUnit, 
            kAudioUnitProperty_3DMixerRenderingFlags, 
            kAudioUnitScope_Input,
            busIndex, 
            &render_flags_3d, 
            &outSize);

    // turn on this render flag and then set the bus
    render_flags_3d |= k3DMixerRenderingFlags_DistanceDiffusion;
    result = AudioUnitSetProperty( mMixerUnit,
             kAudioUnitProperty_3DMixerRenderingFlags,
             kAudioUnitScope_Input, busIndex, 
             &render_flags_3d, 
             sizeof(render_flags_3d));

Конфигурации динамиков

v2.0 3DMixer может представить аудио к стерео, четверке и 5,0 разметкам канала. Несмотря на то, что v2.0 3DMixer соответственно устанавливает свое расположение канала, когда формат потока вывода установлен, рекомендуется, чтобы было явно установлено расположение канала. Поэтому никакие изменения не требуются, чтобы Ваш код, должен будущая версия микшера быть выпущенной, который поддерживает многократные разметки канала, использующие то же число каналов (т.е. 5.1 и 6.0). То то, явно устанавливание расположения канала убедиться выбрать расположение, соответствующее количество каналов потокового формата или ошибки, будет возвращено (установка расположения канала к четверке, например, если потоковый формат будет иметь 5 каналов, возвратит ошибку). Чтобы в полной мере воспользоваться возможностью микшера представить к многократным разметкам канала, необходимо определить то, что пользователь установил для Конфигурации динамиков в Аудио Приложение установки MIDI (см. пример ниже) путем запросов текущего устройства, поскольку это - расположение канала вывода.

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

Перечисление 5  , Определяющее корректное число каналов для рендеринга к

UInt32 GetDesiredRenderChannelCount ()
{
    OSStatus result = noErr;

    // get the HAL device id form the output AU 
    AudioDeviceID    deviceID;
    UInt32    returnValue = 2; // return stereo by default

    UInt32 outSize =  sizeof(deviceID);

    //get the current device
    AudioUnitGetProperty(mOutputUnit, 
                        kAudioOutputUnitProperty_CurrentDevice,
                        kAudioUnitScope_Output, 
                        1,
                        &deviceID, 
                        &outSize);

    //Get the users speaker configuration
    result = AudioDeviceGetPropertyInfo(deviceID, 
                        0, 
                        false, 
                        kAudioDevicePropertyPreferredChannelLayout, 
                        &outSize,
                        NULL);

    if (result != noErr)
        return (returnValue); // return default (stereo) 

    AudioChannelLayout    *layout = NULL;
    layout = (AudioChannelLayout *) calloc(1, outSize);
    if (layout != NULL)
    {
        result = AudioDeviceGetProperty(deviceID, 
                       0, 
                       false, 
                       kAudioDevicePropertyPreferredChannelLayout, 
                       &outSize,
                       layout);
        if (layout->mChannelLayoutTag 
                       == kAudioChannelLayoutTag_UseChannelDescriptions)
        {
        // no channel layout tag is returned, 
                //so walk through the channel descriptions and count
                // the channels that are associated with a speaker
        if (layout->mNumberChannelDescriptions == 2)
        { 
                returnValue = 2; // there is no channel info for stereo
        }
        else
        {
            returnValue = 0;
            for (UInt32 i = 0; i < layout->mNumberChannelDescriptions; i++)
            {
                if (layout->mChannelDescriptions[i].mChannelLabel !=
                                             kAudioChannelLabel_Unknown) 
                    returnValue++;
                }
            }
        }
        else
        {
            switch (layout->mChannelLayoutTag)
            {
                case kAudioChannelLayoutTag_AudioUnit_5_0:
                case kAudioChannelLayoutTag_AudioUnit_5_1:
                case kAudioChannelLayoutTag_AudioUnit_6:
                    returnValue = 5;
                    break;
                case kAudioChannelLayoutTag_AudioUnit_4:
                    returnValue = 4;
                default:
                    returnValue = 2;
            }
        }

        free(layout);
    }
  return returnValue;
}

Перечисление 6  , конфигурирующее AUGraph для расположения канала

void ConfigureGraphForChannelLayout()
{
    OSStatus    result = noErr;

    // get the channel count that should be set
        // for the mixer's output stream format
    mCurrentMixerChannelCount = GetDesiredRenderChannelCount();

    // set the stream format
    CAStreamBasicDescription format; //CoreAudio SDK class
    UInt32 outSize = sizeof(format);
    result = AudioUnitGetProperty(mOutputUnit, 
                               kAudioUnitProperty_StreamFormat,
                               kAudioUnitScope_Output,
                               0, 
                               &format,
                               &outSize);

        // not interleaved
    format.SetCanonical (mCurrentMixerChannelCount, false); 
    format.mSampleRate = mMixerOutputRate;
    outSize = sizeof(format);
    result = AudioUnitSetProperty (mOutputUnit,
                               kAudioUnitProperty_StreamFormat, 
                               kAudioUnitScope_Input, 
                               0, 
                               &format, 
                               outSize);

    result = AudioUnitSetProperty (mMixerUnit, 
                               kAudioUnitProperty_StreamFormat, 
                               kAudioUnitScope_Output, 
                               0, 
                               &format, 
                               outSize);

    return;
}

Локализация звука в 3D пространстве

Устанавливание расстояния, повышения и азимута шины заставляет слушателя чувствовать аудио от отдельного момента в 3-мерном пространстве.

Подача и усиление источников аудиосигналов могут быть изменены на шину в 3DMixer. Подача может быть изменена путем изменения значения параметра k3DMixerParam_PlaybackRate. Усиление может быть изменено путем изменения значения параметра k3DMixerParam_Gain (пример, показанный в «Регулировании Громкости»).

Таблица 1  3-мерные параметры (расположение)

Направление

Модуль

Диапазон

Азимут

Градусы

- От 180 до 180

Повышение

Градусы

- От 90 до 90

Расстояние

Метры

От 0 до 10 000

Таблица 2  3-мерные параметры (Объем и подача)

Направление

Модуль

Диапазон

Усиление

дБ

- От 120 до 20

Скорость воспроизведения (подача)

уровень

0.5 к 4,0

Перечисление 7  , Устанавливающее расстояние и азимут

void    SetObjectCoordinates(UInt32     inMixerInputBus, Float32,
inAzimuth, Float32 inDistance)
{
    AudioUnitSetParameter(mMixerUnit, 
                                            k3DMixerParam_Azimuth, 
                                            kAudioUnitScope_Input, 
                                            inMixerInputBus, 
                                            inAzimuth, 
                                            0);

    AudioUnitSetParameter(mMixerUnit,
                                            k3DMixerParam_Distance, 
                                            kAudioUnitScope_Input,
                                            inMixerInputBus, 
                                            inDistance, 
                                            0);
}

Начиная с v2.0 3DMixer возможно иметь микшер, выполняют всю работу, необходимую для фиксации объема шины на основе указанного ReferenceDistance, настроек MaximumDistance и Attenuation. Эта функция позволяет приложению указывать, как близко/далеко объект в 3D пространстве может фактически добраться до слушателя. Следующий метод демонстрирует, как должным образом установить/получить шину микшера DistanceParams с AudioUnitSetProperty() метод и kAudioUnitProperty_3DMixerDistanceParams свойство.

  Структура Параметров Расстояния Микшера перечисления 8 определяется в AudioUnitProperties.h

typedef struct MixerDistanceParams {     Float32            mReferenceDistance;     Float32            mMaxDistance;     Float32            mMaxAttenuation; // in decibels } MixerDistanceParams;
  График параметров расстояния рисунка 2

Перечисление 9  , Устанавливающее Параметры Расстояния для шины

void    SetDistanceParamsForBus (UInt32     inMixerInputBus)
{ 
         MixerDistanceParams    distanceParams;

    // Get the desired minimum distance an object 
    // can get to the listener (float value in meters)
    // The mixer will play audio on the bus with 0db 
    // of attenuation (no attenuation) for all distance coordinates
    // between 0.0 and this reference distance. This 
    //value must be less than the maximum distance setting.
    distanceParams.mReferenceDistance = GetMyMinimumDistance();

    // Get the desired maximum distance an object 
    // can get from the listener (float value in meters)
    // The mixer will stop attenuating audio on the bus 
    // for all distance coordinates at this maximum 
    // distance or greater. This value must be greater 
    // than the reference distance setting.
    distanceParams.mMaxDistance = GetMyMaximumDistance();

    // Get desired attenuation (in db) for an object when it's 
    // coordinates are at or beyond the maximum distance 
    // (positive float value in dB).
    // The mixer will not attenuate the audio further than 
    // this db setting when the distance coordinates are beyond the 
    // maximum distance setting. 

    distanceParams.mMaxAttenuation = GetMyMinimumAttenuation();

    OSStatus result = AudioUnitSetProperty(mMixerUnit, 
                                kAudioUnitProperty_3DMixerDistanceParams,
                                kAudioUnitScope_Input,
                                inMixerInputBus, 
                                &distanceParams, 
                                sizeof(distanceParams));


}

Spatialization, представляющий Algorithims

Настройки Spatialization идут на шину (ввод микшера) основание и набор с AudioUnitSetProperty() метод и kAudioUnitProperty_SpatializationAlgorithm постоянный. Тип spatialization рендеринг используемого определяется факторами, такими как исходные (моно/стерео) звуковые каналы, выходные аппаратные каналы (стерео, многоканальный), и возможность ЦП. Установка шины spatialization алгоритм может также изменить некоторые флаги рендеринга шины (kAudioUnitProperty_3DMixerRenderingFlags) таким образом, рекомендуется сбросить любые желаемые флаги рендеринга после установки spatialization алгоритма.

Таблица 3  Spatailization Algorithims, подходящий для Вывода Стерео (от AudioUnitProperies.h)

Algorithims

Описание

Вывод

kSpatializationAlgorithm_StereoPassThrough

Когда никакая локализация не желаема для исходных данных стерео, StereoPassThrough должен использоваться. Установка этого алгоритма говорит микшеру брать стереовход и передавать его непосредственно каналам 1 и 2 (Передний L/R, если рендеринг для многоканального) без локализации.

Стерео, многоканальный

kSpatializationAlgorithm_EqualPowerPanning

EqualPowerPanning просто панорамирует данные шины микшера в стереополе. Этот алгоритм походит на кнопку панорамирования, найденную на смесительной полосе канала платы. То, когда этот алгоритм используется, в то время как микшер представляет к многоканальным аппаратным аудиоданным, будет только представлено к каналам 1 и 2 (Передний L/R).

Стерео

kSpatializationAlgorithm_HRTF

HRTF (Функция моделирования восприятия звука) является высококачественной фильтрацией использования алгоритма для эмуляции 3 размерных пространств в наушниках или стереодинамиках. Если включено при рендеринге к многоканальным аппаратным средствам, HRTF представит входные данные только к каналам 1 и 2 (Передний L/R). HRTF является CPU интенсивный алгоритм.

Стерео

kSpatializationAlgorithm_SphericalHead

Как HRTF, алгоритм SpericalHead разработан для эмуляции 3 размерных пространств в наушниках или стереодинамиках. Используя упрощенные алгоритмы, SpericalHead обеспечивает меньший качественный опыт рендеринга, чем HRTF и является немного меньшим количеством интенсивного CPU.

Стерео

kSpatializationAlgorithm_VectorBasedPanning

Данные панорамирований VectorBasedPanning от шины, на основе он - расположение в 3 размерных пространствах между двумя каналами многоканального рендеринга (т.е. между каналами 3 и 4 для рендеринга четверки, если расположение данных было непосредственно позади слушателя). Когда этот алгоритм используется, в то время как микшер представляет к аппаратным средствам стерео, это эффективно становится EqualPowerPanning (см. EqualPowerPanning для большего количества информации), Этот алгоритм не панорамирует движущиеся источники так же гладко как Звуковое поле (kSpatializationAlgorithm_SoundField) алгоритм и лучше подходит для локализации фиксированных источников.

Многоканальный

kSpatializationAlgorithm_SoundField (Звукозапись с эффектом присутствия)

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

Многоканальный

Перечисление 10  , устанавливающее 3DMixer к Spatialization Algorithims

SetSpatializationAlgorithm( UInt32 BusNumber)
{
          UInt32 spatialSetting = GetMySpatializationSetting(); 

          result = AudioUnitSetProperty(mMixerUnit, 
                             kAudioUnitProperty_SpatializationAlgorithm, 
                             kAudioUnitScope_Input,
                             BusNumber,
                             &spatialSetting,
                             sizeof(spatialSetting));
}

Регулирование громкости

Громкость может явно регулироваться для каждой шины на входном объеме 3DMixer, обеспечивая усиление, прежде чем будет смешан звук. Используйте k3DMixerParam_Gain постоянный и AudioUnitSetParameter() метод для регулирования громкости каждой шины микшера (входной объем). Параметр является дБ представления значения плавающим (см. ниже).

Перечисление 11  , Регулирующее громкость на вводе

// busGain represents a range of 0.0 to 1.0 (full volume) 
SetInputBusGain(UInt32 mCurrentPlayBus, Float32 busGain)
{
   Float32    db = 20.0 * log10(busGain); // convert to db
   if (db < -120.0)
      db = -120.0; // clamp minimum audible level at -120db

   AudioUnitSetParameter(mMixerUnit, 
                                       k3DMixerParam_Gain,
                                       kAudioUnitScope_Input,
                                       mCurrentPlayBus, 
                                       db, 
                                       0);
}

Потоковые форматы шины и FormatConverterAU

Если a FormatConverterAU снабжает данными к шине микшера, тогда потоковый формат на входном объеме микшера автоматически установлен, когда соединяются узлы. Однако, если данными снабжают к микшеру непосредственно в рендеринге proc шины, необходимо должным образом установить потоковый формат на входном объеме шины микшера прежде, чем 'вытянуть' для данных.

Соединение, инициализация и запуск AUGraph

Установка теперь завершена, и мы можем соединиться 3DMixer с выходным аудиоустройством по умолчанию. Когда все соединения сделаны, и узлы являются установкой правильно, необходимо инициализировать AUGraph. График теперь завершен, и 3Dmixer готово к употреблению. Вызов к AUGraphStart начнет обрабатывать аудиоданные.

  Соединение перечисления 12, инициализация и запуск AUGraph

 AUGraphConnectNodeInput (mAUGraph, mMixerNode, 0, mOutputNode, 0);         AUGraphInitialize (mAUGraph);         AUGraphStart(mAUGraph);

Избавление от AUGraph

Метод AUGraphStop остановит весь рендеринг всюду по графику. DisposeAUGraph освободит график.

  Остановка перечисления 13 и расположение графика

 AUGraphStop (mAUGraph);          DisposeAUGraph (mAUGraph);         mAUGraph = 0;

Заключение

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

Ссылки и примечания

Core Audio Предварительный документ



История версии документа


ДатаПримечания
14.06.2004

Обновленное ссылочное расположение библиотеки

26.05.2004

Новый документ, обсуждающий, как использовать Core Audio 3DMixer версия 2.0