From 9e228490ffc7deb2969fa5e2b5fd81d763986eed Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Mon, 19 Mar 2018 10:50:45 +0800 Subject: Unified meta event reading code, fixing #6. Fixed playlist dialog behaving oddly. --- ChangeLog | 4 ++++ core/qmpmidiread.cpp | 31 ++++++++++++++------------ qmidiplayer-desktop/main.cpp | 2 +- qmidiplayer-desktop/qmpmainwindow.cpp | 42 ++++++++++------------------------- qmidiplayer-desktop/qmpmainwindow.hpp | 3 ++- 5 files changed, 36 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9750326..3a0d679 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2018-03-19 0.8.6 alpha +Unified meta event reading code. +Fixed playlist dialog behaving oddly. + 2018-02-07 0.8.6 alpha Forgot to unregister UI hooks. diff --git a/core/qmpmidiread.cpp b/core/qmpmidiread.cpp index 42cb88a..e7d92d3 100644 --- a/core/qmpmidiread.cpp +++ b/core/qmpmidiread.cpp @@ -12,6 +12,7 @@ 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"; +#define assert(x) if(!(x))this->error(false,"assertion failure @ qmpmidiread.cpp:%d",__LINE__) void CSMFReader::error(int fatal,const char* format,...) { va_list ap;char buf[1024],bufr[1024]; @@ -68,43 +69,44 @@ int CSMFReader::eventReader()//returns 0 if End of Track encountered if((type&0x0F)==0x0F)//Meta Event { char metatype=fgetc(f); + uint32_t len=readVL();char* str=NULL; + if(len<=1024&&len>0)str=new char[len+8]; + if(str)fread(str,1,len,f);else fseek(f,len,SEEK_CUR); + if(str)str[len]='\0'; switch(metatype) { case 0x00://Sequence Number - fgetc(f);fgetc(f);fgetc(f); + assert(len==2||len==0); break; case 0x20://Channel Prefix - fgetc(f);fgetc(f); + assert(len==1); break; case 0x2F://End of Track - fgetc(f); + assert(len==0); return 0; break; case 0x51://Set Tempo - p1=readDW();p1&=0x00FFFFFF; + assert(len==3); + p1=((str[0]&0xffu)<<16u)|(str[1]&0xffu)<<8u|(str[2]&0xffu); curTrack->appendEvent(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); + assert(len==5); break; case 0x58://Time signature - fgetc(f);p1=readDW(); + assert(len==4); + p1=((str[0]&0xffu)<<24u)|(str[1]&0xffu)<<16u|(str[2]&0xffu)<<8u|(str[3]&0xffu); curTrack->appendEvent(SEvent(curid,curt,type,metatype,p1)); break; case 0x59://Key signature - fgetc(f);p1=readSW(); + assert(len==2); + p1=(str[0]&0xffu)<<8u|(str[1]&0xffu); curTrack->appendEvent(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;cappendEvent(SEvent(curid,curt,type,metatype,0,str)); if(str&&metatype==0x03&&!ret->title) { @@ -116,9 +118,9 @@ int CSMFReader::eventReader()//returns 0 if End of Track encountered ret->copyright=new char[len+8]; strcpy(ret->copyright,str); } - if(len<=1024&&len>0)delete[] str; } } + if(str)delete[] str; } else if((type&0x0F)==0x00||(type&0x0F)==0x07)//SysEx { @@ -200,6 +202,7 @@ int CSMFReader::chunkReader(int hdrXp) uint32_t chnklen=readDW();fseek(f,chnklen,SEEK_CUR);return 0; } else return trackChunkReader(),1; + return 0; } CSMFReader::CSMFReader() { diff --git a/qmidiplayer-desktop/main.cpp b/qmidiplayer-desktop/main.cpp index c7167d0..740d7a5 100644 --- a/qmidiplayer-desktop/main.cpp +++ b/qmidiplayer-desktop/main.cpp @@ -34,7 +34,7 @@ int main(int argc,char **argv) qmpTranslator.load("qmp_"+QLocale::system().name()); a.installTranslator(&qmpTranslator); qmpMainWindow w; - if(w.pharseArgs()==1)return 0; + if(w.parseArgs()==1)return 0; w.init(); return a.exec(); diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp index 558f827..ea1db75 100644 --- a/qmidiplayer-desktop/qmpmainwindow.cpp +++ b/qmidiplayer-desktop/qmpmainwindow.cpp @@ -41,7 +41,7 @@ qmpMainWindow::qmpMainWindow(QWidget *parent) : setButtonHeight(ui->pbPrev,36);setButtonHeight(ui->pbSettings,36);setButtonHeight(ui->pbStop,36); playing=false;stopped=true;dragging=false;fin=false; settingsw=new qmpSettingsWindow(this);pmgr=new qmpPluginManager(); - plistw=new qmpPlistWindow(this);player=NULL;timer=NULL;fluidrenderer=NULL; + player=NULL;timer=NULL;fluidrenderer=NULL; } qmpMainWindow::~qmpMainWindow() @@ -95,6 +95,7 @@ void qmpMainWindow::init() while(f.wait_for(std::chrono::milliseconds(100))==std::future_status::timeout); ui->centralWidget->setEnabled(true); + plistw=new qmpPlistWindow(this); chnlw=new qmpChannelsWindow(this); efxw=new qmpEfxWindow(this); infow=new qmpInfoWindow(this); @@ -102,6 +103,11 @@ void qmpMainWindow::init() timer=new QTimer(this); renderf=new qmpRenderFunc(this); panicf=new qmpPanicFunc(this); + if(havemidi) + { + plistw->emptyList(); + for(auto&i:argfiles)plistw->insertItem(i); + } registerFunctionality(renderf,"Render",tr("Render to wave").toStdString(),getThemedIconc(":/img/render.svg"),0,false); registerFunctionality(panicf,"Panic",tr("Panic").toStdString(),getThemedIconc(":/img/panic.svg"),0,false); registerFunctionality(reloadsynf,"ReloadSynth",tr("Restart fluidsynth").toStdString(),getThemedIconc(":/img/repeat-base.svg"),0,false); @@ -120,7 +126,7 @@ void qmpMainWindow::init() setupWidget();settingsw->verifySF(); } -int qmpMainWindow::pharseArgs() +int qmpMainWindow::parseArgs() { bool loadfolder=false;havemidi=false; QStringList args=QApplication::arguments(); @@ -146,45 +152,21 @@ int qmpMainWindow::pharseArgs() loadfolder=true; } else -#ifdef _WIN32 + if(QFileInfo(args.at(i)).exists()) { - char* c=wcsto8bit(args.at(i).toStdWString().c_str()); - if(fluid_is_midifile(c)) - { - if(!havemidi){havemidi=true;plistw->emptyList();} - if(loadfolder||qmpSettingsWindow::getSettingsIntf()->value("Behavior/LoadFolder",0).toInt()) - { - QDirIterator di(QFileInfo(args.at(i)).absolutePath()); - while(di.hasNext()) - { - QString c=di.next();char* cc=wcsto8bit(c.toStdWString().c_str()); - if((c.endsWith(".mid")||c.endsWith(".midi"))&&fluid_is_midifile(cc)) - plistw->insertItem(c);free(cc); - } - } - else - plistw->insertItem(args.at(i)); - } - free(c); - } -#else - if(fluid_is_midifile(args.at(i).toStdString().c_str())) - { - if(!havemidi){havemidi=true;plistw->emptyList();} + if(!havemidi)havemidi=true; if(loadfolder||qmpSettingsWindow::getSettingsIntf()->value("Behavior/LoadFolder",0).toInt()) { QDirIterator di(QFileInfo(args.at(i)).absolutePath()); while(di.hasNext()) { QString c=di.next(); - if((c.endsWith(".mid")||c.endsWith(".midi"))&&fluid_is_midifile(c.toStdString().c_str())) - plistw->insertItem(c.toStdString().c_str()); + argfiles.push_back(c); } } else - plistw->insertItem(args.at(i).toStdString().c_str()); + argfiles.push_back(args.at(i)); } -#endif } return 0; } diff --git a/qmidiplayer-desktop/qmpmainwindow.hpp b/qmidiplayer-desktop/qmpmainwindow.hpp index cc0630b..a456dec 100644 --- a/qmidiplayer-desktop/qmpmainwindow.hpp +++ b/qmidiplayer-desktop/qmpmainwindow.hpp @@ -157,7 +157,7 @@ class qmpMainWindow:public QMainWindow std::wstring getWTitle(); uint32_t getPlaybackPercentage(); void playerSeek(uint32_t percentage); - int pharseArgs(); + int parseArgs(); void registerFunctionality(qmpFuncBaseIntf* i,std::string name,std::string desc,const char* icon,int iconlen,bool checkable); void unregisterFunctionality(std::string name); int registerUIHook(std::string e,ICallBack* callback,void* userdat); @@ -216,6 +216,7 @@ class qmpMainWindow:public QMainWindow qmpPanicFunc* panicf; qmpReloadSynthFunc* reloadsynf; std::vector enabled_buttons,enabled_actions; + std::vector argfiles; void onfnChanged(); void playerSetup(IFluidSettings *fs); -- cgit v1.2.3