a digital scan of a 35mm film image of a processing sketch running on an LCD
Skip to Content

NIME is Coming

NIME 2010 Poster

December 8 2010 at 3 PM

Signs of the Apocalypse

A glut of headlines relevant to the post-apocalyptic pirate internet have popped up over the last few weeks. Here’s a quick review with commentary.

This first batch is regarding the temporary loss of major online repositories for “user generated content” (to invoke the cliché). Another post discussing the Wikileaks saga is forthcoming in the context of the post-apocalyptic pirate internet is forthcoming.


Tumblr, the celebrated blogging platform, was down for about 24 hours on December 5th. This was their longest outage to date.

Tumblr outage

Users’ trust is shaken by this sort of thing, and a day after the outage they released a backup application that lets users save all of their Tumblr posts to their hard disks.

Here’s the official line:

Unlike other publishing sites’ approach to backups, our goal was to create a useful copy of your blog’s content that can be viewed on any computer, burned to a CD, or hosted as an archive of static HTML files.
Wherever possible, we use simple file formats. Our backup structure is optimized for Mac OS X’s Spotlight for searching and Quick Look for browsing, and we’ll try to use the same structure and achieve the same benefits on other platforms.

To me this reads more like, “Keep uploading! If we implode, we won’t take your data with us.”

The backup app strikes me as Hail Mary decision executed in the interest of damage control (with the side effect of actually being good news for the survivability of the 2+ billion posts Tumblr hosts on their servers). There’s a tension on social media websites between giving users access to their own data (in the form of database dumps) and maximizing “lock in” — since giving users downloadable access to their data can provide an easy means of egress from one service and migration to a competitor. (cf. Facebook’s recent decision to let users dump their data in one step.)

Of course, like most prophylactics, the download tool would only be useful in the context of the post-apocalyptic pirate internet if it 100% of Tumblr publishers used it 100% of the time. Nevertheless, the fact that this piece of preservationist infrastructure was officially released suggests that some portion of the Tumblr staff / users are paranoid enough to prepare for a data or infrastructure related disaster. The app also implicitly migrates the worst-case backup burden from the host to the client. (e.g. “Oops, we lost everything… what, you didn’t back up your posts?”) This represents a significant shift in one of the basic contracts of Web 2.0, which is the idea that “files” as we know them on our PCs don’t exist, you don’t have to worry about which directory things go in, you don’t plan for a day when you’ll need to open Word 3.0 files, and you certainly don’t have to back up. The understanding between consumer and provider is that once something’s uploaded, it’s safe from loss due to technical failure — where every bit is tucked away in multi-million-dollar data centers and placed under the careful watch of bespectacled geeks pacing up and down miles of server racks.

Of course, that’s not how things work out, but the cloud = safe truism is one that will need to be proven catastrophically false before the basic tenet of the post-apocalyptic pirate internet — that local bits are safe bits — can take hold.


Another outage of reasonably high profile (although certainly not on the scale of Tumblr) struck GitHub on November 14th. A botched command by a systems administrator wiped out a database and destroyed some data along the way. The site was unusable for about three hours.

GitHub is much more esoteric than Tumblr, but for the uninitiated it’s basically a web site layering social-networking tools on top of Git. Git, in turn, is a piece of software that runs locally on your computer to keep track of collaborations around / revisions to source code written in the course of developing software.

Anyway, here’s what bad news looked like, as delivered by GitHub’s mascot, the Octocat:

The nature of Git (the version-control system) means that even a total loss of GitHub (the community build on Git) would be inconvenient, but not catastrophic. When you’re working with a Git repository, you have a local copy on your hard disk that is periodically updated and synced to the GitHub server.

If 50 people are working on a particular project, then 50 copies of that project exist on local hard disks in one corner of the world or another. Thus the degree to which a projects is insured against disaster rises proportionally to a project’s popularity / number of collaborators.

So there are two particularly great things about the Git + GitHub combination that should be kept in mind as plans for the post-apocalyptic pirate internet are drawn up:

  1. The same basic software (Git) is running on both your own computer and GitHub’s servers. In this sense, GitHub makes the most of the web when it’s available (by adding a social layer to Git), but Git itself doesn’t completely melt down in the absence of GitHub. In short, Git’s use of the centralized web is value added, not mission critical.

  2. Local backups are generated automatically in the course of using GitHub — unlike Tumblr’s proposed solution, which calls on users to make a conscious decision to back up at regular intervals if they want the safety of their data.

December 8 2010 at 1 PM

It Talks: Text to Speech in Processing

