Class MSplitter
MTreeSpec
, and the notation style
as a set of parameters, realized as instance of MSplitter.CheckedParameters
,
MTree.CheckedParameters
, MCover.CheckedParameters_approximate
and MCover.CheckedParameters_divide
.
The result includes a sequence of
RationalDuration.DottedBaseDuration
, representing
the note heads, additional beaming information and tuplet brackets.
The calculation includes (a) finding an initial cover, as executed by
MCover
,
and (b) merging these nodes to "dotted notation" or "sibling merge" etc., for
stylistic or ergonomic reasons.
Maintains as an internal cache a
Trie
.
Usage: (a) construct one new instance for any new combination of one
MTreeSpec
and the Parameter objects.
These are:
- an optional
MTree.CheckedParameters
, to modify the appearance of beams and brackets.
- One optional instance either of
MCover.CheckedParameters_divide
or - of
MCover.CheckedParameters_approximate
. This is passed down toMCover
to specify the kind of automated MTree expansion. - An optional
MSplitter.CheckedParameters
instance specifies the further processing of the initial coverage by merging, dotting, etc.
process(List)
/ process(List,List)
.
This returns a MSplitter.Result
object (possibly from cache).
From this, an inner instance of MSplitter.Result.WriteOut
must be constructed and the
abstract methods overridden to the desired behaviour; finally its
MSplitter.Result.WriteOut.process()
method is called.
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic class
Parameter setting which is checked for consistency and thus safely usable as argument.class
Represents one result of processing a sequence of qualified durations. -
Field Summary
Modifier and TypeFieldDescriptionprotected Trie<QualifiedRational,
MSplitter.Result> Cache which holds the split result for each particualr sequence of qualified Rationals.protected final Trie.Evaluator<QualifiedRational,
MSplitter.Result> Operator oncache
, needed for entering and retrieving cached keys and values.Internal cache.protected final Map<Rational,
List<RationalDuration.DottedBaseDuration>> protected final Map<Rational,
List<RationalDuration.DottedBaseDuration>> Internal cache.Stemend for negative dottings are inherited from the right-most merged node and must not be overwritten when summing up the durations of the morged nodes.protected final MTree
The growing metric tree.protected final MCover.CheckedParameters_approximate
Parameters for the "binary approximation" mode.protected final MCover.CheckedParameters_divide
Parameters for the "auto-divide" mode.protected final MSplitter.CheckedParameters
The parameters controling sibling merge, dotting, syncopas and hemiolas.protected final boolean
Whether the top-level node has a vanishing bracket. -
Constructor Summary
ConstructorDescriptionMSplitter
(MTreeSpec metricTreeSpec, MTree.CheckedParameters parameters_brackets, MCover.CheckedParameters_approximate parameters_approximate, MCover.CheckedParameters_divide parameters_divide, MSplitter.CheckedParameters parameters_explicit, MessageReceiver<SimpleMessage<?>> msg) Full constructor, specifying all parameters.MSplitter
(MTreeSpec metricTreeSpec, MessageReceiver<SimpleMessage<?>> msg) Simplified constructor, setting all to default but the metric tree spefication. -
Method Summary
Modifier and TypeMethodDescriptionfreeSectioning
(int i, boolean isSound) FIXME DOCprotected List<RationalDuration.DottedBaseDuration>
freeSectioning
(Rational rat, boolean isSound) Delivers a list ofRationalDuration.DottedBaseDuration
which add up to the given duration value.Returns the metric tree in its current state, as modified by all preceding metric splitting tasks.protected void
parseSiblingsAndDottings
(List<MTree> irep, boolean isPause, Set<MTree> printThem, Map<MTree, StemEnd> stemEnds) Delivers all nodes which shall appear in the notation as a symbol, in the output set argument "printThem".process
(List<QualifiedRational> eventStarts) Main entry method: process the (ascending) list of start time points and deliver a semantically sensible rendering plan.Main entry method: process the (ascending) list of start time points and deliver a semantically sensible rendering plan.(package private) void
splitDots_withBeams
(List<MTree> irep, Set<MTree> printThem, Map<MTree, StemEnd> stemEnds, int dotsCount, boolean dotsCountIsMax, int startPos, int endPos, boolean leftNotRight, boolean positiveDotting) Add nodes from Initial Coverage to result, representing a sequence of dotted values not exceeding maxDots.protected boolean
testForSyncopeAndHemiola
(List<MTree> irep, boolean isSound) Returns whether the node list, representing one event, can be replaced by one single symbol, due to syncope or hemiola rules.
-
Field Details
-
metricTree
The growing metric tree. Is initially constructed when this instance is constructed, and is modified whenever new divisions must be synthesized. -
topBracketIsVanishing
protected final boolean topBracketIsVanishingWhether the top-level node has a vanishing bracket. -
parameters_explicit
The parameters controling sibling merge, dotting, syncopas and hemiolas. -
parameters_divide
Parameters for the "auto-divide" mode. -
parameters_approximate
Parameters for the "binary approximation" mode. -
cache
Cache which holds the split result for each particualr sequence of qualified Rationals. (= rational duration and flag whether sound or pause) -
cacheEvaluator
Operator oncache
, needed for entering and retrieving cached keys and values. -
fromNegativeDotting
Stemend for negative dottings are inherited from the right-most merged node and must not be overwritten when summing up the durations of the morged nodes. -
freeSectionings_rat_sound
Internal cache. -
freeSectionings_rat_pause
-
freeSectionings_int_sound
Internal cache. See senzatempo 2013120500:0 0001 A 0 0001 A 0 0001 A 0 0001 A 0 0100 B 0 0100 B 0 1100 B 0 0100 B + 1 0000 C + 10 0000 C + 10 0000 C +100 0000 C --------- --------- --------- --------- 1 0101 21 10 0101 37 10 1101 45 100 0101 69 0 0011 0 0011 0 0011 0 0011 0 0100 0 0100 0 1100 0 0100 + 0 1110 + 01 1110 + 1 1110 + 11 1110 --------- --------- --------- --------- 1 0101 1 0101 10 1101 100 0101 0 0111 7 0 0111 7 0 1111 15 0 0111 7 + 0 1110 14 + 1 1110 30 + 1 1110 30 + 11 1110 62 --------- --------- --------- --------- 1 0101 21 1 0101 37 10 1101 45 100 0101 69
-
freeSectionings_int_pause
-
-
Constructor Details
-
MSplitter
Simplified constructor, setting all to default but the metric tree spefication. -
MSplitter
public MSplitter(MTreeSpec metricTreeSpec, MTree.CheckedParameters parameters_brackets, @Opt MCover.CheckedParameters_approximate parameters_approximate, @Opt MCover.CheckedParameters_divide parameters_divide, MSplitter.CheckedParameters parameters_explicit, MessageReceiver<SimpleMessage<?>> msg) Full constructor, specifying all parameters.- Parameters:
metricTreeSpec
- the specification of the metric treeparameters_brackets
- rules how to insert proportional brackets and beamsparameters_approximate
- rules for the "binary approximation" modeparameters_divide
- rules for the "synthesize divisions" modeparameters_explicit
- rules for sibling merge, dotting, syncopes etc.
-
-
Method Details
-
get_metricTree
Returns the metric tree in its current state, as modified by all preceding metric splitting tasks. -
process
Main entry method: process the (ascending) list of start time points and deliver a semantically sensible rendering plan. Seeprocess(List)
. -
process
Main entry method: process the (ascending) list of start time points and deliver a semantically sensible rendering plan. Processes a list of QualifiedRational (i.e. positive Rational and a Boolean is_sound_not_pause), and finds the list of nodes of theMTree
which must be printed to get a minimal representation in note symobles according to some historical standard note writing patterns. These patterns are realized by "Merge Transformations (MX)", which are sibling-merge (MX-S), dotted merge (MX-D), syncopation (XM-Y) and hemiola (MX-H). and called "siblings". The style is determined by theMTreeSpec
and the settings inMSplitter.CheckedParameters
given when constructing thisMSplitter
.Internally, first an "Initial Coverage" is found, which for each event gives the smallest set of nodes which partition the event's duration. Is automatic mode is supported, new alternative nodes will be constructed if the division factors needed are not yet found in the
MTree
.Output is the set of nodes which shall be printed in the rendering. More precisely: A note symbol shall appear at the start time point of all nodes contained in this set. All nodes which come out of mergings are directly d-writeable (=with one single A note symbol should not appear at the start time point of the nodes which are NOT in the set, but this is not always possible: The algorithm does not check the d-writability of nodes which are NOT the result of merging.
The duration of each symbol is the distance to the follower in this set (or to the end of the measure, resp.). The nodes which come out of merging correspond to more than one node of the Initial Coverage. For convenience, the calculated duration of the merge result is stored in the result object.
Any
MTree
contains already allMTree.EssentialBracket
s which are required by non-power-of-two denominators. These are considered by the MetricSplit merging process and be the final write-out. Additionally, nodes NOT merged, i.e. surviving from the Initial Coverage, may be not d-writeable due to the numerator of their duration. This (in the current implementation) will NOT be fixed by additionally inserted proportions (which could be a feasible alternative), but by writing their child nodes or by writing FreeSectionings. The difference must be found out when generating the symbol sequence by comparing the result set with the original tree.Some of the merge patterns applied here are "closed", ie. they put a condition on start- and end-point of the event and are applied if and only if they cover the whole event by one single notehead. Others are "open", put only a min condition on the extent, and their result can further be prolongated by tied notes. For instances, classically a syncope cannot be tied to another notehead, but a dotting can.
Enscribed into the metric tree, the patterns look as follows:
syncope = MX-Y, a closed pattern. The duration which is exactly as long as the parent metric node, but the event starts later. pTop / / / \ \ \.. toplevel: any division possible / \ p p2 p and its follower p2 must have identical lengths / \ / \ and div-counts [----[ index of start and follower identical > 0 (will be applied only if the duration of p is d-writable (e.g. for 1/8 or 15/16).
In case of p.div==2, the pattern may stretch over more than one intermediate levels, limited by max_level_syncope_2positive dotting = MX-D, an open pattern. pTop / / \ \ / x identical lengths on all levels / / \ x.div==2 required (but not for pTop.div) / x maximal dot count is limited by max_dots_positive. / / \ if exceeded, push dots up or down [----------[ negative dotting = MX-D, an open pattern. pTop / \ \ \ x \ identical lengths on all levels / \ \ x.div==2 required (but not for pTop.div) x \ maximal dot count is limited by max_dots_negative / \ \ if exceeded, push dots up or down [--------]
sibling merge = MX-S, an open pattern p (p.div >2) / | \ - x x ident.length, n*x.duration must be d-writeable [----] x - x [----]
In all patterns it holds that ...- Differences in the duration between siblings (candidates or parents of candidates) are always a barrier.
- Differences in their division number, i.e. their internal structure, in general are not.
- Rules for e-writability of the results are complicated (see user documentation and this (German language) article.
-
Most patterns are not applied when the result is not e-writable without furhter proportion brackets.FIXME LATER:
EXCEPT Dottings, which assume such a proportion will be applied when writing out! This requirement is stored in the setMSplitter.Result.additionalProportions
, which must be considered when programming any later write-out procedure.
FIXME hemiole_punct, syncope_punct requires an alternative metric tree, which would be selected automatically when searching for minimal number of symbols:P 2*3*(1/4) / \ P P / | \ / | \ x x X. Xz z P | 3*2*(1|4) / | \ P Q P / | / \ | \ /\ x x X. Xz z P 2*2*(1/4) / \ P P / \ / \ x X. X z P | 4*1/4 / / \ \ /\ x X. X z P | 1/4+(2*1/4)+1/4 / | \ / Q \ / / \ \ x X. X z etc. 5*2*1/4|1/4+4*2*1/4+1/4 5*2*1/4|1/4+2*1/4+1/4+3*2*1/4|1/2+1/4+2*1/4+1/4+2*1/2| etc.
-
testForSyncopeAndHemiola
Returns whether the node list, representing one event, can be replaced by one single symbol, due to syncope or hemiola rules. Is currently NOT called with pauses. Syncopes and hemioles are CLOSED patterns, i.e. only applied when start AND end points match certain criteria. So they can be checked once, before all other patterns, and only the FACT WHETHER they are found must be returned: Iff true, the reaction of the caller is to enter only the first node into the printed set, etc.
Any denominator !=2^n can be ignored, because it has to be realized by an n-tuplet-notation anyhow (on some higher level).
Returning true requires that the duration of the new note is e-writable (under the current EB-stack, i.e. only w.r.t. the numerator).- Parameters:
irep
- the complete initial representation for one event, which shall be simplified
-
splitDots_withBeams
void splitDots_withBeams(List<MTree> irep, Set<MTree> printThem, Map<MTree, StemEnd> stemEnds, int dotsCount, boolean dotsCountIsMax, int startPos, int endPos, boolean leftNotRight, boolean positiveDotting) Add nodes from Initial Coverage to result, representing a sequence of dotted values not exceeding maxDots. The caller guarantees e-printability for the comprehension of (a) "dotCounts+1" nodes exactly, if "dotCountsIsMax==false"; else for all numbers of nodes <= "dotCount+1"negative positive N N i=in Initial Coverage / \ / \ N Xi Xi N / \ / \ N Xi Xi N / \ / \ N Ni Ni X ---][^^^^^^^^^^^] [^^^^^^^^^]
The whole interval of nodes is given by startpos to endpos (INCLUSIVE). LeftNotRight says on which side to begin the grouping, i.e. on which side the most dots will be found if splitting them is necessary.
LeftNotRight = PositiveDotting XOR parameters.push_dots_down_not_up
BEAMING:
pos dots -> nothing necessary.
neg dots -> shift beams of the last node of every joined group to the first (=representant) of this groupe. -
parseSiblingsAndDottings
protected void parseSiblingsAndDottings(List<MTree> irep, boolean isPause, Set<MTree> printThem, Map<MTree, StemEnd> stemEnds) Delivers all nodes which shall appear in the notation as a symbol, in the output set argument "printThem". Filters out the subsequent nodes which shall not appear with an own symbol. (As a consequence, their durations must be added to the predecessor when writing out, in some later processing step.)Assumes that the input is an Initial Coverage, i.e. adjacent and maximal nodes. Therefore the possible patterns are rather limited, which fact is exploited.
Assumes that the closed patterns (syncope, hemiola, etc.) have already been tested for, with negatove result.The patterns to look for are ...
ppp / / \ \ \ n n+ pp pp / \ / \ / \ n p / \ / \ n [-------------------] positive dotting [----------------------] double pos. dotting [-------------] siblings [------------------] ppp / / \ \ \ +pp n n / \ / \ / \ +p n / \ n n [--------------] double neg. dotting [-----] negative dotting [--------------] siblings Jumps over more than one level imply => no simplification is possible; ppp / / \ \ \ pp N pp \ / \ / \ p p / \ / \ n n [---------] [-------------]
In a first step for every node (except the very first) the kind of move is determined:- up: from a nephew to an uncle, iff nephew.parent.div==2
- down: from an uncle to a nephew, iff nephew.parent.div==2
- horizontal: from sibling to sibling, iff durations identical
- jump: all others (no pattern ever spans a jump)
parent.div==2
and the maximality of the coverage nodes it follows that- before "up" there may be no "down" or "horizontal", and
- after "down" there may be no "up" or "horizontal".
up-up-..-hori-hori-.. down-down pp / \ \ \ / \ \ \ p [] [] p / \ -------- / \ [] / hori \ [] /up \ down i0 i1 i2 i3 .... i0 again phase 0 1 3 4=flush i1 = last of neg.dot, first of siblings i2 = last of siblings, first of pos.dot
But there may be more than one such pattern in the same event:moves: up--up--hori--down-down- hori--down / / \ initial P P P cover: / \ / \ p p p / \ / | \ p q q q /\ X event: [----------------------------]
(Not all appearing patterns can have all phases, because after a down can never come an up, because this would imply a gap in the time cover, or a node with only one child.) -
freeSectioning
Delivers a list ofRationalDuration.DottedBaseDuration
which add up to the given duration value. The calculation of this list is controlled by style parameters, therefore the cache must be maintained specifically, with this MSplitter instanve. -
freeSectioning
FIXME DOC
-