LilyPond snippets: MIDI

# MIDI

Creating MIDI output

## Affectation d’un canal MIDI par voix

Lorsque LilyPond génère un fichier MIDI, chaque portée sera par défaut affectée à un canal, quel que soit le nombre de voix qu’elle contient. Ceci permet d’éviter de se retrouver à court de canaux, sachant qu’il n’y en a que seize de disponibles par piste.

Le fait de déplacer le `Staff_performer` dans le contexte `Voice` permet d’affecter à chaque voix d’une même portée un canal MIDI spécifique. Dans l’exemple suivant, la même portée donnera lieu à deux canaux MIDI différents, chacun étant affecté de son propre `midiInstrument`.

    \score {
      \new Staff <<
        \new Voice \relative c''' {
          \set midiInstrument = #"flute"
          \voiceOne
          \key g \major
          \time 2/2
          r2 g-"Flute" ~
          g fis ~
          fis4 g8 fis e2 ~
          e4 d8 cis d2
        }
        \new Voice \relative c'' {
          \set midiInstrument = #"clarinet"
          \voiceTwo
          b1-"Clarinet"
          a2. b8 a
          g2. fis8 e
          fis2 r
        }
      >>
      \layout { }
      \midi {
        \context {
          \Staff
          \remove "Staff_performer"
        }
        \context {
          \Voice
          \consists "Staff_performer"
        }
        \tempo 2 = 72
      }
    }

## Changement de tempo sans indication sur la partition

Vous pouvez indiquer un changement de tempo pour le fichier MIDI sans pour autant l’imprimer. Il suffit alors de le rendre invisible aux musiciens.

    \score {
      \new Staff \relative c' {
        \tempo 4 = 160
        c4 e g b
        c4 b d c
        \set Score.tempoHideNote = ##t
        \tempo 4 = 96
        d,4 fis a cis
        d4 cis e d
      }
      \layout { }
      \midi { }
    }

## Création de nuance particulière pour la sortie MIDI

L’exemple suivant illustre la manière de créer une indication de nuance, absente de la liste par défaut, et de lui assigner une valeur spécifique utile à la sortie MIDI.

L’indication de nuance `\rfz` (rinforzando) se voit attribuer une valeur de `0.9`.

    #(define (myDynamics dynamic)
        (if (equal? dynamic "rfz")
          0.9
          (default-dynamic-absolute-volume dynamic)))

    \score {
      \new Staff {
        \set Staff.midiInstrument = #"cello"
        \set Score.dynamicAbsoluteVolumeFunction = #myDynamics
        \new Voice {
          \relative {
            a'4\pp b c-\rfz
          }
        }
      }
      \layout {}
      \midi {}
    }

## Personnalisation de batterie pour les sorties imprimable et MIDI

Des noms de « hauteurs » de batterie personnalisée peuvent s’utiliser à la fois pour la sortie imprimable et le fichier MIDI généré. Ces variables doivent être définies en tant que `drumPitchNames`, `drumStyleTable` et `midiDrumPitches`, comme indiqué ci-dessous. En résumé, cet extrait

- définit quelques noms de « hauteur »,
- définit comment ils seront rendus,
- indique à LilyPond de les utiliser pour la mise en forme,
- assigne les hauteurs aux noms,
- indique à LilyPond de les utiliser pour le rendu MIDI.

    %% This snippet tries to amend
    %% NR 2.5.1 Common notation for percussion - Custom percussion staves
    %% http://lilypond.org/doc/v2.18/Documentation/notation/common-notation-for-percussion#custom-percussion-staves

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%
    %% To use custom drum pitch names for your score and midi you need to follow
    %% this route:
    %%
    %%%%%%%%%%%%
    %% LAYOUT:
    %%%%%%%%%%%%
    %%
    %% (1) Define a name and put it in `drumPitchNames'
    %%     This can be done at toplevel with
    %%         drumPitchNames.my-name  = #'my-name
    %%     It's possible to add an alias as well.
    %% (2) Define how it should be printed
    %%     Therefore put them into a top-level list, where each entry should
    %%     be of the form:
    %%         (my-name
    %%           note-head-style-or-default
    %%             articulation-type-or-#f
    %%               staff-position)
    %%     Example:
    %%         #(define my-style
    %%           '(
    %%             (my-name default tenuto -1)
    %%             ; ...
    %%             ))
    %% (3) Tell LilyPond to use these custom definitions, with
    %%         drumStyleTable = #(alist->hash-table my-style)
    %%     in a \layout or \with block
    %%
    %%     Now we're done for layout. Here is a short but complete example:
    %%         \new DrumStaff
    %%           \with { drumStyleTable = #(alist->hash-table my-style) }
    %%           \drummode { my-name }
    %%
    %%%%%%%%%%%%
    %% MIDI:
    %%%%%%%%%%%%
    %%
    %% (1) Again at top-level, assign a pitch to your custom note name
    %%         midiDrumPitches.my-name = ges
    %%     Note that you have to use the name, which is in drumPitchNames, no alias
    %% (2) Tell LilyPond to use this pitch(es), with
    %%         drumPitchTable = #(alist->hash-table midiDrumPitches)
    %%
    %%     Example:
    %%         \score {
    %%            \new DrumStaff
    %%             \with {
    %%               drumStyleTable = #(alist->hash-table my-style)
    %%               drumPitchTable = #(alist->hash-table midiDrumPitches)
    %%             }
    %%             \drummode { my-name4 }
    %%           \layout {}
    %%           \midi {}
    %%         }
    %%
    %%%%%%%%%%%%
    %% TESTING
    %%%%%%%%%%%%
    %%
    %% To test whether all is fine, run the following sequence in terminal:
    %%         lilypond my-file.ly
    %%         midi2ly my-file.midi
    %%         gedit my-file-midi.ly
    %%
    %% This will do the following:
    %% 1. create pdf and midi
    %% 2. transform the midi back to a .ly-file
    %%    (note: midi2ly is not always good in correctly identifying enharmonic pitches)
    %% 3. open this file in gedit (or use another editor)
    %% Now watch what you've got.
    %%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% FULL EXAMPLE
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    drumPitchNames.dbass      = #'dbass
    drumPitchNames.dba        = #'dbass  % 'db is in use already
    drumPitchNames.dbassmute  = #'dbassmute
    drumPitchNames.dbm        = #'dbassmute
    drumPitchNames.do         = #'dopen
    drumPitchNames.dopenmute  = #'dopenmute
    drumPitchNames.dom        = #'dopenmute
    drumPitchNames.dslap      = #'dslap
    drumPitchNames.ds         = #'dslap
    drumPitchNames.dslapmute  = #'dslapmute
    drumPitchNames.dsm        = #'dslapmute

    #(define djembe
      '((dbass      default  #f         -2)
        (dbassmute  default  stopped    -2)
        (dopen      default  #f          0)
        (dopenmute  default  stopped     0)
        (dslap      default  #f          2)
        (dslapmute  default  stopped     2)))

    midiDrumPitches.dbass = g
    midiDrumPitches.dbassmute = fis
    midiDrumPitches.dopen =  a
    midiDrumPitches.dopenmute = gis
    midiDrumPitches.dslap =  b
    midiDrumPitches.dslapmute = ais

    one = \drummode { r4 dba4 do ds r dbm dom dsm }

    \score {
       \new DrumStaff
        \with {
          \override StaffSymbol.line-count =  #3
          instrumentName = #"Djembe "
          drumStyleTable = #(alist->hash-table djembe)
          drumPitchTable = #(alist->hash-table midiDrumPitches)
        }
        \one
      \layout {}
      \midi {}
    }

## Démonstration de `midiInstrument`

Partant du problème que l’on ignore quel `midiInstrument` serait le plus adapté à sa composition, voici un fichier LilyPond de démonstration.

    \header {
      title = "Demo of all midi sounds"
      arranger = "Myself "
    }

    baseMelody = \relative c' {
      c4.\mf g c16 b' c d
      e16 d e f g4 g'4 r
      R1
    }
    melody = {
      \tempo 4 = 150
      \baseMelody
    }

    \score {
      \new Staff <<
        \new Voice \melody
      >>
      \layout { }
    }

    \score {
      \new Staff <<
        \new Voice {
          r\mf
          \set Staff.midiInstrument = #"acoustic grand" \melody
          \set Staff.midiInstrument = #"bright acoustic" \melody
          \set Staff.midiInstrument = #"electric grand" \melody
          \set Staff.midiInstrument = #"honky-tonk" \melody
          \set Staff.midiInstrument = #"electric piano 1" \melody
          \set Staff.midiInstrument = #"electric piano 2" \melody
          \set Staff.midiInstrument = #"harpsichord" \melody
          \set Staff.midiInstrument = #"clav" \melody
          \set Staff.midiInstrument = #"celesta" \melody
          \set Staff.midiInstrument = #"glockenspiel" \melody
          \set Staff.midiInstrument = #"music box" \melody
          \set Staff.midiInstrument = #"vibraphone" \melody
          \set Staff.midiInstrument = #"marimba" \melody
          \set Staff.midiInstrument = #"xylophone" \melody
          \set Staff.midiInstrument = #"tubular bells" \melody
          \set Staff.midiInstrument = #"dulcimer" \melody
          \set Staff.midiInstrument = #"drawbar organ" \melody
          \set Staff.midiInstrument = #"percussive organ" \melody
          \set Staff.midiInstrument = #"rock organ" \melody
          \set Staff.midiInstrument = #"church organ" \melody
          \set Staff.midiInstrument = #"reed organ" \melody
          \set Staff.midiInstrument = #"accordion" \melody
          \set Staff.midiInstrument = #"harmonica" \melody
          \set Staff.midiInstrument = #"concertina" \melody
          \set Staff.midiInstrument = #"acoustic guitar (nylon)" \melody
          \set Staff.midiInstrument = #"acoustic guitar (steel)" \melody
          \set Staff.midiInstrument = #"electric guitar (jazz)" \melody
          \set Staff.midiInstrument = #"electric guitar (clean)" \melody
          \set Staff.midiInstrument = #"electric guitar (muted)" \melody
          \set Staff.midiInstrument = #"overdriven guitar" \melody
          \set Staff.midiInstrument = #"distorted guitar" \melody
          \set Staff.midiInstrument = #"acoustic bass" \melody
          \set Staff.midiInstrument = #"electric bass (finger)" \melody
          \set Staff.midiInstrument = #"electric bass (pick)" \melody
          \set Staff.midiInstrument = #"fretless bass" \melody
          \set Staff.midiInstrument = #"slap bass 1" \melody
          \set Staff.midiInstrument = #"slap bass 2" \melody
          \set Staff.midiInstrument = #"synth bass 1" \melody
          \set Staff.midiInstrument = #"synth bass 2" \melody
          \set Staff.midiInstrument = #"violin" \melody
          \set Staff.midiInstrument = #"viola" \melody
          \set Staff.midiInstrument = #"cello" \melody
          \set Staff.midiInstrument = #"contrabass" \melody
          \set Staff.midiInstrument = #"tremolo strings" \melody
          \set Staff.midiInstrument = #"pizzicato strings" \melody
          \set Staff.midiInstrument = #"orchestral harp" \melody
          \set Staff.midiInstrument = #"timpani" \melody
          \set Staff.midiInstrument = #"string ensemble 1" \melody
          \set Staff.midiInstrument = #"string ensemble 2" \melody
          \set Staff.midiInstrument = #"synthstrings 1" \melody
          \set Staff.midiInstrument = #"synthstrings 2" \melody
          \set Staff.midiInstrument = #"choir aahs" \melody
          \set Staff.midiInstrument = #"voice oohs" \melody
          \set Staff.midiInstrument = #"synth voice" \melody
          \set Staff.midiInstrument = #"orchestra hit" \melody
          \set Staff.midiInstrument = #"trumpet" \melody
          \set Staff.midiInstrument = #"trombone" \melody
          \set Staff.midiInstrument = #"tuba" \melody
          \set Staff.midiInstrument = #"muted trumpet" \melody
          \set Staff.midiInstrument = #"french horn" \melody
          \set Staff.midiInstrument = #"brass section" \melody
          \set Staff.midiInstrument = #"synthbrass 1" \melody
          \set Staff.midiInstrument = #"synthbrass 2" \melody
          \set Staff.midiInstrument = #"soprano sax" \melody
          \set Staff.midiInstrument = #"alto sax" \melody
          \set Staff.midiInstrument = #"tenor sax" \melody
          \set Staff.midiInstrument = #"baritone sax" \melody
          \set Staff.midiInstrument = #"oboe" \melody
          \set Staff.midiInstrument = #"english horn" \melody
          \set Staff.midiInstrument = #"bassoon" \melody
          \set Staff.midiInstrument = #"clarinet" \melody
          \set Staff.midiInstrument = #"piccolo" \melody
          \set Staff.midiInstrument = #"flute" \melody
          \set Staff.midiInstrument = #"recorder" \melody
          \set Staff.midiInstrument = #"pan flute" \melody
          \set Staff.midiInstrument = #"blown bottle" \melody
          \set Staff.midiInstrument = #"shakuhachi" \melody
          \set Staff.midiInstrument = #"whistle" \melody
          \set Staff.midiInstrument = #"ocarina" \melody
          \set Staff.midiInstrument = #"lead 1 (square)" \melody
          \set Staff.midiInstrument = #"lead 2 (sawtooth)" \melody
          \set Staff.midiInstrument = #"lead 3 (calliope)" \melody
          \set Staff.midiInstrument = #"lead 4 (chiff)" \melody
          \set Staff.midiInstrument = #"lead 5 (charang)" \melody
          \set Staff.midiInstrument = #"lead 6 (voice)" \melody
          \set Staff.midiInstrument = #"lead 7 (fifths)" \melody
          \set Staff.midiInstrument = #"lead 8 (bass+lead)" \melody
          \set Staff.midiInstrument = #"pad 1 (new age)" \melody
          \set Staff.midiInstrument = #"pad 2 (warm)" \melody
          \set Staff.midiInstrument = #"pad 3 (polysynth)" \melody
          \set Staff.midiInstrument = #"pad 4 (choir)" \melody
          \set Staff.midiInstrument = #"pad 5 (bowed)" \melody
          \set Staff.midiInstrument = #"pad 6 (metallic)" \melody
          \set Staff.midiInstrument = #"pad 7 (halo)" \melody
          \set Staff.midiInstrument = #"pad 8 (sweep)" \melody
          \set Staff.midiInstrument = #"fx 1 (rain)" \melody
          \set Staff.midiInstrument = #"fx 2 (soundtrack)" \melody
          \set Staff.midiInstrument = #"fx 3 (crystal)" \melody
          \set Staff.midiInstrument = #"fx 4 (atmosphere)" \melody
          \set Staff.midiInstrument = #"fx 5 (brightness)" \melody
          \set Staff.midiInstrument = #"fx 6 (goblins)" \melody
          \set Staff.midiInstrument = #"fx 7 (echoes)" \melody
          \set Staff.midiInstrument = #"fx 8 (sci-fi)" \melody
          \set Staff.midiInstrument = #"sitar" \melody
          \set Staff.midiInstrument = #"banjo" \melody
          \set Staff.midiInstrument = #"shamisen" \melody
          \set Staff.midiInstrument = #"koto" \melody
          \set Staff.midiInstrument = #"kalimba" \melody
          \set Staff.midiInstrument = #"bagpipe" \melody
          \set Staff.midiInstrument = #"fiddle" \melody
          \set Staff.midiInstrument = #"shanai" \melody
          \set Staff.midiInstrument = #"tinkle bell" \melody
          \set Staff.midiInstrument = #"agogo" \melody
          \set Staff.midiInstrument = #"steel drums" \melody
          \set Staff.midiInstrument = #"woodblock" \melody
          \set Staff.midiInstrument = #"taiko drum" \melody
          \set Staff.midiInstrument = #"melodic tom" \melody
          \set Staff.midiInstrument = #"synth drum" \melody
          \set Staff.midiInstrument = #"reverse cymbal" \melody
          \set Staff.midiInstrument = #"guitar fret noise" \melody
          \set Staff.midiInstrument = #"breath noise" \melody
          \set Staff.midiInstrument = #"seashore" \melody
          \set Staff.midiInstrument = #"bird tweet" \melody
          \set Staff.midiInstrument = #"telephone ring" \melody
          \set Staff.midiInstrument = #"helicopter" \melody
          \set Staff.midiInstrument = #"applause" \melody
          \set Staff.midiInstrument = #"gunshot" \melody
        }
      >>
      \midi { }
    }

## Réglage de l’égalisation par défaut des instruments MIDI

L’égaliseur basique peut être modifié par la définition d’une nouvelle procédure Scheme `instrumentEqualizer` au sein du contexte `Score`. Cette procédure prend en unique argument le nom d’un instrument MIDI et renverra une paire de fractions correspondant aux minimum et maximum de volume alloué à cet instrument.

Dans l’exemple suivant sont réglés les volumes relatifs de la flûte et de la clarinette.

    #(define my-instrument-equalizer-alist '())

    #(set! my-instrument-equalizer-alist
      (append
        '(
          ("flute" . (0.7 . 0.9))
          ("clarinet" . (0.3 . 0.6)))
        my-instrument-equalizer-alist))

    #(define (my-instrument-equalizer s)
      (let ((entry (assoc s my-instrument-equalizer-alist)))
        (if entry
          (cdr entry))))

    \score {
      <<
        \new Staff {
          \key g \major
          \time 2/2
          \set Score.instrumentEqualizer = #my-instrument-equalizer
          \set Staff.midiInstrument = "flute"
          \new Voice \relative {
            r2 g''\mp g fis~
            4 g8 fis e2~
            4 d8 cis d2
          }
        }
        \new Staff {
          \key g \major
          \set Staff.midiInstrument = "clarinet"
          \new Voice \relative {
            b'1\p a2. b8 a
            g2. fis8 e
            fis2 r
          }
        }
      >>
      \layout { }
      \midi {  }
    }

#### LilyPond — Morceaux choisis v2.24.4 (branche stable).