I'm trying to masochistically sync note timings to align to this grid: (zoom in to see the grid properly)
(notice how 2 of the rows don't align right) but everything I try doesn't seem to work. My main issue is that this must be done in real-time, I can't preprocess it. (it's already slow enough as it is)
To explain the image:
The first row of the image is the max speed at which notes play. It's 20 NPS (notes per second). The second row doesn't align to the grid, it is 13.25 NPS. The 3rd 10 NPS. The 4th is 6.25 NPS. All the others are 20/n for n from 3 to 20.
If we call each section of the grid a "frame", and considering 20 NPS matches up with the frames, we have 20 FPS. The only thing I can do here is to choose in which frame to play a note. That is, for 20 NPS, I play a note on every frame, but for 10 NPS I skip 1 frame every note, and so on...
What I'm trying to do is come up with an algorithm that skips frames so that a 13.25 NPS song would still sound good even if I have to match/align notes to the 20 NPS/FPS grid.
Any ideas on how I can do this?
You can see everything I've already tried here: https://github.com/SoniEx2/NBSPlayer/commits/eef9ad465a1e337b17ad4e27e9a22d8a9dddfe4d/ats
The linked code would never work, as there is a bug with sleep() that makes it sleep too long. But here is a workaround:
Instead of calling sleep() directly, you should call it like so:
local function sleep_workaround(d)
local t = d * 20
for i=1,math.floor(t) do
sleep(0.05) -- 0.05s sleeps don't trigger the bug
end
end
This is due to faulty ComputerCraft code doing x -= 0.05
each tick, which causes floating point errors, instead of converting the input to an integer and doing x -= 1
each tick. As ComputerCraft uses Java, this is some simple Java code that shows the bug:
for (double d : new double[]{0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0}) {
int i;
double in = d;
for (i = 0; d > 0.0; i++, d -= 0.05) {}
System.out.println(in + " " + i);
}