use of com.xenoage.zong.musiclayout.spacing.BeatOffset in project Zong by Xenoage.
the class StretchMeasuresTest method createSystemWith1Measure.
/**
* Creates and returns a simple {@link SystemSpacing} with only one
* measure with a clef and two notes, using the given parameters.
* @param leadingWidth width of the leading spacing in mm
* @param offsetBeat0 offset of beat 1/4 in mm
* @param offsetBeat1 offset of beat 3/4 in mm
* @param offsetBeat2 width of the voice spacing in mm
*/
public static SystemSpacing createSystemWith1Measure(float leadingWidth, float offsetBeat0, float offsetBeat1, float offsetBeat2) {
Chord chord1 = chord(Companion.pi(0, 0, 4), Companion.fr(2, 4));
Chord chord2 = chord(Companion.pi(1, 0, 4), Companion.fr(2, 4));
Voice voice = new Voice(alist(chord1, chord2));
List<BeatOffset> beatOffsets = alist(new BeatOffset(Companion.fr(1, 4), offsetBeat0), new BeatOffset(Companion.fr(3, 4), offsetBeat1), new BeatOffset(Companion.fr(5, 4), offsetBeat2));
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(chord2), beatOffsets.get(1).getBeat(), beatOffsets.get(1).getOffsetMm()))));
MeasureSpacing measureSpacing = new MeasureSpacing(atMeasure(0, 0), is, voiceSpacings, empty, LeadingSpacingMock.createGClefSpacing(leadingWidth));
List<MeasureSpacing> measureSpacings = alist(measureSpacing);
ColumnSpacing mcs = new ColumnSpacing(-1, measureSpacings, beatOffsets, alist(new BeatOffset(Companion.fr(0, 4), 0), new BeatOffset(Companion.fr(6, 4), offsetBeat2)));
SystemSpacing system = new SystemSpacing(ilist(mcs), 0, 0, leadingWidth + offsetBeat2, null, 0);
return system;
}
use of com.xenoage.zong.musiclayout.spacing.BeatOffset in project Zong by Xenoage.
the class AlignedVoicesSpacerTest method computeTest1.
@Test
public void computeTest1() {
float is = 2;
// voice spacing:
// beats: ..2.4..78
// offsets: | | ||
// | | |⌎- 6
// | | ⌎-- 4
// | ⌎----- 2
// ⌎------- 1
VoiceSpacing voiceSpacing = new VoiceSpacing(Companion.voice(), is, alist(spacing(beat(2), 1f), spacing(beat(4), 2f), spacing(beat(7), 4f), spacing(beat(8), 6f)));
// given beat offsets:
// beats: 0...4...8
// offsets: | | |
// | | ⌎- 20
// | ⌎----- 8
// ⌎--------- 0
List<BeatOffset> beatOffsets = alist(new BeatOffset(beat(0), 0f), new BeatOffset(beat(4), 8f), new BeatOffset(beat(8), 20f));
// shared beats: 4, 8.
//
// resulting spacing:
// beats: ..2.4..78
// offsets: | | ||
// | | |⌎- (20 - 8) / (6 - 2) * (6 - 2) + 8 = 20 } (shared beats 4 and 8)
// | | ⌎-- (20 - 8) / (6 - 2) * (4 - 2) + 8 = 14 } (shared beats 4 and 8)
// | ⌎----- (8 - 0) / (2 - 0) * (2 - 0) + 0 = 8 } (shared beats 0 and 4)
// ⌎------- (8 - 0) / (2 - 0) * (1 - 0) + 0 = 4 } (shared beats 0 and 4)
testee.compute(voiceSpacing, beatOffsets);
List<ElementSpacing> finalSpacing = voiceSpacing.elements;
assertEquals(4, finalSpacing.size());
assertEquals(beat(2), finalSpacing.get(0).beat);
assertEquals(4f / is, finalSpacing.get(0).xIs, df);
assertEquals(beat(4), finalSpacing.get(1).beat);
assertEquals(8f / is, finalSpacing.get(1).xIs, df);
assertEquals(beat(7), finalSpacing.get(2).beat);
assertEquals(14f / is, finalSpacing.get(2).xIs, df);
assertEquals(beat(8), finalSpacing.get(3).beat);
assertEquals(20f / is, finalSpacing.get(3).xIs, df);
}
use of com.xenoage.zong.musiclayout.spacing.BeatOffset in project Zong by Xenoage.
the class AlignedVoicesSpacerTest method testComputeSharedBeats.
@Test
public void testComputeSharedBeats() {
// list 1 beats: 0 3 789
// list 2 beats: 0 5 7 9
// shared beats: 0 7 9
List<ElementSpacing> list1 = alist(spacing(beat(0), 0f), spacing(beat(3), 0f), spacing(beat(7), 0f), spacing(beat(8), 0f), spacing(beat(9), 0f));
List<BeatOffset> list2 = alist(new BeatOffset(beat(0), 0f), new BeatOffset(beat(5), 0f), new BeatOffset(beat(7), 0f), new BeatOffset(beat(9), 0f));
List<BeatOffset> res = testee.computeSharedBeats(list1, list2);
assertEquals(3, res.size());
assertEquals(beat(0), res.get(0).getBeat());
assertEquals(beat(7), res.get(1).getBeat());
assertEquals(beat(9), res.get(2).getBeat());
// list 1 beats: 01 3
// list 2 beats: 2 4
// shared beats: (none)
list1 = alist(spacing(beat(0), 0f), spacing(beat(1), 0f), spacing(beat(3), 0f));
list2 = alist(new BeatOffset(beat(2), 0f), new BeatOffset(beat(4), 0f));
res = testee.computeSharedBeats(list1, list2);
assertEquals(0, res.size());
// list 1 beats: 000033
// list 2 beats: 0123
// shared beats: 0 and 3 (no duplicate values!)
list1 = alist(spacing(beat(0), 0f), spacing(beat(0), 0f), spacing(beat(0), 0f), spacing(beat(0), 0f), spacing(beat(3), 0f), spacing(beat(3), 0f));
list2 = alist(new BeatOffset(beat(0), 0f), new BeatOffset(beat(1), 0f), new BeatOffset(beat(2), 0f), new BeatOffset(beat(3), 0f));
res = testee.computeSharedBeats(list1, list2);
assertEquals(2, res.size());
assertEquals(beat(0), res.get(0).getBeat());
assertEquals(beat(3), res.get(1).getBeat());
}
use of com.xenoage.zong.musiclayout.spacing.BeatOffset in project Zong by Xenoage.
the class AlignedVoicesSpacerTest method computeTestGrace.
/**
* Tests the strategy with a voice that uses grace notes.
* The distance of grace notes to their main notes should not be stretched,
* but should stay the same.
*/
@Test
public void computeTestGrace() {
float is = 2;
// voice spacing:
// beats: 0.2...gg8
// offsets: | | |||
// | | ||⌎- 60
// | | |⌎-- 59 (grace note)
// | | ⌎--- 58 (grace note)
// | ⌎------- 51
// ⌎--------- 50
VoiceSpacing voiceSpacing = new VoiceSpacing(Companion.voice(), is, alist(spacing(beat(0), 0f), spacing(beat(2), 1f), graceSpacing(beat(8), 8f), graceSpacing(beat(8), 9f), spacing(beat(8), 10f)));
// given beat offsets:
// beats: 0.......8
// offsets: | |
// | ⌎- 30
// ⌎--------- 10
List<BeatOffset> beatOffsets = alist(new BeatOffset(beat(0), 10f), new BeatOffset(beat(8), 30f));
// shared beats: 4, 8.
//
// resulting spacing:
// beats: 0.2...gg8
// offsets: | | |||
// | | ||⌎- (30 - 10) / (60 - 50) * (60 - 50) + 10 = 30 = x } (shared beats 0 and 8)
// | | |⌎-- x - (10 - 9) = 30 - (1 * IS) = 28 (because it is a grace note in front of x)
// | | ⌎--- x - (10 - 8) = 30 - (2 * IS) = 26 (because it is a grace note in front of x)
// | ⌎------- (30 - 10) / (60 - 50) * (51 - 50) + 10 = 12 } (shared beats 0 and 8)
// ⌎--------- (30 - 10) / (60 - 50) * (50 - 50) + 10 = 10 } (shared beats 0 and 8)
testee.compute(voiceSpacing, beatOffsets);
List<ElementSpacing> finalSpacing = voiceSpacing.elements;
assertEquals(5, finalSpacing.size());
assertEquals(beat(0), finalSpacing.get(0).beat);
assertEquals(10f / is, finalSpacing.get(0).xIs, df);
assertEquals(beat(2), finalSpacing.get(1).beat);
assertEquals(12f / is, finalSpacing.get(1).xIs, df);
assertEquals(beat(8), finalSpacing.get(2).beat);
assertEquals(26f / is, finalSpacing.get(2).xIs, df);
assertEquals(beat(8), finalSpacing.get(3).beat);
assertEquals(28f / is, finalSpacing.get(3).xIs, df);
assertEquals(beat(8), finalSpacing.get(4).beat);
assertEquals(30f / is, finalSpacing.get(4).xIs, df);
}
use of com.xenoage.zong.musiclayout.spacing.BeatOffset in project Zong by Xenoage.
the class BarlinesBeatOffsetter method compute.
public Result compute(List<BeatOffset> baseOffsets, ColumnHeader columnHeader, float maxInterlineSpace) {
ArrayList<BeatOffset> retNotes = alist(baseOffsets);
ArrayList<BeatOffset> retBarlines = alist();
// start barline
retBarlines.add(new BeatOffset(Fraction.Companion.get_0(), 0));
Barline startBarline = columnHeader.getStartBarline();
if (startBarline != null && startBarline.getRepeat() == BarlineRepeat.Forward) {
// forward repeat: move all beats REPEAT_SPACE IS backward
float move = repeatSpace * maxInterlineSpace;
for (int i = 0; i < retNotes.size(); i++) {
BeatOffset oldOffset = retNotes.get(i);
retNotes.set(i, new BeatOffset(oldOffset.getBeat(), oldOffset.getOffsetMm() + move));
}
}
// mid-measure barlines
for (BeatE<Barline> midBarline : columnHeader.getMiddleBarlines()) {
// get beat of barline, find it in the note offsets and move the following ones
Fraction beat = midBarline.getBeat();
int i = 0;
float move = 0;
for (; i < retNotes.size(); i++) {
if (retNotes.get(i).getBeat().compareTo(beat) >= 0) {
BarlineRepeat repeat = midBarline.getElement().getRepeat();
if (repeat == BarlineRepeat.Backward) {
// backward repeat: additional space before barline
move += repeatSpace * maxInterlineSpace;
BeatOffset oldOffset = retNotes.get(i);
retBarlines.add(new BeatOffset(oldOffset.getBeat(), oldOffset.getOffsetMm() + move));
} else if (repeat == BarlineRepeat.Forward) {
// forward repeat: additional space after barline
BeatOffset oldOffset = retNotes.get(i);
retBarlines.add(new BeatOffset(oldOffset.getBeat(), oldOffset.getOffsetMm() + move));
move += repeatSpace * maxInterlineSpace;
} else if (repeat == BarlineRepeat.Both) {
// forward and backward repeat: additional space before and after barline
move += repeatSpace * maxInterlineSpace;
BeatOffset oldOffset = retNotes.get(i);
retBarlines.add(new BeatOffset(oldOffset.getBeat(), oldOffset.getOffsetMm() + move));
move += repeatSpace * maxInterlineSpace;
} else {
retBarlines.add(retNotes.get(i));
}
move += midBarlineSpace * maxInterlineSpace;
break;
}
}
for (; i < retNotes.size(); i++) {
// move following notes
BeatOffset oldOffset = retNotes.get(i);
retNotes.set(i, new BeatOffset(oldOffset.getBeat(), oldOffset.getOffsetMm() + move));
}
}
// end barline
BeatOffset lastOffset = retNotes.get(retNotes.size() - 1);
Barline endBarline = columnHeader.getEndBarline();
if (endBarline != null && endBarline.getRepeat() == BarlineRepeat.Backward) {
// backward repeat: additional space before end barline
float move = repeatSpace * maxInterlineSpace;
retBarlines.add(new BeatOffset(lastOffset.getBeat(), lastOffset.getOffsetMm() + move));
} else {
retBarlines.add(lastOffset);
}
// return result
retBarlines.trimToSize();
return new Result(retNotes, retBarlines);
}
Aggregations