bug-lilypond
[Top][All Lists]
Advanced

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

Re: Issue 687 in lilypond: Enhancement: inequal MIDI quantization of equ


From: lilypond
Subject: Re: Issue 687 in lilypond: Enhancement: inequal MIDI quantization of equal durations (swing, rubato)
Date: Tue, 13 Jul 2010 10:52:31 +0000


Comment #6 on issue 687 by adam.spiers: Enhancement: inequal MIDI quantization of equal durations (swing, rubato)
http://code.google.com/p/lilypond/issues/detail?id=687

Regarding the previous comment 5 - I agree with both your observations (although I think that the spec in comment 4 already contained your first point implicitly). To put it another way:

- It would *not* be sufficient to only displace Note-On MIDI events, nor even Note-On *and* Note-Off MIDI events.

- It would *not* be sufficient to only displace Note-On/Note-Off MIDI events corresponding to 8th notes (or 16th notes if we were in an imaginary "16th note swing mode"), since you could have 8th notes (or 16th notes) tied to longer notes, or quarter notes or longer starting on the second 8th note (or 16th note) of the measure. For example, if attempting to generate 8th note swing,

  | r8 a4 b c d8~ | d4. f8~ f2 |

would require displacement of the following events:

  - Note-On and Note-Off for 'a4'
  - Note-On and Note-Off for 'b4'
  - Note-On and Note-Off for 'c4'
  - Note-On for 'd8'
  - Note-Off for 'd4.'
  - Note-On for 'f8'

Therefore one might be tempted to think that for conventional jazz swing at least, it would be enough to displace any Note-On and Note-Off MIDI events falling on 8th note boundaries which do not coincide with quarter note boundaries. However, this is still not sufficient!

Firstly, as correctly observed in the previous comment 5, with 8th note swing,

| a8 a a a b16 b b b a8 a |

may or may not require the Note-Off/Note-On boundary in between the second and third 'b' to be displaced. If they are to be displaced, what happens to the boundaries between the first and second 'b', and between the third and fourth 'b' ?

Secondly, we still have to deal with other types of MIDI events, such as Control/Program Change, which are associated with a particular MIDI channel. Most likely their displacement (if any) would be calculated by the same treatment that Note-Off and Note-On events receive. (SysEx messages are another can of worms which hopefully we would not have to worry about in this context.)

Thirdly, there are other more complex types of swing which would need to be catered for. For example, the Viennese waltz requires the 2nd beat of a 3/4 measure to be played slightly early, and in every four 16th notes of samba swing, the second 16th note must be slightly late and the fourth 16th note must be slightly early. Additionally, one might want every single 8th note of the solo instrument slightly delayed and every single 8th note of the bass instrument slightly anticipated, to give a more authentic jazz ensemble feel.

Fourthly, swing is a function of tempo - it can become more or less pronounced as the tempo increases.

So to solve this in a manner which is flexible enough to accommodate any style of swing, we are facing a non-trivial mathematical challenge. Here is a suggested solution:

A swing style is defined as a list of swing displacements. Each swing displacement specifies the criteria for which MIDI events it should apply to, and proportionally by how much time forwards or backwards the displacement should be made. The criteria for displacement should include the following:

- The "denominator" note duration, e.g. for 8th note swing, where displacements only occur on certain 8th note boundaries, this would be 8, and for 16th note swing it would be 16.

- The repeat count, i.e. after how many of the above note durations does the swing pattern finish and start repeating itself. For jazz swing it would be 2, since swing repeats every two 8th (or 16th) notes.

- The "numerator" swing note selector, starting counting from 1, and not exceeding the repeat count above. For jazz swing it would be 2, since every second 8th (or 16th) note is displaced.

This could be expressed in Scheme in the following manner:

    % Displace every second 8th note to be 20% later
    jazzswing8 = #`((8 2 2 20))

    % Make the second quarter note in every measure 30% earlier
    vienneselilt = #`((4 3 2 -30))

    % Make the second 16th note of every four 25% later,
    %  and the fourth 16th note of every four 25% earlier
    sambaswing16 = #`(
        (16 4 2  25)
        (16 4 4 -25)
    )

    % Ensemble "feel" examples
    jazzswing_lazysax = #`(
        (8 2 1  2)
        (8 2 2 22)
    )
    jazzswing_pushingbass = #`(
        (8 2 1 -2)
        (8 2 2 18)
    )

Using simple arithmetic in Scheme, the percentage values could easily be calculated dynamically as a function of tempo, which solves that problem.

Let us now re-examine this case given above:

| a8 a a a b16 b b b a8 a |

and see how the above jazzswing8 definition would apply to it. Since the denominator is 8, the Note-Off/Note-On boundary in between the second and third 'b' would indeed be displaced 20% later. It seems to me that this should not happen by default, because of the implications on the other 16th notes. A solution to this would be to make our implementation of Swing_Performer only displace notes whose start and end *both* fall on a "swing boundary" as determined by the denominator value. In this example, the Note-Off for the second 'b' coincides with an 8th note boundary, but the Note-On does not. Conversely, the Note-On for the third 'b' does, but the Note-Off does not. Therefore neither note would incur any displacement, and in fact, none of the four 16th notes in this example would.

If this displacement *was* required, then it would have to be specified manually at 16th note granularity, eliminating any doubt regarding how the swing should be distributed, e.g.

    % Displace every second 8th note to be 20% later, and also
    % slightly swing 16th notes
    jazzswing8 = #`(
      ( 8 2 2 20)
      % This might sound weird!
      (16 4 2 10)
      (16 4 3 20)
      (16 4 4  5)
    )





reply via email to

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