-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathv2mplayer.h
254 lines (204 loc) · 7.01 KB
/
v2mplayer.h
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/*************************************************************************************/
/*************************************************************************************/
/** **/
/** V2 module player (.v2m) **/
/** (c) Tammo 'kb' Hinrichs 2000-2008 **/
/** This file is under the Artistic License 2.0, see LICENSE.txt for details **/
/** **/
/*************************************************************************************/
/*************************************************************************************/
#ifndef V2MPLAYER_H_
#define V2MPLAYER_H_
/*************************************************************************************/
/** **/
/** Type definitions **/
/** **/
/*************************************************************************************/
#ifndef V2TYPES
#define V2TYPES
typedef int sInt;
typedef unsigned int sUInt;
typedef sInt sBool;
typedef char sChar;
typedef signed char sS8;
typedef signed short sS16;
typedef signed long sS32;
typedef signed __int64 sS64;
typedef unsigned char sU8;
typedef unsigned short sU16;
typedef unsigned long sU32;
typedef unsigned __int64 sU64;
typedef float sF32;
typedef double sF64;
#define sTRUE 1
#define sFALSE 0
template<class T> inline T sMin(const T a, const T b) { return (a<b)?a:b; }
template<class T> inline T sMax(const T a, const T b) { return (a>b)?a:b; }
template<class T> inline T sClamp(const T x, const T min, const T max) { return sMax(min,sMin(max,x)); }
#endif
/*************************************************************************************/
/** **/
/** V2M player class **/
/** **/
/*************************************************************************************/
class V2MPlayer
{
public:
// init
// call this instead of a constructor
void Init(sU32 a_tickspersec=1000) { m_tpc=a_tickspersec; m_base.valid=0; }
// opens a v2m file for playing
//
// a_v2mptr : ptr to v2m data
// NOTE: the memory block has to remain valid
// as long as the player is opened!
// a_samplerate : samplerate at which the synth is operating
// if this is zero, output will be disabled and
// only the timing query functions will work
// returns : flag if succeeded
//
sBool Open (const void *a_v2mptr, sU32 a_samplerate=44100);
// closes player
//
void Close ();
// starts playing
//
// a_time : time offset from song start in msecs
//
void Play (sU32 a_time=0);
// stops playing
//
// a_fadetime : optional fade out time in msecs
//
void Stop (sU32 a_fadetime=0);
// render call (to be used from sound thread et al)
// renders samples (or silence if not playing) into buffer
//
// a_buffer : ptr to stereo float sample buffer (0dB=1.0f)
// a_len : number of samples to render
//
// returns : flag if playing
//
void Render (sF32 *a_buffer, sU32 a_len, sBool a_add=0);
// render proxy for C-style callbacks
//
// a_this : void ptr to instance
// rest as in Render()
//
static void __stdcall RenderProxy(void *a_this, sF32 *a_buffer, sU32 a_len)
{
reinterpret_cast<V2MPlayer*>(a_this)->Render(a_buffer,a_len);
}
// returns if song is currently playing
sBool IsPlaying();
#ifdef V2MPLAYER_SYNC_FUNCTIONS
// Retrieves an array of timer<->song position
//
// a_dest: pointer to a variable which will receive the address of an array of long
// values structured as following:
// first long: time in ms
// second long: song position (see above for a description)
// format: 0xBBBBTTNN, where
// BBBB is the bar number (starting at 0)
// TT is the number of the 32th tick within the current bar
// NN is the total number of 32th ticks a the current bar has
// (32, normally, may change with different time signatures than 4/4)
// ... and so on for every found position
//
// NOTE: it is your responsibility to free the array again.
//
// returns: number of found song positions
//
sU32 CalcPositions(sS32 **a_dest);
#endif
// ------------------------------------------------------------------------------------------------------
// no need to look beyond this point.
// ------------------------------------------------------------------------------------------------------
private:
// struct defs
// General info from V2M file
struct V2MBase
{
sBool valid;
const sU8 *patchmap;
const sU8 *globals;
sU32 timediv;
sU32 timediv2;
sU32 maxtime;
const sU8 *gptr;
sU32 gdnum;
struct Channel {
sU32 notenum;
const sU8 *noteptr;
sU32 pcnum;
const sU8 *pcptr;
sU32 pbnum;
const sU8 *pbptr;
struct CC {
sU32 ccnum;
const sU8 *ccptr;
} ctl[7];
} chan[16];
const char *speechdata;
const char *speechptrs[256];
};
// player state
struct PlayerState
{
enum { OFF, STOPPED, PLAYING, } state;
sU32 time;
sU32 nexttime;
const sU8 *gptr;
sU32 gnt;
sU32 gnr;
sU32 usecs;
sU32 num;
sU32 den;
sU32 tpq;
sU32 bar;
sU32 beat;
sU32 tick;
struct Channel {
const sU8 *noteptr;
sU32 notenr;
sU32 notent;
sU8 lastnte;
sU8 lastvel;
const sU8 *pcptr;
sU32 pcnr;
sU32 pcnt;
sU8 lastpc;
const sU8 *pbptr;
sU32 pbnr;
sU32 pbnt;
sU8 lastpb0;
sU8 lastpb1;
struct CC {
const sU8 *ccptr;
sU32 ccnt;
sU32 ccnr;
sU8 lastcc;
} ctl[7];
} chan[16];
sU32 cursmpl;
sU32 smpldelta;
sU32 smplrem;
sU32 tdif;
};
// \o/
sU8 m_synth[3*1024*1024]; // TODO: keep me uptodate or use "new"
// member variables
sU32 m_tpc;
V2MBase m_base;
PlayerState m_state;
sU32 m_samplerate;
sS32 m_timeoffset;
sU8 m_midibuf[4096];
sF32 m_fadeval;
sF32 m_fadedelta;
// internal methods
sBool InitBase(const void *a_v2m); // inits base struct from v2m
void Reset(); // resets player, inits synth
void Tick(); // one midi player tick
};
#endif