The Mac has a really great text-so-speech (TTS) engine built right in, but at first glance it’s only available at Apple’s whim in specific contexts — e.g. via a menu command in TextEdit, or system-wide through the accessibility settings. Seems grim, but we’re in luck — Apple, in their infinite generosity, have given us a command line program called “say”, which lets us invoke the TTS engine through the terminal. It’s super simple to use, just type the command and then the text you want, e.g. say cosmic manifold.

So that’s great, now what if we wanted to make a Processing sketch talk to us? In Java, as in most languages, there are ways to send commands to the terminal programmatically. By calling Runtime.getRuntime().exec("some command");we can run any code we want on the terminal from within Processing. So to invoke the TTS engine from a Processing sketch, we can just create the say ... command line instruction in a string object, pass that into the runtime execution thing, which in turn handles the TTS conversion.

I’ve put together a small Processing class that makes it easy to add speech to your Processing sketches. It only works on Mac OS, won’t work in a web applet, and has only been tested in Mac OS 10.6. (I think the list of voices has changed since 10.5.)

Note that the since the class is quite simple and really just wraps up a few functions. I’ve set it up for static access, which means that you should never need to instantiate the class by calling something like TextToSpeech tts = new TextToSpeech() — and in fact that would be a Bad Idea. Instead, you can access the methods any time without any prior instantiation using static style syntax, e.g. TextToSpeech.say("cosmic manifold");.

Here’s the class and a sample sketch:

  1. // Processing Text to Speech
  2. // Eric Mika, Winter 2010
  3. // Tested on Max OS 10.6 only, possibly compatible with 10.5 (with modification)
  4. // Adapted from code by Denis Meyer (CallToPower)
  5. // Thanks to Mark Triant for the inspiring sample text
  6.  
  7. String script = "cosmic manifold";
  8. int voiceIndex;
  9. int voiceSpeed;
  10.  
  11. void setup() {
  12.   size(500, 500);
  13. }
  14.  
  15. void draw() {
  16.   background(0);
  17.  
  18.   // set the voice based on mouse y
  19.   voiceIndex = round(map(mouseY, 0, height, 0, TextToSpeech.voices.length - 1));
  20.  
  21.   //set the vooice speed based on mouse X
  22.   voiceSpeed = mouseX;
  23.  
  24.   // help text
  25.   fill(255);
  26.   text("Click to hear " + TextToSpeech.voices[voiceIndex] + "\nsay \"" + script + "\"\nat speed " + mouseX, 10, 20);
  27.  
  28.   fill(128);
  29.   text("Mouse X sets voice speed.\nMouse Y sets voice.", 10, 65);
  30. }
  31.  
  32. void mousePressed() {
  33.   // say something
  34.   TextToSpeech.say(script, TextToSpeech.voices[voiceIndex], voiceSpeed);
  35. }
  36.  
  37.  
  38. // the text to speech class
  39. import java.io.IOException;
  40.  
  41. static class TextToSpeech extends Object {
  42.  
  43.   // Store the voices, makes for nice auto-complete in Eclipse
  44.  
  45.   // male voices
  46.   static final String ALEX = "Alex";
  47.   static final String BRUCE = "Bruce";
  48.   static final String FRED = "Fred";
  49.   static final String JUNIOR = "Junior";
  50.   static final String RALPH = "Ralph";
  51.  
  52.   // female voices
  53.   static final String AGNES = "Agnes";
  54.   static final String KATHY = "Kathy";
  55.   static final String PRINCESS = "Princess";
  56.   static final String VICKI = "Vicki";
  57.   static final String VICTORIA = "Victoria";
  58.  
  59.   // novelty voices
  60.   static final String ALBERT = "Albert";
  61.   static final String BAD_NEWS = "Bad News";
  62.   static final String BAHH = "Bahh";
  63.   static final String BELLS = "Bells";
  64.   static final String BOING = "Boing";
  65.   static final String BUBBLES = "Bubbles";
  66.   static final String CELLOS = "Cellos";
  67.   static final String DERANGED = "Deranged";
  68.   static final String GOOD_NEWS = "Good News";
  69.   static final String HYSTERICAL = "Hysterical";
  70.   static final String PIPE_ORGAN = "Pipe Organ";
  71.   static final String TRINOIDS = "Trinoids";
  72.   static final String WHISPER = "Whisper";
  73.   static final String ZARVOX = "Zarvox";
  74.  
  75.   // throw them in an array so we can iterate over them / pick at random
  76.   static String[] voices = {
  77.     ALEX, BRUCE, FRED, JUNIOR, RALPH, AGNES, KATHY,
  78.     PRINCESS, VICKI, VICTORIA, ALBERT, BAD_NEWS, BAHH,
  79.     BELLS, BOING, BUBBLES, CELLOS, DERANGED, GOOD_NEWS,
  80.     HYSTERICAL, PIPE_ORGAN, TRINOIDS, WHISPER, ZARVOX
  81.   };
  82.  
  83.   // this sends the "say" command to the terminal with the appropriate args
  84.   static void say(String script, String voice, int speed) {
  85.     try {
  86.       Runtime.getRuntime().exec(new String[] {"say", "-v", voice, "[[rate " + speed + "]]" + script});
  87.     }
  88.     catch (IOException e) {
  89.       System.err.println("IOException");
  90.     }
  91.   }
  92.  
  93.   // Overload the say method so we can call it with fewer arguments and basic defaults
  94.   static void say(String script) {
  95.     // 200 seems like a resonable default speed
  96.     say(script, ALEX, 200);
  97.   }
  98.  
  99. }

