[Top][All Lists]
[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