Algorytmiczne generowanie muzyki

Algorytmiczne generowanie muzyki (sztuki) – Początek

O algorytmicznym generowaniu muzyki myślano na długo przed powstaniem szybkich komputerów. W tym i następnych wpisach będę chciał przedstawić różne metody generowania muzyki przez algorytmy. Co raz częściej w kontekście Deep Learningu wspomina się o sztucznej muzyce czy też sztucznym powstawaniu obrazów. Można tutaj wyróżnić takie projekty jak Google Magenda czy projekt DeepJazz.

Jako pionierów generowania sztucznej muzyki uważa się Hillera i Isaacsona. Obaj panowie jako pierwsi w 1957 roku użyli komputera do stworzenia utworu muzycznego. Wygenerowali kompozycje dla kwartetu smyczkowego za pomocą komputera Uniwersytetu w Illinois.

Experimental Music - Hiller, Isaacson

Experimental Music – Hiller, Isaacson

Płyta winylowa z zapisem muzyki wygenerowanej przez Hillera/Isaacsona/Bakera

Płyta winylowa z zapisem muzyki wygenerowanej przez Hillera/Isaacsona/Bakera

 

Profesor Lejaren Hiller w swojej pracowni Experimental Music Studio na University of Illinois's

Profesor Lejaren Hiller w swojej pracowni Experimental Music Studio na University of Illinois’s

 

Fragment książki Hillera i Isaacsona

Fragment książki Hillera i Isaacsona

 

Kolejnym ważnym krokiem w historii był rok 1991, w którym Horner i Goldberg opracowali algorytm genetyczny do generowania muzyki. W 1981 roku David Cope rozpoczął pracę nad algorytmiczną kompozycją. Połączył łańcuchy Markowa z gramatykami i elementami kombinatoryki. Stworzył pół automatyczny system, który nazwał „Experiments in Musical Intelligence”.

David Cope podczas pracą nad EMI

David Cope podczas pracą nad EMI

David Cope w swoich pracach cytuje Xenakisa i Lejarena Hillera jako swoje inspiracje. Łańcuchy Markowa mogą jedynie generować podsekwensje, które pochodzą z utworów, na podstawie których łańcuch został wytrenowany. Rekurencyjne sieci neuronowe (RNN) wychodzą poza te ograniczenia. W 1989 roku odbyły się pierwsze próby generowania muzyki za pomocą rekurencyjnych sieci neuronowych. Badania zostały opracowane przez Petera M. Dodda, Michaela C. Mozera i kliku innych naukowców.

Spójrzmy na definicję słowa generować – tworzyć nieskończony zbiór prawidłowo zbudowanych zdań i wyznaczać dla każdego z nich jednoznaczny opis strukturalny. W kontekście generowania muzyki mamy na myśli produkt, który ma spójną strukturę, nie może to być ciąg chaotycznie ułożonych symboli.

Łańcuchy Markowa

Łańcuch Markowa opisuje sytuacje, w której zmienne losowe są zależne, ale znamy dobrze charakter tej zależności. Model ten został sformalizowany na początku XX wieku w celu modelowania systemów probabilistycznych, jest prężnie wykorzystywany w ekonomii, na giełdzie czy w algorytmie PageRank.  Aby nie wprowadzać matematycznego formalizmu możemy powiedzieć, że Łańcuch Markowa to pewien automat ze stanami. Automat może zmieniać swoje stany, to znaczy że może nastąpić przeniesienie ze stanu A do stanu B. Przykładowo stwórzmy łańcuch Markowa, który będzie modelował zachowanie dziecka. Nasz model będzie miał następujące stany: „bawienie się„, „jedzenie„, „spanie„, „płacz„. Stany w modelu tworzą tak zwaną przestrzeń stanów, czyli listę wszystkich możliwych stanów. Dodatkowo, poza przestrzenią stanów potrzeba jeszcze zdefiniować macierz prawdopodobieństw. Na podstawie macierzy prawdopodobieństw łańcuch Markowa będzie decydował o przeskoku z jednego stanu do innego. Automat bez prawdopodobieństw można zilustrować następująco:

Przestrzeń stanów bez prawdopodobieństw

Graf ilustruje pogląd na model łańcucha. Potrzeba jeszcze zdefiniować macierz prawdopodobieństw przejść dla stanów. W modelu występują 4 stany, więc macierz będzie rozmiaru 4×4.

     \[ M = \begin{bmatrix} 0.3 & 0.1 & 0.4  & 0.2\\ 0.1 & 0.5 & 0.3 & 0.1\\ 0.4 & 0.1 & 0.1 & 0.4 \\ 0.3 & 0.4 & 0.2 & 0.1 \\ \end{bmatrix}\\ \]

Suma prawdopodobieństw w jednym wierszu macierzy musi wynosić 1. Nie więcej, nie mniej 🙂 Pozostaje teraz nanieść prawdopodobieństwa na graf ze stanami. Wygląda to następująco:

Ze względu na to, że stany są cztery rysunek może się wydawać trochę skomplikowany. Proponuje spokojnie go przeanalizować z myślą o tym, że będąc w stanie X mogę udać się do jednego z 4 stanów z określonym prawdopodobieństwem. Mając przestrzeń stanów i macierz przejścia można zamodelować działanie łańcucha Markowa. Dla ułatwienia wprowadźmy oznaczenia: A – stan Play, B – stan Sleep, C – stan Eat, D – stan Cry. Poniższa animacja przedstawia „wędrówkę” po grafie z uwzględnioną macierzą przejść:

Łańcuch Markowa można stworzyć z dowolnej sekwencji, w której elementy powtarzają się i tworzą logiczną strukturę. Zastanówmy się więc jak wykorzystać łańcuch Markowa do wygenerowania fragmentu melodii?

