Search Unity

How to use GetSpectrumData?

Discussion in 'Scripting' started by Steven-Walker, Nov 18, 2010.

  1. Steven-Walker

    Steven-Walker

    Joined:
    Oct 27, 2010
    Posts:
    38
    I'm not having any luck getting GetSpectrumData to work. It's just returning all 0s. A few questions if anyone knows the answer:

    1) Can GetSpectrumData be used in an Editor script?
    2) I'm getting the warning message that GetSpectrumData is deprecated in favor of a method that takes a pre-allocated data block, but there's no documentation on the new method and I haven't been able to guess at the parameters. Anyone know the new parameter form?
    3) What's the difference between GetSpectrumData and GetOuputData? (BTW, neither are returning any data).

    What I'm trying to do is load the spectrum data in an editor script so I can auto-detect certain things about the audio content. What I'm hoping to get are waveform intensities.

    Here's the code I'm working with so far. I have an AudioSource component on AudioTest with an audio clip assigned that plays back fine:

    Code (csharp):
    1.  
    2. var obj : GameObject = GameObject.Find("AudioTest");
    3. var audio : AudioSource = obj.GetComponent(typeof(AudioSource)) as AudioSource;
    4. audio.Play();
    5.  
    6. var samples : float[] = audio.GetSpectrumData(64, 1, FFTWindow.BlackmanHarris);
    7. var output : String = "";
    8. for(var s : float in samples) {
    9.     output += s+",";
    10. }
    11. Debug.Log(output);
    12.  
    Any suggestions/tips?

    Thanks,
    Walker
     
  2. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Hi, welcome to the forum!

    I don't think GetSpectrumData and GetOutputData can be used in editor scripts, unfortunately. The alternative version of GetSpectrumData takes an array as its first parameter. Rather than pass in the number of samples required, if you just pass in an array of the right length, it will get filled in with the right number of samples and avoid allocating extra memory for the return value. This should indeed be documented and I've passed this on to our technical writer.

    GetSpectrumData returns information about the frequency spectrum, while GetOutputData returns the amplitude values that are ultimately used to drive the speakers. If I understand what you mean by waveform intensities, you probably want GetOutputData rather than GetSpectrumData.
     
  3. burnumd

    burnumd

    Joined:
    May 27, 2008
    Posts:
    367
    Someone else has identified that higher frequencies (as you'd hear in speech or music) may fall off logarithmically with frequency (see here), so keep that in mind.

    The alternate GetSpectrumData and GetOutputData are mentioned in the release notes for 3.1, but it looks like the online documentation hasn't been updated for 3.1.

    I'd definitely like to see more documentation on the Audio functions. I've posted about the barely documented but also mentioned in the 3.1 release notes AudioSettings.outputSampleRate (the local docs have even less information than the release notes, somehow) and gotten no response either here or on the Answers site.
     
  4. twilight

    twilight

    Joined:
    Nov 19, 2012
    Posts:
    6
    Hi,

    Problem in using "audio.GetSpectrumData(samples)" in Start(), the problem is samples array is filled with all 0's.
    We are trying to fetch complete music spectrum before playing it, as we have to construct mesh someway before playing it, is that possible?
    Can anybody give solution to this problem? Thanks.

    ** P.S: I request unity team to at least answer questions as documentation is not clear about this. We are breaking our head as we dont have unity source with us.
     
  5. Alastair Callum

    Alastair Callum

    Joined:
    Sep 3, 2012
    Posts:
    71
    I've worked with GetSpectrumData to create audio visualisation demos. The function will only return values on a frame by frame basis, calling it once on start when no audio is playing will not return any data.

    Are you able to explain what it is you need to use the data for? You say you need to construct a mesh based upon audio but you say you need to construct it before playing audio.

    In this case you will need to look at caching some audio data in the background and then apply that to your mesh. BUT as far as i know, the only way to capture the SpectrumData is to have audio playing during runtime. (Correct me if I'm wrong). The kind of stuff I did with GetSPectrumData was realtime visualisations.

    It is important to note the logarithmic fall off of the spectrum array returned by the function. To resolve this you need to create a new array that takes values from the array in multiples of two, 1field,2fields,4fields,8fields,16fields etc. I will try and post some source when I have access to it later.
     
  6. twilight

    twilight

    Joined:
    Nov 19, 2012
    Posts:
    6
    @Alastair Thanks a lot for your reply.
    Yes, we are thinking to pre-generate complete mesh with it's size according to music spectrum data. The reason is we have to show up the 'Complete' generated mesh which shall be according to music spectrum data, before even starting the music game.

    I was able to find method audio.clip.GetData() to get amplitude of music without even playing it. But couldn't find one for fetching spectrum data before even playing music? Any solution to this problem?? Thanks.

    W.r.t. logarithmic fall off of spectrum array, are you speaking about 1st parameter of GetSpectrumData. I think it can hold the array size equal to "number of samples required in shot(max is "8192")?( Correct me if I'm wrong)
     
  7. gl33mer

    gl33mer

    Joined:
    May 24, 2010
    Posts:
    281
    Did this thread just evaporate? I was wondering @Alastair, you mentioned some code? I'd be interested. I'm coming up with quite a few unityScript examples was hoping this was c#.
     
  8. agudmund

    agudmund

    Joined:
    May 6, 2013
    Posts:
    13
    I've been digging around for the same and can't find any default implementations in Unity to get the whole range before playing the audio. Am writing an external python module that exports the data through a socket that Unity reads, similar to exporting Maya MASH audio data towards Unity in realtime but if any of you have a pure c# approach to this that doesn't require a secondary daemon running in the background please feel free to share.