Menu

#5389 partcombine warns about unterminated slur

Accepted
nobody
Defect
2018-07-29
2018-07-19
No

Good morning,

I've been reading up on partcombine recently and I wanted to try out a few examples from the documentation to help me really understand the command, however I get this error with one example:

From:

http://lilypond.org/doc/v2.19/Documentation/notation/multiple-voices#automatic-part-combining

Error:

warning: unterminated slur r2 g'4( f8 e) |


I have not modified the code at all, just copy and paste.

I thought it was due to some voice-issue but I can't figure out how to fix. Thanks for any help.

Code:

musicUp = \relative c'' {
  \time 4/4
  a4 c4.( g8) a4 |
  g4 e' g,( a8 b) |
  c b a2.
} % begin verbatim


musicDown = \relative c'' {
  g4 e4.( d8) c4 |
  r2 g'4( f8 e) |
  d2 \stemDown a
}

\score {
    <<
    \new Staff \with { instrumentName = #"Standard polyphony" }

      << \musicUp \\ \musicDown >>

    \new Staff \with {
      instrumentName = #"PartCombine without text"
      printPartCombineTexts = ##f
    }

    \partcombine \musicUp \musicDown

    \new Staff \with { instrumentName = #"PartCombine with text" }
      \partcombine \musicUp \musicDown
    >>


 \layout {
    indent = 6.0\cm
    \context {
      \Score
      \override SystemStartBar.collapse-height = #30
    }
  }
}

Discussion

  • Anonymous

    Anonymous - 2018-07-19

    From: Simon Albrecht
    Subject: Re: Partcombine Documentation: Example Error
    Date: Tue, 17 Jul 2018 17:34:15 +0200

    On 17.07.2018 11:55, Ben wrote:

    musicUp = \relative c'' {
      \time 4/4
      a4 c4.( g8) a4 |
      g4 e' g,( a8 b) |
      c b a2.
    } % begin verbatim
    

    Even worse, in 2.19.82 the above quoted definition of musicUp seems to be completely elided from the example in the docs – this is on http://lilypond.org/doc/v2.19/Documentation/notation/multiple-voices#automatic-part-combining as well as in the html downloaded via the installer.

    Best, Simon

     
    • Dan Eble

      Dan Eble - 2018-07-22

      Even worse, in 2.19.82 the above quoted definition of musicUp seems to be completely elided from the example in the docs

      That seems worthy of being tracked as a separate issue.

       
  • Anonymous

    Anonymous - 2018-07-19

    2018-07-17 11:55 GMT+02:00 Ben soundsfromsound@gmail.com:

    First bad commit:

    commit b357d2084d1ae252a890e92019e62aa8ccbfdafc
    Author: Dan Eble <nine.fierce.ballads@gmail.com>
    Date: Wed May 27 20:56:37 2015 -0400
    
    Issue 4423: eliminate part combiner's array of context handles (3/4)
    
    Use NullVoice instead of Devnull for the "null" context. This makes
    all outlets a kind of Voice.
    

    Introduced in 2.19.22

    Cheers,
    Harm

     
  • Dan Eble

    Dan Eble - 2018-07-22
    • assigned_to: Dan Eble
     
  • Dan Eble

    Dan Eble - 2018-07-22

    I'll try to investigate this within the next few days.

     
  • Dan Eble

    Dan Eble - 2018-07-24

    Here is a tinier example. I noticed that if the slurs are changed to phrasing slurs, there is no warning. I probably won't go any deeper tonight.

    \version "2.18.2"
    
    musicUp = \relative c'' { g4( a) }
    musicDown = \relative c'' { g4( f) }
    
    \partcombine \musicUp \musicDown
    
     
  • Dan Eble

    Dan Eble - 2018-07-25

    NullVoice is pickier than Devnull.

    Input:

    \version "2.18.2"
    
    \new Score <<
      \new Devnull { c8( }
      \new Devnull { d8\( }
      \new Devnull { e8~ }
      \new Devnull { f8[ }
    >>
    
    \new Score <<
      \new NullVoice { c8( }
      \new NullVoice { d8\( }
      \new NullVoice { e8~ }
      \new NullVoice { f8[ }
    >>
    
    \new Score <<
      \new Voice { c8( }
      \new Voice { d8\( }
      \new Voice { e8~ }
      \new Voice { f8[ }
    >>
    

    Output:

    GNU LilyPond 2.18.2
    Processing `issue-5389.ly'
    Parsing...
    Interpreting music...
    Preprocessing graphical objects...
    Interpreting music...
    issue-5389.ly:11:22: warning: unterminated slur
      \new NullVoice { c8
                         ( }
    issue-5389.ly:14:22: warning: unterminated beam
      \new NullVoice { f8
                         [ }
    Preprocessing graphical objects...
    Interpreting music...
    issue-5389.ly:18:18: warning: unterminated slur
      \new Voice { c8
                     ( }
    issue-5389.ly:19:18: warning: unterminated phrasing slur
      \new Voice { d8
                     \( }
    issue-5389.ly:21:18: warning: unterminated beam
      \new Voice { f8
                     [ }
    Preprocessing graphical objects...
    programming error: Grob direction requested while calculation in progress.
    continuing, cross fingers
    Finding the ideal number of pages...
    Fitting music on 1 page...
    Drawing systems...
    programming error: system with empty extent
    continuing, cross fingers
    Layout output to `issue-5389.ps'...
    Converting to `./issue-5389.pdf'...
    Success: compilation successfully completed
    
     
  • Dan Eble

    Dan Eble - 2018-07-25

    A simple solution would be to go back to using Devnull for the part combiner's "null" Voice context; however, for it to work properly, Staff would need to accept Devnull as a child. Devnull should perhaps be added as an acceptable child of everything that accepts Voice and NullVoice. I'm having trouble imagining unintended consequences of that.

    The dissatisfying thing about it would be having two kinds of null voice contexts: one nominally-null voice context called NullVoice and one even-nuller voice context called Devnull.

     
    • David Kastrup

      David Kastrup - 2018-07-25

      "Dan Eble" eble@users.sourceforge.net writes:

      A simple solution would be to go back to using Devnull for the part
      combiner's "null" Voice context; however, for it to work properly,
      Staff would need to accept Devnull as a child. Devnull should perhaps
      be added as an acceptable child of everything that accepts Voice and
      NullVoice. I'm having trouble imagining unintended consequences of
      that.

      The point of Devnull is not to produce output. Some stuff is engraved
      at Staff level (like time and key signatures) and if Devnull can be a
      child of those, it can produce the respective output via those.

      --
      David Kastrup

       
      • Dan Eble

        Dan Eble - 2018-07-25

        Thanks. Then we could use a variation on that solution that leaves Devnull as it is and uses a new type of context (PartCombinerNullVoice?). Not very appealing, but it would silence the warning.

        There is another aspect of this issue that is deeper than the warning: the decision by the part combiner to mark a single note under a slur as "a2." I don't have Behind Bars in front of me, but I recall that Gould cautions against changing stemming in mid phrase.

        If the part combiner chose to keep the parts double-stemmed in this passage, the slurs would start and stop in their own Voice contexts and there would be no warning.

         
        • David Kastrup

          David Kastrup - 2018-07-25

          "Dan Eble" eble@users.sourceforge.net writes:

          Thanks. Then we could use a variation on that solution that leaves Devnull as it is and uses a new type of context (PartCombinerNullVoice?). Not very appealing, but it would silence the warning.

          There is another aspect of this issue that is deeper than the warning: the decision by the part combiner to mark a single note under a slur as "a2." I don't have Behind Bars in front of me, but I recall that Gould cautions against changing stemming in mid phrase.

          If the part combiner chose to keep the parts double-stemmed in this passage, the slurs would start and stop in their own Voice contexts and there would be no warning.

          One problem with the part combiner is that its principal purpose is to
          junk voicing and create something like a piano extract sound-alike.
          It is not the right tool for combining, say, flute I and flute II into
          one staff in a partitura since it does not reflect voicing in its output
          (and the Solo I, Solo II, a2 notes are not doing much more than papering
          over that fundamental restriction).

          If you want dependable two-voice output, you need to work with
          \voiceOne/\voiceTwo and their ilk.

          The basic operation of the part combiner as bouncing the material around
          a number of contexts is also not particularly appealing and leads to the
          spanner problem we are seeing here. It would probably be a better idea
          to create more usable cross-Voice spanner/stemming mechanisms than to
          fudge around with different null voice constructs here.

          --
          David Kastrup

           
  • Dan Eble

    Dan Eble - 2018-07-26
    • labels: --> partcombine
    • summary: Partcombine: partcombine warns erroneously for unterminated slur --> partcombine warns about unterminated slur
    • status: New --> Accepted
    • assigned_to: Dan Eble --> nobody
     
    • David Kastrup

      David Kastrup - 2018-07-26

      "Dan Eble" eble@users.sourceforge.net writes:

      • labels: --> partcombine
      • summary: Partcombine: partcombine warns erroneously for unterminated slur --> partcombine warns about unterminated slur
      • status: New --> Accepted
      • assigned_to: Dan Eble --> nobody
      • Comment:

      Summary:

      • the part combiner is a kluge
      • the unterminated slur was always there
      • Devnull didn't warn about it, but NullVoice does
      • an easy but ugly way to suppress the warning (probably) is to use a new context similar to Devnull but which is accepted wherever Voice is accepted

      Stupid question: why does it need to be accepted? If the point is to
      ignore events, being outside of the Staff hierarchy seems rather like an
      advantage than otherwise?

      --
      David Kastrup

       
      • Dan Eble

        Dan Eble - 2018-07-26

        A reasonable question. When it comes time to change contexts, the part combiner searches for the next context relative to the current context, and there are no special cases. If this were to escape the current Staff in a multi-staff score, it would not be able to recover.

        Context *
        Part_combine_part_iterator::find_voice (const string &id)
        {
          // Find a Voice among the siblings of the current outlet.  (Well, this might
          // also find a sibling's descendant, but that should not be a problem.)
          Context *c = get_outlet ()->get_parent_context ();
          if (c)
            return find_context_below (c, ly_symbol2scm("Voice"), id);
          programming_error ("no parent context");
          return 0;
        }
        
         
        • David Kastrup

          David Kastrup - 2018-07-27

          "Dan Eble" eble@users.sourceforge.net writes:

          A reasonable question. When it comes time to change contexts, the
          part combiner searches for the next context relative to the current
          context, and there are no special cases. If this were to escape the
          current Staff in a multi-staff score, it would not be able to recover.

          ~~~
          Context *
          Part_combine_part_iterator::find_voice (const string &id)
          {
          // Find a Voice among the siblings of the current outlet. (Well, this might
          // also find a sibling's descendant, but that should not be a problem.)
          Context *c = get_outlet ()->get_parent_context ();
          if (c)
          return find_context_below (c, ly_symbol2scm("Voice"), id);
          programming_error ("no parent context");
          return 0;
          }

          Well, that's the code since

          commit c962a0162c67d8b67593c848d08c9345c8b045f0
          Author: Dan Eble nine.fierce.ballads@gmail.com
          Date: Sat May 30 12:46:44 2015 -0400

          Issue 4485: Refactor \partcombine and \autochange iterators
          
          Move the \partcombine context state machine from C++ to Scheme and
          move the part-specific work into a new Part_combine_part_iterator.
          What remains in Part_combine_iterator is multi-measure rest handling.
          
          The part-specific work is now nothing more than changing context at
          specified times, which is basically what \autochange does.  There are
          still some differences, but most of the implementation of both is now
          in the common base Change_sequence_iterator.
          

          so it's apparently not an inherent part of the historic design. The
          question basically is whether "there are no special cases" does not come
          at a price here since the most reliable way to ignore all events
          definitely is moving out of the current Staff.

          --
          David Kastrup

           
          • Dan Eble

            Dan Eble - 2018-07-28

            The question is rather, does this unhelpful warning need to be silenced? If it needs to be silenced, I would attempt to do it with a special-purpose context rather than give back the gains that that round of changes in 2015 achieved.

             
            • David Kastrup

              David Kastrup - 2018-07-29

              Well, the warning is because of discarded content ending up in a place where it might make a difference.

              At any rate, "give back the gains" sounds like I was pitching for a reversal (which I wasn't) or was implying that the gains were irretrievably tied to working sub-Staff. I am not yet convinced that the bathwater has become so much a part of the baby that it is impossible to throw out.

               
              • Dan Eble

                Dan Eble - 2018-07-29

                There was another generalizing change I had in view, which I did not implement, but which I thought would assist in expanding the part combiner to processing more than two parts at once and allow them to migrate between staves. That change was to supply more information than a simple context ID in the property context-change-list that is read by Change_sequence_iterator.

                This might also involve some parallel improvements to the \change command. I don't have a very clear vision here, but it seems that Change_sequence_iterator could probably be replaced by a sequence of \change commands at some point and there would be fewer things to maintain.

                As it stands, the iterators for \autochange and \partcombine are derived from Change_sequence_iterator, and the derived iterators supply the type of context to find: Staff for \autochange, Voice for \partcombine.

                If you wanted to use Devnull contexts that are children of Score and still let the part combiner find the correct engraving Voice contexts again, giving the Change_sequence_iterator the information to navigate there is part of one possible solution. Another significant part of that solution is for the scheme portion of the part combiner to place that information in the context-change-list.

                 
  • Dan Eble

    Dan Eble - 2018-07-26

    Summary:

    • the part combiner is a kluge
    • the unterminated slur was always there
    • Devnull didn't warn about it, but NullVoice does
    • an easy but ugly way to suppress the warning (probably) is to use a new context similar to Devnull but which is accepted wherever Voice is accepted
     
MongoDB Logo MongoDB