use of com.xenoage.zong.core.music.key.Key in project Zong by Xenoage.
the class AttributesReader method readKey.
private Key readKey(MxlKey mxlKey) {
if (mxlKey == null)
return null;
// read fifths. currently, only -7 to 7 is supported (clamp, if needed)
int mxlFifths = INSTANCE.clamp(mxlKey.fifths, -7, 7);
// write to column header (TODO: attribute "number" for single staves)
Mode mode = getEnumValue(mxlKey.mode, Mode.values());
Key key = new TraditionalKey(mxlFifths, mode);
return key;
}
use of com.xenoage.zong.core.music.key.Key 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().getBeat().equals(Companion.get_0()))
key0 = keys.getFirst().getElement();
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, Companion.get_0(), startOffset));
currentOffset += keyNotation.getWidth().getUsedWidth();
}
// ****
if (time != null) {
Notation timeNotation = notations.get(time, staff);
ret.add(new SimpleSpacing(timeNotation, Companion.get_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.getBeat();
Notation MEnotation = notations.get(ME.getElement());
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.getBeat(), MEx));
}
}
ret.trimToSize();
return ret;
}
use of com.xenoage.zong.core.music.key.Key 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.Companion.getClefTreble());
clefs.add(c = ClefType.Companion.getClefTreble());
new MeasureElementWrite(new Clef(c), measure, Companion.fr(0, 4)).execute();
keys.add(k = new TraditionalKey(1, Mode.Major));
new MeasureElementWrite(k, measure, Companion.fr(0, 4)).execute();
new VoiceElementWrite(measure.getVoice(0), atElement(0, 0, 0, 0), chord(Companion.pi(0, 1, 4), Companion.fr(1, 4)), null).execute();
clefs.add(c = ClefType.Companion.getClefBass());
new MeasureElementWrite(new Clef(c), measure, Companion.fr(1, 4)).execute();
new VoiceElementWrite(measure.getVoice(0), atElement(0, 0, 0, 1), chord(Companion.pi(1, -1, 4), Companion.fr(1, 4)), null).execute();
clefs.add(c = ClefType.Companion.getClefTreble());
new MeasureElementWrite(new Clef(c), measure, Companion.fr(2, 4)).execute();
keys.add(k = new TraditionalKey(-1, Mode.Major));
new MeasureElementWrite(k, measure, Companion.fr(2, 4)).execute();
new VoiceElementWrite(measure.getVoice(0), atElement(0, 0, 0, 2), chord(Companion.pi(0, 0, 4), Companion.fr(1, 4)), null).execute();
// measure 1
measure = score.getMeasure(atMeasure(0, 1));
new VoiceElementWrite(measure.getVoice(0), atElement(0, 1, 0, 0), chord(Companion.pi(0, 1, 4), Companion.fr(1, 4)), null).execute();
keys.add(k = new TraditionalKey(0, Mode.Major));
new MeasureElementWrite(k, measure, Companion.fr(1, 4)).execute();
clefs.add(c = ClefType.Companion.getClefBass());
new MeasureElementWrite(new Clef(c), measure, Companion.fr(1, 4)).execute();
new VoiceElementWrite(measure.getVoice(0), atElement(0, 1, 0, 1), chord(Companion.pi(0, 0, 4), Companion.fr(2, 4)), null).execute();
return t3(score, clefs, keys);
}
use of com.xenoage.zong.core.music.key.Key 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, Companion.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, Companion.fr(0), xOffset));
xOffset += keyNotation.getWidth().getWidth();
}
return new LeadingSpacing(elements, xOffset);
}
use of com.xenoage.zong.core.music.key.Key in project Zong by Xenoage.
the class CursorTest method write_MeasureElement_Test.
@Test
public void write_MeasureElement_Test() {
Score score = ScoreFactory.create1Staff();
Cursor cursor = new Cursor(score, mpe0, true);
cursor.write(new Rest(Companion.fr(1, 4)));
cursor.write(new Rest(Companion.fr(1, 4)));
cursor.write(new Rest(Companion.fr(1, 4)));
// write clef at 1/4
Clef clef1 = new Clef(ClefType.Companion.getClefBass());
cursor.setMp(atElement(0, 0, 0, 1));
cursor.write(clef1);
BeatEList<Clef> clefs = score.getMeasure(atMeasure(0, 0)).getClefs();
assertEquals(1, clefs.size());
assertEquals(Companion.beatE(clef1, Companion.fr(1, 4)), clefs.getFirst());
// write clef at 2/4
Clef clef2 = new Clef(ClefType.Companion.getClefTreble());
cursor.setMp(atElement(0, 0, 0, 2));
cursor.write(clef2);
clefs = score.getMeasure(atMeasure(0, 0)).getClefs();
assertEquals(2, clefs.size());
assertEquals(Companion.beatE(clef1, Companion.fr(1, 4)), clefs.getFirst());
assertEquals(Companion.beatE(clef2, Companion.fr(2, 4)), clefs.getElements().get(1));
// overwrite clef at 1/4
Clef clef3 = new Clef(ClefType.Companion.getClefTreble());
cursor.setMp(atElement(0, 0, 0, 1));
cursor.write(clef3);
clefs = score.getMeasure(atMeasure(0, 0)).getClefs();
assertEquals(2, clefs.size());
assertEquals(Companion.beatE(clef3, Companion.fr(1, 4)), clefs.getFirst());
assertEquals(Companion.beatE(clef2, Companion.fr(2, 4)), clefs.getElements().get(1));
// write key at 1/4
Key key = new TraditionalKey(5, Mode.Major);
cursor.setMp(atElement(0, 0, 0, 1));
cursor.write((MeasureElement) key);
// clefs must still be there
assertEquals(2, score.getMeasure(atMeasure(0, 0)).getClefs().size());
assertEquals(1, score.getMeasure(atMeasure(0, 0)).getPrivateKeys().size());
// write direction at 1/4
Direction direction1 = new Dynamic(DynamicValue.ff);
cursor.setMp(atElement(0, 0, 0, 1));
cursor.write((MeasureElement) direction1);
// clefs must still be there
assertEquals(2, score.getMeasure(atMeasure(0, 0)).getClefs().size());
// key must still be there
assertEquals(1, score.getMeasure(atMeasure(0, 0)).getPrivateKeys().size());
assertEquals(1, score.getMeasure(atMeasure(0, 0)).getDirections().size());
// write another direction at 1/4, which does not replace the first one
Direction direction2 = new Coda();
cursor.setMp(atElement(0, 0, 0, 1));
cursor.write((MeasureElement) direction2);
// clefs must still be there
assertEquals(2, score.getMeasure(atMeasure(0, 0)).getClefs().size());
// key must still be there
assertEquals(1, score.getMeasure(atMeasure(0, 0)).getPrivateKeys().size());
// now two directions
assertEquals(2, score.getMeasure(atMeasure(0, 0)).getDirections().size());
// write instrument change at 1/4
InstrumentChange instrChange = new InstrumentChange(Instrument.Companion.getDefaultInstrument());
cursor.setMp(atElement(0, 0, 0, 1));
cursor.write(instrChange);
// clefs must still be there
assertEquals(2, score.getMeasure(atMeasure(0, 0)).getClefs().size());
// key must still be there
assertEquals(1, score.getMeasure(atMeasure(0, 0)).getPrivateKeys().size());
// directions must still be there
assertEquals(2, score.getMeasure(atMeasure(0, 0)).getDirections().size());
assertEquals(1, score.getMeasure(atMeasure(0, 0)).getInstrumentChanges().size());
// check all added elements
BeatEList<MeasureElement> all = score.getMeasure(atMeasure(0, 0)).getMeasureElements();
assertEquals(6, all.size());
assertEquals(clef3, all.getElements().get(0).getElement());
assertEquals(key, all.getElements().get(1).getElement());
assertEquals(direction1, all.getElements().get(2).getElement());
assertEquals(direction2, all.getElements().get(3).getElement());
assertEquals(instrChange, all.getElements().get(4).getElement());
assertEquals(clef2, all.getElements().get(5).getElement());
}
Aggregations