我正在为Unity引擎中的音频过滤器创建一个C#脚本。
我的问题是,在通过我的过滤器运行后,生成的音频具有一致且频繁的“点击”,“弹出”或“跳过”。听起来有点像旧收音机。我不确定是什么造成了这个。
这是我的代码:
public float cutoff;
public float resonance;
int sampleRate;
void Start()
{
cutoff = 200;
resonance = 1;
sampleRate = AudioSettings.outputSampleRate;
}
void OnAudioFilterRead(float[] data, int channels)
{
float c = 2 * Mathf.PI * cutoff/sampleRate;
float r = 1 / resonance;
float v0 = 0;
float v1 = 0;
for (int i = 0; i < data.Length; i++)
{
v0 = (1 - r * c) * v0 - (c) * v1 + (c) * data[i];
v1 = (1 - r * c) * v1 + (c) * v0;
data[i] = v1;
}
}
以下是OnAudioFilterRead()的文档。
这是我得到original low-pass code的地方。
当截止值接近其最大值(127)时,咔嗒声和砰砰声变得更安静。
我对音频编程很陌生,这很明显,所以我不确定是什么原因造成的。
有人比我更了解我的错误吗?
谢谢!
答案 0 :(得分:3)
点击和弹出的常见原因(按照“共性”的顺序)是:
short
中计算所有内容,而不关心包装值一种很好的调试技术是尝试通过例如将PCM转储直接插入处理音频的例程中来缩小问题的原因。这样,您就可以知道例程的输出是否正常,并且能够相应地集中调试工作。
答案 1 :(得分:1)
我已经解决了。我的c和r变量需要在调用OnAudioFilterRead()时保持不变。让他们成员固定它。这是我完整的,有效的代码:
using UnityEngine;
using System.Collections;
using System;
public class LowPassFilter : MonoBehaviour {
public float cutoff;
public float resonance;
const float CUTOFF_MAX = 128.0f;
const float CUTOFF_MIN = 0.0f;
const float RESONANCE_MAX = 128.0f;
const float RESONANCE_MIN = 0.0f;
float c;
float r;
float v0;
float v1;
int sampleRate;
void Start()
{
cutoff = 20.0f;
resonance = 0.0f;
c = 0.0f;
r = 0.0f;
v0 = 0.0f;
v1 = 0.0f;
sampleRate = AudioSettings.outputSampleRate;
}
void OnAudioFilterRead(float[] data, int channels)
{
cutoff = Mathf.Clamp(cutoff, CUTOFF_MIN, CUTOFF_MAX);
resonance = Mathf.Clamp(resonance, RESONANCE_MIN, RESONANCE_MAX);
c = Mathf.Pow(0.5f, (128.0f - cutoff) / 16.0f);
r = Mathf.Pow(0.5f, (resonance + 24.0f) / 16.0f);
for (int i = 0; i < data.Length; i++)
{
v0 = ((1.0f - r * c) * v0) - (c * v1) + (c * data[i]);
v1 = ((1.0f - r * c) * v1) + (c * v0);
data[i] = Mathf.Clamp(v1, -1.0f, 1.0f);
}
}
}