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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
/*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2008 Simon Peter, <dn.tlp@gmx.net>, et al.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* rol.h - ROL Player by OPLx <oplx@yahoo.com>
*
* Visit: http://tenacity.hispeed.com/aomit/oplx/
*/
#ifndef H_ROLPLAYER
#define H_ROLPLAYER
#include "player.h"
class CrolPlayer: public CPlayer
{
public:
static CPlayer *factory(Copl *newopl);
CrolPlayer(Copl *newopl);
~CrolPlayer();
bool load (const char *filename, const CFileProvider &fp);
bool update ();
void rewind (int subsong); // rewinds to specified subsong
float getrefresh(); // returns needed timer refresh rate
const char * gettype() { return "Adlib Visual Composer"; }
private:
typedef unsigned short uint16;
typedef signed short int16;
#ifdef __x86_64__
typedef signed int int32;
#else
typedef signed long int int32;
#endif
typedef float real32;
typedef struct
{
uint16 version_major;
uint16 version_minor;
char unused0[40];
uint16 ticks_per_beat;
uint16 beats_per_measure;
uint16 edit_scale_y;
uint16 edit_scale_x;
char unused1;
char mode;
char unused2[90];
char filler0[38];
char filler1[15];
real32 basic_tempo;
} SRolHeader;
typedef struct
{
int16 time;
real32 multiplier;
} STempoEvent;
typedef struct
{
int16 number;
int16 duration;
} SNoteEvent;
typedef struct
{
int16 time;
char name[9];
int16 ins_index;
} SInstrumentEvent;
typedef struct
{
int16 time;
real32 multiplier;
} SVolumeEvent;
typedef struct
{
int16 time;
real32 variation;
} SPitchEvent;
enum {
MAX_NOTE_EVENTS = 2000,
};
#define bit_pos( pos ) (1<<pos)
class CVoiceData
{
public:
enum EEventStatus
{
kES_NoteEnd = bit_pos( 0 ),
kES_PitchEnd = bit_pos( 1 ),
kES_InstrEnd = bit_pos( 2 ),
kES_VolumeEnd = bit_pos( 3 ),
kES_None = 0
};
explicit CVoiceData()
: mForceNote ( true )
,mEventStatus ( kES_None )
,current_note ( 0 )
,current_note_duration( 0 )
,mNoteDuration ( 0 )
,next_instrument_event( 0 )
,next_volume_event ( 0 )
,next_pitch_event ( 0 )
,n_note_events (0)
,n_instrument_events(0)
,n_volume_events(0)
,n_pitch_events(0)
{
memset (note_events, 0, sizeof (note_events));
instrument_events = 0;
volume_events = 0;
pitch_events = 0;
}
~CVoiceData () {
delete[] instrument_events;
delete[] volume_events;
delete[] pitch_events;
}
void Reset()
{
mForceNote = true;
mEventStatus = kES_None;
current_note = 0;
current_note_duration = 0;
mNoteDuration = 0;
next_instrument_event = 0;
next_volume_event = 0;
next_pitch_event = 0;
}
SNoteEvent note_events[MAX_NOTE_EVENTS];
int n_note_events;
SInstrumentEvent *instrument_events;
int n_instrument_events;
SVolumeEvent *volume_events;
int n_volume_events;
SPitchEvent *pitch_events;
int n_pitch_events;
bool mForceNote : 1;
int mEventStatus;
unsigned int current_note;
int current_note_duration;
int mNoteDuration;
unsigned int next_instrument_event;
unsigned int next_volume_event;
unsigned int next_pitch_event;
};
typedef struct
{
uint16 index;
char record_used;
char name[9];
} SInstrumentName;
typedef struct
{
char version_major;
char version_minor;
char signature[6];
uint16 number_of_list_entries_used;
uint16 total_number_of_list_entries;
int32 abs_offset_of_name_list;
int32 abs_offset_of_data;
SInstrumentName *ins_name_list;
int n_ins_names;
} SBnkHeader;
typedef struct
{
unsigned char key_scale_level;
unsigned char freq_multiplier;
unsigned char feed_back;
unsigned char attack_rate;
unsigned char sustain_level;
unsigned char sustaining_sound;
unsigned char decay_rate;
unsigned char release_rate;
unsigned char output_level;
unsigned char amplitude_vibrato;
unsigned char frequency_vibrato;
unsigned char envelope_scaling;
unsigned char fm_type;
} SFMOperator;
typedef struct
{
unsigned char ammulti;
unsigned char ksltl;
unsigned char ardr;
unsigned char slrr;
unsigned char fbc;
unsigned char waveform;
} SOPL2Op;
typedef struct
{
char mode;
char voice_number;
SOPL2Op modulator;
SOPL2Op carrier;
} SRolInstrument;
typedef struct
{
const char * name;
SRolInstrument instrument;
} SUsedList;
void load_tempo_events ( binistream *f );
bool load_voice_data ( binistream *f, const char *bnk_filename, const CFileProvider &fp );
void load_note_events ( binistream *f, CVoiceData &voice );
void load_instrument_events( binistream *f, CVoiceData &voice,
binistream *bnk_file, SBnkHeader const &bnk_header );
void load_volume_events ( binistream *f, CVoiceData &voice );
void load_pitch_events ( binistream *f, CVoiceData &voice );
bool load_bnk_info ( binistream *f, SBnkHeader &header );
int load_rol_instrument ( binistream *f, SBnkHeader const &header, const char *name );
void read_rol_instrument ( binistream *f, SRolInstrument &ins );
void read_fm_operator ( binistream *f, SOPL2Op &opl2_op );
int get_ins_index( const char * const &name ) const;
void UpdateVoice( int const voice, CVoiceData &voiceData );
void SetNote( int const voice, int const note );
void SetNoteMelodic( int const voice, int const note );
void SetNotePercussive( int const voice, int const note );
void SetFreq ( int const voice, int const note, bool const keyOn=false );
void SetPitch ( int const voice, real32 const variation );
void SetVolume ( int const voice, int const volume );
void SetRefresh( float const multiplier );
void send_ins_data_to_chip( int const voice, int const ins_index );
void send_operator( int const voice, SOPL2Op const &modulator, SOPL2Op const &carrier );
SRolHeader *rol_header;
STempoEvent *mTempoEvents;
int n_tempo_events;
CVoiceData *voice_data;
int n_voice_data;
SUsedList *ins_list;
int n_used_ins;
unsigned int mNextTempoEvent;
int mCurrTick;
int mTimeOfLastNote;
float mRefresh;
unsigned char bdRegister;
unsigned char bxRegister[9];
unsigned char volumeCache[11];
uint16 freqCache[11];
real32 pitchCache[11];
static int const kSizeofDataRecord;
static int const kMaxTickBeat;
static int const kSilenceNote;
static int const kNumMelodicVoices;
static int const kNumPercussiveVoices;
static int const kBassDrumChannel;
static int const kSnareDrumChannel;
static int const kTomtomChannel;
static int const kTomtomFreq;
static int const kSnareDrumFreq;
static float const kDefaultUpdateTme;
static float const kPitchFactor;
static uint16 const kNoteTable[12];
};
#endif
|