Search in sources :

Example 16 with Fraction

use of com.xenoage.utils.math.Fraction in project Zong by Xenoage.

the class MidiConverter method writeMetronomeTrack.

/**
 * Writes the metronome beats into the metronome track.
 */
private void writeMetronomeTrack(int track) {
    int strongBeatNote = options.midiSettings.metronomeStrongBeatNote;
    int weakBeatNote = options.midiSettings.metronomeWeakBeatNote;
    for (int iRep : range(repetitions)) {
        val rep = repetitions.get(iRep);
        for (int iMeasure : range(rep.start.getMeasure(), rep.end.getMeasure())) {
            TimeSignature timeSig = score.getHeader().getTimeAtOrBefore(iMeasure);
            Fraction startBeat = (rep.start.getMeasure() == iMeasure ? rep.start.getBeat() : Companion.get_0());
            Fraction endBeat = (rep.end.getMeasure() == iMeasure ? rep.end.getBeat() : score.getMeasureBeats(iMeasure));
            if (timeSig != null) {
                boolean[] accentuation = timeSig.getType().getBeatsAccentuation();
                int timeDenominator = timeSig.getType().getDenominator();
                long measureStartTick = timeMap.getByRepTime(iRep, Companion.time(iMeasure, Companion.get_0())).tick;
                for (int beatNumerator : range(timeSig.getType().getNumerator())) {
                    // compute start and stop tick
                    val beat = Companion.fr(beatNumerator, timeDenominator);
                    val time = Companion.time(iMeasure, beat);
                    if (false == rep.contains(time))
                        continue;
                    long tickStart = measureStartTick + durationToTick(Companion.fr(beatNumerator, timeDenominator), resolution);
                    long tickStop = tickStart + durationToTick(Companion.fr(1, timeDenominator), resolution);
                    // write metronome note
                    int note = (accentuation[beatNumerator] ? strongBeatNote : weakBeatNote);
                    int velocity = midiMaxValue;
                    writer.writeNote(track, channel10, tickStart, note, true, velocity);
                    writer.writeNote(track, channel10, tickStop, note, false, 0);
                }
            }
        }
    }
}
Also used : lombok.val(lombok.val) Fraction(com.xenoage.utils.math.Fraction) TimeSignature(com.xenoage.zong.core.music.time.TimeSignature)

Example 17 with Fraction

use of com.xenoage.utils.math.Fraction in project Zong by Xenoage.

the class RepetitionsFinder method collectJumps.

/**
 * Creates the list of jumps for this score.
 */
private void collectJumps() {
    // if not null, the next segno will jump back to this one
    Segno lastSegno = null;
    // in the next volta group, jump to this repeat number
    int lastVoltaCounter = 1;
    Fraction measureStartBeat = null;
    nextMeasure: for (currentMeasureIndex = 0; currentMeasureIndex < score.getMeasuresCount(); ) {
        val measure = score.getColumnHeader(currentMeasureIndex);
        // are we stuck within an endless loop? then do not jump at all.
        if (jumps.size() > maxJumps) {
            jumps.clear();
            return;
        }
        // enter a volta
        if (voltaGroups.getVoltaGroupStartingAt(currentMeasureIndex) != null)
            if (processVolta())
                continue nextMeasure;
        // inner backward repeat barlines
        if (isWithRepeats) {
            for (val e : getInnerBarlines()) {
                val innerBarline = e.getElement();
                val eTime = Companion.time(currentMeasureIndex, e.getBeat());
                if (innerBarline.getRepeat().isBackward())
                    if (processBackwardRepeat(innerBarline, eTime))
                        continue nextMeasure;
            }
        }
        // backward repeat at measure end
        val endBarline = measure.getEndBarline();
        val endTime = Companion.time(currentMeasureIndex + 1, Companion.get_0());
        if (isWithRepeats && endBarline != null) {
            if (endBarline.getRepeat().isBackward()) {
                // ignore it at the end of the final volta of a volta group, otherwise we are stuck in an endless loop
                if (false == isFinalVoltaAt(currentMeasureIndex))
                    if (processBackwardRepeat(endBarline, endTime))
                        continue nextMeasure;
            }
        }
        // origin navigation sign
        // we read them after the backward repeat barlines. e.g. when there is both
        // a repeat and a "to coda", we first play the repeat and then the "to coda".
        val sign = measure.getNavigationOrigin();
        if (sign != null) {
            // da capo ,
            if (MusicElementType.DaCapo.is(sign))
                if (processDaCapo((DaCapo) sign))
                    continue nextMeasure;
            // target segno
            if (MusicElementType.Segno.is(sign))
                if (processSegno((Segno) sign))
                    continue nextMeasure;
            // to coda
            if (MusicElementType.Coda.is(sign))
                if (processCoda((Coda) sign))
                    continue nextMeasure;
        }
        // no jump found in this measure, continue
        currentMeasureIndex++;
        currentMeasureStartBeat = null;
    }
}
Also used : lombok.val(lombok.val) Interval(com.xenoage.zong.core.music.util.Interval) Segno(com.xenoage.zong.core.music.direction.Segno) Fraction(com.xenoage.utils.math.Fraction)