December 6 2010 at 11 AM

Rough Thesis Proposal

Let’s suppose the internet stops working tomorrow. Not the hard disks, just the wires. Government firewall, tiered service, cut fiber, ISP meltdown — pick a scenario.

How much would be lost? How much could be recovered? What would you need to rebuild?

We have the infrastructure — computing power, abundant storage, networking — but not the know-how, organization, will, or sense of impending disaster required to start building a decentralized web. We need a way to easily rearrange our consumer electronics (which are optimized for consumption) into a network that can’t be centrally controlled or destroyed (and is therefore optimized for creation and distribution). Most importantly, the ubiquity and overlap of consumer-created wireless networks in urban areas means that mesh-based networks with thousands of nodes should be feasible without any reliance on centralized network infrastructure.

Hence the post-apocalyptic pirate web kit: everything you need to bootstrap a decentralized web in a single package. This could take several forms, but my initial thinking suggest a suitcase full of hard disks, wireless connections, and processing power designed to restore fragments of the web to nearby users and act as a node in a broader network of data survivalists.

The hard-disks would be pre-loaded with an archival version of the web. The whole of Wikipedia’s english text content, for example, is readily available for download and amounts to abut 5 terabytes. This could fit on three hard disks, which cost about $100 each, and together displace about as much physical space as a loaf of bread.

In its dormant form, the post-apocalyptic pirate web kit is something you might leave plugged in at the corner of the room — it could sit there indefinitely, like a fire extinguisher. The kit could automatically crawl the web and keep its archival mirror as fresh as possible.

When and if disaster strikes, the kit would be ready to switch into server node and thus preserve our way of internet life. (So that we might continue with a spirit of bold curiosity for the adventure ahead!)

November 30 2010 at 10 AM

Dead Drop at 319

This morning I installed a dead drop at 319 Scholes street in Brooklyn. Four gigabytes worth of zeroed bits are now available for web-free semi-anonymous file exchange.

Background
Dead drops was initiated by Aram Bartholl during his residency at Eyebeam — the project involves embedding digital storage in buildings or other large, immovable objects in public space. Aram’s “Dead Drops Manifesto” follows:

Dead Drops is an anonymous, offline, peer to peer file-sharing network in public space. Anyone can access a Dead Drop and everyone may install a Dead Drop in their neighborhood/city. A Dead Drop must be public accessible. A Dead Drop inside closed buildings or private places with limited or temporary access is not a Dead Drop. A real Dead Drop mounts as read and writeable mass storage drive without any custom software. Dead Drops don’t need to be synced or connected to each other. Each Dead Drop is singular in its existence. A very beautiful Dead Drop shows only the metal sheath enclosed type-A USB plug and is cemented into walls.You would hardly notice it. Dead Drops don’t need any cables or wireless technology. Your knees on the ground or a dirty jacket on the wall is what it takes share files offline. A Dead Drop is a naked piece of passively powered Universal Serial Bus technology embedded into the city, the only true public space. In an era of growing clouds and fancy new devices without access to local files we need to rethink the freedom and distribution of data. The Dead Drops movement is on its way for change!

Free your data to the public domain in cement! Make your own Dead Drop now! Un-cloud your files today!!!

I really like this project — it sits at the intersection of the practical and the conceptual, and forces us to rethink data exchange and anonymity. In the course of researching dead drops, I read hundreds of comments from visitors to Aram’s blog posts outlining the project. A huge percentage of the comments are henny penny hysterics about the security implications involved in plugging your laptop into a dead drop. (Viruses! Destructive circuitry! Illegal content!) Such is the nature of creative tear-down on the web.

