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.