コード例 #1
0
        /// <summary>
        /// The divide.
        /// </summary>
        /// <param name="scoreTrack">
        /// The score track.
        /// </param>
        /// <param name="paramPauseTreatment">
        /// The param pause treatment.
        /// </param>
        /// <param name="paramEqualFM">
        /// The param equal fm.
        /// </param>
        /// <returns>
        /// The <see cref="List{FmotivChain}"/>.
        /// </returns>
        public List<FmotivChain> Divide(ScoreTrack scoreTrack, ParamPauseTreatment paramPauseTreatment, ParamEqualFM paramEqualFM)
        {
            var chains = new List<FmotivChain>();

            foreach (CongenericScoreTrack congenericTrack in scoreTrack.CongenericScoreTracks)
            {
                var fmotivChain = (FmotivChain)Divide(congenericTrack, paramPauseTreatment, paramEqualFM).Clone();
                fmotivChain.Id = chains.Count;
                chains.Add(fmotivChain);
            }

            return chains;
        }
コード例 #2
0
        /// <summary>
        /// The divide.
        /// </summary>
        /// <param name="congenericTrack">
        /// The congeneric track.
        /// </param>
        /// <param name="paramPauseTreatment">
        /// The param pause treatment.
        /// параметр как учитывать паузу :
        /// игнорировать, звуковой след предыдущего звука, вырожденныый звук
        /// </param>
        /// <param name="paramEqualFM">
        /// The param equal fm.
        /// как сравнивать ф-мотивы с секвентым переносом, либо нет
        /// </param>
        /// <returns>
        /// The <see cref="FmotivChain"/>.
        /// </returns>
        public FmotivChain Divide(CongenericScoreTrack congenericTrack, ParamPauseTreatment paramPauseTreatment, ParamEqualFM paramEqualFM)
        {
            // сохраняем имя цепи фмотивов как имя монотрека
            var priorityDiscover = new PriorityDiscover();
            var fmotivDivider = new FmotivDivider();
            var fmotivIdentifier = new FmotivIdentifier();

            // подсчет приоритетов
            priorityDiscover.Calculate(congenericTrack);

            // разбиение
            FmotivChain chain = fmotivDivider.GetDivision(congenericTrack, paramPauseTreatment);

            // нахождение одинаковых
            return fmotivIdentifier.GetIdentification(chain, paramPauseTreatment, paramEqualFM);
        }
コード例 #3
0
        /// <summary>
        /// The get identification.
        /// </summary>
        /// <param name="fmotivChain">
        /// The fmotiv chain.
        /// </param>
        /// <param name="paramPauseTreatment">
        /// The param pause treatment.
        /// </param>
        /// <param name="paramEqualFM">
        /// The param equal fm.
        /// </param>
        /// <returns>
        /// The <see cref="FmotivChain"/>.
        /// </returns>
        public FmotivChain GetIdentification(FmotivChain fmotivChain, ParamPauseTreatment paramPauseTreatment, ParamEqualFM paramEqualFM)
        {
            var chain = (FmotivChain)fmotivChain.Clone();

            for (int i = 0; i < chain.FmotivList.Count; i++)
            {
                for (int j = i; j < chain.FmotivList.Count; j++)
                {
                    if (chain.FmotivList[i].FmEquals(chain.FmotivList[j], paramPauseTreatment, paramEqualFM))
                    {
                        chain.FmotivList[j].Id = chain.FmotivList[i].Id;
                    }
                }
            }

            for (int i = 0; i < chain.FmotivList.Max(fl => fl.Id); i++)
            {
                bool haveId = chain.FmotivList.Any(t => t.Id == i); // флаг того что есть такой id в цепочке
                if (!haveId)
                {
                    foreach (Fmotiv fmotiv in chain.FmotivList)
                    {
                        if (fmotiv.Id > i)
                        {
                            // уменьшаем на 1 id тех фмотивов которые больше текущей  id - i, которой не нашлось в цепи
                            fmotiv.Id--;
                        }
                    }

                    // уменьшаем i на 1 чтобы еще раз проверить есть ли это i среди цепи после уменьшения id-ек больших i
                    i--;
                }
            }

            return chain;
        }
コード例 #4
0
        /// <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;
        }
