package com.xenoage.zong.io.musicxml.in.readers; import lombok.RequiredArgsConstructor; import com.xenoage.zong.core.music.clef.Clef; import com.xenoage.zong.core.music.clef.ClefSymbol; import com.xenoage.zong.core.music.clef.ClefType; import com.xenoage.zong.io.musicxml.Equivalents; import com.xenoage.zong.musicxml.types.MxlClef; /** * This class reads a {@link ClefType} from a {@link MxlClef}. * * @author Andreas Wenger */ @RequiredArgsConstructor public class ClefReader { private final MxlClef mxlClef; private ClefSymbol symbol; private ClefType clefType; public Clef read() { if (mxlClef == null) return null; ClefType clefType = readType(); Clef clef = (clefType != null ? new Clef(clefType) : null); return clef; } public int readStaff() { //staff (called "number" in MusicXML), first staff is default return mxlClef.getNumber() - 1; } private ClefType readType() { symbol = Equivalents.clefSymbols.getBy2(mxlClef.getSign()); if (symbol == null) return null; readOctaveShift(); readLine(); return clefType; } private void readOctaveShift() { //for some clefs, we provide octave shifting. If unsupported, we ignore it int octaveChange = mxlClef.getClefOctaveChange(); if (octaveChange != 0) { if (symbol == ClefSymbol.G) { switch (octaveChange) { case -2: symbol = ClefSymbol.G15vb; break; case -1: symbol = ClefSymbol.G8vb; break; case 1: symbol = ClefSymbol.G8va; break; case 2: symbol = ClefSymbol.G15va; break; } } else if (symbol == ClefSymbol.F) { switch (octaveChange) { case -2: symbol = ClefSymbol.F15vb; break; case -1: symbol = ClefSymbol.F8vb; break; case 1: symbol = ClefSymbol.F8va; break; case 2: symbol = ClefSymbol.F15va; break; } } } } private void readLine() { //read line or use default position Integer line = mxlClef.getLine(); if (line == null) { clefType = ClefType.commonClefs.get(symbol); } else { //convert MusicXML line number (1 based) to LP (0 based) int lp = (line - 1) * 2; //special case: in MusicXML, the TAB symbol is based on the top line, but //in Zong!, it is centered, so move it 2 interline spaces down (= 4 LPs) if (symbol == ClefSymbol.Tab || symbol == ClefSymbol.TabSmall) lp -= 4; clefType = new ClefType(symbol, lp); } } }