The next thing to burn your eyes: locative media and augmented reality

January 25th, 2010

This was originally going to be tagged on to the end of my previous blog post about my recent return residency at STEIM. I formed a tenuous link between Amsterdam and the fact that VICE/Nike have created a new app to help iPhone owners get the most out of Europe’s greatest cities, Amsterdam being one of them. However even VICE have journalistic standards to uphold and my pay masters decided that one lousy paragraph at the end of the ‘long and winding road’ that was my residency’s write up was just not good enough to warrant twenty five squids. Fair play to them and shame on me for thinking I could get away with such wanton reckless blagging.

So I’ve decided to write a whole post on the subject of locative media and augmented reality which seems prescient given that everyone is plugging this as the next big thing and when I mention it to non art/tech types I’m still met with blank stares. Before I get into a review of the art and tech of locative media and augmented reality I’ll hit you with my plugged content and earn my monies. Yay for acid soundtrack, nay for Nike who officially suck for abusing pro-skateboarding, worker’s rights and children.

The ‘party line‘ from VBN is that VICE and Nike have teamed together to release an iPhone app called TRUE CITY to help cultural sponges mop up more good times in Europe’s major cities. Paid content promotion aside this is actually pretty interesting stuff as locative media and augmented reality are probably the future. Personally I’m gonna hold out until the whole thing is mounted in ray-bans and I can get the locations of the best crack houses and hookers beamed straight to the back of my retinas. But if you are rich enough to own Apple’s premiere black shiny status symbol (or mugger’s delight – take your pick) and you’re interested in the locations of the best record shops,clubs,events and whore-houses you should download the app and give it a go. Apparently it works by magic and relies on an elite team of cultural vampires to update the app’s database with the locations of the coolest shit and the freshest meat. Just like if you mess with regular vampires they can turn you into a foot soldier of Satan’s army, if you upload the locations of enough cool shit then the app’s moderators will turn you into one of them. Before you know it you’ll be living in Shoreditch, wearing half a watermelon on your head to trendy parties a-la something out of Nathan Barley.

Marketing Blurb

Probably for the best I didn't have access to this form of distraction during my residency or I'd have spent even less time in my atelier working.

DL and have a look! http://bit.ly/NikeUK

This is only the latest in a long line of augmented reality/locative media iPhone apps and before that art installations and military tech development that probably started with ‘head up displays‘ in fighter jets. By this point you’re probably starting to wonder what the buzzwords ‘locative media’ and ‘augmented reality’ mean. This is wandering a little off the kind of development work I do as part of my artistic practice but I’m happy to pontificate on it. Given that a fair portion of the lab at SARC seem to be interested in it, or working with it as part of their practice, I’ve sat through some interesting (and not so interesting) seminars on the subject.

Locative media is basically a buzzword to describe any kind of media content that is tied to a particular geographic region. Normally the set up is this. You have some piece of tech, a GPS enabled mobile phone or a ’special box’ that an artist has hacked together and then the ‘media content’ (i.e. sound/music/visuals/text) spat out by the phone/box/whatever changes depending on the geographic location of the person carrying the tech.

Augmented reality is a bit different in that it basically revolves around the idea of taking a real image and superimposing some extra visual data over the top. Augmented reality is kind of implicitly ‘locative’ in that the tech nearly always augments the reality which is right in front of you, i.e. the local geography of whatever you’re pointing your trendy iPhone’s camera towards.

Speculatively speaking I would say that locative media, within the arts, is on the verge of getting a bit stale and transmuting in to something new, probably augmented reality flavoured. This is just my opinion but how many site specific ‘walkman journeys’ can the arts spew out before the punters start to feel like they’ve heard it all before? Before I get into an epic flame war with any locative media based artists I’d like to state that I probably only feel this way because I often tend to be more interested in how tech artworks work, than the artwork itself. So my opinion counts for very little, it’s like saying how long will punters be content with staring at painted canvas? Obviously the art will continue to develop with the technology. Personally though I’m kinda bored of soundwalks. However while researching around this piece I did find a really interesting article at networkedpublics.org that was talking about how locative media may develop.

“Locative media has been attacked for being too eager to appeal to commercial interests as well as for its reliance on Cartesian mapping systems, yet if these critiques are well-founded, they are also nostalgic, invoking a notion of art as autonomous from the circuits of mass communication technologies, which we argue no longer holds. This essay begins with a survey of the development of locative media, how it has distanced itself from net art, and how it has been critically received before going on to address these critiques and ponder how the field might develop.” – Beyond locative media by Marc Tuters and Kazys Varnelis

Mmm, lovely academic art speak. Note that it points out the attack on appealing to commercial interests, art’s ‘anti-money’ stance has always made me laugh, but I digress.

Matthew Green is a colleague and friend of mine at SARC doing his PhD in the art of locative media. You can read about some of the cool stuff he gets up to with it over at his blog. His installations have been in The Grauniad’s arts section and he’s had residencies in the far east and everything so I’m officially jealous of his success. I wrote to him earlier today to ask for the skinny on the best examples of locative media and augmented reality. Here are his top picks for the arts:

And for the apps:

Which Matt describes as being ‘all a bit like RJDJ for the iphone….’. But Matt’s top pick for locative media artworks are Brighton based collective Blast Theory ‘who make city wide games/experiences by utilising various technologies’. Sounds tasty.

When it comes to augmented reality, writing about it is kind of pointless given the oodles of youtube videos that have been uploaded and slobbered over by tech heads. Personally I say sod the mobile phone I want a headset that looks like something Hicks from Aliens would sport when going on a bug hunt. But then I also want a pulse rifle with over and under grenade launcher. Here are the videos.


So what are we left with other than two new ways to distract ourselves into walking into lamp posts and remove ourselves further from the people around us? What use is locative media and augmented reality going to be to artists given the magic is (allegedly) wearing off with each corporate application? Comments plox, let’s get a debate going.

P.S. Robin Price does not endorse the taking of hard drugs, the prostitution of women or the use of forced labour by sports clothing companies.

P.P.S Neither can he occupy the moral high ground because he takes kickbacks from VICE and currently owns at least fifty items probably produced by child labour. He is however simply racked with lower-middle class guilt which makes it all OK.

P.P.P.S About the next big thing. It’s a good tune and it always has been.

Other stuff , , , ,

Return to STEIM

January 24th, 2010

In November I returned to STEIM in Amsterdam. For those of you who don’t know about STEIM, what rock have you been hiding under? STEIM is a non-academic international centre of excellence for electronic instruments funded by the tax payers of the Netherlands. The place nearly folded not that long ago which would have been a real loss to the electronic music community given the huge amount of knowledge and skill the people there embody. I encourage anyone who gives two shits about experimental electronic music/instrument design to consider looking the place up. They do initiations for the uninitated, workshops, advice and feedback right up to putting up (with) artists in guesthouses and ateliers. Here is its location just so you have no excuses for not visiting.


