time Signature functionality wip

This commit is contained in:
NyxieFemboy
2024-10-06 15:10:51 -04:00
parent a8b6e8ed72
commit 8da7faa0b4
8 changed files with 112 additions and 35 deletions
+93 -32
View File
@@ -10,6 +10,8 @@ typedef BPMChangeEvent =
var stepTime:Float;
var songTime:Float;
var bpm:Float;
var beatsPerMeasure:Float;
var stepsPerBeat:Float;
}
class Conductor
@@ -21,6 +23,8 @@ class Conductor
public static var onBeatHit:FlxTypedSignal<Int->Void> = new FlxTypedSignal();
public static var onStepHit:FlxTypedSignal<Int->Void> = new FlxTypedSignal();
public static var onBPMChange:FlxTypedSignal<Float->Void> = new FlxTypedSignal();
public static var onBeatsPerMeasureChange:FlxTypedSignal<Float->Void> = new FlxTypedSignal();
public static var onStepsPerBeatChange:FlxTypedSignal<Float->Void> = new FlxTypedSignal();
/**
* Current BPM
@@ -108,45 +112,76 @@ class Conductor
songPosition = lastSongPos = curBeatFloat = curStepFloat = curBeat = curStep = 0;
bpmChangeMap = [];
changeBPM(0);
changeTimeSignature(4, 4);
}
public static function setupSong(SONG:ChartData) {
reset();
mapBPMChanges(SONG);
changeBPM(SONG.meta.bpm, cast SONG.meta.beatsPerMeasure.getDefault(4), cast SONG.meta.stepsPerBeat.getDefault(4));
changeBPM(SONG.meta.bpm);
changeTimeSignature(cast SONG.meta.beatsPerMeasure.getDefault(4), cast SONG.meta.stepsPerBeat.getDefault(4));
}
/**
* Maps BPM changes from a song.
* @param song Song to map BPM changes from.
*/
public static function mapBPMChanges(song:ChartData)
{
public static function mapBPMChanges(song:ChartData) {
bpmChangeMap = [
{
stepTime: 0,
songTime: 0,
bpm: song.meta.bpm
bpm: song.meta.bpm,
beatsPerMeasure: song.meta.beatsPerMeasure.getDefault(4),
stepsPerBeat: song.meta.stepsPerBeat.getDefault(4)
}
];
if (song.events == null) return;
var curBPM:Float = song.meta.bpm;
var curBeatsPerMeasure:Float = song.meta.beatsPerMeasure.getDefault(4);
var curStepsPerBeat:Float = song.meta.stepsPerBeat.getDefault(4);
var songTime:Float = 0;
var stepTime:Float = 0;
for(e in song.events) if (e.name == "BPM Change" && e.params != null && e.params[0] is Float) {
if (e.params[0] == curBPM) continue;
var steps = (e.time - songTime) / ((60 / curBPM) * 1000 / 4);
stepTime += steps;
songTime = e.time;
curBPM = e.params[0];
bpmChangeMap.push({
stepTime: stepTime,
songTime: songTime,
bpm: curBPM
});
for(e in song.events) {
if (e.name == "BPM Change" && e.params != null && e.params[0] is Float) {
if (e.params[0] == curBPM) continue;
var steps = (e.time - songTime) / ((60 / curBPM) * 1000 / stepsPerBeat);
stepTime += steps;
songTime = e.time;
curBPM = e.params[0];
bpmChangeMap.push({
stepTime: stepTime,
songTime: songTime,
bpm: curBPM,
beatsPerMeasure: curBeatsPerMeasure, // keep old beatsPerMeasure and stepsPerMeasure so shit doesnt break
stepsPerBeat: curStepsPerBeat
});
}
if (e.name == "Time Signature Change" && e.params != null) {
var newBeatsPerMeasure = e.params[0];
var newStepsPerBeat = e.params[1];
if (newBeatsPerMeasure == curBeatsPerMeasure && newStepsPerBeat == curStepsPerBeat) continue;
var steps = (e.time - songTime) / ((60 / curBPM) * 1000 / stepsPerBeat);
stepTime += steps;
songTime = e.time;
curBeatsPerMeasure = newBeatsPerMeasure;
curStepsPerBeat = newStepsPerBeat;
bpmChangeMap.push({
stepTime: stepTime,
songTime: songTime,
bpm: curBPM, // keep old bpm so shit doesnt break
beatsPerMeasure: curBeatsPerMeasure,
stepsPerBeat: curStepsPerBeat
});
}
}
}
@@ -184,22 +219,32 @@ class Conductor
if (FlxG.state != null && FlxG.state is MusicBeatState && cast(FlxG.state, MusicBeatState).cancelConductorUpdate) return;
__updateSongPos(FlxG.elapsed);
if (bpm > 0) {
// updates curbeat and stuff
// Check for BPM change
__lastChange = {
stepTime: 0,
songTime: 0,
bpm: 0
bpm: 0,
beatsPerMeasure: beatsPerMeasure,
stepsPerBeat: stepsPerBeat
};
for (change in Conductor.bpmChangeMap)
{
for (change in Conductor.bpmChangeMap) {
if (Conductor.songPosition >= change.songTime)
__lastChange = change;
}
// Change BPM if necessary
if (__lastChange.bpm > 0 && bpm != __lastChange.bpm) {
changeBPM(__lastChange.bpm);
}
if (__lastChange.bpm > 0 && bpm != __lastChange.bpm) changeBPM(__lastChange.bpm);
// Check for time signature change
if (__lastChange.beatsPerMeasure != beatsPerMeasure || __lastChange.stepsPerBeat != stepsPerBeat) {
changeTimeSignature(__lastChange.beatsPerMeasure, __lastChange.stepsPerBeat);
}
curStepFloat = __lastChange.stepTime + ((Conductor.songPosition - __lastChange.songTime) / Conductor.stepCrochet);
curBeatFloat = curStepFloat / stepsPerBeat;
curMeasureFloat = curBeatFloat / beatsPerMeasure;
@@ -270,34 +315,50 @@ class Conductor
onBPMChange.dispatch(bpm);
}
public static function changeTimeSignature(newBeatsPerMeasure:Float, newStepsPerBeat:Float) {
beatsPerMeasure = newBeatsPerMeasure;
stepsPerBeat = newStepsPerBeat;
crochet = ((60 / bpm) * 1000);
stepCrochet = crochet / stepsPerBeat;
onBeatsPerMeasureChange.dispatch(beatsPerMeasure);
onStepsPerBeatChange.dispatch(stepsPerBeat);
}
public static function getTimeForStep(step:Float) {
var bpmChange:BPMChangeEvent = {
stepTime: 0,
songTime: 0,
bpm: bpm
bpm: bpm,
beatsPerMeasure: beatsPerMeasure,
stepsPerBeat: stepsPerBeat
};
for(change in bpmChangeMap)
if (change.stepTime < step && change.stepTime >= bpmChange.stepTime)
bpmChange = change;
return bpmChange.songTime + ((step - bpmChange.stepTime) * ((60 / bpmChange.bpm) * (1000/stepsPerBeat)));
return bpmChange.songTime + ((step - bpmChange.stepTime) * ((60 / bpmChange.bpm) * (1000 / bpmChange.stepsPerBeat)));
}
public static function getStepForTime(time:Float) {
var bpmChange:BPMChangeEvent = {
stepTime: 0,
songTime: 0,
bpm: bpm
bpm: bpm,
beatsPerMeasure: beatsPerMeasure,
stepsPerBeat: stepsPerBeat
};
for(change in bpmChangeMap)
if (change.songTime < time && change.songTime >= bpmChange.songTime)
bpmChange = change;
return bpmChange.stepTime + ((time - bpmChange.songTime) / ((60 / bpmChange.bpm) * (1000/stepsPerBeat)));
return bpmChange.stepTime + ((time - bpmChange.songTime) / ((60 / bpmChange.bpm) * (1000 / bpmChange.stepsPerBeat)));
}
public static inline function getMeasureLength()
return stepsPerBeat * beatsPerMeasure;