(Part Two in an occasional series. Part One was three-and-a-half years ago. Try the tip, though, it still works in Winamp 5.) (Oh, and the proper Ning stuff is coming soon, I promise.)
Occasionally, one wants to listen to music in computer data files. One also wants one’s llama’s ass really whipped. To achieve both of these in a single package, Winamp is recommended. (Poor Mac and Gnulix users! They have to choose one or the other. Ha ha ha! But don’t worry, Mac fans – there’s a bonus treat for you at the end of this blog entry.) Winamp gets much of its llama-whippingness from the hardcore n3rd-5|<i((5 of people like Mr Frankel, and this is visible in the insanity of its built-in expression languages.
NOTE how I said expression languages. Not scripting languages. Scripting languages are for arsing about with hotkeys that switch the equalizer mode for every room in your house, or post your current playlist into a Flash movie on your MySpace site every 12 seconds. They are lame, and you suck for wanting them. Expression languages are for manipulation of audio-visual magic using raw, high-power mathematiznics. And the engines for this come built in, super-optimised and remarkably under-documented.
You may have already played with the Winamp AVS – if not, go have some fun with it, ‘cos not only can you get it to produce some remarkably Minter visuals but it gives you the tools to build your own – both by piping existing things together and by writing exciting mini-programs inside of Winamp that you can see working live as you type them. This is incredibly cool, but I’m not going to talk about AVS today. I’m going to talk about something hidden a little deeper that I came across almost by accident.
BUT WAIT! Before you go any further with Winamp, be warned that versions below 5.13 have a stupid great security hole in them and you should upgrade pronto.
So I was on the Caltrain earlier and randomly clicking on things in Winamp while listening to The Fall. My wife was listening to Fear Factory and Linkin Park. She was playing them to the baby as well, thanks to the fabulous belt-speaker-arrangement we bought that allows her to provide surround sound in utero. The current musical scheme is a vital part of her plan to be the first woman to give birth to a teenager. ANYWAY. (Sorry, this is starting to sound a bit too much like a bad Why imitation, who in turn sounds like the CompSci version of a demented vicar. “One day the foxes scurried along the beach and cracked open cans of Tab while throwing boomerangs. And, you know, that’s a little bit like Closures!”)
To do what I did:
- In Winamp (duh) go Options->Preferences->Plugins->DSP
- Click on “Nullsoft Signal Processing Studio” then “Configure active plugin”
- You now see the NSPS editing box. It looks a bit amateurish and, frankly, VBRUNny. But do not be fooled. This is where you can change sound with maths.
You can see the complete docs (as concise and unfriendly as they are) by clicking “Help”. But skip that for the moment, let’s have some fun. Tick the “Enable Processing” checkbox and click the “Show Editor” button, then copy this code snippet into the third big textbox (“Per sample”):
Now play a jolly tune, preferably “Telephone Thing” by the aforementioned Fall. It plays at double speed! I can explain why by starting with this handy PNG of a waveform:
There is your jolly waveform, representing a jolly tune. Along comes a jolly waveform hunter with a jolly gun, and shoots half the pixels out of it:
Half the wavelength = twice the frequency, so everything goes a bit squeaky. But how does this relate to the code snippet? To start with, bear in mind that the code in question is run once for each sample in the MP3 – a sample being equivalent to a single-pixel-strip in the image. Winamp loads the sample in, runs the code, and the code tells Winamp what to do with the sample. Now the code…
- bnot() is this language’s version of the logical NOT operator – it flips 1 to 0 and vice-versa. tmp is a random variable we’ve called into existance. It starts at 0 and is toggled back and forth for each sample.
- skip is a special reserved variable – if it’s set to a true value (i.e. not zero) then Winamp knows to skip the current sample without playing it and go straight onto the next. The more samples that have skip set to true, the faster the tune will be played.
So what the code is doing is alternating the tmp variable between 1 and 0, and setting skip accordingly. This means that every second sample is skipped so the tune plays at twice the speed. (Incidentally, try cutting the code out of the box, then pasting it back in while the music’s playing. It’ll take a second or so, but suddenly it’ll run! In the middle of playing! I love Nullsoft. Their MP3 player compiles code but NEVER STOPS THE ROCK.
Anyway, we’re not done yet. There are these lovely signal processing controls with sliders and buttons that we haven’t touched. Time to randomly grab and twiddle…
Once you’ve pasted this and are playing something suitably durge-y, grab the leftmost slider and pull it upwards. Everything starts speeding up! The variable slider1 contains a value between 0 and 1 according to where the slider is on the scale. The floor(tmp) function returns the nearest integer below the value of tmp – basically, it returns 0 if tmp is below 1, and 1 if it’s above. So in the code above, tmp gradually increases until it’s above 1, when it flips skip and then crashes way below 1 again. The rate depends on the position of the slider.
So let’s have a go at making it swing both ways…
The code above uses the repeat variable, which is like the opposite of skip – it loops around the current sample again without moving on. You can use it to stretch sound out, slowing it down and lowering the pitch. The result of the code above is that the slider has now become an honest-to-goodness +/-8% pitch control, just like you’d find on a Technics SL-1200 (a.k.a. God’s Own Turntable). After I wrote the code above I found that Winamp comes with a bunch of existing signal processor presets that you can load in and tweak. Mr Frankel had already written a pitch control, but his looks like this:
if(above(slider1,0.5), // speedup assign(skip,above(pos,speedupval)) , // slow down assign(repeat,above(pos,slowdownval)) ); pos=if(skip,pos-speedupval,pos); pos=if(repeat,pos-slowdownval,pos); pos=pos+bnot(bor(skip,repeat));
… not including the slider change/initialisation code (another two lines) which means I HAVE TOTALLY OUT-CODED JUSTIN FRANKEL apart from the bit where he wrote the world’s best MP3 player software and P2P network and built a guitar effects box in the shape of a crucifix
Anyway, have a play with the presets, which also include minisamplers and reverbs and other wacky shiznit. Then move onto AVS, which is a whole other world. (and it has prettier colours)
(Have you been hanging on for the bonus Mac tip? Well done! Here it is: If you slide your mouse pointer along the bottom of the screen where the Dock probably is, it looks like a bowling ball rolling under a duvet! Nifty, eh? Have fun!)