use of com.xenoage.zong.core.position.Time in project Zong by Xenoage.
the class DynamicsFinder method findStaffDynamics.
/**
* Walk through the measures of the given staff and repetition and find the dynamics.
* Starts with the given initial dynamic. Returns the dynamic value at the end of the
* repetition.
*/
private DynamicValue findStaffDynamics(int staff, int repetition, DynamicValue startDynamics) {
val rep = repetitions.get(repetition);
// walk through the measures
Time currentStartTime = rep.start;
DynamicsType currentDynamic = new FixedDynamics(startDynamics);
for (int iMeasure : range(rep.start.getMeasure(), rep.end.getMeasure())) {
if (iMeasure >= score.getMeasuresCount())
break;
val measure = score.getMeasure(atMeasure(staff, iMeasure));
for (val beat : measure.getDirections().getBeats()) {
val newTime = Companion.time(iMeasure, beat);
DynamicsType newDynamic = null;
// if beat is out of the repetition range, ignore it
if (false == rep.contains(newTime))
continue;
// find dynamics change
if (currentDynamic instanceof GradientDynamics) {
// wedge ending at this beat?
val closedWedge = getWedgeEndAt(staff, newTime, (GradientDynamics) currentDynamic);
if (closedWedge != null) {
currentDynamic = closedWedge;
// continue with the end dynamic of the wedge
newDynamic = new FixedDynamics(closedWedge.end);
}
} else if (newDynamic == null) {
// new dynamic starting? then close currently open period and open new one
newDynamic = getStaffDynamicStartAt(staff, newTime, currentDynamic.getEndValue());
}
// when change was found, apply it
if (newDynamic != null) {
if (false == currentStartTime.equals(newTime) && false == currentDynamic.equals(newDynamic)) {
val period = new DynamicsPeriod(currentStartTime, newTime, currentDynamic);
periods.addPeriodToStaff(period, staff, repetition);
currentStartTime = newTime;
}
currentDynamic = newDynamic;
}
}
}
// close the dynamics period at the end of the repetition
val period = new DynamicsPeriod(currentStartTime, rep.end, currentDynamic);
periods.addPeriodToStaff(period, staff, repetition);
return currentDynamic.getEndValue();
}
use of com.xenoage.zong.core.position.Time in project Zong by Xenoage.
the class DynamicsPeriods method get.
/**
* Gets the {@link DynamicsPeriod} for the given position.
* The highest priority has a dynamic in the current voice. If there is none,
* the last dynamic of the part is searched. When there are multiple candidates
* on different staves, the current staff wins.
* @param mp the position where to find the dynamic
* @param repetition the index of the {@link Repetition}
* @param partStaves the staves indices in the part
*/
@MaybeNull
public DynamicsPeriod get(MP mp, int repetition, Range partStaves) {
val time = mp.getTime();
// first, find voice dynamics
val voicePeriods = getVoicePeriods(mp.getStaff(), mp.getVoice(), repetition);
val voicePeriod = getPeriod(voicePeriods, time);
if (voicePeriod != null)
return voicePeriod;
// then, for all staves in the part, look for last period(s) - when there
// is more than one at the same time, prefer the one at the own staff
Time maxStartTime = time;
DynamicsPeriod bestMatch = null;
for (int iStaff : partStaves) {
val staffPeriods = getStaffPeriods(mp.getStaff(), repetition);
val staffPeriod = getPeriod(staffPeriods, time);
int compare = staffPeriod.startTime.compareTo(maxStartTime);
if (staffPeriod != null && compare > 0 || (compare >= 0 && iStaff == mp.getStaff())) {
// new best match
maxStartTime = staffPeriod.startTime;
bestMatch = null;
}
}
return bestMatch;
}
use of com.xenoage.zong.core.position.Time in project Zong by Xenoage.
the class Repetitions method mergeRepetitions.
static IList<Repetition> mergeRepetitions(List<Repetition> repetitions) {
CList<Repetition> merged = clist();
// merge consecutive repetitions
Time start = null;
Time end = null;
for (val repetition : repetitions) {
if (start == null) {
// first repetition
start = repetition.start;
end = repetition.end;
} else if (repetition.start.equals(end)) {
// this repetition begins at the ending of the last one; continue it
end = repetition.end;
} else {
// new repetition found. remember old one and start new one
merged.add(new Repetition(start, end));
start = repetition.start;
end = repetition.end;
}
}
if (start != null) {
// close last repetition
merged.add(new Repetition(start, end));
}
return merged.close();
}
use of com.xenoage.zong.core.position.Time in project Zong by Xenoage.
the class RepetitionsFinder method processBackwardRepeat.
/**
* Processes the given backward repeat {@link Barline} at the given {@link Time}.
* When another repeat is to be played, a {@link Jump} is added to
* the jump list, the current measure and start beat are modified
* and true is returned.
* Otherwise false is returned.
*/
private boolean processBackwardRepeat(Barline barline, Time barlineTime) {
int counter = notNull(barlineRepeatCounter.get(barlineTime), 0);
if (counter < barline.getRepeatTimes()) {
// repeat. jump back to last forward repeat
if (// do not count repeats at volta end
false == isVoltaEndAt(barlineTime))
barlineRepeatCounter.put(barlineTime, counter + 1);
Time to = findLastForwardRepeatTime(barlineTime);
addJump(barlineTime, to);
return true;
} else {
// finished, delete counter
barlineRepeatCounter.remove(barlineTime);
return false;
}
}
use of com.xenoage.zong.core.position.Time in project Zong by Xenoage.
the class RepetitionsFinder method find.
private Repetitions find() {
ArrayList<Repetition> ranges = alist();
this.voltaGroups = new VoltaGroupFinder(score).findAllVoltaGroups();
Time start = Companion.time(0, Companion.get_0());
Time end = Companion.time(score.getMeasuresCount(), Companion.get_0());
collectJumps();
if (jumps.size() == 0) {
// simple case: no jumps
ranges.add(new Repetition(start, end));
} else {
// one or more jumps
ranges.add(new Repetition(start, jumps.get(0).from));
for (int i : range(1, jumps.size() - 1)) {
Time lastEnd = jumps.get(i - 1).to;
Time currentStart = jumps.get(i).from;
ranges.add(new Repetition(lastEnd, currentStart));
}
ranges.add(new Repetition(jumps.get(jumps.size() - 1).to, end));
}
return new Repetitions(ranges);
}
Aggregations