I don't usually just make an entry for a link, but The Secret Lives of Numbers is really fascinating. It's basically a histogram of the popularity of the first 100000 integers, popularity being defined as the number of hits returned by a web search engine.
For highly popular integers, there's a list of associations, reflecting the things people tend to look for on the web: highly popular #2 associates with "Diablo 2", "Mission Impossible 2", "Playstation 2", and "World War 2". There's a 1-D histogram, integer on the Y, popularity as a line in the X, which incidentally has nice autoscaling behavior, but possibly more interesting is the 2-D histogram showing 1000 rows of 100 dots, popularity shown as dot brightness. There's a regularity to it, with strong verticals every 10 units, stronger verticals at 50 and 100, a definite gradient every 1000 units, a diagonal representing the multiples of 101 (some of them product numbers like Olympus 3030, Teltone M-8888).
A striking exponential gradient leaps out as you approach 2000, reflecting the denser availability of historical data as you approach the current day — and the explosion of the web itself in 1994. Individual pixel hotspots leap out at the eye: some explained by checking the associations, like 8859 (ISO 8859, a character set specification), some unexplained like 9551 or 8791. The technologies we're all obsessed with leave their marks — a short horizontal streak of warm spots starting at 8080, hot at 8086 and 8088 shows one era of Intel, while a vertical streak from 80286 to 80486 shows another.
Once into the five-digit numbers, American geography plays a role, with some ZIP codes showing up hot in on a generally cooler field than the 4-digit number.
Round binaries get hotspots, and some of their neighbors: 32767, 32768, 65535, 65536, of course, being the most important numbers in the 16-bit world — as well as being significant to residents of Leasburg and Lebanon, MO. But 16384 spikes, along with its successors 16385 and 16386, which is a little surprising. A bit down the road, 16391 through 16394 are inexplicably hot. Lundy's Lane, PA, a city I've never heard of, boosts 16401 — maybe the result of a web-conscious city chamber of commerce? A string of Washington, DC ZIP codes brightens the 20000 line — surely more mail goes to Washington than any other city in the nation. Maryland and Virginia are heavily represented here as well.
And still those streaks every 10 pixels on both axes, reflecting our preference for round numbers. Chicago and suburbs cluster around 60600. A string of bright standouts at the intersections of a thousand-line and a ten-line turn out to be the Macintosh processors — 68000, 68020, 68030, 68040. Texas populates the 75000 line. A chain of hot odd numbers from 81667 to 81679 is unexplained in the associations, but turn out to be postal codes for München, Germany. The 94000s are speckled with the cities of the San Francisco peninsula, naturally.
I could look at these all night.
The life cycle of performance-critical code is supposed to go in three phases: (1) make it work. (2) make it work right. (3) make it work fast. In truth, there's probably another step, (4) make it work right and fast.
Over the last few days, I've been revisiting some of my plugins and doing a step-two on them, fixing some long-standing bugs. In particular, I've been relying heavily on a particular digital filter implementation that becomes, um, explosively unstable at what are really fairly moderate cutoff frequencies.
In the DSP technical sense, a filter amplifies or suppresses portions of an audio signal based on their frequency. I've been relying heavily on one particular kind of digital filter, the Chamberlin 12dB/octave state variable type. This has the advantage of being really simple to code and very flexible. A single block of code simultaneously calculates the low-pass, high-pass, band-pass, and band-stop outputs from the filter. This is good if, like me, you never know what you're going to want. Low-pass filters are the bread and butter of analog synthesizer emulation, but the other forms are also useful.
The Chamberlin filter has a pretty severe limitation in that it becomes computationally unstable as the cutoff frequency increases. Instead of keeping its output in a nice reasonable range of numbers, it goes exponentially out of range, which generally leads to a brief pop followed by silence. Usually it's a digital clipping sort of pop rather than a speaker-cone-ripping sort of pop, but still, not a good thing.
Chamberlin's book, Musical Applications of Microprocessors, neglects to mention this instability at all. It's well known in DSP circles, but I'm new to this whole thing, so only slowly began to grok the connections between discussions of stability limits and the misbehavior of my plugins. I've now known for a while that I needed to do something about it, and finally this week have managed to make the fix.
The basic approach is, since the stability limit is related to the digital sampling rate, to oversample within the filter, increasing the effective sampling rate, thereby increasing the stability limit. You can oversample by a little bit and add some hackery to help avoid the stability limit, or oversample by a lot and restrict the usable range of the cutoff frequency to ensure you never get to the stability limit. (I was restricting the cutoff freq range previously, but now I have a lot more range and a lot more margin of error available simultaneously.) I've now got implementations for both approaches in my filter library — they're each handy in different situations.
So, to take advantage of the new filter implementations, I've revisited some of my early plugins, Breathe Beat and Pegger, and released updated versions with the new filters and sundry other improvements.
Now, Breather, the new version of Breathe Beat, is hooked up to an emulated TR-808 and its output fed through a nasty reverb, and oh my goodness does it sound fabulous when the bandpass filter swoops down through 30Hz just as the 808 kick triggers. It's the kind of thing that makes otherwise reasonable people want to spend thousands of dollars customizing their pickup truck just to cruise around with it thumping out of their subwoofers. To tell the truth, I could do this with the old version too, but it somehow sounds better knowing that the code behind it sucks less.
Okay, so I started this blog/journal/whatever the hell it is to rant about software quality, actually, and haven't really done very much of that. Ironically, my originally-conceived rants were going to be backhandedly complimentary to Microsoft (in short: Eudora, and the Mozilla email client, were so crappy that they drove me to Outlook Express), but this one isn't. Or maybe it is. You'll see.
It's almost too simple to hate Microsoft. They're a large, easy target. Their software appears everywhere. They use the most ruthless business practices they can get away with (and some they can't) to hang onto market share. (In fact, the current MS antitrust litigation, in my opinion, is not about the legality of what MS does. It's about the fact that they've been, corporately, assholes. They've been fucking over everyone they can, consumers and competitors alike, for years. They've made enemies of everyone, and now the customers and the competitors are working together with the government to try and pay back some of the fucking over. MS is trying to argue the letter of the law — and antitrust law is so vague that either side can claim anything they want — but they're missing the point: this is now about vengeance, not about justice.)
But I'm gonna ignore their business practices for the moment and just talk about software. Lots of people assume Microsoft software is unadulterated crap. Everyone makes jokes about how bad it is. "Microsoft = Poor Quality" is a virulent mimetic virus. Back during the days of Y2K nervousness, people joked "Apple may not have done everything right, but they knew the century was going to end," implying that Windows was going to have a Y2K problem. Apparently Windows 3.1 does have a Y2K problem, but I never had a problem with my Win95 machines; I suspect that any Y2K problems with Win95 PCs were about the BIOS, not the OS — ironically, PC BIOSes are one of the only kinds of software Microsoft doesn't dabble in (to the best of my knowledge).
Let me just jump out here with a bold claim: Given what the software is supposed to do, the consumer versions of 32-bit Windows — Windows 95, Windows 98, and Windows ME — are really pretty well-engineered. "Yeah?" you ask. "Then why do they crash so freakin' much?" The answer lies in what the software has to do. It has to provide an environment where 16-bit DOS software, 16-bit Windows software, and 32-bit Windows software can all run side by side, interfacing seamlessly with thousands upon thousands of different hardware configurations. I'm not going to go into the deep technical reasons why this creates lots of opportunities to crash the system, but leave it at this: Right or wrong, Microsoft made the conscious decision that backwards compatibility with old apps was more important than system stability. If you can't accept that tradeoff, you're supposed to be using Windows NT or Windows 2000.
In the Apple world, the OS team can work with the hardware team to make sure that hardware device drivers are working and stable. There are a finite number of hardware configurations and interactions. In the open-source Unix world, new hardware takes a while to get supported, and the initial level of support frequently consists of a quick hack to an older driver to make the new hardware limp along without enabling all its features. In the Windows world, the hardware manufacturer, not Microsoft, typically provides the device driver software. If there's a bug in the driver, Windows may crash with a cryptic blue screen of death; it may, in its mysterious way, blame the correct device specific DLL, but most users don't know how to interpret that information. (Why are most DLL names still 8.3? Wouldn't a blue-screen saying "Unhandled exception in module GemstoneSwiftStar400GraphicsDriver.dll" be better than "GSS400.dll"?)
Likewise, most users are, shall we say, unsophisticated, and when some random application tries to access some block of memory it doesn't own due to a bug, Windows catches it and presents the dreaded "General Protection Fault" message (or whatever it's labeled this time around), the user thinks Windows is doing something wrong. It's like blaming a cop who arrests a lot of criminals for the high crime rate. If Windows could speak, it'd probably say "Hey, buddy, I'm just doing my job!" Of course, nowadays, many users are running primarily Microsoft apps, so it's not unreasonable to go ahead and give Microsoft the blame.
Ah yes, Microsoft apps. The reason I started this whole rant was Internet Explorer. You remember Internet Explorer. Wayyyy back in the 90s, this little company called Netscape created a graphical web browser that revolutionized the way people share and access information. Netscape was a "new economy" company that "got it". They were cool. They were the swift clever mammals to the lumbering dinosaur that was Microsoft. Microsoft's response to Netscape Navigator was to clone it: voila, Internet Explorer. So, Netscape was there first; they had a bunch of sharp, energetic kids who were excited about the transformative power of the software they were creatings. Microsoft was following, not innovating, and they started late, and their motivation was, as usual, market share über alles. If this were an American movie, it's pretty obvious who would win. Alas. Microsoft crushed Netscape, winning in the naive consumer market with their anticompetive business practices (installing Internet Explorer with every installation of Windows), but more significantly for my purposes, winning in the informed consumer market by having fewer and less annoying bugs than Netscape. People trash Microsoft for embrace-and-extend, but in truth, IE rendered "standard" HTML better, more correctly, than Netscape did. So people like me who might have been glad to oppose Microsoft on principle eventually started using IE out of pragmatism. (I myself kept on using Netscape, and later, Mozilla, for years, because I was the one person on the planet who actually liked the Netscape mail/news client. Then Netscape 6 finally tripped my bloat-resistance circuit, and Mozilla screwed up the mail client. I'm an IE/OE man now. However, during all that time using Netscape, I kept being glad I had IE handy to view the occasional page that Netscape just couldn't deal with.) If Microsoft couldn't win the browser war by ramming their product down consumers throats, I think they still would have won just by sucking less.
Now, today, using IE 6, I decided to sort my bookmarks/favorites again. And I was struck by just how incredibly bad the user interface for the "Organize Favorites" system was. Aha! See? Microsoft Must Suck! Crappy UI! Yeah, but this stood out enough for me to rant about it, because MS UI is generally, well, adequate, if not good. Sure, lots of MS apps have some UI bullshit that makes them a little bit awkward, but they aren't usually this PAINFUL.
So what's wrong with Organize Favorites? Okay, when you select it, you get this tiny window that shows, in my case, 12 items in your favorites tree. If I only had twelve items I wouldn't need to organize it, would I? It looks like a fixed-size dialog -- it doesn't have the "resize triangle" in the lower right that most resizable windows do, nor does it have the normal "grabbable border" visual. It doesn't have minimize/maximize buttons. Most users would be forgiven for assuming it was fixed size. But no, it's resizable, thank goodness. Just grab any edge or corner like you would a window with the appropriate visual indicators and resize the sucker. Great! Okay, start going through the list of links. Hm, this one is called "The Master Lists". What the hell was that again? Double-click to open the link. Nothing happens. Sigh. Right-click to see if there's an "open" option. No. I can select "Print" (and does that print the list of links, the name of this link, or the contents of the linked page?), or "Make Available Offline", or "Send To" various apps (and again, does that send the link or the contents?). I must use these operations oh so frequently, to understand them so well, right? Where the hell is the Open option? Okay, fine, I'll just open it from the main browser window, so I can see what the heck this thing is so I know where to file it.
PING. PING.
I can't go to the browser window, because this is a freaking MODAL DIALOG BOX — it prevents its parent window from being selected as long as it's up. Modal dialog boxes are, shall we say, strongly out of favor these days. Modal anything is considered bad in the UI world, because the principle is that things should respond consistently whenever possible &mdash if clicking on a window brings that window to the foreground sometimes, it should bring it to the foreground every time, because the user has that expectation. A modal dialog that prevents the browser window from coming up confuses the user. The machine pings at you and foregrounds some other window that isn't the window the user wanted. In this case, I determine that I can start another browser session to let me browse the links as I sort them, but it still sucks.
It continues to suck in other ways. Even with the Organize Favorites dialog filling my screen, I have more links than will fit. If I drag a link up to some folder off the top or bottom of the list, it automatically scrolls — but slowly and jerkily. If I drag a link over a folder, the folder does eventually auto-open to let me go into subfolders or place the link in a specific place in the folder, but it takes just a bit longer than I expect, so I keep thinking it's not going to auto-open. If I have three links in a row that all go into the same category — common enough, because I'll be surfing for a while on one topic and find multiple keepers on that topic, right? — my UI expectation is that I can select one, shift-select or control-select the others, and drag them together to the target folder, because every other list control or tree control in windows apps does this. Not this one. No multiple selections allowed. This is not a standard list/tree control, which is why it's so sucky. (I think the standard tree control doesn't let you sort items on a single level of hierarchy, is why they couldn't use it here, but I'm not sure.)
Okay, next problem. When I select an item, then drag it into a folder, after the drag, the next item down in the list from the one I initially selected is the one that remains selected. No big deal, except that it's different from expected tree-control behavior — nothing remains selected in a normal tree. So I've got some item selected now, but I want to move a different item next. So I click-drag that item to its new home, but during the drag, the originally selected item remains highlighted the whole time, even at the end, even though it didn't participate in the drag, which did work properly. Half of my brain is warning me that I'm dragging the wrong thing, half of my brain is complaining that the highlighted item didn't get dragged to the destination I selected.
I have folder names that aren't quite right, or I've got some link names that don't tell me what the links are about (so I go into my other browser session, as noted above, to see what the hell they are). I F2 or select Properties to rename them, and at the end of the rename, the link GOES AWAY. What the fuck? Did I delete it? No, it moved it to the end of the list. The whole point of this funky custom control is to let me sort things the way I want to, and it winds up moving things without my say-so. Wrong, wrong, wrong. When I drag an item into a new folder, it takes about a second and a half to update the display. This is on an 800MHz machine. What the hell is taking it so long? I don't have more than 100 or so total links here. That's 12 million CPU cycles per link being spent on something. I can't really conceive what it might be doing that would take that long. Even if it's written in Visual Basic.
I close my folders in the display so I can see more as-yet-unfiled links. I drag a link onto a folder, not caring where in the folder it goes, so I don't wait around for the folder to open before the drop. It doesn't let me pick where in the folder the link goes, this way, but it automatically pops the folder open after the drop so I can see where it went. Which scrolls my next target off the bottom of the list. Except sometimes, when it doesn't auto-open the folder. Dunno why.
There's a folder in here called Links. Well, see, everything in my Favorites should be links, right? So I delete that folder, it's redundant. As soon as I open another browser session, it recreates the folder. I don't know why.
Oh yeah — when I imported all my bookmarks from Mozilla into IE, it kindly alphabetized them all for me. Not devastating, but either the sorting of favorites/bookmarks is significant, in which case it should never override my sorts when I import or rename, or it's insignificant, in which case use the default tree control which works as expected and works at a reasonable speed.
I'm not sure if IE 5 had these problems. I don't remember it being this bad. IE 5.1 on the Mac certainly doesn't have these problems.
I was about to say that there is no excuse for this kind of crap, but as a professional software developer, I think I know what happened. The Kid got the job of writing the Organize Favorites control. Lots of software development teams have The Kid. The Kid is the programmer who has a lot to learn. He's not stupid. He has potential. He's just good enough that he's not actually a detriment to the team's productivity. Everyone else on the team is so overworked that no one has the time to teach him to reach his potential. And in this particular case, the kid hasn't learned about Windows user interface standards, such as they are. As it is, this bookmark organizer is so incredibly painful to use that I'm doing a halfassed job of sorting my bookmarks. Once I get them into the right folders, I'm going to stop, instead of sorting them within the folders the way I'd like them to be. It's just not worth the time and effort.
The creepy thing here, is that the Organize Favorites problems I describe here are actually a credit to how usable — as opposed to great — Microsoft's UI code actually is. It's pretty consistent on the whole. It makes some effort to not fuck the user over constantly.
Oh look, I have a goblin-cat on my lap. I've been trying to tell her all week that the computer goes on my lap and she sits next to me, but she was too swift this time and pounced before I could get the computer in place.
But that's not what this post is about. I got an email from a guy who tried and liked MIDIBounce and had some ideas about enhancing it. Damn him. He set off another wave of ideas in my tender brainmeats, this while I'm too sick to concentrate enough to get the ones I'm already working on to a usable point.
The fundamental idea here is some sort of extended algorithmic scheme for driving a sequence of MIDI data — MIDIBounce currently only works with control changes, but the idea can spill onto note-on/note-off, too — again, nothing too earth-shattering at the core. You hit the start button, the app spews out a bunch of structured MIDI data in real time, you're done. There's two ways you can generate data algorithmically: you can make it suck, or you can make it programmable. For my personal use projects, I could get away with making it suck, because my idea of user interface is to edit the source code and recompile when I want to change things. I figure, though, if someone else gives me the idea, I kinda have to make it somewhat accessible to him, right?
So, I'm thinking of a mind-bogglingly simple-to-parse scripting language, based on rewriting rules, whose lowest-level primitives are MIDI commands and time delays. A more sophisticated language would be beyond my ability to write an interpreter for in any reasonable timeframe, and would be a bit harder for non-programmers to learn, I think.
Oh, yeah, and I have to FIND A JOB. At least when I have a job I'll have a good excuse not to finish my audio projects.
I got Nooner and Renoon out to the mulch-discuss community, finally. I'm still not happy with the MIDI-out device management, but I'm not quite ready to add UI to Renoon to support a better solution.
One of the mulch-discuss guys is putting a track which uses Edge and Pegger onto a compilation CD for a fledgling record company. Above and beyond the letter of the license agreement, he's sending me a CDR copy of the whole comp. Some day I hope to have a big stack of CDs that I can point to and say "those use my tools".
I got Facade sort of working — the timing-based expressions aren't working yet, but the tone- and velocity- based ones more or less are, though it needs a little work — it should be more reluctant to declare a change of key, for instance. What isn't clear yet is how useful it's going to be. Because Facade outputs VCV, and most of my soft-synths want MIDI, and because Renoon is clunky, I didn't test it much with soft-synths; mostly I tested it with Femme because that was easy to hook up for a quick smoke test. Unfortunately, that meant I was listening to all the expressions as pitch changes, which conflicted with what I expected to hear as I hit different notes on the keyboard.
While working on Facade, I figured there'd be some fiddly bits where it wouldn't be putting out quite the right data, and I'd want to see the actual numbers coming off the outputs. This collided in my mind with the various cross-plugin network communication schemes I had, and I figured I should implement a simple UDP socket messaging system and use it to collate debug messages from multiple plugins into a single log. The logger would be a standalone app that just waited for these messages to appear. However, I got on a roll working on Facade, and wound up just opening a console window from the plugin, directly, to output the debuggery. When I'm feeling a bit better maybe I'll try building the logger system again.
One of the other mulch-discussors asked when Animal was gonna be done. I said I didn't really know, then went to revisit the beast. I built a new project workspace for it with my new, improved, nearly sane directory structure, and rewrote half the drum sample synthesis engine to use my filter and waveshaper class objects. That was actually fixing something that wasn't broken, mostly, but hey, whatever. Then I started casting about the web, looking for tips on cymbal synthesis, because I've just about decided that Animal's existing synthesis model just isn't gonna cut it for crash/ride cymbals. (Short summary of existing synthesis technique: one enveloped noise source with a low-or-high-or-band-pass filter, "noise", one damped sinewave oscillator, "tone"; noise and tone are modulated and/or mixed together in one of four modes; output is that mod-mix put through a soft-clipping waveshaper. Sounds like an analog drum machine, pretty passable for a lot of the sounds, though I am learning I have a pretty crappy ear for drums.) No one seems to know how to synthesize good cymbals. Best lead I have so far is a description of the TR808 cymbal-synth circuit; I might try to softwareize that.
I did finally decide that I'm going to allow user-supplied samples to work with Animal, which I had previously rejected due to my UI aversion — I'm gonna do it without a UI! Animal, on startup, is just going to look in its current directory for files named Animal00*.wav-Animal31*.wav; those will fill the drum sample slots, and the * parts will be the names presented by Animal. If one or more of those files are not found, it'll synthesize them on the fly and write them out. So the first time you run it, it'll take a couple of seconds and write out the whole set; then you just go in and replace my sucky cymbals with a good sampled cymbal. My laziness is satisfied, my Animal remains a pure synthesis thang, and the end-user can have whatever sounds he wants. Yes, it's a hack...
In this corner, we have some amount of low-level libertarian idealism. In that corner, we have the possibility of $330 per week from the gummint. In this corner, the annoyance of having to go through a bunch of paperwork and talk on the phone to someone who is probably going to assume I'm trying to scam them. In the other corner, hey! Free money!
Yup, I'm filing for unemployment benefits. I don't really think I'll be unemployed much longer — I had a couple of good interviews this week, and I'm feeling a little more employable than I was a couple of weeks back. Still, why pass up one of the small benefits that our government-heavy lifestyle affords us, huh?
So while working with Renoon, the VCV-to-MIDI converter, I found two things; one, that it was awkward to select a MIDI device via a VST plugin default-host-interface knob or slider (because you don't want it to activate and deactivate MIDI interface number 1 when you're moving the slider from 0 to 2), and two, you need a third-party solution to get your MIDI output from Renoon back into your VST host.
I was successful in using MIDI-OX and MIDI-Yoke to do this plumbing, but it still feels like a cheap hack. It makes me want to avoid this solution for control signals out as much as possible. The VST signal path interface is there, it's convenient, it's easy as anything to write a plugin that uses it, but it's weird for Audiomulch users because there's no way to see the difference between an audio input and a control input in a VST plugin — you just need to read the docs to know what the inputs actually do.
I can live with this for my purposes. I don't have paying customers yet. I'm okay with giving my plugins control inputs, and if I want to use someone else's (MIDI-driven) plugin, I can live with Renoon/MIDI-OX hackery. Remember, this is all a stopgap until Audiomulch gets the ability to map audio signals to contraption parameters.
So why am I trying to think of other ways to send the data around? My first thought was that I'd rather pass things around via local IP sockets. All my plugins could agree on a network port number to listen to (instead of configuring input and output MIDI devices for all of them), and with half as much configuration work, I could at a stroke get the ability to control plugins on other computers either on a LAN or on the internet. Think about that one for a second and see if you can't think of some applications for that: my keyboard playing can fiddle with the effects that your music is going through. Lots of possibilities there. There are various troublesome points regarding varying transmission latency and lost messages. Various solutions have been proposed, such as this. My solution would be to send only self-contained messages (no note-on/off, system-exclusive, or running-status messages) via UDP and accept varying timing as part of the art — remember, all I care about are control signals here. (If MIDI-over-IP doesn't grab you, how about IP-over-MIDI?)
Besides MIDI-over-IP, there's Open Sound Control, which is a network-oriented but transport-independent protocol for sending audio control messages. However, it is designed for targeted communication, with a query system for determining what arbitrary "parameter addresses" a device supports in order to send messages to those parameters; I am after a looser, broadcast-oriented solution where you can send a message like "wackiness=0.87" to the network at large and let any interested device respond to that message as it sees fit, rather than sending a value to "/voices/drone-b/resonators/3/set-Q" on a specific device to manipulate a specific synthesis parameter. I guess I could do this by defining a lot of parameters in the "borogove/" namespace ("borogove/wackiness", "borogove/key-signature", "borogove/resonance") and let my plugins resolve those specific addresses...
The MIDI to Virtual Control Voltage interchangers are just about done — I need to rethink how the user selects MIDI-out devices for that plugin, but it works now, if a bit awkwardly. Those were mostly a bit of insurance for future plugins which will generate control signals, making sure I can build them either as VCV or MIDI generators without painting myself into a corner.
So what are those future plugins? The first is called Façade. Its basic deal is that it will watch MIDI notes incoming and generate control signals corresponding to some higher-level analysis of the notes. The basic idea was sparked by an article in Computer Music Journal about giving synthesizers more avenues of expressiveness.
One output will correspond to the rate at which you play notes. If this control signal is hooked up to parameters in your soft synth, it could, for example, automatically adjust attack and release speeds to give you legato in slow passages and staccato in fast passages — or vice versa. Or it could make fast passages have a different timbre, brighter or darker, than slow. Or whatever. This one is trivial to implement.
Another output would correspond to the difference in note rate from note to note — the irregularity of a passage. This is only slightly harder. Likewise with an output corresponding to whether the interval between notes is ascending or descending, and how far. This lets you make a half-step down to a D-sharp sound different from an octave-step up to the same D-sharp.
Finally, the key of a piece of music can be more or less deduced from a sequence of notes. This is error-prone if the music changes key, or if not all the notes in a key are used, but a good guess can generally be made. This could be used for another two expression outputs: the current key itself could drive an output, so your instrument could sound different in C-minor than in D-flat-major. Consider a song where verse and chorus are in different keys and the guitarist normally toggles some of his effects pedals at the change. This could let you automate the effects change (though it might be hard-pressed to notice the key change at the right time, which would be problematic).
Another key-based output could be the "degree of consonance" of a given note. As Façade tracks the current musical key, each note played can be assigned a consonance value within that key, with the I, IV, and V having high consonance, the II and VI having lower consonance, and off-key notes having the lowest consonance. Once again, this gives rise to a bunch of automatic adjustments — one of the clever possibilities would be to map consonance to pitch-bend such that on-key notes are not altered, but off-key notes are bent up or down a semitone — effectively putting them back on-key!
I had a pretty good job interview yesterday. It was for about three different positions at a game-middleware company. Unfortunately I'm not sure whether I want any of the three positions in question.
Middleware is a fancy way of saying "libraries provided by neither the game developer or by the game platform manufacturer." In this case, it means a graphics API that gives reasonable portability across Windows, Playstation 2, Nintendo GameCube, and X-Box.
It seems like an interesting company, with lots of potential, and lots of smart people working there. It's not directly in the game industry, which is starting to seem like a plus. The position that I'm most qualified for and interested in would expose me to a lot of game development teams at other companies; I'd see a lot of interesting stuff that way, probably make a lot of contacts, and from that standpoint it might be a good way to get back into the game industry later if I decide I don't want to leave for good. Still, I'm just not sure what I want right now.
I have a followup interview there next week to talk in depth about two of the three positions that were mentioned this week. We'll see how it goes.
Another job possibility turned me down today. Once again the gist of the message is "we think you're smart and talented, just not a perfect fit for the position we have open."
Unlike the previous time I heard this line, I actually believe it. Unfortunately, this came along with a sort of half-assed "we have this other position that I can't really describe adequately, on this super-secret project that I really can't talk about, but if you can make the claim that you've done this exact kind of work before, maybe we can hire you for that." So after ten minutes of me talking about things that were sort of tangentially related to what I imagined this guy might be talking about, he came to the conclusion that, no, I hadn't had this exact job before.
And this is the problem. I haven't had the same job for more than about six months running over the last twelve years, because, well, things need to get done, and I think I can do them. At the last permanent job I was on, I was more or less hired to do cross-platform network programming, and wound up getting drafted to debug PS2 rendering code and rewrite PS2 audio code. It's hard to get more disparate programming tasks than those three in today's game industry. Before getting the job, I'd never seen a PS2; just before I quit, the company was trying to bribe me cash money to work extra hours to get the doomed PS2 version out.
So I shift around a lot, and that means that, well, I'm not a sound guy — I did some sound programming back ten years ago, I understand the principles, I can get up to speed on new sound hardware pretty quick. I'm not a network guy — I've added network play to a crappy little puzzle game, and I've written a game-matching client-server networking system. I'm not a graphics guy — I've ported an OpenGL-based game to Direct3D and a Dreamcast/Kamui based rendering engine to GLIDE.
Now I'm to a point where I'm senior enough that I should be an expert at something, but I seem to know a little bit about a lot of subjects instead of a lot about one. Everybody wants to hire someone who's an expert at the task they need — they want, effectively, someone to write the same code at this job that they wrote at their last job. The perception, then, is that I'm "entry level" for any given specialization, but I need a lot more salary than an entry-level programmer does. Never mind that, when some unexpected disaster strikes, and the guy who understands the widget engine gets run over by a Twinkie™ truck, I could volunteer to become the new widget engine expert and wrap my head around it in a few days. You can't schedule that guy getting run over, so you can't schedule the need for his replacement.
The smart thing for me to do here would be to go buy a GeForce3 and spend a month becoming a DX8 and OpenGL vertex-and-pixel-shader GOD by, uh, copying the sample shaders off the nVidia developer support sites and tinkering with them, so I can go around saying I'm a graphics GOD. Unfortunately, I'm a lazy evaluator, or a just-in-time expert system perhaps, and I don't want to fucking bother to fill up my brain with that crap when my next job is just as likely to be network-related as graphics-related.
Yes, I'm a bit frustrated here at this point.
I'm ready to get out of the game industry. I'll have the same problems breaking into a new field, but at least when I get there I'll have some sort of tradition of QA on my side.
Bedtime.