在Unity中预处理音频频谱数据

时间:2017-06-01 15:41:40

标签: c# audio unity3d spectrum audio-source

我正在尝试预先处理一首歌并在播放歌曲之前实现一些节拍检测(不是在播放歌曲时实时)。我的基本想法是每秒大约90次采样频谱数据,我试图通过将AudioSource.timeSamples增加一个值并调用AudioSource.GetSpectrumData()来实现。但我提供的数组似乎总是充满相同的值。

似乎设置timeSamples实际上并没有更新AudioSource使用的样本。但是,如果我正常播放歌曲并拨打GetSpectrumData(),我的阵列就会填充正确的数据。

当我调用GetSpectrumData()时,我可以做些什么来使AudioSource使用在timeSamples中设置的样本,或者我应该通过歌曲解析以获取此数据?

由于

这是一个代码示例(song是一个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;
}

1 个答案:

答案 0 :(得分:1)

我认为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);
}