Search Unity

Audio: A-Weighted Curve algorithm

Discussion in 'Community Learning & Teaching' started by BobBobson108, Oct 5, 2014.

  1. BobBobson108

    BobBobson108

    Joined:
    Mar 13, 2008
    Posts:
    57
    Hey all! If you're going to be doing a lot of stuff with music visualization, this will be very helpful ;)

    I just converted a really nice a-weighting formula to C# that I found here. For more about A-Weighting check out this great Wiki.

    The code below generates the table and saves it off to a text file so you can paste it somewhere in your code. Why calculate it every time if it's always going to be the same? :D

    You put in your sample rate and Play Unity. The text file will be spit out in the Assets folder. Once you have it you can paste it into your code and apply it to any FFT stuff you might be doing (the values are not normalized though). This code assumes your FFT array would be 2048 in length.

    Here's the code that generates the file:
    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.IO;
    4. using System.Collections;
    5.  
    6. public class AWeightingTable : MonoBehaviour
    7. {
    8.     public double sampleRate = 22000;
    9.  
    10.     void Awake ()
    11.     {
    12.         WriteTableFile();
    13.     }
    14.  
    15.     public void WriteTableFile ()
    16.     {
    17.         string finalTableCode = "double[] aWeightedTable = new double[]{" + System.Environment.NewLine;
    18.  
    19.         double[] fft = new double[2048];
    20.         for(int i = 0; i < fft.Length; ++i)
    21.         {
    22.             double freq = (i + 1) * (sampleRate / 4096d);
    23.  
    24.             double f2 = freq * freq;
    25.             double f4 = freq * freq * freq * freq;
    26.  
    27.             fft[i] = 10 * Math.Log(1.562339d * f4 / ((f2 + 107.65265d * 107.65265d)
    28.             * (f2 + 737.86223d * 737.86223d))) / Math.Log(10d)
    29.             + 10f * Math.Log(2.242881E+16d * f4 / ((f2 + 20.598997d * 20.598997d) * (f2 + 20.598997d * 20.598997d)
    30.             * (f2 + 12194.22d * 12194.22d) * (f2 + 12194.22d * 12194.22d))) / Math.Log(10d);
    31.  
    32.             if(double.IsNaN(fft[i]) ||
    33.                double.IsInfinity(fft[i]))
    34.             {
    35.                 fft[i] = 0d;
    36.             }
    37.  
    38.             finalTableCode += fft[i] + ", \t// " + freq + " Hz" + System.Environment.NewLine;
    39.  
    40.             Debug.Log(i + ": " + fft[i]);
    41.         }
    42.  
    43.         finalTableCode += "};";
    44.  
    45.         File.WriteAllText(Application.dataPath + "FinalTableCode" + sampleRate.ToString() + " Hz.txt", finalTableCode);
    46.     }
    47. }
    48.  
    Attached is the txt, just in case you want to copy it straight from here. If you plug the appropriate commented frequencies into the site in the first link, the values it spits out line up perfectly :)
     

    Attached Files:

    Last edited: Oct 5, 2014
    doq likes this.
  2. 2dSparrow

    2dSparrow

    Joined:
    Oct 4, 2014
    Posts:
    20
    Not sure what this is, but thanks!
     
  3. BobBobson108

    BobBobson108

    Joined:
    Mar 13, 2008
    Posts:
    57
    Sure! The human ear filters sound so we hear certain frequencies as being louder than others. Actually, we tend to hear stuff around the frequency of the human voice as louder than anything else!

    So if you're doing anything with music visualization and you can the frequencies of a piece of sound (via either an FFT algorithm of your own or Unity's GetSpectrumData) then certain frequencies will have a much higher volume in the computer, but sound quieter. Your visualization won't really 'line up' with the way you perceive the sound, but this curve helps fix that :D
     
    doq likes this.
  4. doq

    doq

    Joined:
    Aug 17, 2015
    Posts:
    121
    Awesome, I just started playing around with music visualization, and I was looking for a way to 'equalize' the visualization to match human perception. I started looking at stuff like Fletcher-Munson curves and came across A-weighting. Thanks for the code!
     
  5. KILEYI

    KILEYI

    Joined:
    Mar 7, 2015
    Posts:
    52
    Sounds good,if you can add more explaination about those magic number
    1.562339d
    107.65265d
    737.86223d
    should be better
     
  6. doq

    doq

    Joined:
    Aug 17, 2015
    Posts:
    121
    Checkout the wikipedia page on it https://en.wikipedia.org/wiki/A-weighting

    Btw, A-weighting actually isn't a very good representation for human hearing. Instead of A-weighting you can using AnimationCurves to define a frequency response similar to Fletcher-Munson curves that better approximates human hearing for you application.