Libxmp 4.5 API Guide for Developers
Libxmp 4.5 API Guide for Developers
5 API documentation
1
Contents
Introduction 4
Concepts 4
A simple example 4
SDL example 5
API reference 7
Version and player information 7
const char *xmp_version 7
const unsigned int xmp_vercode 7
int xmp_syserrno() 7
const char *const *xmp_get_format_list() 7
Context creation 7
xmp_context xmp_create_context() 7
void xmp_free_context(xmp_context c) 7
Module loading 7
int xmp_test_module(char *path, struct xmp_test_info *test_info) 7
int xmp_test_module_from_memory(const void *mem, long size, struct xmp_test_info *test_info) 8
int xmp_test_module_from_file(FILE *f, struct xmp_test_info *test_info) 8
int xmp_test_module_from_callbacks(void *priv, struct xmp_callbacks callbacks, struct 9
xmp_test_info *test_info)
int xmp_load_module(xmp_context c, char *path) 9
int xmp_load_module_from_memory(xmp_context c, const void *mem, long size) 9
int xmp_load_module_from_file(xmp_context c, FILE *f, long size) 10
int xmp_load_module_from_callbacks(xmp_context c, void *priv, struct xmp_callbacks callbacks) 10
void xmp_release_module(xmp_context c) 10
void xmp_scan_module(xmp_context c) 11
void xmp_get_module_info(xmp_context c, struct xmp_module_info *info) 11
Module playing 12
int xmp_start_player(xmp_context c, int rate, int format) 12
int xmp_play_frame(xmp_context c) 12
int xmp_play_buffer(xmp_context c, void *buffer, int size, int loop) 12
void xmp_get_frame_info(xmp_context c, struct xmp_frame_info *info) 12
void xmp_end_player(xmp_context c) 13
Player control 14
int xmp_next_position(xmp_context c) 14
int xmp_prev_position(xmp_context c) 14
int xmp_set_position(xmp_context c, int pos) 14
int xmp_set_row(xmp_context c, int row) 14
int xmp_set_tempo_factor(xmp_context c, double val) 14
void xmp_stop_module(xmp_context c) 15
void xmp_restart_module(xmp_context c) 15
int xmp_seek_time(xmp_context c, int time) 15
int xmp_channel_mute(xmp_context c, int chn, int status) 15
int xmp_channel_vol(xmp_context c, int chn, int vol) 15
void xmp_inject_event(xmp_context c, int chn, struct xmp_event *event) 15
Player parameter setting 17
int xmp_set_instrument_path(xmp_context c, char *path) 17
int xmp_get_player(xmp_context c, int param) 17
int xmp_set_player(xmp_context c, int param, int val) 18
External sample mixer API 20
Example 20
SMIX API reference 21
int xmp_start_smix(xmp_context c, int nch, int nsmp) 21
int xmp_smix_play_instrument(xmp_context c, int ins, int note, int vol, int chn) 21
2
int xmp_smix_play_sample(xmp_context c, int ins, int vol, int chn) 22
int xmp_smix_channel_pan(xmp_context c, int chn, int pan) 22
int xmp_smix_load_sample(xmp_context c, int num, char *path) 22
int xmp_smix_release_sample(xmp_context c, int num) 22
void xmp_end_smix(xmp_context c) 23
3
Introduction
Libxmp is a module player library supporting many mainstream and obscure module formats including Protracker
MOD, Scream Tracker III S3M and Impulse Tracker IT. Libxmp loads the module and renders the sound as linear
PCM samples in a buffer at rate and format specified by the user, one frame at a time (standard modules usually
play at 50 frames per second).
Possible applications for libxmp include stand-alone module players, module player plugins for other players,
module information extractors, background music replayers for games and other applications, module-to-mp3
renderers, etc.
Concepts
• Player context: Most libxmp functions require a handle that identifies the module player context. Each context
is independent and multiple contexts can be defined simultaneously.
• Sequence: Each group of positions in the order list that loops over itself, also known as “subsong”. Most
modules have only one sequence, but some modules, especially modules used in games can have multiple
sequences. “Hidden patterns” outside the main song are also listed as extra sequences, certain module
authors such as Skaven commonly place extra patterns at the end of the module.
• State: [Added in libxmp 4.2] The player can be in one of three possible states: unloaded, loaded, or playing.
The player is in unloaded state after context creation, changing to other states when a module is loaded or
played.
• External sample mixer: [Added in libxmp 4.2] Special sound channels can be reserved using
xmp_start_smix() to play module instruments or external samples. This is useful when libxmp is used to
provide background music to games or other applications where sound effects can be played in response to
events or user actions
• Amiga mixer: [Added in libxmp 4.4] Certain formats may use special mixers modeled after the original
hardware used to play the format, providing more realistic sound at the expense of CPU usage. Currently
Amiga formats such as Protracker can use a mixer modeled after the Amiga 500, with or without the led filter.
A simple example
This example loads a module, plays it at 44.1kHz and writes it to a raw sound file:
#include <stdio.h>
#include <stdlib.h>
#include <xmp.h>
4
exit(EXIT_FAILURE);
}
fclose(f);
exit(EXIT_SUCCESS);
}
A player context can load and play a single module at a time. Multiple contexts can be defined if needed.
Use xmp_test_module() to check if the file is a valid module and retrieve the module name and type. Use
xmp_load_module() to load the module to memory. These two calls return 0 on success or <0 in case of error. Error
codes are:
Parameters to xmp_start_player() are the sampling rate (up to 48kHz) and a bitmapped integer holding one or more
of the following mixer flags:
After xmp_start_player() is called, each call to xmp_play_frame() will render an audio frame. Call
xmp_get_frame_info() to retrieve the buffer address and size. xmp_play_frame() returns 0 on success or -1 if replay
should stop.
Use xmp_end_player(), xmp_release_module() and xmp_free_context() to release memory and end replay.
SDL example
To use libxmp with SDL, just provide a callback function that renders module data. The module will play when
SDL_PauseAudio(0) is called:
#include <SDL/SDL.h>
#include <xmp.h>
5
xmp_play_buffer(udata, stream, len, 0);
}
a.freq = sampling_rate;
a.format = (AUDIO_S16);
a.channels = channels;
a.samples = 2048;
a.callback = fill_audio;
a.userdata = ctx;
SDL_PauseAudio(0);
SDL_PauseAudio(1);
xmp_end_player(ctx);
xmp_release_module(ctx);
xmp_free_context(ctx);
SDL_CloseAudio();
return 0;
}
SDL callbacks run in a separate thread, so don’t forget to protect sections that manipulate module data with
SDL_LockAudio() and SDL_UnlockAudio().
6
API reference
The library version encoded in a integer value. Bits 23-16 contain the major version number, bits 15-8 contain
the minor version number, and bits 7-0 contain the release number.
int xmp_syserrno()
[Added in libxmp 4.5] Use to retrieve errno if you received -XMP_ERROR_SYSTEM from an xmp function call.
Useful if either libxmp or its client is statically linked to libc.
Context creation
xmp_context xmp_create_context()
Create a new player context and return an opaque handle to be used in subsequent accesses to this context.
Returns:
the player context handle.
void xmp_free_context(xmp_context c)
Module loading
Test if a file is a valid module. Testing a file does not affect the current player context or any currently loaded
module.
Parameters:
7
test_info: NULL, or a pointer to a structure used to retrieve the module title and format if the file is a valid
module. struct xmp_test_info is defined as:
struct xmp_test_info {
char name[XMP_NAME_SIZE]; /* Module title */
char type[XMP_NAME_SIZE]; /* Module format */
};
Returns:
0 if the file is a valid module, or a negative error code in case of error. Error codes can be
-XMP_ERROR_FORMAT in case of an unrecognized file format, -XMP_ERROR_DEPACK if the file is
compressed and uncompression failed, or -XMP_ERROR_SYSTEM in case of system error (the system
error code is set in errno).
[Added in libxmp 4.5] Test if a memory buffer is a valid module. Testing memory does not affect the current
player context or any currently loaded module.
Parameters:
mem: a pointer to the module file image in memory. Multi-file modules or compressed modules can’t
be tested in memory.
size: the size of the module.
test_info: NULL, or a pointer to a structure used to retrieve the module title and format if the memory
buffer is a valid module. struct xmp_test_info is defined as:
struct xmp_test_info {
char name[XMP_NAME_SIZE]; /* Module title */
char type[XMP_NAME_SIZE]; /* Module format */
};
Returns:
0 if the memory buffer is a valid module, or a negative error code in case of error. Error codes can be
-XMP_ERROR_FORMAT in case of an unrecognized file format or -XMP_ERROR_SYSTEM in case of system
error (the system error code is set in errno).
[Added in libxmp 4.5] Test if a module from a stream is a valid module. Testing streams does not affect the
current player context or any currently loaded module.
Parameters:
f: the file stream. Compressed modules that need an external depacker can’t be tested from a
file stream. On return, the stream position is undefined. Caller is responsible for closing the file
stream.
test_info: NULL, or a pointer to a structure used to retrieve the module title and format if the memory
buffer is a valid module. struct xmp_test_info is defined as:
struct xmp_test_info {
char name[XMP_NAME_SIZE]; /* Module title */
char type[XMP_NAME_SIZE]; /* Module format */
};
Returns:
0 if the stream is a valid module, or a negative error code in case of error. Error codes can be
-XMP_ERROR_FORMAT in case of an unrecognized file format, -XMP_ERROR_DEPACK if the stream is
compressed and uncompression failed, or -XMP_ERROR_SYSTEM in case of system error (the system
error code is set in errno).
8
int xmp_test_module_from_callbacks(void *priv, struct xmp_callbacks callbacks,
struct xmp_test_info *test_info)
[Added in libxmp 4.5] Test if a module from a custom stream is a valid module. Testing custom streams does
not affect the current player context or any currently loaded module.
Parameters:
priv: pointer to the custom stream. Multi-file modules or compressed modules can’t be tested using
this function. This should not be NULL.
callbacks: struct specifying stream callbacks for the custom stream. These callbacks should behave as
close to fread/fseek/ftell/fclose as possible, and seek_func must be capable of
seeking to SEEK_END. The close_func is optional, but all other functions must be provided.
If a close_func is provided, the stream will be closed once testing has finished or upon
returning an error code. struct xmp_callbacks is defined as:
struct xmp_callbacks {
unsigned long (*read_func)(void *dest, unsigned long len,
unsigned long nmemb, void *priv);
int (*seek_func)(void *priv, long offset, int whence);
long (*tell_func)(void *priv);
int (*close_func)(void *priv);
};
test_info: NULL, or a pointer to a structure used to retrieve the module title and format if the memory
buffer is a valid module.
struct xmp_test_info {
char name[XMP_NAME_SIZE]; /* Module title */
char type[XMP_NAME_SIZE]; /* Module format */
};
Returns:
0 if the custom stream is a valid module, or a negative error code in case of error. Error codes can be
-XMP_ERROR_FORMAT in case of an unrecognized file format or -XMP_ERROR_SYSTEM in case of system
error (the system error code is set in errno).
Load a module into the specified player context. (Certain player flags, such as XMP_PLAYER_SMPCTL and
XMP_PLAYER_DEFPAN, must be set before loading the module, see xmp_set_player() for more information.)
Parameters:
[Added in libxmp 4.2] Load a module from memory into the specified player context.
Parameters:
9
mem: a pointer to the module file image in memory. Multi-file modules or compressed modules can’t
be loaded from memory.
size: the size of the module.
Returns:
0 if successful, or a negative error code in case of error. Error codes can be -XMP_ERROR_FORMAT in
case of an unrecognized file format, -XMP_ERROR_LOAD if the file format was recognized but the file
loading failed, or -XMP_ERROR_SYSTEM in case of system error (the system error code is set in errno).
[Added in libxmp 4.3] Load a module from a stream into the specified player context.
Parameters:
[Added in libxmp 4.5] Load a module from a custom stream into the specified player context.
Parameters:
struct xmp_callbacks {
unsigned long (*read_func)(void *dest, unsigned long len,
unsigned long nmemb, void *priv);
int (*seek_func)(void *priv, long offset, int whence);
long (*tell_func)(void *priv);
int (*close_func)(void *priv);
};
Returns:
0 if successful, or a negative error code in case of error. Error codes can be -XMP_ERROR_FORMAT in
case of an unrecognized file format, -XMP_ERROR_LOAD if the file format was recognized but the file
loading failed, or -XMP_ERROR_SYSTEM in case of system error (the system error code is set in errno).
void xmp_release_module(xmp_context c)
10
c: the player context handle.
void xmp_scan_module(xmp_context c)
Scan the loaded module for sequences and timing. Scanning is automatically performed by xmp_load_module()
and this function should be called only if xmp_set_player() is used to change player timing (with parameter
XMP_PLAYER_VBLANK) in libxmp 4.0.2 or older.
Parameters:
struct xmp_module_info {
unsigned char md5[16]; /* MD5 message digest */
int vol_base; /* Volume scale */
struct xmp_module *mod; /* Pointer to module data */
char *comment; /* Comment text, if any */
int num_sequences; /* Number of valid sequences */
struct xmp_sequence *seq_data; /* Pointer to sequence data */
};
struct xmp_module {
char name[XMP_NAME_SIZE]; /* Module title */
char type[XMP_NAME_SIZE]; /* Module format */
int pat; /* Number of patterns */
int trk; /* Number of tracks */
int chn; /* Tracks per pattern */
int ins; /* Number of instruments */
int smp; /* Number of samples */
int spd; /* Initial speed */
int bpm; /* Initial BPM */
int len; /* Module length in patterns */
int rst; /* Restart position */
int gvl; /* Global volume */
See the header file for more information about pattern and instrument data.
11
Module playing
Returns:
0 if successful, or a negative error code in case of error. Error codes can be -XMP_ERROR_INTERNAL in
case of a internal player error, -XMP_ERROR_INVALID if the sampling rate is invalid, or
-XMP_ERROR_SYSTEM in case of system error (the system error code is set in errno).
int xmp_play_frame(xmp_context c)
Play one frame of the module. Modules usually play at 50 frames per second. Use xmp_get_frame_info() to
retrieve the buffer containing audio data.
Parameters:
[Added in libxmp 4.1] Fill the buffer with PCM data up to the specified size. This is a convenience function that
calls xmp_play_frame() internally to fill the user-supplied buffer. Don’t call both xmp_play_frame() and
xmp_play_buffer() in the same replay loop. If you don’t need equally sized data chunks, xmp_play_frame()
may result in better performance. Also note that silence is added at the end of a buffer if the module ends and
no loop is to be performed.
Parameters:
12
info: pointer to structure containing current frame data. struct xmp_frame_info is defined as
follows:
This function should be used to retrieve sound buffer data after xmp_play_frame() is called.
Fields buffer and buffer_size contain the pointer to the sound buffer PCM data and its
size. The buffer size will be no larger than XMP_MAX_FRAMESIZE.
void xmp_end_player(xmp_context c)
13
Player control
int xmp_next_position(xmp_context c)
int xmp_prev_position(xmp_context c)
14
void xmp_stop_module(xmp_context c)
void xmp_restart_module(xmp_context c)
15
chn: the channel to insert the new event.
event: the event to insert. struct xmp_event is defined as:
struct xmp_event {
unsigned char note; /* Note number (0 means no note) */
unsigned char ins; /* Patch number */
unsigned char vol; /* Volume (0 to basevol) */
unsigned char fxt; /* Effect type */
unsigned char fxp; /* Effect parameter */
unsigned char f2t; /* Secondary effect type */
unsigned char f2p; /* Secondary effect parameter */
unsigned char _flag; /* Internal (reserved) flags */
};
16
Player parameter setting
Set the path to retrieve external instruments or samples. Used by some formats (such as MED2) to read sample
files from a different directory in the filesystem.
Parameters:
See xmp_set_player for the rest of valid values for each parameter.
Returns:
The parameter value, or -XMP_ERROR_STATE if the parameter is not XMP_PLAYER_STATE and the
player is not in playing state.
17
int xmp_set_player(xmp_context c, int param, int val)
• DSP effects flags: enable or disable DSP effects. Valid effects are:
• [Added in libxmp 4.1] Player flags for current module: same flags as above but after applying
module-specific quirks (if any).
• Disabling sample loading when loading a module allows allows computation of module duration
without decompressing and loading large sample data, and is useful when duration information is
needed for a module that won’t be played immediately.
• [Added in libxmp 4.2] Player volumes: Set the player master volume or the external sample mixer
master volume. Valid values are 0 to 100.
• [Added in libxmp 4.3] Default pan separation: percentual left/right pan separation in formats with only
left and right channels. Default is 100%.
18
• [Added in libxmp 4.4] Player personality: The player can be forced to emulate a specific tracker in
cases where the module relies on a format quirk and tracker detection fails. Valid modes are:
By default, formats similar to S3M such as PTM or IMF will use S3M replayer (without Scream Tracker
3 quirks/bug emulation), and formats similar to XM such as RTM and MDL will use the XM replayer
(without FT2 quirks/bug emulation).
Multichannel MOD files will use the XM replayer, and Scream Tracker 3 MOD files will use S3M
replayer with ST3 quirks. S3M files will use the most appropriate replayer according to the tracker
used to create the file, and enable Scream Tracker 3 quirks and bugs only if created using ST3. XM
files will be played with FT2 bugs and quirks only if created using Fast Tracker II.
Modules created with OpenMPT will be played with all bugs and quirks of the original trackers.
• [Added in libxmp 4.4] Maximum number of mixer voices: the maximum number of virtual channels that
can be used to play the module. If set too high, modules with voice leaks can cause excessive CPU
usage. Default is 128.
Returns:
0 if parameter was correctly set, -XMP_ERROR_INVALID if parameter or values are out of the valid
ranges, or -XMP_ERROR_STATE if the player is not in playing state.
19
External sample mixer API
Libxmp 4.2 includes a mini-API that can be used to add sound effects to games and similar applications, provided
that you have a low latency sound system. It allows module instruments or external sample files in WAV format to be
played in response to arbitrary events.
Example
This example using SDL loads a module and a sound sample, plays the module as background music, and plays the
sample when a key is pressed:
#include <SDL/SDL.h>
#include <xmp.h>
a.freq = sampling_rate;
a.format = (AUDIO_S16);
a.channels = channels;
a.samples = 2048;
a.callback = fill_audio;
a.userdata = ctx;
int video_init()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr, "%s\n", SDL_GetError());
return -1;
}
if (SDL_SetVideoMode(640, 480, 8, 0) == NULL) {
fprintf(stderr, "%s\n", SDL_GetError());
return -1;
}
atexit(SDL_Quit);
}
video_init();
sound_init(ctx, 44100, 2);
20
xmp_start_smix(ctx, 1, 1);
xmp_smix_load_sample(ctx, 0, "blip.wav");
xmp_load_module(ctx, "music.mod");
xmp_start_player(ctx, 44100, 0);
xmp_set_player(ctx, XMP_PLAYER_VOLUME, 40);
SDL_PauseAudio(0);
while (1) {
if (SDL_WaitEvent(&event)) {
if (event.type == SDL_KEYDOWN) {
if (event.key.keysym.sym == SDLK_ESCAPE)
break;
xmp_smix_play_sample(ctx, 0, 60, 64, 0);
}
}
}
SDL_PauseAudio(1);
xmp_end_player(ctx);
xmp_release_module(ctx);
xmp_end_smix(ctx);
xmp_free_context(ctx);
SDL_CloseAudio();
return 0;
}
Initialize the external sample mixer subsystem with the given number of reserved channels and samples.
Parameters:
int xmp_smix_play_instrument(xmp_context c, int ins, int note, int vol, int chn)
Play a note using an instrument from the currently loaded module in one of the reserved sound mixer channels.
Parameters:
21
chn: the reserved channel to use to play the instrument.
Returns:
0 if the instrument was correctly played, -XMP_ERROR_INVALID in case of invalid parameters, or
-XMP_ERROR_STATE if the player is not in playing state.
Play an external sample file in one of the reserved sound channels. The sample must have been previously
loaded using xmp_smix_load_sample().
Parameters:
Load a sound sample from a file. Samples should be in mono WAV (RIFF) format.
Parameters:
22
void xmp_end_smix(xmp_context c)
Deinitialize and resease memory used by the external sample mixer subsystem.
Parameters:
23