Nevertheless there’s something about drawing data exchange into real life that amplifies paranoia and brings out a sense of peril. If my thesis project about building a decentralized mesh-based alternative internet ends up solidifying, I’ll definitely revisit this issue of how trust works so differently in real life.

Process
Installing the drop was relatively simple. I followed the how-to guide. As fate would have it, there was already a hole in the building’s brick facade that was just the right size for a USB key. With that already sorted, I started by cracking open the key’s plastic case and mummifying it in PTFE tape for water protection:

Next I mixed up some cement, and embedded the key in the wall:

Outlook
I seeded the drive with a few files of interest, and posted it to the dead drops database — this is the 66th drop to be installed worldwide. I’ll be checking the drive every few days, and if anything interesting shows up I’ll write a post.

I’ll be interested to see how well / long it holds up to the elements, since the Eyebeam drop met an early demise after a rainstorm, and the Union Square drop was lost to vandalism.

November 29 2010 at 9 AM

Building a Real-Time Web Library for Processing

In the course of working on my big screens project this semester — a real-time web clock — I’ve realized that it would be awfully nice to have a Processing library to abstract away all of the footwork involved in skimming the latest data from the usual Web 2.0 suspects like Twitter, Flickr, Facebook, Foursquare, etc.

There’s already some nice work on this front. Mark McBride’s excellent Tweet Stream library for Processing works exactly as advertised. There are also Java wrappers for popular APIs (flickrj comes to mind) that should work in Processing and are likely to make data extraction easier.

But, many of these approaches are lacking, and getting from a raw API to a real-time stream can be a lot of work. So I’ve started work on a Processing library whose sole function is to provide a real-time stream of web data from as many sources as possible, with as little delay as possible.

A few considerations and concerns for the design and implementation of the library are outlined below.

One Library vs. Many
Traditionally, APIs wrappers / libraries come à la carte. You want Flickr? Download the Flickr library. You want Twitter? Download the Twitter library. Etc.

That’s nice, but all of these libraries work in slightly different ways and putting two or more services together requires plenty of fuss and glue code. I think a lot of the interesting things you can do with real-time data involve placing it in the context of other events, which favors a one-library approach.

Also, consolidating the services into a single library means that we can use polymorphism to make dealing with generic “event” objects from different sources relatively painless. E.g., if you wanted to work with tweets and Flickr updates in similar contexts, you should be able to manage everything from a single array list since their event objects inherit from some kind of generic event class.

Maintainability
Not all services with high-rates of incoming data have clean, public-facing APIs for grabbing said data.

In the case of Foursquare, for example, there’s no way to access the most recent public check-ins through their official API. The API allows certain kinds of interactions with the service, but it doesn’t do exactly what we want.

Likewise, Facebook’s status API doesn’t let you do an empty search for all of the latest updates — instead you’re limited to a specific search term. So, in this case, there’s an API that almost does what we want, but we’ll have to get clever if we want something resembling the whole stream of public status updates.

Therefore getting real-time data from these services will involve some hairy HTTP polling and HTML scraping. These kinds of things are liable to break if / when the structure of the source page changes. There are also potential request rate limits to deal with. Keeping the library up to date and fixing breakage when it happens is going to be a challenge — but I can’t think of a way around this until more sites support officially-sanctioned access to structured real-time data through an API. (And good on Flickr and Twitter for providing real-time data in their APIs already.)

Actual Rate vs. Available Rate
Ideally, every single event from a service would be captured by the real-time web library. However, for extremely high-volume services (Twitter, for example), even the official APIs only give a fraction of the actual event streams. Again, there’s not really a way around this, but keeping tabs on what percentage of the full stream we’re currently reading might be useful — some way to compare the current message rate through the library to the actual message rate on the service’s end. (For example, it would be useful to know that the library’s current Twitter message rate is 30% of actual traffic.)

Conversely, being able to dynamically specify a rate limit for each service might be useful in certain contexts where bandwidth needs to be conserved or services need to be synchronized. (At the very least, rate limiting will be useful for my big screens project, where a full-rate sample of the services would result in graphic slowdowns.)


