This application is a player for tracker music files ("module" files) as they were –and still are– common in the demoscene. With its fullscreen interface and limited interaction options, it's specifically targeted towards presenting tracked music in a competition ("compo") or for random background playback.
- based on libopenmpt, a very well-regarded library for module file playback
- plays all common formats: MOD, XM, IT, S3M, and a dozen others
- fullscreen interface based on OpenGL
- metadata display (title, artist, technical info, module comment, instrument and sample names) with smooth scrolling
- pattern display for visualization, including channel names (if present in the module file)
- optional custom logo in the background of the pattern display
- fake VU meters (based on note velocity and channel, not the actual audio samples)
- smooth fade out (triggered manually, automatically after looping, or after a configurable time)
- loudness normalization, with a built-in EBU R128 (a.k.a. ReplayGain 2.0) loudness analyzer
- many customization options
- configuration using INI files or an internal UI
- cross-platform (tested on Windows and Linux)
- single executable; no extra DLLs/
.so
s needed - open source (MIT license)
Just drag a module file onto the executable, or into the window once the player has already been started. If a directory is opened this way, the first playable file therein is loaded. Note that this is not recursive; TrackMeister won't play entire directory hierarchies. If no file is specified upfront, but there are playable files in the current directory when TrackMeister starts, the (lexicographically) first file is loaded.
The screen is split into three parts: The pattern display, the info bar at the top (containing basic information about the module format as well as filename, title and artist), and the metadata bar at the right (with the free-text module message, instrument and sample names). If the content doesn't fit in the metadata bar, it slowly scrolls down during playback, so it reaches the bottom end at the end of the track or after four minutes, whatever comes first.
If a module's filename starts with exactly two decimal digits, followed by a space, dash (-
) or underscore (_
), the digits will be removed from the filename display and shown as a "track number" in a much larger font in the info bar instead. This can be used to curate playlists by simply prefixing each filename with 01_
, 02_
and so on.
The following other controls are available:
Input | Action |
---|---|
Q or F10 | quit the application |
Esc | cancel current operation: - stops loudness scan if one is running, - pauses audio if it's playing, - quits the application after pressing twice otherwise |
Space | pause / continue playback |
Tab | show / hide the info and metadata bars |
Enter | show / hide the fake VU meters |
N | show / hide the channel name display |
Cursor Left / Right | seek backward / forward one order |
Page Up | load previous module in the directory |
Page Down | load next module in the directory |
Ctrl+Home | load first module in the directory |
Ctrl+End | load last module in the directory |
Mouse Wheel | manually scroll through the metadata bar (stops autoscrolling) |
A | stop / resume autoscrolling |
F | slowly fade out the song |
P | show the current track position in seconds (hold key to update continuously) |
V | show the TrackMeister and libopenmpt version numbers |
F1 | show or hide the help window |
F2 | show the global configuration dialog, or hide it if it's already visible |
F3 | show the file-specific configuration dialog, or hide it if it's already visible |
F5 | reload the current module and the application's configuration |
F11 | toggle fullscreen mode |
+ / - | adjust volume; this adjustment will not be saved (i.e. restarting TrackMeister will start with the default volume again); furthermore, making the sound louder can lead to audio distortion |
Ctrl+L | start (or cancel) EBU R128 loudness scan for the currently loaded module |
Ctrl+Shift+L | start EBU R128 loudness scan for the currently loaded module and all following modules in the current directory (this ignores shuffle mode; it's recommended to press Ctrl+Home first!) |
Ctrl+S | save the changed settings in the currently visible configuration dialog |
Ctrl+Shift+S | save tm_default.ini (see below) |
For directory navigation, "previous" and "next" refer to case-insensitive lexicographical ordering.
To use the loudness normalization feature, perform a loudness scan on the desired module(s); this will write a small .tm
file next to the module file that contains the measured EBU R128 loudness for the currently set up rendering parameters (i.e. filter, stereo separation etc.). The next time that module is loaded, TrackMeister picks up this loudness value and automatically computes a suitable gain to normalize the volume levels to a target of -18 LUFS. (The target can be adjusted with the target loudness
configuration setting.)
TrackMeister can be configured using configuration files with an INI-like syntax, either with an external text editor or the built-in configuration window.
The following aspects can be configured:
- display colors, font sizes and font
- font selection is limited to a few "baked-in" presets
- windowed/fullscreen mode and window size (*)
- audio sample rate and buffer size (*)
- audio interpolation filter
- amount of stereo separation
All items can be changed at runtime when loading a new module or pressing the F5 key, except those marked with an asterisk (*); these are only evaluated once on startup.
The configuration files can contain multiple sections, delimited by lines containing the section name in square brackets, [like so]
. The following sections are evaluated, and all other sections are ignored:
- global settings are loaded from ...
- the unnamed section at the beginning of the file
- sections called
[TrackMeister]
or[TM]
- file-specific settings are loaded from
sections that match the current module's file name, e.g.
[foo*.mod]
; the following rules apply for those:- only the filename is matched, no directory names
- matching is case-insensitive
- exactly one '
*
' may be used as a wildcard (no '?
's, no multiple '*
's)
The following files and sections are searched for configuration, in this order, line by line, with later options overriding earlier ones:
- global settings from
tm.ini
in the program's directory (i.e. directly next totm.exe
) - global settings from
tm.ini
in the currently opened module file's directory - file-specific settings from
tm.ini
in the program directory - file-specific settings from
tm.ini
in the module directory - any settings from a "sidecar" file with the same name as the currently opened module file, but with an extra suffix of
.tm
; for example, forfoo.mod
, the configuration file will befoo.mod.tm
- these are parsed like global settings (i.e. there's no need to have any section markers in the
.tm
files), but they are, of course, handled as file-specific settings
- these are parsed like global settings (i.e. there's no need to have any section markers in the
When saving changes made in the configuration UI (using the Ctrl+S shortcut, or the "Save" button at the bottom of the configuration window), global settings are saved to the tm.ini
file in the currently playing module file's directory if it exists, or the tm.ini
file in the program directory otherwise; file-specific settings are always saves to the .tm
sidecar file next to the currently playing module.
Saving the configuration from the UI always only updates the global sections of the file; file-specific settings from filename-matched sections in the global tm.ini
files are never modified by the UI.
In the configuration files, all lines that are neither empty nor section headers shall contain key-value pairs of the form "key = value
" or "key: value
". Spaces, dashes (-
) and underscores (_
) in key names are ignored. All parts of a line following a semicolon (;
) are ignored. It's allowed to put comments at the end of key/value lines.
To get a list of all possible settings, along with documentation and the default values for each setting, run TrackMeister normally and press Ctrl+Shift+S, or run tm --save-default-config
from a command line. This will generate a file tm_default.ini
in the current directory (usually the program directory) that also be used as a template for an individual configuration. Alternatively, the same information is provided as tooltips in the built-in configuration window that can be opened with the F2 or F3 keys.
All sizes (font sizes, margins etc.) are specified in 1/1000s of the display width, so they are more or less resolution-independent.
Boolean values can use any of the 1
/0
, false
/true
, yes
/no
or enabled
/disabled
nomenclatures.
Colors are specified in HTML/CSS-style hexadecimal RGB notation, but with optional alpha, i.e. in the form #rrggbb
, #rrggbbaa
, #rgb
or #rgba
.
Here's an example for a useful INI file as a compo organizer would set it up for hosting a competition:
[TM]
; generic options, specified in classic INI syntax
; when hosting an actual competition, we want to start playback manually
autoplay=disabled
; and we want fullscreen too!
fullscreen=yes
; if the track has a loop, we want to fade out automatically at this point
fade out after loop = true
[*.mod]
; this section is only active for MOD format files, which tend to be
; written with little stereo separation and no volume ramping in mind
stereo-separation: 20;
volume-ramping: 0;
[03*]
; the entry with the track number 3 in the filename has a loop;
; we want to play the loop, but fade out directly after it;
; the fade has been configured above already, now set up the loop:
loop: true
Note that in practice, the track-specific options would rather be written into the tm.ini
file in the directory where the entries reside, or the even into the .tm
file next to the module file itself, and maybe not into the "global" config file that's located next to tm.exe
.
Another example is this INI file for a typical "random module jukebox" setup:
[TM]
; play all files continuously in random order
autoplay = yes
auto advance = yes
shuffle = yes
; and in fullscreen, of course!
fullscreen = true
Options can also be specified on the command line, in the syntax "+key=value
" or "+key:value
". No extra spaces are allowed around the value. Command-line options take precedence over all configuration files.
Q: TrackMeister quits with an OpenGL error message or runs extremely slowly on Windows. What can I do?
A: This is most likely due to an improperly installed graphics driver. Windows Update automatically installs drivers, but those are often incomplete and sometimes lack OpenGL support. Please install the proper driver from AMD, Intel or NVidia, depending on your hardware.
Q: Can I run TrackMeister on a Raspberry Pi?
A: Turns out, you can! You will need a Raspberry Pi 4 or 5 and some magical incantations to run it, but it's possible. You need to paste the following line in a terminal:
export MESA_GL_VERSION_OVERRIDE=3.3 MESA_GLSL_VERSION_OVERRIDE=330
and then run TrackMeister from there (e.g. ./tm
).
Q: OK, so what do I need to do to host a demoparty competition with TrackMeister?
A: The most basic flow is as follows:
- Put
tm.exe
and the contestant's module files into a directory. - Create a
tm.ini
file with general options in the[TM]
section. The chapter above has a nice example to get started with. - Listen through the files (simply double-clicking
tm.exe
should suffice). Make mental or written notes about the play order as you want to have it in the compo. - Rename the module files by prepending exactly two digits with the running order number, followed by a space, underscore or dash. For example, if you want to play
pt.mod
at position 8 in the compo, it becomes08_pt.mod
,08 pt.mod
or08-pt.mod
. - Listen to the tracks again and configure track-specific options by pressing the F3 key to open the file-specific configuration window, making the desired changes, and pressing Ctrl+S to save them in the end.
Typical per-track options are:- If the track shall loop, set
loop = true
. If you also setfade out after loop = true
, the track will also fade out at this point. - If the track shall fade out at some position, set
fade out at =
to the number of seconds after which fading shall start (e.g.fade out at = 123
fades out after 123 seconds, i.e. 2 minutes and 3 seconds).- To determine the proper value, just pause playback at the position where you want the fade to start (using the Space key) and press the P key to display the position. The raw value in seconds can be directly used for the
fade out at
option.
- To determine the proper value, just pause playback at the position where you want the fade to start (using the Space key) and press the P key to display the position. The raw value in seconds can be directly used for the
- If the track shall be played in mono, set
stereo separation = 0
. - If the track shall be played with some volume ramping, set
volume ramping = -1
; if it shall not use ramping, setvolume ramping = 0
. - You can also override the track's title/artist metadata by setting it manually, e.g.
title = Professional Tracker
andartist = H0ffman feat. Daytripper
. - If the instrument/sample texts in the sidebar are utterly uninteresting, you can hide the sidebar completely with
meta enabled = false
. - In general, you can override almost every option that TrackMeister has! Custom colors per entry? No problem. Or even an image? Sure. Just scroll through the configuration window to see what can be done.
- Note that some option changes don't take place immediately after changing them in the UI, but require reloading the module to become active (F5 key). The status indicator left of each setting gets a difference color (and tooltip) in these cases.
- Do not set a per-track
gain
(volume) yet; we're going to use TrackMeister's assistance for that! - Don't forget to save the settings when done, using Ctrl+S! All changes file-specific settings are lost when changing the currently played track.
- If the track shall loop, set
- When done with the per-track configuration, navigate to track 1 and press Ctrl+Shift+L. This will start loudness measurement of the entire playlist. After restarting TrackMeister, the tracks should play a bit quieter on average, but without loudness jumps between tracks.
- If you really want to fine-tune the volume for each track, this is the time. Use the
gain =
option with the desired adjustment in decibels.
- If you really want to fine-tune the volume for each track, this is the time. Use the
- For the compo itself, make sure that the option
autoplay = false
is set, and thatauto advance
is not set (or set tofalse
too). - During the compo:
- Show the first entry's slide on the bigscreen. In the meantime, run
tm.exe
; it should start with entry #1 loaded, but in paused state. - Switch the bigscreen over to the TrackMeister computer and press Space to start playback.
- After the track is finished, switch over to the bigscreen again.
- While switching the bigscreen from entry #1's slide to entry #2, also press PageDown on TrackMeister to cue the next track.
- Switch the bigscreen over to the TrackMeister computer and press Space to start playback.
- Rinse and repeat.
- Show the first entry's slide on the bigscreen. In the meantime, run
- prerequisites:
- a C++17 compatible compiler (GCC 7.1 or later, Clang 6 or later, Microsoft Visual Studio 2019 or later)
- CMake 3.15 or later
- Python 3.8 or later
- SDL2 development packages (only required on non-Windows systems; on Windows, the SDL2 SDK will be downloaded automatically during building)
- make sure you cloned the repository recursively, as it pulls in a few libraries as submodules; if you forgot to do that, run "
git submodule update --init
" - building itself is done using standard CMake (e.g. "
cmake -S . -B build && cmake --build build
")
TrackMeister was written by Martin J. Fiedler a.k.a. KeyJ of TRBL. It is built upon the following third-party libraries:
- SDL 2 is the basic framework for window management, event handling and audio playback
- GLAD is used as the OpenGL interface generator
- MSDF is what TrackMeister's font rendering is based upon
- Inconsolata is the default vector font that's used in the UI and logo
- Iosevka is an alternate vector font that can be used
- LodePNG is used to decode PNG files
- libopenmpt is doing all the heavy lifting concerning module file parsing and audio rendering
- libebur128 is used for loudness normalization
- Dear ImGui handles the help and interactive configuration UI