I’ve been re-reading Curtis Rodes’ excellent Microsound again recently. It’s packed with all sorts of useful information, and is one of those books that I find myself coming back to time and time again.
In chapter 5, Roads discusses micromontage. Micromontage is a process of composing a sequence of sounds from one or more source files. Whilst it may share some similarities with music concrete, it operates on a much finer scale. In a micromontage, sounds are typically much shorter, often less than 100 milliseconds each. Despite working on a similar time-domain to granular synthesis, micromontage can afford a composer a much greater level of control over the choice and placement of sounds. This control can come at a heavy cost. Manually slicing and mixing back hundreds or thousands of sounds is a process that requires both patience, and an ability to think at both the scale of the sound being placed, and the overall piece.
The below script attempts to create a dumb micro micromontage; it takes slices of an input sound file, and stitches them together into a single sound file.
The aesthetics of the resulting file can be somewhat uninspiring; the output file bears the hallmarks of the input file, due in main to the way in which the output file is constructed:
- The chosen duration range means that slices are (generally) perceptible as distinct sounds
- The method of stitching doesn’t alter slices before stitching them together
- The method of stitching doesn’t include the ability to stitch silence into the output file
- The montage has a single layer; slices sit next to one-another rather than on top of one-another
- The micromontage is made up of parts of a single file, rather than parts of multiple files
Nevertheless, the script is an interesting experiment in what can be done on the command-line using simple tools.
A sample of the output can be found here
#!/bin/zsh
# MICRO-MONTAGE #################
# JL 17-05-17 #
# Creates a montage of a given #
# file see below for usage #
#################################
info='MICRO-MONTAGE\n-------------
Takes audio file, reorders slices of it to specified length
if not specified, outfile = "output.wav", length = 60 seconds
USAGE:
$0 [infile] [outfile] [length(seconds)]'
if [ -z $1 ]; then
echo $info
else
infile=$1 #make the remaining code a little easier to read
inLen=${$(((`soxi -D $infile`*1000)-1))%.*}
if [ -z $2 ]
then
outfile=output.wav
else
outfile=$2
fi
if [ -z $3 ]
then duration=60
else
case $3 in
''|*[!0-9]*) echo 'not an integer, using default value';
duration=60 ;;
*) duration=$3 ;;
esac
fi
##Variables!
curSlice=0 #current slice, useful for
curDur=0 #rolling duration of the output file
temp=temp.wav
while (( $(echo "$curDur < $duration" |bc -l) )); do
currentfile=$curSlice.wav
##select a grain from the infile
# range suggested by Roads.
trima=`shuf -i 0-$inLen -n 1` ##arbitrary point in file
# grain=`shuf -i 20-200 -n 1`
grain=`shuf -i 0-$(($inLen/16)) -n 1`
if (( (trima+grain) < inLen )) then;
trimb=$((trima+grain))
else
trimb=$((trima-grain))
fi
##WHICH IS LARGER TRIMA OR TRIMB?
##SMALLEST BECOMES START, LARGEST BECOMES FINISH
if (( trima > trimb )); then
grainEnd=`echo "scale=2;$trima/1000" |bc`
grainStart=`echo "scale=2;$trimb/1000" |bc`
else
grainStart=`echo "scale=2;$trima/1000" |bc`
grainEnd=`echo "scale=2;$trimb/1000" |bc`
fi
grainLen=$((grainEnd-grainStart))
sox $infile $currentfile trim $grainStart $grainLen
echo $curSlice $grainStart $grainLen
if [ $curSlice = 0 ]; then
cp $currentfile $outfile
else
sox $temp $currentfile $outfile
fi
cp $outfile $temp
rm $currentfile
((curSlice=curSlice+1))
curDur=`soxi -D $outfile`
done
fi
rm $temp