Search Unity

Audio Accurate Audio DeltaTime

Discussion in 'Audio & Video' started by CDF, Apr 25, 2017.

  1. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    Hi, was wondering if there's a solution to increase a timer at the same rate an AudioSource is playing at?

    I've kindof got a solution, although a bit hacky and I'm confused as to why it's necessary.
    It would appear that AudioSettings.dspTime is not actually in sync with the timeline of the AudioSource and I'm not sure why.

    Here's a simple EditorWindow that just prints out the difference between two times.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. using System;
    6.  
    7. public class AudioTimeWindow : EditorWindow {
    8.  
    9.     public AudioSource source;
    10.  
    11.     private double lastDspTime;
    12.     private double playhead;
    13.     private int updates;
    14.  
    15.     [MenuItem("Window/AudioTime")]
    16.     static void Open() {
    17.  
    18.         GetWindow<AudioTimeWindow>().Show();
    19.     }
    20.  
    21.     private void OnGUI() {
    22.  
    23.         source = EditorGUILayout.ObjectField("Source", source, typeof(AudioSource), true) as AudioSource;
    24.  
    25.         EditorGUI.BeginDisabledGroup(!source || !source.clip);
    26.  
    27.         if (GUILayout.Button("Play")) {
    28.  
    29.             Play(source);
    30.         }
    31.  
    32.         EditorGUI.EndDisabledGroup();
    33.     }
    34.  
    35.     private void Play(AudioSource source) {
    36.  
    37.         source.Stop();
    38.         source.Play();
    39.  
    40.         lastDspTime = AudioSettings.dspTime;
    41.         playhead = source.time;
    42.         updates = 0;
    43.     }
    44.  
    45.     private void Update() {
    46.  
    47.         if (source && source.isPlaying) {
    48.  
    49.             double deltaTime = AudioSettings.dspTime - lastDspTime;
    50.             float sourceTime = source.timeSamples / (float)source.clip.frequency;
    51.  
    52.             //uncomment the following to fix the difference
    53.  
    54.             /*
    55.             if (updates < 2) {
    56.  
    57.                 updates++;
    58.                 lastDspTime = AudioSettings.dspTime;
    59.                 deltaTime = sourceTime;
    60.             }
    61.             */
    62.  
    63.             if (deltaTime > 0) {
    64.  
    65.                 playhead += deltaTime;
    66.                 lastDspTime = AudioSettings.dspTime;
    67.             }
    68.            
    69.             float diff = (float)Math.Round(playhead - sourceTime, 3);
    70.  
    71.             if (diff > 0.01) {
    72.  
    73.                 Debug.Log("Difference: " + diff);
    74.             }
    75.             else {
    76.  
    77.                 Debug.Log(diff);
    78.             }
    79.         }
    80.     }
    81. }
    82.  
    As you can see in the Update function. I've commented out a hacky fix for syncing the deltaTime to that of the source. It would appear that during the first 2 frames of playing a source. The elapsed AudioSettings.dspTime doesn't match the elapsed time of the AudioSource. So during this period, I'm overriding the deltaTime to that of the source. It seems to work, but not sure why it's necessary.

    If an AudioSource is played, and I'm getting the difference of that start time vs current time, shouldn't the two match exactly? Doesn't the audio source increase at the rate of AudioSettings.dspTime?

    Weird thing is, sometimes they do, other times the difference is a constant 0.021s. Without rounding the difference I usually get very small numbers, but never 0.

    Anyone have a better method to increase a timer at the exact delta rate of a AudioSource?
    I can't use the delta from the source itself as I'll eventually be evaluating this time passed the end point of the source.

    Thanks
     
  2. willemsenzo

    willemsenzo

    Joined:
    Nov 15, 2012
    Posts:
    585
    Use AudioSource.timeSamples it is basically the clock of the audiosource. You will have to calculate the deltatime yourself but that shouldn't be so hard if you already know the time.