Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

generating track with Audio

Discussion in 'Audio & Video' started by Rocky1234321, Jan 15, 2015.

  1. Rocky1234321

    Rocky1234321

    Joined:
    Apr 10, 2013
    Posts:
    5
    Hello everyone, I am trying to generate a track with audio in the user's library. While I have got some of the generation working with get spectrum data. I still don't know how to preload the music and generate a track so it make it easier for old device to run. It is also important because I'm working on a algorithm which will allow me to detect the pace of music, and change the gameplay accordingly. However my current set up doesn't allow me to read the entire file unless I make the user wait for the music to play for at least once. Would really appreciate some help from someone who has worked on this problem. I am working on electronic music predominately so the detection is much easier as the most variations are obvious however not able to preload music means that my algorithm will never be able to tell if this bit is considered quite overall or load.
     
  2. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    187
    Long post incoming.

    That's not going to work very well with GetSpectrumData, because that will only give you the spectrum of the audio that is currently being played by an AudioSource. You could use a second AudioSource and give it a head start and mute it, but then it would still be tied to the audio that is currently being played. You'd get slightly different results every run and it would be extremely frame rate dependent.

    What you could do is do an FFT yourself at a regular interval. So with AudioClip.GetData you take some samples and calculate a spectrum from that. This way you can analyze it however you want.

    Here is how you could do it. First get this class into your project:
    http://www.lomont.org/Software/Misc/FFT/LomontFFT.html

    And this stuff to simplify things
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public static class Util
    6. {
    7.  
    8.     public static float[] GetSpectrum(float[] samples)
    9.     {
    10.         //Convert samples to doubles for fft.
    11.         double[] doubleSamples = Util.FloatsToDoubles (samples);
    12.            
    13.         //Perform FFT.
    14.         LomontFFT fft = new LomontFFT ();
    15.         fft.RealFFT (doubleSamples, true);
    16.        
    17.         //Calculate spectral magnitudes.
    18.         return SpectrumMagnitude (doubleSamples);
    19.     }
    20.    
    21.     public static float[] SpectrumMagnitude (double[] spectrum)
    22.     {
    23.         float[] output = new float[(spectrum.Length - 2) / 2];
    24.         for (int i = 0; i<output.Length; i++) {
    25.             int ii = (i * 2) + 2;
    26.             float x = (float)spectrum [ii];
    27.             float y = (float)spectrum [ii + 1];
    28.             output [i] = Mathf.Sqrt ((x * x) + (y * y));
    29.         }
    30.         return output;
    31.     }
    32.  
    33.     public static double[] FloatsToDoubles (float[] input)
    34.     {
    35.         double[] output = new double[input.Length];
    36.         for (int i = 0; i < input.Length; i++) {
    37.             output [i] = input [i];
    38.         }
    39.         return output;
    40.     }
    41. }
    42.  

    This is how you use it. With sampleIndex you can point to any sample index in the song. So you could get a spectrum every 1000 samples and analyze it however you want, without even playing the song.
    Code (csharp):
    1.  
    2. //get 2048 samples from the song at sampleIndex
    3. float[] samples = new float[2048];                                  
    4. audio.clip.GetData (samples, sampleIndex);
    5.  
    6. //get the spectrum
    7. float[] spectrum = Util.GetSpectrum(samples);
    8.