diff options
Diffstat (limited to 'qmidiplayerlite.src.d')
-rw-r--r-- | qmidiplayerlite.src.d/deployment.pri | 13 | ||||
-rw-r--r-- | qmidiplayerlite.src.d/main.cpp | 15 | ||||
-rw-r--r-- | qmidiplayerlite.src.d/main.qml | 144 | ||||
-rw-r--r-- | qmidiplayerlite.src.d/qml.qrc | 5 | ||||
-rw-r--r-- | qmidiplayerlite.src.d/qmpcorewrapper.hpp | 58 | ||||
-rw-r--r-- | qmidiplayerlite.src.d/qmpmidiplay.cpp | 406 | ||||
-rw-r--r-- | qmidiplayerlite.src.d/qmpmidiplay.hpp | 137 | ||||
-rw-r--r-- | qmidiplayerlite.src.d/qmpmidiread.cpp | 240 |
8 files changed, 0 insertions, 1018 deletions
diff --git a/qmidiplayerlite.src.d/deployment.pri b/qmidiplayerlite.src.d/deployment.pri deleted file mode 100644 index 265ce71..0000000 --- a/qmidiplayerlite.src.d/deployment.pri +++ /dev/null @@ -1,13 +0,0 @@ -unix:!android { - isEmpty(target.path) { - qnx { - target.path = /tmp/$${TARGET}/bin - } else { - target.path = /opt/$${TARGET}/bin - } - export(target.path) - } - INSTALLS += target -} - -export(INSTALLS) diff --git a/qmidiplayerlite.src.d/main.cpp b/qmidiplayerlite.src.d/main.cpp deleted file mode 100644 index 1a87b33..0000000 --- a/qmidiplayerlite.src.d/main.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include <QApplication> -#include <QtQml> -#include <QQmlApplicationEngine> -#include "qmpcorewrapper.hpp" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - qmlRegisterType<CQMPCoreWrapper>("org.chrisoft.qmpcore",1,0,"CQMPCoreWrapper"); - - QQmlApplicationEngine engine; - engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); - - return app.exec(); -} diff --git a/qmidiplayerlite.src.d/main.qml b/qmidiplayerlite.src.d/main.qml deleted file mode 100644 index 0ec0975..0000000 --- a/qmidiplayerlite.src.d/main.qml +++ /dev/null @@ -1,144 +0,0 @@ -import QtQuick 2.3 -import QtQuick.Window 2.2 -import QtQuick.Controls 1.0 -import QtQuick.Dialogs 1.0 -import org.chrisoft.qmpcore 1.0 - -Window { - id: window1 - width: 420 - height: 240 - title: "QMidiPlayer Lite" - visible: true - property bool playing - playing: false - - MouseArea { - id: mouseArea1 - anchors.rightMargin: 0 - anchors.bottomMargin: 0 - anchors.leftMargin: 0 - anchors.topMargin: 0 - anchors.fill: parent - onClicked: { - //Qt.quit(); - } - - Button { - id: button2 - x: 170 - text: qsTr("Play") - anchors.top: parent.top - anchors.topMargin: 172 - anchors.horizontalCenter: parent.horizontalCenter - onClicked: { - if(!playing) - { - qmpcore.loadFile(fileName.text); - qmpcore.initFluidSynth(); - qmpcore.playFile(); - playing=true; - uiTimer.start(); - text="Stop"; - } - else - { - qmpcore.stop(); - playing=false; - text="Play"; - hsTimer.value=0;uiTimer.stop(); - } - } - } - - Slider { - id: hsTimer - y: 210 - height: 22 - anchors.right: parent.right - anchors.rightMargin: 8 - anchors.left: parent.left - anchors.leftMargin: 8 - anchors.bottom: parent.bottom - anchors.bottomMargin: 8 - tickmarksEnabled: false - stepSize: 1 - maximumValue: 100 - property bool autovalchange: false - onValueChanged: { - if(autovalchange||pressed)return; - if(playing){qmpcore.setTCeptr(value);qmpcore.panic();} - } - onPressedChanged: { - if(!pressed) - { - /*if(playing) - { - if(ui->hsTimer->value()==100){on_pbNext_clicked();return;} - player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value()); - player->playerPanic(); - offset=ui->hsTimer->value()/100.*player->getFtime(); - st=std::chrono::steady_clock::now(); - } - else - { - player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value()); - offset=ui->hsTimer->value()/100.*player->getFtime(); - char ts[100]; - sprintf(ts,"%02d:%02d",(int)(offset)/60,(int)(offset)%60); - ui->lbCurTime->setText(ts); - }*/ - if(playing){qmpcore.setTCeptr(value);qmpcore.panic();} - } - } - } - } - - CQMPCoreWrapper { - id: qmpcore - } - Timer { - id: uiTimer - interval: 100 - running: false - repeat: true - onTriggered: { - if(!hsTimer.pressed) - { - hsTimer.autovalchange=true; - hsTimer.value=qmpcore.getProgress(); - hsTimer.autovalchange=false; - } - } - } - - Text { - id: fileName - text: qsTr("...") - anchors.centerIn: parent - } - - Button { - id: button1 - x: 170 - width: 80 - height: 27 - text: qsTr("Open") - anchors.top: parent.top - anchors.topMargin: 142 - anchors.horizontalCenter: parent.horizontalCenter - onClicked: { - fileDialog.open(); - } - } - - FileDialog { - id: fileDialog - title: qsTr("Select midi file") - nameFilters: ["MIDI Files (*.mid *.midi)"] - onAccepted: { - fileName.text=fileUrl; - } - } -} - diff --git a/qmidiplayerlite.src.d/qml.qrc b/qmidiplayerlite.src.d/qml.qrc deleted file mode 100644 index 5f6483a..0000000 --- a/qmidiplayerlite.src.d/qml.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>main.qml</file> - </qresource> -</RCC> diff --git a/qmidiplayerlite.src.d/qmpcorewrapper.hpp b/qmidiplayerlite.src.d/qmpcorewrapper.hpp deleted file mode 100644 index 558ed74..0000000 --- a/qmidiplayerlite.src.d/qmpcorewrapper.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef QMPCOREWRAPPER_H -#define QMPCOREWRAPPER_H -#include <QObject> -#include <QUrl> -#include <thread> -#include <fluidsynth.h> -#include "../common/qmpmidiplay.hpp" -class CQMPCoreWrapper:public QObject -{ - Q_OBJECT -private: - CMidiPlayer *mp; - std::thread *playerTh; - int curprog; -public: - explicit CQMPCoreWrapper(QObject* parent=0):QObject(parent) - { - mp=new CMidiPlayer(false); - } - ~CQMPCoreWrapper(){delete mp;} - Q_INVOKABLE void initFluidSynth() - { - fluid_settings_t *fsettings=mp->getFluidSettings(); - fluid_settings_setstr(fsettings,"audio.driver","pulseaudio"); - mp->fluidInitialize(); - mp->pushSoundFont("/media/Files/FluidR3_Ext.sf2"); - } - Q_INVOKABLE void deinitFluidSynth() - { - mp->fluidDeinitialize(); - } - Q_INVOKABLE void loadFile(QUrl file) - { - mp->playerLoadFile(file.toLocalFile().toStdString().c_str()); - mp->playerInit();curprog=0; - } - Q_INVOKABLE void playFile() - { - playerTh=new std::thread(&CMidiPlayer::playerThread,mp); - } - Q_INVOKABLE void stop() - { - mp->playerDeinit();playerTh->join();delete playerTh; - } - Q_INVOKABLE int getProgress() - { - while(!mp->isFinished()&&mp->getTCeptr()>mp->getStamp(curprog) - &&curprog<=100) - ++curprog; - return curprog; - } - Q_INVOKABLE void panic(){mp->playerPanic();} - Q_INVOKABLE void setTCeptr(int perct) - { - mp->setTCeptr(mp->getStamp(perct),perct);curprog=perct; - } -}; -#endif // QMPCOREWRAPPER_H diff --git a/qmidiplayerlite.src.d/qmpmidiplay.cpp b/qmidiplayerlite.src.d/qmpmidiplay.cpp deleted file mode 100644 index baec9a2..0000000 --- a/qmidiplayerlite.src.d/qmpmidiplay.cpp +++ /dev/null @@ -1,406 +0,0 @@ -#include <cstdio> -#include <chrono> -#include <thread> -#include <fluidsynth.h> -#include "qmpmidiplay.hpp" -#ifdef _WIN32 -#include <windows.h> -uint64_t pf; -#endif -void CMidiPlayer::fluidPreInitialize() -{ - settings=new_fluid_settings(); -} -void CMidiPlayer::fluidInitialize() -{ - synth=new_fluid_synth(settings); - adriver=new_fluid_audio_driver(settings,synth); - fluid_synth_set_chorus(synth,FLUID_CHORUS_DEFAULT_N,FLUID_CHORUS_DEFAULT_LEVEL, - FLUID_CHORUS_DEFAULT_SPEED,FLUID_CHORUS_DEFAULT_DEPTH, - FLUID_CHORUS_DEFAULT_TYPE); -#ifndef _WIN32 - if(!singleInstance) - { - if(midiFile->getStandard()==4) - fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_MELODIC); - else if(midiFile->getStandard()==1) - fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_DRUM); - else - { - fluid_synth_set_channel_type(synth,9,CHANNEL_TYPE_DRUM); - fluid_synth_bank_select(synth,9,128); - } - } -#endif -} -void CMidiPlayer::fluidDeinitialize() -{ - if(!synth||!adriver||!settings)return; - delete_fluid_settings(settings); - delete_fluid_audio_driver(adriver); - delete_fluid_synth(synth); - settings=NULL;synth=NULL;adriver=NULL; -} -void CMidiPlayer::processEvent(const SEvent *e) -{ - switch(e->type&0xF0) - { - case 0x80://Note off - fluid_synth_noteoff(synth,e->type&0x0F,e->p1); - break; - case 0x90://Note on - if((mute>>(e->type&0x0F))&1)break;//muted - if(solo&&!((solo>>(e->type&0x0F))&1))break; - fluid_synth_noteon(synth,e->type&0x0F,e->p1,e->p2); - break; - case 0xB0://CC - if(e->p1==100)rpnid=e->p2; - if(e->p1==6)rpnval=e->p2; - if(~rpnid&&~rpnval) - { - if(rpnid==0)fluid_synth_pitch_wheel_sens(synth,e->type&0x0F,rpnval); - rpnid=rpnval=-1; - } - fluid_synth_cc(synth,e->type&0x0F,e->p1,e->p2); - break; - case 0xC0://PC - fluid_synth_program_change(synth,e->type&0x0F,e->p1); - break; - case 0xE0://PW - fluid_synth_pitch_bend(synth,e->type&0x0F,e->p1); - break; - case 0xF0://Meta/SysEx - if((e->type&0x0F)==0x0F) - { - switch(e->p1) - { - case 0x51: - ctempo=e->p2;dpt=ctempo*1000/divs; - break; - case 0x58: - ctsn=e->p2>>24; - ctsd=1<<((e->p2>>16)&0xFF); - break; - case 0x59: - cks=e->p2; - break; - case 0x01:case 0x02:case 0x03: - case 0x04:case 0x05:case 0x06: - case 0x07: - if(e->str)puts(e->str); - break; - } - } - if((e->type&0x0F)==0x00||(e->type&0x0F)==07) - { - int io=0; - if(sendSysEx)fluid_synth_sysex(synth,e->str,e->p1,NULL,&io,NULL,0); - } - break; - } -} -void CMidiPlayer::processEventStub(const SEvent *e) -{ - switch(e->type&0xF0) - { - case 0xB0://CC - if(e->p1==100)rpnid=e->p2; - if(e->p1==6)rpnval=e->p2; - if(~rpnid&&~rpnval) - { - if(rpnid==0)ccc[e->type&0x0F][134]=rpnval; - rpnid=rpnval=-1; - } - ccc[e->type&0x0F][e->p1]=e->p2; - break; - case 0xC0://PC - ccc[e->type&0x0F][128]=e->p1; - break; - case 0xD0://CP - ccc[e->type&0x0F][129]=e->p1; - break; - case 0xE0://PW - ccc[e->type&0x0F][130]=e->p1; - break; - case 0xF0://Meta/SysEx - if((e->type&0x0F)==0x0F) - { - switch(e->p1) - { - case 0x51: - ctempo=e->p2;dpt=ctempo*1000/divs; - ccc[0][131]=dpt; - break; - case 0x58: - ccc[0][132]=e->p2; - break; - case 0x59: - ccc[0][133]=e->p2; - break; - } - } - break; - } -} -#ifdef _WIN32 -void w32usleep(uint64_t t) -{ - uint64_t st=0,ct=0; - QueryPerformanceCounter((LARGE_INTEGER*)&st); - do{ - if(t>10000+(ct-st)*1000000/pf)Sleep((t-(ct-st)*1000000/pf)/2000); - else if(t>5000+(ct-st)*1000000/pf)Sleep(1); - else std::this_thread::yield(); - QueryPerformanceCounter((LARGE_INTEGER*)&ct); - }while((ct-st)*1000000<t*pf); -} -#endif -void CMidiPlayer::playEvents() -{ - for(uint32_t ct=midiFile->getEvent(0)->time;tceptr<midiFile->getEventCount();) - { - while(tcpaused)std::this_thread::sleep_for(std::chrono::milliseconds(100)); - while(!tcstop&&midiFile&&tceptr<midiFile->getEventCount()&&ct==midiFile->getEvent(tceptr)->time) - processEvent(midiFile->getEvent(tceptr++)); - if(tcstop||!midiFile||tceptr>=midiFile->getEventCount())break; - if(resumed)resumed=false; - else -#ifdef _WIN32 - w32usleep((midiFile->getEvent(tceptr)->time-ct)*(dpt/1000)); -#else - std::this_thread::sleep_for(std::chrono::nanoseconds(midiFile->getEvent(tceptr)->time-ct)*dpt); -#endif - if(tcstop||!midiFile)break; - ct=midiFile->getEvent(tceptr)->time; - } - while(!tcstop&&synth&&(waitvoice&&fluid_synth_get_active_voice_count(synth)>0))std::this_thread::sleep_for(std::chrono::milliseconds(2)); - finished=1; -} -void CMidiPlayer::fileTimer1Pass() -{ - ftime=.0;ctempo=0x7A120;dpt=ctempo*1000/divs; - for(uint32_t eptr=0,ct=midiFile->getEvent(0)->time;eptr<midiFile->getEventCount();) - { - while(eptr<midiFile->getEventCount()&&ct==midiFile->getEvent(eptr)->time) - processEventStub(midiFile->getEvent(eptr++)); - if(eptr>=midiFile->getEventCount())break; - ftime+=(midiFile->getEvent(eptr)->time-ct)*dpt/1e9; - ct=midiFile->getEvent(eptr)->time; - } -} -void CMidiPlayer::fileTimer2Pass() -{ - double ctime=.0;uint32_t c=1;ctempo=0x7A120;dpt=ctempo*1000/divs; - memset(stamps,0,sizeof(stamps));memset(ccstamps,0,sizeof(ccstamps)); - memset(ccc,0,sizeof(ccc));rpnid=rpnval=-1;for(int i=0;i<16;++i) - { - ccc[i][7]=100;ccc[i][10]=64;ccc[i][11]=127; - ccc[i][11]=127;ccc[i][71]=64;ccc[i][72]=64; - ccc[i][73]=64;ccc[i][74]=64;ccc[i][75]=64; - ccc[i][76]=64;ccc[i][77]=64;ccc[i][78]=64; - ccc[0][131]=dpt;ccc[0][132]=0x04021808; - ccc[0][133]=0;ccc[0][134]=2; - }if(midiFile->getStandard()!=4)ccc[9][0]=128; - for(int i=0;i<16;++i)for(int j=0;j<135;++j) - ccstamps[0][i][j]=ccc[i][j]; - for(uint32_t eptr=0,ct=midiFile->getEvent(0)->time;eptr<midiFile->getEventCount();) - { - while(eptr<midiFile->getEventCount()&&ct==midiFile->getEvent(eptr)->time) - processEventStub(midiFile->getEvent(eptr++)); - if(eptr>=midiFile->getEventCount())break; - ctime+=(midiFile->getEvent(eptr)->time-ct)*dpt/1e9; - while(ctime>ftime*c/100.) - { - for(int i=0;i<16;++i)for(int j=0;j<135;++j) - ccstamps[c][i][j]=ccc[i][j]; - stamps[c++]=eptr; - if(c>100)break; - } - ct=midiFile->getEvent(eptr)->time; - } - while(c<101) - { - for(int i=0;i<16;++i)for(int j=0;j<135;++j) - ccstamps[c][i][j]=ccc[i][j]; - stamps[c++]=midiFile->getEventCount(); - } -} -CMidiPlayer::CMidiPlayer(bool singleInst) -{ - midiFile=NULL;resumed=false;singleInstance=singleInst; - settings=NULL;synth=NULL;adriver=NULL;waitvoice=true; -#ifdef _WIN32 - QueryPerformanceFrequency((LARGE_INTEGER*)&pf); - timeBeginPeriod(1); -#endif -} -CMidiPlayer::~CMidiPlayer() -{ - if(singleInstance)fluidDeinitialize(); -#ifdef _WIN32 - timeEndPeriod(1); -#endif -} -void CMidiPlayer::playerPanic(bool reset) -{ - if(reset)for(int i=0;i<16;++i) - { - fluid_synth_pitch_bend(synth,i,8192); - fluid_synth_cc(synth,i,7,100); - fluid_synth_cc(synth,i,10,64); - fluid_synth_cc(synth,i,11,127); - } - for(int i=0;i<16;++i)fluid_synth_all_notes_off(synth,i); -} -bool CMidiPlayer::playerLoadFile(const char* fn) -{ - midiFile=new CMidiFile(fn); - if(!midiFile->isValid())return false; - divs=midiFile->getDivision(); - fileTimer1Pass(); - fileTimer2Pass(); - return true; -} -void CMidiPlayer::playerInit() -{ - ctempo=0x7A120;ctsn=4;ctsd=4;cks=0;dpt=ctempo*1000/divs; - tceptr=0;tcstop=0;tcpaused=0;finished=0;mute=solo=0; - sendSysEx=true;rpnid=rpnval=-1; - if(!singleInstance)fluidPreInitialize(); -} -void CMidiPlayer::playerDeinit() -{ - tceptr=0;tcstop=1;tcpaused=0; - delete midiFile;midiFile=NULL; - if(!singleInstance)fluidDeinitialize(); -} -void CMidiPlayer::playerThread() -{ - playEvents(); -} - -void CMidiPlayer::rendererLoadFile(const char* ofn) -{ - settings=new_fluid_settings(); - fluid_settings_setstr(settings,"audio.file.name",ofn); -} -void CMidiPlayer::rendererInit(const char* fn) -{ - finished=0; - synth=new_fluid_synth(settings); - player=new_fluid_player(synth); - fluid_player_add(player,fn); -} -void CMidiPlayer::rendererThread() -{ - fluid_file_renderer_t* renderer=new_fluid_file_renderer(synth); - fluid_player_play(player); - while(fluid_player_get_status(player)==FLUID_PLAYER_PLAYING) - if(fluid_file_renderer_process_block(renderer)!=FLUID_OK)break; - delete_fluid_file_renderer(renderer); - finished=1; -} -void CMidiPlayer::rendererDeinit() -{ - delete_fluid_player(player); - delete_fluid_synth(synth); - delete_fluid_settings(settings); - player=NULL;synth=NULL;settings=NULL; -} - -void CMidiPlayer::sendSysX(bool send){sendSysEx=send;} -uint32_t CMidiPlayer::getStamp(int id){return stamps[id];} -uint32_t CMidiPlayer::getTCeptr(){return tceptr;} -void CMidiPlayer::setTCeptr(uint32_t ep,uint32_t st) -{ - resumed=true; - if(ep==midiFile->getEventCount())tcstop=1;else tceptr=ep; - for(int i=0;i<16;++i) - { - for(int j=0;j<120;++j)fluid_synth_cc(synth,i,j,ccstamps[st][i][j]); - fluid_synth_program_change(synth,i,ccstamps[st][i][128]); - //fluid_synth_pitch_bend(synth,i,ccstamps[st][i][130]); - dpt=ccstamps[st][0][131];ctempo=dpt*divs/1000; - ctsn=ccstamps[st][0][132]>>24;ctsd=1<<((ccstamps[st][0][132]>>16)&0xFF); - cks=ccstamps[st][0][133]; - } -} -double CMidiPlayer::getFtime(){return ftime;} -void CMidiPlayer::getCurrentTimeSignature(int *n,int *d){*n=ctsn;*d=ctsd;} -void CMidiPlayer::getCurrentKeySignature(int *ks){*ks=cks;} -uint32_t CMidiPlayer::getFileNoteCount(){return midiFile?midiFile->getNoteCount():0;} -uint32_t CMidiPlayer::getFileStandard(){return midiFile?midiFile->getStandard():0;} -const char* CMidiPlayer::getTitle(){return midiFile?midiFile->getTitle():"";} -const char* CMidiPlayer::getCopyright(){return midiFile?midiFile->getCopyright():"";} -double CMidiPlayer::getTempo(){return 60./(ctempo/1e6)/**ctsd/4.*/;} -uint32_t CMidiPlayer::getTCpaused(){return tcpaused;} -void CMidiPlayer::setTCpaused(uint32_t ps){tcpaused=ps;} -uint32_t CMidiPlayer::isFinished(){return finished;} -void CMidiPlayer::setResumed(){resumed=true;} -void CMidiPlayer::setWaitVoice(bool wv){waitvoice=wv;} -void CMidiPlayer::setGain(double gain){if(settings)fluid_settings_setnum(settings,"synth.gain",gain);} -int CMidiPlayer::getPolyphone(){return synth?fluid_synth_get_active_voice_count(synth):0;} -int CMidiPlayer::getMaxPolyphone(){return synth?fluid_synth_get_polyphony(synth):0;} -void CMidiPlayer::setMaxPolyphone(int p){if(synth)fluid_synth_set_polyphony(synth,p);} - -void CMidiPlayer::getChannelPreset(int ch,int *b,int *p,char *name) -{ - if(!synth)return(void)(b=0,p=0,strcpy(name,"")); - fluid_synth_channel_info_t info; - fluid_synth_get_channel_info(synth,ch,&info); - *b=info.bank;*p=info.program; - strcpy(name,info.name); -} -void CMidiPlayer::setChannelPreset(int ch,int b,int p) -{ - if(!synth)return; - fluid_synth_bank_select(synth,ch,b); - fluid_synth_program_change(synth,ch,p); -} -//16MSB..LSB1 -void CMidiPlayer::setBit(uint16_t &n, uint16_t bn, uint16_t b) -{n^=(-b^n)&(1<<bn);} -void CMidiPlayer::setMute(int ch,bool m) -{setBit(mute,ch,m?1:0);} -void CMidiPlayer::setSolo(int ch,bool s) -{setBit(solo,ch,s?1:0);} -int CMidiPlayer::getCC(int ch, int id) -{int ret=0;synth?fluid_synth_get_cc(synth,ch,id,&ret):0;return ret;} -void CMidiPlayer::setCC(int ch, int id, int val) -{synth?fluid_synth_cc(synth,ch,id,val):0;} -void CMidiPlayer::getReverbPara(double *r,double *d,double *w,double *l) -{ - if(!synth)return; - *r=fluid_synth_get_reverb_roomsize(synth); - *d=fluid_synth_get_reverb_damp(synth); - *w=fluid_synth_get_reverb_width(synth); - *l=fluid_synth_get_reverb_level(synth); -} -void CMidiPlayer::setReverbPara(int e,double r,double d,double w,double l) -{ - if(!synth)return; - fluid_synth_set_reverb_on(synth,e); - fluid_synth_set_reverb(synth,r,d,w,l); -} -void CMidiPlayer::getChorusPara(int *fb,double *l,double *r,double *d,int *type) -{ - if(!synth)return; - *fb=fluid_synth_get_chorus_nr(synth); - *l=fluid_synth_get_chorus_level(synth); - *r=fluid_synth_get_chorus_speed_Hz(synth); - *d=fluid_synth_get_chorus_depth_ms(synth); - *type=fluid_synth_get_chorus_type(synth); -} -void CMidiPlayer::setChorusPara(int e,int fb,double l,double r,double d,int type) -{ - if(!synth)return; - fluid_synth_set_chorus_on(synth,e); - fluid_synth_set_chorus(synth,fb,l,r,d,type); -} -fluid_settings_t* CMidiPlayer::getFluidSettings(){return settings;} -void CMidiPlayer::pushSoundFont(const char *sf) -{fluid_synth_sfload(synth,sf,1);} -int CMidiPlayer::getSFCount() -{return synth?fluid_synth_sfcount(synth):0;} -fluid_sfont_t* CMidiPlayer::getSFPtr(int sfid) -{return synth&&sfid<getSFCount()?fluid_synth_get_sfont(synth,sfid):NULL;} diff --git a/qmidiplayerlite.src.d/qmpmidiplay.hpp b/qmidiplayerlite.src.d/qmpmidiplay.hpp deleted file mode 100644 index fafd677..0000000 --- a/qmidiplayerlite.src.d/qmpmidiplay.hpp +++ /dev/null @@ -1,137 +0,0 @@ -//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 diff --git a/qmidiplayerlite.src.d/qmpmidiread.cpp b/qmidiplayerlite.src.d/qmpmidiread.cpp deleted file mode 100644 index 0bcf597..0000000 --- a/qmidiplayerlite.src.d/qmpmidiread.cpp +++ /dev/null @@ -1,240 +0,0 @@ -//CLI Midi file player based on libfluidsynth -//Midi file reading module -//Written by Chris Xiong, 2015 -#include <cstdio> -#include <cstring> -#include <cstdlib> -#include <cstdint> -#include <cstdarg> -#include <algorithm> -#include "qmpmidiplay.hpp" -const char* GM1SysX={"\xF0\x7E\x7F\x09\x01\xF7"}; -const char* GM2SysX={"\xF0\x7E\x7F\x09\x03\xF7"}; -const char* GSSysEx={"\xF0\x41\x10\x42\x12\x40\x00\x7F\x00\x41\xF7"}; -const char* XGSysEx={"\xF0\x43\x10\x4C\x00\x00\x7E\x00\xF7"}; -bool cmp(SEvent *a,SEvent *b){return a->time-b->time?a->time<b->time:a->iid<b->iid;} -void CMidiFile::error(int fatal,const char* format,...) -{ - va_list ap; - va_start(ap,format);vfprintf(stderr,format,ap);va_end(ap); - fprintf(stderr," at %#lx\n",ftell(f)); - if(fatal)throw 2; -} -uint32_t CMidiFile::readSW() -{ - byteread+=2; - uint32_t ret=0; - for(int i=0;i<2;++i){ret<<=8;ret|=((uint32_t)fgetc(f))&0xFF;} - return ret; -} -uint32_t CMidiFile::readDW() -{ - byteread+=4; - uint32_t ret=0; - for(int i=0;i<4;++i){ret<<=8;ret|=((uint32_t)fgetc(f))&0xFF;} - return ret; -} -uint32_t CMidiFile::readVL() -{ - uint32_t ret=0,t,c=0; - do - { - t=fgetc(f); - if(++c>4)error(1,"E: Variable length type overflow."); - ret<<=7;ret|=(t&0x7F); - }while(t&0x80); - byteread+=c; - return ret; -} -int CMidiFile::eventReader()//returns 0 if End of Track encountered -{ - uint32_t delta=readVL();curt+=delta; - char type=fgetc(f);++byteread;uint32_t p1,p2; - static char lasttype; -retry: - switch(type&0xF0) - { - case 0x80://Note Off - p1=fgetc(f);p2=fgetc(f);byteread+=2; - eventList[eventc++]=new SEvent(curid,curt,type,p1,p2); - break; - case 0x90://Note On - p1=fgetc(f);p2=fgetc(f);byteread+=2; - if(p2) - { - ++notes; - eventList[eventc++]=new SEvent(curid,curt,type,p1,p2); - } - else - eventList[eventc++]=new SEvent(curid,curt,(type&0x0F)|0x80,p1,p2); - break; - case 0xA0://Note Aftertouch - p1=fgetc(f);p2=fgetc(f);byteread+=2; - eventList[eventc++]=new SEvent(curid,curt,type,p1,p2); - break; - case 0xB0://Controller Change - p1=fgetc(f);p2=fgetc(f);byteread+=2; - eventList[eventc++]=new SEvent(curid,curt,type,p1,p2); - break; - case 0xC0://Patch Change - p1=fgetc(f);++byteread; - eventList[eventc++]=new SEvent(curid,curt,type,p1,0); - break; - case 0xD0://Channel Aftertouch - p1=fgetc(f);++byteread; - eventList[eventc++]=new SEvent(curid,curt,type,p1,0); - break; - case 0xE0://Pitch wheel - p1=fgetc(f);p2=fgetc(f);byteread+=2; - eventList[eventc++]=new SEvent(curid,curt,type,(p1|(p2<<7))&0x3FFF,0); - break; - case 0xF0: - if((type&0x0F)==0x0F)//Meta Event - { - char metatype=fgetc(f);++byteread; - switch(metatype) - { - case 0x00://Sequence Number - fgetc(f);fgetc(f);fgetc(f); - byteread+=3; - break; - case 0x20://Channel Prefix - fgetc(f);fgetc(f);byteread+=2; - break; - case 0x2F://End of Track - fgetc(f);++byteread; - return 0; - break; - case 0x51://Set Tempo - p1=readDW();p1&=0x00FFFFFF; - eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1); - break; - case 0x54://SMTPE offset, not handled. - fgetc(f);fgetc(f);fgetc(f); - fgetc(f);fgetc(f);fgetc(f); - byteread+=6; - break; - case 0x58://Time signature - fgetc(f);++byteread; - p1=readDW(); - eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1); - break; - case 0x59://Key signature - fgetc(f);++byteread; - p1=readSW(); - eventList[eventc++]=new SEvent(curid,curt,type,metatype,p1); - break; - case 0x01:case 0x02:case 0x03: - case 0x04:case 0x05:case 0x06: - case 0x07:case 0x7F:default://text-like meta - { - uint32_t len=readVL(),c;char* str=NULL; - if(len<=1024&&len>0)str=new char[len+8]; - for(c=0;c<len;++c) - { - ++byteread;if(str)str[c]=fgetc(f);else fgetc(f); - } - if(str)str[c]='\0';eventList[eventc++]=new SEvent(curid,curt,type,metatype,0,str); - if(str&&metatype==0x03&&!title) - { - title=new char[len+8]; - strcpy(title,str); - } - if(str&&metatype==0x02&&!copyright) - { - copyright=new char[len+8]; - strcpy(copyright,str); - } - if(len<=1024&&len>0)delete[] str; - } - } - } - else if((type&0x0F)==0x00||(type&0x0F)==0x07)//SysEx - { - uint32_t len=readVL(),c;char* str=NULL; - str=new char[len+8]; - if((type&0x0F)==0x00) - { - str[0]=0xF0;++len; - for(c=1;c<len;++c){++byteread;str[c]=fgetc(f);} - } - else for(c=0;c<len;++c){++byteread;str[c]=fgetc(f);} - eventList[eventc++]=new SEvent(curid,curt,type,len,0,str); - if(!strcmp(str,GM1SysX))std=1; - if(!strcmp(str,GM2SysX))std=2; - if(!strcmp(str,GSSysEx))std=3; - if(!strcmp(str,XGSysEx))std=4; - } - else error(0,"W: Unknown event type %#x",type); - break; - default: - fseek(f,-1,SEEK_CUR);--byteread;type=lasttype;goto retry; - } - lasttype=type;++curid; - return 1; -} -void CMidiFile::trackChunkReader() -{ - int chnklen=readDW();byteread=0;curt=0;curid=0; - while(/*byteread<chnklen&&*/eventReader()); - if(byteread<chnklen) - { - error(0,"W: Extra bytes after EOT event."); - while(byteread<chnklen){fgetc(f);++byteread;} - } - /*if(byteread>chnklen) - { - error(1,"E: Read past end of track."); - }*/ -} -void CMidiFile::headerChunkReader() -{ - int chnklen=readDW();byteread=0; - if(chnklen<6)error(1,"E: Header chunk too short."); - if(chnklen>6)error(0,"W: Header chunk length longer than expected. Ignoring extra bytes."); - fmt=readSW();trk=readSW();divs=readSW(); - if(divs&0x8000)error(1,"E: SMTPE format is not supported."); - for(;byteread<chnklen;++byteread){fgetc(f);} -} -int CMidiFile::chunkReader(int hdrXp) -{ - char hdr[6]; - if(!fgets(hdr,5,f))error(1,"E: Unexpected EOF."); - if(hdrXp) - if(strncmp(hdr,"MThd",4)){error(1,"E: Wrong MIDI header.");throw;} - else return headerChunkReader(),0; - else - if(strncmp(hdr,"MTrk",4)) - { - error(0,"W: Wrong track chunk header. Ignoring the whole chunk."); - for(int chnklen=readDW();chnklen>0;--chnklen)fgetc(f);return 0; - } - else return trackChunkReader(),1; -} -CMidiFile::CMidiFile(const char* fn) -{ - title=copyright=NULL;notes=eventc=0;std=0;valid=1; - try - { - if(!(f=fopen(fn,"rb")))throw (fprintf(stderr,"E: file %s doesn't exist!\n",fn),2); - chunkReader(1); - for(uint32_t i=0;i<trk;i+=chunkReader(0)); - printf("%d note(s)\n",notes); - fclose(f); - std::sort(eventList,eventList+eventc,cmp); - } - catch(int){fprintf(stderr,"E: %s is not a supported file.\n",fn);valid=0;} -} -CMidiFile::~CMidiFile() -{ - for(uint32_t i=0;i<eventc;++i)delete eventList[i]; - if(title)delete[] title;if(copyright)delete[] copyright; -} -const SEvent* CMidiFile::getEvent(uint32_t id){return id<eventc?eventList[id]:NULL;} -uint32_t CMidiFile::getEventCount(){return eventc;} -uint32_t CMidiFile::getDivision(){return divs;} -uint32_t CMidiFile::getNoteCount(){return notes;} -uint32_t CMidiFile::getStandard(){return std;} -bool CMidiFile::isValid(){return valid;} -const char* CMidiFile::getTitle(){return title;} -const char* CMidiFile::getCopyright(){return copyright;} |