Example 18 with Fraction

use of com.xenoage.utils.math.Fraction in project Zong by Xenoage.

the class SystemSpacing method getMpAt.

/**
 * Gets the {@link MP} at the given horizontal position in mm.
 * If the given staff is {@link MP#unknown}, all beats of the column
 * are used, otherwise only the beats used by the given staff.
 *
 * If it is between two beats (which will be true almost ever), the
 * the right mark is selected (like it is usual e.g. in text
 * processing applications). If it is behind all known beats of the
 * hit measure, the last known beat is returned.
 *
 * If it is not within the boundaries of a measure, {@link MP#unknownMp} is returned.
 */
public MP getMpAt(float xMm, int staff) {
    // find the measure
    int measureIndex = getSystemMeasureIndexAt(xMm);
    float xMmInMeasure = xMm - getMeasureStartMm(measureIndex);
    // when measure was not found, return null
    if (measureIndex == unknown)
        return unknownMp;
    // get the beat at the given position
    Fraction beat = columns.get(measureIndex).getBeatAt(xMmInMeasure, staff);
    return atBeat(staff, measureIndex, unknown, beat);
}
Also used : Fraction(com.xenoage.utils.math.Fraction)

Example 19 with Fraction

use of com.xenoage.utils.math.Fraction in project Zong by Xenoage.

the class MidiVelocityConverterTry method createTestScore.

