A small XM (FastTracker II Extended Module) player library. Main features:
-
Small size in mind; many features can be disabled at compile-time, or are optimized out by the compiler if not used.
-
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.
-
Should be fairly portable (only dependency is
libm
). Big-endian compatible (tested on s390x). The example programs mostly target Linux.
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 4128 bytes (Linux
x86_64).
cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DXM_DEFENSIVE=OFF -DXM_LIBXM_DELTA_SAMPLES=OFF -DXM_LINEAR_INTERPOLATION=OFF -DXM_RAMPING=OFF -DXM_STRINGS=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.
finetune.xm | PASS | MilkyTracker | Left and right channels should sound identical.
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.