/// <summary> /// Adds properties to a rest object /// </summary> /// <param name="_restobj">Empty Rest object</param> /// <param name="_meirest">MEI rest element</param> /// <returns>Rest object with properties</returns> public static Model.Rest ConvertRest(Model.Rest _restobj, mei.Rest _meirest) { _restobj.Duration = ConvertDuration(_meirest); _restobj.Num = ConverterHelper.ConvertNumNumbase(_meirest.GetNumAttribute()); _restobj.Numbase = ConverterHelper.ConvertNumNumbase(_meirest.GetNumbaseAttribute()); return(_restobj); }
/// <summary> /// Interates through sequence and adds BrevePosition of a Note or Rest according to the Mensur. /// Counter starts at 0 with every Mensur, Proportion, and Barline. /// </summary> /// <param name="_sequence">Sequence to convert</param> public static void ConvertBrevePosition(Sequence _sequence) { //Initialize position counter Fraction brevePos = new Fraction(0); //Save last brevePos nulling object. ObjectType brevePosNuller = ObjectType.Invalid; //Save directly preceeding object for chord handling Model.Rest preceedingRest = new Model.Rest(); //Set Position of Dummy-Rest to -1 preceedingRest.Position = -1; //Save preceeding convertedDur Fraction preceedingConvertedDur = -1; //Iterate through sequence foreach (ObjectInSequence obj in _sequence.ObjectsInSequence) { if (obj is Model.Mensur mensur) { InitMetricTable(mensur); brevePos = 0; brevePosNuller = mensur.Type; } else if (obj is Model.Proportion prop) { brevePos = 0; brevePosNuller = prop.Type; //Set metrical change SetProportion(prop); } else if (obj is Model.Barline) { brevePos = 0; brevePosNuller = obj.Type; } else if (obj is Model.Gap) { brevePos = 0; brevePosNuller = obj.Type; } else if (obj is Model.Rest rest) { //add modify duration with num/numbase Fraction convertedDur = MetricTable[rest.Duration] * rest.Ratio; brevePos = brevePos + convertedDur; rest.BreveDuration = convertedDur; //only apply BrevePosition or AfterGapPosition once per Object.Position if (obj.Position != preceedingRest.Position) { //check if last nulling object was a gap or not if (brevePosNuller == ObjectType.Gap) { rest.AfterGapPosition = brevePos; } else { rest.BrevePosition = brevePos; } } else { //check for equality of convertedDur for current and preceeding object with same position if (preceedingConvertedDur != convertedDur) { throw new InvalidOperationException("Severe error in chord! Child elements don't have same duration."); } } preceedingRest = rest; preceedingConvertedDur = convertedDur; } } //Reset MetricTable and InterNoteQuotient after conversion is done MetricTable = null; InterNoteQuotient = null; //Reset BrevePos and BrevePosNuller brevePos = 0; brevePosNuller = ObjectType.Invalid; }
/// <summary> /// Invokes a Sequence object for the given MEI element /// </summary> /// <param name="_sequence">Sequence</param> /// <param name="layerElement">MEI Element to process</param> internal static ObjectInSequence InvokeSequenceObject(Sequence _sequence, MeiElement layerElement, Evidence evidence = Evidence.Clear, int ligaturePos = 0, string ligForm = null) { ObjectInSequence obj = null; if (layerElement is mei.Note note) { obj = new Model.Note(); NoteConverter.ConvertNote((Model.Note)obj, note); //check for @lig attribute if (note.HasLig()) { ligForm = note.GetLigValue(); } TinyConverters.LigatureHandler((Model.Note)obj, ligaturePos, ligForm); } // Ligatures needs to be be handled recursively to get their elements and store related data else if (layerElement is mei.Ligature ligature) { foreach (MeiElement ligaturChild in ligature.Elements()) { ligaturePos++; InvokeSequenceObject(_sequence, ligaturChild, evidence, ligaturePos, ligature.GetFormValue()); } ligaturePos = 0; } else if (layerElement is mei.Rest) { obj = new Model.Rest(); RestConverter.ConvertRest((Model.Rest)obj, (mei.Rest)layerElement); } else if (layerElement is Chord) { // We need a List of all objects in the Chord to add them to the sequence at the same position List <ObjectInSequence> lstChordEvents = new List <ObjectInSequence>(); foreach (MeiElement noteRest in layerElement.Descendants()) { ObjectInSequence objNoteRest = InvokeSequenceObject(null, noteRest); if (objNoteRest != null) { lstChordEvents.Add(objNoteRest); } } _sequence?.AddToSequence(lstChordEvents.ToArray()); } else if (layerElement is mei.KeySig) { // We need a List of all KeyAccids in the KeySig to add them to the sequence at the same position List <ObjectInSequence> lstAcids = new List <ObjectInSequence>(); foreach (KeyAccid keyAccid in layerElement.Elements()) { lstAcids.Add(InvokeSequenceObject(null, keyAccid)); } _sequence?.AddToSequence(lstAcids.ToArray()); } else if (layerElement is KeyAccid) { obj = new Model.KeyAccidental(); AccidentalConverter.ConvertKeyAccidental((Model.KeyAccidental)obj, (mei.KeyAccid)layerElement); } else if (layerElement is mei.Accid) { obj = new Model.Accidental(); AccidentalConverter.ConvertAccidental((Model.Accidental)obj, (mei.Accid)layerElement); } else if (layerElement is mei.Mensur) { obj = new Model.Mensur(); MensurProportionConverter.ConvertMensur((Model.Mensur)obj, (mei.Mensur)layerElement); } else if (layerElement is mei.Proport) { obj = new Model.Proportion(); MensurProportionConverter.ConvertProportion((Model.Proportion)obj, (mei.Proport)layerElement); } else if (layerElement is mei.BarLine) { obj = new Model.Barline(); TinyConverters.ConvertBarline((Model.Barline)obj, (mei.BarLine)layerElement); } else if (layerElement is mei.Dot) { obj = new Model.Dot(); } else if (layerElement is mei.Clef) { obj = new Model.Clef(); TinyConverters.ConvertClef((Model.Clef)obj, (mei.Clef)layerElement); } else if (layerElement is mei.Custos) { obj = new Model.Custos(); TinyConverters.ConvertCustos((Model.Custos)obj, (mei.Custos)layerElement); } else if (layerElement is mei.Unclear || layerElement is mei.Supplied) { Evidence evd = TinyConverters.GetEvidence(layerElement); foreach (MeiElement evdChild in layerElement.Elements()) { InvokeSequenceObject(_sequence, evdChild, evd); } } else if (layerElement is mei.Damage || layerElement is mei.Gap) { obj = new Model.Gap(); TinyConverters.ConvertGap((Model.Gap)obj, layerElement); } if (obj != null) { //After type definition, add ID of MEI element obj.ID = layerElement.GetId(); //Set Evidence obj.Evidence = evidence; //Add to sequence if defined _sequence?.AddToSequence(obj); } return(obj); }