Improvisation

Subsections of Improvisation

Generator Components

Generator components and data flow:

flowchart TB;

in(( ))
out(( ))

subgraph BNG[Beat Generator];
direction TB
    in1(( ))
    scoreplayer[Score Player]
    improviser[Improviser]
    out1(( ))
    in1 -->|bang| scoreplayer -->|beat number| out1
    in1 -->|beat label| improviser -->|beat number| out1
end

bdnl[Beat Dict Name Lookup "get_beats"]
loop[Looper]
br[Beat Reader]
in -->in1
out1 -->bdnl -->|beat number| loop -->|beat number| br -->|playback data| out

The audio and MIDI generators (djazz.midi.generator and djazz.audio.generator , respectively), are the workhorses of the Djazz 2.0 system. Their makeup is similar

The generator uses the beat number when improvise mode is not on; it uses this to play the next beat or a different beat if one has been selected by the user. In improvise mode, the beat number is not considered. The label produced by the analyzer is used, as described above.

Beat generator components and data flow:

flowchart TB;

in(( ))
out(( ))

subgraph SP[Score Player];
direction TB
    in1(( ))
    speed1[Speed Control]
    bc[Beat Clock]
    out1(( ))
    in1 -->|bang| speed1 -->|bang| bc -->|beat number| out1
end


subgraph I[Improviser];
direction TB
    in2(( ))
    speed2[Speed Control]
    label[hold label]

    subgraph FOP[Factor Oracle Player];
        in3(( ))
        out3(( ))
        FO[Factor Oracle]
        in3 -->FO -->out3
    end

    out2(( ))
    in2 -->|label| label
    in2 -->|label| speed2 -->|bang| label -->|label| in3 
    out3 -->|beat number| out2
end

in-->in1
in-->in2
out1-->out
out2-->out


The beat generator can play in two modes: score player and improviser. Each of these also contain two modes: play at the tempo given by the tap, or play at a different speed: double speed, quadruple speed, half speed, and one and a half speed. This speed change is controlled by an object–the “Speed Control” that, when messages are passed to the generator, modifies the timing of their distribution to the generator’s internal objects. Even though both the score player and the improviser use the Speed Control, the musical result is different, because the Score Player receives beat number messages and the Improviser receives beat label messages. The musical result is described in the manual section on improvisation . Following is a description of the abstractions that control these processes.

The Score Player contains two subpatchers, a “Master Clock Follower” and an “Internal Clock Follower.” In Score Player mode, if the Speed Control is active, beat numbers are sent to the Internal Clock Follower. The Internal Clock Follower contains its own Beat Clock object. It is passed the same asynchronous messages as the Master Beat Clock, concerning the song beat data like the end beat, the current section beats, and whether the current chapter is being looped. If the Speed Control is inactive, the beat number messages given by the Master Beat Clock are simply passed through. If Speed Control is active, beat numbers are output at a different tempo than the input tap.

In the Improviser, it is the beat label messages are passed. Beat labels are passed in at the master tempo. When a label is received, it is saved in a message object and a bang is sent to the Speed Control. If active, the speed control at its modified tempo, which trigger the saved label to be passed to the factor oracle player. The result is that the factor oracle player outputs beats that conform to the harmony of the given beat, even though they are at a different tempo.

Factor Oracle and Player

The factor oracle

The factor oracle data structure is described in detail in the following references:

Allauzen, Crochemore, Raffinot. 1999. Factor Oracle: A New Structure for Pattern Matching. SOFSEM ‘99: Proceedings of the 26th Conference on Current Trends in Theory and Practice of Informatics on Theory and Practice of Informatics. pp. 295 - 310

Gérard Assayag, Shlomo Dubnov. Using Factor Oracles for machine Improvisation. Soft Computing, 2004, 8 (9), pp.604-610.

Maxime Crochemore, Lucian Ilie, Emine Seid-Hilmi. The structure of Factor Oracles. International Journal of Foundations of Computer Science, 2007, 18 (4), pp.781-797

Gérard Assayag, Georges Bloch. NAVIGATING THE ORACLE: A HEURISTIC APPROACH. International Computer Music Conference ‘07, Aug 2007, Copenhagen, Denmark. pp.405-412.

Djazz 2.0 uses a pure Max version of the factor oracle, factor_oracle.maxpat .

The factor oracle player

The factor oracle player creates the improvisation. As its name suggests, it contains and makes use of the “factor_oracle” Max abstraction.

The available messages to the abstraction can be seen from looking into the patch:

factor oracle factor oracle

The data structure itself is saved as a Max dict, where each key is an integer representing the beat number. The value associated with a key is the label of the beat.

The Max dict containing the factor oracle data can be accessed by sending the message “dump,” which sends the name of the Max dict out the rightmost outlet.

