您可以使用原生数字信号处理 (DSP) 插件在 Unity 外部创建的一组代码,用于在 Unity 中创建功能。Unity 中可以使用两种类型的插件:托管插件(使用 Visual Studio 等工具创建的托管 .NET 程序集)和原生插件(特定于平台的原生代码库)。更多信息
请参阅 词汇表 处理音频并公开用户可以用来试验 音频效果可以修改音频混音器组件输出的任何效果,例如过滤声音的频率范围或应用混响。更多信息
请参阅 词汇表 的参数。 Unity 提供的示例插件 是一个很好的实验场所,可以从中获得有关所需参数的想法。
要为 Unity 开发原生音频插件
要创建音频插件文件
下载 最新的音频插件 SDK。
在文件夹中,转到 NativeAudioPlugins > NativeCode。原生示例插件 .cpp 文件位于此处。
您可以复制其中一个插件 .cpp 文件,以便将其用作您自己的插件的模板,直接在一个示例插件文件中工作(例如,Plugin_Equalizer.cpp
),或创建您自己的 .cpp 文件。
如果您的文件中尚未包含 AudioPluginUtil.h
,请将其包含在内。
创建用户在使用插件时与之交互的有用参数列表。要将参数添加到插件中
在您的插件 .cpp 文件中,将参数定义为枚举值。例如
enum Param
{
P_FREQ, //Frequency parameter
P_MIX, //Mix parameter
P_NUM //An extra value to keep track of length of the enum
};
创建一个 UnityAudioParameterDefinitions
数组,并将其大小设置为参数的数量。
int numparams = P_NUM;
definition.paramdefs = new UnityAudioParameterDefinition [numparams];
使用 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 |
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 之间,但在 Unity 的 GUI 中显示的值介于 0% 和 100% 之间。 |
float displayexponent |
3.0f , 1.0f |
将参数映射到滑块。 |
int enumvalue |
P_FREQ , P_MIX |
要将这些值分配到的枚举值。 |
Unity 根据这些基本参数定义生成默认 GUI。
要创建插件的实例,请使用 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
对象存储从主机接收到的数据,并将数据传递给所有回调函数。它存储的数据包括
采样率
处理的样本总数(用于计时)
插件是否被旁路
要释放插件实例,请使用 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;
}
要处理音频处理,请使用 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
。
如果要自定义 Unity 如何显示插件参数,请参阅 自定义音频插件的 GUI。
要将插件导入 Unity,请参阅 在 Unity 中使用您的原生 DSP 插件和 GUI。