Allgemein > Fragen zu Funktionen
Irgendetwas systematisch an Noten automatisch schreiben
harm6:
--- Zitat ---das Problem zu lösen, dass bei deinem Code Oktaven und Vorzeichen unterschlagen werden
--- Ende Zitat ---
Das war Absicht, da der Code auf den Anfängerunterricht gemünzt war und daher Alterationen außer acht läßt.
Wenn Du sie haben willst muß man anders vorgehen.
Ich habe meinen Code aus
https://archiv.lilypondforum.de/index.php?topic=1712.0
als Steinbruch genutzt:
--- Code: ---\version "2.19.52"
#(define (used-notenames lang)
;; returns a subset of 'language-pitch-names', specified by `lang'.
;; key and value are exchanged
;; i.e. the alist is from type '((pitch . name) ... )
(map
(lambda (e) (reverse-interval e))
(assoc-get
(string->symbol lang)
language-pitch-names)))
#(define german-notenames (used-notenames "deutsch"))
#(define (pitch->notename pitch)
(let* ((pitch-octaves (ly:pitch-octave pitch))
(pitch-notename (ly:pitch-notename pitch))
(pitch-alteration (ly:pitch-alteration pitch))
;; create a pitch with alteration, name and
;; octave set to -1
;; this ensures the possibility to look it up in
;; 'used-notenames'
(p (ly:make-pitch -1 pitch-notename pitch-alteration))
(pitch-name-strg
(symbol->string (assoc-get p german-notenames)))
;; recreate the octave-notation
(octave-sign
(cond ((and (>= pitch-octaves -2) (<= pitch-octaves -1)) "")
((<= pitch-octaves -1)
(string-concatenate
(make-list (- (abs pitch-octaves) 2) ",")))
((= pitch-octaves 0) "'")
((> pitch-octaves 0)
(string-concatenate
(make-list (1+ (abs pitch-octaves)) "'")))))
(absolute-pitch-name
(string-append
(if (<= pitch-octaves -2)
(string-upcase pitch-name-strg)
pitch-name-strg)
octave-sign)))
(format #f "~a" absolute-pitch-name)))
#(define pitch-markup-list
;; An alist assigning markups to certain integers, which will be used later
;; as reference for the pitch-names
;; TODO add the missing eps-markups
`(
(0 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: c-eps]"))
(1 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: d-eps]"))
(2 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: e-eps]"))
(3 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: f-eps]"))
(4 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: g-eps]"))
(5 . ,(markup #:halign 0 #:epsfile X 10 "Affe.eps"))
(6 . ,(markup #:halign 0 #:epsfile X 10 "Hase.eps"))))
#(define notenwerteliste-list
;; Analog zur pitch-markup-list
`(
(1 . ,(markup #:fontsize -8 #:halign 0 "Ganze"))
(3/4 . ,(markup #:fontsize -8 #:halign 0 "punktierte Halbe"))
(1/2 . ,(markup #:fontsize -8 #:halign 0 "Halbe"))
(3/8 . ,(markup #:fontsize -8 #:halign 0 "punktierte Viertel"))
(1/4 . ,(markup #:fontsize -8 #:halign 0 "Viertel"))
(1/8 . ,(markup #:fontsize -8 #:halign 0 "Achtel"))
(1/16 . ,(markup #:fontsize -8 #:halign 0 "Sechzehntel"))
(3/16 . ,(markup #:fontsize -8 #:halign 0 "punktierte Achtel"))
))
#(define-markup-command (arc layout props angle)(number?)
#:properties ((radius 1.5)
(font-size 1)
(double-radius-x-ext #t))
"Print a circle-segment relying on @var{angle} in degrees.
The radius may be adjusted by overriding the @code{radius}-property.
The dimensions of the resulting stencil are set properly.
If @var{double-radius-x-ext} is set @code{#t}, (the default) the dimensions are
always from @code{(- radius)} to @code{radius} in Y-axis."
(let* ((scaled-radius (* radius font-size))
(top radius)
(bottom
(if double-radius-x-ext
(- scaled-radius)
(cond ((<= angle 90) 0)
((> angle 180) (- scaled-radius))
(else
(* (cos (degrees->radians angle)) scaled-radius)))))
(left
(cond ((>= angle 270) (- scaled-radius))
((> angle 180)
(* (sin (degrees->radians angle)) scaled-radius))
(else 0)))
(right
(cond ((> angle 90) scaled-radius)
(else
(* (sin (degrees->radians angle)) scaled-radius)))))
(ly:make-stencil
(list 'embedded-ps
(format #f "
gsave currentpoint translate
0.1 setlinewidth
0 0 ~a 90 ~a arcn % Bogen 90 Grad
fill
grestore
"
scaled-radius
(- 90 angle)))
(cons left right)
(cons bottom top))))
addTextScript =
#(define-music-function (music)(ly:music?)
"Adds markups to note-heads.
- a circle-segment above
(relying on and representing the duration of a note-head
- an eps below
(called with the note-name from @code{pitch-markup-list}"
(music-map
(lambda (mus)
(if (music-is-of-type? mus 'note-event)
(let* ((dur-frac (ly:moment-main (ly:music-length mus)))
(pitch (ly:music-property mus 'pitch))
(pitch-name (ly:pitch-notename pitch)))
(ly:music-set-property! mus 'articulations
(append
(list
;; print eps
(make-music
'TextScriptEvent
'direction DOWN
'text
(assoc-get pitch-name pitch-markup-list))
;; print text
(make-music
'TextScriptEvent
'direction UP
'text
(assoc-get dur-frac notenwerteliste-list))
;; print the circles
(make-music
'TextScriptEvent
'direction UP
'text
#{
\markup
\with-color #'(0.6 0.6 0.6)
\arc #(* 360.0 dur-frac)
#})
)
(ly:music-property mus 'articulations)))
mus)
mus))
music)
music)
printGermanNoteNames =
#(define-music-function (solve?)(boolean?)
#{
\override NoteName.stencil =
#(lambda (grob)
(let ((pitch (ly:prob-property (ly:grob-property grob 'cause) 'pitch)))
(grob-interpret-markup
grob
(if solve?
(pitch->notename pitch)
(markup #:with-dimensions-from "XXX" "...")))))
#})
exercise =
#(define-music-function (solve? music)(boolean? ly:music?)
#{
<<
\new Staff
\with {
instrumentName = #(if solve? "Aufösung " "Aufgabe ")
shortInstrumentName = #(if solve? "Aufösung " "Aufgabe ")
}
{
#(if solve?
#{ \unHideNotes #}
#{ \hideNotes #})
\addTextScript $music
}
\new NoteNames
\with {
%\override VerticalAxisGroup.nonstaff-relatedstaff-spacing.padding = 4
\printGermanNoteNames $solve?
}
$music
>>
#})
\paper {
system-system-spacing.padding = 16
indent = 12
short-indent = 12
}
\layout {
\override TextScript.parent-alignment-X = #CENTER
\override TextScript.staff-padding = 2.5
\override TextScript.font-size = 2
\override Staff.VerticalAxisGroup.staff-staff-spacing.padding = 5
\textLengthOn
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
mus = {
\cadenzaOn
c'4 d'2 e'4. f'8 g'16 a'2. b'1 c''8.
\bar "|"
}
<<
%% exercise:
\exercise ##f { \mus \break \transpose c cis \mus }
%% solved:
\exercise ##t { \mus \break \transpose c cis \mus }
>>
--- Ende Code ---
Ob Du mit meinen Formatierungen einverstanden bist, ist natürlich eine andere Frage :D
Gruß,
Harm
Hilflos-im-Code:
Danke. Das mir wichtige sind weniger die Alterationen, sondern die Oktaven, weil g' ist eine Gans und g'' eine Giraffe. Das scheine ich hinzubekommen
Gesamter Code
--- Code: ---\version "2.19.40"
#(define (used-notenames lang)
;; returns a subset of 'language-pitch-names', specified by `lang'.
;; key and value are exchanged
;; i.e. the alist is from type '((pitch . name) ... )
(map
(lambda (e) (reverse-interval e))
(assoc-get
(string->symbol lang)
language-pitch-names)))
#(define german-notenames (used-notenames "deutsch"))
#(define (pitch->notename pitch)
(let* ((pitch-octaves (ly:pitch-octave pitch))
(pitch-notename (ly:pitch-notename pitch))
(pitch-alteration (ly:pitch-alteration pitch))
;; create a pitch with alteration, name and
;; octave set to -1
;; this ensures the possibility to look it up in
;; 'used-notenames'
(p (ly:make-pitch -1 pitch-notename pitch-alteration))
(pitch-name-strg
(symbol->string (assoc-get p german-notenames)))
;; recreate the octave-notation
(octave-sign
(cond ((and (>= pitch-octaves -2) (<= pitch-octaves -1)) "")
((<= pitch-octaves -1)
(string-concatenate
(make-list (- (abs pitch-octaves) 2) ",")))
((= pitch-octaves 0) "'")
((> pitch-octaves 0)
(string-concatenate
(make-list (1+ (abs pitch-octaves)) "'")))))
(absolute-pitch-name
(string-append
(if (<= pitch-octaves -2)
(string-upcase pitch-name-strg)
pitch-name-strg)
octave-sign)))
(format #f "~a" absolute-pitch-name)))
#(define pitch-markup-list
;; An alist assigning markups to certain integers, which will be used later
;; as reference for the pitch-names
;; TODO add the missing eps-markups
`(
(10 1 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: c-eps]"))
(1 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: d-eps]"))
(02 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: e-eps]"))
(3 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: f-eps]"))
(4 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: g-eps]"))
(5 . ,(markup #:halign 0 #:epsfile X 10 "Affe.eps"))
(6 . ,(markup #:halign 0 #:epsfile X 10 "Hase.eps"))))
#(define notenwerteliste-list
;; Analog zur pitch-markup-list
`(
(1 . ,(markup #:fontsize -8 #:halign 0 "Ganze"))
(3/4 . ,(markup #:fontsize -8 #:halign 0 "punktierte Halbe"))
(1/2 . ,(markup #:fontsize -8 #:halign 0 "Halbe"))
(3/8 . ,(markup #:fontsize -8 #:halign 0 "punktierte Viertel"))
(1/4 . ,(markup #:fontsize -8 #:halign 0 "Viertel"))
(1/8 . ,(markup #:fontsize -8 #:halign 0 "Achtel"))
(1/16 . ,(markup #:fontsize -8 #:halign 0 "Sechzehntel"))
(3/16 . ,(markup #:fontsize -8 #:halign 0 "punktierte Achtel"))
))
#(define-markup-command (arc layout props angle)(number?)
#:properties ((radius 1.5)
(font-size 1)
(double-radius-x-ext #t))
"Print a circle-segment relying on @var{angle} in degrees.
The radius may be adjusted by overriding the @code{radius}-property.
The dimensions of the resulting stencil are set properly.
If @var{double-radius-x-ext} is set @code{#t}, (the default) the dimensions are
always from @code{(- radius)} to @code{radius} in Y-axis."
(let* ((scaled-radius (* radius font-size))
(top radius)
(bottom
(if double-radius-x-ext
(- scaled-radius)
(cond ((<= angle 90) 0)
((> angle 180) (- scaled-radius))
(else
(* (cos (degrees->radians angle)) scaled-radius)))))
(left
(cond ((>= angle 270) (- scaled-radius))
((> angle 180)
(* (sin (degrees->radians angle)) scaled-radius))
(else 0)))
(right
(cond ((> angle 90) scaled-radius)
(else
(* (sin (degrees->radians angle)) scaled-radius)))))
(ly:make-stencil
(list 'embedded-ps
(format #f "
gsave currentpoint translate
0.1 setlinewidth
0 0 ~a 90 ~a arcn % Bogen 90 Grad
fill
grestore
"
scaled-radius
(- 90 angle)))
(cons left right)
(cons bottom top))))
addTextScript =
#(define-music-function (music)(ly:music?)
"Adds markups to note-heads.
- a circle-segment above
(relying on and representing the duration of a note-head
- an eps below
(called with the note-name from @code{pitch-markup-list}"
(music-map
(lambda (mus)
(if (music-is-of-type? mus 'note-event)
(let* ((dur-frac (ly:moment-main (ly:music-length mus)))
(pitch (ly:music-property mus 'pitch))
(pitch-name (ly:pitch-notename pitch))
(pitch-alteration (ly:pitch-alteration pitch))
(pitch-octaves (ly:pitch-octave pitch))
)
(ly:music-set-property! mus 'articulations
(append
(list
;; print eps
(make-music
'TextScriptEvent
'direction DOWN
'text
(assoc-get (+ pitch-octaves pitch-name pitch-alteration ) pitch-markup-list))
;; print text
(make-music
'TextScriptEvent
'direction UP
'text
(assoc-get dur-frac notenwerteliste-list))
;; print the circles
(make-music
'TextScriptEvent
'direction UP
'text
#{
\markup
\with-color #'(0.6 0.6 0.6)
\arc #(* 360.0 dur-frac)
#})
)
(ly:music-property mus 'articulations)))
mus)
mus))
music)
music)
printGermanNoteNames =
#(define-music-function (solve?)(boolean?)
#{
\override NoteName.stencil =
#(lambda (grob)
(let ((pitch (ly:prob-property (ly:grob-property grob 'cause) 'pitch)))
(grob-interpret-markup
grob
(if solve?
(pitch->notename pitch)
(markup #:with-dimensions-from "XXX" "...")))))
#})
exercise =
#(define-music-function (solve? music)(boolean? ly:music?)
#{
<<
\new Staff
\with {
instrumentName = #(if solve? "Aufösung " "Aufgabe ")
shortInstrumentName = #(if solve? "Aufösung " "Aufgabe ")
}
{
#(if solve?
#{ \unHideNotes #}
#{ \hideNotes #})
\addTextScript $music
}
\new NoteNames
\with {
%\override VerticalAxisGroup.nonstaff-relatedstaff-spacing.padding = 4
\printGermanNoteNames $solve?
}
$music
>>
#})
\paper {
system-system-spacing.padding = 16
indent = 12
short-indent = 12
}
\layout {
\override TextScript.parent-alignment-X = #CENTER
\override TextScript.staff-padding = 2.5
\override TextScript.font-size = 2
\override Staff.VerticalAxisGroup.staff-staff-spacing.padding = 5
\textLengthOn
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
mus = {
\cadenzaOn
c' cis' d' c'' cis'' d''
\bar "|"
}
<<
%% exercise:
\exercise ##f { \mus }
>>
--- Ende Code ---
aus
--- Code: --- (let* ((dur-frac (ly:moment-main (ly:music-length mus)))
(pitch (ly:music-property mus 'pitch))
(pitch-name (ly:pitch-notename pitch)))
--- Ende Code ---
wurde
--- Code: --- (let* ((dur-frac (ly:moment-main (ly:music-length mus)))
(pitch (ly:music-property mus 'pitch))
(pitch-name (ly:pitch-notename pitch))
(pitch-alteration (ly:pitch-alteration pitch))
(pitch-octaves (ly:pitch-octave pitch))
)
--- Ende Code ---
und aus
(assoc-get pitch-name pitch-markup-list))
wurde
(assoc-get (+ pitch-octaves pitch-name pitch-alteration ) pitch-markup-list))
Aber ich schaffe es nicht Oktavlage noch Alterationen zu berücksichtigen.
So sieht die markupliste aus
--- Code: ---#(define pitch-markup-list
;; An alist assigning markups to certain integers, which will be used later
;; as reference for the pitch-names
;; TODO add the missing eps-markups
`(
(00 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: c'-eps]"))
(001/2 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: cis'-eps]"))
(01 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: d'-eps]"))
(01 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: c''-eps]"))
(101/2 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: cis''-eps]"))
(11 . ,(markup #:fontsize -8 #:halign 0 "[dummy für: d''-eps]"))
))
--- Ende Code ---
harm6:
Ich hatte mich nur darum gekümmert, daß die Noten den richtigen Namen bekommen jetzt auch mit Berücksichtigung der Oktavlage sowie möglichen Alterationen.
--- Zitat ---Das mir wichtige sind weniger die Alterationen, sondern die Oktaven, weil g' ist eine Gans und g'' eine Giraffe.
--- Ende Zitat ---
Wenn ich das richtig verstehe, so geht es in diesem Teilaspekt darum je nach Oktave unerschiedliche eps-Bilder demselben Tonnamen zuzuordnen.
Über wie viele Möglichkeiten reden wir?
Für g,, g, g g' g' g'' g''' wären es ja schon 7, multipliziert mit den sieben Stammtönen 49, multipliziert mit "normal", hoch- und tiefalteriert komme ich schon auf 147, mit doppelten Alterationen auf 245.
Das ist in jedem Fall 'ne ganze Menge...
Ich kann frühestens heute abend hier weitermachen.
Aber es wäre schön Du würdest genau spezifizieren, für welche Oktaven Du etwas haben willst, z.B.:
c, - eps1a
c - eps1b
c'- eps1c
(andere Oktaven nicht)
Gruß,
Harm
Hilflos-im-Code:
Der Anhang tut, was er soll. Aber ob das sauber und richtig ist keine Ahnung.
Geht über neun Oktaven.
Navigation
[0] Themen-Index
[*] Vorherige Sete
Zur normalen Ansicht wechseln