Search in sources :

Example 6 with Clef

use of com.xenoage.zong.core.music.clef.Clef in project Zong by Xenoage.

the class ScoreTest method createTestScoreClefsKeys.

/**
 * Creates a score with a single staff, two measures,
 * and a number of clefs, keys and chords.
 * The score, the list of clefs and the list of keys is returned.
 */
private Tuple3<Score, List<ClefType>, List<Key>> createTestScoreClefsKeys() {
    // create two measures:
    // clef-g, key-Gmaj, C#1/4, clef-f, Db1/4, clef-g, key-Fmaj, Cnat1/4 |
    // C#1/4, key-Cmaj, clef-f, C2/4.
    Score score = ScoreFactory.create1Staff();
    new MeasureAdd(score, 1).execute();
    List<ClefType> clefs = alist();
    List<Key> keys = alist();
    ClefType c;
    Key k;
    // measure 0
    Measure measure = score.getMeasure(atMeasure(0, 0));
    new Clef(ClefType.clefTreble);
    clefs.add(c = ClefType.clefTreble);
    new MeasureElementWrite(new Clef(c), measure, fr(0, 4)).execute();
    keys.add(k = new TraditionalKey(1, Mode.Major));
    new MeasureElementWrite(k, measure, fr(0, 4)).execute();
    new VoiceElementWrite(measure.getVoice(0), atElement(0, 0, 0, 0), chord(pi(0, 1, 4), fr(1, 4)), null).execute();
    clefs.add(c = ClefType.clefBass);
    new MeasureElementWrite(new Clef(c), measure, fr(1, 4)).execute();
    new VoiceElementWrite(measure.getVoice(0), atElement(0, 0, 0, 1), chord(pi(1, -1, 4), fr(1, 4)), null).execute();
    clefs.add(c = ClefType.clefTreble);
    new MeasureElementWrite(new Clef(c), measure, fr(2, 4)).execute();
    keys.add(k = new TraditionalKey(-1, Mode.Major));
    new MeasureElementWrite(k, measure, fr(2, 4)).execute();
    new VoiceElementWrite(measure.getVoice(0), atElement(0, 0, 0, 2), chord(pi(0, 0, 4), fr(1, 4)), null).execute();
    // measure 1
    measure = score.getMeasure(atMeasure(0, 1));
    new VoiceElementWrite(measure.getVoice(0), atElement(0, 1, 0, 0), chord(pi(0, 1, 4), fr(1, 4)), null).execute();
    keys.add(k = new TraditionalKey(0, Mode.Major));
    new MeasureElementWrite(k, measure, fr(1, 4)).execute();
    clefs.add(c = ClefType.clefBass);
    new MeasureElementWrite(new Clef(c), measure, fr(1, 4)).execute();
    new VoiceElementWrite(measure.getVoice(0), atElement(0, 1, 0, 1), chord(pi(0, 0, 4), fr(2, 4)), null).execute();
    return t3(score, clefs, keys);
}
Also used : ClefType(com.xenoage.zong.core.music.clef.ClefType) Clef(com.xenoage.zong.core.music.clef.Clef) TraditionalKey(com.xenoage.zong.core.music.key.TraditionalKey) TraditionalKey(com.xenoage.zong.core.music.key.TraditionalKey) Key(com.xenoage.zong.core.music.key.Key)

Example 7 with Clef

use of com.xenoage.zong.core.music.clef.Clef in project Zong by Xenoage.

the class MeasureElementsSpacer method compute.

