pitched and unpitched instrum. in einem Staff/Midi Track

Begonnen von Arnold, Freitag, 24. März 2023, 17:12

« vorheriges - nächstes »

Arnold

Hallo,

eine kombinierte Notenzeile für Instrumente mit definierter und undefinierter Tonhöhe (im Wechsel) kann ich zwar setzen, aber die Midi-Ausgabe passt dann (mit meiner Einstellung) nicht.
Häufige Kombinationen sind »Drumset & Glockenspiel« oder »Pauken & gr. u. kl. Trommel u. Triangel«.
Das PDF bekomme ich hin, indem ich
  • \accepts DrumVoice im Staff angebe
  • \context - Wechsel zwischen Voice und Drumvoice in meiner Stimme einbaue
.
Aber in der MIDI-Ausgabe sollte dann - beides in einem MIDI-Track, da in einem StaffPerformer - für die Drumms der 10. MIDI-Channel (Nr. 9 ab Null gezählt), für das Melodieinstrument in diesem Beispiel der 3. MIDI-Channel (Nr. 2 ab Null gezählt, da im 3. Staff-Performer) benutzt werden. Tatsächlich kommt aber alles auf einem MIDI-Channel heraus, je nachdem, was zuerst erschien.

Hier mein Beispiel-Code:\version "2.22.0"
%auch version "2.24.1" % mit Guile 2.2
%auch version "2.25.1" % mit Guile 2.2

% postprocessing on a Raspberry PI:
%POSTPROCESS: midi2html -o ${BASENAME}.html -w ${BASENAME}.midi ${BASENAME}-1.midi
%POSTPROCESS: wkhtmltopdf ${BASENAME}.html ${BASENAME}_midi.pdf

Dr = \drummode { bd4 hh8 tri bd4 sn }
Mel = { c''4 <c'' e''> <d'' g''> <e'' c'''> }

DrumLine⁰  = { \Dr R1*3 \Dr }
MelLine⁰   = { R1*2 \Mel R1*2 }
CombiLine⁰ = {
  \context DrumVoice = "Dr1" { s4*0^"Drumset"
  \clef percussion  \set Score.midiInstrument = "drums"         \Dr
  }
  R1
  \context Voice = "V1" { s4*0^"Glockenspiel"
  \clef treble      \set Score.midiInstrument = "glockenspiel"  \Mel
  }
  R1
  \context DrumVoice = "Dr1" { s4*0^"Drumset"
  \clef percussion  \set Score.midiInstrument = "drums"         \Dr
  }
}

DrumLine¹  = { R1*2 \Dr R1*2 }
MelLine¹   = { \Mel R1*3 \Mel }
CombiLine¹ = {
  \context Voice = "V1" { s4*0^"Glockenspiel"
  \clef treble      \set Score.midiInstrument = "glockenspiel"  \Mel
  }
  R1
  \context DrumVoice = "Dr1" { s4*0^"Drumset"
  \clef percussion  \set Score.midiInstrument = "drums"         \Dr
  }
  R1
  \context Voice = "V1" { s4*0^"Glockenspiel"
  \clef treble      \set Score.midiInstrument = "glockenspiel"  \Mel
  }
}

\paper {
  indent = 25 \mm
}

\score {
  <<
    \new StaffGroup <<
      \new Staff \with {
        instrumentName = "Glockenspiel"
        midiInstrument = "glockenspiel"
      } {
        \MelLine⁰
      }
      \new DrumStaff \with {
        instrumentName = "Percussion"
      } {
        \DrumLine⁰
      }
    >>
    \new Staff = "Combi" \with {
      instrumentName = \markup \column { "Glockenspiel" "& Percussion" }
      \accepts DrumVoice
    } {
      \CombiLine⁰
    }
  >>
  \layout {}
  \midi {}
}

\score {
  <<
    \new StaffGroup <<
      \new Staff \with {
        instrumentName = "Glockenspiel"
        midiInstrument = "glockenspiel"
      } {
        \MelLine¹
      }
      \new DrumStaff \with {
        instrumentName = "Percussion"
      } {
        \DrumLine¹
      }
    >>
    \new Staff = "Combi" \with {
      instrumentName = \markup \column { "Glockenspiel" "& Percussion" }
      \accepts DrumVoice
    } {
      \CombiLine¹
    }
  >>
  \layout {}
  \midi {}
}

Und im angehängten PDF die »Lesbar-Machung« der MIDI-Datei.
Der Quelltext der »Lesbar-Machung« ist in angehängter ZIP-Datei zu finden, falls jemand Interesse an dem Programm hat.

Kann man nur durch Konfiguration im Lilypond das gewünschte Ergebnis auch in der MIDI-Datei erzeugen?
Oder müßte dazu der Quellcode (gar die C++-Anteile) geändert werden?
Ist das als Bug anzusehen?

Oder nur ein »currently unsupported feature, perhaps implemented in the far future«?

Mit freundlichen Grüßen

Arnold Wendl

Arnold

Und noch eine Fortsetzung:

Ich definiere je eine Voice und eine DrumVoice im Combi-Staff, entferne den Staff_performer aus dem Staff und setze je einen in die beiden *Voice.
Dann habe ich immer noch Probleme mit:
  • keep-alive des nicht zu Anfang gestarteten Voices
  • temporären Voices
Die Farben veranschaulichen es - beides schlägt voll auf die MIDI-Ausgabe durch.

Die zugehörigen Fragen etwas technischer formuliert:
  • Wie hält man ein Voice über die gesamte Länge seines Staff am Leben?
  • Wie »vererbt« man einen »Staff_performer im Voice-Kontext« an seine »Kind-Voices«?

Hier das Beispiel:
\version "2.24.1" % mit Guile 2.2 auf Raspberry PI
%auch version "2.25.1" % mit Guile 2.2

Dr = \drummode { bd4 hh8 tri bd4 sn }
Mel = { c''4 << { e''8 f'' } \\ { c''4 } >> <d'' g''>4 <e'' c'''> }

