Happy Birthday Alvin Lucier

Happy Birthday Alvin Lucier - spectrogram of ten generations of re-recordings
Happy Birthday Alvin Lucier – spectrogram of ten generations of re-recordings

Just over 50 years ago, Alvin Lucier turned on his tape recorder and started to recite. This wasn’t an entirely unusual thing to do, but what he did next was a little different: he played that tape back, while recording it on another device. He kept doing this until all there was left was the ringing resonant frequency of the room, his voice smeared out of any recognizable sound. He called this piece I am sitting in a room, and it’s still a stunning work of sound art.

Alvin Lucier just turned 90 years old, so in recognition, I made this:

Many Happy Returns: for Alvin Lucier at 90

I don’t have a quiet room with two tape decks, but I do have a large plastic tote in which I can fit a whole bunch of battery-powered recording gubbins:

computer-based recording and playback equipment in plastic tote
my studio in a box. From L to R: Raspberry Pi 3A+, backup audio recorder, microphone stand, battery pack, microphone, USB audio interface, kalimba (for added resonance) and bluetooth speaker

After setting everything up and running, I put the box on my bed and covered it with several layers of blankets to keep our noisy neighbourhood sounds out. The initial audio was made in PicoTTS, and then playback and recording were controlled over wifi and VNC. I (or more accurately, the bash script I wrote) made 90 generations of recordings. I’ve only included the first 10 due to time constraints.

What I did

I guess I’ve been lucky with whatever audio system Raspberry Pi OS is using, because it recognized and used both my ancient Griffin iMic USB microphone adapter and my Sony Bluetooth speaker as default input/output devices.

One annoyance was having to build PicoTTS from source. Raspberry Pi OS doesn’t provide packages for it, but does have the source package. Building it goes something like this: Compile Pico TTS on Raspbian. You might prefer trying flite or espeak-ng, both of which have binary packages available.

I used this script, which may be rather too specific to my particular goal:

#!/bin/bash

parent=/home/pi/Desktop/sitting_in_a_box
gen0="$parent/box0.wav"
dest=${1:-$(date +%y%m%d%H%M)}
outdir="$parent/$dest"
mkdir -p "$outdir" && echo Created "$outdir"
n=0
outfile=$(printf "%s/%s_%03d.wav" "$outdir" "$dest" "$n")
tmpfile=$(printf "%s/%s_TMP.wav" "$outdir" "$dest")

# copy source file
sox -q --norm=-3 "$gen0" "$outfile"
while
    [ ! -f "$parent/STOP" ]
do
    infile="$outfile"
    n=$((n + 1))
    outfile=$(printf "%s/%s_%03d.wav" "$outdir" "$dest" "$n")
    echo Recording "$outfile" . . .
    arecord -f cd -q "$tmpfile" &
    rec_pid=$!
    echo Playing "$infile" . . .
    aplay -q "$infile"
    sleep 0.5
    kill -SIGINT "$rec_pid"
    echo Normalizing "$tmpfile" to "$outfile" . . .
    sox --norm=-3 "$tmpfile" -c 2 "$outfile" && rm "$tmpfile"
    echo ""
done
echo '***' Process stopped after "$n" iterations.

Some notes on the code:

  1. the script creates a folder for the output files, either as specified on the command line, or if not, from the current date/time
  2. I didn’t really know how many iterations I’d want, so I monitored occasional files by pulling them down using scp and listening. When I was satisfied, I’d create a file called STOP in the project folder that would make the loop exit
  3. $gen0 is the name of the source recording
  4. sox -q –norm=-3 infile outfile is a way of normalizing the audio so that it won’t clip
  5. We start the recording in the background (arecord … &) and immediately grab its process ID using $!. This allows us to stop the recording using kill after the audio file has played. arecord doesn’t update the file header when a process is stopped like this, so sox will complain quietly every time
  6. The sleep 0.5 after aplay is to prevent the recording cutting off. Both aplay and sox/play seem to exit as soon as the last block of audio data has been sent to the audio device, and not when the sound has stopped playing. This means you have to edit out increasingly longer gaps from your recordings, but at least you get everything.