List<ElementSpacing> compute(BeatEList<Clef> clefs, @MaybeEmpty BeatEList<Key> keys, @MaybeNull TimeSignature time, boolean existsLeadingSpacing, List<VoiceSpacing> voiceSpacings, int staff, Notations notations, LayoutSettings layoutSettings) {
    Key key0 = null;
    if (keys.size() > 0 && keys.getFirst().beat.equals(_0))
        key0 = keys.getFirst().element;
    if (key0 == null && time == null && (clefs == null || clefs.size() == 0)) {
        // nothing to do
        return empty;
    }
    ArrayList<ElementSpacing> ret = alist();
    float startOffset = layoutSettings.offsetMeasureStart;
    // key and time
    // ************
    boolean isKey = !existsLeadingSpacing && key0 instanceof TraditionalKey;
    boolean isTime = time != null;
    if (isKey || isTime) {
        float currentOffset = startOffset;
        // ***
        if (isKey) {
            Notation keyNotation = notations.get(key0, staff);
            ret.add(new SimpleSpacing(keyNotation, _0, startOffset));
            currentOffset += keyNotation.getWidth().getUsedWidth();
        }
        // ****
        if (time != null) {
            Notation timeNotation = notations.get(time, staff);
            ret.add(new SimpleSpacing(timeNotation, _0, currentOffset + timeNotation.getWidth().symbolWidth / 2));
            currentOffset += timeNotation.getWidth().getUsedWidth();
        }
        // move voice elements, if not enough space before first voice element
        ElementSpacing leftSE = getFirstElementSpacing(voiceSpacings);
        if (leftSE != null) {
            float leftSEx = getLeftX(leftSE);
            // existing space
            float ES = leftSEx;
            // additional needed space
            float AS = currentOffset - ES;
            if (AS > 0) {
                shift(voiceSpacings, AS);
                startOffset += AS;
            }
        }
    }
    // voice 2:       1             o
    if (clefs != null) {
        for (BeatE<Clef> ME : clefs) {
            Fraction MEb = ME.beat;
            Notation MEnotation = notations.get(ME.element);
            float MEwidth = MEnotation.getWidth().getWidth();
            // if there is a leading spacing, ignore elements at beat 0
            if (existsLeadingSpacing && !MEb.isGreater0())
                continue;
            // find VE1 and VE2 for the current element
            ElementSpacing[] ses = getNearestSpacingElements(MEb, voiceSpacings);
            ElementSpacing VE1 = ses[0], VE2 = ses[1];
            // if VE1 is unknown, use startOffset. if VE2 is unknown, ignore this element
            float VE1x = (VE1 != null ? getRightX(VE1) : startOffset);
            if (VE2 == null)
                continue;
            float VE2x = getLeftX(VE2);
            // existing space
            float ES = VE2x - VE1x - 2 * layoutSettings.spacings.widthDistanceMin;
            if (ES < MEwidth) {
                // additional space needed
                float AS = MEwidth - ES;
                // move all elements at or after ME.beat
                VE2x += AS;
                shiftAfterBeat(voiceSpacings, AS, MEb);
            }
            // add measure element
            float MEx = VE2x - layoutSettings.spacings.widthDistanceMin - MEwidth / 2;
            ret.add(new SimpleSpacing(MEnotation, ME.beat, MEx));
        }
    }
    ret.trimToSize();
    return ret;
}
Also used : ElementSpacing(com.xenoage.zong.musiclayout.spacing.ElementSpacing) SimpleSpacing(com.xenoage.zong.musiclayout.spacing.SimpleSpacing) Clef(com.xenoage.zong.core.music.clef.Clef) Fraction(com.xenoage.utils.math.Fraction) TraditionalKey(com.xenoage.zong.core.music.key.TraditionalKey) Notation(com.xenoage.zong.musiclayout.notation.Notation) TraditionalKey(com.xenoage.zong.core.music.key.TraditionalKey) Key(com.xenoage.zong.core.music.key.Key)

Example 8 with Clef

use of com.xenoage.zong.core.music.clef.Clef in project Zong by Xenoage.

the class LeadingSpacer method compute.

/**
 * Computes the {@link LeadingSpacing} for the current measure.
 */
