pinobatch / pently

Scalable music engine for NES games
zlib License
72 stars 4 forks source link

Round musical time to row boundary #37

Closed pinobatch closed 5 years ago

pinobatch commented 5 years ago

Pently has a few quirks because the length of a measure usually isn't an exact multiple of one tick. In "Happy Flappy Crappy" (bf98 in musicseq.pently), for example, it's 133.3 BPM at 3 rows per beat, which gets translated to 400 rows per minute, or 3606 / 400 = 9.015 NTSC ticks per row. pently_update_music accumulates the row's elapsed musical time in pently_tempoCounterHi, and at NTSC true speed (3606 rows per minute), musical time drifts in and out of phase with the tick on roughly a 10 second loop.

In the staccato portion of this piece, measures 17-25, the lengths of detached notes in patterns osti1 and osti2 drift back and forth between being shorter and being longer. The detached implementation relies on musical time per row to know when to cut the note. It also sounds different each loop because the piece's loop length (48 measures at 9 rows per measure, or 432 rows) isn't a multiple of a tick either (432 * 3606 / 400 = 3894.48 ticks).

Some NSF battle platforms (such as Famicompo Pico and Battle of the Bits) have expressed plans to detect song length and loop length by hashing the NSF player's emulated memory each frame and seeing when those hashes repeat. But if a piece's length isn't a multiple of a tick, variance in the fractional musical time will cause it to miss loops.

pinobatch commented 5 years ago

The durations of detached notes in a 400 row per minute piece oscillate between 4 ticks (4/9 row) and 5 ticks (5/9 row). It wasn't noticed elsewhere because most other uses of detached have a row length closer to an even number of ticks.

Others have obvious decimals, more thoroughly mixing the short and long notes.