What I’d do differently next time

  • Probably not used a Bluetooth speaker. Sure, they’re self-powered and you can’t complain about the number of wires, but they’re noisy and low quality
  • Done more work on the microphone interface. The pair of binaural mics I used to use with the Griffin interface (it’s stereo, unlike most USB interfaces) had a dead channel, so I had to fish around for other microphones. Somewhere I have a nice microphone from a Sony Pro Walkman, and I should have used that
  • Maybe considered a band-pass filter to cut the very high frequency ringing. Yes, I know the whole point of I am sitting in a room is to capture the room dynamics, but when you’re recording in a tiny space with very hard walls, the dynamics take over almost too quickly to be interesting
  • Spent more time on playback and record levels beyond the “hey, it works!” settings I used here
  • Used a higher bitrate recording. This might have resulted in more wolf-tones and ringing, though.

Mockingbird in the Rain

Northern Mockingbird (Mimus polyglottos) recorded at Centennial College Ashtonbee campus parking lot near Wexford Woods, 07:52 2020-04-13 (rain, handheld phone, noise filtered)

I went out for a very soggy bike ride this morning just to get out of the house. There were a few more people out than I expected, as it’s a regular work day for most people in Ontario. COVID-19 meant that most workplaces were shuttered.

Splashing through the puddles at Centennial College’s deserted Ashtonbee campus (round about here, if you need a precise location) I heard this mockingbird giving its very best performance. I only got a little over a minute of it, but in that time there was some American Robin, Gull, hawk of some kind and best of all (starting just after 40 s) car alarm.

Centennial’s got a big automotive section, and the empty parking lot’s usually full of cars. Mimus was just repeating what it usually heard. I wonder how long they’ll remember and replay car alarms after we’re gone?

PROTODOME’s wonderful chiptunes: how to play them on your own ATtiny85 chips

electronics breadbord with battery, speaker and sound generated by an 8-ping ATtiny85 mincrocontroller. Additional chips on the board are spares holding other tunes
Six whole tunes ready to play on this tiny chiptune player; a couple are included at the end of this article!

I love the ingenuity that goes into making very tiny projects do very big things. I also love chiptunes. So when I read the metafilter post about PROTODOME’s compositions for the ATtiny85, I was very much there for it.

The circuit to play this is no more than a $2 microcontroller, a lithium coin cell and a speaker or piezo buzzer. The microcontroller has 8 KB of program space and 512 bytes of RAM. The output is a single pin, but with very clever pulse width modulation tricks, sounds like three channels plus percussion.

The album is cool enough on its own, but Blake ‘PROTODOME’ Troise has not only published the source code, but also written an academic article on 1-bit music: “The 1-Bit Instrument: The Fundamentals of 1-Bit Synthesis, Their Implementational Implications, and Instrumental Possibilities.Journal of Sound and Music in Games 1.1 (2020): 44-74.

I remembered I had bought a tube of ATtiny microcontrollers a while back. I knew I had a coin cell and tiny speaker. “I can do this!”, I thought.

So what follows is tutorial on compiling embedded code for an ATtiny85 microcontroller on Linux. There are larger tutorials out there, there are better tutorials: but there are also many out-of-date and misleading tutorials. This isn’t a general ATtiny development tutorial, but one specialized on getting PROTODOME’s tunes playing on your microcontroller.

Hardware

The very minimum you will need to play the music is:

But that’s not all: you’ll need much more kit to program these tiny chips:

  • a computer running Linux. Yes, you can do this under Windows and Mac OS, but I don’t know how and there are search engines that care about that more than I do. I tested all of this on a Raspberry Pi 4. Tablets and phones are out, sorry
  • an AVR programmer. You can use an Arduino for this (either an official one or a cheaper clone) but you’ll need some additional fiddling and a 10 µF capacitor to get that going. I used a dedicated USBtinyISP programmer just because I had one, but it’s not really necessary. Whatever you use, you’ll need a USB cable for it
  • probably more jumper wires.

