Search in sources :

Example 1 with BeatOffset

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;
}
Also used : ChordNotation(com.xenoage.zong.musiclayout.notation.ChordNotation) ColumnSpacing(com.xenoage.zong.musiclayout.spacing.ColumnSpacing) SystemSpacing(com.xenoage.zong.musiclayout.spacing.SystemSpacing) ChordSpacing(com.xenoage.zong.musiclayout.spacing.ChordSpacing) MeasureSpacing(com.xenoage.zong.musiclayout.spacing.MeasureSpacing) BeatOffset(com.xenoage.zong.musiclayout.spacing.BeatOffset) VoiceSpacing(com.xenoage.zong.musiclayout.spacing.VoiceSpacing) ChordFactory.graceChord(com.xenoage.zong.core.music.chord.ChordFactory.graceChord) Chord(com.xenoage.zong.core.music.chord.Chord) Voice(com.xenoage.zong.core.music.Voice)

Example 2 with BeatOffset

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);
}
Also used : ElementSpacing(com.xenoage.zong.musiclayout.spacing.ElementSpacing) BeatOffset(com.xenoage.zong.musiclayout.spacing.BeatOffset) VoiceSpacing(com.xenoage.zong.musiclayout.spacing.VoiceSpacing) Test(org.junit.Test)

Example 3 with BeatOffset

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());
}
Also used : ElementSpacing(com.xenoage.zong.musiclayout.spacing.ElementSpacing) BeatOffset(com.xenoage.zong.musiclayout.spacing.BeatOffset) Test(org.junit.Test)

Example 4 with BeatOffset

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);
}
Also used : ElementSpacing(com.xenoage.zong.musiclayout.spacing.ElementSpacing) BeatOffset(com.xenoage.zong.musiclayout.spacing.BeatOffset) VoiceSpacing(com.xenoage.zong.musiclayout.spacing.VoiceSpacing) Test(org.junit.Test)

Example 5 with BeatOffset

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);
}
Also used : BarlineRepeat(com.xenoage.zong.core.music.barline.BarlineRepeat) BeatOffset(com.xenoage.zong.musiclayout.spacing.BeatOffset) Fraction(com.xenoage.utils.math.Fraction) Barline(com.xenoage.zong.core.music.barline.Barline)

Aggregations

BeatOffset (com.xenoage.zong.musiclayout.spacing.BeatOffset)16 ElementSpacing (com.xenoage.zong.musiclayout.spacing.ElementSpacing)10 VoiceSpacing (com.xenoage.zong.musiclayout.spacing.VoiceSpacing)9 Fraction (com.xenoage.utils.math.Fraction)6 Test (org.junit.Test)6 ColumnSpacing (com.xenoage.zong.musiclayout.spacing.ColumnSpacing)4 MeasureSpacing (com.xenoage.zong.musiclayout.spacing.MeasureSpacing)4 Voice (com.xenoage.zong.core.music.Voice)3 SystemSpacing (com.xenoage.zong.musiclayout.spacing.SystemSpacing)3 ColumnHeader (com.xenoage.zong.core.header.ColumnHeader)2 Chord (com.xenoage.zong.core.music.chord.Chord)2 ChordFactory.graceChord (com.xenoage.zong.core.music.chord.ChordFactory.graceChord)2 ChordNotation (com.xenoage.zong.musiclayout.notation.ChordNotation)2 ChordSpacing (com.xenoage.zong.musiclayout.spacing.ChordSpacing)2 ArrayList (java.util.ArrayList)2 JsonArray (com.google.gson.JsonArray)1 JsonObject (com.google.gson.JsonObject)1 Point2f (com.xenoage.utils.math.geom.Point2f)1 Size2f (com.xenoage.utils.math.geom.Size2f)1 Score (com.xenoage.zong.core.Score)1