Search Unity

Audio Does AudioSource apply a limiter?

Discussion in 'Audio & Video' started by TheCatProblem, Nov 23, 2018.

  1. TheCatProblem

    TheCatProblem

    Joined:
    May 26, 2011
    Posts:
    22
    (Note: I originally posted this question on Unity Answers in March, but there were no responses and it's come up again. Hoping to have better luck here!)

    When an AudioSource plays an AudioClip, it appears to scale the audio data by the square root of 0.5 (0.70710678...), i.e., a value of 1.0 becomes 0.7071, 0.5 becomes 0.3536, etc. This corresponds to a reduction in gain of 3 dB (20*log10( sqrt(1/2) / 1 ) = -3.0103); -3 dB is a common value for limiters in audio production.

    For example, given a wave file with a sample rate of 48000 Hz (which matches AudioSettings.outputSampleRate on my machine) containing one second of a 1 Hz sine wave, the data returned by the AudioClip match the wave file (apart from some minor compression artifacts) but the AudioSource data are scaled. Here's a plot (the ranges are limited by the amount of data that GetData and GetOutputData can return):
    PlotAudioData_output.png

    This behaviour doesn't seem to be documented; can it be disabled?

    For reference, here's the code I used to collect the data plotted above:
    Code (CSharp):
    1. using System.IO;
    2. using UnityEngine;
    3.  
    4. public class AudioTest : MonoBehaviour
    5. {
    6.     public AudioSource audioSource; // Should loop, play on awake, and be 2D.
    7.     public AudioClip audioClip; // Should be the same as the clip specified in the AudioSource's parameters.
    8.  
    9.     private const int SampleCount = 16384; // Should be a power of two for AudioSource.GetOutputData().
    10.     private float[] _samples;
    11.  
    12.     private bool _hasSavedOutput = false;
    13.  
    14.     void Awake()
    15.     {
    16.         _samples = new float[SampleCount];
    17.     }
    18.  
    19.     void Start ()
    20.     {
    21.         print("Sample rate of output device is " + AudioSettings.outputSampleRate + " Hz.");
    22.         audioClip.GetData(_samples, 0);
    23.         OutputSamples("fromClip");
    24.     }
    25.    
    26.     void Update ()
    27.     {
    28.         if (!_hasSavedOutput)
    29.         {
    30.             audioSource.GetOutputData(_samples, 0);
    31.  
    32.             // First couple calls to GetOutputData return no data.
    33.             // Apparently this is by design (see https://issuetracker.unity3d.com/issues/audiosource-dot-getoutputdata-returns-an-empty-array-the-first-time-it-is-called).
    34.             if (!Mathf.Approximately(_samples[0], 0.0f))
    35.             {
    36.                 _hasSavedOutput = true;
    37.                 OutputSamples("fromSource");
    38.             }
    39.         }
    40.     }
    41.  
    42.     void OutputSamples(string filename)
    43.     {
    44.         string output = string.Empty;
    45.  
    46.         foreach (float value in _samples)
    47.         {
    48.             output += value + "\n";
    49.         }
    50.  
    51.         StreamWriter writer = new StreamWriter("C:/TestFolder/" + filename + ".txt");
    52.         writer.Write(output);
    53.         writer.Close();
    54.     }
    55. }
    56.  
     
  2. Docaroo

    Docaroo

    Joined:
    Nov 7, 2017
    Posts:
    82
    I would be very surprised if this is the case ... was the audio running through an Audio mixer group?

    The way I would check this is to use a sound file from my DAW where I see the dB value and then import and play that sound through Unity, while recording the computer audio again in the DAW. Then I would compare the two.

    I haven't noticed any gain reduction being done natively so I would be surprised if there was any difference.
     
  3. TheCatProblem

    TheCatProblem

    Joined:
    May 26, 2011
    Posts:
    22
    Nope, the audio isn't running through an Audio Mixer Group (there aren't any in the project: it's just a test project containing a scene with an object that has an Audio Source component and the AudioTest script from my initial post).

    Thanks for the suggestion to record the output from Unity: its amplitude appears to match that of the source audio. I wonder if this only affects GetOutputData; if so, it's easy enough to compensate for, but odd nonetheless.
     
  4. Docaroo

    Docaroo

    Joined:
    Nov 7, 2017
    Posts:
    82
  5. willemsenzo

    willemsenzo

    Joined:
    Nov 15, 2012
    Posts:
    585
    Short answer. Yes it does limit. I noticed myself when I created some audio, played it back, and was surprised the sound was completely distorted when I wrote it to a wave file.