command allows a Humdrum spine to be broken apart into two or more spines.
Different pieces of information can be distributed to the individual
Consider for example the following spine containing
The rend command might be used to structure this as three independent spines:
Ab3 F#4 C5 *-
The operation of rend requires a reassignment file where each line contains an output exclusive interpretation, followed by a tab, followed by a regular expression. In the above case, the reassignment file (
**note **accidental 3 Ab b 4 F# # 5 C . *- *- *-
reassign) contained the following:
[0-9] **note [A-Gb#x] **accidental [b#x]
The first line tells
that any signifiers matching the character-class 0-9 should be
output in a spine labelled
The second line causes signifiers matching the upper-case letters A to G
x signifiers to be output
in a spine labelled
The third line causes signifiers matching
x to be output
in a spine labelled
The above output was generated by invoking the following command:
rend -i '**pitch' -f reassigninputfile
Note that the -i and -f options are mandatory. The -i option tells rend which input spines to process and the -f option tells rend the name of the file containing the spine-reassignments.
The rend command is typically paired with a subsequent cleave command.
The cleave command amalgamates concurrent data tokens in two or more spines into a single data spine. In effect, cleave does the opposite of rend. By way of example, cleave can be used to transform the following:
**B **C a b c A B C *- *- *-
Specifically, the above "cleaving" would be done using the following command:
abc ABC *-
cleave -i '**A,**B,**C' -o '**new'inputfile
options are mandatory.
which exclusive interpretations should be cleaved together.
In the above case, we have provided a list of three types of data.
what to call the resulting cleaved spine.
In this case, we've simply called the result
Suppose that we would like to automatically add key-velocities
data that reflect the normal accents arising from the meter.
For example, in 4/4 meter, we would like the first note in
each measure to be strongest, the third beat to be next
most strongest and so on.
**MIDI data tokens consist of three
elements: (1) the duration in MIDI clock ticks,
(2) the key number (also on/off indication), and
(3) the key velocity.
In order to add accents, we need to change the key velocity values.
The maximum MIDI key velocity value is 127;
the minimum value is 0; and the default value is 64.
Consider the following hypothetical input file:
The metpos command can be used to identify the metric position of various note onsets. Before using metpos however, we must use the timebase command to create an isorhythmic record structure. Since the shortest note is an eighth-note, the appropriate command is as follows.
*M4/4 =1- 4c 8d 8e 8f 8g 8a 8b =2 2cc *-
timebase -t 8 scale > scale.tb
Using the timebased output, we can then invoke the metpos command:
metpos scale.tb > scale.met
The resulting output contains both the original input (on the left) and the metric position spine (on the right):
Let's now eliminate the null data tokens introduced by timebase. Using humsed, we delete each data record beginning with a period character:
**metpos *M4/4 *M4/4 *tb8 *tb8 =1- =1- 4c 1 . 4 8d 3 8e 4 8f 2 8g 4 8a 3 8b 4 =2 =2 2cc 1 . 4 . 3 . 4 *- *-
humsed '/^\./d' scale.met > scale.tmp
Next, we can use the
command to change the metric position values to appropriate MIDI
We might use the following reassignment file (named
==1 100 ==2 80 ==3 60 ==4 40 else error
In applying recode we will take care to avoid processing measure numbers using the -s (skip) option:
recode -f accent -s ^= -i '**metpos' scale.tmp > scale.acc
The output will now appear as follows:
Now we can use the midi command to generate
**metpos *M4/4 *M4/4 *tb8 *tb8 =1- =1- 4c 100 8d 60 8e 40 8f 80 8g 40 8a 60 8b 40 =2 =2 2cc 100 *- *-
The result is given below:
midi scale.acc > scale.mid
Before using cleave to join the new key velocity values to the
**metpos *Ch1 * *M4/4 *M4/4 *tb8 *tb8 =1- =1- 72/60/64 100 72/-60/64 72/62/64 60 36/-62/64 36/64/64 40 36/-64/64 36/65/64 80 36/-65/64 36/67/64 40 36/-67/64 36/69/64 60 36/-69/64 36/71/64 40 =2 =2 36/-71/64 36/72/64 100 144/-72/64 . *- *-
**MIDIdata we need to delete the current key-down velocities. These are the values `64' preceding the tab character. The humsed command can be used as follows:
/' scale.mid > scale.tmp
The modified output will now be:
Finally, we use cleave to add the new key-down velocities.
**metpos *Ch1 * *M4/4 *M4/4 *tb8 *tb8 =1- =1- 72/60/ 100 72/-60/64 72/62/ 60 36/-62/64 36/64/ 40 36/-64/64 36/65/ 80 36/-65/64 36/67/ 40 36/-67/64 36/69/ 60 36/-69/64 36/71/ 40 =2 =2 36/-71/64 36/72/ 100 144/-72/ . *- *-
cleave -i '**MIDI,**metpos' -o '**MIDI' scale.tmp > scale.mid
The final output is:
* *M4/4 *tb8 =1-=1- 72/60/100 72/-60/64 72/62/60 36/-62/64 36/64/40 36/-64/64 36/65/80 36/-65/64 36/67/40 36/-67/64 36/69/60 36/-69/64 36/71/40 =2=2 36/-71/64 36/72/100 144/-72/ *-
For some analytic tasks it is often useful to generate a special representation
that combines all of the elements or types of data of interest to the researcher.
For example, suppose we were working on a model of melodic organization that
reduced melodies to three types of information:
relative-duration context, gross pitch height, and scale step.
Sample data tokens for our representation and their meanings are given in
the following table.
Notice that the order of signifiers is important:
In Chapter 22 we learned how to use recode to classify various numerical ranges and humsed to classify non-numeric data. We already know how to create the elements of our new representation.
long-short-long rhythm, high pitch, tonic
long-long-short rhythm, low pitch, subdominant
medium-long-short rhythm, medium pitch, leading tone
The scale degree information can be created by using
can be used to transform the signifiers as in the following
We can classify the pitch ranges into high, medium, and low
command, followed by recode.
For example, we could transform the
data using the following reassignment file:
L >16 H >=0 M else r
Durations can be similarly classified into long (L), medium (M), and short (S) using the dur command, followed by recode.
L >0.5 M >0 S
Using context -n 3 we could then create contextual `triples' so that data records contain three durations. Suppose also that we have used sed to change the names of the exclusive interpretations so they are more appropriate. As a result we have three spines that, when assembled together are organized as in Example 26.1
We need to process the first spine with humsed again to eliminate the spaces in the multiple stops. The rhythm spine would be processed as follows:
**range **scale-step L S L H to L L S L sd M L S M lt r r r *- *- *-
humsed 's/ //g' rhythm > rhythm.new
We could assemble these spines using the assemble command:
assemble rhythm.new range scale.step > newfile
Finally we can use cleave to amalgamate all of the data into a single final spine.
cleave -i '**rhythm,**range,**scale-step' -o '**complex' \newfile > output
Having created our new representation, we can continue to process this new data with the various Humdrum tools. For example, we could generate inventories that answer questions such as "How often does a high subdominant note in a long-short-long rhythmic follow a low submediant in a long-long-short context?
A similar approach can be used to address other questions, such as whether large leaps involving chromatically-altered tones tend to have a longer duration on the altered tone. Etc.
In this chapter we have seen how rend and cleave can be used to take bits and pieces of signifiers from potentially many spines, and assemble a composite Humdrum spine that contains precisely the information of interest. Before amalgamating spines, you can use the humsed command to translate the characters/signifiers so that you use your preferred way of representing something.