358 lines
18 KiB
C++
Executable file
358 lines
18 KiB
C++
Executable file
#ifndef _FMOD_CODEC_MIDI_H
|
|
#define _FMOD_CODEC_MIDI_H
|
|
|
|
#include "fmod_settings.h"
|
|
|
|
#ifdef FMOD_SUPPORT_MIDI
|
|
|
|
#include "fmod_music.h"
|
|
|
|
namespace FMOD
|
|
{
|
|
class DSPI;
|
|
class ChannelPool;
|
|
class CodecMIDI;
|
|
class CodecMIDITrack;
|
|
class CodecMIDIChannel;
|
|
|
|
#ifdef FMOD_SUPPORT_PRAGMAPACK
|
|
#pragma pack(1)
|
|
#endif
|
|
|
|
typedef struct
|
|
{
|
|
char mID[4] FMOD_PACKED_INTERNAL;
|
|
unsigned int mSize FMOD_PACKED_INTERNAL;
|
|
} FMOD_PACKED MIDI_CHUNK;
|
|
|
|
typedef struct
|
|
{
|
|
MIDI_CHUNK mChunk FMOD_PACKED_INTERNAL;
|
|
unsigned short mFormat FMOD_PACKED_INTERNAL;
|
|
unsigned short mNumTracks FMOD_PACKED_INTERNAL;
|
|
unsigned short mDivision FMOD_PACKED_INTERNAL;
|
|
} FMOD_PACKED MTHD_CHUNK;
|
|
|
|
#ifdef FMOD_SUPPORT_PRAGMAPACK
|
|
#ifdef CODEWARRIOR
|
|
#pragma pack(0)
|
|
#else
|
|
#pragma pack()
|
|
#endif
|
|
#endif
|
|
|
|
typedef enum
|
|
{
|
|
MIDI_FORMAT_SINGLETRACK,
|
|
MIDI_FORMAT_MULTITRACK,
|
|
MIDI_FORMAT_PATTERN,
|
|
} MIDI_FORMAT;
|
|
|
|
static const unsigned char MIDI_VOICE_NOTEOFF = 0x80;
|
|
static const unsigned char MIDI_VOICE_NOTEON = 0x90;
|
|
static const unsigned char MIDI_VOICE_AFTERTOUCH = 0xA0;
|
|
static const unsigned char MIDI_VOICE_CONTROLLERCHANGE = 0xB0;
|
|
static const unsigned char MIDI_VOICE_PROGRAMCHANGE = 0xC0;
|
|
static const unsigned char MIDI_VOICE_CHANNELKEYPRESSURE= 0xD0;
|
|
static const unsigned char MIDI_VOICE_PITCHBEND = 0xE0;
|
|
static const unsigned char MIDI_SYSEXESCAPE = 0xF7;
|
|
static const unsigned char MIDI_SYSEXEVENT = 0xF0;
|
|
static const unsigned char MIDI_METAEVENT = 0xFF;
|
|
|
|
static const unsigned char MIDI_METAEVENT_SEQNUMBER = 0x00;
|
|
static const unsigned char MIDI_METAEVENT_TEXT = 0x01;
|
|
static const unsigned char MIDI_METAEVENT_COPYRIGHT = 0x02;
|
|
static const unsigned char MIDI_METAEVENT_NAME = 0x03;
|
|
static const unsigned char MIDI_METAEVENT_INSTRUMENT = 0x04;
|
|
static const unsigned char MIDI_METAEVENT_LYRIC = 0x05;
|
|
static const unsigned char MIDI_METAEVENT_MARKER = 0x06;
|
|
static const unsigned char MIDI_METAEVENT_CUEPOINT = 0x07;
|
|
static const unsigned char MIDI_METAEVENT_PATCHNAME = 0x08;
|
|
static const unsigned char MIDI_METAEVENT_PORTNAME = 0x09;
|
|
static const unsigned char MIDI_METAEVENT_CHANNEL = 0x20;
|
|
static const unsigned char MIDI_METAEVENT_PORT = 0x21;
|
|
static const unsigned char MIDI_METAEVENT_ENDOFTRACK = 0x2F;
|
|
static const unsigned char MIDI_METAEVENT_TEMPO = 0x51;
|
|
static const unsigned char MIDI_METAEVENT_SMTPOFFSET = 0x54;
|
|
static const unsigned char MIDI_METAEVENT_TIMESIGNATURE = 0x58;
|
|
static const unsigned char MIDI_METAEVENT_KEYSIGNATURE = 0x59;
|
|
static const unsigned char MIDI_METAEVENT_PROPRIETARY = 0x7F;
|
|
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_BANKSELECT_MSB = 0; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_MODULATIONWHEEL_MSB = 1; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_BREATHCONTROL_MSB = 2; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_FOOTCONTROLLER_MSB = 4; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_PORTAMENTOTIME_MSB = 5; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_DATAENTRY_MSB = 6; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_CHANNELVOLUME_MSB = 7; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_BALANCE_MSB = 8; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_PAN_MSB = 10; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_EXPRESSIONCONTROLLER_MSB = 11; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_EFFECTCONTROL1_MSB = 12; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_EFFECTCONTROL2_MSB = 13; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER1_MSB = 16; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER2_MSB = 17; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER3_MSB = 18; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER4_MSB = 19; // 0-127 MSB
|
|
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_BANKSELECT_LSB = 32; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_MODULATIONWHEEL_LSB = 33; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_BREATHCONTROL_LSB = 34; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_FOOTCONTROLLER_LSB = 36; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_PORTAMENTOTIME_LSB = 37; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_DATAENTRY_LSB = 38; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_CHANNELVOLUME_LSB = 39; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_BALANCE_LSB = 40; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_PAN_LSB = 42; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_EXPRESSIONCONTROLLER_LSB = 43; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_EFFECTCONTROL1_LSB = 44; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_EFFECTCONTROL2_LSB = 45; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER1_LSB = 48; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER2_LSB = 49; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER3_LSB = 50; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER4_LSB = 51; // 0-127 LSB
|
|
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_DAMPERPEDALONOFF = 64; // >64=ON
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_PORTAMENTOONOFF = 65; // >64=ON
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SUSTENUTOONOFF = 66; // >64=ON
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SOFTPEDALONOFF = 67; // >64=ON
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_LEGATOFOOTSWITCH = 68; // >64=ON
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_HOLD2 = 69; // >64=ON
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SOUNDCONTROLLER1 = 70; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SOUNDCONTROLLER2 = 71; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SOUNDCONTROLLER3 = 72; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SOUNDCONTROLLER4 = 73; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SOUNDCONTROLLER5 = 74; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SOUNDCONTROLLER6 = 75; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SOUNDCONTROLLER7 = 76; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SOUNDCONTROLLER8 = 77; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SOUNDCONTROLLER9 = 78; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_SOUNDCONTROLLER10 = 79; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER5 = 80; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER6 = 81; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER7 = 82; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_GENERALPURPOSECONTROLLER8 = 83; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_PORTAMENTOCONTROL = 84; // -127 SOURCE NOTE
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_EFFECTS1DEPTH = 91; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_EFFECTS2DEPTH = 92; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_EFFECTS3DEPTH = 93; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_EFFECTS4DEPTH = 94; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_EFFECTS5DEPTH = 95; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_DATAENTRYINC = 96; // N/A
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_DATAENTRYDEC = 97; // N/A
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_NONREGISTEREDPARAMNUMBER_LSB = 98; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_NONREGISTEREDPARAMNUMBER_MSB = 99; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_REGISTEREDPARAMETERNUMBER_LSB = 100; // 0-127 LSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_REGISTEREDPARAMETERNUMBER_MSB = 101; // 0-127 MSB
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_ALLSOUNDOFF = 120;
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_RESETALLCONTROLLERS = 121;
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_LOCALCONTROLONOFF = 122;
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_ALLNOTESOFF = 123;
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_OMNIMODEOFF = 124;
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_OMNIMODEON = 125;
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_POLYMODEONOFF = 126;
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_POLYMODEON = 127;
|
|
|
|
static const unsigned char MIDI_CONTROLLERCHANGE_RPN_PITCHBENDSENSITIVITY = 0;
|
|
|
|
static const unsigned int MIDI_F_INSTRUMENT_DRUMS = 0x80000000;
|
|
|
|
static const int MIDI_DEFAULTSUBCHANNELS = 32;
|
|
static const int MIDI_MINIMUMSAMPLEGRANULARITY = 512; // 10.66ms @ 48khz :S
|
|
|
|
class CodecMIDIDLSCache : public LinkedListNode
|
|
{
|
|
public:
|
|
|
|
char mFilePath[FMOD_STRING_MAXPATHLEN];
|
|
SoundI *mDLSFile;
|
|
int mRefCount;
|
|
};
|
|
|
|
class CodecMIDISubChannel : public LinkedListNode
|
|
{
|
|
public:
|
|
|
|
CodecMIDI *mMIDI;
|
|
ChannelI mChannel;
|
|
CodecDLSInstrument *mInstrument;
|
|
|
|
float mLFOStartDelay;
|
|
float mLFOTime;
|
|
float mLFOFrequency;
|
|
CodecDLSEnvelope mVolumeEnvelope;
|
|
CodecDLSEnvelope mPitchEnvelope;
|
|
|
|
int mCurrentNote;
|
|
SoundI *mSound;
|
|
unsigned char mKeyOnKey;
|
|
unsigned char mUnityNote;
|
|
int mFineTune;
|
|
unsigned char mKeyOnVelocity;
|
|
int mNumArticulators;
|
|
DLS_CONNECTIONBLOCK *mArticulator;
|
|
|
|
float mTremoloScale;
|
|
float mVibratoScale;
|
|
float mPanbrelloScale;
|
|
|
|
bool mKeyOff;
|
|
int mMiddleC;
|
|
int mKeyGroup;
|
|
float mSampleAttenuation;
|
|
CodecMIDIChannel *mParent;
|
|
|
|
FMOD_RESULT displayArticulators();
|
|
FMOD_RESULT findArticulator(int src, int dest);
|
|
FMOD_RESULT articulateDest(CONN_SRC_FLAGS srcflags, int dest, int *usDestination);
|
|
FMOD_RESULT setUpArticulators();
|
|
FMOD_RESULT stop();
|
|
FMOD_RESULT updateVolume();
|
|
FMOD_RESULT updatePitch();
|
|
FMOD_RESULT updatePan();
|
|
|
|
float getTimeCentsFromlScale(int lScale);
|
|
};
|
|
|
|
class CodecMIDIChannel : public LinkedListNode
|
|
{
|
|
public:
|
|
CodecMIDITrack *mTrack;
|
|
CodecMIDISubChannel mChannelHead;
|
|
unsigned char mIndex;
|
|
unsigned char mKeyOffVelocity;
|
|
unsigned char mKeyOnVelocity;
|
|
unsigned char mAfterTouchKey;
|
|
unsigned char mAfterTouchPressure;
|
|
unsigned int mBank;
|
|
unsigned char mProgram;
|
|
unsigned int mRPN;
|
|
unsigned char mChannelPressure;
|
|
float mMasterVolume;
|
|
int mPitchBend;
|
|
int mPitchBendSensitivity;
|
|
bool mDamperPedal;
|
|
|
|
int mModWheel; // cc1
|
|
int mVolume; // cc7
|
|
int mPan; // cc10
|
|
int mExpression; // cc11
|
|
|
|
FMOD_RESULT getSound(int key, SoundI **sound, CodecDLSInstrument **instrument, int *unitynote, int *finetune, int *attenuation, bool *duplicateallowed, int *keygroup, int *numarticulators, DLS_CONNECTIONBLOCK **articulators);
|
|
FMOD_RESULT process(unsigned char event, bool reuse, unsigned char runningdata, bool calledfromopen);
|
|
FMOD_RESULT update();
|
|
};
|
|
|
|
class CodecMIDITrack
|
|
{
|
|
public:
|
|
|
|
CodecMIDI *mMIDI;
|
|
|
|
unsigned char *mData;
|
|
unsigned int mOffset;
|
|
unsigned int mLength;
|
|
int mIndex;
|
|
bool mReadDelta;
|
|
float mTick;
|
|
bool mFinished;
|
|
unsigned char mPort;
|
|
unsigned char mEvent;
|
|
|
|
FMOD_RESULT readVarLen(unsigned int *result);
|
|
FMOD_RESULT readByte(unsigned char *result);
|
|
FMOD_RESULT readWord(unsigned short *result);
|
|
FMOD_RESULT readDWord(unsigned int *result);
|
|
FMOD_RESULT read(void *buff, int length);
|
|
FMOD_RESULT addTag(const char *name, int length, bool calledfromopen);
|
|
FMOD_RESULT process(bool calledfromopen);
|
|
};
|
|
|
|
|
|
class CodecMIDI : public Codec
|
|
{
|
|
friend class CodecMIDIChannel;
|
|
friend class CodecMIDITrack;
|
|
|
|
private:
|
|
|
|
DSPI *mDSPHead;
|
|
ChannelPool *mChannelPool;
|
|
ChannelSoftware *mChannelSoftware; /* Array of FMOD Ex low level real channels. Each one of these lives in a ChannelI channel. */
|
|
int mNumSubChannels;
|
|
ChannelGroupI mChannelGroup;
|
|
CodecMIDISubChannel *mMIDISubChannel;
|
|
CodecMIDIChannel mMIDIChannel[16];
|
|
|
|
bool mFinished;
|
|
|
|
int mSequenceNumber;
|
|
unsigned int mMixerSamplesLeft;
|
|
unsigned int mMixerSamplesPerTick;
|
|
float mTimingScale;
|
|
unsigned int mPCMOffset;
|
|
unsigned int mDSPTick;
|
|
|
|
int mNumTracks;
|
|
MIDI_FORMAT mMIDIFormat;
|
|
int mDivision;
|
|
unsigned char mSMTPOffsetHours;
|
|
unsigned char mSMTPOffsetMinutes;
|
|
unsigned char mSMTPOffsetSeconds;
|
|
unsigned char mSMTPOffsetFrames;
|
|
unsigned char mSMTPOffsetSubFrames;
|
|
|
|
unsigned char mTimeSignatureNumerator;
|
|
unsigned char mTimeSignatureDenominator;
|
|
unsigned char mTimeSignatureMetronome;
|
|
unsigned char mTimeSignatureNotated32nds;
|
|
|
|
unsigned char mKeySignatureSF;
|
|
unsigned char mKeySignatureMI;
|
|
|
|
CodecMIDITrack *mTrack;
|
|
unsigned int mTempo;
|
|
float mTick;
|
|
float mMillisecondsPerTick;
|
|
float mMillisecondsPlayed; /* Only valid while loading */
|
|
|
|
CodecMIDIDLSCache *mDLSCache;
|
|
SoundI *mDLSSound;
|
|
CodecDLS *mDLS;
|
|
bool *mSampleInclusionList;
|
|
|
|
FMOD_RESULT play(bool fromopen);
|
|
FMOD_RESULT readVarLen(unsigned int *length);
|
|
FMOD_RESULT update(bool audible);
|
|
|
|
FMOD_RESULT openInternal(FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo);
|
|
FMOD_RESULT closeInternal();
|
|
FMOD_RESULT readInternal(void *buffer, unsigned int size, unsigned int *read);
|
|
FMOD_RESULT setPositionInternal(int subsound, unsigned int position, FMOD_TIMEUNIT postype);
|
|
FMOD_RESULT getMusicNumChannelsInternal(int *numchannels);
|
|
FMOD_RESULT setMusicChannelVolumeInternal(int channel, float volume);
|
|
FMOD_RESULT getMusicChannelVolumeInternal(int channel, float *volume);
|
|
|
|
static CodecMIDIDLSCache gDLSCacheHead;
|
|
|
|
public:
|
|
|
|
CodecMIDISubChannel mChannelFreeListHead;
|
|
|
|
static FMOD_RESULT F_CALLBACK openCallback(FMOD_CODEC_STATE *codec, FMOD_MODE usermode, FMOD_CREATESOUNDEXINFO *userexinfo);
|
|
static FMOD_RESULT F_CALLBACK closeCallback(FMOD_CODEC_STATE *codec);
|
|
static FMOD_RESULT F_CALLBACK readCallback(FMOD_CODEC_STATE *codec, void *buffer, unsigned int sizebytes, unsigned int *bytesread);
|
|
static FMOD_RESULT F_CALLBACK setPositionCallback(FMOD_CODEC_STATE *codec, int subsound, unsigned int position, FMOD_TIMEUNIT postype);
|
|
static FMOD_RESULT F_CALLBACK getMusicNumChannelsCallback(FMOD_CODEC_STATE *codec, int *numchannels);
|
|
static FMOD_RESULT F_CALLBACK setMusicChannelVolumeCallback(FMOD_CODEC_STATE *codec, int channel, float volume);
|
|
static FMOD_RESULT F_CALLBACK getMusicChannelVolumeCallback(FMOD_CODEC_STATE *codec, int channel, float *volume);
|
|
|
|
static FMOD_CODEC_DESCRIPTION_EX *getDescriptionEx();
|
|
|
|
};
|
|
}
|
|
|
|
#endif /* FMOD_SUPPORT_MIDI */
|
|
|
|
#endif
|
|
|