Version: Unity 6.0 (6000.0)
语言 : 中文
原生音频插件 SDK
自定义音频插件的 GUI

开发原生 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 kMaxSampleRate1.0f 参数的最大值。
float defaultval 1000.0f0.5f 参数的默认值和初始值。
float displayscale 1.0f100.0f 仅用于显示参数的缩放系数。例如,示例代码中的百分比具有最小值 0、最大值 1 和缩放系数 100.0f。这意味着,虽然实际值介于 0 和 1 之间,但在 Unity 中的 GUI 中显示的值介于 0% 和 100% 之间。
float displayexponent 3.0f1.0f 将参数映射到滑动条。
int enumvalue P_FREQP_MIX 要将这些值分配到的枚举值。

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,请参阅在 Unity 中使用原生 DSP 插件和 GUI

其他资源


原生音频插件 SDK
自定义音频插件的 GUI