123 lines
2.9 KiB
C++
123 lines
2.9 KiB
C++
extern "C"
|
|
{
|
|
#include "main.h"
|
|
}
|
|
#include "drv_buffer.h"
|
|
#include <bfc/platform/types.h>
|
|
|
|
typedef struct
|
|
{
|
|
const char *cmd;
|
|
const char *file;
|
|
const char *title;
|
|
int titleLength;
|
|
int start;
|
|
int startUnit;
|
|
int loops;
|
|
int flags;
|
|
} PlayParams;
|
|
extern "C" int GetSampleSizeFlag();
|
|
extern "C" MMSTREAM *_mm_fopen_rf(const CHAR *fname); //rf_wrapper.c
|
|
BOOL GetPlayParams(const char *fileName, BOOL open, PlayParams *params);
|
|
BOOL InitPlayer(UNIMOD *mf, MPLAYER **ps, const PlayParams *params, BOOL quick);
|
|
// TODO; is there a way to get floating point out of this stuff?
|
|
extern "C"
|
|
{
|
|
__declspec(dllexport) intptr_t winampGetExtendedRead_open(const char *fn, int *size, int *bps, int *nch, int *srate)
|
|
{
|
|
PlayParams params;
|
|
if (!GetPlayParams(fn, FALSE, ¶ms))
|
|
return 0;
|
|
|
|
int requested_channels = *nch;
|
|
int requested_bits = *bps;
|
|
int requested_srate = *srate;
|
|
|
|
uint md_mode = 0;
|
|
if (config_interp & 1) md_mode |= DMODE_INTERP;
|
|
if (config_interp & 2) md_mode |= DMODE_NOCLICK;
|
|
if (config_interp & 4) md_mode |= DMODE_FIR;
|
|
switch(requested_bits)
|
|
{
|
|
case 0:
|
|
md_mode |= GetSampleSizeFlag();
|
|
break;
|
|
case 16:
|
|
md_mode |= DMODE_16BITS;
|
|
break;
|
|
case 24:
|
|
md_mode |= DMODE_24BITS;
|
|
break;
|
|
}
|
|
|
|
|
|
if (requested_channels != 1 && requested_channels != 2) md_mode |= DMODE_SURROUND;
|
|
if (config_panrev) md_mode |= DMODE_REVERSE;
|
|
if (config_resonance) md_mode |= DMODE_RESONANCE;
|
|
|
|
MDRIVER *md = Mikmod_Init(requested_srate?requested_srate:config_srate, 0, 0, MD_STEREO, config_cpu, md_mode, &drv_buffer);
|
|
MPLAYER *mp;
|
|
|
|
MMSTREAM *fp;
|
|
fp = _mm_fopen_rf(params.file);
|
|
if (!fp)
|
|
{
|
|
Mikmod_Exit(md);
|
|
//CleanupTemp();
|
|
return 0;
|
|
}
|
|
UNIMOD *mf=Unimod_Load_FP(md, params.file,fp);
|
|
_mm_fclose(fp);
|
|
if (mf==NULL)
|
|
{
|
|
Mikmod_Exit(md);
|
|
// CleanupTemp();
|
|
return 0;
|
|
}
|
|
|
|
if (!InitPlayer(mf, &mp, ¶ms, FALSE))
|
|
{
|
|
//CleanupTemp();
|
|
Unimod_Free(mf);
|
|
Mikmod_Exit(md);
|
|
return 0;
|
|
}
|
|
|
|
Player_Start(mp);
|
|
DecodeInfo *hwdata = (DecodeInfo *)md->device.local;
|
|
*bps = hwdata->bits;
|
|
*srate = hwdata->mixspeed;
|
|
*nch = hwdata->channels;
|
|
if (mf->songlen)
|
|
*size = MulDiv(mf->songlen, hwdata->mixspeed * hwdata->channels *hwdata->bits, 8*1000);
|
|
else
|
|
*size = -1;
|
|
return (intptr_t)mp;
|
|
}
|
|
|
|
__declspec(dllexport) size_t winampGetExtendedRead_getData(intptr_t handle, char *dest, size_t len, int *killswitch)
|
|
{
|
|
MPLAYER *mp = (MPLAYER *)handle;
|
|
DecodeInfo *hwdata = (DecodeInfo *)mp->mf->md->device.local;
|
|
|
|
if (!Player_Active(mp)) // check if we're done
|
|
return 0;
|
|
|
|
hwdata->buffer = dest;
|
|
hwdata->buffersize = len;
|
|
hwdata->bytesWritten = 0;
|
|
Mikmod_Update(mp->mf->md);
|
|
return hwdata->bytesWritten;
|
|
}
|
|
|
|
|
|
__declspec(dllexport) void winampGetExtendedRead_close(intptr_t handle)
|
|
{
|
|
MPLAYER *mp = (MPLAYER *)handle;
|
|
MDRIVER *md = mp->mf->md;
|
|
UNIMOD *mf = (UNIMOD *)mp->mf;
|
|
Player_Free(mp);
|
|
Unimod_Free(mf);
|
|
Mikmod_Exit(md);
|
|
}
|
|
} |