Распознавание мелодии с помощью нечеткого поиска

Курсовой проект - Компьютеры, программирование

Другие курсовые по предмету Компьютеры, программирование

, данная информация сохраняется в _offsetMTrk, ничего не возвращает

CorrectReadMTrks() - анализирует каждый блок MTrk и определяет сыгранные ноты и такт для нее, ничего не возвращает

ReadMTrks (byte[] data) - определяет сыгранные ноты и такт для нее, возвращает структуру CompareData, в которой хранится список нот и номера тактов для соответствующей ноты

Read() - производит комплексный анализ файла, последовательно вызывая вышеописанные методы, ничего не возвращает.

Класс, который отвечает за отображение интерфейса пользователя - CompareMIDI. Содержит методы, в которых описана реакция приложения на соответствующие действия пользователя, а так же метод SelectFile(), в котором определяется выбранный для сравнения файл и возвращается поток в файле, поддерживающий синхронные и асинхронные операции чтения и записи.

И основной класс приложение - управляющий класс Comparer, он отвечает за сравнение двух мелодий, которые переданы на вход пользователем. В нем реализованы следующие методы:

Compare() - производится сравнение двух мелодий, определяется их процентное соответствие учитывая такт, ничего не возвращает

CompareMelody (MIDI. CompareData data1, MIDI. CompareData data2) - возвращает наименьше расстояние между двумя произведениями (int)

InTaktCompare (IList note2) - производится сравнение двух наборов нот внутри такта с помощью метрики Левенштейна. (double)

TaktCompare (MIDI. CompareData data1, MIDI. CompareData data2) - производится сравнение двух наборов нот, учитывая разбиение по тактам. (double)

GetValueOfStringTransform (String str1, String str2, List editorialRequirement) - вычисляет расстояние между входными строками (int)

Рассмотрим алгоритм работы приложения более подробно.

При нажатии Обзор появляется диалоговое окно выбора файлов для сравнения. Основные действия выполняются по нажатию кнопки Выполнить сравнение.

Алгоритм считывания реализован в методе Read(). В нем сначала происходит считывание предварительной информации: в файле находится и читается необходимая информация (заголовочный блок, тип файла, количество треков, их длина, их содержимое, количество тиков, приходящихся на четверть). Производится чтение так называемой карты темпа. Затем осуществляется подробный анализ блоков MTrk (блок трека): последовательно проходится блок и считывается целиком структура MIDI-сообщения (дельта-время, статус байт, байты данных). На основе этих данных формируется список сыгранных нот и номер такта, в котором эта нота сыграна.

Алгоритм сравнения без учета тактов.

Для сравнения мелодий без учета тактов, необходимо иметь список сыгранных нот (в алгоритме с учетом такта, еще и номер такта, в котором играется нота). Так как ноты уникальны, то им в соответствии ставится уникальный номер (от 0 до 127), а каждому номеру можно поставить в соответствие символ из таблицы Unicode-8, то есть список сыгранных нот - преобразовать в некую строку символов. Тогда алгоритм сравнения без учета тактов будет выглядеть следующим образом. Берутся списки нот каждой мелодии, осуществляется приведение к тональности одной из мелодий (линейный сдвиг номеров нот на значение равное разности между начальными нотами мелодий, с которых начинается сравнение, существенно, если мелодии имеют различное количество сыгранных нот), числовые значения преобразовываются в строки, и вычисляется расстояние Левенштейна. Если количество нот различно, n - количество нот в первой мелодии, m - количество нот во второй мелодии, причем n>m, то количество значений расстояния Левенштейна будет равняться n-m+1 - количество возможных вариантов сравнения. В этом случае будет выбираться минимум из расстояний Левенштейна. Определяется процентное соотношение, вычисленное по формуле:

 

где L - минимум из возможных расстояний Левенштейна, а Ml - наименьшее количество нот, выбранное из сравниваемых мелодий.

Алгоритм сравнения с учетом тактов.

Для сравнения мелодий с учетом тактов дополнительно потребуется знать, номер такта, в котором сыграна конкретная нота. Берутся списки нот каждой мелодии, осуществляется приведение к тональности одной из мелодий (линейный сдвиг номеров нот на значение равное разности между начальными нотами мелодий, с которых начинается сравнение, существенно, если мелодии имеют различное количество сыгранных нот). Затем происходит разбиение списка нот на такты, и уже на основе каждого такта осуществляется преобразование в отдельные строки (отдельный такт - отдельная строка). Последовательно вычисляется расстояние Левенштейна между соответствующими тактами, затем значения расстояния для каждого такта суммируются. Возможных вариантов суммированного расстояния, так же как и при сравнении без учета тактов равняется n-m+1. В этом случае выбирается минимум таких сумм. Определяется процентное соотношение, вычисленное по формуле:

 

 

где L - минимум из возможных расстояний Левенштейна, а Ml - наименьшее количество нот, выбранное из сравниваемых мелодий.

Пользователю выдается наибольшее из процентных значений в виде отдельного сообщения. После этого приложение готово осуществить сравнение следующих мелодий.

Физическое размещение классов по файлам выглядит следующим образом:

 

Рис. 13. Диаграмма размещений (ImplementationDiagram)

 

6. Тестирование

 

Сравнение мелодии и ее части.

 

Рис. 14. Полное совпадение

 

Сравнение коротких мелодий с добавлением лишних нот.

 

Рис. 15. Полное совпадение

Сравнение длинных мелодий с добавле