DrumLine  = \repeat volta 4 { R1*2 \Dr R1*3 \Dr R1 }
MelLine  = \repeat volta 4 { \Mel R1*3 \Mel R1*3 }
CombiLine = \repeat volta 4 {
  \context Voice = "melodic" { s4*0^"Glockenspiel"
  \clef treble      \Mel
  }
  R1
  \context DrumVoice = "drum" { s4*0^"Drumset"
  \clef percussion  \Dr
  }
  R1
  \context Voice = "melodic" { s4*0^"Glockenspiel"
  \clef treble      \Mel
  }
  R1
  \context DrumVoice = "drum" { s4*0^"Drumset"
  \clef percussion  \Dr
  }
  R1
}

Musik = <<
    % \set Score.midiChannelMapping = #'instrument
    \new StaffGroup <<
      \new Staff \with {
        instrumentName = "Glockenspiel"
        midiInstrument = "glockenspiel"
      } {
        \MelLine
      }
      \new DrumStaff \with {
        instrumentName = "Percussion"
      } {
        \DrumLine
      }
    >>
    \new Staff = "Combi" \with {
      instrumentName = \markup \column { "Glockenspiel" "& Percussion" }
      \accepts DrumVoice
      \remove Staff_performer
      % \consists Keep_alive_together_engraver
    } {
      << \new Voice = "melodic" \with {
          \consists Staff_performer
          midiInstrument = "glockenspiel"
          \override NoteHead.color = #blue
          \override Stem.color = #blue
          \override Beam.color = #blue
        } {
          #(skip-of-length CombiLine)    % Andere Methode für ein KeepAlive?
                                          % Diese Länge vergrößert sich nicht
                                          % bei \unfoldRepeats!
        }
        \new DrumVoice = "drum" \with {
          \consists Staff_performer
          midiInstrument = "drums"              % unverzichtbar!
          \override NoteHead.color = #darkred
          \override Stem.color = #darkred
          \override Beam.color = #darkred
        } {
          #(skip-of-length CombiLine)    % Andere Methode für ein KeepAlive?
                                          % Diese Länge vergrößert sich nicht
                                          % bei \unfoldRepeats!
        }
        \CombiLine
      >>
    }
  >>

\paper {
  indent = 25 \mm
}
 
\score {
  \Musik
  \layout {}
  \midi {}
}

\score {
  \unfoldRepeats \Musik
  \layout {}
  \midi {}
}

Mit freundlichen Grüßen (und viel Spaß beim Grübeln und Kopfzerbrechen)

Arnold

Arnold

