Combining percussion parts in one staff

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Combining percussion parts in one staff

Christopher R. Maden
I’m engraving a marching band score.  The pitched instruments were fun.
Percussion is giving me a headache, though.

Each drum has its own part, e.g.:

% bass.ily
\version "2.18.2"
bassMusic = \drummode {
   bd4 \f r bd r |
}

% bass.ly
\version "2.18.2"
\include "bass.ily"
\score {
   \new RhythmicStaff = "bass" {
     \bassMusic
}


% snare.ily
\version "2.18.2"
snareMusic = \drummode {
   r4 sn \f r r |
}

% snare.ly
\version "2.18.2"
\include "snare.ily"
\score {
   \new RhythmicStaff = "snare" {
     \snareMusic
}

In the whole-band score, I’d like something that comes out like:

% score.ly
\version "2.18.2"
\score {
   \new DrumStaff = "percussion" {
     bd4 sn bd r |
   }
}

If I try just parallel parts like this:

% score.ly
\version "2.18.2"
\include "bass.ily"
\include "snare.ily"
\score {
   \new DrumStaff = "percussion" <<
     \bassMusic
     \snareMusic
   >>
}

... 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?

Thanks in advance,
Chris
--
Chris Maden, text nerd & chanteyman
<URL: http://crism.maden.org/ >
<URL: http://music.maden.org/ >
“Send these, the homeless, tempest-tost to me...” — Emma Lazarus

Reply | Threaded
Open this post in threaded view
|

Re: Combining percussion parts in one staff

Valentin Villenave-3
On 5/20/20, Christopher R. Maden <[hidden email]> 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.