0
\$\begingroup\$

In Unity 2022.3.12f1, I made a metronome. Here is a minimal working example:

using System;
using UnityEngine;

public class Metronome : MonoBehaviour
{
    public int tempo = 150;
    public int tempoReference = 4; //e.g., 4 means reference is a quarter note, 2 means reference is a double note,...
    public int timeSignatureTop = 4;
    public int timeSignatureBottom = 4;
    public AudioSource source; //You have to fill this with any short sound
    
    private float delayBeforeNextBeat;        
    private float beatDuration = 0;
    private bool play = false;
    private int beatIndex = 0;

    public void Start()
    {
        source.Play();
        beatDuration = 60f / (timeSignatureBottom / tempoReference * tempo);
        delayBeforeNextBeat = beatDuration;
        beatIndex = 0;
        play = true;
    }

    private void Update()
    {
        if (play)
        {
            delayBeforeNextBeat -= Time.deltaTime;
            if (delayBeforeNextBeat <= 0)
            {
                beatIndex = (beatIndex + 1) % timeSignatureTop;
                delayBeforeNextBeat = beatDuration + delayBeforeNextBeat;
                source.Play();
            }
        }
    }
}

My problem is that the interval between the first two beats (as heard through the AudioSource) is much longer that the next ones. Additional prints indicate that Time.deltaTimes are not particularly longer nor more numerous in this interval than they are in others, though.

I tried to move everything in FixedUpdate, with the same result.

I also tried to move the first source.Play() inside the Update function (with some minor adjustments, like adding a bool firstPlay and initializing beatIndex to -1), with the same result.

Does somebody have an idea?

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Have you looked into PlayScheduled? \$\endgroup\$
    – DMGregory
    Mar 24 at 17:12
  • \$\begingroup\$ Thank you for your help. No I didn't, but I'm not sure it is relevant to my problem, as my metronome (more complex than the minimal example) is used to synchronise together other sound events to a unified tempo. But maybe I'm missing something? \$\endgroup\$
    – jules
    Mar 25 at 19:53
  • \$\begingroup\$ Yes, that's what it's for. \$\endgroup\$
    – DMGregory
    Mar 25 at 21:01
  • \$\begingroup\$ I see. Many thanks, I will look into that. \$\endgroup\$
    – jules
    Mar 26 at 10:52
  • \$\begingroup\$ After checking the function, that is definitely something I will use, thanks again! As a matter of fact, the documentation of PlayScheduled also indirectly answers to my question. I.e., an audio event has to be planned in advance. A comment in the code example explains: "We are now approx. 1 second before the time at which the sound should play, so we will schedule it now in order for the system to have enough time to prepare the playback at the specified time. This may involve opening buffering a streamed file and should therefore take any worst-case delay into account." \$\endgroup\$
    – jules
    Mar 26 at 15:09

0

You must log in to answer this question.

Browse other questions tagged .