diff --git a/Linux/CodeBlocks/QuakeSpasm-SDL2.cbp b/Linux/CodeBlocks/QuakeSpasm-SDL2.cbp
index 3085352e..c726ba4b 100644
--- a/Linux/CodeBlocks/QuakeSpasm-SDL2.cbp
+++ b/Linux/CodeBlocks/QuakeSpasm-SDL2.cbp
@@ -290,6 +290,10 @@
 			<Option compilerVar="CC" />
 		</Unit>
 		<Unit filename="../../Quake/snd_wave.h" />
+		<Unit filename="../../Quake/snd_xmp.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="../../Quake/snd_xmp.h" />
 		<Unit filename="../../Quake/spritegn.h" />
 		<Unit filename="../../Quake/strl_fn.h" />
 		<Unit filename="../../Quake/strlcat.c">
diff --git a/Linux/CodeBlocks/QuakeSpasm.cbp b/Linux/CodeBlocks/QuakeSpasm.cbp
index b1812e31..cb2e1bd0 100644
--- a/Linux/CodeBlocks/QuakeSpasm.cbp
+++ b/Linux/CodeBlocks/QuakeSpasm.cbp
@@ -289,6 +289,10 @@
 			<Option compilerVar="CC" />
 		</Unit>
 		<Unit filename="../../Quake/snd_wave.h" />
+		<Unit filename="../../Quake/snd_xmp.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="../../Quake/snd_xmp.h" />
 		<Unit filename="../../Quake/spritegn.h" />
 		<Unit filename="../../Quake/strl_fn.h" />
 		<Unit filename="../../Quake/strlcat.c">
