lilypond-user
[Top][All Lists]
Advanced

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

Re: Combining percussion parts in one staff


From: Valentin Villenave
Subject: Re: Combining percussion parts in one staff
Date: Wed, 20 May 2020 19:18:08 +0200

On 5/20/20, Christopher R. Maden <address@hidden> wrote:
> ... I get rests scattered all over the place, not to mention redundant
> dynamics.  Is there a way to combine the different drum parts on one
> staff without engraving a terrible mess?

Well, I’m not gonna lie: that’s a tough one. That’s typically what
\partcombine (nowadays \partCombine) is for, but as we’ve seen over
the years, it’d take a substantial amount of effort to make that work
with \drummode.

The best and simplest way you can go, I think, is to decide with voice
is the "master" one, and use all the other voices only for notes but
neither rests nor dynamics:

%%%%

bassMusic = \drummode {
  bd4 \f r bd r |
}

snareMusic = \drummode {
  r4 sn \f r r |
}

\score {
  \new DrumStaff = "percussion" <<
    \bassMusic
    \new minorDrumVoice \snareMusic
  >>
}

\layout {
  \context {
    \DrumVoice
    \name minorDrumVoice
    \remove Dynamic_engraver
    \remove Rest_engraver
  }
  \context {
    \DrumStaff
    \accepts minorDrumVoice
  }
}

%%%%%

I’m not saying it’s perfect, but it may be the simplest option. Now if
you need/want something more advanced, it can be done but not without
some hacks and some assembly required. Have a look at the following
example:

%%%%

#(define (dynamic? x)
   (let ((name (ly:music-property x 'name)))
     (or
      (eq? name 'DynamicEvent)
      (eq? name 'AbsoluteDynamicEvent)
      (eq? name 'CrescendoEvent)
      (eq? name 'DecrescendoEvent)
      (eq? name 'SpanDynamicEvent))))

removeDynamics =
#(define-music-function (parser location m) (ly:music?)
   (music-filter
    (lambda (x)
      (let ((tags (ly:music-property x 'tags))
            (dir (ly:music-property x 'direction)))
        (not (and
              (dynamic? x)
              (not (memq 'keep tags))
              (null? dir)))))
    m))

makeRestsInvisible =
#(define-music-function (parser location m) (ly:music?)
   (music-map
    (lambda (x)
      (if (and
           (music-is-of-type? x 'rest-event)
           (not (memq 'keep
                      (ly:music-property x 'tags))))
          (skip-of-length x)
          x))
    m))

makeNiceTogether =
#(define-music-function (parser location v0 v1 v2 v3)
   (ly:music? ly:music? ly:music? ly:music?)
   #{
     \new DrumVoice <<
       \removeDynamics \makeRestsInvisible $v1
       \removeDynamics \makeRestsInvisible $v2
       \removeDynamics \makeRestsInvisible $v3
       \removeWithTag #'rm $v0
     >>
   #})

keep =
#(define-music-function (parser location m) (ly:music?)
   #{ \tag #'keep $m #})

rm =
#(define-music-function (parser location m) (ly:music?)
   #{ \removeDynamics \makeRestsInvisible $m #})

bassMusic = \drummode {
  bd4 \f \rm r bd r |
}

snareMusic = \drummode {
  r4 sn \f r r |
}

\score {
  \new DrumStaff = "percussion"
    \makeNiceTogether
      \bassMusic
      \snareMusic
      {} %% Extra voice if you need it
      {} %% Extra voice if you need it
}

%%%%

(It’s a pity you’re running 2.18, as 2.20, and 2.21 even more so, have
some nifty shortcuts that could’ve made that syntax a bit more
concise.)

Now, every voice gets crunched together in a single voice, and the
rests get removed. Again, one of the voices acts as the master voice
and all its rests and dynamics are kept (except if you precede them
with the \rm command); reciprocally, all other voices get filtered
like in the previous example (but now the \keep command allows you to
select events that will be kept).

What you *could* do is insert all the definitions above in a .ly file
that you can then include at the top of your master file.

In another .ly file, you could write a dummy definition for rm and keep, such as

rm =
#(define-music-function (parser location m) (ly:music?)
  #{ $m #})

So when you need to compile your voices individually without changing
anything, you can \include the latter (dummy) definition file, but
when compiling the master file you can use the actual useful
definition file. (Unfortunately, the way LilyPond works means that you
can't currently use both at the same time.)

Cheers,
-- V.



reply via email to

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