View Larger Map

A lot this text is stolen from my blog entry at STEIM’s project blog where you can read all about this kind of interesting cutting edge stuff. Think of this as digital recycling… .

Recycle logo

I stole this image - now I'm recycling it!

A year had passed since I last went to STEIM for the microjamboree. Following my last stay much had changed in that my PhD, now drawing to a close, was forcing me to reappraise my past work and my motives. Drawing things together is never easy for me, a case in point – leaving it two months before writing up a residency… .

Image of a shop sign of the word 'bloom'

Welcome to STEIM where ideas 'bloom'.

I went this second time with a project in mind, to work on a set of audience feedback remotes for interactive audiovisual music. I had a prototype, naked and caseless, living in a Farnell bag and a set of half finished Max patches and Arduino code to fill out. I had seriously intended to hole myself up in the attic bunker that STEIM kindly offers wandering artists. However announcing this plan to Daniel, my mentor at STEIM, drew a response that diverted me on to a series of interesting and useful tangents. Perhaps the first lesson to draw about residencies is that the plan one arrives with is often a residency’s first victim. Especially at STEIM.

Swirly overexposed image of a broken Jägermeister bottle lying in the street.

This is what an artistic residency at STEIM may do to your carefully laid plans. Render them beautifully broken.

Daniel gave me some key advice that coloured my ten days in Amsterdam last November; ‘leave programming for the ivory towers and engage in the culture of the city and the richness of feedback’ – or somesuch. So it was in my second residency I focused less on announcing myself and my work to the people around STEIM but instead tried to keep myself open to the intervention, opinions and knowledge of others. This took the form of a series of annotated conversations with Daniel, Kristina and Taku, the trawling through as many galleries as I could stumble upon, all night google sessions and much reflection done in bars and restaurants. In short I attempted to become a cultural sponge. Instead of throwing my ideas at people and seeing which stuck as I am often apt to do, I turned that model on its head and encouraged others to talk while I furiously took down notes.

What did I learn? What stuck? Early on Daniel mentioned two ideas that he had which I was quick to appropriate i.e. steal – in the academic community we call it ‘referencing‘.

  • An artwork has three properties; A name, ‘reference’ and theory.
  • A piece of music has three properties; A name, ‘reference’ and score.

This appeals to me as a model for describing the products that artists, musicians and art musicians arrive at. A good piece of art or music, or in fact anything worth mentioning, should have a name; how else would one talk about it otherwise? The ‘reference’ is easiest to think of in music where I like to think of it as the ‘hook’, the recognisable point of entry for an audience. Meanwhile the score or theory is the aesthetic framework, the pattern of decisions that the artist has made to arrive at the final piece. Perhaps the third property is the most interesting to the artistic community when evaluating a work. But even the casual observer of an art work can quickly ’smell a rat’ when a piece appears to have no underlying logic to it.

Very swirly overexposed image.

This image has no underlying logic.

In a long sofa discourse held in STEIM’s lobby with Kristina I invited her to tear in to my ideas for an interactive music controller for audience feedback. Better that I got used to it then with the friendly STEIMies than go in to my viva later this year unprepared for rigorous (read rough) artistic feedback. Kristina soon knocked some sense into me, forcing me to confront several flaws in my ideas.

At this point it’s worth explaining a little more about the work I brought with me to STEIM. The as yet unnamed music controller features a single rotary encoder, an 8 x 8 tri-colour LED matrix and a ZigBee wireless link as well as the obligatory Arduino. My plan was and still is to use ten of them to allow real time ‘worm polling‘ of my music with an audience, and then use that feedback data to interact/intervene/improve my tunes algorithmically (or should that be algo-rhythy-magically).

Image of my forthcoming music controller.

Naked tech.

Another image of my forthcoming music controller.

Knob to twist and a display for visual feedback. Simples!

Kristina gave me the idea that the items could be shared, not tied to a particular audience member, which I’d overlooked as a concept. Perhaps a side effect of sitting through too many ‘buttoned up’ ’sit down’ electro-acoustic concerts. This forced me to reappraise my notions of how I would box up my controllers. Kristina gave me many suggestions, all of which were useful and relevant. Here are some of my favourites

  • ‘Become the Nielsen family‘. – As a ‘reference’ for my art.
  • ‘Run experiments – the gig is your laboratory’ – On the subject of developing my idea.
  • ‘Use bubblewrap’ – An awesome suggestion for extra rapid prototyping of case designs.
  • Use ‘iterative interaction’ making small changes to the design after each ‘regular deployment’. – On the subject of design strategy.
  • ‘The chemist asks what happens when …?’ – On the subject of how to take the next step in development.
  • Remember there are ‘no imaginary people’ – On the subject of avoiding living in my head/over intellectualising.
  • ‘Go to gigs and test it out. Don’t talk or think about the final thing.’ – On the blunt reality of what I have to do.
  • ‘Convince people you’re allowed to do whack shit and don’t be lame’ – Here Kristina was telling me the secret technique of testing new technology on ‘punters’ but perhaps this should be applied to all art/music/science/life in general?
Image of a don't and a do.

I convinced these people I was a freelance fashion photographer. I'm really not. I had aspirations of selling the photo to VICE's Dos and Don'ts. They weren't interested, but I still love the stop sign above the gormless goon's head. What was she thinking?

After talking to Kristina I left it a couple of days before returning to STEIM. Perhaps I should mention that my last residency was not just an opportunity to work on my artistic practice in STEIM’s appealing attic atelier space, jokingly known as ‘the monastery’. I had far greater responsibilities than simply looking after the development of my ideas, software and hardware. Really I was there to look after Daniel’s cat Cheetah! Daniel had kindly put me up at his Jordaan apartment with instructions for the care and comfort of his domesticated moggy while he was away, ironically at his own artistic residency.

Picture of a man and his cat.

Daniel and Cheetah.

In England we have a saying about people and pets, “he’s a nice guy – but I wouldn’t trust him with my cat“. As such I felt the heavy weight of the commitment and spent much of my time in the Jordaan caring for Cheetah. Cats have an awful habit of sulking when their owners leave them and then sulking even harder when they return, to punish them. Out of respect for Daniel and a curiously English bent for pets I was determined to keep this skitty-kitty happy. I allowed her to rule my day in a way that made my partner at home quite jealous. Working on a laptop, listening to the BBC World Service, feeding and most importantly playing with a cat, I worked on the ideas for my thesis and final pieces. The laser pointer sessions conducted to improvised and new music and the rapidly prototyped cat interaction device I built deeply coloured my thinking on the subject of metaphor; a key part of my thesis. I shall not divulge nor digress into my ideas on cats and dogs as metaphors for people yet. Rather I shall ask one question, what can cats and dogs teach us about the dance floor?

