Meteor
What is it?
Meteor is a song in Pure Data constructed from the coordinates of meteorite
landings in the 1980’s.
There are 50 usable meteorite landings to make music from. Each
meteorite landing has a coordinate associated with it. This coordinate is
converted to a frequency and played over a period of time. These frequencies are
stored outside of Pure Data in text files helping decouple the logic from the
data.
The patch
There are 5 voices going off at any one time. Since there are 50 entries, each
voice can have an entry and repeat 10 times before the song is over.
Underneath the voices is a constant 75hz drone being LFO’d to the BPM of the
song. Coupled with this is a wind-like noise. The wind is a sine wave at 440hz
being modulated by low-passed noise.
Data
In order to get any meaningful audio from the data used for the landings, it was
necessary to clean and normalise the audio.
The data for these landings was obtained from wolframcloud.
Cleansing
Once the data was downloaded, it was necessary to clean it to extract what we’re
interested in.
Here’s a sample of entries before:
"Aachen","1","Valid","L5","Quantity[21, ""Grams""]","Fell","DateObject[{1880}, ""Year"", ""Gregorian"", -5.]","GeoPosition[{50.775, 6.08333}]"
"Aarhus","2","Valid","H6","Quantity[720, ""Grams""]","Fell","DateObject[{1951}, ""Year"", ""Gregorian"", -5.]","GeoPosition[{56.18333, 10.23333}]"
"Abee","6","Valid","EH4","Quantity[107000, ""Grams""]","Fell","DateObject[{1952}, ""Year"", ""Gregorian"", -5.]","GeoPosition[{54.21667, -113.}]"
"Acapulco","10","Valid","Acapulcoite","Quantity[1914, ""Grams""]","Fell","DateObject[{1976}, ""Year"", ""Gregorian"", -5.]","GeoPosition[{16.88333, -99.9}]"
"Achiras","370","Valid","L6","Quantity[780, ""Grams""]","Fell","DateObject[{1902}, ""Year"", ""Gregorian"", -5.]","GeoPosition[{-33.16667, -64.95}]"
And after, we have our coordinate. In this case, the latitude:
50.775
56.18333
54.21667
16.88333
-33.16667
The data was cleaned with a variety of methods, but mostly with vim. I was only
interested in the year 1980 (this provided a decent amount of results), so I
removed everything but 1980 with :v/{1980/d
.
Once this was done, we needed to remove all the noise. We were only interested
in coordinates, i.e. The first element in GeoPosition
.
This was achieved with a heavy use of :%s
. Once again, Vim.
All of this could’ve been done properly with a script and a json library but the
reality is it was quicker to do this in vim. It probably took 2 minutes in total
to get something usable.
Normalising
Once cleaned, the data was good to go, but the numbers were not. Here’s a small sampling of
what we’ve got to work with (You can see the complete list in
here).
37.1
15.
24.8
34.8
31.25
As you can see, there’s not much variation here and we’re interested in numbers
spanning from 20 all the way up to 20,000 so we normalise it with this normalisation script which is basically:
def normalise(n, min_n, max_n, min_range, max_range):
return (n - min_n) * (max_range - min_range) / (max_n - min_n) + min_range
And we arrive at:
20000
20
8879
17920
14711
Once normalised, we have a fair amount of duplicates, so we remove them too (I
used vim for this but you could just as easily do sort -u
).
This gives us 50 unique
frequencies to play around with.
Abstractions
blip
blip
is the glockenspiel-like chime that you can hear. This is the fundamental
frequency coupled with the 9th and 25th partials (just like how a triangle wave
starts to form). It has a quick attack and a slow decay.
panner
panner
is responsible for panning and uses simple linear panning. It was
shamelessly stolen from Designing Sound by Andy Farnell
pd wind
pd wind
is the wind-like noise you can hear in the background. Using noise~
as a modulator is something I learnt recently, it works surprisingly well.
spigot blip
This is a wrapper around blip
to trigger on different bangs of the main
patch.
spigot
allows a value through if a condition is met. This is used to determine
which oscillator should play what frequency and when.
The focus for this wasn’t to learn Pure Data (like the other patches), but
ironically that’s what happened the most.
The biggest godsend to this patch are learning about send~
, receive~
,
throw~
, and catch~
.
These objects allow you to
do wireless connections by creating variables that can be read from anywhere
within the scope of a pure data patch. It feels slightly hacky but it’s better
than the mess of wires that were there before.
Visualisation
Visuals were done with projectM and the rogue-wave preset.