lilypond-devel
[Top][All Lists]
Advanced

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

Re: Part Combiner


From: Kristof Bastiaensen
Subject: Re: Part Combiner
Date: Tue, 30 Aug 2005 03:01:14 +0200
User-agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.7 (Sanjō) APEL/10.6 MULE XEmacs/21.4 (patch 17) (Jumbo Shrimp) (i386-debian-linux)

At Mon, 29 Aug 2005 23:51:06 +0200,
Han-Wen Nienhuys wrote:
> 
> Kristof Bastiaensen wrote:
> > I am not sure if I could do something about this.  Perhaps I could
> > refactor the code a bit to make it clearer to understand.  Especially
> > the final part is too complicated.  I am considering if some kind of a
> > pattern-matcher could simplify the whole thing.
> > 
> > If there are comments that don't make sense, I would gladly modify
> > them.
> 
> To me, the new code reads like a long list of small function 
> definitions. It's difficult to tell how the different parts are related.
>

Yes, I wrote it that way because I believe it is easier to understand
many little functions that one monolithic block.  This is a style that
is actually prefered by most scheme programmers.  I had included a
roadmap in the source that documents the general structure, and the
source follows that structure.  The different parts are:

- a list is made for the notes and the spanners containing the start
and end moment for each item (the note-lengths and spanner-lengths
functions).

- various information is extracted from the event-lists, like the
position in the measure for each moment (measure-positions), the
limits for blocks as calculated from the measure lengths
(measure-limits), the longest voice and the end-moment of that voice
(music-end+longest).

- input and output configurations are calculated between both voices
from those lists (as explained in the roadmap).  This is in the
(probably not so well named :-/) function make-type-context-list.
(Perhaps I should rename it to make-configuration-list).

- Some merges are prevented to keep the flow of voices inside
measures (fix-rests-in-measures!).

- Changes in output configuration are only allowed for blocks that
have a large enough size (i.e. to avoid change from a due to solo and
back in one measure) (fix-blocks!).

The way the last two fases work is commented extensively in the source.

This structure can also be seen clearly from the definition of the
toplevel determine-split-list function:

(define-public (determine-split-list evl1 evl2)
  "EVL1 and EVL2 should be ascending"
  (multi-let*
      ((moments (merge-moments evl1 evl2))
       (notes1 (note-lengths evl1))
       (notes2 (note-lengths evl2))
       (span1 (spanner-lengths evl1))
       (span2 (spanner-lengths evl2))
       (measurepos (measure-positions moments evl1 evl2))
       (music-end longest (music-end+longest evl1 evl2))
       (measurelimits (measure-limits longest))
       (types (make-type-context-list moments notes1 notes2
                                      span1 span2 measurepos
                                      measurelimits)))
    (fix-rests-in-measures! types #f #f)
    (let loop ()
      (if (fix-blocks! types #f #t music-end)
          (if (fix-rests-in-measures! types #f #f)
              loop)))
    (synthesize-types types)))

> >>In addition, the whole design of the part-combiner will be trashed
> >>anyway when we have sensible music stream datastructures (see the
> >>mail in lilypond-devel by Erik S)
> >>
> > 
> > 
> > That looks interesting.  The music-stream datastructure looks to me
> > like an AST (Abstract Syntax Tree) for a compiler.  Many functional
> > languages (Haskell, Ocaml, SML) are based on such datatypes, and their
> > type-system makes handling such AST's especially easy, together with
> > other features like pattern-matching on types.
> 
> Yes, but it's not. You should rather think of a MIDI file, but
> 
>   - with rational numbers iso. ticks
>   - with events suitable for typesetting
>   - without arbitrary limits.
>

Ok, I hope to learn more about it when there is more info (or is there
already?).

> > It doesn't have as far as I know (as much as that is possible to say
> > about new code).  The regression tests that came with the previous
> > part-combiner will not work anymore, but that is deliberatly.  My
> > part-combiner only makes changes (from and to solo, a due, ...) for
> > larger blocks (with a rather complicated algorithm to determine the
> > beginning and end of blocks).  That is to prevent to many changes from
> > happening in a short time, making the score more cluttered and less
> > readable.  The regression tests are all small fragments, and my
> > part-combiner will likely put the whole fragment apart, a due or solo.
> 
> But the thresholds can be tuned, no? For the regtest, you could tune 
> them down, so we can still verify whether everything works.
>

Erm, actually not, but making it tunable would be a trivial change.

> Also, it would be helpful if we could have the new and current 
> partcombiner together for a couple of release so we can see the 
> differences, and get some feedback.
>

Yes.

> 
> --
>   Han-Wen Nienhuys - address@hidden - http://www.xs4all.nl/~hanwen




reply via email to

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