|
|
Friday, December 9th, 2011
| |
9:18 pm - The Care And Feeding Of Songs
|
|
It is a truth universally acknowledged that some songs are better than others. And it ought to be pretty widely acknowledged that there are some people who can take a perfectly good song and perform it in a way that makes you wish you were temporarily deaf. The second thought came to me this morning. Our neighbour on one side is a perfectly nice old Aussie bloke who likes music from a certain period and/or genre. The genius of the Shadows frequently features on his playlist. Top hits of the late 60s and early 70s can often be heard, especially since he's a little deaf and likes to turn it up a bit. But this is all fine... or was, until he played Richard Clayderman whilst we were eating breakfast. To be fair, it may not have been Mr Clayderman. I'm sure there are other instrumentalists who make their livings by reducing good songs to feeble elevator muzak... in any event it got me thinking about what makes a good song. Or rather, a good "track", and by that I mean a performance of a song, rather that just the song itself. Here's my theory: in order to be listenable, a track has to have at least one of: (a) an interesting melody that's balanced between predictability and surprise (b) interesting lyrics that mean something to the listener (c) a genuine and moving performance Time for some examples. Let's take (c) first, because I'm feeling perverse. The Sex Pistols 'God Save The Queen' has no real melody and the lyrics aren't all that hot ("potential H-bomb"? What?). But it works (for me) because it's played with a sneering, raucous enthusiasm that makes a very simple song work. The same's true of, say, Iggy Pop's 'I Wanna Be Your Dog': four chords, not very many words and yet it can grab some people by the scruff of their brain. Or (c) can be achieved by just a voice; personally, I could listen to Cerys Matthews reciting the digits of pi for hours just to hear her voice. Moving away from tracks to songs: it's easy to find examples for (b). And it's this that Mr Clayderman's performance was making me ponder this morning. Since there were no words, all you could hear was the melody and when he performed Foreigner's 'I Wanna Know What Love Is', it showed up just how boring the melody of that song is. Not that it's a song I particularly like anyway, but if it works at all, it only works with the words. As a piece of music, it's tedious. Or we could go back a generation or two: the first verse of Cole Porter's 'Night And Day' is all sung on one note. The words are what's important. Or take almost anything by AC/DC: there's more melody in one bar of any of Angus's solos than in any verse, but (especially when Bon Scott was writing them) the lyrics carry the song. Or for an example that's a whole subculture: rap. No melody, all words. So finally, we come to (a): songs with melodies that can lift even simple lyrics. This is what (for me) separates real musicians from wannabees. Example one: Kate Bush's 'Wuthering Heights'. Now, I quite like Ms B's music, but I wouldn't argue that the words make the song. Or even that the words make sense half the time... but you could play the melody of that song without any words and it stands up as a damn good piece of music. Example two (and this is going to date me): any one of a whole bunch of tracks by Yes. Let's take 'Close To The Edge': the lyrics are incomprehensible stoned-hippy trash, and yet (assuming you're ok with progressive rock) they're carried by interesting music. And then there are the exceptions that prove the rule: tracks with none of the above. Well, you could turn on the radio and wait ten minutes and you're bound to hear an example or two. Anything by Good Charlotte would do: worthless, lazy songwriting. Churning out 'product' with as much attention as the average burger-flipper pays to the hundredth Big Mac of the day. But then again... there are the tracks with two or even three of the Key Attributes. In the 70s you could have heard Carole King produce a whole album of them (Tapestry). In the last few years, Elbow have done the same. The art of songwriting is far from dead, and one great song can remind me that music is worth persevering with. Of course, these are my examples. Yours will be different. But I reckon that in every track you really love, there will be at least one of (a), (b) or (c).
Posted via LiveJournal app for iPad.
|
|
(comment on this)
|
| |
9:24 am - Ready-to-handness, and bed.
|
|
So here's an interesting study done on a sample size of one (me). I'm pondering a blog entry, and I have two ways to write it. I can (a) get up, walk to the study, unlock one of the Linux laptops waiting patiently, fire up the LiveJournal web page and then type, on a proper keyboard. And it'll be a fast machine, with a sprightly web browser to find interesting and relevant links. Or, (b), I could use the LiveJournal app on the iPad. Which means two-finger typing on a screen keyboard, fighting the autocorrect. And a slow browser, with the sluggish copy-and-paste that iOS 5 has brought to the original iPad (thanks, Apple, I was worried the iPad was too fast before you released iOS 5). So, in terms of the actual task I want to do, no contest. But (b) means I don't have to get up yet. And the iPad's already here. And I'm comfy. Damn. Posted via LiveJournal app for iPad.
|
|
(comment on this)
|
| Wednesday, January 20th, 2010
| |
5:10 pm
|
Working around the egregious Firefox cache collision defect. Properly.
It just occurred to me that the subject line of this post won't work nearly so well if you're Australian, or American, since natives of those nations pronounce "cache" in a novel colonial way; it should of course rhyme with "cash", which is how the Queen would pronounce it, if she knew what a cache was.
Anyway... those of you who have to deal with the complex and complicated world of efficiently serving up HTTP responses may know about an issue with Firefox (or possibly Mozilla, depending on how you like to classify it). Probably the most relevant bug report is here as Mozilla bug 290032, but here's a summary:- Firefox stores cached data by hashing the URL to a value.
- The hash algorithm is weak, and generates duplicate values for similar URLs.
- The cache can only store one cached URL per has value.
The upshot is that some URLs are always reloaded from the server and never cached. Now, this may not seem like a very big deal, and if you're just a plain old Firefox user, you may not care if there's a little bit more network traffic. But for anyone running a high-traffic server, it can be a serious issue. Every time a user reloads data from your server rather than their cache, you have a server hit and a bandwidth hit. Multiply that by a large number of users and it becomes a problem worth considering.
Let's look at the problem in more detail. First, we could do with a way to generate hashes from URLs so that we can do some tests. Here, in the Programming Language Of The Gods, is an implementation of the Firefox/Mozilla cache hash algorithm:
def hash(url):
#Hash starts as zero
h=0
#Iterate through the characters of the URL
for c in url:
#Take the ASCII value of each character
cv=ord(c)
#Rotate the hash value left four bits,
#as a 32-bit value
bits1=(h&0xF0000000) >> 28
bits2=(h&0x0FFFFFFF) << 4
h = bits1 | bits2
#XOR the ASCII character value with the
#hash
h = h ^ cv
return h
There are various plavces online where you can find the fault with this algorithm summed up as: the Firefox disk cache hash functions can generate collisions for URLs that differ only slightly, namely only on 8-character boundaries and the hash algorithm generates collisions for urls that are "similar enough". From the bug "similiar enough" seems to mean every 4 characters (or perhaps 8) the urls are the same. In fact, it's more complex than that. Let's take two example URLs provided by sembiance at stackoverflow.
ben@quad-14:~/working/hashing$ python
Python 2.6.2 (release26-maint, Apr 19 2009, 01:58:18)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from hashcheck import hash
>>> print "0x%08x" % hash("http://worldofsolitaire.com/decks/paris/5/12c.png")
0x40d8c8e9
>>> print "0x%08x" % hash("http://worldofsolitaire.com/decks/paris/5/13s.png")
0x40d8c8e9
>>>
Yow. Both URLs generate the same hash, though they differ by two adjacent characters. This means that only one of them can be cached by Firefox; if pages on the site regularly use both images, then at least one of them will be reloaded more often than it should. If you care to do the binary mathematics of the hash, you'll see that the reason for the clash is that differences between two characters in the two URLs can be cancelled out by differences in later characters.
Someone else who suffers from this bug: Google, or more specifically, Google Maps. Like most mapping sites that are based on "image tiles" (which includes Google Maps, Bing Maps, OpenStreetMap, NearMap, etc), there is a URL to load any individual 256x256 pixel "tile" image from their servers. Since there are many[1] possible tiles, there are many very similar URLs to load them. Let's consider a couple of Google URLs that clash:
>>> print "0x%08x"%hash("http://khm2.google.com/kh/v=52&x=118346&y=80466&z=17")
0x198cc05f
>>> print "0x%08x"%hash("http://khm2.google.com/kh/v=52&x=118350&y=80470&z=17")
0x198cc05f
>>>Because these two URLs clash, as with the other example above, only one of them can be cached by Firefox at any one time. I picked these two also because they're URLs for two images that are quite likely to appear together; they're only 4 tiles away from each other horizontally and vertically, so it's entirely possible to have them displayed together.
But if you crank up Firebug and watch Google URLs, you'll see that they use a trick to work around the issue; they append a substring (as the s parameter) to their URLs. This adds a substring of "Galileo" to each URL. This is sometimes (incorrectly) referred to as a "safeword" and described as a security measure that Google use to restrict access to their site; it's nothing of the sort, as you can see by testing the URLs without the s parameter, or even with it set to something completely different:
   The first image has the "legal" Google URL, the second has no substring and the third has the substring "Sfondrati"[3], and they all return the same image. The use of the substring is just to make simiular URLs sufficiently different that they don't generate the same hash value in the Firefox cache system.
