Search Unity

Audio accurate Metronome with PlayScheduled() doesn't work

Discussion in 'Audio & Video' started by lang_matthias, Nov 19, 2017.

  1. lang_matthias

    lang_matthias

    Joined:
    Nov 18, 2017
    Posts:
    2
    Hi. I'm trying to program an accurate metronome in unity. I know, that there are already some questions for that, but I can't find a solution for my problem.
    My first naive implementation used Play() or PlayOneShot(). But unfortunately it wasn't very accurate. So I thought, I could implement it with PlayScheduled() and a buffer time. Like in this example: http://www.schmid.dk/talks/2014-05-21-Nordic_Game_Jam/Schmid-2014-05-21-NGJ-140.pdf
    But this also did not work and either I get no sound at all, or the sound is sometimes cut off, as if the beginning of the sound isn't played.
    Why doesn't the scheduled sound play?

    This is my code so far:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [RequireComponent(typeof(AudioSource))]
    6.  
    7. public class inaccurateMetronome : MonoBehaviour {
    8.  
    9.     public double bpm = 140.0F;
    10.  
    11.     public AudioClip sound0;
    12.     public AudioSource audio0;
    13.  
    14.     bool running = false;
    15.     bool ticked = false;
    16.  
    17.     public double buff = 0.2d;
    18.     double timePerTick;
    19.     double nextTick;
    20.     double dspTime;
    21.    
    22.  
    23.     void Start () {
    24.         double startTick = AudioSettings.dspTime;
    25.         nextTick = startTick + buff;
    26.         audio0 = GetComponent<AudioSource>();
    27.         audio0.clip = sound0;
    28.  
    29.     }
    30.  
    31.     public void toggleMetronome() {
    32.         if (running)
    33.             stopMetronome();
    34.         else
    35.             startMetronome();
    36.     }
    37.  
    38.     public void startMetronome() {
    39.         if (running) {
    40.             Debug.LogError("Metronome: already running");
    41.             return;
    42.         } else {
    43.             running = true;
    44.             timePerTick = 60.0f / bpm;
    45.             nextTick = AudioSettings.dspTime + buff;
    46.             Debug.Log("Metronome started");
    47.         }
    48.     }
    49.  
    50.     public void stopMetronome() {
    51.         if (!running) {
    52.             Debug.LogError("Metronome: not yet running");
    53.             return;
    54.         } else {
    55.             running = false;
    56.             Debug.Log("Metronome stopped");
    57.         }
    58.     }
    59.  
    60.     public void setBpm(double bpm){
    61.         this.bpm = bpm;
    62.         this.timePerTick = 60.0f / bpm;
    63.     }
    64.  
    65.  
    66.     void FixedUpdate() {
    67.         dspTime = AudioSettings.dspTime;
    68.         if ( running && dspTime + buff >= nextTick) {
    69.             ticked = false;
    70.             nextTick += timePerTick;
    71.         }
    72.         else if ( running && !ticked && nextTick >= AudioSettings.dspTime ) {
    73.                     audio0.PlayScheduled(nextTick);
    74.                     Debug.Log("Tick");
    75.                 ticked = true;
    76.         }
    77.     }
    78.  
    79. }
    80.  
    It would be fantastic, if someone could help me with that.
    Thanks!