As with all the data-related patches in Djazz 2.0, no dict name is specific to this patch, and no dict is created or maintained inside this patch (see Handling Data" ).

The method for choosing beats from the factor oracle in a real-time improvisation setting is described in Jérôme Nika, Marc Chemillier. Improtek: integrating harmonic controls into improvisation in the filiation of OMax. International Computer Music Conference (ICMC), Sep 2012, Ljubljana, Slovenia. pp.180-187.

The factor_oracle_player.maxpat abstraction follows the algorithm described in section 3.4, “Constrained Navigation and Continuity,” of the above paper. Its design is as follows:

factor oracle player factor oracle player

When the maximum continuity is reached, it takes a suffix link and searches for a matching label. If no matching label is found, it chooses a random state.

The analyzer

The analyzer uses the same set of symbols (labels) as the factor oracle. It is used both offline, to create a file of labeled beats for a song, and online, to convert the data at the beginning of each beat into a symbol to be passed to the factor oracle player. This label is then used as the query to the factor oracle to produce the next beat. See the next section on labels for more information on the format and analysis of labels in the factor oracle player.

Labels

Definition:

A beat is a collection of notes that occurs between two timepoints. These timepoints are considered to occur at regular intervals. Thus a piece of music that has a pulse can be considered a sequence of beats.

At each new beat, calculate a new beat’s worth of music to play. The calculation consists of finding a beat in the database that is the “best match” (or at least a “good match”) based on the data that exists at the beginning of the new beat.

This data can be based on any of the following:

  1. The location in the song/musical piece. For example, “the A minor 7 chord that occurs at the beginning of measure 13.” A good match is a beat from the database that occurs over the same chord. This could be the same beat as in the original piece, or it could be a different beat that has the same chord, which is more interesting. This creates correct adherence to musical form, if such form exists in the piece.

  2. What we just played in the last beat. For example, an ascending scale in the previous beat could look for a melody that starts on the next note in the scale in the next beat. This creates continuity.

  3. What other listeners have played. This creates responsiveness.

In the current usage of Djazz, this match is based only on option 1: the chord symbol that occurs on the given beat.

Label matching

Matching is done by comparing labels. Each beat has a label which reflects the data described above. It is a string of symbols. The nature of this string is determined by the user. In the current usage of Djazz, this string represents the chord symbol, which consists of the chord root and its quality, separated by an underline. Chord roots are numbered from zero to eleven, with zero representing C; thus, C# (or Db) is 1, D is 2, etc. For example, “0_maj7” represents a C major seventh chord.

A match can be made by exact comparison, or by “fuzzy” methods. In the current usage of Djazz, a chord represents a match if the quality is the same, but the root can be a small distance away from the desired one. The melody is then transposed to match the correct root.

Offline analysis currently consists of adding the chord labels to each beat. The user inputs this using a graphical tool that takes chord information and stores it in a list of beats; that is, no analysis is done save for copying the “chord chart” into a data file. This data file, which also contains other data like the song tempo, time signature, section starting and ending beats, and song title, is loaded into Djazz when a song is played.

Online analysis, as a result, is just a case of reading the chord label from the dictionary when a beat number is generated. This is in fact done by the master clock: it sends out the tempo, chord label, beat number, in immediate succession each time a tap is input.

The methods here are general, and the current usage of Djazz can be changed to admit other types of music. This would involve using an extant system, devising a new one, or modifying an extant one to label beats. Optionally defining the definition of a match, if it is not defined as exact.

The following criteria must be met: The online analyzer uses the same set of labels as the offline analyzer, if an offline analyzer is used.

Also, the architecture is modular, which means that other methods of improvisation are possible. That means that another object can replace the factor oracle player within “improviser” as long as it adheres to the following criteria:

  1. It receives a label at the beginning of each beat
  2. It produces a beat number, in response to the label, that represents the next beat to play.

Example: Song with the same chord for all beats.

In the case where all the beat labels are the same, the factor oracle player algorithm will ground out to simply choosing a measure aleatorically.

In some cases this could be desired. It is perhaps more interesting, though, to take advantage of the label-matching behavior to create one’s own labels, and thus direct the improvisation.

Following the description of the matching criteria, the first half of the label must be a chord root symbol, but the second half can be anything: it will be matched by exact string matching.

A song with beats labeled thus:

E m7E m7E m7E m7E m7E m7E m7E m7
E m7E m7E m7E m7E m7E m7E m7E m7

courld be written as

E 1E 2E 3E 4E 1E 2E 3E 4
E 1E 2E 3E 4E 1E 2E 3E 4

which would always select a measure labelled with a 2 to follow a measure labelled with a 1, a 3 to follow a 2, etc. Like this, formal positions in sections could be preserved.

E aE fE dE cE aE bE aE b
E dE fE cE 4E 1E 2E 3E 4

Djazz supplies a software framework for empirical inquiry into the suitability of a particular data encoding for music: ascertaining the “correctness” of an analysis via listening to the resulting synthesis.