核心利用:
MonoBehaviour::OnAudioFilterRead(float[] data, int channel)
这个函数会以DSP常用的形式输出声音数据,即波形构成本身。通过对这些数据的操控可以实现对音频本身的控制。
基于以上信息,可以在unity内部进行DSP编程,但仅能在unity内部使用。因此可以定义一个类来在unity内专门处理DSP。
缺点:优化差,未经过Burst优化的代码极其容易造成严重的延迟。
基于以上信息,可以尝试制作一个基于模块进行的声音处理。
在MIDI CC协议中,信息交互的控制是基于特定通道的,因此可以借鉴这一点来实现控制
public class ccMap{
public float[] channel = new float[32];
}
如果当前插件需要用外部控制信息的时候,只需在channel数组内指定一个位置并读取即可。而外部插件连线需要将控制数据输出给当前插件时仅需要找到对应channel数组位置调整即可。
其实channel数组倒也是没必要限制在32,只不过MIDI CC协议在最早的时候给的通道也就128,这128通道只要不过分基本用不干净的,更何况我这个是小项目,基于我对效果器参数的理解来说,可控参数估摸着也不会超过32个吧,又不是serum这种大头玩意(笑)因此基于以上信息,一个模块父类将会有至少以下信息:
public class pluginBase{
public ccMap map;
public bool isActive;
public float[] inData;
public float[] outData;
void active(){}
}
isActive: 用于确认该插件是否启用,如果为否则状态为bypass,将会把inData数据直接传输给outData并输出至下一个,即active()的功能。
基于模块父类上,一个模块应该具备这样子的框架:
public class plugin: pluginBase{
public plugin audioFrom, audioTo;
public class modulation{
public plugin[] to;
public float[] channel;
}
public void output(){}
void Function1(){/*Implementation...*/}
void Function2(){/*Implementation...*/}
void Function3(){/*Implementation...*/}
//...
}
audio前缀代表着音频流,通常情况下,仅允许有一个输入口和一个输出口,否则容易发生数据混合但不能确定要如何处理混合数据的情况。如果需要混合数据则需编写额外模块来处理。
[等待更新...]
标签:...,插件,void,float,计划,AudioNode,public,channel From: https://www.cnblogs.com/ComputerEngine/p/17561610.html