Utwór muzyczny składa się ze zbioru symboli – nut. Każda nuta określa czas trwania dźwięku i jego wysokość. Mamy więc zbiór symboli, który jest sekwencją, która to rządzi się określonymi zasadami. Dla uproszczenia w dalszych rozważaniach będziemy mówić o melodii składającej się tylko z jednego klucza – wiolinowego (klucz basowy zostawiamy w spokoju) oraz o stałej długości czasu trwania pojedynczego dźwięku. Do stworzenia łańcucha Markowa potrzebujemy dwóch rzeczy: przestrzeni stanów i macierzy prawdopodobieństw. Weźmy więc skończoną sekwencje nut, powiedzmy długości 10. Przestrzenią stanów dla tej sekwencji będą nuty, a macierz przejść może zostać zbudowana biorąc pod uwagę kolejność występowania nut w sekwencji. Mamy więc przygotowany model, który za pomocą prawdopodobieństw może generować nowe sekwencje. Sprawdźmy to w praktyce.

Przykład

W przykładzie będę chciał wykorzystać podstawowy model łańcucha Markowa to wygenerowania nut na podstawie zadanej melodii.

Krok 1. Początkowa melodia

Niech początkową melodią będzie ciąg nut: D5 D#5 D5 A#4 G4 A#4 D5 D#5 D5 A#4 (liczby przy nutach oznaczają numer oktawy)

Oktawy

Oktawy

Krok 2. Stworzenie macierzy przejścia

Z początkowej sekwencji nut należy utworzyć macierz przejścia, która pokaże ile razy z danej nuty nastąpiło przejście do innej.

D#5A#4D5G4
D52200
D#50020
A#40011
G40100

Jak to czytać? Każda macierz składa się z wierszy i kolumn oraz ma określony rozmiar. Rozmiar macierzy w naszym przypadku jest określony przez liczbę „unikalnych” nut. Macierz powyżej jest rozmiaru 4×4, ponieważ unikalne nuty w początkowej sekwencji nut to: D5 D#5 A#4 G4. Unikalne nuty są nazywane kluczami. Każdy klucz w macierzy ma jakieś wartości. Klucz D5 ma wartości: D#5 oraz A#4. Na tej podstawie widać, że z nuty D5 nastąpiło dwukrotne przejście do nuty D#5 oraz A#4.

Krok 3. Generowanie nowej sekwencji

Generowanie nowej sekwencji wygląda w następujący sposób:

Losujemy klucz, następnie z danego klucza losujemy wartość, tutaj ma znaczenie ilość występowania danej nuty. Jeżeli  np. D5 występuje więcej razy niż inne nuty to prawdopodobieństwo wylosowania D5 jest oczywiście większe.

Wylosowana wartość zapisujemy.

Następnie dokonujemy kolejnego losowania. Tym razem klucz już mamy, jest nim poprzednia wylosowana wartość. Cały proces powtarzamy określoną ilość razy. Na końcu mamy wygenerowany nową sekwencję nut. Oczywiście nie jest to nic nadzwyczajnego, ponieważ nowa sekwencja bazuje tylko na następstwach z oryginalnej melodii.

Interaktywny przykład

Wejściowa melodia:


Wykorzystując jednorodny łańcuch Markowa, nie jesteśmy w stanie wygenerować niczego nadzwyczajnego. Należy pamiętać, że utwór muzyczny to zbiór cech: długość trwania dźwięku, wysokość, barwa, frazowanie itp. Aby uwzględnić te wszystkie cechy potrzeba bardziej rozbudowanego modelu. Niektóre z tych rzeczy można zrobić wykorzystując ukryte modele Markowa, ale o tym postaram się napisać w kolejnym wpisie.

 

Analogique

Iannis Xenakis używał łańcuchów Markowa w swoich kompozycjach, które potem zostały wydane na płycie Analogique A et B w 1958 roku nakładem GRM Paris. Cały proces opisał w książce o nazwie „Formalized Music: Thought and Mathematics in Composition”. Całe dzieło w formacie PDF można znaleźć tutaj.  Xenakis w swojej książce opisuje cały proces tworzenia muzyki. Można w niej znaleźć między innymi informacje na temat macierzy przejścia, w której zdefiniowane jest prawdopodobieństwo dla danych dźwięków.

Rozdział 3 - Markovian Stochastic Music - Applications

Rozdział 3 – Markovian Stochastic Music – Applications

Dzieła Xenakisa można posłuchać na YouTube.

Brzmi to dość nietypowo 🙂

Dla porównania muzyka z systemu Davia Copa (połączenie łańcuchów Markowa z gramatykami i kombinatoryką)

Jeżeli temat Cię zainteresował to zostaw komentarz!

Polecam inne artykuły z kategorii informatyka:

Uruchomienie Linuxa obok androida

Steganografia z poziomu teoretycznego i programowalnego

Niebawem pojawi się kolejny artykuł dotyczący algorytmicznego generowania muzyki, stay tuned 🙂

Część 2 – Ukryte Modele Markowa 

Źródła

  1. https://en.wikipedia.org/wiki/Markov_chain
  2. http://smurf.mimuw.edu.pl/node/713
  3. https://dke.maastrichtuniversity.nl/gm.schoenmakers/wp-content/uploads/2015/09/Linskens-Final-Draft.pdf
  4. https://www.americanscientist.org/article/first-links-in-the-markov-chain
  5. https://collected.jcu.edu/cgi/viewcontent.cgi?referer=https://www.google.pl/&httpsredir=1&article=1001&context=honorspapers
  6. Understanding Markov Chains: Examples and Applications

 

 

Algorytmiczne generowanie muzyki – początek cyklu
4.5 (90.59%) 17 votes
Share: