Это очередная статья в серии обучающих статей для разработчиков в сфере искусственного интеллекта. В предыдущих статьях и мы рассмотрели сбор и подготовку данных с изображениями, в данной статье мы продолжим обсуждение сбора и изучения музыкальных данных.
Целью данного проекта является:
- Создание приложения, принимающего на входе набор изображений.
- Выделение эмоциональной окраски изображений.
- Получение на выходе музыкального произведения, отражающего соответствующую эмоцию.
Данный проект использует для генерации музыки, модулированной с помощью эмоций, алгоритм (Музыкальной трансформации на основе эмоций), который выполняет изменение базовой мелодии в соответствии с конкретной эмоцией и последующую гармонизацию и завершение мелодии с помощью модели глубокого обучения. Для выполнения этой задачи потребуются следующие музыкальные наборы данных:
- Набор данных для обучения алгоритма завершения мелодии (хоралы Баха).
- Набор популярных мелодий, служащих шаблонами для модуляции эмоций.
Сбор и изучение музыкального набора данных
Хоралы Баха — проект Music21
Music21 представляет собой набор инструментов на базе Python для музыковедческой работы с использованием компьютера. Он содержит полную коллекцию хоралов Баха в качестве одной из составных частей своего собрания сочинений. Поэтому процедура сбора данных является очень простой — требуется всего лишь установить пакет music21 (доступны руководства для macOS*, Windows* и Linux*).
После установки доступ к хоралам Баха можно получить с помощью следующего кода:
from music21 import corpus
for score in corpus.chorales.Iterator(numberingSystem='bwv', returnType='stream'):
pass
# do stuff with scores here
Итерация по всем хоралам Баха
В качестве альтернативы можно использовать следующий код: он возвращает список имен файлов для всех хоралов Баха, который можно в дальнейшем обработать с помощью функции разбора:
from music21 import corpus
chorales = corpus.getBachChorales()
score = corpus.parse(chorales[0])
# do stuff with score
Получение списка всех хоралов Баха
Изучение данных
После завершения сбора данных (в этом случае после получения доступа к нему) следующим действием является проверка и изучение признаков этих данных.
Следующий код отображает текстовое представление музыкального файла:
>>> from music21 import corpus
>>> chorales = corpus.getBachChorales()
>>> score = corpus.parse(chorales[0])
>>> score.show('text')
{0.0} <music21.text.TextBox "BWV 1.6 W...">
{0.0} <music21.text.TextBox "Harmonized...">
{0.0} <music21.text.TextBox "PDF 2004 ...">
{0.0} <music21.metadata.Metadata object at 0x117b78f60>
{0.0} <music21.stream.Part Horn 2>
{0.0} <music21.instrument.Instrument P1: Horn 2: Instrument 7>
{0.0} <music21.stream.Measure 0 offset=0.0>
{0.0} <music21.layout.PageLayout>
{0.0} <music21.clef.TrebleClef>
{0.0} <music21.key.Key of F major>
{0.0} <music21.meter.TimeSignature 4/4>
{0.0} <music21.note.Note F>
{1.0} <music21.stream.Measure 1 offset=1.0>
{0.0} <music21.note.Note G>
{0.5} <music21.note.Note C>
{1.0} <music21.note.Note F>
{1.5} <music21.note.Note F>
{2.0} <music21.note.Note A>
{2.5} <music21.note.Note F>
{3.0} <music21.note.Note A>
{3.5} <music21.note.Note C>
{5.0} <music21.stream.Measure 2 offset=5.0>
{0.0} <music21.note.Note F>
{0.25} <music21.note.Note B->
{0.5} <music21.note.Note A>
{0.75} <music21.note.Note G>
{1.0} <music21.note.Note F>
{1.5} <music21.note.Note G>
{2.0} <music21.note.Note A>
{3.0} <music21.note.Note A>
{9.0} <music21.stream.Measure 3 offset=9.0>
{0.0} <music21.note.Note F>
{0.5} <music21.note.Note G>
.
.
.
>>> print(score)
<music21.stream.Score 0x10bf4d828>
Текстовое представление хорала
Выше представлено отображение текстового представления хорала в качестве объекта music21.stream.Score. Узнать о том, как проект music21 представляет музыку в коде, интересно, однако не слишком полезно с точки зрения изучения важных признаков данных. Поэтому нам требуется программное обеспечение, которое может отображать партитуру.
Как было ранее указано в статье Настройка модели и гиперпараметров для распознавания эмоций на изображениях, партитура в собрании сочинений music21 хранится в файлах MusicXML* (с расширениями .xml или .mxl). Для просмотра этих файлов в музыкальной нотации используется бесплатное приложение Finale NotePad*2 (ознакомительная версия профессионального пакета Finale* для работы с музыкальной нотацией). Приложение Finale NotePad доступно для ОС Mac и Windows. После загрузки Finale Notepad запустите следующий код для настройки music21 для работы с Finale Notepad:
>>> import music21
>>> music21.configure.run()
Теперь мы можем запустить вышепрведенный код, однако использовать при этом фрагмент score.show() вместо score.show(‘text’). При этом файл MusicXML будет открыт в приложении Finale, которое выглядит примерно следующим образом:
Первая страница хорала Баха в музыкальной нотации
Данный формат обеспечивает более понятное визуальное представление для хоралов. При рассмотрении нескольких хоралов убеждаемся в том, что данные соответствуют нашим ожиданиям: Это короткие музыкальные пьесы, содержащие по меньшей мере четыре партии (сопрано, альт, тенор и бас), разделенные на отдельные фразы посредством фермат.
Обычно в рамках процедуры изучения данных выполняется вычисление определенной описательной статистики. В данном случае мы можем определить, сколько раз встречается в собрании сочинений каждая тональность. Далее приведен пример кода, позволяющего вычислить и визуализировать рейтинг использования каждой тональности в наборе данных.
from music21 import*
import matplotlib.pyplot as plt
chorales = corpus.getBachChorales()
dict = {}
for chorale in chorales:
score = corpus.parse(chorale)
key = score.analyze('key').tonicPitchNameWithCase
dict[key] = dict[key] + 1 if key in dict.keys() else 1
ind = [i for i in range(len(dict))]
fig, ax = plt.subplots()
ax.bar(ind, dict.values())
ax.set_title('Frequency of Each Key')
ax.set_ylabel('Frequency')
plt.xticks(ind, dict.keys(), rotation='vertical')
plt.show()
Частота использования каждой тональности в собрании сочинений. Минорные тональности представлены буквами в нижнем регистре, а мажорные тональности — буквами в нижнем регистре. Бемоли обозначаются знаком «-»
Ниже приведена некоторая статистика, связанная с собранием сочинений.
Распределение используемых тональностей в наборе сочинений
Расположение нот, рассчитанное как смещение от начала такта в четвертных нотах
Описательная статистика, представляющая интерес для вычисления, будет различаться для каждого проекта. Однако в большинстве случаев она может помочь вам разобраться в том, с каким типом данных вы работаете, и даже управлять определенными действиями при предварительной обработке данных. Данная статистика также может служить в качестве отправной точки для изучения результатов предварительной обработки данных.
Музыкальная трансформация — теоретические сведения
Существует два основных носителя экспрессии в музыке — высота звуков и ритм. Эти носители экспрессии мы используем в качестве параметров, чтобы переписать нашу мелодию в выбранном настроении.
В музыкальной теории, когда речь идет о высоте звуков в мелодии, подразумевается соотношение высот между нотами. Система музыкальных нот, основанная на последовательности звуков определенной высоты, называется звукорядом. Интервалы или мера ширины каждого шага последовательности могут отличаться друг от друга. Такая разница или ее отсутствие создает отношения между тонами и мелодические тенденции, в которых стабильные сочетания и тяготения создают экспрессию настроения. В западной музыкальной традиции, когда речь идет о простом диатоническом звукоряде, положение ноты относительно первой ноты звукоряда называется ступенью звукоряда (I-II-III-IV-V-VI-VII). В соответствии с устойчивыми сочетаниями и тяготениями, ступень звукоряда обеспечивает музыкальный тон, выполняющий свою функцию в системе. Это делает понятие ступени звукоряда очень полезным в анализе простого мелодического рисунка и кодировании его с возможностью присваивания различных значений.
На начальном уровне нам необходимо выбрать звукоряды, подходящие с художественной точки зрения для создания любого конкретного настроения. Таким образом, если нам необходимо изменить настроение мелодии, следует исследовать ее функциональную структуру с помощью описанного понятия звукоряда, после чего присвоить новые значения существующему шаблону из ступеней звукоряда. Подобно карте, этот шаблон также содержит информацию о направлениях и периодах в мелодии.
Для каждого конкретного настроения мы используем некоторые дополнительные параметры, чтобы сделать наши новые мелодии более экспрессивными, гармоничными и выразительными.
Ритм — это способ организации звуков во времени. Он включает в себя такую информацию, как: порядок появления тонов в мелодии, их относительная длина, паузы между ними и различные акценты. Таким образом для структурирования музыкального размера создаются временные периоды. Если нам необходимо сохранить исходный мелодический рисунок, то следует сохранить его ритмическую структуру. Для достижения поставленной цели необходимо лишь изменить некоторые параметры ритма — длину нот и пауз — и этого должно быть достаточно с художественной точки зрения. Помимо этого, чтобы сделать нашу видоизмененную мелодию более экспрессивной, мы можем использовать некоторые дополнительные способы, чтобы подчеркнуть ее настроение.
Например, БЕСПОКОЙСТВО может быть выражено с помощью минорной тональности и более энергичного ритма. Шаблон нашего исходного звукоряда выглядит следующим образом: V-V-VI-V-I-VII V-V-VI-V-II-I V-V-V (переход на октаву выше)-III-I-VII-VI IV-IV-III-I-II-I.
Исходный шаблон
Исходная мелодия написана в мажорной тональности, которая отличается от минорной тремя нотами — в мажорной тональности III, VI и VII ступени являются мажорными (на полтона выше), а в минорной тональности — минорными (на полтона ниже). Поэтому если нам необходимо изменить используемую тональность, следует просто заменить повышенные ступени на пониженные (или наоборот). Однако для создания еще более рельефного эффекта беспокойства необходимо оставить VII ступень мажорной (повышенной) — это увеличит неустойчивость этого тона и подчеркнет наш звукоряд особым способом.
Чтобы сделать ритм более энергичным, мы можем добавить в него синкопу, или синкопическое прерывание регулярного движения ритма, посредством изменения положения некоторых нот. В этом случае мы переместим некоторые похожие ноты на один такт вперед.
Преобразование БЕСПОКОЙСТВО
ГРУСТЬ также может быть выражена с помощью простой минорной тональности, однако ее ритм при этом должен быть спокойным. Итак, мы заменяем мажорные ступени на минорные, включая VII ступень. Чтобы сделать ритм более спокойным, необходимо заполнить паузы с помощью увеличения длины нот перед ними.
Преобразование ГРУСТЬ
Для выражения БЛАГОГОВЕНИЯ нам следует избегать решительных и строгих интонаций — это будет принципом соответствующего преобразования. Как видите, в соответствии с отличиями используемой последовательности звуков, ступени звукоряда имеют различное значение и расстояние от первой (I) ступени. Таким образом создается их значение в общей картине. Поэтому движение от IV ступени к I ступени является очень прямолинейным вследствие своей функции. Интонация при движении от V ступени к I ступени также звучит очень прямолинейно. Мы будем избегать этих двух интонаций, чтобы создать впечатление пространства и неопределенности.
Поэтому в каждом элементе шаблона, в котором после V ступени следует I ступень, либо после IV ступени следует I ступень, а также при обратном порядке следования этих ступеней, мы заменим одну из этих нот (либо обе ноты) на ближайшие к ним ступени. Изменить ритм можно способом, аналогичным созданию эффекта ГРУСТИ — просто за счет снижения темпа.
Преобразование БЛАГОГОВЕНИЕ
РЕШИТЕЛЬНОСТЬ связана с мощным движением, поэтому простейший способ показать ее — это изменить ритм способом, аналогичным изменению для эффекта БЕСПОКОЙСТВО. При этом также необходимо сократить длительность всех нот за исключением каждой последней ноты каждого периода, V-V-VI-V-I-VII V-V-VI-V-II-I.
Преобразование РЕШИТЕЛЬНОСТЬ
Мажорная тональность сама по себе звучит позитивно и радостно, однако для подчеркивания и выражения СЧАСТЬЯ/РАДОСТИ мы используем мажорную пентатоническую тональность. Она состоит из тех же ступеней за исключением двух из них — четвертой и седьмой, I-II-III-V-VI.
Поэтому каждый раз при обнаружении этих двух ступеней в нашем шаблоне мы заменяем их ближайшими к ним ступенями. Чтобы подчеркнуть простоту, обеспечиваемую нашей тональностью, мы используем нисходящий мелодический фрагмент, состоящий из пяти или более нот, в качестве пошаговой демонстрации нашего звукоряда.
Преобразование РАДОСТЬ
СПОКОЙСТВИЕ/БЕЗМЯТЕЖНОСТЬ может быть выражено не только посредством изменения тональности, также для этого необходимо преобразование мелодического движения. Для этого необходимо проанализировать исходный шаблон и выделить в нем похожие сегменты. Первая нота каждого сегмента определяет гармонический контекст всей фразы, поэтому эти ноты представляют для нас наибольшую ценность: V-V-VI-V-I-VII V-V-VI-V-II-I V-V-V-III-I-VII-VI IV-IV-III-I-II-I.
Для первого сегмента следует использовать только следующие ступени: IV-V-I-VII; для второго: V-VII-II-I; для третьего: VI-VII-III-II; для четвертого: VII-IV-I-VII.
Эти наборы возможных ступеней в действительности являются другим типом музыкальной структуры, аккордами. Однако мы по-прежнему можем использовать их в качестве системы для преобразования мелодии. Ступени звукоряда можно заменить на ближайшие к ним ступени из указанных аккордовых шаблонов. Если целый сегмент начинается с тона, который ниже исходного, то необходимо заменить все ступени в нем на более низкие ступени, которые доступны в указанном шаблоне. Для создания эффекта задержки также необходимо разбить длительность каждой ноты на восьмые ноты и постепенно уменьшать скорость этих новых восьмых нот.
Преобразование СПОКОЙСТВИЕ/БЕЗМЯТЕЖНОСТЬ
Чтобы подчеркнуть БЛАГОДАРНОСТЬ, необходимо использовать ее стилистическое отображение в ритме, создавая эффект арпеджио: мы возвращаемся к первой ноте в конце каждого сегмента (фразы). Необходимо сократить вдвое длительность каждой последней ноты в сегменте и поместить туда первую ноту этого сегмента.
Преобразование БЛАГОДАРНОСТЬ
Практическая часть
Python и набор инструментов music21
Скрипт для трансформации был реализован с использованием языка Python и набора инструментов music21.
Music21 представляет собой очень универсальный и высокоуровневый класс для выполнения манипуляций с такими музыкальными понятиями, как: ноты, размер, аккорд, тональность и т. д. Он позволяет выполнять операции непосредственно в предметной области в отличие от низкоуровневых манипуляций с «сырыми» данными из файла цифрового интерфейса музыкальных инструментов (MIDI). Однако прямая работа с MIDI-файлами в music21 не всегда удобна, особенно когда речь идет о визуализации партитуры. Поэтому для визуализации и реализации алгоритма более удобным способом будет преобразование исходных MIDI-файлов в формат musicXML. Кроме того, формат musicXML является входным форматом для BachBot, который представляет собой следующий этап в нашей последовательности обработки.
Преобразование может быть выполнено с помощью Musescore:
для получения на выходе файла musicXML:
musescore input.mid -o output.xml
для получения на выходе MIDI-файла:
musescore input.mid -o output.mid
Jupyter
Набор инструментов music21 хорошо интегрирован с приложением Jupyter. Кроме этого, интеграция с Musescore позволяет отображать партитуру непосредственно в документе Jupyter notebook и прослушивать полученные результаты через встроенный проигрыватель в процессе разработки и экспериментирования.
Документ Jupyter notebook с кодом, партитурой и проигрывателем
Функция Score Show особенно полезна для командной работы программиста и музыканта-теоретика. Сочетание интерактивного характера Jupyter, специфичного для предметной области представления music21 и простоты языка Python делает этот рабочий процесс особенно обещающим для данного вида междисциплинарных исследований.
Реализация
Скрипт для трансформации был реализован в качестве модуля Python, таким образом он позволяет выполнять прямой вызов:
python3 emotransform.py --emotion JOY input.mid
Или же его можно вызвать через внешний скрипт (или Jupyter):
from emotransform import transform transform('input.mid','JOY')
В обоих случаях результатом работы будет файл, модулированный с помощью определенной эмоции.
Преобразования, связанные с изменениями нотных ступеней — БЕСПОКОЙСТВО, ГРУСТЬ, БЛАГОГОВЕНИЕ и РАДОСТЬ — основаны на использовании функции music21.Note.transpose в сочетании с анализом текущего и требуемого положения нотных ступеней. Здесь мы используем модуль music21.scale и его функции для построения требуемого звукоряда от любой тоники. Для получения тоники конкретной мелодии можно использовать функцию analyze('key') из модуля music21.Stream7.
Для преобразований, основанных на фразах — РЕШИТЕЛЬНОСТЬ, БЛАГОДАРНОСТЬ, СПОКОЙСТВИЕ/БЕЗМЯТЕЖНОСТЬ — требуется дополнительное исследование. Данное исследование позволит нам точно обнаруживать начало и конец музыкальных фраз.
Заключение
В данной статье мы представили основную идею, лежащую в основе музыкальной трансформации на основе эмоций — изменение положения отдельной ноты в звукоряде относительно тоники (нотная ступень), темпа пьесы, а также музыкальной фразы. Данная идея была реализована в виде скрипта на языке Python. Однако реализация теоретических идей в реальном мире не всегда является простой, поэтому мы столкнулись с некоторыми трудностями и определили возможные направления для будущих исследований. Данное исследование в основном связано с обнаружением музыкальных фраз и их преобразованиями. Правильный выбор инструментов (music21) и исследования в сфере получения музыкальной информации являются ключевыми факторами для решения таких задач.
Музыкальная трансформация на основе эмоций представляет собой первый этап в нашей последовательности обработки музыкальных данных, следующим этапом является подача преобразованной и подготовленной мелодии на вход BachBot.