I'm developing a basic Python 2.7 musical sequencer.
A small background for people not used to musical terms.
A sequencer is a program that can "ask" some other program or device to "play" events at specific times, somehow similar to the "piano rolls" of an old Player piano. One thing that a software sequencer always makes available to the user is the "quantization", which is the ability to "move" events (usually notes that have been input via GUI or through an external instrument) to specific timings, and then obtain a more precise sound reproduction based on the current tempo.
Musical timings are based on simple 2 or 3 multiples fractions, so you can have a note that starts or has a length of a quater, 3 eights, a third and so on.
What I need is a fast function that is able to quantize "inaccurate" values.
For example, if the quantization is set to quarters and a note has a timing of 2.6, its value will become 2.5. If the quantization is based on eights, the value will be 2.625.
So far, the fastest function I was able to find was this one:
def quantize(value, numerator, denominator):
#use the least common multiple, so I can get a
#reference integer to round to.
temp = round(value * numerator * denominator, 0)
#return the re-normalized value
return temp * numerator / float(denominator)
I've been looking into the Python decimal
module and its quantize()
method, but I wasn't able to understand if it can actually do what I need.
Is there a faster and, maybe, builtin function/method in the standard library that I could use instead?
Please note that I'm not interested in the round method differences whenever the last reference float is 5, as it doesn't need to be "programmatically" precise by concept.
Also, to all the musicians reading this: the actual reference will be "beats" (as in quarter notes for common time based music), so I will obviously multiply the temp
value by 4 before rounding and then divide the value again before returning, but that's not the point here :-)