diff --git a/MacOSX/codecs/include/xmp.h b/MacOSX/codecs/include/xmp.h
new file mode 100644
index 00000000..52a8257e
--- /dev/null
+++ b/MacOSX/codecs/include/xmp.h
@@ -0,0 +1,360 @@
+#ifndef XMP_H
+#define XMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XMP_VERSION "4.4.2"
+#define XMP_VERCODE 0x040402
+#define XMP_VER_MAJOR 4
+#define XMP_VER_MINOR 4
+#define XMP_VER_RELEASE 2
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# if defined(BUILDING_STATIC)
+#  define EXPORT
+# elif defined(BUILDING_DLL)
+#  define EXPORT __declspec(dllexport)
+# else
+#  define EXPORT __declspec(dllimport)
+# endif
+#elif defined(__OS2__) && defined(__WATCOMC__) && defined(__SW_BD)
+#  define EXPORT __declspec(dllexport)
+#elif (defined(__GNUC__) || defined(__clang__) || defined(__HP_cc)) && defined(XMP_SYM_VISIBILITY)
+# define EXPORT __attribute__((visibility ("default")))
+#elif defined(__SUNPRO_C) && defined(XMP_LDSCOPE_GLOBAL)
+# define EXPORT __global
+#elif defined(EMSCRIPTEN)
+# define EXPORT EMSCRIPTEN_KEEPALIVE
+#else
+# define EXPORT 
+#endif
+
+#define XMP_NAME_SIZE		64	/* Size of module name and type */
+
+#define XMP_KEY_OFF		0x81	/* Note number for key off event */
+#define XMP_KEY_CUT		0x82	/* Note number for key cut event */
+#define XMP_KEY_FADE		0x83	/* Note number for fade event */
+
+/* mixer parameter macros */
+
+/* sample format flags */
+#define XMP_FORMAT_8BIT		(1 << 0) /* Mix to 8-bit instead of 16 */
+#define XMP_FORMAT_UNSIGNED	(1 << 1) /* Mix to unsigned samples */
+#define XMP_FORMAT_MONO		(1 << 2) /* Mix to mono instead of stereo */
+
+/* player parameters */
+#define XMP_PLAYER_AMP		0	/* Amplification factor */
+#define XMP_PLAYER_MIX		1	/* Stereo mixing */
+#define XMP_PLAYER_INTERP	2	/* Interpolation type */
+#define XMP_PLAYER_DSP		3	/* DSP effect flags */
+#define XMP_PLAYER_FLAGS	4	/* Player flags */
+#define XMP_PLAYER_CFLAGS	5	/* Player flags for current module */
+#define XMP_PLAYER_SMPCTL	6	/* Sample control flags */
+#define XMP_PLAYER_VOLUME	7	/* Player module volume */
+#define XMP_PLAYER_STATE	8	/* Internal player state (read only) */
+#define XMP_PLAYER_SMIX_VOLUME	9	/* SMIX volume */
+#define XMP_PLAYER_DEFPAN	10	/* Default pan setting */
+#define XMP_PLAYER_MODE 	11	/* Player personality */
+#define XMP_PLAYER_MIXER_TYPE	12	/* Current mixer (read only) */
+#define XMP_PLAYER_VOICES	13	/* Maximum number of mixer voices */
+
+/* interpolation types */
+#define XMP_INTERP_NEAREST	0	/* Nearest neighbor */
+#define XMP_INTERP_LINEAR	1	/* Linear (default) */
+#define XMP_INTERP_SPLINE	2	/* Cubic spline */
+
+/* dsp effect types */
+#define XMP_DSP_LOWPASS		(1 << 0) /* Lowpass filter effect */
+#define XMP_DSP_ALL		(XMP_DSP_LOWPASS)
+
+/* player state */
+#define XMP_STATE_UNLOADED	0	/* Context created */
+#define XMP_STATE_LOADED	1	/* Module loaded */
+#define XMP_STATE_PLAYING	2	/* Module playing */
+
+/* player flags */
+#define XMP_FLAGS_VBLANK	(1 << 0) /* Use vblank timing */
+#define XMP_FLAGS_FX9BUG	(1 << 1) /* Emulate FX9 bug */
+#define XMP_FLAGS_FIXLOOP	(1 << 2) /* Emulate sample loop bug */
+#define XMP_FLAGS_A500		(1 << 3) /* Use Paula mixer in Amiga modules */
+
+/* player modes */
+#define XMP_MODE_AUTO		0	/* Autodetect mode (default) */
+#define XMP_MODE_MOD		1	/* Play as a generic MOD player */
+#define XMP_MODE_NOISETRACKER	2	/* Play using Noisetracker quirks */
+#define XMP_MODE_PROTRACKER	3	/* Play using Protracker quirks */
+#define XMP_MODE_S3M		4	/* Play as a generic S3M player */
+#define XMP_MODE_ST3		5	/* Play using ST3 bug emulation */
+#define XMP_MODE_ST3GUS		6	/* Play using ST3+GUS quirks */
+#define XMP_MODE_XM		7	/* Play as a generic XM player */
+#define XMP_MODE_FT2		8	/* Play using FT2 bug emulation */
+#define XMP_MODE_IT		9	/* Play using IT quirks */
+#define XMP_MODE_ITSMP		10	/* Play using IT sample mode quirks */
+
+/* mixer types */
+#define XMP_MIXER_STANDARD	0	/* Standard mixer */
+#define XMP_MIXER_A500		1	/* Amiga 500 */
+#define XMP_MIXER_A500F		2	/* Amiga 500 with led filter */
+
+/* sample flags */
+#define XMP_SMPCTL_SKIP		(1 << 0) /* Don't load samples */
+
+/* limits */
+#define XMP_MAX_KEYS		121	/* Number of valid keys */
+#define XMP_MAX_ENV_POINTS	32	/* Max number of envelope points */
+#define XMP_MAX_MOD_LENGTH	256	/* Max number of patterns in module */
+#define XMP_MAX_CHANNELS	64	/* Max number of channels in module */
+#define XMP_MAX_SRATE		49170	/* max sampling rate (Hz) */
+#define XMP_MIN_SRATE		4000	/* min sampling rate (Hz) */
+#define XMP_MIN_BPM		20	/* min BPM */
+/* frame rate = (50 * bpm / 125) Hz */
+/* frame size = (sampling rate * channels * size) / frame rate */
+#define XMP_MAX_FRAMESIZE	(5 * XMP_MAX_SRATE * 2 / XMP_MIN_BPM)
+
+/* error codes */
+#define XMP_END			1
+#define XMP_ERROR_INTERNAL	2	/* Internal error */
+#define XMP_ERROR_FORMAT	3	/* Unsupported module format */
+#define XMP_ERROR_LOAD		4	/* Error loading file */
+#define XMP_ERROR_DEPACK	5	/* Error depacking file */
+#define XMP_ERROR_SYSTEM	6	/* System error */
+#define XMP_ERROR_INVALID	7	/* Invalid parameter */
+#define XMP_ERROR_STATE		8	/* Invalid player state */
+
+struct xmp_channel {
+	int pan;			/* Channel pan (0x80 is center) */
+	int vol;			/* Channel volume */
+#define XMP_CHANNEL_SYNTH	(1 << 0)  /* Channel is synthesized */
+#define XMP_CHANNEL_MUTE  	(1 << 1)  /* Channel is muted */
+#define XMP_CHANNEL_SPLIT	(1 << 2)  /* Split Amiga channel in bits 5-4 */
+#define XMP_CHANNEL_SURROUND	(1 << 4)  /* Surround channel */
+	int flg;			/* Channel flags */
+};
+
+struct xmp_pattern {
+	int rows;			/* Number of rows */
+	int index[1];			/* Track index */
+};
+
+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 */
+};
+
+struct xmp_track {
+	int rows;			/* Number of rows */
+	struct xmp_event event[1];	/* Event data */
+};
+
+struct xmp_envelope {
+#define XMP_ENVELOPE_ON		(1 << 0)  /* Envelope is enabled */
+#define XMP_ENVELOPE_SUS	(1 << 1)  /* Envelope has sustain point */
+#define XMP_ENVELOPE_LOOP	(1 << 2)  /* Envelope has loop */
+#define XMP_ENVELOPE_FLT	(1 << 3)  /* Envelope is used for filter */
+#define XMP_ENVELOPE_SLOOP	(1 << 4)  /* Envelope has sustain loop */
+#define XMP_ENVELOPE_CARRY	(1 << 5)  /* Don't reset envelope position */
+	int flg;			/* Flags */
+	int npt;			/* Number of envelope points */
+	int scl;			/* Envelope scaling */
+	int sus;			/* Sustain start point */
+	int sue;			/* Sustain end point */
+	int lps;			/* Loop start point */
+	int lpe;			/* Loop end point */
+	short data[XMP_MAX_ENV_POINTS * 2];
+};
+
+struct xmp_instrument {
+	char name[32];			/* Instrument name */
+	int vol;			/* Instrument volume */
+	int nsm;			/* Number of samples */
+	int rls;			/* Release (fadeout) */
+	struct xmp_envelope aei;	/* Amplitude envelope info */
+	struct xmp_envelope pei;	/* Pan envelope info */
+	struct xmp_envelope fei;	/* Frequency envelope info */
+
+	struct {
+		unsigned char ins;	/* Instrument number for each key */
+		signed char xpo;	/* Instrument transpose for each key */
+	} map[XMP_MAX_KEYS];
+
+	struct xmp_subinstrument {
+		int vol;		/* Default volume */
+		int gvl;		/* Global volume */
+		int pan;		/* Pan */
+		int xpo;		/* Transpose */
+		int fin;		/* Finetune */
+		int vwf;		/* Vibrato waveform */
+		int vde;		/* Vibrato depth */
+		int vra;		/* Vibrato rate */
+		int vsw;		/* Vibrato sweep */
+		int rvv;		/* Random volume/pan variation (IT) */
+		int sid;		/* Sample number */
+#define XMP_INST_NNA_CUT	0x00
+#define XMP_INST_NNA_CONT	0x01
+#define XMP_INST_NNA_OFF	0x02
+#define XMP_INST_NNA_FADE	0x03
+		int nna;		/* New note action */
+#define XMP_INST_DCT_OFF	0x00
+#define XMP_INST_DCT_NOTE	0x01
+#define XMP_INST_DCT_SMP	0x02
+#define XMP_INST_DCT_INST	0x03
+		int dct;		/* Duplicate check type */
+#define XMP_INST_DCA_CUT	XMP_INST_NNA_CUT
+#define XMP_INST_DCA_OFF	XMP_INST_NNA_OFF
+#define XMP_INST_DCA_FADE	XMP_INST_NNA_FADE
+		int dca;		/* Duplicate check action */
+		int ifc;		/* Initial filter cutoff */
+		int ifr;		/* Initial filter resonance */
+	} *sub;
+
+	void *extra;			/* Extra fields */
+};
+
+struct xmp_sample {
+	char name[32];			/* Sample name */
+	int len;			/* Sample length */
+	int lps;			/* Loop start */
+	int lpe;			/* Loop end */
+#define XMP_SAMPLE_16BIT	(1 << 0)  /* 16bit sample */
+#define XMP_SAMPLE_LOOP		(1 << 1)  /* Sample is looped */
+#define XMP_SAMPLE_LOOP_BIDIR	(1 << 2)  /* Bidirectional sample loop */
+#define XMP_SAMPLE_LOOP_REVERSE	(1 << 3)  /* Backwards sample loop */
+#define XMP_SAMPLE_LOOP_FULL	(1 << 4)  /* Play full sample before looping */
+#define XMP_SAMPLE_SLOOP	(1 << 5)  /* Sample has sustain loop */
+#define XMP_SAMPLE_SLOOP_BIDIR	(1 << 6)  /* Bidirectional sustain loop */
+#define XMP_SAMPLE_SYNTH	(1 << 15) /* Data contains synth patch */
+	int flg;			/* Flags */
+	unsigned char *data;		/* Sample data */
+};
+
+struct xmp_sequence {
+	int entry_point;
+	int duration;
+};
+
+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 */
+
+	struct xmp_pattern **xxp;	/* Patterns */
+	struct xmp_track **xxt;		/* Tracks */
+	struct xmp_instrument *xxi;	/* Instruments */
+	struct xmp_sample *xxs;		/* Samples */
+	struct xmp_channel xxc[XMP_MAX_CHANNELS]; /* Channel info */
+	unsigned char xxo[XMP_MAX_MOD_LENGTH];	/* Orders */
+};
+
+struct xmp_test_info {
+	char name[XMP_NAME_SIZE];	/* Module title */
+	char type[XMP_NAME_SIZE];	/* Module format */
+};
+
+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_frame_info {			/* Current frame information */
+	int pos;			/* Current position */
+	int pattern;			/* Current pattern */
+	int row;			/* Current row in pattern */
+	int num_rows;			/* Number of rows in current pattern */
+	int frame;			/* Current frame */
+	int speed;			/* Current replay speed */
+	int bpm;			/* Current bpm */
+	int time;			/* Current module time in ms */
+	int total_time;			/* Estimated replay time in ms*/
+	int frame_time;			/* Frame replay time in us */
+	void *buffer;			/* Pointer to sound buffer */
+	int buffer_size;		/* Used buffer size */
+	int total_size;			/* Total buffer size */
+	int volume;			/* Current master volume */
+	int loop_count;			/* Loop counter */
+	int virt_channels;		/* Number of virtual channels */
+	int virt_used;			/* Used virtual channels */
+	int sequence;			/* Current sequence */
+
+	struct xmp_channel_info {	/* Current channel information */
+		unsigned int period;	/* Sample period (* 4096) */
+		unsigned int position;	/* Sample position */
+		short pitchbend;	/* Linear bend from base note*/
+		unsigned char note;	/* Current base note number */
+		unsigned char instrument; /* Current instrument number */
+		unsigned char sample;	/* Current sample number */
+		unsigned char volume;	/* Current volume */
+		unsigned char pan;	/* Current stereo pan */
+		unsigned char reserved;	/* Reserved */
+		struct xmp_event event;	/* Current track event */
+	} channel_info[XMP_MAX_CHANNELS];
+};
+
+
+typedef char *xmp_context;
+
+EXPORT extern const char *xmp_version;
+EXPORT extern const unsigned int xmp_vercode;
+
+EXPORT xmp_context xmp_create_context  (void);
+EXPORT void        xmp_free_context    (xmp_context);
+EXPORT int         xmp_test_module     (char *, struct xmp_test_info *);
+EXPORT int         xmp_load_module     (xmp_context, char *);
+EXPORT void        xmp_scan_module     (xmp_context);
+EXPORT void        xmp_release_module  (xmp_context);
+EXPORT int         xmp_start_player    (xmp_context, int, int);
+EXPORT int         xmp_play_frame      (xmp_context);
+EXPORT int         xmp_play_buffer     (xmp_context, void *, int, int);
+EXPORT void        xmp_get_frame_info  (xmp_context, struct xmp_frame_info *);
+EXPORT void        xmp_end_player      (xmp_context);
+EXPORT void        xmp_inject_event    (xmp_context, int, struct xmp_event *);
+EXPORT void        xmp_get_module_info (xmp_context, struct xmp_module_info *);
+EXPORT char      **xmp_get_format_list (void);
+EXPORT int         xmp_next_position   (xmp_context);
+EXPORT int         xmp_prev_position   (xmp_context);
+EXPORT int         xmp_set_position    (xmp_context, int);
+EXPORT void        xmp_stop_module     (xmp_context);
+EXPORT void        xmp_restart_module  (xmp_context);
+EXPORT int         xmp_seek_time       (xmp_context, int);
+EXPORT int         xmp_channel_mute    (xmp_context, int, int);
+EXPORT int         xmp_channel_vol     (xmp_context, int, int);
+EXPORT int         xmp_set_player      (xmp_context, int, int);
+EXPORT int         xmp_get_player      (xmp_context, int);
+EXPORT int         xmp_set_instrument_path (xmp_context, char *);
+EXPORT int         xmp_load_module_from_memory (xmp_context, void *, long);
+EXPORT int         xmp_load_module_from_file (xmp_context, void *, long);
+
+/* External sample mixer API */
+EXPORT int         xmp_start_smix       (xmp_context, int, int);
+EXPORT void        xmp_end_smix         (xmp_context);
+EXPORT int         xmp_smix_play_instrument(xmp_context, int, int, int, int);
+EXPORT int         xmp_smix_play_sample (xmp_context, int, int, int, int);
+EXPORT int         xmp_smix_channel_pan (xmp_context, int, int);
+EXPORT int         xmp_smix_load_sample (xmp_context, int, char *);
+EXPORT int         xmp_smix_release_sample (xmp_context, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* XMP_H */
diff --git a/MacOSX/codecs/lib/libxmp.dylib b/MacOSX/codecs/lib/libxmp.dylib
new file mode 100755
index 00000000..49401edb
Binary files /dev/null and b/MacOSX/codecs/lib/libxmp.dylib differ
diff --git a/Quake/Makefile b/Quake/Makefile
index d0c8214e..ce000730 100644
--- a/Quake/Makefile
+++ b/Quake/Makefile
@@ -16,8 +16,9 @@ USE_CODEC_FLAC=0
 USE_CODEC_MP3=1
 USE_CODEC_VORBIS=1
 USE_CODEC_OPUS=0
-# either mikmod (preferred) or modplug, not both
+# either mikmod, or xmp (or modplug.)
 USE_CODEC_MIKMOD=0
+USE_CODEC_XMP=0
 USE_CODEC_MODPLUG=0
 USE_CODEC_UMX=0
 
@@ -168,6 +169,10 @@ ifeq ($(USE_CODEC_MIKMOD),1)
 CFLAGS+= -DUSE_CODEC_MIKMOD
 CODECLIBS+= -lmikmod
 endif
+ifeq ($(USE_CODEC_XMP),1)
+CFLAGS+= -DUSE_CODEC_XMP
+CODECLIBS+= -lxmp
+endif
 ifeq ($(USE_CODEC_MODPLUG),1)
 CFLAGS+= -DUSE_CODEC_MODPLUG
 CODECLIBS+= -lmodplug
@@ -208,6 +213,7 @@ MUSIC_OBJS:= bgmusic.o \
 	$(mp3_obj) \
 	snd_mikmod.o \
 	snd_modplug.o \
+	snd_xmp.o \
 	snd_umx.o
 COMOBJ_SND := snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS)
 SYSOBJ_SND := snd_sdl.o
