Академический Документы
Профессиональный Документы
Культура Документы
Научный руководитель,
доцент кафедры СП, к.ф.-м.н.
__________ С.А. Иванов
Автор работы,
студент группы КЭ-220
__________ Д.И. Ураканов
Ученый секретарь
(нормоконтролер)
_____________ И.Д. Володченко
«___»___________ 2021 г.
Челябинск, 2021 г.
МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное автономное образовательное учреждение
высшего образования
«Южно-Уральский государственный университет
(национальный исследовательский университет)»
Высшая школа электроники и компьютерных наук
Кафедра системного программирования
УТВЕРЖДАЮ
Зав. кафедрой СП
__________ Л.Б. Соколинский
08.02.2021 г.
ЗАДАНИЕ
на выполнение выпускной квалификационной работы магистра
студенту группы КЭ-220
Ураканову Денису Ивановичу,
обучающемуся по направлению
02.04.02 «Фундаментальная информатика и информационные технологии»
(магистерская программа «Машинное обучение и анализ больших данных»)
Научный руководитель,
доцент кафедры СП, к.ф.-м.н. С.А. Иванов
5
3) осуществить выбор средств реализации задачи;
4) организовать структуру баз данных и очередей сообщений;
5) реализовать модуль системы поиска схожих записей;
6) реализовать серверную и клиентскую части веб-приложения;
7) протестировать разработанное веб-приложение.
Структура и содержание работы
Работа состоит из введения, четырех глав, заключения и списка лите-
ратуры. Объем работы составляет 64 страницы, объем списка литературы –
21 источник.
Первая глава «Теоретическая часть» содержит обзор и сравнительное
исследование существующих подходов для поиска схожих аудиозаписей. В
главе рассмотрены основные пункты одного из алгоритмов для дальнейшей
реализации. В данной части также приводится сравнительный обзор анало-
гов на рынке.
Вторая глава «Проектирование» посвящена проектированию архитек-
туры веб-приложения для определения степени сходства музыкальных тре-
ков. В главе описаны основные компоненты системы, которые необходимо
реализовать.
В третьей главе «Реализация» содержится описание основных шагов
для реализации каждого компонента и интеграции в единую систему. В
главе предлагаются также собственные решения поставленных задач и их
обоснования.
В четвертой главе «Тестирование» приведены результаты тестов и
экспериментов для демонстрации степени корректной работы веб-приложе-
ния.
В заключении перечислены достигнутые результаты в выполнении за-
дач и приведены направления дальнейших исследований.
6
1. ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
1.1 Обзор литературы изучаемой темы
Литература, посвященная анализу звуковых сигналов и спектрограмм,
появилась задолго до создания систем анализа музыкальных записей. Од-
ним из первых приложений на массовом рынке стал Shazam. Со-основатель
компании-разработчика Ли-Чун Ванг написал статью [1] о глобальной кон-
цепции работы такого типа систем. В рамках данной статьи описываются
основные подходы к созданию алгоритма, устойчивого к шумам и искаже-
ниям, вычислительно эффективного и масштабируемого, способного
быстро идентифицировать короткий фрагмент музыки, записанной даже че-
рез микрофон телефона при наличии голосов на переднем плане, шумов, и
подвергающемуся сжатию кодека.
Основное понятие в данной статье и дальнейшей работе это отпечаток
аудиозаписи. «Отпечаток» аудиозаписи – это набор хеш-токенов, определя-
ющие идентификатор записи в ключе и некоторую адресацию частот в спек-
трограмме, хешированную, например, в формате md5, в значении ключа. Та-
кой «отпечаток» позволяет хранить основную информацию об аудиозаписи
в удобном формате в специальных хранилищах типа «hash-value» для быст-
рого доступа к ним.
Алгоритм, описанный в статье, определяет основные шаги для созда-
ния такой системы: оцифровка, дискретизация, перевод от стерео к моно,
даунсэмплинг (снижение частоты дискретизации), выполнение FFT (Быст-
рое преобразование Фурье), построение спектрограммы, выделение наибо-
лее сильных частот в единицу времени, сохранение в базу данных
хеш-токенов (отпечатков) и сравнение отпечатков записей между собой.
Более подробно с содержательным описанием оригинального доку-
мента процессы создания отпечатка описываются в статье в Интернете [5].
Здесь основные шаги, описанные в статье, вполне полно иллюстрируют про-
цесс, но детали, которые необходимы при разработке аналогичной системы,
7
опускаются или на них мало обращается внимание. Например, выполнение
даунсэмплинга должно зависеть от ряда параметров, но каких именно, в ста-
тье не указывается. Или, например, при создании хэш-токена, требуется вы-
числить определенную разницу во времени. В статьях не указаны приемы и
способы нахождения наиболее оптимальных значений для хэш-токена.
В статье [3] предпринята попытка создания алгоритма, основанной на
локально-линейном внедрении (Local Linear Embedding, LLE) с получением
отпечатка аудиозаписи, который потенциально занимает меньше места в
хранилище. Таким образом, анализатор меньше тратит времени на операции
чтение и записи с хранилищем. В данном алгоритме полосы делятся вокруг
каждого пика в частотной области на четыре группы подобластей, и вычис-
ляется энергия каждой подобласти. Затем выполняется алгоритм LLE для
каждой группы, а отпечаток аудиозаписи кодируется путем сравнения со-
седних энергий.
Общее между классическим подходом в Shazam и LLE в том, что со-
храняются не просто значения пиковых частот в аудиозаписи, а относитель-
ное положение определенной частоты среди ближайших к нему пиковых ча-
стот. Такой подход на порядок лучше «грубой силы» (brute force) тем, что
требуется меньше места в хранилище отпечатков. Разница в том, что LLE
оперирует понятиями «энергия области вокруг пиковой частоты», в то же
время, в классическом подходе выполняется получение относительного по-
ложения точки сигнала с помощью нахождения разницы во времени между
интересующей частотой и соседними.
В данной работе будет рассмотрен и реализован алгоритм на основа-
нии статьи [1] в рамках функционала необходимого для осуществления по-
ставленных требований.
8
1.2. Базовый принцип работы
В статье [1] предлагается, что каждый аудиофайл подвергается созда-
нию отпечатка – процессу извлечения воспроизводимых хеш-токенов. От-
печатки неизвестного образца сравниваются с большим набором отпечат-
ков, полученными из базы данных. И база данных, и исследуемый
аудиофайл подвергаются одинаковому процессу создания отпечатка.
Соответствующие кандидатуры впоследствии оцениваются на пред-
мет правильности совпадения. Один из критериев правильности совпадения
является синхронизация по времени. Группа хеш-токенов может быть ло-
кально равно удалена от той же идентичной группы хеш-токенов другой
аудиозаписи, что может означать, что исследуемая аудиозапись является ча-
стью из любого временного диапазона другой аудиозаписи.
Для решения проблемы надежной идентификации песен при наличии
шумов и искажений необходимо принимать в расчет только наиболее силь-
ные по амплитуде частоты в срезе временной области. Такие пики в каждой
временной области с наибольшей вероятностью выдержат искажения.
Наборы таких пиков на спектрограмме двух похожих аудиозаписей будет
достаточно или полностью схожими. Спектрограмма отображает мощность
сигнала с течением времени на различных частотах [11]. Спектрограммы
могут быть двухмерными графиками с третьей переменной, представленной
цветом, или трехмерными графиками с четвертой цветовой переменной.
9
Вместо того, чтобы сравнивать каждую частотно-временную точку на
спектрограмме одну за другой, необходимо искать несколько точек одно-
временно – в Shazam эта группа точек называется целевой зоной [12].
Чтобы быть уверенным в том, что и отрывок, и полная песня, будут
генерировать одни и те же целевые зоны, понадобятся соотношения между
частотно-временными точками в фильтрованной спектрограмме.
1. Если две частотно-временные точки имеют одинаковое время, то
точка с самой низкой частотой идет первой.
2. Впереди идут точки с самым маленьким временем.
Далее необходимо создать относительные адреса сразу целевой зоны,
а не определенной одной точки. Необходимо выбрать опорную точку за пре-
делом самой целевой зоны.
Допустим, что для работы размер целевой зоны равен 5, а опорная
точка – это третья точка перед каждой зоной.
10
На рисунке 1 продемонстрирован график, на котором ось абсцисс это
время, ось ординат – это частота. Точка номер «0» является опорной точкой,
а точка номер «3» является целевой точкой.
Далее необходимо сформировать адрес следующего плана:
[«Частота опорной точки», «Частота целевой точки», «Разница во вре-
мени между опорной точкой и целевой точкой»].
Например, адрес точки номер «4» в рамках зоны отмеченной на ри-
сунке 1 будет [10, 10, 2], а для точки номер «6» в той же зоне [10, 30, 2].
Для более оптимального хранения в виде ключа в «hash-value» храни-
лище адрес в виде массива можно захэшировать в md5.
Статья [5], описывающая основы работы системы Shazam, указывает,
что в рамках значения захэшированного ключа следует использовать кор-
теж из абсолютного времени опорной точки в песне и идентификатора
песни в реляционной базе. Абсолютное время опорной точки необходимо
для согласованности по времени.
11
Рисунок 2 – Похожие целевые зоны в разных аудиозаписях
12
3) в значении ключа должно быть поле с идентификатором интересу-
ющей аудиозаписи и, возможно, поля с идентификаторами иных аудиозапи-
сей;
4) если существуют поля с идентификаторами других аудиозаписей,
то вычисляется дельта между абсолютным временем исследуемой записи и
интересующей.
Данные сохраняются в хэш-таблицу для последующей обработки.
13
1.6. Ранжирование списка схожих аудиозаписей
Теперь нужно ранжировать список сравниваемых к интересующей
аудиозаписи между собой от наиболее схожих к наименее. В данной вы-
пускной работе предложены два подхода: использование среднеквадратиче-
ского отклонения или ранжирование по количеству дельт.
Так как наиболее схожие аудиозаписи имеют наименьшее различие в
значениях дельт времени, то можно утверждать, что значение дисперсии
набора дельт обратно пропорционально схожести аудиозаписей.
Второй предложенный подход заключается в подсчете количества
дельт времени, причем только тех, которые наиболее близки к определен-
ным N дельтам. Данные N дельт – это первые N дельт в списке дельт, отсор-
тированном в порядке уменьшения количества совпадений. Второй подход
хорошо подходит для случаев, когда исследуемый небольшой отрывок
имеет сравнительно маленькое значение дисперсии по сравнению с другими
аудиозаписями из-за небольшой энтропии дельт, связанной с короткой про-
должительностью записи.
14
Таблица 1 – Преимущества и недостатки приложений для поиска
определенной песни
Преимущества Недостатки
Быстрое и качественное нахожде- Приложение отвечает, что найден один трек,
ние определенного музыкального либо дает сигнал, что в базе не найдено похо-
трека. жих треков, либо указывает на неверный трек.
Обычно огромная база индексируе-
мых музыкальных треков.
Внедренная в приложение система
профиля, истории и удобного UI.
15
3. Системы нахождения аудиозаписей, интегрированные в поиско-
вые движки (таблица 3).
Пример: Google Assistant (Android).
Таблица 3 – Преимущества и недостатки систем, интегрированных
в поисковые движки
Преимущества Недостатки
Получение схожего трека по записи с Результат поиска – один определенный трек
микрофона или напева при полном соответствии
Выдача ресурсов от компании Google, Такие системы не могут проанализировать
где возможно прослушать полностью только личные пользовательские аудиоза-
писи
Получение нескольких схожих треков,
но только при частичном соответствии
16
2. ПРОЕКТИРОВАНИЕ
2.1. Требования к системе
Функциональные требования
1. Система должна предоставлять интерфейс для загрузки аудиоза-
писей пользователей.
2. Система должна выполнять создание «отпечатка» аудиозаписи по
требованию пользователя. С ростом количества запросов на создание «от-
печатка» система не должна терять производительность в любом ином
функционале.
3. Система должна выполнять анализ по нахождению схожих аудио-
записей по требованию пользователя. С ростом количества запросов на по-
иск система не должна терять производительность в любом ином функцио-
нале.
4. Система должна выполнять обновление списка схожих аудиозапи-
сей по требованию пользователя.
5. Система должна предоставлять интерфейс для просмотра схожих
аудиозаписей в ранжированном списке от наиболее схожих к наименее.
6. Система должна предоставлять возможность прослушивания
аудиозаписей.
7. Система должна предоставлять форму регистрации и авторизации.
Нефункциональные требования
1. Приложение должно работать с форматами .mp3, .ogg, .wav.
2. Приложение должно быть спроектировано таким образом, чтобы
иметь возможность горизонтального и вертикального масштабирования.
3. Определенные части приложения должны иметь возможность за-
пускаться в Docker контейнерах для удобного процесса развертывания на
различном оборудовании, создав при этом изоляцию непосредственно мо-
дуля от железа, на котором работает программа.
17
4. Каждый пользователь, работающий в системе должен, зарегистри-
роваться в системе, указав: e-mail пользователя, пароль для входа в систему.
Каждый пользователь должен иметь доступ к тому материалу, к которому
он привязан с учетом прав доступа.
5. Авторизация производится с помощью JWT (JSON Web Tokens).
6. Пользователь при входе в систему обязан указывать логин и па-
роль.
7. Пользователь при регистрации в системе обязать указывать пароль
два раза (для подтверждения).
8. Пароль шифруется на стороне сервера-обработчика.
9. Важные конфиденциальные данные передаются на сервер POST
запросом.
18
Пользователь системы имеет возможность прослушать открытые
аудиозаписи сообщества. Закрытые аудиозаписи видны только самому за-
грузившему в систему.
Авторизованный пользователь может управлять личным профилем,
например, изменять пароль или добавлять новую информацию о себе. К
тому же такой пользователь вправе управлять списком собственных аудио-
записей: добавлять новые, удалять или изменить название загруженного
трека. В дополнение к этому пользователь по требованию может создать от-
печаток аудиозаписи в хранилище. С имеющимся отпечатком система мо-
жет выполнить поиск схожих аудиозаписей в рамках личной библиотеки
пользователя или в рамках сообщества.
19
системе. Создаваемые запросы передаются с помощью REST HTTP на Rest-
сервер.
Rest-сервер выполняет авторизацию пользователей, передает нужную
информацию по требованию из реляционной базы данных и для выполнения
трудоемких операций отправляет сообщения в одну из очередей.
Реляционная база данных хранит информацию о пользователях и
аудиозаписях. В базе содержится информация о текущем состоянии выпол-
нении операций над определенной аудиозаписью.
Очередь сообщений является удобным средством для реализации
асинхронного выполнения задач, когда существуют операции, которые тре-
буют большего времени выполнения.
Модуль создания отпечатка принимает от очереди сообщение, в кото-
ром содержится информация о типе операции и нужных идентификаторах,
по которым возможно получить информацию из реляционной базы данных.
NoSQL база данных «ключ-значение» необходима для хранения отпе-
чатков аудиозаписей.
20
пляры класса User. Обновленную информацию Rest-сервер отправляет об-
ратно клиенту. На клиентской стороне возможна реализация реактивного
обновления, например, с помощью веб-сокетов.
21
При открытии страницы, отображающей список аудиозаписей, клиент
получает сначала список DTO (Data Transfer Object) данных записей. По тре-
бованию клиента запустить прослушивание аудиозаписи выполняется пере-
дача байтов информации записи. Передача возможна не только от бинар-
ного поля в базе данных, но и от файла в S3 (Simple Storage Service, Объект-
ное облачное хранилище).
На рисунке 7 представлена диаграмма по управлению списком аудио-
записей пользователя.
22
Данная диаграмма схожа по смыслу с диаграммой рисунка 6. Сначала
при запросе от пользователя Rest-сервер обрабатывает токен (resolve(token))
и по нему же определяет какой именно список аудиозаписей необходимо
отправить клиенту. В данном случае графический интерфейс пользователя
передает обновленную информацию объектам класса Track. К тому же поль-
зователь может как добавлять, так и удалять объекты класса Track.
Диаграмма вариантов использования уже демонстрировала, что поль-
зователь может сначала загрузить аудиозапись, только затем выполнить со-
здание отпечатка, а затем с уже существующим отпечатком в NoSQL «hash-
value» хранилище выполнить поиск схожих треков. На рисунке 8 представ-
лена диаграмма взаимодействия создания отпечатка аудиозаписи.
23
Для выполнения создания отпечатка актор может загрузить новую
аудиозапись, что необязательно, или выполнить операцию над уже суще-
ствующей записью. Актор отправляет сообщение о создании отпечатка с ин-
формацией о самой записи и параметрами. Далее работу принимают сер-
висы и хранилища.
Сервис TrackService является бизнес сервисом в компоненте «Rest-
сервис», его задача – отправить в очередь по созданию отпечатка информа-
цию о выполнения данной операции. Параллельно выполнению ранее опи-
санного процесса FingerprintModule (модуль в компоненте «Модуль созда-
ния отпечатка») уже получает очередное сообщения из очереди по созданию
отпечатка. В данном сообщении содержится необходимая для данного мо-
дуля информация: идентификатор аудиозаписи, по которым можно взять
непосредственно саму бинарную запись из реляционной базы данных, и воз-
можные параметры для уточнения выполнения операции. В рамках созда-
ния отпечатка модуль постоянно обращается к хранилищу «hash-value»,
чтобы сохранить часть отпечатка исследуемой записи.
На рисунке 9 представлена диаграмма взаимодействия выполнения
анализа схожих треков. Актор отправляет сообщение с информацией о
треке, у которого необходимо найти схожие записи, и типе операции (искать
схожие в рамках личной библиотеки пользователя или среди открытых со-
общества). TrackService отправляет сообщение в очередь, предназначенную
для анализа аудиозаписей. AnalyzeModule (модуль в компоненте «Модуль
выполнения анализа») принимает сообщения от очереди. В сообщении со-
держится информация об идентификаторе аудиозаписи и типе операции.
В процессе выполнения логики по поиску похожих аудиозаписей мо-
дуль обращается к хранилищу типа «ключ-значение» для получения необ-
ходимых данных для анализа.
После выполнения процедуры результат сохраняется в определенное
поле записи трека в реляционной базе данных.
24
Рисунок 9 – Диаграмма взаимодействия анализа схожих треков
25
Рисунок 10 – Диаграмма состояний класса Track (класса аудиозаписи)
26
3. РЕАЛИЗАЦИЯ
3.1. Организация схемы реляционной базы данных
Выбор СУБД
Для постоянного хранения данных о пользователях и аудиозаписях в
системе необходима база данных (БД). Так как доменная структура не явля-
ются специфичными, то следует выбрать классическую реляционную СУБД
(система управления базами данных). В качестве такой СУБД выбрана Post-
greSQL [8]. У данной СУБД есть ряд преимуществ: свободное распростра-
нение, высокопроизводительные механизмы транзакций и наличие большой
документации [21].
Схема базы данных
На рисунке 11 изображена схема базы данных для разрабатываемой
системы.
27
Таблица 4 – Описание полей таблицы Track
Поле Описание
Id Идентификатор записи
Compare_list Список с ранжированными идентификаторами аудиозапи-
сей наиболее похожих на текущую. Поле заполняется по-
сле выполнения методов модуля анализа отпечатка.
Content Непосредственно содержимое аудиозаписи
Created_date Дата создания записи в БД
File_name Наименование файла аудиозаписи
Fingerprint_index_status Статус выполнения создания отпечатка
Global_index_status Статус выполнения поиска похожих аудиозаписей в рам-
ках всех открытых записей сообщества
Local_index_status Статус выполнения поиска похожих аудиозаписей в рам-
ках библиотеки пользователя
Modified_date Дата изменения записи в БД
Name Пользовательское наименование аудиозаписи
User_id Внешний ключ на идентификатор (id) таблицы users
Length Длина аудиозаписи
Visible_status Статус области видимости аудиозаписи
28
Таблица Users_role_rel служит для создания связи многие-ко-многим
между таблицами Users и Track. Таким образом привязывается определен-
ная роль к пользователю. В таблице 7 указаны поля таблицы Users_role_rel
и их описание.
Таблица 7 – Описание полей таблицы Users_role_rel
Поле Описание
User_id Внешний ключ на идентификатор записи таблицы Users
Track_id Внешний ключ на идентификатор записи таблицы Track
29
В очереди (queue) сообщения хранятся сообщения до тех пор, пока не
будут забраны клиентом.
Для асинхронной работы Rest-сервера, модуля создания отпечатка и
модуля анализа отпечатка необходимы две очереди: в первой передается ин-
формация для выполнения создания отпечатка, во второй для выполнения
анализа.
В RabbitMQ для данных целей созданы две точки обмена: track-ana-
lyze-exchange и track-fingerpring-exchange с типом fanout (рисунок 12).
30
иного языка потребовалось либо писать определенные операции абсолютно
с нуля, либо пытаться дополнять возможности библиотеки. Одной из клю-
чевых библиотек, использующихся в модуле, является librosa. С ее помо-
щью выполняется быстрое преобразование Фурье и визуализация спектро-
граммы – что экономит время на этапе разработки.
Аналогово-цифровое преобразование звука и быстрое преобразо-
вание Фурье
Звук – это упругие волны в среде, которые невидимы, но воспринима-
емые человеческим ухом (волна воздействует на барабанную перепонку
уха). Звуковая волна является продольной волной сжатия и разрежения [14].
Любая волна может быть с любой точностью аппроксимирована (прибли-
жена) совокупностью синусоидальных волн.
Сначала выполняется аналогово-цифровое преобразование звука.
Цифровой звук – это аналоговый звуковой сигнал, представленный посред-
ством дискретных численных значений его амплитуды [19].
Оцифровка звука включает в себя два процесса.
1. Процесс дискретизации (осуществление выборки) сигнала по вре-
мени.
2. Процесс квантования по амплитуде.
Процесс дискретизации по времени – процесс получения значений
сигнала, который преобразуется с определенным временным шагом – шагом
дискретизации. Количество замеров величины сигнала, осуществляемых в
единицу времени, называют частотой дискретизации или частотой выборки,
или частотой сэмплирования (от англ. «sampling» – «выборка») [13].
Чем меньше шаг дискретизации, тем выше частота дискретизации и
тем более точное представление о сигнале нами будет получено. Соответ-
ственно, есть и обратная сторона – увеличение частоты сэмплирования уве-
31
личивает выходной временной ряд, представляющий набор частот, ампли-
туд и времени. Слишком большую информацию о звуковом сигнале трудно
хранить в рамках миллиона записей и неэффективно обрабатывать.
В научном сообществе данная проблема выбора оптимальной частоты
дискретизации уже была давно решена. Люди могут слышать звуки от 20 Гц
до 20 кГц. Исходя из теоремы Котельникова [15], чтобы оцифрованный сиг-
нал содержал информацию о всем диапазоне слышимых частот исходного
аналогового сигнала (20 Гц – 20 кГц) необходимо, чтобы выбранное значе-
ние частоты дискретизации составляло не менее 40 кГц.
В рамках реализуемого приложения система уже будет принимать
оцифрованный звук, но необходим ресэмплинг (изменение частоты сэмпли-
рования на иную).
Для выполнения многих уже известных операций над звуковым сиг-
налом в работе используется библиотека на языке Python librosa. С помощью
данной библиотеки получим временной ряд, репрезентирующий синусои-
дальную кривую по времени (рисунок 14).
x, sr = librosa.load("dst.wav", sr=SR)
32
Кратковременное быстрое преобразование Фурье (Short-time Fourier
Transform) выполняет быстрое преобразование Фурье не над всем массивом
данных, а только над ее частью, называемой «окном» (window) (рисунок 15).
33
Рисунок 16 – Размер сдвига кратковременного БПФ
34
Используя библиотеку librosa, выполним быстрое преобразование
Фурье.
В листинге 1 указан ряд констант:
1) FRAME_SIZE – размер окна;
2) HOP_SIZE – размер hop size;
3) SR – значение частоты дискретизации;
4) CHUNKS – массив для распределения строк frequency bins для со-
здания отпечатка.
Листинг 1 – Быстрое преобразование Фурье
FRAME_SIZE = 2048
HOP_SIZE = 512
SR = 22100
CHUNKS = [0, 10, 30, 60, 100, 200, 1024]
X = librosa.stft(x, n_fft=FRAME_SIZE, hop_length=HOP_SIZE)
35
Рисунок 18 – Спектрограмма с логарифмической шкалой
36
max_val = max(max_candidates)
max_chunk_list.append((max_val, chunk_val + max_candi-
dates.index(max_val)))
max_list.append(max_chunk_list)
return max_list
37
данного аспекта будет реализовано при поиске схожих, используя статисти-
ческие методы нахождения выбросов и аномалий.
Листинг 5 – Получение пиковых частот выше среднего значения
def getMaxOverAverage(max_list):
means = []
for index in range(0, len(max_list[0])):
column = list(map(lambda x: x[index], max_list))
means.append(np.mean(list(map(lambda x: x[0], column))))
max_over_average = []
for iter, max_list_column in enumerate(trans_max_list):
new_max_list_col = []
for max_list_value_tuple in max_list_column:
if max_list_value_tuple[0] < means[iter]:
new_max_list_col.append((max_list_value_tuple[0], -1000))
else:
new_max_list_col.append((max_list_value_tuple[0],
max_list_value_tuple[1]))
max_over_average.append(new_max_list_col)
max_over_average = np.array(max_over_average).transpose(1, 0,
2).tolist()
return max_over_average
38
элементами типа массив целочисленных значений, где первый элемент это
временной бин, а второй бин – это бин частоты (листинг 6).
Листинг 6 – Выполнение трансформации матрицы
def getMaxCoordArray(max_over_average):
max_over_average = np.array(max_over_average).transpose(1, 0,
2).tolist()
new_current_column_max_y = []
new_current_column_max_x = []
Пример:
Вход (листинг 7):
Листинг 7 – Входная матрица метода getMaxCoordArray()
[[[2, 1], [3, 0], [3, 1], [4, 0], [4, 1], [2, 0]],
[[2, 2], [2, -1000], [1, -1000], [2, -1000], [1, -1000], [3, 2]],
[[0, -1000], [4, 3], [3, 3], [4, 3], [2, -1000], [0, -1000]]]
39
Redis позволяет хранить информацию в формате HASH-VALUE. Дан-
ный формат наиболее подходит для текущей задачи. Так как в роли ключа
будет захэшированное значение адреса целевой точки (ключ уникален в
рамках базы), поле в рамках ключа – это идентификатор аудиозаписи в ре-
ляционной базе данных PostgreSQL (поле уникально в рамках ключа), а зна-
чение поля – это абсолютное время опорной точки в аудиозаписи.
В работе используется целевая зона из 25 точек, а опорная точка – это
третья точка до целевой зоны. Данные параметры выбраны эмпирическим
путем исходя из тестирования алгоритма (листинг 9).
Листинг 9 – Создание и сохранение отпечатка в хранилище
def getFingerPrint(max_coord, track_id):
max_coord = np.array(max_coord).T.tolist()
iter_proc = 0
for iter, maxima in enumerate(maxima_array):
if iter > 2:
anchor_point = maxima_array[iter - 3]
for target_point in maxima_array[iter:(iter + 25)]:
delta_time = target_point[0] - anchor_point[0]
address = [anchor_point[1], target_point[1], delta_time]
key = hashlib.md5(str(address).encode()).hexdigest()
iter_proc = iter_proc + 1
if redis_instance.hexists(key, track_id) == 1:
if redis_instance.hexists(key, track_id) != 1:
redis_instance.hset(key, track_id, anchor_point[0])
else:
redis_instance.hset(key, track_id, anchor_point[0])
40
построения отпечатка. В методе создания отпечатка getFingerPrint() исполь-
зуется библиотека redis для взаимодействия с хранилищем Redis. Метод
HSET() позволяет сохранить HASH-VALUE значение. Метод HEXISTS()
служит для определения – есть ли в базе определенный ключ с определен-
ным полем.
Интегрирование всех методов для создания отпечатка
Каждый из прошедших шагов выполняет определенную задачу в бо-
лее глобальной – создание и сохранение отпечатка аудиозаписи, информа-
ция о которой хранится в реляционной базе.
Определим далее порядок их следования, интегрировав в одном ме-
тоде process(), который запускается при получении очередного сообщения в
модуль создания отпечатка (листинг 10).
Листинг 10 – Интегрирование методов создания отпечатка
def process(track_id: int):
content = get_track_content_by_id(session, track_id)
41
Листинг 11 – Пример содержимого отпечатков hash-value в Redis
{
‘3d27085b5c1f9596e71a2a92b6871945’: {
‘1092’: 764.2187381,
‘82’: 21.3123123,
‘2402’: 102.321332
},
‘53880af179ef68fd5c0224f54180c744’: {
‘11’: 167.4564566,
‘49’: 60.3418877
},
‘e6d46a50df6ca22a9ffe53cb6c68a5f0’: {
‘9’: 54.345312
}
}
42
между абсолютным значением времени опорной точки кандидата и интере-
сующей записи в рамках одного ключа. Так как у кандидата и интересую-
щего трека может быть множество точек с одинаковым ключом, то инфор-
мация о разнице во времени сохраняется в памяти в hash-value таблицу, где
ключ – это идентификатор кандидата, а значение – это массив кортежей с
информацией о разнице во времени (временной дельте) и количества появ-
ления данной разницы (дельты). Возможная хэш-таблица представлена в ли-
стинге 12.
Листинг 12 – Получение всех дельт согласованности во времени
интересующей записи и сравниваемых (в рамках одинаковых ключей)
{'17283': [(1.51, 19),
(0.56, 13),
(0.19, 13),
(1.41, 12),
(0.09, 11),
(1.78, 10),
(-1.6, 10),
(10, 20)],
'34563': [(0.37, 84),
(0.0, 74),
(74.09, 61),
(0.74, 38),
(-1.71, 37),
(-50, 27),
(0.49, 33),
(-0.35, 30)]}
43
delta = round(float(current_song_average_time) -
float(redis_instance.hget(hash_value, song_id)), 2)
if full_delta_hash.get(song_id) is not None:
if full_delta_hash[song_id].get(delta) is not None:
full_delta_hash[song_id][delta] =
full_delta_hash[song_id][delta] + 1
else:
full_delta_hash[song_id][delta] = 1
else:
full_delta_hash[song_id] = {delta: 1}
44
Рисунок 19 – Правило трех сигм
45
Соответственно, можно ожидать, что чем сильнее отличается сравниваемая
запись от интересующей, тем больше различных дельт будет присутство-
вать.
Таким образом, можно попробовать ранжировать сравниваемые за-
писи по разбросу значений дельт, то есть использовать вычисление диспер-
сии и СКО для массива временных дельт (листинг 15).
Листинг 15 – Поиск и ранжирование схожих с помощью СКО
dispersion_dict = {}
for delta_hash in full_audio_delta_hash:
delta_arr = []
for delta_value in full_audio_delta_hash[delta_hash]:
delta_arr.extend([delta_value[0]] * delta_value[1])
dispersion_dict[delta_hash] = np.var(delta_arr)
dispersion_dict
= dict(sorted(dispersion_dict.items(), key=lambda item: item[1]))
46
Листинг 16 – Поиск и ранжирование похожих записей через количество
дельт
full_audio_delta_hash_max = {}
for music in full_audio_delta_hash:
if operation == '0':
user_id = get_track_user_id(session, int(music))
if user_id is None or str(user_id) != message_user_id:
continue
top_3_deltas = np.array(full_audio_delta_hash[mu-
sic]).T.tolist()[0][:3]
mean = np.mean(top_3_deltas)
full_delta_count = 0
for delta_tuple in full_audio_delta_hash[music]:
if delta_tuple[0] != 0 and (delta_tuple[0] > (mean - 1) or
delta_tuple[0] < (mean + 1)):
full_delta_count = full_delta_count + delta_tuple[1]
# Запись во временную хэш таблицу значения количества дельт для
определенной записи по ИД
full_audio_delta_hash_max[int(music)] = full_delta_count
message_user_id = '0'
if operation == '0':
message_user_id = message_params[2]
47
В листинге 17 описан метод, в котором сначала получено сообщение
строчного типа формата «trackId-operationType-userId», где trackId – иден-
тификатор аудиозаписи, operationType – код типа операции (0 – сравнение
аудиозаписи в рамках библиотеки пользователя, 1 – сравнение в рамках всех
открытых треков сообщества), userId – идентификатор пользователя. Если
необходим анализ в рамках библиотеки пользователя, то сравниваемые
треки – это аудиозаписи, загруженные самим пользователем.
После выполнения создания отпечатка интересующей записи, испол-
няются методы анализа и ранжирования, описанные ранее. Далее будет по-
лучен массив, содержащий значения идентификаторов схожих аудиозапи-
сей и ранжированный по критерию количества дельт. Для хранения резуль-
тата массив сериализуется в формат JSON и сохраняется в поле таблицы
Track реляционной базы данных. Статус выполнения анализа изменяется в
записи в таблице Track.
Далее при необходимости получить информацию о схожих треках для
данной аудиозаписи информация из поля будет десериализована из формата
JSON и выведена на пользовательский экран.
48
В таблице 8 перечислены основные конечные точки (endpoints), к ко-
торым может обращаться внешний участник.
Таблица 8 – Конечные точки для взаимодействия с аудиозаписями
Путь (api/tracks/) HTTP метод Краткое описание
bytes/{trackId} GET Получение записи трека в байтах
?userId={}&pageable={} GET Получение списка аудиозаписей
upload POST Загрузка аудиозаписи
{trackId} DELETE Удаление аудиозаписи
fingerprint/{trackId} GET Создание отпечатка для аудиоза-
писи
analyze/{trackId} GET Выполнения анализа для аудиоза-
писи
analyze/list/{trackId} GET Получение списка похожих аудио-
записей
49
Листинг 18 – Класс для генерации JWT токена
public String generateJwtToken(Authentication authentication) {
UserDetails userPrincipal = (UserDetails) authentication.getPrinci-
pal();
Date now = new Date();
return Jwts.builder()
.setSubject((userPrincipal.getUsername()))
.setIssuedAt(now)
.setExpiration(new Date((now).getTime() + jwtExpiration))
.signWith(Keys.hmacShaKeyFor(jwtSecret.getBytes()), SignatureAl-
gorithm.HS512).compact();
}
SecurityContextHolder.getContext().setAuthentication(au-
thentication);
}
} catch (Exception e) {
logger.error("Can NOT set user authentication -> Message: {}",
e);
SecurityContextHolder.clearContext();
} filterChain.doFilter(request, response);}
50
3.5. Реализация модуля SPA
В качестве фреймворка для фронт-энд части приложения был выбран
Vue.js. Данная технология имеет обширную документацию даже на русском
языке, большое сообщество и широкий выбор библиотек компонентов (ком-
поненты ввода, загрузки, выпадающего меню и т.п.).
Для задачи создания первоначальной версии приложения необходима
какая-либо из библиотек компонент. Такой библиотекой выбрана Quasar.
Реализация веб-оформления
Одностраничное приложение (single page application, SPA) – это веб-
приложение или веб-сайт, использующий единственный HTML-доку-
мент как оболочку для всех веб-страниц и организующий взаимодействие с
пользователем через динамически подгружаемые HTML, CSS, JavaScript,
обычно посредством AJAX [10].
В модуле SPA существует лишь один HTML документ. Бизнес-логика
приложения располагается в однофайловых компонентах .vue. Такой файл
хранит сразу шаблон компонента, javascript исходный код и CSS стили.
После входа в приложение пользователю будет отображаться основ-
ное меню (рисунок 20), из которого можно перейти в другие страницы (или
через боковое меню).
51
На странице «Мои треки» (рисунок 21) представлен список загружен-
ных пользователем аудиозаписей. Справа находится окно для загрузки но-
вых треков. В левой части окна расположено быстрое меню для перехода на
основные страницы приложения. В центре пользователь может запускать
прослушивание треков, создание отпечатков или анализ трека на схожесть
с другими.
52
Рисунок 23 – Ожидание создания отпечатка
53
Рисунок 25 – Статус о процессе выполнения анализа
54
Рисунок 28 – Страница схожих треков ремикса «Турецкий марш»
55
4. ТЕСТИРОВАНИЕ
Тестирование веб-приложения для определения степени схожести му-
зыкальных треков разделено на модульное тестирование, функциональное
тестирование и эксперимент по качеству нахождения схожих записей.
Данные формы тестирования проводились на оборудовании с ви-
деокартой NVIDIA GeForce GTX 1660 SUPER, ОЗУ 16 Гб, процессором
AMD Ryzen 5 3600 6 × 3600 МГц.
56
Листинг 20 – Пример модульного тестирования
# Модульное тестирование метода frameIndexToTime
def test_frameIndexToTime(self):
FRAME_SIZE = 2048
HOP_SIZE = 512
SR = 22100
57
4.2. Функциональное тестирование
Функциональное тестирование заключается в проверке факта кор-
ректной работы функционала, заявленных в требованиях к системе, реали-
зованных на базе спроектированных модулей. Функциональные тесты прой-
дены успешно. Система выполняет асинхронное выполнение трудоемких
операций успешно. Система является горизонтально и вертикально масшта-
бируемой. Детальные результаты тестирования приведены в таблице 10.
Таблица 10 – Функциональное тестирование веб-приложения
№ Функционал Ожидаемый результат Результат
тестирова-
ния
1 Регистрация пользователя Запись пользователя корректно Пройден
занесена в базу данных. Пользо-
ватель перенаправляется на
страницу логина
2 Авторизация пользователя с Переход на главную домашнюю Пройден
корректным логином и па- страницу веб-приложения
ролем
3 Авторизация пользователя с Появления предупреждения о Пройден
некорректным логином и некорректно заполняемых полях
паролем
4 Загрузка аудиозаписей че- Запись успешно загружена. По- Пройден
рез пользовательский ин- явление новой строчки в списке
терфейс аудиозаписей пользователя
5 Выполнение создания «от- Появление меню напротив за- Пройден
печатка» аудиозаписи фор- писи о возможности выполнить
матов .mp3, .ogg, .wav. поиск похожих аудиозаписей
6 Выполнение поиска схожих Появление меню напротив за- Пройден
аудиозаписей писи о возможности просмотра
похожих аудиозаписей в ранжи-
рованном формате
7 Выполнение очередного по- Появление меню напротив за- Пройден
вторного поиска схожих писи о возможности просмотра
аудиозаписей похожих аудиозаписей в ранжи-
рованном формате
8 Просмотр схожих аудиоза- Появление интерфейса с наиме- Пройден
писей нованием интересующей аудио-
записи и ранжированным спис-
ком похожих к интересующей
аудиозаписей
9 Прослушивание аудиоза- Появление звука данной аудио- Пройден
писи записи. Аудиоплеер браузера
показывает корректное время за-
писи
58
Окончание таблицы 10
10 Создание десяти заявок на Система отображает для записей Пройден
выполнение создание «от- с заявками статус «В процессе
печатка» создания отпечатка». Система
выполняет иной другой функци-
онал без ожидания выполнения
заявок
11 Создание десяти заявок на Система отображает для записей Пройден
поиск схожих аудиозаписей с заявками статус «В процессе
анализа». Система выполняет
иной другой функционал без
ожидания выполнения заявок
59
различных жанров и направлений. Результаты такого тестирования пред-
ставлены в таблице 11.
Таблица 11 – Проверка качества поиска схожих треков
№ Наименование ориги- Место реми- Примечание
нала кса в списке
схожих
1 В.А. Моцарт, «Турецкий 1 Иные классические произведения
марш» располагаются по 5 место
2 В.Р. Вагнер, «Полет валь- 2 На первом месте симфония № 40
кирий» В.А. Моцарта
3 Людвиг ван Бетховен, 1 «Турецкий марш» Моцарта на 2-ом
Bagatelle no 25 «К Элизе» месте. По 5 место поп-песни или
песни жанра кантри
4 Queen, «We are the cham- 1 Большинство песен из первых 10
pions» мест – это поп-песни с выделяющи-
мися гитарными звучаниями
60
создана аудиозапись, анализируемая на данном шаге. Кроме того, была за-
гружена аудиозапись («We are the champions – К Элизе»), созданная анало-
гично анализируемой, но с обратным порядком соединения двух ремиксов –
в первой половине «We are the champions», во второй половине «К Элизе».
Результат полученных наиболее похожих аудиозаписей для послед-
него созданного вручную трека «К Элизе – We are the champions» представ-
лен в таблице 12.
Таблица 12 – Схожие аудиозаписи для «К Элизе – We are the champions»
№ Наименование аудиозаписи Место аудиозаписи
в списке схожих
1 Людвиг ван Бетховен, Bagatelle no 25 «К Элизе» 1
(ремикс)
2 «We are the champions – К Элизе» 2
3 Queen, «We are the champions» (ремикс) 3
4 Людвиг ван Бетховен, Bagatelle no 25 «К Элизе» 4
5 Queen, «We are the champions» 5
6 Maluma, «Que Chimba» 6
7 В.А. Моцарт, «Турецкий марш» 7
8 Matt Stell, «That ain`t Me No More» 8
61
ЗАКЛЮЧЕНИЕ
Цель данной работы состояла в разработке веб-приложения для опре-
деления степени сходства музыкальных треков. Поставленная цель была до-
стигнута.
В ходе выполнения работы были решены следующие задачи.
1. Проведен анализ существующих алгоритмов определения схожих
треков и выполнен обзор аналогов.
2. Выполнено проектирование архитектуры приложения.
3. Осуществлен выбор средств реализации задачи.
4. Организована структура баз данных и очередей сообщений.
5. Реализован модуль системы поиска схожих записей.
6. Реализованы серверная и клиентская части веб-приложения.
7. Протестировано разработанное веб-приложение.
Направления дальнейших исследований
В дальнейшей работе по данному проекту планируется добавить авто-
матическое определение музыкального жанра, используя MFCC (Mel-
frequency cepstral coefficients, Мел-кепстральные коэффициенты), а также
повысить качество определения схожих аудиозаписей с помощью жанровой
принадлежности.
62
ЛИТЕРАТУРА
1. An Industrial –Strength Audio Search Algorithm. [Электронный ре-
сурс] URL: https://www.ee.columbia.edu/~dpwe/papers/Wang03-shazam.pdf
(дата обращения: 24.04.2021 г.).
2. An Interactive Guide To The Fourier Transform. [Электронный ре-
сурс] URL: https://betterexplained.com/articles/an-interactive-guide-to-the-fou-
rier-transform/ (дата обращения: 24.04.2021 г.).
3. Audio Fingerprint Extraction Based on Locally Linear Embedding for
Audio Retrieval System. [Электронный ресурс] URL:
https://www.mdpi.com/2079-9292/9/9/1483 (дата обращения: 22.04.2021 г.).
4. Ayanoglu E., Aytas Y., Nahum D. Mastering RabbitMQ. – Packt Pub-
lishing, 2015. – P. 286.
5. How does Shazam work. [Электронный ресурс] URL: http://coding-
geek.com/how-shazam-works/ (дата обращения: 26.04.2021 г.).
6. Interpret FFT, complex DFT, frequency bins & FFTShift. [Электрон-
ный ресурс] URL: https://www.gaussianwaves.com/2015/11/interpreting-fft-
results-complex-dft-frequency-bins-and-fftshift (дата обращения:
24.04.2021 г.).
7. JSON Web Tokens. [Электронный ресурс] URL: https://jwt.io/intro-
duction (дата обращения: 24.04.2021 г.).
8. PostgreSQL 10.16 Documentation. [Электронный ресурс] URL:
https://www.postgresql.org/files/documentation/pdf/10/postgresql-10-A4.pdf
(дата обращения: 24.04.2021 г.).
9. RabbitMQ. Documentation. [Электронный ресурс] URL:
https://www.rabbitmq.com/documentation.html (дата обращения:
24.04.2021 г.).
10. SPA (Single-page Application). [Электронный ресурс] URL:
https://developer.mozilla.org/en-US/docs/Glossary/SPA (дата обращения:
25.04.2021 г.).
63
11. What is a spectrogram? [Электронный ресурс] URL: https://vibra-
tionresearch.com/blog/what-is-a-spectrogram/ (дата обращения: 24.04.2021 г.).
12. Whitepaper Review: How Shazam Works – Part 2. [Электронный
ресурс] URL: https://www.mcand.ru/how-shazam-works-part-2 (дата обраще-
ния: 24.04.2021 г.).
13. Звук: немного теории. [Электронный ресурс] URL: http://web-
sound.ru/articles/theory/sound-theory.htm (дата обращения: 24.04.2021 г.).
14. Звуковые волны. [Электронный ресурс] URL:
http://msk.edu.ua/ivk/Fizika/Konspekt/Zvuk.php (дата обращения:
26.04.2021 г.).
15. Котельников В.А. О пропускной способности эфира и прово-
локи в электросвязи – Всесоюзный энергетический комитет. – М.: Управ-
ление связи РККА, 1933. – С. 762 – 770.
16. Модульное тестирование. Зачем, как и кто. [Электронный ре-
сурс] URL: http://citforum.ru/SE/testing/unit_testing/ (дата обращения:
21.04.2021 г.).
17. Нуссбаумер Г. Быстрое преобразование Фурье и алгоритмы вы-
числения сверток. – М.: Радио и связь, 1985. – 248 с.
18. Плохотников К.Э. Статистика // К.Э. Плохотников, С.В. Кол-
ков – М.: ФЛИНТА, 2012. – 288 с.
19. Понятно о кодировании аудио. [Электронный ресурс] URL:
http://websound.ru/articles/technologies/clarification_r.htm (дата обращения:
24.04.2021 г.).
20. Что такое ремикс, ремейк и кавер. [Электронный ресурс] URL:
http://www.as-workshop.ru/articles/276-remix (дата обращения:
24.04.2021 г.).
21. Шенинг Г. Ю. PostgreSQL 11 Мастерство разработки. / пер. с
англ. А.А. Слинкина. – М.: ДМК Пресс, 2019. – 352 с.
64