Trumpet and Gray Code

This is one of those posts where analog meets digital. I’ve played trumpet since 4th grade. It’s an interesting bit of plumbing applied to your face. In essence, it’s 7 bugles welded together with a not-quite-binary switching system. In a trumpet, there are typically (but not always) 3 valves which are set up to drop the pitch being played by the following table:


Valve setting Drop in Pitch in semitones
000 0
010 1
100 2
110 3
011 4
101 5
111 6



Now, this is not quite true binary. It’s a little unusual because there is one combination that isn’t in there: 001. 001 is equivalent to 110. Equivalent is a funny word for this though because it’s not. 001 is close to 110, but different. 001 is slightly out of tune and it gets used really only for pieces where you have to quickly switch between some other valve combination and 110 and them something else and it’s quicker to switch to 001 and something else. For example, if you have to trill between a concert F and a concert G, your choice is to quickly switch between 000 and 110 or 000 and 001.

So let’s talk about Gray Code. Gray Code is a way to encode binary digits such that only one bit changes between successive values. This is useful, for example, when you need to have a counter that fires relays and you need to minimize the number of relay changes to minimize mechanical wear.

This morning I was wondering about the relative differences in the difficlutie sof playing in different keys on the trumpet and if the valve layout was optimized to be as close to Gray Code transitions as possible.

Then I thought that really, what you want is to build a database of musical trigrams and maybe quadgrams in typical trumpet music and to compare the difference in valve changes from standard to non-standard layouts and see which is more optimal across most keys.

Part of the impetus is that there are certain keys on trumpet that are considered ‘hard’: Db, Cb, F#, B (and the corresponding parallel minor keys) and are they really hard or is it a mental block? There are some fingering exercises that are brutal in those keys (especially Clarke’s Second Study), but I remember my teacher being able to rip through the ‘hard’ keys as easily as the ‘easy’ keys.

I know how to do this analysis. Do I have time? Oh, god no.

I’m Old, Part XIV: Platform Cliques

When we were working on Acrobat 1.0, there were several distinct cliques within the group. For 1.0, we were writing code that would run on Windows 3.1, Windows NT, DOS, Mac System 6.something, and Mac System 7, but these divided up into 3 groups: Windows, Mac, and DOS. Each group had 2 people dedicated to it, but the Mac group had 3 (I was the third, but honestly, Mike Pell was split between doing UI code and being responsible for the builds and the installers, so he was a little thin). On top of that, there were engineers who were dedicated to the main portable engine that was shared across platforms.


For sure, the various platforms were cliques. Ken Grant and Mike Diamond on Windows routinely referred to the Mac as “The Dead Platform”. The Mac people teased them about kowtowing to the Evil Empire. And the DOS people? Well, they were just sad because they knew they had no future.

At the same time, as much ribbing as we handed out and received, we also had to work together. When I was working on the Find tool, I was actively making the underlying code more complicated as I came to understand the complexity of the problem.

As an aside, there are sections of the PDF specification that, if you’re code to it, you look at and thing, “holy shit, my life just got a whole lot more complicated.” And me, having worked on it, can point at those portions and name the person responsible for it. Blessed few of the pain points have my name on them, but there is one in particular that was informed by me, and it has to do with highlighting search results.

When I finally got find word/phrase limping, I was constantly irritated by how the results looked. The code would find the approximate axis-aligned bounding box of the word and highlight it. Unfortunately, when you have anything more complicated than simple blocks of rectilinear text, the bounding boxes look like shit. On top of that, words may be split across lines or be bent along curves, and so on. So in my mind, a highlight wasn’t a single (or set of) axis-aligned rectangles but a set of quadrilaterals that don’t have to be axis aligned nor do they have to be rectangles.

The PDF highlight annotation is represented as a set of quadrilaterals, and that complication is totally my fault.

So after I had reworked all the search code on the Mac, it needed to happen on Windows, so I spent a lot of time in Mike Diamond’s office working with him to make sure that the Windows UI mapped onto the underlying code.

So cliquish or not, we still had to work together to make sure that features had parity.

