Hochschule für Technik, Wirtschaft und Kultur Leipzig Fakultät Informatik, Mathematik und Naturwissenschaften Masterstudiengang Medieninformatik Schriftliche Ausarbeitung zum Masterprojekt Entwicklung eines Algorithmus zur Generierung optimaler Tonsätze zu Akkordsymbol-Folgen Eingereicht von: Martin Finke Matrikelnummer: 61931 Leipzig, 30. März 2015 Betreuer: Prof. Dr. rer. nat. Johannes Waldmann Abstrakt Im harmonischen Tonsystem westlicher Musik werden Akkorde oft als Akkordsymbole dargestellt. Beim Spielen auf einem Instrument entscheiden Musiker, wie die zu spielenden Töne angeordnet werden. Diese Arbeit zeigt einen Algorithmus, der zu jedem Akkordsymbol eines Songs eine optimale Anordnung der Töne findet. Dafür werden Bewertungsregeln und Constraints verwendet, die den Bedürfnissen und Fähigkeiten des Musikers angepasst werden, zum Beispiel der Reichweite seiner Hände. Jeder Akkord wird einzeln sowie im Zusammenhang mit seinem Vorgänger und Nachfolger bewertet. Das Problem wird als kürzeste-Wege-Problem in einem Graphen modelliert, die Laufzeit ist polynomial. Eine Implementation in der Programmiersprache Haskell mit Bewertungsfunktionen für das Klavier ist vorhanden. i Abstract In tonality of Western music, chords are commonly represented as chord symbols. Musicians playing an instrument arrange the notes to be played for a given chord symbol. This paper shows an algorithm that finds an optimal arrangement of notes for each chord symbol in a song. It uses rating rules and constraints that can be customized to fit the user’s requirements and capabilities, like the reaching area of his hands. Each chord is rated in isolation and in the context of its ancestor and successor. The problem is modeled as a shortest path problem in a graph and solved in polynomial time. An implementation in the Haskell programming language is provided, including rating functions for the piano. ii Inhaltsverzeichnis 1 Einleitung 1.1 Grundbegriffe . . . . . 1.2 Motivation . . . . . . . 1.3 Zielsetzung . . . . . . 1.4 Vorhandene Lösungen 1.5 Lösungsplan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Beschreibung des Algorithmus 2.1 Datenmodell . . . . . . . . . . . . . 2.2 Vorgehensweise . . . . . . . . . . . 2.3 Erzeugung möglicher Hände . . . . 2.4 Erzeugung möglicher Sub-Folgen . 2.5 Verbindung der Sub-Folgen . . . . 2.6 Finden einer optimalen Hand-Folge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 1 2 3 3 . . . . . . 4 4 8 9 12 13 15 3 Ergebnisse 17 4 Ausblick 21 Literatur I iii 1 Einleitung 1.1 Grundbegriffe Ein Akkord ist das das gleichzeitige Erklingen von zwei oder mehr Noten [Kár65, S. 63]. Akkorde sind eine der Grundlagen des harmonischen Tonsystems westlicher Musik [Deb07, S. 45] und spielen besonders in der Jazz- und Popmusik eine zentrale Rolle. In diesen Musikrichtungen ist es üblich, Akkorde nicht als Noten darzustellen, sondern als Akkordsymbol. Dieses gibt an, welche Tonart und welches Tongeschlecht ein Akkord hat (zum Beispiel C-Dur). Es kann außerdem Angaben über Töne enthalten, die zusätzlich zu Grundton, Quinte und der Terz des Tongeschlechts gespielt werden sollen. Diese zusätzlichen Töne heißen Spannungstöne. Ein Akkordsymbol kann explizit angeben, welcher Ton beim Spielen der tiefste sein muss (Slash-Akkord), enthält aber darüber hinaus keine Festlegung über die Anordnung der Töne im Notensystem. Außerdem ist nicht festgelegt, welcher Finger welchen Ton spielt. 1.2 Motivation Musiker, die Akkordinstrumente wie Gitarre oder Klavier spielen, setzen Akkordsymbole in gespielte Töne auf dem Instrument um. Dabei entscheiden sie über die Anordnung der Töne und über den Fingersatz. Eine Akkordlage ist eine mögliche Anordnung der Töne eines Akkordsymbols. Besonders im Jazz wird dieser Schritt häufig improvisiert, während das Lied gespielt wird. Der Grund ist, dass Lieder spontan während einer Jam-Session ausgewählt werden. Wegen der Größe 1 1 Einleitung des Liederkatalogs bereiten sich Musiker nicht auf jedes einzelne Lied vor, sondern entwickeln durch Üben an verschiedenen Liedern ein allgemeines Verständnis, wie ein einzelnes Akkordsymbol oder eine Akkordsymbol-Folge auf dem Instrument gespielt wird, um einen bestimmten Klang zu erzielen [Aeb67, S. 3]. Eine andere Vorgehensweise ist, für alle Akkordsymbole festzulegen, in welcher Lage sie gespielt werden. Dieser Arbeitsschritt heißt Tonsatz und ist verbreitet, wenn das Lied in einem größeren Zusammenhang (zum Beispiel Konzert) aufgeführt wird. Ein weiterer Grund kann sein, dass das Stück anspruchsvoll ist und der Musiker seine Aufmerksamkeit beim Spielen auf andere Dinge richten möchte. Theoretisch ist die Anzahl der Möglichkeiten, ein Akkordsymbol auf einem Instrument zu spielen, exponentiell zur Anzahl der zu spielenden Töne. In der Praxis sind die Möglichkeiten durch technische Grenzen des Instruments sowie durch anatomische Grenzen und ästhetische Ziele des Musikers eingeschränkt. 1.3 Zielsetzung Diese Arbeit beschreibt einen Algorithmus, der zu einer Folge von Akkordsymbolen einen optimalen Tonsatz durchführt und Fingersätze zuweist. Die Optimalität ist bezüglich vorgegebener Regeln, die jeweils einer Akkordlage oder einer Folge von Akkordlagen eine Bewertungszahl zuordnen. Außerdem wird durch vorgegebene Constraints (zum Beispiel anatomische Möglichkeiten des Instrumentalisten) eingeschränkt, welche Akkordlagen überhaupt infrage kommen. Der Algorithmus soll Instrumentalisten dabei helfen, für Lieder oder Passagen innerhalb eines Liedes spielbare und den ästhetischen Zielen entsprechende Akkordlagen zu finden. 2 1 Einleitung 1.4 Vorhandene Lösungen Vorhandene Lösungen zu ähnlichen Problemen lassen sich in folgende Kategorien einteilen: • Hinzufügen von Akkorden zu einer gegebenen Melodie [RP98; KMH13; PR01]. Dieses Problem wird Automatic Harmonization Problem (AHP) genannt. • Erzeugen von Akkordsymbolen ohne Vorgabe einer Melodie [HS11; EP10]. • Funktionsharmonische Analyse von Akkordsymbolen [Haa+11; LJ83]. • Erzeugen eines Fingersatzes zu einem gegebenen Tonsatz [KNR07; YKS07]. • Erzeugen von Gitarrentabulaturen zu mehrstimmigen Musikstücken [TP05]. Ein genetischer Algorithmus zur Erzeugung spielbarer Gitarrentabulaturen [TP05] hat ein ähnliches Ziel wie diese Arbeit: Die Töne eines mehrstimmigen Musikstücks werden den Saiten einer Gitarre so zugewiesen, dass das Ergebnis angenehm spielbar ist. Die Bewertung erfolgt durch eine Fitnessfunktion, wobei jeweils ein Lösungskandidat eine mögliche Tabulatur für das gesamte Musikstück ist. Der Algorithmus findet im Allgemeinen lokale Optima und betrachtet immer das gesamte Musikstück. Der in dieser Arbeit beschriebene Algorithmus findet ein globales Optimum und betrachtet Teilabschnitte eines Musikstücks. Die Länge der Teilabschnitte ist variabel und kann so gewählt werden, dass das gesamte Musikstück betrachtet wird. Außerdem werden keine Gitarrentabulaturen erzeugt, sondern ein Notensatz mit Klavierfingersätzen. 1.5 Lösungsplan Das Problem wird als ein kürzeste-Wege-Problem in einem Graphen modelliert. Ein kürzester Weg wird durch eine Implementierung in Haskell mit der Functional Graph Library (FGL) [Erw] bestimmt. 3 2 Beschreibung des Algorithmus 2.1 Datenmodell In diesem Abschnitt werden die verwendeten Datentypen definiert. Der entsprechende Typ der Haskell-Implementierung1 ist jeweils als Fußnote vermerkt. Sei P die Menge der Töne2 (engl. pitch class) ohne enharmonische Verwechslung, definiert als: P = {pC , pC♯ , pD , pD♯ , pE , pF , pF♯ , pG , pG♯ , pA , pA♯ , pB } (2.1) Eine Tonhöhe kann durch ein Paar bestehend aus Ton und Oktave eindeutig beschrieben werden. Im MIDI-Standard werden Oktaven als natürliche Zahlen von 0 aufsteigend dargestellt. Der Standard beschreibt außerdem Tonhöhen durch die natürlichen Zahlen 0 (entspricht (pC , 0)) bis 127 (entspricht (pG , 10)) [95, S. 10]. Diese Konvention wird im folgenden übernommen und verallgemeinert, sodass auch Tonhöhen außerhalb des Intervalls {0, . . . , 127} darstellbar sind. Also werden Oktaven und Tonhöhen als ganze Zahlen dargestellt. Die Menge der Tonhöhen3 (engl. pitch) ist die Menge der ganzen Zahlen: Pabs = Z 1 (2.2) Die Haskell-Implementierung ist unter http://github.com/martinfinke/Harmony verfügbar. Entspricht dem Typ Types.PitchClass. 3 Entspricht dem Typ Types.Pitch. 2 4 2 Beschreibung des Algorithmus Die Funktion pitch ordnet einem Paar aus Ton und Oktave eine Tonhöhe zu:4 pitch : (P × Z) → Pabs (2.3) pitch(p, o) = 12 · o + pitchClassOffset(p) mit: pitchClassOffset : P → Z { (pC , 0), (pC♯ , 1), (pD , 2), (pD♯ , 3), pitchClassOffset = (pE , 4), (pF , 5), (pF♯ , 6), (pG , 7), (pG♯ , 8), (pA , 9), (pA♯ , 10), (pB , 11) (2.4) } Die Funktion pitch entspricht zwischen (pC , 0) und (pG , 10) dem MIDI-Standard. Beispiel 2.1: Für den Ton pF♯ in der Oktave 4 ist die Tonhöhe: pitch(pF♯ , 4) = 12 · 4 + pitchClassOffset(pF♯ ) = 48 + 6 = 54. Die Menge der Tongeschlechter5 (engl. mode) ist definiert als: M = {Minor, Major} (2.5) Die Menge der Spannungstöne6 (engl. tension) ist wie folgt definiert: T = {♭5 , ♯5 , ♭6 , 6 , ♭7 , 7 , maj7 , ♭9 , 9 , ♯9 , 11 , ♯11 , ♭13 , 13 } (2.6) Wobei die Elemente aus T als Symbole zu verstehen sind, nicht als Zahlen. 4 pitch entspricht der Funktion Types.toPitch. pitchClassOffset entspricht der Funktion fromEnum der Enum-Instanz von PitchClass. 5 Entspricht dem Typ Types.MajMin. 6 Entspricht dem Typ Types.Tension. 5 2 Beschreibung des Algorithmus Die Menge der Akkordsymbole7 (engl. chord symbol) ist definiert als: { C = (p, m, b, T ) | p ∈ P, m ∈ M ∪ {Nothing}, b ∈ P ∪ {Nothing}, T ⊆ T } (2.7) Ein Akkordsymbol C ∈ C besteht also aus: • einer Grundtonart p • einem optionalen Tongeschlecht m (Nothing bedeutet, dass der Akkord kein Tongeschlecht hat) • einer optionalen Basstonangabe b (Nothing bedeutet, dass der Basston beliebig gewählt werden kann) • einer Menge von Spannungstönen T . Beispiel 2.2: Die in der Musiknotation übliche Schreibweise G7♯9 für einen G-Dur-Septakkord mit übermäßiger None entspricht dem Akkordsymbol ( ) C = pG , Major, Nothing, {7 , ♯9 } . Ein Akkordsymbol beschreibt, welche Töne gespielt werden müssen. Durch die Wahl einer Oktave für jeden zu spielenden Ton entsteht eine endliche Menge von Tonhöhen, die Lage genannt wird. Die Menge der Lagen8 ist: L = {L | L ⊂ Pabs } (2.8) Beispiel 2.3: Eine mögliche Lage für das Akkordsymbol C aus Beispiel 2.2 ist { L = pitch(pG , 3), pitch(pB , 3), pitch(pD , 4), pitch(pF , 4), pitch(pA♯ , 4) } = {43, 47, 50, 53, 58}. Es gibt für ein Akkordsymbol mehrere mögliche Lagen. Beim Klavier legt die Lage fest, welche Tasten beim Spielen des Akkords gedrückt werden. Es ist nicht festge7 8 Entspricht dem Typ Types.ChordSymbol. Entspricht dem Typ Types.Chord. 6 2 Beschreibung des Algorithmus legt, welcher Finger (welcher Hand) welche Tonhöhe spielt. Ein Fingersatz ordnet Tonhöhen Finger zu. Dabei werden Finger durch die natürlichen Zahlen 1 bis 5 bezeichnet, wobei der Daumen der Zahl 1 entspricht. Den anderen vier Fingern werden entsprechend aufsteigende Zahlen zugeordnet: Der Zeigefinger entspricht der 2 und der kleine Finger der 5. Das entspricht der üblichen Konvention für Klavierfingersätze [Her09, S. 24]. Also ist die Menge der Finger:9 F = {1, 2, 3, 4, 5} (2.9) Eine Hand ist eine partielle Abbildung von Fingern auf absolute Tonhöhen. Damit ist die Menge der Hände:10 H = {h | h : F ,→ Pabs } (2.10) Beispiel 2.4: Ein möglicher Fingersatz zur Lage L aus Beispiel 2.3 ist die Hand { } h = (5, 43), (3, 47), (4, 50), (1, 53), (2, 58) Da der Algorithmus mit Folgen nacheinander zu spielender Hände arbeitet, wird außerdem die Menge der Hand-Folgen11 definiert als: { S = (h1 , . . . , hn ) | n ∈ N und hi ∈ H für i = 1, . . . , n 9 } (2.11) Entspricht dem Typ Types.Finger. Entspricht dem Typ Types.Hand. 11 Entspricht Types.SubProgression. Die Bezeichnung S wurde gewählt, da H und F bereits vergeben sind. 10 7 2 Beschreibung des Algorithmus Beispiel 2.5: Die Hand-Folge s= = ({ } { }) (1, pitch(pC , 5)), (5, pitch(pG , 5)) , (1, pitch(pC , 5)), (5, pitch(pE , 5)) ({ } { (1, 60), (5, 67) , (1, 60), (5, 64) }) beschreibt, dass der erste und fünfte Finger zuerst eine Quinte und danach eine große Terz spielen. 2.2 Vorgehensweise Der Algorithmus12 generiert zu einer Folge von Akkordsymbolen (C1 , . . . , Cn ) eine optimale Hand-Folge Hands ∗ = (h∗1 , . . . , h∗n ). Dabei wird zunächst für jedes Akkordsymbol die Menge möglicher Lagen erzeugt. Aus jeder Lage entsteht durch Hinzufügen eines Fingersatzes eine Hand. Dann werden aus den Händen aufeinanderfolgender Akkordsymbole alle Hand-Folgen für diese Akkordsymbole generiert. Diese Hand-Folgen sind die Knoten eines gewichteten Graphen G = (V, E). Die Knoten werden so durch Kanten verbunden, dass ein Weg durch den Graphen eine mögliche Hand-Folge für die Akkordsymbolfolge liefert. Das Überqueren einer Kante bedeutet, dass zu den bereits gespielten Händen genau eine weitere dazukommt. Das Gewicht der Kante sagt aus, wie unbequem spielbar beziehungsweise unharmonisch (gemäß gegebener Bewertungsregeln) das Spielen der neuen Hand ist. Ein kürzester13 Weg durch den Graphen liefert eine optimale Hand-Folge. Im Folgenden ist n ∈ N die Länge der gegebenen Akkordsymbolfolge. Die Zahl i = 1, . . . , n beschreibt eine Position in der Folge. 12 13 Entspricht der Funktion HandProgressionGraph.optimalHandProgression. Mit kürzester Weg ist hier ein Weg gemeint, der die Summe über die Gewichte der überquerten Kanten minimiert. 8 2 Beschreibung des Algorithmus 2.3 Erzeugung möglicher Hände In diesem Abschnitt wird beschrieben, wie zu einem einzelnen Akkordsymbol C = (p, g, b, T ) die Menge möglicher Hände H ⊆ H erzeugt wird14 . Zuerst wird die Menge relativer Halbtonabstände Obasic ⊂ N erzeugt: { } Obasic = {0} ∪ tensionToSemitones(t) | t ∈ T ∪ {7} , falls ♭5 ∈ /T {} , sonst (2.12) Wobei: tensionToSemitones : T → N { (♭5 , 6), (♯5 , 8), (♭6 , 8), (6 , 9), tensionToSemitones = (♭7 , 9), (7 , 10), (maj7 , 11), (2.13) (♭9 , 1), (9 , 2), (♯9 , 3), (11 , 5), (♯11 , 6), (♭13 , 8), (13 , 9) } Zu beachten ist, dass tensionToSemitones nicht injektiv ist, zum Beispiel: tensionToSemitones(♯5 ) = tensionToSemitones(♭6 ) = tensionToSemitones(♭13 )). In Obasic kommt aber, da es eine Menge ist, kein Element mehrfach vor. Obasic enthält den Grundton (dargestellt durch die Zahl 0) sowie für jeden Spannungston seinen Halbtonabstand zum Grundton. Es wird außerdem eine Quinte hinzugefügt (Halbtonabstand 7), sofern es sich nicht um einen verminderten Akkord handelt, also keine verminderte Quinte (♭5 ) als Spannungston angegeben ist. Spannungstöne, die mehr als eine Oktave über dem Grundton liegen, werden um eine Oktave nach unten transponiert. 14 Entspricht der Funktion GenerateChords.handsForChordSymbol. 9 2 Beschreibung des Algorithmus Beispiel 2.6: Die Menge relativer Halbtonabstände für das Akkordsymbol C aus Beispiel 2.2 { } ist Obasic = {0} ∪ tensionToSemitones(t) | t ∈ {7 , ♯9 } ∪ {7} = {0, 10, 3, 7}. Zu Obasic wird, falls ein Tongeschlecht angegeben wurde, eine entsprechende (kleine oder große) Terz hinzugefügt. Das ergibt die Halbtonabstandsmenge Omode : Obasic Omode = , wenn g = Nothing Obasic ∪ {3} O basic ∪ {4} (2.14) , wenn g = Minor , wenn g = Major Beispiel 2.7: Das Akkordsymbol C aus Beispiel 2.2 beschreibt einen Dur-Akkord. Daher ist Omode = Obasic ∪ {4} = {0, 10, 3, 7, 4}. Anschließend wird jeder Halbtonabstand aus Omode entweder nicht verändert, oder um eine Oktave nach oben oder unten transponiert. Dadurch entstehen verschiedene Möglichkeiten, die Töne des Akkords anzuordnen. Es seien o1 , . . . , o|Omode | ∈ Omode alle Elemente aus Omode . Dann ist die Menge der Variationsmöglichkeiten für einen Halbtonabstand o ∈ Omode definiert als: Ovar,k = {ok , ok + 12, ok − 12} (2.15) (k = 1, . . . , |Omode |) Beispiel 2.8: Sei o4 = 7 der Halbtonabstand der Quinte aus Omode (Beispiel 2.7). Dann ist Ovar,4 = {7, 19, −5}. Die Menge der Variationsmöglichkeiten für einen Akkord mit den Halbtonabständen Omode ist: { Ocomb = {ovar,k | ovar,k ∈ Ovar,k , k = 1, . . . , |Omode |} 10 } (2.16) 2 Beschreibung des Algorithmus Beispiel 2.9: Für die Halbtonabstandsmenge O = {0, 4} ist die Menge der Variationsmöglichkeiten: { Ocomb = {0, 4}, {0, 16}, {0, −8}, {12, 4}, {12, 16}, {12, −8}, {−12, 4}, {−12, 16}, {−12, −8} } Die relativen Halbtonabstände werden in Tonhöhen umgewandelt. Dabei wird der Grundton 0 auf die MIDI-Notennummer mit Grundtonart p in der dritten Oktave abgebildet. Alle anderen Halbtonabstände werden um den gleichen Betrag transponiert. Das ergibt die Menge der Lagen LC ⊂ L für das Akkordsymbol.15 Beispiel 2.10: Für die Halbtonabstandsmenge O = {0, 3, 7} und die Grundtonart p = pD ist { } die Lage L = pitch(pD , 3), pitch(pD , 3) + 3, pitch(pD , 3) + 7 = {38, 41, 45}. Wenn im Akkordsymbol eine Basstonangabe vorhanden ist (b ̸= Nothing), werden aus LC nur die Lagen übernommen, deren tiefster Ton der Angabe entspricht: { } LC,slash = L ∈ LC | ∃o ∈ Z : pitch(b, o) = min L (2.17) Beispiel 2.11: Für die Lage L aus Beispiel 2.10 und eine Basstonangabe b = pD gilt: L ∈ LC,slash , denn pitch(pD , 3) = 38 = min L. Jede Lage wird in eine Hand umgewandelt, indem den tiefsten fünf Tönen (sofern vorhanden) die Finger 5, 4, . . . , 1 zugeordnet werden: toHand : L → H { toHand(L) = (5, min L), (4, min(L \ min L)), . . . 15 Entspricht der Funktion GenerateChords.chordsForChordSymbol. 11 } (2.18) 2 Beschreibung des Algorithmus Beispiel 2.12: { } Für die Lage L aus Beispiel 2.10 ist die Hand H = toHand(L) = (5, 38), (4, 41), (3, 45) . 2.4 Erzeugung möglicher Sub-Folgen In diesem Abschnitt wird erklärt, wie der Algorithmus zu Teilabbschnitten der Akkordfolge mögliche Hand-Folgen erzeugt. Diese werden als Sub-Folgen bezeichnet. Die Länge dieser Sub-Folgen ist die maximale Anzahl aufeinanderfolgender Akkorde, die eine Regel bewerten kann. Sie wird im Folgenden durch die Konstante l festgelegt,16 wobei l ∈ N \ {0}. Sei Hi die Menge möglicher Hände an der Song-Position i (der erste zu spielende Akkord ist bei i = 1). Dann wird für jede Position i die Menge möglicher SubFolgen erzeugt:17 { ∀i : Si = (hmax{1,i−l+1} , . . . , hi−1 , hi ) | hj ∈ Hj für j = 1, . . . , n } (2.19) Ein Si enthält alle Möglichkeiten, einen Abschnitt der Akkordfolge zu greifen. Die Länge der Tupel eines Si richtet sich nach l und danach, ob i < l: S1 enthält nur 1-Tupel, und alle Si für i ≥ l enthalten nur l-Tupel. Beispiel 2.13: Für einen Song der Länge n = 3 mit den Mengen möglicher Hände H1 = {h1,1 }, H2 = {h2,1 , h2,2 }, H3 = {h3,1 } sind mit l = 2 die Mengen möglicher Sub-Folgen: { } S1 = (h1,1 ) { } { } S2 = (h1,1 , h2,1 ), (h1,1 , h2,2 ) S3 = (h2,1 , h3,1 ), (h2,2 , h3,1 ) . 16 17 Entspricht HandProgressionGraph.subProgressionLength. Entspricht HandProgressionGraph.makeSubProgressions. 12 2 Beschreibung des Algorithmus Die Knotenmenge V des Graphen besteht aus zwei Markierungsknoten für den Anfang und das Ende der Akkordfolge, sowie allen Sub-Folgen aller Positionen i: n ∪ V = {Start, End} ∪ (2.20) Si i=1 2.5 Verbindung der Sub-Folgen In diesem Abschnitt wird beschrieben, wie die Kantenmenge E des Graphen erzeugt wird.18 Außerdem wird das Gewicht w(e) der Kanten definiert (e ∈ E). Das Startsymbol wird mit allen Sub-Folgen der Position 1 verbunden: { E1 = (Start, s) | s ∈ S1 } (2.21) Außerdem werden alle Sub-Folgen an der Position n (also die letzten in der Akkordfolge) mit dem End-Knoten verbunden: { En+1 = (s, End) | s ∈ Sn } (2.22) An allen anderen Position werden zwei Sub-Folgen benachbarter Positionen genau dann verbunden, wenn sie das Prädikat precedes erfüllen: { } Ei = (spred , scurr ) | spred ∈ Si−1 , scurr ∈ Si , precedes(spred , scurr ) (1 < i ≤ n) 18 Entspricht HandProgressionGraph.makeEdges. 13 (2.23) 2 Beschreibung des Algorithmus Wobei: precedes : (S × S) → {0, 1} 1, falls h1,u = h2,v−1 ∧ h1,u−1 = h2,v−2 ∧ precedes((h1,1 , . . . , h1,u ), (h2,1 , . . . , h2,v )) = ... ∧ h1,u−v+2 = h2,1 (2.24) 0, sonst Das Prädikat precedes bestimmt, ob eine Sub-Folge s ∈ Si−1 vor einer anderen s′ ∈ Si gespielt werden kann. Das ist genau dann der Fall, wenn die letzten v − 1 Hände von s gleich den ersten v − 1 Händen von s′ sind (wobei v die Länge von s′ ist). Mit anderen Worten: Wenn alle Hände in s′ bis auf die letzte auch schon am Ende von s gespielt wurden. Die Bedeutung einer Kante (s, s′ ) ist also, dass die Hände aus s gespielt werden, und danach die letzte Hand aus s′ . Beispiel 2.14: Für die Sub-Folgen (h1,1 , h2,2 ), (h2,1 , h3,1 ) und (h2,2 , h3,1 ) aus Beispiel 2.13 gilt: ( ) precedes (h1,1 , h2,2 ), (h2,1 , h3,1 ) = 0, da h2,2 ̸= h2,1 und ( ) precedes (h1,1 , h2,2 ), (h2,2 , h3,1 ) = 1, da h2,2 = h2,2 . Damit ist die Kantenmenge des Graphen: E= n+1 ∪ (2.25) Ei i=1 Beispiel 2.15: Für S1 , S2 , S3 aus Beispiel 2.13 ist die Kantemenge E = E1 ∪ E2 ∪ E3 ∪ E4 , mit: {( )} E1 = Start, (h1,1 ) E2 = E3 = E4 = {( {( {( ) ( )} (h1,1 ), (h1,1 , h2,1 ) , (h1,1 ), (h1,1 , h2,2 ) ) ( )} (h1,1 , h2,1 ), (h2,1 , h3,1 ) , (h1,1 , h2,2 ), (h2,2 , h3,1 ) ) ( (h2,1 , h3,1 ), End , (h2,2 , h3,1 ), End 14 )} 2 Beschreibung des Algorithmus Die Funktion w : E → R≥0 ordnet Kanten des Graphen Gewichte zu. Das Gewicht w(e) einer Kante e ∈ E ist: w((spred , scurr )) = 0 , falls scurr = End rate(scurr ) , sonst (2.26) Wobei die Funktion rate : S → R≥0 eine Sub-Folge nach bestimmten Regeln bewertet.19 Die Anwendung einer Regel ergibt eine Bewertung in Form einer positiven reellen Zahl, wobei 0 als neutrales Element der Addition bedeutet, dass die Regel perfekt eingehalten wurde. Wird eine Regel verletzt, wird eine Strafe penalty > 0 vergeben. rate wendet alle Regeln an und summiert die Strafen auf. Eine Regel liefert auch immer dann die Bewertung 0, wenn die zu bewertende SubFolge für diese Regel zu kurz ist. Das kann nur für Sub-Folgen s ∈ Si mit i < l eintreten. 2.6 Finden einer optimalen Hand-Folge Der Algorithmus von Dijkstra [Dij59] wird benutzt, um im Graph G einen kürzesten Weg W ∗ vom Knoten Start zum Knoten End zu finden:20 W ∗ = (Start, s∗1 , . . . , s∗n , End) (2.27) (s∗i ∈ Si , i = 1, . . . , n) Beispiel 2.16: Es werden S1 , S2 , S3 aus Beispiel 2.13 sowie E aus Beispiel 2.15 verwendet. Des( ) ( ) ( ) ( ) weiteren sei rate (h1,1 , h2,1 ) +rate (h2,1 , h3,1 ) > rate (h1,1 , h2,2 ) +rate (h2,2 , h3,1 ) . ( ) Dann ist W ∗ = Start, (h1,1 ), (h1,1 , h2,2 ), (h2,2 , h3,1 ), End . 19 20 Entspricht RateSubProgression.totalRating. Entspricht HandProgressionGraph.bestIndexPath. 15 2 Beschreibung des Algorithmus Aus jeder Sub-Folge s∗i wird die letzte Hand ausgewählt. Das ergibt eine optimale Hand-Folge: ( ) Hands ∗ = last(s∗1 ), . . . , last(s∗n ) , ( ) wobei last (h1 , . . . , hv ) = hv Beispiel 2.17: Für W ∗ aus Beispiel 2.16 ist Hands ∗ = (h1,1 , h2,2 , h3,1 ). 16 (2.28) 3 Ergebnisse Die Haskell-Implementation des Algorithmus wurde mit den Akkordsymbolfolgen neun verschiedener Jazz-Standards getestet.1 Zur Berechnung der Kantengewichte wurden folgende Bewertungskriterien verwendet:2 • Bestrafung, wenn ein Finger um mehr als eine große Terz springt • Bestrafung, wenn die höchste Stimme um mehr als eine Quarte springt • Bestrafung, wenn ein Finger über eine schwarze Taste springen muss • Bestrafung, wenn ein Finger eine weiße Taste im Bereich zwischen zwei schwarzen Tasten treffen muss • Bestrafung, wenn sich der Greifumfang zweier aufeinanderfolgender Lagen um mehr als eine Quinte unterscheidet • Bestrafung von Clustern • Bestrafung, wenn Akkordtöne mehr als eine Quinte voneinander entfernt liegen Im Folgenden wird beispielhaft der Song »Donna Lee« von Charlie Parker betrachtet [04, S. 123]. Die Akkordsymbole sind im Real Book angegeben als A♭maj7 , F 7 , . . . , E♭7 . 1 Die IO-Aktion LilypondOutput.allExamplesToPdf erzeugt zu jedem der neun Beispiele ein Notenblatt wie Abbildung 3.1 im PDF-Format. 2 Die Bewertungsfunktionen sind in RateSubProgression.allSubProgressionRaters. 17 3 Ergebnisse Die Eingabe für das Programm ist (verkürzt dargestellt) der Haskell-Ausdruck:3 [ChordSymbol aFlat (Just Major) [MajorSeventh] Nothing, ChordSymbol F (Just Major) [Seventh] Nothing, ... ChordSymbol eFlat (Just Major) [Seventh] Nothing] Der Aufruf optimalHandProgression donnaLee liefert eine Liste von Hands, wobei jede Hand eine Abbildung von Finger auf Pitch ist. Das ist die Ausgabe des Programms: [fromList [(2,Pitch 44),(3,Pitch 43),(4,Pitch 39),(5,Pitch 36)], fromList [(2,Pitch 45),(3,Pitch 41),(4,Pitch 39),(5,Pitch 36)], ... fromList [(2,Pitch 51),(3,Pitch 49),(4,Pitch 46),(5,Pitch 43)]] Mit den LilyPond-Bindings für Haskell [Hog] können daraus Noten gerendert werden (Abbildung 3.1). Die Gesamtkosten (als Summe über die Gewichte aller überquerten Kanten) sind 163,0.4 Die Notation zeigt, dass die Akkordlagen einhändig spielbare Lagen sind, für die sich ein Pianist entscheiden würde. Auffällig sind Auf- und Abwärtsbewegungen der Akkordlagen (zum Beispiel aufwärts in Takt 1, sprunghaft abwärts in Takt 3). Ähnliche Bewegungen waren auch bei den Ausgaben zu anderen Songs vorhanden. Im Allgemeinen reduziert ein Pianist solche Bewegungen, um Kollisionen mit einer darüber gespielten Melodiestimme zu vermeiden. Wird die Bedingung hinzugefügt, dass alle Akkorde in Grundstellung sein müssen (also der Grundton der tiefste Ton ist), sind die Kosten 386,0.5 Abbildung 3.2 zeigt die gerenderte Ausgabe. Um jeden Akkord in Grundstellung zu spielen, sind größere Sprünge notwendig, wodurch erhöhte Kosten entstehen. 3 Dieser Ausdruck ist ExampleChordProgressions.donnaLee. Der Wert wird berechnet mit: minimumCost donnaLee. 5 Berechnung mit: minimumCost (forbidInversions donnaLee). 4 18 3 Ergebnisse A 7 9 4 7 F maj7 ~ ~ B 7 7 B - 7 F B F- B 7 E 7 A maj7 E -7 ~ ~ ~ ~ ~ ~ ~ 7 E ~ ~ ~ ~ ~ ~ 7 ø G C 7 B -7 o7 B A ~ ~ maj7 C- ~ ~ ~ ~ ~ ~ 7 ~~ 7 F B 7 7 D 7 7 B - ø G E maj7 D -7 G 7 A maj7 ~ ~ ~ ~ 7 A ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 7 9 C ~ ~ ~ F D maj7 F- 7 7 C F- 7 E ~ ~ ~ 7 9 F B - ~ ~ ~ ~ ~ ~ ~ 7 7 Abbildung 3.1: Mit LilyPond gerenderte optimale Hand-Folge (ohne Fingersätze) zu den 37 Akkordsymbolen des Songs »Donna Lee«. Die Akkordsymbole entsprechen denen im Real Book und wurden von Hand hinzugefügt. Da der Algorithmus keine Enharmonik berücksichtigt, sind auch ♭-Tonarten mit Kreuz (♯) notiert. Die in Gleichung 2.18 vorgestellte Zuweisung von Fingersätzen zu Tonhöhen hat Nachteile bei Lagen mit weniger als 5 Tonhöhen: Wenn eine Akkordlage zum Beispiel aus nur zwei Tonhöhen besteht, die eine Oktave voneinander entfernt liegen, werden den Tonhöhen die Finger 5 und 4 zugewiesen. Die Hand wird als unspielbar bewertet, da der Abstand zwischen den beiden Fingern zu groß ist. Die Lage wäre aber mit den Fingern 5 und 1 problemlos greifbar. Ein weiteres Problem bei der Umwandlung einer Lage in eine Hand ist, dass nur die tiefsten fünf Töne einer Lage übernommen werden. Dadurch werden Akkordsymbole mit mehr als fünf Tönen unvollständig umgesetzt. Die Berechnung einer optimalen Hand-Folge für »Donna Lee« mit l = 2 benötigte auf einem 1,7 GHz Intel Core i5 und 4 GB 1333 MHz DDR3-Arbeitsspeicher 176 ms, davon 11 ms für System-Aufrufe.6 Setzen von l = 3 erhöhte die benötigte Zeit auf 2,68 s, mit l = 4 stieg sie auf 1 min 41 s. Erhöhen von l erhöht die Knotenanzahl an jeder Song-Position exponentiell, was den starken Anstieg der Laufzeit erklärt. Durch die Verwendung des Dijkstra-Algorithmus ist die Laufzeit bei konstantem l polynomial bezüglich der Anzahl n der Akkordsymbole. 6 Es wurde der Haskell-Compiler GHC in Version 7.8.3 mit dem Parameter -O3 verwendet. Music engraving by LilyPond 2.18.2—www.lilypond.org 19 3 Ergebnisse A ~~ ~ ~ B B - B B C- F B E A ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ø G 7 B 7 7 B -7 ~ E 7 A maj7 E -7 D7 D maj7 D -7 G 7 A maj7 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 7 F ø 7 7 9 7 7 7 7 ~ E 7 A maj7 F7 B G C FC F~ ~ ~ ~~ ~ ~ ~ ~ ~ ~ ~~ ~ ~ ~ 7 9 F 4 maj7 7 C F- 7 o7 7 7 7 7 maj7 7 ~ E 7 ~ ~ ~ ~~ ~ 7 9 F B - Abbildung 3.2: Mit LilyPond gerenderte optimale Hand-Folge für »Donna Lee«, unter der Bedingung, dass alle Akkorde in Grundstellung sein müssen. 20 4 Ausblick Eine mögliche Verbesserung des Algorithmus ist eine andere Fingersatzberechnung. Für die Hand-Bewertung werden bereits Abstandsmaße zwischen Fingern benutzt. Diese können benutzt werden, um zu einer Lage Fingersätze zu finden, die spielbar sind. Die verlustbehaftete Umsetzung von Akkordsymbolen mit mehr als fünf Tönen kann verbessert werden. Eine Möglichkeit ist das Bevorzugen wichtiger Tonhöhen. Es ist zum Beispiel üblich, bei Akkorden mit vielen Tonhöhen die Quinte nicht zu spielen, da sie am wenigsten zum Klang beiträgt. Die Wichtigkeit verschiedener Tonhöhen und Spannungstöne muss durch den Benutzer global oder für jedes Akkordsymbol anpassbar sein. Da anatomische Grenzen und musikalischer Geschmack vom Benutzer abhängen, müssen für eine praktische Anwendung Constraints wie der maximale Fingerabstand vom Benutzer einstellbar sein. Außerdem müssen Bewertungsregeln unterschiedlich gewichtet in die Beurteilung eingehen, da je nach Anwendungsfall andere musikalische Merkmale wichtig sind. Der Algorithmus ist auf andere Akkordinstrumente (zum Beispiel Gitarre) übertragbar, da die Bewertung von Händen vom Rest des Algorithmus getrennt ist. Es ist zu überprüfen, ob sich die Merkmale anderer Instrumente mit dem vorhandenen Datenmodell darstellen lassen. 21 Literatur [04] The Real Book. 6. Aufl. Hal Leonard Corporation, Sep. 2004. [95] MIDI 1.0 Detailed Specification. Document Version 4.2. MIDI Manufacturers Association Incorporated, Sep. 1995. [Aeb67] Jamey Aebersold. Volume 1, How to Play Jazz and Improvise: Revised 6th Edition. Jamey Aebersold Jazz. Jamey Aebersold Jazz Incorporated, 1967. [Deb07] J. Debbeler. Harmonie und Perspektive: die Entstehung des neuzeitlichen abendländischen Kunstmusiksystems. Aesthetica theatralia. epodiumVerlag, 2007. [Dij59] Edsger. W. Dijkstra. »A note on two problems in connexion with graphs.« In: Numerische Mathematik 1 (1959), S. 269–271. [EP10] Arne Eigenfeldt und Philippe Pasquier. »Realtime generation of harmonic progressions using controlled Markov selection«. In: Proceedings of ICCC-X-Computational Creativity Conference. 2010. [Erw] Martin Erwig. FGL/Haskell - A Functional Graph Library for Haskell. url: http://web.engr.oregonstate.edu/~erwig/fgl/haskell/ (besucht am 24. 03. 2015). [Haa+11] W. Bas de Haas u. a. »HarmTrace: Improving harmonic similarity estimation using functional harmony analysis«. In: In Proceedings of the 12th International Society for Music Information Retrieval Conference. 2011, S. 67–72. [Her09] Alan Hersh. A Pianist’s Dictionary: Reflections on a Life. Hamilton Books, 2009. I [Hog] Hans Hoglund. lilypond: Bindings to Lilypond | Hackage. url: https: //hackage.haskell.org/package/lilypond (besucht am 24. 03. 2015). [HS11] Dorien Herremans und Kenneth Sörensen. A variable neighbourhood search algorithm to generate first species counterpoint musical scores. Working Papers 2011017. University of Antwerp, Faculty of Applied Economics, Okt. 2011. [Kár65] Ottó Károlyi. Introducing Music. Penguin Books, 1965. [KMH13] Hendrik Vincent Koops, José Pedro Magalhães und W. Bas de Haas. »A Functional Approach to Automatic Melody Harmonisation«. In: Proceedings of the First ACM SIGPLAN Workshop on Functional Art, Music, Modeling & Design. FARM ’13. Boston, Massachusetts, USA: ACM, 2013, S. 47–58. [KNR07] Alia Al Kasimi, Eric Nichols und Christopher Raphael. »A Simple Algorithm for Automatic Generation of Polyphonic Piano Fingerings«. In: Proceedings of the 8th International Conference on Music Information Retrieval, Vienna, Austria, September 23-27. Österreichische Computer Gesellschaft, 2007, S. 355–356. [LJ83] Fred Lerdahl und Ray Jackendoff. A generative theory of tonal music. Cambridge. MA: The MIT Press, 1983. [PR01] Francois Pachet und Pierre Roy. »Musical Harmonization with Constraints: A Survey«. In: Constraints 6.1 (Jan. 2001), S. 7–19. [RP98] R. Ramirez und J. Peralta. »A constraint-based melody harmonizer«. In: Workshop on Constraints for Artistic Applications. 1998. [TP05] D. R. Tuohy und W. D. Potter. »A genetic algorithm for the automatic generation of playable guitar tablature«. In: Proceedings of the International Computer Music Conference. 2005, S. 499–502. [YKS07] Yuichiro Yonebayashi, Hirokazu Kameoka und Shigeki Sagayama. »Automatic Decision of Piano Fingering Based on Hidden Markov Models«. In: Proceedings of the 20th International Joint Conference on Artifical Intelligence. IJCAI’07. Hyderabad, India: Morgan Kaufmann Publishers Inc., 2007, S. 2915–2921.