> index > recordings > mother of vinegar > "degradation" scripts


lllllllldlllllllldlllllllldlllllllldlllllllldlllll
llllldOKOlllllokKOlllllokKKlllllox0Xllllllx0Xollll
llokKXXXOlllx0XXXOlllx0XXXKlllx0XXXXllldOXXXXolldO
x0XXXXXXOx0XXXXXX0xOXXXXXXKdOXXXXXXXdOKXXXXXXxkKXX
XXXXXXXXXXXXXXXOdolc::;;;;;::cclodkXXXXXXXXXXXXXXX
XXXXXXX0d:'.  ... .' .: :, ;. '. .,c' .,cdKXXXXXXX
XXXXKc.  .. ,' ,; ': .c :, c. :' ;, ', ..  ,lXXXXX
XXXXkoOkoOkoOkokOokOoxOoOkoOxoOkdOkokOokOokOoOXXXX
XXXXl .. ,. ;, ,; ': .c :, c. :' ;, ,; ., .. dXXXX
XXXXXKd;.    .,,. ., .c :, c. ;' ..      .:xXXXXXX
XXXXXXXXXKOddK0,.                .,OxldOXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXK00000000KXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Degradation scripts


This page lists the programs used to generate the audio in two Mother of Vinegar streams. While every other stream in that project uses one particular commercial "digital audio workstation" program to sequence and synchronize samples, the two "Degradation" streams (nos. 036 and 039) feature individual snippets of audio processed with computer scripts of my own design, written and invoked in my computer's terminal emulator. I am not a programmer by trade and these are among the first computer programs I ever put together. MP3 audio of the streams can be downloaded through links below.

With every pass of the loop, junk data replaces an increasingly larger portion of the audio file, leading to unpredictable distortion and drop-outs. This was intended to represent, in an accelerated way, the processes by which digital media storage systems fail to reproduce the data written to them as they decay, an experiment exploring counterexamples to the widespread overly-sentimentalized use of contrived recordings of decaying analogue audio recordings -- that is, recordings of or simulating decaying audio tape or phonograph discs.




From MOV-036, "Degradation":


degrade.sh

00: while :
01: do
02:     afplay 00.wav
03:     shred -n 1 -s 1 foo.txt
04:     python rand.py
05:     cat bar.txt
06:     printf "\n"
07: done


This is a simple shell script with an infinite loop; see the "Shell Scripts" and "Looping Constructs" sections of the GNU Bash Reference Manual.

"afplay" in line 02 is "audio file play," the Darwin (Mac OS) equivalent of the Linux "aplay" command, used to play an audio file from the command line; unlike aplay, afplay returns an error if the file is not recognized as audio.

Line 02 plays "00.wav," then in line 03 the "shred" command is used to write a random byte to "foo.txt"; see the "shred" section of the GNU Coreutils Reference Manual.

Line 04 invokes the Python script "rand.py," reproduced below, which deletes a portion of "00.wav," selected at random, and writes the contents of "foo.txt" in its place; the amount of 00.wav that gets deleted increases with each iteration of the loop.

Line 05 prints the value of a counter ("bar.txt"), incremented by "rand.py," showing how many times the loop has been invoked. Line 06 prints the "new line" character so the value of the counter prints on a new line each time.

Each file to be processed with this script I copied manually to "00.wav," then I executed the script, breaking the loop manually with Control-C once afplay began returning an error, then manually resetting the counter with the "echo" command before copying the next file to be "degraded" to "00.wav" and starting the process over again.


rand.py

00: import random
01: infile=open("foo.txt")
02: f=infile.read()
03: infile.close()
04: infile=open("bar.txt","r")
05: n=infile.read()
06: infile.close
07: x=(int(n)*10)
08: n=(int(n)+1)
09: outfile=open("bar.txt","w")
10: outfile.write(str(n))
11: outfile.close
12: infile=open("00.wav","r")
13: s=infile.read()
14: r=random.randrange(len(s))
15: t=s[:r]+f+s[r+x:]
16: outfile=open("00.wav","w")
17: outfile.write(t)