In an ideal world, we would have been less specialists and more generalists and were writing code for all the platforms, but like it or not, there are only so many hours in the day to become a specialist on a new platform.

I’m Old, Part XXIII, Goodbye Adobe, Hello Axial

I was at Adobe for close to 6 years. I had gotten completely burnt out on Acrobat and decided to look around the company to see what other opportunities were available. There was an opening on Premiere, and I decided to give it a shot. I was there trying to move the product forward in features as well as improve the cross-platform portability. Originally, Premiere had been a Mac product and it was a hack and a glorious one at that. Nearly everything in the app was an extension or plug-in. New functionality was added by creating a new plug-in to create it. As a result, the app itself was small, but load time was terrible and portability was awful since the plug-in mechanism wasn’t all that cross-platform friendly. I did my best to help out the team by trying to make more of the windowing and UI widgets portable, but I never felt like I fit into the team.

Well before I left the Acrobat team, Alan Wootton (one of the original Acrobat/PDF designers) left the company. During off hours, we were playing the games Doom and/or Marathon, which were primitive FPS games. Alan was looking at the games and wondering why they weren’t full 6 degree of freedom games instead of limited pseudo-3D games. He did some experiments to figure out the rendering budget to get reasonable 3D performance and the math added up. He struck out on his own to make this happen.

We met up with Alan now and again to see how he was progressing and jokingly referred to him as a vampire because he was getting up late in the day and working into the night.

At one point, he had a party where I got to meet a long time friend of his, Marty Hess. He and Marty had produced a product called PlayWrite which was a word processor that was geared specifically for people writing screenplays. I remember having a talk with Marty, but I don’t really remember about what.

A couple months later, Alan and Marty secured venture funding for Alan’s 3D engine, created a company called Axial and started bringing on infrastructure. I got a call and had one of the weirdest interviews I ever had. I was sitting in with Alan and Jim Lloyd (an early employee) while Alan explained how his BSP tree code worked to determine visibility of polygons. I was in a daze and missed half of it. They offered me job anyway.

I got a very generous offer and it came at a point where I was about to have an annual review at Adobe. The Adobe review offered me a pay increase that set my salary below the offer from Axial. I told my boss that I had that offer (hoping to get a counter). He looked liked a deflated balloon, but the die was cast.

I left Adobe to work at a start up.

I was impressed with how much infrastructure they had in place. There was a source control system, a build system (IIRC), QA, tech support/documentation, and HR, with plans to hire sales and marketing all packed into an office suite in a nice section of Saratoga, CA.

I was shown my office and was given a modest budget for setting it up. I looked around at other people’s offices and saw similar things: desks, chairs, and broken chip board book cases. Wait, what? Yeah. Every office had the same type of book case, each one broken in the same way. One of our VC’s, Roland, was a very tall man. Six foot seven, if I recall correctly. When he made visits to the office, he would go in and talk with the staff and since most offices were spare on furniture, he was sit on top of a bookcase and break it. That’s was I was told by Marty, Alan, Jim, and Andy Hess. Interesting.

I bought a book case of a totally different design that was solid wood and that had no room to sit on because screw you, Roland, I like my furniture. While setting up my office and my system, I had to walk around the office looking for tools which were always spread far and wide. It drove me nuts. One of the first things I did to enhance corporate culture was to see about getting a case of tool kits for the office. Each kit had a reversible Phillips/flat head screwdriver, a socket driver, a chip remover, forceps, a tube for holding screws, and a couple other useless things. Whenever a new person was hired, I presented them with the toolkit and said, “and don’t ever ask me for a screwdriver again!”

I liked working at Axial. It was in a very nice location – it was a reverse commute for me so I had absolutely no traffic problems in either direction. The set of suites were in a ring of buildings with a koi pond in the center, open to the sky. The koi pond is its own story. I liked that the front door had the name on a piece of copy paper with a simple logo with the ‘A’ in Axial rendered in simple vector arrows – a quick job done by Mike Pell. It was the beginning of a very intense period of my life, personally and professionally.

I’m Old, Part XXII: Don’t Be Me

