A small XM (Fasttracker II Extended Module) player library. Main features:
-
Small and hackable: many features can be disabled at compile-time, or are optimized out by the compiler if not used. It is easy to bundle libxm in your game, demo, intro, etc.
-
Fairly portable. Minimal dependencies (just libm). No memory allocations. Big-endian compatible (tested on s390x).
-
Reasonable accuracy compared to Fasttracker 2. Deviations from FT2 playback, that aren't obviously bugs in FT2, are also libxm bugs.
-
Can load most XM/MOD files, however playback accuracy of non-XM is best-effort.
-
Timing functions for synchronising against specific instruments, samples or channels.
-
Samples can be loaded and altered at run-time, making it possible to use libxm with softsynths or other real-time signal processors.
Written in C23 and released under the WTFPL license, version 2.
-
Build the library:
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -Bbuild -Ssrc make -C build
-
Build a specific example:
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -Bbuild-FOO -Sexamples/FOO make -C build-FOO
-
To build a shared library and link dynamically, use
cmake -DBUILD_SHARED_LIBS=ON
. -
To see a list of build options, use
cmake -L
orcmake-gui
. -
To use libxm in your program, put these lines in the
CMakeLists.txt
of your project, then#include <xm.h>
:add_subdirectory(/path/to/libxm/src libxm_build) target_link_libraries(my_stuff PRIVATE xm)
libxmtoau
can be compiled (with all playback features enabled) and
crushed to about 4081 bytes (Linux
x86_64).
cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DXM_VERBOSE=OFF -DXM_LIBXM_DELTA_SAMPLES=OFF -DXM_LINEAR_INTERPOLATION=OFF -DXM_RAMPING=OFF -DXM_STRINGS=OFF -DXM_TIMING_FUNCTIONS=OFF -DXM_SAMPLE_TYPE=float -Bbuild-libxmize -Sexamples/libxmize
make -C build-libxmize libxmtoau
strip -R .eh_frame_hdr -R .eh_frame build-libxmize/libxmtoau
xzcrush build-libxmize/libxmtoau
If you are using libxm to play a single module (like in a demo/intro), disable
features as suggested by libxmize
to save a few more bytes.
-
libxm.js is a very simple XM player/visualiser that runs in a browser (emscripten port).
-
xmgl
is a simple music visualiser that uses OpenGL, GLFW and JACK for very precise audio synchronisation. See a demo here: https://www.youtube.com/watch?v=SR-fSa7J698 -
xmprocdemo
: a simple non-interactive demo that plays back a single module with procedurally generated samples. Somewhat optimized for size. (Dream Candy by Drozerix, public domain. Thank you Drozerix for the great music!) -
libxmize
converts a.xm
module to the libxm format. It is highly non-portable and is meant for static linking and sizecoding (loading code is much shorter and libxm format compresses better). -
libxmtoau
reads standard input (a file generated bylibxmize
) and writes a .AU file to standard output. Somewhat optimized for size, see size section above. You can test it with, for example,libxmize file.xm | libxmtoau | mpv -
.
Here are some interesting modules, most showcase unusual or advanced tracking techniques (and thus are a good indicator of a player's accuracy):
- Cerror - Expatarimental
- Lamb - Among the stars
- Raina - Cyberculosis
- Raina - Slumberjack
- Strobe - One for all
- Strobe - Paralysicical death
See GitHub issues.
Some test XM files are in the tests
directory. Their goal is to test
a certain feature against regressions.
A few tests can be automatically run:
cmake -Bbuild-tests -Stests
make -C build-tests all test
Other tests require manual checking, see the table below.
Test | Status | Tested against | Extras
-------------------------------+----------------+------------------------+------------------------------------------------
autovibrato-turnoff.xm | PASS | MilkyTracker | Same pitches should be heard twice in a row.
multiretrig-volume.xm | PASS | FT2, OpenMPT | Should sound identical.
panning-law.xm | PASS | MilkyTracker, FT2clone | Should sound identical.
pattern-loop-quirk.xm | PASS | MilkyTracker | Should play the same notes at the same time.
pos_jump.xm | PASS | Milkytracker, OpenMPT | Only one beep should be heard.
ramping.xm | PASS | MilkyTracker | If XM_RAMPING is ON, no loud clicks should be heard.
ramping2.xm | PASS | MilkyTracker | If XM_RAMPING is ON, no loud clicks should be heard.
retrig-vol-fade.xm | PASS | MT, FT2clone, OpenMPT | Should sound identical.
tone-portamento.xm | PASS | MilkyTracker | Should sound identical.
Thanks to:
-
Thunder kurttt@sfu.ca, for writing the
modfil10.txt
file; -
Matti "ccr" Hamalainen ccr@tnsp.org, for writing the
xm-form.txt
file; -
Mr.H of Triton and Guru and Alfred of Sahara Surfers, for writing the specification of XM 1.04 files;
-
All the MilkyTracker contributors, for the thorough documentation of effects;
-
Vladimir Kameñar, for writing
The Unofficial XM File Format Specification
; -
All the people that helped on
#milkytracker
IRC; -
All the libxm contributors.