public class DottedNotationExpander extends Object
T 1 2 VOX Alt c. d e. (f fis) g ..aExactly two(<=2) events are affected by dot notation: an event with trailing dots and its successor, or an event with leading dots and its predecessor. This is called "positive" and "negative" dotting. Only one of two neighbouring events may carry a dot. The event with the dots will become longer. The second of both events must have a "floating" notation of its starting time, i.e. not bound to a time point in the time line, because this start time will be changed by the dotting.
T 1 2 3 4 5 VOX Alt a. b c .d e f. g h i // posit. negative invalid, because "g" is fixed to a point in the time line "T" // allowed, "event g" is NOT positioned at "Tp 4": VOX Ten e (f. g ) h i
For this behaviour, an instance of this class can be constructed and
applied to a voice (more precisely: to the list of events of this voice in source order),
after this voice has been built when the containing
Part
has been parsed by
Util.parseTimeScape(File, Modifiers, MessageReceiver)
and before the start time information of the events of this
voice are calculated.
(E.g. by
Util.getRationalValue(Function, Map,Tp,MessageReceiver,Map)
.
--- see the source text of Score_cwn
as an example.)
The implementation here is somehow hacky: A text transformation is applied
to a sequence of events
which is still in source text sequential order of one monodic voice.
The dotted event and its successor/predecessor must lie in the same
time division and occupy the same duration.
(The latter is currently not yet checked !)
Then a new division is created, which divides their sum duration by four/eight/sixteen, etc.,
depending on the number of dots.
Then it distributes the interval in the requested proportion:
1+3, 1+7, 1+15, etc., for negative dotting,
iff the dots are leading in the second event,
or 3+1 , 7+1, 15+1 etc., for positive dotting,
iff the dots are trailing in the first event.
This transformation has to be called before any "duration per event" is calculated.
The dots characters are removed from the parameter values, and all further
processing can happen as if the proportions had been notated explicitly. e.g by
parantheses:
a.. b ==> a(-(- b))The following situations can occur:
ALLOWED: a .b a. b .a b. ERRORS: .a. a. b. a. .b ALLOWED a. (b. ) ( .b) .a ERRORS: a (.b ) ( a.) b
Modifier and Type | Field and Description |
---|---|
(package private) String |
dotString
The terminal string representing the prolongation dot.
|
(package private) String |
mainParamName
The name of the main parameter of the voice, corrsponding to the "
VOX .. " line
and defining the time points of the events. |
(package private) MessageReceiver<SimpleMessage<XMLDocumentIdentifier>> |
msg
Drain of all messages.
|
(package private) boolean |
ok
Output register of
parseOne(Event) : if dot combinations are legal. |
(package private) int |
postDots
Output register of
parseOne(Event) : dots to the right of the current event. |
(package private) int |
preDots
Output register of
parseOne(Event) : dots to the left of the current event. |
(package private) Map<TDivision,TDivision> |
tdiv2shifted
Temporary map for all time divisions affected by a dotting.
|
(package private) Map<TpSub,TpSub> |
tpsub2shifted
Temporary map for all time points affected by a dotting.
|
Constructor and Description |
---|
DottedNotationExpander(MessageReceiver<SimpleMessage<XMLDocumentIdentifier>> msg,
String dotString,
String mainParamName)
Public constructor, must be called before calling
apply(List) . |
Modifier and Type | Method and Description |
---|---|
void |
apply(List<Event> events)
Service access point, called from outside.
|
protected void |
clearDots(Event ev,
boolean leftIsDotted,
int dotcount)
The dotted event must be a simple one (no parenthesis), and the dots part must
be part of the text of the main parameter.
|
protected @Opt TDivision |
getTdivshifted(TDivision tdiv)
Return new, shifted divison, or null iff tdivision is NOT affected by shift.
|
protected @Opt TpSub |
getTpsubshifted(TpSub tpsub)
Returns new, shifted TpSub, or null iff tdivision is NOT affected by shift.
|
(package private) boolean |
isLastInDivision(Tp tp)
Returns whether the time point is the very last in its containing division.
|
protected void |
parseOne(Event ev)
Sets global output values and makes some syntax check.
|
protected void |
replace(List<Event> events,
int indexRight,
Event left,
Event right,
int dotcount,
boolean leftIsDotted)
Central function for adjusting the time structure according to a
dotted rhythm.
|
(package private) boolean |
sameLevel(Event left,
Event right)
Returns whether both events have their time point in the same time point division.
|
protected boolean |
testEvent(Event ev)
Returns whether the Event is affected.
|
final MessageReceiver<SimpleMessage<XMLDocumentIdentifier>> msg
final String dotString
final String mainParamName
VOX ..
" line
and defining the time points of the events.int preDots
parseOne(Event)
: dots to the left of the current event.int postDots
parseOne(Event)
: dots to the right of the current event.boolean ok
parseOne(Event)
: if dot combinations are legal.final Map<TpSub,TpSub> tpsub2shifted
public DottedNotationExpander(MessageReceiver<SimpleMessage<XMLDocumentIdentifier>> msg, String dotString, String mainParamName)
apply(List)
.dotString
- a String of length=1
which represents one single dot (normally = ".")mainParamName
- the paramter track name to which the modifications will
be applied.protected void parseOne(Event ev)
boolean sameLevel(Event left, Event right)
public void apply(List<Event> events)
a. .b
),
and applies timepoint adjustment.boolean isLastInDivision(Tp tp)
protected void replace(List<Event> events, int indexRight, Event left, Event right, int dotcount, boolean leftIsDotted)
a. b x a. (b c ) x a. (b (c. d) ) x //OR negative case a .b x (a a) .b x // ERROR, not the same TDivision: a. (b (.c d) ) x (a a.) bSearch process is as follows:
tpSomewhere tpLeft tpRight --> tpNewRight | tpNewRight<---- | ------tDDiv------ | tp tp | --tDDiv--------------------------| tp tp tp | -----tDiv--- tXALL events at ALL tp's must be shifted, up to the first "tX" which lies totally to the right side of tpRight, thus is not affected by shifting.
protected final boolean testEvent(Event ev)
@Opt protected @Opt TpSub getTpsubshifted(TpSub tpsub)
@Opt protected @Opt TDivision getTdivshifted(TDivision tdiv)
protected void clearDots(Event ev, boolean leftIsDotted, int dotcount)