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