Software

There are two separate toolchains involved — one to build the mmml-compiler to convert PROTODOME’s compositions to µc embedded C code, and another to compile that to ATtiny85 instructions. We can install it all in one go:

sudo apt install avrdude gcc-avr binutils-avr avr-libc build-essential git

Building mmml-compiler is easy enough:

git clone https://github.com/protodomemusic/mmml.git
cd mmml/mmml-compiler
gcc -o mmml-compiler mmml-compiler.c

You can then run the compiler on each of the songs; the album title track, for example:

cd ../demo-songs/4000ad/
../../mmml-compiler/mmml-compiler 4000ad.mmml

⚠️ If you get [ERROR 14] Too few channels stated! instead of Successfully compiled! it seems that the compiler isn’t too happy running on some 64-bit systems. I did all my compilation on a Raspberry Pi 4 running Raspbian and all was well. If you can’t get them to compile, I’ve pre-compiled them for you and they’re at the end of this article.

You should now have a musicdata.h file that contains all the tune data. Copy it to the same folder as the mmml-player C code:

cp musicdata.h ../../mmml-player/
cd ../../mmml-player/

That folder now contains the player and one tune data file. Now you need to compile it into AVR instruction to write to your chip:

avr-gcc -g -Os -mmcu=attiny85 -DF_CPU=8000000 -o mmml.bin mmml.c
avr-objcopy -j .text -j .data -O ihex mmml.bin mmml.hex
rm mmml.bin

The end result of what that just did is create a single small file mmml.hex containing the ATtiny85 program instructions for the 8+ minute track 4000AD. If you’re compiling for a different µc, you’ll need a different avr-gcc line:

  • -mmcu=attiny85 will need to be changed for your µc. avr-gcc –target-help lists the supported targets in the ‘Known MCU names’ section way up at the top of its too-copious output. If you’re using the ATmega32P chip made popular by Arduinos, that option should be -mmcu=atmega328p
  • -DF_CPU=8000000 tells the compiler that the CPU frequency should be 8 MHz. The AVR µcs can run at a huge range of speeds, but PROTODOME’s music is timed to work at 8 MHz only.

→→→ aside

If you find yourself compiling a few simple AVR projects but want to stop short of a fine-but-overly-complex Makefile project for AVR development, this script to create a hex file from a single embedded C source file might be useful:

#!/bin/bash
# avrbuild.sh - build a simple AVR project - scruss, 2020-04
# usage: avrbuild.sh file.c mcutype freq
# eg: avrbuild.sh mmml.c attiny85 8000000

b="${1%.c}"
rm -f "$b.bin" "$b.hex"
avr-gcc -g -Os -mmcu="$2" -DF_CPU="$3" -o "$b.bin" "$b.c"
avr-objcopy -j .text -j .data -O ihex "$b.bin" "$b.hex"
avr-size --format=avr --mcu="$2" "$b.bin"
rm -f "$b.bin"

In addition to creating a hex file, it also runs the avr-size tool to show you much memory your program uses. The 4000AD tune uses 98% of the ATtiny85’s 8192 byte program space — not quite enough to include that 14 minute extra bass solo, sorry …

←←← end aside

Flashing the chip

So now we do some wiring. If you’re using a dedicated programmer, use jumpers to connect its ICSP port to the ATtiny 85 like this:

                        ________              
                       |o   A   |             
               Reset  -+ 1  T  8+-  VCC       
                       |    t   |             
                      -+ 2  i  7+-  SCK       
                       |    n   |             
                      -+ 3  y  6+-  MISO      
                       |    8   |             
               GND    -+ 4  5  5+-  MOSI      
                       |________|             
                                              

                 MISO    o1 2o   VCC   
                 SCK     o3 4o   MOSI     
                 Reset   o5 6o   GND 

                          ICSP
                        Connector

