Skip to content

Getting Started with Bintracker Development


As Bintracker is written in the Scheme programming language, you will need some understanding of Scheme or another Lisp-like language. Although Scheme's syntax is very different from other programming languages, it is very easy to learn. Even a basic understanding is enough to start running some simple code in Bintracker's REPL or tweaking configs/config.scm.

If you plan on writing more than a few lines of code for Bintracker, you should consider using an editor with a structured editing mode. Vim, Atom, and VS Code all support something akin to Emacs' paredit.

Reading the Source

If this is your first time working with Scheme or another language from the Lisp family, reading the Bintracker source code can seem a bit intimidating. This section gives some general hints on how to find your way around in the Bintracker source.

  1. There are no header files, as you might be used to when coming from C or C++. However, the compiler generates various header-like files during compilation. Any .scm files in the source tree whose name contains more than one dot are auto-generated, you usually can ignore those.

  2. There is no explicit main. The top level source file is bintracker.scm, which recursively depends on all other files in the source tree.

  3. Bintracker is split into several core components.

  4. Read source files from the bottom. When writing Scheme code, the most high-level abstractions often end up near the bottom of the file.

  5. Namespace management: In Chicken Scheme, Modules are the main means of managing namespaces. Each source file in the main source directory and the libmdal sub-directory contains a single module.

  6. There is a hierarchy of modules: libmdal/mdal.scm is the meta-module of all libmdal modules, and bintracker-core.scm is the top-level meta-module of Bintracker, which re-exports all bindings that will be visible to user code at runtime. To find out what a given module depends on, look for (import ...) statements near the top of an .scm file. If you don't find a module mentioned in an import statement in the source tree, then it is probably a 3rd party extension.

  7. After startup, Bintracker is controlled by the Tcl/Tk interpreter. There is no Tcl code involved, however. Bintracker uses pstk to interface with Tcl/Tk. The relevant GUI code resides in bt-gui.scm.

  8. While libmdal is mostly purely functional, other parts of Bintracker are not. Most GUI abstractions use the coops object orientation extension, and closures are frequently used to wrap state. The bt-state module handles global state in Bintracker.


Core Components


bintracker-core comprises the main application.


Libmdal is an implementation of the Music Data Abstraction Language. It covers all parts related to the handling of music modules. Libmdal is a compiler generator: Given a MDEF engine definition, it generates a compiler that can transform a suitable MMOD into binary output.


Schemta is Bintracker's assembler. It is integrated into libmdal but can also be built as a stand-alone executable.


PEG parsing, comparse/parsec object-orientation: coops multithreading model: srfi-18

In addition to the core and the libmdal API, the following procedures and APIs are available:

Useful Resources

Scheme Language

Chicken Scheme

  • Manual
  • Wiki
  • Chicken API, a search engine for the official Chicken Scheme documentation. Use this as reference for all Scheme and Chicken-related topics.