Re: Helper macros for music analysis

2018-11-07 Thread Jérôme Plût
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

2018-11-03 Thread Thomas Morley
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

2018-11-03 Thread 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, 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

2018-11-01 Thread Thomas Morley
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

2018-11-01 Thread 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; 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

2018-11-01 Thread Thomas Morley
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

2018-11-01 Thread 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
; (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