I have some code that uses GetSpectrumData from an AudioSource playing a song to create a level layout for the player to play. I want to add a functionality where the players can upload their own songs and play the levels created with the data from these songs. Unfortunately, when comparing different audio files, I encountered this:

enter image description here

As you can see, the amplitude differs drastically from clip to clip, subsequently creating levels that are trivial to complete or almost impossible. I want to find a way to determine this "loudness" so I can tone it down or amplify it with a multiplier after getting the data from the song. Also, is there a way to extract this data without playing the song?

up vote 9 down vote accepted

A manual way to do that is to use AudioClip.GetData to get the sample data in an array. Then loop through the data and find the Root Mean Square to find the "loudness" of the audio clip.

You can also then scale the whole array so that the maximum value is 1.0f and write it back to the audioclip with AudioClip.SetData. This is called normalizing audio, and it makes samples have the loudest point to max volume. Note that this does not take in to account that if your audio clips are very low volume, but have very high peaks. There are more advanced techniques for that (noted below).

Unity also is doing normalization automatically by default. So if you have not touched the import settings, this operation is done automatically and you do not need to worry about it. If you still have the issue even though you are sure the audio is normalized, you then probably need to compress the audio with dynamic range compression (note: very different thing from data compression, has nothing to do with file sizes or memory usage) to fit your needs with external software.

  • Awesome answer, will look into all of this with more detail. Thank you! – Gardener Jan 23 '17 at 16:14
  • 5
    The maximum value isn't always the best option (as you said). Very very short loud spikes (these sound like clicks) don't seem as loud as a continuous sound. If you want the perceived loudness, you need to square all the values, average that, and then take the square root. Doing it this way is what normalization does, so hopefully there's a Unity built in for it. – Jezzamon Jan 23 '17 at 16:51
  • 2
    Loudness is related to sound energy, and the way of determining this is, as @Jezzamon hints at, by calculating the root-mean-square (RMS). dsp.stackexchange.com/questions/2951/loudness-of-pcm-stream – Zac Crites Jan 23 '17 at 21:34

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.