I have always had an intense fascination with writing software. Not only are novel puzzles intriguing, but seeing them through to completion, running on their own, and/or being used by other people really hits the right spot.


The problem here is one of intense concentration over time. It is wearying and on top of that –and let’s be honest here– writing software is truly hard on your body. It is largely static work that can take many hours to reach a reasonable stopping point.

I developed a pattern – I would work long hours for many days at a stretch and not take care of myself and then I would get an injury and put myself out of commission, sometimes inside work, sometimes outside of work.

During my tenure at Adobe (and in no particular order): I herniated two different discs (each on different occasions), tore a ligament in my knee, got a running injury, tendinitis, and a really bad injury that put me in the hospital for three weeks. I don’t talk about that one publicly as I have made it my policy to only tell that story in exchange for a pint of beer as it that is about the right amount of libation needed to tell the story. Buy me a pint, ask nicely, and I might just tell you.

At one point, Pam Deziel, who was working in marketing for Acrobat joked that I needed to stop using injuries as my vacation time. Honestly, this wasn’t a laughing matter because so many people had accrued the limit of vacation time (as mention earlier here). At the I’m I probably either rolled my eyes or said, “I know, I know.” I was probably thinking, “shyeah, right! And how do I do that?”

When I had injured my knee, I was back at work the following day with ice packs and a cane. What was I thinking?I remember that during my recovery,  I had interviewed Eswar Priyadarshan, who was hired to work on Acrobat Catalog as well as on fast serving of PDFs (aka, Johnny Cache). Most people who I have interviewed remember it as a very intense process. Eswar told me how much it stood out in his memory because in addition to the tough questions, I was intensely moving around with the cane back and forth from a chair to the white board.

Later on in my career, I learned a lesson from Marty Hess, my boss at Newfire, that I wish I had known earlier: “You don’t earn vacation time, you take it. Don’t hesitate to take it.” At Newfire, I got better about taking vacations just to get away.

Still, even later, I’ve found several things that have helped me greatly. Right now, just past 50, I’m in better shape than I have been since my 20’s and I’m in much better overall health.

What have I done:

  1. Exercise regularly (I run, albeit slowly, 3 times per week even in the winter).
  2. Take breaks during the day. If you can’t concentrate to get into the “zone”, take a walk no matter the weather.
  3. Stop eating garbage. Seriously. Most of the food in American grocery stores is pure, unadulterated garbage. Last year, I cut nearly all food with added sugar from my diet, all caffeine, and made a huge increase in the amount of fresh and cooked vegetables. I’m not following paleo, vegan, or really any other diet per se. Instead, I try to ensure that most if not all the processing of my food is done in my kitchen. If you need to learn to cook, do that too. If you can understand how to write software, you can learn to cook.
  4. Take regular vacations, if for no other reason than to put the work away for a while.
  5. Make time for a hobby. If it’s a hobby with a partner or a group, it makes it much harder to avoid it. I play trumpet in a local community band. I used to also play in a brass quintet, but I don’t have time for both lately. I also make my own beer and have a nice garden.
  6. Try to sleep well. That’s easy for me to say, but at times (especially with kids and more so with kids with challenges) that’s near impossible. That’s why I say ‘try’.

And while I can’t guarantee that this will help, I can say that in my own experience I’ve felt better physically and emotionally (even when life has been extremely challenging). I’ve also gotten colds far less frequently and what colds I’ve had have been brief and minor. In my 20’s, every few months I would get something that would leave me in bed wishing that death be visited upon me. Mind you, one ingredient in that is that my kids are now at the point where they naturally wash their hands after using the toilet and before meals, so my little vectors aren’t nearly as infectious, but still in the past year, there have been nasty colds that have worked their way through the house taking out everyone except me, and that has never been the case previously.

By the way, the picture up top is my own thumb. That was the result of a plain, stupid, accident.

So when I say, “Don’t be me.” What I mean is, “Don’t be me in my 20’s and 30’s”. Learn from my mistakes and be careful about your body and your mind. Better health is the reward.

I’m Old, Part XXI: It’s Coo-kull, not See-kwull

