X-Git-Url: http://git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=snd_xmp.c;h=9876803d571fbcfc8c0922ba1d513b5100d1f2d5;hp=7fde6137ebb002e6512e86760e35e7a903d31b19;hb=415f1e0e46791994cfa2f6dd3a29f793e3bb9cd9;hpb=ac8080688588aba1ab7934f7ba0c2ffea0c8eb91
diff --git a/snd_xmp.c b/snd_xmp.c
index 7fde6137..9876803d 100644
--- a/snd_xmp.c
+++ b/snd_xmp.c
@@ -20,12 +20,16 @@
*/
-#include "quakedef.h"
+#include "darkplaces.h"
#include "snd_main.h"
#include "snd_xmp.h"
+#include "sound.h"
#ifdef LINK_TO_LIBXMP
#include
+#if ((XMP_VERCODE+0) < 0x040200)
+#error libxmp version 4.2 or newer is required when linking to libxmp
+#endif
/* libxmp API */
// Version and player information
@@ -36,7 +40,7 @@
#define qxmp_create_context xmp_create_context // xmp_context xmp_create_context()
#define qxmp_free_context xmp_free_context // void xmp_free_context(xmp_context c)
// Module loading
-#define qxmp_test_module xmp_test_module // int xmp_test_module(char *path, struct xmp_test_info *test_info)
+//#define qxmp_test_module xmp_test_module // int xmp_test_module(char *path, struct xmp_test_info *test_info)
//#define qxmp_load_module xmp_load_module // int xmp_load_module(xmp_context c, char *path)
#define qxmp_load_module_from_memory xmp_load_module_from_memory // int xmp_load_module_from_memory(xmp_context c, void *mem, long size)
//#define qxmp_load_module_from_file xmp_load_module_from_file // int xmp_load_module_from_file(xmp_context c, FILE *f, long size)
@@ -66,11 +70,7 @@
#define xmp_dll 1
-qboolean XMP_OpenLibrary (void)
-{
- Con_Printf("Linked against libxmp version %s (0x0%x)\n", qxmp_version, qxmp_vercode);
- return true;
-}
+qbool XMP_OpenLibrary (void) {return true;}
void XMP_CloseLibrary (void) {}
#else
@@ -122,8 +122,8 @@ void XMP_CloseLibrary (void) {}
//#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_MAX_SRATE 49170 /* max sampling rate (Hz) */
+#define XMP_MIN_SRATE 4000 /* min sampling rate (Hz) */
//#define XMP_MIN_BPM 20 /* min BPM */
#define XMP_MAX_FRAMESIZE (5 * XMP_MAX_SRATE * 2 / XMP_MIN_BPM)
@@ -144,11 +144,11 @@ static const char **qxmp_version;
static const unsigned int *qxmp_vercode;
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 */
-// int flg; /* Channel flags */
+ 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 */
+ int flg; /* Channel flags */
};
//struct xmp_sequence {
@@ -178,10 +178,10 @@ struct xmp_module {
unsigned char xxo[XMP_MAX_MOD_LENGTH]; /* Orders */
};
-struct xmp_test_info {
+//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 */
@@ -192,7 +192,8 @@ struct xmp_module_info {
struct xmp_sequence *seq_data; /* Pointer to sequence data */
};
-struct xmp_frame_info { /* Current frame information */
+struct xmp_frame_info
+// { /* Current frame information */
// int pos; /* Current position */
// int pattern; /* Current pattern */
// int row; /* Current row in pattern */
@@ -224,12 +225,13 @@ struct xmp_frame_info { /* Current frame information */
// unsigned char reserved; /* Reserved */
// struct xmp_event event; /* Current track event */
// } channel_info[XMP_MAX_CHANNELS];
-};
+//}
+;
// Functions exported from libxmp
static xmp_context (*qxmp_create_context) (void);
static void (*qxmp_free_context) (xmp_context);
-static int (*qxmp_test_module) (char *, struct xmp_test_info *);
+//static int (*qxmp_test_module) (char *, struct xmp_test_info *);
//static int (*qxmp_load_module) (xmp_context, char *);
//static void (*qxmp_scan_module) (xmp_context);
static void (*qxmp_release_module) (xmp_context);
@@ -287,7 +289,7 @@ static dllfunction_t xmpfuncs[] =
{"xmp_create_context", (void **) &qxmp_create_context},
{"xmp_free_context", (void **) &qxmp_free_context},
// Module loading
- {"xmp_test_module", (void **) &qxmp_test_module},
+// {"xmp_test_module", (void **) &qxmp_test_module},
// {"xmp_load_module", (void **) &qxmp_load_module},
{"xmp_load_module_from_memory", (void **) &qxmp_load_module_from_memory}, // since libxmp 4.2.0
// {"xmp_load_module_from_file", (void **) &qxmp_load_module_from_file}, // since libxmp 4.3.0
@@ -344,11 +346,12 @@ XMP_OpenLibrary
Try to load the libxmp DLL
====================
*/
-qboolean XMP_OpenLibrary (void)
+qbool XMP_OpenLibrary (void)
{
const char* dllnames_xmp [] =
{
#if defined(WIN32)
+ "libxmp-4.dll",
"libxmp.dll",
#elif defined(MACOSX) // FIXME: untested, please test a mac os build
"libxmp.4.dylib",
@@ -364,19 +367,20 @@ qboolean XMP_OpenLibrary (void)
return true;
// COMMANDLINEOPTION: Sound: -noxmp disables xmp module sound support
- if (COM_CheckParm("-noxmp"))
+ if (Sys_CheckParm("-noxmp"))
return false;
// Load the DLL
- if (Sys_LoadLibrary (dllnames_xmp, &xmp_dll, xmpfuncs))
+ if (Sys_LoadDependency (dllnames_xmp, &xmp_dll, xmpfuncs))
{
if (*qxmp_vercode < 0x040200)
{
Con_Printf("Found incompatible XMP library version %s, not loading. (4.2.0 or higher required)\n", *qxmp_version);
- Sys_UnloadLibrary (&xmp_dll);
+ Sys_FreeLibrary (&xmp_dll);
return false;
}
- Con_Printf("XMP library loaded, version %s (0x0%x)\n", *qxmp_version, *qxmp_vercode);
+ if (developer_loading.integer >= 1)
+ Con_Printf("XMP library loaded, version %s (0x0%x)\n", *qxmp_version, *qxmp_vercode);
return true;
}
else
@@ -393,7 +397,7 @@ Unload the libxmp DLL
*/
void XMP_CloseLibrary (void)
{
- Sys_UnloadLibrary (&xmp_dll);
+ Sys_FreeLibrary (&xmp_dll);
}
#endif
@@ -461,9 +465,22 @@ static void XMP_GetSamplesFloat(channel_t *ch, sfx_t *sfx, int firstsampleframe,
}
// start playing the loaded file
- if (sfx->format.width == 1) { format |= XMP_FORMAT_8BIT; } // else 16bit
+ if (sfx->format.width == 1) { format |= XMP_FORMAT_8BIT | XMP_FORMAT_UNSIGNED; } // else 16bit
if (sfx->format.channels == 1) { format |= XMP_FORMAT_MONO; } // else stereo
- if (qxmp_start_player(per_ch->playercontext, sfx->format.speed, format) < 0) // FIXME: only if speed is in XMP acceptable range, else default to 48khz and let DP mix
+
+ if (qxmp_start_player(per_ch->playercontext, sfx->format.speed, format) < 0)
+ {
+ Mem_Free(per_ch);
+ return;
+ }
+ /* percentual left/right channel separation, default is 70. */
+ if (sfx->format.channels == 2 && (qxmp_set_player(per_ch->playercontext, XMP_PLAYER_MIX, 50) != 0))
+ {
+ Mem_Free(per_ch);
+ return;
+ }
+ /* interpolation type, default is XMP_INTERP_LINEAR */
+ if (qxmp_set_player(per_ch->playercontext, XMP_PLAYER_INTERP, XMP_INTERP_SPLINE) != 0)
{
Mem_Free(per_ch);
return;
@@ -576,7 +593,7 @@ XMP_LoadModFile
Load an XMP module file into memory
===============
*/
-qboolean XMP_LoadModFile(const char *filename, sfx_t *sfx)
+qbool XMP_LoadModFile(const char *filename, sfx_t *sfx)
{
fs_offset_t filesize;
unsigned char *data;
@@ -590,7 +607,7 @@ qboolean XMP_LoadModFile(const char *filename, sfx_t *sfx)
#endif
// COMMANDLINEOPTION: Sound: -noxmp disables xmp module sound support
- if (COM_CheckParm("-noxmp"))
+ if (Sys_CheckParm("-noxmp"))
return false;
// Return if already loaded
@@ -631,23 +648,23 @@ qboolean XMP_LoadModFile(const char *filename, sfx_t *sfx)
// set dp sfx
sfx->memsize += sizeof(*per_sfx);
sfx->memsize += filesize; // total memory used (including sfx_t and fetcher data)
-// sfx->format // format describing the audio data that fetcher->getsamplesfloat shall return
- sfx->format.speed = 48000; // default to this sample rate
- sfx->format.width = 2; // default to 16 bit samples
-// sfx->format.width = 1; // 8-bit
- sfx->format.channels = 2; // default to stereo
-// sfx->format.channels = 1; // mono
+ if (S_GetSoundRate() > XMP_MAX_SRATE)
+ sfx->format.speed = 48000;
+ else if (S_GetSoundRate() < XMP_MIN_SRATE)
+ sfx->format.speed = 8000;
+ else
+ sfx->format.speed = S_GetSoundRate();
+ sfx->format.width = S_GetSoundWidth(); // 2 = 16 bit samples
+ sfx->format.channels = S_GetSoundChannels();
sfx->flags |= SFXFLAG_STREAMED; // cf SFXFLAG_* defines
-// sfx->total_length // in (pcm) sample frames
- sfx->total_length = 1<<30; // 2147384647; // they always loop (FIXME this breaks after 6 hours, we need support for a real "infinite" value!)
+ sfx->total_length = 1<<30; // 2147384647; // in (pcm) sample frames - they always loop (FIXME this breaks after 6 hours, we need support for a real "infinite" value!)
sfx->loopstart = sfx->total_length; // (modplug does it) in sample frames. equals total_length if not looped
sfx->fetcher_data = per_sfx;
sfx->fetcher = &xmp_fetcher;
-// sfx->volume_mult // for replay gain (multiplier to apply)
-// sfx->volume_peak // for replay gain (highest peak); if set to 0, ReplayGain isn't supported
+ sfx->volume_peak = 0;
qxmp_get_module_info(xc, &mi);
- if (developer_loading.integer >= 1)
+ if (developer_loading.integer >= 2)
{
Con_Printf("Decoding module (libxmp):\n"
" Module name : %s\n"
@@ -666,7 +683,7 @@ qboolean XMP_LoadModFile(const char *filename, sfx_t *sfx)
mi.mod->spd, mi.mod->bpm, mi.mod->rst, mi.mod->gvl
);
}
- else if (developer.integer >= 1)
+ else if (developer_loading.integer == 1)
Con_Printf("Decoding module (libxmp) \"%s\" (%s)\n", mi.mod->name, mi.mod->type);
qxmp_free_context(xc);