The length of the substring is generated from the x and y values using the algorithm <i>length=((3*x)+y)%8</i> (where % means modulo). So if we use the URLs with the s parameter added, we get:
>>> print "0x%08x"%hash("http://khm2.google.com/kh/v=52&x=118346&y=80466&z=17&s=")
0xcc05d095
>>> print "0x%08x"%hash("http://khm2.google.com/kh/v=52&x=118350&y=80470&z=17&s=")
0xcc05d095
>>>Oops. What happened? The answer is that in both cases, the s parameter value is the same; 0 characters from the string "Galileo":
>>> ((3*118346)+80466)%8
0
>>> ((3*118350)+80470)%8
0
So there are still clashes. Google's extra parameter reduces the number of collisions, but certainly doesn't elimate them. In fact, it's extremely difficult to completely eliminate collisions[2] between URLs, but we can do better than Google's approach. At NearMap, we've been testing out a new way to generate substring, which uses the individual characters of the variant parts of the URL: the x and y and also the nmd (date) parameter that Nearmap have (and Google don't). Here's a Python sample implementation:
substring="Vk52edzNRYKbGjF8Ur0WhmQlZs4wgipDETyL1oOMXIAvqtxJBuf7H36acCnS9P" #Nonrepeating A-Z, a-z and digits
def differenceEngine(s,a):
"""Use string a to return a deterministic but pseudo-random substring from within substring s"""
result=""
#Take the characters of a, which MUST all be digits
offset=0
for c in a:
try:
v=int(c)
except ValueError:
#This exception fired if the character is not a digit, which is wrong, but
#we should cope without crashing.
continue
offset += v
#Use the value of this digit as an offset into the string, and take
#the character at that position.
p=s[offset%len(s)]
result += p
return result
def substringFor(x,y,nmd=None):
"""Return the substring parameter for a URL, given the x, y and nmd values.
The x and y should be integers, the nmd should be a string - if no date is
included in the URL, pass an empty string or None."""
arg=str(x)+str(y)+str((3*x)+y)
if nmd:
arg += nmd
return differenceEngine(substring,arg)
To test this, I took the logs for a day's worth of traffic on the NearMap site and analyzed the has collisions. With the Google "Galileo" algorithm, around 10% of all URLs collided. With this alternative approach, the collision rate is around 0.02%.
Okay, so this isn't a simple and clear chunk of code that you can use to modify your own URLs, but it demonstrates some principles:- The hash algorithm is based on characters, so if you use the 'add a substring parameter' approach, base that substring on the characters of the URL, not parameter values.
- Use as many different characters as possible in your substring so that it varies as much as possible; "Galileo" doesn't allow for very many different substrings.
- Build yourself a test setup (feel free to use the hash method above) that you can pass URLs through to spot collisions. Use that to tune your URL construction code to minimize the collision rate.
[1]Many? The standard tiling system that all these sites use divides the world up into square tiles. At zoom level 0, the whole world is shown in one tile. At zoom level 1, the world is shown in 4 tiles, at zoom level 2, 8 tiles, and so on. So at each zoom level z, the number of tiles is 2z squared. By the time you're at zoom level 21, where Google tend to stop, there are more than 4x1012 tiles. Which is many, by most standards. [2]Actually, it's impossible, since to completely avoid them, you'd need to modify all the URLs used in the world. Which you can't. What I'm really aiming at here is to try and avoid collisions across the set of similar URLs used on one site. [3]Paolo Emilio Sfondrati was the Secretary of the Inquisition at the time that Galileo was denounced for heresy and brought to trial. So probably Sfondrati would be an invalid string to replace Galileo...
|
|
(1 comment | comment on this)
|
| Monday, March 9th, 2009
| |
5:21 pm - Solving Sudoku With Superpositions
|
So I'm dead.
Actually, no, but that is a killer first line, from the movie Confidence. And when you have a killer first line, you go with it.
So I find myself writing up some examples and explanations of how to do basic object oriented design and development, and thus having to come up with something to serve as an example of how you might actually approach designing and implementing some code in C#. A problem slightly more connected to the real world than, say, yet another example like:
class Shape { virtual void Draw{} { } }
class Circle : Shape { override void Draw{} { } }
Sudoku will serve pretty well. First of all, it's a fairly easy problem to understand. Also, anyone who's of an algorithmic frame of mind and has encoutered a Sudoku puzzle has probably spent a while thinking about how to generally solve them. Programmers know that working out how to solve any problem of type X is more fun than actually solving any given individual problem of type X. And writing the code to do it also keeps you looking busy while someone else goes and does the actual work.
So, here is the algorithm that I've used as a basis, which I like to call solving with superposition because it lets me get all quantum and esoteric about it. To follow, you'll need to know at least the basic rules of Sudoku puzzles, which are ably explained in the relevant Wikipedia article.
On first encountering a Sudoku puzzle, such as this:
 we can see that:
