bug-lilypond
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: autochange with multiple voices


From: Thomas Morley
Subject: Re: autochange with multiple voices
Date: Wed, 19 Aug 2015 00:13:57 +0200

2015-08-18 22:32 GMT+02:00 Thomas Morley <address@hidden>:
> 2015-08-18 11:57 GMT+02:00 David Kastrup <address@hidden>:
>> Nik Repka <address@hidden> writes:
>>
>>> I am attempting to make a scales sheet for piano.  I need to use autochange
>>> simultaneously in two voices.
>>>
>>> I am using the syntax from this snippet page:
>>> http://www.lilypond.org/doc/v2.15/Documentation/snippets-big-page#keyboards-using-autochange-with-more-than-one-voice.
>>>
>>> The issue I am having is that autochange only works on the top voice, and it
>>> drags the lower voice up into the top staff.  Here is the code:
>>>
>>> \version "2.18.2"
>>>
>>> scaleRH = \relative c' {c d e f g a b c c b a g f e d c
>>> g a b c d e fis g g fis e d c b a g}
>>>
>>> scaleLH = \relative c {c d e f g a b c c b a g f e d c
>>> g a b c d e fis g g fis e d c b a g}
>>>
>>>
>>> \score {
>>>    \new PianoStaff
>>>
>>>       << \new Staff = "up"
>>>          <<
>>>            \new Voice {
>>>            \voiceOne
>>>            \autochange
>>>
>>>            \scaleRH
>>>
>>>            }
>>>
>>>            \new Voice {
>>>            \voiceTwo \autochange
>>>
>>>            \scaleLH
>>>            }
>>>          >>
>>>
>>>       \new Staff = "down" {
>>>           \clef bass
>>>       }
>>>       >>
>>> }
>>
>> Ok, disregard my previous reply.  It turns out that the whole
>> catastrophe happens _exclusively_ when the first note of the first voice
>> is c' (or probably one of cis' cisis' ces' ceses').
>
> This not entirely true.
>
> It happens when the first note is the same as the turning point.
> Because 2.19.25 allows for different turning points, we can test easily:
>
> \version "2.19.25"
>
> scaleRH = \relative c' { d c d e }
>
> scaleLH = \relative c { d c d e }
>
>
> \new PianoStaff
>   << \new Staff = "up"
>      <<
>        \new Voice {
>          \voiceOne
>          \autochange d'
>          \scaleRH
>        }
>
>        \new Voice {
>          \voiceTwo
>          \autochange d'
>          \scaleLH
>        }
>      >>
>   \new Staff = "down" {
>       \clef bass
>   }
>   >>
>
>
> returns badly as well.
>
> Investgating further ...
>
>
> Cheers,
>   Harm

I tried to patch autochange.scm with:

(define-public (make-autochange-music ref-pitch music)
  (define (generate-split-list change-moment prev-dir event-list acc)
    (if (null? event-list)
        acc
        (let* ((now-tun (caar event-list))
               (evs (map car (cdar event-list)))
               (now (car now-tun))
               (notes (filter (lambda (x)
                                (ly:in-event-class? x 'note-event))
                              evs))
               (pitch (if (pair? notes)
                          (ly:event-property (car notes) 'pitch)
                          #f))
;; changed:
               (dir (cond ((and pitch
                               (= (ly:pitch-steps ref-pitch)
                                  (ly:pitch-steps
                                    (ly:music-property
                                      (car
                                        (extract-named-music music 'NoteEvent))
                                      'pitch))))
                           1)
                          (pitch
                            (sign
                              (- (ly:pitch-steps pitch)
                                 (ly:pitch-steps ref-pitch))))
                          (else 0))))
          ;; tail recursive.
          (if (and (not (= dir 0))
                   (not (= dir prev-dir)))
              (generate-split-list #f
                                   dir
                                   (cdr event-list)
                                   (cons (cons
                                          (if change-moment
                                              change-moment
                                              now)
                                          (if (< dir 0) 'down 'up)) acc))
              (generate-split-list
               (if pitch #f (if change-moment change-moment now))
               dir
               (cdr event-list) acc)))))

  (let* ((m (make-music 'AutoChangeMusic))
         (m1 (context-spec-music (make-non-relative-music music) 'Voice ""))
         (context-list
           (recording-group-emulate m1
                                    (ly:parser-lookup 'partCombineListener)))
         (rev (reverse! (cdar context-list)))
         (split (reverse! (generate-split-list
                           #f
                           0
                           rev
                           '())
                          '())))
    (set! (ly:music-property m 'element) m1)
    (set! (ly:music-property m 'context-change-list) split)
    m))

If I didn't overlook something, the autochange related regtests look
ok. But I didn't do make check so far (it's late and it lasts too long
on my not so powerful laptop)

Though, I have the feeling it cures the symptom not the underlaying problem.
Therefore I didn't upload a patch yet.

If you think it's appropiate I'll create a tracker and do the upload.

For testing you may use the code above or the patch attached.


Cheers,
  Harm

Attachment: 0001-fix-autochange.scm-when-starting-pitch-and-ref-pitch.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]