How to sync audio and visuals in rhythm game?

I am working on a rhythm game and I wanted to sync visuals with the audio file playing. I already know the audio is playing at 60 beats per minute.

The problem I have is the visuals and audio is completely out of sync.

Can anyone provide some assistance to fix this?

private float musicBMP = 60.0f;

void Awake()
{
    audioSourceBeatIntro = gameObject.GetComponent<AudioSource>();
}

void Start () {

    audioSourceBeatIntro.clip = playClip;
    audioSourceBeatIntro.time = 0.0f;
    audioSourceBeatIntro.Stop();
    audioPlaying = false;

    audioFreq = audioSourceBeatIntro.clip.frequency;

    tempoTime = 60.0f / musicBMP;
}
	
void Update () {

        

    if (Input.GetKeyDown(KeyCode.S))
    {
        audioSourceBeatIntro.time = 0.0f;
        audioSourceBeatIntro.Play();
        audioPlaying = true;
    }

    if (audioPlaying)
    {
        tempoTimeAmount += Time.deltaTime;

        if (tempoTimeAmount >= tempoTime)
        {
            tempoTimeAmount = 0;
            ChangeScale();
        }
    }
	
}

private void ChangeScale()
{
    if (currentScale == 1.0f)
    {
        currentScale = 5.0f;
    }
    else
    {
        currentScale = 1.0f;
    }
    gameObject.transform.localScale = new Vector3(currentScale, currentScale, currentScale);
}

you just have to find the frequency of the bass line you use. and scale to that.
you can read the output of the spectrum data. and if its bigger than a certain value scale it up or just use the direct scaling data just like I’ve done here.

public string tagName = "SpectruObject";
	public int specStat1 = 700,specStat2 = 750; // this is the spectrum data position.
	private float spectrumScale,curveEnhancer = 950f;
	private GameObject[] soundObject;	

	// Use this for initialization
	void Start () 
	{
		soundObject = GameObject.FindGameObjectsWithTag (tagName);
	}
	
	// Update is called once per frame
	void Update () 
	{
		float[] spectrum = audio.GetSpectrumData (1024, 1, FFTWindow.BlackmanHarris);// you can use other calculations than blackmanharris.

		spectrumScale = 1f + ((spectrum [specStat1] + spectrum [specStat2]) * curveEnhancer);
		for (int i = 0; i<= (soundObject.Length)-1;i++)
		{
			soundObject*.gameObject.transform.localScale = new Vector3(spectrumScale,spectrumScale,spectrumScale);*
  •  }*
    
  • }*

I found very nice explanation here