Music - Bintracker: in search of the ideal tracker for creating beeper music

Bintracker
Bintracker: in search of the ideal tracker 
utz 

 In the beginning there was a beeper

   You probably already know that I have been
I work on music engines and wrote
there are quite a lot of them, mostly for one-bits─
beeperZX Spectrum,and also forAtari
2600, Dragon/CoCo, etc. It is clear that one thing─ 
the music engine is not enough - well─
wife is also an instrument for writing music
under it. Initially I solved this problem
using the conversion of music text from the fores─
mat XM  and wrote such converters. But what
the more powerful my engines became, the more they would─
is it more difficult, and converting from XM has become
uncomfortable. I wrote engine after engine, and not─
the engines used were simply accumulated for mo─
on the hard drive. Fortunately,Shirubegan
add some of them to1tracker,but
we soon encountered restrictions
1tracker. 
 But I still wanted to use these
engines, so at the end2016was born
plan. The plan was that I myself would...
I'm writing my tracker. I should have anyway
learn to program for real
(I, so to speak, got into assembly language with─
completely by accident a few years ago, and
I didn’t study programming at all before this─
nuyu), and here I would still have the opportunity
realize your vision of the “ideal” tre─
kera. But in my enthusiasm and naivety I
I didn't take two things into account. Firstly, my vision
the ideal tracker turned out to be quite foggy─
nym, to say the least. Secondly, I
clearly underestimated the amount of work. However, this
and not bad, otherwise I wouldn’t even have started!
   My idea of the "ideal" tracker looked like
something like this:
 1. The tracker should support without any problems─ 
create all types of music engines, through 
unified user interface. 
 2.The user interface should 
be simple and effective. 
 3. The editor must be powerful.
4.The editor itself should not be an ogre─ 
restrict the user, you can even allow 
"shoot yourself in the foot." 
   Needless to say, I was fascinated
the above-mentioned  1tracker, which forward─
recently implemented support for multiple engines
through the plugin mechanism. I wanted to continue
this concept, but cure some tests─
lems of1tracker itself.
 - Plugin for  1tracker - essentially bare 
implementation of the conversion code from the standard 
format .1tm  into a binary. This approach, co─ 
of course, flexible, but with such a system new 
plugins are difficult and tedious to write. This will be done─ 
takes a while to master on the part of engine authors. 
  -As I said, some of my engines 
require features that are not included in  1tracker. 
The tool editor is especially limited─ 
tov and lack of tables. 
  -Many exotic platforms, with which─ 
which I deal with cannot be supported 
in 1tracker, because it works through 
Game_Music_Emu. 
 - I certainly love minimalism, and in 
rejection of patterns in1trackersomething 
there is, but it cannot be denied that such a thing is necessary─ 
a simple approach can scare off a lot of people. 
this, as well as the lack of mouse support. 
   To solve the first problem, I came up with 
MDAL  (Music Data Abstraction Language - 
music data abstraction language).MDAL
defines two standards calledMMOD  and MDEF . MMOD - standardized 
music module format. This is, in essence,
text representation of the tracker module,
like .vt2 in Vortex Tracker or .1tm
in  1tracker, but with some ideas from
musical notations likeMML.What about─
is MDEF, then this is the format for describing the config─
walkie-talkies for a specific music engine.
It indicates which elementsMMOD are used─
are in place and how the output data will be constructed─
new Pay attention to a couple of important ones from─
lichen  First, the files MDEF describe 
configuration,and not code, like.1teplugins 
for 1tracker. Secondly, filesMDEFeven
do not describe the  algorithm  conversion to binary─
nickname The algorithm must be completely contained
in the universal compilerMDAL.
 So, the next step was to write─
Get this magical compiler. And so do I
did, and I really succeeded in knowing
to a considerable extent to carry out the plan.
Then I wrote a graphical interface for it─
face, which became the prototypeBintracker
(now, of course, it is outdated). This proto─
the type wasC++,contained a custom emulator─
torusZX Spectrumand custom view set─
user interface elements, reali─
called withAllegro.Some even
wrote some great 1-bit tracks in it!
However, it soon became obvious that
its design had serious flaws.
   It was simply unrealistic to write custom─
new emulators for all platforms that I
wanted to support. User Inter─
face took too much time at a time─
work and at the same time was buggy. But the most important part─
However, it became clear that the compilerMDAL
I couldn't seesupport even half of mine
own engines, not to mention others. And
in general, by that time I was already dissatisfied
that basic implementation of the tracker, my view─
the concept of the “ideal tracker” has changed greatly─
elk, and the current implementation is not even close
would come close to this.

