2006-02-24 04:48:15 +00:00
|
|
|
/*
|
|
|
|
* Name: Main header include file
|
|
|
|
* Project: MUS File Player Library
|
|
|
|
* Version: 1.75
|
|
|
|
* Author: Vladimir Arnost (QA-Software)
|
|
|
|
* Last revision: Mar-9-1996
|
|
|
|
* Compiler: Borland C++ 3.1, Watcom C/C++ 10.0
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __MUSLIB_H_
|
|
|
|
#define __MUSLIB_H_
|
|
|
|
|
|
|
|
#ifndef __DEFTYPES_H_
|
|
|
|
#include "deftypes.h"
|
|
|
|
#endif
|
|
|
|
#include "files.h"
|
|
|
|
|
|
|
|
/* Global Definitions */
|
|
|
|
|
|
|
|
#define MLVERSION 0x0175
|
|
|
|
#define MLVERSIONSTR "1.75"
|
|
|
|
extern char MLversion[];
|
|
|
|
extern char MLcopyright[];
|
|
|
|
|
|
|
|
#define CHANNELS 16 // total channels 0..CHANNELS-1
|
|
|
|
#define PERCUSSION 15 // percussion channel
|
|
|
|
|
|
|
|
/* MUS file header structure */
|
|
|
|
struct MUSheader {
|
|
|
|
char ID[4]; // identifier "MUS" 0x1A
|
|
|
|
WORD scoreLen; // score length
|
|
|
|
WORD scoreStart; // score start
|
|
|
|
WORD channels; // primary channels
|
|
|
|
WORD sec_channels; // secondary channels (??)
|
|
|
|
WORD instrCnt; // used instrument count
|
|
|
|
WORD dummy;
|
|
|
|
// WORD instruments[...]; // table of used instruments
|
|
|
|
};
|
|
|
|
|
|
|
|
/* OPL2 instrument */
|
|
|
|
struct OPL2instrument {
|
|
|
|
/*00*/ BYTE trem_vibr_1; /* OP 1: tremolo/vibrato/sustain/KSR/multi */
|
|
|
|
/*01*/ BYTE att_dec_1; /* OP 1: attack rate/decay rate */
|
|
|
|
/*02*/ BYTE sust_rel_1; /* OP 1: sustain level/release rate */
|
|
|
|
/*03*/ BYTE wave_1; /* OP 1: waveform select */
|
|
|
|
/*04*/ BYTE scale_1; /* OP 1: key scale level */
|
|
|
|
/*05*/ BYTE level_1; /* OP 1: output level */
|
|
|
|
/*06*/ BYTE feedback; /* feedback/AM-FM (both operators) */
|
|
|
|
/*07*/ BYTE trem_vibr_2; /* OP 2: tremolo/vibrato/sustain/KSR/multi */
|
|
|
|
/*08*/ BYTE att_dec_2; /* OP 2: attack rate/decay rate */
|
|
|
|
/*09*/ BYTE sust_rel_2; /* OP 2: sustain level/release rate */
|
|
|
|
/*0A*/ BYTE wave_2; /* OP 2: waveform select */
|
|
|
|
/*0B*/ BYTE scale_2; /* OP 2: key scale level */
|
|
|
|
/*0C*/ BYTE level_2; /* OP 2: output level */
|
|
|
|
/*0D*/ BYTE unused;
|
|
|
|
/*0E*/ sshort basenote; /* base note offset */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* OP2 instrument file entry */
|
|
|
|
struct OP2instrEntry {
|
|
|
|
/*00*/ WORD flags; // see FL_xxx below
|
|
|
|
/*02*/ BYTE finetune; // finetune value for 2-voice sounds
|
|
|
|
/*03*/ BYTE note; // note # for fixed instruments
|
|
|
|
/*04*/ struct OPL2instrument instr[2]; // instruments
|
|
|
|
};
|
|
|
|
|
|
|
|
#define FL_FIXED_PITCH 0x0001 // note has fixed pitch (see below)
|
|
|
|
#define FL_UNKNOWN 0x0002 // ??? (used in instrument #65 only)
|
|
|
|
#define FL_DOUBLE_VOICE 0x0004 // use two voices instead of one
|
|
|
|
|
|
|
|
|
|
|
|
#define OP2INSTRSIZE sizeof(struct OP2instrEntry) // instrument size (36 bytes)
|
|
|
|
#define OP2INSTRCOUNT (128 + 81-35+1) // instrument count
|
|
|
|
|
|
|
|
/* From MLOPL_IO.CPP */
|
|
|
|
#define OPL2CHANNELS 9
|
|
|
|
#define OPL3CHANNELS 18
|
|
|
|
#define MAXCHANNELS 18
|
|
|
|
|
|
|
|
|
|
|
|
/* Channel Flags: */
|
|
|
|
#define CH_SECONDARY 0x01
|
|
|
|
#define CH_SUSTAIN 0x02
|
|
|
|
#define CH_VIBRATO 0x04 /* set if modulation >= MOD_MIN */
|
|
|
|
#define CH_FREE 0x80
|
|
|
|
|
|
|
|
struct OPLdata {
|
|
|
|
uint channelInstr[CHANNELS]; // instrument #
|
|
|
|
uchar channelVolume[CHANNELS]; // volume
|
|
|
|
uchar channelLastVolume[CHANNELS]; // last volume
|
|
|
|
schar channelPan[CHANNELS]; // pan, 0=normal
|
|
|
|
schar channelPitch[CHANNELS]; // pitch wheel, 0=normal
|
|
|
|
uchar channelSustain[CHANNELS]; // sustain pedal value
|
|
|
|
uchar channelModulation[CHANNELS]; // modulation pot value
|
|
|
|
};
|
|
|
|
|
|
|
|
struct OPLio {
|
2006-05-22 01:34:07 +00:00
|
|
|
virtual ~OPLio() {}
|
|
|
|
|
2006-02-24 04:48:15 +00:00
|
|
|
void OPLwriteChannel(uint regbase, uint channel, uchar data1, uchar data2);
|
|
|
|
void OPLwriteValue(uint regbase, uint channel, uchar value);
|
|
|
|
void OPLwriteFreq(uint channel, uint freq, uint octave, uint keyon);
|
|
|
|
uint OPLconvertVolume(uint data, uint volume);
|
|
|
|
uint OPLpanVolume(uint volume, int pan);
|
|
|
|
void OPLwriteVolume(uint channel, struct OPL2instrument *instr, uint volume);
|
|
|
|
void OPLwritePan(uint channel, struct OPL2instrument *instr, int pan);
|
|
|
|
void OPLwriteInstrument(uint channel, struct OPL2instrument *instr);
|
|
|
|
void OPLshutup(void);
|
|
|
|
|
|
|
|
virtual int OPLinit(uint numchips, uint rate);
|
|
|
|
virtual void OPLdeinit(void);
|
|
|
|
virtual void OPLwriteReg(int which, uint reg, uchar data);
|
|
|
|
|
|
|
|
uint OPLchannels;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct musicBlock {
|
|
|
|
musicBlock();
|
|
|
|
~musicBlock();
|
|
|
|
|
|
|
|
BYTE *score;
|
|
|
|
BYTE *scoredata;
|
|
|
|
int playingcount;
|
|
|
|
OPLdata driverdata;
|
|
|
|
OPLio *io;
|
|
|
|
|
|
|
|
struct OP2instrEntry *OPLinstruments;
|
|
|
|
|
|
|
|
ulong MLtime;
|
|
|
|
|
|
|
|
int playTick();
|
|
|
|
|
|
|
|
void OPLplayNote(uint channel, uchar note, int volume);
|
|
|
|
void OPLreleaseNote(uint channel, uchar note);
|
|
|
|
void OPLpitchWheel(uint channel, int pitch);
|
|
|
|
void OPLchangeControl(uint channel, uchar controller, int value);
|
|
|
|
void OPLplayMusic();
|
|
|
|
void OPLstopMusic();
|
|
|
|
void OPLchangeVolume(uint volume);
|
|
|
|
|
|
|
|
int OPLloadBank (FileReader &data);
|
|
|
|
|
|
|
|
private:
|
|
|
|
/* OPL channel (voice) data */
|
|
|
|
struct channelEntry {
|
|
|
|
uchar channel; /* MUS channel number */
|
|
|
|
uchar note; /* note number */
|
|
|
|
uchar flags; /* see CH_xxx below */
|
|
|
|
uchar realnote; /* adjusted note number */
|
|
|
|
schar finetune; /* frequency fine-tune */
|
|
|
|
sint pitch; /* pitch-wheel value */
|
|
|
|
uint volume; /* note volume */
|
|
|
|
uint realvolume; /* adjusted note volume */
|
|
|
|
struct OPL2instrument *instr; /* current instrument */
|
|
|
|
ulong time; /* note start time */
|
|
|
|
} channels[MAXCHANNELS];
|
|
|
|
|
|
|
|
void writeFrequency(uint slot, uint note, int pitch, uint keyOn);
|
|
|
|
void writeModulation(uint slot, struct OPL2instrument *instr, int state);
|
|
|
|
uint calcVolume(uint channelVolume, uint MUSvolume, uint noteVolume);
|
|
|
|
int occupyChannel(uint slot, uint channel,
|
|
|
|
int note, int volume, struct OP2instrEntry *instrument, uchar secondary);
|
|
|
|
int releaseChannel(uint slot, uint killed);
|
|
|
|
int releaseSustain(uint channel);
|
|
|
|
int findFreeChannel(uint flag, uint channel, uchar note);
|
|
|
|
struct OP2instrEntry *getInstrument(uint channel, uchar note);
|
|
|
|
|
|
|
|
friend class Stat_opl;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
enum MUSctrl {
|
|
|
|
ctrlPatch = 0,
|
|
|
|
ctrlBank,
|
|
|
|
ctrlModulation,
|
|
|
|
ctrlVolume,
|
|
|
|
ctrlPan,
|
|
|
|
ctrlExpression,
|
|
|
|
ctrlReverb,
|
|
|
|
ctrlChorus,
|
|
|
|
ctrlSustainPedal,
|
|
|
|
ctrlSoftPedal,
|
|
|
|
_ctrlCount_,
|
|
|
|
ctrlSoundsOff = _ctrlCount_,
|
|
|
|
ctrlNotesOff,
|
|
|
|
ctrlMono,
|
|
|
|
ctrlPoly,
|
|
|
|
ctrlResetCtrls
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // __MUSLIB_H_
|