Allgemein > Allgemeine Diskussion
\score dynamisch erzeugen
RobUr:
Hallo Manuel!
--- Zitat von: derburn ---Gibt es eigtl. ein Pendant zu \displayMusic, das einem den generierten Code auch für Scores anzeigt?
--- Ende Zitat ---
Reicht dir
--- Code: ---\score {
\displayMusic {
<<
\myDrumScore
>>
}
\layout {
\context {
\DrumStaff
\remove Clef_engraver
\override Stem #'direction = #UP
\override Beam #'positions = #'(3.5 . 3.5)
}
}
}
--- Ende Code ---
? Aufpassen, dass der \layout-Block nicht mit eingeklammert wird.
--- Zitat von: derburn ---… vorausgesetzt, ich bekomme noch das Problem in den Griff, dass ich die Anzahl DrumStaffs per Listenübergabe generiere.
--- Ende Zitat ---
Oh, keine Ahnung, wie das in Scheme umgesetzt wird (sicher denkst du an dynamisch generierte [eindimensionale] Arrays wie in Java, PHP & Co.?). Ein Ansatz wäre vielleicht die Simulation von Schleifen durch rekursive Funktionsaufrufe. Oder du schaust dir die Sache mit Paaren und Listen genauer an.
Grüße, Robert
derburn:
Hi Robert,
leider reicht Dein Vorschlag nicht aus, da es genau der Code aus der Score und dem Layout ist, der mich interessiert...
Trotzdem danke!
Ich bin derzeit dran, mir die Listen in Scheme genauer anzusehen, und bin auf Folgendes gestoßen:
--- Code: ---#(define displayList
(lambda (ls)
(if (null? ls)
(newline)
(begin
(display (car ls))
(newline)
(displayList (cdr ls))))))
#(displayList '())
#(displayList '(I'm a loser baby so why don't you kill me))
#(displayList '(bla blubb))
--- Ende Code ---
Das erzeugt die Ausgabe:
I'm
a
loser
baby
so
why
don't
you
kill
me
bla
blubb
Das ist genau der Rekursionsansatz: car gibt einem das erste Listenelement zurück, cdr den Rest der Liste.
Ruft man sich also immer wieder selbst auf mit dem Übergabeparameter cdr, dann schleift man sich
(meines Erachtens höchst umständlich) durch die Liste und kann dann mit jedem einzelnen Listenelement
irgendwas anstellen - in diesem Fall einfach nur ausgeben.
Das ist dann die Zeile "display (car ls)".
Allerdings sind schon meine Versuche gescheitert, die Liste als einen zusammengehängten String zurückzugeben,
also das Pendant zu der PHP- bzw. perl-Funktion "join". Ich versuche, mit "let" einen Leerstring zu definieren und
daran jedes Listenelement anzuhängen, aber schon da passen dem Compiler entweder die Aufrufparameter nicht
oder das Ergebnis ist immer das, was bei der Abfrage "(null? ls)" im true-Falle steht.
Mal sehen, wohin das alles führt...
Ich geb nicht auf und bin natürlich weiterhin für alle Tipps dankbar! ;)
Viele liebe Grüße,
Manuel
derburn:
Hallöchen allerseits,
mittlerweile hätte ich eine Lösung, die zwar ziemlich unelegant ist, aber doch sehr wirksam.
Ausgehend von meinem ursprünglichen Funktionsvorschlag fiel mir auf, dass die Funktion tatsächlich eine Score erzeugt,
wenn man "\score" durch "\new Score" ersetzt. Vermutlich wird bei \new Score gerade erst das Objekt erzeugt, während
\score ein bereits existierendes Objekt voraussetzt.
Um das Problem mit mehreren Staffs pro Score zu lösen, kann man sich einfach Scores mit jeweils 1,2,3...n Staffs definieren.
Wirklich nicht schön, aber effektiv.
Hier ein Beispielcode:
--- Code: ---\version "2.13.51"
myDrumScore = #(define-music-function (parser location musicOne beamsOne) (ly:music? pair?)
#{
\new Score <<
\new DrumStaff \with {
\remove Clef_engraver
\override Stem #'direction = #UP
\override Beam #'positions = #$beamsOne
\override StaffSymbol #'staff-space = #'1.15
} << { $musicOne } >>
>>
#})
myDrumScoreTwo = #(define-music-function (parser location musicOne beamsOne musicTwo beamsTwo) (ly:music? pair? ly:music? pair?)
#{
\new Score <<
\new DrumStaff \with {
\remove Clef_engraver
\override Stem #'direction = #UP
\override Beam #'positions = #$beamsOne
\override StaffSymbol #'staff-space = #'1.15
} << { $musicOne } >>
\new DrumStaff \with {
\remove Clef_engraver
\override Stem #'direction = #UP
\override Beam #'positions = #$beamsTwo
\override StaffSymbol #'staff-space = #'1.15
} << { $musicTwo } >>
>>
#})
myDrumScoreThree = #(define-music-function (parser location musicOne beamsOne musicTwo beamsTwo musicThree beamsThree) (ly:music? pair? ly:music? pair? ly:music? pair?)
#{
\new Score <<
\new DrumStaff \with {
\remove Clef_engraver
\override Stem #'direction = #UP
\override Beam #'positions = #$beamsOne
\override StaffSymbol #'staff-space = #'1.15
} << { $musicOne } >>
\new DrumStaff \with {
\remove Clef_engraver
\override Stem #'direction = #UP
\override Beam #'positions = #$beamsTwo
\override StaffSymbol #'staff-space = #'1.15
} << { $musicTwo } >>
\new DrumStaff \with {
\remove Clef_engraver
\override Stem #'direction = #UP
\override Beam #'positions = #$beamsThree
\override StaffSymbol #'staff-space = #'1.15
} << { $musicThree } >>
>>
#})
eins = \drummode { bda8. bda16 sn8. bda16 r16 bda8 bda16 sn4 }
\displayMusic { <<
\myDrumScoreThree { \eins } #'(2.5 . 2.5)
{ \eins } #'(3.5 . 3.5)
{ \eins } #'(4.5 . 4.5)
>> }
\layout {
indent = 1\cm
\context {
\Score
\remove "System_start_delimiter_engraver"
} % context
} % layout
--- Ende Code ---
Im Beispiel kann man die DrumStaffs sogar rudimentär konfigurieren.
Außerdem zeigt \displayMusic den ganzen Score-Inhalt an.
Warum der \layout-Block nicht in die Score selbst eingebaut werden kann, weiß ich nicht. (Fehler: 'unexpected \layout').
Wenn man obige 'myDrumScore...'-Definitionen auslagert, kann man damit eigentlich recht bequem arbeiten.
Sehr viel schöner wäre es natürlich, wenn man die ganzen Definitionen nicht per Hand machen müsste, sondern einfach eine
Liste mit Musik & sonstiger Konfiguration pro DrumStaff übergeben könnte...
Solange dies nicht gelingt, werde ich wohl obigen Vorschlag nutzen...
Ich hoffe, Ihr könnt das gebrauchen... :)
Viele liebe Grüße,
Manuel
Navigation
[0] Themen-Index
[*] Vorherige Sete
Zur normalen Ansicht wechseln