Second attempt

   I put the project aside for a while, and then...
preparing for the inevitable: rewriting everything─
go from scratch. I've already been sucked into the rabbit hole
hole of (modern) programming, and I
started looking at other languages besides 
C/C++. And so, in the winter  2017/2018  I sat in 
some wilderness without access to the Internet
and tinkered with Nyquist,mysterious descendant 
Lispwhich is used as a script 
language in the audio editorAudacity.
 Having almost no documentation, I couldn’t─
nothing to understand, but was fascinated by the syntax,
which was very different from everything I
seen before. I should have stopped at
this. But I focused instead on
the idea that the compilerMDAL mechanism needed
scenarios to compensate for what is not
can be solved with a configuration file. Excess─
don't say that script writing is the language─
I was supposed to becomeLisp.In the end I
settled on the dialectof Lisp,which is lu─
best suits me as a minimalist: 
Scheme. 
   When I was fiddling with rewriting com─
epilator MDAL about six months, I understood two
things: 1. interpreterScheme,which I
planned to implement, did not fit well with
object model C++, and, more importantly, 
2.writing a compiler and tracker inC++ 
It will simply take too long. So
that I took a deep breath, threw away these six
months of coding and started again, rewriting
the entire project is onScheme.Back to the beginning─
lu, in a little over a month and by 1/10 volume─
ema code I was sure that I was on the right
ways.
   Howmentioned earlier, my vision
the "ideal" tracker has evolved, and according to
as I progressed it should have
develop further. It's still changing
por. The prototypeBintrackerproved that the general
the idea of supporting various sound engines
in a single interface was viable,
so that part of the concept remained.
Ideas about interface design and
defining what a “powerful” editor is─
ctor As for the interface, I never
I especially didn’t like that you couldn’t write without
patterns, but I still wanted to do
Bintracker  available for composers 
accustomed to the traditional approach with patte─
rnami and warrant.
   Therefore, Bintracker  must be under─
keep both approaches.I also came to you─
water that ultimately none of these
will not completely solve the problem, namely: the order
annoying because it makes the musician─
to interrupt the creative flow in order to
deal with technical details. On the other hand
hand, in the absence of a warrant it is more difficult to
determine the general structure of the work. Bye
these problems have not been solved, I think it’s worth pro─
continue experimenting with the tracker interface─
catfish AndBintrackershouldprovide in─
opportunity for such experiments.
   Regarding "power", the main stone
plugins became a stumbling block. Not plugins
sense of sound engine plugins, and plugins─
us for the tracker itself. Plugin Interface
should allow you to save the kernelBintracker
quite compact, but unlimited
expand it with new and sophisticated functions─
tions. Do you want graphic editing with
piano roll and envelopes? Do you want the library─
ku for storing fragments of melodies and music─
swarms of tools? What about the controls?
projects with version control so that you can
was to roll back to the previous version, not
digging through a bunch of backup files? Or
what about live online collaboration? I
I think that a powerful chiptune editor should
support such things.
   Another thing I often stay on is