Picture of a man with someone else's cat.

Portrait of the young artist with a little cat.

Returning to STEIM for a final interview with Taku I was keen to ask his advice on an idea that had occurred to me when searching for the ‘theory’ behind my work. It is often the case that artists simply ‘do’ and then search for the theory after the fact, the same occurs in the sciences – or so I am told. My own ‘theory’ was that in my first two serious pieces I had been obsessed with embedding my own modern ideas for interactive audio visual music in the bodies of existing old technologies, namely the radio and the TV. I had been interested early on with Duchamp’s ready mades but also deeply concerned with artistic intervention/re-appropriation and subversion of existing technologies. I decided to coin the term ‘post-neo-retro-futurism’ as googling it yielded no hits – which surely meant I had at least some space to develop in to artistically. Essentially it was a made up phrase designed to encapsulate my ideas about taking our past ideas of what future technology would bring and then colliding them with my own current ideas of ‘future’ art/tech.

Talking with Taku about my ideas of the future and in particular looking at our past ideas of what future technologies would bring allowed me to put some meaty ‘art theory’ on the bones of what could otherwise smell like another poorly thought out idea. Taku reminded me that historically thinking the concept of the ‘future’ is a relatively recent one, emerging from enlightenment thinking in the 1600s and opposing the older, more static, Greek notions of ‘concepts‘ and ‘knowledge‘. Apt topics for discussion in a great enlightenment city like Amsterdam where Descartes himself had once lived. Descartes it should be noted is my favourite philosopher, a hang over perhaps from my days as an undergraduate studying theoretical physics, he invented the subject… .

Multiple exposure of image of a lot of cables.

I don't know what post neo retro futurism looks like yet, but it will definitely require a lot of cables. Which is lucky because I seem to collect them.

Quite apart from picking Taku’s brain for juicy thesis references I was keen to ask him for his opinions on the subject of artistic appropriation as we share a common love of DJ-ing and stolen/sampled/sample based music. Taku pointed out to me that in his opinion there were no real ‘ethics’ of sampling.

“The ‘ethic’ comes in during the act of making or the listening of the audience. If your medium’s recorded media you just do what feels right. Nobody can own me when I play. I control the music.” – Taku/DJ Sniff

Perhaps that’s an interesting place to finish this review of my residency with the idea of Taku controlling his music, reading the crowd manually with his eyes and ears. Meanwhile I’m still trying to reinvent the wheel and build a system where the audience battle the DJ with their own set of knobs to twist and push the music forward. Till next time STEIM… .

Picture of UK Border sign at an airport.

After ten days I went home. But I'll be back. If they'll have me.

Blogging , , ,

WTF is this blog even for?

January 9th, 2010

You might have noticed things went a little quiet round here for six months. This isn’t due to any lack of activity on my part. I’m still plodding away building synths, programming computers, making acid, attempting PhD research, teaching, art, etc, etc. It’s just blog fatigue.

Demotivational image of an apathetic man sat at a computer.

Work long enough with computers and you too can be bored to tears by that which you once loved.

For a while I got quite caught up with the following algorithm:

  1. Attempt to make awesome shit.
  2. Write blog entry detailing attempted awesome shit and in process give that shit away for free to all and sundry.
  3. ?
  4. Profit.

This algorithm only really holds water if you can accept the tenuous idea that the warm fuzzy feeling of getting my ego stroked by awstats telling me I have around 2000 hits a month is a profit.

Unfortunately over time I got more and more precious about blogging and less and less willing to post unless I had something totally super awesome and finished to bleat to the world about.

Given that the blog was initially supposed to be:

  • Shameless self promotion.
  • A means of seducing potential employers.
  • A documentary of my artistic practice and development.
  • For the hell of it, filled with cake and win, made with lulz in mind.

Somewhere along the line I obviously forgot about this and became too interested in keeping the customers satisfied which given I’m not actually selling anything (yet) is pretty fucking stupid.

I’m so tired. I’m oh-oh-oh-so tired.

I realised this state of affairs was counter-intuitive, given that I don’t owe anyone anything and I’m pretty sure I could still count on the fingers of no hands how many people would give a shit if I went ‘BAWWWWW’ and deleted fucking everything.

Picture of an anthropromorphic comic rabbit saying "BAWWWW!" while rubbing his eyes

Oh noes my blog's gone wrong.

As such and given I am currently developing some internet art pieces I started to really wonder WTF is this blog for (which led to the above) and by extension WTF is the internet for?

Image of a grinning business man punching the air while looking at a computer. Subtitled 'Internet - A Series Of Tubes!' with the words 'Serious Business' crossed out.

The internet - he understands it. Do you?

I came to the conclusion that ‘teh internet’, a giant series of connected tubes – if you will, is a global tool for wanking and passive agressiveness on a scale hitherto unimaginable.

This idle philosophising didn’t just happen on it’s own. It took months of research on social networking sites to come to this conclusion; which is where we are now. My blog is back. A few things have changed, much will stay the same. The changes are:

  • VICE magazine recently put a call out for bloggers to join their own personal army of sponsored sycophants which given my penchant for VICE’s brand of brutal honesty, I answered. In return for plugging the ocasional link they have alluded to the idea of paying me some monies and sending me their magazine in the post.
  • I will blog more often but about less awesome shit. Sorry, but I’m doing this for me and I can’t be done with my perfectionism anymore. If you like the warez and the tunes then good for you. If you’re expecting me to finish some CAD designs anytime soon to help you with your project then keep waiting…

The constants are:

  • I’m still writing about my continuing adventures in technology, music, visuals, hardware, software.
  • I’ll still give away a fair amount of cake in the form of tunes, code, patches, etc, etc.

As such I’m going to finish with a song and try and earn myself some money in the process.

Simian Mobile Disco are super awesome. You’ve already heard them, even if you don’t know it, after their Hustler track blew up and got licensed over all kinds of stuff, mostly Channel 4 ‘yoof’ type TV show promos. VBS interviewed them and have all kinds of yummy content here on their new heroes site which seems have been sponsored by Vodafone in an attempt to firmly implant the idea of ‘cool indie/dance music’ in your mind whenever you think of the hulking telecomms giant. Please enjoy.

Blogging, Music, Other stuff

MPEG7 Encoder for MaxMSP alpha release now here !

June 26th, 2009

