1、手机在麦克风有部分手机识别16000HZ音频时会导致失真。unity默认是44100HZ
但是发到阿里的语音sdk 只识别8K和16K的所以需要转换采样一下
AudioClip ResampleAudio44100(AudioClip sourceClip)
{
// 1. 提取原始数据
float[] sourceData = new float[sourceClip.samples * sourceClip.channels];
sourceClip.GetData(sourceData, 0);
// 2. 抗混叠滤波(截止频率8kHz)
float[] filtered = ApplyFIRFilter(sourceData, 8000, 44100);
// 3. 非整数倍重采样(44100→16000)
float ratio = 16000f / 44100f;
float[] resampledData = new float[Mathf.FloorToInt(filtered.Length * ratio)];
for (int i = 0; i < resampledData.Length; i++)
{
float srcIndex = i / ratio;
int floor = Mathf.FloorToInt(srcIndex);
float t = srcIndex - floor;
// 线性插值
resampledData[i] = Mathf.Lerp(filtered[floor], filtered[Mathf.Min(floor + 1, filtered.Length - 1)], t);
}
// 4. 创建新AudioClip
AudioClip newClip = AudioClip.Create("Resampled", resampledData.Length, 1, 16000, false);
newClip.SetData(resampledData, 0);
return newClip;
}
float[] coeffs = { 0.001f, 0.02f, 0.05f, 0.12f, 0.2f, 0.12f, 0.05f, 0.02f, 0.001f }; // 示例系数
// FIR低通滤波器实现
private float[] ApplyFIRFilter(float[] input, float cutoffFreq, int sourceRate)
{
float[] output = new float[input.Length];
int kernelRadius = coeffs.Length / 2;
for (int i = kernelRadius; i < input.Length - kernelRadius; i++)
{
float sum = 0;
for (int j = 0; j < coeffs.Length; j++)
{
sum += input[i - kernelRadius + j] * coeffs[j];
}
output[i] = sum;
}
return output;
}