Anatomy of an Update

January 18, 2017

Anatomy of an Update

Back in late December, we released a firmware update for Sequencer 1, version 1.5.0. This was the eighth update in the last couple of years, and while it wasn't the most exciting update we've put out, a behind-the-scenes look will show some of the thought processes that go into these updates.

Firmware updates for the sequencer generally fall into two categories: big updates that contain exciting new features, and small updates which mostly fix bugs. We try to always add some small new feature to the latter sort. We figure that if you're going to go to the length of unracking your sequencer to update its firmware, it's far more fun if you get something new (even a small something) for your efforts. This update was of the latter sort: A couple of users had brought some defects to our attention via the Muff Wiggler forum, and while they weren't disastrous, they needed to be fixed.

There were three problems, as reported by our loyal users: 1) A pattern change brought on by an Action would always override a pattern change initiated by the panel buttons. Even worse, the LCD would lie, saying that the button-press pattern change would happen. 2) Ratcheted gate pulses didn't happen correctly when the sequencer was following an external clock signal. 3) In the previous update, we added a feature (in response to a previous suggestion from a user) which let accent, slide, and ratchet settings be edited in the same manner as gates, i.e. by clicking the step buttons. Unfortunately, in our excitement, we overlooked the problem that this new feature made it impossible to see the setting for the current step itself. Oops.

The pattern-change bug was easy. All that needed to be done was making a little addition to the code which does the Action-based switching. That addition just says, in essence, "if the user has requested a pattern change via the front panel, ignore the Action altogether." That's the nice sort of bug fix: simple, clean, nothing tricky.

The ratcheting bug wasn't so easy. Since the user reported that they were encountering the problem when using external clocking, naturally I started by looking for ways that the ratcheting code might be influenced by different clock sources. Nothing sprang out at me, so I patched stuff up and listened. Eventually I figured out that it wasn't just ratcheting that wasn't working; the length of the gate output wasn't changing correctly when the external clock changed. Seemingly nobody had noticed this, including us. I don't know when, exactly, that problem came to life, but it's possible that it was a mistake I made (back in version 1.4.2) when I added the code for the then-new feature which divides the input clock by a user-settable number. In any case, fixing that problem fixed the ratcheting problem, since the timing and duration of the ratchets are based on the duration of the gate output.

The third problem was perhaps the most interesting: it involved a design flaw, rather than a coding mistake. Design flaws are generally more interesting because they arise from our thought processes (or lack thereof) about how Sequencer 1 should behave. Coding mistakes are just that: they're sometimes nothing more than typos. David Zicarelli once said to me, "all bugs are typos." That overstates the point, but in some sense it's true in that coding errors represent a flawed translation from design to implementation, from the mental activity of thought to the physical activity of the machine controlled by the software one is writing.

The particular design flaw in this case was that there was no visual differentiation between which of the four parameters (gate, accent, slide, ratchet) was selected for editing, and the value of that parameter for the current step. (We probably overlooked this because we were so used to the way we'd originally designed the system and lived with it for the following 2.5 years. We should have caught it anyway.) After some thought, we decided to solve it by using different levels of brightness to indicate the value of the parameter, differentiating it from the value of the other parameters. Fortunately the LEDs are controlled by chips which provide a fine degree of control over brightness, so implementing this behavior was straightforward.

So, that did it for the bug fixing. For the small-something new feature, we added the ability for pattern Actions to switch to any of the 63 other patterns in the sequencer's memory. Someone had asked for this addition on Muff Wiggler, and--at first glance--it was fairly easy to add to the existing code. The funny twist was that, back when we were originally designing the Actions, we explicitly made the decision that it wasn't necessary to allow such changes. Our thinking was that Actions could be a little different than basic pattern chaining--a little more unpredictable, a little less run-of-the-mill. But there was no arguing with the notion that such behavior could be useful, particularly since someone had asked for it.

That funny twist introduced a complication: since we had made that decision, there was no place in the pattern data structure to save the number of the target pattern. This meant that the data structure had to change, which in turn meant that the file format for the patterns had to change, which in turn meant that the file-reading code had to be expanded to not only read the new format but also gracefully read all of the older formats since all such formats might be present on the user's memory card. This is all well-trod coding territory, but it was more than expected at the start.

Once that feature was written, the rest was routine: I handed the new firmware to Chris for initial testing. Once it met his approval he handed it to our testers. Meanwhile I updated the manual. The testers gave us a thumbs-up and Chris put it up for download on Christmas Day.