A third of what drove my tv installation piece was the audio analysis software that allowed me to segment, analyse and database the sound track of youtube movies. These had been stripped from the downloads and saved as wavs. At first I wrote a simple slicer and segmenter in VASP that allowed me to get basic amplitude spectral data for entry into a database. But this was hacky, the output data wasn’t standardised making it useless to use with other patches and crashy (it would analyse solidly for ten minutes then crash Max in annoying fashion). So I came back to an MPEG7 audio encoder written under LGPL in Java.

I’d looked at Holger Crysandt’s library early on in my PhD when I was playtesting ways of getting good audio metadata but ended up sticking with Tristian Jehan’s analyzer~ external. This works great with with signals in real time but if you want to analyze say ten minutes of sound then it takes the ten minutes to play it through analyzer~ and log the details. My desire for faster than realtime, offline analysis, was largely what drove me to write a wrapper in max Java around Holger’s library.

Alpha release is here !

Alpha release is here !

The alpha release is now finished and I’m posting a jar file for windows. UPDATED:  NOW MAC COMPATIBLE.

This alpha release includes an example application patch showing off the slicing abilities and a reference text file to talk you through the numerous attributes of the external (though this is a work in progress, you will need to refer to Holger’s website and the MPEG7 audio standard for lots of useful details).

frecycle is a recycle clone entirely in max msp

frecycle is a recycle clone entirely in max msp

The frecycle patch is modelled on Propellerhead’s beat mash up defining Recycle. Simpy load a mono audio wav and drag the slice threshold bar to the right to increase the number of slices. These are automatically mapped to midi keyboard keys starting at midi note number 36. The pitch bender gives +/- 50% pitch range and the funky autosequence gives good results with one or two bar drum loops with the slice threshold moderately low. Enjoy!

To install the alpha release simply download the zip and follow the installation instructions in INSTALL.txt.

DL: Mpeg7Encoder-alpha-distro-mac-compatible.zip

The technically enclined may enjoy the source code at the project’s Sourceforge page.

Hopefully next week I’ll follow up with my meta sampler patch that allows you to use the SQL database to auto map sounds according to their spectral features.

Other stuff, Software , , ,

5 reasons why you need analysed segmented audio

June 8th, 2009

I checked my google analytics page today and found my bounce rate was over 80%. After having taken the time to find out what that meant I read google’s (not at all evil) guide to writing web headlines. Hence the title.

I’ve spent the past fortnight polishing up an external I wrote to analyse, segment and store information on sounds in MaxMSP, there are a couple of other objects that do similar stuff like Jehan’s analyzer~ or the mac only and now defunct slice~ but I wanted something that could work offline, automated and in a database friendly fashion. The version I came up with to achieve this uses a fairly thick wrapper, written in mxj, around Holger Crysandt’s java MPEG7 encoder.So what are the five reasons why this might be any use to you?

  1. How often do you find yourself wishing you had a simple beat slicer like that of recycle, kontakt or live in max that didn’t need a load of patching on your part but could just be dropped in to work with files or audio? I work with libraries of breakbeats in my music making and spend a lot of time slicing, plus for generative art pieces as I am wont to create, segmenting audio is often the first step in reappraising and changing existing works into new ones.
  2. Wouldn’t it be nice if when the slicing was finished rather than grouping kicks, snares, hats and other percussion by hand you could let the computer do it for you? A slicer that has inbuilt audio analysis is the first step for doing this.
  3. When you’re working on a beat and you want to try similar sounds wouldn’t it be nice if the computer could suggest similar sounds from a set you’ve specified? Analysed audio with good metadata can make this possible.
  4. Isn’t life too short to spend an age cutting and labelling every beat before deciding if they even work in a track? By using automated tools for cutting up audio you could test many sounds, find surprising new relationships before saving the segments for use in whatever package you fancy.
  5. Segmented, meta-data heavy audio file formats such as MPEG7 open up some interesting new possibilities for generative and interactive audio as well as regular music applications, why not get ahead on an emerging standard by spending a few hours knobbing about with it in everyone’s favourite graphical patching language?

That’s it, those were my five reasons, and if you don’t click on the below photo for a closer look at my MPEG7 external development then my bounce rate will only increase. Expect a buggy beta this week.

Screenshot of MPEG7 encoder and database externals for MaxMSP, writing helpfiles and proper documentation are some of the least fun things I do

Screenshot of MPEG7 encoder and database externals for MaxMSP, writing helpfiles and proper documentation are some of the least fun things I do.

Blogging, Music, Software , , , , ,

Euclidean beat generator redux

June 8th, 2009

After developing my euclidean beat generator for use in my Journey through a burning brain exhibit and reading some of the feedback from other users, I have developed some new features. This version is fully pattrstorage compatible allowing interpolation between beat presets. This came out of a conversation I had with a user I met on the max forums who had put the patch to use with his own genetic algorithms using brain waves as a fitness test. I was pretty impressed with what he’d done and was delighted to see a photo of his patch on David Zicarelli’s look back at expo ‘74.

Expo '74 Attendee patch running EEG (brainwave) controlled genetic algorithms for better euclidean beats. Photo by attendee John Manoogian III.

Expo '74 Attendee patch running EEG (brainwave) controlled genetic algorithms for better euclidean beats. Photo by attendee John Manoogian III.

Future versions will include less buggy gui recall and the ability to specify simple strings to the js object that program the sequences.

Euclidean beat generator 1.01, now with added preset interpolation, discover the grooves between the grooves

Euclidean beat generator 1.01, now with added preset interpolation, discover the grooves between the grooves

Euclid Max Source Patches: EUCLID.zip

Euclid Standalone: euclid_standalone.zip

Software , , ,

Journey through a burning brain

May 26th, 2009

Last Saturday as part of the 2009 Symposium on user generated content, interaction and design I had the opportunity to road test my installation piece ‘Journey through a burning brain’ which until I was forced to choose a title for the printed materials was previously known as my ‘youtube TV installation’.

IMG_0683.jpg

Similar to my previous radio piece I chose an old piece of hardware to form the interface which I could then go about subverting. This time a 1970’s Hitachi TV that I found languishing under the stairs when I moved into my flat was put into service along with a gigantic space age TV remote that I found in Maplins. On reflection the space age remote might go next time around as it sort of breaks with the conceit of interacting with an aged decrepit telly.

The central idea behind the piece was to use the content of youtube to provide a navigable database of content which could be reinterpreted through algorithmic cut ups. Again as with my radio piece it’s about the idea of browsing, channel hopping, surfing, constantly hunting through media for the next thing that will satiate us for a moment.

Technically the installation consisted of three laptops running MaxMSP/Jitter, my IR ardiuno box, the telly and remote.  The first laptop took care of downloading, transcoding and analysing videos from youtube, the second receiving and interpreting the user’s clicks and re-sequencing and playing the audio while the third played the videos through my Rutt Etra jitter synth and visualized the youtube database.

