lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Algorithm to calculate tuplets?


From: Myron Marston
Subject: Re: Algorithm to calculate tuplets?
Date: Wed, 4 Jun 2008 08:51:20 +0800

Thanks Trevor, that's really useful.  I can definitely see that there's no single right way to go about this conversion.  Your suggestion to generate the exact rhythmic notation during the composition process is a good one, especially if the main output of my application was sheet music.  However, my application is focused on producing midi files so that users can here the generated music.  Because of the nature of midi, storing my durations as fraction is a better approach.  The sheet music (if and when I get this to work!) is just a nice added bonus feature I'm tacking on.  I'm OK if the results aren't "perfect"--i.e. the way a human would transcribe it.  I'd just like something.

Isn't there a midi-to-lily converter?  I figure that must have an algorithm like this...

Anyhow, this morning I came up with a (fairly) simple algorithm that seems to work in most cases (at least the ones I have thought of!).  Here's some pseudo code for it:

if you encounter a duration with a denominator that is not a power of 2:
1. make a list of durations, beginning with this one, until they collectively add up to a power of 2
2. find the fraction with the smallest denominator that is not a power of 2
3. get the largest power of 2 that is less than this fraction's denominator
4. multiply these two together to get the tuplet multiplier
5. divide each duration by this multiplier to get its new duration within the multiplier
6. recursively apply this algorithm to this tuplet list

Examples:
triplet example:
step 1: 1/6 1/12 1/12 1/6
step 2: 1/6
step 3: 4
step 4: 4 * 1/6 = 2/3
step 5: 2/3 (1/4 1/8 1/8 1/4)

quintuplet example:
step 1: 1/5 1/10 1/10 1/5 1/5 1/5
step 2: 1/5
step 3: 4
step 4: 4 * 1/5 = 4/5
step 5: 4/5 (1/4 1/8 1/8 1/4 1/4 1/4)

nested tuplets example:
step 1: 1/5 1/10 1/10 1/15 1/15 1/15 1/5 1/5
step 2: 1/5
step 3: 4
step 4: 4 * 1/5 = 4/5
step 5: 4/5 (1/4 1/8 1/8 1/12 1/12 1/12 1/4 1/4)
apply this recursively...
step 1: 1/12 1/12 1/12
step 2: 1/12
step 3: 8
step 4: 8 * 1/12 = 2/3
step 5: 2/3 (1/8 1/8 1/8)
final result: 4/5 (1/4 1/8 1/8  2/3(1/8 1/8 1/8)  1/4 1/4)

'broken' tuplet example:
step 1: 1/12, 1/8, 1/8, 1/12, 1/12
step 2: 1/12
step 3: 8
step 4: 8 * 1/12 = 2/3
step 5: 2/3 (1/8 3/16 3/16 1/8 1/8)
(3/16 can easily be converted to a dotted 8th)

Comments?  Suggestions?  Can you think of any examples where this wouldn't work?

Thanks,
Myron



On Wed, Jun 4, 2008 at 1:08 AM, Trevor Bača <address@hidden> wrote:
On Tue, Jun 3, 2008 at 10:09 AM, Myron Marston <address@hidden> wrote:
I'm working on an application that generates music.  I'd like to use Lilypond to
generate my scores, but I'm having difficulty figuring out the best way to
produce the proper lilypond notation for the durations of the notes.
Internally, all of my rhythmic durations are represented as fractions (i.e. 1/4
for a quarter note, 3/8 for a dotted quarter, 1/6 for one note of a quarter note
triplet, etc).  As long as my durations have a power of 2 in the denominator,
it's not difficult to figure out the correct lilypond notation.  But tuplets are
much more difficult, especially when you get into nested tuplets, tuplets that
mix durations (i.e. 8ths and 16ths in the same tuplet), etc.

Does anyone know of an algorithm to convert from fractional representations of
durations to the lilypond format?


Hi Myron,

The "duration mapping" question you're pointing to is, in my opinion, one of *the key* questions in the formalized generation of notation.

Warning: personal opinion follows!

Short answer: there is no general algorithm to handle the numeric-to-rhythmic mapping. Why? Because, although the rhythmic-to-numeric mapping of some bit of rhythmic notation into a list of floats or rationals is one-to-one, the numeric-to-rhythmic mapping of a flat list of numeric values to rhythmic notation is one-to-(infinitely)-many.

We can consider the list [1/12, 1/8, 1/8, 1/12, 1/12, 1/12] as an example. Do we notate as a 'broken' triplet into which we've inserted to consecutive eighth notes? Or maybe a measure of 1/12, followed by a measure of 2/8, followed by a measure of 2/12? Maybe a tuplet of depth 1 as \times 2/3 { c'8 c'8. c'8. c'8 c'8 c'8 }? Or maybe a nested tuplet of depth 2 to 'undo' the inner prolation as \times 2/3 { c'8 \times 3/2 { c'8 c'8 } c'8 c'8 }?

Any useful numeric-to-rhythmic mapping algorithm will need to pick among the best of these options ... but what counts as 'best' will likely need reference to ...

  1. metric context

... or ...

  2. compositional process of derivation

... of both, which are absent from a simplified representation as a numeric list of values.

Pulling nested structure from a flat list is hard ... without reference to some other set of structures to guide the fitting process.

Solution: if you want to generate the trees and branches of conventional rhythmic notation then generate the trees and branches of conventional rhythmic notation directly. Model dots, brackets, ties and the effects of time signature denominators as some data structure directly and do composerly things to that. One published example is the RTree implementation in OpenMusic.

Modelling rhythmic time as a flat list of floats or rationals shows up all over everywhere in the literature on computer-assisted and algorithmic composition. But it's a trade-off: the simplicity of a flat-list representation of rhythmic time guarantees ambiguity for transcription into western rhythmic notation in precisely the same way that an unambigous model of western rhythmic notation guarantees more complex data.

So there's one quite personal opinion on rhythmic modelling: if you want exact rhythmic notation, generate it directly rather than searching for a way to apply nested structure to a flat list after the fact.

A final note. If you're willing to round some or all of your numeric values, then there's a huge literature on quantization available; maybe one of the best is an article by Paul Nauert in Perspectives of new music based on a posited notion of performance difficulty:

Nauert, P. (1994). A theory of complexity to constrain the approximation of arbitrary
sequences of timepoints. Perspectives of New Music, 32(2):226–263.

Though when it comes to quantization I've never been able to shake the following, nagging question: if you need to quantize at the end of the generative process ... then what do the intervening steps of your rhythmic transformation actually *mean*?


Trevor.



--
Trevor Bača
address@hidden


reply via email to

[Prev in Thread] Current Thread [Next in Thread]