Re: Helper macros for music analysis
Tertio Nonas Novembres MMXVIII scripsit Thomas Morley : > > I tried to hunt this down... > > Although, I still don't know why #(load "file.scm") done in a ly-file > > stopped working, [...] > > Still no clue, though, in ly-files (load ...) works only with an absolute > path. > In native guilev2, it works with a relative path as well. > > Any hints to boil this down even further? I am really not that familiar with the Guile module management system. My best guess is that it has to do with this: https://www.gnu.org/software/guile/manual/html_node/Load-Paths.html Also, scm/lily.scm contains some allusions to a difference of behaviour between guile v1 and v2: (define-public (ly:load x) (let* ((file-name (%search-load-path x))) (ly:debug "[~A" file-name) (if (not file-name) (ly:error (_ "cannot find: ~A") x)) (primitive-load-path file-name) ;; to support Guile V2 autocompile ;; TODO: Any chance to use ly:debug here? Need to extend it to prevent ;; a newline in this case (if (ly:get-option 'verbose) (ly:progress "]\n" ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Helper macros for music analysis
Am Sa., 3. Nov. 2018 um 16:16 Uhr schrieb Thomas Morley : > > Am Do., 1. Nov. 2018 um 16:21 Uhr schrieb Thomas Morley > : > > > Furthermore, compiling your code with my guilev2-setup fails right > > from the beginning with: > > error: GUILE signaled an error for the expression beginning here > > # > > (load "motif.scm") > > Unable to find file "./motif.scm" in load path > > I tried to hunt this down... > Although, I still don't know why #(load "file.scm") done in a ly-file > stopped working, [...] Still no clue, though, in ly-files (load ...) works only with an absolute path. In native guilev2, it works with a relative path as well. Any hints to boil this down even further? Cheers, Harm ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Helper macros for music analysis
Am Do., 1. Nov. 2018 um 16:21 Uhr schrieb Thomas Morley : > Furthermore, compiling your code with my guilev2-setup fails right > from the beginning with: > error: GUILE signaled an error for the expression beginning here > # > (load "motif.scm") > Unable to find file "./motif.scm" in load path I tried to hunt this down... Although, I still don't know why #(load "file.scm") done in a ly-file stopped working, I've found #(primitive-load "file.scm) working for guilv1 and guilev2. While working on it I've found a little syntax-mistake in 'music-insert-before!' of your motif.scm It should be (fold (lambda (m b) (or b (music-insert-before! pos m items))) ...) and not (fold (lambda (m b) (b or (music-insert-before! pos m items))) ...) No clue why guilev1 didn't warn. Though, the guilev2 message is not that helpful either: error: GUILE signaled an error for the expression beginning here # (primitive-load "motif.scm") source expression failed to match any pattern Meaning: "there's a problem in this multiple hundred-lines-of-code-file, Good Luck." Yeah... Cheers, Harm ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Helper macros for music analysis
Am Do., 1. Nov. 2018 um 19:37 Uhr schrieb Jérôme Plût : > > Kalendis Novembribus MMXVIII scripsit Thomas Morley : > > Part of the problem is you use 'structure as a music-property without > > declaring it. As a consequence using the option -dcheck-internal-types > > makes the compilation fail. > > This is why, in a previous iteration of this code, I used an invisible > articulation to hold the metadata (cf. my previous message on this > list; ...]. I had seen your request. And tried several codings, to no avail until gave up. In the light of your mail I retried with success. :) I posted the code to this thread: http://lilypond.1069038.n5.nabble.com/Three-questions-about-Scheme-functions-td216957.html > > I just had a look at define-music-properties.scm -- I had not realized > that it was even possible to *declare* a music property. Adding these > lines makes my code compile even with -dcheck-internal-types: > > (music-property-description 'structure markup? "structural markup") > (music-property-description 'harmony markup? "harmony markup") > (music-property-description 'motif-define markup? "motif name") Not sure this will be sufficient, but this is only my gut feeling, I haven't looked in the source again. > There are still a few warnings because of an invalid 'origin property, > but these would take quite a bit longer to fix (the correct location > object would need to be passed along a *long* chain of procedure > calls). > > By the way, I have one more question: Given (on the Scheme side) a > list L of markup objects, I can build a column with > (make-column-markup L), but this column is left-aligned. How could I > make it right-aligned? (make-right-column-markup '("one" "two" "three")) Best, Harm ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Helper macros for music analysis
Kalendis Novembribus MMXVIII scripsit Thomas Morley : > Part of the problem is you use 'structure as a music-property without > declaring it. As a consequence using the option -dcheck-internal-types > makes the compilation fail. This is why, in a previous iteration of this code, I used an invisible articulation to hold the metadata (cf. my previous message on this list; by the way, let me apologize for the triple posting, I was under the impression that the sending had failed). I just had a look at define-music-properties.scm -- I had not realized that it was even possible to *declare* a music property. Adding these lines makes my code compile even with -dcheck-internal-types: (music-property-description 'structure markup? "structural markup") (music-property-description 'harmony markup? "harmony markup") (music-property-description 'motif-define markup? "motif name") There are still a few warnings because of an invalid 'origin property, but these would take quite a bit longer to fix (the correct location object would need to be passed along a *long* chain of procedure calls). By the way, I have one more question: Given (on the Scheme side) a list L of markup objects, I can build a column with (make-column-markup L), but this column is left-aligned. How could I make it right-aligned? ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Helper macros for music analysis
Am Do., 1. Nov. 2018 um 14:44 Uhr schrieb Jérôme Plût : > > > I wrote some macros to help write analysis of musical pieces. > Here is an example file (on Bach's Invention I). > > Structural analysis is (of course) performed by hand, and displayed on > a Lyrics structure on top of the music. (This part is only a set of > very simple macros). > > Harmonic analysis is performed mostly by hand (I also have some code > that does harmonic analysis, but it works mostly on chorales; the code > here only detects octave-drop cadences) and displayed on a Lyrics > structure below the music. > > The code also does a bit of motif analysis, which is done > automatically (motives are declared once by hand, then later > occurrences and inversions are identified automatically). > > The enclosed files: > motif.scm contains most of the parentheses > bwv772.ly is the example for Invention I > > TThe code compiles with both v2.18 (Debian stable; this is the only > version I have access to on some of my systems) and v2.19. > > I am interested in any feedback you would have on this code! > > -- > Jérôme Hi Jérôme, I've only started looking at it... Very nice! Some observations, though: Right from looking at the output of bwv772.ly it bugged me that "Ainv" (with it's arrow-head) is not in the same way aligned to the NoteColumn like the simple "A". So I changed 'mark-motif-leaf ' to: (define (mark-motif-leaf leaf name first trans) (let* ( (p (ly:music-property leaf 'pitch)) (color (color-variant (get-motif-color name) trans)) (grobs '(NoteHead Stem Dots Flag Script Accidental)) ) (if first (ly:music-set-property! leaf 'articulations (cons (make-music 'TextScriptEvent 'direction 1 'tweaks (list (cons (quote parent-alignment-X) 0) (cons (quote self-alignment-X) 0)) 'text (motif-markup name)) (ly:music-property leaf 'articulations (make-sequential-music (append (map (lambda (g) (prop-override `(Staff ,g color) color)) grobs) (list leaf) (map (lambda (g) (prop-revert `(Staff ,g color))) grobs))) )) Iirc, 'parent-alignment-X is a 2.19.-feature, though. I then intended to do similar with 'structural-corner'. But I failed. Part of the problem is you use 'structure as a music-property without declaring it. As a consequence using the option -dcheck-internal-types makes the compilation fail. Even not using this option, \tweaks etc can't be apllied in a reasonable way. One could change the basic markup, ofcourse, but I'd recommend to better cope with the 'structure-music-property. Furthermore, compiling your code with my guilev2-setup fails right from the beginning with: error: GUILE signaled an error for the expression beginning here # (load "motif.scm") Unable to find file "./motif.scm" in load path Maybe creating a module is more promising than using 'load', but now I'm guessing ... Didn't investigate further, though. So far, many thanks for sharing your code, Harm ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user
Helper macros for music analysis
I wrote some macros to help write analysis of musical pieces. Here is an example file (on Bach's Invention I). Structural analysis is (of course) performed by hand, and displayed on a Lyrics structure on top of the music. (This part is only a set of very simple macros). Harmonic analysis is performed mostly by hand (I also have some code that does harmonic analysis, but it works mostly on chorales; the code here only detects octave-drop cadences) and displayed on a Lyrics structure below the music. The code also does a bit of motif analysis, which is done automatically (motives are declared once by hand, then later occurrences and inversions are identified automatically). The enclosed files: motif.scm contains most of the parentheses bwv772.ly is the example for Invention I TThe code compiles with both v2.18 (Debian stable; this is the only version I have access to on some of my systems) and v2.19. I am interested in any feedback you would have on this code! -- Jérôme ; (music-fold-time order f data init music): f(data, leaf, X, pos) ; General utilities {{{1 (define (print . l) (map display l) (newline) #f) (define (assert b . l) (or b (apply error l))) ; https://stackoverflow.com/questions/108169/how-do-i-take-a-slice-of-a-list-a-sublist-in-scheme (define (slice l start length) (take (drop l start) length)) (define (insert l position x) (append (take l position) (cons x (drop l position ; returns interval [start, stop[ with given step (define (interval-open start step stop) (if (>= start stop) '() (cons start (interval-open (+ start step) step stop ; returns the last element of a closed list (define (last l) (car (last-pair l))) (define (anything->color c) (cond ((symbol? c) (x11-color c)) ((and (number? c) (> c 1)) (map (lambda (x) (/ x 255.)) `(,c ,c ,c))) ((number? c) `(,c ,c ,c)) ((and (list? c) (> (car c) 1) (map (lambda(x) (/ x 255.)) c))) (else c))) ; Cosmetic functions {{{1 ; Color variant {{{2 (define (color-comp-variant1 t x) (/ (* x t) (+ 1 (* (- t 1) x (define (color-variant c n) (let* (;{{{ (n (modulo (* 4 n) 7)) (t `((0 0 1) (1 1 0) (0 1 1) (1 0 1) (0 1 0) (1 0 1) (0 0 0))) (d (map (lambda (x) (list-ref `(1.3 .8) x)) (list-ref t n))) ) ; c = RGB color ; n = integer 0..6 (map color-comp-variant1 d c)) );}}} (define (theme-color-variant c m);{{{ (color-variant c (ly:pitch-notename (first-note m;}}} ; hsv->rgb {{{2 (define (hsv->rgb z) (let* ( (h (modulo (car z) 360)) (s (cadr z)) (v (caddr z)) (i (floor (/ h 60.))) (c (* v s)) (t (/ h 60.)) (hmod2 (- t (* 2 (floor (/ t 2) (absh (abs (- hmod2 1))) (x (* c (- 1 absh))) ) (map (lambda (y) (+ y (- v c))) (cond ((<= t 1) `(,c ,x 0)) ((<= t 2) `(,x ,c 0)) ((<= t 3) `(0 ,c ,x)) ((<= t 4) `(0 ,x ,c)) ((<= t 5) `(,x 0 ,c)) ((<= t 6) `(,c 0 ,x));}}} ; with-background {{{2 ; after http://lsr.di.unimi.it/LSR/Snippet?id=969 (define-markup-command (with-background layout props color arg) (color? markup?) (let* ((stencil (interpret-markup layout props arg)) (X-ext (ly:stencil-extent stencil X)) (Y-ext (ly:stencil-extent stencil Y))) (ly:stencil-add (ly:make-stencil (list 'color color (ly:stencil-expr (ly:round-filled-box X-ext Y-ext 0)) X-ext Y-ext)) stencil))) (define mark-below (define-music-function (parser location label) (markup?) (make-sequential-music (list (prop-override '(Score RehearsalMark extra-offset) '(0 . -8.5) #t) (prop-override '(Score RehearsalMark baseline-skip) 9 #t) (make-music 'MarkEvent 'label label) (define framed-mark (define-music-function (parser location text1) (markup?) (make-sequential-music (list (prop-override `(Bottom LyricText self-alignment-X) LEFT) (make-music 'MarkEvent 'label (markup #:line (#:box #:fontsize -3 text1))) (define corner-mark (define-music-function (parser location text2) (markup?) (make-music 'MarkEvent 'label (markup #:fontsize -3 (#:combine (#:path .15 '((lineto 0 2) (lineto 3 2))) #:line (" " text2)) ; General utilities for music {{{1 ; Naming convention: ; make-foobar: direct constructor for a foobar ; create-foobar: defines a function which returns a foobar (define (pitch->int p) (assert (ly:pitch? p) "pitch->int: must be a pitch: " p) (if (ly:pitch? p) (+ (* 7 (ly:pitch-octave p)) (ly:pitch-notename p (define (pitch->semitone p) (assert (ly:pitch? p) "pitch->semitone: must be a pitch: " p) (if (ly:pitch? p) (+ (* 12 (ly:pitch-octave p)) (list-ref `(0 2 4 5 7 9 11) (ly:pitch-notename p)) (* 2 (ly:pitch-alteration p) ; music-length: duration (as a rational) {{{2 (define moment->rational ly:moment-main) (define (duration->rational dur) (ly:moment-main (ly:duration-length dur))) (define (music-length m) "Duration of m, as a rational" (moment->rational (ly:music-length m))) (define (rational->d