- It's made up of 81 cells
- They're arranged into 9 rows, 9 columns and 9 squares, each of which contains 9 cells.
- Each cell either contains a number (we'll call these solved), or is blank (unsolved)
For the purposes of this algorithm, let's start off by assuming that each unsolved cell contains all the possible numbers 1 to 9 that it might hold. The work of solving the puzzle then involves finding numbers that cannot be in unsolved cells, and removing them, until each unsolved cell only contains one possible number, which means that it's then a solved cell. I call this process pruning.
I should point out here that there are many different ways to solve Sudoku puzzles. This is just one, and not necessarily the best one; I've chosen it because it's a nice little algorithmic example. If you have better approaches, go write a Wikipedia article.
Anyway, back to the explanation. Let's show how the top-left group of nine cells in the example puzzle might be written out by a programmer trying out this algorithm. Conceptually it looks like this:
5 |
3 |
123 456 789
|
6 |
123 456 789
|
123 456 789
|
123 456 789
|
9 |
8
|
When we prune the puzzle, we follow this approach:
- For each solved cell in turn, remove the number it contains from all the unsolved cells in the same row, column and square.
- If, as a result of that, an unsolved cell is left containing only one number, that cell is now solved.
- Keep doing this until either the puzzle is completely solved, or there are no more solved cells to process.
The thoughtful amongst you will have noticed that this will, so far, only solve very simple puzzles. Patience: more is yet to follow. For the moment, let's prune that example square of the board I showed above.
First, the topmost/leftmost cell contains a 5. So we know that we must remove the 5 from all the unsolved cells in the same row, column and square.
5 |
3 |
123 4 6 789
|
6 |
123 4 6 789
|
123 4 6 789
|
123 4 6 789
|
9 |
8
|
We can then do the same for the other cells that are already solved (the 3, 6, 9 and 8):
5 |
3 |
12 4 7
|
6 |
12 4 7
|
12 4 7
|
12 4 7
|
9 |
8
|
Okay, we now have a number of cells that are still ambiguous; that is, we know that they may still be one of n possible values, even though we've reduced the value of n by eliminating values that can't be in the cell.
Here's the superposition bit: we take a cell that still needs to be solved, and for every value that the cell could hold, we generate a different version of the board. So if we take the cell after the 5 & 3, that could be 1, 2, 4 or 7 (in red here):
5 |
3 |
12 4 7
|
6 |
12 4 7
|
12 4 7
|
12 4 7
|
9 |
8
|
...we generate four versions of the board, one in which the red cell holds 1, one in which it holds 2, one in which it holds 4 and one in which it holds 7. You can think of this (if you like to play with quantum terminology) as a superposition of four possible boards. We then take each board in turn and proceed to try and solve it, using the same techniques again. For example, if we take the superposition in which the red cell holds 2, then we need to remove the 2 from any other cells in the same row, column and square...
5 |
3 |
2
|
6 |
1 4 7
|
1 4 7
|
1 4 7
|
9 |
8
|
We still have some ambiguous cells, such as the one in blue that could hold 1, 4 or 7. So we create three further superpositions, one for each of the possible values of the blue cell, and then proceed to solve each of those.
Okay, the software-oriented amongst you will immediately have started thinking about recursion and stacks. Which is exactly what I was after: an example which requires that the students think about objects as elements in data structures that must then be subjected to processing. I need only make it compulsory for them to use the generic System.Collections.Generic.Stack collection, and I have an interesting algorithmic problem for them to solve...
current mood: contemplative
|
|
(comment on this)
|
| Friday, January 25th, 2008
| |
5:51 pm - The Same Only Different
|
A tiny entry, but I have to...
A friend of mine: "C# is the closest thing to Python of all the C-derived languages".
I think I get this: C# isn't dynamic, of course, but the Collections bring to mind the power of Python lists and dictionaries, nullable types are as useful as None and Namespaces are one honking great idea.
I'm not doing much Python these days, but I am doing quite a lot of C#. So I'm minded[0] to post a bunch of C# stuff.
[0] minded is the UK Policitician's phrase for going to. As in I am minded to do what I've been paid to do (as is a politician's wont).
|
|
(1 comment | comment on this)
|
| Tuesday, August 15th, 2006
| |
2:09 pm - Sometimes, The Point Is To Have No Point
|
It occurred to me last night, as I examined the calluses and blisters on the fingertips of my left hand, that I've been playing the guitar for thirty years.
This is an approximation; I don't remember exactly when I started, but it would have been around age 12 or so. The fact that I don't remember starting probably means that it snuck[1] up on me and gradually became, at first, something I did and then later, a part of my self-definition. Interestingly, it would have been around the same sort of time that I began to see myself as a programmer, and then an engineer. Thus are sown the seeds of one's own self-limitation, or something along those lines.
Part of what interests me about music is the complexity. It's like trying to understand a fractal; every part of it that you open up reveals yet more to learn. On the other hand, as Sid Vicious said You just pick a chord, go twang, and you've got music, so it's both complex and accessible in one easy measure. It slices and it dices. That fractal complexity[2], though, can be intimidating. It's a sort of endless challenge, a mountain range that always has a higher peak. Nobody can be best at every single aspect of music; for all musicians, there is always someone else who is better than you at some part of what you do. You can become dispirited by that, or you can learn to set your own goals and measure your progress by them.
To do that, I think it's important to understand who it is you're playing for. Most of us have our own internal critics (and when I played in bands I wished, on occasion, that some people had more of them) but it can take a degree of introspection to work out whether those critics are worth impressing. For example, at some point in my twenties I became aware that I was judging my playing by whether my father would be impressed. As soon as I realised this, it was evident how ridiculous it was: my dad's an talented, intelligent man of towering achievements, but he can't play a note on the guitar and our tastes in music overlap only slightly at best. The worst internal critic, though, is myself, at around age sixteen or so. For him, what matters is being able to play better than someone else; faster, using fancier fretboard tricks, and so forth. It's taken much longer to get rid of him than it should, and to accept, finally, that the only person who need judge how well I can play is me. The same me who sets myself goals to achieve, for no other (or better) reason than I think that they would be fun to do.
Which lets me segue towards some sort of point; the reason that you're doing something, whether it's playing the guitar or building software, is easy to forget and yet vital to keep in mind. This is a simple and obvious truism, captured in the endearingly bluff American aphorism When you're up to your ass in alligators it's difficult to remember that your initial objective was to drain the swamp. Simple and obvious, yet there are still those moments, usually at a pause in the meeting, when someone[3] says "hang on a minute, let's get back to why we're doing this" and thus short-circuits a deep and inwardly-spiralling argument (which is usually very technical).
Anyway, getting back to playing the guitar (which is far more interesting than actual work); since I realised that there is actually no point to it, that there is no final grade to be given or accolade to be awarded, it's become far more enjoyable. My latest goal is to be able to play the guitar parts from Pink Floyd's Money, Shine On You Crazy Diamond and Another Brick In The Wall (Part 2), including the solos, to my own satisfaction. In this I will be ably abetted by the excellent backing tracks available from LickLibrary[4]. Should you also be of a guitar-playing frame of mind, you may find it a Good Site To Visit.
Let there be Rock...
[1] A far nicer past participle than "sneaked", even if it is American. [2] An excellent name for a geek jazz band, if anyone fancies it. [3] Occasionally this someone is actually me, but not often enough for me to feel superior about it. [4] Anyone else get a frisson of Spinal Tap when you hear that name?
|
|
(3 comments | comment on this)
|
| Wednesday, August 9th, 2006
| |
2:27 pm - It Lives, Igor!
|
It's been a while since my last entry, but there have been reasons.
The job of writing a technical article lands on my to-do list every so often. Between occurrences, I manage to forget about the need to do these so that each time a new one pops up it comes as the same surprise: a mix of anticipation at the chance to do some writing and worry about where the time to do it will come from. Anyway, in order to bolster my usual mix of weak reasoning and doubtful conclusions with some half-baked evidence, I turned to Google. In the recesses of my memory I seemed to recall that someone had once combined a PC and a Sega Megadrive[1] in one unit; a spectacular example of the misplaced faith that will lead to a convergence disaster. Googling for combined pc megadrive found me what I wanted... and also, ninth entry on the first page was a blog posting by some lamebrained pontificator who seemed to think that using eight words where one would do was somehow admirable or witty. Of course, it was me.
When I'd raided my own half-forgotten rambings for some vaguely relevant and nearly true "facts" for the article, I noticed that the last entry was back in November 2005 and decided that, come coffee-break, it was time to blog again[2].
The reasons for the break are several:
- Back at the end of last year, I had to change jobs, quite suddenly and not out of choice, having been made redundant. It wasn't a pleasant parting of ways, and it turned legal (you should read that phrase as roughly equivalent to and then it turned gangrenous). During times like that blogging is neither fun nor advisable: you don't want to say anything that might get quoted out of context against you. All the legal stuff carried on until a couple of months ago.
- My new job (like many) started off fairly undefined and has only recently evolved to the point where I could say for sure what it is I'm responsible for and where we're going. During times like that, blogging is tricky, since finding your feet in a new organisation is difficult enough without potentially revealing all your incorrect assumptions to everyone you work with :)
- I just flat out haven't had the time or mental bandwidth to come up with anything worth writing about.
Well, anyone who reads more than a couple of entries here will know that the last point shouldn't really have been any barrier: there's not an entry in here that's ever been worth the time. However, as ever, I shall quixotically endeavour to say something worth saying, knowing that my continual failure will annoy others far more than it inconveniences me. Hooray for the Internet :)
So now I'm working for the company who built a good part of The Mobile Phone Project; an excellent bunch of engineers. And despite entries like this I've been involved in something that's remarkably heavy on C++. Which has confirmed some predjudices. Other predjudices about C++ have remained unscathed at the very least.
A large part of what I'm doing is concerned with the way in which a services organization develops products. It's fascinating and rewarding to start reusing the same insights gained and lessons learned (the hard way) about the vast gap that lies between the unsullied, tender idea, newly conceived, dew-fresh and trembling with antici....pation[3] and the eventual product: buttressed with user guides, FAQs, installation (and deinstallation) scripts and ready to face the cruel, unforgiving world of actual users. Which leads me, finally and via a deliberately circuitous route, to what might actually be a useful link for this entry: Finance For Geeks, where Eric Sink summarises a number of basic business principles in a way that makes sense to yer average techie. I think he does a cracking job (in that and other articles) of wrapping up stuff that I learned the hard way in the dim and distant days when it began to dawn on me that the world did not operate by the same sort of rules as computer systems. But that's another posting...
[1] That'd be a Sega Genesis, for Americans. To save you the tedium of looking, it was Amstrad, a British company who have often displayed a flair for producing items that are so high-tech they're ahead of the market and yet so cheaply made that they're beneath the contempt of even the wildest early adopter. [2] "Oh, baby, I'll try to blog again but I know... the first post is the deepest". Etc. Well, it was in my head, now it's in yours. [3] It's a Rocky Horror reference. Either you'll get it, or you won't.
|
|
(comment on this)
|
| Tuesday, November 29th, 2005
| |
1:53 pm - Doing The Light Handango
|
I'm getting rather brassed off with hearing the word "Handango". Not, you understand, because I have a problem with them or their business, though they are in fact rather difficult to do business with. Nor because of any aesthetic judgements and opinions I may have about their site. Not even because of their distinctly American Corporate brand of English... no, my problem is with the word as an answer to a question.
The question to which I refer is: "suppose we develop product X, how would we sell it?" In the world of mobile applications it's a pretty important consideration when evaluating any idea; arguably more important than "what could we build" or "hey, look at what I coded up last night". If you can't sell it, you can't make money from it, and you're out of business[0]. Unfortunately, "Handango" is not an answer to the question.
At the time of writing, Handango are proudly advertising 75,000 downloads. Let's think about that a second; seventy five thousand different things that you might want for your device. They don't break it down by platform unfortunately (and don't get me started on the way they use "Symbian" as a platform - as if the average end user knew what that meant or whether they even have a Symbian phone). But let's say that there are 10,000 applications in the Symbian section. A new application offered for sale there is, therefore, competing for attention with all those thousands of other products. There's no way to get attention; it's the same problem as was faced in the early days of the web - unless you promote your site, nobody knows that you're there.
So putting your product on Handango is really just the very first step in a process of getting it to market. Where will it be advertised? Who will pay for the advertising? Who will write the copy for the adverts (and for the pages on Handango, come to that)? Too often the assumption seems to be that one puts the product on Handango and then starts leafing through the Rolls-Royce brochures whilst waiting for the cheques. In the immortal words of Helen Parr[1], "I don't think so!".
[0] Of course, if you're talking open source, freeware or just-put-it-up-for-vanity-ware, this doesn't (necessarily) apply. But you still want people to find it, right? [1] Elastigirl, of course.
current mood: annoyed
|
|
(comment on this)
|
| Thursday, November 24th, 2005
| |
4:23 pm - Two Nations Divided By A Common Language
|
Now that was annoying. I see news of an excellent new feature in Google Mail; custom "From" addresses. Now, this is a good thing because it allows me to appear to my contacts via the same address they've been used to seeing but also because "googlemail.com" addresses seem to be helping my emails get marked as spam. Hmph. Anyway, off I go to set up a new address... and I find that there's no way to do it. The "Accounts" tab that the Help so carefully explains doesn't appear for me. I feel so rejected. However, a few moment's thought and Googling shows me the problem; I changed my language to "English (UK)". Changing it to "English (US)" causes the magical new options to appear in full. Hoorah. Now my email has the right "From:" header... but also a different "Sender:" header, causing yet more spam detectors to scream with suspicion. Hey ho. Anyway, there you have it; blogged so that others in the same situation might find the solution.
current mood: accomplished
|
|
(comment on this)
|
| |
12:15 pm - The Applicance Of Science
|
A couple of contacts have become involved with science.tv, a "broadband TV channel dedicated to science". Maybe it's just me, but everytime I type the word science I hear Magnus Pyke, as sampled in Thomas Dolby's timeless[0] classic "She Blinded Me With Science".
Anyway, hand-waving wild-haired boffins apart, they're soliciting Ideas for Science Programmes. A bit of a wide brief, really. I tend to find myself thinking about this like I do technology product development; don't start from what can we make? but start from who would we make it for?, or even better, who can we sell it to?. Find the market need first, guys. And there is a market need; as I've noted before, the public perception of science and scientists is pretty skewed by people like Dan Brown (on whom may everlasting opprobrium and contempt fall) or even Michael "We're In The Hands Of Engineers" Crichton. Where are the Bronowskis of today? David Attenborough is hanging up his optimistically white suits after his next series. There's a need, oh yes.
[0] Timeless in the sense that the 80s classics are all, um, timeless. Which is to say, dated.
current mood: contemplative
|
|
(comment on this)
|
| Friday, November 4th, 2005
| |
10:12 am - You Have Mail
|
I've spent much of the last week or so in an office where the Internet is accessible only through the tightest of firewalls. There's no complaint implied here; the value of some of the IP in the building might exceed the value of the entire company, so paranoia is amply justified, but it does mean that I can't fetch my usual POP3 email. This gave me the perfect excuse to see how GMail is going.
I should really refer to it as GoogleMail since I'm in the UK where, amusingly enough, some other outfit has been using the name "GMail" for a while. I do enjoy it when Big American Corporations forget that the rest of the world exists when they're looking at trademarks and patents. Any road up, whatever you call it, a couple of IMs later I had an invitation to sign up and a shiny new googlemail.com address. Many others have written with far more skill and judgement than I on the subject of how G[oogle]Mail does what it does, so I'll refrain from cluttering up the RSS feeds with yet more. What struck me as worth commenting on was the contrast with other web mail interfaces... specifically Exchange's.
For reasons of not-getting-around-to-it, I have only web access to an email account at the place I'm working (it's my laptop, it's not in their domain, etc, etc). This gives me the sort of web interface that takes one back to the heady, pre-Ajax days five years ago, when Hotmail was king. I mean: it's awful. Pages refresh for any change, looking up any data whilst in the middle of writing an email involves an endless dance of Open Link In New Tab (this is all in Firefox, but IE doesn't add anything). Google, in contrast, have really worked hard and come up with a web interface that's arguably better than some PC-based mail clients.
I think it's a question of attitude. Google have jumped headfirst into the whole Ajax & web thing (with the exception of Google Earth). Thus the web interface is a poor relation in the eyes of any company who see the world in terms of PC-based applications, whereas it's the primary way of doing anything for Google.
current mood: Transitional
|
|
(2 comments | comment on this)
|
| Tuesday, October 25th, 2005
| |
4:49 pm - Plus Ca Change
|
The lack of updates (for which many will have found their RSS feeds to be the cleaner and more informative) is for a good reason; I'm just emerging from a period of transition from one job to another. During such a time, Those Who Blog can find it appropriate to stop saying anything new in public lest it affect the impression that potential employers have of them. Thus the silence. Of course, it's daft to start worrying about what your blog says when you move jobs; you should worry when you make any entry. In fact, you should worry just before you click "Post" or the equivalent and consider: What will that entry say about me in five years' time? Google caching and the Wayback Machine, amongst others, mean that every youthful indiscretion that one blogs is, potentially, there forever (and that, as Prince said, is a mighty long time). I don't think there's anything on here that's counted against me, though one contact did ask me why there was so much about programming when I don't really market myself as a programmer any more. My response was to point out that one should never lose touch with the basic skills of your profession, whatever your level in it. And that there's no good reason I shouldn't mess around with bits of Python and Java if I want to, even if I'm now moving on to do a job even more removed from the basic bit-shuffling that we laughingly term software engineering. For better or worse, whether I'm presenting a proposal to a board or trying to define a mobile product strategy, I am at heart still someone who sees systems in terms of lines of code; I don't think that'll ever change and I wouldn't want it to. Vive, if you will, la provenance...
current mood: Transitional
|
|
(comment on this)
|
| Wednesday, September 14th, 2005
| |
2:52 pm - Realer Than It Was Before
|
That should be "more real", but I ain't a-gonna pedant no more.
There are points in a product's life when it stops being an idea, or a project, or that-stuff-you-slave-over-all-week and becomes real. It becomes a Thing That People Buy, people who have no idea of what went on behind the scenes to make the bit of shiny plastic they take home.
The Playstation Project is on Amazon. Now, that's real.
current mood: Buzzed
|
|
(comment on this)
|
| Thursday, August 11th, 2005
| |
9:04 am - Absolument Disparu, Like Mother's Mink
|
The title today being a quotation from Nigel Molesworth's serious and worthwhile autobiographies, which you either know or you don't.
The guys over at Penny Arcade experience the Lesson About Backups that hits us all, eventually. I've long believed that there's an axiom of computing (of the practise, not the theory) that states:
You will only truly understand how important backups are when you realise that you don't have one, and that because you don't, you have lost something now irretrievable.
At that moment, one becomes enlightened, though it is probably not nirvana that you reach. However, experience, it is said, is cheap at any price and doubly so when someone else is paying. So I took a quarter of an hour to quickly run through the many and varied backup systems here and at the office, verifying that they're working as they should. Conveniently enough, there's a gap of ninety miles between the two; sufficiently large that any natural disaster capable of affecting both would leave me with other priorities than recovering backups, like basic survival in a post-holocaust wilderness, for example. Thus backups run between the two sites, overnight, replicating all critical data. That's in addition to the suite of tape drives in the office, and the Linux mirrored array that holds duplicates of the family photos and digital documents from the working PCs here.
I don't think I've ever heard a genuine geek say that backup system is too redundant. At least, nobody who's been through their own Lesson About Backups.
current mood: busy
|
|
(comment on this)
|
| Wednesday, July 20th, 2005
| |
10:50 am - Wibbly Wobbly WBXML
|
Ok, so I couldn't think of a title that's as wilfully obscure as the usual ones. Whatever.
For reasons of Commerce, I need to be able to generate WBXML messages within the guts of the mighty Python/Zope engine that powers the Mobile Phone Project[0]. What, I hear you ask, the blinking flip is WBXML? Well, if you don't know, you probably want to keep it that way, but you did ask.
WBXML is a binary encoding of XML. XML is, of course, a textual encoding of data... some of which may originally have been binary. So it's sort of an extra level of complication added to something that's already complicated, but hey, that's what geeks do, isn't it? The reason that it's a binary encoding is that XML is bulky. Most of the time that bulk doesn't matter that much; I'll trade bandwidth, memory or CPU time for explicitness any day of the week. But if you're trying to pack XML over a slow, laggy, prone-to-being-interrupted-by-trees-or-birds wireless link to a phone, bulk is bad. It's even worse if you're trying to pack an XML Service Indication (essentially, a pushed URL) into the tiny size of a single SMS message. Hence the binaryness.
WBXML isn't anything as simple as, say, a gzipped version of the XML stream. Instead, it's a carefully rigorous specification of how individual single byte values map to either XML or text strings. For example, the XML <SI> maps to the binary value 0x05, and <INDICATION> maps to 0x06. But it's clever; if the HREF attribute of the INDICATION starts with "http://", then the whole attribute-starting-http maps to 0x0C. If the HREF starts with "http://www" then it's mapped to 0x0D, saving another three bytes, and so on. The more common the string, the more likely it is to have a fixed mapping. There's also a neat string-table option; commonly used string can be folded into single-byte offsets into a string table (in effect, any repeated string longer than three bytes is worth string-table-izing).
This is non-trivial stuff to knock up in a hurry, so it's just as well that there's the libwbxml open-source library to handle it all. That library, however, is in C, and I'm working in Python. There appear to be no published Python binding to libwbxml, so it was time to dust off my ancient experience of #include <Python.h> and get to it.
Here's the C code that allows a Python call to libwbxml's xml2wbxml function:
static PyObject *wbxml_xml2wbxml(PyObject *self, PyObject *args) {
/*A WB_UTINY is an unsigned char, so we can allow conversion directly from the Python string*/
WB_UTINY *xml;
WB_UTINY *wbxml;
WB_ULONG wbxmllen;
int status;
WBXMLConvXML2WBXMLParams params;
WB_UTINY *errstr;
PyObject *result;
/* Verify and read a string arg (xml) */
if (!PyArg_ParseTuple(args, "s", &xml))
return NULL;
/* Pass that to libwbxml2 */
params.keep_ignorable_ws = FALSE;
params.use_strtbl = TRUE;
params.wbxml_version = WBXML_VERSION_11;
status = wbxml_conv_xml2wbxml(xml,&wbxml,&wbxmllen,¶ms);
if(status == WBXML_OK) {
errstr = NULL; /*we return None to mean no error*/
} else {
errstr = (WB_UTINY *)wbxml_errors_string(status);
}
/* Build the return tuple of wbxml, error.
The wbxml string is binary, so we need to convert it with a z#
rather than a z.*/
result = Py_BuildValue("(z#z)",wbxml,wbxmllen,errstr);
/* Free the buffer that came back from the converter (thanks, Bob!) */
wbxml_free((void *)wbxml);
return result;
}
For details, I recommend you to the excellent on-line reference to the Python/C API (link goes directly to the section that explains conversion of values between C and Python).
[edit - removed dead link to the source for this... I don't have it anymore, sorry!]
Right now, I don't need to convert WBXML back to XML, so there's no link to the reverse wbxml2xml function. Like they say, open-source software scratches one's own itches. And if you did want to send the resulting SI in one or more SMS messages to a mobile, you'd also need to wrap the binary WBXML in a WSP (Wireless Session Protocol) header, which is another topic entirely[1].
[0] I suppose I should start calling this the Mobile Phone Content Project, since that's a more accurate name. Maybe when the tv adverts start... [1] I do have working code to do this, so if anyone needs to wrangle WSP, feel free to drop me an email (or ask via blog comment) and I'll share what I know.
|
|
(7 comments | comment on this)
|
| Tuesday, July 19th, 2005
| |
8:59 am - He's More Machine Now Than Man
|
Or, combining Exchange and PostFix to form a hideous cyborg being.
This useful article popped up on OSNews about avoiding the need to pay mucho dinero to upgrade ageing Exchange 5 setups by using PostFix (or some other secure MTA) to insulate Exchange from the wild and woolly Internet.
At our main office we have an old NT server (SBS to be exact) running Exchange 5.5. It came as part of an original IT installation I inherited when I joined, together with a web-proxy-only Net connection over ISDN for which the installers charged an extortionate fee per month (as well as ISDN dialup charges). One day I'll have a little rant about how unsurprising it is that many small businesses don't trust IT companies when ripoffs like that are so common... but not today. Anyway, the problem I had was that the users were throroughly wedded to Outlook, when we switched to a sensible Net connection I had no intention of having the NT server and Exchange directly connected. My previous job had included a huge mix of NT and Unix servers and I'd had the unpleasant experience of watching the Microsoft kit fall before the onslaught of vulnerabilities like sandcastles under an incoming tide. I wanted something reliable and robust between the Net and NT.
The first job was to liberate an old machine and put RedHat on it (this was so long ago that RedHat 6.1 was current). Next, Squid proxying to make the most of the (initially limited) bandwidth. Then PostFix to deal with all incoming and outgoing email. I used the redirect facility in ipchains to force all outgoing SMTP connections to port 25 to be rerouted through PostFix (thus giving me a way to at least track any trojans with built-in MTAs). The NT server was moved behind this firewall system onto the LAN and Exchange was set to use Postfix for all outgoing mail. All incoming mail was also routed to Exchange (after spam and virus filtering). The users all keep their Outlook mailboxes and shared calendars. All is well. I'd migrate everyone to IMAP or even POP mail access, but frankly there's no benefit to them and a lot of work for me. So Exchange can stay, at version 5.5.
One of the many criticisms of MS operating systems is how often they need to be rebooted, but after this migration the NT server has actually been extremely stable. It's been rebooted after the odd IE update[0], but otherwise it's run alongside a brace of Linux machines quite happily. If only I could manage it by command line instead of VNC-over-VPN, I'd be even happier.
[0] Worth pointing out that it's never used for web browsing, except to download the occasional update from Microsoft. That in itself reduces the risk of exposure considerably.
|
|
(4 comments | comment on this)
|
| Wednesday, June 15th, 2005
| |
2:37 pm - Have It Your Way
|
...As Burger King allegedly say. Pondering customizability.
The inscrutable Raymond Chen has an blog called The Old New Thing, in which he (as a Microsoft person) posts on many detailed and interesting topics related to the internals of Windows. Even if you're a Unixite so fervent that your car has a command line, it's worth reading to see why certain things in Windows are they way that they are. He has a recent entry on Why can't the default drag/drop behavior be changed? (in Explorer) which highlights something I was thinking about recently; the twin and somewhat opposed worldviews regarding interfaces.
When, in the past, I've run Linux desktops[0], I've spent happy hours playing with the myriad subtle and singular configuration options that let me set it up just how I like it, with all my favourite key and mouse combinations spread across all the applications that I need to use. Windows, naturalmente, doesn't let me do that. It works how it works. The rationale for this, according to Raymond is:
[customization] removes some of the predictability from the user interface. One of the benefits of a common user interface is that once you learn it, you can apply the rules generally. But if each user could customize how drag/drop works, then the knowledge you developed with drag/drop wouldn't transfer to other people's machines.
Further:
Infinite customizability also means that you can't just sit down in front of somebody's machine and start using it. You first have to learn how they customized their menus, button clicks, default drag effects, and keyboard macros.
I'm not sure where I'd stand on this point. I like things the way I like them, but I also hate sitting down at an unfamiliar system and not having things ready-to-hand. Perhaps it's a question of ownership of the machine in question...
[0] No axe to grind here, it's just that all my Linux systems are servers these days.
current mood: contemplative
|
|
(3 comments | comment on this)
|
| Tuesday, June 14th, 2005
| |
5:04 pm - Misidentification cards
|
Things spread via links. Thus, at the risk of annoying the places where this blog is syndicated, may I offer for any other UK citizens who have concerns about ID cards, this link to a pledge to refuse to register for them. I now return you to your regularly scheduled programmes of useful Python/Java-related information.
current mood: activistic
|
|
(comment on this)
|
| |
4:27 pm - Those Sodding Puzzles
|
The perceptive Tom Hume posts about getting puzzles onto mobile phones. Our own mobile project(s) are beginning to ramp up heavily (we're even recruiting, so if you know a ZPT-literate web designer who might want a job, let me know), but not in the direction of puzzles. I think it'll be interesting to see how someone approaches the problem of making a phone interface do anything as nice as a piece of paper with a puzzle on.
Like many other Brits, I've been caught up to some extent in the frenzy of Sudoku. And being, at the very core of my head, a programmer, I've been pondering algorithms for solving them. I'm not about to post any Python or Java to help here (not yet, at any rate), but what might be useful to others is this worksheet. The idea's very simple; the bottom sheet has all the possible numbers for every square shown. Cross them out with a pen/pencil as they become evidently impossible. As Sherlock Holmes said, when you eliminate the impossible, whatever's left must be true. Although he was a sociopathic junkie, really. And didn't do sudoku.
current mood: contemplative
|
|
(3 comments | comment on this)
|
| Wednesday, May 18th, 2005
| |
7:04 am - A Matter Of Questions
|
The PlayStation Project revealed. Another case study of Python and open-source tools on another Interesting Problem.
A Little Bit Of Background E3 thunders towards us on the calendar[0] and mortal development teams quail before the onrushing juggernauts of deadlines. Apart from our team, for whom the E3 deadline was a while back. Now we have a whole new set of amusing comedy deadlines for beta tests, but that's not important right now. E3 is a big deal for us because it's where the Playstation Project is now exposed to the nerveless, searching gaze of the Eye of Sauron... no, wait, I mean The Games Industry Press. Same thing, smaller spiked helmets, as I understand it.
I'm a regular reader of Penny Arcade. Not that I'm really a player in any sense these days; my favourite game is still Homeworld2, which is pretty much gathering dust on the shelves of most gamers' rooms. But I like Tycho's writing, and Gabe's style of art. A while ago, they posted some comments from Geoffrey Zatkin, on the subject of new ideas for games. Here's a quote:
At PAX this year I was a judge for their "pitch your idea for a game" sit-in. I got to break a lot of hearts by telling the audience a very sad fact – that in my 8+ years as a professional game designer, not once has any boss of mine ever asked me for an idea for a new game. Not once. Again, unless you own the company, you get assigned a project (or jump ship to another company working on a game that sounds interesting). Sure, I've helped flesh out any number of games from concept to fully realized design. And that's the hard part. Coming up with a good idea for a game is like coming up with a good idea for a novel. Everybody does that. But very few people have the discipline to sit down and write the book. The ideas are easy – the execution of the idea is the hard part.
But that's what we've done; we came up with a new idea, something that genuinely hasn't been done before[3], and we've done a massive great chunk of the work of executing that idea. And it's been interesting, in the best senses of the word.
It isn't a first-person shooter. It's not a racing game. No busty women swing over pits and solve puzzles. It's something a bit new, in a number of ways. The game's called Buzz![1], and it is, at heart, a music quiz. There are nearly 1200 different clips of tracks involved, with a total of over 47,000 questions, in ten languages. Our development partners do the clever 3D interface work (and a damn fine job they've done of it as well). It's been our job to gather, generate, edit, collate, audit, process and provide all of this data on which the quiz is based. So, since this blog is (ostensibly) chiefly about techie things, I thought it might be interesting to explain the set of open-source software and tools that we've used to manage all of this.
Of Databases And Babel Let's start with the database engine (since that's the core of it all). The requirements that I drew up[2] were pretty much these:
- Open-source database. There is no religious reason for this. It's a budget thing.
- That interfaces well with Python. More on this below.
- And that supports Unicode properly. I mean; has tools that support input and output of international characters sets. And that does Unicode via the Python interface.
- Supports transactions.
- Accessible from Windows tools (ODBC, Python)
- Runs on Linux. All our serious development servers run Fedora.
Given the above, it was pretty much a question of MySQL or PostgreSQL. I chose MySQL for two reasons. First; I'd used it many times before. Second; the various Python/PostgreSQL packages all seemed to lack in one way or another, especially when it got down to sorting out Unicode. It may be that there are neat solutions to any/all of the issues I found, but there seemed to be no great advantage to swapping a database I was familiar with for another I wasn't. MySQL (as of version 4.1.1) also has excellent Unicode support and speaks unto Python via the truly excellent MySQLdb package, courtesy of Andy Dustman, to whom I shall one day build a small shrine.
None of this would be much use if the general query tools for MySQL (like the Query Browser) didn't work properly with international strings on Windows. All our desktop machines run XP, and it's critical that display, edit and copy/paste of strings in any language work. Well, as long as you choose the right tools, they do, but that's the nature of Unicode work for you.
The Language That Gets Everywhere Why, you might ask, purely because it would help me move on to the next point, do you need a database that links with Python? Thanks for asking. Early on in the whole development process, I gave a lot of thought to the jobs that we'd have to do. There were some guiding principles I followed.
- Whatever we think we're going to be doing, it probably won't happen the way we think it will. Columns will change meaning. Entities will be discarded and new ones appear. Be flexible.
- We're going to be gathering data from a zillion different sources. Any data we capture is going to be dirty and need auditing and cleaning.
- There's going to be so much data that any manual task applied to the thousands of records we'll have might mean that we'll run out of time. Automate.
It would be nice, one day, to work again on the sort of project for which BigDesignUpFront would be applicable (that doesn't, of course, mean that I'd do it; I'm pro-iterative myself). Unfortunately, when you're starting to gather data well in advance of knowing how that data will be used, you need to come up with something that'll handle Big Change. Thus "the database" in our little world doesn't really mean the MySQL repository in which the data's kept. It's MySQL plus thirty or so Python scripts and modules that Do Things To Data.
It's always seemed to me that there are two approaches to database work. I shall, for the purposes of discussion[4] class them as Database-centric and Code-centric development.
The database-centric approach was typified for me by a database developer I worked with at breathe, several years ago. His approach to starting the working day was to (a) sit down at PC, (b) fire up a SQL Server client. And that was him done; everything (and I mean everything) else was done from within the client. List a directory? Do some file copying? It could all, apparently, be done from within the Database That God Gave Him. A nice enough guy, but a tad fixated.
Of course, there are lesser examples of the approach and there's much to be said for keeping the business logic next to the code in funky stored procedures. But I never liked the languages in which they were written, nor the way in which the rectangular nature of the data forced its way into every corner of the design. I am a dyed-in-the-wool code centric guy. And, naturally, the code-centric approachs works thusly; your database holds your data. Operations on that data are carried out by code, which fetches the data (whether that be into simple structures, objects that relate to the schema or objects that relate to whatever the hell they want to), Does Stuff to the data and rewrites the data back to the database.
The big point for me, though, that favours code-centricity is that it's proven in the past to be more flexible in the ways that matter to me. Maybe it's a sign that I came to databases after high level programming languages (and to those after assembler). Whatever; I like the code paradigm. And in this case, it meant that I didn't even attempt to create a vast and allencompassing ERD that encapsulated every last semantic of the data. We just created a base set of simple tables that the data gathering team could begin to populate. Over time and as prototypes of the game were created and revised, the schema grew to reflect the uses of the data; now it's pretty complex.
So for this project, the phrase "the database" usually refers to the set of tables in the MySQL server plus the code that operates on it. And that's all in Python.
There were a couple of other options open to us. We could have started in Access... but apart from the obvious scale issues, we needed a proper multi-user database that could be efficiently hosted on a remote server, with replication. Also, I'm not a great fan of VB as a development language; for quick-and-dirty user interface jobs it's great. Slapping together forms to edit data? Access can be the solution you need, using linked tables to get at the MySQL data where necessary. We could have used Java for the main development, but working in a dynamic language has rather spoiled me for Java in odd ways. Most of the supporting code for the database is all in a single Python module and the convenience of firing up a Python interpreter and being able to do ad-hoc processing at the command line was too good to pass up. In fact, as we've approached the last few deadlines there have been many, many audits and sensibility checks all run from inside a Python interpreter (often Quasi). The Java development cycle is just that bit too slow, and the definitions of objects a little too fixed to match that convenience.
The Swiss Army Chainsaw There're many audio files involved in this project, which means that sox has been a complete necessity at times. Same rule applies as with the data; for a small company, even the simplest, fastest manual processing can be impossible when multiplied up by thousands of files. Thus automation's been key here, allowing all the samples to be crossfaded and normalised in batches. For a lot of editing work, though, there is really no substitute for having the waveform visible on a PC and here, for once, proprietary tools have really won out. Two of us in the company are musicians with home studios, and applications like Cool Edit or Wavelab have done a lot of the work.
So that's it. Perhaps it's not an in-depth industry exposé of the use of open-source stuff to create the next Duke Nukem or Doom, but there's a real project here resulting in a real game and that's a snapshot of some of the ways we did it. And are continuing to do it... there's still work to do. Back to Eclipse and QueryBrowser for me...
[0] RSS feeds and individual workloads being what they are, you may well be reading this after E3 2005 has come and gone. In which case, try to imagine yourself back in the heady old days of May 2005. Feel the period atmosphere. Good, isn't it? Do they have flying cars yet in your time? [1] Yes, the exclamation mark's part of the name. Like Yahoo! [2] This was way back at the end of 2003. It's taken a long time to get this thing under way, and I might do another blog entry to explain why, and what happened along the way. [3] True. Yes, there have been quizzes. Yes, there have been quizzes with clips of music (like the DVD Pepsi Challenge game, or the CD-based Spot The Intro). But nobody's ever done one with 1200 tracks on it. [4] As opposed to the Porpoises of Discursion. I had a small spelling checker issue that was too good to delete entirely...
current mood: tired
|
|
(3 comments | comment on this)
|
|
|
|
|