aboutsummaryrefslogblamecommitdiff
path: root/qmidiplayer-lite/qmpmidiplay.hpp
blob: e2ef047f4dee9b2df3e542a227e22f960038fb23 (plain) (tree)
1
2
3
4
5
6
7
8
9








                                     






















                                                                                                  


               







                                                             
 


















                                                   


                 

















                                                                             
 
















                                                      
 



                                           
 








                                             
 







                                                 
 




                                
 









                                                                              
 



                                         

      
//sorry for the stupid C-like code...
#ifndef QMPMIDIPLAY_H
#define QMPMIDIPLAY_H
#include <cstring>
#include <cstdint>
#include <cstdlib>
#include <fluidsynth.h>
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