Clone() публичный Метод

The clone.
public Clone ( ) : IBaseObject
Результат IBaseObject
        /// <summary>
        /// The third temp method.
        /// </summary>
        /// <param name="fmotivBuffer">
        /// The fmotiv buffer.
        /// </param>
        /// <param name="fmotivType">
        /// The fmotiv type.
        /// </param>
        /// <param name="noteCount">
        /// The note count.
        /// </param>
        /// <returns>
        /// The <see cref="Fmotiv"/>.
        /// </returns>
        private Fmotiv ThirdTempMethod(Fmotiv fmotivBuffer, string fmotivType, int noteCount)
        {
            var fmotiv = new Fmotiv(fmotivType);
            while (fmotivBuffer.NoteList.Count > 0)
            {
                if (ExtractNoteList(fmotiv).Count == noteCount)
                {
                    if (paramPauseTreatment != ParamPauseTreatment.NoteTrace)
                    {
                        break;
                    }

                    if ((paramPauseTreatment == ParamPauseTreatment.NoteTrace) &&
                        (fmotivBuffer.NoteList[0].Pitch.Count > 0))
                    {
                        break;
                    }
                }

                fmotiv.NoteList.Add((ValueNote)fmotivBuffer.NoteList[0].Clone());
                fmotivBuffer.NoteList.RemoveAt(0);

                TempMethod(fmotiv, fmotivBuffer);
            }

            return (Fmotiv)fmotiv.Clone();
        }
        /// <summary>
        /// The divide same duration notes.
        /// </summary>
        /// <param name="fmotivBuff">
        /// The fmotiv buff.
        /// </param>
        /// <returns>
        /// The <see cref="List{FMotiv}"/>.
        /// </returns>
        /// <exception cref="Exception">
        /// Thrown if amount of collected notes in buffer is less than 2.
        /// </exception>
        private List<Fmotiv> DivideSameDurationNotes(Fmotiv fmotivBuff)
        {
            // создаем копию входного объекта
            var fmotivBuffer = (Fmotiv)fmotivBuff.Clone();

            // выходной список фмотивов
            var result = new List<Fmotiv>();

            // проверка на случай когда в аругменте метода количество собранных нот (из пауз/лиг) меньше двух
            if (ExtractNoteList(fmotivBuffer).Count < 2)
            {
                throw new Exception("LibiadaMusic DivideSameDurationNotes: notes < 2");
            }

            if (ExtractNoteList(fmotivBuffer).Count % 2 == 0)
            {
                // то начинаем анализ из расчета : по две ноты в фмотиве
                // сохраняем количество раз, так как потом меняется
                int count = ExtractNoteList(fmotivBuffer).Count / 2;
                for (int i = 0; i < count; i++)
                {
                    if (ThirdTempComparator(fmotivBuffer))
                    {
                        // приоритет первой ноты выше приоритета второй ноты (собранные ноты)
                        // ПМТ и записываем все что входит в цепочку нот - в эти две собранные ноты, в очередной фмотив

                        // собираем в цикле, пока не кончатся ноты в буфере 2 полноценные ноты в зависимостиот того, чем мы считаем паузу
                        // (когда звуковой след, надо добавить в след идущие паузы за последним звуком)
                        result.Add(ThirdTempMethod(fmotivBuffer, "ПМТ", 2));
                    }
                    else
                    {
                        // приоритет первой ноты ниже приоритета второй ноты (метрически слабее)
                        // ЧМТ и записываем все что входит в первую собранную ноту в очередной фмотив,
                        // и вызываем для оставшихся нот повторный анализ цепочки равнодлительных звуков
                        // потому что количество равндлительных звуков поменялось, и алгоритм анализа может поменяться

                        // собираем в цикле, пока не кончатся ноты в буфере 1 полноценную ноту в зависимостиот того, чем мы считаем паузу
                        // (когда звуковой след, надо добавить в след идущие паузы за последним звуком)
                        result.Add(ThirdTempMethod(fmotivBuffer, "ЧМТ", 1));

                        // если осталась одна нота то заносим ее в фмотив ЧМТ
                        SecondTempMethod(fmotivBuffer, result);

                        return result;
                    }
                }

                // прошли все ПМТ без ЧМТ, то вернуть результат
                return result;
            }

            if (ExtractNoteList(fmotivBuffer).Count % 3 == 0)
            {
                // то начинаем анализ из расчета : по три ноты в фмотиве
                // сохраняем количество раз, так как потом меняется
                int count = ExtractNoteList(fmotivBuffer).Count / 3;
                for (int i = 0; i < count; i++)
                {
                    if (ThirdTempComparator(fmotivBuffer))
                    {
                        // приоритет первой ноты выше приоритета второй ноты (собранные ноты)
                        if (SecondTempComparator(fmotivBuffer))
                        {
                            // приоритет первой ноты выше приоритета третьей ноты (собранные ноты)
                            // ПМТ и записываем все что входит в цепочку нот - в эти три собранные ноты, в очередной фмотив

                            // собираем в цикле, пока не кончатся ноты в буфере 3 полноценные ноты в зависимости от того, чем мы считаем паузу
                            // (когда звуковой след, надо добавить в след идущие паузы за последним звуком)
                            result.Add(ThirdTempMethod(fmotivBuffer, "ПМТ", 3));
                        }
                        else
                        {
                            // приоритет первой ноты ниже или равен приоритету третьей ноты (собранные ноты)
                            // ПМТ и записываем все что входит в цепочку нот - в эти две собранные ноты, в очередной фмотив
                            // (ЧМТ - если есть знак триоли хотя бы у одной ноты)
                            string typeF = "ПМТ"; // тип ПМТ если не триоль
                            if (TempComparator(fmotivBuffer))
                            {
                                typeF = "ЧМТ"; // если есть хотя б один знак триоли
                            }

                            // собираем в цикле, пока не кончатся ноты в буфере 2 полноценные ноты в зависимости от того, чем мы считаем паузу
                            // (когда звуковой след, надо добавить в след идущие паузы за последним звуком)
                            result.Add(ThirdTempMethod(fmotivBuffer, typeF, 2));

                            // если осталась одна нота то заносим ее в фмотив ЧМТ
                            SecondTempMethod(fmotivBuffer, result);
                            return result;
                        }
                    }
                    else
                    {
                        // приоритет первой ноты ниже или равен приоритету второй ноты (метрически слабее или равен)
                        // ЧМТ и записываем все что входит в первую собранную ноту в очередной фмотив,
                        // и вызываем для оставшихся нот повторный анализ цепочки равнодлительных звуков
                        // потому что количество равнодлительных звуков поменялось, и алгоритм анализа может поменяться

                        // собираем в цикле, пока не кончатся ноты в буфере 1 полноценная нота в зависимости от того, чем мы считаем паузу
                        // (когда звуковой след, надо добавить в след идущие паузы за последним звуком)
                        result.Add(ThirdTempMethod(fmotivBuffer, "ЧМТ", 1));

                        // если осталась одна нота то заносим ее в фмотив ЧМТ
                        SecondTempMethod(fmotivBuffer, result);
                        return result;
                    }
                }

                // прошли все ПМТ без ЧМТ, то вернуть результат
                return result;
            }
            else
            {
                // то начинаем анализ из расчета : по две ноты в фмотиве (к-3)/2 раза, а в последнем 3 ноты
                // сохраняем количество раз, так как потом меняется
                int count = (ExtractNoteList(fmotivBuffer).Count - 3) / 2;
                for (int i = 0; i < count; i++)
                {
                    if (ThirdTempComparator(fmotivBuffer))
                    {
                        // приоритет первой ноты выше приоритета второй ноты (собранные ноты)
                        // ПМТ и записываем все что входит в цепочку нот - в эти две собранные ноты, в очередной фмотив

                        // собираем в цикле, пока не кончатся ноты в буфере 2 полноценные ноты в зависимости от того, чем мы считаем паузу
                        // (когда звуковой след, надо добавить в след идущие паузы за последним звуком)
                        result.Add(ThirdTempMethod(fmotivBuffer, "ПМТ", 2));
                    }
                    else
                    {
                        // приоритет первой ноты ниже приоритета второй ноты (метрически слабее)
                        // ЧМТ и записываем все что входит в первую собранную ноту в очередной фмотив,
                        // и вызываем для оставшихся нот повторный анализ цепочки равнодлительных звуков
                        // потому что количество равндлительных звуков поменялось, и алгоритм анализа может поменяться

                        // собираем в цикле, пока не кончатся ноты в буфере 1 полноценную ноту в зависимости от того, чем мы считаем паузу
                        // (когда звуковой след, надо добавить в след идущие паузы за последним звуком)
                        result.Add(ThirdTempMethod(fmotivBuffer, "ЧМТ", 1));

                        // вызываем рекурсию на оставшиеся ноты
                        // отправляем последовательность равнодлительных звуков на анализ, получаем цепочку фмотивов и заносим их в выходную последовательность
                        List<Fmotiv> dividedSameDuration = DivideSameDurationNotes(fmotivBuffer);
                        foreach (Fmotiv fmotiv in dividedSameDuration)
                        {
                            // заносим очередной фмотив
                            result.Add((Fmotiv)fmotiv.Clone());
                        }

                        return result;
                    }
                }

                // анализируем оставшиеся 3 ноты
                if (ThirdTempComparator(fmotivBuffer))
                {
                    // приоритет первой ноты выше приоритета второй ноты (собранные ноты) !!!!!!!!!!!!!!!!!!! сравнение на саомо деле происход первой и третьей, разве нет? 08.04.2012
                    if (SecondTempComparator(fmotivBuffer))
                    {
                        // приоритет первой ноты выше приоритета третьей ноты (собранные ноты)
                        // ПМТ и записываем все что входит в цепочку нот - в эти три собранные ноты, в очередной фмотив

                        // собираем в цикле, пока не кончатся ноты в буфере 3 полноценные ноты в зависимости от того, чем мы считаем паузу
                        // (когда звуковой след, надо добавить в след идущие паузы за последним звуком)
                        result.Add(ThirdTempMethod(fmotivBuffer, "ПМТ", 3));
                    }
                    else
                    {
                        // приоритет первой ноты ниже или равен приоритету третьей ноты (собранные ноты)
                        // ПМТ и записываем все что входит в цепочку нот - в эти две собранные ноты, в очередной фмотив
                        // (ЧМТ - если есть знак триоли хотя бы у одной ноты)
                        string typeF = "ПМТ"; // тип ПМТ если не триоль
                        if (TempComparator(fmotivBuffer))
                        {
                            typeF = "ЧМТ"; // если есть хотя б один знак триоли
                        }

                        // собираем в цикле, пока не кончатся ноты в буфере 3 полноценные ноты в зависимости от того, чем мы считаем паузу
                        // (когда звуковой след, надо добавить в след идущие паузы за последним звуком)
                        result.Add(ThirdTempMethod(fmotivBuffer, typeF, 2));

                        // если осталась одна нота то заносим ее в фмотив ЧМТ
                        SecondTempMethod(fmotivBuffer, result);
                        return result;
                    }
                }
                else
                {
                    // приоритет первой ноты ниже или равен приоритету второй ноты (метрически слабее или равен)
                    // ЧМТ и записываем все что входит в первую собранную ноту в очередной фмотив,
                    // и вызываем для оставшихся нот повторный анализ цепочки равнодлительных звуков
                    // потому что количество равнодлительных звуков поменялось, и алгоритм анализа может поменяться

                    // собираем в цикле, пока не кончатся ноты в буфере 3 полноценные ноты в зависимости от того, чем мы считаем паузу
                    // (когда звуковой след, надо добавить в след идущие паузы за последним звуком)
                    result.Add(ThirdTempMethod(fmotivBuffer, "ЧМТ", 1));

                    // если осталась одна нота то заносим ее в фмотив ЧМТ
                    SecondTempMethod(fmotivBuffer, result);
                    return result;
                }

                // если все собрали, то возвращаем выходную цепочку
                return result;
            }
        }
        /// <summary>
        /// The second temp method.
        /// </summary>
        /// <param name="fmotivBuffer">
        /// The fmotiv buffer.
        /// </param>
        /// <param name="fmotivList">
        /// The fmotiv list.
        /// </param>
        private void SecondTempMethod(Fmotiv fmotivBuffer, List<Fmotiv> fmotivList)
        {
            if (ExtractNoteList(fmotivBuffer).Count == 1)
            {
                var fm = new Fmotiv("ЧМТ");
                for (int j = 0; j < fmotivBuffer.NoteList.Count; j++)
                {
                    // заносим
                    fm.NoteList.Add((ValueNote)fmotivBuffer.NoteList[j].Clone());
                }

                // добавляем в выходную цепочку получившийся фмотив
                fmotivList.Add((Fmotiv)fm.Clone());
                fmotivBuffer.NoteList.Clear();
            }
            else
            {
                // если больше 1 ноты, то вызываем рекурсию на оставшиеся ноты
                // отправляем последовательность равнодлительных звуков на анализ, получаем цепочку фмотивов и заносим их в выходную последовательность
                List<Fmotiv> dividedSameDuration = DivideSameDurationNotes(fmotivBuffer);
                foreach (Fmotiv fmotiv in dividedSameDuration)
                {
                    // заносим очередной фмотив
                    fmotivList.Add((Fmotiv)fmotiv.Clone());
                }
            }
        }
        /// <summary>
        /// The get division.
        /// </summary>
        /// <param name="congenericTrack">
        /// The congeneric track.
        /// </param>
        /// <param name="paramPauseTreatment">
        /// The param pause treatment.
        /// </param>
        /// <returns>
        /// The <see cref="FmotivChain"/>.
        /// </returns>
        /// <exception cref="Exception">
        /// Thrown in many cases.
        /// </exception>
        public FmotivChain GetDivision(CongenericScoreTrack congenericTrack, ParamPauseTreatment paramPauseTreatment)
        {
            var chain = new FmotivChain { Name = congenericTrack.Name }; // выходная, результирующая цепочка разбитых ф-мотивов
            this.paramPauseTreatment = paramPauseTreatment;

            var fmotivBuffer = new Fmotiv(string.Empty);

            // буффер для накопления нот, для последующего анализа его содержимого
            var noteChain = new List<ValueNote>();

            // цепочка нот, куда поочередно складываются ноты из последовательности тактов
            // для дальнейшего их анализа и распределения по ф-мотивам.

            // заполняем NoteChain всеми нотам из данной монофонической цепи unitrack
            foreach (Measure measure in congenericTrack.MeasureList)
            {
                foreach (ValueNote note in measure.NoteList)
                {
                    noteChain.Add((ValueNote)note.Clone());
                }
            }

            // счетчик реальных нот/пауз для первой группировки в реальную нот
            int n = 0;

            // флаг который говорит, что была нота перемещена в буфер после последнего флага Next, для pause notetrace
            bool wasNote = false;

            // флаг, говорит что собралась очередная нота для рассмотрения
            bool next = false;

            // флаг, говорящий что собирается последовательность равнодлительных звуков (1,2 тип фмотива - ПМТ,ЧМТ)
            bool sameDurationChain = false;

            // флаг, говорящий что собирается возрастающая последовательность (3 тип фмотива)
            bool growingDurationChain = false;

            // флаг, говорящий что собирается комбинация - ПМТ/ЧМТ и возрастающая последовательность (4 тип фмотива)
            bool combination = false;

            // пока анализируемая цепь содержит элементы, идет выполнение анализа ее содержимого
            while (noteChain.Count > 0)
            {
                fmotivBuffer.NoteList.Add((ValueNote)noteChain[0].Clone());
                noteChain.RemoveAt(0);

                // проверка на наличие лиги у очередной ноты, если есть то заносим в буффер все ноты, объединенные данной лигой
                if (fmotivBuffer.NoteList[fmotivBuffer.NoteList.Count - 1].Tie != Tie.None)
                {
                    // если есть флаг начала лиги, то записываем в буфер все остальные лигованные ноты, пока не будет флага конца лиги
                    if (fmotivBuffer.NoteList[fmotivBuffer.NoteList.Count - 1].Tie == Tie.Start)
                    {
                        // TODO: желательно сделать проверку когда собирается очередная лига,
                        // не будет ли пуста цепь нот, до того как лига закончится (будет флаг конца лиги)
                        while (noteChain[0].Tie == Tie.StartStop)
                        {
                            // пока продолжается лига, заносим ноты в буфер
                            fmotivBuffer.NoteList.Add((ValueNote)noteChain[0].Clone());
                            noteChain.RemoveAt(0);
                        }

                        if (noteChain[0].Tie == Tie.Stop)
                        {
                            // если есть флаг конца лиги у очередной ноты, то заносим конечную ноту лиги в буфер
                            fmotivBuffer.NoteList.Add((ValueNote)noteChain[0].Clone());
                            noteChain.RemoveAt(0);

                            wasNote = true; // была нота пермещена в буфер

                            switch (paramPauseTreatment)
                            {
                                case ParamPauseTreatment.Ignore:
                                    // удаляем все паузы в возвращаемом объекте (0) (паузы игнорируются)
                                    // если у очередной ноты нет лиги, то проверяем: если нота - не пауза, то выставляем флаг о следущей рассматриваемой ноте
                                    if (fmotivBuffer.NoteList[fmotivBuffer.NoteList.Count - 1].Pitch.Count > 0)
                                    {
                                        next = true;
                                    }

                                    break;
                                case ParamPauseTreatment.NoteTrace:
                                    // длительность паузы прибавляется к предыдущей ноте, а она сама удаляется из текста (1) (пауза - звуковой след ноты)
                                    if (noteChain.Count > 0)
                                    {
                                        // если следующая не паузы то переходим к анализу буфера
                                        if (noteChain[0].Pitch.Count > 0)
                                        {
                                            next = true;
                                        }
                                    }
                                    else
                                    {
                                        next = true;
                                    }

                                    break;
                                case ParamPauseTreatment.SilenceNote:
                                    // Пауза - звук тишины, рассматривается как нота без высоты звучания (2)
                                    // ничего не треуется
                                    next = true;
                                    break;
                                default:
                                    throw new Exception("Error Fmotiv.PauseTreatment parameter contains wrong value!");
                            }
                        }
                        else
                        {
                            // когда лига не заканчивается флагом конца, то ошибка
                            throw new Exception("LibiadaMusic: FmotivDivider, wrong Tie organization!End!");
                        }
                    }
                    else
                    {
                        // когда начинается лига не с флага начала, а с какого то другого, то ошибка
                        throw new Exception("LibiadaMusic: FmotivDivider, wrong Tie organization!Begining!");
                    }
                }
                else
                {
                    // если у очередной ноты нет лиги
                    switch (paramPauseTreatment)
                    {
                        case ParamPauseTreatment.Ignore:
                            // удаляем все паузы в возвращаемом объекте (0) (паузы игнорируются)
                            // если у очередной ноты нет лиги, то проверяем: если нота - не пауза, то выставляем флаг о следущей рассматриваемой ноте
                            if (fmotivBuffer.NoteList[fmotivBuffer.NoteList.Count - 1].Pitch.Count > 0)
                            {
                                next = true;
                            }

                            break;
                        case ParamPauseTreatment.NoteTrace:
                            // длительность паузы прибавляется к предыдущей ноте, а она сама удаляется из текста (1) (пауза - звуковой след ноты)
                            // проверяем: если нота - не пауза, то выставляем флаг о следущей рассматриваемой ноте
                            if (fmotivBuffer.NoteList[fmotivBuffer.NoteList.Count - 1].Pitch.Count > 0)
                            {
                                wasNote = true;
                            }

                            if (noteChain.Count > 0)
                            {
                                // если следующая в н. тексте не пауза то переходим к анализу буфера
                                if ((noteChain[0].Pitch.Count > 0) && wasNote)
                                {
                                    next = true;
                                }
                            }
                            else
                            {
                                if (wasNote)
                                {
                                    next = true;
                                }
                            }

                            break;
                        case ParamPauseTreatment.SilenceNote:
                            // Пауза - звук тишины, рассматривается как нота без высоты звучания (2)
                            // ничего не треуется
                            next = true;
                            break;
                        default:
                            throw new Exception("Error Fmotiv.PauseTreatment parameter contains wrong value!");
                    }
                }

                // если готова (собрана) следущая нота для анализа
                if (next)
                {
                    // убираем флаг следущей готовой (собранной ноты), так как после анализа не известно что там будет
                    next = false;
                    wasNote = false;

                    if (ExtractNoteList(fmotivBuffer).Count == 1)
                    {
                        // сохранили сколько нот/пауз входит в первую рассматриваемую ноту
                        n = fmotivBuffer.NoteList.Count;
                    }

                    if (ExtractNoteList(fmotivBuffer).Count == 2)
                    {
                        // если длительность первой собранной ноты больше длительности второй собранной ноты
                        if (TempExtractor(fmotivBuffer, 0).Duration.Value > TempExtractor(fmotivBuffer, 1).Duration.Value)
                        {
                            // заносим ноты/паузы первой собранной ноты в очередной фмотив с типом ЧМТ, и удаляем из буфера
                            var fm = new Fmotiv("ЧМТ", chain.FmotivList.Count);
                            for (int i = 0; i < n; i++)
                            {
                                // заносим
                                fm.NoteList.Add((ValueNote)fmotivBuffer.NoteList[0].Clone());

                                // удаляем
                                fmotivBuffer.NoteList.RemoveAt(0);
                            }

                            // добавляем в выходную цепочку получившийся фмотив
                            chain.FmotivList.Add((Fmotiv)fm.Clone());

                            // сохранили n на случай если за этим фмотивом следует еще один ЧМТ
                            n = fmotivBuffer.NoteList.Count;

                            // сохранили сколько нот/пауз входит в первую рассматриваемую ноту
                        }
                        else
                        {
                            if (AnotherTempComparator(fmotivBuffer))
                            {
                                // выставляем флаг для сбора последовательности равнодлительных звуков
                                sameDurationChain = true;
                                n = fmotivBuffer.NoteList.Count; // сохранили сколько нот/пауз входит в буфер
                            }
                            else
                            {
                                if (SecondAnotherTempComparator(fmotivBuffer))
                                {
                                    // выставляем флаг для сбора возрастающей последовательности
                                    growingDurationChain = true;

                                    // сохранили сколько нот/пауз входит в буфер
                                    n = fmotivBuffer.NoteList.Count;
                                }
                            }
                        }
                    }

                    if (ExtractNoteList(fmotivBuffer).Count > 2)
                    {
                        if (sameDurationChain)
                        {
                            // если длительность предпоследнего меньше длительности последнего
                            if (TempExtractor(fmotivBuffer, ExtractNoteList(fmotivBuffer).Count - 2).Duration.Value <
                                TempExtractor(fmotivBuffer, ExtractNoteList(fmotivBuffer).Count - 1).Duration.Value)
                            {
                                var fmotivBuffer2 = new Fmotiv(string.Empty);

                                // помещаем в буффер2 последнюю собранную ноту - большей длительности чем все равнодлительные
                                // так как меняется в процессе
                                int count = fmotivBuffer.NoteList.Count;
                                for (int i = n; i < count; i++)
                                {
                                    fmotivBuffer2.NoteList.Add((ValueNote)fmotivBuffer.NoteList[n].Clone());
                                    fmotivBuffer.NoteList.RemoveAt(n);
                                }

                                // отправляем последовательность равнодлительных звуков на анализ, получаем цепочку фмотивов и заносим их в выходную последовательность
                                // заисключением последнего фмотива - он останется в буфере вместе с нотой длительность которой больше последней ноты этого фмотива
                                List<Fmotiv> dividedSameDuration = DivideSameDurationNotes(fmotivBuffer);
                                for (int i = 0; i < (dividedSameDuration.Count - 1); i++)
                                {
                                    // заносим очередной фмотив
                                    chain.FmotivList.Add((Fmotiv)dividedSameDuration[i].Clone());

                                    // присваиваем очередной id
                                    chain.FmotivList[chain.FmotivList.Count - 1].Id = chain.FmotivList.Count - 1;
                                }

                                // в буфер заносим последний фмотив цепочки фмотивов нот с равнодлительностью
                                fmotivBuffer = (Fmotiv)dividedSameDuration[dividedSameDuration.Count - 1].Clone();

                                // добавляем сохраненную ноту с большой длительностью
                                for (int i = 0; i < fmotivBuffer2.NoteList.Count; i++)
                                {
                                    fmotivBuffer.NoteList.Add((ValueNote)fmotivBuffer2.NoteList[i].Clone());
                                }

                                // флаг комбинации
                                combination = true;

                                // флаг возрастающей последовательности, чтобы завершить фмотив - комбинация
                                growingDurationChain = true;

                                // убираем флаг для сбора равнодлительных нот
                                sameDurationChain = false;

                                // сохранили сколько нот/пауз входит в текущий буфер
                                n = fmotivBuffer.NoteList.Count;
                            }

                            // если длительность предпоследнего равна длительности последнего
                            if (TempExtractor(fmotivBuffer, ExtractNoteList(fmotivBuffer).Count - 2).Duration.Equals(TempExtractor(fmotivBuffer, ExtractNoteList(fmotivBuffer).Count - 1).Duration))
                            {
                                // записываем очередную ноты в фмотив с типом последовательность равнодлительных звуков
                                // (она уже записана, поэтому просто сохраняем число входящих в фмотив на данный момент нот/пауз)
                                // сохранили сколько нот/пауз входит в буфер
                                n = fmotivBuffer.NoteList.Count;
                            }

                            // если длительность предпоследнего больше длительности последнего
                            if (FifthTempComparator(fmotivBuffer))
                            {
                                var fmotivBuffer2 = new Fmotiv(string.Empty);

                                // помещаем в буффер2 последнюю собранную ноту - меньшей длительности чем все равнодлительные
                                int count = fmotivBuffer.NoteList.Count; // так как меняется в процессе
                                for (int i = n; i < count; i++)
                                {
                                    fmotivBuffer2.NoteList.Add((ValueNote)fmotivBuffer.NoteList[n].Clone());
                                    fmotivBuffer.NoteList.RemoveAt(n);
                                }

                                // отправляем последовательность равнодлительных звуков на анализ, получаем цепочку фмотивов и заносим их в выходную последовательность
                                foreach (Fmotiv fmotiv in DivideSameDurationNotes(fmotivBuffer))
                                {
                                    // заносим очередной фмотив
                                    chain.FmotivList.Add((Fmotiv)fmotiv.Clone());

                                    // присваиваем очередной id
                                    chain.FmotivList[chain.FmotivList.Count - 1].Id = chain.FmotivList.Count - 1;
                                }

                                // очищаем буффер
                                fmotivBuffer.NoteList.Clear();

                                // добавляем состав сохраненной ноты (паузы/лиги) с меньшей длительностью в буфер
                                for (int i = 0; i < fmotivBuffer2.NoteList.Count; i++)
                                {
                                    fmotivBuffer.NoteList.Add((ValueNote)fmotivBuffer2.NoteList[i].Clone());
                                }

                                // убираем флаг для сбора равнодлительных нот
                                sameDurationChain = false;

                                // сохранили сколько нот/пауз входит в текущий буфер
                                n = fmotivBuffer.NoteList.Count;
                            }
                        }
                        else
                        {
                            if (growingDurationChain)
                            {
                                // если длительность предпоследнего меньше длительности последнего
                                if (ForthTempComparator(fmotivBuffer))
                                {
                                    // записываем очередную ноты в фмотив с типом возрастающая последовательность
                                    // (она уже записана, поэтому просто сохраняем число входящих в фмотив на данный момент нот)
                                    n = fmotivBuffer.NoteList.Count; // сохранили сколько нот/пауз входит в буфер
                                }
                                else
                                {
                                    // иначе если длительности равны, или последняя по длительности меньше предпоследней, то составляем новый фмотив
                                    // также сохраняем не вошедшую последнюю ноту (не удаляем ее)
                                    if (combination)
                                    {
                                        var fm = new Fmotiv(fmotivBuffer.Type + "ВП", chain.FmotivList.Count);

                                        // ЧМТВП или ПМТВП
                                        for (int i = 0; i < n; i++)
                                        {
                                            // заносим
                                            fm.NoteList.Add((ValueNote)fmotivBuffer.NoteList[0].Clone());

                                            // удаляем
                                            fmotivBuffer.NoteList.RemoveAt(0);
                                        }

                                        // добавляем в выходную цепочку получившийся фмотив
                                        chain.FmotivList.Add((Fmotiv)fm.Clone());

                                        // сохранили сколько нот/пауз осталось в буфере от последней не вошедшей в фмотив ноты
                                        n = fmotivBuffer.NoteList.Count;

                                        // убрали флаг сбора возрастающей последовательности
                                        growingDurationChain = false;

                                        // убрали флаг сбора возрастающей последовательности
                                        combination = false;
                                    }
                                    else
                                    {
                                        var fm = new Fmotiv("ВП", chain.FmotivList.Count);
                                        for (int i = 0; i < n; i++)
                                        {
                                            // заносим
                                            fm.NoteList.Add((ValueNote)fmotivBuffer.NoteList[0].Clone());

                                            // удаляем
                                            fmotivBuffer.NoteList.RemoveAt(0);
                                        }

                                        // добавляем в выходную цепочку получившийся фмотив
                                        chain.FmotivList.Add((Fmotiv)fm.Clone());

                                        // сохранили сколько нот/пауз осталось в буфере от последней не вошедшей в фмотив ноты
                                        n = fmotivBuffer.NoteList.Count;

                                        // убрали флаг сбора возрастающей последовательности
                                        growingDurationChain = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // если в буфере осталась 1 непроанализированная нота
            if (ExtractNoteList(fmotivBuffer).Count == 1)
            {
                // заносим ноты/паузы 1 собранной ноты в очередной фмотив с типом ЧМТ, и удаляем из буфера
                var fm = new Fmotiv("ЧМТ", chain.FmotivList.Count);

                // for (int i = 0; i < FmotivBuffer.NoteList.Count; i++)
                foreach (ValueNote note in fmotivBuffer.NoteList)
                {
                    // заносим
                    fm.NoteList.Add((ValueNote)note.Clone());
                }

                // добавляем в выходную цепочку получившийся фмотив
                chain.FmotivList.Add((Fmotiv)fm.Clone());

                // очищаем буффер
                fmotivBuffer.NoteList.Clear();
            }

            // если в буфере остались непроанализированные ноты (больше 1)
            if (ExtractNoteList(fmotivBuffer).Count > 1)
            {
                if (sameDurationChain)
                {
                    // отправляем последовательность равнодлительных звуков на анализ, получаем цепочку фмотивов и заносим их в выходную последовательность
                    foreach (Fmotiv fmotiv in DivideSameDurationNotes(fmotivBuffer))
                    {
                        // заносим очередной фмотив
                        chain.FmotivList.Add((Fmotiv)fmotiv.Clone());

                        // присваиваем очередной id
                        chain.FmotivList[chain.FmotivList.Count - 1].Id = chain.FmotivList.Count - 1;
                    }

                    // очищаем буффер
                    fmotivBuffer.NoteList.Clear();
                }
                else
                {
                    if (growingDurationChain)
                    {
                        if (combination)
                        {
                            // заносим оставшиеся ноты в комбинированный фмотив ЧМТ/ПМТ + ВП и в выходную цепочку
                            var fm = new Fmotiv(fmotivBuffer.Type + "ВП", chain.FmotivList.Count); // ЧМТВП или ПМТВП
                            foreach (ValueNote note in fmotivBuffer.NoteList)
                            {
                                // заносим
                                fm.NoteList.Add((ValueNote)note.Clone());
                            }

                            // добавляем в выходную цепочку получившийся фмотив
                            chain.FmotivList.Add((Fmotiv)fm.Clone());

                            // очищаем буффер
                            fmotivBuffer.NoteList.Clear();
                        }
                        else
                        {
                            // заносим оставшиеся ноты в фмотив ВП и в выходную цепочку
                            var fm = new Fmotiv("ВП", chain.FmotivList.Count);
                            foreach (ValueNote note in fmotivBuffer.NoteList)
                            {
                                // заносим
                                fm.NoteList.Add((ValueNote)note.Clone());
                            }

                            // добавляем в выходную цепочку получившийся фмотив
                            chain.FmotivList.Add((Fmotiv)fm.Clone());

                            // очищаем буффер
                            fmotivBuffer.NoteList.Clear();
                        }
                    }
                }
            }

            return chain;
        }