So, jetzt habe ich noch eine Möglichkeit mit zwei Notenzeilen (und zwei Staff_performer) gefunden, aber einer einzigen, sequenziellen Definition:
  • Die unterschiedlichen Abschnitte mit je einem Tag versehen, z. Bsp. #'Melo und #'Perc - aber bei \repeat-Abschnitten nur innerhalb dieser, damit später das \unfold gelingt
  • Auch die Schlüsselwechsel außerhalb dieser markierten Bereiche einfügen.
  • Mit einer (selbst erstellten) Music-Map-Routine dann zwei Ableitung daraus erzeugen, bei denen jeweils einer der beiden Anteile durch Skips ersetzt wird.
  • Nun können ein Staff und ein DrumStaff übereinander gedruckt werden (deswegen auch die \clef-Angaben in beiden Extrakten) - OneStaff macht's möglich (auch wenn ich darüber im Notationshandbuch nichts gefunden habe).
Im folgenden Beispiel werden die beiden Extraktions-Zeilen etwas kleiner gedruckt, und in der Zusammenführung die Noten je nach Quelle (aus welchem der beiden Unter-Staff im One-Staff) unterschiedlich gefärbt.
\version "2.24.1" % mit Guile 2.2

#(define ((tag-to-skip sym) mus)
  (if (ly:music? mus)
   (let ((mtype (ly:music-property mus 'name))
         (mtag (ly:music-property mus 'tags)))
    (if (memq sym mtag)
     (let ((skm (skip-of-length mus)))
      (if (eq? mtype 'SequentialMusic)
       (make-music 'SequentialMusic
        'tags mtag
        'elements (list skm))
       skm))
     mus))
   mus))

Dr = \drummode { bd4 hh8 tri bd4 sn }
Mel = { c''4 << { e''8 f'' } \\ { c''4 } >> <d'' g''>4 <e'' c'''> }

CombiLine = {
  \clef treble
  \repeat volta 4 {
    \tag #'Melo {
      \Mel
    }
    \clef percussion
    \tag #'Perc {
      R1
      \Dr
    }
    \clef treble
    \tag #'Melo {
      R1
      \Mel
    }
    \clef percussion
    \tag #'Perc {
      R1
      \Dr
    } 
  } \alternative {
    \tag #'Melo {
      R1
    }
    \tag #'Perc \drummode {
      <bd hh>2 r
    }
  }
}

PercExtract = \musicMap #(tag-to-skip 'Melo) \CombiLine
MeloExtract = \musicMap #(tag-to-skip 'Perc) \CombiLine

Musik = <<
    \new StaffGroup <<
      \new Staff \with {
        instrumentName = \markup \column { "Glockenspiel-" "extrakt" }
        midiInstrument = "glockenspiel"
        \magnifyStaff #(magstep -4)
      } {
        \MeloExtract
      }
      \new DrumStaff \with {
        instrumentName = \markup \column { "Percussions-" "extrakt" }
        \magnifyStaff #(magstep -4)
      } {
        \PercExtract
      }
    >>
    \new OneStaff \with {
      instrumentName = \markup \column { "Glockenspiel" "& Percussion" }
      \consists Instrument_name_engraver
    } <<
      \new Staff \with {
        midiInstrument = "glockenspiel"
        \override NoteHead.color = #blue
        \override Stem.color = #blue
        \override Beam.color = #blue
        \override Rest.color = #blue
        \override MultiMeasureRest.color = #blue
        \override MultiMeasureRestNumber.color = #blue
      } \new Voice {
        \MeloExtract
      }
      \new DrumStaff \with {
        \override NoteHead.color = #darkred
        \override Stem.color = #darkred
        \override Beam.color = #darkred
        \override Rest.color = #darkred
        \override MultiMeasureRest.color = #darkred
        \override MultiMeasureRestNumber.color = #darkred
      } \new DrumVoice {
        \PercExtract
      }
    >>
  >>

\paper {
  indent = 25 \mm
}
 
\score {
  \Musik
  \layout {}
  \midi {}
}

\score {
  \unfoldRepeats \Musik
  \layout {}
  \midi {}
}

Wäre das etwas für die Snippets?
Wäre solch ein »Tagged sections to skips«-Filter etwas für die LILYPOND-Standardfunktionen?
Oder wäre gar ein (aufwändigerer) Filter, der die beiden Note-Event-Arten selbständig voneinander unterscheidet, sinnvoll?

Arnold.