/// <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);
        }
Example #2
0
        /// <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;
        }
Example #3
0
        /// <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);
        }