Allgemein > Allgemeine Diskussion
Neues Code Snippet - Akkordeon Standard Stradella Basssystem zeichnen
fugenkomponist:
Ja, in Musikfunktionen geht das, bei markup-commands anscheinend nicht (bzw. falls doch, weiß ich nicht, wie). Aber wie wärs damit?
--- Code: ---draw-acc-bass-default =
\markup \draw-acc-bass #1 #(+ dm-circle dm-circle 0.2) #dm-circle
\bookpart {
\markup {
\column {
\vspace #1 "Draw an Accordion Stradella Bass with standard distances"
\vspace #2 \translate #'(0 . 0 ) \scale #'(0.75 . 0.75)
\draw-acc-bass-default
}
}
}
\bookpart {
\markup {
\column {
\vspace #1 "Draw an Accordion Stradella Bass with some funny distances"
\vspace #2 \translate #'(10 . 0 ) \scale #'(0.9 . 0.9)
\draw-acc-bass #0.8 #(+ dm-circle dm-circle -1) #(* -0.5 dm-circle)
}
}
}
--- Ende Code ---
Edit: Davon abgesehen ist das ja auch kein realer Anwendungsfall, das Diagramm mehr als einmal drucken zu wollen und dann auch noch mit verschiedenen Maßen. Also eigentlich kein Problem.
Manuela:
--- Zitat von: fugenkomponist am Sonntag, 28. August 2016, 13:55 ---Edit: Davon abgesehen ist das ja auch kein realer Anwendungsfall, das Diagramm mehr als einmal drucken zu wollen und dann auch noch mit verschiedenen Maßen. Also eigentlich kein Problem.
--- Ende Zitat ---
Du hast recht, das wäre nur für Demonstrationszwecke gewesen. Trotzdem verstehe ich nicht, wieso die Zuordnung den davor stehenden Code beeinflusst. Ich habe eigens zwei bookparts angelegt in der Hoffnung, dass Lilypond die Umgebungen irgendwie trennt. Hat nix genutzt.
Und immer wieder falle ich darauf rein, dass in den Versionen 2.18.xx "parser location" in musicfunktionen verwendet werden muss.
Ich hoffe, das hier kompiliert:
--- Code: ---\version "2.18.0"
\language "deutsch"
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Drawing a standard Stradella Accordion Bass
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% defining circle diameter and distances
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#(define dm-circle 3.3) %% the radius of the buttons
#(define col-dist (+ (* 2 dm-circle) 0.1)) %% distance between 2 button columns, default: 2*radius plus a little
#(define row-dist 1) %% the vertical distance of the button rows, check out smaller values
#(define h-shift dm-circle) %% defines much a button row is shifted horizontally relativ to the next lower row
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% pitch+music functions and definitions
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#(define (pitch-equals? p1 p2)
;(write-me "pitch-equals? ----------------------------> " (list p1 p2))
(and
(= (ly:pitch-alteration p1) (ly:pitch-alteration p2))
(= (ly:pitch-notename p1) (ly:pitch-notename p2))))
#(define (note-name->german-string pitch)
(define (pitch-alteration-semitones pitch)
(inexact->exact (round (* (ly:pitch-alteration pitch) 2))))
(let* ((name (ly:pitch-notename pitch))
(alt-semitones (pitch-alteration-semitones pitch))
(n-a (if (equal? (cons name alt-semitones) '(6 . -1))
(cons 7 alt-semitones)
(if (equal? (cons name alt-semitones) '(6 . -2))
(cons 7 -2)
(cons name alt-semitones)
)
)))
(string-append
(vector-ref #("C" "D" "E" "F" "G" "A" "H" "B") (car n-a))
(let ((alteration (/ (cdr n-a) 2)))
;(write-me "alteration: -------------> " alteration)
(cond
((and (= alteration FLAT) (= (car n-a) 7))
"")
((and (= alteration DOUBLE-FLAT) (= (car n-a) 7)) ;; we write Heses as Bes because it is shorter
"es")
((and (= alteration FLAT) (or (= (car n-a) 5) (= (car n-a) 2) ))
"s")
((= alteration FLAT)
"es")
((and (= alteration DOUBLE-FLAT) (or (= (car n-a) 5)(= (car n-a) 2)))
"ses")
((= alteration DOUBLE-FLAT)
"eses")
((= alteration SHARP)
"is")
((= alteration DOUBLE-SHARP)
"isis")
(else ""))))))
#(define Q-circle ;; define circle of fifths as pitchlist
(list
(ly:make-pitch 0 6 DOUBLE-FLAT) ;; heses
(ly:make-pitch 0 3 FLAT) ;; fes
(ly:make-pitch 0 0 FLAT) ;; ces
(ly:make-pitch 0 4 FLAT) ;; ges
(ly:make-pitch 0 1 FLAT) ;; des
(ly:make-pitch 0 5 FLAT) ;; as
(ly:make-pitch 0 2 FLAT) ;; es
(ly:make-pitch 0 6 FLAT) ;; b
(ly:make-pitch 0 3 0) ;; f
(ly:make-pitch 0 0 0) ;; c
(ly:make-pitch 0 4 0) ;; g
(ly:make-pitch 0 1 0) ;; d
(ly:make-pitch 0 5 0) ;; a
(ly:make-pitch 0 2 0) ;; e
(ly:make-pitch 0 6 0) ;; h
(ly:make-pitch 0 3 SHARP) ;; fis
(ly:make-pitch 0 0 SHARP) ;; cis
(ly:make-pitch 0 4 SHARP) ;; gis
(ly:make-pitch 0 1 SHARP) ;; dis
(ly:make-pitch 0 5 SHARP) ;; ais
))
#(define Terz-circle ;; define terzbasses
(list
(ly:make-pitch 0 1 FLAT) ;; des
(ly:make-pitch 0 5 FLAT) ;; as
(ly:make-pitch 0 2 FLAT) ;; es
(ly:make-pitch 0 6 FLAT) ;; b
(ly:make-pitch 0 3 0) ;; f
(ly:make-pitch 0 0 0) ;; c
(ly:make-pitch 0 4 0) ;; g
(ly:make-pitch 0 1 0) ;; d
(ly:make-pitch 0 5 0) ;; a
(ly:make-pitch 0 2 0) ;; e
(ly:make-pitch 0 6 0) ;; h
(ly:make-pitch 0 3 SHARP) ;; fis
(ly:make-pitch 0 0 SHARP) ;; cis
(ly:make-pitch 0 4 SHARP) ;; gis
(ly:make-pitch 0 1 SHARP) ;; dis
(ly:make-pitch 0 5 SHARP) ;; ais
(ly:make-pitch 0 2 SHARP) ;; eis
(ly:make-pitch 0 6 SHARP) ;; his
(ly:make-pitch 0 4 0) ;; g
(ly:make-pitch 0 1 0) ;; d
))
#(define (get-Index p)
(list-index (lambda(x)(pitch-equals? x p)) Q-circle))
#(define (get-Name p)
(note-name->german-string p))
#(define (DMSV n)
;; n=0: "Dur-"
;; n=1: Moll
;; n=2: Sept
;; n=3: Dim
(cond
( (= n 0) "")
((= n 1) "m")
((= n 2) "7")
((= n 3) "o")
))
#(define (ChordName->markup p n)
(let* ((m (- n 2))
(bname (string-downcase (get-Name p)))
(cname (string-capitalize bname))
(i (get-Index p))
(terz (get-Name (list-ref Terz-circle i)))
(simple
(cond
((>= n 2)
bname)
((= n 1)
cname)
(else terz)
))
(hoch
(cond
((>= n 3) (DMSV m))
(else ""))))
(make-concat-markup
(list
(make-simple-markup simple)
(make-smaller-markup
(make-raise-markup 0.6 (make-simple-markup hoch)))))))
rowDist=#(define-scheme-function (parser location dist)
(number?)
(set! row-dist dist))
colDist=#(define-scheme-function (parser location dist)
(number?)
(set! col-dist dist))
slope=#(define-scheme-function (parser location dist)
(number?)
(set! h-shift dist))
#(define-markup-command (draw-acc-bass layout props)()
#:properties ((font-size 0) (thickness 2.5) (offset 3.5))
(let* ((my-circle (make-circle-stencil dm-circle 0.1 #f))
; (cir-dist (+ (* 2 dm-circle) xdist)) ;; dist: how much distance between two cirles
(thick (* (magstep font-size) (ly:output-def-lookup layout 'line-thickness)))
(underline-thick (* thickness thick))
(y (* thick (- offset)))
)
;procedure body
(apply ly:stencil-add
empty-stencil
(map
(lambda (z)
(ly:stencil-translate
(apply ly:stencil-add
empty-stencil
(map
(lambda (x)
(let* ((m
(interpret-markup layout props
(ChordName->markup (list-ref Q-circle x) z)))
(myx (ly:stencil-extent m X))
(xstart (car myx))
(xend (cdr myx))
(breite (- xend xstart))
(myy (ly:stencil-extent m Y))
(hoch (- (cdr myy) (car myy))))
(ly:stencil-translate-axis
(ly:stencil-add
(ly:stencil-translate-axis
(ly:stencil-translate-axis
(ly:stencil-add
(if (= 0 z)
(make-line-stencil underline-thick xstart y xend y)
empty-stencil)
m)
(- 0 (/ breite 2)) X)
(- 0 (/ hoch 2)) Y) ;; chordname plus underline if terzbass
my-circle) ;; circled chordname
(* x col-dist) X)))
(iota 20 0)))
(cons (* z h-shift) (* z col-dist (* row-dist -1)))))
(iota 6)))))
\bookpart {
\rowDist #1
\colDist #(+ dm-circle dm-circle 0.2)
\slope #dm-circle
\markup {
\column {
\vspace #1 "Draw an Accordion Stradella Bass with standard distances"
\vspace #2 \translate #'(0 . 0 ) \scale #'(0.75 . 0.75) \draw-acc-bass
}
}
}
\bookpart {
\rowDist #0.8
\colDist #(+ dm-circle dm-circle -1)
\slope #(* -0.5 dm-circle)
\markup {
\column {
\vspace #1 "Draw an Accordion Stradella Bass with some funny distances"
\vspace #2 \translate #'(10 . 0 ) \scale #'(0.9 . 0.9) \draw-acc-bass
}
}
}
--- Ende Code ---
harm6:
Hallo Manuela,
ich schrieb früher schon:
Generell ist das destruktive neu setzen einer Variable durchaus mit Vorsicht zu geniessen...
Denn es funktioiniert nicht immer.
In diesem Fall scheint es so zu sein, daß das markup-command die neu gesetzten Werte erst zu sehen bekommt nachdem der LilyPond-parser sie endgültig zugeordnet hat, im Unterschied zu Funktionen. Betrachte:
--- Code: ---%% markup-command
#(define-markup-command (tst layout props)()
(write-me "foo:\t" foo)
empty-stencil)
#(define foo 1)
\markup \tst
#(set! foo 1.1)
\markup \tst
%% music-function
testII =
#(define-music-function (parser location)()
(write-me "testII-bla:\t" bla)
#{#})
#(define bla 2)
\testII
#(set! bla 2.1)
\testII
--- Ende Code ---
Auch im log sieht man, daß die Anzeige im markup-command viel später erscheint als die der Funktion.
Darüber hinaus ist das setzen von top-level-Variablen und späterem reset auch nicht LilyPondisch.
Für sowas benutzt man context-, grob-, markup-properties oder optionale Argumente.
Auch ist ein markup-command ohne Argumente immer befremdlich, imho
Verwende doch define-scheme-function, da kannst Du auch optionale Argumente unterbringen, zumindest in beschränktem Umfang.
Gruß,
Harm
Manuela:
Ich habe das Snippet jetzt umgeschrieben. Es werden internationale Bezeichnungen verwendet, außerdem kann ein Button durch Angabe von Zeilen- und Spaltennummer eingefärbt werden. Ursprünglich wollte ich eine Tonhöhe für die Spaltennummer verwenden, aber ich kriege es nicht gebacken, der Markup-Funktion einen Pitch als Parameter zu übergeben (mit define-scheme-music funktioniert es).
--- Code: ---\version "2.18.0"
\language "deutsch"
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Drawing a standard Stradella Accordion Bass
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% pitch+music functions and definitions
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#(define (pitch-equals? p1 p2)
(and
(= (ly:pitch-alteration p1) (ly:pitch-alteration p2))
(= (ly:pitch-notename p1) (ly:pitch-notename p2))))
#(define (note-name->string pitch)
(let* ((a (ly:pitch-alteration pitch))
(n (ly:pitch-notename pitch)))
(make-concat-markup
(list
(make-simple-markup
(vector-ref #("C" "D" "E" "F" "G" "A" "B") n))
(if (= a 0)
(make-line-markup (list empty-markup))
(make-line-markup
(list
(alteration->text-accidental-markup a)
(make-hspace-markup 0.1))))))))
#(define (DMSV n)
(cond
((= n 2) "M")
((= n 3) "m")
((= n 4) "7")
((= n 5) "o")
(else "")))
#(define (ChordName->markup p n)
(let* ((i (get-Index p))
(terz (note-name->string (list-ref Terz-circle i)))
(bas (note-name->string (list-ref Q-circle i)))
(simple
(if (= n 0) terz bas)))
(make-concat-markup
(list
simple
(make-smaller-markup
(make-raise-markup 0.6 (make-simple-markup (DMSV n))))))))
#(define Q-circle ;; define circle of fifths as pitchlist
(list
(ly:make-pitch 0 6 DOUBLE-FLAT) ;; heses
(ly:make-pitch 0 3 FLAT) ;; fes
(ly:make-pitch 0 0 FLAT) ;; ces
(ly:make-pitch 0 4 FLAT) ;; ges
(ly:make-pitch 0 1 FLAT) ;; des
(ly:make-pitch 0 5 FLAT) ;; as
(ly:make-pitch 0 2 FLAT) ;; es
(ly:make-pitch 0 6 FLAT) ;; b
(ly:make-pitch 0 3 0) ;; f
(ly:make-pitch 0 0 0) ;; c
(ly:make-pitch 0 4 0) ;; g
(ly:make-pitch 0 1 0) ;; d
(ly:make-pitch 0 5 0) ;; a
(ly:make-pitch 0 2 0) ;; e
(ly:make-pitch 0 6 0) ;; h
(ly:make-pitch 0 3 SHARP) ;; fis
(ly:make-pitch 0 0 SHARP) ;; cis
(ly:make-pitch 0 4 SHARP) ;; gis
(ly:make-pitch 0 1 SHARP) ;; dis
(ly:make-pitch 0 5 SHARP) ;; ais
))
#(define Terz-circle ;; define terzbasses
(list
(ly:make-pitch 0 1 FLAT) ;; des
(ly:make-pitch 0 5 FLAT) ;; as
(ly:make-pitch 0 2 FLAT) ;; es
(ly:make-pitch 0 6 FLAT) ;; b
(ly:make-pitch 0 3 0) ;; f
(ly:make-pitch 0 0 0) ;; c
(ly:make-pitch 0 4 0) ;; g
(ly:make-pitch 0 1 0) ;; d
(ly:make-pitch 0 5 0) ;; a
(ly:make-pitch 0 2 0) ;; e
(ly:make-pitch 0 6 0) ;; h
(ly:make-pitch 0 3 SHARP) ;; fis
(ly:make-pitch 0 0 SHARP) ;; cis
(ly:make-pitch 0 4 SHARP) ;; gis
(ly:make-pitch 0 1 SHARP) ;; dis
(ly:make-pitch 0 5 SHARP) ;; ais
(ly:make-pitch 0 2 SHARP) ;; eis
(ly:make-pitch 0 6 SHARP) ;; his
(ly:make-pitch 0 4 0) ;; g
(ly:make-pitch 0 1 0) ;; d
))
#(define (get-Index p)
(list-index (lambda(x)(pitch-equals? x p)) Q-circle))
#(define-markup-command (accordion-bass layout props i1 n)
(index? index? )
;; mark pitch p in row n with different color
#:properties ((font-size 0) (thickness 2.5) (offset 3.5)(circle-padding 0.2))
(let* ((myA (interpret-markup layout props
(make-concat-markup
(list
(make-simple-markup "ges")
(make-smaller-markup
(make-raise-markup 0.6 (make-simple-markup "m")))))))
(ces7-xt ( ly:stencil-extent myA X))
(ces7-x (- (cdr ces7-xt) (car ces7-xt)))
(pad (* (magstep font-size) circle-padding 2))
(dm-circle (+ (/ ces7-x 2) pad)) ;; don'tm mess radius with diameter!
(col-dist (+ (* 2 dm-circle) pad))
(row-dist 0.9)
(h-shift (+ dm-circle 0))
(thick (* (magstep font-size) (ly:output-def-lookup layout 'line-thickness)))
(underline-thick (* thickness thick))
(my-circle (make-circle-stencil dm-circle thick #f))
(y (* thick (- offset)))
(a1 (- 6 n)))
(apply ly:stencil-add
empty-stencil
(map
(lambda (z)
(let ((zz z))
(ly:stencil-translate
(apply ly:stencil-add
empty-stencil
(map
(lambda (x)
(let* ((m (interpret-markup layout props
(ChordName->markup (list-ref Q-circle x) z)))
(myx (ly:stencil-extent m X))
(xstart (car myx))
(xend (cdr myx))
(breite (- xend xstart))
(myy (ly:stencil-extent m Y))
(hoch (- (cdr myy) (car myy))))
(ly:stencil-translate-axis
(ly:stencil-add
(if (and (= 1 z)(= 9 x)) ;; mark C-Button
(ly:stencil-add
(ly:stencil-in-color (make-circle-stencil dm-circle 0 #t)
1 1 1)
(make-circle-stencil (- dm-circle (* 5 thick)) (* 5 thick) #f))
empty-stencil)
(if (and (= 1 z)(or (= 5 x)(= 13 x))) ;; mark As- and E-Buttons
(ly:stencil-add
(ly:stencil-in-color (make-circle-stencil dm-circle 0 #t)
1 1 1)
(make-circle-stencil (- dm-circle (* 5 thick)) (* 2.5 thick) #f))
empty-stencil)
(if (and (= a1 z)(= i1 x)) ;; mark p Button
(ly:stencil-in-color (make-circle-stencil dm-circle 0 #t)
0.9 1 0.9)
empty-stencil)
(ly:stencil-translate-axis
(ly:stencil-translate-axis
(ly:stencil-add
(if (= 0 zz)
(make-line-stencil underline-thick xstart y xend y)
empty-stencil)
m)
(- 0 (/ breite 2)) X)
(- 0 (/ hoch 2)) Y) ;; chordname plus underline if terzbass
my-circle) ;; circled chordname
(* x col-dist) X)))
(iota 20 0)))
(cons (* zz h-shift) (* zz col-dist (* row-dist -1))))))
(iota 6)))))
\markup \column {
\line { "Draw a standard Accordion bass system using Markup-funcions of Lilypond" }
\line { "the Buttons A" \flat ", C and E are marked" }
\line { "mark a button in a different color by entering its row and column number" }
\line { "first number: column (0=B" \hspace #-0.5 \super \fontsize #1 \doubleflat ", 19=A" \hspace #-0.5 \super \sharp ")" }
\line { "second number: row (1=diminished chords, 6=terz basses)" }
\line { "if the parameters are outside this range no button is colored" }
\line { "change the scale factor to a number you like" }
\line { "usage:" \bold " \markup \scale #'(0.75 . 0.75) \accordion-bass #4 #2" }
\line { " " }
}
\markup \scale #'(0.75 . 0.75) \accordion-bass #4 #2
--- Ende Code ---
ingmar:
hallo - könntest du dem Thread noch einen sinnvollen Namen geben? Danke!
--ingmar
Navigation
[0] Themen-Index
[#] Nächste Seite
[*] Vorherige Sete
Zur normalen Ansicht wechseln