Reputation: 41
I'm trying to pre-process a song and implement some beat detection before playing the song (not in real-time as the song plays). My basic idea is to sample the spectrum data at about 90 times per second and I'm trying to do that by incrementing AudioSource.timeSamples
by a value and making calls to AudioSource.GetSpectrumData()
. But the array I supply always seems to be filled with the same values.
It seems like setting timeSamples isn't actually updating the sample being used by the AudioSource. However, if I play the song normally and make calls to GetSpectrumData()
my array is filled with the correct data as I would expect.
Is there something I can do to make AudioSource use the sample that is set in timeSamples when I make the call to GetSpectrumData()
, or some other way I should be parsing through the song to get this data?
Thanks
Here's a code sample (song is an AudioSource), the 2nd for loop is the area of interest:
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;
}
Upvotes: 4
Views: 2230
Reputation: 46
I think AudioSource.GetSpectrumData relies on the AudioSource currently being engaged in playback. My guess is that it is sampling from the audio thread instead of the clip itself, since a user might also have added subsequent audio filters. Try explicitly playing the clip in your loop:
for (int i = 1, j = 0; j < arr_siz; i += sample_rate, j++)
{
song.Play();
song.timeSamples = i;
song.GetSpectrumData(spectrum[j], 0, win);
}
Upvotes: 1