It was well recieved at the symposium but I feel that the remote control button’s mapping to the indivual features of the piece needs a little work before I find a gallery where it can sit for a week. I’m now hoping to move the piece online and use google’s youtube API to automatically repost my algorithmic video mashups and then incorporate video rating/play counts as a fitness test for genetic algorithms controlling the sequencing and sample selection.

Other stuff , , , , , ,

Euclidean algorithmic beat generator

April 4th, 2009
euclid

Euclidean rhythm generator with minimalist sequence visualizer

After stumbling upon an interesting thread on the max forums, reading Godfried Toussaint’s interesting paper on the subject and checking out some other similar creations across the internets, including a vst, ruby and lisp implementation I decided this sounded interesting enough to devote some time to and perhaps a good excuse to learn some scripting for Max. I won’t bother going over how Euclid’s algorithm works for sequencing beats as it is detailed very well in the paper and this blog post by Ruin & Wesen. Instead I’ll focus on how I made the patch and the things I learnt along the way. For those who just want the patch to play with I’ll post the links here to save you a whole load of scrolling. I’ve also built a standalone version for those without Max who want to get in on the whole algorithmic beat generation thing.

euclid_patches.zip Max 5 Patcher file and js

euclid_patches.zip Max 5 standalone

Scripting the creation, connection and destruction of Max objects from inside Max itself is pretty much the last thing in the instruction manual. I think is because of the weight Cycling put into the idea that Max is a graphical programming language for non-programmer types. While I think it’s great that Max appeals to arty programming phobes I like programming and and I’m arrogant enough to think I’m pretty good at it. I also periodically yearn for ‘for’ loops and proper conditional logic while patching without resorting to convoluted chains of uzis, gates and less-than objects. I think some people are really good at using Max that way and can mangle a coll into doing their evil bidding through shear patch magic, but I get annoyed after three clicks when I know I could achieve the same task in a single line in a ‘proper’ programming language.

As such I’ve become increasingly enamoured with Max’s js and mxj objects that allow you to program in javascript and java respectively, as well as Thomas Grill’s really nice py external which allows for python scripting inside Max. For this project I quickly decided on js as I wanted to try out some auto patch generation. As most of the gui objects have their creation scripted I don’t have to bother monotonously naming each of them and pixel pushing them into alignment. This is js’s first really nice feature but I quickly learnt that it’s best if your js checks for the existence of an object before creating one or you have to delete all your objects before you reload your altered js program every time you make a change.

In the rhythm sequencer I wanted boxes for the number of steps, pulses, accents, offset, accent offset and midi note number and I wanted a set of these boxes for each rhythm part. This is what the first part of the code achieves.

//maximum number of parts
var maxparts = 16;

//x and y to start drawing boxes from
var px = 30;
var py = 500;

//inlets and outlets
inlets = 1;
outlets = 1;

//global variables
var p = this.patcher; //saves typing
var numparts;

//Maxobj variables for scripting
var step_boxes = new Array(maxparts);
var s_message = new Array(maxparts);
var pulse_boxes = new Array(maxparts);
var p_message = new Array(maxparts);
var accent_boxes = new Array(maxparts);
var a_message = new Array(maxparts);
var offset_boxes = new Array(maxparts);
var o_message = new Array(maxparts);
var aoffset_boxes = new Array(maxparts);
var ao_message = new Array(maxparts);
var note_boxes = new Array(maxparts);
var n_message = new Array(maxparts);
var seq;
var lcd1;
var lcd2;
var lcd_width = 300;
var lcd_height = 600;

//arrays for holding steps, pulses, accents and offsets and midi note numbers
var steps = new Array(maxparts);
var pulses = new Array(maxparts);
var accents = new Array(maxparts);
var offsets = new Array(maxparts);
var aoffsets = new Array(maxparts);
var outnote = new Array(maxparts);

//array for all the sequences
var riddims = new Array();

//useful number
var deg2rad = 2 * Math.PI / 360

