package com.xenoage.zong.musiclayout.spacer.system.fill; import static com.xenoage.utils.collections.CList.ilist; import static com.xenoage.utils.collections.CollectionUtils.alist; import static com.xenoage.utils.math.Delta.df; import static com.xenoage.utils.math.Fraction.fr; import static com.xenoage.zong.core.music.Pitch.pi; import static com.xenoage.zong.core.music.chord.ChordFactory.chord; import static com.xenoage.zong.core.music.chord.ChordFactory.graceChord; import static com.xenoage.zong.core.position.MP.atMeasure; import static com.xenoage.zong.musiclayout.spacer.system.fill.StretchMeasures.stretchMeasures; import static com.xenoage.zong.musiclayout.spacing.ElementSpacing.empty; import static org.junit.Assert.assertEquals; import java.util.List; import org.junit.Test; import com.xenoage.zong.core.music.Voice; import com.xenoage.zong.core.music.chord.Chord; import com.xenoage.zong.musiclayout.notation.ChordNotation; import com.xenoage.zong.musiclayout.spacing.BeatOffset; import com.xenoage.zong.musiclayout.spacing.ChordSpacing; import com.xenoage.zong.musiclayout.spacing.ColumnSpacing; import com.xenoage.zong.musiclayout.spacing.LeadingSpacingMock; import com.xenoage.zong.musiclayout.spacing.MeasureSpacing; import com.xenoage.zong.musiclayout.spacing.SystemSpacing; import com.xenoage.zong.musiclayout.spacing.VoiceSpacing; /** * Tests for {@link StretchMeasures}. * * @author Andreas Wenger */ public class StretchMeasuresTest { private StretchMeasures testee = stretchMeasures; @Test public void computeTest() { //create an easy system for testing float leadingWidth = 4; float offsetBeat1 = 3; float offsetBeat2 = 7; float offsetBeat3 = 12; SystemSpacing system = createSystemWith1Measure(leadingWidth, offsetBeat1, offsetBeat2, offsetBeat3); //stretch the system float newWidth = 20; testee.compute(system, newWidth); //compare the result //since the leading spacing (4 spaces) is not scaled, the //remaining 12 spaces of the voices width have to be scaled float stretch = (newWidth - leadingWidth) / offsetBeat3; ColumnSpacing newCol = system.columns.get(0); //beat offsets assertEquals(offsetBeat1 * stretch, newCol.getBeatOffsets().get(0).getOffsetMm(), df); assertEquals(offsetBeat2 * stretch, newCol.getBeatOffsets().get(1).getOffsetMm(), df); //element spacings VoiceSpacing newVoice = newCol.measures.get(0).voices.get(0); assertEquals(offsetBeat1 * stretch, newVoice.elements.get(0).xIs, df); assertEquals(offsetBeat2 * stretch, newVoice.elements.get(1).xIs, df); } /** * Checking if the elements are stretched correctly in a simple system * where there are grace notes. The space between grace notes and their following * full chord may not be stretched. */ @Test public void computeSystemArrangementTestGrace() { //create an easy system for testing float offsetChord1 = 3; float offsetChord2 = 12; float offsetMeasureEnd = 16; float graceDistance = 2; SystemSpacing system = createSystemWith1MeasureGrace(offsetChord1, offsetChord2, offsetMeasureEnd, graceDistance); //stretch the system float newWidth = 28; testee.compute(system, newWidth); //compare the result ColumnSpacing newCol = system.columns.get(0); float stretch = (newWidth - +newCol.getLeadingWidthMm()) / offsetMeasureEnd; //beat offsets assertEquals(offsetChord1 * stretch, newCol.getBeatOffsets().get(0).getOffsetMm(), df); assertEquals(offsetChord2 * stretch, newCol.getBeatOffsets().get(1).getOffsetMm(), df); //element spacings VoiceSpacing newVoice = newCol.measures.get(0).voices.get(0); assertEquals(offsetChord1 * stretch, newVoice.elements.get(0).xIs, df); assertEquals(offsetChord2 * stretch - 2 * graceDistance, newVoice.elements.get(1).xIs, df); assertEquals(offsetChord2 * stretch - 1 * graceDistance, newVoice.elements.get(2).xIs, df); assertEquals(offsetChord2 * stretch, newVoice.elements.get(3).xIs, df); } /** * 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(pi(0, 0, 4), fr(2, 4)); Chord chord2 = chord(pi(1, 0, 4), fr(2, 4)); Voice voice = new Voice(alist(chord1, chord2)); List<BeatOffset> beatOffsets = alist(new BeatOffset(fr(1, 4), offsetBeat0), new BeatOffset( fr(3, 4), offsetBeat1), new BeatOffset(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(fr(0, 4), 0), new BeatOffset(fr(6, 4), offsetBeat2))); SystemSpacing system = new SystemSpacing(ilist(mcs), 0, 0, leadingWidth + offsetBeat2, null, 0); return system; } /** * 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(pi(0, 0, 4), fr(2, 4)); Chord chord2grace = graceChord(pi(1, 0, 4)); Chord chord3grace = graceChord(pi(2, 0, 4)); Chord chord4 = chord(pi(3, 0, 4), fr(2, 4)); Voice voice = new Voice(alist(chord1, chord2grace, chord3grace, chord4)); List<BeatOffset> beatOffsets = alist(new BeatOffset(fr(0, 4), offsetChord1), new BeatOffset( fr(2, 4), offsetChord2), new BeatOffset(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(fr(0, 4), 0), new BeatOffset(fr(4, 4), offsetMeasureEnd))); SystemSpacing system = new SystemSpacing(alist(mcs), 0, 0, offsetMeasureEnd, null, 0); return system; } }