我正在尝试对歌曲进行预处理,并在播放歌曲之前实现一些节拍检测(而不是在播放歌曲时实时进行)。我的基本想法是以每秒约90次的速度对频谱数据进行采样,而我正在尝试通过将AudioSource.timeSamples
增加一个值并调用AudioSource.GetSpectrumData()
来做到这一点。但是我提供的数组似乎总是被相同的值填充。
似乎设置timeSamples实际上并没有更新AudioSource使用的样本。但是,如果我正常播放歌曲并调用GetSpectrumData()
,则我的数组将充满我期望的正确数据。
当我对GetSpectrumData()
进行调用时,我可以做些什么使AudioSource使用timeSamples中设置的示例吗,或者应该通过其他方式解析歌曲以获取此数据的其他方法?
谢谢
这是一个代码示例(歌曲是AudioSource),第二个for循环是您感兴趣的区域:
float[][] get_spectrum_data()
{
int samples = song.clip.samples;
int sample_rate = song.clip.frequency / parse_rate;
int arr_siz = samples / sample_rate;
FFTWindow win = FFTWindow.Rectangular; //which type do we want?
float[][] spectrum = new float[arr_siz][];
for (int i = 0; i < arr_siz; i++)
{
spectrum[i] = new float[spec_res];
}
for (int i = 1, j = 0; j < arr_siz; i += sample_rate, j++)
{
song.timeSamples = i;
song.GetSpectrumData(spectrum[j], 0, win);
}
return spectrum;
}
最佳答案
我认为AudioSource.GetSpectrumData依赖于当前正在播放的AudioSource。我的猜测是,它是从音频线程而不是剪辑本身采样的,因为用户可能还添加了后续的音频过滤器。尝试在循环中显式播放剪辑:
for (int i = 1, j = 0; j < arr_siz; i += sample_rate, j++)
{
song.Play();
song.timeSamples = i;
song.GetSpectrumData(spectrum[j], 0, win);
}