public Data.MML.MML Convert(Data.Intermediate.Intermediate intermediate, Settings settings, List <Data.Intermediate.NotesStatus> statusList)
        {
            try
            {
                List <Data.MML.Part> partlist = CreatePartList(intermediate, settings, statusList);

                return(CreateMMLInstance(partlist, intermediate.Title, intermediate.CountsPerWholeNote));
            }
            catch (Exception ex)
            {
                throw new Exception(Resources.ErrorConverterFailedToMML, ex);
            }
        }
        private List <Data.MML.Part> CreatePartList(Data.Intermediate.Intermediate intermediate, Settings settings, List <Data.Intermediate.NotesStatus> statusList)
        {
            int[][] lentable = CreateLengthTable((uint)settings.mmlExpression.TimeBase, settings.noteRest);


            var partList = new List <Data.MML.Part>();

            LinkedListNode <Data.Intermediate.Event.Tempo> tempoNode = intermediate.TempoList.First;

            foreach (Data.Intermediate.Track track in intermediate.TrackList)
            {
                Data.Intermediate.Notes       notes  = track.NotesList[0];
                Data.Intermediate.NotesStatus status = statusList.Find(x => (x.TrackNumber == track.Number && x.NumberInTrack == notes.NumberInTrack));

                LinkedListNode <Data.Intermediate.Event.NoteRest>      noteNode = notes.NoteList.First;
                LinkedListNode <Data.Intermediate.Event.Instrument>    instNode = track.InstrumentList.First;
                LinkedListNode <Data.Intermediate.Event.Volume>        volNode  = track.VolumeList.First;
                LinkedListNode <Data.Intermediate.Event.Pan>           panNode  = track.PanList.First;
                LinkedListNode <Data.Intermediate.Event.KeySignature>  ksNode   = intermediate.KeySignatureList.First;
                LinkedListNode <Data.Intermediate.Event.TimeSignature> tsNode   = intermediate.TimeSignatureList.First;

                int barCnt  = 1;
                Key key     = Key.CMaj;
                var barList = new List <Data.MML.Bar>();

                for (int i = 1; i <= track.Length.Bar; i++)
                {
                    var  comList  = new LinkedList <Data.MML.Command.Command>();
                    bool prevTied = false;

                    MMLCommandRelation relation = MMLCommandRelation.Clear;
                    while (true)
                    {
                        string addCommandName;
                        if (intermediate.TrackList.IndexOf(track) == 0)
                        {
                            addCommandName = GetEarliestCommandName(ksNode?.Value, tempoNode?.Value, instNode?.Value, volNode?.Value, panNode?.Value, noteNode?.Value, i, prevTied, settings);
                        }
                        else
                        {
                            addCommandName = GetEarliestCommandName(ksNode?.Value, null, instNode?.Value, volNode?.Value, panNode?.Value, noteNode?.Value, i, prevTied, settings);
                        }

                        Data.MML.Command.Command addCommand = null;
                        if (addCommandName == typeof(Data.Intermediate.Event.KeySignature).Name)
                        {
                            key    = ksNode.Value.Key;
                            ksNode = ksNode.Next;
                            continue;
                        }
                        else if (addCommandName == typeof(Data.Intermediate.Event.Tempo).Name)
                        {
                            if (comList.Count > 0)
                            {
                                comList.Last.Value.CommandRelation |= MMLCommandRelation.NextControl;
                            }

                            addCommand = CreateTempoInstance(tempoNode.Value.Value, relation);

                            relation |= MMLCommandRelation.PrevControl;
                            tempoNode = tempoNode.Next;
                        }
                        else if (addCommandName == typeof(Data.Intermediate.Event.Instrument).Name)
                        {
                            if (comList.Count > 0)
                            {
                                comList.Last.Value.CommandRelation |= MMLCommandRelation.NextControl;
                            }

                            addCommand = CreateInstrumentInstance(instNode.Value.Value, relation);

                            relation |= MMLCommandRelation.PrevControl;
                            instNode  = instNode.Next;
                        }
                        else if (addCommandName == typeof(Data.Intermediate.Event.Volume).Name)
                        {
                            if (comList.Count > 0)
                            {
                                comList.Last.Value.CommandRelation |= MMLCommandRelation.NextControl;
                            }

                            addCommand = CreateVolumeInstance(volNode.Value.Value, relation);

                            relation |= MMLCommandRelation.PrevControl;
                            volNode   = volNode.Next;
                        }
                        else if (addCommandName == typeof(Data.Intermediate.Event.Pan).Name)
                        {
                            if (comList.Count > 0)
                            {
                                comList.Last.Value.CommandRelation |= MMLCommandRelation.NextControl;
                            }

                            addCommand = CreatePanInstance(panNode.Value.Value, relation);

                            relation |= MMLCommandRelation.PrevControl;
                            panNode   = panNode.Next;
                        }
                        else if (addCommandName == typeof(Data.Intermediate.Event.Note).Name)
                        {
                            if (comList.Count > 0)
                            {
                                comList.Last.Value.CommandRelation &= ~MMLCommandRelation.NextControl;
                            }

                            var note = (Data.Intermediate.Event.Note)noteNode.Value;
                            Data.Intermediate.Position poslen = CalculateLength(note.Start, note.End, intermediate.TimeSignatureList, (int)settings.mmlExpression.TimeBase);
                            List <int>         length         = ConvertLengthFormat(poslen, lentable);
                            MMLCommandRelation tempRel        = relation;
                            if (note.TieFlag)
                            {
                                tempRel  |= MMLCommandRelation.TieAfter;
                                relation |= MMLCommandRelation.TieBefore;
                            }
                            else
                            {
                                tempRel  &= ~MMLCommandRelation.TieAfter;
                                relation &= ~MMLCommandRelation.TieBefore;
                            }

                            addCommand = CreateNoteInstance((note.KeyNumber / 12 - 1), Tables.NoteNameDictionary[key][note.KeyNumber % 12], length, tempRel);

                            relation &= ~MMLCommandRelation.PrevControl;
                            prevTied  = note.TieFlag;
                            noteNode  = noteNode.Next;
                        }
                        else if (addCommandName == typeof(Data.Intermediate.Event.Rest).Name)
                        {
                            if (comList.Count > 0)
                            {
                                comList.Last.Value.CommandRelation &= ~MMLCommandRelation.NextControl;
                            }

                            var rest = (Data.Intermediate.Event.Rest)noteNode.Value;
                            Data.Intermediate.Position poslen = CalculateLength(rest.Start, rest.End, intermediate.TimeSignatureList, (int)settings.mmlExpression.TimeBase);
                            List <int> length = ConvertLengthFormat(poslen, lentable);

                            MMLCommandRelation tempRel = relation;
                            if (rest.TieFlag)
                            {
                                tempRel  |= MMLCommandRelation.TieAfter;
                                relation |= MMLCommandRelation.TieBefore;
                            }
                            else
                            {
                                tempRel  &= ~MMLCommandRelation.TieAfter;
                                relation &= ~MMLCommandRelation.TieBefore;
                            }

                            addCommand = CreateRestInstance(length, tempRel);

                            relation &= ~MMLCommandRelation.PrevControl;
                            prevTied  = rest.TieFlag;
                            noteNode  = noteNode.Next;
                        }
                        else
                        {
                            break;
                        }

                        comList.AddLast(addCommand);
                    }


                    if (settings.mmlExpression.NewBlockByBar == 1 && i == tsNode.Value.Position.Bar)
                    {
                        barCnt = 1;
                    }
                    else
                    {
                        barCnt++;
                    }

                    uint nextTSBar = (tsNode.Next?.Value.Position.Bar ?? 0);
                    if (i + 1 == nextTSBar)
                    {
                        tsNode = tsNode.Next;
                    }
                    string seperateSign = GetSeperateSign(i, barCnt, nextTSBar, settings.mmlExpression);


                    barList.Add(new Data.MML.Bar(comList, i, seperateSign));
                }

                if (track.Length.Tick == 0)
                {
                    Data.MML.Bar lastBar = barList.Last();
                    if (lastBar.CommandList.Count == 0)
                    {
                        barList.Remove(lastBar);
                    }
                }


                partList.Add(new Data.MML.Part(barList, status.SoundModule, track.Name));
            }


            return(partList);
        }