In the 90’s, there were three main platforms to target for software: Mac OS, Windows, and Unix. Unix was far behind as a platform at that point because the reasonable Unix workstations (at that point made by Sun, DEC, SGI, or NeXT) were few in number and vast in price. For end-user products, Adobe targeted Mac and Windows and was very good about building balanced teams.


For Acrobat Search, the balance was not so good. There were two engineers on Windows initially: John Ciccarelli and Carl Orthlieb, plus Daryoush Paknad who was responsible for the indexing portion. Later, they dropped John, brought in Eswar Priyadarshan, and Kevin Binkley (both doing indexing).

On the Mac side, there was me. Or a portion of me since I was on Acrobat proper until it had shipped and Search was targeted for 2.0. Since I was the only Mac engineer for Search, when I was finally released from Acrobat, I was already behind and seriously outnumbered.

Carl was a great engineer. At one point, he was trying to implement a query language parser so that people could write relatively natural phrases “a or b but not c” and have them turn into something the search engine could manage. I had a book by Andy Tannenbaum that had a nice write-up of the railroad shunting yard algorithm. I handed Carl the book and he made short work of it. Out of that came CQL: Carl Query Language. Carl was very careful to pronounce it “COO-kull”, so it wouldn’t be confused with “SQL” (SEE-kwull).

It worked and it worked well and I was happy that all I needed to do was port it, instead of reimplement it. In the meantime, I was busy writing a UI library that could live in a plug-in in Acrobat because we were having so many changes to the UI that I needed a more effective toolset to allow me to keep up.

Carl and I used a shared UNIX box for source control. This was a mistake, but since we were just two engineers, it worked out. We staged files via FTP and then telnet’ed in and used sccs tools to maintain parity. It was painful, but the only other viable alternative was SourceSafe, also known as SourceUNSafe since it frequently self-corrupted its database.

Writing portable code was hard. There were a number of sins that one platform let you get away with that turned into hard crashes on another. When that happened (more often to me since I was behind and catching up), I’d walk into Carl’s office and interrupt him and let him know what was going on so we could collaborate on a fix. Carl, as often as not, would fall into a fit of drama that he had created a bug and would commit mock seppuku.

Carl and I got along pretty well. I teased him a little bit for being Canadian, but then he would turn around and make up stories about being Canadian. Like that every Canadian was required to serve in the Navy or Airforce and those in the Navy would end up with a tattoo of a moose wearing a toque on one butt cheek. A true Canadian knew that the moose’s name was Skippy.

Once I asked Carl’s wife about Carl’s butt tattoo. Utter confusion.

Later on, I moved out of my cube and into an office adjacent to Carl (this story will come later) and I was give and brand new PowerMac 8100 for development. One of the big things on this box was voice recognition (a precursor to Siri), which worked OK. You could name your computer (default was ‘Computer’) and you could address it directly. Things it recognized were, more or less, turned into AppleEvents and sent to the applications that published that they could respond to them.

It really couldn’t do much, honestly. It was a cute novelty, at best.

I named my computer ‘Carl’.

My Carl and the one next door responded with about the same latency except the one next door swore a lot more.

“Carl, what time is it?”

“It’s about two thir…God DAMN it, Steve.”

It was a fantastic misuse of technology, although certainly not the first and definitely not the last.


I’m Old, Part XX: API Design and Physics

When I worked at Newfire, we were initially producing a high performance VRML engine that we wanted to target towards producing games in your web browser. VRML had a set of scripting language hooks for doing things outside of the typical 3D node/interpolator structure, but it was designed, well, wrong. It depended upon using either Java or VRMLScript (a JavaScript clone) as an entirely subordinate entity to VRML. None of the major Java VMs at the time were really not happy being subordinate to VRML. I had to do some serious hackery just to get it to barely run. In a fit of rage, I went into my manager’s office, erased his white board and wrote out a 3D API that could be built in Java or C/C++ and would drive a VRML engine directly. I then went back to my office and continued to hack on the spec’ed version.


Marty, my manager, had just brought on an intern, Andrew, who shared his office and gave him my spec to implement. It was concise, simple, extensible, and performant. Andrew implemented that API.