This is the Python script invoked by "degrade.sh," reproduced above.

Line 00 imports the Python module "random," which contains functions for generating pseudo-random numbers.

Lines 01-03 read the contents of "foo.txt" (a random byte generated in "degrade.sh" above, line 03) and store it as variable "f" for use in line 15; lines 04-06 do the same for "bar.txt," which contains the value of the counter.

Line 07 sets variable "x" at ten times the value read from "bar.txt," then lines 08-11 increment the counter by one and write the new value back to "bar.txt"; lines 12-13 read "00.wav" and store it as variable "s"; line 14 gets a random location within "s" and stores it as variable "r."

Line 15 replaces "x" bytes at point "r" within "s" with the random byte "f," storing the result as a variable ("t") that lines 16-17 then write back to "00.wav"; the amount removed from the audio file thus gets larger with each pass through the loop.



From MOV-039, "Degradation 2":


degrade-2.sh

00: select fname in *;
01: do
02:     echo degrading $fname \($REPLY\)
03:     cp $fname 00
04:     echo Copying $fname to 00...
05:     sleep 2
06:     gls -sh1 --color="auto" $fname 00
07:     sleep 2
08:     break;
09: done
10: echo 0 > counter
11: while afplay 00;
12: do
13:     shred -n 1 -s 1 foo
14:     python rand-2.py
15:     cat counter
16:     printf "\n"
17: done
18: echo 0 > counter
19: sleep .5
20: printf "Done\n"
21: sleep 2
22: gls -sh1 --color="auto" $fname 00
23: sleep 2


This script puts more of a "user interface" on top of "degrade.sh" above; while it still always operates on the same file, lines 00-09 prompt the user to select a file from the current directory when the script is invoked, then copies the selected file to the file on which the script operates, while previously I was manually copying the audio to the target file.

Line 06 displays the size of the selected file compared with the target file (which should be close to zero, having previously been "degraded"); the command "gls" in this line and line 22 specifies the GNU Coreutils implementation of the Unix command "ls," rather than the old BSD version that comes with Mac OSX; for more information see the "ls" section of the GNU Coreutils Reference Manual. Line 10 automates resetting the counter, which I'd also been doing manually before.

Lines 11-17 refine the method used in "degrade.sh" above. Now the "afplay" command is part of the loop condition, so the loop breaks automatically when it returns an error. Line 13 writes a random byte to "foo," exactly as above in "degrade.sh," line 03; line 14 then invokes the Python script "rand-2.py," reproduced below.

Line 15 prints the counter, then line 16 prints a new line, exactly as above in "degrade.sh," lines 05-06. Line 18 resets (echoes "0" back to) the counter (redundant with line 10); lines 19-23 print the word "Done" and then again displays the size of the selected file alongside that of the target file, showing how much data has been lost.


rand-2.py

00: import random
01: import os
02: infile=open("foo")
03: f=infile.read()
04: infile.close()
05: infile=open("counter","r")
06: n=infile.read()
07: infile.close
08: x=(int(n)*10)
09: n=(int(n)+1)
10: outfile=open("counter","w")
11: outfile.write(str(n))
12: outfile.close
13: infile=open("00","r")
14: s=infile.read()
15: r=random.randrange(len(s))
16: t=s[:r]+f+s[r+x:]
17: outfile=open("00","w")
18: outfile.write(t)


The only differences between this script and "rand.py" above are the replacement of the names of the files it operates on with ones that lack filename extensions: "foo.txt" is now just "foo," "bar.txt" is now "counter," and "00.wav" is now just "00." Additionally line 01 specifies the Python module "os," but as the rest of the lines contain all the same functions as the older script, I cannot remember why I did this. Refer to the notes on "rand.py" above for a more detailed explanation.


The code on this page is made available under the terms of the latest version of the GNU General Public License.

The text pattern at the top of the page was generated from an image with the program jp2a.



back to mother of vinegar // back to home page




> index > recordings > mother of vinegar > "degradation" scripts



( version history )