Unity 6.3
0 онлайн 8 гостей 3 в системе
Вход

Разработка нативного DSP аудио плагина

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

Чтобы разработать собственный аудио плагин для Unity:

  1. Создать файл аудио-плагина.

  2. Определите параметры в файле плагина.

  3. Создайте экземпляр плагина.

  4. Разгрузите плагин.

  5. Обработка звука в вашем плагине.

1. Создание файла аудио-плагина

Чтобы создать файл аудиоплагина:

  1. Загрузите последний аудио плагин SDK.

  2. В папке перейдите в NativeAudioPlugins > NativeCode. Здесь находятся файлы примера плагина .cpp.

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

  4. Включите AudioPluginUtil.h в свой файл, если он еще там нет.

2. Определите параметры в файле аудио-плагина

Создайте список параметров, которые будут полезны для взаимодействия пользователя при использовании вашего плагина. Чтобы добавить параметры в плагин:

  1. В файле .cpp своего плагина объявите параметры как значения перечисления. Например:

    enum Param
    {
        P_FREQ, //Frequency parameter
        P_MIX,  //Mix parameter
        P_NUM   //An extra value to keep track of length of the enum
    };
    
  2. Создайте массив UnityAudioParameterDefinitions и установите его размер на количество параметров, которое у вас есть:

    int numparams = P_NUM;
    definition.paramdefs = new UnityAudioParameterDefinition [numparams];
    
  3. Используйте RegisterParameter функцию, чтобы зарегистрировать каждое значение вашего перечисления.

    int InternalRegisterEffectDefinition(UnityAudioEffectDefinition& definition)
    {
                int numparams = P_NUM;
            definition.paramdefs = new  UnityAudioParameterDefinition [numparams];
            RegisterParameter(definition, "Frequency", "Hz",
                0.0f, kMaxSampleRate, 1000.0f,
                1.0f, 3.0f,
                P_FREQ);
            RegisterParameter(definition, "Mix amount", "%",
                0.0f, 1.0f, 0.5f,
                100.0f, 1.0f,
                P_MIX);
            return numparams;
    }
    

В следующей таблице представлен обзор функции RegisterParameter, ее параметров и того, как она используется в вышеприведенном примере кода:

Тип и имя параметра Переменная в примере кода Описание
UnityAudioEffectDefinition definition definition Структура UnityAudioEffectDefinition содержит массив UnityAudioParameterDefinition. Функция RegisterParameter вставляет ваше определение параметра в качестве записи в этот массив.
char* name “Frequency”, “Mix Amount” Отображаемое имя параметра.
char* unit “Hz”, “%” Тип значения.
float minval 0.0f Минимальное значение параметра.
float maxval kMaxSampleRate, 1.0f Максимальное значение параметра.
float defaultval 1000.0f, 0.5f Значение по умолчанию и первоначальное значение параметра.
float displayscale 1.0f, 100.0f Коэффициент масштаба только для отображения параметров. Например, процент в примерном коде имеет минимальное значение 0, максимальное значение 1 и коэффициент масштаба 100.0f. Это означает, что, хотя фактическое значение находится между 0 и 1, значение, которое отображается в GUI в Unity, находится между 0% и 100%.
float displayexponent 3.0f, 1.0f Сопоставляет параметры с ползунками.
int enumvalue P_FREQ , P_MIX Значение Enum для назначения этих значений.

Unity генерирует по умолчанию GUI из этих базовых определений параметров.

3. Инстантировать свой нативный аудио DSP плагин

Чтобы создать экземпляр вашего плагина, используйте функцию CreateCallback. Unity вызывает функцию CreateCallback, как только она создает ваш плагин. Она может быть null.

struct EffectData
{
    struct Data
    {
        float p[P_NUM]; // Parameters
        float s;        // Sine output of oscillator
        float c;        // Cosine output of oscillator
    };
    union
    {
        Data data;
        unsigned char pad[(sizeof(Data) + 15) & ~15];
    };
};
UNITY_AUDIODSP_RESULT UNITY_AUDIODSP_CALLBACK CreateCallback(
    UnityAudioEffectState* state)
{
    EffectData* effectdata = new EffectData;
    memset(effectdata, 0, sizeof(EffectData));
    effectdata->data.c = 1.0f;
    state->effectdata = effectdata;
    InitParametersFromDefinitions(
        InternalRegisterEffectDefinition, effectdata->data.p);
    return UNITY_AUDIODSP_OK;
}

Объект UnityAudioEffectState хранит данные, которые он получает от хоста и передает их всем функциям обратного вызова. Данные, которые он хранит, включают:

  • частота выборки

  • общее число обработанных проб (для определения времени)

  • обходится ли плагин

4. Разгрузить свой нативный аудио DSP плагин

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

UNITY_AUDIODSP_RESULT UNITY_AUDIODSP_CALLBACK ReleaseCallback(
    UnityAudioEffectState* state)
{
    EffectData::Data* data = &state->GetEffectData<EffectData>()->data;
    delete data;
    return UNITY_AUDIODSP_OK;
}

5. Обработка аудио в вашем плагине

Для обработки звука используйте функцию ProcessCallback. Unity повторяет вызов функции ProcessCallback с блоком входного звука для чтения и блоком выходного звука для записи.

В следующем коде приводится пример умножения синусоидальной волны на все каналы:

UNITY_AUDIODSP_RESULT UNITY_AUDIODSP_CALLBACK ProcessCallback(
    UnityAudioEffectState* state,
    float* inbuffer, float* outbuffer,
    unsigned int length,
    int inchannels, int outchannels)
{
    EffectData::Data* data = &state->GetEffectData<EffectData>()->data;

    float w = 2.0f * sinf(kPI * data->p[P_FREQ] / state->samplerate);
    for(unsigned int n = 0; n < length; n++)
    {
        for(int i = 0; i < outchannels; i++)
        {
            outbuffer[n * outchannels + i] =
                inbuffer[n * outchannels + i] *
                (1.0f - data->p[P_MIX] + data->p[P_MIX] * data->s);
        }
        data->s += data->c * w; // cheap way to calculate a sine-wave
        data->c -= data->s * w;
    }

    return UNITY_AUDIODSP_OK;
}

Функция GetEffectData является вспомогательной функцией, которая переводит поле effectdata состояние переменной в поле EffectData::Data в структуре.

Настройте GUI и импортируйте аудио плагин в Unity

Если вы хотите настроить, как Unity отображает параметры вашего плагина, ознакомьтесь с Настройка GUI для вашего аудио плагина.

Чтобы импортировать ваши плагины в Unity, см. Используйте свой нативный плагин DSP и GUI в Unity.

Дополнительные ресурсы