Wire VCC to VCC, MISO to MISO, MOSI to MOSI, SCK to SCK, Reset to Reset and GND to GND. If you’re using an Arduino, you want to do this:

This is ‘OLD_STYLE_WIRING’ for using ArduinoISP, apparently. But it works!

The wiring for that is:

  • Arduino D10 → ATtiny Pin 1 (Reset)
  • Arduino GND → ATtiny Pin 4 (GND)
  • Arduino D11 → ATtiny Pin 5 (MOSI)
  • Arduino D12 → ATtiny Pin 6 (MISO)
  • Arduino D13 → ATtiny Pin 7 (SCK)
  • Arduino 5V → ATtiny Pin 8 (VCC)
  • You’ll also need to put a 1-10 µF electrolytic capacitor between the Arduino’s Reset and GND pins, but only after you’ve programmed it with the ArduinoISP sketch.

You’re almost there!

Setting up the programmer: USBtinyISP

If you haven’t used one with your computer before, you need to do a little bit of prep so your computer recognizes it. These are modified from a gist:

  • do sudo vi /etc/udev/rules.d/41-usbtiny.rules
  • add the line SUBSYSTEM=="usb", ATTR{idVendor}=="1781", ATTR{idProduct}=="0c9f", GROUP="plugdev", MODE="0666"
  • save and exit
  • do sudo udevadm control --reload then sudo udevadm trigger

Your system should automatically recognize the device and give you permission to use it without sudo privileges.

Setting up the programmer: ArduinoISP

  • Load the ArduinoISP sketch (it’s in FileExamples)
  • Add (or find and uncomment) the line #define USE_OLD_STYLE_WIRING
  • Upload the code to your Arduino
  • Connect the 1-10 µF electrolytic capacitor between the Arduino’s Reset and GND pins

To program the mmml.hex you created earlier, you’ll need one of these avrdude commands:

For USBTinyISP:

avrdude -c usbtiny -p attiny85 -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xff:m -U flash:w:mmml.hex:i

For ArduinoISP:

avrdude -c arduino -P /dev/ttyUSB0 -b 19200 -p attiny85 -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xff:m -U flash:w:mmml.hex:i

What all that means:

  • -c usbtiny or -c arduino: programmer type. In addition, the arduino programmer takes additional parameters -P /dev/ttyUSB0 -b 19200 which specify the port (usually /dev/ttyUSB0 or /dev/ttyACM0) and the baud rate (always 19200, unless you changed it in the source of ArduinoISP)
  • -p attiny85: the chip type, as used in the avr-gcc compiler call way up the top
  • -U lfuse:w:0xe2:m -U hfuse:w:0xdf:m -U efuse:w:0xff:m: fuses are AVR’s confusing name for configuration bits. You might just have to take my word that this sets an ATtiny85 to use the internal 8 MHz oscillator (as opposed to an external crystal) we told the compiler to use further back. A guide to fuse settings is available at the Engbedded AVR Fuse Calculator
  • -U flash:w:mmml.hex:i: the hex file we prepared, mmml.hex.

If everything went right with your flashing process, you should see lots of “avrdude: verifying … done. Thank you”. If you don’t, likely you missed a connection somewhere.

♫ Playing the tunes! ♫

This circuit’s a lot simpler than it looks!