コード例 #5
0
        // TODO: убрать все частные и заменить на общие!!!!!!!!! заменил все withoutpauses() на PauseTreatment с параметорм ignore
        /// <summary>
        /// The pause treatment.
        /// </summary>
        /// <param name="paramPauseTreatment">
        /// The param pause treatment.
        /// </param>
        /// <returns>
        /// The <see cref="Fmotiv"/>.
        /// </returns>
        /// <exception cref="Exception">
        /// Thrown if paramPauseTreatment is unknown.
        /// </exception>
        public Fmotiv PauseTreatment(ParamPauseTreatment paramPauseTreatment)
        {
            // возвращает копию этого объекта
            switch (paramPauseTreatment)
            {
                case ParamPauseTreatment.Ignore:
                        // удаляем все паузы в возвращаемом объекте (0) (паузы игнорируются)
                        var temp = (Fmotiv)Clone();
                        for (int i = 0; i < temp.NoteList.Count; i++)
                        {
                            if (temp.NoteList[i].Pitch != null && temp.NoteList[i].Pitch.Count == 0)
                            {
                                temp.NoteList.RemoveAt(i);
                                i--;
                            }
                        }

                        return temp;

                case ParamPauseTreatment.NoteTrace:
                        // длительность паузы прибавляется к предыдущей ноте,
                        // а она сама удаляется из текста (1) (пауза - звуковой след ноты)
                        var temp2 = (Fmotiv)Clone();

                        // если пауза стоит вначале текста (и текст не пустой) то она удаляется
                        while (temp2.NoteList.Count > 0)
                        {
                            if (temp2.NoteList[0].Pitch != null && temp2.NoteList[0].Pitch.Count > 0)
                            {
                                break;
                            }

                            temp2.NoteList.RemoveAt(0);
                        }

                        for (int i = 0; i < temp2.NoteList.Count; i++)
                        {
                            if (temp2.NoteList[i].Pitch.Count == 0)
                            {
                                // к длительности предыдущего звука добавляем длительность текущей паузы
                                temp2.NoteList[i - 1].Duration.AddDuration((Duration)temp2.NoteList[i].Duration.Clone());

                                // удаляем паузу
                                temp2.NoteList.RemoveAt(i);
                                i--;
                            }
                        }

                        return temp2;

                case ParamPauseTreatment.SilenceNote:
                        // Пауза - звук тишины, рассматривается как нота без высоты звучания (2)
                        // ничего не треуется
                        return (Fmotiv)Clone();

                default:
                    throw new Exception("Error Fmotiv.PauseTreatment parameter contains wrong value!");
            }
        }
コード例 #6
0
        /// <summary>
        /// The fm equals.
        /// </summary>
        /// <param name="obj">
        /// The object.
        /// </param>
        /// <param name="paramPauseTreatment">
        /// The param pause treatment.
        /// </param>
        /// <param name="paramEqualFM">
        /// The param equal fm.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        /// <exception cref="Exception">
        /// Thrown if paramEqualFM is unknown.
        /// </exception>
        public bool FmEquals(object obj, ParamPauseTreatment paramPauseTreatment, ParamEqualFM paramEqualFM)
        {
            // для сравнения паузы не нужны, поэтому сравнивае ф-мотивы без пауз (они игнорируются, но входят в состав ф-мотива)
            Fmotiv self = PauseTreatment(paramPauseTreatment).TieGathered();
            Fmotiv other = ((Fmotiv)obj).PauseTreatment(paramPauseTreatment).TieGathered();
            int modulation = 0;
            bool firstTime = true;

            if (self.NoteList.Count != other.NoteList.Count)
            {
                // фмотивы - неодинаковы, так как входит разное количество нот
                return false;
            }

            for (int i = 0; i < self.NoteList.Count; i++)
            {
                // одинаково ли количество высот у нот?
                if (self.NoteList[i].Pitch.Count != other.NoteList[i].Pitch.Count)
                {
                    // если нет - фмотивы - неодинаковы
                    return false;
                }

                // одинаковы ли длительности у нот?
                if (!self.NoteList[i].Duration.Equals(other.NoteList[i].Duration))
                {
                    // если нет - фмотивы - неодинаковы
                    return false;
                }

                if ((self.NoteList[i].Pitch.Count == 0) || (other.NoteList[i].Pitch.Count == 0))
                {
                    if (!((self.NoteList[i].Pitch.Count == 0) && (other.NoteList[i].Pitch.Count == 0)))
                    {
                        // если одна из нот пауза, а вторая - нет, то ф-мотивы не одинаковы
                        return false;
                    }

                    // если две паузы одно длительности то идем дальше. пропуская их (считаем что это две одинаковые ноты в любом случае)
                }
                else
                {
                    // если две ноты - не паузы
                    // в зависимости от параметра учета секвентного переноса
                    switch (paramEqualFM)
                    {
                        case ParamEqualFM.Sequent: // учитывая секентный перенос (Sequent)
                            for (int j = 0; j < self.NoteList[i].Pitch.Count; j++)
                            {
                                if (firstTime)
                                {
                                    // при первом сравнении вычисляем на сколько полутонов отличаются первые ноты,
                                    // последущие должны отличаться на столько же, чтобы фмотивы были равны
                                    modulation = self.NoteList[i].Pitch[j].MidiNumber -
                                                 other.NoteList[i].Pitch[j].MidiNumber;
                                    firstTime = false;
                                }

                                // одинаковы ли при этом высоты / правильно ли присутствует секвентный перенос (модуляция)
                                if (modulation !=
                                    (self.NoteList[i].Pitch[j].MidiNumber - other.NoteList[i].Pitch[j].MidiNumber))
                                {
                                    return false;
                                }
                            }

                            break;

                        case ParamEqualFM.NonSequent:
                            // без секвентного переноса (NonSequent)
                            for (int j = 0; j < self.NoteList[i].Pitch.Count; j++)
                            {
                                if (self.NoteList[i].Pitch[j].MidiNumber != other.NoteList[i].Pitch[j].MidiNumber)
                                {
                                    return false;
                                }
                            }

                            break;

                        default:
                            throw new Exception("Error Fmotiv.ParamEqualFM parameter contains wrong value!");
                    }
                }
            }

            return true;
        }