[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: detecting the start and end of a polyphonic passage from scheme
From: |
Thomas Morley |
Subject: |
Re: detecting the start and end of a polyphonic passage from scheme |
Date: |
Wed, 1 Jul 2020 13:09:56 +0200 |
Am Mi., 1. Juli 2020 um 11:08 Uhr schrieb Maurits Lamers
<maurits@weidestraat.nl>:
>
> Hi all,
>
> Follow up question: is there a way to know the "parent" of the voices as they
> are defined in the code?
> In the following example, I would like to determine that voice "two" splits
> off from voice "one" without relying on the context-id.
> (ly:context-parent ctx) gives me the staff, not the "parent voice"...
>
> \score {
> \new Staff {
> \time 2/2
>
> <<
> \new Voice = "one" {
> \relative c'' {
> \voiceOne
> g8 e
> }
> <<
> \new Voice = "two" {
> \voiceOne
> \relative c'' { a8. g16 f8 e16 f g f e d }
> }
> \new Voice = "three" {
> \voiceTwo
> \relative c' { c8 a d8. c16 b8 a16 b }
> }
> >>
> }
> \new Voice = bottom {
> \voiceTwo
> \relative c' { g1 }
> }
> >>
>
> }
> }
>
> Thanks in advance!
>
Hi Maurits,
I second Aaron, saying Voices are not parent of each other.
Below some other code I once made. Not exactly what you need, maybe
some addition to the fine code Aaron already provided, though.
#(define (my-engraver ctx)
(let ((new-contexts '()))
`(
(listeners
(AnnounceNewContext
.
,(lambda (engraver event)
(set! new-contexts (cons event new-contexts)))))
(finalize
.
,(lambda (trans)
(let ((ctx-type-id
(map
(lambda (c)
(let ((creator (ly:event-property c 'creator)))
(list
(ly:event-property creator 'type)
(ly:event-property creator 'id))))
(delete-duplicates (reverse new-contexts)))))
(format #t
"\nInside this score ~a new contexts are created. Type and id are:\n~y"
(length ctx-type-id)
ctx-type-id)
(set! ctx-type-id '()))))
)))
#(define (single-context-parent-tree ctx)
(if (and (ly:context? ctx) (ly:context? (ly:context-parent ctx)))
(single-context-parent-tree (ly:context-parent ctx))
(format #f "~a" ctx)))
printBottomContextParents =
\context Bottom
\applyContext
#(lambda (a)
(let ((ls (drop-right
(string-split
(single-context-parent-tree a)
(car (string->list "(")))
1)))
(format #t "\n\nThe Context-parent-tree:")
(format #t
"\n(Only contexts of type Global, Score, Staff and Voice are printed)")
(for-each
(lambda (s)
(format #t "\n~a~a"
(cond ((string-contains s "Score")
(make-string 1 #\tab))
((string-contains s "Staff")
(make-string 2 #\tab))
((string-contains s "Voice")
(make-string 3 #\tab))
(else ""))
(string-trim-both s (lambda (c)
(or (eqv? c #\>)
(eqv? c #\sp)
(eqv? c #\)))))))
ls)))
\score {
\new Staff {
\time 2/2
<<
\new Voice = "one" {
\relative c'' {
\voiceOne
g8 e
}
<<
\new Voice = "two" {
\voiceOne
\relative c'' { a8. g16 f8 e16 f g f e d }
}
\new Voice = "three" {
\voiceTwo
\relative c' { c8 a d8. c16 b8 a16 b }
}
>>
}
\new Voice = bottom {
\voiceTwo
\relative c' { g1 }
}
>>
}
\layout {
\context {
\Score
\consists \my-engraver
}
\printBottomContextParents
}
}
Cheers,
Harm