06 Jun 2021
Wow, it’s actually been over half a year since the last update. My sincere apologies for the long silence. Not only did the break I announced last time take longer than planned, thanks to a few unexpected side projects. It also turns out that getting our new homestead up and running takes up even more time than expected. Nevertheless, Bintracker is alive and kicking, and I’ve been making good progress in what little time I can spare.
Before we go any further, it’s time for a big shout-out to radian, who passed a sizeable donation my way a while back. Thanks a lot, mate!
A lot of the recent work has been focussed on improving stability and usability. A great many bugs were squashed, including a particularly nasty one that prevented spinboxes (those little selector widgets used to set the edit step, base octave etc.) from working properly. I’ve struggled with that one for almost a year. I’ve also made some minor tweaks to the GUI, and made the default key bindings a bit more intuitive.
Furthermore, MAME version 0.227 introduced breaking changes to the LUA engine. This affected emulation in Bintracker, since it relies on the LUA engine to control MAME (thanks Jeremy Penner for reporting this). While implementing a work-around that ensures compatibility with both old and new versions of MAME, I also improved the rest of the MAME bridge at bit. There’s still more work to be done, but at least I got rid of most of the audio glitches that where quite common until now.
Now for some big news: Support for unordered Groups is done. That means Bintracker can now handle things like effect tables, ornaments, samples, and wavetables. This was one of the biggest missing building blocks needed to complete the Bintracker core application. It was quite a tough nut to crack, but in the end I found a rather elegant solution that required just a few hundred lines of code. Long-winded explanation follows, feel free to skip ahead to the end of this section if you aren’t interested in the gory details.
Bintracker’s MDAL backend treats any kind of repeating structure (eg. patterns, tables, samples) as a Group node with one or more Block members. A Group may be ordered or unordered, in other words, a Group’s Block members may or may not be sequenced. Ordered Groups use an additional block member to control the order of the remaining block instances. A typical MDAL engine definition will have an ordered Group for (note) patterns, where each block member represents a channel/track, and the Order block represents the sequence/order list. But what does it even mean for a Group to be unordered?
One possible use case would be samples, which can be realized as an unordered Group with a single Block member holding the sample data. In theory, this Group does not need an order list, because we just want each sample added once to the output. However, Block instances in MDAL are either endless, or have a fixed length. So in practice our Group does need an Order block, to specify the length of the sample block instances. It is even conceivable (if slightly uncommon) that users would use the same sample twice, with different lengths.
This led me to the realization that the easiest way of implementing unordered Groups is to treat them exactly like ordered Groups, as far as input is concerned. As the old saying goes, the best code is no code. The only part of MDAL for which ordered-ness matters is the compiler, which can skip generating output orders for unordered Groups. Also, there are some corner cases that affect the Bintracker GUI. For example, editing should be disabled for the order of a Group containing a single, fixed-length Block member (think fixed length wavetables).
In its current form, sample/wavetable support is rather minimal. There are no graphical editing capabilities yet, Bintracker just shows plain numbers for everything. The plan is to keep extended GUI features such as plotting/drawing samples out of the main application, and implement them as plug-ins instead. I would love to start working on this, but there are some more pressing issues, see below. I might do PCM WAV import though, since we already have a resampler in MDAL. In any case, I modified the wiz4v engine to use user-definable wavetables, so give that a try if you’re already running Bintracker.
Long story short, all of this means that we’re down to one major task that needs to be done before the beta release. That task is implementing support for Label commands. Label commands are needed to implement loop points, for example. I already implemented the GUI part of this, and am now in the middle of tackling the backend part. Now, don’t hit me, but I’m actually going to rewrite the compiler once more. The current implementation has grown somewhat organically, to the point where it has become quite a mess. The compiler solves a complex task, so some complexity in the code is to be expected. However, by now even I have problems understanding my own code, which is a clear sign that I should clean this up before bolting on even more functionality. A rewrite will also allow me to address a few other issues along the way. For example, references are currently resolved immediately. This has two problems. First, it means the compiler cannot resolve forward references. Second, it cannot count references, which is something the optimizer will require. Speaking of which, I’ll probably also implement a simple optimizer while I’m at it. I need to touch all the relevant parts of the code anyway, and I have some ideas as to how it can be done with little extra effort.
Once the compiler rewrite is done and Label commands are implemented, it’s time to prepare for the beta release. I finally got around to replacing my development machine’s semi-broken Gentoo installation with a shiny, up-to-date Void Linux one. This should clear the road towards setting up all the tools that are required for building releases. Nevertheless, I’m expecting this to be rather challenging work. The main obstacle here will be providing builds for Windows. Anybody out there willing to help with this, please get in touch! Just reply to this newsletter, or open an issue on Github if you prefer.