diff --git a/Quake/Makefile.darwin b/Quake/Makefile.darwin
index 258f7c51..5e59d219 100644
--- a/Quake/Makefile.darwin
+++ b/Quake/Makefile.darwin
@@ -1,6 +1,6 @@
 # GNU Makefile for compiling Mac OS X version of QuakeSpasm.
 # Usage: "make -f Makefile.darwin"
-# To cross-compile on Linux hosts, see the "build_cross_osx*.sh" scripts.
+# To cross-compile on Linux hosts, see the build_cross_osx*.sh scripts.
 # "make DEBUG=1" to build a debug client.
 # "make SDL_FRAMEWORK_PATH=/path/to/Frameworks" to specify the directory
 #    containing SDL.framework and override the locally included versions.
@@ -18,8 +18,9 @@ USE_CODEC_FLAC=1
 USE_CODEC_MP3=1
 USE_CODEC_VORBIS=1
 USE_CODEC_OPUS=1
-# either mikmod (preferred) or modplug, not both
+# either mikmod, or xmp (or modplug.)
 USE_CODEC_MIKMOD=1
+USE_CODEC_XMP=0
 USE_CODEC_MODPLUG=0
 USE_CODEC_UMX=1
 
@@ -187,6 +188,12 @@ CODEC_INC = -I../MacOSX/codecs/include
 CODEC_LINK= -L../MacOSX/codecs/lib
 CODECLIBS+= -lmikmod
 endif
