aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Input/in_mod/mikamp/src/ExtendedRead.cpp
blob: 71db9ea40933c86e50573b55f2a47c47af914107 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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, &params))
			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, &params, 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);
	}
}