lilypond-devel
[Top][All Lists]
Advanced

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

Re: Support articulations, slurs and breaths in MIDI (issue 26470047)


From: Devon Schudy
Subject: Re: Support articulations, slurs and breaths in MIDI (issue 26470047)
Date: Fri, 15 Nov 2013 19:18:19 -0500

Dan Eble wrote:
> Fermata performance is not necessarily uniform.  In some music it
> just marks the end of each line of the poem, and it is left as a
> matter of interpretation whether to perform it as a long hold, an
> extra beat, a shortening of the note to breathe in tempo, or not at
> all.  It can vary from line to line and even for the same line in
> different stanzas.

This is why articulation performance needs to be customizable.
Whatever Lilypond does won't always be right — but if users who care
can override it, it doesn't have to be. Fortunately, a conservative
interpretation (e.g. half-length staccatos; fermatas one beat longer)
is much better than nothing for almost everyone.

> If the performer will by default modify the tempo at fermatas, I
> hope that there will at least be a simple and documented way to
> suppress it at chosen points.
>
> I’m curious if this patch handles offset fermatas well, e.g.
>
> soprano = { e4 e’\fermata }
> alto    = { b2\fermata }

This patch doesn't handle fermatas at all; they're just something to
support in the future. Like all of these MIDI features, this could be
disabled by changing the relevant property. Maybe \override should
affect audio too, not just grobs, to make this easier: \override
Fermata.perform = ##f

> [Uh oh, here comes the urge to rant about pianists arranging cello
> parts.  Must... resist...]

I'm actually a wind player, not a pianist, but MIDI is designed (and
mostly used) for keyboards, so their interpretation is usually the
best one to use in MIDI. Keyboard interpretation of slurs varies —
sometimes it just suppresses the gap between notes, as in
articulate.ly — but overlap is the one synthesizers recognize.

> I wonder if it would be difficult to call out to a scheme function
> which receives two chords and returns the overlap, which can be
> negative to indicate that the transition must have a gap rather than
> an overlap.

Oh, good idea! This is more general than just changing the length of
individual notes. It would cover:
 * the interpretation where there's a gap between unslurred notes
 * instructions like "sempre staccato"
 * the interpretation where there's a gap between repeated notes but
   not betweensuccessive different notes.
 * Slurs (with a negative gap)
 * Staccat(issim)o, portato, breaths

If it's extended (later; Audio_item doesn't support this yet) to allow
changing the start of the following note as well as end of the
previous, then it could also handle:
 * swing (by altering only note pairs that are aligned with a beat)
 * time-stealing tenuto
 * starting notes with slow attacks (e.g. low notes on winds and
   strings) earlier

Design questions:
 * Should it return a gap or a duration? I think the latter is
   convenient a little more often.
 * Should slurs use a different duration function or should it take
   slur status be a parameter? The latter saves a context property,
   and covers the staccato-under-slur notation for portato.
 * Should it take chords or individual notes? The latter is easier to
   use, and supports partially tied chords. Does the gap between notes
   ever depend on other notes in the chord?
 * If it takes individual notes, should it take NoteEvents or just
   pitch and duration? The latter is more convenient but less general.

> Also, is overlap defined in units that are independent of tempo?  To
> me it would seem unnatural for a slur between the same two notes to
> overlap longer at 40 bpm than it does at 120 bpm.  I would want my
> overlap function to say “this requires a big shift, so perform it
> with a 125-ms gap” rather than having to figure out how to express
> the gap in terms of the current tempo.

It isn't independent of tempo but it probably should be. I used
written durations because that's what Lilypond uses internally, and
because breaths and staccatos sound better if they align with the
rhythm. However, staccatissimo and gap/overlap want absolute
durations. Maybe it should be expressed in written durations, but
there should be a ly:milliseconds convenience function to express
absolute times in moments. (Does this require a context argument?)

So eventually, typical use (e.g. for a more staccato style: very short
staccatos, half-length portatos, and gaps between unslurred notes)
would look something like:

staccato =
(make-articulation "staccato"
 'perform-duration
 (lambda (pitch next-pitch duration slur?)
   (ly:milliseconds (if (< (ly:pitch-octave pitch) -1) 40 30))))

portato =
(make-articulation "portato"
 'perform-duration
 (lambda (pitch next-pitch duration slur?)
   (let ((beat (ly:get-context-property context 'tempo-unit)))
     (ly:moment-mul (if (ly:moment<? duration beat) duration beat)
                    (ly:make-moment 1 2)))))
;;I wish the ordinary numeric operators worked on moments

\set Staff #'perform-duration =
(lambda (pitch next-pitch duration slur?)
  (if slur?
    duration
    (ly:moment-sub duration (ly:milliseconds 20))))



reply via email to

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