use of com.xenoage.zong.musiclayout.spacing.SystemSpacing in project Zong by Xenoage.
the class StretchSystemsTest method createSystem.
/**
* Creates and returns a simple {@link SystemSpacing} using the
* given values.
*/
public static SystemSpacing createSystem(int stavesCount, float staffHeight, float staffDistance, float offsetY) {
float is = staffHeight / 5;
List<Staff> staves = alist(stavesCount);
for (int i = 0; i < stavesCount; i++) staves.add(new Staff(alist(), 5, is));
float[] staffDistances = new float[stavesCount - 1];
for (int i : range(stavesCount - 1)) staffDistances[i] = staffDistance;
return new SystemSpacing(CollectionUtils.<ColumnSpacing>alist(), 0, 0, 0, new StavesSpacing(staves, staffDistances, is), offsetY);
}
use of com.xenoage.zong.musiclayout.spacing.SystemSpacing in project Zong by Xenoage.
the class StretchSystemsTest method computeTest.
@Test
public void computeTest() {
// create a simple frame for testing
float usableHeight = 400;
int stavesCount = 2;
float staffHeight = 10;
float staffDistance = 30;
float offset1 = 0;
float offset2 = 100;
float offset3 = 200;
SystemSpacing system1 = createSystem(stavesCount, staffHeight, staffDistance, offset1);
SystemSpacing system2 = createSystem(stavesCount, staffHeight, staffDistance, offset2);
SystemSpacing system3 = createSystem(stavesCount, staffHeight, staffDistance, offset3);
FrameSpacing frame = new FrameSpacing(ilist(system1, system2, system3), new Size2f(10, usableHeight));
// apply strategy
testee.compute(frame, null);
// compare values
// remaining space is usable height - offset3 - (height of last system)
float remainingSpace = usableHeight - offset3 - system3.getHeightMm();
// the last two systems are moved down, each remainingSpace/2
float additionalSpace = remainingSpace / 2;
// compare new offsets
assertEquals(offset2 + 1 * additionalSpace, frame.getSystems().get(1).offsetYMm, df);
assertEquals(offset3 + 2 * additionalSpace, frame.getSystems().get(2).offsetYMm, df);
}
use of com.xenoage.zong.musiclayout.spacing.SystemSpacing in project Zong by Xenoage.
the class StretchMeasuresTest method createSystemWith1MeasureGrace.
/**
* Creates and returns a simple {@link SystemSpacing} with only one
* measure and three notes: two main notes and two grace notes between them.
*/
public static SystemSpacing createSystemWith1MeasureGrace(float offsetChord1, float offsetChord2, float offsetMeasureEnd, float graceDistance) {
Chord chord1 = chord(Companion.pi(0, 0, 4), Companion.fr(2, 4));
Chord chord2grace = graceChord(Companion.pi(1, 0, 4));
Chord chord3grace = graceChord(Companion.pi(2, 0, 4));
Chord chord4 = chord(Companion.pi(3, 0, 4), Companion.fr(2, 4));
Voice voice = new Voice(alist(chord1, chord2grace, chord3grace, chord4));
List<BeatOffset> beatOffsets = alist(new BeatOffset(Companion.fr(0, 4), offsetChord1), new BeatOffset(Companion.fr(2, 4), offsetChord2), new BeatOffset(Companion.fr(4, 4), offsetMeasureEnd));
float is = 1;
List<VoiceSpacing> voiceSpacings = alist(new VoiceSpacing(voice, is, alist(new ChordSpacing(new ChordNotation(chord1), beatOffsets.get(0).getBeat(), beatOffsets.get(0).getOffsetMm()), new ChordSpacing(new ChordNotation(chord2grace), beatOffsets.get(1).getBeat(), beatOffsets.get(1).getOffsetMm() - 2 * graceDistance), new ChordSpacing(new ChordNotation(chord3grace), beatOffsets.get(1).getBeat(), beatOffsets.get(1).getOffsetMm() - 1 * graceDistance), new ChordSpacing(new ChordNotation(chord4), beatOffsets.get(1).getBeat(), beatOffsets.get(1).getOffsetMm()))));
MeasureSpacing measureSpacing = new MeasureSpacing(atMeasure(0, 0), is, voiceSpacings, empty, null);
ColumnSpacing mcs = new ColumnSpacing(-1, alist(measureSpacing), beatOffsets, alist(new BeatOffset(Companion.fr(0, 4), 0), new BeatOffset(Companion.fr(4, 4), offsetMeasureEnd)));
SystemSpacing system = new SystemSpacing(alist(mcs), 0, 0, offsetMeasureEnd, null, 0);
return system;
}
use of com.xenoage.zong.musiclayout.spacing.SystemSpacing in project Zong by Xenoage.
the class WedgeStamper method stamp.
/**
* Creates a {@link WedgeStamping} for the given {@link Wedge} on the given staff.
* The start and end measure of the wedge may be outside the staff, then the
* wedge is clipped to the staff.
*/
public WedgeStamping stamp(Wedge wedge, StaffStamping staffStamping) {
SystemSpacing system = staffStamping.system;
Range systemMeasures = system.getMeasures();
// musical positions of wedge
MP p1 = MP.getMP(wedge);
MP p2 = MP.getMP(wedge.getWedgeEnd());
// clip start to staff
float x1Mm;
if (p1.measure < systemMeasures.getStart()) {
// begins before staff
x1Mm = system.getMeasureStartAfterLeadingMm(systemMeasures.getStart());
} else {
// begins within staff
x1Mm = system.getXMmAt(p1.getTime());
}
// clip end to staff
float x2Mm;
if (p2.measure > systemMeasures.getStop()) {
// ends after staff
x2Mm = system.getMeasureEndMm(systemMeasures.getStop());
} else {
// ends within staff
x2Mm = system.getXMmAt(p2.getTime());
}
// spread
float d1Is = 0;
float d2Is = 0;
float defaultSpreadIS = 1.5f;
if (wedge.getType() == WedgeType.Crescendo) {
d2Is = (wedge.getSpread() != null ? wedge.getSpread() : defaultSpreadIS);
} else if (wedge.getType() == WedgeType.Diminuendo) {
d1Is = (wedge.getSpread() != null ? wedge.getSpread() : defaultSpreadIS);
}
// custom horizontal position
Position customPos = asPosition(wedge.getPositioning());
float length = x2Mm - x1Mm;
if (customPos != null && customPos.x != null)
x1Mm = customPos.x;
x1Mm += Position.getRelativeX(customPos);
x2Mm = x1Mm + length;
// vertical position
float lp;
if (customPos != null && customPos.y != null)
lp = customPos.y;
else
lp = -6;
lp += Position.getRelativeY(customPos);
return new WedgeStamping(lp, x1Mm, x2Mm, d1Is, d2Is, staffStamping);
}
use of com.xenoage.zong.musiclayout.spacing.SystemSpacing in project Zong by Xenoage.
the class CursorOutput method write.
public JsonObject write(ScoreDoc doc) {
JsonObject ret = new JsonObject();
// create midi sequence and mp mappings
Score score = doc.getScore();
val seq = MidiConverter.convertToSequence(score, optionsForFileExport, new JseMidiSequenceWriter());
// save time map
JsonArray jsonMPs = new JsonArray();
val timeMap = seq.getTimeMap();
for (int iRep : range(timeMap.getRepetitionsCount())) {
for (val time : timeMap.getTimesSorted(iRep)) {
val midiTime = timeMap.getByRepTime(iRep, time);
JsonObject jsonMP = new JsonObject();
jsonMP.addProperty("measure", time.measure);
jsonMP.addProperty("beat", "" + time.beat);
jsonMP.addProperty("ms", midiTime.ms);
jsonMPs.add(jsonMP);
}
}
ret.add("mps", jsonMPs);
// collect data
int measuresCount = score.getMeasuresCount();
ArrayList<System> systems = new ArrayList<>();
ArrayList<Measure> measures = new ArrayList<>();
for (int i = 0; i < measuresCount; i++) {
measures.add(new Measure());
}
int systemCount = 0;
Layout layout = doc.getLayout();
for (int iPage : range(layout.getPages())) {
Page page = layout.getPages().get(iPage);
Size2f pageSize = page.getFormat().getSize();
for (Frame frame : page.getFrames()) {
if (frame instanceof ScoreFrame) {
Point2f absPos = frame.getAbsolutePosition();
float offsetX = absPos.x - frame.getSize().width / 2;
float offsetY = absPos.y - frame.getSize().height / 2;
ScoreFrameLayout sfl = ((ScoreFrame) frame).getScoreFrameLayout();
for (SystemSpacing systemSpacing : sfl.getFrameSpacing().getSystems()) {
// read system data
int systemIndex = systemCount + systemSpacing.getSystemIndexInFrame();
while (systems.size() - 1 < systemIndex) systems.add(new System());
System system = systems.get(systemIndex);
system.page = iPage;
system.top = (offsetY + systemSpacing.offsetYMm) / pageSize.height;
system.bottom = (offsetY + systemSpacing.offsetYMm + systemSpacing.getHeightMm()) / pageSize.height;
// read measure beats
float systemOffsetX = systemSpacing.marginLeftMm;
for (int iMeasure : systemSpacing.getMeasures()) {
Measure measure = measures.get(iMeasure);
measure.system = systemIndex;
measure.left = (offsetX + systemOffsetX + systemSpacing.getMeasureStartMm(iMeasure)) / pageSize.width;
measure.right = (offsetX + systemOffsetX + systemSpacing.getMeasureEndMm(iMeasure)) / pageSize.width;
for (BeatOffset bo : systemSpacing.getColumn(iMeasure).getBeatOffsets()) {
measure.beats.put(bo.getBeat(), (offsetX + systemOffsetX + bo.getOffsetMm()) / pageSize.width);
}
}
}
systemCount += sfl.getFrameSpacing().getSystems().size();
}
}
}
// save systems
JsonArray jsonSystems = new JsonArray();
for (int i = 0; i < systems.size(); i++) {
System system = systems.get(i);
JsonObject jsonSystem = new JsonObject();
jsonSystem.addProperty("number", i);
jsonSystem.addProperty("page", system.page);
jsonSystem.addProperty("top", system.top);
jsonSystem.addProperty("bottom", system.bottom);
jsonSystems.add(jsonSystem);
}
ret.add("systems", jsonSystems);
// save measures
JsonArray jsonMeasures = new JsonArray();
for (int i = 0; i < measuresCount; i++) {
Measure measure = measures.get(i);
JsonObject jsonMeasure = new JsonObject();
jsonMeasure.addProperty("number", i);
jsonMeasure.addProperty("system", measure.system);
jsonMeasure.addProperty("left", measure.left);
jsonMeasure.addProperty("right", measure.right);
// beats
JsonArray jsonBeats = new JsonArray();
ArrayList<Fraction> sortedBeats = new ArrayList<>(measure.beats.keySet());
Collections.sort(sortedBeats);
for (Fraction beat : sortedBeats) {
JsonObject jsonBeat = new JsonObject();
jsonBeat.addProperty("at", "" + beat);
jsonBeat.addProperty("x", measure.beats.get(beat));
jsonBeats.add(jsonBeat);
}
jsonMeasure.add("beats", jsonBeats);
jsonMeasures.add(jsonMeasure);
}
ret.add("measures", jsonMeasures);
// save time cursors
JsonArray jsonTCs = new JsonArray();
for (int iRep : range(timeMap.getRepetitionsCount())) {
for (val time : timeMap.getTimesSorted(iRep)) {
val midiTime = timeMap.getByRepTime(iRep, time);
JsonObject jsonTC = new JsonObject();
jsonTC.addProperty("time", midiTime.ms);
Measure measure = measures.get(time.measure);
System system = systems.get(measure.system);
jsonTC.addProperty("page", system.page);
jsonTC.addProperty("top", system.top);
jsonTC.addProperty("left", measure.beats.get(time.beat));
jsonTC.addProperty("bottom", system.bottom);
jsonTCs.add(jsonTC);
}
}
ret.add("timecursors", jsonTCs);
return ret;
}
Aggregations