//executed on startup
function loadbang() {
    post("euclidean rhythm generator - robin price 2009\n");
    //do comments
    step_comment = p.getnamed("step_comment");
    if (step_comment == null) {
        step_comment = p.newdefault(px, py + 20, "comment", "@text", "Steps", "@varname", "step_comment", "@presentation", 1);
    }
    pulse_comment = p.getnamed("pulse_comment");
    if (pulse_comment == null) {
        pulse_comment = p.newdefault(px + 60, py + 20, "comment", "@text", "Pulses", "@varname", "pulse_comment", "@presentation", 1);
    }
    accent_comment = p.getnamed("accent_comment");
    if (accent_comment == null) {
        accent_comment = p.newdefault(px + 120, py + 20, "comment", "@text", "Accents", "@varname", "accent_comment", "@presentation", 1);
    }
    offset_comment = p.getnamed("offset_comment");
    if (offset_comment == null) {
        offset_comment = p.newdefault(px + 180, py + 20, "comment", "@text", "Offset", "@varname", "offset_comment", "@presentation", 1);
    }
    aoffset_comment = p.getnamed("aoffset_comment");
    if (aoffset_comment == null) {
        aoffset_comment = p.newdefault(px + 240, py + 20, "comment", "@varname", "aoffset_comment", "@presentation", 1);
        aoffset_comment.message("set", "Accent\nOffset");
    }
    note_comment = p.getnamed("note_comment");
    if (note_comment == null) {
        note_comment = p.newdefault(px + 300, py + 20, "comment", "@varname", "note_comment", "@presentation", 1);
        note_comment.message("set", "Output\nNote");
    }
    //other scripted objects
    seq = p.getnamed("seq");
    if (seq == null) {
        seq = p.newdefault(1000, 1000, "seq~");
        seq.message("sendbox", "varname", "seq");
    }
    lcd1 = p.getnamed("lcd1");
    if (lcd1 == null) {
        lcd1 = p.newdefault(900, 900, "lcd", "@border", 0, "@ignoreclick", 1, "@presentation", 1);
        lcd1.message("varname", "lcd1");
        lcd1.message("size", lcd_width, lcd_height);
    }
    lcd2 = p.getnamed("lcd2");
    if (lcd2 == null) {
        lcd2 = p.newdefault(900, 900, "lcd", "@border", 0, "@ignoreclick", 1, "@bgtransparent", 1, "@presentation", 1);
        lcd2.message("varname", "lcd2");
        lcd2.message("size", lcd_width, lcd_height);
        p.bringtofront(lcd2);
    }
    for (i = 0; i < maxparts; i++) {
        steps[i] = 16;
        pulses[i] = 4;
        accents[i] = 2;
        offsets[i] = 0;
        aoffsets[i] = 0;
        outnote[i] = 60 + i;
        //step boxes and messages
        step_boxes[i] = p.getnamed("step_" + i);
        if (step_boxes[i] == null) {
            step_boxes[i] = p.newdefault(px, py - i*25, "number", "@minimum", 1, "@maximum", 128, "@varname", "step_" + i);
        }
        step_boxes[i].set(steps[i]);
        s_message[i] = p.getnamed("step_message_" + i);
        if (s_message[i] == null) {
            s_message[i] = p.newdefault(px, 100 + py + i*25, "message", "@varname", "step_message_" + i);
        }
        s_message[i].message("set", "step", i, "\$1");
        p.connect(step_boxes[i], 0, s_message[i], 0);
        p.connect(s_message[i], 0, this.box, 0);
        //pulse boxes and messages
        pulse_boxes[i] = p.getnamed("pulse_" + i);
        if (pulse_boxes[i] == null) {
            pulse_boxes[i] = p.newdefault(px + 60, py - i*25, "number", "@minimum", 0, "@varname", "pulse_" + i);
        }
        pulse_boxes[i].set(pulses[i]);
        pulse_boxes[i].message("maximum", steps[i]);
        p_message[i] = p.getnamed("pulse_message_" + i);
        if (p_message[i] == null) {
            p_message[i] = p.newdefault(px + 60, 100 + py + i*25, "message", "@varname", "pulse_message_" + i);
        }
        p_message[i].message("set", "pulse", i, "\$1");
        p.connect(pulse_boxes[i], 0, p_message[i], 0);
        p.connect(p_message[i], 0, this.box, 0);
        //accent boxes and messages
        accent_boxes[i] = p.getnamed("accent_" + i);
        if (accent_boxes[i] == null) {
            accent_boxes[i] = p.newdefault(px + 120, py - i*25, "number", "@minimum", 0, "@varname", "accent_" + i);
        }
        accent_boxes[i].set(accents[i]);
        accent_boxes[i].message("maximum", pulses[i]);
        a_message[i] = p.getnamed("accent_message_" + i);
        if (a_message[i] == null) {
            a_message[i] = p.newdefault(px + 120, 100 + py + i*25, "message", "@varname", "accent_message_" + i);
        }
        a_message[i].message("set", "accent", i, "\$1");
        p.connect(accent_boxes[i], 0, a_message[i], 0);
        p.connect(a_message[i], 0, this.box, 0);
        //offset boxes and messages
        offset_boxes[i] = p.getnamed("offset_" + i);
        if (offset_boxes[i] == null) {
            offset_boxes[i] = p.newdefault(px + 180, py - i*25, "number", "@minimum", 0, "@varname", "offset_" + i);
        }
        offset_boxes[i].set(offsets[i]);
        offset_boxes[i].message("maximum", steps[i] - 1);
        o_message[i] = p.getnamed("offset_message_" + i);
        if (o_message[i] == null) {
            o_message[i] = p.newdefault(px + 180, 100 + py + i*25, "message", "@varname", "offset_message_" + i);
        }
        o_message[i].message("set", "offset", i, "\$1");
        p.connect(offset_boxes[i], 0, o_message[i], 0);
        p.connect(o_message[i], 0, this.box, 0);
        //accent offset boxes and messages
        aoffset_boxes[i] = p.getnamed("accent_offset_" + i);
        if (aoffset_boxes[i] == null) {
            aoffset_boxes[i] = p.newdefault(px + 240, py - i*25, "number", "@minimum", 0, "@varname", "accent_offset_" + i);
        }
        aoffset_boxes[i].set(aoffsets[i]);
        aoffset_boxes[i].message("maximum", pulses[i] - 1);
        ao_message[i] = p.getnamed("accent_offset_message_" + i);
        if (ao_message[i] == null) {
            ao_message[i] = p.newdefault(px + 240, 100 + py + i*25, "message", "@varname", "accent_offset_message_" + i);
        }
        ao_message[i].message("set", "accent_offset", i, "\$1");
        p.connect(aoffset_boxes[i], 0, ao_message[i], 0);
        p.connect(ao_message[i], 0, this.box, 0);
        //note boxes and messages
        note_boxes[i] = p.getnamed("note_" + i);
        if (note_boxes[i] == null) {
            note_boxes[i] = p.newdefault(px + 300, py - i*25, "number", "@minimum", 0, "@maximum", 127, "@format", 4, "@varname", "note_" + i);
        }
        note_boxes[i].set(outnote[i]);
        n_message[i] = p.getnamed("note_message_" + i);
        if (n_message[i] == null) {
            n_message[i] = p.newdefault(px + 300, 100 + py + i*25, "message", "@varname", "note_message_" + i);
        }
        n_message[i].message("set", "note", i, "\$1");
        p.connect(note_boxes[i], 0, n_message[i], 0);
        p.connect(n_message[i], 0, this.box, 0);
    }
    notifyclients();
    calculate(-1);
    parts(1);
    bang();
}

 This seems fairly dense at first but mostly it’s just doing the same thing over and over again to create all the number boxes along with a message box that allow us to update our variable inside js. I chose this method of creating each number box connected to a personalised message box because js in Max has no native method of reading the contents of a screen object. Hence the workaround, each group of objects, step, pulse boxes or whatever are created connected to a message box which is connected to the js object. The message boxes are formatted so that when the user changes the number in any of the gui boxes a method is called that tells js which box changed and what number it now carries. This allows for a user interface where each of the boxes is updated as the other entries are changed. This lets you add nice features like number boxes that update the other boxes around them so they cannot display nonsensical values, i.e. a rhythm part with more pulses than steps to hold them.

Looking through the code you can see first off I define a maxparts global variable which sets the maximum number of rhythm parts and thus groups of number boxes the script creates. I then create variables to control where the patch starts creating the objects in the patcher window and the number of inlets and outlets on the js box itself. The variable p is just to save typing this.patcher every time I want to do something with the patcher and numparts describes the number of active rhythm parts at the present time. Next I create references to all of the objects I’ll create and access in the script, for the most part these references are stored in arrays as there are so many of them and doing so allows for thing like iterating across them. Then I create arrays to hold the settings for each rhythm part and an array that will hold all the sequences that have been generated.

The loadbang() is executed when the patch is started just like a loadbang in the patch, this creates the comments, number and message boxes and a few other goodies. Note the form for each object.

step_comment = p.getnamed("step_comment");
if (step_comment == null) {
    step_comment = p.newdefault(px, py + 20, "comment", "@text", "Steps", "@varname", "step_comment", "@presentation", 1);
}

First I try and get a reference to an object in the patch and then I check if that reference is null, if it is it’s obviously been clobbered or something so I recreate it. This way whenever you reload a js during its development it doesn’t create multiple copies of the same set of objects.

