Mods: make styles your own

The preset styles that you can choose in the Viviscore app are nothing more than a collection of predefined parameters. The user can modify some or all of these parameters using “mods”. The following sections of documentation will explain how it works. First, it is necessary to understand some of the internal structures that the Viviscore algorithm uses to represent music. Then the format of a mod is described. Next, a listing of all parameters is given. Finally, some common example mods are given to get you started.

The mod interface is accessed by expanding the “Advanced features” tab at the bottom of the Viviscore app. The top row of this section is used to provide information about the currently-selected style. The lower sections allow the creation and application of modes.

When a style is selected from the dropdown, the “Voices in style:” list becomes populated with the different voices present in the given style. These voices can be selected to look up Voice parameters in the preset style, and also be used in a mod to alter those parameters.

The “Style info” section allows the user to look up parameters in the currently-selected style, within a particular group. This is allows you to find out the current parameter settings, so you can modify them as desired. The “Select group” text box selects the group to look at, in the branch format described below. For example empty brackets [] looks up a parameter applied to the whole piece, or [0] looks up a parameter in the first section of the piece. (See also (add link) for how parameters are applied to different levels of the grouping hierarchy. The parameter to look up is then selected in the “Select parameter” drop-down list. Parameters that begin with “v.[parameter name]” are Voice parameters, and the others are Group parameters. To look up a Voice parameter, select the desired voice from the list at the left. To look up the parameter, click the “Lookup param” button. The parameter will appear in the table at the right. The table can be cleared with the “Clear params” button. Note that this just clears the table; it doesn’t affect the parameter values.

Mods can be either prepared in a text file and uploaded in the box on the left side, or entered directly into the text box on the right side. The basic mod format is shown in the text box by default, with the format of the group and voice mod entries shown in the text boxes below. These can be cut and paste into the mod specification.

If a mod file is uploaded, it will automatically be applied to the subsequent compositions. If a mod is entered into the text box, click “Apply mod” to upload the mod, and activate it for subsequent compositions.

How Viviscore represents music

In order to understand how to gain full control over the output of compositions in Viviscore, it is important to understand the internal structures used to represent music in the algorithm.

The structure of music can be described by hierarchies at different scales and along different dimensions. Viviscore uses two types of hierarchy:

  1. The metric hierarchy, and

  2. The grouping hierarchy.

The metric hierarchy

The metric hierarchy specifies the meter of music. Just as the meter in poetry (e.g. iambic pentameter) specifies a repeated pattern of stressed and unstressed syllables, the metric hierarchy specifies a repeated pattern of musical stresses in time. In Viviscore, the pattern specified by the meter repeats once per measure, and governs how rhythms and melodies are generated.

In traditional music notation, the meter is suggested by the time signature. For example, in the four quarter note beats in a measure of 4/4 time, beat 1 is metrically the strongest, beat 3 is the next strongest, and beats 2 and 4 are weaker. Eighth notes at the “ands” of the beats are weaker still. In general, beat 1 of a measure is the strongest, with subsequent divisions in time becoming weaker.

Viviscore uses a more explicit method for defining the metric hierarchy, as opposed to the traditional time signature. The time signature is replaced by a list of numbers specifying subsequent divisions in time. The length of this list specifies the shortest-duration note possible. For example, a 4/4 hierarchy can be described by

2, 2, 2

This is illustrated in the table below. We start with a time span from the downbeat to the downbeat of the next measure. The first “2” indicates that the measure should be divided in half (i.e. into two half note spans). The second “2” indicates that those half-measures should be divided into two (i.e. into two quarter note spans). And the final “2” indicates that the quarter notes are each divided into two eighth note spans. Each division creates a new level of the hierarchy: beat 1 is the highest level, then beat 3 created by the first division is next highest, followed by beats 2 and 4 created by the next division. Subsequent divisions at the same level are, by default, set to have slightly lower metric strength the previous ones. That is, in this case, beat 4 is slightly weaker than beat 2.

div

1

and

2

and

3

and

4

and

1

.

x

.

.

.

.

.

.

.

x

2

.

.

.

.

x

.

.

.

.

2

.

.

x

.

.

.

x

.

.

2

.

x

.

x

.

x

.

x

.

Another example of a metric hierarchy specification is

3, 2, 2

Here, the measure is first divided into three beats, as indicated by the “3,” as is the case in 3/4 time. As always, beat 1 is at the strongest level, and now beats 2 and 3 are at a weaker level.

The “2” then specifies that each beat may be divided into two sub-beats (e.g. eighth notes in 3/4 time). And the final two specifies that those eighth notes may be divided into sixteenth notes.

As a final example, consider

2, 3, 2

Here, the measure is divided into two spans, each of which is then divided into three. This meter would typically be notated as 6/8. In this case, beat 1 is the highest level and beat 4 is the next strongest. Then those spans are divided into three eight notes adding beats 2, 3, 5, and 6. The final “2” specifies that those eighth notes may be divided into sixteenth notes.

As will be described in more detail later, each level of the hierarchy has a numerical “strength” associated with it, typically with higher levels of the hierarchy having greater strength. However, this default assumption can be overridden to introduce interesting syncopations.

Division order and metric order

The metric hierarchy leads to two orderings of the beats that are used extensively in the Viviscore algorithm: division order and metric order.

Division order:

Division order is the order of creation of the beats as the measure is successively divided. Beats are numbered starting at zero. So the downbeat of the measure is beat zero in division order. Importantly, the first beat of the next measure is always included in the ordering. So then the first beat of the next measure is beat one in division order. If the first division in the metric hierarchy is a two, then the the next beat in division order is at the middle of the measure (e.g. beat 3 in 4/4 time). If the first division in the metric hierarchy is a three, then the two beats created by that division are the third and fourth beats in division order.

For example, 4/4 time specified by the metric hierarchy 2,2,2 would be ordered in the following way.

1

and

2

and

3

and

4

and

1

0

.

.

.

.

.

.

.

1

.

.

.

.

2

.

.

.

.

.

.

3

.

.

.

4

.

.

.

5

.

6

.

7

.

8

.

0

5

3

6

2

7

4

8

1

As another example, 3/4 time specified by the metric hierarchy 3,2 would be specified as follows

1

and

2

and

3

and

1

0

.

.

.

.

.

1

.

.

2

.

3

.

.

.

4

.

5

.

6

.

0

4

2

5

3

6

1

Metric order:

Metric order lists the beats in order from strongest to weakest. This is quite similar, and often identical, to division order. In the 4/4 example above, metric order would be the same as division order. In the 3/4 example however, beat 3 is by default slightly stronger than beat 2, so metric order would be as follows:

1

and

2

and

3

and

1

0

.

.

.

.

.

1

.

.

3

.

2

.

.

.

4

.

5

.

6

.

0

4

3

5

2

6

1

Another time when metric order differs from division order is if the metric hierarchy has been altered from the default, to create for example, syncopated rhythms. For example a syncopated rhythm where the “and” of 2 is strengthened above beat 2, and beat 3 is weakened to below beats 2 and 4 (effectively swapping the “and” of 2 with beat 3), the metric order would be as follows:

1

and

2

and

and

4

and

1

0

.

.

.

.

.

.

.

1

.

.

.

2

.

.

.

.

.

.

.

3

.

.

.

4

.

.

.

.

.

.

5

.

.

.

.

.

6

.

.

.

7

.

8

.

0

6

3

2

5

7

4

8

1

Why use division or metric order

Division order and metric order can take some getting used to. However, they offer significant convenience and flexibility in many cases. Here are a few examples.

  1. In metric and division order, the more “important” beats come first. For example, consider a time signature 2,2,2,2 (4/4 time including 16th notes). If you want to specify that a voice should play a three-note chord on beats 1 and 3 and single notes elsewhere, that could be specified in time order:

    3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3

    But in metric order we can specify that as

    3, 3, 3, 1, 1 …

    This saves us from having to count how many 1’s go between the threes, and also allows us to quickly adapt to a different time signature. For example the division order specification still works in 2,2,2 or 2,2,2,2,2, or even 2,3,2 (6/8 time). A further simplification is that the user doesn’t have to specify all the numbers in metric or division order - Viviscore will pad out the list with the default value (1, in the case of chord notes). So the above specification can just be

    3, 3, 3

  2. The advantage of metric order over division order is that the strongest beats still come first, even if the default metric hierarchy is altered. For example, consider the case of syncopated 4/4 time above, where the “and” of 2 is stronger than beat 3. The chord note specification 3, 3, 3 will still place the triads on the strongest beats (now beat 1, beat 1 of the next measure, and the “and” of 2.). In this way, metric order specification can help retain musical sensibility when the metric hierarchy is changed.

The grouping hierarchy

The grouping hierarchy divides up the structure of music into groups at longer timespans than the metric hierarchy. The top level of the grouping hierarchy is always a group that contains the entire piece. That top-level group is then divided up into some number of child groups that might represent sections of a piece (e.g. exposition/development/recapitulation or verse/chorus or ABACA, etc.). Each group can subsequently be divided into subgroups representing shorter and shorter sections of the piece, such as phrases, or shorter musical statements. The smallest group allowed by Viviscore has a length of one measure.

Groups are important because they define the boundaries where things tend to change within the music. Points in time where higher-level groups end tend to change in more significant ways. As will be described below, group endings are likely to be characterized by things like:

  1. A longer note.

  2. A larger step in pitch to the first note of the next group.

  3. A rest following the last note of the group.

  4. A particular harmony known as cadence, often ending on the tonic or dominant.

By default, the higher up in the hierarchy a group ending extends, the more likely the above items will occur. This extent is referred to as the “group end level.” A bottom-level group whose end does not align with the end of its parent has the lowest group end level. The end of the piece has the highest group end level. Certain parameters are set depending on the group end level.

Groups are also important because they form the units in which the user can set parameters. This allows the user to control how things change throughout the piece. Certain properties affect the group as a whole, such as the key or the tempo. Other properties affect only individual voices within the group, such as the metric strengths or the pitch range. This introduces the next topic: voices.

Voices

Each group contains a set of voices. These voices can be thought of as different instruments or separate parts on the same instrument. Specifically, a voice can have only one rhythm, with one or more pitches sounded at each beat of the rhythm. For example, the left- and right-hand parts of a piano piece would typically be represented by separate voices. Each voice is specified by a set of parameters, including the pitch range, the metric hierarchy, melody parameters, repeats, and parameters for playback.

Each voice can hold one measure worth of rhythm and melody. If a rhythm and melody are specified for a voice within a group, then it will serve as motif, or as a general pattern that the generated rhythm and melody will tend to follow. The voices contained in the groups will then be used to generate the voices in the measures that make up the generated music.

Measures

When the piece is generated, a set of measures are created that will contain the actual music. Measures also contain voices, as well as harmonies. The measures are generated according to the grouping structure. First a harmonic progression (or chord progression) is generated according to the harmony settings contained in the groups, with each measure containing one or more chords. Specifically, the harmonies are generated from the groups at the second-lowest level. (The lowest level groups are usually so short that it doesn’t make sense to change harmony parameters that fast.) Then the voices are copied into each measure, again according to the grouping structure. In this case, parameters are taken from the lowest level of groups (with the exception of several parameters that are summed from all parent groups). Finally the rhythm and melody are generated and stored in each voice, in all the measures, yielding the generated music.

Propagation of parameters

When looking up a parameter or changing a parameter using a mod, it is important to understand how parameters are set at different levels of the grouping hierarchy.

In general, changing a parameter in a selected group will also change that parameter in all of the groups below the selected group in the hierarchy. (Though several exceptions are noted below). For example, if the top-level group is selected, a parameter change will affect the entire piece. When the music is generated, most parameters are taken from the lowest level of groups. The propagation of parameters thus allows the user to change parameters in many groups in the lowest level at once.

The propagation of parameters means that caution is required when looking up parameters. The value of a parameter in a higher level group may not be the same as that parameter at the lowest level. This would occur if a parameter was initially set at the top global level, but then altered in a particular section.

The exceptions to the parameter propagation are the following group parameters:

  1. keytranspose: changes key by a number of semitones

  2. tempomult: multiplies the tempo by a factor

  3. tempodelt: specifies accelerando/ritardando

  4. vdelt: specifies crescendo/diminuendo

When changed, the parameters in the list above do not propagate and are changed only in the selected group. When the music is generated from the lowest level groups, these parameters are used additively, not just from the lowest level group, but from all of the successive parent groups as well.

Voice variants

Each voice has several possible variants. At the moment, all voice variants are changed when a parameter is changed, but in a future version, it will be possible to separately change the voice variants. The variants are the “Main voice,” “Anacrusis,” and several “End voices.” The “Anacrusis” variant is applied in the portion of group (if any) before the first full measure of the group. The “End voices” are applied on the last measure of the group. The end voices are numbered by the beat on which the group has its last note. The numbers are in division order. So “0” is the first beat of the measure. (Recall the “1” is the first beat of the next measure, so is not used here). Then “2” is the next division of the measure (e.g. beat 3 in 4/4 time, or beat 4 in 6/8 time).

Examples of where voice variants are useful could include:

  1. A voice plays single notes throughout a phrase, but then a chord on the final note of the phrase (end voice).

  2. A voice plays offbeats throughout the phrase, but then on the beat at the phrase end (end voice).

  3. A voice plays steady quarter notes throughout the phrases, but a more complex riff is desired leading into phrases (anacrusis voice).

Mod format

Style mods in Viviscore are written in JSON format, in the following way:

{
    "mods": {
        "groupMods": [

        ],
        "voiceMods": [

        ]
    }
}

Individual mod entries will be added to the groupMods array (if they set parameters that affect a group) or to the voiceMods array (if they set parameters for an individual voice within a group).

Group mods are specified by array elements:

{"branch": [], "param": "param_name", "value": 0}

Any number of group mods can be added to the groupMods array with the elements above separated by commas. The values assigned to "branch", "param" and "value" will be explained below.

Voice mods are similarly specified by array elements:

{"branch": [], "voice": "voice_name", "param": "param_name", "value": 0}

Any number of voice mods can be added to the voiceMods array with the elements above separated by commas. The only difference from the group mod format is that the particular voice is also specified. If the "voice" element is an empty string "", the mod will be applied to all voices. The values assigned to "branch", "param", "voice" and "value" will be explained below.

As an example, the following code sets two (fictitious) group parameters and one (fictitious) voice parameter:

{
    "mods": {
        "groupMods": [
            {"branch": [], "param": "param_name1", "value": 0},
            {"branch": [0], "param": "param_name2", "value": [0.5, 2]}
        ],
        "voiceMods": [
            {"branch": [], "voice": "voice_name", "param": "param_name3", "value": 23}
        ]
    }
}

Branch specification

The "branch" element in a mod statement specifies which group in the composition the mod should be applied to. Recall the structure of the piece is a hierarchy of groups. The top level of the hierarchy is a group that represents the whole piece. That group is then subdivided into a number of subgroups. The groups in this second level define the sections of the piece that are demarcated by the markers in the Viviscore app. Groups are further subdivided, typically for a total of 4 or 5 divisions, down to groups with a length of typically 1 or 2 measures.

The "branch" element takes an array of integers that specifies how to traverse this hierarchy of groups. An empty array [] represents the whole piece. A mod with "branch": [] will affect the whole composition. A single entry in the array selects a group in the second level, starting with zero. So "branch": [0] will affect the first section of the piece, and "branch": [1] represents the second section. "branch": [-1] can be used to represent the final section of the piece. (The “children” of a group are stored in a python list; we are providing the index of that list here.) Lower level groups can be specified by adding more numbers to the list. It is important to note, however, that when the piece is composed, at lower levels only the parameters from the first and last subgroups are retained. That is, the first number in the branch array specifies the section, and any subsequent numbers should either be 0 or -1, specifying the first or last subgroup. For example, "branch": [0,0,0,0,0,0] would specify the first, lowest level of the the piece. (If the branch list specifies more levels than exist in the piece, any extra levels are ignored.) Alternatively, "branch": [-1,-1,-1,-1,-1,-1] would specify the very last group. As another example "branch": [2,0,0,0,0,0] would specify the first group at the lowest level of the third section.

Parameter specifications

Listing of group and voice parameters.

Group parameters

Harmony parameters

keytranspose:

An array of integers. Transposes the pitches in the active harmony by the specified number of semitones. This effectively changes the key. This does not affect the pitch range of each voice, which will still be used as specified in the Voice parameters. In general, keytranspose should be set as a single element array, e.g. [7].

Unlike most settings, the transpose settings are applied additively across the grouping hierarchy. For example if a piece contains a key change at some lower level of the hierarchy, say from 0 (tonic) to 7 (dominant), then the overall tonic key can be shifted at the top level group maintaining the same key change at the lower levels.

Example:
{"branch": [2], "param": "keytranspose", "value": [2]}

This changes the key of the third section by one whole step (e.g. from C to D).`

pivot:

An integer. This specifies a modulation by the specified number of semitones to a new key within the selected group. The setting is only has effect in the second-to-lowest grouping level. For example, a setting of 7 will choose a harmonic progression for this group that gracefully pivots from the current key to a key a fifth higher. This occurs by a common-pitch modulation if possible, or a circle-of-fifths modulation otherwise. Note that if you want the next group to continue in the new key, you must specify that using the keytranspose parameter of the next and any subsequent groups.

Example:
{"branch": [1,-1,-1,-1], "param": "pivot", "value": 2}

This modulates the key during the final group of the second section.

harmony:

A string. Selects the preset harmony style for the selected group from a list of options. The preset harmony style specifies which chords are used and how they are used. This setting chooses, for example, between major and minor modes.

Possible choices are:
  1. “major_basic”: standard major harmony

  2. “major_mozart”: more complex major harmonies

  3. “major_romantic”: major harmony following conventions of the Romantic classical period.

  4. “major_jazz”: major harmony including some jazz chords

  5. “major_pop”: major harmony following pop music conventions

  6. “major_rock”: major harmony following Rock’n’Roll conventions

  7. “minor_basic”: standard minor harmony

  8. “minor_jazz”: minor harmony including some jazz chords.

Example:

{"branch": [], "param": "harmony", "value": "major_basic"}

This sets the entire composition to a major harmony.

muharm, Tharm:

Floating point numbers. These parameters set the harmonic rhythm in the selected group – that is, how often the chord changes. These parameters function exactly like the the those used to set the rhythm for each voice, but choose when the chord changes instead of when a new note begins. The parameter muharm sets the typical duration for each chord, with lower values being longer. A value < 1 will typically result in one chord per measure (the highest level of the metric hierarchy). A value between 1 and 2 will typically result in chords changing at the next level of the metric hierarchy (two chords per measure in 4/4 time for example). The parameter Tharm sets the variability of the number of chords per bar. A very small value will rigidly enforce the setting of muharm. A larger value will cause the value of muharm to fluctuate with the specified value of Tharm.

Example:

{"branch": [], "param": "muharm", "value": 1.5},
{"branch": [], "param": "Tharm", "value": 0.1}

This sets the entire composition to have a harmonic rhythm that very regularly changes the chord twice per measure.

muharmdelt:

Array of floats. Sets how much to change the parameter muharm in the penultimate measure of group preceding a cadence, at different group end levels, starting from the second lowest and increasing. This has the effect of increasing the harmonic rhythm at the ends of phrases.

Example:

{"branch": [], "param": "muharmdelt", "value": [0, 0.5, 1, 1]}

This sets the entire composition to not increase the harmonic rhythm at the lowest group end levels, increase by 0.5 and the next lowest, and increase by 1 at higher levels.

resolve:

Array of floats. Sets the probability that a harmonic cadence will occur at a group ending, within the selected group. (Harmonies are chosen at the second-to-lowest group level, so cadences will not be chosen at the ends of lowest-level groups.) The list is in order of group end level. The first element sets the parameter for second-to-lowest groups whose end does not coincide with the end of the parent group. The element sets the parameter for groups whose end coincides with the end of just one higher grouping level, and so on. Generally, higher group end levels will have higher cadence probability.

Example:

{"branch": [], "param": "resolve", "value": [0, 0.5, 1, 1]}

This sets the entire composition to not cadence at the second-to-lowest group ending level, cadence with probability 50% at the next highest level, and always cadence at higher group ending levels.

Tempo and dynamics parameters:

tempomult:

A float. This allows you to set the tempo of the group. The specified number multiplies whatever the tempo was at the end of the previous group. The initial tempo is set to 30 bars per minute (e.g. 120 beats per minute in 4/4 time). For example, a tempo multiplier of 2 in the first group of the piece will change the starting tempo to 60 bars per minute (e.g. 240 beats per minute in 4/4 time). Tempo multipliers in subsequent groups could then allow tempo changes throughout the piece.

This setting propagates in a unique way. When the setting is changed in a group, the setting propagates only to the first of its children and all lower first children. This is because it is a parameter that only has an effect at the beginning of the selected group.

Example:

{"branch": [], "param": "tempomult", "value": 0.8}

This sets the beginning tempo of the piece to 24 bars per minute (96 beats per minute in 4/4 time).

tempodelt:

A float. Specifies amount to accel. or rit. over the span of the selected group. A number greater than 1 is a ritard, and less than one is an accelerando. Tempo changes can only be applied at the lowest level groups, in the first or last group of a section. Note that this number works in the inverse way as compared to tempomult. For example, a tempodelt of 1.5 would decrease the tempo by a factor of 1.5 across the group. This is handy if you want to return to a tempo in the next group – you just use a tempomult equal to the previous tempo change, in this case 1.5.

Examples:

{"branch": [0,-1,-1,-1,-1], "param": "tempodelt", "value": 1.5},
{"branch": [1], "param": "tempomult", "value": 1.5}

This creates a ritard at the end of the first section, and then a tempo to begin the second section.

{"branch": [-1,-1,-1,-1,-1], "param": "tempodelt", "value": 1.5}

This creates a ritard at the end of the piece.

swing:

A float. Amount to delay every other beat, at the smallest division in any voice in this group. Odd numbered beats (in time order) are delayed by a fraction of the shortest possible time between beats. Settings around 0.2 swing pretty solidly. Note that the swing is set in the shortest possible beat division, even if there are no notes at that level. That is, if the fastest time signature of any voice is set to (2, 2, 2, 2), any sixteenth notes will be swung, and if there are no sixteenth notes, nothing will swing.

Example:

{"branch": [1], "param": "swing", "value": 0.2}

This creates a swing rhythm in the second section.

vdelt:

Two-element array of floats. This parameter is used to set crescendos and diminuendos or sudden dynamic changes. The values change the dynamic from the default level (say, mezzo-forte). Roughly speaking, a change of 1 is about one dynamic level (from mezzo-forte up to forte or down to mezzo-piano.) In other words, a change of 2 is a pretty extreme change.

The first and second elements of the array set the starting and ending dynamic for the selected group. If they are equal, then there is a constant dynamic shift for the duration of the group. If they are not equal, then there will be a crescendo or diminuendo over the duration of the group. Note that the change only applies over the selected group. For example, a crescendo specified in one group will not cause the next group to stay at the final dynamic level. If that is desired, the user should change the vdelt in the next group.

This parameter is not propagated to lower-level groups, but instead is applied additively. For example, a mid-level group could be specified to have a uniform increased dynamic, and then lower-level groups could be specified to have crescendos or diminuendos on top of that increased dynamic level.

Example:

{"branch": [0], "param": "vdelt", "value": [1, 1] },
{"branch": [0,0,0], "param": "vdelt", "value": [-1, 0]}

This creates a crescendo from 0 to 1 in the first group 3 levels down, then stays at 1 for the duration of the first section. (Note that the two statements are applied additively.) If no other vdelt parameters are set, then the dynamic will drop back to 0 subito in the second section.

Voice parameters

Parameters that control individual voices within a group.

Pitch parameters

pmin, pmax:

An integer. Sets the pitch range for the voice in the selected group, in semitones, relative to middle C (C3).

Example:

{"branch": [2], "voice": "violin", "param": "pmin", "value": -1 },
{"branch": [2], "voice": "violin", "param": "pmax", "value": 14 }

Sets the range of the violin in the third section from the B below middle C, to the D above a ninth above middle C.

rootnote:

An integer. Sets how many beats, in metric order, will be required to play the bass note pitch of the current harmony. (This would be the root pitch in the absence of an inversion.) For example, if the value is 2 in standard 4/4 time, and the current harmony is a C major triad with no inversion, then beats 1 and 3 of the bar, if they have a new note starting there, will be a C.

Example:

{"branch": [0], "voice": "cello", "param": "rootnote", "value": 1 }

Requires the cello in the first section to play the bass note of the current chord on the downbeat of each measure.

bassnote:

An integer. Sets how many beats, in metric order, will be required to play a note in the lowest octave of the pitch range (if a note begins on those beats.)

Example:

{"branch": [0], "voice": "cello", "param": "bassnote", "value": 1 }

Requires the cello in the first section to choose a pitch in the lowest octave of its range (specified by pmin and pmax) on the downbeat of each measure.

Rhythm parameters

tsig:

An array of integers. Sets the time signature as given by a metric hierarchy specification. Note that different voices can have different time signatures, allowing for polyrhythms.

Example:

{"branch": [], "voice": "", "param": "tsig", "value": [2, 3, 2] }

Sets the all voices throughout the piece to a 6/8 time signature with sixteenth notes as the shortest notes.

mu:

A float. Sets the typical note length. Units are levels of the metric hierarchy. A value of zero is a note spanning the entire measure, a value of one specifies notes spanning the first division of the metric hierarchy (e.g. half-notes in 4/4 time or quarter notes in 3/4 time), and so on.

Example:

{"branch": [1], "voice": "violin", "param": "mu", "value": 3.5 }

Sets the typical note length for the violin in the second section to be eighth or 16th notes.

T:

A float. (“Temperature.”) Sets the typical range of different note lengths appearing in the rhythm, in units of the metric levels. For example, a value much less than one generally results in all notes of the same length. A value of 1 would yield a particular note length (say, quarter notes), with a fair number of notes one level higher (half notes) and one level lower (eighth notes). Values around 0.5 are typical.

Example:

{"branch": [1], "voice": "violin", "param": "T", "value": 0.1 }

Sets the typical note length for the violin in the second section to be eighth or 16th notes.

mu2, T2:

Floats. These parameters govern the likelihood of repeated notes, and are analogous to mu and T:, respectively. While the parameters above set the rhythmic pattern of note onsets, these parameters set the rhythmic pattern of pitch changes. For example, if mu2 is zero, then it spans a whole measure and the pitch will not change throughout the measure. If there are multiple notes in the measure, they will have the same pitch. On the other hand, if mu2 is large, then notes within the measure will not be required to have the same pitch (though they might, depending on the Pitch repetition settings below).

Example:

{"branch": [0], "voice": "timpani", "param": "T", "value": 0.5 },
{"branch": [0], "voice": "timpani", "param": "mu", "value": 2.5 },
{"branch": [0], "voice": "timpani", "param": "T2", "value": 0.1 },
{"branch": [0], "voice": "timpani", "param": "mu2", "value": 0.1 }

Sets the timpani in the first section to play a rhythm with a mix of mostly quarter and eighth notes, but almost certainly playing just a single pitch in each measure.

restlev:

An array of floats. Sets the probability of a rest at each level of the metric hierarchy, starting from the highest level. Setting the first element to 1 sets a rest on the downbeat of each measure. If a rest appears on a particular beat, no new notes will begin in immediately preceding weaker beats. Therefore, if the downbeats of the measures all have rests, then the voice will rest continuously (assuming the downbeats are the strongest beats, as in the default metric hierarchy). If rests are desired on the downbeats with other notes played in the bar, then the metric hierarchy must be altered so that the downbeats are not the strongest. Likewise, if the second element is nonzero, so a rest occurs on beat 3 in 4/4 time, the preceding note can only start on the downbeat (again, assuming the default metric hierarchy.)

Example:

{"branch": [], "voice": "bassdrum",
    "param": "restlev", "value": [0,0,1,0] }

Sets the bass drum to rest on beats 2 and 4 (assuming 4/4 time).

bdelt:

An array of floats. This parameter allows the user to alter the metric hierarchy. The array of numbers shifts the metric strength of each beat, in division order. A value of 1 shifts that beat up by one level of the metric hierarchy, or -1 down by one level. If the list is truncated, all further values are taken to be zero. For example, in 4/4 time,

[0,0,1]

would leave the downbeat of this and the next measure alone (the first two zeros), and would shift beat three up by one level so as to be equal in strength to the downbeat. Subsequent beats in division order are unaffected.

As another example,

[0,0,-1.5,1]

would shift beat 3 to be weaker than beats 2 and 4, and then shift beat 2 to where beat 3 used to be. This can yield a syncopated rhythm with a tie into beat 3.

bdelt, and rdelt for altering the rest probabilities below, are cases where the first and second entries in division order, specifying the downbeat of this measure and the next, might be different. The key thing is that the first value for the downbeat (first in division order) will be used if this is the first measure in which a new set of voice parameters is copied from the group. If it is a continuation of the same voice parameters, then the “downbeat of the next measure” (second in division order) is used. A new set of voice parameters is applied at the beginning of each group, and in the final measure of each group (the “end voice” variant). So the second value in division order is only used in the interior of groups longer than two measures. In the majority of cases, these two values should be the same.

Example:

{"branch": [], "voice": "snaredrum",
    "param": "restlev", "value": [1,1,0,0] },
{"branch": [], "voice": "snaredrum",
    "param": "bdelt", "value": [-2,-2,-1,1, 1] }

First sets the snare drum to rest on beats 1 and 3 (assuming 4/4 time). In the default metric hierarchy, this would cause the snare drum to rest continuously. The next line however, shifts the first two levels of the hierarchy down (the downbeat, the downbeat of the next measure, and beat 3), and then shifts beats 2 and 4 up one level so they are stronger than the beats 1 and 3.

rdelt:

Array of floats. This parameter allows the user to alter the rest probability for each beat, in division order. (restlev require the rest probability to be the same for all beats in the hierarchy.) These values add to any set by the restlev values. If the list is truncated, subsequent values are taken to be zero.

Example:

{"branch": [], "voice": "bassdrum",
    "param": "rdelt", "value": [0,0,0,0,0.5] },

Sets a bassdrum voice to have a 50/50 chance of resting on beat 4 (in 4/4 time) when a note is placed there.

tupledelt:

Array of ints. This array of values changes the meter to have triplets, duples, or generally n-plets. The numbers change each subsequent division (in division order) of the bar by the specified value. The first two values are not used (as they correspond to the downbeats). The third value corresponds to the first division of the measure. For example, if the first value in the metric hierarchy is a 2, normally this divides the measure in half. But the third value of tuple delta adds to this value. So if that value is a 1, then the measure will instead be divided into 3, creating a set of triplets that span the measure. As another example, if the metric hierarchy is 2,2,2, then the tupledelt

[0, 0, 0, 0, 1]

creates a set of triplet quarter notes that span the final half of the measure. The one here indicates the division that would normally divide the second half of the measure into two quarter notes; instead it is divided into a three-quarter-note triplet. Numbers greater than one can be used to make n-tuplets for any n. If a division was originally a 3, the tuple delta can be set to -1 to create a duple.

Example:

{"branch": [1], "voice": "snaredrum",
    "param": "tupledelt", "value": [0,0,0,0,0,0,1,0,1] }

In 4/4 time, sets the snare drum to play eighth note triplets on beat 2 and 4.

Melody parameters

tsigmalev:

Array of floats. Pitches are chosen mainly according to two parameters: the pitch time range and the voice leading range. tsigmalev sets this value for each level of the metric hierarchy. Once the rhythm has been chosen for a measure, pitches are assigned to each pitch change event, in metric order. Pitches are drawn from the chord progression. The pitch time range sets how far from the current point in the chord progression pitches can be selected, in units of measures. A very small number (much less than 1) will require the pitch to be chosen from one of the pitch classes in the present chord. A value of 1 will typically choose from the chord(s) in the present measure, or those in the previous or next measure. Generally, the tsigmalev values increase with each level going down the metric hierarchy.

Example:

{"branch": [], "voice": "electricbass",
    "param": "tsigmalev", "value": [0.01,0.01,0.01, 0.01,0.01] }

Sets the electric bass to only choose notes from the current chord (all values of tsigmalev much less than 1.)

vlsigmalev:

Array of floats. This parameter sets how closely each pitch is spaced to its neighbors in semitones, yielding voice leading. The values specify settings for each metric level. Since the pitches are chosen in metric order, the first value specifies how close the pitch of the downbeat of the next measure is to the downbeat of this measure. The next value (in 4/4 time, say) specifies how close beat 3 is to the two preceding and following downbeats. Left to its own devices, this procedure would probably over-represent repeated pitches. To avoid that, the preprlev and prepllev parameters serve to suppress repeated pitches.

Example:

{"branch": [], "voice": "violin",
    "param": "vlsigmalev", "value": [12, 12, 12, 3, 2] }

With the first three values of 12, the downbeat, beat 3, and beats 2 and 4 are all allowed to have octave-range jumps in pitch, though any eighth or sixteenth notes will be more likely to appear close to midway between their neighbors.

chordNotes:

Array of int. Specifies the number of notes to play at each point in the measure, if a new note begins there. The list is in metric order. If truncated, the list is padded with ones.

Example:

{"branch": [], "voice": "pianoLH",
    "param": "chordNotes", "value": [1,1,1,3,3] }

Specifies that the piano left hand should play a single note on beats one and three, and triads on beats 2 and 4, whenever notes begin on those beats (assuming 4/4 time).

chordInterval:

Int. If a chord of more than one note is chosen, this parameter specifies that maximum interval for the notes of the chord, in semitones. The bass note of the chord is chosen in the range specified by pmin and pmax. Then the rest of the pitches are chosen in the chordInterval above that pitch. Note that this can choose pitches above the specified pmax. pmax should be understood to only apply to the lowest note of a chord.

Example:

{"branch": [], "voice": "pianoLH", "param": "chordInterval", "value": 12 }

Specifies that the piano left hand should play any chords with pitches within one octave.

prepllev and preprlev:

Arrays of floats. These arrays govern the probability that a pitch will be allowed to repeat at different levels of the metric hierarchy. A value of zero means that pitches may repeat, and a large negative number suppresses repetition (something like -50). As the pitches are chosen in metric order, this repetition refers to whether a new note is chosen that repeats the nearest already-chosen pitch to the left (controlled by prepllev), and the nearest already-chosen pitch to the right (controlled by preprlev). For example, the first value affects repetition of pitches at the beginning of measures. If the first value of prepllev is set to zero, then the pitch at the downbeat of a measure may be the same as the pitch at the downbeat of the previous measure. Or in 4/4 time, the second value sets the probability that beat three is the same pitch as beat one of that measure (in prepllev) or as beat one of the next measure (in preprlev). This setting counteracts the tendency of vlsigmalev to favor repeated pitches. This is independent of the pitch change rhythm set by mu2 and T2. If the pitch change rhythm calls for a new pitch, the pitch may still repeat if prepllev and preprlev are set to zero. But if the pitch change rhythm calls for a repeated pitch, this setting cannot override that.

Example:

{"branch": [], "voice": "violin",
    "param": "prepllev", "value": [0,-50,-50,-50,-50] },
{"branch": [], "voice": "violin",
    "param": "preprlev", "value": [0, 0,-50,-50,-50] }

Sets the violin to repeat pitches at successive downbeats, but prevents repetition of a downbeat on beat 3. However, repetition of beat 3 at the next downbeat is allowed. Further repetition is suppressed.

Motif Parameters

rhyth:

Array of ints. A motif can be specified for a measure of rhythm in this group. The format is as a list of numbers where 0 means a new note begins, and a 1 means a note is held. The list is separated by commas, and is in metric order. So if one wanted to specify new notes on the four strongest beats of a measure only and the downbeat of the next measure, the entry would be

[0, 0, 0, 0, 0]

Any further values are taken to be 1. Note that there are 5 zeros in this example because the second zero refers to the first beat of the next measure.

A motif is only a suggestion. The settings of mu and T still act as a starting point, but the rhythm is biased towards the specified motif, with a biasing strength set by repstr.

The rhythm motif is repeated for every measure in the selected group. If different motifs are desired for different measures, multiple motifs can be specified by placing each measure in nested arrays. For example:

[0, 0], [0, 0, 0]

in 4/4 time would specify a motif of one whole note measure followed by two half notes. The pattern would then repeat in subsequent measures. Note, however, that that this only is useful if the lowest level group is longer than two measures. If the lowest level group is one or two measures long, then this is not necessary as each main voice measure and/or end voice measure can separately be specified.

Example:

{"branch": [0], "voice": "trumpet",
    "param": "rhyth", "value": [0,0,0,1,0] }

Specifies that a trumpet voice in 4/4 time will tend to play a rhythm of a half note followed by two quarter notes (notes begin on downbeats, beat 3 and beat 4, but not beat 2).

mel:

Array of arrays of ints. Like rhyth, the mel specifies a general pattern for the melodic line in each measure within the selected group. The melody motif is given in units of semitones, with each time point in square brackets. The motif is specified in metric order.

As with rhyth, mel does not specify the actual pitches to be used, but biases the shape of the melodic line towards the given shape. Pitches are still chosen from the harmonic progression according to the tsigmalev setting, but with relative intervals biased towards those in the motif. For example,

[[0], [0], [7]]

in 4/4 time with the default metric hierarchy would specify a motif where the down beat of the next measure is the same as the downbeat of this measure (because the first two numbers are the same), with beat 3 higher by 7 semitones (a perfect fifth). The actual pitches chosen may or not be exactly this, depending on which pitches are available in the harmony, and some random chance.

Any further divisions of the measure are generated with the usual tendency towards parsimonious voice leading (avoidance of large jumps in pitch) with no motif applied.

As with rhyth, mel can be specified for more than one measure by nesting the motif measures inside another (third) array. Note, however, that that this only is useful if the lowest level group is longer than two measures. If the lowest level group is one or two measures long, then this is not necessary as each main voice measure and/or end voice measure can separately be specified.

Note: at the moment there seems to be a bug if you specify a melody motif with no rhythm motif. This will be fixed in the future.

Example:

{"branch": [0], "voice": "pianoLH",
    "param": "rhyth", "value": [0,0,0,0,0,0,0,0,0] },
{"branch": [0], "voice": "pianoLH",
    "param": "mel", "value": [[0],[0],[0],[4],[4],[7],[7],[7],[7]] }

Specifies that the piano left hand in 4/4 time will tend to play an “Alberti” bass line. The rhythm will tend to be eighth notes, with the melody biased towards a bass note on the downbeat and beat 3, a major third (4 semitones) above the bass note on beats 2 and 4, and a fifth above (7 semitones) on the “ands” of each beat.

repstr:

A float. This parameter, the “Rhythm repeat strength” governs how closely the rhythm follows a specified rhythm motif, either as specified in the voice, or if a motif repeat is selected for the group. A value of zero means that the rhythm will not be biased towards the motif at all. A value of 0.5 will generally follow the motif, as long as the rhythm parameters mu and T are set to allow that sort of rhythm. A value of 1 is a fairly strong bias. A value of 2 is very strong, and can often force the rhythm to be repeated even if the rhythm parameters disagree with the motif. The units are essentially in levels of the metric hierarchy.

Example:

{"branch": [0], "voice": "violin",
    "param": "rhyth", "value": [0,0,0,0,0,0,0,0,0] },
{"branch": [0], "voice": "violin", "param": "repstr", "value": 3 }

The first line sets a violin voice to play a run of eighth notes. The second line sets the repeat strength to a very high value, making it very likely that the rhythm motif will be followed exactly, even if mu is set to make eighth notes unlikely.

Group end parameters

endshift:

Array of floats. These (typically negative) values set the likelihood that the last note of a group will be held longer, as compared to other notes in the group. This is accomplished by suppressing the metric strength of any beats after the group’s end beat by the specified amount. Therefore, the units are levels of the metric hierarchy. A value of -1 will tend to make the final note of the group last one level of the metric hierarchy longer than typical notes in the rhythm (e.g. a quarter note, if the typical notes are eighth notes). The sliders are in end-level order. (The first value affects bottom-level groups that do not share an end with any higher-level groups, the value affects bottom-level groups that share an ending with their parent group only, etc.)

Example:

{"branch": [2], "voice": "violin",
    "param": "endshift", "value": [0, -0.25, -0.5, -2] }

Sets a violin voice to not alter the note lengths at the lowest-level, least significant group endings, with growing note length increase as the significance of the group endings increase. Large sections at the fourth group-end level will have their typical note lengths extended by two metric levels – if a typical note length is a quarter note, the section may end with a whole note.

endrest:

Array of floats. These values set the likelihood of a rest following the last note of a group. 0 means no chance of rest, and 1 means always place a rest if a new note is chosen after the last note of the group, but before the downbeat of the next measure. Note that this means that a value of 1 does not guarantee a rest. A value of 1 only decides between a rest and a possible pick-up note into the next group. The values are in end-level order. (The first value affects bottom-level groups that do not share an end with any higher-level groups, the next value affects bottom-level groups that share an ending with their parent group only, etc.)

Example:

{"branch": [0], "voice": "violin",
    "param": "endrest", "value": [0, 0.5, 1, 1] }

Sets a violin voice to place no rests after the lowest-level group endings. If the last note of such a group does not extend to the end of its measure, the remainder of the measure will contain pick-up notes (an “anacrusis”) into the next group. The second lowest group-end level will have a 50/50 chance of a rest following the group end note, if such a note exists in the measure, and larger groups will definitely have a rest as opposed to a pickup note immediately following the previous end note.

Output parameters

clef:

A string. Sets the clef to be used when notating this voice in the score. Possible values are “treble”, “tenor”, “alto”, “bass”, and “percussion”.

Example:

{"branch": [], "voice": "violin", "param": "clef", "value": "treble" }

Sets a violin voice to be noted in treble clef.

vel:

A float. Sets the overall dynamic level for this voice. Dynamics and dynamic changes for all voices can be set as a Group setting (vdelt). This setting is useful, however, for mixing the different voices. The value roughly corresponds to the midi velocity in the range 0-128, but combines with the group level dynamic settings.

Example:

{"branch": [2], "voice": "viola", "param": "vel", "value": 90 }

Sets a viola voice in the third section to be rather loud (as compared to the default level of 64).

strum:

Array of floats. This array is used to set various values affecting the playback, with “strum” only referring to the first value. Currently, there are three values set here, but more may be added. The first value sets the degree to which chords are arpeggiated - that is, a time delay between successive notes of a chord from lowest to highest. A value of 1 spreads the notes of the chord over a time span equal to the smallest time division of the meter. The second value acts like a sustain pedal, with a value of 0 or 1. With a value of 0, notes begin and end as usual. With a value of 1, a note begins as usual but does not end until the next chord change. The third value in the array controls marcato/legato, with a floating point value between -1 and 1. A negative value puts extra space between notes, and a value greater than one overlaps adjacent notes slightly.

Example:

{"branch": [0], "voice": "guitar", "param": "strum", "value": [0.3, 1, 0] }

Sets a guitar voice in the first section to have a moderate strum effect (the first value), to sustain notes until the next chord change (the second value), and to begin and end note times normally (the third value).

acclev:

Array of floats. Sets a deviation of the midi expression depending on the level of metric hierarchy. The first value affects the highest metric level (i.e. downbeats), and in 4/4 time, the second value affects beat 3, etc. The overall expression level spans 0-128, but typical accent levels change this by a number on the order of 10.

Example:

{"branch": [0], "voice": "pianoLH", "param": "acclev", "value": [0,0,10] }

Sets the piano left hand in the first section to have accents on beats 2 and 4, assuming 4/4 time.

beatfade:

A float. Phrasing will be automatically added to the playback in a way that attempts to follow the melodic line of the first voice. This value sets how much to change the midi expression control according to the phrasing. A value of 1 is typical.

Example:

{"branch": [], "voice": "violin", "param": "beatfade", "value": 0 }

Sets the violin voice to have no automatic phrasing.

generalmidi:

An int. This sets the midi program to use for playback, selecting the instrument according to the general midi standard. This only affects outputted midi files and the in-browser preview playback; it is not possible to change the instruments in the rendered audio download. Also note that the instruments are indexed starting with 0 (Acoustic Grand Piano).

Example:

{"branch": [], "voice": "violin", "param": "generalmidi", "value": 79 }

Sets the violin voice to actually be played on an ocarina.

perc:

An int. Sets whether the voice is an unpitched percussion voice. A value of 0 indicates that this is not an unpitched percussion voice. A different value sets the midi note value for the desired percussion instrument. Melodies will not be generated for such a voice, with the selected value chosen as the pitch for all notes in the generated rhythm. Note that this parameter does affect the rendered audio download, but possibly in unpredictable ways depending on the sound samples used in the backend for the rendering.

Example:

{"branch": [], "voice": "snare", "param": "perc", "value": 47 }

Changes the snare drum voice to actually be the Low-Mid Tom.