I already described all of the bits in the bill of materials in the Hardware section. If you want it in ASCII art, here’s all there is to it:

                        ________              
                       |o   A   |             
          VCC--(10kΩ)--+ 1  T  8+--VCC        
                       |    t   |             
                      -+ 2  i  7+-            
                       |    n   |             
                      -+ 3  y  6+-      (     
                       |    8   |      ((     
                  GND--+ 4  5  5+--(SPKR(--GND
                       |________|      ((     
                                        (     

          Pin 1: RST - held high through pull-up to prevent reset
          Pin 4: GND
          Pin 5: PB0 - through speaker/buzzer to GND
          Pin 8: VCC - can be a CR2032 Lithium coin cell

          Not shown: 100 nF decoupling capacitor between VCC and GND
          Short Pin 1 to GND to restart song

If you weren’t able to compile the tunes, I’ve included (with Blake’s permission) source for any AVR µc plus hex files for ATtiny85s here: protodome-mmml-examples.zip

Last but not least, there are a couple of tracks included in the source that aren’t on the 4000AD album. Blake gave me permission to include them here, too:

Fly Me to the Moon by Bart Howard, arranged for ATtiny85 microcontroller by PROTODOME, 2020.
Download: fly_me_to_the_moon.mp3
Till There was You by Meredith Willson (from the musical ‘The Music Man’), arranged for ATtiny85 microcontroller by PROTODOME, 2020.
Download: till_there_was_you.mp3

These weren’t recorded from a tiny speaker (that went badly), but directly to a Marantz solid state recorder. The rig’s the same as the playback one, with the speaker replaced by a potentiometer (for level control), a 100 µF capacitor (to take off some of the DC bias and also to cut some of the very high frequencies) and a headphone socket. Have fun!

it’s the most awkward walkman!

Ringing like 1984: Western Electric “Princess”

Western Electric “Princess” compact telephone from 1984

I got this phone at a junk swap event. It had a broken handset jack, but I got a replacement from OldPhoneWorks.

It has a distinctive, loud ring:

(Alternative Freesound link: Western Electric Princess Telephone Ringing)

That’s a lot of noise from a small phone!

Western Electric “Princess” compact telephone ­— base. Note mid-1984 production date: after the US Bell breakup

If you want the ringtone for your phone, here it is as an Ogg file for Android: WesternElectric-Princess_Ring-mobile.zip

Western Electric “Princess” Telephone Ringing
Recording © 2018, Stewart C. Russell — scruss.com

provided under the Creative Commons — Attribution 2.5 
Canada — CC BY 2.5 CA licence:
https://creativecommons.org/licenses/by/2.5/ca/

The Yonge & St Clair Autoharp Guy

This guy sets up on the SE corner of Yonge & St Clair most afternoons, and plays endless variations on the above recording. He’s playing an autoharp with the chord bars removed, and run through a homebrew battery-powered amplifier with much reverb and distortion. A bunch of the burbly noises are 8kbit/s voice recorder artifacts from my phone.

Although the themes seem repetitive, I don’t think they repeat exactly every time. He seems to be in a happy place playing them.

More fun with plotters: graphing, simplifying, and random noises …

  1. If you go to the Incompetech Multi-Color Graph Paper PDF Generator and set the grid spacing to 0.4, 0.8 and 4 lines/cm, you get a nifty HP-GL unit grid with major lines at 1000 units (25 mm), intermediate lines at 500 units (12½ mm) and minor lines at 100 units (2½ mm):
    hpgl-grid-web
  2. By a very roundabout route, I used GDAL’s simplify function to half the line count of my hypotrochoid plots with little visible degradation. The optimised page took far less time to plot:
    hypo1
    hypo2
    Next time, I’d definitely use Shapely instead of messing about with GIS formats. Who knows, I might even integrate it into Chiplotle. Eventually. (Update: though I have some code that does something …)
  3. Plotters are resolutely electromechanical devices. They turn digital command into analogue output, but my one never sounds too happy doing it. It grumbles, sighs and even moos as it plots. A recent plot sounded a bit like this: .

Raspberry Pi as a USB audio capture device

The Raspberry Pi’s hardware and software support has come a long way in the few months it has been in the wild. I first tried this application in the summer, and the results were dismal. Now, thanks much improved USB driver support under Raspbian, I’m pleased to say it works flawlessly.

Earlier this year, I bought a turntable (ack!) for transferring vinyl to mp3. I have a TC-772 USB phono preamp, which spits out a 48 kHz stereo audio stream. If you plug the USB output of the preamp into a Rapberry Pi (running Raspbian Wheezy with all the updates), it’s instantly recognized as an audio device:

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. 
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
Bus 001 Device 004: ID 08bb:2902 Texas Instruments Japan PCM2902 Audio Codec

If you install the ALSA recording utilities (sudo apt-get install alsa-utils pulseaudio – this should pull in a whole bunch of necessary packages), you can record directly from this device with the following command:

arecord -D 'pulse' -V stereo -c 2 -f dat -d 900 out.wav

which records from the ‘pulse’ audio device, displaying a stereo text VU meter (handy for setting levels), writing to a two channel 16-bit 48 kHz file called ‘out.wav’ for a maximum of 900 seconds (15 minutes). arecord has a baffling number of recording source options; arecord -L will show them. ‘pulse’ was the first one I tried.

So how does it sound? Here’s a 30 second excerpt from the only single I owned for years, The Music Tapes‘ “The Television Tells Us/Freeing Song by Reindeer”: Freeing Song by Reindeer – excerpt [mp3]. I’ve saved an even smaller snippet as lossless FLAC so you can see that the waveform’s pretty clean: FreeingSongbyReindeer-tiny_excerpt [flac].

Sounds pretty good. Not quite as good as having Julian play it in your house, I’ll allow, but not bad for a first try with a $35 computer.

the happiest sound

Click image for sound [mp3].

That’s the rapid clatter of chopping up Kothu Roti at Amma at the end of our street. You know that tasty spicy food is imminent when you hear that sound. I’m really pleased that Amma’s back under the original management. The other proprietors just didn’t care as much about their food.

“Go scratch a rock on some congealed oil and tell me what it sounds like”

I’m either getting old or conventional, ‘cos I bought something I said I would never have enough time or space for: a turntable. I won’t forsake my beloved MP3s, but there are somethings you just can’t get electronically. One of them being the 1981 Stampfel & Weber album “Going Nowhere Fast”, which I snagged from Etsy from a west coast seller.

I bought an elderly Technics from Ring Audio, and set it up with a USB phono preamp from Phonopreamps.com. It sounds good, I guess. It certainly sounds different from MP3s, but better …? Dunno. My two cynical theories hypotheses of vinyl snobbery are:

  1. The more you have invested in your system, the more confirmation bias tells you it sounds better.
  2. Vinyl is the record industry’s last-gasp attempt attempt at relevancy, because you can’t home-cut your own discs. As there’s always analogue loss in ripping from vinyl, it’s self-policed rights management by the sound quality snobs. Imagine that: DRM conditioned into the listeners themselves!

I have not got a lot of records:

Albums

  1. Going Nowhere Fast — Stampfel & Weber
  2. The Holy Modal Rounders
  3. The Holy Modal Rounders 2 (are you sensing a pattern here?)
  4. Acedia — Black Walls

Single-ish Things

  1. The Television Tells Us / Freeing Song by Reindeer — The Music Tapes (Julian sent me this in 1998, and I think this is the first time I’ve played it. For a few days, it was the only record I had, and it was merciful that Catherine was away, as she only has a normal human tolerance for this sort of thing)
  2. Ghetto Kitty Island Split 7″ – featuring Chicken on a Raft, Of Montreal, Bart Davenport and The Minders.

Speaking of which, I understand that the latter EP is not exactly widely known, is totes OOP, and completists might dig Of Montreal‘s ”Epistle to a Pathological Creep (demo)”, so here it is ripped for your listening pleasure:

Ghetto Kitty Island Split 7" (2004)I recorded it with arecord, and edited it with Audacity.  The arecord command line (more for my reference than your interest) was:

arecord -D 'hw:CARD=CODEC,DEV=0' -V stereo -c 2 -f dat -d 900 ghettokittyisland.wav

which records 900 seconds of audio at DAT quality to the file ghettokittyisland.wav, while showing a simple text meter on the screen.