//sorry for the stupid C-like code... #ifndef QMPMIDIPLAY_H #define QMPMIDIPLAY_H #include #include #include #include struct SEvent { uint32_t iid, time, p1, p2; uint8_t type; char *str; SEvent() { time = p1 = p2 = 0; type = 0; str = NULL; } SEvent(uint32_t _iid, uint32_t _t, char _tp, uint32_t _p1, uint32_t _p2, const char *s = NULL) { iid = _iid; time = _t; type = _tp; p1 = _p1; p2 = _p2; if (s) { str = new char[strlen(s) + 2]; strcpy(str, s); } else str = NULL; } }; class CMidiFile { private: SEvent *eventList[10000000]; char *title, *copyright; uint32_t eventc, std; //standard 0=? 1=GM 2=GM2 3=GS 4=XG uint32_t fmt, trk, divs; FILE *f; int byteread, valid; uint32_t notes, curt, curid; void error(int fatal, const char *format, ...); uint32_t readSW(); uint32_t readDW(); uint32_t readVL(); int eventReader(); void trackChunkReader(); void headerChunkReader(); int chunkReader(int hdrXp); public: CMidiFile(const char *fn); ~CMidiFile(); const SEvent *getEvent(uint32_t id); uint32_t getEventCount(); uint32_t getDivision(); uint32_t getNoteCount(); uint32_t getStandard(); const char *getTitle(); const char *getCopyright(); bool isValid(); }; class CMidiPlayer { private: CMidiFile *midiFile; uint32_t stamps[101]; uint32_t ccstamps[101][16][135], ccc[16][135]; //0..127:cc 128:pc 129:cp 130:pb 131:tempo 132:ts 133:ks 134:pbr int32_t rpnid, rpnval; uint16_t mute, solo; double ftime; bool sendSysEx, singleInstance, waitvoice; fluid_settings_t *settings; fluid_synth_t *synth; fluid_audio_driver_t *adriver; fluid_player_t *player; uint32_t ctempo, ctsn, ctsd, dpt, divs, cks; //raw tempo, timesig num., timesig den., delay per tick, division, keysig //thread control uint32_t tceptr, tcpaused, tcstop; uint32_t finished, resumed; void setBit(uint16_t &n, uint16_t bn, uint16_t b); void processEvent(const SEvent *e); void processEventStub(const SEvent *e); void playEvents(); void fileTimer1Pass(); void fileTimer2Pass(); public: CMidiPlayer(bool singleInst = false); ~CMidiPlayer(); bool playerLoadFile(const char *fn); void playerInit(); void fluidPreInitialize(); void fluidInitialize(); void fluidDeinitialize(); void playerDeinit(); void playerThread(); void playerPanic(bool reset = false); void rendererLoadFile(const char *ofn); void rendererInit(const char *fn); void rendererThread(); void rendererDeinit(); //playing control methods uint32_t getStamp(int id); uint32_t getTCeptr(); void setTCeptr(uint32_t ep, uint32_t st); uint32_t getTCpaused(); void setTCpaused(uint32_t ps); uint32_t isFinished(); void setResumed(); void setWaitVoice(bool wv); double getFtime(); void getCurrentTimeSignature(int *n, int *d); void getCurrentKeySignature(int *ks); uint32_t getFileNoteCount(); uint32_t getFileStandard(); double getTempo(); const char *getTitle(); const char *getCopyright(); void setGain(double gain); void sendSysX(bool send); int getPolyphone(); int getMaxPolyphone(); void setMaxPolyphone(int p); void setChannelPreset(int ch, int b, int p); void getChannelPreset(int ch, int *b, int *p, char *name); void setMute(int ch, bool m); void setSolo(int ch, bool s); int getCC(int ch, int id); void setCC(int ch, int id, int val); void getReverbPara(double *r, double *d, double *w, double *l); void setReverbPara(int e, double r, double d, double w, double l); void getChorusPara(int *fb, double *l, double *r, double *d, int *type); void setChorusPara(int e, int fb, double l, double r, double d, int type); fluid_settings_t *getFluidSettings(); void pushSoundFont(const char *sf); int getSFCount(); fluid_sfont_t *getSFPtr(int sfid); }; #endif