Theses
Thesis/Dissertation Collections
1992
Computer improvisation of jazz solos
Daniel Chen
Follow this and additional works at:
http://scholarworks.rit.edu/theses
This Thesis is brought to you for free and open access by the Thesis/Dissertation Collections at RIT Scholar Works. It has been accepted for inclusion in Theses by an authorized administrator of RIT Scholar Works. For more information, please [email protected].
Recommended Citation
This thesis
discusses
the possibilities of using acomputer to create Jazz solos. Various
implementations usingstochastic and rule
based
approaches were created and applied toanalyze
the original melody as well as the chord
progressions. Based on the melodiesgenerated,
a rule-based approach that considered the
original melody and the chord progression was
found
to produce the most"musical"
1
.0Introduction
andOverview
3
2.0 Background
-Approachesto
Computer
Composed
Music
4
2.1 Historical Approaches
4
2.2 A Stochastic Approach
8
2.3 An Approach using
Binary
Trees
13
2.4
Computer Jazz Improvisation
16
2.5 Background Conclusion
19
3.0 Implementation
20
3.1 Level 1 Low Level Functions
21
3.2 Level 2 Music
Theory
Functions
27
3.3 Level 3 High Level Functions
37
3.4 Level 4 Improvise
52
3.5 User Interactions
55
4.0 Results
59
1.
Introduction & Overview
The
originalidea
to write a thesis todeal
with music originated with a classassignment
dealing
with the role of aknowledge base
engineer. The job of theknowledge base
engineer is to query an expertfor information
to gather enoughbasic
rules andfacts
to create an expertknowledge base.
Theknowledge base
inthis case
dealt
with"improvising"
jazz
music.During
thequerying
process theexpert gave the opinion that
he felt
it was veryunlikely
a computer could everproduce
any kind
of music. This opinion on computer composed musicbecame
thebasis
ofthisthesis,
an attemptto programa computerto"improvise" music.Richard Kram
has
aninteresting
belief
that"Musicians
make goodProgrammers"
[Kram85].
He goes on tohypothesize
that this isdueto thefact
thatboth
music and computer programs are normallylinear
processes. Amisplaced notecould ruin a musical phrase, and a misplaced computer instruction can make a block
of code useless. Both composers and programmers must deal with measurements
subjectively. When
does
a piece of musicbecome
boring
or redundant? Whendoes
a computer program
become
unstructured or inefficient? If both composers andprogrammers must
find
and correct errors in their works, cana programmerbuild
aprogramtowrite code?
Many interesting
questions and issues arise whendealing
with computercomposed music. A group of notes organized randomly may be considered noisy
and chaotic, not musical. A group of notes organized in a simple repetitive pattern
may be
considered tooboring
and also not musical. Wouldsomething between
arandom and a constant pattern
be
considered music? A computeris
well suitedfor
reproducing
patterns, and pseudo-random behavior canbe
simulated with acomputer, too. But can a computer compose good music? The
quality
of musicis
series of notes qualifies as music? This thesis will not attempt to answer this
problem,
but
it will make an attempt atproducing
musicthatlisteners
can judgefor
themselves.
This
is
a thesis thatdeals
with the creation of Jazz solos through the use of acomputer. The software
for
the thesis was written inProlog
with aknowledge base
containing
elements ofbasic
musictheory
with rules todevelop
a solo. Part of thebackground
section willdescribe
other systemsthathave
created musicthrough theuse ofcomputers, and the next section
describes
in more detail several systems thatused computers to compose music. The final
background
section willdescribe
basicassumptions that the thesis makes. Section
3,
on theimplementation,
describes inmore
detail
thestructures ofthecode and it's interactions. Section 4will contain theresults. The result section contains a comparison of several improvised songs. Astep
by
step example of one song is also contained in the results section. Thefinal
section, section
5,
is
the conclusions. In this section, a description of the overall2.0 Background
-Approaches
to
Computer
Composed
Music.
This
document
was written with the assumption that the readerhas
somebasic knowledge
of musictheory
and theProlog
computer language. A briefdescription
of musictheory
is presented in AppendixA,
and a more in-depth view ofmusic
theory
canbe found
in a standard musictheory
book [Benw83].
Section 2.1 will
briefly
describe
severalhistorical
approaches to computercomposed music. A more
detailed description
of systems that use a stochasticapproach
is
provided in Section 2.2. Aninteresting
method of usingbinary
trees tocreate a simple melody is
described
in Section 2.3. Section 2.4 describes a thesissimilar to this one, which attempted to use a computer
for
jazz improvisation. Thefinal
section 2.5 istheconclusionforthisbackground.2.1 Historical Approaches
This section will
briefly
describe several previous attemptsatusing computersto create a melody. It is included to give the reader a
"flavor"
of what
has
beenaccomplished.
Many
music scholars have tried to use computers as an aid to musictheory. This research has
been
dominatedby
statistical techniques. Some countthenumber ofB
flats
orthe number oftimes a major third occurs in ordertofigure
outa musical style [Road85]. Such a statistical profile, combined with common patterns
inother pieces,can be used as a rather limited method for constructing music.
Ebcioglu
[Ebci84]
developed a knowledge-based expert system to generatechorales in the style of J. S. Bach. The chorale program is written in BSL
(Backtracking
SpecificationLanguage),
and is based on a direct compilation of aformula
taken from first order predicate calculus.Currently
the programonly
harmonizes
an existing chorale melody. The knowledgebase
contains 190rules andpersonal
intuitions.
The system generates choralesfrom left
to right,backtracking
until a solutionthatsatisfies all theconstraints is
found.
Another
early
attempt at music composition wasdescribed
by
Olson-Belar[Hill70].
Theircomposing
machine used signal generators to generate randomnumbers, which were
fed into devices
that assigned weighted probabilities tocontrol the pitch and rhythm of the composition
being
generated. Inputsfor
theweights were taken
from
1 1 Stephen Foster tunes. These tunes were transposed to D majorsothat the probabilitysampleofpitches covered a greater range of pitches.First,
second, andthird orderfrequency
countsof pitcheswere gathered and appliedto the weighting. Olson and Belar
actually
reproduced one of the original elevenStephen Foster tunes with this
device,
whichdemonstrates
that the basic music structure canbe
generatedbased
upon probability.Brooks, Hopkins, Neumann,
and Wright[Hill70]
provided a more substantial work on the applicability of stochastic models in both the analysis and synthesis ofsimple music. Theauthorsstatisticallyanalyzed 37 hymntunes uptoan eighth order
approximation. The tunes were constrained such that
they
all had tobe
in C majorand in a common meter. The various transition or interval
frequencies
were used intables
for
transition probabilities for creating new tunes. The probability of atransition depended on the transition before the current transition. Random
integers
were generated and screeneddepending
on howthey
fit
against theprobabilities. A "try-again
routine"
was used to rewrite unacceptable passages. Their results showed that if the order of synthesis is too
low,
the note sequences were not typical of the sample analyzed. If the order of synthesis was toohigh,
duplication of the original sample would occur. A point inbetween
the two extremes of synthesis resulted in tunes thatwere recognizable members ofthe classfrom
which the sample was drawn from. The best level of synthesis seemed tobe
Bakeranalyzed selected musical passages
from
Haydn, Mozart,
andBeethoven,
andfound
thatlower
orders of analysis and synthesismay be
sufficient if a simpleenough stochastic model
is
used.A survey reported
by
Hillerdescribes
a generative approach to music[Hill70].He
describes
three goals that a program musthave
to generate music: a scientificverification of a music
theory
(simulating
aknown
style);producing
an object ofaesthetic interest
(original
composition); and recreational value(colloquially
referred to as
fun).
Stylehas been
approachedby
gathering
statistical data on aspecific composer. Original composition
has been
attained through the use ofrandom numbertables. I
feel
the recreational value is attained through completing the task anddemonstrating
it to others. Most ofthe work in computer composedmusic seems to
be based
on a gatheringdata
on a specific style and applying astochastic approximation of different orders of approximation. The methods
described
inthenextsections also usethestochastic processtosomedegree,
but
also2.2
Stochastic Approach
This section will
describe
in moredetail
several systems that use a stochasticapproach. The
first
methoddescribed
willbe
an approach using stochasticapproximation.
Following
that,
willbe
several methods that use structures tofurther
constrain thestochasticapproach.As stated earlier, musicmay
be
createdby
randomlygenerating
alist
of notes.Mozart
supposedly did
this using dice[Bate80]. One proposed method describedby
Bateman
[Bate80]
first
generates random numbersfrom
-12 to12,
whichrepresented
intervals between
successive notes. A series of notes isthen generatedfrom
the intervals. A table was created that weighted thedesirability
of differentintervals,
where short and consonantintervals
were given a heavier weight thanlonger
intervals. The melodies generated with this process were not be veryinteresting
to most people.Instead of weighting intervals on how short or
long
they
are, one could basethe weighting on a more desirable interval
having
aheavier
weighting, and a lessInterval
Number Relationship -12 - Octave
-11 - Majorseventh
-10 - Minorseventh
-9 - Majorsixth
-8 - Minorsixth
-7 - Perfectfifth
-6
-5 -Perfectfourth -4 - Majorthird
-3 - Minor third
-2 -Wholestep -1 -Halfstep
0 Unison
Probability Interval
Probability
ofSelection Number
Relationship
ofSelection3% 0 Unison 4%
1% + 1 +Halfstep 7%
2% +2 +Wholestep 6%
3% +3 +Minor third 5%
3% +4 +Major third 4%
7% +5 +Perfectfourth 6%
1% +6 +Tritone 1%
6% +7 +Perfectfifth 7%
4% +8 +Minorsixth 3%
5% +9 +Majorsixth 3%
6% +10 +Minorseventh 2% 7% +11 +Majorseventh 1%
4% +12 +Octave 3%
Figure 1 Example ofprobabilitydistribution
function
desirable
intervalhaving
less
weight. Figure 1 shows one such possible intervala greater weight than a
less desirable interval
of a tritone or a major seventh. Thismethod of
constraining
the note selectionmay
produce abetter
melody, but it stillneeds more structure.
Selecting
notesby
this method is termed"first
order"because
the noteselected is
dependent
on only one parameter(the preceding
note.) Asecond ordersystem can
be
used to create more structure andfurther
constrain a random notepattern. There are manyways a second order system can
be
constructed. The notecould be selected
by
the preceding two notes; or as Bateman suggests, the intervaldetermines a set of 10 possible
functions
that are used to determine the next note.For example, a tritone intraditional music is usually
followed
by
a stepwise interval.The stepwise interval then will
be
given ahigher
ratingfor
that next note. Thisprocess of selecting notes can
be
considered a stochastic process and can becontinued to a third order,
fourth
order, etc. process. To make it moreinteresting,
exceptions could
be
incorporated. For example, no more than three consecutiveleaps
or no more than four consecutive alternating ascending anddescending
intervals could occur in a row. Another possibility is to incorporate a small routine
thatwould selectthe next set ofintervals.
Another method ofviewing thiswould
be
to usea Markov Chain asdescribed
by
Jones [Jone81]. Jones defines a stochastic process as a collection of randomvariable quantities distributed in space or time. Computer music systems usually
require specific information of all the parameters relating to a sound. This may
be
much more information than what is in a musical score. Stochastictechniques offer
a useful means of
data
reduction.Defining
parameterlimits
on the actual valuesthat are generated stochastically can significantly reduce the amount of work
required. Composer usuallyrely on a
performers'
interpretations
for
thefine
controlof parameters like
intonation,
duration,
timbre, and intensity.Stochastic
techniquesone to
break
thelimits
ofimagination.
Jones used a randomdecaying
function togenerate random numbers. In
composing
Firelake,
a randominteger
generatorwasused to call itself recursively in the
form
ofRAND(RAND(N)).
Thefunction
RAND(N)
returned a random
integer
from
1 toN,
so when thefunction
is called recursively,thewhole
function
will produce numbers weighted toward 1. When these numbersare applied to events, event e1 will occur most often, while, event e2 will occur
less
frequently. If the events were pitches, it allows the pitches generated to be built
around a quasi-tonal center.
Using
this method ofgenerating
numbers, Jonescombined this using Markov chains as
acontrolling
mechanism. This issimilar to themethodthat Bateman suggests,
but has
more of a structurethan thefirst
order noteselection
described
inthe previous section.A Markov chain takes into accountthe context of an event in a sequence and
makes the probability of
its
occurrencedepended
on the event that preceded it.Basic properties of Markov chain events are commutative, reflexive, symmetric,
transitive,
recurrent, and transient. A recurrent event is onethat may happen againafter it
has
occurred. Atransient event is one that will not recur. Figure 2 shows astochastic matrix of a Markov chain of order eight. Event e2
has
a 100% chance ofoccurring ifthe previous event was e1, but ifthe previousevent was e2, there is only
a 50% chanceof evente2occurring.
Next Events
e1 e2 e3 e4 e5 e6 e7 e8
Current e1 0 1.0 0 0 0 0 0 0
Events e2 0.5 0.5 0 0 0 0 0 0
e3 0.1 0.1 0.4 0.4 0 0 0 0
e4 0 0.2 0 0 0.8 0 0 0
e5 0 0 0.5 0.5 0 0 0 0
e6 0.1 0 0.1 0 0.1 0.7 0 0
e7 0 0 0 0 0.4 0 0.3 0.3
e8 0 0.2 0
Fi 0.2
igure 2
0 0 0.6 0
An event relation
diagram
of the matrixin Figure
2 is shown in Figure 3 toFigure 3 Event Relation Diagram
help
visualizethe structure. In thisdiagram,
evente2 is shown ashaving
two arrowsexiting
from
evente2. Thearrowto e1has
a 50% chance ofoccurring andthe arrowback
to itselfalsohas
a 50% chance of occurring. Each event isthen associated witha note sequence. Figure 4 shows three possible event sequences that might
be
generatedfrom
the matrix. Sequence S1 starts with event e6. Event e6 shows thepossibilityofevents e1, e3, e5, ore6 of occurring. In this case evente6 occurred
first,
from
thesecond event e6, evente3 occurred. From event e3, events e1, e2, e3, or e4S1=e6e6e3 e3 e4e5e5 e4e2 e2e1 e2e1 e2 e1 e2 e2 e2
S2=e6 e6 e6e6 e1 e2 e1 e2e1 e2e2 e1 e1 e2 e1 e2 e1 e2 e2
S3=e8e4e2 e2e1 e2e1 e2 e2 e2e2 e1 e2 e2 e1 e2 e1 e2
Figure4Several Possible Event Sequences
could occur. The Figure 5 shows how an event may
be
associated with a notesequence. Figure 6 then shows howthe
first few
events in sequence S1 wouldlook
like
as an actual note sequence. A Markov chain structuremay be
used uponanotherto increase the order of the Markov system. So the events e1-e8 could
be
j.
fi
e,e2
e3
e4
e5
e6
e7
e8
Figure 5Possible Note Sequences for Events
S1 =e6e6e3 e3 e4e5
i
jfji
/
j
^1
Figure 6Partial expansion of sequenceS1
big
eventEn,
or a sub event e9 couldbe
created which proceeds to somebig
eventthat
follows
big
event En. This would in turn change eventsfrom
scalar values tovectors and eventually to a
finite
state grammar. Markov chains maintain a rigidstructure,
but
still use a stochastic approach. The next section will describeanother2.3 An
approach
using
a
binary
tree
Richard
Kram[Kram85]
describes
aninteresting
method which usesbinary
trees. Kram's method uses a set of triads to generate a melodic pattern.
First,
themethod of
storing
willbe
described;
then a process ofcreating
a melody willbe
discussed.
In Kram's example, two
alternating
triads a step apart are used(Fig
7a). Thenotes of
both
triads arestrung
out in alinear
representation(Fig
7b). Thelabels
F8 D8 Bb8 Eb8 G8 C8 C9
Twotriadsa stepapart
Figure 7a
Triadsseparated intoa sequenceofnotes
Figure 7b
below each note in
figure
7b represent the note name and the octave, where anoctave change occurs
from
the note Bto the noteC. Thenotes arethen selected andplaced
into
abinary
tree,
suchthattheleft
child isof lower pitchthan the rootoftheRootoftree Figure 8a
D8 Lower pitchthan F8 Figure 8b
Bb8 Higherpitch than F8 Figure8c
tree and the right child is a
higher
pitch than the root. In the example given, F8thefirst
note is used as the root of the tree(Figure
8a). The next note D8 is oflower
pitch so it is placed in the
left
child of the tree(Figure
8b). The next note Bb8is
sequence and
final
treeis
shown inFigure
9 There arelimitations
in thisbinary
Triadsplaced in a
binary
tree Figure 9tree representation of storage. One
limitation
mentionedby
Kram is thelack
ofability to store two notes of the same pitch. Another is that the original note
ordering
islost.
The process of creating the melody is dependent on
how
one selects the treetraversal. The three most obvious methods would be either an inorder:
left,
node,right;
(Fig
10a),
preorder: node,left,
right;(Fig
10b)
or postorder:left,
right, nodetraversal
(Fig
10c)
of thebinary
tree. Other methods of tree traversalmay
produceinteresting
patterns, too. Anotherway to traverse a tree isto unwind it. It is mucheasier to visualize this as
first
selecting the leaves of the tree andcontinuing
uptothe root as the
leaves for
that depth of the tree are used(Fig
11). A separate treewith a set of transposed notes could
be
used to create aharmonic
variation.Since
obfr o
Fig
10a Inorder=5S
bb^P
Fig
10b Preorder>6^
OO IjQ
Fig
10c PostorderFig
11Unwinding
the treeharmonic
variation will notbe
discussed. Another method that may reduce themodal sound would use notesthat were not in the
first
tree toform
a second tree.The notes would
be
selected alternately between both treesto generatethe melodicpattern. The resultant set of notes may create an odd combination of
both
chromaticism and modality. More patterns may
be
createdby
channeling
theoutput ofthe currenttree into a new tree and
traversing
thattree. There aremany
2.4 Computer Jazz
Improvisation
Itwould
be
much more useful ifthe computer could make connections withinthe music, in a sense understand music structure and
build
on it. Ifeel
David Levittcame
very
close todoing
this. Levitt's mastersthesis[Levi81] deals
with JazzImprovisation. The program can
be broken
down intotwoparts. Thefirst is
a simpleanalysis ofthechord progression, and the second
is
the melody.The chord progression is analyzed to
determine
a progression of modeswhichare used to
determine
consonance against which the melody is analyzed. Themelody is
divided
into phrases and ranked onhow
well it canbe
usedfor
improvisation material. The chords providea
framework
toanalyze the melody andproduce improvisation. Each chord is analyzedto
determine
intowhich modes itfits.
When a chord changes,a minimal motion criterion is applied. The minimal motion is
defined
such that the previous mode is retained unlessthechord givesevidencethatthe mode
has
changed. This is noticed when just one of the tones in the chord isdissonant
withtheprevious mode. This newtone isthoughtofasthedisambiguator
for
the new mode and it will direct a transition to the nearest mode consonant withthat chord. Figure 12 shows how a change in one note affects the current mode. If
two or more tones differ
from
the previous mode or if the previously mentionedalgorithm
fails
a new algorithm is used. The program detects this as a"discontinuous
modulation"andthe program usesa "typical
progression"
heuristic.
A
discontinuous
modulation to an asymmetric chord is assumed tobe
a progressionforming
a new"well known
chord progression". This wouldbe
known assomething
like
the"2
5 1" chord progression.After the chords are analyzed
for
their mode, the melody mustbe broken
upinto
phrases. Levitt simply breaks up the melody at two measureboundaries
for
Figure
patterns that can
be
repeated. The lasttwo measures ofthe initial melody are usedto startthe solo. After this phrase, a new melodic material will
be
generated. Thevariation the program appliestothetheme is
based
on an algorithm thatlooks
forafeature
and then produces a given pattern. An outline of Levitt's variation-makingscheme isshown in
figure
13.FEATURE RepeatedPitch
Leap
>Fifth ScalewiseINHERITED PATTERN Contour
Interval-size
chord-Degree(all
Modal)
Unresolved Dissonance Modeand Chord consonance patterns Uniform
features
Else
Repeatuniform
features
ContourFigure 13
The
first feature
canbe
thought of as if a repeated pitchis
recognized, therepeated pitch pattern
is
inherited too. The secondfeature
duplicates
theinterval,
but
not necessarilythedirection ofthe interval. So ifthe interval is a minor seventhfeature is described
as ainterval
of a major second orless.
In this case, the inheritedpattern
is
a parallel motion with respect to the chord root. If an unresolveddissonance is
present, the patterns of mode and chord consonance are inherited.Dissonances in music are apparent to
listeners
and provide a strong parallelframework. Ifall the previous
features
fail,
the program seeksfor
generalfeatures
whose imitation might
keep
the solo coherent. What the programlooks for
ispitches that are all chord consonant, intervals that are the same size or within a
minor
third,
and a uniformascending
ordescending
interval over the whole phraseratherthan a particular note. If one ofthese
features
is recognized the variation isconstrainedto inheritthesame
feature.
If noneofthese are recognized, theoriginalrhythm and general direction ofthe pitches is still inherited. The recognizers
do
nothave
tobe found
asthenext sectionwillfurther
constrainthe solution.The previously
described
algorithm may notfully
constrain a pitch. If it doesnot, another set of rules is applied to the note. The program next applies the
following
rules inthe order shown(Fig
14). If a rule is applied and no optionsresult,Leaps largerthana Fifth (with respectto the neighbor)
Pitchescloseto theedge ofthe instrument range The neighbor pitch itself (i.e. avoid repeated pitches)
Leaps largerthana Major3rd Pitchesdissonantwiththe mode
The neighbors otherneighbor, if known
Leaps
largerthan a Major 2nd Pitchesdissonantwiththe chordLeaps largerthan a minor2nd. Figure 14
that rule
is
ignored and the nextis
tried. When the option restrictionhas been
performed, there still may
be
more than one pitch which satisfies the constraints. The programwill then choosethe pitch which isclosest in pitch withtheneighboring
there
is
nojustification for
this.Levitt
also mentions that this algorithmis
not verycomplicated, and
lacks
noisesources,but it is
motivatedby
theory.2.5
Background
conclusion
My
thesis willdeal
with a program that willbe based
on oneform
ofcontemporary Western
music, Jazz. The note relations willbe
based on a well-tempered 12-tone scale. Time willbe
in common(4/4)
time,
and a maximum of 2chord changes per measure can occur.
They
willbe
on the 1st and 3rdbeat
ofthemeasure.
Harmony
will notbe dealt
with,but
provisions maybe
made to allowrhythm. The notes producedwill all
be
ofconstantduration.
Inputs to the
knowledge
base
such as chord progressions,desired
notepatterns, etc. will
be
required. A set of note patterns willbe
extractedfrom
at least two of thefollowing
tunes: Now's TheTime,
YardbirdSuite,
Don't Get AroundMuch
Any
More,
Lady
Bird,
All the Things YouAre, Four,
BlueBossa,
A Night inTunisia,
and Green Dolphin Street. The music then will be analyzed toform
thedetails
of the implementation. The solo will notbe
generated in real time. Theknowledge
base
will not generate anykind
of rhythm.Song
length willbe
eithertwelve or thirty-two measures in
length,
which canbe
repeated as many times asnecessary. The harmonic progression, which
forms
an outline of the composition,alreadyexists asthe chord progression taken
from
a standardfake
book. The chordsare
limited
tofive
chord types: major, minor,dominant,
half diminished
and diminished. The final output willbe
a list of notes. If time permits an attempt will3.0 Implementation
Ageneral
layout
ofthe softwareis
depicted
in thefollowing
diagram(figure
16). It
is
brokendown into
4different levels:
Level 1being
thelowest,
and Level 4Level 4 3.4 Improvise
Level 3 3.3.1 Input Routines 3.3.2.1 Weighted Notes 3.3.2.2 Random
By
Mode 3.3.2.3Binary
Tree 3.3.2.4 Rule Based 3.3.1 Output Routines 3.3.3 Progression Level 2 3.2.2Basic Music& Basic Note Functions 3.2.1
Music Relations & Rhythm
Level 1 3.1.1
Music Symbols
3.1.2
General Functions
3.1.3
Music Environment
Figure 1 5software layout
being
the highest level. Within each level are one or moreblocks,
each of these blocks corresponds to one or more software modules. This chapter is divided intosections corresponding to these levels and blocks. In addition to these sections is a
section which describesthe user interactions. Each block depicted in thediagram is dependent on the block below it. So the
blocks
labeled RandomBy
Mode,
Binary
Tree,
and Rule Based are all dependent on the block labeledProgression,
but the block labeled Output Routines does notdepend
on Progression. The numbersindicated in each block representthesectionthatdescribesthat block.
Terminology
and verbiage used in this section is described in the glossary. In
Prolog,
symbolsmust begin with a lower case letter. Examples in the
following
section willfollow
this rule. Words
beginning
in uppercase represent variables, as this ishow
they
are3.1
Level
1
Low Level
Functions
Level 1 corresponds to the
lowest level functions.
These are usually symboldefinitions,
genericprolog
functions,
constants, and otherdata
thatmay
effect theoutput,
but does
not affect the process. Level 1 isbroken down
into three sections,titled Music
Symbols,
General
Functions,
and Music Environment.3.1.1
Music
Symbols
The music symbols module
determines how
some of thedata
atoms arerepresented
internally
andhow
they
are inputted. Listed below are afew
of thesymbols and a
description.
note_symbols(xtA/ote/Vame,
IntNoteName,
NextlntNoteName, HSDist)
Converts the input note name to the symbol used internally.Currently,
each input note maps to the same internal symbol. ExtNoteNameis
the symbol the user would typefrom
the keyboard. IntNoteName is the symbol that is represented internally. NextlntNoteName is the symbol thatfollows
the IntNoteName inascending
orhigher
pitched order. HSDist isthedistance
inhalfsteps
between
IntNoteName and NextlntNoteName.Adding
a newtypeofnote
is
as simple asadding
another note_symbols rule. The order isdependent
in thedatabase.
Thefirst
rulelisted
under note_symbols isassumed tobe
the start of a new octave.rest_symbol
(ExterhalSymbol,
InternalSymbol). sharp_symbo\(ExternalSymbol, InternalSymbol).i\at_symbo\(ExternalSymbol,
InternalSymbol).Converts the external rest, sharp or
flat
symbolfrom
what the userwould type in on the
keyboard
to how itis
representedinternally.
Currently
the internal and external representations arethesame.number_of_note_names(A/t/m)
conver\{ExternalChordSymbol,lnternalChordSymbol)
Converts
ExternalChordSymbol
or what the user typed in to aninternal representation and returnsit
in
InternalChordSymbol.3.1.2
General
Functions
Thissection will
list
rulesthatwere created tosupportthe music routinesorwere usedtoaid inthe I/O.
add_item_to_each_elem(Z./st7,
Instance, List2)
Adds an Instanceto each
item
inthelist!.
Backtracking
thisclause willfail.
Implementation
file:
GeneralFunctions.p
Example:
>addJtem_to_each_elem([a,b,c],[1,2],NewList).
NewList =
[[a,
[1,2]], [b, [1,2]], [c, [1,2]]];
no
assign(/tem,
Item)
Is usedto 'assign' a list orother
data
structureto an un-instantiatedorunbound variable.
Backtracking
this clause willfail.Implementation
file:
GeneralFunctions.p
Example:
?-assign([g,[f],1],GFIat).
GFIat =
[g,[f],1];
no
generate_list_of(A/umer/'c,
Atom,
List)
Generatesa listAtoms Numerictimes.
Backtracking
thisclausewillfail.
Example:
?-generate_list_of(3,
f,
List).List =
[f,f,f];
no
Is used to return an
item
on alist.
Ifbacktracked
to,
the nextitem
inthe
list
willbe
returned.This
will continue until there are no moreitems in
thelist.
Implementation
file:GeneralFunctions.p
Example:
?-get_next([a,b,c],Next).
Next =
a;
Next =
b;
Next = c; nolengthenJist(Z./st7,
Numeric,
List2)
Duplicates
ListlNumeric
times.Implementation file:
GeneralFunctions.p
Example:
?-Iengthen_list([a,b,c],2,
BigList).BigList
=[a,b,c,a,b,c];
nomake_random_list_from(Z./st7,
Numeric,
List2).Returns a
Iist2
ofby
picking
itemsfrom
//st7 Numerictimes.Implementation
file:
GeneralFunctions.p
Example:
?-make_random_list_from([a,b,c],
6,
RandomList).RandomList =
[c,
a, a, c,b,
a]; nopop(List1,
Atom, List2)
Returns
thefirst
Atom in the listandthe resultinglist
withoutthefirst
atom.Implementation
file:
GeneralFunctions.p
Example:
?-pop([a,b,c],ltem, List).
pop_bottom(Z./st7,
Atom, List2)
Returnsthe
last
atom inthelist
and the resultinglist
withoutthelast
atom. Z./sf7 must contain at
least
twoatom.Implementation file:
GeneralFunctions.p
Example:
?-pop_bottom([a,b,c],
Item,
List).Item = c, List =
[a,b];
no
positive_random(/vume/7c)
Returnsa positive random number.
Implementation
file:
GeneralFunctions.p
Example:
?-positive_random(Number).
Number =
13242;
no
random(/Vumer/c7,
Numeric2, Numeric3)
Returnsa random number between Numeric!and Numeric2inclusive.
Implementation
file:
GeneralFunctions.p
Example:?-random(3,
5,
Num).Num =
3;
no
rotate_list(Z./st7,
Numeric,
List2)
RotatesZ./st7 Numerictimes.
Implementation
file:
GeneralFunctions.p
Example:?-rotate_list([a,b,c],
2,
RotatedList).RotatedList =
[c,
a,b];
no
splitJist(Z./st7,
Numeric, List2, List3)
SplitsListl at position Numeric.
Example:
?-split_list([a,b,c,d,e],
2,
Front,
Back)
Front =[a, b],
Back =[c, d,
e];no
traverse_tree(TreeL/st,
TreePath, Order)
Traverses
tree TreeList and returns eachleaf
visited in alist
inTreePath.
TreeList is
alist
ofthreeitems.
Thefirst
is an atom. Theremaining
two mustbe lists.
The traversal method isdetermined
by
Order.
Order canbe
one of thefollowing:
postorder, revpostorder,inorder,
revinorder, preorder, revpreorderImplementation file:
GeneralFunctions.p
Example:
?-traverse_tree([a,[b,
nil, nil],[c,
nil, nil]],List,
inorder).List =
[b,
a, c];
no
ungroup_list(L/st7,
List2)
Removes
alevel
oflists.
Implementation file:
GeneralFunctions.p
Example:
?-ungroup_list([[a,b],[c,d]], Ungrouped).
Ungrouped =
[a,b,c,d];
no
3.1.3 Music Environment
This module is used to
define
basic parameters and conversions ofthe system.This module also
defines
the external interface with a program written in C to playthe actual pitch. A changeable configuration
file
is consulted withinthis module toallow
changing
of parameterslike
median pitch and unit ofduration. Listed below
are the rules created to convert the internal note
format
to one where the Cconvert_duration_to_internal(Durat/'on,
NumericDuration)
Converts
the Internal representation ofduration from
afraction
to an absolute number. This conversionis
dependent
on rulesbeat_duration,
andduration_to_beat
which canbe
changedonline
by
loading
a new configurationfile.
Example:
?- convert_duration_to_internal([1,2], Duration).
A =
600;
no
convert_note_to_pitch(A/ote,
NumericPitch)
Converts the internal representation of a note into an absolute
number. This conversion is dependent on pitch_offset which defines
the starting point or lowest possible pitch. The output of this may also
be
changed onlineby loading
a new configurationfile.
Example:
?-convert_note_to_pitch([a,
[],
5],
Pitch).P=
70;
no
play_note_internal(\/o/ume,
Pitch, Duration)
3.2
Level 2-Music
Theory
Functions
Level 2 modules are a collection of procedures which relate to music theory.
This section
is
broken down into
two parts. Thefirst
partdeals
with the simplermusic
theory
and the second partdeals
with the more advanced parts of musictheory.
3.2.1
Music Relations
and
Rhythm
Music Relationsand Music Rhythm arethe simpler rules used
by
the program.Mostof MusicRelations rules are conversions or translations,whiletherhythm
file
isjust
fraction
arithmetichandling
ofduration.The Music Relations module contains some basicassociations between modes,
intervals,
scales, and chordtypes. Thefollowing
is a partiallist
oftheserelationships.interval(A/oteA/ame7,
NoteName2,
HS)
Returns the interval in halfsteps betweenthe two note names.
intervals(/nterva/, Hs, Degree)
Gives the relationship between an interval name, the number of
halfsteps,
and the typical degree associated with that interval. Thefollowing
table defines what is currently supportedby
the rule intervals.modes(Mode)
Mode isa symbol which representsone ofthe possible modes
defined
inthedatabase.
Example:
?-modes(Mode).
Mode =
ionian;
interval
halfsteps
degree
unison 0 0
mi2 1 1
ma2 2 1
mi3 3 2
ma3 4 2
P4 5 3
a4 6 3
d5 6 4
P5 7 4
mi6 8 5
ma6 9 5
mi7 10 6
ma7 11 6
p8, octave 12 7
Mode
Mode
no
locrianS2;
superLocrian;
mode_scale(Moc/e,
OffsetList)
Returns a list of numbers representing the number of halfsteps
from
a root
key
defined
by
Mode. Example:?-mode_scale(ionian, OffsetList).
OffsetList =
[0,
2,
4,
5,
7,
9,
11, 12]
mode_interval(Moc/e,
IntervalList)
Returns a
list
of intervals in IntervalList representing the intervalsbetween each ofthe notes inthescaledefined
by
Mode. Example:?-mode_interval(ionian, IntervalList).
baseJntervals_in_scale(/nterva/Z./st).
base_hmJntervals_in_scale(/nterva//./st).
base_mm_intervals_in_scale(/nterva//./st)
Defines the
intervals
for
each of thebase
modes.Currently
threebased
modes aredefined.
They
are major,harmonic
minor, andmelodic minor. The IntervalList returned
is
alist
of the intervalsbetween
the notesfor
a scale inthatbase
mode.chord_type_intervals(Cbord7ype,
IntervalList)
Returns the
list
ofintervals
in IntervalList that are used to composethe type of chord specified in ChordType. Listed below are the
Seven Chord Name Internal
Symbol Intervals
Major7 maseven ma3, mi3, ma3
Dominate7 seven ma3, mi3, mi3
Minor 7 miseven mi3, ma3, mi3
half diminished hdim mi3, mi3, ma3
diminished seven
dim
mi3, mi3, mi3minor sevensharp 5 misevens5 mi3, ma3, ma3
minor sevensharp 7 misevens7 ma3, ma3, mi3
relationshipsthataredefined
for
theseven chordtypes.interval_sum(/nterva/7,
Interval,
HS)
interval_sub(/nterva/7,
Interval,
HS)
Returns the sum or the difference between the Interval! and
Intervalin halfsteps in HS.
interval_total(/nterva//./st, Total)
Sumsthe intervals in IntervalListand returnsthe total numberof
halfsteps in Total.
Example:
Total =
3;
no
The
MusicRhythm.p
module allows various calculations on the rhythm.Basically
the rhythmis implemented
as aduration.
Theduration
being
afraction
ofa whole. Listed
below
are afew
ofthe rules used.Since,
duration is represented asfractions,
therules end upbeing
mathematical operationsonfractions.
frac_add(Durat/on7,
Duration2, TotalDuration)
Adds the
fraction
in Durationl with thefraction
in Duration2 andreturnsthe result in TotalDuration. An attempt is madeto reducethe
fraction,
and ifthe result is negative, the numerator hasthe negative sign.Example:
?-
f
rac_add([1,2],[1,2],TotalDuration).TotalDuration =
[1,1];
no
frac_sub(Divrat/'on7, Duration2, Difference)
Subtracts Duration2 from Durationl and returns the result in
Difference. An attempt is made to reduce the
fraction,
and if the resultis
negative, thenumeratorhas
the negative sign.Example:
?-frac_sub([1,2],[1,
4],
Difference).Difference =
[1,4];
no
f
rac_equal(Di/rat/'on7, Duration2)
3.2.2
Basic Music
and
Note Functions
This section will
describe
the general music rules implemented in modulesBasicMusic.p
andBasicNoteFunctions.p.
Theruleswillbe listed
inalphabetical order.Exceptions to this are rules that are dependent on a parent rule such as recursive
functions.
chord_to_mode(C/7orc/,
Mode)
For a given chord, returns which Mode the specified Chord exists in.
Backtracking
will return othermodes.Implementation
file:
BasicMusic.p
Example:
?-chord_to_mode([a,
[],
maseven], Mode).Mode = ionian ;
Mode = lydian ;
Mode = sixthHM ;
Mode = major;
no
?-chord_to_mode([a,
[],
maseven], Mode). Mode = ionian ;Mode = lydian ;
Mode = sixthHM ;
Mode = major ;
no
find_root(C/7ord,
Mode,
RootNote, Degree)
Returnsa possible RootNoteand Degreefora given Chordina given Mode.
Implementation
file:
BasicMusic.p
Example:
?-find_root([[a,
[],
maseven],[1,1]],
ionian, Root,
D).Root =
[a,[]],
D = 1 ;Root =
[e,[]],
D=4;
get_notes_fromJntervalJist(A/ote, IntervalList, NoteList)
Converts
aninterval list into
a sequence of notes. The sequence ofnotes will usethe
degree based
ontheinterval.
An interval of mi2 orma2 will result
in
the notebeing
onedegree
apart. Aninterval
ofmi6 or ma6 will resultin the notes
being
5degrees
apart.Implementation
file:
BasicMusic.p
Example:
?-get_notes_from_interval_list([c,[],2],[ma2,
mi2, ma2],N).N =
[[c,[],2],[d,[],2],[e,[f],2],[f,[],2]]
;no
get_root_name(A/ote/Vame7,
NoteName2, Degree)
Returns
the number ofdegree's
between
two note names.Implementation file:
BasicMusic.p
Example:
?-get_root_name(a,c,P).
P =
6;
no
?-get_root_name(a,
G,
5).G =
d;
no
?-get_root_name(a,
N,D).N = a, D = 1 ;
N = g, D = 2 ;
N =
f
, D = 3 ;
N = e, D = 4 ;
N =
d,
D = 5N = c, D = 6 ;
N =
b,
D = 7;no
in_consonance(/Woo(e,
Note, NoteList)
Determines
if a given notelist is
in consonance relative to theMode
andthe Notespecified.
Implementation
file:
BasicMusic.p
Example:
yes
?-in_consonance(M, [c,[],1],
[[c,[],1],[d,[],1],[e,[],1]]).
M =
ionian
;M =
lydian
;M = mixolydian ;
M =thirdHM;
M =
lydianAug
;M =
lydianF7
;M = mixolydianF6 ;
M = major ;
no
match_chord_mode(mode,
degree,
chordtype)
Matches the chord type
for
a mode and the given degree. Degreemust
be
an instantiated variable.Backtracking
will attempt tofind
othersolutions.
Implementation
file:
BasicMusic.p
Example:
?-match_chord_mode(ionian,
3,
ChordType).ChordType = miseven;
no
?- match_chord_mode(Mode,
1,
ChordType).Mode =
ionian,
ChordType = maseven;Mode =
dorian,
ChordType = miseven;Mode =
firstHM,
ChordType = misevens7Mode = melodicMinor, ChordType = misevens7
Mode = superLocrian, ChordType =
hdim;
no
next_note_name(note name
7,
notename2, numeric)Determines the note name adjacent to a given note name. The
numeric
field
willbe
1 if a wrap-around occurs, otherwise it willbe
Implementation file:
BasicNoteFunctions.p
Example:
?-next_note_name(a,
NextNote,
WrapAround).NextNote
=b,
WrapAround =0;
no
?- next_note_name(PreviousNote, a,WrapAround).
PreviousNote = g,WrapAround =
1;
no
note_distance(/Vumer/c,
Note!, Note2)
Determinesthe number of
halfsteps
between two notes. Distance is measured relative to Note2. Notel and Note2 must be symbols orinstantiated
variables. If the a desired note some number ofhalfsteps
awayfrom
another note isdesired,
shift_note_intervalshould
be
used.Implementation file:
BasicNoteFunctions.p
Example:
?-note_distance(HS, [a,[],1],[c,[f],1]).
HS =
-2;
no
?-note_distance(-2, [a,[],1],N).
no
notes_of_chord(Chord,
NoteList)
Returnsthe listof notesfora given chord. Implementation
file: BasicMusic.p
Example:
?- notes_of_chord([[c,
[],
maseven],[1,1]],
N).N = [[[c,[],5],[1,4]],[[e,[],5],[1,4]],[[g,[],5],[1,4]],
[[b,[],6],[1,4]]]
;no
reverse_sharps_flats(SR/st7,
SFList2)
Reverses a list of sharps to a list of flats or a list of
flats
to alist
of sharps. Noerror checking is done on thesharp orflat
list. Ifeither of the inputlists does
not contain a valid symbol, the result is alsoImplementation file:
BasicNoteFunctions.p
Example:
?-reverse_sharps_flats([f,f],N).
N =
[s,s]
?-reverse_sharps_flats([s,s],N).
N =
[f
,f]
?- reverse_sharps_f
lats(N,[f]).
N =
[s]
;no
sf_value(s/7/st, numeric)
Allowstheconversion of an sflistto a
halfstep
value(numeric)
orthereverse, the conversion of a half stepvaluetoa
list
of sharps orflats.
Backtracking
willfail.
Implementation
file:
BasicNoteFunctions.p
Example:
?-sf_value([f,f,f],SFValue).
SFValue = -3;
no
?-sf_value(SFList,
2).SFList =
[s,s];
no
shift_note(note7,
degree!,
mode,degree2,
note2)Returns the note that is a given number of
degrees from
anothernote, degree! is the degree that note7 belongs to
for
the modescale.
degree2
is the degree note7 isfrom
note2.Backtracking
willfail.
Implementationfile:
BasicNoteFunctions.p
Example:
?-shift_note([g,
[],
1],
ionian, 6,
Note2).Note2 =
[f, Is],
2];
no
?-shift_note([a,
[],
1],
3, ionian, 1,
Note2).Note2 =
[b, [f],
1];
shift_note_interval(Note1,
Numeric,
Degree, Note2)
Shifts
Notel the number ofhalfsteps
given in Numeric. Degree wilspecify
the note name of note2.Implementation
file:
BasicNoteFunctions.p
Example:
?-shift_note_interval([a,[],1],2,2,N).
Degree =
[c,[f],1];
no
?- shift_noteJnterval([a,[],1],HalfSteps,2,[c,[f],1]).
HalfSteps = 2 ;
no
?-shift_note_interval([a,[],1],2,Degree,[c,[f],1]). Degree = 2 ;
3.3 Level
3-
High Level Functions
Level 3 contains the
higher level functions.
This
sectionis broken
up into 3sections, the
input
and output routines, the note generation methods, andthe chordanalysis or progression section.
3.3.1
Input
and
Output
Routines
The Input and Output modules contain all the input and output rules. The
Input module
is dependent
on the Music Symbols module to convert input symbolsinto their
corresponding
internal representation. The rules in the Input moduleallow general
keyboard
input,
menu prompts, andprocessing
of input. Generalkeyboard
input is used to enter input oroutputfile
names. Window like menus aredisplayed for
boolean queries. The menu rules willdisplay
the menu, promptfor
input,
and then return the chosen selection.Processing
of input is required wheninput
data
is required. The input data is parsed and translated into an internalformat.
Thefollowing
isa partial listofthe rules in the Input module.select_option
{Options, OptionSelected)
Options is a list of two items. The first item is a string which is
displayed
to the user. The second item is the corresponding atomthat
is
returned for which ever option the user selected.OptionSelected is instantiated with this item. This rule will
display
the options
proceeding
each item with a number. The user will beprompted
for
a numbercorresponding totheoptionthey
desire.Example:
?- select_option([[messageX,
first], [messageY,
second]],Option).1)
messageX2)
messageYEnter Choice:2
read_file(F/7e5tream,
NoteList,
ChordList)
Reads
from
the FileStreamtheNoteListandthe ChordList.get_file_name(Prompt,
FileName, FileType)
Prompts user
for
afile
name. If the user specifiedfile does
not existor
is
in adifferent
search path, the standard Macintosh Finderdialog
display
will appear. The Promptis
a string thatis
usedfor
thefirst
query to the user. The FileName is a
string
containing thefile
name that the userhas
inputted. The FileType is only partially implemented. It maybe
used infuture
additions to restrict to onlyentering
file
names of a specificfile
type.Currently
threefile
types aredefined.
They
are config,input,
and, output, which are all mappedto the Macintosh Finderfile
type of['TEXT'].
Any
othertype is mappedto[].
get_notes_from_stream(Stream,
NoteList)
Reads note
data from
Stream. Data inputtedfrom
the stream isfiltered
andthe note information is extracted, and addedtoNoteList.remove_extras(/npt/t,
Line)
This rule is used to extract any extraneous input data from Input.
Input
is
a listof characters.Unnecessary
data
includesspaces ortabs.Comments are also removed here. A comment
is
considered tobe
two consecutive dashes and any data
following
the two consecutive dashes. Thexesultantis returned in Line.Example:
?- explodec("dmi7 -dminseven",
CharList),
remove_extras(CharList, Line).
CharList =
['d','m','i','7',' ',' ','-','-','
','d','m','i','n','s'.'e',V/e','n'],
Line =
['d','m,,'i','7'];
no
Displays a window with
Question,
and twobuttons labeled
Option!and Option2. The user
may
then click on thedesired
option. Theoption selected
is
then returned in Result.Question is
a string, andOptionl,
and Option2are atoms.The Output module
depends
on the Music Environmentmodule. This modulecontains rules to convert
internal data
structures to either a readable, audible, orelectronically accessible
form.
Readableform
changes internal symbolsto some setof text and
displays
them to the screen. Audibleform
output will convert a set ofinternal notes
into
sounds played through the speaker of the computer.Electronically
accessibleform
allows improviseddata
to be written to afile for
lateruse. The
following
is
alist
of some oftherules inthe Outputmodule.print_note_name(A/ote/vame)
Displays the atom correspondingtothe NoteName. If the NoteName
isa rest, thetextstring 'rest' is
displayed.
pri nt_sf
(SFList)
Displays sharps andflats. If therearetwo sharps, then the textstring
'sharp
x2'
is displayed. If there are no sharps or
flats,
nothing isdisplayed. If there is only one sharp or
flat,
then a'#'
or
'f
isdisplayed.
Example:
print_sf([f,f]).
flat
X 2yes
play'(ChordList,
NoteList)
The current implementation can only output one pitch at any one
time so the ChordList
field is
ignored. NoteListis
passed to ruleCalls rule convert_whole_play_list to convert the List into an
internal note
format. The
values arethen asserted intothe databaseandthen passedto play_converted_listto playthenote
list.
play_saved_output
Prompts user
for
afile
whichis
then reconsulted into the prologdatabase. A check ismadeto
determine
ifthe conversion parametersare
different
than those originally used. Ifthey
aredifferent,
theuser
is
prompted on whether or not the output should reflect thenew parameters. The notes arethen played.
save_output
This rule allows the userto savethe output ofan improvisation. The
user
is
queriedfor
an outputfile
name. Thedata
saved is retrievedfrom
the prolog database. The rules areinput,
results, pitch_offset,beat_duration, duration_to_beat,
and the internal representation3.3.2 Note Generation
This section
describes
thecurrently implemented
note generation methods.The
first
sectiondescribes
the stochastic approach ofselecting
notes. The nextsection
describes
the use of random chord notes. The third sectiondescribes
usingchords in conjunction with a
binary
tree. Thelast
sectionis
a rulebased
noteselection. In most casesthe input rhythm
is
retainedby
using
thesame rhythm astheinput. Reststhat occurred were also retained whenthe inputrhythm was used.
3.3.2.1
Stochastic Note Generation
This method of
selecting
notes uses weightedintervals
selectedby
random.The interval table
described
in section 2.2 was used. The table is implemented inmodule
IntervalWeightings.p
as ruleinterval_weights(lnterval,
WeightUp,
WeightDown). Interval represents the internal symbol
for
a specific music interval.WeightUp
and WeightDown are numbers which represent the weights of thatinterval either upordown. The
higher
the numberthe heaviertheweight. Thefirst
note ofthe melody
is
used asthestarting noteofthe improvisedsolo. Thenext noteis
determined
by
an interval weighttable. The interval weighttable consists oftwonumbers which represents a range. If a randomly selected number
falls
within thisrange, that interval is selected. The greater the range, the higher weight of that
interval. A check
is
madetokeep
the intervalfrom
going out ofthe actual high andlow
note range of the original melody. The rules implemented for the stochasticnote generation can
be
found
in module WeightedNoteSelection.p. Some of therules are as
follows.
get_weighted_notes(Me/ody,
WeightedNotes)
original
melody
aredetermined
by
calling
get_lo_hi_notes. TheWeightedNotes are then
determined
by
callingget_next_weighted_note. The
first
or seed note used is thefirst
note ofthe Melody.
calc_weights(MaxlrVe/g/7t)
Determines what the maximum weight can
be
and stores the rangeof valid ranges
for
each interval in thedatabase.
The maximumweightis calculated,and a ruleweight isasserted foreach interval up
and down. This rule will
be
of theform
weight(HalfSteps,Degree,
RangeLo,
RangeHi). Halfsteps isthe number ofhalfsteps
up ordown.This implementation allowsan interval up and an intervaldown to be
represented as separate rules. Degree specifies the degree of the
note. RangeLo and RangeHi specify the range
for
which the randomnumber must
fall between for
the intervalto be selected.Example:
?- calc_weights(MaxWeight).
MaxWeight =
100;
no
get_weighted_deg_hs(/?Degree,
HS)
Returns a randomlyselected degreeand halfstep. This rule generates
a random number, and then searches through the database for an
interval where the random number
falls
between the weightedrange.
Example:
?- get_weighted_deg_hs(RDeg, HS).
RDeg
=5,
HS =8;
RDeg
= -2, HS = -3;RDeg
= -1,HS = -1;get_next_weighted_note(Me/ody,
SeedNote,
Lo, Hi,
WeightedNoteList)
Generates a
list
of weighted notes using the rhythm from thestarting
note. Itis
used todetermine
the next note. The interval thatis
chosen is relative to this note. Lo and Hi are the minimum andmaximum notes allowed.
WeightedNoteList is
the returnedlist
ofnotes.
3.3.2.2
Random Chord Note Generation
Random chord note generation will generate the
list
of notesby
randomlyselecting notes that make up the chords in the original melody. There are two
groupings
for
this. Thefirst
will group all the chord notes intoa pool and randomlyselect
from
this pool. Since itis
possiblethat akey
change couldhave
occurred, thismethod
may
resultin
a notebeing
played over a measure where it doesn't belong.The second
grouping
eliminates thisby
grouping the pool of notesby
thekey.
Thechord progression
is
initially
analyzed and then broken down into several groups ofnotes. Notes
for
eachkey
are pickedfrom
the pool thatbelong
with thatkey.
Therhythm
for
thefirst
methoddescribed
is strictly a quarter of the duration of thechord. If the chord
duration
was a whole note,each notethatwasderived from
thatchordwould
be
a quarter note. Rhythmfor
the second method is matched with theinput melody. The
following
is a description of one ofthe rules usedfor
chord notegeneration.
get_random_mode_notes(CnordGroupL/st,
NoteGroupList)
A
list
of chord groups groupedby
mode is transformed into a list ofnotes grouped within the same group. ChordGroupList is a list of a
list
ofchords groupedby
mode. The notesof each ofthese individuallists
isthen placed intoanother listoflists.
Arandom list is generatedfor
each of theselists,
where the number of notes chosen is twice asmany
as in the originallist.
This is because randomly selected notes,may
end up picking onlythe shorterduration notes.Any
extra notesare then trimmed off. NoteGroupList is the resulting
list
of alist
of3.3.2.3
Binary
Tree
Binary
tree selectionis
an offshoot of the random chord note generationmethod. Again this method will use notes of the chord, and only the notes of the
chord thatare in the same
key.
Thedifference here
isthat the notes are not pickedin random. Each note of a chord
is
sortedinto
abinary
tree. The note selection isdetermined
by
how
the treeis
traversed. The current implementation allows sixdifferent tree traversals.
They
are post order, reverse post order, in order, reverseinorder,
preorder, and reverse preorder. The rhythm is matched one for one withthe input melody. The main part is
implemented
in the module titled BinaryTree.One ofthe rules isas
follows.
get_binary_tree_notes(ChordGroupZ./'st,
NoteGroupList, Traversal)
ChordGroupList is a
list
of alist
of chords groupedby
mode.NoteGroupList is the resulting
list
of a listof notes groupedby
mode.Traversal method isan atom representingthe traversal method used.
Since
tree traversal canbe
thought of as a genericfunction,
the treetraversal methods are not
listed
here,
but in the GeneralFunctionsmodule. get_binary_tree_notes
first
turns each chord list into atree of notes,
by
calling make_tree. The resulting tree is thentraversed. This process continues with eachgroupof
list
of chords.3.3.2.4 Rule Base
The rule
based
note selection uses the input notes to determine what notesshould
be
used. Some rules were derivedfrom
Levitt'sthesis,
and some were chosenbased
upon personaljudgment. Most ofthe rulesdepend
on the previous note andthe current note ofthe input melody. The
first
note ofthe note selection isthefirst
note of the melody.
Again,
the rhythm is identical to that of theinput
melody.Some oftherules inthe RuleBase module are asfollows.
This rule uses
data
storedin
theprolog database in
theform
ofrule_db.
Currently
t