Sedsongs

From XPUB & Lens-Based wiki

This exercise explores how the pipeline can be used to translate textual data (in this case the numbers of the current date and time) into a short musical sequence.

timidity

MIDI is a file format (and general protocol for communication between keyboards and synthesizers) that was created in the 1980s. Timidity is a good program to play midi files. Here is a sample file (File:I.mid). Play with:

timidity I.mid

midge

The MIDI file format is a binary one. This means that you need special tools that understand the format to work with them (create / modify). [seq24] is one such tool.

Midge is a program that tranlates a (plain) text file in a particular markup language, into a playable (binary) midi file. This lets us work simply with text as a means of producing a MIDI song.

According to midge's special notation / markup, a very simple song would be:

@head {
    $time_sig 4/4
    $tempo 120
}
@body {

    @channel 1 {
        $patch 1
        $octave 4
        $length 16
        
        # notes here!
        c e g
        
    }
}

(For more example files, see the examples that come with midge. Where are those? Try the command:

dpkg --listfiles midge

to see and look for the .mg files)

To prepare the midi file, you'd type the following command (assuming the above is called "song.mg":

midge song.mg

This produces an output file (if there were no errors), called "a.mid.out". You can choose a nicer name with the -o option:

midge song.mg -o song.mid

sed

sed is one of the most powerful (if sometimes cryptic) commandline program. In this case we create a "sed script" (text file with a list of commands) to perform a number of search and replaces. In each case the rule takes the form:

s/a/b/g

Which means, search for "a", replace with "b", and replace all (the "g" or global option).

Below, the rules replace each digit with a tone (from c to a sharp). The first rule means "replace anything that isn't a number with nothing" (ie delete them).

s/[^0123456789]//g
s/1/c /g
s/2/c+ /g
s/3/d /g
s/4/d+ /g
s/5/e /g
s/6/f+ /g
s/7/g /g
s/8/g+ /g
s/9/a /g
s/0/a+ /g

You can run this sed script (assume it's called "digits.sed") with:

sed -f digits.sed

This will then wait for you to type some input, type something like:

123123 111 222 333

And press Ctrl-D and see what happens.

Note that extra spaces are added so that each note is separated as midge requires.

wrap.sh

This is a simple script that outputs the midge file header, then outputs whatever is coming through the pipeline (stdin) -- this is the lone "cat" command, and finally outputs the end of the midge file format. In other words, when you pipe some notes into this script, you get a simple complete midge file.

cat <<EOF
@head {
    \$time_sig 4/4
    \$tempo 120
}
@body {
 
    @channel 1 {
        \$patch 1
        \$octave 4
        \$length 16

        # notes here!
EOF

cat

cat <<EOF
    }
}
EOF

pipeline

date | sed -f digits.sed | bash wrap.sh | midge -o sed.mid
timidity sed.mid

Sedsongs.png

File:Date.ogg

looping

To here what happens over time, the following script runs the command 30 times, renames each file to a numbered file, then uses the oggCat tool to join all the files to a single audio file. [1]

for ((i=0; i<30; i++))
do
date | sed -f digits.sed | bash wrap.sh | midge -o date.mid
timidity date.mid -Ov
mv date.ogg date$(printf '%02d' $i).ogg
done
oggCat dateloop.ogg date*.ogg

The result: File:Dateloop.ogg