HeavenStudioPlus/Assets/Scripts/Conductor.cs

223 lines
7.1 KiB
C#
Raw Normal View History

2021-12-19 04:10:43 +00:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Starpelly;
// I CANNOT STRESS THIS ENOUGH, SET "Project Settings/Audio/DSP Buffer Size" to "Best latency" or else AudioSource.time WILL NOT update every frame.
2021-12-21 01:10:49 +00:00
namespace RhythmHeavenMania
2021-12-19 04:10:43 +00:00
{
2021-12-21 01:10:49 +00:00
[RequireComponent(typeof(AudioSource))]
public class Conductor : MonoBehaviour
{
//Song beats per minute
//This is determined by the song you're trying to sync up to
public float songBpm;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//The number of seconds for each song beat
public float secPerBeat;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//Current song position, in seconds
public float songPosition;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//Current song position, in beats
public float songPositionInBeats;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//How many seconds have passed since the song started
public float dspSongTime;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//an AudioSource attached to this GameObject that will play the music.
public AudioSource musicSource;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//The offset to the first beat of the song in seconds
public float firstBeatOffset;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//the number of beats in each loop
public float beatsPerLoop;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//the total number of loops completed since the looping clip first started
public int completedLoops = 0;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//The current position of the song within the loop in beats.
public float loopPositionInBeats;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//The current relative position of the song within the loop measured between 0 and 1.
public float loopPositionInAnalog;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//Conductor instance
public static Conductor instance;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//Pause times
2021-12-25 02:37:03 +00:00
// private int pauseTime = 0;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
public float beatThreshold;
2021-12-19 04:10:43 +00:00
private float lastTime;
private float lastMst_F;
private int framesSinceLastSame;
2021-12-21 01:10:49 +00:00
void Awake()
{
instance = this;
}
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
void Start()
{
//Load the AudioSource attached to the Conductor GameObject
musicSource = GetComponent<AudioSource>();
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//Calculate the number of seconds in each beat
secPerBeat = 60f / songBpm;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//Record the time when the music starts
dspSongTime = (float)musicSource.time;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//Start the music
// musicSource.Play();
}
2021-12-19 04:10:43 +00:00
public void Play(float startBeat)
{
musicSource.Play();
}
public void Update()
2021-12-19 04:10:43 +00:00
{
// Conductor.instance.musicSource.pitch = Time.timeScale;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
/*if (Input.GetKeyDown(KeyCode.Space))
{
pauseTime++;
if (pauseTime == 1)
musicSource.Pause();
else if (pauseTime > 1) { musicSource.UnPause(); pauseTime = 0; }
}*/
2021-12-19 04:10:43 +00:00
float mst = musicSource.timeSamples / (float)musicSource.clip.frequency;
float mst_f = mst + 0;
if (mst == lastTime && musicSource.isPlaying)
{
framesSinceLastSame++;
mst_f = mst_f + (Time.deltaTime * framesSinceLastSame) * musicSource.pitch;
2021-12-28 07:38:55 +00:00
if (mst_f <= lastMst_F)
{
2021-12-28 07:38:55 +00:00
// mst_f = lastMst_F;
float b = lastMst_F + (Time.deltaTime) * musicSource.pitch;
mst_f = b;
// print(b);
// print(mst_f + " " + b + " " + lastMst_F);
}
else if (mst_f < lastTime)
{
Debug.LogError("What the fuck.");
}
2021-12-28 07:38:55 +00:00
// print($"{lastMst_F}, {mst_f}");
}
else
{
framesSinceLastSame = 0;
}
lastTime = mst;
lastMst_F = mst_f;
2021-12-21 01:10:49 +00:00
//determine how many seconds since the song started
songPosition = (float)(mst_f - dspSongTime - firstBeatOffset);
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//determine how many beats since the song started
songPositionInBeats = songPosition / secPerBeat;
2021-12-28 07:38:55 +00:00
// print($"{mst_f}(AudioSource.time), {Time.frameCount}(Time.fasrameCount)");
// print($"{musicSource.time}(0), {mst_f}");
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
//calculate the loop position
if (songPositionInBeats >= (completedLoops + 1) * beatsPerLoop)
completedLoops++;
loopPositionInBeats = songPositionInBeats - completedLoops * beatsPerLoop;
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
loopPositionInAnalog = loopPositionInBeats / beatsPerLoop;
}
2021-12-19 04:10:43 +00:00
2021-12-21 01:10:49 +00:00
public float GetLoopPositionFromBeat(float startBeat, float length)
{
float a = Mathp.Normalize(songPositionInBeats, startBeat, startBeat + length);
return a;
2021-12-21 01:10:49 +00:00
}
2021-12-23 02:28:05 +00:00
public void SetBpm(float bpm)
{
this.songBpm = bpm;
secPerBeat = 60f / songBpm;
}
2021-12-21 01:10:49 +00:00
public bool InThreshold(float beat)
2021-12-19 04:10:43 +00:00
{
2021-12-21 01:10:49 +00:00
//Check if the beat sent falls within beatThreshold
//Written to handle the looping
if (beat <= beatThreshold + 1)
2021-12-19 04:10:43 +00:00
{
2021-12-21 01:10:49 +00:00
//Debug.Log("Case 1, beat is close to 1");
if (loopPositionInBeats > beat + beatThreshold)
2021-12-19 04:10:43 +00:00
{
2021-12-21 01:10:49 +00:00
if (loopPositionInBeats >= (beat + songPositionInBeats - 1) + beatThreshold)
{
//Debug.Log("LoopPos just below loop point");
return true;
}
else
{
//Debug.Log("LoopPos not within beat threshold");
}
2021-12-19 04:10:43 +00:00
}
else
{
2021-12-21 01:10:49 +00:00
//Debug.Log("Case 1, loopPos between loop point and beat threshold");
2021-12-19 04:10:43 +00:00
}
}
2021-12-21 01:10:49 +00:00
else if (beat < (songPositionInBeats + 1 - beatThreshold))
2021-12-19 04:10:43 +00:00
{
2021-12-21 01:10:49 +00:00
//Debug.Log("Case 2, beat is far from loop point.");
if (loopPositionInBeats >= beat - beatThreshold && loopPositionInBeats <= beat + beatThreshold)
{
//Debug.Log("LoopPos within threshold");
return true;
}
2021-12-19 04:10:43 +00:00
}
2021-12-21 01:10:49 +00:00
else if (beat >= (songPositionInBeats + 1 - beatThreshold))
2021-12-19 04:10:43 +00:00
{
2021-12-21 01:10:49 +00:00
//Debug.Log("Case 3, beat is close to loop point");
if (loopPositionInBeats < beat)
2021-12-19 04:10:43 +00:00
{
2021-12-21 01:10:49 +00:00
if (loopPositionInBeats >= beat - beatThreshold)
{
//Debug.Log("LoopPos just below beat");
return true;
}
else if (loopPositionInBeats < (beat - songPositionInBeats + 1) - beatThreshold)
{
//Debug.Log("LoopPos just above loop point");
return true;
}
2021-12-19 04:10:43 +00:00
}
2021-12-21 01:10:49 +00:00
else
2021-12-19 04:10:43 +00:00
{
2021-12-21 01:10:49 +00:00
//Debug.Log("LoopPos just above beat");
2021-12-19 04:10:43 +00:00
return true;
}
2021-12-21 01:10:49 +00:00
2021-12-19 04:10:43 +00:00
}
else
{
2021-12-21 01:10:49 +00:00
Debug.LogError("Strange Case. Where is this beat? This should never happen");
2021-12-19 04:10:43 +00:00
}
2021-12-21 01:10:49 +00:00
return false;
2021-12-19 04:10:43 +00:00
}
}
}