+ifeq ($(USE_CODEC_XMP),1)
+CFLAGS+= -DUSE_CODEC_XMP
+CODEC_INC = -I../MacOSX/codecs/include
+CODEC_LINK= -L../MacOSX/codecs/lib
+CODECLIBS+= -lxmp
+endif
 ifeq ($(USE_CODEC_MODPLUG),1)
 CFLAGS+= -DUSE_CODEC_MODPLUG
 CODEC_INC = -I../MacOSX/codecs/include
@@ -234,6 +241,7 @@ MUSIC_OBJS:= bgmusic.o \
 	$(mp3_obj) \
 	snd_mikmod.o \
 	snd_modplug.o \
+	snd_xmp.o \
 	snd_umx.o
 COMOBJ_SND := snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS)
 SYSOBJ_SND := snd_sdl.o
diff --git a/Quake/Makefile.w32 b/Quake/Makefile.w32
index 1b84bc3d..bfc34be7 100644
--- a/Quake/Makefile.w32
+++ b/Quake/Makefile.w32
@@ -1,6 +1,6 @@
 # GNU Makefile for compiling Win32 quakespasm.exe using MinGW or MinGW-w64.
 # Usage: "make -f Makefile.w32"
-# To cross-compile on Linux hosts, see the "build_cross_win32*.sh" scripts.
+# To cross-compile on Linux hosts, see the build_cross_win32*.sh scripts.
 # "make DEBUG=1" to build a debug client.
 # "make SDL_CONFIG=/path/to/sdl-config" to override the locally included SDL versions.
 # "make WINSOCK2=1" to use WinSock2 api instead of old WinSock 1.1.
@@ -14,8 +14,9 @@ USE_CODEC_FLAC=1
 USE_CODEC_MP3=1
 USE_CODEC_VORBIS=1
 USE_CODEC_OPUS=1
-# either mikmod (preferred) or modplug, not both
+# either mikmod, or xmp (or modplug.)
 USE_CODEC_MIKMOD=1
+USE_CODEC_XMP=0
 USE_CODEC_MODPLUG=0
 USE_CODEC_UMX=1
 
@@ -153,6 +154,12 @@ CODEC_INC = -I../Windows/codecs/include
 CODEC_LINK= -L../Windows/codecs/x86
 CODECLIBS+= -lmikmod
 endif
+ifeq ($(USE_CODEC_XMP),1)
+CFLAGS+= -DUSE_CODEC_XMP
+CODEC_INC = -I../Windows/codecs/include
+CODEC_LINK= -L../Windows/codecs/x86
+CODECLIBS+= -lxmp
+endif
 ifeq ($(USE_CODEC_MODPLUG),1)
 CFLAGS+= -DUSE_CODEC_MODPLUG
 CODEC_INC = -I../Windows/codecs/include
@@ -198,6 +205,7 @@ MUSIC_OBJS:= bgmusic.o \
 	$(mp3_obj) \
 	snd_mikmod.o \
 	snd_modplug.o \
+	snd_xmp.o \
 	snd_umx.o
 COMOBJ_SND := snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS)
 SYSOBJ_SND := snd_sdl.o
diff --git a/Quake/Makefile.w64 b/Quake/Makefile.w64
index 538a9d62..6ae90860 100644
--- a/Quake/Makefile.w64
+++ b/Quake/Makefile.w64
@@ -1,6 +1,6 @@
 # GNU Makefile for compiling Win64 quakespasm.exe using MinGW-w64.
 # Usage: "make -f Makefile.w64"
-# To cross-compile on Linux hosts, see the "build_cross_win32*.sh" scripts.
+# To cross-compile on Linux hosts, see the build_cross_win32*.sh scripts.
 # "make DEBUG=1" to build a debug client.
 # "make SDL_CONFIG=/path/to/sdl-config" to override the locally included SDL versions.
 # "make WINSOCK2=0" to use the old WinSock 1.1 api (NOT RECOMMENDED)
@@ -14,8 +14,9 @@ USE_CODEC_FLAC=1
 USE_CODEC_MP3=1
 USE_CODEC_VORBIS=1
 USE_CODEC_OPUS=1
-# either mikmod (preferred) or modplug, not both
+# either mikmod, or xmp (or modplug.)
 USE_CODEC_MIKMOD=1
+USE_CODEC_XMP=0
 USE_CODEC_MODPLUG=0
 USE_CODEC_UMX=1
 
@@ -151,6 +152,12 @@ CODEC_INC = -I../Windows/codecs/include
 CODEC_LINK= -L../Windows/codecs/x64
 CODECLIBS+= -lmikmod
 endif
+ifeq ($(USE_CODEC_XMP),1)
+CFLAGS+= -DUSE_CODEC_XMP
+CODEC_INC = -I../Windows/codecs/include
+CODEC_LINK= -L../Windows/codecs/x64
+CODECLIBS+= -lxmp
+endif
 ifeq ($(USE_CODEC_MODPLUG),1)
 CFLAGS+= -DUSE_CODEC_MODPLUG
 CODEC_INC = -I../Windows/codecs/include
@@ -196,6 +203,7 @@ MUSIC_OBJS:= bgmusic.o \
 	$(mp3_obj) \
 	snd_mikmod.o \
 	snd_modplug.o \
+	snd_xmp.o \
 	snd_umx.o
 COMOBJ_SND := snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS)
 SYSOBJ_SND := snd_sdl.o
diff --git a/Quake/snd_codec.c b/Quake/snd_codec.c
index 243dd3d0..96a82d79 100644
--- a/Quake/snd_codec.c
+++ b/Quake/snd_codec.c
@@ -30,6 +30,7 @@
 /* headers for individual codecs */
 #include "snd_mikmod.h"
 #include "snd_modplug.h"
+#include "snd_xmp.h"
 #include "snd_umx.h"
 #include "snd_wave.h"
 #include "snd_flac.h"
@@ -72,6 +73,9 @@ void S_CodecInit (void)
 #ifdef USE_CODEC_MIKMOD
 	S_CodecRegister(&mikmod_codec);
 #endif
+#ifdef USE_CODEC_XMP
+	S_CodecRegister(&xmp_codec);
+#endif
 #ifdef USE_CODEC_WAVE
 	S_CodecRegister(&wav_codec);
 #endif
