Demonstration 10 provides the practical component for Chapter 14: “Constrained Search” of my unpublished textbook on composing programs. It illustrates the use of constrained searches in a full-fledged composing program which applies the principle of bottom-up design. The composition produced by this program is a study in what Robert Erickson (1975) terms “perceptual channeling”, that is, the mechanism by which listeners perceive disjoint musical events as components of an ongoing process, or “channel”. In Demonstration 11, the major factor contributing to channeling is register, although the fact that each pitch constantly associates with a fixed group of partners also plays in important role.
The compositional process divides into four stages of production:
As happened in Demonstration 10, the present Stage II induces the form of Demonstration 11 from the ‘bottom up’ on the basis of qualities inherent in material composed during Stage I. Information from Stage II enables Stage III to describe all of the notes in the piece to the extent of rhythms and cell numbers. Stage IV completes the process by filling in inflections.
Stage I generates the material of the piece, which consists of eight melodic cells. Figure 1 depicts the products of this stage. Each cell consists of three ‘inflections’ of a register: low, middle, and high. These ‘inflections’ are realized by chromatic pitches spaced no farther apart than a whole tone. The material has the following properties:
Curved brackets in Figure 1 indicate semitones; square brackets indicate whole tones.
The piece consists of 18 segments. Stage II of the composing program assigns cells to segments. Eight segments draw material from one cell only; five segments draw material from two cells simultaneously; three segments draw material from three cells; and the remaining two segments draw material from four cells at once. Since the effect is of implied counterpoint, it will be appropriate to use the word ‘part’ to distinguish between cells simultaneously exploited in a segment. It will also be appropriate to refer to the various segments as ‘solos’, ‘duets’, ‘trios’, and ‘quartets’, depending upon the number of parts involved.
The constraints governing selection of cells for segments are:
Stage III selects period between consecutive attacks by direct random selection using John Myhill's variation on exponential distribution, fixing the ratio of maximum to minimum durations to 8.0. The upper graph in Figure 2 details the average period between attacks for each segment. Notice that this average decreases (equivalently, the density of notes increases) as the amount of available material rises.
The program selects cells using cumulative feedback leavened by randomness. This procedure allows unpredictable short-term choices while balancing cell-usage out over the longer term.
Articulation is sensitive to whether or not a note's successor shares the same cell:
Stage IV of the the composing process selects for each note which of the three registral inflections available to the cell specified in Stage III will provide the pitch. The program attempts to keep these inflections in balance by employing cumulative feedback to favor the least-used inflection of any cell. It also forbids any cell from repeating an inflection without in the meantime stating at least one of the cell's two alternative inflections.
Since the type of harmonic connections suggested by inter-cell consonances would contradict the central motivations of the piece, the pitches in Demonstration 11 adhere to a dissonant style. As a minimum precaution against cross-channeling, the pitch-selecting program avoids virtual octaves; that is, when one cell plays a chromatic degree shared by a second cell, at least one of the two cells must play a different degree before the second cell may use the shared degree. In addition, consecutive notes must obey the stylistic matrix illustrated in Figure 3. Unlike stylistic constraints employed for previous Demonstrations, the present program skips over chromatic identities in order to apply this matrix to the first two distinct degrees immediately preceding the current note.
Columns in Figure 3 indicate current chromatic intervals given the most recent interval indicated by the row. Non-blank entries show acceptable intervallic sequences.
The end-product of stages I-IV is shown in Figure 4.
The following explanations seek to illustrate constrained searches in play. The explanations are peppered with line numbers, but you are are by no means expected to chase down every line of code. Rather, you should follow through with line numbers only when you have a specific question that the narrative is not answering.
DEMO11 proper appears as Listing 1; the
routine used to initialize
COMMON memory variables appears as Listing 2.
The program which assigned pitches to cells (Stage I) will not be documented, but it too employed
the constrained search strategy.
After some initialization work, the body of program
DEMO11 simply calls out to two subroutines, each of which implements a stage
The call to subroutine
FORM in line 17 executes Stage II, which assigns cells
The call to subroutine
RHYTHM in line 18 executes Stage III, which composes
all of the notes in the piece to the extent of describing periods, cells, and articulations.
RHYTHM stores its intermediate results to the file named “DEMO11.RHY” for later processing.
An independent run by program RHYTHM picks up data from file “DEMO11.RHY”
then executes Stage IV, which selects cell-inflections (pitches) for notes and writes out a human-readable
listing of the completed product.
Listing 1: Program
The source code for subroutine
FORM appears in Listing 3 (a) and
Listing 3 (b). This subroutine implements a constrained search which selects from one to
four cells for each segment. The initial data resides in two arrays: array element
NUMSEG(ISEG) holds the number
of parts in segment
ISEG while array element
DURSEG(ISEG) holds the segment's duration in sixteenths.
These two arrays are populated in lines 6-8 of the
BLOCK DATA routine.
Listing 3 (a): Subroutine
Listing 3 (b): Subroutine
FORM stores and accesses cells for each part in each segment by employing arrays
LIMSEG along with the following indexing scheme: Cells selected for the
Ith segment reside in elements
CELPRT. Lines 10-16 of program
proper initialize the relative positions stored in
LIMSEG from the cell counts stored in
The variable IPRT serves as the recursive index and as a pointer to the part and segment currently under consideration. Notice that
FORM does not reset
IPRT to 1 when it advances to a new segment; referring to Figure 2
IPRT=2 for segment 2, part 1;
IPRT=7 for segment 5, part 2; and so on.
Since a cell may appear no more than once within any segment,
FORM derives one schedule of cells for the whole segment.
It then proceeds to allot cells to parts by sampling this schedule without replacement. Array element
holds the cell scheduled
Jth in line for the
Ith segment; array element
which position in the schedule is currently being considered for the segment and part accessed by index
the actual cell number resides in array element
CELIDX(IDXCEL(J),I). Sampling without replacement is
enforced by maintaining
IDXCEL(LIMSEG(I)) in strictly increasing order (due to
line 137 of
Prior to the search, program
DEMO11 proper computes for each segment the portion of the segment's duration which the
program expects to devote to the individual parts (line 15 of the loop spanning lines 10-16), storing this value in the real
CUMCEL maintains statistics of cumulative usage for each of the eight cells.
Each time it selects a cell,
FORM increments the appropriate element of array
INCSEG(ISEG). Calls to the library subroutine
effect random scheduling with a strong bias —
the offset of 1.0 falls far short of the smallest value stored in
INCSEG — toward the least-used cells (lies 38 and
The bulk of subroutine
FORM imposes the constraints upon the search.
LGLCELinitialized in lines 11-18) in order to determine whether or not the cell currently under consideration is compatible with this earlier commitment.
FORM encounters a configuration which proves nonviable in the light of choices made for an earlier segment,
it updates the backtracking variable
FORM scrupulously considers every possible configuration
of cells for the current segment until either it discovers a workable arrangement or it runs out of combinations. In the latter case,
BAKSEG provides the most recent segment responsible for any conflict.
RHYTHM is listed in Listing 4. This subroutine
implements Stage III of compositional processing, which selects periods between consecutive attacks,
which selects cells for notes, and which selects articulations.
The main body of subroutine
RHYTHM consists of an outer loop (lines 32-94) iterating once for each of the
18 segments and an inner loop (lines 38-86) iterating once for each note in a segment.
RHYTHM selects periods between consecutive attacks (lines 40-42) via the library function
Average periods are drawn from array
AVGNUM (initialized in line 8) and depend upon the number of parts in the
The subprogram selects cells (lines 44-65) using the methods of the library subroutine
DECIDE. At the end
of each segment,
RHYTHM steps through the active cells, subtracting each cell's ‘expected’
SUM*INCCEL(ICEL) from the actual value
CUMCEL(ICEL) (lines 86-91). This
procedure insures that if a cell has received its fair share of note durations within a segment, it starts out fresh in the next
segment; however, when cells have been either slighted or overindulged,
RHYTHM retains awareness of such
imbalances and acts to compensate for them in later segments.
Articulations (lines 67-72) must be selected one step behind in the process since how a note connects to its successor depends on
whether the successor exploits the same cell or a different cell.
RHYTHM selects articulations by asking the library
SUCCES to conduct Bernoulli trials; array
ARTIC (initialized in line 8) controls likelihoods that
two consecutive notes sharing identical cell numbers will be slurred; this likelihood depends on the number of parts in the current segment.
PITCH is listed in Listing 5 (a). This routine runs independently
implements Stage IV of compositional processing, which selects cell inflections (pitches) for each
note in the piece.
Listing 5 (a): Subroutine
Listing 5 (b): Subroutine
PITCH organizes data pertaining to individual notes in several parallel queues. Each queue is
distinguished by the root abbreviation
QUE; the following abbreviated prefixes signify
information read by subroutine
RNOTE (see Listing 8) from the intermediate
TIM— Starting time in sixteenths.
PER— Period to next attack in sixteenths.
DUR— Duration of note in sixteenths.
CEL— Melodic cell (1-8).
SEG— Segment (1-18).
Listing 8: Subroutine
Listing 9: Subroutine
RNOTE creates three additional items of data per note.
Two items, a backward link
OLDQUE and forward link
to access notes quickly when it needs information pertinent to specific cells. Figure 5 illustrates
the linked structure derived by
RNOTE for an actual sequence of notes read in from “DEMO11.RHY”.
Pointers to the head of the backward list for each cell reside in the auxiliary array
OLDCEL. The third item
RNOTE, a decision count
CNTQUE, indicates a note's position in the
absolute sequence of decisions; this information assists the backtracking mechanism.
Each row of numbers in Figure 5 signifies a note; the left network of arrows shows backward links while the right network shows forward links. The information depicted in Figure 5 describes the portion of Figure 4 beginning with the second quarter of measure 14 and ending after the fifth sixteenth of measure 28.
Listing 6: Function
Listing 7: Function
The head and tail of the queue are indicated by the integer variables
IQUE serves as the recursive index and also locates the note currently under consideration.
The integer functions
IADV (Listing 6) and
IRET (Listing 7)
handle the wrap-around arithmetic necessary to keep this and related indices between 1 and the queue-size
NFLQUE(IDXNFL(IQUEU),IQUE) holds the inflection under scrutiny;
dereferences this value into the holding variable
DEGNFL (populated in lines 25-26)
supplies the chromatic degrees illustrated in Figure 1 for each inflection in each cell;
PITCH dereferences the current note's degree from array element
the holding variable
IDEG are also stored in queues of their own for easy
PITCH selects an inflection for a note, the subprogram increments the appropriate element of array
CUMNFL by the duration of the note. Calls to the library subroutine
SHUFLE in line 49 and line 120
suppress scheduling bias through random shuffling. Calls to the library subroutine
ISORT in line 50 and line 121
sort the schedule of inflections so that the least-used inflections are favored.
The constraints controlling how degrees of the chromatic scale may recur are greatly facilitated by the linked structure illustrated in Figure 5:
PITCHinitiates its test for inflections repeated immediately within the same cell (lines 65-69) by locating the most recent note exploiting the same cell through array
OLDCEL. The test then reduces to simply comparing inflection numbers.
OLDCELto locate the other cell's most recent note. If both notes share the same chromatic degree and if the current cell has no intervening note, then the program rejects the current inflection.
LGLTVL(populated in the
DATAstatement spanning lines 14-24). in order to determine if the intervallic sequence is suitable.
The backtracking mechanism for program
PITCH first consults array
BAKQUE in order to determine the
source of an immediate conflict. Sometimes the subprogram approves all of the inflections considered for a note, only to propagate
impasses at later notes in each instance.
PITCH was unable to supply information for dependency-directed
backtracking in such cases, so the subprogram was forced to grope back note-by-note
in order to pinpoint the source of conflict empirically.
|© Charles Ames||Original Text: 1984-11-01||Page created: 2017-03-12||Last updated: 2017-03-12|