sequence:goToStep fails when trying to go past step 97392

When playing the giveyouup.mid bundled with the sdk and some other midi files, playback from start to finish works fine. But when using goToStep to go to a step past a certain point, the sequence instead resets to the start.
Happens on simulator and on device.

Analysis
When analysing the commonalities between songs that are and are not affected, it seems this happens exclusively with high stepCount, which tend to also have high tempo:

  • giveyouup, E4M3 and E2M3 have high tempo and stepCounts above 100000 and are affected. reset point is at 97393 exactly. Meaning that goToStep(97392) works and goToStep(97393) resets the sequence to the start
  • CGMusic is not affected, has total length of 46021 steps
  • countdown_60 is not affected, has total length of 15459 steps

Conclusion: it seems that moveToStep() cannot move past step 97392

Sample project

Relevant code

function ViewModel:movePlayHead(change)
    local targetStep = self:getCurrentStep() + floor(change * self.crankSpeed)
    targetStep = targetStep % self:getNumSteps()
    self.sequence:goToStep(targetStep, true)
end

Reproduction

  • Start the project and use the crank to scrobble through the midi file. Some files play correctly from start to end. To start another song, select the song title with :d_up: and press :a:
    Examples of affected songs are giveyouup.mid and E2M3.mid
  • notice that when letting the song play past the "reset point" normally without cranking works as expected

midi_master_progress_reset

Issue unfortunately persists in 1.13.0

It's an integer overflow in the function that computes the time offset. When step == 97392 (we subtract one before calling the low-level function, since Lua is 1-based) we get 97392 * 44100 = 4294943100, which overflows the 32-bit int and wraps around to 19904. I noticed that the C API has a setTime() function that I forgot to add to Lua (and was about to make you a Lua wrapper for it) but it has the exact same problem: The time argument is a sample offset and that gets multiplied by the step rate from the midi file, so it overflows at exactly the same place. I'll get a fix in the queue now, though it won't show up until after the 1.13.1 release we're getting out the door asap to plug the game breakers we let slip through in 1.13.0.

The only workaround I can think of is to lower the step resolution in the midi files.. somehow. :confused:

1 Like

Ay that explains it. I was surprised at first why the number I found did not line up with a binary int max value as I suspected an overflow as well.

All good with the delay, the priority seems reasonable.

Here is an affected pdx for your convenience when resting a fix: https://github.com/ninovanhooff/MIDI-Master/releases/download/0.1.0/midi_master-v0_1_0.pdx.zip