diff --git a/Quake/snd_xmp.c b/Quake/snd_xmp.c
new file mode 100644
index 00000000..90718fb0
--- /dev/null
+++ b/Quake/snd_xmp.c
@@ -0,0 +1,165 @@
+/* tracker music (module file) decoding support using libxmp >= v4.2.0
+ * https://sourceforge.net/projects/xmp/
+ * https://github.com/cmatsuoka/libxmp.git
+ *
+ * Copyright (C) 2016 O.Sezer <sezero@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "quakedef.h"
+
+#if defined(USE_CODEC_XMP)
+#include "snd_codec.h"
+#include "snd_codeci.h"
+#include "snd_xmp.h"
+#include <xmp.h>
+#if ((XMP_VERCODE+0) < 0x040200)
+#error libxmp version 4.2 or newer is required
+#endif
+
+static int S_XMP_StartPlay (snd_stream_t *stream)
+{
+	int fmt = 0;
+
+	if (stream->info.channels == 1)
+		fmt |= XMP_FORMAT_MONO;
+	if (stream->info.width == 1)
+		fmt |= XMP_FORMAT_8BIT|XMP_FORMAT_UNSIGNED;
+
+	return xmp_start_player((xmp_context)stream->priv, stream->info.rate, fmt);
+}
+
+static qboolean S_XMP_CodecInitialize (void)
+{
+	return true;
+}
+
+static void S_XMP_CodecShutdown (void)
+{
+}
+
+static qboolean S_XMP_CodecOpenStream (snd_stream_t *stream)
+{
+/* need to load the whole file into memory and pass it to libxmp
+ * using xmp_load_module_from_memory() which requires libxmp >= 4.2.
+ * libxmp-4.0/4.1 only have xmp_load_module() which accepts a file
+ * name which isn't good with files in containers like paks, etc. */
+	xmp_context c;
+	byte *moddata;
+	long len;
+	int mark;
+
+	c = xmp_create_context();
+	if (c == NULL)
+		return false;
+
+	len = FS_filelength (&stream->fh);
+	mark = Hunk_LowMark();
+	moddata = (byte *) Hunk_Alloc(len);
+	FS_fread(moddata, 1, len, &stream->fh);
+	if (xmp_load_module_from_memory(c, moddata, len) != 0)
+	{
+		Con_DPrintf("Could not load module %s\n", stream->name);
+		goto err1;
+	}
+
+	Hunk_FreeToLowMark(mark); /* free original file data */
+	stream->priv = c;
+	if (shm->speed > XMP_MAX_SRATE)
+		stream->info.rate = 44100;
+	else if (shm->speed < XMP_MIN_SRATE)
+		stream->info.rate = 11025;
+	else	stream->info.rate = shm->speed;
+	stream->info.bits = shm->samplebits;
+	stream->info.width = stream->info.bits / 8;
+	stream->info.channels = shm->channels;
+
+	if (S_XMP_StartPlay(stream) != 0)
+		goto err2;
+	/* percentual left/right channel separation, default is 70. */
+	if (stream->info.channels == 2)
+		if (xmp_set_player(c, XMP_PLAYER_MIX, 100) != 0)
+			goto err3;
+	/* interpolation type, default is XMP_INTERP_LINEAR */
+	if (xmp_set_player(c, XMP_PLAYER_INTERP, XMP_INTERP_SPLINE) != 0)
+		goto err3;
+
+	return true;
+
+err3:	xmp_end_player(c);
+err2:	xmp_release_module(c);
+err1:	xmp_free_context(c);
+	return false;
+}
+
+static int S_XMP_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer)
+{
+	int r;
+	/* xmp_play_buffer() requires libxmp >= 4.1.  it will write
+	 * native-endian pcm data to the buffer.  if the data write
+	 * is partial, the rest of the buffer will be zero-filled.
+	 * the last param is the number that the current sequence of
+	 * the song will be looped at max. */
+	r = xmp_play_buffer((xmp_context)stream->priv, buffer, bytes, 1);
+	if (r == 0) {
+		return bytes;
+	}
+	if (r == -XMP_END) {
+		Con_DPrintf("XMP EOF\n");
+		return 0;
+	}
+	return -1;
+}
+
+static void S_XMP_CodecCloseStream (snd_stream_t *stream)
+{
+	xmp_context c = (xmp_context)stream->priv;
+	xmp_end_player(c);
+	xmp_release_module(c);
+	xmp_free_context(c);
+	S_CodecUtilClose(&stream);
+}
+
+static int S_XMP_CodecRewindStream (snd_stream_t *stream)
+{
+	int ret;
+
+	ret = S_XMP_StartPlay(stream);
+	if (ret < 0) return ret;
+
+	/*ret = xmp_set_position((xmp_context)stream->priv, 0);*/
+	ret = xmp_seek_time((xmp_context)stream->priv, 0);
+	if (ret < 0) return ret;
+
+	return 0;
+}
+
+snd_codec_t xmp_codec =
+{
+	CODECTYPE_MOD,
+	true,	/* always available. */
+	"s3m",
+	S_XMP_CodecInitialize,
+	S_XMP_CodecShutdown,
+	S_XMP_CodecOpenStream,
+	S_XMP_CodecReadStream,
+	S_XMP_CodecRewindStream,
+	S_XMP_CodecCloseStream,
+	NULL
+};
+
+#endif	/* USE_CODEC_XMP */
diff --git a/Quake/snd_xmp.h b/Quake/snd_xmp.h
new file mode 100644
index 00000000..9516a498
--- /dev/null
+++ b/Quake/snd_xmp.h
@@ -0,0 +1,12 @@
+/* module tracker decoding support using libxmp */
+#if !defined(_SND_XMP_H_)
+#define _SND_XMP_H_
+
+#if defined(USE_CODEC_XMP)
+
+extern snd_codec_t xmp_codec;
+
+#endif	/* USE_CODEC_XMP */
+
+#endif	/* ! _SND_XMP_H_ */
+
diff --git a/Windows/CodeBlocks/QuakeSpasm-SDL2.cbp b/Windows/CodeBlocks/QuakeSpasm-SDL2.cbp
index 396442b3..2b312ae8 100644
--- a/Windows/CodeBlocks/QuakeSpasm-SDL2.cbp
+++ b/Windows/CodeBlocks/QuakeSpasm-SDL2.cbp
@@ -308,6 +308,10 @@
 			<Option compilerVar="CC" />
 		</Unit>
 		<Unit filename="..\..\Quake\snd_wave.h" />
+		<Unit filename="..\..\Quake\snd_xmp.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\Quake\snd_xmp.h" />
 		<Unit filename="..\..\Quake\spritegn.h" />
 		<Unit filename="..\..\Quake\strl_fn.h" />
 		<Unit filename="..\..\Quake\strlcat.c">