Next I define a set of functions that will be called by the user changing the values of the number boxes. These allow the script to take care of updating the other boxes and the seq~ object whenever anything changes. Here is the function for the step boxes.

function step(n, val) {
    if (n >= 0 && n < maxparts && val >= 0 && val <= 128) {
        //number of steps must always be greater than or equal to the number of pulses
        if (val >= pulses[n] && val > offsets[n] && val >= accents[n]) {
            steps[n] = val;
            pulse_boxes[n].message("maximum", val);
            offset_boxes[n].message("maximum", val - 1);
        } else {
            if (val < pulses[n]) {
                pulses[n] = val;
                pulse_boxes[n].message("set", val);
                pulse_boxes[n].message("maximum", val);
                if (val <= aoffsets[n]) {
                    aoffsets[n] = val;
                    aoffset_boxes[n].message("set", val - 1);
                    aoffset_boxes[n].message("maximum", val - 1);
                }
            }
            if (val <= offsets[n]) {
                offsets[n] = val - 1;
                offset_boxes[n].message("set", val - 1);
                offset_boxes[n].message("maximum", val - 1);
            }
            if (val < accents[n]) {
                accents[n] = val;
                accent_boxes[n].message("set", val);
                accent_boxes[n].message("maximum", val);
            }
            steps[n] = val;
        }
        notifyclients();
        calculate(n);
        programme_seq(n);
        bang();
    } else {
        post("steps message needs two integers between 0 0 and " + maxparts + " 128\n");
    }
}

This function starts by checking the values it’s been passed (which number box got changed, n, and it’s new value, val) make sense and then goes on to update the internal representation steps[n] and update the other number boxes in the rhythm part if the new value requires it. Finaly it causes the new rhythm to be calculated, programmes the seq~ and redraws the graphics which I’ll discuss after touching on the next noteworthy function.

function parts(i) {
    if (arguments.length) { //bail if no arguments
        a = arguments[0];
        if (a < 0) a = 0;
        if (a > maxparts) a = maxparts;
        numparts = a;
        for (z = 0; z < maxparts; z++) {
            if (z < numparts) {
                step_boxes[z].message("presentation", 1);
                pulse_boxes[z].message("presentation", 1);
                accent_boxes[z].message("presentation", 1);
                offset_boxes[z].message("presentation", 1);
                aoffset_boxes[z].message("presentation", 1);
                note_boxes[z].message("presentation", 1);
                programme_seq(z);
            } else {
                step_boxes[z].message("presentation", 0);
                pulse_boxes[z].message("presentation", 0);
                accent_boxes[z].message("presentation", 0);
                offset_boxes[z].message("presentation", 0);
                aoffset_boxes[z].message("presentation", 0);
                note_boxes[z].message("presentation", 0);
                clear_seq(z);
            }
        }
        notifyclients();
        bang();
    } else {
        post("parts message needs integer argument between 0 and " + maxparts + "\n");
    }
}

This nugget of javascript allows us to change the number of currently active rhythm parts and update the visible elements of the patch so we’re not distracted by anything that isn’t doing anything.

As for calculating the rhythm this is taken care of by the calculate() function which gets the euclidean sequence for a given number of pulses and steps, the sequence for a number of accents and pulses, applies any rotation to the either sequences (using code I stole from here) and applies the accents to the rhythm. Actually most of the work is done by sub functions eugen() and apply_accents().

function eugen(s, p) {
    var r = new Array();
    if (p >= s || s == 1 || p == 0) { //test for input for sanity
        if (p >= s) {
            for (i = 0; i < s; i++) { //give trivial rhythm of a pulse on every step
                r.push(1);
            }
        } else if (s == 1) {
            if (p == 1) {
                r.push(1);
            } else {
                r.push(0);
            }
        } else {
            for (i = 0; i < s; i++) {
                r.push(0);
            }
        }
    } else { //sane input
        pauses = s - p;
        if (pauses >= p) { //first case more pauses than p
            per_pulse = Math.floor(pauses / p);
            remainder = pauses % p;
            for (i = 0; i < p; i++) {
                r.push(1);
                for (j = 0; j < per_pulse; j++) {
                    r.push(0);
                }
                if (i < remainder) {
                    r.push(0);
                }
            }
        } else { //second case more p than pauses
            per_pause = Math.floor( (p - pauses) / pauses);
            remainder = (p - pauses) % pauses;
            for (i = 0; i < pauses; i++) {
                r.push(1);
                r.push(0);
                for (j = 0; j < per_pause; j++) {
                    r.push(1);
                }
                if (i < remainder) {
                    r.push(1);
                }
            }
        }
    }
    return r;
}

function apply_accents(r, a) {
    var offset = 0;
    var out = new Array(r.length);
    for (b = 0; b < r.length; b++) {
        if (r[b] == 1) {
            if (a[offset] == 1) {
                out[b] = 1;
            } else {
                out[b] = 0.5;
            }
            offset += 1;
        } else {
            out[b] = 0;
        }
    }
    return out;
}

Eugen() is basically the most important part of the whole thing as it implements the algorithm for the distribution of the beats. When the rhythm is programmed the seq~ object in the Max patch is updated by the programme_seq() function. This sends a sequence of messages to the named seq~ object in the patch (no need for patch cables, we can send them direct) that programmes the id number and midi notes into the seq~.

function programme_seq(arg) {
    clear_seq(arg);
    r = riddims[arg];
    for (l = 0; l < steps[arg]; l++) {
        if (r[l] == 1) {
            seq.message("add", 0, l / steps[arg], arg, outnote[arg], 127);
            seq.message("add", 0, l / steps[arg] + (1 / steps[arg] - 1 / 256), arg, outnote[arg], 0);
        } else if (r[l] == 0.5) {
            seq.message("add", 0, l / steps[arg], arg, outnote[arg], 100);
            seq.message("add", 0, l / steps[arg] + (1 / steps[arg] - 1 / 256), arg, outnote[arg], 0);
        }
    }
}

programme_seq.local = 1;

function clear_seq(arg) {
    if (arg == -1) {
        for (h = 0; h < maxparts; h++) {
            seq.message("delete", 0, 0.0, 1.0, h);
        }
    } else {
        seq.message("delete", 0, 0.0, 1.0, arg); //delete all entries for sequence
    }
}

clear_seq.local = 1;

The last part of the js takes care of the ultra minimalistic sequence visualization. At first I tried using Max’s jsui object but I found it is an exceptional CPU hog so I created two lcd objects one for the sequence and one for the red line showing the playback location. The red line lcd has a transparent background and sits on top of the other sequence visualizer. This way when ever the playback line is redrawn we don’t have to redraw the rest of the sequence visualization. This is a really good example of using js’s procedural (as opposed to graphical) logic to send a set of messages to a Max object, this would be tricky (for me at least) to achieve with native Max graphical methods.

