#ifdef SND_MODPLUG_STATIC
-#include "libmodplug/modplug.h"
+#include <libmodplug/modplug.h>
qboolean ModPlug_OpenLibrary (void)
{
return true; // statically linked
{
}
#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
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 */
// 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}
};
{
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
// 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
- if (! Sys_LoadLibrary (dllnames_modplug, &modplug_dll, modplugfuncs))
+ if(Sys_LoadLibrary (dllnames_modplug, &modplug_dll, modplugfuncs))
{
- Sys_UnloadLibrary (&modplug_dll);
- Con_Printf ("ModPlug support disabled\n");
- return false;
+ 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;
}
-
- Con_Printf ("ModPlug support enabled\n");
- return true;
+ else
+ return false;
}
=================================================================
*/
-#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
{
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;
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",
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)
{
if (per_ch != NULL)
{
// Free the modplug decoder
- ModPlug_Unload (per_ch->mf);
+ qModPlug_Unload (per_ch->mf);
Mem_Free (per_ch);
}
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 };
/*
if (data == NULL)
return false;
- Con_DPrintf ("Loading ModPlug file \"%s\"\n", filename);
+ 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;
}
- Con_DPrintf ("\"%s\" will be streamed\n", filename);
+#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));
strlcpy(per_sfx->name, sfx->name, sizeof(per_sfx->name));
sfx->memsize += sizeof (*per_sfx);