Common Music Reference Manual |
 |
|
4 Working with Parameterized Data
This chapter presents a variety of different strategies for
working with various types of parameterized data in music composition.
For a discussion about frequency and scales see the separate
chapter Frequency, Tunings and Modes
in the documentation.
4.1 Time and Rhythm
Time values can be expressed as seconds, milliseconds, or as proportional
quantities scaled by a tempo factor. The rhythm
function converts proportional values to time in seconds suitable for
event parameters such as time or duration or
as wait values
in a process definition.
A proportional value can be a Lisp ratio (such as 1/4, 7/8,
1/3, 2 and so on) or a rhythmic symbol. A rhythmic symbol consists
of a letter:
M=maxima,
L=longa,
B=brevis,
W=whole,
H=half,
Q=quarter,
E=eighth,
S=sixteenth,
T=thirty-second,
X=sixty-fourth.
This symbol may be optionally preceded by
T (triplet) or Q (quintuplet) and optionally
followed by any number of dots.
Mensural symbols also support simple "expressions" that add, subtract and
multiply.
Example 4-1
|
q
e.
tq
h...
qh
s+tq
w-ts
w*4
| | |
rhythm &optional tempo beat
|
[Function] |
Returns the value of rhythm converted to seconds. rhythm
can be a number, a rhythmic symbol or list of the same. tempo provides the
metronome speed and defaults to the value of *tempo*, initially set to 60.0.
beat
specifies the metronome's pulse and defaults to the value of *beat*,
initially set to .25 (quarter note.) If tempo and beat are both
rational then rhythm will return rational values.
Example 4-2
|
? (rhythm 'q)
1.0
? (rhythm 'te 60 1/4)
1/3
? (rhythm 1/4 120.0)
.5
? (rhythm 1/4 60 1/3)
3/4
? (rhythm '(q th e.. x) 90)
(2/3 8/9 7/12 1/24)
? (setf *tempo* 120.0)
120.0
? (rhythm '(q th e.. x) )
(0.5 0.6666666666666666 0.4375 0.03125)
| | |
The default metronome factor used by the rhythm function.
Defaults to 60 beats per minute.
The default metronome beat used by the rhythm function.
Defaults to .25, or quarter note.
4.2 Logical Amplitude
Amplitude values can be specified directly or by using logical amplitudes
in conjunction with the amplitude function.
amplitude amp &optional softest loudest power
|
[Function] |
Converts logical amplitude amp to a value between softest and loudest
according to the power curve. A logical amplitude is a number between 0 and 1
or an amplitude symbol: niente, pppp, ppp, pp,
p, mp, mf,
f, ff, fff, ffff.
The values of softest, loudest and power default
to the value of the global variables *softest*, *loudest*
and *power*.
Example 4-3
|
? (amplitude 'mp)
.5
? (amplitude 'mp 0 127)
63.5
? (amplitude 1/2 0 127 1)
127/2
? (amplitude .5 0 1 4)
0.0625
| | |
The default minimum amplitude value when the logical amplitude is 0.0. Defaults to 0.0.
The default maximum amplitude value when the logical amplitude is 1.0. Defaults to 1.0.
The power curve for calculating amplitude values from logical amplitudes.
The default value is 1.0. which means that amplitude values increase linearly
from *softest* to *loudest*. Values greater than 1.0
cause the power curve to become increasing exponential toward the maximum value.
4.3 Scaling and Offsetting
rescale number old-min old-max new-min new-max
|
[Function] |
Returns a value between new-min and new-max
that is proportional to number between old-min and old-max.
Example 4-4
|
? (rescale .51 0 1 0 100)
51.0
? (rescale 1.2 1 2 80 90)
85.0
| | |
fit number min max &optional mode
|
[Function] |
Forces number to lie between min and max according to mode.
If mode is :reflect (the default), then the min and max
boundaries reflect the value back into range. If mode is
:wrap then fit returns the remainder of number modulus
the boundary range.
Example 4-5
|
? (loop for i from -20 to 20 by 5 collect (fit i 0 10))
(0 5 10 5 0 5 10 5 0)
| | |
expl power &key :y0 :y1 :base
|
[Function] |
Returns an exponential value between :y0 and :y1
according to power, which ranges from 0 to 1. When power is 0 :y0 is returned, when power is 1 :y1 is returned. :y0 and :y1
default to 0 and 1, respectively.
:base determines the slope of the exponential curve, if it is
less than 1 then the exponential curve is concave, otherwise a convex curve
is produced. The default value of :base is 2.
Example 4-6
|
? (expl 0 5 1 1/256)
0.0
? (expl 1 5 1 1/256)
5.0
? (expl .5 5 1 1/256)
1.235
;;; create envelope ramping from 3 to .5
? (loop for i to 1 by .2 append (list i (expl i 3 .5 1/256)))
(0 3.0 0.2 1.31 0.4 0.76 0.6 0.58 0.8 0.51 1.0 0.5)
| | |
explseg i length sum power
|
[Function] |
Returns the ith segment of length number of exponential
segments that add up to sum. The exponential curve is defined by
power, where 0<power<1 yields concave slopes
and power>1 yields convex slopes.
explsegs length sum power
|
[Function] |
Like explseg but returns a list of length number of exponential segments.
Example 4-7
|
? (setf l (explsegs 4 10 2))
(1.8920711500272102 2.250064473703739 2.6757926813433408
3.18207169492571)
? (apply #'+ l)
10.0
| | |
quantize value step
|
[Function] |
Rounds value to the nearest multiple of step.
Example 4-8
|
? (loop repeat 10 collect (quantize (random 1.0) .2))
(0.8 0.4 0.2 0.2 0.6 0.8 0.8 0.2 0.4 0.4)
| | |
decimals number places
|
[Function] |
Rounds number to places number of decimal places.
Example 4-9
|
? (decimals 0.5931282184890065 3)
0.593
? (decimals 1/3 3)
0.333
| | |
4.4 Envelopes and Interpolation
An envelope is a list of x y values. Plotter can be
used to create and edit envelopes graphically. Use Plotter's
Import and Export commands to convert
between envelopes and their graphical displays.
lookup x list &key :test
|
[Function] |
Returns the "y value" of x in list according
to :test. The default test function is <.
Since lookup does not perform interpolation the y entries
in list do not need to be numeric values.
Example 4-10
|
? (lookup .5 '(0 c4 .4 c5 .7 c6))
C6
| | |
interp x &rest coords
|
[Function] |
Returns a linear interpolated y value for x in coords.
Example 4-11
|
? (interp 75 0 0 50 .5 100 0)
.25
| | |
interpl x envelope &key :scale :offset :base :min :max
|
[Function] |
Returns the y value of x in envelope, a list of x y coordinates.
The value returned can be optionally scaled and offset according to
the :scale and :offset arguments.
:scale and :offset can also be specified as :min and
:max, in which case :min becomes the offset and :scaler is
set to max-min. If :base is 1 (the default) then linear interpolation is performed.
If :base is greater than one then the y value is interpolated along an
exponential curve; values greater than 1 produce concave curves, values
less than 1 but greater than 0 produce convex curves.
Example 4-12
|
? (interpl 50 '(0 0 100 1) :scale 2 :offset 3)
4.0
| | |
tendency x low high &key :scale :offset :min :max :state
|
[Function] |
Returns a random y value that lies between the value of x in low and high
envelopes. If low or high are unchanging they may be expressed as
a single value. Use :random to provide a random generator other
than the random function. This generator is passed two arguments: the floating
point range high to low and the :state, a random
state object that defaults to *random-state*
The value returned by tendency can be optionally scaled and offset according to
the :scale and :offset arguments.
:scale and :offset can be alternately specified as :min and
:max, in which case :min is the offset and
:scaler is set to (max-min).
Example 4-13
|
? (loop for i by .2 to 2
collect (tendency i '(0 0 1.5 .5) '(0 1 1.5 .75))
(.37 .77 .62 .50 .44 .34 .75 .48 .55 .66 .69)
| | |
rescale-envelope env &key :x-min :x-max :y-min :y-max
|
[Function] |
Returns a copy of env with x and y values optionally rescaled to
lie between new minima and maxima.
Example 4-14
|
? (rescale-envelope '(0 0 .5 .5 1 1) :y-min 100 :y-max 200 )
(0 100 0.5 150.0 1 200)
? (rescale-envelope '(0 0 .5 .5 1 1) :x-min 0 :x-max 100 )
(0 0 50.0 0.5 100 1)
? (rescale-envelope '(0 0 .5 .5 1 1) :x-max 100 :y-max 100 )
(0 0 50.0 50.0 100 100)
| | |
4.5 Random Selection
ran &key :below :from :type :a :b :state
|
[Function] |
Generates random numbers in a variety of different distributions.
ran accepts the following keyword arguments:
-
:below number
-
Sets the exclusive upper bounds for random number generation. Defaults to a value
specific to the type of distribution specified to ran, usually 1.0.
-
:from number
-
Sets the inclusive upper bounds for random number generation. Defaults to a value
specific to the type of distribution specified to ran, usually 0.0.
-
:type
-
Sets the distribution for random number generation to type specified
as a symbol or keyword. Defaults to :uniform.
ran supports the following distribution types:
-
:uniform
-
Numbers are evenly distributed between :from and :below.
:uniform can also be specified as :u.
-
:low-pass
-
Prefers lower numbers between :from and :below.
Density = f(x)=2*(1-x) for {x 0<1}. Mean = .2929.
:low-pass can also be specified as :lp.
-
:high-pass
-
Prefers higher numbers between :from and :below.
Density = f(x)=2*(1-x) for {x 0<1}. Mean = .2929.
:high-pass can also be specified as :hp.
-
:band-pass
-
Prefers middle numbers between :from and :below.
Mean = n/2.
:band-pass can also be specified as :bp.
-
:beta
-
The :a and :b parameters to ran determine beta
density behavior. When a=b=1 uniform distribution results. When a=b, the
distribution is symmetric around .5. When a<1 and b<1 then density of large and
small numbers increases. When a>1 and b>1, density is similar to the
gaussian distribution.
-
:exponential
-
Returns a floating point value >0.
The :a parameter to ran is a stretching factor (lambda).
Increasing :a prefers smaller numbers. The value
returned is unbounded but when :a=1 then %99.9 of the time the value is
less than 6.9077554, ie -log(.001). Density = f(x)=(exp -x). Mean=1.0
:exponential can also be specified as :exp.
-
:gaussian
-
Gaussian (normal) distribution returns an unbounded value. The spread (standard
deviation) is 1.0 centered at 0, so 68.26% of the results are -1<=x<=1, and 99.74% of
the results are -3<=x<=3.
:gaussian can also be specified as :gauss.
-
:cauchy
-
Returns an unbounded value. The density function is a bell shaped curve centered
at 0 similar to a normal distribution but with more values at the extremes.
The mean and standard deviation of the Cauchy distribution are undefined.
If the parameter :a is non-nil, only positive values are returned.
Density = f(x)=1/(pi(1 + x^2))
-
:poisson
-
A discrete distribution: returns positive integer values, theoretically unbounded
but practically limited by the shape parameter. :a is a shape
parameter which must be positive. The mean is a and the standard
deviation is sqrt(a)
-
:gamma
-
Returns a floating point value >0. :a is the shape parameter which must be
positive. In this implementation, a can only take integer values. If a non-integer is
provided, the value is rounded. When a=1, the distribution is the same as
exponential. As a increases, the probability density function becomes a curve with
mean = a and standard deviation = sqrt(a)
The :type argument may also be specified as :distribution.
-
:a number
-
An optional control parameter whose interpretation depends on the distribution type.
-
:b number
-
An optional control parameter whose interpretation depends on the distribution type.
-
:state random state
-
The random state object to use. Defaults to the Lisp
variable *random-state*.
between lb ub &optional exclude state
|
[Function] |
Returns a random number equal to or greater than lb but less than ub.
If excludeis specified that value will not be selected.
state is an optional random state object and defaults to *random-state*.
Example 4-15
|
? (between 1 2)
1
? (between 1 2.0)
1.234551
? (loop repeat 10 for n = (between 1 5 n) collect n)
(4 2 3 4 1 4 2 3 1 4)
| | |
vary value pct &optional fit state
|
[Function] |
Returns a random number that deviates from value by up to
pct percentage. fit determines how the
variance is to be offset from value; :above returns
a percentage variance with value at the minimum,
:below returns a percentage variance with value at the maximum
and :around returns a percentage variance with value in the middle.
The default value is :around.
Example 4-16
|
? (vary 100 .05 :around)
98.2
(vary 100 .05 :above)
103.237
(vary 100 .05 :below)
96.933
| | |
odds prob &optional true false state
|
[Function] |
Returns true if a randomly generated number is less than
prob, a number between 0.0 and 1.0. Otherwise
returns false. The default values
for true and false are t and nil, respectively.
state is the random state object and defaults to *random-state*
Example 4-17
|
? (odds 1)
t
? (odds .2 "Yup" "Nope")
"Nope"
| | |
pick &rest args
|
[Function] |
Returns a randomly chosen argument to the function.
Example 4-18
|
? (pick 1 2 3 4 :foo 5)
3
? (pick 1 2 3 4 :foo 5)
:foo
| | |
pickl list &key :end :start :avoid :state
|
[Function] |
Returns a randomly chosen element from list, which may be a list
or array. :start is the lower selection bound and defaults to
0. :end is the upper selection bound and defaults to the length
of list. Use :avoid to specify an element that cannot
be directly reselected. :state defaults to *random-state*.
Example 4-19
|
? (pickl '(1 two 3 four 5))
3
? (pick "foobar" :start 1)
#\a
| | |
shuffle list &key :start :end :state :copy
|
[Function] |
Returns a random reordering of list, which can be a list or
sequence. Reordering takes place between
:start and :end, which default to the full length of the
sequence. If :copy is t
(the default) then a reordered copy of list is
returned, otherwise seq is destructively modified and returned.
:state defaults to *random-state*.
Example 4-20
|
? (shuffle '(a b c d e))
(b a e d c)
| | |
drunk n width &key :low :high :mode :state
|
[Function] |
Returns a random value constrained to lie between n-width and n+width.
Passing in previous values of n implements a random walk
(brown noise). If :low and :high are
specified then the random walk is bounded and values that exceed either
value are automatically adjusted to lie within bounds according to :mode.
If :mode is :reflect (the default) then the outlying
value is reflected back in bounds. If :mode is :limit then
the closest boundary is returned. If :mode is :reset
then the outlier is centered between :low and :high.
If :mode is :jump the a random value between
:low and :high is selected.
:state defaults to *random-state*.
Example 4-21
|
? (loop with i = .5 repeat 10 collect (setf i (drunk i .25)))
(0.58 0.72 0.57 0.72 0.64 0.85 1.03 1.05 1.22 1.19)
? (loop with i = 60 repeat 10 collect (setf i (drunk i 3 :low 54 :high 66)))
(60 60 61 61 62 64 63 64 64 63)
? (drunk 11 1 :low 0 :high 10 :mode :reset)
5
| | |
4.6 Analysis Tools
The following functions are provided to assist in compositional analysis.
histogram data min max slots
|
[Function] |
Returns a histogram of numbers. min and max are
the lower and upper bounds for values in numbers.
slots is the number of sampling segements between
low and high to count.
Example 4-22
|
? (histogram (loop repeat 100 collect (random 700)) 0 700 7)
(17 15 13 12 11 19 13)
| | |
markov-analyze sequence &key :order :print? :pattern? :key
|
[Function] |
Performs an analysis of sequence then prints and/or returns the
analysis results according to :print? and :pattern?.
markov-analyze supports the following keyword arguments:
-
:order number
-
The order of the Markov analysis, defaults to 1.
-
:print {t | :table | :pattern | nil}
-
The value t (the default) means to print both
the transition table detailing the of distribution of inputs and outputs
as well as the markov
pattern description that would instantiate that table. Otherwise :print
can be specified as just :table or :pattern if
only that information is wanted, or nil if no printing
is desired.
-
:pattern {nil | t}
-
If nil (the default) then markov-analyze does not
return values. If :pattern? is t then a
markov pattern based on the analysis transition table is returned.
-
:key function
-
A Lisp function to apply to each item in sequence. function
should take one argument and return the actual datum to be analyzed.
:sort {list | function}
Specifies the order of labels in the columns and rows of
the table. If a list of labels
is specified its ordering determines
the column order of the table. If :sort is a function it
is passed to sort to sort the table labels.
:decimals {number}
Specifies the number of decimals to use when printing
the table. Defaults to 3.
Example 4-23
|
? (defparameter happy-birthday
#n(c4 c d c f e c c d c g f c c c5 a4 f e d bf bf a f g f))
happy-birthday
? (markov-analyze happy-birthday :order 2)
D4 C4 F4 E4 G4 C5 A4 BF4
(D4 C4) ----- ----- 0.500 ----- 0.500 ----- ----- -----
(D4 BF4) ----- ----- ----- ----- ----- ----- ----- 1.000
(C4 D4) ----- 1.000 ----- ----- ----- ----- ----- -----
(C4 C4) 0.667 ----- ----- ----- ----- 0.333 ----- -----
(C4 F4) ----- ----- ----- 1.000 ----- ----- ----- -----
(C4 G4) ----- ----- 1.000 ----- ----- ----- ----- -----
(C4 C5) ----- ----- ----- ----- ----- ----- 1.000 -----
(F4 C4) ----- 1.000 ----- ----- ----- ----- ----- -----
(F4 E4) 0.500 0.500 ----- ----- ----- ----- ----- -----
(F4 G4) ----- ----- 1.000 ----- ----- ----- ----- -----
(E4 D4) ----- ----- ----- ----- ----- ----- ----- 1.000
(E4 C4) ----- 1.000 ----- ----- ----- ----- ----- -----
(G4 F4) ----- 1.000 ----- ----- ----- ----- ----- -----
(C5 A4) ----- ----- 1.000 ----- ----- ----- ----- -----
(A4 F4) ----- ----- ----- 0.500 0.500 ----- ----- -----
(BF4 A4) ----- ----- 1.000 ----- ----- ----- ----- -----
(BF4 BF4) ----- ----- ----- ----- ----- ----- 1.000 -----
(MARKOV (D4 C4 -> (F4 0.5) (G4 0.5))
(D4 BF4 -> (BF4 1.0))
(C4 D4 -> (C4 1.0))
(C4 C4 -> (D4 0.667) (C5 0.3333333333333333))
(C4 F4 -> (E4 1.0))
(C4 G4 -> (F4 1.0))
(C4 C5 -> (A4 1.0))
(F4 C4 -> (C4 1.0))
(F4 E4 -> (C4 0.5) (D4 0.5))
(F4 G4 -> (F4 1.0))
(E4 D4 -> (BF4 1.0))
(E4 C4 -> (C4 1.0))
(G4 F4 -> (C4 1.0))
(C5 A4 -> (F4 1.0))
(A4 F4 -> (E4 0.5) (G4 0.5))
(BF4 A4 -> (F4 1.0))
(BF4 BF4 -> (A4 1.0)))
| | |
Common Music Homepage | © 2002 Heinrich Taube |
Last Modified: 20 May 2002
|