public static Score createTestScore() {
    Score ret = new Score();
    Instrument instr = Instrument.Companion.getDefaultInstrument();
    Part pianoPart = new Part("Test", "T", 1, ilist(instr));
    new PartAdd(ret, pianoPart, 0, null).execute();
    Cursor cursor = new Cursor(ret, mp0, true);
    cursor.write((ColumnElement) new TraditionalKey(-3));
    cursor.write((ColumnElement) new TimeSignature(Companion.timeType(3, 4)));
    cursor.write(new Clef(ClefType.Companion.getClefTreble()));
    Fraction f4 = Companion.fr(1, 4);
    Chord attachC;
    cursor.write(attachC = chord(f4, Pitch.Companion.pi(Pitch.Companion.getG(), 4)));
    attachC.addDirection(new Dynamic(DynamicValue.pp));
    cursor.write(attachC = chord(f4, Pitch.Companion.pi(Pitch.Companion.getA(), 4)));
    attachC.addDirection(new Dynamic(DynamicValue.ff));
    cursor.write(attachC = chord(f4, Pitch.Companion.pi(Pitch.Companion.getG(), 4)));
    attachC.addDirection(new Dynamic(DynamicValue.sfp));
    /*
		Chord chord;
		Voice voice = measure.getVoices().get(0);
		chord = voice.addNote(pi'G', 0, 4), fr(1, 4));
		chord.addDirection(new Dynamic(DynamicsType.pp));
		
		

		chord = voice.addNote(pi'A', 0, 4), fr(1, 4));
		chord.addDirection(new Dynamic(DynamicsType.ff));

		chord = voice.addNote(pi'G', 0, 4), fr(1, 4));
		chord.addDirection(new Dynamic(DynamicsType.sfp));
		*/
    cursor.setMp(mp0.withVoice(1));
    cursor.write(attachC = chord(f4, Pitch.Companion.pi(Pitch.Companion.getC(), 4)));
    attachC.addDirection(new Dynamic(DynamicValue.fff));
    /*
		voice = measure.addVoice();
		
		chord = voice.addNote(pi'C', 0, 4), fr(1, 4));
		chord.addDirection(new Dynamic(DynamicsType.fff));
		*/
    cursor.setMp(mp0.withMeasure(1));
    cursor.write(attachC = chord(f4, Pitch.Companion.pi(Pitch.Companion.getG(), 4)));
    // cursor.withScore(ScoreController.attachElement(cursor.getScore(), attachC, new Dynamic(DynamicsType.pp)));
    cursor.write(attachC = chord(f4, Pitch.Companion.pi(Pitch.Companion.getA(), 4)));
    attachC.addDirection(new Dynamic(DynamicValue.pp));
    cursor.write(attachC = chord(f4, Pitch.Companion.pi(Pitch.Companion.getG(), 4)));
    attachC.addDirection(new Dynamic(DynamicValue.pp));
    cursor.setMp(cursor.getMP().withElement(0).withVoice(1));
    cursor.write(attachC = chord(f4, Pitch.Companion.pi(Pitch.Companion.getC(), 5)));
    /*		
		measure = staff.getMeasures().get(1);

		voice = measure.getVoices().get(0);
		chord = voice.addNote(pi'G', 0, 4), fr(1, 4));
		//chord.addDirection(new Dynamic(DynamicsType.pp));

		chord = voice.addNote(pi'A', 0, 4), fr(1, 4));
		chord.addDirection(new Dynamic(DynamicsType.pp));

		chord = voice.addNote(pi'G', 0, 4), fr(1, 4));
		chord.addDirection(new Dynamic(DynamicsType.pp));

		voice = measure.addVoice();
		chord = voice.addNote(pi'C', 0, 5), fr(1, 4));
		*/
    cursor.setMp(mp0.withMeasure(2));
    cursor.write(attachC = chord(f4, Pitch.Companion.pi(Pitch.Companion.getG(), 4)));
    attachC.addDirection(new Dynamic(DynamicValue.sfz));
    cursor.write(chord(f4, Pitch.Companion.pi(Pitch.Companion.getA(), 4)));
    // cursor = cursor.withScore(ScoreController.attachElement(cursor.getScore(), attachC, new Dynamic(DynamicsType.pp)));
    cursor.write(chord(f4, Pitch.Companion.pi(Pitch.Companion.getG(), 4)));
    // cursor = cursor.withScore(ScoreController.attachElement(cursor.getScore(), attachC, new Dynamic(DynamicsType.pp)));
    cursor.setMp(mp0.withMeasure(2).withVoice(2));
    cursor.write(chord(f4, Pitch.Companion.pi(Pitch.Companion.getC(), 5)));
    /*
		measure = staff.getMeasures().get(2);

		
		voice = measure.getVoices().get(0);
		chord = voice.addNote(pi'G', 0, 4), fr(1, 4));
		chord.addDirection(new Dynamic(DynamicsType.sfz));

		chord = voice.addNote(pi'A', 0, 4), fr(1, 4));
		//chord.addDirection(new Dynamic(DynamicsType.pp));

		chord = voice.addNote(pi'G', 0, 4), fr(1, 4));
		//chord.addDirection(new Dynamic(DynamicsType.pp));
		
		voice = measure.addVoice();
		voice = measure.addVoice();
		chord = voice.addNote(pi'C',0,5), fr(1,2));

		*/
    return cursor.getScore();
}
Also used : Score(com.xenoage.zong.core.Score) Dynamic(com.xenoage.zong.core.music.direction.Dynamic) Part(com.xenoage.zong.core.music.Part) Instrument(com.xenoage.zong.core.instrument.Instrument) PartAdd(com.xenoage.zong.commands.core.music.PartAdd) Clef(com.xenoage.zong.core.music.clef.Clef) Fraction(com.xenoage.utils.math.Fraction) TraditionalKey(com.xenoage.zong.core.music.key.TraditionalKey) Cursor(com.xenoage.zong.io.selection.Cursor) Chord(com.xenoage.zong.core.music.chord.Chord) TimeSignature(com.xenoage.zong.core.music.time.TimeSignature)