When I was done with my pain, I took it over, but to make it a full game engine required much more than I could type. Alex Benton worked on the client/server coding (games were transparently client/server so that you got multiplayer out of the box, and if you didn’t use it, you didn’t notice). It had a modular physics engine, which was handed to Cowboy Dave (who I mentioned earlier).

Cowboy Dave was a true ambassador of corporate culture for us. He drove an immense Dodge (?) flatbed that he referred to as “three and half tons of MoTown steel” and he bought a large charcoal grill that he strapped on the back and drove to our office and set up on Friday afternoons to grill lemon pepper chicken.

Dave decided that we needed to do some field research for the physics engine, so he arranged a company trip to a demolition derby near Hollister. It was a great change of scene from Saratoga, where we had our office. I went with my girlfriend Evie (she married me anyway) and we had several other people from the office.

Since demo derbies are sporting events, they usually start with the National Anthem. In this case, there wasn’t a good flagpole at the site, so they got two bikini clad women on an ATV to drive back and forth in the ring holding the flag.

Besides enjoying the spectacle (which I now share with my family – the picture above is from our local fair’s derby last night), I liked looking over at Cowboy Dave, who watched enthralled. He had such a look of beatific joy.

Since this was a company event, we expensed it. Dave wrote it up as Inelastic Collision Field Research or some such thing. The concession stand wouldn’t give out receipts, which was irritating. I don’t know if Dave followed through on this or not, but at the time he threatened to staple empty plastic beer cups to the expense form.

Partly because of this experience, I’ve always tried to keep in mind the very human aspects of a job that can be dehumanizing. I try to ensure that places I work are fun. At my previous place, we had a slogan “work hard, play harder” which are great words to live by.

I’m Old, Part XIX: Really, I’m Old

Today is my 50th birthday and while 50 is probably less significant to me than anniversaries that are powers of 2 (or powers of 2 – 1), it’s nice to reflect on what I’ve seen.


When I was kid, my dad worked at Bell Labs as an electrical engineer. He brought home various devices at points including a TI calculator with an LED display that was fun to get it to have 7.734 x 1040 power on the display (or OH HEL.L when you flipped it over). I also remember an boat anchor of a computer that couldn’t do much, but it did have a cartridge that let you play craps on it.

One year before Christmas, we got to go into Bell Labs and look around. We saw my dad’s office and we also went into a machine room where they would run a stack of punch cards and print out a picture of Snoopy or a calendar on the immense line printer. The room was full of big cabinets of computing machinery, and I’m typing into a $350 laptop that has more computing power and more storage than likely everything in the US at that point in time.

Several people have commented to me on my ability to recall all the things in this blog in such detail. It’s a party trick. I don’t have a true photographic memory as I do have huge gaps, but what I do recall, I remember visually and to a lesser degree audibly, so I’m able to replay things in my mind with vivid detail.

So I can see that two guys from Bell Labs who visited our school when I was in 5th grade to introduce us to programming in FORTRAN. We wrote code on paper, it got put onto punch cards and then we got the output the next week. I don’t think I got anything to work. I didn’t really get it yet.

Next, my dad had picked up a Z-80 and some support chips. I don’t know what he had in mind for it, but he ended up giving to a kid who didn’t live far from us who was into this. I asked what it was, since to me it was just a chip with pins. “It’s a microprocessor.” “But what does it do?” And there’s the rub. The actual answer to that is “really not a whole lot; at least not on its own.” My dad had trouble answering the questions I was peppering him with.

In 1979, he bought an Apple II+ computer from a newly opened computer shop. The machine had 32K of RAM, ran at 1MHz, and came with a disk drive, which caught fire on the first day, relegating us to using a cassette tape. I coded on this machine for 6 years which went into college.

Overlapping this, my dad had brought home a TI Silent 700 terminal and we frequently dialed up Bell Labs where my brother had an account and played Adventure or Zork.

In high school, I had no access to the school’s computer, but I had an after school job at Bell Labs, so I used the department’s VAX 780 machines.

