-
Notifications
You must be signed in to change notification settings - Fork 178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improving timing for music #472
Comments
Proposal #4: Make a
|
What do you mean by this? When is the 60 bps a problem? |
In short, because not many BPMs are well divisible with 60. More proper explanation: The best solution right now is to stick to a BPM which divides perfectly. Here's a quick calculation of currently usable BPMs and their "tick waits" (considering 4 notes per beat):
It's not terrible, it's just not flexible. The issue becomes more apparent when you if you need for example 8 notes per beat, or different grooves. |
While this issue still exists, it's not as important as I first phrased it to be, and after having thought about it quite a lot more, I've reached the conclusion that fixing it with any of the proposed solutions would affect the simplicity of the architecture of WASM-4 too much. The "cleanest" possible solution I can think of would be a "high framerate mode" flag for WASM-4 that switches it to run at a 120hz clock instead of a 60hz one. This would of course increase the fps too. It could be written in such a way that it would work on 60hz devices too (but with a half a frame of lag built in). For now, I'm in personally against adding an extra clock in addition to the |
There has been much discussion in the past about how the audio interface could be made more versatile.
One improvement is in the frequency domain, where the most elaborate (and in my opinion best) solution is #333.
Another improvement that is still left unanswered is the time domain, which is difficult because WASM-4 operates on a tick-basis that is hard to break without also breaking fundamental design decisions.
This is a problem because notes currently need to be aligned to 60th of a second, which greatly limits the BPM choices if you want to stay accurate in tempo.
Proposal #1:
timer(fn, ms)
This would, to the user, be a quite simple API which calls any given function after
ms
milliseconds.(I briefly mentioned this in an old issue comment.)
Limiting this to one active timer at once is no problem for this purpose, and would probably greatly simplify implementation.
The
FRAMEBUFFER
buffer and theGAMEPAD
flags would be the same as on the lastupdate
, and any changes toFRAMEBUFFER
orPALETTE
wouldn't change what's currently on screen (though they would remain in the nextupdate
whenSYSTEM_PRESERVE_FRAMEBUFFER
is set), meaning no graphical weirdness could happen.tone
could remain as-is, still operating on a tick-basis, and callingtone
again would interrupt any currently playing audio on the given channel.The timing could either be made to align to ticks, or to be offset to whatever the current offset from the tick "grid" is, it doesn't matter too much since it could be corrected the next tick
update
if needed.Practically, this could be implemented on another thread that syncs with the thread running
update
using a mutex, or on the same thread if doing some math and syncing is kept well in check.Proposal #2:
timer
as a called functionMake a seprate
update
(e.g.timer
,sequence
,tick
) whose interval is configurable through a system flag. This would work similarly totimer
above both in implementation and usage, but limited to a single timer in the API specification itself.Proposal #3:
tone
queueAnother solution to this could be to make a "command queue" for
tone
and make theduration
argument a 10th or even 100th of a tick to greatly reduce the current temporal error. Weaved in with a System Flag to enable the previously referenced new frequency mode, the flag would also enable this new temporal mode which works on a more precise scale.Practically, this could work as a fixed buffer with a size of whatever the chosen divisor is (10, 100, etc.), which is then checked whenever a new sample is to be played (similar to what is already done with attackTime, releaseTime, etc.). Whenever a new tick starts, the last item in the queue would be moved to the front set as the currently playing to prevent misuse.
As an API user, this means you could queue up multiple tones in an
update
that would happen in sequence.This wouldn't have any performance impact at all on the current WASM-4 runtimes, since they already check a
releaseTime
on each sample iteration (which with this would instead be a time in the tone queue).Conclusion
In short:
timer
proposals either require threading or use of precise timing, but have a very simple APItone
queue proposal requires a more complextone
API with an internal bufferI'm not sure what's best, but I think it's good to have a discussion about this since having music out of sync is sad :C
The text was updated successfully, but these errors were encountered: