Helper macros for music analysis

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Helper macros for music analysis

Jérôme Plût-2

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

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user

motif.scm (33K) Download Attachment
bwv772.ly (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Helper macros for music analysis

Thomas Morley-2
Am Do., 1. Nov. 2018 um 14:44 Uhr schrieb Jérôme Plût <[hidden email]>:

>
>
> 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
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Helper macros for music analysis

Jérôme Plût-2
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
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Helper macros for music analysis

Thomas Morley-2
Am Do., 1. Nov. 2018 um 19:37 Uhr schrieb Jérôme Plût <[hidden email]>:
>
> 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
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Helper macros for music analysis

Thomas Morley-2
In reply to this post by Thomas Morley-2
Am Do., 1. Nov. 2018 um 16:21 Uhr schrieb Thomas Morley
<[hidden email]>:

> 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
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Helper macros for music analysis

Thomas Morley-2
Am Sa., 3. Nov. 2018 um 16:16 Uhr schrieb Thomas Morley
<[hidden email]>:

>
> Am Do., 1. Nov. 2018 um 16:21 Uhr schrieb Thomas Morley
> <[hidden email]>:
>
> > 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
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: Helper macros for music analysis

Jérôme Plût-2
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
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user