In college, I had access to their VAX 750 and 780 machines, as well as being able to use the brand new Macintosh. Compared to the Apple, the Mac ran at 8Mhz, had 128K of RAM, 400K storage on the floppy.

I’ve had various machines since then, but it’s been astounding in my career to actively ride the curve of Moore’s law on CPUs. Every big project, the capacity and speed of the next machine I used doubled.

We’re now seeing that happening with CPU cores, especially on smart phones. My last phone had 1 core. My current has 4 and is 32 bit. The market has 8 core 64 bit ARM chips. Neat! (and yes, I know, they are heterogeneous cores, but still).

Through all of this, I’ve done real world projects with 15 different programming languages. And through them I’ve seen a number of changes in language paradigms, some of which are useful and some of which are, well, not so good. They just seem to be trends like a fashion designer got a look at a Backus-Naur reference and added wide lapels to Java. Yet through this all, we’ve gotten much better at writing code and writing compilers (I still find a compiler bug here and there, but not as often as I used to). These improvements have created another barrier which came along when the size and scope of our projects increased. Managing complexity is a continuing and worsening problem as are build systems.

And though I’ve been doing this career for 33 non-contiguous years, it’s still a fascinating one with interesting problem spaces to be explored.

I’m Old, Part XVIII: Life Before Decent Libraries

One of the things that is very attractive about C is that it is a highly minimalist language. There is a fairly direct mapping from C to most machine architectures and it’s possible to do fairly decent abstractions if you put your mind to it.


Unfortunately, most of the support for any kind of higher level abstractions stop at the standard library and that doesn’t go too particularly deep. While I worked on Acrobat, I needed to make a set of Model objects to represent things UI elements behind the scenes (Model is the M in MVC).

I found that I often needed lists of things, so I made a pseudo list class that looked like this:

typedef struct t_genlist {
   t_genlist *next;
} t_genlist;

This is the kernel of structures that could be linked lists. To make a thing into a linked list, all you needed to do was embed a genlist as the first element in a struct. So if I needed to have a window that could be in a list, I would do something like this:

typedef struct t_window { /* not what I actually used */
   t_genlist list;
   Rect bounds;
   WindowPtr win;
} t_window;

And as long as that t_genlist is first, I could treat a t_window as a t_genlist. Now, I know that in OOP design, this represents a violation of “is a”/”has a”. A window should not be a list element. Instead of defining a list as having a generic void * and having to have the overhead of extra tiny objects fragmenting my heap and double the allocations, I decided to unify them. This also let me write the following code:

typedef void * (*forEachFunc)(t_genlist *list, void *cookie);
genListForEach(t_genlist *list, forEachFunc f, void *cookie)
    while (list) {
        void *result = f(list, cookie);
        if (result) return result;
        list = list->next;
    return null;

Which is a tiny iterator which could do things like this:

static void *windowMatch(t_genlist *list, void *cookie)
    return (WindowPtr)cookie == ((t_window *)list)->win ? list : 0;
t_window *FindWindow(t_window *winlist, WindowPtr macWin) {
    return (t_window *)genListForEach((t_genlist *)winlist, windowMatch, (void *)macWin);

In addition to for-each (which doubles as find), I had insert, remove, append, nth, count, and so on. I think I also had something that also worked as a fold, although I didn’t call it that.

This was a real workhorse that I used all over the place in the Acrobat search plug-in for the Mac as well as Catalog for the Mac. I used gen lists to represent UI items, windows layers, menus, search results, and so on.

Again, it was fantastic that C could create something so useful that compiled down to next to nothing. At the same time, C necessitated that you write this code again and again since there really wasn’t any kind of standard that I knew of at the time and there was also an unfortunate “not invented here” attitude that was rampant within the programming culture of the time. It happened so much that Nathan Graham likened it to being asked to wear someone else’s underwear. After all, you’re fully comfortable with your own and you know which pair have the holes and skid marks and you don’t want to go exploring to find out where those are in someone else’s underwear. Eww.

At this point, I’m happy to have C# List<T> and Linq at my disposal when I’m in C# land. I’ve never really liked the STL, but most of my distaste has to do with a nomenclature that I don’t like, which is again a case of “not my underwear.”