diff --git a/Windows/CodeBlocks/QuakeSpasm.cbp b/Windows/CodeBlocks/QuakeSpasm.cbp
index 63015844..58398cc1 100644
--- a/Windows/CodeBlocks/QuakeSpasm.cbp
+++ b/Windows/CodeBlocks/QuakeSpasm.cbp
@@ -307,6 +307,10 @@
 			<Option compilerVar="CC" />
 		</Unit>
 		<Unit filename="..\..\Quake\snd_wave.h" />
+		<Unit filename="..\..\Quake\snd_xmp.c">
+			<Option compilerVar="CC" />
+		</Unit>
+		<Unit filename="..\..\Quake\snd_xmp.h" />
 		<Unit filename="..\..\Quake\spritegn.h" />
 		<Unit filename="..\..\Quake\strl_fn.h" />
 		<Unit filename="..\..\Quake\strlcat.c">
diff --git a/Windows/VisualStudio/quakespasm-sdl2.vcproj b/Windows/VisualStudio/quakespasm-sdl2.vcproj
index a9ff8532..8e86a0e0 100644
--- a/Windows/VisualStudio/quakespasm-sdl2.vcproj
+++ b/Windows/VisualStudio/quakespasm-sdl2.vcproj
@@ -585,6 +585,10 @@
 				RelativePath="..\..\Quake\snd_wave.c"
 				>
 			</File>
+			<File
+				RelativePath="..\..\Quake\snd_xmp.c"
+				>
+			</File>
 			<File
 				RelativePath="..\..\Quake\strlcat.c"
 				>
@@ -855,6 +859,10 @@
 				RelativePath="..\..\Quake\snd_wave.h"
 				>
 			</File>
+			<File
+				RelativePath="..\..\Quake\snd_xmp.h"
+				>
+			</File>
 			<File
 				RelativePath="..\..\Quake\spritegn.h"
 				>
diff --git a/Windows/VisualStudio/quakespasm.vcproj b/Windows/VisualStudio/quakespasm.vcproj
index c93207ac..a38c42a6 100644
--- a/Windows/VisualStudio/quakespasm.vcproj
+++ b/Windows/VisualStudio/quakespasm.vcproj
@@ -585,6 +585,10 @@
 				RelativePath="..\..\Quake\snd_wave.c"
 				>
 			</File>
+			<File
+				RelativePath="..\..\Quake\snd_xmp.c"
+				>
+			</File>
 			<File
 				RelativePath="..\..\Quake\strlcat.c"
 				>
@@ -855,6 +859,10 @@
 				RelativePath="..\..\Quake\snd_wave.h"
 				>
 			</File>
+			<File
+				RelativePath="..\..\Quake\snd_xmp.h"
+				>
+			</File>
 			<File
 				RelativePath="..\..\Quake\spritegn.h"
 				>