poured in. We basically perceive three─
ker as a kind of electronic editor
tables for music, so we think about but─
tah, patterns and order as data. Od─
However, we can think of them as scripts:
list of instructions that are executed by mu─
musical engine (for example, "play note 
X for Y ticks" ). In this sense, three─ 
kers become the medium of audiovisual
programming.Writing music in tr─
Kere is programming. Many powerful
programming languages have the ability to
which is called metaprogramming.
Instead of writing the code itself, in meta─
in programming you write code that
writes code. The question is, how does this relate to the
writing music?
   I think it's an open question for now,
one of the possible answers to this is
algorithmic composition. Algorithmics─
which composition is not particularly popular among
eight-bit composers, but she became─
is becoming increasingly popular in the wider community─
versity of hackers. So algorithm support─
ical composition in Bintracker can introduce─
you bring a fresh stream into the scene, and it should be
good.Bintrackercan also benefit from
this, because people doing algo─
rhythmic composition, they usually know how to
to gram and may be interested in
programming theBintracker itself,if not
The transition will be quite smooth. So,
in essence,Bintrackershould be "hackable"
"em".

 Sounds great, but how?

   Let's talk briefly about technologies and stack
technologies used inBintracker.
 The most interesting technology is, of course─
Of course, the compilerMDAL,which generates─
This is the result from the engine description in the format 
MDEF  and a module in the formatMMOD.Because 
data structures of existing and future
sound engines vary greatly, the main thing is
The main task was to create a common
abstraction that could represent
all varieties. The details are still being finalized─
exist, but the overall structure has already become stable─
line. MDEF  consists of three main elements─
ments: input nodes, output nodes and commands.
Input nodes define the input format pattern─
mat MMOD. There are 3 types of input nodes:
groups, fields and blocks.Field - the main unit─
value representing a single value
any type.Blocks - two-dimensional mass─
sow fields. A block can represent such
structures such as patterns, orders, tables
or samples.Group - recursive structure─
ra, it can contain fields,blocks and others─
gee groups. This allows you to create vlo─
related structures, for example,Module -> Song 
-> Patterns. By default, nodes can have 
unlimited number of copies, cro─
me groups that are always unique. All included─
These nodes  MDEF are parts of the implicit
global node (group), forming a tree.
   Field types are determined by commands. Yes
several types of commands: String (use─
is used to represent title type texts
and the author of the composition), Trigger (uses─
for reel type events by clicking in
engine Huby or launching the envelope in SID ), 
Reference (numeric reference to another group─ 
pu, for example, on a pattern in an order or ins─
trument in the pattern), Label (used
to indicate the location in the block instance, on─
example, loop point), Int  and Uint
(signed and unsigned integer arbitrary─
size, can also store logical
values), as well asKeyandUkey,representing─
containing signed and unsigned key pairs,
meaning. TheKey andUkey commands can have
associated commandsModifierwhich
contain an arithmetic operator and integers─
measured value corresponding to the range─
Well, the command values Key / Ukey. Please note
Please note that there is no "note" type: notes descriptions─
are available through typeUkey,possibly with modification─
Cators for implementing detuning.MDAL
usually doesn't care about the function of the command or
input node, he only cares about his ti─
ne. However, commands and input nodes may
have an arbitrary number of flags, and
this mechanism, for example, can communicate
Bintracker,should be considered by─ 
le with the command  Ukey  likenote or something
more. The entire tree of input nodes is contained in
implicit global node.
   The astute reader may have replaced─
til I didn't talk much about the warrant when
mentioned input nodes. Entry order
is given implicitly, its definition is created
automatically by the compilerMDAL (it can be
configure to enable additional
fields for transposition and the like─
noe). The entry order is always matri─
purpose: each channel/track in a block has
a separate track in the order, and stalemate numbers─
turns in different channels do not intersect.
Since input blocks by definition
have unlimited length, the order also
contains a track of length that is set─
determines the length of each step. Besides this, op─
der - also a regular input node like
"block".
   The input nodes are sparse, that is, instance
Node lars are not created until they are completed
will achieve, and instances of nodes, the meaning of which─
Some are not installed by the user, have
value NULL.What happens when you turn─
connection to such a non-existent node depends
from the requester, the node type and, in
case of fields, depending on the type of command. For T nodes─
pa "group" and "block", if the requested ek─
node instance does not exist, it is created and
initialized as empty. This way─
zom when the user enters the phone number─turn, which is not in the order, then this stalemate─
the turn is automatically created as a new pot─
stop knot. When the user then enters─
dit, say, a note in the eighth line, eczema─
fields of fields up to and including line 8 cos─
are given and set toNULL,and in the field,
which I just edited favorably─
operator, what he entered is recorded. Kog─
yes, the compiler requests the block field, but
which has the valueNULL,it depends on
field commands: either the reverse will be performed─
new tracing to find the last whisker─
the given value, or there will be a value
default.
   Output nodes are somewhat more complicated. In the present─
There are currently 6 types of output nodes. 
Osymbols  work like labels in assembler 
that is, they either take the value of the current
addresses are either explicitly assigned.Ofields -
single integer values of arbitrary
size.Oblocks - block data arrays,
equivalent to input blocks. They consist
from Ofields.Ogroups contain Oblocks  and 
Ofields.They can generate orders 
which, in turn, are used by bonds─
lami  Oorder to create the actual order─
dera. Finally, the Oasm nodes represent co─
fight bare assembly code. For example, in
such a node may contain the player code.
CompilerMDALintegrates with assembly─
rum, that is, the assembler can see the definition
dividing level symbolsMDAL,andMDALcan
keep track of the current address in assembler.
Oasm  nodes can be completely pre─
strictly assembled (that is, the output
code is created in advance) or can be used─
write partially evaluated expressions if
assembly code depends on symbols, op─
allocated at the levelMDAL.
 From these definitions, the compiler MDAL co─
creates a parser that
reads modules.mmod into the internal pre─setting and generating the compiler, specifics─
appropriate for this configuration MDEF. Therefore
compilerMDAL - this is actually not the case─
compiler, and the compiler is a compiler. Ispo─
Using a custom compiler speeds up
compilationMMOD.According to the general concept, the structure
The input structure is completely virtual and can
be designed as a logical representation─
deletion of module elements, and not in accordance─
vii with the output structure. Thus,
usually separate blocks are assigned for each
channel, even if in the output structure
combined patterns from
all channels, and will not install
fixed length for input blocks,
even if the output nodes must be fixed─
fixed length - except when it is
important (wave tables come to mind).
   When it comes to the tech stack, many
from the fantasy wish list items
from the previous section, drones became possible
Thanks to the languageSchemeand its used re─
implementations: Chicken Scheme . Chicken Scheme
can work both as an interpreter and as
compiler (with a powerful external interface
functions forinteraction with code in C ).
This means that time-critical parts
kernels can be accelerated by compilation, and
extensions are interpreted, and for them
startup does not require recompilation.
Having built the interpreter intoBintracker,we
gained the ability to metaprogram
practically free. And this does not apply
only for creating music: all Bintracker
can be programmed at runtime.
In factBintrackeris not a tracker.
This is an interpreter for the language Scheme,which
launches the tracker application.
   Since it was clear that writing
emulators for each supported board─
forms are not the point, it was planned to use
callMAME as the server part of the emulation,
with the ability to support other emulators
later. So far, MAMEhas a pretty bad reputation─
tion regarding the accuracy of the emulation, but how
I think the situation has improved significantly over the past
recent years, and emulation of many questions─
damaged platforms are now not inferior to special ones─
socialized emulators.
   Any programmer who has everdealt with native interface development─
tkoy knows that all GUI libraries are from─
wait. In the end I settled on the one
which for me sucks the least.
She's almost as old as our favorites
8-bit machines, written in a language that
even weirder thanScheme,but it almost works
everywhere, and it's called "Tk". Yes, I know:
now at least half of you, respect─
self-proclaimed programmers are probably running around
with screams. The rest probably can’t stand it─
Please see the source code.

 Current state and future of Bintracker

   The last two years have been serious for me─
a significant test, since I am constantly ra─
I'm working on this project without having the opportunity─
you have nothing to show. Fortunately, it's now
things are getting better. I've released the source code
at the end of May, so you can take a chance on─
try Bintracker in its current, early
alpha stages. Until then you have to do it yourself
compile and you're probably better off
have for this Linux (but WSL2 should also
work). Although by the time you leave─
children this number Info Guide,I may
I'll get to creating assembliesunderWindows.This
one of the first points in my plan. In love─
In any case, at the momentBintracker
comes with several different engines─
mi under the Spectrum beeper, and also nearby
engines for more exotic platforms. B
I'm currently working on support
Atari 2600,which means that later I can switch to 
to many other platforms based on 6502.
Metaprogramming is fully implemented─
tew, although somewhat awkward, in the term─
le interpreterScheme.Not already available─
how many examples of simple plugins.
   There are still a few important details missing─
lei. Compiler  MDAL  does not optimize yet
output data, that is, the bi created by it
Nar files are longer than they could be.
Something is missing in the implementationMDAL,
which limits the set of sound engines,
which at this stage can support
Bintracker. Another detail that is not 
enough, regarding the order: support now─
onlyorder in the form of a matrix (by
pattern for each channel, and for all sra─
zu, as inXMorVortex Tracker ). I'm planning─
It is possible to implement two levels of abstraction
top: mode with a single order and mode without
orders (like 1tracker ). Moreover, how
mentioned above, not executable yet
assemblies. And, of course, there is much more in the program
glitches. As soon as I deal with them, you─
The official beta version is running. According to my races─
I guess it will probably happen later
in the fall.
   In the meantime, check out the project at 
https://bintracker.org.There you can also─ 
please subscribe to our newsletter about
Bintracker, if you want to receive the latest 
news about the project.

Share your thoughts about the article