Example 20 with Fraction

use of com.xenoage.utils.math.Fraction in project Zong by Xenoage.

the class AlignedVoicesSpacer method computeSharedBeats.

/**
 * Returns the shared beats of the given {@link ElementSpacing}s and {@link BeatOffset}s.
 * If there are no beats used by both lists, an empty list is returned.
 */
public List<BeatOffset> computeSharedBeats(List<ElementSpacing> spacingElements, List<BeatOffset> beatOffsets) {
    ArrayList<BeatOffset> ret = alist(Math.min(spacingElements.size(), beatOffsets.size()));
    int iElement = 0, iBeat = 0;
    Fraction lastAddedBeat = Companion.fr(-1);
    while (iElement < spacingElements.size() && iBeat < beatOffsets.size()) {
        Fraction elementBeat = spacingElements.get(iElement).beat;
        BeatOffset beatOffset = beatOffsets.get(iBeat);
        if (elementBeat.equals(beatOffset.beat)) {
            if (beatOffset.beat.equals(lastAddedBeat)) {
                // when this beat was already added, replace it. the
                // rightmost offset is the offset we need.
                ret.set(ret.size() - 1, beatOffset);
            } else {
                ret.add(beatOffset);
            }
            lastAddedBeat = beatOffset.beat;
            iElement++;
        } else if (elementBeat.compareTo(beatOffset.beat) > 0) {
            iBeat++;
        } else {
            iElement++;
        }
    }
    return ret;
}
Also used : BeatOffset(com.xenoage.zong.musiclayout.spacing.BeatOffset) Fraction(com.xenoage.utils.math.Fraction)

Aggregations

Fraction (com.xenoage.utils.math.Fraction)32 BeatOffset (com.xenoage.zong.musiclayout.spacing.BeatOffset)6 Chord (com.xenoage.zong.core.music.chord.Chord)5 ElementSpacing (com.xenoage.zong.musiclayout.spacing.ElementSpacing)5 lombok.val (lombok.val)5 Voice (com.xenoage.zong.core.music.Voice)4 Measure (com.xenoage.zong.core.music.Measure)3 VoiceElement (com.xenoage.zong.core.music.VoiceElement)3 Clef (com.xenoage.zong.core.music.clef.Clef)3 TraditionalKey (com.xenoage.zong.core.music.key.TraditionalKey)3 TimeSignature (com.xenoage.zong.core.music.time.TimeSignature)3 VoiceSpacing (com.xenoage.zong.musiclayout.spacing.VoiceSpacing)3 ColumnElementWrite (com.xenoage.zong.commands.core.music.ColumnElementWrite)2 Score (com.xenoage.zong.core.Score)2 Part (com.xenoage.zong.core.music.Part)2 Note (com.xenoage.zong.core.music.chord.Note)2 Rest (com.xenoage.zong.core.music.rest.Rest)2 ChordNotation (com.xenoage.zong.musiclayout.notation.ChordNotation)2 JsonArray (com.google.gson.JsonArray)1 JsonObject (com.google.gson.JsonObject)1