Fugue generation using genetic algorithms Claudio Coutinho de Biasi, Alexandre Mattioli debiasi@centroin.com.br mattioli@rj.conectiva.com. br Resumo: Este artigo propõe um sistema capaz de gerar peças originais de música sob a forma de fugas, a partir do zero. Muitos sistemas existentes precisam de uma semente para começar ou intervenção humana para orientar a evolução. Este sistema evolui gerando um assunto, a resposta e os assuntos de contador. Para obter os melhores resultados foram ajustados os parâmetros. O algoritmo desenvolveu fugas interessantes em poucos segundos. Palavras-chave: algoritmos genéticos, fugas Abstract: This article proposes a system capable of generating original pieces of music in the form of fugues from scratch. Many existing systems require a seed to start or human intervention to guide the evolution. This system evolves generating a subject's response and then issuing the counter. To obtain the best results the parameters were adjusted. The algorithm developed interesting fugues in a few seconds. Keywords: genetic algorithms, trails 1 Introduction The goal of this article is to create interesting and pleasing fugues from scratch. Our work was based in [1], which describes an algorithm to create fugues. We studied the problem and adjusted parameters to generate more interesting and pleasing fugues in much less time. 2 Algorithm description 2.1 Parameters to adjust We developed a software, called Fugue Generator, which generates a fugue, given some parameters. Parts of these parameters are related to the genetic algorithms while others are related to the evaluation function. The parameters related to the genetic algorithm are the population size, the number of generations, the number of rounds, the initial crossover rate, the final crossover rate, the initial mutation rate and the final mutation rate. The result of the end of one round is used as a seed in the next round. It is also possible to choose the optimization mode, which can be none, simple or with elitism optionally without duplicated chromosomes. 2.2 Algorithm description There are two main parts to our program: subject generation and fugue generation from the subject. The first part is accomplished through the use of a genetic algorithm that tries random subjects, and then mutates and crosses them to improve them into fascinating subjects. The program Fugue Generator is capable of generating subjects or the rest of the fugue, which is based upon the generated subject. This way, it is possible to generate several fugues from the same subject. The subject, answer and countersubjects generated by this program are text files with the pitch of the notes followed by their duration. When the
subject is generated, a binary file is also generated. The answer and counter-subjects are generated from this file. 2.3 GA data structure Fig. 1. Fugue Generator screenshot G-2/1 RST/1 G-2/1 D-3/1 G#3/2 F-3/1 RST/1 B-2/1 G#3/1 RST/1 A#2/1 C#3/1 G#3/1 A#3/1 B-4/1 A-4/2 B-4/2 F-3/2 G-3/2 C#3/1 G#3/1 A-3/1 E-3/1 F-3/2 A#3/1 A#3/1 G#4/1 G#3/1 B-3/1 G-3/1 C-3/1 D-3/1 A-3/1 G#3/1 D#3/2 F#3/2 F#4/1 C#4/1 A#1/1 A#4/1 C-5/1 F-4/1 A-3/1 A-3/1 G-3/2 C#4/2 A#3/1 C-3/1 D-4/1 C-4/1 E-3/1 A#3/1 E-4/1 A-4/1 In the format Pitch- Octave/Length where duration number/4 gives the note length. Subject generated with the parameters shown above The entire subject is represented as a bit string, where every byte is one bin, which represents a 16 th note. The entire subject is 4 measures long, so the subject is 64 bins long. The advantage of this structure is that every subject in the population is exactly the same size, regardless of the rhythms or amount of notes contained in it. Note that there is no reason to limit the subject to 4 measures. This was used only as an initial approach. Within each bin, the first 6 bins represent the pitch of the note. On the original article, the bin was 9 bits wide, representing the pitch on a midi scale of 0 to 127. However, we decided to use only 8 bits, because it is easier to deal with and 6 bits are sufficient for pitch range. So, in our representation, 0 represents C-1 and 63 represents D#6. We just discarded very high and very low pitch values. The last 2 bits in the bin represent the style of the bin. The style is either a link to the next bin, a rest, or the end of a note. In this way, several adjacent bins with the style of link combine to form longer notes. The link style is used to link only notes, not rests. Two consecutive bins with rest style represent a longer rest. Since there are only 3 style possibilities, and 4 possible permutations of the 2 style bins, we allow 2 of the permutations to represent the link style, so that our initial subjects, and mutation that occur will tend to favor linking notes
together, so that we do not simply end up with lots of 16 th notes. We wanted to allow any possible combination of bits to be a legal subject, so we had to define the following cases: In a group of linked bins, the pitch values do not have to match. The pitch of the note is determined by the pitch value of the first bin in the group. If a rest is linked to something, the bin succeeding the rest counts as a note. If a group of linked bins links to a rest, the bin before the rest counts as an end of the note instead, and the rest is not linked in. Likewise, if the subject ends on a bin with a link style, it just counts as the end of the note (and the subject). Below are the features evaluated: The given weight are values found by experiment and are only an example of values which we found to work well to our particular taste, different values can and should be used to suit other tastes. 1.Similar pitch: To avoid tune jumping around randomly between distant notes, each bin is discouraged being different from its predecessor. This rule is applied even if the bin represents a rest. d: difference of pitch between current note and its predecessor. m: minimum pitch difference penalty (4) M: maximum pitch difference penalty (12) s: subject length (64) Condition Penalty Normalization Weight d < m 0 s*(m-m) pitch style pitch style pitch style 2 10 m <= d <= M (d-m) 2 d > M (M-m) 2 2.4 GA fitness function Our fitness function parses through the bins, picks out the notes, and looks at different features of the subject. It either encourages or discourages them by rewarding good features and penalizing bad features. We obtain several reward and penalty values and then normalize them (dividing by the maximum possible value, so that the result ranges from 0 to 1), multiply by a weight, and sum them all. If the feature has a penalty value, we use the complement of the value obtained. 2. Similar length: This test compares a bin s length to the length of the previous bin in the subject, and encourages them to be alike. This helps lend continuity to the piece by encouraging 16 th or 8 th note runs, or slower quarter notes to be grouped together, rather than the rhythm switching around arbitrarily. This rule is applied even if the bin represents a rest. d: difference of duration between current note and its predecessor. m: minimum duration difference penalty (0)
M: maximum duration difference penalty (2) n: total number of notes and rests in the subject from sounding syncopated or lost, because it tends to come back to eighth not boundaries (the first and third bins in each set of 4). Condition Penalty Normalization Bins where notes Weight start Reward Normalization W d < m 0 n*(m-m) 2 Odd 1 1 Number of notes in the subject m <= d <= M (d-m) 2 Even 0 d > M (M-m) 2 6. In key: We reward notes for being in the key of C. This goes a long way toward making the subject sound better. It removes the majority of sharps and flats from the subject, making it much nicer to listen to. 3. Power of 2: The next test is whether a bin s length is a power of 2 or not. If it is, the subject is rewarded. The goal of this reward is to encourage more 16 th, 8 th, quarter, and half notes in a piece, rather than dotted eight and dotted quarter notes. These other notes will still appear, but will be less common, helping the piece to sound more regular. This rule is applied even if the bin is a rest. 4. Tie over a bar line: We discourage notes for being held over between measures (the last bin in a measure s style tells us this). This helps keep the measures separate and distinct, as they should be. s: subject length (64) m: measure length (16) 5. Notes start on 1 st or 3 rd bin of a beat: By encouraging notes that start on the 1 st or 3 rd bins of a beat, we encourage a regular beat throughout the subject. This keeps the subject s = subject length Pitch values: C = 10 C# = 0 Condition Reward D = Normalization 2 Weight Pitch is power of 2 1 Number D# = 0 of notes and rests 10 Pitch is not power of 2 0 E = 7 F = 6 F# = 2 G = 8 G# = 2 A = 4 A# = 0 B =6 Reward Normalization Weight Pitch value s * C 20 7. Not a rest: This test rewards a subject Bins 15, 31 or 47 Penalty Normalization for each bin that is not a Weight rest. Style = LINK 1 (s/m)-1 10 Style!= LINK 0 s = subject length Condition Reward Normalization W Style!= REST 1 s Style = REST 0
8. Note bonus: Gives a bonus to the subject for every note it contains. 9. Out of range penalty: Some subjects would not have pitches differing from each other largely, but they would all end up changing in the same direction, which would result in the subject going very high, or very low. This test checks to see if the pitch of a note is outside of our predefined range, and penalizes it if it is. c: pitch center (48) p: pitch of current note m: minimum penalty distance (12) M: maximum penalty distance (36) s: subject length (64) d: c-p we have the subject. Condition Penalty Normalization Weight d < m 0 s*(m-m) 2 20 m <= d <= M (d-m) 2 d > M (M-m) 2 Using this fitness function, we run our genetic algorithm for 10 rounds of 50 generations, and then take the subject in our population with the highest fitness, and move on to next part of our program with it. 3 Generating the answer and counter-subjects s = subject length Suited to the rest of the program. It n = number of notes in the subject creates a Phrase object, which is made up of Note objects, each of which has a pitch and a rhythm value (quarter Reward Normalization Weight note, eighth note, etc.). The subject is n s 5 one Phrase, as is the answer and each counter subject. These Phases are then added to Parts. There are three Parts in a fugue: soprano, alto, and bass. A different instrument plays each Part. We then add the three Parts to a Score object, which we can then output to a midi file. To do all of this, though, we must first generate the Phrases we will use. 3.1 Generating the answer phrase The answer is simply the same rhythm as the subject, but with all the notes transposed down by an offset (4 / major third). This is simple to do once 3.2 Generating the countersubjects The counter-subjects are designed to be played alongside the subject and answer, and should complement them nicely. To create a good countersubject, we parse through the notes in the subject (or answer), looking at different possible cases in each beat: 2 eighths: To complement this we decide randomly to either join the eighth notes into one quarter note, or split
them into 4 sixteenth notes. If they are split into 16 th s, the new notes will inherit the pitch of the bin where they are. 4 sixteenths: If we have a run of 4 sixteenths, we put 2 eighth notes in the countersubject, thus accenting the 1 st and 3 rd notes of the run. 1 quarter note: we break quarter notes into 2 eighth notes, in the same fashion that we broke the eighth notes in the first case above. Also, the final generated countersubject is transposed up one third from the subject/answer it was generated from. We need to generate 2 countersubjects to write the fugue, but since our counter-subject generating algorithm has a significant amount or randomness built into it, we can just call it twice (once for the answer, once for the subject), and we get 2 different counter-subjects to use. Once we have the subject, answer, and counter-subjects, we can then build our little fugue, using the rules of how a fugue should be arranged: Table 1. Fugue Parts Soprano: Subject Subject this method. Subject Alto: Answer Answer Answer Tenor: Counter-Subject 1 Counter-Subject 1 Bass: Counter-Subject 2 We then end our fugue with a static final chord (major triad in C). This gives the fugue closure, and works better than trying to encourage the genetic algorithm to produce fugues that cadence properly. This is because the combination of the three parts is not being done with a genetic algorithm. 4 Results The pieces generated with this algorithms are of a very interesting nature, being heard by professional musicians, both instrumentalists and composers, which were quite amazed by its quality and the little time it took to be composed. With 500 generations it took about 12 seconds in a 1000 MIPS machine (AMD K6-II 500). In the average musicians rated it in the level of a composition by a sophomore in music. 5 Conclusions This shows that Genetical Algorithms is a promising field in Musical Composition by computers. It must be noticed that it is not with the help of computers, but by computers. The pieces created in this manner show some interesting features that are typical of musical creativity. Further refinements of the technique can enhance and expand the capabilities of
References [1] Eric Milkie, Joel Chestnutt, CS 473 Artificial Intelligence Project Fugue Generation with Genetic Algortithms