So how should it work from the library programmer’s perspective? Maybe something like this:

  1. WebStream webStream;
  2.  
  3. void setup() {
  4.   // instantiate the web stream object
  5.   webStream = new WebStream(this);
  6.  
  7.   // add as many (or as few) real-time services as you like
  8.   webStream.activateFlickr("api key here");
  9.   webStream.activateFacebook();
  10.   webStream.activateTwitter("api key here");
  11. }
  12.  
  13. void draw() {
  14.   // Nothing to see here, yet
  15. }
  16.  
  17. void streamEvent(Update u) {
  18.   // the web stream returns updates via a callback event
  19.   // this would print a quick summary of the most recent event
  20.   println("content: " + u.getText() +
  21.           " via: " + u.getAuthor() +
  22.           " at: " + u.getTime() +
  23.           " from: " + u.getServiceName());
  24. }

That’s the plan, at least. I’ll work on this over the next week and eventually have some code for public consumption in the next month or two. If anyone has feature requests or a different take on how something like this should work, let me know.

November 18 2010 at 3 AM

Concept Dump

An ever-expanding list of assorted things of direct or tangential relevance to my continued inquiry regarding a thesis on the subject of a post-apocalyptic pirate internet.

Books:
Inventing the Internet - Janet Abbate
Internet Architecture and Innovation - Barbara van Schewick
The Internet Imaginaire - Patrice Flichy
Access Controlled, The Shaping of Power, Rights, and Rule in Cyberspace
Wirelessness Radical Empiricism in Network Cultures - Adrian Mackenzie
Crypto Anarchy, Cyberstates, and Pirate Utopias - Edited by Peter Ludlow
Security in Wireless Mesh Networks - Editors Zhang, Zheng, and Hu

Articles:
The Temporary Autonomous Zone
BitTorrent Monitoring As a Work of Art
Hacker Spoofs Cell Phone Tower to Intercept Calls
As We May Think

Groups:
Men in Grey F.A.T.
Eyebeam
The Church of Wifi
Archive Team

Software:
Firesheep
Wireshark
Carnivoe
Assorted wardriving tools

People:
Aram Bartholl
Thomson & Craighead
Gordan Savicic
Danja Vasiliev

Works:
Dead Drops - Aram Bartholl
Six Square Meters of RAM - James Irwin

Words:
Prepared
Paranoid
Ad-Hoc
Mesh
Self-healing
Archive
Survival
Shelter
Network
Wireless
Web
Indestructible
Bootstrapped
Autonomous
Displaced
Intercept
Splice
Reroute

November 16 2010 at 10 AM

Dead Dead Drops

Dead Drops is a project fresh out of Eyebeam that proposes a new and unsanitary means of network-free data exchange. The project seems highly relevant to my nascent thesis idea, The Post-Apocalyptic Pirate Web Kit.

Artist Aram Bartholl describes the project:

‘Dead Drops’ is an anonymous, offline, peer to peer file-sharing network in public space. USB flash drives are embedded into walls, buildings and curbs accessable to anybody in public space. Everyone is invited to drop or find files on a dead drop. Plug your laptop to a wall, house or pole to share your favorite files and data.

It’s the digital equivalent of a glory hole.

I was curious to see what kind of content the drops have accumulated in their first few days of existence, so I printed a handful of maps and set out to visit each one. The site’s location database is a little clunky, but it turned up five drop locations in Brooklyn and Manhattan:

Eyebeam was the first stop. Here’s the drop:

Plugging in was a bit of an anticlimax — nothing happened:

The drive refused to show up on my desktop, and poking around with Disk Utility suggested that the issue went beyond a botched format or a corrupt partition. I emailed Aram about it, and he confirms that it’s gone down and attributes the loss to rain.

The Union Square subway drop also went down earlier today, possibly the result of vandalism. So it goes.

That leaves three more drops to explore, I’ll update this post as I make the rounds.

Even though my attempt to use the drop was a failure (thus far, at least), the concept stands on its own and presents an interesting counter-scenario to the ethereal mesh-networks I’m proposing for the post-apocalyptic pirate internet.

Let’s consider some dead drop novelties:

  • There is no electrical network — feet and subway trains do the work of shuffling packets around the city.

  • There are no loops — a drop is a dead end.

  • There is no censorship — there is no CAPTCHA or filter or firewall. Maintaining a standard of content is perpetually up to the next person to visit the drop.

  • There is no permission — anyone can delete or create any file on the drop indiscriminately.

  • There is no privacy — though the files on a drop may be of anonymous origin, you must be physically present at the drop’s point of installation to exchange data.

  • There is no protocol — where most networks impose a structure for communication (TCP / IP, UDP, OSC, MIDI, AT), the drop’s only structure is derived from the file system.

November 16 2010 at 6 AM