Home

Awesome

About

pocketmod is a small ANSI C library for turning ProTracker MOD files into playable PCM audio. It comes as an STB-style single-file library, with no external dependencies (not even the C standard library). The library has been tested on a wide range of MOD files, and should be fairly accurate. The code is MIT-licensed.

Using the library

Integration

pocketmod.h is meant to be dropped into your source tree and compiled along with the rest of your code. To create the library implementation, #define POCKETMOD_IMPLEMENTATION before including the header in one source file.

Library API

This is the entire public API of the library:

typedef struct pocketmod_context pocketmod_context;
int pocketmod_init(pocketmod_context *c, const void *data, int size, int rate);
int pocketmod_render(pocketmod_context *c, void *buffer, int size);
int pocketmod_loop_count(pocketmod_context *c);

Below is a detailed description of each part.

pocketmod_context

struct pocketmod_context {
    /* ... */
};

This structure holds state used during rendering. It's declared publicly so that you can instantiate it anywhere you like, but its data fields should be considered private. The structure is relatively small (less than 2 KiB), so you can put it on the stack if you want.

pocketmod_init

int pocketmod_init(pocketmod_context *c, const void *data, int size, int rate);

This function initializes a context and prepares it for rendering from the start of a song. data is a buffer containing MOD file data, and size is the size of that buffer in bytes. rate is the desired sample rate in Hertz, for example 44100 for CD-quality audio. The function returns a nonzero value on success, or zero if it was given an invalid MOD file.

Note that the library reads pattern and instrument data directly out of data during rendering, so you should make sure that it remains valid until the last call to pocketmod_render().

pocketmod_render

int pocketmod_render(pocketmod_context *c, void *buffer, int size);

This function renders the next part of the song and writes the rendered PCM audio data to buffer, which should be at least size bytes large. It returns the number of bytes worth of sample data that was written to buffer.

Each sample consists of two float PCM values, first the left channel and then the right channel. pocketmod_render() generally writes as many samples as it can, but it may stop short when reaching the end of a pattern. This is done so that you can check if the song looped, and decide for yourself if you want to keep going or not.

pocketmod_loop_count

int pocketmod_loop_count(pocketmod_context *c);

This function returns the number of times the song has looped. The song is considered to have looped when reaching a previously encountered pattern order position.

Configuration

There are a few preprocessor symbols that may be #defined before including pocketmod.h to change the behavior of the library:

Note that if you define any of the above symbols, you should make sure that they're defined the same in every source file that includes pocketmod.h. I recommend that you use your build system to do this consistently across your whole project.

Example programs

There are two small example programs included, to demostrate how the library is used.

MOD to WAV converter

This is a simple command-line tool for converting MOD files to WAV files. Here's an example of what building and using it looks like:

$ make converter
cc examples/converter.c -o converter -I.
$ ./converter songs/spacedeb.mod spacedeb.wav
Writing: 'spacedeb.wav' [54.0 MB] [5:05] Press Ctrl + C to stop

SDL2-based MOD player

This is a command-line MOD player. To build the example, you need to have SDL2 installed. On Debian-based Linux you can get it the usual way:

$ sudo apt-get install libsdl2-dev

And here's what it looks like:

$ make player
cc examples/player.c -o player -I. -lSDL2main -lSDL2
$ ./player songs/king.mod
Playing 'king.mod' [00:03] Press Ctrl + C to stop

Song credits

A small collection of test songs is included in the songs/ directory. All credit for these go to their respective authors. I have shortened the filename of some of the songs, but they are otherwise unaltered.

FilenameAuthorLicense
bananasplit.moddizzy / cncdModArchive license
chill.modChromagModArchive license
elysium.modJesterCC BY-NC-SA 3.0
king.modDreamweaverModArchive license
nemesis.modradixModArchive license
overture.modJogeir LiljedahlModArchive license
spacedeb.modMarkus KaarlonenModArchive license
stardstm.modJesterCC BY-NC-SA 3.0
sundance.modPurple MotionModArchive license
sundown.modChromagModArchive license
supernova.modradixModArchive license