mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-10 23:02:03 +00:00
Add support for MOD, XM, IT, and S3M tracker music through libxmp-lite.
Building with support must be manually enabled by invoking make with HAVE_XMP=1 on platforms other than Windows, because libxmp-lite is not common in package managers. This setup will be improved in the future. git-svn-id: https://svn.eduke32.com/eduke32@5927 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
2fea171ad7
commit
4ca5e25e2c
10 changed files with 736 additions and 6 deletions
|
@ -163,6 +163,7 @@ AUDIOLIB_OBJS = \
|
||||||
vorbis \
|
vorbis \
|
||||||
flac \
|
flac \
|
||||||
xa \
|
xa \
|
||||||
|
xmp \
|
||||||
driver_nosound \
|
driver_nosound \
|
||||||
|
|
||||||
AUDIOLIB_ROOT=$(DUKE3D_SRC)/jaudiolib
|
AUDIOLIB_ROOT=$(DUKE3D_SRC)/jaudiolib
|
||||||
|
@ -471,16 +472,25 @@ ifneq (0,$(LUNATIC))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(SUBPLATFORM),LINUX)
|
ifeq ($(SUBPLATFORM),LINUX)
|
||||||
|
ifneq (0,$(HAVE_XMP))
|
||||||
|
LIBS += -lxmp-lite
|
||||||
|
endif
|
||||||
LIBS += -lFLAC -lvorbisfile -lvorbis -logg
|
LIBS += -lFLAC -lvorbisfile -lvorbis -logg
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(PLATFORM),BSD)
|
ifeq ($(PLATFORM),BSD)
|
||||||
|
ifneq (0,$(HAVE_XMP))
|
||||||
|
LIBS += -lxmp-lite
|
||||||
|
endif
|
||||||
LIBS += -lFLAC -lvorbisfile -lvorbis -logg -lexecinfo
|
LIBS += -lFLAC -lvorbisfile -lvorbis -logg -lexecinfo
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(PLATFORM),DARWIN)
|
ifeq ($(PLATFORM),DARWIN)
|
||||||
# LIBDIRS += -L$(AUDIOLIB_ROOT)/third-party/Apple/lib
|
# LIBDIRS += -L$(AUDIOLIB_ROOT)/third-party/Apple/lib
|
||||||
|
|
||||||
|
ifneq (0,$(HAVE_XMP))
|
||||||
|
LIBS += -lxmp-lite
|
||||||
|
endif
|
||||||
LIBS += -lFLAC -lvorbisfile -lvorbis -logg -lm \
|
LIBS += -lFLAC -lvorbisfile -lvorbis -logg -lm \
|
||||||
-Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,OpenGL \
|
-Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,OpenGL \
|
||||||
-Wl,-framework,CoreMIDI -Wl,-framework,AudioUnit \
|
-Wl,-framework,CoreMIDI -Wl,-framework,AudioUnit \
|
||||||
|
@ -495,6 +505,9 @@ ifeq ($(PLATFORM),DARWIN)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(PLATFORM),WINDOWS)
|
ifeq ($(PLATFORM),WINDOWS)
|
||||||
|
ifneq (0,$(HAVE_XMP))
|
||||||
|
LIBS += -lxmp-lite
|
||||||
|
endif
|
||||||
LIBS += -lFLAC -lvorbisfile -lvorbis -logg
|
LIBS += -lFLAC -lvorbisfile -lvorbis -logg
|
||||||
LIBDIRS += -L$(AUDIOLIB_ROOT)/third-party/Windows/lib$(WINLIB)
|
LIBDIRS += -L$(AUDIOLIB_ROOT)/third-party/Windows/lib$(WINLIB)
|
||||||
DUKE3D_GAME_OBJS+= gameres winbits startwin.game
|
DUKE3D_GAME_OBJS+= gameres winbits startwin.game
|
||||||
|
|
|
@ -181,6 +181,11 @@ USE_LIBPNG ?= 1
|
||||||
USE_LIBVPX ?= 1
|
USE_LIBVPX ?= 1
|
||||||
HAVE_VORBIS ?= 1
|
HAVE_VORBIS ?= 1
|
||||||
HAVE_FLAC ?= 1
|
HAVE_FLAC ?= 1
|
||||||
|
ifeq ($(PLATFORM),WINDOWS)
|
||||||
|
HAVE_XMP ?= 1
|
||||||
|
else
|
||||||
|
HAVE_XMP ?= 0
|
||||||
|
endif
|
||||||
NETCODE ?= 1
|
NETCODE ?= 1
|
||||||
|
|
||||||
LUNATIC ?= 0
|
LUNATIC ?= 0
|
||||||
|
@ -424,6 +429,7 @@ ifeq ($(PLATFORM),WII)
|
||||||
override USE_LIBVPX = 0
|
override USE_LIBVPX = 0
|
||||||
override NETCODE = 0
|
override NETCODE = 0
|
||||||
override HAVE_FLAC = 0
|
override HAVE_FLAC = 0
|
||||||
|
override HAVE_XMP = 0
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM),GCW)
|
ifeq ($(PLATFORM),GCW)
|
||||||
override USE_LIBVPX = 0
|
override USE_LIBVPX = 0
|
||||||
|
@ -654,6 +660,9 @@ endif
|
||||||
ifneq (0,$(HAVE_FLAC))
|
ifneq (0,$(HAVE_FLAC))
|
||||||
COMPILERFLAGS+= -DHAVE_FLAC
|
COMPILERFLAGS+= -DHAVE_FLAC
|
||||||
endif
|
endif
|
||||||
|
ifneq (0,$(HAVE_XMP))
|
||||||
|
COMPILERFLAGS+= -DHAVE_XMP
|
||||||
|
endif
|
||||||
ifneq (0,$(EFENCE))
|
ifneq (0,$(EFENCE))
|
||||||
LIBS+= -lefence
|
LIBS+= -lefence
|
||||||
COMPILERFLAGS+= -DEFENCE
|
COMPILERFLAGS+= -DEFENCE
|
||||||
|
|
358
polymer/eduke32/platform/Windows/include/libxmp-lite/xmp.h
Normal file
358
polymer/eduke32/platform/Windows/include/libxmp-lite/xmp.h
Normal file
|
@ -0,0 +1,358 @@
|
||||||
|
#ifndef XMP_H
|
||||||
|
#define XMP_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define XMP_VERSION "4.4.1"
|
||||||
|
#define XMP_VERCODE 0x040401
|
||||||
|
#define XMP_VER_MAJOR 4
|
||||||
|
#define XMP_VER_MINOR 4
|
||||||
|
#define XMP_VER_RELEASE 1
|
||||||
|
|
||||||
|
#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 __GNUC__ >= 4 || defined(__HP_cc)
|
||||||
|
# define EXPORT __attribute__((visibility ("default")))
|
||||||
|
#elif defined(__SUNPRO_C)
|
||||||
|
# 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 */
|
BIN
polymer/eduke32/platform/Windows/lib/32/libxmp-lite.a
Normal file
BIN
polymer/eduke32/platform/Windows/lib/32/libxmp-lite.a
Normal file
Binary file not shown.
BIN
polymer/eduke32/platform/Windows/lib/64/libxmp-lite.a
Normal file
BIN
polymer/eduke32/platform/Windows/lib/64/libxmp-lite.a
Normal file
Binary file not shown.
|
@ -87,6 +87,7 @@ typedef enum
|
||||||
FMT_VORBIS,
|
FMT_VORBIS,
|
||||||
FMT_FLAC,
|
FMT_FLAC,
|
||||||
FMT_XA,
|
FMT_XA,
|
||||||
|
FMT_XMP,
|
||||||
FMT_MAX
|
FMT_MAX
|
||||||
} wavefmt_t;
|
} wavefmt_t;
|
||||||
|
|
||||||
|
@ -146,6 +147,12 @@ int32_t MV_PlayXA3D(char *ptr, uint32_t length, int32_t loophow, int32_t pitchof
|
||||||
int32_t priority, uint32_t callbackval);
|
int32_t priority, uint32_t callbackval);
|
||||||
int32_t MV_PlayXA(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend, int32_t pitchoffset, int32_t vol,
|
int32_t MV_PlayXA(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend, int32_t pitchoffset, int32_t vol,
|
||||||
int32_t left, int32_t right, int32_t priority, uint32_t callbackval);
|
int32_t left, int32_t right, int32_t priority, uint32_t callbackval);
|
||||||
|
int32_t MV_PlayXMP3D(char *ptr, uint32_t length, int32_t loophow, int32_t pitchoffset, int32_t angle, int32_t distance,
|
||||||
|
int32_t priority, uint32_t callbackval);
|
||||||
|
int32_t MV_PlayXMP(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend, int32_t pitchoffset, int32_t vol,
|
||||||
|
int32_t left, int32_t right, int32_t priority, uint32_t callbackval);
|
||||||
|
|
||||||
|
int MV_IdentifyXMP(char const *ptr, uint32_t length);
|
||||||
|
|
||||||
int32_t MV_GetPosition(int32_t handle, int32_t *position);
|
int32_t MV_GetPosition(int32_t handle, int32_t *position);
|
||||||
int32_t MV_SetPosition(int32_t handle, int32_t position);
|
int32_t MV_SetPosition(int32_t handle, int32_t position);
|
||||||
|
|
|
@ -169,10 +169,13 @@ int32_t MV_GetFLACPosition(VoiceNode *voice);
|
||||||
void MV_SetFLACPosition(VoiceNode *voice, int32_t position);
|
void MV_SetFLACPosition(VoiceNode *voice, int32_t position);
|
||||||
int32_t MV_GetXAPosition(VoiceNode *voice);
|
int32_t MV_GetXAPosition(VoiceNode *voice);
|
||||||
void MV_SetXAPosition(VoiceNode *voice, int32_t position);
|
void MV_SetXAPosition(VoiceNode *voice, int32_t position);
|
||||||
|
int32_t MV_GetXMPPosition(VoiceNode *voice);
|
||||||
|
void MV_SetXMPPosition(VoiceNode *voice, int32_t position);
|
||||||
|
|
||||||
void MV_ReleaseVorbisVoice(VoiceNode *voice);
|
void MV_ReleaseVorbisVoice(VoiceNode *voice);
|
||||||
void MV_ReleaseFLACVoice(VoiceNode *voice);
|
void MV_ReleaseFLACVoice(VoiceNode *voice);
|
||||||
void MV_ReleaseXAVoice(VoiceNode *voice);
|
void MV_ReleaseXAVoice(VoiceNode *voice);
|
||||||
|
void MV_ReleaseXMPVoice(VoiceNode *voice);
|
||||||
|
|
||||||
// implemented in mix.c
|
// implemented in mix.c
|
||||||
void MV_Mix16BitMono(uint32_t position, uint32_t rate, const char *start, uint32_t length);
|
void MV_Mix16BitMono(uint32_t position, uint32_t rate, const char *start, uint32_t length);
|
||||||
|
|
|
@ -133,6 +133,11 @@ static wavefmt_t FX_DetectFormat(char const * const ptr, uint32_t length)
|
||||||
fmt = FMT_WAV;
|
fmt = FMT_WAV;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (MV_IdentifyXMP(ptr, length))
|
||||||
|
{
|
||||||
|
fmt = FMT_XMP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,10 +147,10 @@ static wavefmt_t FX_DetectFormat(char const * const ptr, uint32_t length)
|
||||||
int32_t FX_Play(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend, int32_t pitchoffset,
|
int32_t FX_Play(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend, int32_t pitchoffset,
|
||||||
int32_t vol, int32_t left, int32_t right, int32_t priority, uint32_t callbackval)
|
int32_t vol, int32_t left, int32_t right, int32_t priority, uint32_t callbackval)
|
||||||
{
|
{
|
||||||
EDUKE32_STATIC_ASSERT(FMT_MAX == 7);
|
static int32_t(*const func[])(char *, uint32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, uint32_t) =
|
||||||
|
{ NULL, NULL, MV_PlayVOC, MV_PlayWAV, MV_PlayVorbis, MV_PlayFLAC, MV_PlayXA, MV_PlayXMP };
|
||||||
|
|
||||||
static int32_t(*const func[FMT_MAX])(char *, uint32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, int32_t, uint32_t) =
|
EDUKE32_STATIC_ASSERT(FMT_MAX == ARRAY_SIZE(func));
|
||||||
{ NULL, NULL, MV_PlayVOC, MV_PlayWAV, MV_PlayVorbis, MV_PlayFLAC, MV_PlayXA };
|
|
||||||
|
|
||||||
wavefmt_t const fmt = FX_DetectFormat(ptr, length);
|
wavefmt_t const fmt = FX_DetectFormat(ptr, length);
|
||||||
|
|
||||||
|
@ -164,10 +169,10 @@ int32_t FX_Play(char *ptr, uint32_t length, int32_t loopstart, int32_t loopend,
|
||||||
int32_t FX_Play3D(char *ptr, uint32_t length, int32_t loophow, int32_t pitchoffset, int32_t angle, int32_t distance,
|
int32_t FX_Play3D(char *ptr, uint32_t length, int32_t loophow, int32_t pitchoffset, int32_t angle, int32_t distance,
|
||||||
int32_t priority, uint32_t callbackval)
|
int32_t priority, uint32_t callbackval)
|
||||||
{
|
{
|
||||||
EDUKE32_STATIC_ASSERT(FMT_MAX == 7);
|
static int32_t (*const func[])(char *, uint32_t, int32_t, int32_t, int32_t, int32_t, int32_t, uint32_t) =
|
||||||
|
{ NULL, NULL, MV_PlayVOC3D, MV_PlayWAV3D, MV_PlayVorbis3D, MV_PlayFLAC3D, MV_PlayXA3D, MV_PlayXMP3D };
|
||||||
|
|
||||||
static int32_t (*const func[FMT_MAX])(char *, uint32_t, int32_t, int32_t, int32_t, int32_t, int32_t, uint32_t) =
|
EDUKE32_STATIC_ASSERT(FMT_MAX == ARRAY_SIZE(func));
|
||||||
{ NULL, NULL, MV_PlayVOC3D, MV_PlayWAV3D, MV_PlayVorbis3D, MV_PlayFLAC3D, MV_PlayXA3D };
|
|
||||||
|
|
||||||
wavefmt_t const fmt = FX_DetectFormat(ptr, length);
|
wavefmt_t const fmt = FX_DetectFormat(ptr, length);
|
||||||
|
|
||||||
|
|
|
@ -229,6 +229,9 @@ static void MV_StopVoice(VoiceNode *voice)
|
||||||
case FMT_FLAC: MV_ReleaseFLACVoice(voice); break;
|
case FMT_FLAC: MV_ReleaseFLACVoice(voice); break;
|
||||||
#endif
|
#endif
|
||||||
case FMT_XA: MV_ReleaseXAVoice(voice); break;
|
case FMT_XA: MV_ReleaseXAVoice(voice); break;
|
||||||
|
#ifdef HAVE_XMP
|
||||||
|
case FMT_XMP: MV_ReleaseXMPVoice(voice); break;
|
||||||
|
#endif
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,6 +331,9 @@ static void MV_ServiceVoc(void)
|
||||||
case FMT_FLAC: MV_ReleaseFLACVoice(voice); break;
|
case FMT_FLAC: MV_ReleaseFLACVoice(voice); break;
|
||||||
#endif
|
#endif
|
||||||
case FMT_XA: MV_ReleaseXAVoice(voice); break;
|
case FMT_XA: MV_ReleaseXAVoice(voice); break;
|
||||||
|
#ifdef HAVE_XMP
|
||||||
|
case FMT_XMP: MV_ReleaseXMPVoice(voice); break;
|
||||||
|
#endif
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,6 +697,9 @@ int32_t MV_GetPosition(int32_t handle, int32_t *position)
|
||||||
case FMT_FLAC: *position = MV_GetFLACPosition(voice); break;
|
case FMT_FLAC: *position = MV_GetFLACPosition(voice); break;
|
||||||
#endif
|
#endif
|
||||||
case FMT_XA: *position = MV_GetXAPosition(voice); break;
|
case FMT_XA: *position = MV_GetXAPosition(voice); break;
|
||||||
|
#ifdef HAVE_XMP
|
||||||
|
case FMT_XMP: *position = MV_GetXMPPosition(voice); break;
|
||||||
|
#endif
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,6 +724,9 @@ int32_t MV_SetPosition(int32_t handle, int32_t position)
|
||||||
case FMT_FLAC: MV_SetFLACPosition(voice, position); break;
|
case FMT_FLAC: MV_SetFLACPosition(voice, position); break;
|
||||||
#endif
|
#endif
|
||||||
case FMT_XA: MV_SetXAPosition(voice, position); break;
|
case FMT_XA: MV_SetXAPosition(voice, position); break;
|
||||||
|
#ifdef HAVE_XMP
|
||||||
|
case FMT_XMP: MV_SetXMPPosition(voice, position); break;
|
||||||
|
#endif
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
323
polymer/eduke32/source/jaudiolib/src/xmp.c
Normal file
323
polymer/eduke32/source/jaudiolib/src/xmp.c
Normal file
|
@ -0,0 +1,323 @@
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_XMP
|
||||||
|
|
||||||
|
#include "pitch.h"
|
||||||
|
#include "multivoc.h"
|
||||||
|
#include "_multivc.h"
|
||||||
|
|
||||||
|
#define BUILDING_STATIC
|
||||||
|
#include "libxmp-lite/xmp.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void * ptr;
|
||||||
|
VoiceNode *owner;
|
||||||
|
size_t length;
|
||||||
|
xmp_context context;
|
||||||
|
int time;
|
||||||
|
} xmp_data;
|
||||||
|
|
||||||
|
int32_t MV_GetXMPPosition(VoiceNode *voice)
|
||||||
|
{
|
||||||
|
xmp_data * xmpd = (xmp_data *)voice->rawdataptr;
|
||||||
|
return xmpd->time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MV_SetXMPPosition(VoiceNode *voice, int32_t position)
|
||||||
|
{
|
||||||
|
xmp_data * xmpd = (xmp_data *)voice->rawdataptr;
|
||||||
|
xmp_seek_time(xmpd->context, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
static playbackstatus MV_GetNextXMPBlock(VoiceNode *voice)
|
||||||
|
{
|
||||||
|
xmp_data * xmpd = (xmp_data *)voice->rawdataptr;
|
||||||
|
struct xmp_frame_info mi;
|
||||||
|
|
||||||
|
if (xmp_play_frame(xmpd->context) != 0)
|
||||||
|
{
|
||||||
|
if (voice->LoopSize > 0)
|
||||||
|
{
|
||||||
|
xmp_restart_module(xmpd->context);
|
||||||
|
if (xmp_play_frame(xmpd->context) != 0)
|
||||||
|
{
|
||||||
|
voice->Playing = FALSE;
|
||||||
|
return NoMoreData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
voice->Playing = FALSE;
|
||||||
|
return NoMoreData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xmp_get_frame_info(xmpd->context, &mi);
|
||||||
|
|
||||||
|
xmpd->time = mi.time;
|
||||||
|
|
||||||
|
voice->sound = (char const *)mi.buffer;
|
||||||
|
voice->length = mi.buffer_size << 14; // since 2-channel, 16-bit is hardcoded
|
||||||
|
// voice->length = (mi.buffer_size << 16) / (voice->channels * (voice->bits >> 3));
|
||||||
|
voice->position = 0;
|
||||||
|
voice->BlockLength = 0;
|
||||||
|
voice->Playing = TRUE;
|
||||||
|
|
||||||
|
MV_SetVoiceMixMode(voice);
|
||||||
|
|
||||||
|
return KeepPlaying;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t MV_PlayXMP3D(char *ptr, uint32_t ptrlength, int32_t loophow, int32_t pitchoffset, int32_t angle,
|
||||||
|
int32_t distance, int32_t priority, uint32_t callbackval)
|
||||||
|
{
|
||||||
|
int32_t left;
|
||||||
|
int32_t right;
|
||||||
|
int32_t mid;
|
||||||
|
int32_t volume;
|
||||||
|
int32_t status;
|
||||||
|
|
||||||
|
if (!MV_Installed)
|
||||||
|
{
|
||||||
|
MV_SetErrorCode(MV_NotInstalled);
|
||||||
|
return MV_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (distance < 0)
|
||||||
|
{
|
||||||
|
distance = -distance;
|
||||||
|
angle += MV_NUMPANPOSITIONS / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
volume = MIX_VOLUME(distance);
|
||||||
|
|
||||||
|
// Ensure angle is within 0 - 127
|
||||||
|
angle &= MV_MAXPANPOSITION;
|
||||||
|
|
||||||
|
left = MV_PanTable[angle][volume].left;
|
||||||
|
right = MV_PanTable[angle][volume].right;
|
||||||
|
mid = max( 0, 255 - distance );
|
||||||
|
|
||||||
|
status = MV_PlayXMP(ptr, ptrlength, loophow, -1, pitchoffset, mid, left, right, priority, callbackval);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t MV_PlayXMP(char *ptr, uint32_t ptrlength, int32_t loopstart, int32_t loopend, int32_t pitchoffset, int32_t vol,
|
||||||
|
int32_t left, int32_t right, int32_t priority, uint32_t callbackval)
|
||||||
|
{
|
||||||
|
VoiceNode *voice;
|
||||||
|
xmp_data * xmpd = 0;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
UNREFERENCED_PARAMETER(loopend);
|
||||||
|
|
||||||
|
if (!MV_Installed)
|
||||||
|
{
|
||||||
|
MV_SetErrorCode(MV_NotInstalled);
|
||||||
|
return MV_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmpd = (xmp_data *)calloc(1, sizeof(xmp_data));
|
||||||
|
if (!xmpd)
|
||||||
|
{
|
||||||
|
MV_SetErrorCode(MV_InvalidFile);
|
||||||
|
return MV_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmpd->ptr = ptr;
|
||||||
|
xmpd->length = ptrlength;
|
||||||
|
|
||||||
|
if ((xmpd->context = xmp_create_context()) == NULL)
|
||||||
|
{
|
||||||
|
free(xmpd);
|
||||||
|
MV_SetErrorCode(MV_InvalidFile);
|
||||||
|
return MV_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((retval = xmp_load_module_from_memory(xmpd->context, ptr, ptrlength)) != 0)
|
||||||
|
{
|
||||||
|
MV_Printf("MV_PlayXMP: xmp_load_module_from_memory failed (%i)\n", retval);
|
||||||
|
MV_SetErrorCode(MV_InvalidFile);
|
||||||
|
return MV_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request a voice from the voice pool
|
||||||
|
voice = MV_AllocVoice(priority);
|
||||||
|
if (voice == NULL)
|
||||||
|
{
|
||||||
|
xmp_release_module(xmpd->context);
|
||||||
|
xmp_free_context(xmpd->context);
|
||||||
|
free(xmpd);
|
||||||
|
MV_SetErrorCode(MV_NoVoices);
|
||||||
|
return MV_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmpd->owner = voice;
|
||||||
|
|
||||||
|
voice->wavetype = FMT_XMP;
|
||||||
|
voice->rawdataptr = (void*)xmpd;
|
||||||
|
voice->GetSound = MV_GetNextXMPBlock;
|
||||||
|
voice->LoopCount = 0;
|
||||||
|
voice->BlockLength = 0;
|
||||||
|
voice->PitchScale = PITCH_GetScale(pitchoffset);
|
||||||
|
voice->next = NULL;
|
||||||
|
voice->prev = NULL;
|
||||||
|
voice->priority = priority;
|
||||||
|
voice->callbackval = callbackval;
|
||||||
|
|
||||||
|
voice->bits = 16;
|
||||||
|
voice->channels = 2;
|
||||||
|
voice->SamplingRate = MV_MixRate;
|
||||||
|
|
||||||
|
voice->Playing = TRUE;
|
||||||
|
voice->Paused = FALSE;
|
||||||
|
|
||||||
|
voice->LoopStart = 0;
|
||||||
|
voice->LoopEnd = 0;
|
||||||
|
voice->LoopSize = loopstart >= 0 ? 1 : 0;
|
||||||
|
|
||||||
|
xmp_start_player(xmpd->context, MV_MixRate, 0);
|
||||||
|
|
||||||
|
// CODEDUP multivoc.c MV_SetVoicePitch
|
||||||
|
voice->RateScale = (voice->SamplingRate * voice->PitchScale) / MV_MixRate;
|
||||||
|
voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - voice->RateScale;
|
||||||
|
MV_SetVoiceMixMode(voice);
|
||||||
|
|
||||||
|
MV_SetVoiceVolume(voice, vol, left, right);
|
||||||
|
MV_PlayVoice(voice);
|
||||||
|
|
||||||
|
return voice->handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MV_ReleaseXMPVoice(VoiceNode * voice)
|
||||||
|
{
|
||||||
|
xmp_data * xmpd = (xmp_data *) voice->rawdataptr;
|
||||||
|
|
||||||
|
if (voice->wavetype != FMT_XMP)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xmp_end_player(xmpd->context);
|
||||||
|
xmp_release_module(xmpd->context);
|
||||||
|
xmp_free_context(xmpd->context);
|
||||||
|
free(xmpd);
|
||||||
|
|
||||||
|
voice->rawdataptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include "_multivc.h"
|
||||||
|
|
||||||
|
static char const NoXMP[] = "MV_PlayXMP: libxmp-lite support not included in this binary.\n";
|
||||||
|
|
||||||
|
int32_t MV_PlayXMP(char *ptr, uint32_t ptrlength, int32_t loopstart, int32_t loopend, int32_t pitchoffset, int32_t vol,
|
||||||
|
int32_t left, int32_t right, int32_t priority, uint32_t callbackval)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(ptr);
|
||||||
|
UNREFERENCED_PARAMETER(ptrlength);
|
||||||
|
UNREFERENCED_PARAMETER(loopstart);
|
||||||
|
UNREFERENCED_PARAMETER(loopend);
|
||||||
|
UNREFERENCED_PARAMETER(pitchoffset);
|
||||||
|
UNREFERENCED_PARAMETER(vol);
|
||||||
|
UNREFERENCED_PARAMETER(left);
|
||||||
|
UNREFERENCED_PARAMETER(right);
|
||||||
|
UNREFERENCED_PARAMETER(priority);
|
||||||
|
UNREFERENCED_PARAMETER(callbackval);
|
||||||
|
|
||||||
|
MV_Printf(NoXMP);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t MV_PlayXMP3D(char *ptr, uint32_t ptrlength, int32_t loophow, int32_t pitchoffset, int32_t angle,
|
||||||
|
int32_t distance, int32_t priority, uint32_t callbackval)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(ptr);
|
||||||
|
UNREFERENCED_PARAMETER(ptrlength);
|
||||||
|
UNREFERENCED_PARAMETER(loophow);
|
||||||
|
UNREFERENCED_PARAMETER(pitchoffset);
|
||||||
|
UNREFERENCED_PARAMETER(angle);
|
||||||
|
UNREFERENCED_PARAMETER(distance);
|
||||||
|
UNREFERENCED_PARAMETER(priority);
|
||||||
|
UNREFERENCED_PARAMETER(callbackval);
|
||||||
|
|
||||||
|
MV_Printf(NoXMP);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// KEEPINSYNC libxmp-lite/src/loaders/*_load.c
|
||||||
|
|
||||||
|
static int it_test_memory(char const *ptr, uint32_t ptrlength)
|
||||||
|
{
|
||||||
|
static char const it_magic[] = "IMPM";
|
||||||
|
|
||||||
|
if (ptrlength < sizeof(it_magic)-1 ||
|
||||||
|
memcmp(ptr, it_magic, sizeof(it_magic)-1))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mod_test_memory(char const *ptr, uint32_t ptrlength)
|
||||||
|
{
|
||||||
|
if (ptrlength < 1084)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
char const * const buf = ptr + 1080;
|
||||||
|
|
||||||
|
if (!strncmp(buf + 2, "CH", 2) && isdigit((int)buf[0]) && isdigit((int)buf[1]))
|
||||||
|
{
|
||||||
|
int i = (buf[0] - '0') * 10 + buf[1] - '0';
|
||||||
|
if (i > 0 && i <= 32)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(buf + 1, "CHN", 3) && isdigit((int)*buf))
|
||||||
|
{
|
||||||
|
if (*buf >= '0' && *buf <= '9')
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memcmp(buf, "M.K.", 4))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int s3m_test_memory(char const *ptr, uint32_t ptrlength)
|
||||||
|
{
|
||||||
|
static char const s3m_magic[] = "SCRM";
|
||||||
|
#define s3m_magic_offset 44
|
||||||
|
|
||||||
|
if (ptrlength < s3m_magic_offset + sizeof(s3m_magic)-1 ||
|
||||||
|
memcmp(ptr + s3m_magic_offset, s3m_magic, sizeof(s3m_magic)-1) ||
|
||||||
|
ptr[29] != 0x10)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xm_test_memory(char const *ptr, uint32_t ptrlength)
|
||||||
|
{
|
||||||
|
static char const xm_magic[] = "Extended Module: ";
|
||||||
|
|
||||||
|
if (ptrlength < sizeof(xm_magic)-1 ||
|
||||||
|
memcmp(ptr, xm_magic, sizeof(xm_magic)-1))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MV_IdentifyXMP(char const *ptr, uint32_t ptrlength)
|
||||||
|
{
|
||||||
|
return it_test_memory(ptr, ptrlength) == 0 ||
|
||||||
|
mod_test_memory(ptr, ptrlength) == 0 ||
|
||||||
|
s3m_test_memory(ptr, ptrlength) == 0 ||
|
||||||
|
xm_test_memory(ptr, ptrlength) == 0;
|
||||||
|
}
|
Loading…
Reference in a new issue