With a bottom-up approach to music making, one might first start with building up small units of music. This could be a drum pattern, a melodic line, a granular cloud, a processed sample of sound, or more. Once smaller units are created, it is natural to build up larger units of music, which in turn may be used to build up even larger units of music. This framework or approach to music making has been used long before computers, and numerous approaches have been taken within computer music. (The music system HMSL has been very inspiring for this work.)
Score offers two primary functions for higher level organisation of music:
convert-timed-score
and convert-measured-score
. The two functions take in
list data structures written in timed- or measured-score formats. They will
process the score formats and yield a single, flattened note list. The two
functions operate similarly with the exception of how they work with time
specifications. They are described with examples below.
convert-timed-score
allows the user to organise smaller blocks of
score into a larger score. The user specifies a list of values that can
either be numbers or note lists. If a number is encountered, it sets the
current time for note list start time translation. If a note list is
encountered, it will be translated in time by the current time. For note
lists, convert-timed-score
requires that the second field of each note
be a value for a start time.
The following shows an example usage of
convert-timed-score
. First, a score fragment is
explicitly written out by hand and assigned to the pattern variable.
Second, the score
variable is defined in the timed-score
format. It reads as “at time 0.0, play pattern, and at time 4.0, play
the pattern again”.
(def pattern
[['bass-drum 0.0 0.5]
['bass-drum 1.0 0.5]
['bass-drum 2.0 0.5]
['bass-drum 3.0 0.5]])
(def score
[0.0 pattern
4.0 pattern])
(println (convert-timed-score score))
The following shows the note list generated by calling convert-timed-score
with the score
variable.
([bass-drum 0.0 0.5]
[bass-drum 1.0 0.5]
[bass-drum 2.0 0.5]
[bass-drum 3.0 0.5]
[bass-drum 4.0 0.5]
[bass-drum 5.0 0.5]
[bass-drum 6.0 0.5]
[bass-drum 7.0 0.5])
convert-timed-score
also allows for multiple note lists to
be used for a given time.
The following shows an example where
two note lists, bd-pattern
and snare-pattern
,
are used together in the timed-score.
(def bd-pattern
[['bass-drum 0.0 0.5]
['bass-drum 1.0 0.5]
['bass-drum 2.0 0.5]
['bass-drum 3.0 0.5]])
(def snare-pattern
[['snare-drum 1.0 0.5]
['snare-drum 3.0 0.5]])
(def score
[0.0 bd-pattern
4.0 bd-pattern snare-pattern])
(println (convert-timed-score score))
The resulting processed score would be:
([bass-drum 0.0 0.5]
[bass-drum 1.0 0.5]
[bass-drum 2.0 0.5]
[bass-drum 3.0 0.5]
[bass-drum 4.0 0.5]
[bass-drum 5.0 0.5]
[bass-drum 6.0 0.5]
[bass-drum 7.0 0.5]
[snare-drum 5.0 0.5]
[snare-drum 7.0 0.5])
Since the notes lists are just lists, users can hand-write blocks of notes, use note-processing functions, and use note-generating functions within a timed score. For example:
(def score
[0.0 bd-pattern
4.0 (process-notes bd-pattern 2 #(* % 0.5))
snare-pattern
[['single-shot-sample 2.0 2.0]]])
(println (convert-timed-score score))
shows an example of using inline hand-written note lists and function
calls within a time-score. In the example, the second use of
bd-pattern
has been processed with the process-notes
function, such
that the 3rd field of each note has its value multiplied by 0.5. Also, a
single-shot-sample note has been introduced to the score, written in by
hand. Results of processing are shown below.
([bass-drum 0.0 0.5]
[bass-drum 1.0 0.5]
[bass-drum 2.0 0.5]
[bass-drum 3.0 0.5]
[bass-drum 4.0 0.25]
[bass-drum 5.0 0.25]
[bass-drum 6.0 0.25]
[bass-drum 7.0 0.25]
[snare-drum 5.0 0.5]
[snare-drum 7.0 0.5]
[single-shot-sample 6.0 2.0])
convert-timed-score
provides users a way to organise score fragments
in time. The results from calling this function is a flattened note
list. This note list may in turn be assigned to a variable and used
within other calls to convert-timed-score
.
convert-measured-score
operates similarly to convert-timed-score
,
but uses the measure as a unit of time rather than a time value. The
measured-score is also a list, but begins with a :meter definition.
Following the meter, values may be either numbers or lists, just as in
timed-scores, but the numbers are interpreted as measure numbers. The following:
(def score
[:meter 4 4
0 bd-pattern
1 bd-pattern snare-pattern])
(println (convert-measured-score score))
shows an example usage of convert-measured-score
. The score reads as “with a 4/4
meter, at measure 0, play bd-pattern, and at measure 1, play bd-pattern
and snare-pattern”. Start time values for notes are interpreted as
beats, and beats map to quarter note values of the meter. The results
are shown below.
([bass-drum 0.0 0.5]
[bass-drum 1.0 0.5]
[bass-drum 2.0 0.5]
[bass-drum 3.0 0.5]
[bass-drum 4.0 0.5]
[bass-drum 5.0 0.5]
[bass-drum 6.0 0.5]
[bass-drum 7.0 0.5]
[snare-drum 5.0 0.5]
[snare-drum 7.0 0.5])
convert-measured-score
allows for multiple note lists to be
used per measure. Also, users may use in-lined, hand-written note lists
and function calls embedded within measure-scores just as they would
with timed-scores. For musical genres that use a regular, measured
framework of time, using convert-measured-score
may be more convenient
to use and think with than using convert-timed-score
. Choosing between
one or the other system of time will be dependent upon the user’s own
musical goals.
convert-measured-score
and convert-timed-score
simply process score
lists and generate a note list. The results of these functions may
themselves be further processed. This allows the user to mix usage of
each time system. For example, if one was working on a film score, one
could use measured-score to write the main music track and use a
timed-score to add sound effects according to clock time. The user could
then use concat
to merge the two scores together.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close