function draw() {
    lcd1.message("clear");
    var rowheight = (0.5 * lcd_height) / numparts;
    for (y = numparts - 1; y >= 0; y--) {
        var boxwidth = lcd_width / steps[y];
        var arcwidth = 360 / steps[y];
        var arcradius = (lcd_width/2) * (y + 1) / numparts;
        var r = riddims[y];
        for (x = 0; x < steps[y]; x++) {
            if (r[x] == 1) {
                lcd1.message("frgb", 0, 0, 0);
                lcd1.message("pensize", 1, 1);
                lcd1.message("paintarc", lcd_width/2 - arcradius, lcd_width/2 - arcradius, lcd_width/2 + arcradius, lcd_width/2 + arcradius, x * arcwidth, arcwidth + 2);
                lcd1.message("paintrect", boxwidth*x, lcd_height - rowheight*(y+1), boxwidth*(x+1), lcd_height - rowheight*y);
            } else if (r[x] == 0.5) {
                lcd1.message("frgb", 100, 100, 100);
                lcd1.message("pensize", 1, 1);
                lcd1.message("paintarc", lcd_width/2 - arcradius, lcd_width/2 - arcradius, lcd_width/2 + arcradius, lcd_width/2 + arcradius, x * arcwidth, arcwidth + 2);
                lcd1.message("paintrect", boxwidth*x, lcd_height - rowheight*(y+1), boxwidth*(x+1), lcd_height - rowheight*y);
            } else {
                lcd1.message("frgb", 255, 255, 255);
                lcd1.message("pensize", 1, 1);
                lcd1.message("paintarc", lcd_width/2 - arcradius, lcd_width/2 - arcradius, lcd_width/2 + arcradius, lcd_width/2 + arcradius, x * arcwidth, arcwidth + 2);
            }
        }
    }
    for (y = 0; y < numparts; y++) {
        var boxwidth = lcd_width / steps[y];
        for (x = 0; x < steps[y]; x++) {
            lcd1.message("frgb", 255, 255, 255);
            lcd1.message("linesegment", boxwidth*x, lcd_height - rowheight * y - 1, boxwidth * x, lcd_height - rowheight * (y+1));
        }
    }
}

function settime(time) {
    lcd2.message("clear");
    lcd2.message("frgb", 255, 0, 0);
    lcd2.message("linesegment", ((time + 0.001) * lcd_width) % lcd_width, lcd_height/2, ((time + 0.001) * lcd_width) % lcd_width, lcd_height);
    lcd2.message("linesegment", lcd_width/2, lcd_height/4, lcd_width/2 + (lcd_width/2) * Math.sin(-time*Math.PI*2 - Math.PI), lcd_width/2 + (lcd_width/2) * Math.cos(-time*Math.PI*2 - Math.PI));
}

That pretty much covers most of what my patch is doing, in the future I hope to update it with some interesting swing and shuffle options by sending the phasor~ signal through a table lookup waveshaper and some industrial sounding msp beatbox voices.

Music , , ,

Acieeeeeeeeed Sunrise

March 22nd, 2009
10,000 Hours in MS-Paint

10,000 Hours in MS-Paint

A new track is here, a new dawn rises on the world of acid based music as blah blah blah. My ears are ringing from mixing all weekend so I’ll cut to the chase, here’s the track.

Acid Sunrise

This track grew out of little riff that I had programmed in to my x0xb0x when experimenting with ridiculously long slides. Andy and I bopped and grooved for about 3 hours in the studio while recording variations on it, mainly tweaking out shit loads of distortion off Brian Castro’s excellent x0xi0 back panel mod. At the same time I came up with a melody on the Juno which Andy knob twiddled all over, riding the filter like porn stars ride big black cocks. This left us with a shit load of wavs and no real structure, so we gave the whole thing to Pete for a fortnight. Pete started looping tiny sections of the Juno’s sunshine sound and created the rythmic pad element that is the key to the whole track as well as coming up with some really nice drum patterns. We then got back together and worked out a 6 minute slow burning acid build up that busts out into low pass filtered joy by the end of the track.

I really enjoyed making this but it has come at some cost, I’m pretty sure my upstairs neighbours hate me. They’re new to the house and don’t have the same tolerance for repetitive bass heavy sound at all hours of the day as the previous tennants. As well as the typical foot stomping in protest (maybe praise ??) at my band’s output at one point all out sound war was declared as the brought a power drill into their room above my studio and tried to out do me. Fuckers.

Music

Rubber Steak Knife Acid

March 7th, 2009
ACIEED

ACIEEEEEEED

Between working frantically on my youtube TV installation I have finished off a track that me and a mate called Andy started one rainy afternoon. Andy’s pretty awesome at the old techno though he won’t admit it because he’s faaaaart too nice to be in your face with that kind of stuff. Anyway me and Pete who together form A.C.I.D decided we should let him in the band and this is his first track with us. Andy programmed the bass lines which came off my x0xb0x and Native Instrument’s Massive while I made some simple ‘pippy’ drums on my Jomox XBase09 which Andy augmented with some 808 samples in Battery. Basically we grooved around my studio for a few hours a fortnight ago in Ableton Live making a big loop which I padded out into 7 minutes of repetitive funk over the last two weeks. I added the lead synth line while Andy was in the studio off a Juno 60 which coincidentally was Andy’s till I bought it off him last December for £400. The Juno’s a lovely synth and there’s buckets of sounds to explore inside it’s simple architecture, here I was using all 3 oscillators and keeping the amplitude envelope’s sustain down low while twiddling the decay and release knobs. When I was fleshing the track out I went for dub delay drenched sound inspired by Kruder and Dorfmeister after Pete said that when dry the Juno sounded too trancy. The delay lines, all 3 of them, came from from Reaktor’s echomania ensemble which is a personal favourite of mine and a one stop dub delay shop. The low tone in the background and the high pads came off my two Waldorf Pulses as did the reversed wooshing sound at 3:50. A heavily filtered FM8 sample made into the first break down and I think that was pretty much it.

Andy and I were both really inspired after listening to M.A.N.D.Y At The Controls mix album (probably one of the best cd’s I’ve bought, definitely in the top 5) and we were going for that kind of minimal tech house kind of style. I don’t know if the dub delay crowded the mix too much but either way I’m pleased with the results. Check the track below and let us know what you think.

Rubber Steak Knife Acid

About the name, the bass is kind of rubbery, the beat is sort of meaty and the lead line is sharp, simples.

Music ,