X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=snd_modplug.c;h=596b38ff75ab7d8e3a85da14a225dc285c6bd2b9;hp=a3179868200f419615c7edfc7a1a9c59be2ebebe;hb=5873729e60f4dfad4523a04ac67a925e0039e71d;hpb=8d376b57de94bafd3bae224088b469649c853028 diff --git a/snd_modplug.c b/snd_modplug.c index a3179868..596b38ff 100644 --- a/snd_modplug.c +++ b/snd_modplug.c @@ -37,6 +37,13 @@ void ModPlug_CloseLibrary (void) { } #define modplug_dll 1 +#define qModPlug_Load ModPlug_Load +#define qModPlug_Unload ModPlug_Unload +#define qModPlug_Read ModPlug_Read +#define qModPlug_Seek ModPlug_Seek +#define qModPlug_GetSettings ModPlug_GetSettings +#define qModPlug_SetSettings ModPlug_SetSettings +#define qModPlug_SetMasterVolume ModPlug_SetMasterVolume #else // BEGIN SECTION FROM modplug.h @@ -74,6 +81,9 @@ void ModPlug_CloseLibrary (void) int mBits; /* Bits per sample - 8, 16, or 32 */ int mFrequency; /* Sampling rate - 11025, 22050, or 44100 */ int mResamplingMode; /* One of MODPLUG_RESAMPLE_*, above */ + + int mStereoSeparation; /* Stereo separation, 1 - 256 */ + int mMaxMixChannels; /* Maximum number of mixing channels (polyphony), 32 - 256 */ int mReverbDepth; /* Reverb level 0(quiet)-100(loud) */ int mReverbDelay; /* Reverb delay in ms, usually 40-200ms */ @@ -90,21 +100,24 @@ void ModPlug_CloseLibrary (void) // END SECTION FROM modplug.h -static ModPlugFile* (*ModPlug_Load) (const void* data, int size); -static void (*ModPlug_Unload) (ModPlugFile* file); -static int (*ModPlug_Read) (ModPlugFile* file, void* buffer, int size); -static void (*ModPlug_Seek) (ModPlugFile* file, int millisecond); -static void (*ModPlug_GetSettings) (ModPlug_Settings* settings); -static void (*ModPlug_SetSettings) (const ModPlug_Settings* settings); +static ModPlugFile* (*qModPlug_Load) (const void* data, int size); +static void (*qModPlug_Unload) (ModPlugFile* file); +static int (*qModPlug_Read) (ModPlugFile* file, void* buffer, int size); +static void (*qModPlug_Seek) (ModPlugFile* file, int millisecond); +static void (*qModPlug_GetSettings) (ModPlug_Settings* settings); +static void (*qModPlug_SetSettings) (const ModPlug_Settings* settings); +typedef void (ModPlug_SetMasterVolume_t) (ModPlugFile* file,unsigned int cvol) ; +ModPlug_SetMasterVolume_t *qModPlug_SetMasterVolume; + static dllfunction_t modplugfuncs[] = { - {"ModPlug_Load", (void **) &ModPlug_Load}, - {"ModPlug_Unload", (void **) &ModPlug_Unload}, - {"ModPlug_Read", (void **) &ModPlug_Read}, - {"ModPlug_Seek", (void **) &ModPlug_Seek}, - {"ModPlug_GetSettings", (void **) &ModPlug_GetSettings}, - {"ModPlug_SetSettings", (void **) &ModPlug_SetSettings}, + {"ModPlug_Load", (void **) &qModPlug_Load}, + {"ModPlug_Unload", (void **) &qModPlug_Unload}, + {"ModPlug_Read", (void **) &qModPlug_Read}, + {"ModPlug_Seek", (void **) &qModPlug_Seek}, + {"ModPlug_GetSettings", (void **) &qModPlug_GetSettings}, + {"ModPlug_SetSettings", (void **) &qModPlug_SetSettings}, {NULL, NULL} }; @@ -130,15 +143,13 @@ qboolean ModPlug_OpenLibrary (void) { const char* dllnames_modplug [] = { -#if defined(WIN64) - "libmodplug64.dll", -#elif defined(WIN32) - "libmodplug-0.dll", +#if defined(WIN32) + "libmodplug-1.dll", "modplug.dll", #elif defined(MACOSX) "libmodplug.dylib", #else - "libmodplug.so.0", + "libmodplug.so.1", "libmodplug.so", #endif NULL @@ -155,7 +166,15 @@ qboolean ModPlug_OpenLibrary (void) // Load the DLLs // We need to load both by hand because some OSes seem to not load // the modplug DLL automatically when loading the modplugFile DLL - return Sys_LoadLibrary (dllnames_modplug, &modplug_dll, modplugfuncs); + if(Sys_LoadLibrary (dllnames_modplug, &modplug_dll, modplugfuncs)) + { + qModPlug_SetMasterVolume = (ModPlug_SetMasterVolume_t *) Sys_GetProcAddress(modplug_dll, "ModPlug_SetMasterVolume"); + if(!qModPlug_SetMasterVolume) + Con_Print("Warning: modplug volume control not supported. Try getting a newer version of libmodplug.\n"); + return true; + } + else + return false; } @@ -181,13 +200,6 @@ void ModPlug_CloseLibrary (void) ================================================================= */ -#define STREAM_BUFFER_DURATION 1.5f // 1.5 sec -#define STREAM_BUFFER_SIZE(format_ptr) ((int)(ceil (STREAM_BUFFER_DURATION * ((format_ptr)->speed * (format_ptr)->width * (format_ptr)->channels)))) -// We work with 1 sec sequences, so this buffer must be able to contain -// 1 sec of sound of the highest quality (48 KHz, 16 bit samples, stereo) -static unsigned char resampling_buffer [48000 * 2 * 2]; - - // Per-sfx data structure typedef struct { @@ -238,13 +250,19 @@ static const snd_buffer_t* ModPlug_FetchSound (void *sfxfetcher, void **chfetche per_ch = (modplug_stream_perchannel_t *)Mem_Alloc (snd_mempool, memsize); // Open it with the modplugFile API - per_ch->mf = ModPlug_Load(per_sfx->file, per_sfx->filesize); + per_ch->mf = qModPlug_Load(per_sfx->file, per_sfx->filesize); if (!per_ch->mf) { Con_Printf("error while reading ModPlug stream \"%s\"\n", per_sfx->name); Mem_Free (per_ch); return NULL; } + +#ifndef SND_MODPLUG_STATIC + if(qModPlug_SetMasterVolume) +#endif + qModPlug_SetMasterVolume(per_ch->mf, 512); // max volume, DP scales down! + per_ch->bs = 0; per_ch->sb_offset = 0; @@ -298,10 +316,10 @@ static const snd_buffer_t* ModPlug_FetchSound (void *sfxfetcher, void **chfetche Con_DPrintf("warning: mod file needed to seek (to %d)\n", modplug_start); - ModPlug_Seek(per_ch->mf, modplug_start); + qModPlug_Seek(per_ch->mf, modplug_start); sb->nbframes = 0; - real_start = (float)modplug_start / 1000 * snd_renderbuffer->format.speed; + real_start = (unsigned int) ((float)modplug_start / 1000 * snd_renderbuffer->format.speed); if (*start - real_start + nbsampleframes > sb->maxframes) { Con_Printf ("ModPlug_FetchSound: stream buffer too small after seek (%u sample frames required)\n", @@ -319,22 +337,23 @@ static const snd_buffer_t* ModPlug_FetchSound (void *sfxfetcher, void **chfetche per_ch->sb_offset = real_start; - // We add exactly 1 sec of sound to the buffer: - // 1- to ensure we won't lose any sample during the resampling process - // 2- to force one call to ModPlug_FetchSound per second to regulate the workload - if (sb->format.speed + sb->nbframes > sb->maxframes) + // We add more than one frame of sound to the buffer: + // 1- to ensure we won't lose many samples during the resampling process + // 2- to reduce calls to ModPlug_FetchSound to regulate workload + newlength = (int)(per_sfx->format.speed*STREAM_BUFFER_FILL); + if ((size_t) ((double) newlength * (double)sb->format.speed / (double)per_sfx->format.speed) + sb->nbframes > sb->maxframes) { - Con_Printf ("ModPlug_FetchSound: stream buffer overflow (%u sample frames / %u)\n", - sb->format.speed + sb->nbframes, sb->maxframes); + Con_Printf ("ModPlug_FetchSound: stream buffer overflow (%u + %u = %u sample frames / %u)\n", + (unsigned int) ((double) newlength * (double)sb->format.speed / (double)per_sfx->format.speed), sb->nbframes, (unsigned int) ((double) newlength * (double)sb->format.speed / (double)per_sfx->format.speed) + sb->nbframes, sb->maxframes); return NULL; } - newlength = per_sfx->format.speed * factor; // -> 1 sec of sound before resampling + newlength *= factor; // convert from sample frames to bytes if(newlength > (int)sizeof(resampling_buffer)) newlength = sizeof(resampling_buffer); // Decompress in the resampling_buffer done = 0; - while ((ret = ModPlug_Read (per_ch->mf, (char *)&resampling_buffer[done], (int)(newlength - done))) > 0) + while ((ret = qModPlug_Read (per_ch->mf, (char *)&resampling_buffer[done], (int)(newlength - done))) > 0) done += ret; if(done < newlength) { @@ -367,7 +386,7 @@ static void ModPlug_FetchEnd (void *chfetcherdata) if (per_ch != NULL) { // Free the modplug decoder - ModPlug_Unload (per_ch->mf); + qModPlug_Unload (per_ch->mf); Mem_Free (per_ch); } @@ -396,13 +415,13 @@ static void ModPlug_FreeSfx (void *sfxfetcherdata) ModPlug_GetFormat ==================== */ -static const snd_format_t* ModPlug_GetFormat (sfx_t* sfx) +static const snd_format_t* qModPlug_GetFormat (sfx_t* sfx) { modplug_stream_persfx_t* per_sfx = (modplug_stream_persfx_t *)sfx->fetcher_data; return &per_sfx->format; } -static const snd_fetcher_t modplug_fetcher = { ModPlug_FetchSound, ModPlug_FetchEnd, ModPlug_FreeSfx, ModPlug_GetFormat }; +static const snd_fetcher_t modplug_fetcher = { ModPlug_FetchSound, ModPlug_FetchEnd, ModPlug_FreeSfx, qModPlug_GetFormat }; /* @@ -435,23 +454,28 @@ qboolean ModPlug_LoadModPlugFile (const char *filename, sfx_t *sfx) if (developer_loading.integer >= 2) Con_Printf ("Loading ModPlug file \"%s\"\n", filename); - ModPlug_GetSettings(&s); + qModPlug_GetSettings(&s); s.mFlags = MODPLUG_ENABLE_OVERSAMPLING | MODPLUG_ENABLE_NOISE_REDUCTION | MODPLUG_ENABLE_REVERB; s.mChannels = 2; s.mBits = 16; s.mFrequency = 44100; s.mResamplingMode = MODPLUG_RESAMPLE_SPLINE; s.mLoopCount = -1; - ModPlug_SetSettings(&s); + qModPlug_SetSettings(&s); // Open it with the modplugFile API - if (!(mf = ModPlug_Load (data, filesize))) + if (!(mf = qModPlug_Load (data, filesize))) { Con_Printf ("error while opening ModPlug file \"%s\"\n", filename); Mem_Free(data); return false; } +#ifndef SND_MODPLUG_STATIC + if(qModPlug_SetMasterVolume) +#endif + qModPlug_SetMasterVolume(mf, 512); // max volume, DP scales down! + if (developer_loading.integer >= 2) Con_Printf ("\"%s\" will be streamed\n", filename); per_sfx = (modplug_stream_persfx_t *)Mem_Alloc (snd_mempool, sizeof (*per_sfx));