Quartet Music Generator (v2)ContentsApply velocity and tempo envelope IntroductionQuartet Generator v2 is the new version of Quartet Generator. This is the absolute music generation software. Absolute music (sometimes also called abstract music) is music that is not explicitly "about" anything. It is intended to be appreciated without any particular reference to the outside world. In my opinion there is a subtle difference between the music, that is not explicitly "about" anything and the music, that is not for listening at all. The goal of the project was to create the absolute music generation robot, using a lot of convenient music rules and simulating performer's habits. Robot's basic algorithms used for music generation were aimed at infinite developing melody line, always developing and dynamic, but not going anywhere in particular. Later additions of envelopes, reprises and parts resulted in more structured music, yet keeping an infinity touch. Example of QGen2 in action is Rhaos - Western Train Suite. Quartet Generator v2 generates music in steps, where step is at least one note changing. Generator uses voices, which limit the number of notes that can sound at the same time and also the number of notes that can change at a time. There are 6 voices in the figure. You can download Quartet Generator v2 (QGen2) and see examples of Quartet Generator v2 music at the bottom of the page in the Examples section. Quartet Generator produces music based on the random numbers with uniform distribution. During the generation of each step several rules are checked and the quality of resulting music is analysed (for example, good quality is no or little dissonance intervals). If the quality is poor, the generation for particular step is repeated until good quality is achieved. Generator outputs music in midi format (which can be imported for example into Sibelius to see sheetmusic) and also shows graphical representation of the generation process, where many variables are shown for each step (see Examples section for details): Algorithm is highly customizable. It needs more than 300 starting constants to be set to run. But you can always use default values instead. Generation processHere is the flow of the generation process. The "Generate one step" process is repeated for each step. All the stages of generation are described in separate sections below. The result of multi-part generation, including reprises, may look like this (2 parts are shown for example): Each part is generated independently. Only the mode is usually transferred from the end of the previous part to the start of the next part to avoid unexpected alterations. Each part may have its unique set of constants or some predefined collection of constants, called Style. For example, for generation of West Train Suite, the following structure of Styles was used:
Note limits generationHigh note and low note limit is changed during the generation to decrease the possibility of repeating very high and very low notes. Note limits move up and down in a linear fashion between the static limits (note_max_max and note_max_min, note_min_max and note_min_min) with a customizable step. When a note limit comes close to a voice, it stops until the voice moves away. Here the note limits are black and when they stop, they become gray. You can see more detailed information and listen to music in the Examples section below. Step length generationTo generate step length a finite-state machine is used. Each note length is represented as the length of time a note sounds (note sounding time). The following note length groups are allowed from the box:
Minimum repeat count shows the number of steps the length cannot be changed if it was selected. This prevents complex syncopation and rhythm shift. Each note length group is a state. Each step the probability vector to change to all the other states is calculated. The vector looks like this (example for some particular state):
Then random number is generated with uniform distribution between 1 and 100. Numbers from 1 to 33 mean changing to state 15, numbers from 34 to 63 mean changing to state 20 and so on. This guarantees that changing the particular state has the probability from the vector. When algorithm approaches the end of the piece, probability array of lengths may gradually change to a different one. I usually increase probability of long lengths and decrease probability of short lengths. This leads to a more stable ending, even if chords are not tonic. The result of the generation can be like this. In the time row you see the length passed from the begining to the start of the step. Green cells represent length, that is multiple of 120 (full measure). You can see more detailed information and listen to music in the Examples section below. Step mode generationIn QGen2 only major/minor keys are used. They are called "modes" because algorithm does not provide any preference to any of the 7 notes of the mode. In CityGen algorithm you can see use of non-major/minor modes. Mode generation is pretty simple. The starting mode in my models is usually C major, but you can set it anything. Each time a number of measure is passed (I use step of 4 measures), the probability to change mode is checked against random generator. If it wins, the mode is changed forward or backward the circle of fifths. How far the mode goes by the circle is determined by the mode step, which will always be between the starting constants (mode_mut_min and mode_mut_max). I usually use only 1 step (up or down) for more gradual modulation and less alterations that are added during the mode change. The result of the mode generation with step of 2 measures, probability of 60% and maximum step of 1 looks like this: Step notes generationNotes generation is the most sophisticated procedure of the algorithm. First the number of moving voices is determined (usually from 1 to 4). It depends on the following probabilities:
Of course, if there are not enough voices, that can move, the number of moving voices is decreased. After the number of moving voices is determined, we start to choose, which particular voices will move. I usually use 6 voices, which helps guarantee that there will be enough movable voices if for example algorithm will try to move 4 of them. The problem can be that the voice is smothered between other voices or is pressed to the higher or lower limit and cannot move until the surrounding voices make it more loose. Determining which voices will move is also a complex random process and it takes the following probabilities into account:
After the voices that should move are chosen, algorithm starts to move the voices:
After the above algorithm has worked for all the voices that were chosen to move, program starts to analyse the resulting music. The result of analysis is the total cost of the step. The lower the cost, the higher the quality of music is. This is why the program then tries to optimize the cost by moving voices again and again and recalculating the cost. Each time the program sees the cost lower than any cost of the previous tries, it memorizes the move. If it was not possible to minimize the cost to zero this way, the program chooses the variant with the lowest cost, that was memorized. The number of tries depends on the number of moving voices. For many moving voices the task is more complex and more tries are allowed. If during this cycle it was not possible to minimize the cost (to the number lower than first cost limit) with the fixed moving voices numbers, then new voices are elected for moving (dotted line). If during after several iterations of new moving voices election it is still not possible to minimize the cost (to the number lower than second cost limit, which is usually lower that first limit), than the variant with the lowest cost is used. The following is added to form the cost:
I show the types of notes interaction in the figure below: On the figure below you can see an example of sounding (audible) note volume calculation. You see that sounding volume of F note initially equals its note hit velocity and then gradually decreases. When E and H notes are introduced, F note is barely audible and the dissonance of F with H (tritone) and E (major 7th) has low quality cost. You can also see that the slope of souding note volume decrease depends on the pitch of the note. Higher notes decay faster, while bass notes decay slower, which is also taken into account in the algorithm. On the figure you can see the most difference in the slope between the E4 and C6 notes. Frankly speaking, linear approximation of the sounding volume is not exact, but it is enough for approximation. After the note moves are fixed, algorithm starts to decide which notes to retrigger. Retriggering means that the voice does not move, but the note of the voice is repeated in the current step. Retriggering notes usually have lower velocities than normal notes. When deciding if to retrigger each voice or not, the algorithm takes the following into account:
Retriggering of each note is independent and in some cases all notes except the moving one can retrigger. An example of the resulting notes sequence is shown below (mcount is number of changing notes).
You can see more detailed information and listen to music in the Examples section below. To understand this chart better, pay attention to that a single color column is built above a single note and represents its qualities (yellow, orange, green, blue or black). Creating diatonic movementIn QGen2 diatonic movement means a sequence of notes moving diatonically along the scale (with or without occasional moves over a third): You see diatonic movement from F to A, then movement over a third from A to C, then diatonic movement from C to E. Movements over a third are introduced to avoid tritone (F - H in example). Diatonic movement creation algorithm is used in place of normal note generation algorithm (described in section Step notes generation). First thing to do is to decide when to switch to a diatonic movement creation algorithm and thus start diatonic movement. Every step before note generation possibility to switch to diatonic movement is analysed:
If general conditions are met, two separate diatonic movements are simulated between two selected voices (up and down) and resulting music quality is analysed. If resulting music quality is not too low, diatonic movement is allowed and is started. Algorithm selects the direction of diatonic movement, which resulted in better music quality. Of course, diatonic movement walks through a current mode (scale). Each step when continuing diatonic movement the following is checked:
Example of resulting diatonic movement (from real algorithm run): Step velocities generationVelocities (midi velocities, or volume in other words) are generated for each note and are based on smooth model and increases for:
The smooth model usually has low range, which ensures that velocities do not change much without cause. See description of smooth model in a separate section below. Music analysisDuring the analysis phase the final melody is analyzed for:
For chord detection only sounding notes are analysed. Array of currently sounding notes is compared to a database of chord types, each transposed to all of the 12 possible keys. Currently the following chord types are supported:
If exact chord cannot be determined (because there is no exact match, e.g. in case of A + G + H triad), the closest match is found. The closest matching takes the number of notes repeated and does not pay much attention to the notes, that are not in current mode, which are usually chromatic alterations. In this case closest matching chord is written in parentheses. If bass note is different from the chord tonic, it is printed after slash (e.g. Am/E). The color of the chord shows amount of tension that it creates. Melody character is analysed by counting number of notes, which belong to the character group of current mode (I, III, V notes for tonic; II, V, VII notes for dominant; I, IV, VI for subdominant) and dividing by total number of sounding notes. Then resulting variables are averaged using moving average algorithm (I usually use averaging radius of 5 steps). Melody character is shown using a 3-color chart, where for each step 3 colored blocks are shown:
You can see in the figure that when mode changes from C to G, tonic character in C (C, E, G) becomes subdominant in G (C, E, G). Find and filter culminationsCulminations are detected when there are no notes higher in range of n steps (n is customizable, I use 26 steps) and note makes a jump at least x semitones (x is customizable, usually 2, but may be 1 to use chromatic turn effect). Culminations receive rating based on their height. After the analysis all the culminations are sorted by their height and those which are lowest are thrown away. Filtering is based on percentage, which is customizable. For example, if you say to throw away 40% culminations, then if 5 culminations are detected during the whole piece, 2 of them will be thrown away and will not cause tempo changes. Culminations, that are already stressed by the pause, are also thrown away. Culminations, that suffer filtering process, receive tempo decrease before culmination and return of tempo to its previous value after culmination (tempo decreased due to culmination is shown yellow in the Tempo row): Add chromatic alterationsChromatic turns are introduced by moving the note down chromatically to decrease the pitch change when both notes before and after the changing note are lower. When both notes are higher, note is moved up chromatically. For this to be allowed, several requirements must be met:
In the figure G is altered down to Gb (turn). C is altered up to C# (introduction). D is altered to C# (shift). Chromatic introductions are created by moving the note down to the next note when the previous note is higher and next note is lower then the current note. When previous note is lower and next note is higher then the current note, current note is moved up. For this to be allowed, several requirements must be met:
As opposed to other alterations, chromatic shifts are created not from the three notes, but from two notes - by moving the second note one semitone to the previous note in the voice. Two initial notes must have an interval of one whole tone between them. The result is three notes going in chromatic semitone fashion. Chromatic alterations (turns, introductions and shifts) are allowed only when the following conditions are met:
Create arpeggiosCreating arpeggio is really distribution of the chord notes on the time scale. Arpeggios are created for the chords, that have at least L length (L is customizable, I use 100). During the arpegio generation the time between arpegiated notes is chosen randomly between minimum and maximum values. Also a slowing down with random tempo can be added (a), if the length of the pause allows. First the random time offset increase a is calculated, which falls within the available pause time. All the notes of the current step (which do not dissonate and are not locked) are retriggered for longer arpeggio experience. To extend the arpeggio experience, a note one octave above the highest note in the initial arpeggio may be added. This is done with some probability (I use 100%) only if the followig conditions are met:
Generate tempoTempo generation has an algorithm similar to note velocities generation. In the figure the colors are similar to the colors in the tempo histogram of the algorithm output. On the histogram you see how much tempo each algorithm subtracts: The following is used to generate tempo:
Generate pausesDuring the pause generation stage algorithm counts the probability of creating a pause. The probability depends on:
The chart shows the probability of the pause with the intensity of the yellow color. If the probability is less than 100% there is always possibility that there will be no pause. Pause is added to step length. Pauses are added recursively, each time checking the probability, until the maximum value is reached. Apply velocity and tempo envelopeAt the beginning of the piece tempo and note velocities gradually increase to their normal values. At the end of the piece tempo and note velocities gradually decrease. Tempo envelope for short melody of 30 notes is shown below: Final time randomizationBefore convertion to midi the start of each note is randomized by 1/15 of the eighth note length for less machine-gun sound. This randomization is not included in MIDI files generated for music software to allow more exact recognition of notes. Creating reprisesQGen2 creates reprises for more structured and repetetive music experience. Reprise in QGen2 is repeating notes from previous steps. First thing to do is to decide if we should start reprise. This decision is done every step before starting to generate anything (see Generation process section):
If algorithm decides that it can start reprise, several starting parameters are chosen:
When reprise properties are determined, the reprise starts. Now for each step the following actions are taken:
I would say that using reprises makes music both more repetitive and more experimental. If you want more uniform experience, use reprises with caution or do not use them. When copying notes from template to a reprise, only moving notes are copied to avoid unwanted multivoice move in the beginning of each reprise. Sometimes this leads to crossing voices, when voice that was below, becomes above another voice. In these cases voices exchange ntoes to avoid crossing: lower voice always takes lower note and higher voice always take higher note. To avoid unwanted dissonances, notes that are retriggered due to crossing resolution have decreased volume (I usually use 50%). In the example below you can see that when repeating a template crossed voices are flipped (each voice has its own color): E note becomes highest voice and D note becomes middle voice. Also you can see that only moving voices are repeated (only middle voice is moving in template). In this case D note is retriggered in the second measure two times (in different voices) and each time it has decreased volume. Remember, that tempo is generated later and usually is slightly different for each repeated sentence, as you can see in example below. Example of reprise is shown in the figure: "Reprise" row shows pink background color for steps that are being used as templates for repeating. Darker pink background with numbers shows steps, where step length is copied from previous template (pink) steps. The number shows how many steps are left before the end of current reprise sentence. If number is bold, it means, that note moves are copied from template steps. If not bold, notes are not copied. In the example you can see that reprise starts at step 78 by repeating note moves of step 65. Then in step 79 note moves of step 66 are repeated and so on up to step 88. In step 88 only step len is repeated from step 75 (this is noted by non-bold font of reprise number). This happens to allow new notes at the end of reprised music sentence. Then in step 91note moves of step 65 are repeated again. In this example mode is constant (Eb major). You can see small tempo decreases (light green) at the beginning of each reprise. Here is how the resulting sheet music of the example look like: Template steps 65-77 are marked here with measure numbers 90-93. Notes that were repeated from the template steps are marked green. You can see that measure 97 has the same note lengths as measure 93. This is because note lengths were repeated, but new notes were generated for that lengths. Measures 100 and 101 also have different note moves from measures 92-93 and 96-97. Pay attention, that in our case note lengths in measures 100-101 match note lengths in measures 96-97, but this happened by accident. Note lengths in measures 100-101 were generated from scratch, but it happened that they matched measures 96-97. In other cases they can be different. Music conversionMusic conversion is used when notes are reprised, but the mode has changed and notes need to fall into the new mode. Usual transposition is not used, because it would lead to the movement of notes over long intervals and would create junction problems in places where mode changes. Instead, special conversion technique is used, which allows each note move not further than one semitone. Conversion algorithm run as follows for each step:
Here you can see an example of music conversion from F major mode to Bb major mode (from real algorithm run): In the figure above, copied notes are green. Notes, that were copied, but converted to new mode, are red. You can see, that 54 measure has not only new notes, but also new note lengths, because the reprise is totally aborted in the end. About Smooth modelingIn Quarter Generator smooth modeling is used for velocity and tempo modeling. I can tell you that much more profound use of smooth modeling can be found in my City Generator, where smooth models are also used for note pitches and note lengths. Smooth model works in a step-by-step manner, modeling the second derivative of the target value, then using it to model the first derivative and then modeling the target value. Here is an example of smooth modeling a value. Important properties of the model is that it produces cycling value without jumps, with changing period and amplitude peaks. Full music generation cycleIf you want to generate music with Quartet Generator v2, you will need to:
QGen2 outputs the following files that you may need:
When generating MIDI files for Sibelius display and printing, QGen2 uses the following notation:
ExamplesHere you can see several examples of the Quartet Generator in action. You can view music analysis only in Chrome. Other browsers are not supported.
Download QGen2Quartet Generator v2 is a PHP project. To run it you need an HTTP server (Apache) with PHP installed. You should understand that generation is very CPU intensive. For an example, generation of 100 step music (about 40 seconds of sounding) takes algorithm about 3-7 seconds to run, during which the CPU is used 100%. Download Quartet Generator source code (180 Kb) If you want only to change settings, do not modify any files except CQSettings.php and CQSet.php ThanksI would like to thank people who helped me designing and developing this algorithm:
|