public LeadingSpacing compute(Context context, Notations notations) {
    float xOffset = context.settings.offsetMeasureStart;
    boolean useKey = false;
    MusicContext musicContext = context.getMusicContext(At, null);
    Key key = musicContext.getKey();
    if (key instanceof TraditionalKey) {
        useKey = true;
    }
    List<ElementSpacing> elements = alist(useKey ? 2 : 1);
    // it is not the same element instance, but has the same meaning
    Clef clef = new Clef(musicContext.getClef());
    ClefNotation clefNotation = new ClefNotation(clef, new ElementWidth(0, context.settings.spacings.widthClef, 0), musicContext.getClef().getLp(), 1);
    notations.add(clefNotation);
    xOffset += context.settings.spacings.widthClef / 2;
    elements.add(new SimpleSpacing(clefNotation, fr(0), xOffset));
    xOffset += context.settings.spacings.widthClef / 2;
    if (useKey) {
        TraditionalKey tkey = (TraditionalKey) key;
        xOffset += context.settings.spacings.widthDistanceMin;
        // it is not the same element instance, but has the same meaning
        TraditionalKey tradKey = new TraditionalKey(tkey.getFifths(), tkey.getMode());
        TraditionalKeyNotation keyNotation = traditionalKeyNotator.compute(tradKey, context);
        notations.add(keyNotation);
        elements.add(new SimpleSpacing(keyNotation, fr(0), xOffset));
        xOffset += keyNotation.getWidth().getWidth();
    }
    return new LeadingSpacing(elements, xOffset);
}
Also used : ElementWidth(com.xenoage.zong.musiclayout.spacing.ElementWidth) LeadingSpacing(com.xenoage.zong.musiclayout.spacing.LeadingSpacing) SimpleSpacing(com.xenoage.zong.musiclayout.spacing.SimpleSpacing) Clef(com.xenoage.zong.core.music.clef.Clef) ClefNotation(com.xenoage.zong.musiclayout.notation.ClefNotation) TraditionalKey(com.xenoage.zong.core.music.key.TraditionalKey) MusicContext(com.xenoage.zong.core.music.MusicContext) ElementSpacing(com.xenoage.zong.musiclayout.spacing.ElementSpacing) TraditionalKeyNotation(com.xenoage.zong.musiclayout.notation.TraditionalKeyNotation) TraditionalKey(com.xenoage.zong.core.music.key.TraditionalKey) Key(com.xenoage.zong.core.music.key.Key)

Example 9 with Clef

use of com.xenoage.zong.core.music.clef.Clef in project Zong by Xenoage.

the class ScoreReader method readToScore.

public void readToScore(Score score, ErrorHandling errorHandling) {
    Context context = new Context(score, new ReaderSettings(errorHandling));
    // create the measures of the parts
    It<MxlPart> mxlParts = it(doc.getParts());
    for (MxlPart mxlPart : mxlParts) {
        // create measures
        execute(new MeasureAddUpTo(score, mxlPart.getMeasures().size()));
        // initialize each measure with a C clef
        Part part = score.getStavesList().getParts().get(mxlParts.getIndex());
        StavesRange stavesRange = score.getStavesList().getPartStaffIndices(part);
        for (int staff : stavesRange.getRange()) {
            execute(new MeasureElementWrite(new Clef(ClefType.clefTreble), score.getMeasure(MP.atMeasure(staff, 0)), _0));
        }
    }
    // write a 4/4 measure and C key signature in the first measure
    execute(new ColumnElementWrite(new TimeSignature(TimeType.time_4_4), score.getColumnHeader(0), _0, null));
    execute(new ColumnElementWrite(new TraditionalKey(0), score.getColumnHeader(0), _0, null));
    // read the parts
    mxlParts = it(doc.getParts());
    for (MxlPart mxlPart : mxlParts) {
        // clear part-dependent context values
        context.beginNewPart(mxlParts.getIndex());
        // read the measures
        It<MxlMeasure> mxlMeasures = it(mxlPart.getMeasures());
        for (MxlMeasure mxlMeasure : mxlMeasures) {
            try {
                MeasureReader.readToContext(mxlMeasure, mxlMeasures.getIndex(), context);
            } catch (MusicReaderException ex) {
                throw new RuntimeException("Error at " + ex.getContext().toString(), ex);
            } catch (Exception ex) {
                throw new RuntimeException("Error (roughly) around " + context.toString(), ex);
            }
        }
    }
    // remove unclosed elements
    context.removeUnclosedWedges();
    // go through the whole score, and fill empty measures (that means, measures where
    // voice 0 has no single VoiceElement) with rests
    Fraction measureDuration = fr(1, 4);
    for (int iStaff = 0; iStaff < score.getStavesCount(); iStaff++) {
        Staff staff = score.getStaff(atStaff(iStaff));
        for (int iMeasure : range(staff.getMeasures())) {
            Measure measure = staff.getMeasure(iMeasure);
            TimeSignature newTime = score.getHeader().getColumnHeader(iMeasure).getTime();
            if (newTime != null) {
                // time signature has changed
                measureDuration = newTime.getType().getMeasureBeats();
            }
            if (measureDuration == null) {
                // senza misura
                // use whole rest
                measureDuration = fr(4, 4);
            }
            Voice voice0 = measure.getVoice(0);
            if (voice0.isEmpty()) {
                // TODO: "whole rests" or split. currently, also 3/4 rests are possible
                MP mp = atElement(iStaff, iMeasure, 0, 0);
                new VoiceElementWrite(score.getVoice(mp), mp, new Rest(measureDuration), null).execute();
            }
        }
    }
}
Also used : VoiceElementWrite(com.xenoage.zong.commands.core.music.VoiceElementWrite) MP.atStaff(com.xenoage.zong.core.position.MP.atStaff) Staff(com.xenoage.zong.core.music.Staff) ColumnElementWrite(com.xenoage.zong.commands.core.music.ColumnElementWrite) MxlPart(com.xenoage.zong.musicxml.types.partwise.MxlPart) Clef(com.xenoage.zong.core.music.clef.Clef) TraditionalKey(com.xenoage.zong.core.music.key.TraditionalKey) MxlMeasure(com.xenoage.zong.musicxml.types.partwise.MxlMeasure) MeasureAddUpTo(com.xenoage.zong.commands.core.music.MeasureAddUpTo) StavesRange(com.xenoage.zong.core.music.group.StavesRange) Rest(com.xenoage.zong.core.music.rest.Rest) MxlMeasure(com.xenoage.zong.musicxml.types.partwise.MxlMeasure) Measure(com.xenoage.zong.core.music.Measure) MP(com.xenoage.zong.core.position.MP) MusicReaderException(com.xenoage.zong.io.musicxml.in.util.MusicReaderException) Fraction(com.xenoage.utils.math.Fraction) MusicReaderException(com.xenoage.zong.io.musicxml.in.util.MusicReaderException) TimeSignature(com.xenoage.zong.core.music.time.TimeSignature) MxlPart(com.xenoage.zong.musicxml.types.partwise.MxlPart) Part(com.xenoage.zong.core.music.Part) MeasureElementWrite(com.xenoage.zong.commands.core.music.MeasureElementWrite) Voice(com.xenoage.zong.core.music.Voice)

