gzdoom/src/oplsynth/muslib.h

193 lines
5.8 KiB
C
Raw Normal View History

/*
* 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 {
virtual ~OPLio() {}
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_