diff --git a/Windows/codecs/include/xmp.h b/Windows/codecs/include/xmp.h
new file mode 100644
index 00000000..52a8257e
--- /dev/null
+++ b/Windows/codecs/include/xmp.h
@@ -0,0 +1,360 @@
+#ifndef XMP_H
+#define XMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XMP_VERSION "4.4.2"
+#define XMP_VERCODE 0x040402
+#define XMP_VER_MAJOR 4
+#define XMP_VER_MINOR 4
+#define XMP_VER_RELEASE 2
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# if defined(BUILDING_STATIC)
+#  define EXPORT
+# elif defined(BUILDING_DLL)
+#  define EXPORT __declspec(dllexport)
+# else
+#  define EXPORT __declspec(dllimport)
+# endif
+#elif defined(__OS2__) && defined(__WATCOMC__) && defined(__SW_BD)
+#  define EXPORT __declspec(dllexport)
+#elif (defined(__GNUC__) || defined(__clang__) || defined(__HP_cc)) && defined(XMP_SYM_VISIBILITY)
+# define EXPORT __attribute__((visibility ("default")))
+#elif defined(__SUNPRO_C) && defined(XMP_LDSCOPE_GLOBAL)
+# define EXPORT __global
+#elif defined(EMSCRIPTEN)
+# define EXPORT EMSCRIPTEN_KEEPALIVE
+#else
+# define EXPORT 
+#endif
+
+#define XMP_NAME_SIZE		64	/* Size of module name and type */
+
+#define XMP_KEY_OFF		0x81	/* Note number for key off event */
+#define XMP_KEY_CUT		0x82	/* Note number for key cut event */
+#define XMP_KEY_FADE		0x83	/* Note number for fade event */
+
+/* mixer parameter macros */
+
+/* sample format flags */
+#define XMP_FORMAT_8BIT		(1 << 0) /* Mix to 8-bit instead of 16 */
+#define XMP_FORMAT_UNSIGNED	(1 << 1) /* Mix to unsigned samples */
+#define XMP_FORMAT_MONO		(1 << 2) /* Mix to mono instead of stereo */
+
+/* player parameters */
+#define XMP_PLAYER_AMP		0	/* Amplification factor */
+#define XMP_PLAYER_MIX		1	/* Stereo mixing */
+#define XMP_PLAYER_INTERP	2	/* Interpolation type */
+#define XMP_PLAYER_DSP		3	/* DSP effect flags */
+#define XMP_PLAYER_FLAGS	4	/* Player flags */
+#define XMP_PLAYER_CFLAGS	5	/* Player flags for current module */
+#define XMP_PLAYER_SMPCTL	6	/* Sample control flags */
+#define XMP_PLAYER_VOLUME	7	/* Player module volume */
+#define XMP_PLAYER_STATE	8	/* Internal player state (read only) */
+#define XMP_PLAYER_SMIX_VOLUME	9	/* SMIX volume */
+#define XMP_PLAYER_DEFPAN	10	/* Default pan setting */
+#define XMP_PLAYER_MODE 	11	/* Player personality */
+#define XMP_PLAYER_MIXER_TYPE	12	/* Current mixer (read only) */
+#define XMP_PLAYER_VOICES	13	/* Maximum number of mixer voices */
+
+/* interpolation types */
+#define XMP_INTERP_NEAREST	0	/* Nearest neighbor */
+#define XMP_INTERP_LINEAR	1	/* Linear (default) */
+#define XMP_INTERP_SPLINE	2	/* Cubic spline */
+
+/* dsp effect types */
+#define XMP_DSP_LOWPASS		(1 << 0) /* Lowpass filter effect */
+#define XMP_DSP_ALL		(XMP_DSP_LOWPASS)
+
+/* player state */
+#define XMP_STATE_UNLOADED	0	/* Context created */
+#define XMP_STATE_LOADED	1	/* Module loaded */
+#define XMP_STATE_PLAYING	2	/* Module playing */
+
+/* player flags */
+#define XMP_FLAGS_VBLANK	(1 << 0) /* Use vblank timing */
+#define XMP_FLAGS_FX9BUG	(1 << 1) /* Emulate FX9 bug */
+#define XMP_FLAGS_FIXLOOP	(1 << 2) /* Emulate sample loop bug */
+#define XMP_FLAGS_A500		(1 << 3) /* Use Paula mixer in Amiga modules */
+
+/* player modes */
+#define XMP_MODE_AUTO		0	/* Autodetect mode (default) */
+#define XMP_MODE_MOD		1	/* Play as a generic MOD player */
+#define XMP_MODE_NOISETRACKER	2	/* Play using Noisetracker quirks */
+#define XMP_MODE_PROTRACKER	3	/* Play using Protracker quirks */
+#define XMP_MODE_S3M		4	/* Play as a generic S3M player */
+#define XMP_MODE_ST3		5	/* Play using ST3 bug emulation */
+#define XMP_MODE_ST3GUS		6	/* Play using ST3+GUS quirks */
+#define XMP_MODE_XM		7	/* Play as a generic XM player */
+#define XMP_MODE_FT2		8	/* Play using FT2 bug emulation */
+#define XMP_MODE_IT		9	/* Play using IT quirks */
+#define XMP_MODE_ITSMP		10	/* Play using IT sample mode quirks */
+
+/* mixer types */
+#define XMP_MIXER_STANDARD	0	/* Standard mixer */
+#define XMP_MIXER_A500		1	/* Amiga 500 */
+#define XMP_MIXER_A500F		2	/* Amiga 500 with led filter */
+
+/* sample flags */
+#define XMP_SMPCTL_SKIP		(1 << 0) /* Don't load samples */
+
+/* limits */
+#define XMP_MAX_KEYS		121	/* Number of valid keys */
+#define XMP_MAX_ENV_POINTS	32	/* Max number of envelope points */
+#define XMP_MAX_MOD_LENGTH	256	/* Max number of patterns in module */
+#define XMP_MAX_CHANNELS	64	/* Max number of channels in module */
+#define XMP_MAX_SRATE		49170	/* max sampling rate (Hz) */
+#define XMP_MIN_SRATE		4000	/* min sampling rate (Hz) */
+#define XMP_MIN_BPM		20	/* min BPM */
+/* frame rate = (50 * bpm / 125) Hz */
+/* frame size = (sampling rate * channels * size) / frame rate */
+#define XMP_MAX_FRAMESIZE	(5 * XMP_MAX_SRATE * 2 / XMP_MIN_BPM)
+
+/* error codes */
+#define XMP_END			1
+#define XMP_ERROR_INTERNAL	2	/* Internal error */
+#define XMP_ERROR_FORMAT	3	/* Unsupported module format */
+#define XMP_ERROR_LOAD		4	/* Error loading file */
+#define XMP_ERROR_DEPACK	5	/* Error depacking file */
+#define XMP_ERROR_SYSTEM	6	/* System error */
+#define XMP_ERROR_INVALID	7	/* Invalid parameter */
+#define XMP_ERROR_STATE		8	/* Invalid player state */
+
+struct xmp_channel {
+	int pan;			/* Channel pan (0x80 is center) */
+	int vol;			/* Channel volume */
+#define XMP_CHANNEL_SYNTH	(1 << 0)  /* Channel is synthesized */
+#define XMP_CHANNEL_MUTE  	(1 << 1)  /* Channel is muted */
+#define XMP_CHANNEL_SPLIT	(1 << 2)  /* Split Amiga channel in bits 5-4 */
+#define XMP_CHANNEL_SURROUND	(1 << 4)  /* Surround channel */
+	int flg;			/* Channel flags */
+};
+
+struct xmp_pattern {
+	int rows;			/* Number of rows */
+	int index[1];			/* Track index */
+};
+
+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 */
+};
+
+struct xmp_track {
+	int rows;			/* Number of rows */
+	struct xmp_event event[1];	/* Event data */
+};
+
+struct xmp_envelope {
+#define XMP_ENVELOPE_ON		(1 << 0)  /* Envelope is enabled */
+#define XMP_ENVELOPE_SUS	(1 << 1)  /* Envelope has sustain point */
+#define XMP_ENVELOPE_LOOP	(1 << 2)  /* Envelope has loop */
+#define XMP_ENVELOPE_FLT	(1 << 3)  /* Envelope is used for filter */
+#define XMP_ENVELOPE_SLOOP	(1 << 4)  /* Envelope has sustain loop */
+#define XMP_ENVELOPE_CARRY	(1 << 5)  /* Don't reset envelope position */
+	int flg;			/* Flags */
+	int npt;			/* Number of envelope points */
+	int scl;			/* Envelope scaling */
+	int sus;			/* Sustain start point */
+	int sue;			/* Sustain end point */
+	int lps;			/* Loop start point */
+	int lpe;			/* Loop end point */
+	short data[XMP_MAX_ENV_POINTS * 2];
+};
+
+struct xmp_instrument {
+	char name[32];			/* Instrument name */
+	int vol;			/* Instrument volume */
+	int nsm;			/* Number of samples */
+	int rls;			/* Release (fadeout) */
+	struct xmp_envelope aei;	/* Amplitude envelope info */
+	struct xmp_envelope pei;	/* Pan envelope info */
+	struct xmp_envelope fei;	/* Frequency envelope info */
+
+	struct {
+		unsigned char ins;	/* Instrument number for each key */
+		signed char xpo;	/* Instrument transpose for each key */
+	} map[XMP_MAX_KEYS];
+
+	struct xmp_subinstrument {
+		int vol;		/* Default volume */
+		int gvl;		/* Global volume */
+		int pan;		/* Pan */
+		int xpo;		/* Transpose */
+		int fin;		/* Finetune */
+		int vwf;		/* Vibrato waveform */
+		int vde;		/* Vibrato depth */
+		int vra;		/* Vibrato rate */
+		int vsw;		/* Vibrato sweep */
+		int rvv;		/* Random volume/pan variation (IT) */
+		int sid;		/* Sample number */
+#define XMP_INST_NNA_CUT	0x00
+#define XMP_INST_NNA_CONT	0x01
+#define XMP_INST_NNA_OFF	0x02
+#define XMP_INST_NNA_FADE	0x03
+		int nna;		/* New note action */
+#define XMP_INST_DCT_OFF	0x00
+#define XMP_INST_DCT_NOTE	0x01
+#define XMP_INST_DCT_SMP	0x02
+#define XMP_INST_DCT_INST	0x03
+		int dct;		/* Duplicate check type */
+#define XMP_INST_DCA_CUT	XMP_INST_NNA_CUT
+#define XMP_INST_DCA_OFF	XMP_INST_NNA_OFF
+#define XMP_INST_DCA_FADE	XMP_INST_NNA_FADE
+		int dca;		/* Duplicate check action */
+		int ifc;		/* Initial filter cutoff */
+		int ifr;		/* Initial filter resonance */
+	} *sub;
+
+	void *extra;			/* Extra fields */
+};
+
+struct xmp_sample {
+	char name[32];			/* Sample name */
+	int len;			/* Sample length */
+	int lps;			/* Loop start */
+	int lpe;			/* Loop end */
+#define XMP_SAMPLE_16BIT	(1 << 0)  /* 16bit sample */
+#define XMP_SAMPLE_LOOP		(1 << 1)  /* Sample is looped */
+#define XMP_SAMPLE_LOOP_BIDIR	(1 << 2)  /* Bidirectional sample loop */
+#define XMP_SAMPLE_LOOP_REVERSE	(1 << 3)  /* Backwards sample loop */
+#define XMP_SAMPLE_LOOP_FULL	(1 << 4)  /* Play full sample before looping */
+#define XMP_SAMPLE_SLOOP	(1 << 5)  /* Sample has sustain loop */
+#define XMP_SAMPLE_SLOOP_BIDIR	(1 << 6)  /* Bidirectional sustain loop */
+#define XMP_SAMPLE_SYNTH	(1 << 15) /* Data contains synth patch */
+	int flg;			/* Flags */
+	unsigned char *data;		/* Sample data */
+};
+
+struct xmp_sequence {
+	int entry_point;
+	int duration;
+};
+
+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 */
+
+	struct xmp_pattern **xxp;	/* Patterns */
+	struct xmp_track **xxt;		/* Tracks */
+	struct xmp_instrument *xxi;	/* Instruments */
+	struct xmp_sample *xxs;		/* Samples */
+	struct xmp_channel xxc[XMP_MAX_CHANNELS]; /* Channel info */
+	unsigned char xxo[XMP_MAX_MOD_LENGTH];	/* Orders */
+};
+
+struct xmp_test_info {
+	char name[XMP_NAME_SIZE];	/* Module title */
+	char type[XMP_NAME_SIZE];	/* Module format */
+};
+
+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_frame_info {			/* Current frame information */
+	int pos;			/* Current position */
+	int pattern;			/* Current pattern */
+	int row;			/* Current row in pattern */
+	int num_rows;			/* Number of rows in current pattern */
+	int frame;			/* Current frame */
+	int speed;			/* Current replay speed */
+	int bpm;			/* Current bpm */
+	int time;			/* Current module time in ms */
+	int total_time;			/* Estimated replay time in ms*/
+	int frame_time;			/* Frame replay time in us */
+	void *buffer;			/* Pointer to sound buffer */
+	int buffer_size;		/* Used buffer size */
+	int total_size;			/* Total buffer size */
+	int volume;			/* Current master volume */
+	int loop_count;			/* Loop counter */
+	int virt_channels;		/* Number of virtual channels */
+	int virt_used;			/* Used virtual channels */
+	int sequence;			/* Current sequence */
+
+	struct xmp_channel_info {	/* Current channel information */
+		unsigned int period;	/* Sample period (* 4096) */
+		unsigned int position;	/* Sample position */
+		short pitchbend;	/* Linear bend from base note*/
+		unsigned char note;	/* Current base note number */
+		unsigned char instrument; /* Current instrument number */
+		unsigned char sample;	/* Current sample number */
+		unsigned char volume;	/* Current volume */
+		unsigned char pan;	/* Current stereo pan */
+		unsigned char reserved;	/* Reserved */
+		struct xmp_event event;	/* Current track event */
+	} channel_info[XMP_MAX_CHANNELS];
+};
+
+
+typedef char *xmp_context;
+
+EXPORT extern const char *xmp_version;
+EXPORT extern const unsigned int xmp_vercode;
+
+EXPORT xmp_context xmp_create_context  (void);
+EXPORT void        xmp_free_context    (xmp_context);
+EXPORT int         xmp_test_module     (char *, struct xmp_test_info *);
+EXPORT int         xmp_load_module     (xmp_context, char *);
+EXPORT void        xmp_scan_module     (xmp_context);
+EXPORT void        xmp_release_module  (xmp_context);
+EXPORT int         xmp_start_player    (xmp_context, int, int);
+EXPORT int         xmp_play_frame      (xmp_context);
+EXPORT int         xmp_play_buffer     (xmp_context, void *, int, int);
+EXPORT void        xmp_get_frame_info  (xmp_context, struct xmp_frame_info *);
+EXPORT void        xmp_end_player      (xmp_context);
+EXPORT void        xmp_inject_event    (xmp_context, int, struct xmp_event *);
+EXPORT void        xmp_get_module_info (xmp_context, struct xmp_module_info *);
+EXPORT char      **xmp_get_format_list (void);
+EXPORT int         xmp_next_position   (xmp_context);
+EXPORT int         xmp_prev_position   (xmp_context);
+EXPORT int         xmp_set_position    (xmp_context, int);
+EXPORT void        xmp_stop_module     (xmp_context);
+EXPORT void        xmp_restart_module  (xmp_context);
+EXPORT int         xmp_seek_time       (xmp_context, int);
+EXPORT int         xmp_channel_mute    (xmp_context, int, int);
+EXPORT int         xmp_channel_vol     (xmp_context, int, int);
+EXPORT int         xmp_set_player      (xmp_context, int, int);
+EXPORT int         xmp_get_player      (xmp_context, int);
+EXPORT int         xmp_set_instrument_path (xmp_context, char *);
+EXPORT int         xmp_load_module_from_memory (xmp_context, void *, long);
+EXPORT int         xmp_load_module_from_file (xmp_context, void *, long);
+
+/* External sample mixer API */
+EXPORT int         xmp_start_smix       (xmp_context, int, int);
+EXPORT void        xmp_end_smix         (xmp_context);
+EXPORT int         xmp_smix_play_instrument(xmp_context, int, int, int, int);
+EXPORT int         xmp_smix_play_sample (xmp_context, int, int, int, int);
+EXPORT int         xmp_smix_channel_pan (xmp_context, int, int);
+EXPORT int         xmp_smix_load_sample (xmp_context, int, char *);
+EXPORT int         xmp_smix_release_sample (xmp_context, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* XMP_H */
diff --git a/Windows/codecs/x64/libxmp.dll b/Windows/codecs/x64/libxmp.dll
new file mode 100644
index 00000000..3cd61103
Binary files /dev/null and b/Windows/codecs/x64/libxmp.dll differ
diff --git a/Windows/codecs/x64/libxmp.dll.a b/Windows/codecs/x64/libxmp.dll.a
new file mode 100644
index 00000000..abe2da52
Binary files /dev/null and b/Windows/codecs/x64/libxmp.dll.a differ
diff --git a/Windows/codecs/x64/libxmp.lib b/Windows/codecs/x64/libxmp.lib
new file mode 100644
index 00000000..c3d388a0
Binary files /dev/null and b/Windows/codecs/x64/libxmp.lib differ
diff --git a/Windows/codecs/x86/libxmp.dll b/Windows/codecs/x86/libxmp.dll
new file mode 100644
index 00000000..d2d5b2e4
Binary files /dev/null and b/Windows/codecs/x86/libxmp.dll differ
diff --git a/Windows/codecs/x86/libxmp.dll.a b/Windows/codecs/x86/libxmp.dll.a
new file mode 100644
index 00000000..7d25914a
Binary files /dev/null and b/Windows/codecs/x86/libxmp.dll.a differ
diff --git a/Windows/codecs/x86/libxmp.lib b/Windows/codecs/x86/libxmp.lib
new file mode 100644
index 00000000..eb373f7d
Binary files /dev/null and b/Windows/codecs/x86/libxmp.lib differ