Example 10 with Clef

use of com.xenoage.zong.core.music.clef.Clef in project Zong by Xenoage.

the class ClefReader method read.

public Clef read() {
    if (mxlClef == null)
        return null;
    ClefType clefType = readType();
    Clef clef = (clefType != null ? new Clef(clefType) : null);
    return clef;
}
Also used : ClefType(com.xenoage.zong.core.music.clef.ClefType) Clef(com.xenoage.zong.core.music.clef.Clef) MxlClef(com.xenoage.zong.musicxml.types.MxlClef)

Aggregations

Clef (com.xenoage.zong.core.music.clef.Clef)16 TraditionalKey (com.xenoage.zong.core.music.key.TraditionalKey)9 Key (com.xenoage.zong.core.music.key.Key)5 Rest (com.xenoage.zong.core.music.rest.Rest)5 TimeSignature (com.xenoage.zong.core.music.time.TimeSignature)5 ElementSpacing (com.xenoage.zong.musiclayout.spacing.ElementSpacing)5 Fraction (com.xenoage.utils.math.Fraction)4 Score (com.xenoage.zong.core.Score)4 ClefType (com.xenoage.zong.core.music.clef.ClefType)4 Part (com.xenoage.zong.core.music.Part)3 Dynamic (com.xenoage.zong.core.music.direction.Dynamic)3 Test (org.junit.Test)3 Tuple2 (com.xenoage.utils.kernel.Tuple2)2 ColumnElementWrite (com.xenoage.zong.commands.core.music.ColumnElementWrite)2 PartAdd (com.xenoage.zong.commands.core.music.PartAdd)2 Instrument (com.xenoage.zong.core.instrument.Instrument)2 InstrumentChange (com.xenoage.zong.core.music.InstrumentChange)2 Chord (com.xenoage.zong.core.music.chord.Chord)2 StavesRange (com.xenoage.zong.core.music.group.StavesRange)2 Cursor (com.xenoage.zong.io.selection.Cursor)2