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);