From 70f0007154992c0bc89e11af4fe7dcc2c493aac3 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Fri, 10 Feb 2017 00:00:57 +0800 Subject: Fix building on Windows. Behavior changes: 1. DnD into the main window now causes the dropped file to play. 2. Switch back to w32usleep to increase bpm accuracy. 3. Scan for plugins in application folder (in Windows), not in the working directory. --- ChangeLog | 10 +++ core/qmpmidiplay.cpp | 6 ++ doc/APIdoc.md | 2 +- qmidiplayer-desktop/qmpmainwindow.cpp | 111 ++++++++++----------------------- qmidiplayer-desktop/qmpmainwindow.hpp | 1 + qmidiplayer-desktop/qmpplistwindow.cpp | 12 +++- qmidiplayer-desktop/qmpplistwindow.hpp | 3 +- qmidiplayer-desktop/qmpplugin.cpp | 2 +- visualization/qmpvisualization.cpp | 2 +- 9 files changed, 65 insertions(+), 84 deletions(-) diff --git a/ChangeLog b/ChangeLog index 20dfb18..fdcd7c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2017-02-09 0.8.5 indev +Fix building on Windows. +Behavior changes: + 1. DnD into the main window now causes the dropped + file to play. + 2. Switch back to w32usleep to increase bpm accuracy. + 3. Scan for plugins in application folder (in Windows), + not in the working directory. + + 2017-02-09 0.8.5 indev Add extra midi formats support via the file reader API. Fix note counting. diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp index 76c7d16..0bb73f9 100644 --- a/core/qmpmidiplay.cpp +++ b/core/qmpmidiplay.cpp @@ -212,7 +212,11 @@ void CMidiPlayer::playEvents() if(resumed)resumed=false; else if(sendtime.count()<(midiReaders->getEvent(tceptr)->time-ct)*dpt) +#ifdef _WIN32 + w32usleep(((midiReaders->getEvent(tceptr)->time-ct)*dpt-sendtime.count())/1000); +#else std::this_thread::sleep_for(std::chrono::nanoseconds((midiReaders->getEvent(tceptr)->time-ct)*dpt-sendtime.count())); +#endif if(tcstop||!midiReaders)break; ct=midiReaders->getEvent(tceptr)->time; } @@ -278,6 +282,8 @@ CMidiPlayer::CMidiPlayer(bool singleInst) memset(eventHandlerCBuserdata,0,sizeof(eventHandlerCBuserdata)); memset(eventReaderCB,0,sizeof(eventReaderCB)); memset(eventReaderCBuserdata,0,sizeof(eventReaderCBuserdata)); + memset(fileReadFinishCB,0,sizeof(fileReadFinishCB)); + memset(fileReadFinishCBuserdata,0,sizeof(fileReadFinishCBuserdata)); memset(mappedoutput,0,sizeof(mappedoutput)); memset(deviceusage,0,sizeof(deviceusage)); mapper=new qmpMidiMapperRtMidi(); diff --git a/doc/APIdoc.md b/doc/APIdoc.md index 5b69b5e..bc5e210 100644 --- a/doc/APIdoc.md +++ b/doc/APIdoc.md @@ -19,7 +19,7 @@ First of all, you should make your library distinct from other libraries that ar it by exporting the symbols `qmpPluginGetInterface` and `qmpPluginGetAPIRev`. Specifically, what you should do is to add the following snipplet to somewhere of your code: -``` +```C++ extern "C"{ EXPORTSYM qmpPluginIntf* qmpPluginGetInterface(qmpPluginAPI* api) //semicolon or implementation here. diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp index 876b0e9..56d3824 100644 --- a/qmidiplayer-desktop/qmpmainwindow.cpp +++ b/qmidiplayer-desktop/qmpmainwindow.cpp @@ -229,6 +229,7 @@ void qmpMainWindow::dropEvent(QDropEvent *event) for(int i=0;iinsertItems(sl); + switchTrack(plistw->getLastItem()); } void qmpMainWindow::dragEnterEvent(QDragEnterEvent *event) { @@ -259,32 +260,7 @@ void qmpMainWindow::updateWidgets() } else { - timer->stop();player->playerDeinit();playerTh->join(); - delete playerTh;playerTh=NULL; - ui->hsTimer->setValue(0); - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->stop(); - if(singleFS)player->playerPanic(true); - chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked(); - QString fns=plistw->getNextItem();setWindowTitle(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.'))+" - QMidiPlayer"); - ui->lbFileName->setText(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.'))); - onfnChanged(); - LOAD_FILE; - char ts[100]; - sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60); - ui->lbFinTime->setText(ts); - player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize(); - for(int i=settingsw->getSFWidget()->rowCount()-1;i>=0;--i){if(!((QCheckBox*)settingsw->getSFWidget()->cellWidget(i,0))->isChecked())continue; - LOAD_SOUNDFONT; - }} - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->start(); - player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange(); - player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt()); - playerTh=new std::thread(&CMidiPlayer::playerThread,player); -#ifdef _WIN32 - SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL); -#endif - st=std::chrono::steady_clock::now();offset=0; - timer->start(UPDATE_INTERVAL); + } } if(renderTh) @@ -323,6 +299,35 @@ void qmpMainWindow::updateWidgets() } QString qmpMainWindow::getFileName(){return ui->lbFileName->text();} +void qmpMainWindow::switchTrack(QString s) +{ + timer->stop();player->playerDeinit();playerTh->join(); + delete playerTh;playerTh=NULL; + ui->hsTimer->setValue(0); + for(int i=0;i<16;++i)if(VIs[i])VIs[i]->stop(); + if(singleFS)player->playerPanic(true); + chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked(); + QString fns=s;setWindowTitle(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.'))+" - QMidiPlayer"); + ui->lbFileName->setText(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.'))); + onfnChanged(); + LOAD_FILE; + char ts[100]; + sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60); + ui->lbFinTime->setText(ts); + player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize(); + for(int i=settingsw->getSFWidget()->rowCount()-1;i>=0;--i){if(!((QCheckBox*)settingsw->getSFWidget()->cellWidget(i,0))->isChecked())continue; + LOAD_SOUNDFONT; + }} + for(int i=0;i<16;++i)if(VIs[i])VIs[i]->start(); + player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange(); + player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt()); + playerTh=new std::thread(&CMidiPlayer::playerThread,player); +#ifdef _WIN32 + SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL); +#endif + st=std::chrono::steady_clock::now();offset=0; + timer->start(UPDATE_INTERVAL); +} std::string qmpMainWindow::getTitle() { if(!qmpSettingsWindow::getSettingsIntf())return ""; @@ -541,62 +546,12 @@ void qmpMainWindow::on_pbChannels_clicked() void qmpMainWindow::on_pbPrev_clicked() { - timer->stop();player->playerDeinit(); - if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;} - if(singleFS)player->playerPanic(true); - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->stop(); - ui->hsTimer->setValue(0);chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked(); - QString fns=plistw->getPrevItem();if(fns.length()==0)return on_pbStop_clicked(); - setWindowTitle(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.'))+" - QMidiPlayer"); - ui->lbFileName->setText(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.'))); - onfnChanged(); - LOAD_FILE; - char ts[100]; - sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60); - ui->lbFinTime->setText(ts); - player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize(); - for(int i=settingsw->getSFWidget()->rowCount()-1;i>=0;--i){if(!((QCheckBox*)settingsw->getSFWidget()->cellWidget(i,0))->isChecked())continue; - LOAD_SOUNDFONT; - }} - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->start(); - player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange(); - player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt()); - playerTh=new std::thread(&CMidiPlayer::playerThread,player); -#ifdef _WIN32 - SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL); -#endif - st=std::chrono::steady_clock::now();offset=0; - timer->start(UPDATE_INTERVAL); + switchTrack(plistw->getPrevItem()); } void qmpMainWindow::on_pbNext_clicked() { - timer->stop();player->playerDeinit(); - if(playerTh){playerTh->join();delete playerTh;playerTh=NULL;} - if(singleFS)player->playerPanic(true); - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->stop(); - ui->hsTimer->setValue(0);chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked(); - QString fns=plistw->getNextItem();if(fns.length()==0)return on_pbStop_clicked(); - ui->lbFileName->setText(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.'))); - setWindowTitle(QUrl::fromLocalFile(fns).fileName().left(QUrl::fromLocalFile(fns).fileName().lastIndexOf('.'))+" - QMidiPlayer"); - onfnChanged(); - LOAD_FILE; - char ts[100]; - sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60); - ui->lbFinTime->setText(ts); - player->playerInit();if(!singleFS){playerSetup();player->fluidInitialize(); - for(int i=settingsw->getSFWidget()->rowCount()-1;i>=0;--i){if(!((QCheckBox*)settingsw->getSFWidget()->cellWidget(i,0))->isChecked())continue; - LOAD_SOUNDFONT; - }} - for(int i=0;i<16;++i)if(VIs[i])VIs[i]->start(); - player->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange(); - player->setWaitVoice(qmpSettingsWindow::getSettingsIntf()->value("Midi/WaitVoice",1).toInt()); - playerTh=new std::thread(&CMidiPlayer::playerThread,player); -#ifdef _WIN32 - SetThreadPriority(playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL); -#endif - st=std::chrono::steady_clock::now();offset=0; - timer->start(UPDATE_INTERVAL); + switchTrack(plistw->getNextItem()); } void qmpMainWindow::selectionChanged() diff --git a/qmidiplayer-desktop/qmpmainwindow.hpp b/qmidiplayer-desktop/qmpmainwindow.hpp index 71161c2..0b835e7 100644 --- a/qmidiplayer-desktop/qmpmainwindow.hpp +++ b/qmidiplayer-desktop/qmpmainwindow.hpp @@ -65,6 +65,7 @@ class qmpMainWindow:public QMainWindow QTimer* getTimer(){return timer;} bool isFinalizing(){return fin;} QString getFileName(); + void switchTrack(QString s); std::string getTitle(); std::wstring getWTitle(); uint32_t getPlaybackPercentage(); diff --git a/qmidiplayer-desktop/qmpplistwindow.cpp b/qmidiplayer-desktop/qmpplistwindow.cpp index 5805fcb..799f99a 100644 --- a/qmidiplayer-desktop/qmpplistwindow.cpp +++ b/qmidiplayer-desktop/qmpplistwindow.cpp @@ -228,11 +228,19 @@ void qmpPlistWindow::on_pbShuffle_clicked() } } -QString qmpPlistWindow::getFirstItem() +QString qmpPlistWindow::getFirstItem(bool a) { if(ui->lwFiles->count()==0)return QString(); int id=0; - if(shuffle)id=rand()%ui->lwFiles->count(); + if(shuffle&&!a)id=rand()%ui->lwFiles->count(); + ui->lwFiles->setCurrentRow(id); + return ui->lwFiles->item(id)->text(); +} +QString qmpPlistWindow::getLastItem(bool a) +{ + if(ui->lwFiles->count()==0)return QString(); + int id=ui->lwFiles->count()-1; + if(shuffle&&!a)id=rand()%ui->lwFiles->count(); ui->lwFiles->setCurrentRow(id); return ui->lwFiles->item(id)->text(); } diff --git a/qmidiplayer-desktop/qmpplistwindow.hpp b/qmidiplayer-desktop/qmpplistwindow.hpp index 6ceeb60..b1deab4 100644 --- a/qmidiplayer-desktop/qmpplistwindow.hpp +++ b/qmidiplayer-desktop/qmpplistwindow.hpp @@ -26,7 +26,8 @@ class qmpPlistWindow : public QDialog void dropEvent(QDropEvent *event); void dragEnterEvent(QDragEnterEvent *event); int getRepeat(); - QString getFirstItem(); + QString getFirstItem(bool a=false); + QString getLastItem(bool a=false); QString getNextItem(); QString getPrevItem(); QString getSelectedItem(); diff --git a/qmidiplayer-desktop/qmpplugin.cpp b/qmidiplayer-desktop/qmpplugin.cpp index 5de1dd5..7370e20 100644 --- a/qmidiplayer-desktop/qmpplugin.cpp +++ b/qmidiplayer-desktop/qmpplugin.cpp @@ -192,7 +192,7 @@ int qmpPluginAPI::registerVisualizationIntf(qmpVisualizationIntf* intf) void qmpPluginAPI::unregisterVisualizationIntf(int intfhandle) {qmw->unregisterVisualizationIntf(intfhandle);} int qmpPluginAPI::registerFileReadFinishedHandlerIntf(IMidiCallBack* cb,void* userdata) -{qmw->getPlayer()->setFileReadFinishedCB(cb,userdata);} +{return qmw->getPlayer()->setFileReadFinishedCB(cb,userdata);} void qmpPluginAPI::unregisterFileReadFinishedHandlerIntf(int intfhandle) {qmw->getPlayer()->unsetFileReadFinishedCB(intfhandle);} void qmpPluginAPI::registerFileReader(IMidiFileReader* reader,std::string name) diff --git a/visualization/qmpvisualization.cpp b/visualization/qmpvisualization.cpp index fd64ea0..8bc0ecb 100644 --- a/visualization/qmpvisualization.cpp +++ b/visualization/qmpvisualization.cpp @@ -69,7 +69,7 @@ void CEventHandlerCallBack::callBack(void*,void*) void CFRFinishedCallBack::callBack(void*,void*) { std::sort(par->tspool.begin(),par->tspool.end()); - for(int tk=0,n=4,s=0;tk<=par->api->getMaxTick();){ + for(uint32_t tk=0,n=4,s=0;tk<=par->api->getMaxTick();){ while(tk<(s>=par->tspool.size()?par->api->getMaxTick():par->tspool[s].first)){ par->pool.push_back(new MidiVisualEvent{tk,tk,0,0,999}); tk+=n*par->api->getDivision(); -- cgit v1.2.3