local myMath = require("modules.math") local logging = require("modules.logging") local conductor = {} conductor.bpm = 120 conductor.crochet = 1000 conductor.stepCrochet = conductor.crochet/4 conductor.songPosition = 0 conductor.bpmChangeMap = {} function conductor:getBPMFromSeconds(time) local lastChange = { stepTime = 0, songTime = 0, bpm = self.bpm, stepCrochet = self.stepCrochet } for _, change in next, self.bpmChangeMap do if time >= change.songTime then lastChange = change end end return lastChange end function conductor:calculateCrochet(bpm) return (60/bpm) * 1000 end function conductor:setBpm(newBpm) self.bpm = newBpm self.crochet = self:calculateCrochet(newBpm) self.stepCrochet = self.crochet / 4 end function conductor:getStep(time) local lastChange = self:getBPMFromSeconds(time) return lastChange.stepTime + (time - lastChange.songTime) / lastChange.stepCrochet end function conductor:getStepRounded(time) local lastChange = self:getBPMFromSeconds(time) return math.floor(lastChange.stepTime + math.floor(time - lastChange.songTime) / lastChange.stepCrochet) end function conductor:getBeat(time) return self:getStep(time) / 4 end function conductor:getBeatRounded(time) return math.floor(self:getStep(time) / 4) end function conductor:getSectionBeats(song, section) local beats = nil if song["notes"][section] then beats = song["notes"][section]["sectionBeats"] end return beats or 4 end function conductor:mapBpmChanges(song) local curBPM = song["bpm"] local totalSteps = 0 local totalPos = 0 for index, section in next, song["notes"] do if section["changeBPM"] then curBPM = section["bpm"] local change = { stepTime = totalSteps, songTime = totalPos, bpm = curBPM, stepCrochet = self:calculateCrochet(curBPM)/4 } table.insert(self.bpmChangeMap, change) end local deltaSteps = myMath.round(self:getSectionBeats(song, index) * 4) totalSteps = totalSteps + deltaSteps totalPos = (totalPos + (60/curBPM) * 1000 / 4) * deltaSteps end print("Mapped the song BPM changes.") end return conductor