aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/qmpmidioutfluid.cpp640
-rw-r--r--core/qmpmidioutfluid.hpp148
-rw-r--r--core/qmpmidioutrtmidi.cpp636
-rw-r--r--core/qmpmidioutrtmidi.hpp72
-rw-r--r--core/qmpmidiplay.cpp1157
-rw-r--r--core/qmpmidiplay.hpp301
-rw-r--r--core/qmpmidiread.cpp552
-rw-r--r--include/qmpcorepublic.hpp336
-rw-r--r--midifmt-plugin/midifmtplugin.cpp183
-rw-r--r--midifmt-plugin/midifmtplugin.hpp64
-rw-r--r--qmidiplayer-desktop/main.cpp71
-rw-r--r--qmidiplayer-desktop/qdialskulpturestyle.cpp742
-rw-r--r--qmidiplayer-desktop/qdialskulpturestyle.hpp10
-rw-r--r--qmidiplayer-desktop/qmpchanneleditor.cpp207
-rw-r--r--qmidiplayer-desktop/qmpchanneleditor.hpp55
-rw-r--r--qmidiplayer-desktop/qmpchannelswindow.cpp612
-rw-r--r--qmidiplayer-desktop/qmpchannelswindow.hpp129
-rw-r--r--qmidiplayer-desktop/qmpcustomizewindow.cpp103
-rw-r--r--qmidiplayer-desktop/qmpcustomizewindow.hpp31
-rw-r--r--qmidiplayer-desktop/qmpdeviceprioritydialog.cpp141
-rw-r--r--qmidiplayer-desktop/qmpdeviceprioritydialog.hpp33
-rw-r--r--qmidiplayer-desktop/qmpdevpropdialog.cpp149
-rw-r--r--qmidiplayer-desktop/qmpdevpropdialog.hpp31
-rw-r--r--qmidiplayer-desktop/qmpefxwindow.cpp367
-rw-r--r--qmidiplayer-desktop/qmpefxwindow.hpp95
-rw-r--r--qmidiplayer-desktop/qmphelpwindow.cpp51
-rw-r--r--qmidiplayer-desktop/qmphelpwindow.hpp21
-rw-r--r--qmidiplayer-desktop/qmpinfowindow.cpp125
-rw-r--r--qmidiplayer-desktop/qmpinfowindow.hpp65
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.cpp1399
-rw-r--r--qmidiplayer-desktop/qmpmainwindow.hpp459
-rw-r--r--qmidiplayer-desktop/qmpplistwindow.cpp532
-rw-r--r--qmidiplayer-desktop/qmpplistwindow.hpp91
-rw-r--r--qmidiplayer-desktop/qmpplugin.cpp582
-rw-r--r--qmidiplayer-desktop/qmpplugin.hpp182
-rw-r--r--qmidiplayer-desktop/qmppresetselect.cpp205
-rw-r--r--qmidiplayer-desktop/qmppresetselect.hpp41
-rw-r--r--qmidiplayer-desktop/qmpsettings.cpp320
-rw-r--r--qmidiplayer-desktop/qmpsettings.hpp131
-rw-r--r--qmidiplayer-desktop/qmpsettingswindow.cpp1013
-rw-r--r--qmidiplayer-desktop/qmpsettingswindow.hpp162
-rw-r--r--qmidiplayer-lite/main.cpp10
-rw-r--r--qmidiplayer-lite/qmpcorewrapper.hpp106
-rw-r--r--qmidiplayer-lite/qmpmidiplay.cpp749
-rw-r--r--qmidiplayer-lite/qmpmidiplay.hpp237
-rw-r--r--qmidiplayer-lite/qmpmidiread.cpp525
-rw-r--r--sample-plugin/sampleplugin.cpp28
-rw-r--r--sample-plugin/sampleplugin.hpp34
-rw-r--r--simple-visualization/qmpkeyboardwindow.cpp107
-rw-r--r--simple-visualization/qmpkeyboardwindow.hpp34
-rw-r--r--simple-visualization/qmppianowidget.cpp105
-rw-r--r--simple-visualization/qmppianowidget.hpp28
-rw-r--r--simple-visualization/simplevisualization.cpp66
-rw-r--r--simple-visualization/simplevisualization.hpp42
-rw-r--r--visualization/extrasmeltutils.cpp657
-rw-r--r--visualization/extrasmeltutils.hpp234
-rw-r--r--visualization/qmpvirtualpiano3d.cpp426
-rw-r--r--visualization/qmpvirtualpiano3d.hpp20
-rw-r--r--visualization/qmpvisualization.cpp2249
-rw-r--r--visualization/qmpvisualization.hpp188
-rw-r--r--visualization/renderer/main.cpp80
-rw-r--r--visualization/renderer/qmppluginapistub.cpp220
-rw-r--r--visualization/renderer/qmppluginapistub.hpp140
-rw-r--r--visualization/renderer/qmpsettingsro.cpp310
-rw-r--r--visualization/renderer/qmpsettingsro.hpp103
-rw-r--r--visualization/renderer/qmpvisrendercore.cpp463
-rw-r--r--visualization/renderer/qmpvisrendercore.hpp67
67 files changed, 10767 insertions, 8705 deletions
diff --git a/core/qmpmidioutfluid.cpp b/core/qmpmidioutfluid.cpp
index 649cb1c..bfa6016 100644
--- a/core/qmpmidioutfluid.cpp
+++ b/core/qmpmidioutfluid.cpp
@@ -4,375 +4,431 @@
#include "qmpmidioutfluid.hpp"
qmpMidiOutFluid::qmpMidiOutFluid()
{
- settings=new_fluid_settings();
- synth=nullptr;adriver=nullptr;
+ settings = new_fluid_settings();
+ synth = nullptr;
+ adriver = nullptr;
}
qmpMidiOutFluid::~qmpMidiOutFluid()
{
- delete_fluid_settings(settings);
- settings=nullptr;
+ delete_fluid_settings(settings);
+ settings = nullptr;
}
void qmpMidiOutFluid::registerOptions(qmpPluginAPI *coreapi)
{
- default_driver=-1;
- fluid_settings_t *fsettings=new_fluid_settings();
- auto insert_driver=[](void* d,const char*,const char* driver)->void{
- qmpMidiOutFluid *me=static_cast<qmpMidiOutFluid*>(d);
- me->drivers.push_back(std::string(driver));
+ default_driver = -1;
+ fluid_settings_t *fsettings = new_fluid_settings();
+ auto insert_driver = [](void *d, const char *, const char *driver)->void
+ {
+ qmpMidiOutFluid *me = static_cast<qmpMidiOutFluid *>(d);
+ me->drivers.push_back(std::string(driver));
#ifdef WIN32
- if(std::string(driver)=="waveout")
+ if (std::string(driver) == "waveout")
#else
- if(std::string(driver)=="pulseaudio")
- me->default_driver=static_cast<int>(me->drivers.size()-1);
+ if (std::string(driver) == "pulseaudio")
+ me->default_driver = static_cast<int>(me->drivers.size() - 1);
#endif
- };
- fluid_settings_foreach_option(fsettings,"audio.driver",this,insert_driver);
- delete_fluid_settings(fsettings);
- coreapi->registerOptionEnumInt("Audio","Audio Driver","FluidSynth/AudioDriver",drivers,default_driver);
- coreapi->registerOptionInt("Audio","Audio Buffer Size","FluidSynth/BufSize",64,8192,
+ };
+ fluid_settings_foreach_option(fsettings, "audio.driver", this, insert_driver);
+ delete_fluid_settings(fsettings);
+ coreapi->registerOptionEnumInt("Audio", "Audio Driver", "FluidSynth/AudioDriver", drivers, default_driver);
+ coreapi->registerOptionInt("Audio", "Audio Buffer Size", "FluidSynth/BufSize", 64, 8192,
#ifdef WIN32
- 512
+ 512
#else
- 64
+ 64
#endif
- );
- coreapi->registerOptionInt("Audio","Audio Buffer Count","FluidSynth/BufCnt",2,64,
+ );
+ coreapi->registerOptionInt("Audio", "Audio Buffer Count", "FluidSynth/BufCnt", 2, 64,
#ifdef WIN32
- 8
+ 8
#else
- 16
+ 16
#endif
- );
- coreapi->registerOptionEnumInt("Audio","Sample Format","FluidSynth/SampleFormat",{"16bits","float"},0);
- coreapi->registerOptionInt("Audio","Sample Rate","FluidSynth/SampleRate",8000,96000,48000);
- coreapi->registerOptionInt("Audio","Max Polyphony","FluidSynth/Polyphony",1,65535,256);
- coreapi->registerOptionInt("Audio","CPU Cores","FluidSynth/Threads",1,256,1);
- coreapi->registerOptionBool("Audio","Auto Bank Select Mode","FluidSynth/AutoBS",true);
- coreapi->registerOptionEnumInt("Audio","Bank Select Mode","FluidSynth/BankSelect",{"GM","GS","XG","MMA"},1);
+ );
+ coreapi->registerOptionEnumInt("Audio", "Sample Format", "FluidSynth/SampleFormat", {"16bits", "float"}, 0);
+ coreapi->registerOptionInt("Audio", "Sample Rate", "FluidSynth/SampleRate", 8000, 96000, 48000);
+ coreapi->registerOptionInt("Audio", "Max Polyphony", "FluidSynth/Polyphony", 1, 65535, 256);
+ coreapi->registerOptionInt("Audio", "CPU Cores", "FluidSynth/Threads", 1, 256, 1);
+ coreapi->registerOptionBool("Audio", "Auto Bank Select Mode", "FluidSynth/AutoBS", true);
+ coreapi->registerOptionEnumInt("Audio", "Bank Select Mode", "FluidSynth/BankSelect", {"GM", "GS", "XG", "MMA"}, 1);
}
void qmpMidiOutFluid::deviceInit()
{
- synth=new_fluid_synth(settings);
- if(!synth){fputs("Error creating fluidsynth instance!",stderr);return;}
- fluid_set_log_function(FLUID_DBG,nullptr,nullptr);
- fluid_set_log_function(FLUID_INFO,nullptr,nullptr);
- fluid_set_log_function(FLUID_WARN,nullptr,nullptr);
- fluid_set_log_function(FLUID_ERR,fluid_default_log_function,nullptr);
- fluid_set_log_function(FLUID_PANIC,fluid_default_log_function,nullptr);
- adriver=new_fluid_audio_driver(settings,synth);
- if(!adriver)
- {
- fputs("Error creating fluidsynth audio driver!",stderr);
- delete_fluid_synth(synth);synth=nullptr;
- return;
- }
- fluid_synth_set_chorus(synth,3,2.0,0.3,8.0,
- FLUID_CHORUS_MOD_SINE);
- bnk.clear();pst.clear();
-}
-void qmpMidiOutFluid::deviceDeinit(){deviceDeinit(false);}
+ synth = new_fluid_synth(settings);
+ if (!synth)
+ {
+ fputs("Error creating fluidsynth instance!", stderr);
+ return;
+ }
+ fluid_set_log_function(FLUID_DBG, nullptr, nullptr);
+ fluid_set_log_function(FLUID_INFO, nullptr, nullptr);
+ fluid_set_log_function(FLUID_WARN, nullptr, nullptr);
+ fluid_set_log_function(FLUID_ERR, fluid_default_log_function, nullptr);
+ fluid_set_log_function(FLUID_PANIC, fluid_default_log_function, nullptr);
+ adriver = new_fluid_audio_driver(settings, synth);
+ if (!adriver)
+ {
+ fputs("Error creating fluidsynth audio driver!", stderr);
+ delete_fluid_synth(synth);
+ synth = nullptr;
+ return;
+ }
+ fluid_synth_set_chorus(synth, 3, 2.0, 0.3, 8.0, FLUID_CHORUS_MOD_SINE);
+ bnk.clear();
+ pst.clear();
+}
+void qmpMidiOutFluid::deviceDeinit()
+{
+ deviceDeinit(false);
+}
void qmpMidiOutFluid::deviceDeinit(bool freshsettings)
{
- if(!synth||!adriver)return;
- delete_fluid_audio_driver(adriver);
- delete_fluid_synth(synth);
- synth=nullptr;adriver=nullptr;
- bnk.clear();pst.clear();
- if(freshsettings)
- {
- delete_fluid_settings(settings);
- settings=new_fluid_settings();
- }
-}
-void qmpMidiOutFluid::basicMessage(uint8_t type,uint8_t p1,uint8_t p2)
-{
- uint8_t chan=type&0x0F;
- switch(type&0xF0)
- {
- case 0x80:
- fluid_synth_noteoff(synth,chan,p1);
- break;
- case 0x90:
- if(p2)fluid_synth_noteon(synth,chan,p1,p2);
- else fluid_synth_noteoff(synth,chan,p1);
- break;
- case 0xB0:
- fluid_synth_cc(synth,chan,p1,p2);
- break;
- case 0xC0:
- fluid_synth_program_change(synth,chan,p1);
- break;
- case 0xE0:
- fluid_synth_pitch_bend(synth,chan,(p1|p2<<7)&0x3fff);
- break;
- }
-}
-void qmpMidiOutFluid::extendedMessage(uint32_t length,const char *data)
-{
- int rlen=0;
- fluid_synth_sysex(synth,data,int(length),nullptr,&rlen,nullptr,0);
-}
-void qmpMidiOutFluid::rpnMessage(uint8_t ch,uint16_t type,uint16_t val)
-{
- if(type==0)fluid_synth_pitch_wheel_sens(synth,ch,val>>7);
- else
- {
- fluid_synth_cc(synth,ch,0x64,type&0x7F);
- fluid_synth_cc(synth,ch,0x65,type>>7);
- fluid_synth_cc(synth,ch,0x06,val>>7);
- fluid_synth_cc(synth,ch,0x26,val&0x7F);
- }
-}
-void qmpMidiOutFluid::nrpnMessage(uint8_t ch,uint16_t type,uint16_t val)
-{
- fluid_synth_cc(synth,ch,0x62,type&0x7F);
- fluid_synth_cc(synth,ch,0x63,type>>7);
- fluid_synth_cc(synth,ch,0x06,val>>7);
- fluid_synth_cc(synth,ch,0x26,val&0x7F);
+ if (!synth || !adriver)
+ return;
+ delete_fluid_audio_driver(adriver);
+ delete_fluid_synth(synth);
+ synth = nullptr;
+ adriver = nullptr;
+ bnk.clear();
+ pst.clear();
+ if (freshsettings)
+ {
+ delete_fluid_settings(settings);
+ settings = new_fluid_settings();
+ }
+}
+void qmpMidiOutFluid::basicMessage(uint8_t type, uint8_t p1, uint8_t p2)
+{
+ uint8_t chan = type & 0x0F;
+ switch (type & 0xF0)
+ {
+ case 0x80:
+ fluid_synth_noteoff(synth, chan, p1);
+ break;
+ case 0x90:
+ if (p2)
+ fluid_synth_noteon(synth, chan, p1, p2);
+ else
+ fluid_synth_noteoff(synth, chan, p1);
+ break;
+ case 0xB0:
+ fluid_synth_cc(synth, chan, p1, p2);
+ break;
+ case 0xC0:
+ fluid_synth_program_change(synth, chan, p1);
+ break;
+ case 0xE0:
+ fluid_synth_pitch_bend(synth, chan, (p1 | p2 << 7) & 0x3fff);
+ break;
+ }
+}
+void qmpMidiOutFluid::extendedMessage(uint32_t length, const char *data)
+{
+ int rlen = 0;
+ fluid_synth_sysex(synth, data, int(length), nullptr, &rlen, nullptr, 0);
+}
+void qmpMidiOutFluid::rpnMessage(uint8_t ch, uint16_t type, uint16_t val)
+{
+ if (type == 0)
+ fluid_synth_pitch_wheel_sens(synth, ch, val >> 7);
+ else
+ {
+ fluid_synth_cc(synth, ch, 0x64, type & 0x7F);
+ fluid_synth_cc(synth, ch, 0x65, type >> 7);
+ fluid_synth_cc(synth, ch, 0x06, val >> 7);
+ fluid_synth_cc(synth, ch, 0x26, val & 0x7F);
+ }
+}
+void qmpMidiOutFluid::nrpnMessage(uint8_t ch, uint16_t type, uint16_t val)
+{
+ fluid_synth_cc(synth, ch, 0x62, type & 0x7F);
+ fluid_synth_cc(synth, ch, 0x63, type >> 7);
+ fluid_synth_cc(synth, ch, 0x06, val >> 7);
+ fluid_synth_cc(synth, ch, 0x26, val & 0x7F);
}
void qmpMidiOutFluid::panic(uint8_t ch)
{
- fluid_synth_cc(synth,ch,64,0);
- fluid_synth_pitch_bend(synth,ch,8192);
- fluid_synth_all_notes_off(synth,ch);
+ fluid_synth_cc(synth, ch, 64, 0);
+ fluid_synth_pitch_bend(synth, ch, 8192);
+ fluid_synth_all_notes_off(synth, ch);
}
void qmpMidiOutFluid::reset(uint8_t ch)
{
- if(!~ch){fluid_synth_system_reset(synth);return;}
- this->panic(ch);
- for(int i=0;i<128;++i)
- fluid_synth_cc(synth,ch,i,0);
- if(ch==9)
- fluid_synth_cc(synth,ch,0,127);
- else
- fluid_synth_cc(synth,ch,0,0);
- fluid_synth_cc(synth,ch,7,100);
- fluid_synth_cc(synth,ch,8,64);
- fluid_synth_cc(synth,ch,10,64);
- fluid_synth_cc(synth,ch,11,127);
- fluid_synth_pitch_wheel_sens(synth,ch,2);
-}
-void qmpMidiOutFluid::onMapped(uint8_t,int)
-{
-}
-void qmpMidiOutFluid::onUnmapped(uint8_t,int)
-{
-}
-std::vector<std::pair<uint16_t,std::string>> qmpMidiOutFluid::getBankList()
-{
- return bnk;
-}
-std::vector<std::pair<uint8_t,std::string>> qmpMidiOutFluid::getPresets(uint16_t bank)
-{
- std::vector<std::pair<uint8_t,std::string>> ret;
- if(pst.find(bank)==pst.end())return ret;
- for(uint8_t i=0;i<128;++i)
- {
- if(pst[bank][i].length())
- ret.emplace_back(i,pst[bank][i]);
- }
- return ret;
-}
-std::string qmpMidiOutFluid::getPresetName(uint16_t bank,uint8_t preset)
-{
- if(pst.find(bank)==pst.end())return "";
- //should consult fluidsynth instead? (4 bank mapping methods)
- return pst[bank][preset];
-}
-bool qmpMidiOutFluid::getChannelPreset(int ch,uint16_t *bank,uint8_t *preset,std::string &presetname)
-{
- if(!synth)return false;
- fluid_preset_t* chpreset=fluid_synth_get_channel_preset(synth,ch);
- if(!chpreset)
- {
- *bank=*preset=-1;
- presetname="---";
- return true;
- }
- *bank=fluid_preset_get_banknum(chpreset);
- *preset=fluid_preset_get_num(chpreset);
- presetname=fluid_preset_get_name(chpreset);
- return true;
-}
-uint8_t qmpMidiOutFluid::getInitialCCValue(uint8_t cc,uint8_t)
-{
- switch(cc)
- {
- case 11:return 127;
- case 7:return 100;
- case 8:case 10:case 71:case 72:
- case 73:case 74:case 75:case 76:
- case 77:case 78:return 64;
- case 129:return 2;
- default:return 0;
- }
-}
-void qmpMidiOutFluid::setOptStr(const char *opt,const char *val)
-{
- fluid_settings_setstr(settings,opt,val);
-}
-void qmpMidiOutFluid::setOptInt(const char *opt,int val)
-{
- fluid_settings_setint(settings,opt,val);
-}
-void qmpMidiOutFluid::setOptNum(const char *opt,double val)
-{
- fluid_settings_setnum(settings,opt,val);
+ if (!~ch)
+ {
+ fluid_synth_system_reset(synth);
+ return;
+ }
+ this->panic(ch);
+
+ for (int i = 0; i < 128; ++i)
+ fluid_synth_cc(synth, ch, i, 0);
+
+ if (ch == 9)
+ fluid_synth_cc(synth, ch, 0, 127);
+ else
+ fluid_synth_cc(synth, ch, 0, 0);
+
+ fluid_synth_cc(synth, ch, 7, 100);
+ fluid_synth_cc(synth, ch, 8, 64);
+ fluid_synth_cc(synth, ch, 10, 64);
+ fluid_synth_cc(synth, ch, 11, 127);
+ fluid_synth_pitch_wheel_sens(synth, ch, 2);
+}
+void qmpMidiOutFluid::onMapped(uint8_t, int)
+{
+}
+void qmpMidiOutFluid::onUnmapped(uint8_t, int)
+{
+}
+std::vector<std::pair<uint16_t, std::string>> qmpMidiOutFluid::getBankList()
+{
+ return bnk;
+}
+std::vector<std::pair<uint8_t, std::string>> qmpMidiOutFluid::getPresets(uint16_t bank)
+{
+ std::vector<std::pair<uint8_t, std::string>> ret;
+ if (pst.find(bank) == pst.end())
+ return ret;
+ for (uint8_t i = 0; i < 128; ++i)
+ {
+ if (pst[bank][i].length())
+ ret.emplace_back(i, pst[bank][i]);
+ }
+ return ret;
+}
+std::string qmpMidiOutFluid::getPresetName(uint16_t bank, uint8_t preset)
+{
+ if (pst.find(bank) == pst.end())
+ return "";
+ //should consult fluidsynth instead? (4 bank mapping methods)
+ return pst[bank][preset];
+}
+bool qmpMidiOutFluid::getChannelPreset(int ch, uint16_t *bank, uint8_t *preset, std::string &presetname)
+{
+ if (!synth)
+ return false;
+ fluid_preset_t *chpreset = fluid_synth_get_channel_preset(synth, ch);
+ if (!chpreset)
+ {
+ *bank = *preset = -1;
+ presetname = "---";
+ return true;
+ }
+ *bank = fluid_preset_get_banknum(chpreset);
+ *preset = fluid_preset_get_num(chpreset);
+ presetname = fluid_preset_get_name(chpreset);
+ return true;
+}
+uint8_t qmpMidiOutFluid::getInitialCCValue(uint8_t cc, uint8_t)
+{
+ switch (cc)
+ {
+ case 11:
+ return 127;
+ case 7:
+ return 100;
+ case 8:
+ case 10:
+ case 71:
+ case 72:
+ case 73:
+ case 74:
+ case 75:
+ case 76:
+ case 77:
+ case 78:
+ return 64;
+ case 129:
+ return 2;
+ default:
+ return 0;
+ }
+}
+void qmpMidiOutFluid::setOptStr(const char *opt, const char *val)
+{
+ fluid_settings_setstr(settings, opt, val);
+}
+void qmpMidiOutFluid::setOptInt(const char *opt, int val)
+{
+ fluid_settings_setint(settings, opt, val);
+}
+void qmpMidiOutFluid::setOptNum(const char *opt, double val)
+{
+ fluid_settings_setnum(settings, opt, val);
}
void qmpMidiOutFluid::loadSFont(const char *path)
{
- if(synth)fluid_synth_sfload(synth,path,1);
- update_preset_list();
+ if (synth)
+ fluid_synth_sfload(synth, path, 1);
+ update_preset_list();
}
int qmpMidiOutFluid::getSFCount()
{
- return synth?fluid_synth_sfcount(synth):0;
+ return synth ? fluid_synth_sfcount(synth) : 0;
}
void qmpMidiOutFluid::update_preset_list()
{
- bnk.clear();pst.clear();
- for(int i=getSFCount()-1;i>=0;--i)
- {
- fluid_sfont_t* psf=fluid_synth_get_sfont(synth,i);
- fluid_preset_t* preset;
- fluid_sfont_iteration_start(psf);
- while(preset=fluid_sfont_iteration_next(psf))
- {
- uint16_t b=fluid_preset_get_banknum(preset);
- uint8_t p=fluid_preset_get_num(preset);
- if(bnk.empty()||bnk.back().first!=b)
- bnk.emplace_back(b,"");
- if(pst[b].empty())pst[b].resize(128);
- pst[b][p]=std::string(fluid_preset_get_name(preset));
- if(!pst[b][p].length())pst[b][p]=" ";
- }
- }
- std::sort(bnk.begin(),bnk.end());
- bnk.erase(std::unique(bnk.begin(),bnk.end()),bnk.end());
+ bnk.clear();
+ pst.clear();
+ for (int i = getSFCount() - 1; i >= 0; --i)
+ {
+ fluid_sfont_t *psf = fluid_synth_get_sfont(synth, i);
+ fluid_preset_t *preset;
+ fluid_sfont_iteration_start(psf);
+ while ((preset = fluid_sfont_iteration_next(psf)))
+ {
+ uint16_t b = fluid_preset_get_banknum(preset);
+ uint8_t p = fluid_preset_get_num(preset);
+ if (bnk.empty() || bnk.back().first != b)
+ bnk.emplace_back(b, "");
+ if (pst[b].empty())
+ pst[b].resize(128);
+ pst[b][p] = std::string(fluid_preset_get_name(preset));
+ if (!pst[b][p].length())
+ pst[b][p] = " ";
+ }
+ }
+ std::sort(bnk.begin(), bnk.end());
+ bnk.erase(std::unique(bnk.begin(), bnk.end()), bnk.end());
}
int qmpMidiOutFluid::getPolyphone()
{
- return synth?fluid_synth_get_active_voice_count(synth):0;
+ return synth ? fluid_synth_get_active_voice_count(synth) : 0;
}
int qmpMidiOutFluid::getMaxPolyphone()
{
- return synth?fluid_synth_get_polyphony(synth):0;
+ return synth ? fluid_synth_get_polyphony(synth) : 0;
}
void qmpMidiOutFluid::setGain(double gain)
{
- if(settings)fluid_settings_setnum(settings,"synth.gain",gain);
-}
-void qmpMidiOutFluid::getChannelInfo(int ch,int *b,int *p,char *s)
-{
- if(!synth)return;
- fluid_preset_t* chpreset=fluid_synth_get_channel_preset(synth,ch);
- if(!chpreset)
- {
- *b=*p=-1;
- strcpy(s,"---");
- return;
- }
- *b=fluid_preset_get_banknum(chpreset);
- *p=fluid_preset_get_num(chpreset);
- strncpy(s,fluid_preset_get_name(chpreset),256);
-}
-void qmpMidiOutFluid::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 qmpMidiOutFluid::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 qmpMidiOutFluid::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(synth);
- *d=fluid_synth_get_chorus_depth(synth);
- *type=fluid_synth_get_chorus_type(synth);
-}
-void qmpMidiOutFluid::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);
+ if (settings)
+ fluid_settings_setnum(settings, "synth.gain", gain);
+}
+void qmpMidiOutFluid::getChannelInfo(int ch, int *b, int *p, char *s)
+{
+ if (!synth)
+ return;
+ fluid_preset_t *chpreset = fluid_synth_get_channel_preset(synth, ch);
+ if (!chpreset)
+ {
+ *b = *p = -1;
+ strcpy(s, "---");
+ return;
+ }
+ *b = fluid_preset_get_banknum(chpreset);
+ *p = fluid_preset_get_num(chpreset);
+ strncpy(s, fluid_preset_get_name(chpreset), 256);
+}
+void qmpMidiOutFluid::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 qmpMidiOutFluid::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 qmpMidiOutFluid::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(synth);
+ *d = fluid_synth_get_chorus_depth(synth);
+ *type = fluid_synth_get_chorus_type(synth);
+}
+void qmpMidiOutFluid::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);
}
-qmpFileRendererFluid::qmpFileRendererFluid(const char *_fn,const char *_ofn)
+qmpFileRendererFluid::qmpFileRendererFluid(const char *_fn, const char *_ofn)
{
- settings=new_fluid_settings();
- fluid_settings_setstr(settings,"audio.file.name",_ofn);
- fn=std::string(_fn);
- finished=false;
+ settings = new_fluid_settings();
+ fluid_settings_setstr(settings, "audio.file.name", _ofn);
+ fn = std::string(_fn);
+ finished = false;
}
qmpFileRendererFluid::~qmpFileRendererFluid()
{
- if(player||synth||settings)renderDeinit();
+ if (player || synth || settings)
+ renderDeinit();
}
void qmpFileRendererFluid::renderInit()
{
- synth=new_fluid_synth(settings);
- player=new_fluid_player(synth);
- fluid_player_add(player,fn.c_str());
+ synth = new_fluid_synth(settings);
+ player = new_fluid_player(synth);
+ fluid_player_add(player, fn.c_str());
}
void qmpFileRendererFluid::renderDeinit()
{
- delete_fluid_player(player);
- delete_fluid_synth(synth);
- delete_fluid_settings(settings);
- player=nullptr;synth=nullptr;settings=nullptr;
+ delete_fluid_player(player);
+ delete_fluid_synth(synth);
+ delete_fluid_settings(settings);
+ player = nullptr;
+ synth = nullptr;
+ settings = nullptr;
}
void qmpFileRendererFluid::renderWorker()
{
- 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=true;
+ 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 = true;
}
-void qmpFileRendererFluid::setOptStr(const char *opt,const char *val)
+void qmpFileRendererFluid::setOptStr(const char *opt, const char *val)
{
- fluid_settings_setstr(settings,opt,val);
+ fluid_settings_setstr(settings, opt, val);
}
-void qmpFileRendererFluid::setOptInt(const char *opt,int val)
+void qmpFileRendererFluid::setOptInt(const char *opt, int val)
{
- fluid_settings_setint(settings,opt,val);
+ fluid_settings_setint(settings, opt, val);
}
-void qmpFileRendererFluid::setOptNum(const char *opt,double val)
+void qmpFileRendererFluid::setOptNum(const char *opt, double val)
{
- fluid_settings_setnum(settings,opt,val);
+ fluid_settings_setnum(settings, opt, val);
}
void qmpFileRendererFluid::loadSFont(const char *path)
{
- if(synth)fluid_synth_sfload(synth,path,1);
+ if (synth)
+ fluid_synth_sfload(synth, path, 1);
}
bool qmpFileRendererFluid::isFinished()
{
- return finished;
+ return finished;
}
void qmpFileRendererFluid::setGain(double gain)
{
- if(settings)fluid_settings_setnum(settings,"synth.gain",gain);
+ if (settings)
+ fluid_settings_setnum(settings, "synth.gain", gain);
}
-void qmpFileRendererFluid::setReverbPara(int e,double r,double d,double w,double l)
+void qmpFileRendererFluid::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);
+ if (!synth)
+ return;
+ fluid_synth_set_reverb_on(synth, e);
+ fluid_synth_set_reverb(synth, r, d, w, l);
}
-void qmpFileRendererFluid::setChorusPara(int e,int fb,double l,double r,double d,int type)
+void qmpFileRendererFluid::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);
+ if (!synth)
+ return;
+ fluid_synth_set_chorus_on(synth, e);
+ fluid_synth_set_chorus(synth, fb, l, r, d, type);
}
diff --git a/core/qmpmidioutfluid.hpp b/core/qmpmidioutfluid.hpp
index 63963ee..acefb68 100644
--- a/core/qmpmidioutfluid.hpp
+++ b/core/qmpmidioutfluid.hpp
@@ -8,85 +8,85 @@
#include <fluidsynth.h>
class IFluidSettings
{
- public:
- virtual void setOptStr(const char* opt,const char* val)=0;
- virtual void setOptInt(const char* opt,int val)=0;
- virtual void setOptNum(const char* opt,double val)=0;
- virtual void loadSFont(const char* path)=0;
- virtual void setGain(double gain)=0;
- virtual void setReverbPara(int e,double r,double d,double w,double l)=0;
- virtual void setChorusPara(int e,int fb,double l,double r,double d,int type)=0;
+public:
+ virtual void setOptStr(const char *opt, const char *val) = 0;
+ virtual void setOptInt(const char *opt, int val) = 0;
+ virtual void setOptNum(const char *opt, double val) = 0;
+ virtual void loadSFont(const char *path) = 0;
+ virtual void setGain(double gain) = 0;
+ virtual void setReverbPara(int e, double r, double d, double w, double l) = 0;
+ virtual void setChorusPara(int e, int fb, double l, double r, double d, int type) = 0;
};
-class qmpMidiOutFluid:public qmpMidiOutDevice,public IFluidSettings
+class qmpMidiOutFluid: public qmpMidiOutDevice, public IFluidSettings
{
- private:
- fluid_settings_t* settings;
- fluid_synth_t* synth;
- fluid_audio_driver_t* adriver;
- std::vector<std::pair<uint16_t,std::string>> bnk;
- std::unordered_map<uint16_t,std::vector<std::string>> pst;
- qmpPluginAPI* coreapi;
- std::vector<std::string> drivers;
- int default_driver=-1;
- void update_preset_list();
- public:
- qmpMidiOutFluid();
- ~qmpMidiOutFluid();
- void registerOptions(qmpPluginAPI *coreapi);
- void deviceInit();
- void deviceDeinit();
- void deviceDeinit(bool freshsettings);
- void basicMessage(uint8_t type,uint8_t p1,uint8_t p2);
- void extendedMessage(uint32_t length,const char *data);
- void rpnMessage(uint8_t ch,uint16_t type,uint16_t val);
- void nrpnMessage(uint8_t ch,uint16_t type,uint16_t val);
- void panic(uint8_t ch);
- void reset(uint8_t ch);
- void onMapped(uint8_t ch,int refcnt);
- void onUnmapped(uint8_t ch,int refcnt);
- std::vector<std::pair<uint16_t,std::string>> getBankList();
- std::vector<std::pair<uint8_t,std::string>> getPresets(uint16_t bank);
- std::string getPresetName(uint16_t bank,uint8_t preset);
- bool getChannelPreset(int ch,uint16_t *bank,uint8_t *preset,std::string &presetname);
- uint8_t getInitialCCValue(uint8_t cc,uint8_t ch);
- //FluidSynth specific stuff
- void setOptStr(const char* opt,const char* val);
- void setOptInt(const char* opt,int val);
- void setOptNum(const char* opt,double val);
- void loadSFont(const char* path);
- int getSFCount();
+private:
+ fluid_settings_t *settings;
+ fluid_synth_t *synth;
+ fluid_audio_driver_t *adriver;
+ std::vector<std::pair<uint16_t, std::string>> bnk;
+ std::unordered_map<uint16_t, std::vector<std::string>> pst;
+ qmpPluginAPI *coreapi;
+ std::vector<std::string> drivers;
+ int default_driver = -1;
+ void update_preset_list();
+public:
+ qmpMidiOutFluid();
+ ~qmpMidiOutFluid();
+ void registerOptions(qmpPluginAPI *coreapi);
+ void deviceInit();
+ void deviceDeinit();
+ void deviceDeinit(bool freshsettings);
+ void basicMessage(uint8_t type, uint8_t p1, uint8_t p2);
+ void extendedMessage(uint32_t length, const char *data);
+ void rpnMessage(uint8_t ch, uint16_t type, uint16_t val);
+ void nrpnMessage(uint8_t ch, uint16_t type, uint16_t val);
+ void panic(uint8_t ch);
+ void reset(uint8_t ch);
+ void onMapped(uint8_t ch, int refcnt);
+ void onUnmapped(uint8_t ch, int refcnt);
+ std::vector<std::pair<uint16_t, std::string>> getBankList();
+ std::vector<std::pair<uint8_t, std::string>> getPresets(uint16_t bank);
+ std::string getPresetName(uint16_t bank, uint8_t preset);
+ bool getChannelPreset(int ch, uint16_t *bank, uint8_t *preset, std::string &presetname);
+ uint8_t getInitialCCValue(uint8_t cc, uint8_t ch);
+ //FluidSynth specific stuff
+ void setOptStr(const char *opt, const char *val);
+ void setOptInt(const char *opt, int val);
+ void setOptNum(const char *opt, double val);
+ void loadSFont(const char *path);
+ int getSFCount();
- int getPolyphone();
- int getMaxPolyphone();
- void setGain(double gain);
- void getChannelInfo(int ch,int *b,int *p,char *s);
- 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);
+ int getPolyphone();
+ int getMaxPolyphone();
+ void setGain(double gain);
+ void getChannelInfo(int ch, int *b, int *p, char *s);
+ 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);
};
-class qmpFileRendererFluid:public IFluidSettings
+class qmpFileRendererFluid: public IFluidSettings
{
- private:
- fluid_settings_t* settings;
- fluid_synth_t* synth;
- fluid_player_t* player;
- bool finished;
- std::string fn;
- public:
- qmpFileRendererFluid(const char* _fn,const char* _ofn);
- ~qmpFileRendererFluid();
- void renderInit();
- void renderDeinit();
- void renderWorker();
- void setOptStr(const char* opt,const char* val);
- void setOptInt(const char* opt,int val);
- void setOptNum(const char* opt,double val);
- void loadSFont(const char *path);
- bool isFinished();
- void setGain(double gain);
- void setReverbPara(int e,double r,double d,double w,double l);
- void setChorusPara(int e,int fb,double l,double r,double d,int type);
+private:
+ fluid_settings_t *settings;
+ fluid_synth_t *synth;
+ fluid_player_t *player;
+ bool finished;
+ std::string fn;
+public:
+ qmpFileRendererFluid(const char *_fn, const char *_ofn);
+ ~qmpFileRendererFluid();
+ void renderInit();
+ void renderDeinit();
+ void renderWorker();
+ void setOptStr(const char *opt, const char *val);
+ void setOptInt(const char *opt, int val);
+ void setOptNum(const char *opt, double val);
+ void loadSFont(const char *path);
+ bool isFinished();
+ void setGain(double gain);
+ void setReverbPara(int e, double r, double d, double w, double l);
+ void setChorusPara(int e, int fb, double l, double r, double d, int type);
};
#endif // QMPMIDIOUTFLUID_H
diff --git a/core/qmpmidioutrtmidi.cpp b/core/qmpmidioutrtmidi.cpp
index 2f7125e..04594e4 100644
--- a/core/qmpmidioutrtmidi.cpp
+++ b/core/qmpmidioutrtmidi.cpp
@@ -7,353 +7,405 @@
#include "RtMidi.h"
#include "qmpmidioutrtmidi.hpp"
-void split(std::string s,char c,std::deque<std::string>& v)
+void split(std::string s, char c, std::deque<std::string> &v)
{
- v.clear();
- for(size_t anch=0;;)
- {
- std::string sec;
- if(s.find(c,anch)==std::string::npos)
- sec=s.substr(anch);
- else sec=s.substr(anch,s.find(c,anch)-anch);
- if(!sec.empty())v.push_back(sec);
- if(s.find(c,anch)==std::string::npos)break;
- anch=s.find(c,anch)+1;
- }
+ v.clear();
+ for (size_t anch = 0;;)
+ {
+ std::string sec;
+ if (s.find(c, anch) == std::string::npos)
+ sec = s.substr(anch);
+ else
+ sec = s.substr(anch, s.find(c, anch) - anch);
+ if (!sec.empty())
+ v.push_back(sec);
+ if (s.find(c, anch) == std::string::npos)
+ break;
+ anch = s.find(c, anch) + 1;
+ }
}
-qmpDeviceInitializer* qmpDeviceInitializer::parse(const char* path)
+qmpDeviceInitializer *qmpDeviceInitializer::parse(const char *path)
{
- qmpDeviceInitializer *ret=new qmpDeviceInitializer();
- ret->initseq.eventList.clear();
- memset(ret->sinitv,0xFF,sizeof(ret->sinitv));
+ qmpDeviceInitializer *ret = new qmpDeviceInitializer();
+ ret->initseq.eventList.clear();
+ memset(ret->sinitv, 0xFF, sizeof(ret->sinitv));
- bool st_inmapping=false;
- char buf[1024];
- int ln=0;
- int cmsb=-1,clsb=-1;
+ bool st_inmapping = false;
+ char buf[1024];
+ int ln = 0;
+ int cmsb = -1, clsb = -1;
#define err(e) {delete ret;return fprintf(stderr,"line %d: %s",ln,e),nullptr;}
- FILE* f=fopen(path,"r");
- if(!f)err("file not found")
+ FILE *f = fopen(path, "r");
+ if (!f)
+ err("file not found")
- //writing such a bad parser makes me want my money for
- //the credits from "compiler principles" back...
- auto h2d=[](char c)->char{return 'F'>=c&&c>='A'?c-'A'+10:'9'>=c&&c>='0'?c-'0':-1;};
- auto hh2d=[](const char *c)->int
- {
- if(!c||!*c||strlen(c)>2)return -1;
- int x=-1,r;
- r=sscanf(c,"%x",&x);
- (x<0||x>0xff)&&(x=-1);
- return r==1?x:-1;
- };
- while(fgets(buf,1024,f))
- {
- ++ln;
- if(buf[0]=='#')continue;
- std::string b(buf);
- while(b.length()&&b.back()=='\n')b.pop_back();
- std::deque<std::string> tok;
- split(b,' ',tok);
- if(!tok.size())continue;
- if(tok.front()=="MAP")
- {
- if(st_inmapping)
- err("invalid command")
- st_inmapping=true;
- }
- else if(tok.front()=="ENDMAP")
- {
- if(!st_inmapping)
- err("invalid command")
- st_inmapping=false;
- }
- else if(tok.front()=="X")
- {
- if(st_inmapping)
- err("invalid command")
- tok.pop_front();
- std::string sysx;
- for(auto&i:tok)sysx+=i;
- SEvent ev;
- ev.type=0xF0;
- ev.str="";
- for(auto i=sysx.begin();i!=sysx.end();++i)
- {
- char hn=h2d((char)toupper(*i));
- if(hn<0)err("invalid sysex")
- if(++i==sysx.end())err("invalid sysex")
- char ln=h2d((char)toupper(*i));
- ev.str.push_back((char)(hn<<4|ln));
- }
- ret->initseq.appendEvent(ev);
- }
- else if(tok.front()=="C")
- {
- if(st_inmapping)
- err("invalid command")
- if(tok.size()!=4)err("invalid control")
- int ch=hh2d(tok[1].c_str());
- int cc=hh2d(tok[2].c_str());
- int cv=hh2d(tok[3].c_str());
- if(!~cc||!~cv)err("invalid control parameters")
- if(ch==0xff)
- {
- for(int i=0;i<16;++i)
- {
- SEvent e;
- e.type=(uint8_t)(0xB0|i);
- e.p1=(uint8_t)cc;
- e.p2=(uint8_t)cv;
- ret->initseq.appendEvent(e);
- }
- }
- else if(ch>=0&&ch<0x10)
- {
- SEvent e;
- e.type=(uint8_t)(0xB0|ch);
- e.p1=(uint8_t)cc;
- e.p2=(uint8_t)cv;
- ret->initseq.appendEvent(e);
- }
- else err("invalid channel")
- }
- else if(tok.front()=="IV")
- {
- if(st_inmapping)
- err("invalid command")
- int ci=0;
- tok.pop_front();
- for(auto&tk:tok)
- {
- int v=0,rep=1;
- if(tk.find(',')!=std::string::npos)
- sscanf(tk.c_str(),"%x,%d",&v,&rep);
- else sscanf(tk.c_str(),"%x",&v);
- if(v>0xff||v<0)err("invalid init vector value")
- for(int i=0;i<rep;++i)
- {
- if(ci>=130)err("invalid init vector")
- ret->initv[ci++]=(uint8_t)v;
- }
- }
- }
- else if(tok.front()=="SIV")
- {
- if(st_inmapping)
- err("invalid command")
- int ch=hh2d(tok[1].c_str());
- int cc=hh2d(tok[2].c_str());
- int cv=hh2d(tok[3].c_str());
- ret->sinitv[ch][cc]=uint8_t(cv);
- }
- else if(st_inmapping)
- {
- if(b.front()=='['&&b.back()==']')
- {
- b=b.substr(1,b.length()-2);
- split(b,':',tok);
- if(tok.size()<3)err("invalid bank")
- cmsb=strtol(tok[0].c_str(),nullptr,10);
- clsb=strtol(tok[1].c_str(),nullptr,10);
- ret->banks[cmsb<<7|clsb]=BankStore{{},tok[2]};
- }
- else if(b.find('=')!=std::string::npos)
- {
- if(!~cmsb||!~clsb)err("inst outside a bank")
- split(b,'=',tok);
- if(tok.size()<2)err("invalid inst")
- int p=strtol(tok[0].c_str(),nullptr,10);
- ret->banks[cmsb<<7|clsb].presets[p]=tok[1];
- }
- else err("invalid mapping line")
- }
- }
+ //writing such a bad parser makes me want my money for
+ //the credits from "compiler principles" back...
+ auto h2d = [](char c)->char
+ {
+ return 'F' >= c && c >= 'A' ?
+ c - 'A' + 10 :
+ '9' >= c && c >= '0' ? c - '0' : -1;
+ };
+ auto hh2d = [](const char *c)->int
+ {
+ if (!c || !*c || strlen(c) > 2)
+ return -1;
+ int x = -1, r;
+ r = sscanf(c, "%x", &x);
+ (x < 0 || x > 0xff) &&(x = -1);
+ return r == 1 ? x : -1;
+ };
+ while (fgets(buf, 1024, f))
+ {
+ ++ln;
+ if (buf[0] == '#')
+ continue;
+ std::string b(buf);
+ while (b.length() && b.back() == '\n')
+ b.pop_back();
+ std::deque<std::string> tok;
+ split(b, ' ', tok);
+ if (!tok.size())
+ continue;
+ if (tok.front() == "MAP")
+ {
+ if (st_inmapping)
+ err("invalid command")
+ st_inmapping = true;
+ }
+ else if (tok.front() == "ENDMAP")
+ {
+ if (!st_inmapping)
+ err("invalid command")
+ st_inmapping = false;
+ }
+ else if (tok.front() == "X")
+ {
+ if (st_inmapping)
+ err("invalid command")
+ tok.pop_front();
+ std::string sysx;
+ for (auto &i : tok)
+ sysx += i;
+ SEvent ev;
+ ev.type = 0xF0;
+ ev.str = "";
+ for (auto i = sysx.begin(); i != sysx.end(); ++i)
+ {
+ char hn = h2d((char)toupper(*i));
+ if (hn < 0)
+ err("invalid sysex")
+ if (++i == sysx.end())
+ err("invalid sysex")
+ char ln = h2d((char)toupper(*i));
+ ev.str.push_back((char)(hn << 4 | ln));
+ }
+ ret->initseq.appendEvent(ev);
+ }
+ else if (tok.front() == "C")
+ {
+ if (st_inmapping)
+ err("invalid command")
+ if (tok.size() != 4)
+ err("invalid control")
+ int ch = hh2d(tok[1].c_str());
+ int cc = hh2d(tok[2].c_str());
+ int cv = hh2d(tok[3].c_str());
+ if (!~cc || !~cv)
+ err("invalid control parameters")
+ if (ch == 0xff)
+ {
+ for (int i = 0; i < 16; ++i)
+ {
+ SEvent e;
+ e.type = (uint8_t)(0xB0 | i);
+ e.p1 = (uint8_t)cc;
+ e.p2 = (uint8_t)cv;
+ ret->initseq.appendEvent(e);
+ }
+ }
+ else if (ch >= 0 && ch < 0x10)
+ {
+ SEvent e;
+ e.type = (uint8_t)(0xB0 | ch);
+ e.p1 = (uint8_t)cc;
+ e.p2 = (uint8_t)cv;
+ ret->initseq.appendEvent(e);
+ }
+ else err("invalid channel")
+ }
+ else if (tok.front() == "IV")
+ {
+ if (st_inmapping)
+ err("invalid command")
+ int ci = 0;
+ tok.pop_front();
+ for (auto &tk : tok)
+ {
+ int v = 0, rep = 1;
+ if (tk.find(',') != std::string::npos)
+ sscanf(tk.c_str(), "%x,%d", &v, &rep);
+ else sscanf(tk.c_str(), "%x", &v);
+ if (v > 0xff || v < 0)
+ err("invalid init vector value")
+ for (int i = 0; i < rep; ++i)
+ {
+ if (ci >= 130)
+ err("invalid init vector")
+ ret->initv[ci++] = (uint8_t)v;
+ }
+ }
+ }
+ else if (tok.front() == "SIV")
+ {
+ if (st_inmapping)
+ err("invalid command")
+ int ch = hh2d(tok[1].c_str());
+ int cc = hh2d(tok[2].c_str());
+ int cv = hh2d(tok[3].c_str());
+ ret->sinitv[ch][cc] = uint8_t(cv);
+ }
+ else if (st_inmapping)
+ {
+ if (b.front() == '[' && b.back() == ']')
+ {
+ b = b.substr(1, b.length() - 2);
+ split(b, ':', tok);
+ if (tok.size() < 3)
+ err("invalid bank")
+ cmsb = strtol(tok[0].c_str(), nullptr, 10);
+ clsb = strtol(tok[1].c_str(), nullptr, 10);
+ ret->banks[cmsb << 7 | clsb] = BankStore{{}, tok[2]};
+ }
+ else if (b.find('=') != std::string::npos)
+ {
+ if (!~cmsb || !~clsb)
+ err("inst outside a bank")
+ split(b, '=', tok);
+ if (tok.size() < 2)
+ err("invalid inst")
+ int p = strtol(tok[0].c_str(), nullptr, 10);
+ ret->banks[cmsb << 7 | clsb].presets[p] = tok[1];
+ }
+ else err("invalid mapping line")
+ }
+ }
#undef err
- fclose(f);
- return ret;
+ fclose(f);
+ return ret;
}
qmpMidiOutRtMidi::qmpMidiOutRtMidi(unsigned _portid)
{
- portid=_portid;
- outport=nullptr;
- devinit=nullptr;
+ portid = _portid;
+ outport = nullptr;
+ devinit = nullptr;
}
qmpMidiOutRtMidi::~qmpMidiOutRtMidi()
{
- if(!outport)return;
- if(devinit){delete devinit;devinit=nullptr;}
- if(outport->isPortOpen())outport->closePort();
- delete outport;outport=nullptr;
+ if (!outport)
+ return;
+ if (devinit)
+ {
+ delete devinit;
+ devinit = nullptr;
+ }
+ if (outport->isPortOpen())
+ outport->closePort();
+ delete outport;
+ outport = nullptr;
}
void qmpMidiOutRtMidi::deviceInit()
{
- try
- {
- outport=new RtMidiOut();
- reset(0xFF);
- }
- catch(RtMidiError &e)
- {
- fprintf(stderr,"Cannot create RtMidi Output instance: %s\n",e.what());
- outport=nullptr;
- }
+ try
+ {
+ outport = new RtMidiOut();
+ reset(0xFF);
+ }
+ catch (RtMidiError &e)
+ {
+ fprintf(stderr, "Cannot create RtMidi Output instance: %s\n", e.what());
+ outport = nullptr;
+ }
}
void qmpMidiOutRtMidi::deviceDeinit()
{
- if(!outport||!outport->isPortOpen())return;
- outport->closePort();
+ if (!outport || !outport->isPortOpen())
+ return;
+ outport->closePort();
}
-void qmpMidiOutRtMidi::basicMessage(uint8_t type,uint8_t p1,uint8_t p2)
+void qmpMidiOutRtMidi::basicMessage(uint8_t type, uint8_t p1, uint8_t p2)
{
- if(!outport||!outport->isPortOpen())return;
- std::vector<unsigned char>msg;
- msg.push_back(type);
- msg.push_back(p1);
- if(((type&0xF0)!=0xC0)&&((type&0xF0)!=0xD0))
- msg.push_back(p2);
- try
- {
- outport->sendMessage(&msg);
- }
- catch(RtMidiError &e)
- {
- fprintf(stderr,"Failed to send midi message: %s\n",e.what());
- }
+ if (!outport || !outport->isPortOpen())
+ return;
+ std::vector<unsigned char>msg;
+ msg.push_back(type);
+ msg.push_back(p1);
+ if (((type & 0xF0) != 0xC0) && ((type & 0xF0) != 0xD0))
+ msg.push_back(p2);
+ try
+ {
+ outport->sendMessage(&msg);
+ }
+ catch (RtMidiError &e)
+ {
+ fprintf(stderr, "Failed to send midi message: %s\n", e.what());
+ }
}
-void qmpMidiOutRtMidi::extendedMessage(uint32_t length,const char *data)
+void qmpMidiOutRtMidi::extendedMessage(uint32_t length, const char *data)
{
- if(!outport||!outport->isPortOpen())return;
- std::vector<unsigned char>msg(data,data+length);
- try
- {
- outport->sendMessage(&msg);
- }
- catch(RtMidiError &e)
- {
- fprintf(stderr,"Failed to send midi message: %s\n",e.what());
- }
+ if (!outport || !outport->isPortOpen())
+ return;
+ std::vector<unsigned char>msg(data, data + length);
+ try
+ {
+ outport->sendMessage(&msg);
+ }
+ catch (RtMidiError &e)
+ {
+ fprintf(stderr, "Failed to send midi message: %s\n", e.what());
+ }
}
-void qmpMidiOutRtMidi::rpnMessage(uint8_t ch,uint16_t type,uint16_t val)
+void qmpMidiOutRtMidi::rpnMessage(uint8_t ch, uint16_t type, uint16_t val)
{
- basicMessage(0xB0|ch,0x64,type&0x7F);
- basicMessage(0xB0|ch,0x65,type>>7);
- basicMessage(0xB0|ch,0x06,val>>7);
- basicMessage(0xB0|ch,0x26,val&0x7F);
+ basicMessage(0xB0 | ch, 0x64, type & 0x7F);
+ basicMessage(0xB0 | ch, 0x65, type >> 7);
+ basicMessage(0xB0 | ch, 0x06, val >> 7);
+ basicMessage(0xB0 | ch, 0x26, val & 0x7F);
}
-void qmpMidiOutRtMidi::nrpnMessage(uint8_t ch,uint16_t type,uint16_t val)
+void qmpMidiOutRtMidi::nrpnMessage(uint8_t ch, uint16_t type, uint16_t val)
{
- basicMessage(0xB0|ch,0x62,type&0x7F);
- basicMessage(0xB0|ch,0x63,type>>7);
- basicMessage(0xB0|ch,0x06,val>>7);
- basicMessage(0xB0|ch,0x26,val&0x7F);
+ basicMessage(0xB0 | ch, 0x62, type & 0x7F);
+ basicMessage(0xB0 | ch, 0x63, type >> 7);
+ basicMessage(0xB0 | ch, 0x06, val >> 7);
+ basicMessage(0xB0 | ch, 0x26, val & 0x7F);
}
void qmpMidiOutRtMidi::panic(uint8_t ch)
{
- //maybe all notes off is more close to panic?
- basicMessage(0xE0|ch,0x0,0x40);
- basicMessage(0xB0|ch,123,0);
+ //maybe all notes off is more close to panic?
+ basicMessage(0xE0 | ch, 0x0, 0x40);
+ basicMessage(0xB0 | ch, 123, 0);
}
void qmpMidiOutRtMidi::reset(uint8_t ch)
{
- if(ch==0xFF)
- {
- if(devinit)
- for(auto&msg:devinit->initseq.eventList)
- {
- if((msg.type&0xF0)==0xF0)
- extendedMessage(msg.str.length(),msg.str.data());
- else
- basicMessage(msg.type,msg.p1,msg.p2);
- }
- }
- else
- {
- basicMessage(0xB0|ch,121,0);
- basicMessage(0xB0|ch,123,0);
- }
+ if (ch == 0xFF)
+ {
+ if (devinit)
+ for (auto &msg : devinit->initseq.eventList)
+ {
+ if ((msg.type & 0xF0) == 0xF0)
+ extendedMessage(msg.str.length(), msg.str.data());
+ else
+ basicMessage(msg.type, msg.p1, msg.p2);
+ }
+ }
+ else
+ {
+ basicMessage(0xB0 | ch, 121, 0);
+ basicMessage(0xB0 | ch, 123, 0);
+ }
}
-void qmpMidiOutRtMidi::onMapped(uint8_t,int)
+void qmpMidiOutRtMidi::onMapped(uint8_t, int)
{
- if(!outport)deviceInit();
- if(outport->isPortOpen())return;
- try
- {
- outport->openPort(portid);
- }
- catch(RtMidiError &e)
- {
- fprintf(stderr,"Device initialization failure: %s\n",e.what());
- }
+ if (!outport)
+ deviceInit();
+ if (outport->isPortOpen())
+ return;
+ try
+ {
+ outport->openPort(portid);
+ }
+ catch (RtMidiError &e)
+ {
+ fprintf(stderr, "Device initialization failure: %s\n", e.what());
+ }
}
-void qmpMidiOutRtMidi::onUnmapped(uint8_t ch,int refcnt)
+void qmpMidiOutRtMidi::onUnmapped(uint8_t ch, int refcnt)
{
- panic(ch);
- if(!refcnt&&outport)outport->closePort();
+ panic(ch);
+ if (!refcnt && outport)
+ outport->closePort();
}
-std::vector<std::pair<uint16_t,std::string>> qmpMidiOutRtMidi::getBankList()
+std::vector<std::pair<uint16_t, std::string>> qmpMidiOutRtMidi::getBankList()
{
- if(!devinit)return{};
- std::vector<std::pair<uint16_t,std::string>> ret;
- for(auto&i:devinit->banks)
- ret.push_back({i.first,i.second.bankname});
- std::sort(ret.begin(),ret.end(),[](std::pair<uint16_t,std::string>&a,std::pair<uint16_t,std::string>&b){return a.first<b.first;});
- return ret;
+ if (!devinit)
+ return{};
+ std::vector<std::pair<uint16_t, std::string>> ret;
+ for (auto &i : devinit->banks)
+ ret.push_back({i.first, i.second.bankname});
+ std::sort(ret.begin(), ret.end(), [](std::pair<uint16_t, std::string> &a, std::pair<uint16_t, std::string> &b)
+ {
+ return a.first < b.first;
+ });
+ return ret;
}
-std::vector<std::pair<uint8_t,std::string>> qmpMidiOutRtMidi::getPresets(uint16_t bank)
+std::vector<std::pair<uint8_t, std::string>> qmpMidiOutRtMidi::getPresets(uint16_t bank)
{
- if(!devinit)return{};
- if(devinit->banks.find(bank)==devinit->banks.end())return{};
- std::vector<std::pair<uint8_t,std::string>> ret;
- for(auto&i:devinit->banks[bank].presets)
- ret.push_back({i.first,i.second});
- std::sort(ret.begin(),ret.end(),[](std::pair<uint8_t,std::string>&a,std::pair<uint8_t,std::string>&b){return a.first<b.first;});
- return ret;
+ if (!devinit)
+ return{};
+ if (devinit->banks.find(bank) == devinit->banks.end())
+ return{};
+ std::vector<std::pair<uint8_t, std::string>> ret;
+ for (auto &i : devinit->banks[bank].presets)
+ ret.push_back({i.first, i.second});
+ std::sort(ret.begin(), ret.end(), [](std::pair<uint8_t, std::string> &a, std::pair<uint8_t, std::string> &b)
+ {
+ return a.first < b.first;
+ });
+ return ret;
}
-std::string qmpMidiOutRtMidi::getPresetName(uint16_t bank,uint8_t preset)
+std::string qmpMidiOutRtMidi::getPresetName(uint16_t bank, uint8_t preset)
{
- if(!devinit)return"";
- if(devinit->banks.find(bank)!=devinit->banks.end())
- if(devinit->banks[bank].presets.find(preset)!=devinit->banks[bank].presets.end())
- return devinit->banks[bank].presets[preset];
- return"";
+ if (!devinit)
+ return std::string();
+ if (devinit->banks.find(bank) != devinit->banks.end())
+ if (devinit->banks[bank].presets.find(preset) != devinit->banks[bank].presets.end())
+ return devinit->banks[bank].presets[preset];
+ return std::string();
}
-bool qmpMidiOutRtMidi::getChannelPreset(int ch,uint16_t *bank,uint8_t *preset,std::string &presetname)
+bool qmpMidiOutRtMidi::getChannelPreset(int ch, uint16_t *bank, uint8_t *preset, std::string &presetname)
{
- //This ain't a state-tracking device
- return false;
+ //This ain't a state-tracking device
+ return false;
}
-uint8_t qmpMidiOutRtMidi::getInitialCCValue(uint8_t cc,uint8_t ch)
+uint8_t qmpMidiOutRtMidi::getInitialCCValue(uint8_t cc, uint8_t ch)
{
- if(!devinit||cc>=130)return 0;//Nope!
- if(ch<16&&devinit->sinitv[ch][cc]!=0xFF)
- return devinit->sinitv[ch][cc];
- return devinit->initv[cc];
+ if (!devinit || cc >= 130)
+ return 0;
+ if (ch < 16 && devinit->sinitv[ch][cc] != 0xFF)
+ return devinit->sinitv[ch][cc];
+ return devinit->initv[cc];
}
-void qmpMidiOutRtMidi::setInitializerFile(const char* path)
+void qmpMidiOutRtMidi::setInitializerFile(const char *path)
{
- if(devinit)delete devinit;
- devinit=qmpDeviceInitializer::parse(path);
- reset(0xFF);
+ if (devinit)
+ delete devinit;
+ devinit = qmpDeviceInitializer::parse(path);
+ reset(0xFF);
}
-std::vector<std::pair<qmpMidiOutRtMidi*,std::string>> qmpRtMidiManager::devices;
-std::vector<std::pair<qmpMidiOutRtMidi*,std::string>> qmpRtMidiManager::getDevices()
+std::vector<std::pair<qmpMidiOutRtMidi *, std::string>> qmpRtMidiManager::devices;
+std::vector<std::pair<qmpMidiOutRtMidi *, std::string>> qmpRtMidiManager::getDevices()
{
- if(devices.size())return devices;
- RtMidiOut *dummy;
- try{dummy=new RtMidiOut();}
- catch(RtMidiError &e)
- {
- fprintf(stderr,"Failed to initialize the dummy device: %s\n",e.what());
- return{};
- }
- for(unsigned i=0;i<dummy->getPortCount();++i)
- devices.push_back(std::make_pair(new qmpMidiOutRtMidi(i),dummy->getPortName(i)));
- delete dummy;
- return devices;
+ if (devices.size())
+ return devices;
+ RtMidiOut *dummy;
+ try
+ {
+ dummy = new RtMidiOut();
+ }
+ catch (RtMidiError &e)
+ {
+ fprintf(stderr, "Failed to initialize the dummy device: %s\n", e.what());
+ return{};
+ }
+ for (unsigned i = 0; i < dummy->getPortCount(); ++i)
+ devices.push_back(std::make_pair(new qmpMidiOutRtMidi(i), dummy->getPortName(i)));
+ delete dummy;
+ return devices;
}
diff --git a/core/qmpmidioutrtmidi.hpp b/core/qmpmidioutrtmidi.hpp
index 45662ba..8276cce 100644
--- a/core/qmpmidioutrtmidi.hpp
+++ b/core/qmpmidioutrtmidi.hpp
@@ -6,53 +6,53 @@
#include "../include/qmpcorepublic.hpp"
struct qmpDeviceInitializer
{
- CMidiTrack initseq;
- struct BankStore
- {
- std::unordered_map<uint8_t,std::string> presets;
- std::string bankname;
- };
- std::unordered_map<uint16_t,BankStore> banks;
- uint8_t initv[130];
- uint8_t sinitv[16][130];
+ CMidiTrack initseq;
+ struct BankStore
+ {
+ std::unordered_map<uint8_t, std::string> presets;
+ std::string bankname;
+ };
+ std::unordered_map<uint16_t, BankStore> banks;
+ uint8_t initv[130];
+ uint8_t sinitv[16][130];
- static qmpDeviceInitializer* parse(const char* path);
+ static qmpDeviceInitializer *parse(const char *path);
};
class RtMidiOut;
-class qmpMidiOutRtMidi:public qmpMidiOutDevice
+class qmpMidiOutRtMidi : public qmpMidiOutDevice
{
private:
- unsigned portid;
- RtMidiOut* outport;
- qmpDeviceInitializer* devinit;
+ unsigned portid;
+ RtMidiOut *outport;
+ qmpDeviceInitializer *devinit;
public:
- qmpMidiOutRtMidi(unsigned _portid);
- ~qmpMidiOutRtMidi();
- void deviceInit();
- void deviceDeinit();
- void basicMessage(uint8_t type,uint8_t p1,uint8_t p2);
- void extendedMessage(uint32_t length,const char *data);
- void rpnMessage(uint8_t ch,uint16_t type,uint16_t val);
- void nrpnMessage(uint8_t ch,uint16_t type,uint16_t val);
- void panic(uint8_t ch);
- void reset(uint8_t ch);
- void onMapped(uint8_t ch,int refcnt);
- void onUnmapped(uint8_t ch,int refcnt);
- std::vector<std::pair<uint16_t,std::string>> getBankList();
- std::vector<std::pair<uint8_t,std::string>> getPresets(uint16_t bank);
- std::string getPresetName(uint16_t bank,uint8_t preset);
- bool getChannelPreset(int ch,uint16_t *bank,uint8_t *preset,std::string &presetname);
- uint8_t getInitialCCValue(uint8_t cc,uint8_t ch);
+ qmpMidiOutRtMidi(unsigned _portid);
+ ~qmpMidiOutRtMidi();
+ void deviceInit();
+ void deviceDeinit();
+ void basicMessage(uint8_t type, uint8_t p1, uint8_t p2);
+ void extendedMessage(uint32_t length, const char *data);
+ void rpnMessage(uint8_t ch, uint16_t type, uint16_t val);
+ void nrpnMessage(uint8_t ch, uint16_t type, uint16_t val);
+ void panic(uint8_t ch);
+ void reset(uint8_t ch);
+ void onMapped(uint8_t ch, int refcnt);
+ void onUnmapped(uint8_t ch, int refcnt);
+ std::vector<std::pair<uint16_t, std::string>> getBankList();
+ std::vector<std::pair<uint8_t, std::string>> getPresets(uint16_t bank);
+ std::string getPresetName(uint16_t bank, uint8_t preset);
+ bool getChannelPreset(int ch, uint16_t *bank, uint8_t *preset, std::string &presetname);
+ uint8_t getInitialCCValue(uint8_t cc, uint8_t ch);
- void setInitializerFile(const char* path);
+ void setInitializerFile(const char *path);
};
class qmpRtMidiManager
{
- private:
- static std::vector<std::pair<qmpMidiOutRtMidi*,std::string>> devices;
- public:
- static std::vector<std::pair<qmpMidiOutRtMidi*,std::string>> getDevices();
+private:
+ static std::vector<std::pair<qmpMidiOutRtMidi *, std::string>> devices;
+public:
+ static std::vector<std::pair<qmpMidiOutRtMidi *, std::string>> getDevices();
};
#endif // QMPMIDIMAPPERS_H
diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp
index a354d6e..c987e01 100644
--- a/core/qmpmidiplay.cpp
+++ b/core/qmpmidiplay.cpp
@@ -9,609 +9,778 @@
#include <windows.h>
uint64_t pf;
#endif
-CMidiPlayer* CMidiPlayer::ref=nullptr;
+CMidiPlayer *CMidiPlayer::ref = nullptr;
bool CMidiPlayer::processEvent(const SEvent *e)
{
- SEvent fe(*e);
- fe.flags&=0xfe;
- if(tceptr>=eorder.size()-1||getEvent(tceptr+1)->time>e->time)
- fe.flags|=0x01;
- for(int i=0;i<16;++i)if(eventHandlerCB[i])
- eventHandlerCB[i]->callBack((void*)&fe,eventHandlerCBuserdata[i]);
- for(auto i=event_handlers.begin();i!=event_handlers.end();++i)
- if(!std::get<2>(i->second))
- std::get<0>(i->second)((void*)e,std::get<1>(i->second));
- uint8_t ch=e->type&0x0F;
- if((e->type&0xF0)<0xF0)
- levtt[ch]=std::chrono::system_clock::now();
- switch(e->type&0xF0)
- {
- case 0x80://Note off
- return true;
- case 0x90://Note on
- if((mute>>ch)&1&&e->p2)return false;//muted
- if(solo&&!((solo>>ch)&1)&&e->p2)return false;//excluded by solo flags
- return true;
- case 0xB0://CC
- if(e->p1==100)rpnid[ch]=e->p2;
- if(e->p1==6)rpnval[ch]=e->p2;
- if(~rpnid[ch]&&~rpnval[ch])
- {
- if(rpnid[ch]==0)
- {
- mididev[mappedoutput[ch]].dev->rpnMessage(ch,0,rpnval[ch]<<7);
- pbr[ch]=rpnval[ch];
- }
- rpnid[ch]=rpnval[ch]=-1;
- }
- chstatus[ch][e->p1]=e->p2;
- return true;
- case 0xC0://PC
- chstatus[ch][128]=e->p1;
- return true;
- case 0xE0://PW
- pbv[ch]=(e->p1|(e->p2<<7))&0x3FFF;
- return true;
- case 0xF0://Meta/SysEx
- if((e->type&0x0F)==0x0F)
- {
- switch(e->p1)
- {
- case 0x51:
- {
- ctempo=0;
+ SEvent fe(*e);
+ fe.flags &= 0xfe;
+ if (tceptr >= eorder.size() - 1 || getEvent(tceptr + 1)->time > e->time)
+ fe.flags |= 0x01;
+ for (int i = 0; i < 16; ++i)
+ if (eventHandlerCB[i])
+ eventHandlerCB[i]->callBack((void *)&fe, eventHandlerCBuserdata[i]);
+ for (auto i = event_handlers.begin(); i != event_handlers.end(); ++i)
+ if (!std::get<2>(i->second))
+ std::get<0>(i->second)((void *)e, std::get<1>(i->second));
+ uint8_t ch = e->type & 0x0F;
+ if ((e->type & 0xF0) < 0xF0)
+ levtt[ch] = std::chrono::system_clock::now();
+ switch (e->type & 0xF0)
+ {
+ case 0x80://Note off
+ return true;
+ case 0x90://Note on
+ if ((mute >> ch) & 1 && e->p2)
+ return false; //muted
+ if (solo && !((solo >> ch) & 1) && e->p2)
+ return false; //excluded by solo flags
+ return true;
+ case 0xB0://CC
+ if (e->p1 == 100)
+ rpnid[ch] = e->p2;
+ if (e->p1 == 6)
+ rpnval[ch] = e->p2;
+ if (~rpnid[ch] && ~rpnval[ch])
+ {
+ if (rpnid[ch] == 0)
+ {
+ mididev[mappedoutput[ch]].dev->rpnMessage(ch, 0, rpnval[ch] << 7);
+ pbr[ch] = rpnval[ch];
+ }
+ rpnid[ch] = rpnval[ch] = -1;
+ }
+ chstatus[ch][e->p1] = e->p2;
+ return true;
+ case 0xC0://PC
+ chstatus[ch][128] = e->p1;
+ return true;
+ case 0xE0://PW
+ pbv[ch] = (e->p1 | (e->p2 << 7)) & 0x3FFF;
+ return true;
+ case 0xF0://Meta/SysEx
+ if ((e->type & 0x0F) == 0x0F)
+ {
+ switch (e->p1)
+ {
+ case 0x51:
+ {
+ ctempo = 0;
#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__)||defined(_WIN32)
- std::string x(e->str);
- std::reverse(x.begin(),x.end());
- memcpy(&ctempo,x.data(),3);
+ std::string x(e->str);
+ std::reverse(x.begin(), x.end());
+ memcpy(&ctempo, x.data(), 3);
#else
- memcpy(&ctempo,e->str.data(),3);
- ctempo>>=8;
+ memcpy(&ctempo, e->str.data(), 3);
+ ctempo >>= 8;
#endif
- dpt=ctempo*1000./divs;
- ttime=std::chrono::high_resolution_clock::now();
- ttick=getTick();
- }
- break;
- case 0x58:
- ctsn=(uint32_t)e->str[0];
- ctsd=1<<((uint32_t)e->str[1]);
- break;
- case 0x59:
- if(e->str.length()==2)
- cks=(e->str[0]<<8u)|e->str[1];
- 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)&&sendSysEx)
- for(auto& i:mididev)
- if(i.refcnt)
- i.dev->extendedMessage(uint32_t(e->str.length()),e->str.c_str());
- return false;
- }
- return false;
+ dpt = ctempo * 1000. / divs;
+ ttime = std::chrono::high_resolution_clock::now();
+ ttick = getTick();
+ }
+ break;
+ case 0x58:
+ ctsn = (uint32_t)e->str[0];
+ ctsd = 1 << ((uint32_t)e->str[1]);
+ break;
+ case 0x59:
+ if (e->str.length() == 2)
+ cks = (e->str[0] << 8u) | e->str[1];
+ 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) && sendSysEx)
+ for (auto &i : mididev)
+ if (i.refcnt)
+ i.dev->extendedMessage(uint32_t(e->str.length()), e->str.c_str());
+ return false;
+ }
+ return false;
}
void CMidiPlayer::processEventStub(const SEvent *e)
{
- switch(e->type&0xF0)
- {
- case 0xB0://CC
- if(e->p1==100)rpnid[e->type&0x0F]=e->p2;
- if(e->p1==6)rpnval[e->type&0x0F]=e->p2;
- if(~rpnid[e->type&0x0F]&&~rpnval[e->type&0x0F])
- {
- if(rpnid[e->type&0x0F]==0)ccc[e->type&0x0F][134]=rpnval[e->type&0x0F];
- rpnval[e->type&0x0F]=-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|(e->p2<<7))&0x3FFF;
- break;
- case 0xF0://Meta/SysEx
- if((e->type&0x0F)==0x0F)
- {
- switch(e->p1)
- {
- case 0x51:
- {
- ctempo=0;
+ switch (e->type & 0xF0)
+ {
+ case 0xB0://CC
+ if (e->p1 == 100)
+ rpnid[e->type & 0x0F] = e->p2;
+ if (e->p1 == 6)
+ rpnval[e->type & 0x0F] = e->p2;
+ if (~rpnid[e->type & 0x0F] && ~rpnval[e->type & 0x0F])
+ {
+ if (rpnid[e->type & 0x0F] == 0)
+ ccc[e->type & 0x0F][134] = rpnval[e->type & 0x0F];
+ rpnval[e->type & 0x0F] = -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 | (e->p2 << 7)) & 0x3FFF;
+ break;
+ case 0xF0://Meta/SysEx
+ if ((e->type & 0x0F) == 0x0F)
+ {
+ switch (e->p1)
+ {
+ case 0x51:
+ {
+ ctempo = 0;
#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__)||defined(_WIN32)
- std::string x(e->str);
- std::reverse(x.begin(),x.end());
- memcpy(&ctempo,x.data(),3);
+ std::string x(e->str);
+ std::reverse(x.begin(), x.end());
+ memcpy(&ctempo, x.data(), 3);
#else
- memcpy(&ctempo,e->str.data(),3);
- ctempo>>=8;
+ memcpy(&ctempo, e->str.data(), 3);
+ ctempo >>= 8;
#endif
- dpt=ctempo*1000./divs;
- ccc[0][131]=ctempo;
- }
- break;
- case 0x58:
- ccc[0][132]=(e->str[0]<<24u)|(e->str[1]<<16u);
- break;
- case 0x59:
- if(e->str.length()>=2)
- ccc[0][133]=(e->str[0]<<8u)|e->str[1];
- break;
- }
- }
- break;
- }
+ dpt = ctempo * 1000. / divs;
+ ccc[0][131] = ctempo;
+ }
+ break;
+ case 0x58:
+ ccc[0][132] = (e->str[0] << 24u) | (e->str[1] << 16u);
+ break;
+ case 0x59:
+ if (e->str.length() >= 2)
+ ccc[0][133] = (e->str[0] << 8u) | e->str[1];
+ break;
+ }
+ }
+ break;
+ }
}
#ifdef _WIN32
void w32usleep(uint64_t t)
{
- uint64_t st=0,ct=0;
- timeBeginPeriod(1);
- 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);
- timeEndPeriod(1);
+ uint64_t st = 0, ct = 0;
+ timeBeginPeriod(1);
+ 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);
+ timeEndPeriod(1);
}
#endif
-SEvent* CMidiPlayer::getEvent(uint32_t id)
+SEvent *CMidiPlayer::getEvent(uint32_t id)
{
- size_t t=eorder[id].first,e=eorder[id].second;
- return &midiFile->tracks[t].eventList[e];
+ size_t t = eorder[id].first, e = eorder[id].second;
+ return &midiFile->tracks[t].eventList[e];
}
void CMidiPlayer::prePlayInit()
{
- playerPanic(true);
- for(size_t i=0;i<mididev.size();++i)
- if(mididev[i].refcnt)
- mididev[i].dev->reset(0xFF);
+ playerPanic(true);
+ for (size_t i = 0; i < mididev.size(); ++i)
+ if (mididev[i].refcnt)
+ mididev[i].dev->reset(0xFF);
}
void CMidiPlayer::playEvents()
{
- static uint32_t _lrtick;_lrtick=0;
- ttick=getEvent(0)->time;ttime=std::chrono::high_resolution_clock::now();
- for(ct=getEvent(0)->time;tceptr<ecnt;)
- {
- using namespace std::chrono;
- while(tcpaused)std::this_thread::sleep_for(milliseconds(100));
- if(resumed){
- resumed=false;
- ct=getEvent(tceptr)->time;
- ttick=getTick();
- ttime=high_resolution_clock::now();
- continue;
- }
- high_resolution_clock::time_point b=high_resolution_clock::now();
- if(getTick()-_lrtick>divs){
- _lrtick=getTick();
- //double _dt=(getTick()-ttick)*dpt-duration_cast<nanoseconds>((b-ttime)).count();
- //<0: slower than expected, >0: faster than expected
- //fprintf(stderr,"@ tick %u, dtime %.6fus",getTick(),_dt/1000.);
- }
- for(;!tcstop&&midiReaders&&tceptr<ecnt&&ct==getEvent(tceptr)->time;++tceptr)
- {
- if(processEvent(getEvent(tceptr)))
- {
- SEvent* e=getEvent(tceptr);
- mididev[mappedoutput[e->type&0x0F]].dev->basicMessage(e->type,e->p1,e->p2);
- }
- for(auto i=event_handlers.begin();i!=event_handlers.end();++i)
- if(std::get<2>(i->second))
- std::get<0>(i->second)((void*)getEvent(tceptr),std::get<1>(i->second));
- }
- if(tcstop||!midiReaders||tceptr>=ecnt)break;
- high_resolution_clock::time_point a=high_resolution_clock::now();
- auto sendtime=a-b;
- if(sendtime.count()<(getEvent(tceptr)->time-ct)*dpt)
- {
- double ns_sleep=(getEvent(tceptr)->time-ct)*dpt-sendtime.count();
- double correction=(getTick()-ttick)*dpt-(b-ttime).count();
- if(correction>0)correction=0;
+ static uint32_t _lrtick;
+ _lrtick = 0;
+ ttick = getEvent(0)->time;
+ ttime = std::chrono::high_resolution_clock::now();
+ for (ct = getEvent(0)->time; tceptr < ecnt;)
+ {
+ using namespace std::chrono;
+ while (tcpaused)
+ std::this_thread::sleep_for(milliseconds(100));
+ if (resumed)
+ {
+ resumed = false;
+ ct = getEvent(tceptr)->time;
+ ttick = getTick();
+ ttime = high_resolution_clock::now();
+ continue;
+ }
+ high_resolution_clock::time_point b = high_resolution_clock::now();
+ if (getTick() - _lrtick > divs)
+ {
+ _lrtick = getTick();
+ //double _dt=(getTick()-ttick)*dpt-duration_cast<nanoseconds>((b-ttime)).count();
+ //<0: slower than expected, >0: faster than expected
+ //fprintf(stderr,"@ tick %u, dtime %.6fus",getTick(),_dt/1000.);
+ }
+ for (; !tcstop && midiReaders && tceptr < ecnt && ct == getEvent(tceptr)->time; ++tceptr)
+ {
+ if (processEvent(getEvent(tceptr)))
+ {
+ SEvent *e = getEvent(tceptr);
+ mididev[mappedoutput[e->type & 0x0F]].dev->basicMessage(e->type, e->p1, e->p2);
+ }
+ for (auto i = event_handlers.begin(); i != event_handlers.end(); ++i)
+ if (std::get<2>(i->second))
+ std::get<0>(i->second)((void *)getEvent(tceptr), std::get<1>(i->second));
+ }
+ if (tcstop || !midiReaders || tceptr >= ecnt)
+ break;
+ high_resolution_clock::time_point a = high_resolution_clock::now();
+ auto sendtime = a - b;
+ if (sendtime.count() < (getEvent(tceptr)->time - ct)*dpt)
+ {
+ double ns_sleep = (getEvent(tceptr)->time - ct) * dpt - sendtime.count();
+ double correction = (getTick() - ttick) * dpt - (b - ttime).count();
+ if (correction > 0)
+ correction = 0;
#ifdef _WIN32
- w32usleep((uint64_t)(((getEvent(tceptr)->time-ct)*dpt-sendtime.count())/1000));
+ w32usleep((uint64_t)(((getEvent(tceptr)->time - ct)*dpt - sendtime.count()) / 1000));
#else
- std::this_thread::sleep_for(std::chrono::nanoseconds((uint64_t)(ns_sleep+correction)));
+ std::this_thread::sleep_for(std::chrono::nanoseconds((uint64_t)(ns_sleep + correction)));
#endif
- }
- if(tcstop||!midiReaders)break;
- ct=getEvent(tceptr)->time;
- }
- if(tceptr>=ecnt)
- finished=1;
+ }
+ if (tcstop || !midiReaders)
+ break;
+ ct = getEvent(tceptr)->time;
+ }
+ if (tceptr >= ecnt)
+ finished = 1;
}
void CMidiPlayer::fileTimer1Pass()
{
- ftime=.0;ctempo=0x7A120;dpt=ctempo*1000./divs;
- for(uint32_t eptr=0,ct=getEvent(0)->time;eptr<ecnt;)
- {
- while(eptr<ecnt&&ct==getEvent(eptr)->time)
- processEventStub(getEvent(eptr++));
- if(eptr>=ecnt)break;
- ftime+=(getEvent(eptr)->time-ct)*dpt/1e9;
- ct=getEvent(eptr)->time;
- }
+ ftime = .0;
+ ctempo = 0x7A120;
+ dpt = ctempo * 1000. / divs;
+ for (uint32_t eptr = 0, ct = getEvent(0)->time; eptr < ecnt;)
+ {
+ while (eptr < ecnt && ct == getEvent(eptr)->time)
+ processEventStub(getEvent(eptr++));
+ if (eptr >= ecnt)
+ break;
+ ftime += (getEvent(eptr)->time - ct) * dpt / 1e9;
+ ct = 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));memset(rpnid,0xFF,sizeof(rpnid));memset(rpnval,0xFF,sizeof(rpnval));
- for(int i=0;i<16;++i)
- {
- memset(ccc[i],0xFF,128*sizeof(uint32_t));
- ccc[i][131]=ctempo;ccc[i][132]=0x04021808;
- ccc[i][133]=0;ccc[i][134]=2;
- }
- 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=getEvent(0)->time;eptr<ecnt;)
- {
- while(eptr<ecnt&&ct==getEvent(eptr)->time)
- processEventStub(getEvent(eptr++));
- if(eptr>=ecnt)break;
- ctime+=(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=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++]=ecnt;
- }
+ 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));
+ memset(rpnid, 0xFF, sizeof(rpnid));
+ memset(rpnval, 0xFF, sizeof(rpnval));
+ for (int i = 0; i < 16; ++i)
+ {
+ memset(ccc[i], 0xFF, 128 * sizeof(uint32_t));
+ ccc[i][131] = ctempo;
+ ccc[i][132] = 0x04021808;
+ ccc[i][133] = 0;
+ ccc[i][134] = 2;
+ }
+ 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 = getEvent(0)->time; eptr < ecnt;)
+ {
+ while (eptr < ecnt && ct == getEvent(eptr)->time)
+ processEventStub(getEvent(eptr++));
+ if (eptr >= ecnt)
+ break;
+ ctime += (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 = 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++] = ecnt;
+ }
}
CMidiPlayer::CMidiPlayer()
{
- midiReaders=new CMidiFileReaderCollection();
- resumed=false;midiFile=nullptr;
- waitvoice=true;
- event_handlers_id=event_read_handlers_id=file_read_finish_hooks_id=0;
- memset(eventHandlerCB,0,sizeof(eventHandlerCB));
- 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,0xff,sizeof(mappedoutput));
- memset(chstatus,0,sizeof(chstatus));
- for(int i=0;i<16;++i)
- memset(chstatus[i],0xff,128*sizeof(uint8_t));
+ midiReaders = new CMidiFileReaderCollection();
+ resumed = false;
+ midiFile = nullptr;
+ waitvoice = true;
+ event_handlers_id = event_read_handlers_id = file_read_finish_hooks_id = 0;
+ memset(eventHandlerCB, 0, sizeof(eventHandlerCB));
+ 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, 0xff, sizeof(mappedoutput));
+ memset(chstatus, 0, sizeof(chstatus));
+ for (int i = 0; i < 16; ++i)
+ memset(chstatus[i], 0xff, 128 * sizeof(uint8_t));
#ifdef _WIN32
- QueryPerformanceFrequency((LARGE_INTEGER*)&pf);
+ QueryPerformanceFrequency((LARGE_INTEGER *)&pf);
#endif
- ref=this;
+ ref = this;
}
CMidiPlayer::~CMidiPlayer()
{
- if(midiFile)delete midiFile;delete midiReaders;
+ if (midiFile)
+ delete midiFile;
+ delete midiReaders;
}
void CMidiPlayer::playerPanic(bool reset)
{
- for(auto& i:mididev)
- if(i.refcnt)
- {
- for(uint8_t j=0;j<16;++j)
- reset?i.dev->reset(j):i.dev->panic(j);
- }
-}
-bool CMidiPlayer::playerLoadFile(const char* fn)
-{
- notes=0;if(midiFile)delete midiFile;
- midiFile=midiReaders->readFile(fn);
- if(!midiFile||!midiFile->valid)return false;
- divs=midiFile->divs;maxtk=ecnt=0;
- for(CMidiTrack& i:midiFile->tracks)
- {
- ecnt+=i.eventList.size();
- if(i.eventList.size())
- maxtk=std::max(maxtk,i.eventList.back().time);
- }
- for(int i=0;i<16;++i)if(fileReadFinishCB[i])
- fileReadFinishCB[i]->callBack(nullptr,fileReadFinishCBuserdata[i]);
- for(auto i=file_read_finish_hooks.begin();i!=file_read_finish_hooks.end();++i)
- i->second.first(nullptr,i->second.second);
- eorder.clear();
- for(size_t i=0;i<midiFile->tracks.size();++i)
- for(size_t j=0;j<midiFile->tracks[i].eventList.size();++j)
- eorder.push_back(std::make_pair(i,j));
- std::sort(eorder.begin(),eorder.end(),
- [this](std::pair<size_t,size_t> &a,std::pair<size_t,size_t> &b)->bool{
- return midiFile->tracks[a.first].eventList[a.second]<
- midiFile->tracks[b.first].eventList[b.second];
- }
- );
- fileTimer1Pass();
- fileTimer2Pass();
- return true;
+ for (auto &i : mididev)
+ if (i.refcnt)
+ {
+ for (uint8_t j = 0; j < 16; ++j)
+ reset ? i.dev->reset(j) : i.dev->panic(j);
+ }
+}
+bool CMidiPlayer::playerLoadFile(const char *fn)
+{
+ notes = 0;
+ if (midiFile)
+ delete midiFile;
+ midiFile = midiReaders->readFile(fn);
+ if (!midiFile || !midiFile->valid)
+ return false;
+ divs = midiFile->divs;
+ maxtk = ecnt = 0;
+ for (CMidiTrack &i : midiFile->tracks)
+ {
+ ecnt += i.eventList.size();
+ if (i.eventList.size())
+ maxtk = std::max(maxtk, i.eventList.back().time);
+ }
+ for (int i = 0; i < 16; ++i)
+ if (fileReadFinishCB[i])
+ fileReadFinishCB[i]->callBack(nullptr, fileReadFinishCBuserdata[i]);
+ for (auto i = file_read_finish_hooks.begin(); i != file_read_finish_hooks.end(); ++i)
+ i->second.first(nullptr, i->second.second);
+ eorder.clear();
+ for (size_t i = 0; i < midiFile->tracks.size(); ++i)
+ for (size_t j = 0; j < midiFile->tracks[i].eventList.size(); ++j)
+ eorder.push_back(std::make_pair(i, j));
+ std::sort(eorder.begin(), eorder.end(),
+ [this](std::pair<size_t, size_t> &a, std::pair<size_t, size_t> &b)->bool
+ {
+ return midiFile->tracks[a.first].eventList[a.second] <
+ midiFile->tracks[b.first].eventList[b.second];
+ });
+ fileTimer1Pass();
+ fileTimer2Pass();
+ return true;
}
void CMidiPlayer::playerInit()
{
- ctempo=0x7A120;ctsn=4;ctsd=4;cks=0;dpt=ctempo*1000./divs;
- tceptr=0;tcstop=false;tcpaused=0;finished=0;mute=solo=0;
- for(int i=0;i<16;++i)pbr[i]=2,pbv[i]=8192;
- sendSysEx=true;memset(rpnid,0xFF,sizeof(rpnid));memset(rpnval,0xFF,sizeof(rpnval));
- memset(chstatus,0,sizeof(chstatus));
- for(int i=0;i<16;++i)
- memset(chstatus[i],0xff,128*sizeof(uint8_t));
+ ctempo = 0x7A120;
+ ctsn = 4;
+ ctsd = 4;
+ cks = 0;
+ dpt = ctempo * 1000. / divs;
+ tceptr = 0;
+ tcstop = false;
+ tcpaused = 0;
+ finished = 0;
+ mute = solo = 0;
+ for (int i = 0; i < 16; ++i)
+ pbr[i] = 2, pbv[i] = 8192;
+ sendSysEx = true;
+ memset(rpnid, 0xFF, sizeof(rpnid));
+ memset(rpnval, 0xFF, sizeof(rpnval));
+ memset(chstatus, 0, sizeof(chstatus));
+ for (int i = 0; i < 16; ++i)
+ memset(chstatus[i], 0xff, 128 * sizeof(uint8_t));
}
void CMidiPlayer::playerDeinit()
{
- tceptr=0;tcstop=true;tcpaused=0;
- delete midiFile;midiFile=nullptr;
+ tceptr = 0;
+ tcstop = true;
+ tcpaused = 0;
+ delete midiFile;
+ midiFile = nullptr;
}
void CMidiPlayer::playerThread()
{
- prePlayInit();
- playEvents();
+ prePlayInit();
+ playEvents();
}
-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==ecnt)tcstop=true;else tceptr=ep;
- for(int i=0;i<16;++i)
- {
- qmpMidiOutDevice* dest=mididev[mappedoutput[i]].dev;
- for(int j=0;j<120;++j)
- {
- if(~ccstamps[st][i][j])
- {
- dest->basicMessage(0xB0|i,j,ccstamps[st][i][j]);
- chstatus[i][j]=ccstamps[st][i][j];
- }
- }
- dest->basicMessage(0xC0|i,ccstamps[st][i][128],0);
- chstatus[i][128]=ccstamps[st][i][128];
- dest->rpnMessage(i,0,ccstamps[st][i][134]<<7);
- pbr[i]=ccstamps[st][i][134];
- ctempo=ccstamps[st][0][131];dpt=ctempo*1000./divs;
- 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;}
-int CMidiPlayer::getCurrentKeySignature(){return cks;}
-uint32_t CMidiPlayer::getFileNoteCount(){return notes;}
-uint32_t CMidiPlayer::getFileStandard(){return midiFile?midiFile->std:0;}
-const char* CMidiPlayer::getTitle(){return midiFile?midiFile->title:"";}
-const char* CMidiPlayer::getCopyright(){return midiFile?midiFile->copyright:"";}
-double CMidiPlayer::getTempo(){return 60./(ctempo/1e6);}
-uint32_t CMidiPlayer::getTick(){return ct;}
-uint32_t CMidiPlayer::getRawTempo(){return ctempo;}
-uint32_t CMidiPlayer::getDivision(){return divs;}
-uint32_t CMidiPlayer::getMaxTick(){return maxtk;}
-double CMidiPlayer::getPitchBend(int ch){return((int)pbv[ch]-8192)/8192.*pbr[ch];}
-double CMidiPlayer::getPitchBendRaw(int ch,uint32_t *pb,uint32_t *pbr)
-{
- if(pb)*pb=this->pbv[ch];
- if(pbr)*pbr=this->pbr[ch];
-}
-uint32_t CMidiPlayer::getTCpaused(){return tcpaused;}
-void CMidiPlayer::setTCpaused(uint32_t ps){tcpaused=ps;}
-uint32_t CMidiPlayer::isFinished(){return finished;}
-bool CMidiPlayer::stopFlag(){return tcstop;}
-void CMidiPlayer::setResumed(){resumed=true;}
+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 == ecnt)
+ tcstop = true;
+ else tceptr = ep;
+ for (int i = 0; i < 16; ++i)
+ {
+ qmpMidiOutDevice *dest = mididev[mappedoutput[i]].dev;
+ for (int j = 0; j < 120; ++j)
+ {
+ if (~ccstamps[st][i][j])
+ {
+ dest->basicMessage(0xB0 | i, j, ccstamps[st][i][j]);
+ chstatus[i][j] = ccstamps[st][i][j];
+ }
+ }
+ dest->basicMessage(0xC0 | i, ccstamps[st][i][128], 0);
+ chstatus[i][128] = ccstamps[st][i][128];
+ dest->rpnMessage(i, 0, ccstamps[st][i][134] << 7);
+ pbr[i] = ccstamps[st][i][134];
+ ctempo = ccstamps[st][0][131];
+ dpt = ctempo * 1000. / divs;
+ 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;
+}
+int CMidiPlayer::getCurrentKeySignature()
+{
+ return cks;
+}
+uint32_t CMidiPlayer::getFileNoteCount()
+{
+ return notes;
+}
+uint32_t CMidiPlayer::getFileStandard()
+{
+ return midiFile ? midiFile->std : 0;
+}
+const char *CMidiPlayer::getTitle()
+{
+ return midiFile ? midiFile->title : "";
+}
+const char *CMidiPlayer::getCopyright()
+{
+ return midiFile ? midiFile->copyright : "";
+}
+double CMidiPlayer::getTempo()
+{
+ return 60. / (ctempo / 1e6);
+}
+uint32_t CMidiPlayer::getTick()
+{
+ return ct;
+}
+uint32_t CMidiPlayer::getRawTempo()
+{
+ return ctempo;
+}
+uint32_t CMidiPlayer::getDivision()
+{
+ return divs;
+}
+uint32_t CMidiPlayer::getMaxTick()
+{
+ return maxtk;
+}
+double CMidiPlayer::getPitchBend(int ch)
+{
+ return ((int)pbv[ch] - 8192) / 8192.*pbr[ch];
+}
+double CMidiPlayer::getPitchBendRaw(int ch, uint32_t *pb, uint32_t *pbr)
+{
+ if (pb)
+ *pb = this->pbv[ch];
+ if (pbr)
+ *pbr = this->pbr[ch];
+}
+uint32_t CMidiPlayer::getTCpaused()
+{
+ return tcpaused;
+}
+void CMidiPlayer::setTCpaused(uint32_t ps)
+{
+ tcpaused = ps;
+}
+uint32_t CMidiPlayer::isFinished()
+{
+ return finished;
+}
+bool CMidiPlayer::stopFlag()
+{
+ return tcstop;
+}
+void CMidiPlayer::setResumed()
+{
+ resumed = true;
+}
-void CMidiPlayer::setChannelPreset(int ch,int b,int p)
+void CMidiPlayer::setChannelPreset(int ch, int b, int p)
{
- chstatus[ch][128]=p;
- chstatus[ch][0]=b>>7;chstatus[ch][32]=b&0x7F;
- qmpMidiOutDevice* d=mididev[mappedoutput[ch]].dev;
- d->basicMessage(0xB0|ch,0x00,b>>7);
- d->basicMessage(0xB0|ch,0x20,b&0x7F);
- d->basicMessage(0xC0|ch,p,0);
+ chstatus[ch][128] = p;
+ chstatus[ch][0] = b >> 7;
+ chstatus[ch][32] = b & 0x7F;
+ qmpMidiOutDevice *d = mididev[mappedoutput[ch]].dev;
+ d->basicMessage(0xB0 | ch, 0x00, b >> 7);
+ d->basicMessage(0xB0 | ch, 0x20, b & 0x7F);
+ d->basicMessage(0xC0 | ch, p, 0);
}
void CMidiPlayer::dumpFile()
{
- if(!midiFile)return;
- for(CMidiTrack &i:midiFile->tracks)
- for(SEvent &j:i.eventList)
- if(j.str.length())
- printf("type %x #%d @%d p1 %d p2 %d str %s\n",j.type,
- j.iid,j.time,j.p1,j.p2,j.str.c_str());
- else
- printf("type %x #%d @%d p1 %d p2 %d\n",j.type,j.iid,
- j.time,j.p1,j.p2);
+ if (!midiFile)
+ return;
+ for (CMidiTrack &i : midiFile->tracks)
+ for (SEvent &j : i.eventList)
+ if (j.str.length())
+ printf("type %x #%d @%d p1 %d p2 %d str %s\n", j.type,
+ j.iid, j.time, j.p1, j.p2, j.str.c_str());
+ else
+ printf("type %x #%d @%d p1 %d p2 %d\n", j.type, j.iid,
+ j.time, j.p1, j.p2);
}
//16MSB..LSB1
void CMidiPlayer::setBit(uint16_t &n, uint16_t bn, uint16_t b)
-{n^=(((~b)+1)^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);}
+{
+ n ^= (((~b) + 1)^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);
+}
bool CMidiPlayer::getChannelMask(int ch)
-{return((mute>>ch)&1)||(solo&&!((solo>>ch)&1));}
-uint16_t CMidiPlayer::getCC(int ch,int id)
{
- if(chstatus[ch][id]==0xff)
- return getChannelOutputDevice(ch)->getInitialCCValue(uint8_t(id),uint8_t(ch));
- return chstatus[ch][id];
+ return ((mute >> ch) & 1) || (solo && !((solo >> ch) & 1));
+}
+uint16_t CMidiPlayer::getCC(int ch, int id)
+{
+ if (chstatus[ch][id] == 0xff)
+ return getChannelOutputDevice(ch)->getInitialCCValue(uint8_t(id), uint8_t(ch));
+ return chstatus[ch][id];
}
-void CMidiPlayer::setCC(int ch,int id,int val)
+void CMidiPlayer::setCC(int ch, int id, int val)
{
- chstatus[ch][id]=val;
- mididev[mappedoutput[ch]].dev->basicMessage(0xB0|ch,id,val);
+ chstatus[ch][id] = val;
+ mididev[mappedoutput[ch]].dev->basicMessage(0xB0 | ch, id, val);
}
-void CMidiPlayer::registerMidiOutDevice(qmpMidiOutDevice* dev,std::string name)
+void CMidiPlayer::registerMidiOutDevice(qmpMidiOutDevice *dev, std::string name)
{
- SMidiDev d;
- d.dev=dev;d.name=name;
- d.refcnt=0;
- mididev.push_back(d);
+ SMidiDev d;
+ d.dev = dev;
+ d.name = name;
+ d.refcnt = 0;
+ mididev.push_back(d);
}
void CMidiPlayer::unregisterMidiOutDevice(std::string name)
{
- for(auto i=mididev.begin();i!=mididev.end();++i)
- if(i->name==name)
- {
- i->dev->deviceDeinit();
- mididev.erase(i);
- break;
- }
+ for (auto i = mididev.begin(); i != mididev.end(); ++i)
+ if (i->name == name)
+ {
+ i->dev->deviceDeinit();
+ mididev.erase(i);
+ break;
+ }
}
std::vector<std::string> CMidiPlayer::getMidiOutDevices()
{
- std::vector<std::string> ret;
- for(auto &i:mididev)
- ret.push_back(i.name);
- return ret;
+ std::vector<std::string> ret;
+ for (auto &i : mididev)
+ ret.push_back(i.name);
+ return ret;
}
int CMidiPlayer::getChannelOutput(int ch)
{
- return mappedoutput[ch];
-}
-qmpMidiOutDevice* CMidiPlayer::getChannelOutputDevice(int ch)
-{
- return mididev[mappedoutput[ch]].dev;
-}
-void CMidiPlayer::setChannelOutput(int ch,int outid)
-{
- int origoutput=mappedoutput[ch];
- if(origoutput==outid)
- return;
- SMidiDev& dnew=mididev[outid];
- dnew.dev->onMapped(ch,++dnew.refcnt);
- for(int i=0;i<124;++i)
- {
- if(i!=6&&i!=38&&i!=100&&i!=101)//avoid sending RPN/NRPN
- {
- unsigned st=chstatus[ch][i];
- if(!~st)
- st=dnew.dev->getInitialCCValue(i,ch);
- dnew.dev->basicMessage(0xB0|ch,i,chstatus[ch][i]);
- }
- }
- dnew.dev->basicMessage(0xC0|ch,~chstatus[ch][128]?chstatus[ch][128]:dnew.dev->getInitialCCValue(128,ch),0);
- mappedoutput[ch]=outid;
- if(~origoutput)
- {
- SMidiDev& dold=mididev[origoutput];
- dold.dev->onUnmapped(ch,--dold.refcnt);
- }
-}
-const std::chrono::system_clock::time_point* CMidiPlayer::getLastEventTS()
-{return levtt;}
-int CMidiPlayer::setEventHandlerCB(ICallBack *cb,void *userdata)
-{
- for(int i=0;i<16;++i)
- {
- if(eventHandlerCB[i]==cb)return i;
- if(eventHandlerCB[i]==nullptr)
- {
- eventHandlerCB[i]=cb;eventHandlerCBuserdata[i]=userdata;
- return i;
- }
- }
- return -1;
+ return mappedoutput[ch];
+}
+qmpMidiOutDevice *CMidiPlayer::getChannelOutputDevice(int ch)
+{
+ return mididev[mappedoutput[ch]].dev;
+}
+void CMidiPlayer::setChannelOutput(int ch, int outid)
+{
+ int origoutput = mappedoutput[ch];
+ if (origoutput == outid)
+ return;
+ SMidiDev &dnew = mididev[outid];
+ dnew.dev->onMapped(ch, ++dnew.refcnt);
+ for (int i = 0; i < 124; ++i)
+ {
+ if (i != 6 && i != 38 && i != 100 && i != 101) //avoid sending RPN/NRPN
+ {
+ unsigned st = chstatus[ch][i];
+ if (!~st)
+ st = dnew.dev->getInitialCCValue(i, ch);
+ dnew.dev->basicMessage(0xB0 | ch, i, chstatus[ch][i]);
+ }
+ }
+ dnew.dev->basicMessage(0xC0 | ch, ~chstatus[ch][128] ? chstatus[ch][128] : dnew.dev->getInitialCCValue(128, ch), 0);
+ mappedoutput[ch] = outid;
+ if (~origoutput)
+ {
+ SMidiDev &dold = mididev[origoutput];
+ dold.dev->onUnmapped(ch, --dold.refcnt);
+ }
+}
+const std::chrono::system_clock::time_point *CMidiPlayer::getLastEventTS()
+{
+ return levtt;
+}
+int CMidiPlayer::setEventHandlerCB(ICallBack *cb, void *userdata)
+{
+ for (int i = 0; i < 16; ++i)
+ {
+ if (eventHandlerCB[i] == cb)
+ return i;
+ if (eventHandlerCB[i] == nullptr)
+ {
+ eventHandlerCB[i] = cb;
+ eventHandlerCBuserdata[i] = userdata;
+ return i;
+ }
+ }
+ return -1;
}
void CMidiPlayer::unsetEventHandlerCB(int id)
-{eventHandlerCB[id]=nullptr;eventHandlerCBuserdata[id]=nullptr;}
-int CMidiPlayer::setEventReaderCB(ICallBack *cb,void *userdata)
-{
- for(int i=0;i<16;++i)
- {
- if(eventReaderCB[i]==cb)return i;
- if(eventReaderCB[i]==nullptr)
- {
- eventReaderCB[i]=cb;eventReaderCBuserdata[i]=userdata;
- return i;
- }
- }
- return -1;
+{
+ eventHandlerCB[id] = nullptr;
+ eventHandlerCBuserdata[id] = nullptr;
+}
+int CMidiPlayer::setEventReaderCB(ICallBack *cb, void *userdata)
+{
+ for (int i = 0; i < 16; ++i)
+ {
+ if (eventReaderCB[i] == cb)
+ return i;
+ if (eventReaderCB[i] == nullptr)
+ {
+ eventReaderCB[i] = cb;
+ eventReaderCBuserdata[i] = userdata;
+ return i;
+ }
+ }
+ return -1;
}
void CMidiPlayer::unsetEventReaderCB(int id)
-{eventReaderCB[id]=nullptr;eventReaderCBuserdata[id]=nullptr;}
-int CMidiPlayer::setFileReadFinishedCB(ICallBack *cb,void *userdata)
-{
- for(int i=0;i<16;++i)
- {
- if(fileReadFinishCB[i]==cb)return i;
- if(fileReadFinishCB[i]==nullptr)
- {
- fileReadFinishCB[i]=cb;fileReadFinishCBuserdata[i]=userdata;
- return i;
- }
- }
- return -1;
+{
+ eventReaderCB[id] = nullptr;
+ eventReaderCBuserdata[id] = nullptr;
+}
+int CMidiPlayer::setFileReadFinishedCB(ICallBack *cb, void *userdata)
+{
+ for (int i = 0; i < 16; ++i)
+ {
+ if (fileReadFinishCB[i] == cb)
+ return i;
+ if (fileReadFinishCB[i] == nullptr)
+ {
+ fileReadFinishCB[i] = cb;
+ fileReadFinishCBuserdata[i] = userdata;
+ return i;
+ }
+ }
+ return -1;
}
void CMidiPlayer::unsetFileReadFinishedCB(int id)
-{fileReadFinishCB[id]=nullptr;fileReadFinishCBuserdata[id]=nullptr;}
-int CMidiPlayer::registerEventHandler(callback_t cb,void *userdata,bool post)
{
- int ret;
- event_handlers[ret=event_handlers_id++]=std::make_tuple(cb,userdata,post);
- return ret;
+ fileReadFinishCB[id] = nullptr;
+ fileReadFinishCBuserdata[id] = nullptr;
+}
+int CMidiPlayer::registerEventHandler(callback_t cb, void *userdata, bool post)
+{
+ int ret;
+ event_handlers[ret = event_handlers_id++] = std::make_tuple(cb, userdata, post);
+ return ret;
}
void CMidiPlayer::unregisterEventHandler(int id)
{
- event_handlers.find(id)!=event_handlers.end()&&event_handlers.erase(id);
+ event_handlers.find(id) != event_handlers.end() &&event_handlers.erase(id);
}
-int CMidiPlayer::registerEventReadHandler(callback_t cb,void *userdata)
+int CMidiPlayer::registerEventReadHandler(callback_t cb, void *userdata)
{
- int ret;
- event_read_handlers[ret=event_read_handlers_id++]=std::make_pair(cb,userdata);
- return ret;
+ int ret;
+ event_read_handlers[ret = event_read_handlers_id++] = std::make_pair(cb, userdata);
+ return ret;
}
void CMidiPlayer::unregisterEventReadHandler(int id)
{
- event_read_handlers.find(id)!=event_read_handlers.end()&&event_read_handlers.erase(id);
+ event_read_handlers.find(id) != event_read_handlers.end() &&event_read_handlers.erase(id);
}
-int CMidiPlayer::registerFileReadFinishHook(callback_t cb,void *userdata)
+int CMidiPlayer::registerFileReadFinishHook(callback_t cb, void *userdata)
{
- int ret;
- file_read_finish_hooks[ret=file_read_finish_hooks_id++]=std::make_pair(cb,userdata);
- return ret;
+ int ret;
+ file_read_finish_hooks[ret = file_read_finish_hooks_id++] = std::make_pair(cb, userdata);
+ return ret;
}
void CMidiPlayer::unregisterFileReadFinishHook(int id)
{
- file_read_finish_hooks.find(id)!=file_read_finish_hooks.end()&&file_read_finish_hooks.erase(id);
+ file_read_finish_hooks.find(id) != file_read_finish_hooks.end() &&file_read_finish_hooks.erase(id);
+}
+void CMidiPlayer::registerReader(qmpFileReader *reader, std::string name)
+{
+ midiReaders->registerReader(reader, name);
}
-void CMidiPlayer::registerReader(qmpFileReader *reader,std::string name)
-{midiReaders->registerReader(reader,name);}
void CMidiPlayer::unregisterReader(std::string name)
-{midiReaders->unregisterReader(name);}
+{
+ midiReaders->unregisterReader(name);
+}
void CMidiPlayer::callEventReaderCB(SEvent d)
{
- if((d.type&0xF0)==0x90)++notes;
- for(int i=0;i<16;++i)if(eventReaderCB[i])
- eventReaderCB[i]->callBack(&d,eventReaderCBuserdata[i]);
- for(auto i=event_read_handlers.begin();i!=event_read_handlers.end();++i)
- i->second.first(&d,i->second.second);
+ if ((d.type & 0xF0) == 0x90)
+ ++notes;
+ for (int i = 0; i < 16; ++i)
+ if (eventReaderCB[i])
+ eventReaderCB[i]->callBack(&d, eventReaderCBuserdata[i]);
+ for (auto i = event_read_handlers.begin(); i != event_read_handlers.end(); ++i)
+ i->second.first(&d, i->second.second);
}
void CMidiPlayer::discardCurrentEvent()
{
- if(midiReaders->getCurrentReader())
- midiReaders->getCurrentReader()->discardCurrentEvent();
+ if (midiReaders->getCurrentReader())
+ midiReaders->getCurrentReader()->discardCurrentEvent();
}
void CMidiPlayer::commitEventChange(SEvent d)
{
- if(midiReaders->getCurrentReader())
- midiReaders->getCurrentReader()->commitEventChange(d);
+ if (midiReaders->getCurrentReader())
+ midiReaders->getCurrentReader()->commitEventChange(d);
}
-CMidiPlayer* CMidiPlayer::getInstance(){return ref;}
+CMidiPlayer *CMidiPlayer::getInstance()
+{
+ return ref;
+}
diff --git a/core/qmpmidiplay.hpp b/core/qmpmidiplay.hpp
index 471c1db..b6a40d9 100644
--- a/core/qmpmidiplay.hpp
+++ b/core/qmpmidiplay.hpp
@@ -11,169 +11,170 @@
#define QMP_MAIN
#include "qmpcorepublic.hpp"
class CMidiPlayer;
-class CSMFReader:public qmpFileReader
+class CSMFReader : public qmpFileReader
{
- private:
- CMidiFile* ret;
- CMidiTrack* curTrack;
- uint32_t fmt,trk;
- FILE *f;
- bool eventdiscarded;
- uint32_t byteread,curt,curid;
+private:
+ CMidiFile *ret;
+ CMidiTrack *curTrack;
+ uint32_t fmt, trk;
+ FILE *f;
+ bool eventdiscarded;
+ uint32_t byteread, curt, curid;
- void error(int fatal,const char* format,...);
- uint8_t read_u8();
- uint16_t read_u16();
- uint32_t read_u32();
- uint32_t read_varlen();
- int read_event();
- void read_track();
- void read_header();
- uint32_t read_chunk(int is_header);
- public:
- CSMFReader();
- ~CSMFReader();
- CMidiFile* readFile(const char* fn);
- void discardCurrentEvent();
- void commitEventChange(SEvent d);
+ void error(int fatal, const char *format, ...);
+ uint8_t read_u8();
+ uint16_t read_u16();
+ uint32_t read_u32();
+ uint32_t read_varlen();
+ int read_event();
+ void read_track();
+ void read_header();
+ uint32_t read_chunk(int is_header);
+public:
+ CSMFReader();
+ ~CSMFReader();
+ CMidiFile *readFile(const char *fn);
+ void discardCurrentEvent();
+ void commitEventChange(SEvent d);
};
-class CMidiFileReaderCollection{
- private:
- std::vector<std::pair<qmpFileReader*,std::string>> readers;
- qmpFileReader* currentReader;
- public:
- CMidiFileReaderCollection();
- ~CMidiFileReaderCollection();
- void registerReader(qmpFileReader* reader,std::string name);
- void unregisterReader(std::string name);
- CMidiFile* readFile(const char* fn);
- qmpFileReader* getCurrentReader();
+class CMidiFileReaderCollection
+{
+private:
+ std::vector<std::pair<qmpFileReader *, std::string>> readers;
+ qmpFileReader *currentReader;
+public:
+ CMidiFileReaderCollection();
+ ~CMidiFileReaderCollection();
+ void registerReader(qmpFileReader *reader, std::string name);
+ void unregisterReader(std::string name);
+ CMidiFile *readFile(const char *fn);
+ qmpFileReader *getCurrentReader();
};
class CMidiPlayer
{
- friend class CMidiFileReaderCollection;
- private:
- CMidiFileReaderCollection *midiReaders;
- CMidiFile* midiFile;
- std::vector<std::pair<size_t,size_t>> eorder;
- uint32_t stamps[101],notes,ecnt,maxtk;
- 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[16],rpnval[16];
- uint16_t mute,solo;
- double ftime;
- bool sendSysEx,waitvoice;
- uint8_t chstatus[16][130];//0..127: cc 128: pc
- uint32_t ctempo,ctsn,ctsd,divs,cks;
- double dpt;//time per tick
- //raw tempo, timesig num., timesig den., division, keysig
- //thread control
- uint32_t tceptr,tcpaused,ct;
- bool tcstop;
- uint32_t finished,resumed;
- uint32_t pbr[16],pbv[16];
- //playback correction
- uint32_t ttick;
- std::chrono::high_resolution_clock::time_point ttime;
- std::chrono::system_clock::time_point levtt[16];
- struct SMidiDev
- {
- std::string name;
- qmpMidiOutDevice* dev;
- int refcnt;
- };
- std::vector<SMidiDev> mididev;
- int mappedoutput[16];
- ICallBack* eventHandlerCB[16];
- ICallBack* eventReaderCB[16];
- ICallBack* fileReadFinishCB[16];
- void* eventHandlerCBuserdata[16];
- void* eventReaderCBuserdata[16];
- void* fileReadFinishCBuserdata[16];
- std::unordered_map<int,std::tuple<callback_t,void*,bool>> event_handlers;
- std::unordered_map<int,std::pair<callback_t,void*>> event_read_handlers;
- std::unordered_map<int,std::pair<callback_t,void*>> file_read_finish_hooks;
- int event_handlers_id,event_read_handlers_id,file_read_finish_hooks_id;
- static CMidiPlayer* ref;
+ friend class CMidiFileReaderCollection;
+private:
+ CMidiFileReaderCollection *midiReaders;
+ CMidiFile *midiFile;
+ std::vector<std::pair<size_t, size_t>> eorder;
+ uint32_t stamps[101], notes, ecnt, maxtk;
+ 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[16], rpnval[16];
+ uint16_t mute, solo;
+ double ftime;
+ bool sendSysEx, waitvoice;
+ uint8_t chstatus[16][130];//0..127: cc 128: pc
+ uint32_t ctempo, ctsn, ctsd, divs, cks;
+ double dpt;//time per tick
+ //raw tempo, timesig num., timesig den., division, keysig
+ //thread control
+ uint32_t tceptr, tcpaused, ct;
+ bool tcstop;
+ uint32_t finished, resumed;
+ uint32_t pbr[16], pbv[16];
+ //playback correction
+ uint32_t ttick;
+ std::chrono::high_resolution_clock::time_point ttime;
+ std::chrono::system_clock::time_point levtt[16];
+ struct SMidiDev
+ {
+ std::string name;
+ qmpMidiOutDevice *dev;
+ int refcnt;
+ };
+ std::vector<SMidiDev> mididev;
+ int mappedoutput[16];
+ ICallBack *eventHandlerCB[16];
+ ICallBack *eventReaderCB[16];
+ ICallBack *fileReadFinishCB[16];
+ void *eventHandlerCBuserdata[16];
+ void *eventReaderCBuserdata[16];
+ void *fileReadFinishCBuserdata[16];
+ std::unordered_map<int, std::tuple<callback_t, void *, bool>> event_handlers;
+ std::unordered_map<int, std::pair<callback_t, void *>> event_read_handlers;
+ std::unordered_map<int, std::pair<callback_t, void *>> file_read_finish_hooks;
+ int event_handlers_id, event_read_handlers_id, file_read_finish_hooks_id;
+ static CMidiPlayer *ref;
- SEvent *getEvent(uint32_t id);
- void dumpFile();
- void setBit(uint16_t &n,uint16_t bn,uint16_t b);
- bool processEvent(const SEvent *e);
- void processEventStub(const SEvent *e);
- void prePlayInit();
- void playEvents();
- void fileTimer1Pass();
- void fileTimer2Pass();
- public:
- CMidiPlayer();
- ~CMidiPlayer();
- bool playerLoadFile(const char* fn);
- void playerInit();
- void playerDeinit();
- void playerThread();
- void playerPanic(bool reset=false);
+ SEvent *getEvent(uint32_t id);
+ void dumpFile();
+ void setBit(uint16_t &n, uint16_t bn, uint16_t b);
+ bool processEvent(const SEvent *e);
+ void processEventStub(const SEvent *e);
+ void prePlayInit();
+ void playEvents();
+ void fileTimer1Pass();
+ void fileTimer2Pass();
+public:
+ CMidiPlayer();
+ ~CMidiPlayer();
+ bool playerLoadFile(const char *fn);
+ void playerInit();
+ void playerDeinit();
+ void playerThread();
+ void playerPanic(bool reset = false);
- //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();
- bool stopFlag();
- void setResumed();
+ //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();
+ bool stopFlag();
+ void setResumed();
- double getFtime();
- void getCurrentTimeSignature(int *n,int *d);
- int getCurrentKeySignature();
- uint32_t getFileNoteCount();
- uint32_t getFileStandard();
- double getTempo();
- uint32_t getTick();
- uint32_t getRawTempo();
- uint32_t getDivision();
- uint32_t getMaxTick();
- double getPitchBend(int ch);
- double getPitchBendRaw(int ch,uint32_t *pb,uint32_t *pbr);
- const char* getTitle();
- const char* getCopyright();
+ double getFtime();
+ void getCurrentTimeSignature(int *n, int *d);
+ int getCurrentKeySignature();
+ uint32_t getFileNoteCount();
+ uint32_t getFileStandard();
+ double getTempo();
+ uint32_t getTick();
+ uint32_t getRawTempo();
+ uint32_t getDivision();
+ uint32_t getMaxTick();
+ double getPitchBend(int ch);
+ double getPitchBendRaw(int ch, uint32_t *pb, uint32_t *pbr);
+ const char *getTitle();
+ const char *getCopyright();
- void sendSysX(bool send);
+ void sendSysX(bool send);
- void setChannelPreset(int ch,int b,int p);
- void setMute(int ch,bool m);
- void setSolo(int ch,bool s);
- bool getChannelMask(int ch);
- uint16_t getCC(int ch,int id);
- void setCC(int ch,int id,int val);
+ void setChannelPreset(int ch, int b, int p);
+ void setMute(int ch, bool m);
+ void setSolo(int ch, bool s);
+ bool getChannelMask(int ch);
+ uint16_t getCC(int ch, int id);
+ void setCC(int ch, int id, int val);
- void registerMidiOutDevice(qmpMidiOutDevice* dev,std::string name);
- void unregisterMidiOutDevice(std::string name);
- std::vector<std::string> getMidiOutDevices();
- int getChannelOutput(int ch);
- qmpMidiOutDevice* getChannelOutputDevice(int ch);
- void setChannelOutput(int ch,int outid);
- const std::chrono::system_clock::time_point* getLastEventTS();
- int setEventHandlerCB(ICallBack *cb,void *userdata);
- void unsetEventHandlerCB(int id);
- int setEventReaderCB(ICallBack *cb,void *userdata);
- void unsetEventReaderCB(int id);
- int setFileReadFinishedCB(ICallBack *cb,void *userdata);
- void unsetFileReadFinishedCB(int id);
- int registerEventHandler(callback_t cb,void *userdata,bool post);
- void unregisterEventHandler(int id);
- int registerEventReadHandler(callback_t cb,void *userdata);
- void unregisterEventReadHandler(int id);
- int registerFileReadFinishHook(callback_t cb,void *userdata);
- void unregisterFileReadFinishHook(int id);
- void registerReader(qmpFileReader* reader,std::string name);
- void unregisterReader(std::string name);
- void callEventReaderCB(SEvent d);
+ void registerMidiOutDevice(qmpMidiOutDevice *dev, std::string name);
+ void unregisterMidiOutDevice(std::string name);
+ std::vector<std::string> getMidiOutDevices();
+ int getChannelOutput(int ch);
+ qmpMidiOutDevice *getChannelOutputDevice(int ch);
+ void setChannelOutput(int ch, int outid);
+ const std::chrono::system_clock::time_point *getLastEventTS();
+ int setEventHandlerCB(ICallBack *cb, void *userdata);
+ void unsetEventHandlerCB(int id);
+ int setEventReaderCB(ICallBack *cb, void *userdata);
+ void unsetEventReaderCB(int id);
+ int setFileReadFinishedCB(ICallBack *cb, void *userdata);
+ void unsetFileReadFinishedCB(int id);
+ int registerEventHandler(callback_t cb, void *userdata, bool post);
+ void unregisterEventHandler(int id);
+ int registerEventReadHandler(callback_t cb, void *userdata);
+ void unregisterEventReadHandler(int id);
+ int registerFileReadFinishHook(callback_t cb, void *userdata);
+ void unregisterFileReadFinishHook(int id);
+ void registerReader(qmpFileReader *reader, std::string name);
+ void unregisterReader(std::string name);
+ void callEventReaderCB(SEvent d);
- void discardCurrentEvent();
- void commitEventChange(SEvent d);
+ void discardCurrentEvent();
+ void commitEventChange(SEvent d);
- static CMidiPlayer* getInstance();
+ static CMidiPlayer *getInstance();
};
#endif
diff --git a/core/qmpmidiread.cpp b/core/qmpmidiread.cpp
index c7d11f2..b3d4efe 100644
--- a/core/qmpmidiread.cpp
+++ b/core/qmpmidiread.cpp
@@ -7,248 +7,315 @@
#include <cstdint>
#include <cstdarg>
#include <algorithm>
+#include <stdexcept>
#include "qmpmidiplay.hpp"
-static const char* GM1SysX="\xF0\x7E\x7F\x09\x01\xF7";
-static const char* GM2SysX="\xF0\x7E\x7F\x09\x03\xF7";
-static const char* GSSysEx="\xF0\x41\x10\x42\x12\x40\x00\x7F\x00\x41\xF7";
-static const char* XGSysEx="\xF0\x43\x10\x4C\x00\x00\x7E\x00\xF7";
+static const char *GM1SysX = "\xF0\x7E\x7F\x09\x01\xF7";
+static const char *GM2SysX = "\xF0\x7E\x7F\x09\x03\xF7";
+static const char *GSSysEx = "\xF0\x41\x10\x42\x12\x40\x00\x7F\x00\x41\xF7";
+static 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,...)
+void CSMFReader::error(int fatal, const char *format, ...)
{
- va_list ap;char buf[1024],bufr[1024];
- va_start(ap,format);vsnprintf(buf,1024,format,ap);va_end(ap);
- snprintf(bufr,1024,"%s at %#lx",buf,ftell(f));
- if(fatal)throw std::runtime_error(bufr);
- else fprintf(stderr,"CSMFReader W: %s.\n",bufr);
+ va_list ap;
+ char buf[1024], bufr[1024];
+ va_start(ap, format);
+ vsnprintf(buf, 1024, format, ap);
+ va_end(ap);
+ snprintf(bufr, 1024, "%s at %#lx", buf, ftell(f));
+ if (fatal)
+ throw std::runtime_error(bufr);
+ else fprintf(stderr, "CSMFReader W: %s.\n", bufr);
}
uint8_t CSMFReader::read_u8()
{
- uint8_t ret=0;
- int t=fgetc(f);
- if(!~t)error(1,"Unexpected EOF");
- ret=(uint8_t)t;
- return ret;
+ uint8_t ret = 0;
+ int t = fgetc(f);
+ if (!~t)
+ error(1, "Unexpected EOF");
+ ret = (uint8_t)t;
+ return ret;
}
uint16_t CSMFReader::read_u16()
{
- uint16_t ret=0;
- size_t sz=fread(&ret,2,1,f);
- if(sz<1)error(1,"Unexpected EOF");
+ uint16_t ret = 0;
+ size_t sz = fread(&ret, 2, 1, f);
+ if (sz < 1)
+ error(1, "Unexpected EOF");
#if defined(_MSC_VER)&&defined(_WIN32)
- ret=_byteswap_ushort(ret);
+ ret = _byteswap_ushort(ret);
#elif __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
- ret=__builtin_bswap16(ret);
+ ret = __builtin_bswap16(ret);
#endif
- return ret;
+ return ret;
}
uint32_t CSMFReader::read_u32()
{
- uint32_t ret=0;
- size_t sz=fread(&ret,4,1,f);
- if(sz<1)error(1,"Unexpected EOF");
+ uint32_t ret = 0;
+ size_t sz = fread(&ret, 4, 1, f);
+ if (sz < 1)
+ error(1, "Unexpected EOF");
#if defined(_MSC_VER)&&defined(_WIN32)
- ret=_byteswap_ulong(ret);
+ ret = _byteswap_ulong(ret);
#elif __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
- ret=__builtin_bswap32(ret);
+ ret = __builtin_bswap32(ret);
#endif
- return ret;
+ return ret;
}
uint32_t CSMFReader::read_varlen()
{
- uint32_t ret=0,c=0;
- int t;
- do
- {
- t=fgetc(f);
- if(!~t)error(1,"Unexpected EOF");
- if(++c>4)error(1,"Variable length type overflow");
- ret<<=7;ret|=(t&0x7F);
- }while(t&0x80);
- return ret;
+ uint32_t ret = 0, c = 0;
+ int t;
+ do
+ {
+ t = fgetc(f);
+ if (!~t)
+ error(1, "Unexpected EOF");
+ if (++c > 4)
+ error(1, "Variable length type overflow");
+ ret <<= 7;
+ ret |= (t & 0x7F);
+ } while (t & 0x80);
+ return ret;
}
int CSMFReader::read_event()//returns 0 if End of Track encountered
{
- uint32_t delta=read_varlen();curt+=delta;
- uint8_t type=read_u8();uint32_t p1,p2;
- static uint8_t lasttype;eventdiscarded=false;
- if(!(type&0x80)){fseek(f,-1,SEEK_CUR);type=lasttype;}
- switch(type&0xF0)
- {
- case 0x80://Note Off
- case 0x90://Note On
- case 0xA0://Note Aftertouch
- case 0xB0://Controller Change
- case 0xE0://Pitch wheel
- p1=read_u8();p2=read_u8();
- curTrack->appendEvent(SEvent(curid,curt,type,p1,p2));
- break;
- case 0xC0://Patch Change
- case 0xD0://Channel Aftertouch
- p1=read_u8();
- curTrack->appendEvent(SEvent(curid,curt,type,p1,0));
- break;
- case 0xF0:
- if((type&0x0F)==0x0F)//Meta Event
- {
- uint8_t metatype=read_u8();
- uint32_t len=read_varlen();char* str=nullptr;
- if(len<=1024&&len>0)str=new char[len+8];
- if(str)fread(str,1,len,f);else fseek(f,len,SEEK_CUR);
- std::string sstr;
- if(str){str[len]='\0';sstr=std::string(str,len);}
- switch(metatype)
- {
- case 0x00://Sequence Number
- assert(len==2||len==0);
- break;
- case 0x20://Channel Prefix
- assert(len==1);
- break;
- case 0x2F://End of Track
- assert(len==0);
- return 0;
- case 0x51://Set Tempo
- assert(len==3);
- curTrack->appendEvent(SEvent(curid,curt,type,metatype,0,sstr));
- break;
- case 0x54://SMTPE offset, not handled.
- assert(len==5);
- break;
- case 0x58://Time signature
- assert(len==4);
- curTrack->appendEvent(SEvent(curid,curt,type,metatype,0,sstr));
- break;
- case 0x59://Key signature
- assert(len==2);
- curTrack->appendEvent(SEvent(curid,curt,type,metatype,0,sstr));
- break;
- case 0x01:case 0x02:case 0x03:
- case 0x04:case 0x05:case 0x06:
- case 0x07:case 0x7F:default://text-like meta
- {
- curTrack->appendEvent(SEvent(curid,curt,type,metatype,0,sstr));
- if(str&&metatype==0x03&&!ret->title)
- {
- ret->title=new char[len+8];
- strcpy(ret->title,str);
- }
- if(str&&metatype==0x02&&!ret->copyright)
- {
- ret->copyright=new char[len+8];
- strcpy(ret->copyright,str);
- }
- }
- }
- if(str)delete[] str;
- }
- else if((type&0x0F)==0x00||(type&0x0F)==0x07)//SysEx
- {
- uint32_t len=read_varlen();char* str=nullptr;
- str=new char[len+8];
- if((type&0x0F)==0x00)
- {
- str[0]=char(0xF0);++len;
- size_t sz=fread(str+1,1,len-1,f);
- if(sz<len-1)error(1,"Unexpected EOF");
- }
- else
- {
- size_t sz=fread(str,1,len,f);
- if(sz<len)error(1,"Unexpected EOF");
- }
- curTrack->appendEvent(SEvent(curid,curt,type,0,0,std::string(str,len)));
- if(!strcmp(str,GM1SysX))ret->std=1;
- if(!strcmp(str,GM2SysX))ret->std=2;
- if(!strcmp(str,GSSysEx))ret->std=3;
- if(!strcmp(str,XGSysEx))ret->std=4;
- delete[] str;
- }
- else error(0,"Unknown event type %#x",type);
- break;
- default:
- error(0,"Unknown event type %#x",type);
- }
- lasttype=type;++curid;
- if(curTrack->eventList.size())
- {
- SEvent& le=curTrack->eventList.back();
- CMidiPlayer::getInstance()->callEventReaderCB(le);
- }
- return 1;
+ uint32_t delta = read_varlen();
+ curt += delta;
+ uint8_t type = read_u8();
+ uint32_t p1, p2;
+ static uint8_t lasttype;
+ eventdiscarded = false;
+ if (!(type & 0x80))
+ {
+ fseek(f, -1, SEEK_CUR);
+ type = lasttype;
+ }
+ switch (type & 0xF0)
+ {
+ case 0x80://Note Off
+ case 0x90://Note On
+ case 0xA0://Note Aftertouch
+ case 0xB0://Controller Change
+ case 0xE0://Pitch wheel
+ p1 = read_u8();
+ p2 = read_u8();
+ curTrack->appendEvent(SEvent(curid, curt, type, p1, p2));
+ break;
+ case 0xC0://Patch Change
+ case 0xD0://Channel Aftertouch
+ p1 = read_u8();
+ curTrack->appendEvent(SEvent(curid, curt, type, p1, 0));
+ break;
+ case 0xF0:
+ if ((type & 0x0F) == 0x0F) //Meta Event
+ {
+ uint8_t metatype = read_u8();
+ uint32_t len = read_varlen();
+ char *str = nullptr;
+ if (len <= 1024 && len > 0)
+ str = new char[len + 8];
+ if (str)
+ fread(str, 1, len, f);
+ else
+ fseek(f, len, SEEK_CUR);
+ std::string sstr;
+ if (str)
+ {
+ str[len] = '\0';
+ sstr = std::string(str, len);
+ }
+ switch (metatype)
+ {
+ case 0x00://Sequence Number
+ assert(len == 2 || len == 0);
+ break;
+ case 0x20://Channel Prefix
+ assert(len == 1);
+ break;
+ case 0x2F://End of Track
+ assert(len == 0);
+ return 0;
+ case 0x51://Set Tempo
+ assert(len == 3);
+ curTrack->appendEvent(SEvent(curid, curt, type, metatype, 0, sstr));
+ break;
+ case 0x54://SMTPE offset, not handled.
+ assert(len == 5);
+ break;
+ case 0x58://Time signature
+ assert(len == 4);
+ curTrack->appendEvent(SEvent(curid, curt, type, metatype, 0, sstr));
+ break;
+ case 0x59://Key signature
+ assert(len == 2);
+ curTrack->appendEvent(SEvent(curid, curt, type, metatype, 0, sstr));
+ break;
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x7F:
+ default://text-like meta
+ {
+ curTrack->appendEvent(SEvent(curid, curt, type, metatype, 0, sstr));
+ if (str && metatype == 0x03 && !ret->title)
+ {
+ ret->title = new char[len + 8];
+ strcpy(ret->title, str);
+ }
+ if (str && metatype == 0x02 && !ret->copyright)
+ {
+ ret->copyright = new char[len + 8];
+ strcpy(ret->copyright, str);
+ }
+ }
+ }
+ if (str)
+ delete[] str;
+ }
+ else if ((type & 0x0F) == 0x00 || (type & 0x0F) == 0x07) //SysEx
+ {
+ uint32_t len = read_varlen();
+ char *str = nullptr;
+ str = new char[len + 8];
+ if ((type & 0x0F) == 0x00)
+ {
+ str[0] = char(0xF0);
+ ++len;
+ size_t sz = fread(str + 1, 1, len - 1, f);
+ if (sz < len - 1)
+ error(1, "Unexpected EOF");
+ }
+ else
+ {
+ size_t sz = fread(str, 1, len, f);
+ if (sz < len)
+ error(1, "Unexpected EOF");
+ }
+ curTrack->appendEvent(SEvent(curid, curt, type, 0, 0, std::string(str, len)));
+ if (!strcmp(str, GM1SysX))
+ ret->std = 1;
+ if (!strcmp(str, GM2SysX))
+ ret->std = 2;
+ if (!strcmp(str, GSSysEx))
+ ret->std = 3;
+ if (!strcmp(str, XGSysEx))
+ ret->std = 4;
+ delete[] str;
+ }
+ else
+ error(0, "Unknown event type %#x", type);
+ break;
+ default:
+ error(0, "Unknown event type %#x", type);
+ }
+ lasttype = type;
+ ++curid;
+ if (curTrack->eventList.size())
+ {
+ SEvent &le = curTrack->eventList.back();
+ CMidiPlayer::getInstance()->callEventReaderCB(le);
+ }
+ return 1;
}
void CSMFReader::read_track()
{
- ret->tracks.push_back(CMidiTrack());
- curTrack=&ret->tracks.back();
- uint32_t chnklen=read_u32();byteread=ftell(f);curt=0;curid=0;
- while(read_event());
- byteread=ftell(f)-byteread;
- if(byteread<chnklen)
- {
- error(0,"Extra bytes after EOT event");
- for(;byteread<chnklen;++byteread)fgetc(f);
- }
- if(byteread>chnklen)
- error(1,"Read past end of track");
+ ret->tracks.push_back(CMidiTrack());
+ curTrack = &ret->tracks.back();
+ uint32_t chnklen = read_u32();
+ byteread = ftell(f);
+ curt = 0;
+ curid = 0;
+ while (read_event());
+ byteread = ftell(f) - byteread;
+ if (byteread < chnklen)
+ {
+ error(0, "Extra bytes after EOT event");
+ for (; byteread < chnklen; ++byteread)
+ fgetc(f);
+ }
+ if (byteread > chnklen)
+ error(1, "Read past end of track");
}
void CSMFReader::read_header()
{
- uint32_t chnklen=read_u32();byteread=ftell(f);
- if(chnklen<6)error(1,"Header chunk too short");
- if(chnklen>6)error(0,"Header chunk length longer than expected. Ignoring extra bytes");
- fmt=read_u16();trk=read_u16();ret->divs=read_u16();
- if(ret->divs&0x8000)error(1,"SMTPE format is not supported");
- for(byteread=ftell(f)-byteread;byteread<chnklen;++byteread){fgetc(f);}
+ uint32_t chnklen = read_u32();
+ byteread = ftell(f);
+ if (chnklen < 6)
+ error(1, "Header chunk too short");
+ if (chnklen > 6)
+ error(0, "Header chunk length longer than expected. Ignoring extra bytes");
+ fmt = read_u16();
+ trk = read_u16();
+ ret->divs = read_u16();
+ if (ret->divs & 0x8000)
+ error(1, "SMTPE format is not supported");
+ for (byteread = ftell(f) - byteread; byteread < chnklen; ++byteread)
+ fgetc(f);
}
uint32_t CSMFReader::read_chunk(int is_header)
{
- char hdr[6];
- fread(hdr,1,4,f);
- if(feof(f))error(1,"Unexpected EOF");
- if(is_header)
- {
- if(!strncmp(hdr,"RIFF",4))
- {
- fseek(f,4,SEEK_CUR);
- fread(hdr,1,4,f);
- if(strncmp(hdr,"RMID",4)){error(1,"Wrong file type in RIFF container");}
- fseek(f,8,SEEK_CUR);
- fread(hdr,1,4,f);
- }
- if(strncmp(hdr,"MThd",4)){error(1,"Wrong MIDI header.");}
- else return read_header(),0;
- }
- else
- if(strncmp(hdr,"MTrk",4))
- {
- error(0,"Wrong track chunk header. Ignoring the entire chunk.");
- uint32_t chnklen=read_u32();fseek(f,chnklen,SEEK_CUR);return 0;
- }
- else return read_track(),1;
- return 0;
+ char hdr[6];
+ fread(hdr, 1, 4, f);
+ if (feof(f))
+ error(1, "Unexpected EOF");
+ if (is_header)
+ {
+ if (!strncmp(hdr, "RIFF", 4))
+ {
+ fseek(f, 4, SEEK_CUR);
+ fread(hdr, 1, 4, f);
+ if (strncmp(hdr, "RMID", 4))
+ error(1, "Wrong file type in RIFF container");
+ fseek(f, 8, SEEK_CUR);
+ fread(hdr, 1, 4, f);
+ }
+ if (strncmp(hdr, "MThd", 4))
+ error(1, "Wrong MIDI header.");
+ else return read_header(), 0;
+ }
+ else if (strncmp(hdr, "MTrk", 4))
+ {
+ error(0, "Wrong track chunk header. Ignoring the entire chunk.");
+ uint32_t chnklen = read_u32();
+ fseek(f, chnklen, SEEK_CUR);
+ return 0;
+ }
+ else
+ return read_track(), 1;
+ return 0;
}
CSMFReader::CSMFReader()
{
- f=nullptr;
+ f = nullptr;
}
-CMidiFile* CSMFReader::readFile(const char* fn)
+CMidiFile *CSMFReader::readFile(const char *fn)
{
- ret=new CMidiFile;
- ret->title=ret->copyright=nullptr;ret->std=0;ret->valid=1;
- try
- {
- if(!(f=fopen(fn,"rb")))
- throw std::runtime_error("Can't open file");
- read_chunk(1);
- for(uint32_t i=0;i<trk;i+=read_chunk(0));
- fclose(f);f=nullptr;
- }
- catch(std::runtime_error& e)
- {
- fprintf(stderr,"CSMFReader E: %s is not a supported file. Cause: %s.\n",fn,e.what());
- ret->valid=0;if(f)fclose(f);f=nullptr;
- }
- return ret;
+ ret = new CMidiFile;
+ ret->title = ret->copyright = nullptr;
+ ret->std = 0;
+ ret->valid = 1;
+ try
+ {
+ if (!(f = fopen(fn, "rb")))
+ throw std::runtime_error("Can't open file");
+ read_chunk(1);
+ for (uint32_t i = 0; i < trk; i += read_chunk(0));
+ fclose(f);
+ f = nullptr;
+ }
+ catch (std::runtime_error &e)
+ {
+ fprintf(stderr, "CSMFReader E: %s is not a supported file. Cause: %s.\n", fn, e.what());
+ ret->valid = 0;
+ if (f)
+ fclose(f);
+ f = nullptr;
+ }
+ return ret;
}
CSMFReader::~CSMFReader()
{
@@ -256,54 +323,65 @@ CSMFReader::~CSMFReader()
void CSMFReader::discardCurrentEvent()
{
- if(eventdiscarded)return;eventdiscarded=true;
- curTrack->eventList.pop_back();
+ if (eventdiscarded)
+ return;
+ eventdiscarded = true;
+ curTrack->eventList.pop_back();
}
void CSMFReader::commitEventChange(SEvent d)
{
- curTrack->eventList.back().time=d.time;
- curTrack->eventList.back().type=d.type;
- curTrack->eventList.back().p1=d.p1;
- curTrack->eventList.back().p2=d.p2;
+ curTrack->eventList.back().time = d.time;
+ curTrack->eventList.back().type = d.type;
+ curTrack->eventList.back().p1 = d.p1;
+ curTrack->eventList.back().p2 = d.p2;
}
CMidiFileReaderCollection::CMidiFileReaderCollection()
{
- readers.clear();currentReader=nullptr;
- registerReader(new CSMFReader(),"Default SMF Reader");
+ readers.clear();
+ currentReader = nullptr;
+ registerReader(new CSMFReader(), "Default SMF Reader");
}
CMidiFileReaderCollection::~CMidiFileReaderCollection()
{
- delete readers[0].first;
+ delete readers[0].first;
}
-void CMidiFileReaderCollection::registerReader(qmpFileReader* reader,std::string name)
+void CMidiFileReaderCollection::registerReader(qmpFileReader *reader, std::string name)
{
- for(unsigned i=0;i<readers.size();++i)
- if(readers[i].second==name)return;
- readers.push_back(std::make_pair(reader,name));
+ for (unsigned i = 0; i < readers.size(); ++i)
+ if (readers[i].second == name)
+ return;
+ readers.push_back(std::make_pair(reader, name));
}
void CMidiFileReaderCollection::unregisterReader(std::string name)
{
- for(auto i=readers.begin();i!=readers.end();++i)
- if(i->second==name)
- {
- readers.erase(i);
- return;
- }
+ for (auto i = readers.begin(); i != readers.end(); ++i)
+ if (i->second == name)
+ {
+ readers.erase(i);
+ return;
+ }
}
-CMidiFile* CMidiFileReaderCollection::readFile(const char* fn)
+CMidiFile *CMidiFileReaderCollection::readFile(const char *fn)
{
- CMidiFile *file=nullptr;
- for(unsigned i=0;i<readers.size();++i)
- {
- currentReader=readers[i].first;
- CMidiPlayer::getInstance()->notes=0;
- CMidiFile* t=readers[i].first->readFile(fn);
- if(t->valid){file=t;break;}
- else delete t;
- }
- currentReader=nullptr;
- return file;
+ CMidiFile *file = nullptr;
+ for (unsigned i = 0; i < readers.size(); ++i)
+ {
+ currentReader = readers[i].first;
+ CMidiPlayer::getInstance()->notes = 0;
+ CMidiFile *t = readers[i].first->readFile(fn);
+ if (t->valid)
+ {
+ file = t;
+ break;
+ }
+ else
+ delete t;
+ }
+ currentReader = nullptr;
+ return file;
+}
+qmpFileReader *CMidiFileReaderCollection::getCurrentReader()
+{
+ return currentReader;
}
-qmpFileReader* CMidiFileReaderCollection::getCurrentReader()
-{return currentReader;}
diff --git a/include/qmpcorepublic.hpp b/include/qmpcorepublic.hpp
index c6caed5..8376af8 100644
--- a/include/qmpcorepublic.hpp
+++ b/include/qmpcorepublic.hpp
@@ -13,193 +13,221 @@
//MIDI Event structure
struct SEvent
{
- uint32_t iid,time;
- uint8_t type,p1,p2;
- uint8_t flags;
- std::string str;
- SEvent(){time=iid=0;type=p1=p2=0;flags=0;str="";}
- SEvent(uint32_t _iid,uint32_t _t,uint8_t _tp,uint8_t _p1,uint8_t _p2,const char* s=nullptr)
- {
- iid=_iid;time=_t;type=_tp;
- p1=_p1;p2=_p2;flags=0;
- if(s)str=std::string(s);else str="";
- }
- SEvent(uint32_t _iid,uint32_t _t,uint8_t _tp,uint8_t _p1,uint8_t _p2,std::string s):
- iid(_iid),time(_t),type(_tp),p1(_p1),p2(_p2),str(s){}
- friend bool operator <(const SEvent& a,const SEvent& b){return a.time-b.time?a.time<b.time:a.iid<b.iid;}
+ uint32_t iid, time;
+ uint8_t type, p1, p2;
+ uint8_t flags;
+ std::string str;
+ SEvent()
+ {
+ time = iid = 0;
+ type = p1 = p2 = 0;
+ flags = 0;
+ str = "";
+ }
+ SEvent(uint32_t _iid, uint32_t _t, uint8_t _tp, uint8_t _p1, uint8_t _p2, const char *s = nullptr)
+ {
+ iid = _iid;
+ time = _t;
+ type = _tp;
+ p1 = _p1;
+ p2 = _p2;
+ flags = 0;
+ if (s)str = std::string(s);
+ else str = "";
+ }
+ SEvent(uint32_t _iid, uint32_t _t, uint8_t _tp, uint8_t _p1, uint8_t _p2, std::string s):
+ iid(_iid), time(_t), type(_tp), p1(_p1), p2(_p2), str(s) {}
+ friend bool operator <(const SEvent &a, const SEvent &b)
+ {
+ return a.time - b.time ? a.time < b.time : a.iid < b.iid;
+ }
};
//MIDI Track class
-class CMidiTrack{
- public:
- std::vector<SEvent> eventList;
- void appendEvent(SEvent e){eventList.push_back(e);}
- SEvent& operator[](size_t sub){return eventList[sub];}
+class CMidiTrack
+{
+public:
+ std::vector<SEvent> eventList;
+ void appendEvent(SEvent e)
+ {
+ eventList.push_back(e);
+ }
+ SEvent &operator[](size_t sub)
+ {
+ return eventList[sub];
+ }
};
//MIDI File class
-class CMidiFile{
- public:
- bool valid;
- char *title,*copyright;
- std::vector<CMidiTrack> tracks;
- uint32_t std,divs;
- ~CMidiFile()
- {
- if(title)delete[] title;
- if(copyright)delete[] copyright;
- }
+class CMidiFile
+{
+public:
+ bool valid;
+ char *title, *copyright;
+ std::vector<CMidiTrack> tracks;
+ uint32_t std, divs;
+ ~CMidiFile()
+ {
+ if (title)delete[] title;
+ if (copyright)delete[] copyright;
+ }
};
//Generic callback function that can be used for hooking the core.
//"userdata" is set when you register the callback function.
//Deprecated. Removing in 0.9.x.
class ICallBack
{
- public:
- ICallBack(){}
- virtual void callBack(const void* callerdata,void* userdata)=0;
- virtual ~ICallBack(){}
+public:
+ ICallBack() {}
+ virtual void callBack(const void *callerdata, void *userdata) = 0;
+ virtual ~ICallBack() {}
};
//alternative callback function type
-typedef std::function<void(const void*,void*)> callback_t;
+typedef std::function<void(const void *, void *)> callback_t;
//MIDI file reader interface. Use this to implement your file importer.
class qmpFileReader
{
- public:
- qmpFileReader(){}
- virtual ~qmpFileReader(){}
- virtual CMidiFile* readFile(const char* fn)=0;
- virtual void discardCurrentEvent()=0;
- virtual void commitEventChange(SEvent d)=0;
+public:
+ qmpFileReader() {}
+ virtual ~qmpFileReader() {}
+ virtual CMidiFile *readFile(const char *fn) = 0;
+ virtual void discardCurrentEvent() = 0;
+ virtual void commitEventChange(SEvent d) = 0;
};
//Functionality interface.
class qmpFuncBaseIntf
{
- public:
- qmpFuncBaseIntf(){}
- virtual void show()=0;
- virtual void close()=0;
- virtual ~qmpFuncBaseIntf(){}
+public:
+ qmpFuncBaseIntf() {}
+ virtual void show() = 0;
+ virtual void close() = 0;
+ virtual ~qmpFuncBaseIntf() {}
};
//Midi mapper plugin interface.
class qmpMidiOutDevice
{
- public:
- qmpMidiOutDevice(){}
- virtual void deviceInit()=0;
- virtual void deviceDeinit()=0;
- virtual void basicMessage(uint8_t type,uint8_t p1,uint8_t p2)=0;
- virtual void extendedMessage(uint32_t length,const char* data)=0;
- virtual void rpnMessage(uint8_t ch,uint16_t type,uint16_t val)=0;
- virtual void nrpnMessage(uint8_t ch,uint16_t type,uint16_t val)=0;
- virtual void panic(uint8_t ch)=0;
- virtual void reset(uint8_t ch)=0;
- virtual void onMapped(uint8_t ch,int refcnt)=0;
- virtual void onUnmapped(uint8_t ch,int refcnt)=0;
- virtual std::vector<std::pair<uint16_t,std::string>> getBankList()=0;
- virtual std::vector<std::pair<uint8_t,std::string>> getPresets(uint16_t bank)=0;
- virtual std::string getPresetName(uint16_t bank,uint8_t preset)=0;
- virtual bool getChannelPreset(int ch,uint16_t *bank,uint8_t *preset,std::string &presetname)=0;
- virtual uint8_t getInitialCCValue(uint8_t cc,uint8_t ch)=0;
- virtual ~qmpMidiOutDevice(){}
+public:
+ qmpMidiOutDevice() {}
+ virtual void deviceInit() = 0;
+ virtual void deviceDeinit() = 0;
+ virtual void basicMessage(uint8_t type, uint8_t p1, uint8_t p2) = 0;
+ virtual void extendedMessage(uint32_t length, const char *data) = 0;
+ virtual void rpnMessage(uint8_t ch, uint16_t type, uint16_t val) = 0;
+ virtual void nrpnMessage(uint8_t ch, uint16_t type, uint16_t val) = 0;
+ virtual void panic(uint8_t ch) = 0;
+ virtual void reset(uint8_t ch) = 0;
+ virtual void onMapped(uint8_t ch, int refcnt) = 0;
+ virtual void onUnmapped(uint8_t ch, int refcnt) = 0;
+ virtual std::vector<std::pair<uint16_t, std::string>> getBankList() = 0;
+ virtual std::vector<std::pair<uint8_t, std::string>> getPresets(uint16_t bank) = 0;
+ virtual std::string getPresetName(uint16_t bank, uint8_t preset) = 0;
+ virtual bool getChannelPreset(int ch, uint16_t *bank, uint8_t *preset, std::string &presetname) = 0;
+ virtual uint8_t getInitialCCValue(uint8_t cc, uint8_t ch) = 0;
+ virtual ~qmpMidiOutDevice() {}
};
//Main plugin interface.
class qmpPluginIntf
{
- public:
- qmpPluginIntf(){}
- virtual ~qmpPluginIntf(){}
- virtual void init(){}
- virtual void deinit(){}
- virtual const char* pluginGetName(){return "";}
- virtual const char* pluginGetVersion(){return "";}
+public:
+ qmpPluginIntf() {}
+ virtual ~qmpPluginIntf() {}
+ virtual void init() {}
+ virtual void deinit() {}
+ virtual const char *pluginGetName()
+ {
+ return "";
+ }
+ virtual const char *pluginGetVersion()
+ {
+ return "";
+ }
};
#ifdef QMP_MAIN
-extern "C"{
+extern "C" {
#endif
//The API class provided by the core. Plugins use this class to interact with
//the core.
-class qmpPluginAPI
-{
- public:
- virtual ~qmpPluginAPI(){}
- virtual uint32_t getDivision()=0;
- virtual uint32_t getRawTempo()=0;
- virtual double getRealTempo()=0;
- virtual uint32_t getTimeSig()=0;
- virtual int getKeySig()=0;
- virtual uint32_t getNoteCount()=0;
- virtual uint32_t getMaxTick()=0;
- virtual uint32_t getCurrentPolyphone()=0;
- virtual uint32_t getMaxPolyphone()=0;
- virtual uint32_t getCurrentTimeStamp()=0;
- virtual uint32_t getCurrentPlaybackPercentage()=0;
- virtual int getChannelCC(int ch,int cc)=0;
- virtual int getChannelPreset(int ch)=0;
- virtual void playerSeek(uint32_t percentage)=0;
- virtual double getPitchBend(int ch)=0;
- virtual void getPitchBendRaw(int ch,uint32_t *pb,uint32_t *pbr)=0;
- virtual bool getChannelMask(int ch)=0;
- virtual std::string getTitle()=0;
- virtual std::wstring getWTitle()=0;
- virtual std::string getChannelPresetString(int ch)=0;
- virtual bool isDarkTheme()=0;
- virtual void* getMainWindow()=0;
+ class qmpPluginAPI
+ {
+ public:
+ virtual ~qmpPluginAPI() {}
+ virtual uint32_t getDivision() = 0;
+ virtual uint32_t getRawTempo() = 0;
+ virtual double getRealTempo() = 0;
+ virtual uint32_t getTimeSig() = 0;
+ virtual int getKeySig() = 0;
+ virtual uint32_t getNoteCount() = 0;
+ virtual uint32_t getMaxTick() = 0;
+ virtual uint32_t getCurrentPolyphone() = 0;
+ virtual uint32_t getMaxPolyphone() = 0;
+ virtual uint32_t getCurrentTimeStamp() = 0;
+ virtual uint32_t getCurrentPlaybackPercentage() = 0;
+ virtual int getChannelCC(int ch, int cc) = 0;
+ virtual int getChannelPreset(int ch) = 0;
+ virtual void playerSeek(uint32_t percentage) = 0;
+ virtual double getPitchBend(int ch) = 0;
+ virtual void getPitchBendRaw(int ch, uint32_t *pb, uint32_t *pbr) = 0;
+ virtual bool getChannelMask(int ch) = 0;
+ virtual std::string getTitle() = 0;
+ virtual std::wstring getWTitle() = 0;
+ virtual std::string getChannelPresetString(int ch) = 0;
+ virtual bool isDarkTheme() = 0;
+ virtual void *getMainWindow() = 0;
- //WARNING!!: This function should be called from event reader callbacks only and
- //it is somehow dangerous -- other plugins might be unaware of the removal of the
- //event. The design might be modified afterward.
- virtual void discardCurrentEvent()=0;
- //WARNING!!: This function should be called from event reader callbacks only and
- //it is somehow dangerous -- other plugins might be unaware of the event change.
- //The design might be modified afterward.
- virtual void commitEventChange(SEvent d)=0;
- //This function should be called from a file reader when it has read a new event
- virtual void callEventReaderCB(SEvent d)=0;
- virtual void setFuncState(std::string name,bool state)=0;
- virtual void setFuncEnabled(std::string name,bool enable)=0;
+ //WARNING!!: This function should be called from event reader callbacks only and
+ //it is somehow dangerous -- other plugins might be unaware of the removal of the
+ //event. The design might be modified afterward.
+ virtual void discardCurrentEvent() = 0;
+ //WARNING!!: This function should be called from event reader callbacks only and
+ //it is somehow dangerous -- other plugins might be unaware of the event change.
+ //The design might be modified afterward.
+ virtual void commitEventChange(SEvent d) = 0;
+ //This function should be called from a file reader when it has read a new event
+ virtual void callEventReaderCB(SEvent d) = 0;
+ virtual void setFuncState(std::string name, bool state) = 0;
+ virtual void setFuncEnabled(std::string name, bool enable) = 0;
- virtual void registerFunctionality(qmpFuncBaseIntf* i,std::string name,std::string desc,const char* icon,int iconlen,bool checkable)=0;
- virtual void unregisterFunctionality(std::string name)=0;
- virtual int registerUIHook(std::string e,ICallBack* cb,void* userdat)=0;
- virtual int registerUIHook(std::string e,callback_t cb,void* userdat)=0;
- virtual void unregisterUIHook(std::string e,int hook)=0;
- virtual void registerMidiOutDevice(qmpMidiOutDevice* dev,std::string name)=0;
- virtual void unregisterMidiOutDevice(std::string name)=0;
- virtual int registerEventReaderIntf(ICallBack* cb,void* userdata)=0;
- virtual void unregisterEventReaderIntf(int intfhandle)=0;
- virtual int registerEventHandlerIntf(ICallBack* cb,void* userdata)=0;
- virtual void unregisterEventHandlerIntf(int intfhandle)=0;
- virtual int registerFileReadFinishedHandlerIntf(ICallBack* cb,void* userdata)=0;
- virtual void unregisterFileReadFinishedHandlerIntf(int intfhandle)=0;
- virtual int registerEventHandler(callback_t cb,void *userdata,bool post=false)=0;
- virtual void unregisterEventHandler(int id)=0;
- virtual int registerEventReadHandler(callback_t cb,void *userdata)=0;
- virtual void unregisterEventReadHandler(int id)=0;
- virtual int registerFileReadFinishHook(callback_t cb,void *userdata)=0;
- virtual void unregisterFileReadFinishHook(int id)=0;
- virtual void registerFileReader(qmpFileReader* reader,std::string name)=0;
- virtual void unregisterFileReader(std::string name)=0;
+ virtual void registerFunctionality(qmpFuncBaseIntf *i, std::string name, std::string desc, const char *icon, int iconlen, bool checkable) = 0;
+ virtual void unregisterFunctionality(std::string name) = 0;
+ virtual int registerUIHook(std::string e, ICallBack *cb, void *userdat) = 0;
+ virtual int registerUIHook(std::string e, callback_t cb, void *userdat) = 0;
+ virtual void unregisterUIHook(std::string e, int hook) = 0;
+ virtual void registerMidiOutDevice(qmpMidiOutDevice *dev, std::string name) = 0;
+ virtual void unregisterMidiOutDevice(std::string name) = 0;
+ virtual int registerEventReaderIntf(ICallBack *cb, void *userdata) = 0;
+ virtual void unregisterEventReaderIntf(int intfhandle) = 0;
+ virtual int registerEventHandlerIntf(ICallBack *cb, void *userdata) = 0;
+ virtual void unregisterEventHandlerIntf(int intfhandle) = 0;
+ virtual int registerFileReadFinishedHandlerIntf(ICallBack *cb, void *userdata) = 0;
+ virtual void unregisterFileReadFinishedHandlerIntf(int intfhandle) = 0;
+ virtual int registerEventHandler(callback_t cb, void *userdata, bool post = false) = 0;
+ virtual void unregisterEventHandler(int id) = 0;
+ virtual int registerEventReadHandler(callback_t cb, void *userdata) = 0;
+ virtual void unregisterEventReadHandler(int id) = 0;
+ virtual int registerFileReadFinishHook(callback_t cb, void *userdata) = 0;
+ virtual void unregisterFileReadFinishHook(int id) = 0;
+ virtual void registerFileReader(qmpFileReader *reader, std::string name) = 0;
+ virtual void unregisterFileReader(std::string name) = 0;
- //if desc=="", the option won't be visible in the settings form.
- //it will only show up in the configuration file.
- virtual void registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval)=0;
- virtual int getOptionInt(std::string key)=0;
- virtual void setOptionInt(std::string key,int val)=0;
- virtual void registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min,unsigned max,unsigned defaultval)=0;
- virtual unsigned getOptionUint(std::string key)=0;
- virtual void setOptionUint(std::string key,unsigned val)=0;
- virtual void registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval)=0;
- virtual bool getOptionBool(std::string key)=0;
- virtual void setOptionBool(std::string key,bool val)=0;
- virtual void registerOptionDouble(std::string tab,std::string desc,std::string key,double min,double max,double defaultval)=0;
- virtual double getOptionDouble(std::string key)=0;
- virtual void setOptionDouble(std::string key,double val)=0;
- virtual void registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool ispath=false)=0;
- virtual std::string getOptionString(std::string key)=0;
- virtual void setOptionString(std::string key,std::string val)=0;
- virtual void registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> options,int defaultval)=0;
- virtual int getOptionEnumInt(std::string key)=0;
- virtual void setOptionEnumInt(std::string key,int val)=0;
-};
+ //if desc=="", the option won't be visible in the settings form.
+ //it will only show up in the configuration file.
+ virtual void registerOptionInt(std::string tab, std::string desc, std::string key, int min, int max, int defaultval) = 0;
+ virtual int getOptionInt(std::string key) = 0;
+ virtual void setOptionInt(std::string key, int val) = 0;
+ virtual void registerOptionUint(std::string tab, std::string desc, std::string key, unsigned min, unsigned max, unsigned defaultval) = 0;
+ virtual unsigned getOptionUint(std::string key) = 0;
+ virtual void setOptionUint(std::string key, unsigned val) = 0;
+ virtual void registerOptionBool(std::string tab, std::string desc, std::string key, bool defaultval) = 0;
+ virtual bool getOptionBool(std::string key) = 0;
+ virtual void setOptionBool(std::string key, bool val) = 0;
+ virtual void registerOptionDouble(std::string tab, std::string desc, std::string key, double min, double max, double defaultval) = 0;
+ virtual double getOptionDouble(std::string key) = 0;
+ virtual void setOptionDouble(std::string key, double val) = 0;
+ virtual void registerOptionString(std::string tab, std::string desc, std::string key, std::string defaultval, bool ispath = false) = 0;
+ virtual std::string getOptionString(std::string key) = 0;
+ virtual void setOptionString(std::string key, std::string val) = 0;
+ virtual void registerOptionEnumInt(std::string tab, std::string desc, std::string key, std::vector<std::string> options, int defaultval) = 0;
+ virtual int getOptionEnumInt(std::string key) = 0;
+ virtual void setOptionEnumInt(std::string key, int val) = 0;
+ };
#ifdef QMP_MAIN
}
#endif
@@ -208,7 +236,7 @@ class qmpPluginAPI
//as its entry point. A pointer to the core API is also passed to the plugin
//through the parameter. This function should return a pointer to a class
//that implementes the plugin pinterface (qmpPluginIntf).
-typedef qmpPluginIntf*(*qmpPluginEntry)(qmpPluginAPI*);
+typedef qmpPluginIntf *(*qmpPluginEntry)(qmpPluginAPI *);
//The following symbol only presents in plugins. Its purpose is to help the core reject incompatible plugins.
-typedef const char*(*qmpPluginAPIRevEntry)();
+typedef const char *(*qmpPluginAPIRevEntry)();
#endif // QMPCOREPUBLIC_HPP
diff --git a/midifmt-plugin/midifmtplugin.cpp b/midifmt-plugin/midifmtplugin.cpp
index 62a9af1..39d6d4f 100644
--- a/midifmt-plugin/midifmtplugin.cpp
+++ b/midifmt-plugin/midifmtplugin.cpp
@@ -2,115 +2,140 @@
#include <algorithm>
#include <stdexcept>
#include "midifmtplugin.hpp"
-qmpPluginAPI* qmpMidiFmtPlugin::api=nullptr;
+qmpPluginAPI *qmpMidiFmtPlugin::api = nullptr;
uint32_t CMidiStreamReader::readDWLE()
{
- uint32_t ret=0;
- for(uint32_t i=0;i<4;++i)ret|=((uint32_t)fgetc(f))<<(i<<3);
- return ret;
+ uint32_t ret = 0;
+ for (uint32_t i = 0; i < 4; ++i)
+ ret |= ((uint32_t)fgetc(f)) << (i << 3);
+ return ret;
}
bool CMidiStreamReader::RIFFHeaderReader()
{
- char hdr[9];
- fread(hdr,1,4,f);
- if(strncmp(hdr,"RIFF",4))return false;
- fseek(f,4,SEEK_CUR);
- fread(hdr,1,8,f);
- if(strncmp(hdr,"MIDSfmt ",8))return false;
- if(readDWLE()!=0x0C)return false;
- ret->divs=readDWLE();
- readDWLE();
- fmt=readDWLE();
- return true;
+ char hdr[9];
+ fread(hdr, 1, 4, f);
+ if (strncmp(hdr, "RIFF", 4))
+ return false;
+ fseek(f, 4, SEEK_CUR);
+ fread(hdr, 1, 8, f);
+ if (strncmp(hdr, "MIDSfmt ", 8))
+ return false;
+ if (readDWLE() != 0x0C)
+ return false;
+ ret->divs = readDWLE();
+ readDWLE();
+ fmt = readDWLE();
+ return true;
}
bool CMidiStreamReader::midsBodyReader()
{
- char buf[9];
- fread(buf,1,4,f);
- if(strncmp(buf,"data",4))return false;
- readDWLE();//size
- uint32_t cblocks=readDWLE();
- uint32_t curid=0,cts=0;
- for(uint32_t i=0;i<cblocks;++i)
- {
- readDWLE();
- uint32_t blocksz=readDWLE(),cpos=ftell(f);
- while(ftell(f)-cpos<blocksz)
- {
- cts+=readDWLE();
- if(!(fmt&1))readDWLE();
- uint32_t e=readDWLE();
- SEvent ev;
- if(e>>24==1)//set tempo
- {
- char s[3]={'\0'};
- for(int i=0;i<3;++i)
- s[i]=(e>>(8*(2-i)))&0xff;
- ev=SEvent(curid,cts,0xFF,0x51,0);
- ev.str=std::string(s,3);
- }
- else if(e>>24==0)//midishortmsg
- ev=SEvent(curid,cts,e&0xFF,(e>>8)&0xFF,(e>>16)&0xFF);
- else return false;
- ret->tracks.back().appendEvent(ev);eventdiscarded=0;
- qmpMidiFmtPlugin::api->callEventReaderCB(ev);
- if(eventdiscarded)ret->tracks.back().eventList.pop_back();
- ++curid;
- }
- }
- return true;
+ char buf[9];
+ fread(buf, 1, 4, f);
+ if (strncmp(buf, "data", 4))
+ return false;
+ readDWLE();//size
+ uint32_t cblocks = readDWLE();
+ uint32_t curid = 0, cts = 0;
+ for (uint32_t i = 0; i < cblocks; ++i)
+ {
+ readDWLE();
+ uint32_t blocksz = readDWLE(), cpos = ftell(f);
+ while (ftell(f) - cpos < blocksz)
+ {
+ cts += readDWLE();
+ if (!(fmt & 1))readDWLE();
+ uint32_t e = readDWLE();
+ SEvent ev;
+ if (e >> 24 == 1) //set tempo
+ {
+ char s[3] = {'\0'};
+ for (int i = 0; i < 3; ++i)
+ s[i] = (e >> (8 * (2 - i))) & 0xff;
+ ev = SEvent(curid, cts, 0xFF, 0x51, 0);
+ ev.str = std::string(s, 3);
+ }
+ else if (e >> 24 == 0) //midishortmsg
+ ev = SEvent(curid, cts, e & 0xFF, (e >> 8) & 0xFF, (e >> 16) & 0xFF);
+ else return false;
+ ret->tracks.back().appendEvent(ev);
+ eventdiscarded = 0;
+ qmpMidiFmtPlugin::api->callEventReaderCB(ev);
+ if (eventdiscarded)
+ ret->tracks.back().eventList.pop_back();
+ ++curid;
+ }
+ }
+ return true;
}
-CMidiFile* CMidiStreamReader::readFile(const char *fn)
+CMidiFile *CMidiStreamReader::readFile(const char *fn)
{
- ret=new CMidiFile;
- ret->title=ret->copyright=nullptr;ret->std=0;ret->valid=1;
- ret->tracks.push_back(CMidiTrack());
- try
- {
- if(!(f=fopen(fn,"rb")))throw std::runtime_error("File doesn't exist");
- if(!RIFFHeaderReader())throw std::runtime_error("Wrong RIFF header");
- if(!midsBodyReader())throw std::runtime_error("MIDS data error");
- }catch(std::runtime_error& e)
- {
- fprintf(stderr,"CMidiStreamReader E: %s is not a supported file. Cause: %s.\n",fn,e.what());
- ret->valid=0;if(f)fclose(f);f=nullptr;
- }
- return ret;
+ ret = new CMidiFile;
+ ret->title = ret->copyright = nullptr;
+ ret->std = 0;
+ ret->valid = 1;
+ ret->tracks.push_back(CMidiTrack());
+ try
+ {
+ if (!(f = fopen(fn, "rb")))
+ throw std::runtime_error("File doesn't exist");
+ if (!RIFFHeaderReader())
+ throw std::runtime_error("Wrong RIFF header");
+ if (!midsBodyReader())
+ throw std::runtime_error("MIDS data error");
+ }
+ catch (std::runtime_error &e)
+ {
+ fprintf(stderr, "CMidiStreamReader E: %s is not a supported file. Cause: %s.\n", fn, e.what());
+ ret->valid = 0;
+ if (f)
+ fclose(f);
+ f = nullptr;
+ }
+ return ret;
}
void CMidiStreamReader::discardCurrentEvent()
{
- eventdiscarded=1;
+ eventdiscarded = 1;
}
void CMidiStreamReader::commitEventChange(SEvent d)
{
- ret->tracks.back().eventList.back().time=d.time;
- ret->tracks.back().eventList.back().type=d.type;
- ret->tracks.back().eventList.back().p1=d.p1;
- ret->tracks.back().eventList.back().p2=d.p2;
+ ret->tracks.back().eventList.back().time = d.time;
+ ret->tracks.back().eventList.back().type = d.type;
+ ret->tracks.back().eventList.back().p1 = d.p1;
+ ret->tracks.back().eventList.back().p2 = d.p2;
}
CMidiStreamReader::CMidiStreamReader()
{
- ret=nullptr;f=nullptr;
+ ret = nullptr;
+ f = nullptr;
}
CMidiStreamReader::~CMidiStreamReader()
{
}
qmpMidiFmtPlugin::qmpMidiFmtPlugin(qmpPluginAPI *_api)
-{api=_api;}
+{
+ api = _api;
+}
qmpMidiFmtPlugin::~qmpMidiFmtPlugin()
-{api=nullptr;}
+{
+ api = nullptr;
+}
void qmpMidiFmtPlugin::init()
{
- api->registerFileReader(mdsreader=new CMidiStreamReader,"MIDS reader");
+ api->registerFileReader(mdsreader = new CMidiStreamReader, "MIDS reader");
}
void qmpMidiFmtPlugin::deinit()
{
- api->unregisterFileReader("MIDS reader");
- delete mdsreader;
+ api->unregisterFileReader("MIDS reader");
+ delete mdsreader;
+}
+const char *qmpMidiFmtPlugin::pluginGetName()
+{
+ return "QMidiPlayer extra midi formats plugin";
+}
+const char *qmpMidiFmtPlugin::pluginGetVersion()
+{
+ return PLUGIN_VERSION;
}
-const char* qmpMidiFmtPlugin::pluginGetName()
-{return "QMidiPlayer extra midi formats plugin";}
-const char* qmpMidiFmtPlugin::pluginGetVersion()
-{return PLUGIN_VERSION;}
diff --git a/midifmt-plugin/midifmtplugin.hpp b/midifmt-plugin/midifmtplugin.hpp
index 038a2a7..b4eeddb 100644
--- a/midifmt-plugin/midifmtplugin.hpp
+++ b/midifmt-plugin/midifmtplugin.hpp
@@ -4,42 +4,46 @@
#include <cstdio>
#include "../include/qmpcorepublic.hpp"
-class CMidiStreamReader:public qmpFileReader
+class CMidiStreamReader: public qmpFileReader
{
- private:
- CMidiFile* ret;
- FILE* f;
- int eventdiscarded,fmt;
- uint32_t readDWLE();
- bool RIFFHeaderReader();
- bool midsBodyReader();
- public:
- CMidiStreamReader();
- ~CMidiStreamReader();
- CMidiFile* readFile(const char *fn);
- void discardCurrentEvent();
- void commitEventChange(SEvent d);
+private:
+ CMidiFile *ret;
+ FILE *f;
+ int eventdiscarded, fmt;
+ uint32_t readDWLE();
+ bool RIFFHeaderReader();
+ bool midsBodyReader();
+public:
+ CMidiStreamReader();
+ ~CMidiStreamReader();
+ CMidiFile *readFile(const char *fn);
+ void discardCurrentEvent();
+ void commitEventChange(SEvent d);
};
-class qmpMidiFmtPlugin:public qmpPluginIntf
+class qmpMidiFmtPlugin: public qmpPluginIntf
{
- private:
- CMidiStreamReader* mdsreader;
- public:
- static qmpPluginAPI* api;
- qmpMidiFmtPlugin(qmpPluginAPI* _api);
- ~qmpMidiFmtPlugin();
- void init();
- void deinit();
- const char* pluginGetName();
- const char* pluginGetVersion();
+private:
+ CMidiStreamReader *mdsreader;
+public:
+ static qmpPluginAPI *api;
+ qmpMidiFmtPlugin(qmpPluginAPI *_api);
+ ~qmpMidiFmtPlugin();
+ void init();
+ void deinit();
+ const char *pluginGetName();
+ const char *pluginGetVersion();
};
-extern "C"{
- EXPORTSYM qmpPluginIntf* qmpPluginGetInterface(qmpPluginAPI* api)
- {return new qmpMidiFmtPlugin(api);}
- EXPORTSYM const char* qmpPluginGetAPIRev()
- {return QMP_PLUGIN_API_REV;}
+extern "C" {
+ EXPORTSYM qmpPluginIntf *qmpPluginGetInterface(qmpPluginAPI *api)
+ {
+ return new qmpMidiFmtPlugin(api);
+ }
+ EXPORTSYM const char *qmpPluginGetAPIRev()
+ {
+ return QMP_PLUGIN_API_REV;
+ }
}
#endif // MIDIFMTPLUGIN_HPP
diff --git a/qmidiplayer-desktop/main.cpp b/qmidiplayer-desktop/main.cpp
index 6bf21c0..c9408b9 100644
--- a/qmidiplayer-desktop/main.cpp
+++ b/qmidiplayer-desktop/main.cpp
@@ -26,56 +26,57 @@
#include <windows.h>
#endif
-int main(int argc,char **argv)
+int main(int argc, char **argv)
{
#ifdef _WIN32
- if(!LoadLibraryA("libbacktrace.dll"))
- fputs("Failed to load backtrace library. Stack trace will not be printed if unhandled exception occurs.\n",stderr);
+ if (!LoadLibraryA("libbacktrace.dll"))
+ fputs("Failed to load backtrace library. Stack trace will not be printed if unhandled exception occurs.\n", stderr);
#endif
- QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
- QCoreApplication::setApplicationName("qmidiplayer");
- QCoreApplication::setApplicationVersion(APP_VERSION);
- if(!qgetenv("QT_SCALE_FACTOR").length()&&!qgetenv("QT_SCREEN_SCALE_FACTORS").length())
- QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- qSetMessagePattern("%{time} @ %{file} : %{line}, in %{function} : %{message}");
- QApplication a(argc,argv);
+ QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+ QCoreApplication::setApplicationName("qmidiplayer");
+ QCoreApplication::setApplicationVersion(APP_VERSION);
+ if (!qgetenv("QT_SCALE_FACTOR").length() && !qgetenv("QT_SCREEN_SCALE_FACTORS").length())
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ qSetMessagePattern("%{time} @ %{file} : %{line}, in %{function} : %{message}");
+ QApplication a(argc, argv);
- QTranslator qtTranslator;
- qtTranslator.load("qt_"+QLocale::system().name(),
- QLibraryInfo::location(QLibraryInfo::TranslationsPath));
- a.installTranslator(&qtTranslator);
- QTranslator qmpTranslator;
+ QTranslator qtTranslator;
+ qtTranslator.load("qt_" + QLocale::system().name(),
+ QLibraryInfo::location(QLibraryInfo::TranslationsPath));
+ a.installTranslator(&qtTranslator);
+ QTranslator qmpTranslator;
#ifndef NON_PORTABLE
- qmpTranslator.load("qmp_"+QLocale::system().name(),
- QCoreApplication::applicationDirPath()+"/translations/");
+ qmpTranslator.load("qmp_" + QLocale::system().name(),
+ QCoreApplication::applicationDirPath() + "/translations/");
#else
#define strify(s) #s
- qmpTranslator.load("qmp_"+QLocale::system().name(),
- QString(strify(INSTALL_PREFIX))+"/share/qmidiplayer/translations");
+ qmpTranslator.load("qmp_" + QLocale::system().name(),
+ QString(strify(INSTALL_PREFIX)) + "/share/qmidiplayer/translations");
#undef strify
#endif
- a.installTranslator(&qmpTranslator);
+ a.installTranslator(&qmpTranslator);
- QCommandLineParser clp;
- clp.setApplicationDescription(QCoreApplication::translate("main","A cross-platform MIDI player."));
- clp.addHelpOption();
- clp.addVersionOption();
- clp.addPositionalArgument("file",QCoreApplication::translate("main","midi files to play (optional)."),"[files...]");
- clp.addOption(QCommandLineOption("plugin",QCoreApplication::translate("main","Load a plugin from <plugin library>."),"plugin library"));
- clp.addOption(QCommandLineOption({"l","load-all-files"},QCoreApplication::translate("main","Load all files from the same folder.")));
+ QCommandLineParser clp;
+ clp.setApplicationDescription(QCoreApplication::translate("main", "A cross-platform MIDI player."));
+ clp.addHelpOption();
+ clp.addVersionOption();
+ clp.addPositionalArgument("file", QCoreApplication::translate("main", "midi files to play (optional)."), "[files...]");
+ clp.addOption(QCommandLineOption("plugin", QCoreApplication::translate("main", "Load a plugin from <plugin library>."), "plugin library"));
+ clp.addOption(QCommandLineOption({"l", "load-all-files"}, QCoreApplication::translate("main", "Load all files from the same folder.")));
#ifdef _WIN32
- clp.addOption(QCommandLineOption("keep-console",QCoreApplication::translate("main","Keep console window open.")));
+ clp.addOption(QCommandLineOption("keep-console", QCoreApplication::translate("main", "Keep console window open.")));
#endif
- clp.process(a);
+ clp.process(a);
#ifdef _WIN32
- if(!clp.isSet("keep-console"))
- FreeConsole();
+ if (!clp.isSet("keep-console"))
+ FreeConsole();
#endif
- qmpMainWindow w(&clp);
- if(w.parseArgs()==1)return 0;
- w.init();
+ qmpMainWindow w(&clp);
+ if (w.parseArgs() == 1)
+ return 0;
+ w.init();
- return a.exec();
+ return a.exec();
}
diff --git a/qmidiplayer-desktop/qdialskulpturestyle.cpp b/qmidiplayer-desktop/qdialskulpturestyle.cpp
index 7650edb..29c8f79 100644
--- a/qmidiplayer-desktop/qdialskulpturestyle.cpp
+++ b/qmidiplayer-desktop/qdialskulpturestyle.cpp
@@ -36,35 +36,40 @@
static const bool UsePixmapCache = true;
static void
-paintIndicatorCached(QPainter *painter, const QStyleOption *option, std::function<void(QPainter*,const QStyleOption*)> paintFunc, bool useCache, const QString &pixmapName)
+paintIndicatorCached(QPainter *painter, const QStyleOption *option, std::function<void(QPainter *, const QStyleOption *)> paintFunc, bool useCache, const QString &pixmapName)
{
- QRect rect = option->rect;
- QPixmap internalPixmapCache;
- QImage imageCache;
- QPainter *p = painter;
- int txType = painter->deviceTransform().type() | painter->worldTransform().type();
- bool doPixmapCache = useCache && (!option->rect.isEmpty())
- && ((txType <= QTransform::TxTranslate) || (painter->deviceTransform().type() == QTransform::TxScale));
- if (doPixmapCache && QPixmapCache::find(pixmapName, &internalPixmapCache)) {
- painter->drawPixmap(option->rect.topLeft(), internalPixmapCache);
- } else {
- if (doPixmapCache) {
- rect.setRect(0, 0, option->rect.width(), option->rect.height());
- qreal pixelRatio=painter->device()->devicePixelRatioF();
- imageCache = QImage(option->rect.size() * pixelRatio, QImage::Format_ARGB32_Premultiplied);
- imageCache.setDevicePixelRatio(pixelRatio);
- imageCache.fill(0);
- p = new QPainter(&imageCache);
- }
- paintFunc(p,option);
- if (doPixmapCache) {
- p->end();
- delete p;
- internalPixmapCache = QPixmap::fromImage(imageCache);
- painter->drawPixmap(option->rect.topLeft(), internalPixmapCache);
- QPixmapCache::insert(pixmapName, internalPixmapCache);
- }
- }
+ QRect rect = option->rect;
+ QPixmap internalPixmapCache;
+ QImage imageCache;
+ QPainter *p = painter;
+ int txType = painter->deviceTransform().type() | painter->worldTransform().type();
+ bool doPixmapCache = useCache && (!option->rect.isEmpty())
+ && ((txType <= QTransform::TxTranslate) || (painter->deviceTransform().type() == QTransform::TxScale));
+ if (doPixmapCache && QPixmapCache::find(pixmapName, &internalPixmapCache))
+ {
+ painter->drawPixmap(option->rect.topLeft(), internalPixmapCache);
+ }
+ else
+ {
+ if (doPixmapCache)
+ {
+ rect.setRect(0, 0, option->rect.width(), option->rect.height());
+ qreal pixelRatio = painter->device()->devicePixelRatioF();
+ imageCache = QImage(option->rect.size() * pixelRatio, QImage::Format_ARGB32_Premultiplied);
+ imageCache.setDevicePixelRatio(pixelRatio);
+ imageCache.fill(0);
+ p = new QPainter(&imageCache);
+ }
+ paintFunc(p, option);
+ if (doPixmapCache)
+ {
+ p->end();
+ delete p;
+ internalPixmapCache = QPixmap::fromImage(imageCache);
+ painter->drawPixmap(option->rect.topLeft(), internalPixmapCache);
+ QPixmapCache::insert(pixmapName, internalPixmapCache);
+ }
+ }
}
void
@@ -73,120 +78,132 @@ paintDialBase(QPainter *painter, const QStyleOption *option)
// painter->fillRect(option->rect, Qt::red);
// painter->save();
// painter->setRenderHint(QPainter::Antialiasing, true);
- int d = qMin(option->rect.width(), option->rect.height());
-/* if (d > 20 && option->notchTarget > 0) {
- d += -1;
- }
-*/ QRectF r((option->rect.width() - d) / 2.0, (option->rect.height() - d) / 2.0, d, d);
- const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0;
+ int d = qMin(option->rect.width(), option->rect.height());
+ /* if (d > 20 && option->notchTarget > 0) {
+ d += -1;
+ }
+ */
+ QRectF r((option->rect.width() - d) / 2.0, (option->rect.height() - d) / 2.0, d, d);
+ const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0;
// const qreal angle = 90;
- painter->setPen(Qt::NoPen);
- painter->setRenderHint(QPainter::Antialiasing);
- QColor border_color = option->palette.color(QPalette::Window);
+ painter->setPen(Qt::NoPen);
+ painter->setRenderHint(QPainter::Antialiasing);
+ QColor border_color = option->palette.color(QPalette::Window);
#if 0
- {
- QRadialGradient depth_gradient(r.center(), d / 2);
+ {
+ QRadialGradient depth_gradient(r.center(), d / 2);
// depth_gradient.setColorAt(0.0, QColor(0, 0, 0, 255));
- depth_gradient.setColorAt(0.5, QColor(0, 0, 0, 255));
- depth_gradient.setColorAt(1.0, QColor(0, 0, 0, 0));
- painter->setBrush(depth_gradient);
- painter->drawEllipse(r);
- }
+ depth_gradient.setColorAt(0.5, QColor(0, 0, 0, 255));
+ depth_gradient.setColorAt(1.0, QColor(0, 0, 0, 0));
+ painter->setBrush(depth_gradient);
+ painter->drawEllipse(r);
+ }
#endif
#if 1
- if (option->state & QStyle::State_HasFocus && option->state & QStyle::State_KeyboardFocusChange) {
- painter->setBrush(option->palette.color(QPalette::Highlight).darker(180));
- r.adjust(1, 1, -1, -1);
- painter->drawEllipse(r);
- painter->setBrush(border_color);
- r.adjust(1, 1, -1, -1);
- painter->drawEllipse(r);
- r.adjust(1, 1, -1, -1);
- } else {
- painter->setBrush(border_color);
- r.adjust(1, 1, -1, -1);
- painter->drawEllipse(r);
- r.adjust(1, 1, -1, -1);
- QConicalGradient border_gradient(r.center(), angle);
- if (!(option->state & QStyle::State_Enabled)) {
- border_color = border_color.lighter(120);
- }
- border_gradient.setColorAt(0.0, border_color.darker(180));
- border_gradient.setColorAt(0.3, border_color.darker(130));
- border_gradient.setColorAt(0.5, border_color.darker(170));
- border_gradient.setColorAt(0.7, border_color.darker(130));
- border_gradient.setColorAt(1.0, border_color.darker(180));
- painter->setBrush(border_gradient);
+ if (option->state & QStyle::State_HasFocus && option->state & QStyle::State_KeyboardFocusChange)
+ {
+ painter->setBrush(option->palette.color(QPalette::Highlight).darker(180));
+ r.adjust(1, 1, -1, -1);
+ painter->drawEllipse(r);
+ painter->setBrush(border_color);
+ r.adjust(1, 1, -1, -1);
+ painter->drawEllipse(r);
+ r.adjust(1, 1, -1, -1);
+ }
+ else
+ {
+ painter->setBrush(border_color);
+ r.adjust(1, 1, -1, -1);
+ painter->drawEllipse(r);
+ r.adjust(1, 1, -1, -1);
+ QConicalGradient border_gradient(r.center(), angle);
+ if (!(option->state & QStyle::State_Enabled))
+ {
+ border_color = border_color.lighter(120);
+ }
+ border_gradient.setColorAt(0.0, border_color.darker(180));
+ border_gradient.setColorAt(0.3, border_color.darker(130));
+ border_gradient.setColorAt(0.5, border_color.darker(170));
+ border_gradient.setColorAt(0.7, border_color.darker(130));
+ border_gradient.setColorAt(1.0, border_color.darker(180));
+ painter->setBrush(border_gradient);
// painter->setBrush(Qt::blue);
- painter->drawEllipse(r);
- r.adjust(1, 1, -1, -1);
- }
- d -= 6;
-
- QColor dial_color;
- if (option->state & QStyle::State_Enabled) {
- dial_color = option->palette.color(QPalette::Button).lighter(101);
- if (option->state & QStyle::State_MouseOver) {
- dial_color = dial_color.lighter(103);
- }
- } else {
- dial_color = option->palette.color(QPalette::Window);
- }
- qreal t = option->state & QStyle::State_Enabled ? 2.0 : 1.5;
- // ###: work around Qt 4.3.0 bug? (this works for 4.3.1)
- QConicalGradient border_gradient(r.center(), angle);
- border_gradient.setColorAt(0.0, dial_color.lighter(120));
- border_gradient.setColorAt(0.2, dial_color);
- border_gradient.setColorAt(0.5, dial_color.darker(130));
- border_gradient.setColorAt(0.8, dial_color);
- border_gradient.setColorAt(1.0, dial_color.lighter(120));
- painter->setPen(QPen(border_gradient, t));
+ painter->drawEllipse(r);
+ r.adjust(1, 1, -1, -1);
+ }
+ d -= 6;
+
+ QColor dial_color;
+ if (option->state & QStyle::State_Enabled)
+ {
+ dial_color = option->palette.color(QPalette::Button).lighter(101);
+ if (option->state & QStyle::State_MouseOver)
+ {
+ dial_color = dial_color.lighter(103);
+ }
+ }
+ else
+ {
+ dial_color = option->palette.color(QPalette::Window);
+ }
+ qreal t = option->state & QStyle::State_Enabled ? 2.0 : 1.5;
+ // ###: work around Qt 4.3.0 bug? (this works for 4.3.1)
+ QConicalGradient border_gradient(r.center(), angle);
+ border_gradient.setColorAt(0.0, dial_color.lighter(120));
+ border_gradient.setColorAt(0.2, dial_color);
+ border_gradient.setColorAt(0.5, dial_color.darker(130));
+ border_gradient.setColorAt(0.8, dial_color);
+ border_gradient.setColorAt(1.0, dial_color.lighter(120));
+ painter->setPen(QPen(border_gradient, t));
#if 0
- QLinearGradient dial_gradient(r.topLeft(), r.bottomLeft());
- dial_gradient.setColorAt(0.0, dial_color.darker(105));
- dial_gradient.setColorAt(0.5, dial_color.lighter(102));
- dial_gradient.setColorAt(1.0, dial_color.lighter(105));
+ QLinearGradient dial_gradient(r.topLeft(), r.bottomLeft());
+ dial_gradient.setColorAt(0.0, dial_color.darker(105));
+ dial_gradient.setColorAt(0.5, dial_color.lighter(102));
+ dial_gradient.setColorAt(1.0, dial_color.lighter(105));
#elif 1
- QLinearGradient dial_gradient(option->direction == Qt::LeftToRight ? r.topLeft() : r.topRight(), option->direction == Qt::LeftToRight ? r.bottomRight() : r.bottomLeft());
+ QLinearGradient dial_gradient(option->direction == Qt::LeftToRight ? r.topLeft() : r.topRight(), option->direction == Qt::LeftToRight ? r.bottomRight() : r.bottomLeft());
// QLinearGradient dial_gradient(r.topLeft(), r.bottomLeft());
- if (option->state & QStyle::State_Enabled) {
+ if (option->state & QStyle::State_Enabled)
+ {
#if 1
- dial_gradient.setColorAt(0.0, dial_color.darker(106));
- dial_gradient.setColorAt(1.0, dial_color.lighter(104));
+ dial_gradient.setColorAt(0.0, dial_color.darker(106));
+ dial_gradient.setColorAt(1.0, dial_color.lighter(104));
#else
- dial_gradient.setColorAt(0.0, dial_color.lighter(101));
- dial_gradient.setColorAt(0.5, dial_color.darker(103));
- dial_gradient.setColorAt(1.0, dial_color.lighter(104));
+ dial_gradient.setColorAt(0.0, dial_color.lighter(101));
+ dial_gradient.setColorAt(0.5, dial_color.darker(103));
+ dial_gradient.setColorAt(1.0, dial_color.lighter(104));
#endif
- } else {
- dial_gradient.setColorAt(0.0, dial_color);
- dial_gradient.setColorAt(1.0, dial_color);
- }
+ }
+ else
+ {
+ dial_gradient.setColorAt(0.0, dial_color);
+ dial_gradient.setColorAt(1.0, dial_color);
+ }
#elif 0
- QConicalGradient dial_gradient(r.center(), angle);
- dial_gradient.setColorAt(0.0, dial_color.lighter(102));
- dial_gradient.setColorAt(0.5, dial_color.darker(103));
- dial_gradient.setColorAt(1.0, dial_color.lighter(102));
+ QConicalGradient dial_gradient(r.center(), angle);
+ dial_gradient.setColorAt(0.0, dial_color.lighter(102));
+ dial_gradient.setColorAt(0.5, dial_color.darker(103));
+ dial_gradient.setColorAt(1.0, dial_color.lighter(102));
#else
- QBrush dial_gradient(dial_color);
+ QBrush dial_gradient(dial_color);
#endif
- painter->setBrush(dial_gradient);
- t = t / 2;
- painter->drawEllipse(r.adjusted(t, t, -t, -t));
+ painter->setBrush(dial_gradient);
+ t = t / 2;
+ painter->drawEllipse(r.adjusted(t, t, -t, -t));
// painter->setPen(Qt::NoPen);
// painter->setBrush(dial_color);
// painter->drawEllipse(r.adjusted(d / 4, d / 4, - d / 4, - d / 4));
#if 0
- QLinearGradient border2_gradient(r.topLeft(), r.bottomRight());
- border2_gradient.setColorAt(1.0, dial_color.darker(425));
- border2_gradient.setColorAt(0.9, dial_color);
- border2_gradient.setColorAt(0.0, dial_color.darker(400));
- painter->setPen(QPen(border2_gradient, 1.3));
- painter->setBrush(Qt::NoBrush);
- painter->drawEllipse(r.adjusted(0.3, 0.3, -0.3, -0.3));
+ QLinearGradient border2_gradient(r.topLeft(), r.bottomRight());
+ border2_gradient.setColorAt(1.0, dial_color.darker(425));
+ border2_gradient.setColorAt(0.9, dial_color);
+ border2_gradient.setColorAt(0.0, dial_color.darker(400));
+ painter->setPen(QPen(border2_gradient, 1.3));
+ painter->setBrush(Qt::NoBrush);
+ painter->drawEllipse(r.adjusted(0.3, 0.3, -0.3, -0.3));
#endif
// painter->restore();
#endif
@@ -195,262 +212,297 @@ paintDialBase(QPainter *painter, const QStyleOption *option)
void
paintCachedDialBase(QPainter *painter, const QStyleOptionSlider *option)
{
- bool useCache = UsePixmapCache;
- QString pixmapName;
- QRect r = option->rect;
- int d = qMin(r.width(), r.height());
-
- if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ d > 128) {
- useCache = false;
- }
- if (useCache) {
- uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_KeyboardFocusChange | QStyle::State_HasFocus);
- if (!(state & QStyle::State_Enabled)) {
- state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus | QStyle::State_KeyboardFocusChange);
- }
- // state &= ~(QStyle::State_HasFocus);
- pixmapName = QString("scp-qdb-%1-%2-%3-%4")
- .arg(state, 0, 16)
- .arg(option->direction, 0, 16)
- .arg(option->palette.cacheKey(), 0, 16)
- .arg(d, 0, 16);
- }
- paintIndicatorCached(painter, option, paintDialBase, useCache, pixmapName);
+ bool useCache = UsePixmapCache;
+ QString pixmapName;
+ QRect r = option->rect;
+ int d = qMin(r.width(), r.height());
+
+ if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ d > 128)
+ {
+ useCache = false;
+ }
+ if (useCache)
+ {
+ uint state = uint(option->state) & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_KeyboardFocusChange | QStyle::State_HasFocus);
+ if (!(state & QStyle::State_Enabled))
+ {
+ state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus | QStyle::State_KeyboardFocusChange);
+ }
+ // state &= ~(QStyle::State_HasFocus);
+ pixmapName = QString("scp-qdb-%1-%2-%3-%4")
+ .arg(state, 0, 16)
+ .arg(option->direction, 0, 16)
+ .arg(option->palette.cacheKey(), 0, 16)
+ .arg(d, 0, 16);
+ }
+ paintIndicatorCached(painter, option, paintDialBase, useCache, pixmapName);
}
void
paintIndicatorDial(QPainter *painter, const QStyleOptionSlider *option)
{
- int d = qMin(option->rect.width(), option->rect.height());
- QRect rect(option->rect.center() - QPoint((d - 1) / 2, (d - 1) / 2), QSize(d, d));
- QStyleOptionSlider opt;
- opt.QStyleOption::operator=(*option);
- opt.rect = rect;
- paintCachedDialBase(painter, &opt);
+ int d = qMin(option->rect.width(), option->rect.height());
+ QRect rect(option->rect.center() - QPoint((d - 1) / 2, (d - 1) / 2), QSize(d, d));
+ QStyleOptionSlider opt;
+ opt.QStyleOption::operator=(*option);
+ opt.rect = rect;
+ paintCachedDialBase(painter, &opt);
}
QColor
shaded_color(const QColor &color, int shade)
{
#if 1
- const qreal contrast = 1.0;
- int r, g, b;
- color.getRgb(&r, &g, &b);
- int gray = qGray(r, g, b);
- gray = qMax(r, qMax(g, b));
- gray = (r + b + g + 3 * gray) / 6;
- if (shade < 0) {
- qreal k = 220.0 / 255.0 * shade;
- k *= contrast;
- int a = 255;
- if (gray > 0) {
- a = int(k * 255 / (0 - gray));
- if (a < 0) a = 0;
- if (a > 255) a = 255;
- }
- return QColor(0, 0, 0, a);
- } else {
- qreal k = (255 - 220.0) / (255.0) * shade;
- k *= contrast;
- int a = 255;
- if (gray < 255) {
- a = int(k * 255 / (255 - gray));
- if (a < 0) a = 0;
- if (a > 255) a = 255;
- }
- return QColor(255, 255, 255, a);
- }
+ const qreal contrast = 1.0;
+ int r, g, b;
+ color.getRgb(&r, &g, &b);
+ int gray = qGray(r, g, b);
+ gray = qMax(r, qMax(g, b));
+ gray = (r + b + g + 3 * gray) / 6;
+ if (shade < 0)
+ {
+ qreal k = 220.0 / 255.0 * shade;
+ k *= contrast;
+ int a = 255;
+ if (gray > 0)
+ {
+ a = int(k * 255 / (0 - gray));
+ if (a < 0) a = 0;
+ if (a > 255) a = 255;
+ }
+ return QColor(0, 0, 0, a);
+ }
+ else
+ {
+ qreal k = (255 - 220.0) / (255.0) * shade;
+ k *= contrast;
+ int a = 255;
+ if (gray < 255)
+ {
+ a = int(k * 255 / (255 - gray));
+ if (a < 0) a = 0;
+ if (a > 255) a = 255;
+ }
+ return QColor(255, 255, 255, a);
+ }
#else
- if (shade < 0) {
- return QColor(0, 0, 0, -shade);
- } else {
- return QColor(255, 255, 255, shade);
- }
+ if (shade < 0)
+ {
+ return QColor(0, 0, 0, -shade);
+ }
+ else
+ {
+ return QColor(255, 255, 255, shade);
+ }
#endif
}
static void
paintGrip(QPainter *painter, const QStyleOption *option)
{
- //painter->fillRect(option->rect, Qt::red);
- int d = qMin(option->rect.width(), option->rect.height());
- // good values are 3 (very small), 4 (small), 5 (good), 7 (large), 9 (huge)
- // int d = 5;
- QRectF rect(QRectF(option->rect).center() - QPointF(d / 2.0, d / 2.0), QSizeF(d, d));
- const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0;
+ //painter->fillRect(option->rect, Qt::red);
+ int d = qMin(option->rect.width(), option->rect.height());
+ // good values are 3 (very small), 4 (small), 5 (good), 7 (large), 9 (huge)
+ // int d = 5;
+ QRectF rect(QRectF(option->rect).center() - QPointF(d / 2.0, d / 2.0), QSizeF(d, d));
+ const qreal angle = option->direction == Qt::LeftToRight ? 135.0 : 45.0;
// const qreal angle = 90;
- QColor color;
- qreal opacity = 0.9;
-
- painter->save();
- painter->setRenderHint(QPainter::Antialiasing);
- painter->setPen(Qt::NoPen);
- if (option->state & QStyle::State_Enabled) {
- if (option->state & QStyle::State_Sunken) {
- color = option->palette.color(QPalette::Highlight).darker(110);
- } else {
- color = option->palette.color(QPalette::Button);
- }
- } else {
- color = option->palette.color(QPalette::Button);
- opacity = 0.5;
- }
-
- QConicalGradient gradient1(rect.center(), angle);
- gradient1.setColorAt(0.0, shaded_color(color, -110));
- gradient1.setColorAt(0.25, shaded_color(color, -30));
- gradient1.setColorAt(0.5, shaded_color(color, 180));
- gradient1.setColorAt(0.75, shaded_color(color, -30));
- gradient1.setColorAt(1.0, shaded_color(color, -110));
- painter->setBrush(color);
- painter->drawEllipse(rect);
- painter->setBrush(gradient1);
+ QColor color;
+ qreal opacity = 0.9;
+
+ painter->save();
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->setPen(Qt::NoPen);
+ if (option->state & QStyle::State_Enabled)
+ {
+ if (option->state & QStyle::State_Sunken)
+ {
+ color = option->palette.color(QPalette::Highlight).darker(110);
+ }
+ else
+ {
+ color = option->palette.color(QPalette::Button);
+ }
+ }
+ else
+ {
+ color = option->palette.color(QPalette::Button);
+ opacity = 0.5;
+ }
+
+ QConicalGradient gradient1(rect.center(), angle);
+ gradient1.setColorAt(0.0, shaded_color(color, -110));
+ gradient1.setColorAt(0.25, shaded_color(color, -30));
+ gradient1.setColorAt(0.5, shaded_color(color, 180));
+ gradient1.setColorAt(0.75, shaded_color(color, -30));
+ gradient1.setColorAt(1.0, shaded_color(color, -110));
+ painter->setBrush(color);
+ painter->drawEllipse(rect);
+ painter->setBrush(gradient1);
#if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0))
- // ### merge opacity into color
- painter->setOpacity(opacity);
+ // ### merge opacity into color
+ painter->setOpacity(opacity);
#endif
- painter->drawEllipse(rect);
+ painter->drawEllipse(rect);
#if (QT_VERSION >= QT_VERSION_CHECK(4, 2, 0))
- painter->setOpacity(1.0);
- if (d > 2) {
- QConicalGradient gradient2(rect.center(), angle);
- gradient2.setColorAt(0.0, shaded_color(color, -40));
- gradient2.setColorAt(0.25, shaded_color(color, 0));
- gradient2.setColorAt(0.5, shaded_color(color, 210));
- gradient2.setColorAt(0.75, shaded_color(color, 0));
- gradient2.setColorAt(1.0, shaded_color(color, -40));
- rect.adjust(1, 1, -1, -1);
- painter->setBrush(color);
- painter->drawEllipse(rect);
- painter->setBrush(gradient2);
- painter->setOpacity(opacity);
- painter->drawEllipse(rect);
- painter->setOpacity(1.0);
- if (d > 8) {
- QConicalGradient gradient3(rect.center(), angle);
- gradient3.setColorAt(0.0, shaded_color(color, -10));
- gradient3.setColorAt(0.25, shaded_color(color, 0));
- gradient3.setColorAt(0.5, shaded_color(color, 180));
- gradient3.setColorAt(0.75, shaded_color(color, 0));
- gradient3.setColorAt(1.0, shaded_color(color, -10));
- rect.adjust(2, 2, -2, -2);
- painter->setBrush(color);
- painter->drawEllipse(rect);
- painter->setBrush(gradient3);
- painter->setOpacity(opacity);
- painter->drawEllipse(rect);
- painter->setOpacity(1.0);
- }
- }
+ painter->setOpacity(1.0);
+ if (d > 2)
+ {
+ QConicalGradient gradient2(rect.center(), angle);
+ gradient2.setColorAt(0.0, shaded_color(color, -40));
+ gradient2.setColorAt(0.25, shaded_color(color, 0));
+ gradient2.setColorAt(0.5, shaded_color(color, 210));
+ gradient2.setColorAt(0.75, shaded_color(color, 0));
+ gradient2.setColorAt(1.0, shaded_color(color, -40));
+ rect.adjust(1, 1, -1, -1);
+ painter->setBrush(color);
+ painter->drawEllipse(rect);
+ painter->setBrush(gradient2);
+ painter->setOpacity(opacity);
+ painter->drawEllipse(rect);
+ painter->setOpacity(1.0);
+ if (d > 8)
+ {
+ QConicalGradient gradient3(rect.center(), angle);
+ gradient3.setColorAt(0.0, shaded_color(color, -10));
+ gradient3.setColorAt(0.25, shaded_color(color, 0));
+ gradient3.setColorAt(0.5, shaded_color(color, 180));
+ gradient3.setColorAt(0.75, shaded_color(color, 0));
+ gradient3.setColorAt(1.0, shaded_color(color, -10));
+ rect.adjust(2, 2, -2, -2);
+ painter->setBrush(color);
+ painter->drawEllipse(rect);
+ painter->setBrush(gradient3);
+ painter->setOpacity(opacity);
+ painter->drawEllipse(rect);
+ painter->setOpacity(1.0);
+ }
+ }
#endif
- painter->restore();
+ painter->restore();
}
void
paintCachedGrip(QPainter *painter, const QStyleOption *option)
{
- bool useCache = UsePixmapCache;
- QString pixmapName;
-
- if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ option->rect.width() * option->rect.height() > 4096) {
- useCache = false;
- }
- if (useCache) {
- QStyle::State state = option->state & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_Sunken | QStyle::State_HasFocus);
- if (!(state & QStyle::State_Enabled)) {
- state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus);
- }
- state &= ~(QStyle::State_HasFocus);
- QByteArray colorName = option->palette.color(QPalette::Button).name().toLatin1();
- pixmapName = QString("scp-isg-%1-%2-%3-%4-%5")
- .arg(state, 0, 16)
- .arg(option->direction, 0, 16)
- .arg(QString(colorName))
- .arg(option->rect.width(), 0, 16)
- .arg(option->rect.height(), 0, 16);
- }
- paintIndicatorCached(painter,option,
- [=](QPainter *painter,const QStyleOption *option){
- QStyleOption opt(*option);
- opt.rect.moveTo(0, 0);
- paintGrip(painter,&opt);
- },
- useCache,pixmapName);
+ bool useCache = UsePixmapCache;
+ QString pixmapName;
+
+ if (/* option->state & (QStyle::State_HasFocus | QStyle::State_MouseOver) ||*/ option->rect.width() * option->rect.height() > 4096)
+ {
+ useCache = false;
+ }
+ if (useCache)
+ {
+ QStyle::State state = option->state & (QStyle::State_Enabled | QStyle::State_On | QStyle::State_MouseOver | QStyle::State_Sunken | QStyle::State_HasFocus);
+ if (!(state & QStyle::State_Enabled))
+ {
+ state &= ~(QStyle::State_MouseOver | QStyle::State_HasFocus);
+ }
+ state &= ~(QStyle::State_HasFocus);
+ QByteArray colorName = option->palette.color(QPalette::Button).name().toLatin1();
+ pixmapName = QString("scp-isg-%1-%2-%3-%4-%5")
+ .arg(state, 0, 16)
+ .arg(option->direction, 0, 16)
+ .arg(QString(colorName))
+ .arg(option->rect.width(), 0, 16)
+ .arg(option->rect.height(), 0, 16);
+ }
+ paintIndicatorCached(painter, option,
+ [ = ](QPainter * painter, const QStyleOption * option)
+ {
+ QStyleOption opt(*option);
+ opt.rect.moveTo(0, 0);
+ paintGrip(painter, &opt);
+ },
+ useCache, pixmapName);
}
void
-QDialSkulptureStyle::drawComplexControl( ComplexControl cc,
- const QStyleOptionComplex *optc,
- QPainter *painter,
- const QWidget *widget) const
+QDialSkulptureStyle::drawComplexControl(ComplexControl cc,
+ const QStyleOptionComplex *optc,
+ QPainter *painter,
+ const QWidget *widget) const
{
- if (cc != QStyle::CC_Dial) {
- QCommonStyle::drawComplexControl(cc, optc, painter, widget);
- return;
- }
-
- const QStyleOptionSlider *option = qstyleoption_cast<const QStyleOptionSlider *>(optc);
- if (option == nullptr)
- return;
-
- int d = qMin(option->rect.width() & ~1, option->rect.height() & ~1);
- QStyleOptionSlider opt = *option;
- const QAbstractSlider *slider = nullptr;
- // always highlight knob if pressed (even if mouse is not over knob)
- if ((option->state & QStyle::State_HasFocus) && (slider = qobject_cast<const QAbstractSlider *>(widget))) {
- if (slider->isSliderDown()) {
- opt.state |= QStyle::State_MouseOver;
- }
- }
-
- // tickmarks
- opt.palette.setColor(QPalette::Inactive, QPalette::WindowText, QColor(80, 80, 80, 255));
- opt.palette.setColor(QPalette::Active, QPalette::WindowText, QColor(80, 80, 80, 255));
- opt.state &= ~QStyle::State_HasFocus;
- opt.rect.setWidth(opt.rect.width() & ~1);
- opt.rect.setHeight(opt.rect.height() & ~1);
- opt.rect.moveCenter(option->rect.center());
- QCommonStyle::drawComplexControl(QStyle::CC_Dial, &opt, painter, widget);
-
- // focus rectangle
- if (option->state & QStyle::State_HasFocus) {
- QStyleOptionFocusRect focus;
- opt.state |= QStyle::State_HasFocus;
- focus.QStyleOption::operator=(opt);
- focus.rect.adjust(-1, -1, 1, 1);
- //drawPrimitive(QStyle::PE_FrameFocusRect, &focus, painter, widget);
- }
- opt.palette = option->palette;
-
- // dial base
- if (d <= 256) {
- QStyleOptionSlider topt(opt);
- topt.rect.adjust(2,2,-2,-2);
- topt.rect.moveCenter(option->rect.center());
- paintIndicatorDial(painter, &topt);
- } else {
- // large dials are slow to render, do not render them
- }
-
- // dial knob
- d -= 6;
- int gripSize = (option->fontMetrics.height() / 4) * 2 - 1;
- opt.rect.setSize(QSize(gripSize, gripSize));
- opt.rect.moveCenter(option->rect.center());
- // angle calculation from qcommonstyle.cpp (c) Trolltech 1992-2007, ASA.
- qreal angle;
- int sliderPosition = option->upsideDown ? option->sliderPosition : (option->maximum - option->sliderPosition);
- int range = option->maximum - option->minimum;
- if (!range) {
- angle = M_PI / 2;
- } else if (option->dialWrapping) {
- angle = M_PI * 1.5 - (sliderPosition - option->minimum) * 2 * M_PI / range;
- } else {
- angle = (M_PI * 8 - (sliderPosition - option->minimum) * 10 * M_PI / range) / 6;
- }
-
- qreal rr = d / 2.0 - gripSize - 2;
- opt.rect.translate(int(0.5 + rr * cos(angle)), int(0.5 - rr * sin(angle)));
- paintCachedGrip(painter, &opt);
+ if (cc != QStyle::CC_Dial)
+ {
+ QCommonStyle::drawComplexControl(cc, optc, painter, widget);
+ return;
+ }
+
+ const QStyleOptionSlider *option = qstyleoption_cast<const QStyleOptionSlider *>(optc);
+ if (option == nullptr)
+ return;
+
+ int d = qMin(option->rect.width() & ~1, option->rect.height() & ~1);
+ QStyleOptionSlider opt = *option;
+ const QAbstractSlider *slider = nullptr;
+ // always highlight knob if pressed (even if mouse is not over knob)
+ if ((option->state & QStyle::State_HasFocus) && (slider = qobject_cast<const QAbstractSlider *>(widget)))
+ {
+ if (slider->isSliderDown())
+ {
+ opt.state |= QStyle::State_MouseOver;
+ }
+ }
+
+ // tickmarks
+ opt.palette.setColor(QPalette::Inactive, QPalette::WindowText, QColor(80, 80, 80, 255));
+ opt.palette.setColor(QPalette::Active, QPalette::WindowText, QColor(80, 80, 80, 255));
+ opt.state &= ~QStyle::State_HasFocus;
+ opt.rect.setWidth(opt.rect.width() & ~1);
+ opt.rect.setHeight(opt.rect.height() & ~1);
+ opt.rect.moveCenter(option->rect.center());
+ QCommonStyle::drawComplexControl(QStyle::CC_Dial, &opt, painter, widget);
+
+ // focus rectangle
+ if (option->state & QStyle::State_HasFocus)
+ {
+ QStyleOptionFocusRect focus;
+ opt.state |= QStyle::State_HasFocus;
+ focus.QStyleOption::operator=(opt);
+ focus.rect.adjust(-1, -1, 1, 1);
+ //drawPrimitive(QStyle::PE_FrameFocusRect, &focus, painter, widget);
+ }
+ opt.palette = option->palette;
+
+ // dial base
+ if (d <= 256)
+ {
+ QStyleOptionSlider topt(opt);
+ topt.rect.adjust(2, 2, -2, -2);
+ topt.rect.moveCenter(option->rect.center());
+ paintIndicatorDial(painter, &topt);
+ }
+ else
+ {
+ // large dials are slow to render, do not render them
+ }
+
+ // dial knob
+ d -= 6;
+ int gripSize = (option->fontMetrics.height() / 4) * 2 - 1;
+ opt.rect.setSize(QSize(gripSize, gripSize));
+ opt.rect.moveCenter(option->rect.center());
+ // angle calculation from qcommonstyle.cpp (c) Trolltech 1992-2007, ASA.
+ qreal angle;
+ int sliderPosition = option->upsideDown ? option->sliderPosition : (option->maximum - option->sliderPosition);
+ int range = option->maximum - option->minimum;
+ if (!range)
+ {
+ angle = M_PI / 2;
+ }
+ else if (option->dialWrapping)
+ {
+ angle = M_PI * 1.5 - (sliderPosition - option->minimum) * 2 * M_PI / range;
+ }
+ else
+ {
+ angle = (M_PI * 8 - (sliderPosition - option->minimum) * 10 * M_PI / range) / 6;
+ }
+
+ qreal rr = d / 2.0 - gripSize - 2;
+ opt.rect.translate(int(0.5 + rr * cos(angle)), int(0.5 - rr * sin(angle)));
+ paintCachedGrip(painter, &opt);
}
diff --git a/qmidiplayer-desktop/qdialskulpturestyle.hpp b/qmidiplayer-desktop/qdialskulpturestyle.hpp
index 2f3ba04..42a8e0d 100644
--- a/qmidiplayer-desktop/qdialskulpturestyle.hpp
+++ b/qmidiplayer-desktop/qdialskulpturestyle.hpp
@@ -25,14 +25,14 @@
#include <QCommonStyle>
-class QDialSkulptureStyle:public QCommonStyle
+class QDialSkulptureStyle : public QCommonStyle
{
public:
- QDialSkulptureStyle(){}
- virtual ~QDialSkulptureStyle(){}
+ QDialSkulptureStyle() {}
+ virtual ~QDialSkulptureStyle() {}
- virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
- const QWidget *widget=0) const;
+ virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
+ const QWidget *widget = nullptr) const;
};
diff --git a/qmidiplayer-desktop/qmpchanneleditor.cpp b/qmidiplayer-desktop/qmpchanneleditor.cpp
index 5343c1c..8f92932 100644
--- a/qmidiplayer-desktop/qmpchanneleditor.cpp
+++ b/qmidiplayer-desktop/qmpchanneleditor.cpp
@@ -4,140 +4,163 @@
#include "qmpmainwindow.hpp"
qmpChannelEditor::qmpChannelEditor(QWidget *parent):
- QDialog(parent),
- ui(new Ui::qmpChannelEditor)
+ QDialog(parent),
+ ui(new Ui::qmpChannelEditor)
{
- ui->setupUi(this);ch=0;
- styl=new QDialSkulptureStyle();
- dials=findChildren<QDial*>();
- for(auto&d:dials)
- d->setStyle(styl);
+ ui->setupUi(this);
+ ch = 0;
+ styl = new QDialSkulptureStyle();
+ dials = findChildren<QDial *>();
+ for (auto &d : dials)
+ d->setStyle(styl);
}
qmpChannelEditor::~qmpChannelEditor()
{
- delete styl;
- delete ui;
+ delete styl;
+ delete ui;
}
void qmpChannelEditor::setupWindow(int chid)
{
- char str[256];if(~chid)ch=chid;
- setWindowTitle(tr("Channel Parameter Editor - Channel #%1").arg(ch+1));
- CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
- uint16_t b;uint8_t p;std::string pstn;
- if(!player->getChannelOutputDevice(ch)->getChannelPreset(ch,&b,&p,pstn))
- {
- b=player->getCC(ch,0)<<7|player->getCC(ch,32);
- p=player->getCC(ch,128);
- pstn=player->getChannelOutputDevice(ch)->getPresetName(b,p);
- }
- ui->lbPresetName->setText(pstn.c_str());
- sprintf(str,"BK: %03d",b);ui->lbBank->setText(str);
- sprintf(str,"PC: %03d",p);ui->lbPreset->setText(str);
- ui->lbChannelNumber->setText(QString::number(ch+1));
- auto setupControl=[this,player](int ccid,QLabel* lb,QDial* d,QString ccname,std::function<QString(uint16_t)> valconv)
- {
- uint16_t b=player->getCC(ch,ccid);
- lb->setText(QString("%1 %2").arg(ccname).arg(valconv(b)));
- d->setValue(b);
- };
- auto defconv=std::bind(static_cast<QString(*)(uint,int)>(&QString::number),std::placeholders::_1,10);
- auto panconv=[](uint v)->QString{
- if(v==64)return tr("C");
- else if(v<64)return tr("L%1").arg(64-v);
- else return tr("R%1").arg(v-64);
- };
- setupControl(7,ui->lbVol,ui->dVol,tr("Vol."),defconv);
- setupControl(91,ui->lbReverb,ui->dReverb,tr("Rev."),defconv);
- setupControl(93,ui->lbChorus,ui->dChorus,tr("Chr."),defconv);
- setupControl(71,ui->lbReso,ui->dReso,tr("Res."),defconv);
- setupControl(74,ui->lbCut,ui->dCut,tr("Cut."),defconv);
- setupControl(73,ui->lbAttack,ui->dAttack,tr("Atk."),defconv);
- setupControl(75,ui->lbDecay,ui->dDecay,tr("Dec."),defconv);
- setupControl(72,ui->lbRelease,ui->dRelease,tr("Rel."),defconv);
- setupControl(76,ui->lbRate,ui->dRate,tr("Rate"),defconv);
- setupControl(77,ui->lbDepth,ui->dDepth,tr("Dep."),defconv);
- setupControl(78,ui->lbDelay,ui->dDelay,tr("Del."),defconv);
- setupControl(10,ui->lbPan,ui->dPan,tr("Pan."),panconv);
+ char str[256];
+ if (~chid)
+ ch = chid;
+ setWindowTitle(tr("Channel Parameter Editor - Channel #%1").arg(ch + 1));
+ CMidiPlayer *player = qmpMainWindow::getInstance()->getPlayer();
+ uint16_t b;
+ uint8_t p;
+ std::string pstn;
+ if (!player->getChannelOutputDevice(ch)->getChannelPreset(ch, &b, &p, pstn))
+ {
+ b = player->getCC(ch, 0) << 7 | player->getCC(ch, 32);
+ p = player->getCC(ch, 128);
+ pstn = player->getChannelOutputDevice(ch)->getPresetName(b, p);
+ }
+ ui->lbPresetName->setText(pstn.c_str());
+ sprintf(str, "BK: %03d", b);
+ ui->lbBank->setText(str);
+ sprintf(str, "PC: %03d", p);
+ ui->lbPreset->setText(str);
+ ui->lbChannelNumber->setText(QString::number(ch + 1));
+ auto setupControl = [this, player](int ccid, QLabel *lb, QDial *d, QString ccname, std::function<QString(uint16_t)> valconv)
+ {
+ uint16_t b = player->getCC(ch, ccid);
+ lb->setText(QString("%1 %2").arg(ccname).arg(valconv(b)));
+ d->setValue(b);
+ };
+ auto defconv = std::bind(static_cast<QString(*)(uint, int)>(&QString::number), std::placeholders::_1, 10);
+ auto panconv = [](uint v)->QString
+ {
+ if (v == 64)
+ return tr("C");
+ else if (v < 64)
+ return tr("L%1").arg(64 - v);
+ else return tr("R%1").arg(v - 64);
+ };
+ setupControl(7, ui->lbVol, ui->dVol, tr("Vol."), defconv);
+ setupControl(91, ui->lbReverb, ui->dReverb, tr("Rev."), defconv);
+ setupControl(93, ui->lbChorus, ui->dChorus, tr("Chr."), defconv);
+ setupControl(71, ui->lbReso, ui->dReso, tr("Res."), defconv);
+ setupControl(74, ui->lbCut, ui->dCut, tr("Cut."), defconv);
+ setupControl(73, ui->lbAttack, ui->dAttack, tr("Atk."), defconv);
+ setupControl(75, ui->lbDecay, ui->dDecay, tr("Dec."), defconv);
+ setupControl(72, ui->lbRelease, ui->dRelease, tr("Rel."), defconv);
+ setupControl(76, ui->lbRate, ui->dRate, tr("Rate"), defconv);
+ setupControl(77, ui->lbDepth, ui->dDepth, tr("Dep."), defconv);
+ setupControl(78, ui->lbDelay, ui->dDelay, tr("Del."), defconv);
+ setupControl(10, ui->lbPan, ui->dPan, tr("Pan."), panconv);
}
void qmpChannelEditor::sendCC()
{
- CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
- player->setCC(ch,7,ui->dVol->value());
- player->setCC(ch,10,ui->dPan->value());
- player->setCC(ch,91,ui->dReverb->value());
- player->setCC(ch,93,ui->dChorus->value());
- player->setCC(ch,71,ui->dReso->value());
- player->setCC(ch,74,ui->dCut->value());
- player->setCC(ch,73,ui->dAttack->value());
- player->setCC(ch,75,ui->dDecay->value());
- player->setCC(ch,72,ui->dRelease->value());
- player->setCC(ch,76,ui->dRate->value());
- player->setCC(ch,77,ui->dDepth->value());
- player->setCC(ch,78,ui->dDelay->value());
- qmpMainWindow::getInstance()->invokeCallback("channel.ccchange",nullptr);
+ CMidiPlayer *player = qmpMainWindow::getInstance()->getPlayer();
+ player->setCC(ch, 7, ui->dVol->value());
+ player->setCC(ch, 10, ui->dPan->value());
+ player->setCC(ch, 91, ui->dReverb->value());
+ player->setCC(ch, 93, ui->dChorus->value());
+ player->setCC(ch, 71, ui->dReso->value());
+ player->setCC(ch, 74, ui->dCut->value());
+ player->setCC(ch, 73, ui->dAttack->value());
+ player->setCC(ch, 75, ui->dDecay->value());
+ player->setCC(ch, 72, ui->dRelease->value());
+ player->setCC(ch, 76, ui->dRate->value());
+ player->setCC(ch, 77, ui->dDepth->value());
+ player->setCC(ch, 78, ui->dDelay->value());
+ qmpMainWindow::getInstance()->invokeCallback("channel.ccchange", nullptr);
}
void qmpChannelEditor::showEvent(QShowEvent *e)
{
- knobpressed=0;
- setupWindow();
- connectSlots();
- updconn=connect(qmpMainWindow::getInstance()->getTimer(),&QTimer::timeout,std::bind(&qmpChannelEditor::setupWindow,this,-1));
- e->accept();
+ knobpressed = 0;
+ setupWindow();
+ connectSlots();
+ updconn = connect(qmpMainWindow::getInstance()->getTimer(), &QTimer::timeout, std::bind(&qmpChannelEditor::setupWindow, this, -1));
+ e->accept();
}
void qmpChannelEditor::closeEvent(QCloseEvent *e)
{
- disconnectSlots();
- disconnect(updconn);
- e->accept();
+ disconnectSlots();
+ disconnect(updconn);
+ e->accept();
}
void qmpChannelEditor::on_pbChLeft_clicked()
{
- disconnectSlots();
- if(ch>0)--ch;else ch=15;setupWindow();
- connectSlots();
+ disconnectSlots();
+ if (ch > 0)
+ --ch;
+ else ch = 15;
+ setupWindow();
+ connectSlots();
}
void qmpChannelEditor::on_pbChRight_clicked()
{
- disconnectSlots();
- if(ch<15)++ch;else ch=0;setupWindow();
- connectSlots();
+ disconnectSlots();
+ if (ch < 15)
+ ++ch;
+ else ch = 0;
+ setupWindow();
+ connectSlots();
}
void qmpChannelEditor::commonPressed()
{
- disconnect(updconn);
- knobpressed=1;
+ disconnect(updconn);
+ knobpressed = 1;
}
void qmpChannelEditor::commonReleased()
{
- updconn=connect(qmpMainWindow::getInstance()->getTimer(),&QTimer::timeout,std::bind(&qmpChannelEditor::setupWindow,this,-1));
- sendCC();knobpressed=0;
+ updconn = connect(qmpMainWindow::getInstance()->getTimer(), &QTimer::timeout, std::bind(&qmpChannelEditor::setupWindow, this, -1));
+ sendCC();
+ knobpressed = 0;
}
void qmpChannelEditor::commonChanged()
-{if(knobpressed){sendCC();setupWindow();}}
+{
+ if (knobpressed)
+ {
+ sendCC();
+ setupWindow();
+ }
+}
void qmpChannelEditor::connectSlots()
{
- for(auto&d:dials)
- {
- connect(d,&QDial::sliderPressed,this,&qmpChannelEditor::commonPressed);
- connect(d,&QDial::sliderReleased,this,&qmpChannelEditor::commonReleased);
- connect(d,&QDial::valueChanged,this,&qmpChannelEditor::commonChanged);
- }
+ for (auto &d : dials)
+ {
+ connect(d, &QDial::sliderPressed, this, &qmpChannelEditor::commonPressed);
+ connect(d, &QDial::sliderReleased, this, &qmpChannelEditor::commonReleased);
+ connect(d, &QDial::valueChanged, this, &qmpChannelEditor::commonChanged);
+ }
}
void qmpChannelEditor::disconnectSlots()
{
- for(auto&d:dials)
- {
- disconnect(d,&QDial::sliderPressed,this,&qmpChannelEditor::commonPressed);
- disconnect(d,&QDial::sliderReleased,this,&qmpChannelEditor::commonReleased);
- disconnect(d,&QDial::valueChanged,this,&qmpChannelEditor::commonChanged);
- }
+ for (auto &d : dials)
+ {
+ disconnect(d, &QDial::sliderPressed, this, &qmpChannelEditor::commonPressed);
+ disconnect(d, &QDial::sliderReleased, this, &qmpChannelEditor::commonReleased);
+ disconnect(d, &QDial::valueChanged, this, &qmpChannelEditor::commonChanged);
+ }
}
diff --git a/qmidiplayer-desktop/qmpchanneleditor.hpp b/qmidiplayer-desktop/qmpchanneleditor.hpp
index c7ef028..9749124 100644
--- a/qmidiplayer-desktop/qmpchanneleditor.hpp
+++ b/qmidiplayer-desktop/qmpchanneleditor.hpp
@@ -6,40 +6,41 @@
#include <QCloseEvent>
#include "qdialskulpturestyle.hpp"
-namespace Ui {
- class qmpChannelEditor;
+namespace Ui
+{
+class qmpChannelEditor;
}
class QDial;
-class qmpChannelEditor:public QDialog
+class qmpChannelEditor: public QDialog
{
- Q_OBJECT
+ Q_OBJECT
- public:
- explicit qmpChannelEditor(QWidget *parent=nullptr);
- ~qmpChannelEditor();
- protected:
- void showEvent(QShowEvent *e);
- void closeEvent(QCloseEvent *e);
- public slots:
- void setupWindow(int chid=-1);
+public:
+ explicit qmpChannelEditor(QWidget *parent = nullptr);
+ ~qmpChannelEditor();
+protected:
+ void showEvent(QShowEvent *e);
+ void closeEvent(QCloseEvent *e);
+public slots:
+ void setupWindow(int chid = -1);
- private slots:
- void commonPressed();
- void commonReleased();
- void commonChanged();
- void on_pbChLeft_clicked();
- void on_pbChRight_clicked();
+private slots:
+ void commonPressed();
+ void commonReleased();
+ void commonChanged();
+ void on_pbChLeft_clicked();
+ void on_pbChRight_clicked();
- private:
- Ui::qmpChannelEditor *ui;
- int ch,knobpressed;
- void sendCC();
- void connectSlots();
- void disconnectSlots();
- QList<QDial*> dials;
- QMetaObject::Connection updconn;
- QCommonStyle* styl;
+private:
+ Ui::qmpChannelEditor *ui;
+ int ch, knobpressed;
+ void sendCC();
+ void connectSlots();
+ void disconnectSlots();
+ QList<QDial *> dials;
+ QMetaObject::Connection updconn;
+ QCommonStyle *styl;
};
#endif // QMPCHANNELEDITOR_H
diff --git a/qmidiplayer-desktop/qmpchannelswindow.cpp b/qmidiplayer-desktop/qmpchannelswindow.cpp
index 0854e4c..e22d75e 100644
--- a/qmidiplayer-desktop/qmpchannelswindow.cpp
+++ b/qmidiplayer-desktop/qmpchannelswindow.cpp
@@ -9,360 +9,394 @@
#include "ui_qmpchannelswindow.h"
#include "qmpmainwindow.hpp"
-qmpChannelsModel::qmpChannelsModel(QObject*parent):QAbstractTableModel(parent)
+qmpChannelsModel::qmpChannelsModel(QObject *parent): QAbstractTableModel(parent)
{
- evh=qmpMainWindow::getInstance()->getPlayer()->registerEventHandler(
- [this](const void* _e,void*){
- if(!updatequeued)
- {
- updatequeued=true;
- const SEvent *e=(const SEvent*)(_e);
- if((e->p1&0xF0)==0xC0)
- emit dataChanged(index(e->p1&0xF0,4),index(e->p1&0xF0,4),{Qt::ItemDataRole::DisplayRole});
- QMetaObject::invokeMethod(this, &qmpChannelsModel::updateChannelActivity, Qt::ConnectionType::QueuedConnection);
- }
- }
- ,nullptr,false);
- QTimer*t=new QTimer(this);
- t->setInterval(500);
- t->setSingleShot(false);
- connect(t,&QTimer::timeout,[this](){emit this->dataChanged(this->index(0,4),this->index(15,4),{Qt::ItemDataRole::DisplayRole});});
- memset(mute,0,sizeof(mute));
- memset(solo,0,sizeof(solo));
+ evh = qmpMainWindow::getInstance()->getPlayer()->registerEventHandler(
+ [this](const void *_e, void *)
+ {
+ if (!updatequeued)
+ {
+ updatequeued = true;
+ const SEvent *e = (const SEvent *)(_e);
+ if ((e->p1 & 0xF0) == 0xC0)
+ emit dataChanged(index(e->p1 & 0xF0, 4), index(e->p1 & 0xF0, 4), {Qt::ItemDataRole::DisplayRole});
+ QMetaObject::invokeMethod(this, &qmpChannelsModel::updateChannelActivity, Qt::ConnectionType::QueuedConnection);
+ }
+ }
+ , nullptr, false);
+ QTimer *t = new QTimer(this);
+ t->setInterval(500);
+ t->setSingleShot(false);
+ connect(t, &QTimer::timeout, [this]()
+ {
+ emit this->dataChanged(this->index(0, 4), this->index(15, 4), {Qt::ItemDataRole::DisplayRole});
+ });
+ memset(mute, 0, sizeof(mute));
+ memset(solo, 0, sizeof(solo));
}
-int qmpChannelsModel::columnCount(const QModelIndex&parent)const
-{return parent.isValid()?0:6;}
-int qmpChannelsModel::rowCount(const QModelIndex&parent)const
-{return parent.isValid()?0:16;}
-QModelIndex qmpChannelsModel::parent(const QModelIndex&child)const
+int qmpChannelsModel::columnCount(const QModelIndex &parent)const
{
- Q_UNUSED(child)
- return QModelIndex();
+ return parent.isValid() ? 0 : 6;
}
-QVariant qmpChannelsModel::data(const QModelIndex&index,int role)const
+int qmpChannelsModel::rowCount(const QModelIndex &parent)const
{
- switch(index.column())
- {
- case 0:
- if(role==Qt::ItemDataRole::DecorationRole)
- {
- using namespace std::chrono_literals;
- bool lit=(std::chrono::system_clock::now()-qmpMainWindow::getInstance()->getPlayer()->getLastEventTS()[index.row()])<50ms;
- return lit?QIcon(":/img/ledon.svg"):QIcon(":/img/ledoff.svg");
- }
- break;
- case 1:
- if(role==Qt::ItemDataRole::CheckStateRole)
- return mute[index.row()]?Qt::CheckState::Checked:Qt::CheckState::Unchecked;
- break;
- case 2:
- if(role==Qt::ItemDataRole::CheckStateRole)
- return solo[index.row()]?Qt::CheckState::Checked:Qt::CheckState::Unchecked;
- break;
- case 3:
- if(role==Qt::ItemDataRole::DisplayRole)
- {
- std::vector<std::string> devs=qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices();
- return QString::fromStdString(devs[qmpMainWindow::getInstance()->getPlayer()->getChannelOutput(index.row())]);
- }
- break;
- case 4:
- {
- if(role==Qt::ItemDataRole::DisplayRole)
- {
- int ch=index.row();
- uint16_t b;uint8_t p;
- std::string nm;
- char data[256];
- CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
- bool r=plyr->getChannelOutputDevice(ch)->getChannelPreset(ch,&b,&p,nm);
- sprintf(data,"%03d:%03d %s",b,p,nm.c_str());
- if(!r)
- {
- nm=plyr->getChannelOutputDevice(ch)->getPresetName(plyr->getCC(ch,0)<<7|plyr->getCC(ch,32),plyr->getCC(ch,128));
- sprintf(data,"%03d:%03d:%03d %s",plyr->getCC(ch,0),plyr->getCC(ch,32),plyr->getCC(ch,128),nm.c_str());
- }
- return QString(data);
- }
- }
- break;
- case 5:
- if(role==Qt::ItemDataRole::DisplayRole)
- return "...";
- if(role==Qt::ItemDataRole::TextAlignmentRole)
- return Qt::AlignmentFlag::AlignCenter;
- break;
- }
- return QVariant();
+ return parent.isValid() ? 0 : 16;
}
-bool qmpChannelsModel::setData(const QModelIndex&index,const QVariant&value,int role)
+QModelIndex qmpChannelsModel::parent(const QModelIndex &child)const
{
- if(index.column()==3)
- {
- if(role!=Qt::ItemDataRole::DisplayRole)return false;
- std::vector<std::string> dsv=CMidiPlayer::getInstance()->getMidiOutDevices();
- int idx=std::find(dsv.begin(),dsv.end(),value.toString().toStdString())-dsv.begin();
- if(idx==CMidiPlayer::getInstance()->getChannelOutput(index.row()))return false;
- CMidiPlayer::getInstance()->setChannelOutput(index.row(),idx);
- emit dataChanged(index,index,{Qt::DisplayRole});
- return true;
- }
- return false;
+ Q_UNUSED(child)
+ return QModelIndex();
}
-QVariant qmpChannelsModel::headerData(int section,Qt::Orientation orientation,int role)const
+QVariant qmpChannelsModel::data(const QModelIndex &index, int role)const
{
- if(role!=Qt::ItemDataRole::DisplayRole)return QVariant();
- if(orientation==Qt::Orientation::Vertical)
- return section+1;
- switch(section)
- {
- case 0:return QString("A");
- case 1:return QString("M");
- case 2:return QString("S");
- case 3:return QString("Device");
- case 4:return QString("Preset");
- case 5:return QString("...");
- }
- return QString();
+ switch (index.column())
+ {
+ case 0:
+ if (role == Qt::ItemDataRole::DecorationRole)
+ {
+ using namespace std::chrono_literals;
+ bool lit = (std::chrono::system_clock::now() - qmpMainWindow::getInstance()->getPlayer()->getLastEventTS()[index.row()]) < 50ms;
+ return lit ? QIcon(":/img/ledon.svg") : QIcon(":/img/ledoff.svg");
+ }
+ break;
+ case 1:
+ if (role == Qt::ItemDataRole::CheckStateRole)
+ return mute[index.row()] ? Qt::CheckState::Checked : Qt::CheckState::Unchecked;
+ break;
+ case 2:
+ if (role == Qt::ItemDataRole::CheckStateRole)
+ return solo[index.row()] ? Qt::CheckState::Checked : Qt::CheckState::Unchecked;
+ break;
+ case 3:
+ if (role == Qt::ItemDataRole::DisplayRole)
+ {
+ std::vector<std::string> devs = qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices();
+ return QString::fromStdString(devs[qmpMainWindow::getInstance()->getPlayer()->getChannelOutput(index.row())]);
+ }
+ break;
+ case 4:
+ {
+ if (role == Qt::ItemDataRole::DisplayRole)
+ {
+ int ch = index.row();
+ uint16_t b;
+ uint8_t p;
+ std::string nm;
+ char data[256];
+ CMidiPlayer *plyr = qmpMainWindow::getInstance()->getPlayer();
+ bool r = plyr->getChannelOutputDevice(ch)->getChannelPreset(ch, &b, &p, nm);
+ sprintf(data, "%03d:%03d %s", b, p, nm.c_str());
+ if (!r)
+ {
+ nm = plyr->getChannelOutputDevice(ch)->getPresetName(plyr->getCC(ch, 0) << 7 | plyr->getCC(ch, 32), plyr->getCC(ch, 128));
+ sprintf(data, "%03d:%03d:%03d %s", plyr->getCC(ch, 0), plyr->getCC(ch, 32), plyr->getCC(ch, 128), nm.c_str());
+ }
+ return QString(data);
+ }
+ }
+ break;
+ case 5:
+ if (role == Qt::ItemDataRole::DisplayRole)
+ return "...";
+ if (role == Qt::ItemDataRole::TextAlignmentRole)
+ return Qt::AlignmentFlag::AlignCenter;
+ break;
+ }
+ return QVariant();
}
-Qt::ItemFlags qmpChannelsModel::flags(const QModelIndex&idx)const
+bool qmpChannelsModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
- Qt::ItemFlags ret=Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable;
- if(idx.column()==1||idx.column()==2)
- ret|=Qt::ItemFlag::ItemIsUserCheckable;
- if(idx.column()==3)
- ret|=Qt::ItemFlag::ItemIsEditable;
- return ret;
+ if (index.column() == 3)
+ {
+ if (role != Qt::ItemDataRole::DisplayRole)
+ return false;
+ std::vector<std::string> dsv = CMidiPlayer::getInstance()->getMidiOutDevices();
+ int idx = std::find(dsv.begin(), dsv.end(), value.toString().toStdString()) - dsv.begin();
+ if (idx == CMidiPlayer::getInstance()->getChannelOutput(index.row()))
+ return false;
+ CMidiPlayer::getInstance()->setChannelOutput(index.row(), idx);
+ emit dataChanged(index, index, {Qt::DisplayRole});
+ return true;
+ }
+ return false;
+}
+QVariant qmpChannelsModel::headerData(int section, Qt::Orientation orientation, int role)const
+{
+ if (role != Qt::ItemDataRole::DisplayRole)
+ return QVariant();
+ if (orientation == Qt::Orientation::Vertical)
+ return section + 1;
+ switch (section)
+ {
+ case 0:
+ return QString("A");
+ case 1:
+ return QString("M");
+ case 2:
+ return QString("S");
+ case 3:
+ return QString("Device");
+ case 4:
+ return QString("Preset");
+ case 5:
+ return QString("...");
+ }
+ return QString();
+}
+Qt::ItemFlags qmpChannelsModel::flags(const QModelIndex &idx)const
+{
+ Qt::ItemFlags ret = Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable;
+ if (idx.column() == 1 || idx.column() == 2)
+ ret |= Qt::ItemFlag::ItemIsUserCheckable;
+ if (idx.column() == 3)
+ ret |= Qt::ItemFlag::ItemIsEditable;
+ return ret;
}
void qmpChannelsModel::updateChannelActivity()
{
- emit dataChanged(index(0,0),index(15,0),{Qt::ItemDataRole::DecorationRole});
- updatequeued=false;
+ emit dataChanged(index(0, 0), index(15, 0), {Qt::ItemDataRole::DecorationRole});
+ updatequeued = false;
}
-void qmpChannelsModel::channelMSClicked(const QModelIndex&idx)
+void qmpChannelsModel::channelMSClicked(const QModelIndex &idx)
{
- bool*x[3]={nullptr,mute,solo};
- if(x[idx.column()][idx.row()]^=1)
- x[3-idx.column()][idx.row()]=0;
- qmpMainWindow::getInstance()->getPlayer()->setMute(idx.row(),mute[idx.row()]);
- qmpMainWindow::getInstance()->getPlayer()->setSolo(idx.row(),solo[idx.row()]);
- emit dataChanged(index(idx.row(),1),index(idx.row(),2),{Qt::ItemDataRole::CheckStateRole});
+ bool *x[3] = {nullptr, mute, solo};
+ if (x[idx.column()][idx.row()] ^= 1)
+ x[3 - idx.column()][idx.row()] = 0;
+ qmpMainWindow::getInstance()->getPlayer()->setMute(idx.row(), mute[idx.row()]);
+ qmpMainWindow::getInstance()->getPlayer()->setSolo(idx.row(), solo[idx.row()]);
+ emit dataChanged(index(idx.row(), 1), index(idx.row(), 2), {Qt::ItemDataRole::CheckStateRole});
}
void qmpChannelsModel::channelMSClearAll(int type)
{
- if(type==1)
- {
- memset(mute,0,sizeof(mute));
- for(int i=0;i<16;++i)
- qmpMainWindow::getInstance()->getPlayer()->setMute(i,0);
- emit dataChanged(index(0,1),index(15,1),{Qt::ItemDataRole::CheckStateRole});
- }
- if(type==2)
- {
- memset(solo,0,sizeof(solo));
- for(int i=0;i<16;++i)
- qmpMainWindow::getInstance()->getPlayer()->setSolo(i,0);
- emit dataChanged(index(0,2),index(15,2),{Qt::ItemDataRole::CheckStateRole});
- }
+ if (type == 1)
+ {
+ memset(mute, 0, sizeof(mute));
+ for (int i = 0; i < 16; ++i)
+ qmpMainWindow::getInstance()->getPlayer()->setMute(i, 0);
+ emit dataChanged(index(0, 1), index(15, 1), {Qt::ItemDataRole::CheckStateRole});
+ }
+ if (type == 2)
+ {
+ memset(solo, 0, sizeof(solo));
+ for (int i = 0; i < 16; ++i)
+ qmpMainWindow::getInstance()->getPlayer()->setSolo(i, 0);
+ emit dataChanged(index(0, 2), index(15, 2), {Qt::ItemDataRole::CheckStateRole});
+ }
}
-qmpDeviceItemDelegate::qmpDeviceItemDelegate(bool ignoreInternal,QWidget*parent):
- QStyledItemDelegate(parent),par(parent),nofs(ignoreInternal){}
-void qmpDeviceItemDelegate::paint(QPainter*painter,const QStyleOptionViewItem&option,const QModelIndex&index)const
+qmpDeviceItemDelegate::qmpDeviceItemDelegate(bool ignoreInternal, QWidget *parent):
+ QStyledItemDelegate(parent), par(parent), nofs(ignoreInternal) {}
+void qmpDeviceItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)const
{
- QStyleOptionViewItem opt;
- initStyleOption(&opt,index);
- QStyleOptionComboBox socb;
- socb.currentText=opt.text;
- socb.editable=false;
- socb.rect=option.rect;
- socb.state=opt.state;
- par->style()->drawComplexControl(QStyle::ComplexControl::CC_ComboBox,&socb,painter,option.widget);
- par->style()->drawControl(QStyle::CE_ComboBoxLabel,&socb,painter,option.widget);
+ QStyleOptionViewItem opt;
+ initStyleOption(&opt, index);
+ QStyleOptionComboBox socb;
+ socb.currentText = opt.text;
+ socb.editable = false;
+ socb.rect = option.rect;
+ socb.state = opt.state;
+ par->style()->drawComplexControl(QStyle::ComplexControl::CC_ComboBox, &socb, painter, option.widget);
+ par->style()->drawControl(QStyle::CE_ComboBoxLabel, &socb, painter, option.widget);
}
-QSize qmpDeviceItemDelegate::sizeHint(const QStyleOptionViewItem&option,const QModelIndex&index)const
+QSize qmpDeviceItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index)const
{
- QStyleOptionViewItem opt;
- initStyleOption(&opt,index);
- QStyleOptionComboBox socb;
- socb.currentText=opt.text;
- socb.editable=false;
- socb.rect=option.rect;
- QSize sz=par->fontMetrics().size(Qt::TextFlag::TextSingleLine,socb.currentText);
- return par->style()->sizeFromContents(QStyle::ContentsType::CT_ComboBox,&socb,sz,option.widget);
+ QStyleOptionViewItem opt;
+ initStyleOption(&opt, index);
+ QStyleOptionComboBox socb;
+ socb.currentText = opt.text;
+ socb.editable = false;
+ socb.rect = option.rect;
+ QSize sz = par->fontMetrics().size(Qt::TextFlag::TextSingleLine, socb.currentText);
+ return par->style()->sizeFromContents(QStyle::ContentsType::CT_ComboBox, &socb, sz, option.widget);
}
-QWidget* qmpDeviceItemDelegate::createEditor(QWidget*parent,const QStyleOptionViewItem&option,const QModelIndex&index)const
+QWidget *qmpDeviceItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index)const
{
- Q_UNUSED(option)
- Q_UNUSED(index)
- QComboBox *cb=new QComboBox(parent);
- cb->setEditable(false);
- connect(cb,static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),this,[index,cb](int){
- const_cast<QAbstractItemModel*>(index.model())->setData(index,cb->currentText(),Qt::ItemDataRole::DisplayRole);
- cb->hidePopup();
- });
- return cb;
+ Q_UNUSED(option)
+ Q_UNUSED(index)
+ QComboBox *cb = new QComboBox(parent);
+ cb->setEditable(false);
+ connect(cb, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [index, cb](int)
+ {
+ const_cast<QAbstractItemModel *>(index.model())->setData(index, cb->currentText(), Qt::ItemDataRole::DisplayRole);
+ cb->hidePopup();
+ });
+ return cb;
}
-void qmpDeviceItemDelegate::setEditorData(QWidget*widget,const QModelIndex&index)const
+void qmpDeviceItemDelegate::setEditorData(QWidget *widget, const QModelIndex &index)const
{
- /*
- * We want to quit editing as soon as the popup of the combobox is closed.
- * Unfortunately QTableView does not do that. And I don't feel like sub-classing
- * it. So here are some dirty tricks to make it work that way.
- */
- QComboBox *cb=qobject_cast<QComboBox*>(widget);
- QSignalBlocker sblk(cb);
- cb->clear();
- std::vector<std::string> devs=qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices();
- for(auto s:devs)
- if(!nofs||(nofs&&s!="Internal FluidSynth"))
- cb->addItem(QString::fromStdString(s));
- cb->setCurrentText(index.data().toString());
- cb->showPopup();
+ /*
+ * We want to quit editing as soon as the popup of the combobox is closed.
+ * Unfortunately QTableView does not do that. And I don't feel like sub-classing
+ * it. So here are some dirty tricks to make it work that way.
+ */
+ QComboBox *cb = qobject_cast<QComboBox *>(widget);
+ QSignalBlocker sblk(cb);
+ cb->clear();
+ std::vector<std::string> devs = qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices();
+ for (auto s : devs)
+ if (!nofs || (nofs && s != "Internal FluidSynth"))
+ cb->addItem(QString::fromStdString(s));
+ cb->setCurrentText(index.data().toString());
+ cb->showPopup();
}
-void qmpDeviceItemDelegate::setModelData(QWidget*editor,QAbstractItemModel*model,const QModelIndex&index)const
+void qmpDeviceItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index)const
{
- QComboBox *cb=qobject_cast<QComboBox*>(editor);
- model->setData(index,cb->currentText(),Qt::ItemDataRole::DisplayRole);
+ QComboBox *cb = qobject_cast<QComboBox *>(editor);
+ model->setData(index, cb->currentText(), Qt::ItemDataRole::DisplayRole);
}
-void qmpDeviceItemDelegate::updateEditorGeometry(QWidget*editor,const QStyleOptionViewItem&option,const QModelIndex&index)const
+void qmpDeviceItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index)const
{
- Q_UNUSED(index)
- editor->setGeometry(option.rect);
+ Q_UNUSED(index)
+ editor->setGeometry(option.rect);
}
-qmpChannelsWindow::qmpChannelsWindow(QWidget *parent) :
- QWidget(parent,Qt::Dialog),
- ui(new Ui::qmpChannelsWindow)
+qmpChannelsWindow::qmpChannelsWindow(QWidget *parent):
+ QWidget(parent, Qt::Dialog),
+ ui(new Ui::qmpChannelsWindow)
{
- ui->setupUi(this);
- mainwindow=qmpMainWindow::getInstance();
- ui->tvChannels->setHorizontalHeader(new QHeaderView(Qt::Orientation::Horizontal));
- ui->tvChannels->setModel(chmodel=new qmpChannelsModel(ui->tvChannels));
- ui->tvChannels->setItemDelegateForColumn(3,new qmpDeviceItemDelegate(false,ui->tvChannels));
- ui->tvChannels->setAlternatingRowColors(true);
- ui->tvChannels->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
- ui->tvChannels->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);
- ui->tvChannels->horizontalHeader()->setSectionResizeMode(4, QHeaderView::ResizeMode::Stretch);
- connect(ui->tvChannels,&QTableView::clicked,[this](const QModelIndex&idx){
- if(idx.column()==1||idx.column()==2)
- this->chmodel->channelMSClicked(idx);
- if(idx.column()==3)
- this->ui->tvChannels->edit(idx);
- if(idx.column()==5)
- this->showChannelEditorWindow(idx.row());
- });
- connect(ui->tvChannels,&QTableView::activated,[this](const QModelIndex&idx){
- if(idx.column()==4)
- {
- pselectw->show();
- pselectw->setupWindow(idx.row());
- }
- });
- pselectw=new qmpPresetSelector(this);
- ceditw=new qmpChannelEditor(this);
- cha=new QIcon(":/img/ledon.svg");chi=new QIcon(":/img/ledoff.svg");
- eh=qmpMainWindow::getInstance()->getPlayer()->registerEventHandler(
- [this](const void *ee,void*){
- const SEvent *e=(const SEvent*)ee;
- if((e->type&0xF0)==0x90&&e->p2>0&&(e->flags&0x01))
- emit this->noteOn();
- }
- ,nullptr,false);
- qmpMainWindow::getInstance()->registerFunctionality(
- chnlf=new qmpChannelFunc(this),
- std::string("Channel"),
- tr("Channel").toStdString(),
- getThemedIconc(":/img/channel.svg"),
- 0,
- true
- );
- if(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999))
- setGeometry(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect());
- if(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlWShown",0).toInt())
- {show();qmpMainWindow::getInstance()->setFuncState("Channel",true);}
+ ui->setupUi(this);
+ mainwindow = qmpMainWindow::getInstance();
+ ui->tvChannels->setHorizontalHeader(new QHeaderView(Qt::Orientation::Horizontal));
+ ui->tvChannels->setModel(chmodel = new qmpChannelsModel(ui->tvChannels));
+ ui->tvChannels->setItemDelegateForColumn(3, new qmpDeviceItemDelegate(false, ui->tvChannels));
+ ui->tvChannels->setAlternatingRowColors(true);
+ ui->tvChannels->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
+ ui->tvChannels->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);
+ ui->tvChannels->horizontalHeader()->setSectionResizeMode(4, QHeaderView::ResizeMode::Stretch);
+ connect(ui->tvChannels, &QTableView::clicked, [this](const QModelIndex &idx)
+ {
+ if (idx.column() == 1 || idx.column() == 2)
+ this->chmodel->channelMSClicked(idx);
+ if (idx.column() == 3)
+ this->ui->tvChannels->edit(idx);
+ if (idx.column() == 5)
+ this->showChannelEditorWindow(idx.row());
+ });
+ connect(ui->tvChannels, &QTableView::activated, [this](const QModelIndex &idx)
+ {
+ if (idx.column() == 4)
+ {
+ pselectw->show();
+ pselectw->setupWindow(idx.row());
+ }
+ });
+ pselectw = new qmpPresetSelector(this);
+ ceditw = new qmpChannelEditor(this);
+ cha = new QIcon(":/img/ledon.svg");
+ chi = new QIcon(":/img/ledoff.svg");
+ eh = qmpMainWindow::getInstance()->getPlayer()->registerEventHandler(
+ [this](const void *ee, void *)
+ {
+ const SEvent *e = (const SEvent *)ee;
+ if ((e->type & 0xF0) == 0x90 && e->p2 > 0 && (e->flags & 0x01))
+ emit this->noteOn();
+ }
+ , nullptr, false);
+ qmpMainWindow::getInstance()->registerFunctionality(
+ chnlf = new qmpChannelFunc(this),
+ std::string("Channel"),
+ tr("Channel").toStdString(),
+ getThemedIconc(":/img/channel.svg"),
+ 0,
+ true
+ );
+ if (mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW", QRect(-999, -999, 999, 999)).toRect() != QRect(-999, -999, 999, 999))
+ setGeometry(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW", QRect(-999, -999, 999, 999)).toRect());
+ if (mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlWShown", 0).toInt())
+ {
+ show();
+ qmpMainWindow::getInstance()->setFuncState("Channel", true);
+ }
}
void qmpChannelsWindow::showEvent(QShowEvent *event)
{
- if(mainwindow->getSettings()->getOptionBool("Behavior/DialogStatus"))
- {
- mainwindow->getSettings()->setOptionRaw("DialogStatus/ChnlWShown",1);
- }
- if(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999))
- setGeometry(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW",QRect(-999,-999,999,999)).toRect());
- event->accept();
+ if (mainwindow->getSettings()->getOptionBool("Behavior/DialogStatus"))
+ {
+ mainwindow->getSettings()->setOptionRaw("DialogStatus/ChnlWShown", 1);
+ }
+ if (mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW", QRect(-999, -999, 999, 999)).toRect() != QRect(-999, -999, 999, 999))
+ setGeometry(mainwindow->getSettings()->getOptionRaw("DialogStatus/ChnlW", QRect(-999, -999, 999, 999)).toRect());
+ event->accept();
}
void qmpChannelsWindow::closeEvent(QCloseEvent *event)
{
- if(mainwindow->getSettings()->getOptionBool("Behavior/DialogStatus"))
- {
- mainwindow->getSettings()->setOptionRaw("DialogStatus/ChnlW",geometry());
- }
- setVisible(false);
- if(!qmpMainWindow::getInstance()->isFinalizing()&&mainwindow->getSettings()->getOptionBool("Behavior/DialogStatus"))
- {
- mainwindow->getSettings()->setOptionRaw("DialogStatus/ChnlWShown",0);
- }
- mainwindow->setFuncState("Channel",false);
- event->accept();
+ if (mainwindow->getSettings()->getOptionBool("Behavior/DialogStatus"))
+ {
+ mainwindow->getSettings()->setOptionRaw("DialogStatus/ChnlW", geometry());
+ }
+ setVisible(false);
+ if (!qmpMainWindow::getInstance()->isFinalizing() && mainwindow->getSettings()->getOptionBool("Behavior/DialogStatus"))
+ {
+ mainwindow->getSettings()->setOptionRaw("DialogStatus/ChnlWShown", 0);
+ }
+ mainwindow->setFuncState("Channel", false);
+ event->accept();
}
void qmpChannelsWindow::selectDefaultDevice()
{
- std::string selecteddev;
- std::vector<std::string> devs=mainwindow->getPlayer()->getMidiOutDevices();
- size_t devc=devs.size();
- std::set<std::string> devset;
- for(auto dev:devs)devset.insert(dev);
- QVariant *devpriov=static_cast<QVariant*>(qmpMainWindow::getInstance()->getSettings()->getOptionCustom("Midi/DevicePriority"));
- QList<QVariant> devprio=devpriov->toList();
- delete devpriov;
- for(auto &setdev:devprio)
- if(devset.find(setdev.toString().toStdString())!=devset.end())
- {
- selecteddev=setdev.toString().toStdString();
- break;
- }
- for(int ch=0;ch<16;++ch)
- {
- for(size_t j=0;j<devc;++j)
- {
- if(selecteddev==devs[j])
- mainwindow->getPlayer()->setChannelOutput(ch,j);
- }
- }
+ std::string selecteddev;
+ std::vector<std::string> devs = mainwindow->getPlayer()->getMidiOutDevices();
+ size_t devc = devs.size();
+ std::set<std::string> devset;
+ for (auto dev : devs)
+ devset.insert(dev);
+ QVariant *devpriov = static_cast<QVariant *>(qmpMainWindow::getInstance()->getSettings()->getOptionCustom("Midi/DevicePriority"));
+ QList<QVariant> devprio = devpriov->toList();
+ delete devpriov;
+ for (auto &setdev : devprio)
+ if (devset.find(setdev.toString().toStdString()) != devset.end())
+ {
+ selecteddev = setdev.toString().toStdString();
+ break;
+ }
+ for (int ch = 0; ch < 16; ++ch)
+ {
+ for (size_t j = 0; j < devc; ++j)
+ {
+ if (selecteddev == devs[j])
+ mainwindow->getPlayer()->setChannelOutput(ch, j);
+ }
+ }
}
qmpChannelsWindow::~qmpChannelsWindow()
{
- mainwindow->unregisterFunctionality("Channel");
- mainwindow->getPlayer()->unregisterEventHandler(eh);
- delete chnlf;
- delete chi;delete cha;
- delete ui;
+ mainwindow->unregisterFunctionality("Channel");
+ mainwindow->getPlayer()->unregisterEventHandler(eh);
+ delete chnlf;
+ delete chi;
+ delete cha;
+ delete ui;
}
void qmpChannelsWindow::on_pbUnmute_clicked()
{
- chmodel->channelMSClearAll(1);
+ chmodel->channelMSClearAll(1);
}
void qmpChannelsWindow::on_pbUnsolo_clicked()
{
- chmodel->channelMSClearAll(2);
+ chmodel->channelMSClearAll(2);
}
void qmpChannelsWindow::showChannelEditorWindow(int chid)
{
- ceditw->show();
- ceditw->setupWindow(chid);
+ ceditw->show();
+ ceditw->setupWindow(chid);
}
qmpChannelFunc::qmpChannelFunc(qmpChannelsWindow *par)
-{p=par;}
+{
+ p = par;
+}
void qmpChannelFunc::show()
-{p->show();}
+{
+ p->show();
+}
void qmpChannelFunc::close()
-{p->close();}
+{
+ p->close();
+}
diff --git a/qmidiplayer-desktop/qmpchannelswindow.hpp b/qmidiplayer-desktop/qmpchannelswindow.hpp
index f78d032..c8443e7 100644
--- a/qmidiplayer-desktop/qmpchannelswindow.hpp
+++ b/qmidiplayer-desktop/qmpchannelswindow.hpp
@@ -15,88 +15,89 @@
#include "../core/qmpmidiplay.hpp"
#include "../core/qmpmidioutrtmidi.hpp"
-namespace Ui {
- class qmpChannelsWindow;
+namespace Ui
+{
+class qmpChannelsWindow;
}
class qmpChannelsWindow;
class qmpMainWindow;
-class qmpChannelFunc:public qmpFuncBaseIntf
+class qmpChannelFunc : public qmpFuncBaseIntf
{
- private:
- qmpChannelsWindow *p;
- public:
- qmpChannelFunc(qmpChannelsWindow *par);
- void show();
- void close();
+private:
+ qmpChannelsWindow *p;
+public:
+ qmpChannelFunc(qmpChannelsWindow *par);
+ void show();
+ void close();
};
-class qmpChannelsModel:public QAbstractTableModel
+class qmpChannelsModel : public QAbstractTableModel
{
- Q_OBJECT
- public:
- explicit qmpChannelsModel(QObject*parent=nullptr);
- int columnCount(const QModelIndex&parent=QModelIndex())const override;
- int rowCount(const QModelIndex&parent=QModelIndex())const override;
- QModelIndex parent(const QModelIndex&child)const override;
- QVariant data(const QModelIndex&index,int role=Qt::ItemDataRole::DisplayRole)const override;
- bool setData(const QModelIndex &index,const QVariant &value,int role=Qt::EditRole)override;
- QVariant headerData(int section,Qt::Orientation orientation,int role=Qt::ItemDataRole::DisplayRole)const override;
- Qt::ItemFlags flags(const QModelIndex&idx)const override;
- public slots:
- void updateChannelActivity();
- void channelMSClicked(const QModelIndex&idx);
- void channelMSClearAll(int type);
- private:
- int evh;
- bool updatequeued;
- bool mute[16],solo[16];
+ Q_OBJECT
+public:
+ explicit qmpChannelsModel(QObject *parent = nullptr);
+ int columnCount(const QModelIndex &parent = QModelIndex())const override;
+ int rowCount(const QModelIndex &parent = QModelIndex())const override;
+ QModelIndex parent(const QModelIndex &child)const override;
+ QVariant data(const QModelIndex &index, int role = Qt::ItemDataRole::DisplayRole)const override;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::ItemDataRole::DisplayRole)const override;
+ Qt::ItemFlags flags(const QModelIndex &idx)const override;
+public slots:
+ void updateChannelActivity();
+ void channelMSClicked(const QModelIndex &idx);
+ void channelMSClearAll(int type);
+private:
+ int evh;
+ bool updatequeued;
+ bool mute[16], solo[16];
};
-class qmpDeviceItemDelegate:public QStyledItemDelegate
+class qmpDeviceItemDelegate: public QStyledItemDelegate
{
- Q_OBJECT
- public:
- explicit qmpDeviceItemDelegate(bool ignoreInternal=false,QWidget*parent=nullptr);
- void paint(QPainter*painter,const QStyleOptionViewItem&option,const QModelIndex&index)const override;
- QSize sizeHint(const QStyleOptionViewItem&option,const QModelIndex&index)const override;
- QWidget* createEditor(QWidget*parent,const QStyleOptionViewItem&option,const QModelIndex&index)const override;
- void setEditorData(QWidget*editor,const QModelIndex&index)const override;
- void setModelData(QWidget*editor,QAbstractItemModel*model,const QModelIndex&index)const override;
- void updateEditorGeometry(QWidget*editor,const QStyleOptionViewItem&option,const QModelIndex&index)const override;
- private:
- QWidget *par;
- bool nofs;
+ Q_OBJECT
+public:
+ explicit qmpDeviceItemDelegate(bool ignoreInternal = false, QWidget *parent = nullptr);
+ void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)const override;
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index)const override;
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index)const override;
+ void setEditorData(QWidget *editor, const QModelIndex &index)const override;
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index)const override;
+ void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index)const override;
+private:
+ QWidget *par;
+ bool nofs;
};
-class qmpChannelsWindow:public QWidget
+class qmpChannelsWindow: public QWidget
{
- Q_OBJECT
+ Q_OBJECT
- public:
- explicit qmpChannelsWindow(QWidget *parent=nullptr);
- ~qmpChannelsWindow();
- void showEvent(QShowEvent *event);
- void closeEvent(QCloseEvent *event);
- void selectDefaultDevice();
- public slots:
- void showChannelEditorWindow(int chid);
- void on_pbUnmute_clicked();
- void on_pbUnsolo_clicked();
+public:
+ explicit qmpChannelsWindow(QWidget *parent = nullptr);
+ ~qmpChannelsWindow();
+ void showEvent(QShowEvent *event);
+ void closeEvent(QCloseEvent *event);
+ void selectDefaultDevice();
+public slots:
+ void showChannelEditorWindow(int chid);
+ void on_pbUnmute_clicked();
+ void on_pbUnsolo_clicked();
- signals:
- void noteOn();
+signals:
+ void noteOn();
- private:
- qmpMainWindow* mainwindow;
- Ui::qmpChannelsWindow *ui;
- qmpPresetSelector *pselectw;
- qmpChannelEditor *ceditw;
- qmpChannelsModel *chmodel;
- QIcon *cha,*chi;
- qmpChannelFunc *chnlf;
- int eh;
+private:
+ qmpMainWindow *mainwindow;
+ Ui::qmpChannelsWindow *ui;
+ qmpPresetSelector *pselectw;
+ qmpChannelEditor *ceditw;
+ qmpChannelsModel *chmodel;
+ QIcon *cha, *chi;
+ qmpChannelFunc *chnlf;
+ int eh;
};
#endif // QMPCHANNELSWINDOW_H
diff --git a/qmidiplayer-desktop/qmpcustomizewindow.cpp b/qmidiplayer-desktop/qmpcustomizewindow.cpp
index 0ea3228..f4346b4 100644
--- a/qmidiplayer-desktop/qmpcustomizewindow.cpp
+++ b/qmidiplayer-desktop/qmpcustomizewindow.cpp
@@ -9,83 +9,86 @@
#include "ui_qmpcustomizewindow.h"
qmpCustomizeWindow::qmpCustomizeWindow(QWidget *parent):
- QDialog(parent),
- ui(new Ui::qmpCustomizeWindow)
+ QDialog(parent),
+ ui(new Ui::qmpCustomizeWindow)
{
- ui->setupUi(this);
+ ui->setupUi(this);
}
qmpCustomizeWindow::~qmpCustomizeWindow()
{
- delete ui;
+ delete ui;
}
void qmpCustomizeWindow::load(void *data)
{
- ui->lwAvail->clear();
- ui->lwEnabled->clear();
- QList<QVariant> list=static_cast<QVariant*>(data)->toList();
- std::vector<std::string> v;
- for(auto i:list)
- v.push_back(i.toString().toStdString());
- std::map<std::string,qmpFuncPrivate>& m=qmpMainWindow::getInstance()->getFunc();
- std::set<std::string> s;
- for(auto i=v.begin();i!=v.end();++i)
- {
- if(m.find(*i)==m.end())continue;
- s.insert(*i);
- QListWidgetItem* it=new QListWidgetItem(
- m[*i].icon(),
- QString(m[*i].desc().c_str())
- );
- it->setToolTip(i->c_str());
- ui->lwEnabled->addItem(it);
- }
- for(auto i=m.begin();i!=m.end();++i)
- {
- if(s.find(i->first)==s.end())
- {
- QListWidgetItem* it=new QListWidgetItem(
- i->second.icon(),
- QString(i->second.desc().c_str())
- );
- it->setToolTip(i->first.c_str());
- ui->lwAvail->addItem(it);
- }
- }
+ ui->lwAvail->clear();
+ ui->lwEnabled->clear();
+ QList<QVariant> list = static_cast<QVariant *>(data)->toList();
+ std::vector<std::string> v;
+ for (auto i : list)
+ v.push_back(i.toString().toStdString());
+ std::map<std::string, qmpFuncPrivate> &m = qmpMainWindow::getInstance()->getFunc();
+ std::set<std::string> s;
+ for (auto i = v.begin(); i != v.end(); ++i)
+ {
+ if (m.find(*i) == m.end())
+ continue;
+ s.insert(*i);
+ QListWidgetItem *it = new QListWidgetItem(
+ m[*i].icon(),
+ QString(m[*i].desc().c_str())
+ );
+ it->setToolTip(i->c_str());
+ ui->lwEnabled->addItem(it);
+ }
+ for (auto i = m.begin(); i != m.end(); ++i)
+ {
+ if (s.find(i->first) == s.end())
+ {
+ QListWidgetItem *it = new QListWidgetItem(
+ i->second.icon(),
+ QString(i->second.desc().c_str())
+ );
+ it->setToolTip(i->first.c_str());
+ ui->lwAvail->addItem(it);
+ }
+ }
}
void *qmpCustomizeWindow::save()
{
- QList<QVariant> ret;
- for(int i=0;i<ui->lwEnabled->count();++i)
- {
- ret.push_back(QVariant(ui->lwEnabled->item(i)->toolTip()));
- }
- return new QVariant(ret);
+ QList<QVariant> ret;
+ for (int i = 0; i < ui->lwEnabled->count(); ++i)
+ {
+ ret.push_back(QVariant(ui->lwEnabled->item(i)->toolTip()));
+ }
+ return new QVariant(ret);
}
void qmpCustomizeWindow::on_tbAdd_clicked()
{
- if(!ui->lwAvail->currentItem())return;
- ui->lwEnabled->addItem(ui->lwAvail->takeItem(ui->lwAvail->currentRow()));
- ui->lwAvail->removeItemWidget(ui->lwAvail->currentItem());
+ if (!ui->lwAvail->currentItem())
+ return;
+ ui->lwEnabled->addItem(ui->lwAvail->takeItem(ui->lwAvail->currentRow()));
+ ui->lwAvail->removeItemWidget(ui->lwAvail->currentItem());
}
void qmpCustomizeWindow::on_tbRemove_clicked()
{
- if(!ui->lwEnabled->currentItem())return;
- ui->lwAvail->addItem(ui->lwEnabled->takeItem(ui->lwEnabled->currentRow()));
+ if (!ui->lwEnabled->currentItem())
+ return;
+ ui->lwAvail->addItem(ui->lwEnabled->takeItem(ui->lwEnabled->currentRow()));
}
void qmpCustomizeWindow::on_buttonBox_accepted()
{
- accept();
- close();
+ accept();
+ close();
}
void qmpCustomizeWindow::on_buttonBox_rejected()
{
- reject();
- close();
+ reject();
+ close();
}
diff --git a/qmidiplayer-desktop/qmpcustomizewindow.hpp b/qmidiplayer-desktop/qmpcustomizewindow.hpp
index 321c22e..002d2fc 100644
--- a/qmidiplayer-desktop/qmpcustomizewindow.hpp
+++ b/qmidiplayer-desktop/qmpcustomizewindow.hpp
@@ -3,28 +3,29 @@
#include <QDialog>
-namespace Ui {
+namespace Ui
+{
class qmpCustomizeWindow;
}
-class qmpCustomizeWindow:public QDialog
+class qmpCustomizeWindow: public QDialog
{
- Q_OBJECT
+ Q_OBJECT
- public:
- explicit qmpCustomizeWindow(QWidget *parent=nullptr);
- ~qmpCustomizeWindow();
- void load(void* data);
- void* save();
+public:
+ explicit qmpCustomizeWindow(QWidget *parent = nullptr);
+ ~qmpCustomizeWindow();
+ void load(void *data);
+ void *save();
- private slots:
- void on_tbAdd_clicked();
- void on_tbRemove_clicked();
- void on_buttonBox_accepted();
- void on_buttonBox_rejected();
+private slots:
+ void on_tbAdd_clicked();
+ void on_tbRemove_clicked();
+ void on_buttonBox_accepted();
+ void on_buttonBox_rejected();
- private:
- Ui::qmpCustomizeWindow *ui;
+private:
+ Ui::qmpCustomizeWindow *ui;
};
#endif // QMPCUSTOMIZEWINDOW_HPP
diff --git a/qmidiplayer-desktop/qmpdeviceprioritydialog.cpp b/qmidiplayer-desktop/qmpdeviceprioritydialog.cpp
index bf358d8..9c77e0a 100644
--- a/qmidiplayer-desktop/qmpdeviceprioritydialog.cpp
+++ b/qmidiplayer-desktop/qmpdeviceprioritydialog.cpp
@@ -6,107 +6,108 @@
#include "ui_qmpdeviceprioritydialog.h"
qmpDevicePriorityDialog::qmpDevicePriorityDialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::qmpDevicePriorityDialog)
+ QDialog(parent),
+ ui(new Ui::qmpDevicePriorityDialog)
{
- ui->setupUi(this);
- model=new QStandardItemModel(this);
- ui->tvDevices->setModel(model);
- ui->tvDevices->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
- ui->tvDevices->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);
- ui->tvDevices->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows);
- model->setHorizontalHeaderLabels({"E","Device","Connected?"});
+ ui->setupUi(this);
+ model = new QStandardItemModel(this);
+ ui->tvDevices->setModel(model);
+ ui->tvDevices->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
+ ui->tvDevices->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);
+ ui->tvDevices->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows);
+ model->setHorizontalHeaderLabels({"E", "Device", "Connected?"});
}
qmpDevicePriorityDialog::~qmpDevicePriorityDialog()
{
- delete ui;
+ delete ui;
}
void qmpDevicePriorityDialog::setupRegisteredDevices()
{
- std::set<std::string> sset,sconn;
- auto conndevs=CMidiPlayer::getInstance()->getMidiOutDevices();
- for(auto dev:conndevs)
- sconn.insert(dev);
- model->removeRows(0,model->rowCount());
- for(auto dev:setdevs)
- {
- QStandardItem *e=new QStandardItem;
- e->setCheckable(true);
- e->setEditable(false);
- e->setCheckState(Qt::CheckState::Checked);
- QStandardItem *a=new QStandardItem;
- a->setText(sconn.find(dev.toString().toStdString())!=sconn.end()?"Connected":"Disconnected");
- a->setEditable(false);
- QStandardItem *devn=new QStandardItem(dev.toString());
- devn->setEditable(false);
- model->appendRow({e,devn,a});
- sset.insert(dev.toString().toStdString());
- }
- for(auto dev:conndevs)
- {
- if(sset.find(dev)!=sset.end())continue;
- QStandardItem *e=new QStandardItem;
- e->setCheckable(true);
- e->setEditable(false);
- e->setCheckState(Qt::CheckState::Unchecked);
- QStandardItem *a=new QStandardItem;
- a->setText("Connected");
- a->setEditable(false);
- QStandardItem *devn=new QStandardItem(QString::fromStdString(dev));
- devn->setEditable(false);
- model->appendRow({e,devn,a});
- }
+ std::set<std::string> sset, sconn;
+ auto conndevs = CMidiPlayer::getInstance()->getMidiOutDevices();
+ for (auto dev : conndevs)
+ sconn.insert(dev);
+ model->removeRows(0, model->rowCount());
+ for (auto dev : setdevs)
+ {
+ QStandardItem *e = new QStandardItem;
+ e->setCheckable(true);
+ e->setEditable(false);
+ e->setCheckState(Qt::CheckState::Checked);
+ QStandardItem *a = new QStandardItem;
+ a->setText(sconn.find(dev.toString().toStdString()) != sconn.end() ? "Connected" : "Disconnected");
+ a->setEditable(false);
+ QStandardItem *devn = new QStandardItem(dev.toString());
+ devn->setEditable(false);
+ model->appendRow({e, devn, a});
+ sset.insert(dev.toString().toStdString());
+ }
+ for (auto dev : conndevs)
+ {
+ if (sset.find(dev) != sset.end())
+ continue;
+ QStandardItem *e = new QStandardItem;
+ e->setCheckable(true);
+ e->setEditable(false);
+ e->setCheckState(Qt::CheckState::Unchecked);
+ QStandardItem *a = new QStandardItem;
+ a->setText("Connected");
+ a->setEditable(false);
+ QStandardItem *devn = new QStandardItem(QString::fromStdString(dev));
+ devn->setEditable(false);
+ model->appendRow({e, devn, a});
+ }
}
void qmpDevicePriorityDialog::load(void *data)
{
- setdevs=static_cast<QVariant*>(data)->toList();
- setupRegisteredDevices();
+ setdevs = static_cast<QVariant *>(data)->toList();
+ setupRegisteredDevices();
}
void *qmpDevicePriorityDialog::save()
{
- QList<QVariant> ret;
- for(int i=0;i<model->rowCount();++i)
- if(model->item(i,0)->checkState()==Qt::CheckState::Checked)
- ret.push_back(model->item(i,1)->text());
- return new QVariant(ret);
+ QList<QVariant> ret;
+ for (int i = 0; i < model->rowCount(); ++i)
+ if (model->item(i, 0)->checkState() == Qt::CheckState::Checked)
+ ret.push_back(model->item(i, 1)->text());
+ return new QVariant(ret);
}
void qmpDevicePriorityDialog::on_pbUp_clicked()
{
- const QModelIndex &idx=ui->tvDevices->selectionModel()->currentIndex();
- if(idx.isValid()&&idx.row()>0)
- {
- int row=idx.row();
- auto r=model->takeRow(row);
- model->insertRow(row-1,r);
- ui->tvDevices->clearSelection();
- ui->tvDevices->selectionModel()->setCurrentIndex(model->index(row-1,idx.column()),QItemSelectionModel::Rows|QItemSelectionModel::Select);
- }
+ const QModelIndex &idx = ui->tvDevices->selectionModel()->currentIndex();
+ if (idx.isValid() && idx.row() > 0)
+ {
+ int row = idx.row();
+ auto r = model->takeRow(row);
+ model->insertRow(row - 1, r);
+ ui->tvDevices->clearSelection();
+ ui->tvDevices->selectionModel()->setCurrentIndex(model->index(row - 1, idx.column()), QItemSelectionModel::Rows | QItemSelectionModel::Select);
+ }
}
void qmpDevicePriorityDialog::on_pbDown_clicked()
{
- const QModelIndex &idx=ui->tvDevices->selectionModel()->currentIndex();
- if(idx.isValid()&&idx.row()<model->rowCount()-1)
- {
- int row=idx.row();
- auto r=model->takeRow(row);
- model->insertRow(row+1,r);
- ui->tvDevices->clearSelection();
- ui->tvDevices->selectionModel()->setCurrentIndex(model->index(row+1,idx.column()),QItemSelectionModel::Rows|QItemSelectionModel::Select);
- }
+ const QModelIndex &idx = ui->tvDevices->selectionModel()->currentIndex();
+ if (idx.isValid() && idx.row() < model->rowCount() - 1)
+ {
+ int row = idx.row();
+ auto r = model->takeRow(row);
+ model->insertRow(row + 1, r);
+ ui->tvDevices->clearSelection();
+ ui->tvDevices->selectionModel()->setCurrentIndex(model->index(row + 1, idx.column()), QItemSelectionModel::Rows | QItemSelectionModel::Select);
+ }
}
void qmpDevicePriorityDialog::on_buttonBox_accepted()
{
- accept();
+ accept();
}
void qmpDevicePriorityDialog::on_buttonBox_rejected()
{
- reject();
+ reject();
}
diff --git a/qmidiplayer-desktop/qmpdeviceprioritydialog.hpp b/qmidiplayer-desktop/qmpdeviceprioritydialog.hpp
index 78ce3fa..85170b9 100644
--- a/qmidiplayer-desktop/qmpdeviceprioritydialog.hpp
+++ b/qmidiplayer-desktop/qmpdeviceprioritydialog.hpp
@@ -5,32 +5,33 @@
#include <QShowEvent>
#include <QStandardItemModel>
-namespace Ui {
+namespace Ui
+{
class qmpDevicePriorityDialog;
}
-class qmpDevicePriorityDialog:public QDialog
+class qmpDevicePriorityDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit qmpDevicePriorityDialog(QWidget *parent=nullptr);
- ~qmpDevicePriorityDialog();
- void load(void* data);
- void* save();
+ explicit qmpDevicePriorityDialog(QWidget *parent = nullptr);
+ ~qmpDevicePriorityDialog();
+ void load(void *data);
+ void *save();
private slots:
- void on_pbUp_clicked();
- void on_pbDown_clicked();
- void on_buttonBox_accepted();
+ void on_pbUp_clicked();
+ void on_pbDown_clicked();
+ void on_buttonBox_accepted();
- void on_buttonBox_rejected();
+ void on_buttonBox_rejected();
- private:
- Ui::qmpDevicePriorityDialog *ui;
- QStandardItemModel *model;
- QList<QVariant> setdevs;
- void setupRegisteredDevices();
+private:
+ Ui::qmpDevicePriorityDialog *ui;
+ QStandardItemModel *model;
+ QList<QVariant> setdevs;
+ void setupRegisteredDevices();
};
#endif // QMPDEVICEPRIORITYDIALOG_HPP
diff --git a/qmidiplayer-desktop/qmpdevpropdialog.cpp b/qmidiplayer-desktop/qmpdevpropdialog.cpp
index 3b9ccc4..c5f1966 100644
--- a/qmidiplayer-desktop/qmpdevpropdialog.cpp
+++ b/qmidiplayer-desktop/qmpdevpropdialog.cpp
@@ -10,108 +10,113 @@
#include "ui_qmpdevpropdialog.h"
qmpDevPropDialog::qmpDevPropDialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::qmpDevPropDialog)
+ QDialog(parent),
+ ui(new Ui::qmpDevPropDialog)
{
- ui->setupUi(this);
- ui->twProps->setItemDelegateForColumn(0,new qmpDeviceItemDelegate(true,ui->twProps));
- ui->twProps->setEditTriggers(QAbstractItemView::EditTrigger::NoEditTriggers);
- connect(ui->twProps,&QTableWidget::cellClicked,[this](int r,int c){
- if(c==0)
- this->ui->twProps->edit(ui->twProps->model()->index(r,c));
- if(c==3)
- {
- QString p=QFileDialog::getOpenFileUrl(this,tr("Select Device Initialization File"),QUrl()).toLocalFile();
- if(p.length())this->ui->twProps->item(r,2)->setText(p);
- }
- });
- connect(ui->twProps,&QTableWidget::cellChanged,this,[this](int r,int c){
- if(c!=0)return;
- QString connst(tr("Disconnected"));
- for(auto&ds:qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices())
- if(ui->twProps->item(r,c)->text()==QString::fromStdString(ds))
- {
- connst=tr("Connected");
- break;
- }
- ui->twProps->item(r,1)->setText(connst);
- });
+ ui->setupUi(this);
+ ui->twProps->setItemDelegateForColumn(0, new qmpDeviceItemDelegate(true, ui->twProps));
+ ui->twProps->setEditTriggers(QAbstractItemView::EditTrigger::NoEditTriggers);
+ connect(ui->twProps, &QTableWidget::cellClicked, [this](int r, int c)
+ {
+ if (c == 0)
+ this->ui->twProps->edit(ui->twProps->model()->index(r, c));
+ if (c == 3)
+ {
+ QString p = QFileDialog::getOpenFileUrl(this, tr("Select Device Initialization File"), QUrl()).toLocalFile();
+ if (p.length())
+ this->ui->twProps->item(r, 2)->setText(p);
+ }
+ });
+ connect(ui->twProps, &QTableWidget::cellChanged, this, [this](int r, int c)
+ {
+ if (c != 0)
+ return;
+ QString connst(tr("Disconnected"));
+ for (auto &ds : qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices())
+ if (ui->twProps->item(r, c)->text() == QString::fromStdString(ds))
+ {
+ connst = tr("Connected");
+ break;
+ }
+ ui->twProps->item(r, 1)->setText(connst);
+ });
}
qmpDevPropDialog::~qmpDevPropDialog()
{
- delete ui;
+ delete ui;
}
void qmpDevPropDialog::load(void *data)
{
- QList<QVariant> lst=static_cast<QVariant*>(data)->toList();
- ui->twProps->clearContents();
- ui->twProps->setRowCount(0);
- for(auto&i:lst)
- {
- QPair<QString,QString> p=i.value<QPair<QString,QString>>();
- setupRow(p.first,p.second);
- }
+ QList<QVariant> lst = static_cast<QVariant *>(data)->toList();
+ ui->twProps->clearContents();
+ ui->twProps->setRowCount(0);
+ for (auto &i : lst)
+ {
+ QPair<QString, QString> p = i.value<QPair<QString, QString>>();
+ setupRow(p.first, p.second);
+ }
}
void *qmpDevPropDialog::save()
{
- QList<QVariant> ret;
- for(int i=0;i<ui->twProps->rowCount();++i)
- {
- QPair<QString,QString> p
- {
- ui->twProps->item(i,0)->text(),
- ui->twProps->item(i,2)->text()
- };
- ret.push_back(QVariant::fromValue(p));
- }
- return new QVariant(ret);
+ QList<QVariant> ret;
+ for (int i = 0; i < ui->twProps->rowCount(); ++i)
+ {
+ QPair<QString, QString> p
+ {
+ ui->twProps->item(i, 0)->text(),
+ ui->twProps->item(i, 2)->text()
+ };
+ ret.push_back(QVariant::fromValue(p));
+ }
+ return new QVariant(ret);
}
void qmpDevPropDialog::on_pbAdd_clicked()
{
- setupRow();
+ setupRow();
}
void qmpDevPropDialog::on_pbRemove_clicked()
{
- ui->twProps->removeRow(ui->twProps->currentRow());
+ ui->twProps->removeRow(ui->twProps->currentRow());
}
-void qmpDevPropDialog::setupRow(const QString&dn,const QString&din)
+void qmpDevPropDialog::setupRow(const QString &dn, const QString &din)
{
- int r;
- ui->twProps->insertRow(r=ui->twProps->rowCount());
- ui->twProps->setRowHeight(r,32);
- QTableWidgetItem *cbx=new QTableWidgetItem;
- ui->twProps->setItem(r,1,cbx);
- QTableWidgetItem *cb;
- ui->twProps->setItem(r,0,cb=new QTableWidgetItem);
- ui->twProps->setItem(r,2,new QTableWidgetItem);
- ui->twProps->setItem(r,3,new QTableWidgetItem("..."));
- if(din.length())ui->twProps->item(r,2)->setText(din);
- cbx->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable);
- cbx->setText(tr("Disconnected"));
- ui->twProps->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);
- if(dn.length())
- {
- cb->setText(dn);
- cb->setFlags(cb->flags()|Qt::ItemFlag::ItemIsEditable);
- std::vector<std::string> dsv=CMidiPlayer::getInstance()->getMidiOutDevices();
- if(std::find(dsv.begin(),dsv.end(),dn.toStdString())==dsv.end())
- cb->setFlags(cb->flags()&(~Qt::ItemFlag::ItemIsEnabled));
- else cb->setFlags(cb->flags()|Qt::ItemFlag::ItemIsEnabled);
- }
+ int r;
+ ui->twProps->insertRow(r = ui->twProps->rowCount());
+ ui->twProps->setRowHeight(r, 32);
+ QTableWidgetItem *cbx = new QTableWidgetItem;
+ ui->twProps->setItem(r, 1, cbx);
+ QTableWidgetItem *cb;
+ ui->twProps->setItem(r, 0, cb = new QTableWidgetItem);
+ ui->twProps->setItem(r, 2, new QTableWidgetItem);
+ ui->twProps->setItem(r, 3, new QTableWidgetItem("..."));
+ if (din.length())
+ ui->twProps->item(r, 2)->setText(din);
+ cbx->setFlags(Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable);
+ cbx->setText(tr("Disconnected"));
+ ui->twProps->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);
+ if (dn.length())
+ {
+ cb->setText(dn);
+ cb->setFlags(cb->flags() | Qt::ItemFlag::ItemIsEditable);
+ std::vector<std::string> dsv = CMidiPlayer::getInstance()->getMidiOutDevices();
+ if (std::find(dsv.begin(), dsv.end(), dn.toStdString()) == dsv.end())
+ cb->setFlags(cb->flags() & (~Qt::ItemFlag::ItemIsEnabled));
+ else cb->setFlags(cb->flags() | Qt::ItemFlag::ItemIsEnabled);
+ }
}
void qmpDevPropDialog::on_buttonBox_accepted()
{
- accept();
+ accept();
}
void qmpDevPropDialog::on_buttonBox_rejected()
{
- reject();
+ reject();
}
diff --git a/qmidiplayer-desktop/qmpdevpropdialog.hpp b/qmidiplayer-desktop/qmpdevpropdialog.hpp
index e98aba9..eb69d81 100644
--- a/qmidiplayer-desktop/qmpdevpropdialog.hpp
+++ b/qmidiplayer-desktop/qmpdevpropdialog.hpp
@@ -3,32 +3,33 @@
#include <QDialog>
-namespace Ui {
+namespace Ui
+{
class qmpDevPropDialog;
}
class qmpDevPropDialog : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
- public:
- explicit qmpDevPropDialog(QWidget *parent = nullptr);
- ~qmpDevPropDialog();
- void load(void* data);
- void* save();
+public:
+ explicit qmpDevPropDialog(QWidget *parent = nullptr);
+ ~qmpDevPropDialog();
+ void load(void *data);
+ void *save();
- private slots:
- void on_pbAdd_clicked();
+private slots:
+ void on_pbAdd_clicked();
- void on_pbRemove_clicked();
+ void on_pbRemove_clicked();
- void on_buttonBox_accepted();
+ void on_buttonBox_accepted();
- void on_buttonBox_rejected();
+ void on_buttonBox_rejected();
- private:
- Ui::qmpDevPropDialog *ui;
- void setupRow(const QString &dn="",const QString &din="");
+private:
+ Ui::qmpDevPropDialog *ui;
+ void setupRow(const QString &dn = QString(), const QString &din = QString());
};
#endif // QMPDEVPROPDIALOG_HPP
diff --git a/qmidiplayer-desktop/qmpefxwindow.cpp b/qmidiplayer-desktop/qmpefxwindow.cpp
index 7691756..ec1cef3 100644
--- a/qmidiplayer-desktop/qmpefxwindow.cpp
+++ b/qmidiplayer-desktop/qmpefxwindow.cpp
@@ -4,215 +4,296 @@
#include "qmpmainwindow.hpp"
qmpEfxWindow::qmpEfxWindow(QWidget *parent) :
- QWidget(parent,Qt::Dialog),
- ui(new Ui::qmpEfxWindow)
-{
- ui->setupUi(this);initialized=false;
- styl=new QDialSkulptureStyle();
- QList<QDial*> dials=findChildren<QDial*>();
- for(int i=0;i<dials.count();++i)
- dials.at(i)->setStyle(styl);
- qmpSettings *settings=qmpMainWindow::getInstance()->getSettings();
- ui->cbEnabledC->setChecked(settings->getOptionRaw("Effects/ChorusEnabled",1).toInt());
- ui->cbEnabledR->setChecked(settings->getOptionRaw("Effects/ReverbEnabled",1).toInt());
- rr=settings->getOptionRaw("Effects/ReverbRoom",0.2).toDouble();
- rd=settings->getOptionRaw("Effects/ReverbDamp",0.0).toDouble();
- rw=settings->getOptionRaw("Effects/ReverbWidth",0.5).toDouble();
- rl=settings->getOptionRaw("Effects/ReverbLevel",0.9).toDouble();
-
- cfb=settings->getOptionRaw("Effects/ChorusFeedbk",3).toInt();
- cl=settings->getOptionRaw("Effects/ChorusLevel",2.0).toDouble();
- cr=settings->getOptionRaw("Effects/ChorusRate",0.3).toDouble();
- cd=settings->getOptionRaw("Effects/ChorusDepth",8.0).toDouble();
- ct=settings->getOptionRaw("Effects/ChorusType",FLUID_CHORUS_MOD_SINE).toInt();
- qmpMainWindow::getInstance()->registerFunctionality(
- efxf=new qmpEfxFunc(this),
- std::string("Effects"),
- tr("Effects").toStdString(),
- getThemedIconc(":/img/effects.svg"),
- 0,
- true
- );
- if(settings->getOptionRaw("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999))
- setGeometry(settings->getOptionRaw("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect());
- if(settings->getOptionRaw("DialogStatus/EfxWShown",0).toInt())
- {show();qmpMainWindow::getInstance()->setFuncState("Effects",true);}
+ QWidget(parent, Qt::Dialog),
+ ui(new Ui::qmpEfxWindow)
+{
+ ui->setupUi(this);
+ initialized = false;
+ styl = new QDialSkulptureStyle();
+ QList<QDial *> dials = findChildren<QDial *>();
+ for (int i = 0; i < dials.count(); ++i)
+ dials.at(i)->setStyle(styl);
+ qmpSettings *settings = qmpMainWindow::getInstance()->getSettings();
+ ui->cbEnabledC->setChecked(settings->getOptionRaw("Effects/ChorusEnabled", 1).toInt());
+ ui->cbEnabledR->setChecked(settings->getOptionRaw("Effects/ReverbEnabled", 1).toInt());
+ rr = settings->getOptionRaw("Effects/ReverbRoom", 0.2).toDouble();
+ rd = settings->getOptionRaw("Effects/ReverbDamp", 0.0).toDouble();
+ rw = settings->getOptionRaw("Effects/ReverbWidth", 0.5).toDouble();
+ rl = settings->getOptionRaw("Effects/ReverbLevel", 0.9).toDouble();
+
+ cfb = settings->getOptionRaw("Effects/ChorusFeedbk", 3).toInt();
+ cl = settings->getOptionRaw("Effects/ChorusLevel", 2.0).toDouble();
+ cr = settings->getOptionRaw("Effects/ChorusRate", 0.3).toDouble();
+ cd = settings->getOptionRaw("Effects/ChorusDepth", 8.0).toDouble();
+ ct = settings->getOptionRaw("Effects/ChorusType", FLUID_CHORUS_MOD_SINE).toInt();
+ qmpMainWindow::getInstance()->registerFunctionality(
+ efxf = new qmpEfxFunc(this),
+ std::string("Effects"),
+ tr("Effects").toStdString(),
+ getThemedIconc(":/img/effects.svg"),
+ 0,
+ true
+ );
+ if (settings->getOptionRaw("DialogStatus/EfxW", QRect(-999, -999, 999, 999)).toRect() != QRect(-999, -999, 999, 999))
+ setGeometry(settings->getOptionRaw("DialogStatus/EfxW", QRect(-999, -999, 999, 999)).toRect());
+ if (settings->getOptionRaw("DialogStatus/EfxWShown", 0).toInt())
+ {
+ show();
+ qmpMainWindow::getInstance()->setFuncState("Effects", true);
+ }
}
qmpEfxWindow::~qmpEfxWindow()
{
- qmpMainWindow::getInstance()->unregisterFunctionality("Effects");
- delete efxf;
- delete styl;
- delete ui;
+ qmpMainWindow::getInstance()->unregisterFunctionality("Effects");
+ delete efxf;
+ delete styl;
+ delete ui;
}
void qmpEfxWindow::closeEvent(QCloseEvent *event)
{
- qmpSettings *settings=qmpMainWindow::getInstance()->getSettings();
- if(settings->getOptionBool("Behavior/DialogStatus"))
- {
- settings->setOptionRaw("DialogStatus/EfxW",geometry());
- }
- setVisible(false);
- if(!qmpMainWindow::getInstance()->isFinalizing()&&settings->getOptionBool("Behavior/DialogStatus"))
- {
- settings->setOptionRaw("DialogStatus/EfxWShown",0);
- }
- qmpMainWindow::getInstance()->setFuncState("Effects",false);
- event->accept();
+ qmpSettings *settings = qmpMainWindow::getInstance()->getSettings();
+ if (settings->getOptionBool("Behavior/DialogStatus"))
+ {
+ settings->setOptionRaw("DialogStatus/EfxW", geometry());
+ }
+ setVisible(false);
+ if (!qmpMainWindow::getInstance()->isFinalizing() && settings->getOptionBool("Behavior/DialogStatus"))
+ {
+ settings->setOptionRaw("DialogStatus/EfxWShown", 0);
+ }
+ qmpMainWindow::getInstance()->setFuncState("Effects", false);
+ event->accept();
}
void qmpEfxWindow::showEvent(QShowEvent *event)
{
- //CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
- //These parameters will never be modified outside this window...
- /*if(initialized)
- {
- player->getReverbPara(&rr,&rd,&rw,&rl);
- player->getChorusPara(&cfb,&cl,&cr,&cd,&ct);
- }*/
- ui->sbRoom->setValue((int)round(rr*100));ui->dRoom->setValue((int)round(rr*100));
- ui->sbDamp->setValue((int)round(rd*100));ui->dDamp->setValue((int)round(rd*100));
- ui->sbWidth->setValue((int)round(rw*100));ui->dWidth->setValue((int)round(rw*100));
- ui->sbLevelR->setValue((int)round(rl*100));ui->dLevelR->setValue((int)round(rl*100));
-
- ui->sbFeedBack->setValue(cfb);ui->dFeedBack->setValue(cfb);
- ui->sbRate->setValue(cr);ui->dRate->setValue((int)round(cr*100));
- ui->sbDepth->setValue(cd);ui->dDepth->setValue((int)round(cd*10));
- ui->sbLevelC->setValue((int)round(cl*100));ui->dLevelC->setValue((int)round(cl*100));
- if(ct==FLUID_CHORUS_MOD_SINE)ui->rbSine->setChecked(true),ui->rbTriangle->setChecked(false);
- if(ct==FLUID_CHORUS_MOD_TRIANGLE)ui->rbSine->setChecked(false),ui->rbTriangle->setChecked(true);
- initialized=true;
- qmpSettings *settings=qmpMainWindow::getInstance()->getSettings();
- if(settings->getOptionRaw("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999))
- setGeometry(settings->getOptionRaw("DialogStatus/EfxW",QRect(-999,-999,999,999)).toRect());
- if(settings->getOptionBool("Behavior/DialogStatus"))
- {
- settings->setOptionRaw("DialogStatus/EfxWShown",1);
- }
- event->accept();
+ //These parameters will never be modified outside this window...
+ /*if(initialized)
+ {
+ player->getReverbPara(&rr,&rd,&rw,&rl);
+ player->getChorusPara(&cfb,&cl,&cr,&cd,&ct);
+ }*/
+ ui->sbRoom->setValue((int)round(rr * 100));
+ ui->dRoom->setValue((int)round(rr * 100));
+ ui->sbDamp->setValue((int)round(rd * 100));
+ ui->dDamp->setValue((int)round(rd * 100));
+ ui->sbWidth->setValue((int)round(rw * 100));
+ ui->dWidth->setValue((int)round(rw * 100));
+ ui->sbLevelR->setValue((int)round(rl * 100));
+ ui->dLevelR->setValue((int)round(rl * 100));
+
+ ui->sbFeedBack->setValue(cfb);
+ ui->dFeedBack->setValue(cfb);
+ ui->sbRate->setValue(cr);
+ ui->dRate->setValue((int)round(cr * 100));
+ ui->sbDepth->setValue(cd);
+ ui->dDepth->setValue((int)round(cd * 10));
+ ui->sbLevelC->setValue((int)round(cl * 100));
+ ui->dLevelC->setValue((int)round(cl * 100));
+ if (ct == FLUID_CHORUS_MOD_SINE)
+ {
+ ui->rbSine->setChecked(true);
+ ui->rbTriangle->setChecked(false);
+ }
+ if (ct == FLUID_CHORUS_MOD_TRIANGLE)
+ {
+ ui->rbSine->setChecked(false);
+ ui->rbTriangle->setChecked(true);
+ }
+ initialized = true;
+ qmpSettings *settings = qmpMainWindow::getInstance()->getSettings();
+ if (settings->getOptionRaw("DialogStatus/EfxW", QRect(-999, -999, 999, 999)).toRect() != QRect(-999, -999, 999, 999))
+ setGeometry(settings->getOptionRaw("DialogStatus/EfxW", QRect(-999, -999, 999, 999)).toRect());
+ if (settings->getOptionBool("Behavior/DialogStatus"))
+ {
+ settings->setOptionRaw("DialogStatus/EfxWShown", 1);
+ }
+ event->accept();
}
void qmpEfxWindow::sendEfxChange(void *_fs)
{
- if(!qmpMainWindow::getInstance()||!initialized)return;
- rr=ui->sbRoom->value()/100.;rd=ui->sbDamp->value()/100.;
- rw=ui->sbWidth->value()/100.;rl=ui->sbLevelR->value()/100.;
- ct=ui->rbSine->isChecked()?FLUID_CHORUS_MOD_SINE:FLUID_CHORUS_MOD_TRIANGLE;
- cfb=ui->sbFeedBack->value();cl=ui->sbLevelC->value()/100.;
- cr=ui->sbRate->value();cd=ui->sbDepth->value();
- IFluidSettings* fs=(IFluidSettings*)_fs;
- if(!_fs)fs=qmpMainWindow::getInstance()->getFluid();
- fs->setReverbPara(ui->cbEnabledR->isChecked()?1:0,rr,rd,rw,rl);
- fs->setChorusPara(ui->cbEnabledC->isChecked()?1:0,cfb,cl,cr,cd,ct);
-
- qmpSettings *settings=qmpMainWindow::getInstance()->getSettings();
- settings->setOptionRaw("Effects/ChorusEnabled",ui->cbEnabledC->isChecked()?1:0);
- settings->setOptionRaw("Effects/ReverbEnabled",ui->cbEnabledR->isChecked()?1:0);
- settings->setOptionRaw("Effects/ReverbRoom",rr);
- settings->setOptionRaw("Effects/ReverbDamp",rd);
- settings->setOptionRaw("Effects/ReverbWidth",rw);
- settings->setOptionRaw("Effects/ReverbLevel",rl);
-
- settings->setOptionRaw("Effects/ChorusFeedbk",cfb);
- settings->setOptionRaw("Effects/ChorusLevel",cl);
- settings->setOptionRaw("Effects/ChorusRate",cr);
- settings->setOptionRaw("Effects/ChorusDepth",cd);
- settings->setOptionRaw("Effects/ChorusType",ct);
+ if (!qmpMainWindow::getInstance() || !initialized)
+ return;
+ rr = ui->sbRoom->value() / 100.;
+ rd = ui->sbDamp->value() / 100.;
+ rw = ui->sbWidth->value() / 100.;
+ rl = ui->sbLevelR->value() / 100.;
+ ct = ui->rbSine->isChecked() ? FLUID_CHORUS_MOD_SINE : FLUID_CHORUS_MOD_TRIANGLE;
+ cfb = ui->sbFeedBack->value();
+ cl = ui->sbLevelC->value() / 100.;
+ cr = ui->sbRate->value();
+ cd = ui->sbDepth->value();
+ IFluidSettings *fs = (IFluidSettings *)_fs;
+ if (!_fs)
+ fs = qmpMainWindow::getInstance()->getFluid();
+ fs->setReverbPara(ui->cbEnabledR->isChecked() ? 1 : 0, rr, rd, rw, rl);
+ fs->setChorusPara(ui->cbEnabledC->isChecked() ? 1 : 0, cfb, cl, cr, cd, ct);
+
+ qmpSettings *settings = qmpMainWindow::getInstance()->getSettings();
+ settings->setOptionRaw("Effects/ChorusEnabled", ui->cbEnabledC->isChecked() ? 1 : 0);
+ settings->setOptionRaw("Effects/ReverbEnabled", ui->cbEnabledR->isChecked() ? 1 : 0);
+ settings->setOptionRaw("Effects/ReverbRoom", rr);
+ settings->setOptionRaw("Effects/ReverbDamp", rd);
+ settings->setOptionRaw("Effects/ReverbWidth", rw);
+ settings->setOptionRaw("Effects/ReverbLevel", rl);
+
+ settings->setOptionRaw("Effects/ChorusFeedbk", cfb);
+ settings->setOptionRaw("Effects/ChorusLevel", cl);
+ settings->setOptionRaw("Effects/ChorusRate", cr);
+ settings->setOptionRaw("Effects/ChorusDepth", cd);
+ settings->setOptionRaw("Effects/ChorusType", ct);
}
void qmpEfxWindow::dailValueChange()
{
- if(!initialized)return;
- ui->sbRoom->setValue(ui->dRoom->value());
- ui->sbDamp->setValue(ui->dDamp->value());
- ui->sbWidth->setValue(ui->dWidth->value());
- ui->sbLevelR->setValue(ui->dLevelR->value());
- ui->sbFeedBack->setValue(ui->dFeedBack->value());
- ui->sbRate->setValue(ui->dRate->value()/100.);
- ui->sbDepth->setValue(ui->dDepth->value()/10.);
- ui->sbLevelC->setValue(ui->dLevelC->value());
- sendEfxChange();
+ if (!initialized)
+ return;
+ ui->sbRoom->setValue(ui->dRoom->value());
+ ui->sbDamp->setValue(ui->dDamp->value());
+ ui->sbWidth->setValue(ui->dWidth->value());
+ ui->sbLevelR->setValue(ui->dLevelR->value());
+ ui->sbFeedBack->setValue(ui->dFeedBack->value());
+ ui->sbRate->setValue(ui->dRate->value() / 100.);
+ ui->sbDepth->setValue(ui->dDepth->value() / 10.);
+ ui->sbLevelC->setValue(ui->dLevelC->value());
+ sendEfxChange();
}
void qmpEfxWindow::spinValueChange()
{
- if(!initialized)return;
- ui->dRoom->setValue(ui->sbRoom->value());
- ui->dDamp->setValue(ui->sbDamp->value());
- ui->dWidth->setValue(ui->sbWidth->value());
- ui->dLevelR->setValue(ui->sbLevelR->value());
- ui->dFeedBack->setValue(ui->sbFeedBack->value());
- ui->dRate->setValue((int)(ui->sbRate->value()*100));
- ui->dDepth->setValue((int)(ui->sbDepth->value()*10));
- ui->dLevelC->setValue(ui->sbLevelC->value());
- sendEfxChange();
+ if (!initialized)
+ return;
+ ui->dRoom->setValue(ui->sbRoom->value());
+ ui->dDamp->setValue(ui->sbDamp->value());
+ ui->dWidth->setValue(ui->sbWidth->value());
+ ui->dLevelR->setValue(ui->sbLevelR->value());
+ ui->dFeedBack->setValue(ui->sbFeedBack->value());
+ ui->dRate->setValue((int)(ui->sbRate->value() * 100));
+ ui->dDepth->setValue((int)(ui->sbDepth->value() * 10));
+ ui->dLevelC->setValue(ui->sbLevelC->value());
+ sendEfxChange();
}
void qmpEfxWindow::on_dRoom_valueChanged()
-{dailValueChange();}
+{
+ dailValueChange();
+}
void qmpEfxWindow::on_dDamp_valueChanged()
-{dailValueChange();}
+{
+ dailValueChange();
+}
void qmpEfxWindow::on_dWidth_valueChanged()
-{dailValueChange();}
+{
+ dailValueChange();
+}
void qmpEfxWindow::on_dLevelR_valueChanged()
-{dailValueChange();}
+{
+ dailValueChange();
+}
void qmpEfxWindow::on_dFeedBack_valueChanged()
-{dailValueChange();}
+{
+ dailValueChange();
+}
void qmpEfxWindow::on_dRate_valueChanged()
-{dailValueChange();}
+{
+ dailValueChange();
+}
void qmpEfxWindow::on_dDepth_valueChanged()
-{dailValueChange();}
+{
+ dailValueChange();
+}
void qmpEfxWindow::on_dLevelC_valueChanged()
-{dailValueChange();}
+{
+ dailValueChange();
+}
void qmpEfxWindow::on_sbRoom_valueChanged(QString s)
-{s=QString();spinValueChange();}
+{
+ s = QString();
+ spinValueChange();
+}
void qmpEfxWindow::on_sbDamp_valueChanged(QString s)
-{s=QString();spinValueChange();}
+{
+ s = QString();
+ spinValueChange();
+}
void qmpEfxWindow::on_sbWidth_valueChanged(QString s)
-{s=QString();spinValueChange();}
+{
+ s = QString();
+ spinValueChange();
+}
void qmpEfxWindow::on_sbLevelR_valueChanged(QString s)
-{s=QString();spinValueChange();}
+{
+ s = QString();
+ spinValueChange();
+}
void qmpEfxWindow::on_sbFeedBack_valueChanged(QString s)
-{s=QString();spinValueChange();}
+{
+ s = QString();
+ spinValueChange();
+}
void qmpEfxWindow::on_sbRate_valueChanged(QString s)
-{s=QString();spinValueChange();}
+{
+ s = QString();
+ spinValueChange();
+}
void qmpEfxWindow::on_sbDepth_valueChanged(QString s)
-{s=QString();spinValueChange();}
+{
+ s = QString();
+ spinValueChange();
+}
void qmpEfxWindow::on_sbLevelC_valueChanged(QString s)
-{s=QString();spinValueChange();}
+{
+ s = QString();
+ spinValueChange();
+}
void qmpEfxWindow::on_cbEnabledC_stateChanged()
-{sendEfxChange();}
+{
+ sendEfxChange();
+}
void qmpEfxWindow::on_cbEnabledR_stateChanged()
-{sendEfxChange();}
+{
+ sendEfxChange();
+}
void qmpEfxWindow::on_rbSine_toggled()
-{sendEfxChange();}
+{
+ sendEfxChange();
+}
void qmpEfxWindow::on_rbTriangle_toggled()
-{sendEfxChange();}
+{
+ sendEfxChange();
+}
qmpEfxFunc::qmpEfxFunc(qmpEfxWindow *par)
-{p=par;}
+{
+ p = par;
+}
void qmpEfxFunc::show()
-{p->show();}
+{
+ p->show();
+}
void qmpEfxFunc::close()
-{p->close();}
+{
+ p->close();
+}
diff --git a/qmidiplayer-desktop/qmpefxwindow.hpp b/qmidiplayer-desktop/qmpefxwindow.hpp
index bacda1d..9e5e8bf 100644
--- a/qmidiplayer-desktop/qmpefxwindow.hpp
+++ b/qmidiplayer-desktop/qmpefxwindow.hpp
@@ -9,64 +9,65 @@
#include "qdialskulpturestyle.hpp"
#include "../include/qmpcorepublic.hpp"
-namespace Ui {
- class qmpEfxWindow;
+namespace Ui
+{
+class qmpEfxWindow;
}
class qmpEfxWindow;
-class qmpEfxFunc:public qmpFuncBaseIntf
+class qmpEfxFunc : public qmpFuncBaseIntf
{
- private:
- qmpEfxWindow *p;
- public:
- qmpEfxFunc(qmpEfxWindow *par);
- void show();
- void close();
+private:
+ qmpEfxWindow *p;
+public:
+ qmpEfxFunc(qmpEfxWindow *par);
+ void show();
+ void close();
};
-class qmpEfxWindow:public QWidget
+class qmpEfxWindow : public QWidget
{
- Q_OBJECT
+ Q_OBJECT
- public:
- explicit qmpEfxWindow(QWidget *parent=0);
- ~qmpEfxWindow();
- void closeEvent(QCloseEvent *event);
- void showEvent(QShowEvent *event);
- void sendEfxChange(void *_fs=nullptr);
+public:
+ explicit qmpEfxWindow(QWidget *parent = nullptr);
+ ~qmpEfxWindow();
+ void closeEvent(QCloseEvent *event);
+ void showEvent(QShowEvent *event);
+ void sendEfxChange(void *_fs = nullptr);
- private slots:
- void on_dRoom_valueChanged();
- void on_dDamp_valueChanged();
- void on_dWidth_valueChanged();
- void on_dLevelR_valueChanged();
- void on_dFeedBack_valueChanged();
- void on_dRate_valueChanged();
- void on_dDepth_valueChanged();
- void on_dLevelC_valueChanged();
- void on_sbRoom_valueChanged(QString s);
- void on_sbDamp_valueChanged(QString s);
- void on_sbWidth_valueChanged(QString s);
- void on_sbLevelR_valueChanged(QString s);
- void on_sbFeedBack_valueChanged(QString s);
- void on_sbRate_valueChanged(QString s);
- void on_sbDepth_valueChanged(QString s);
- void on_sbLevelC_valueChanged(QString s);
- void on_cbEnabledC_stateChanged();
- void on_cbEnabledR_stateChanged();
- void on_rbSine_toggled();
- void on_rbTriangle_toggled();
+private slots:
+ void on_dRoom_valueChanged();
+ void on_dDamp_valueChanged();
+ void on_dWidth_valueChanged();
+ void on_dLevelR_valueChanged();
+ void on_dFeedBack_valueChanged();
+ void on_dRate_valueChanged();
+ void on_dDepth_valueChanged();
+ void on_dLevelC_valueChanged();
+ void on_sbRoom_valueChanged(QString s);
+ void on_sbDamp_valueChanged(QString s);
+ void on_sbWidth_valueChanged(QString s);
+ void on_sbLevelR_valueChanged(QString s);
+ void on_sbFeedBack_valueChanged(QString s);
+ void on_sbRate_valueChanged(QString s);
+ void on_sbDepth_valueChanged(QString s);
+ void on_sbLevelC_valueChanged(QString s);
+ void on_cbEnabledC_stateChanged();
+ void on_cbEnabledR_stateChanged();
+ void on_rbSine_toggled();
+ void on_rbTriangle_toggled();
- private:
- void dailValueChange();
- void spinValueChange();
- Ui::qmpEfxWindow *ui;
- double rr,rd,rw,rl;
- int cfb,ct,initialized;
- double cl,cr,cd;
- QCommonStyle* styl;
- qmpEfxFunc *efxf;
+private:
+ void dailValueChange();
+ void spinValueChange();
+ Ui::qmpEfxWindow *ui;
+ double rr, rd, rw, rl;
+ int cfb, ct, initialized;
+ double cl, cr, cd;
+ QCommonStyle *styl;
+ qmpEfxFunc *efxf;
};
#endif // QMPEFXWINDOW_HPP
diff --git a/qmidiplayer-desktop/qmphelpwindow.cpp b/qmidiplayer-desktop/qmphelpwindow.cpp
index 4579e2c..082c2f6 100644
--- a/qmidiplayer-desktop/qmphelpwindow.cpp
+++ b/qmidiplayer-desktop/qmphelpwindow.cpp
@@ -2,43 +2,44 @@
#include "qmphelpwindow.hpp"
#include "ui_qmphelpwindow.h"
-static const char *months="JanFebMarAprMayJunJulAugSepOctNovDec";
+static const char *months = "JanFebMarAprMayJunJulAugSepOctNovDec";
std::string parseDate(const char *date)
{
- char ms[8];
- int y,d,m;sscanf(date,"%s %d %d",ms,&d,&y);
- m=(strstr(months,ms)-months)/3+1;
- char r[16];
- sprintf(r,"%04d-%02d-%02d",y,m,d);
- return std::string(r);
+ char ms[8];
+ int y, d, m;
+ sscanf(date, "%s %d %d", ms, &d, &y);
+ m = (strstr(months, ms) - months) / 3 + 1;
+ char r[16];
+ sprintf(r, "%04d-%02d-%02d", y, m, d);
+ return std::string(r);
}
qmpHelpWindow::qmpHelpWindow(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::qmpHelpWindow)
+ QDialog(parent),
+ ui(new Ui::qmpHelpWindow)
{
- ui->setupUi(this);
- ui->textBrowser->setSearchPaths(QStringList(QString(":/doc"))+QStringList(QString(":/img")));
- ui->textBrowser->setSource(QUrl("qrc:///doc/index_internal.html"));
+ ui->setupUi(this);
+ ui->textBrowser->setSearchPaths(QStringList(QString(":/doc")) + QStringList(QString(":/img")));
+ ui->textBrowser->setSource(QUrl("qrc:///doc/index_internal.html"));
}
qmpHelpWindow::~qmpHelpWindow()
{
- delete ui;
+ delete ui;
}
void qmpHelpWindow::on_textBrowser_sourceChanged(const QUrl &src)
{
- if(src.fileName()==QString("version_internal.html"))
- {
- QString s=ui->textBrowser->toHtml();
- s.replace("CT_QT_VERSION_STR",QT_VERSION_STR);
- s.replace("RT_QT_VERSION_STR",qVersion());
- s.replace("CT_FLUIDSYNTH_VERSION",FLUIDSYNTH_VERSION);
- s.replace("RT_FLUIDSYNTH_VERSION",fluid_version_str());
- s.replace("APP_VERSION",APP_VERSION);
- s.replace("BUILD_DATE",parseDate(__DATE__).c_str());
- s.replace("BUILD_MACHINE",QT_STRINGIFY(BUILD_MACHINE));
- ui->textBrowser->setHtml(s);
- }
+ if (src.fileName() == QString("version_internal.html"))
+ {
+ QString s = ui->textBrowser->toHtml();
+ s.replace("CT_QT_VERSION_STR", QT_VERSION_STR);
+ s.replace("RT_QT_VERSION_STR", qVersion());
+ s.replace("CT_FLUIDSYNTH_VERSION", FLUIDSYNTH_VERSION);
+ s.replace("RT_FLUIDSYNTH_VERSION", fluid_version_str());
+ s.replace("APP_VERSION", APP_VERSION);
+ s.replace("BUILD_DATE", parseDate(__DATE__).c_str());
+ s.replace("BUILD_MACHINE", QT_STRINGIFY(BUILD_MACHINE));
+ ui->textBrowser->setHtml(s);
+ }
}
diff --git a/qmidiplayer-desktop/qmphelpwindow.hpp b/qmidiplayer-desktop/qmphelpwindow.hpp
index a94da33..35824ed 100644
--- a/qmidiplayer-desktop/qmphelpwindow.hpp
+++ b/qmidiplayer-desktop/qmphelpwindow.hpp
@@ -6,23 +6,24 @@
#define BUILD_MACHINE UNKNOWN
#endif
-namespace Ui {
- class qmpHelpWindow;
+namespace Ui
+{
+class qmpHelpWindow;
}
class qmpHelpWindow : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
- public:
- explicit qmpHelpWindow(QWidget *parent = 0);
- ~qmpHelpWindow();
+public:
+ explicit qmpHelpWindow(QWidget *parent = nullptr);
+ ~qmpHelpWindow();
- private slots:
- void on_textBrowser_sourceChanged(const QUrl &src);
+private slots:
+ void on_textBrowser_sourceChanged(const QUrl &src);
- private:
- Ui::qmpHelpWindow *ui;
+private:
+ Ui::qmpHelpWindow *ui;
};
#endif // QMPHELPWINDOW_H
diff --git a/qmidiplayer-desktop/qmpinfowindow.cpp b/qmidiplayer-desktop/qmpinfowindow.cpp
index c0b8892..654c8f4 100644
--- a/qmidiplayer-desktop/qmpinfowindow.cpp
+++ b/qmidiplayer-desktop/qmpinfowindow.cpp
@@ -4,84 +4,95 @@
#include "qmpmainwindow.hpp"
#include "qmpsettingswindow.hpp"
-const char* minors="abebbbf c g d a e b f#c#g#d#a#";
-const char* majors="CbGbDbAbEbBbF C G D A E B F#C#";
-const char* standards="? GM GM2GS XG ";
+const char *minors = "abebbbf c g d a e b f#c#g#d#a#";
+const char *majors = "CbGbDbAbEbBbF C G D A E B F#C#";
+const char *standards = "? GM GM2GS XG ";
qmpInfoWindow::qmpInfoWindow(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::qmpInfoWindow)
+ QDialog(parent),
+ ui(new Ui::qmpInfoWindow)
{
- ui->setupUi(this);
- qmpMainWindow::getInstance()->registerFunctionality(
- infof=new qmpInfoFunc(this),
- std::string("FileInfo"),
- tr("File Information").toStdString(),
- getThemedIconc(":/img/info.svg"),
- 0,
- true
- );
+ ui->setupUi(this);
+ qmpMainWindow::getInstance()->registerFunctionality(
+ infof = new qmpInfoFunc(this),
+ std::string("FileInfo"),
+ tr("File Information").toStdString(),
+ getThemedIconc(":/img/info.svg"),
+ 0,
+ true
+ );
}
qmpInfoWindow::~qmpInfoWindow()
{
- qmpMainWindow::getInstance()->unregisterFunctionality("FileInfo");
- delete infof;
- delete ui;
+ qmpMainWindow::getInstance()->unregisterFunctionality("FileInfo");
+ delete infof;
+ delete ui;
}
void qmpInfoWindow::closeEvent(QCloseEvent *e)
{
- setVisible(false);
- qmpMainWindow::getInstance()->setFuncState("FileInfo",false);
- e->accept();
+ setVisible(false);
+ qmpMainWindow::getInstance()->setFuncState("FileInfo", false);
+ e->accept();
}
void qmpInfoWindow::hideEvent(QHideEvent *e)
{
- qmpMainWindow::getInstance()->setFuncState("FileInfo",false);
- e->accept();
+ qmpMainWindow::getInstance()->setFuncState("FileInfo", false);
+ e->accept();
}
void qmpInfoWindow::updateInfo()
{
- char str[256];
- CMidiPlayer* player=qmpMainWindow::getInstance()->getPlayer();
- std::string textencoding=qmpMainWindow::getInstance()->getSettings()->getOptionEnumIntOptName("Midi/TextEncoding");
- ui->lbFileName->setText(QString("File name: ")+qmpMainWindow::getInstance()->getFileName());
- if(player->getTitle())
- {
- if(textencoding!="Unicode")
- ui->lbTitle->setText(QString("Title: ")+
- QTextCodec::codecForName(textencoding.c_str())->toUnicode(player->getTitle()));
- else
- ui->lbTitle->setText(QString("Title: ")+player->getTitle());
- }
- else ui->lbTitle->setText(QString("Title: "));
- if(player->getCopyright())
- {
- if(textencoding!="Unicode")
- ui->lbCopyright->setText(QString("Copyright: ")+
- QTextCodec::codecForName(textencoding.c_str())->toUnicode(player->getCopyright()));
- else
- ui->lbCopyright->setText(QString("Copyright: ")+player->getCopyright());
- }
- else ui->lbCopyright->setText(QString("Copyright: "));
- ui->lbTempo->setText(QString("Tempo: ")+QString::number(player->getTempo(),'g',5));
- int t,r;t=player->getCurrentKeySignature();r=(int8_t)((t>>8)&0xFF)+7;
- strncpy(str,t&0xFF?minors+2*r:majors+2*r,2);str[2]='\0';
- ui->lbKeySig->setText(QString("Key Sig.: ")+str);
- player->getCurrentTimeSignature(&t,&r);sprintf(str,"Time Sig.: %d/%d",t,r);
- ui->lbTimeSig->setText(str);
- sprintf(str,"Note count: %u",player->getFileNoteCount());
- ui->lbNoteCount->setText(str);
- strncpy(str,standards+player->getFileStandard()*3,3);str[3]='\0';
- ui->lbFileStandard->setText(QString("File standard: ")+str);
+ char str[256];
+ CMidiPlayer *player = qmpMainWindow::getInstance()->getPlayer();
+ std::string textencoding = qmpMainWindow::getInstance()->getSettings()->getOptionEnumIntOptName("Midi/TextEncoding");
+ ui->lbFileName->setText(QString("File name: ") + qmpMainWindow::getInstance()->getFileName());
+ if (player->getTitle())
+ {
+ if (textencoding != "Unicode")
+ ui->lbTitle->setText(QString("Title: ") +
+ QTextCodec::codecForName(textencoding.c_str())->toUnicode(player->getTitle()));
+ else
+ ui->lbTitle->setText(QString("Title: ") + player->getTitle());
+ }
+ else ui->lbTitle->setText(QString("Title: "));
+ if (player->getCopyright())
+ {
+ if (textencoding != "Unicode")
+ ui->lbCopyright->setText(QString("Copyright: ") +
+ QTextCodec::codecForName(textencoding.c_str())->toUnicode(player->getCopyright()));
+ else
+ ui->lbCopyright->setText(QString("Copyright: ") + player->getCopyright());
+ }
+ else ui->lbCopyright->setText(QString("Copyright: "));
+ ui->lbTempo->setText(QString("Tempo: ") + QString::number(player->getTempo(), 'g', 5));
+ int t, r;
+ t = player->getCurrentKeySignature();
+ r = (int8_t)((t >> 8) & 0xFF) + 7;
+ strncpy(str, t & 0xFF ? minors + 2 * r : majors + 2 * r, 2);
+ str[2] = '\0';
+ ui->lbKeySig->setText(QString("Key Sig.: ") + str);
+ player->getCurrentTimeSignature(&t, &r);
+ sprintf(str, "Time Sig.: %d/%d", t, r);
+ ui->lbTimeSig->setText(str);
+ sprintf(str, "Note count: %u", player->getFileNoteCount());
+ ui->lbNoteCount->setText(str);
+ strncpy(str, standards + player->getFileStandard() * 3, 3);
+ str[3] = '\0';
+ ui->lbFileStandard->setText(QString("File standard: ") + str);
}
qmpInfoFunc::qmpInfoFunc(qmpInfoWindow *par)
-{p=par;}
+{
+ p = par;
+}
void qmpInfoFunc::show()
-{p->show();}
+{
+ p->show();
+}
void qmpInfoFunc::close()
-{p->close();}
+{
+ p->close();
+}
diff --git a/qmidiplayer-desktop/qmpinfowindow.hpp b/qmidiplayer-desktop/qmpinfowindow.hpp
index 6a179af..7e09b8a 100644
--- a/qmidiplayer-desktop/qmpinfowindow.hpp
+++ b/qmidiplayer-desktop/qmpinfowindow.hpp
@@ -10,50 +10,51 @@
#include <QHideEvent>
#include "../include/qmpcorepublic.hpp"
-namespace Ui {
- class qmpInfoWindow;
+namespace Ui
+{
+class qmpInfoWindow;
}
class QClickableLabel : public QLabel
{
- Q_OBJECT
- public:
- explicit QClickableLabel(QWidget *parent=0):QLabel(parent){}
- protected:
- void mousePressEvent(QMouseEvent *e)
- {
- QLabel::mousePressEvent(e);
- if(e->buttons()&Qt::LeftButton)
- QApplication::clipboard()->setText(text());
- }
+ Q_OBJECT
+public:
+ explicit QClickableLabel(QWidget *parent = nullptr) : QLabel(parent) {}
+protected:
+ void mousePressEvent(QMouseEvent *e)
+ {
+ QLabel::mousePressEvent(e);
+ if (e->buttons() & Qt::LeftButton)
+ QApplication::clipboard()->setText(text());
+ }
};
class qmpInfoWindow;
-class qmpInfoFunc:public qmpFuncBaseIntf
+class qmpInfoFunc : public qmpFuncBaseIntf
{
- private:
- qmpInfoWindow *p;
- public:
- qmpInfoFunc(qmpInfoWindow *par);
- void show();
- void close();
+private:
+ qmpInfoWindow *p;
+public:
+ qmpInfoFunc(qmpInfoWindow *par);
+ void show();
+ void close();
};
class qmpInfoWindow : public QDialog
{
- Q_OBJECT
-
- public:
- explicit qmpInfoWindow(QWidget *parent = 0);
- ~qmpInfoWindow();
- void closeEvent(QCloseEvent *e);
- void hideEvent(QHideEvent *e);
- public slots:
- void updateInfo();
-
- private:
- Ui::qmpInfoWindow *ui;
- qmpInfoFunc *infof;
+ Q_OBJECT
+
+public:
+ explicit qmpInfoWindow(QWidget *parent = nullptr);
+ ~qmpInfoWindow();
+ void closeEvent(QCloseEvent *e);
+ void hideEvent(QHideEvent *e);
+public slots:
+ void updateInfo();
+
+private:
+ Ui::qmpInfoWindow *ui;
+ qmpInfoFunc *infof;
};
#endif // QMPINFOWINDOW_HPP
diff --git a/qmidiplayer-desktop/qmpmainwindow.cpp b/qmidiplayer-desktop/qmpmainwindow.cpp
index ea90493..98378aa 100644
--- a/qmidiplayer-desktop/qmpmainwindow.cpp
+++ b/qmidiplayer-desktop/qmpmainwindow.cpp
@@ -16,797 +16,938 @@
#define setButtonWidth(x,h) {x->setMaximumWidth(h*(logicalDpiY()/96.));x->setMinimumWidth(h*(logicalDpiY()/96.));}
#ifdef _WIN32
#include <windows.h>
-char* wcsto8bit(const wchar_t* s)
+char *wcsto8bit(const wchar_t *s)
{
- int size=WideCharToMultiByte(CP_OEMCP,WC_NO_BEST_FIT_CHARS,s,-1,0,0,0,0);
- char* c=(char*)calloc(size,sizeof(char));
- WideCharToMultiByte(CP_OEMCP,WC_NO_BEST_FIT_CHARS,s,-1,c,size,0,0);
- return c;
+ int size = WideCharToMultiByte(CP_OEMCP, WC_NO_BEST_FIT_CHARS, s, -1, 0, 0, 0, 0);
+ char *c = (char *)calloc(size, sizeof(char));
+ WideCharToMultiByte(CP_OEMCP, WC_NO_BEST_FIT_CHARS, s, -1, c, size, 0, 0);
+ return c;
}
#endif
#define UPDATE_INTERVAL 66
-qmpMainWindow* qmpMainWindow::ref=nullptr;
-
-qmpMainWindow::qmpMainWindow(QCommandLineParser *_clp,QWidget *parent):
- QMainWindow(parent),
- ui(new Ui::qmpMainWindow),
- clp(_clp)
-{
- ui->setupUi(this);
- ui->lbCurPoly->setText("00000");ui->lbMaxPoly->setText("00000");
- ui->lbFileName->setText("");ref=this;ui->verticalLayout->setAlignment(ui->pushButton,Qt::AlignRight);
- setButtonHeight(ui->pbNext,36);setButtonHeight(ui->pbPlayPause,36);setButtonHeight(ui->pbAdd,36);
- setButtonHeight(ui->pbPrev,36);setButtonHeight(ui->pbSettings,36);setButtonHeight(ui->pbStop,36);
- playing=false;stopped=true;dragging=false;fin=false;
- settings.reset(new qmpSettings());
- settingsw=new qmpSettingsWindow(settings.get(),this);
- player=nullptr;timer=nullptr;fluidrenderer=nullptr;
+qmpMainWindow *qmpMainWindow::ref = nullptr;
+
+qmpMainWindow::qmpMainWindow(QCommandLineParser *_clp, QWidget *parent):
+ QMainWindow(parent),
+ ui(new Ui::qmpMainWindow),
+ clp(_clp)
+{
+ ui->setupUi(this);
+ ui->lbCurPoly->setText("00000");
+ ui->lbMaxPoly->setText("00000");
+ ui->lbFileName->setText("");
+ ref = this;
+ ui->verticalLayout->setAlignment(ui->pushButton, Qt::AlignRight);
+ setButtonHeight(ui->pbNext, 36);
+ setButtonHeight(ui->pbPlayPause, 36);
+ setButtonHeight(ui->pbAdd, 36);
+ setButtonHeight(ui->pbPrev, 36);
+ setButtonHeight(ui->pbSettings, 36);
+ setButtonHeight(ui->pbStop, 36);
+ playing = false;
+ stopped = true;
+ dragging = false;
+ fin = false;
+ settings.reset(new qmpSettings());
+ settingsw = new qmpSettingsWindow(settings.get(), this);
+ player = nullptr;
+ timer = nullptr;
+ fluidrenderer = nullptr;
}
qmpMainWindow::~qmpMainWindow()
{
- QList<QAction*>a=ui->lbFileName->actions();
- for(unsigned i=0;i<a.size();++i)
- {
- ui->lbFileName->removeAction(a[i]);
- delete a[i];
- }
- pmgr->deinitPlugins();
- auto rtdev=qmpRtMidiManager::getDevices();
- for(auto &i:rtdev)player->unregisterMidiOutDevice(i.second);
- delete pmgr;
- if(timer)delete timer;
- delete helpw;helpw=nullptr;
- delete efxw;efxw=nullptr;
- delete chnlw;chnlw=nullptr;
- delete plistw;plistw=nullptr;
- delete infow;infow=nullptr;
- delete settingsw;settingsw=nullptr;
- delete panicf;panicf=nullptr;
- delete renderf;renderf=nullptr;
- delete reloadsynf;reloadsynf=nullptr;
- if(player)delete player;
- internalfluid->deviceDeinit();
- delete internalfluid;
- delete ui;
+ QList<QAction *>a = ui->lbFileName->actions();
+ for (unsigned i = 0; i < a.size(); ++i)
+ {
+ ui->lbFileName->removeAction(a[i]);
+ delete a[i];
+ }
+ pmgr->deinitPlugins();
+ auto rtdev = qmpRtMidiManager::getDevices();
+ for (auto &i : rtdev)
+ player->unregisterMidiOutDevice(i.second);
+ delete pmgr;
+ if (timer)
+ delete timer;
+ delete helpw;
+ helpw = nullptr;
+ delete efxw;
+ efxw = nullptr;
+ delete chnlw;
+ chnlw = nullptr;
+ delete plistw;
+ plistw = nullptr;
+ delete infow;
+ infow = nullptr;
+ delete settingsw;
+ settingsw = nullptr;
+ delete panicf;
+ panicf = nullptr;
+ delete renderf;
+ renderf = nullptr;
+ delete reloadsynf;
+ reloadsynf = nullptr;
+ if (player)
+ delete player;
+ internalfluid->deviceDeinit();
+ delete internalfluid;
+ delete ui;
}
void qmpMainWindow::init()
{
- show();
- ui->centralWidget->setEnabled(false);
-
- pmgr=new qmpPluginManager();
- registerMidiOptions();
-
- std::future<void> f=std::async(std::launch::async,
- [this]
- {
- player=new CMidiPlayer();
- internalfluid=new qmpMidiOutFluid();
- player->registerMidiOutDevice(internalfluid,"Internal FluidSynth");
- reloadsynf=new qmpReloadSynthFunc(this);
-
- internalfluid->registerOptions(pmgr->pluginAPI);
- playerSetup(internalfluid);
- internalfluid->deviceInit();
- loadSoundFont(internalfluid);
- for(int i=0;i<16;++i)
- player->setChannelOutput(i,0);
-
- auto rtdev=qmpRtMidiManager::getDevices();
- for(auto &i:rtdev)
- player->registerMidiOutDevice(i.first,i.second);
- }
- );
- while(f.wait_for(std::chrono::milliseconds(100))==std::future_status::timeout)
- QApplication::processEvents();
- ui->centralWidget->setEnabled(true);
-
- settingsw->registerSoundFontOption();
- registerBehaviorOptions();
- settingsw->registerCustomizeWidgetOptions();
-
- plistw=new qmpPlistWindow(this);
- chnlw=new qmpChannelsWindow(this);
- efxw=new qmpEfxWindow(this);
- infow=new qmpInfoWindow(this);
- helpw=new qmpHelpWindow(this);
- timer=new QTimer(this);
- renderf=new qmpRenderFunc(this);
- panicf=new qmpPanicFunc(this);
- if(argfiles.size())
- {
- plistw->emptyList();
- for(auto&i:argfiles)plistw->insertItem(i);
- }
-
- if(settings->getOptionBool("Behavior/DialogStatus"))
- {
- QRect g=settings->getOptionRaw("DialogStatus/MainW",QRect(-999,-999,999,999)).toRect();
- if(g!=QRect(-999,-999,999,999))setGeometry(g);
- }
-
- 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);
- const QStringList &qpp=clp->values("plugin");
- std::vector<std::string> pp;
- for(auto s:qpp)
- pp.push_back(s.toStdString());
- pmgr->scanPlugins(pp);
- settingsw->registerPluginOption(pmgr);
- settingsw->updatePluginList(pmgr);
- pmgr->initPlugins();
-
- settingsw->registerExtraMidiOptions();
-
- QVariant* dinif_v=static_cast<QVariant*>(settings->getOptionCustom("Midi/DeviceInitializationFiles"));
- QList<QVariant> devinif_list=dinif_v->toList();
- delete dinif_v;
- QMap<QString,QString> devinif_map;
- for(auto &i:devinif_list)
- {
- QPair<QString,QString> p=i.value<QPair<QString,QString>>();
- devinif_map[p.first]=p.second;
- }
- auto rtdev=qmpRtMidiManager::getDevices();
- for(auto &i:rtdev)
- {
- if(devinif_map.contains(QString(i.second.c_str())))
- i.first->setInitializerFile(devinif_map[QString(i.second.c_str())].toStdString().c_str());
- }
- chnlw->selectDefaultDevice();
-
- ui->vsMasterVol->setValue(settings->getOptionRaw("FluidSynth/Gain",50).toInt());
- connect(timer,&QTimer::timeout,this,&qmpMainWindow::updateWidgets);
- connect(timer,&QTimer::timeout,infow,&qmpInfoWindow::updateInfo);
- ui->pbNext->setIcon(QIcon(getThemedIcon(":/img/next.svg")));
- ui->pbPrev->setIcon(QIcon(getThemedIcon(":/img/prev.svg")));
- ui->pbPlayPause->setIcon(QIcon(getThemedIcon(":/img/play.svg")));
- ui->pbStop->setIcon(QIcon(getThemedIcon(":/img/stop.svg")));
- ui->pbSettings->setIcon(QIcon(getThemedIcon(":/img/settings.svg")));
- ui->pbAdd->setIcon(QIcon(getThemedIcon(":/img/open.svg")));
- if(argfiles.size())on_pbPlayPause_clicked();
- setupWidget();settingsw->postInit();
+ show();
+ ui->centralWidget->setEnabled(false);
+
+ pmgr = new qmpPluginManager();
+ registerMidiOptions();
+
+ std::future<void> f = std::async(std::launch::async, [this]
+ {
+ player = new CMidiPlayer();
+ internalfluid = new qmpMidiOutFluid();
+ player->registerMidiOutDevice(internalfluid, "Internal FluidSynth");
+ reloadsynf = new qmpReloadSynthFunc(this);
+
+ internalfluid->registerOptions(pmgr->pluginAPI);
+ playerSetup(internalfluid);
+ internalfluid->deviceInit();
+ loadSoundFont(internalfluid);
+ for (int i = 0; i < 16; ++i)
+ player->setChannelOutput(i, 0);
+
+ auto rtdev = qmpRtMidiManager::getDevices();
+ for (auto &i : rtdev)
+ player->registerMidiOutDevice(i.first, i.second);
+ });
+ while (f.wait_for(std::chrono::milliseconds(100)) == std::future_status::timeout)
+ QApplication::processEvents();
+ ui->centralWidget->setEnabled(true);
+
+ settingsw->registerSoundFontOption();
+ registerBehaviorOptions();
+ settingsw->registerCustomizeWidgetOptions();
+
+ plistw = new qmpPlistWindow(this);
+ chnlw = new qmpChannelsWindow(this);
+ efxw = new qmpEfxWindow(this);
+ infow = new qmpInfoWindow(this);
+ helpw = new qmpHelpWindow(this);
+ timer = new QTimer(this);
+ renderf = new qmpRenderFunc(this);
+ panicf = new qmpPanicFunc(this);
+ if (argfiles.size())
+ {
+ plistw->emptyList();
+ for (auto &i : argfiles)
+ plistw->insertItem(i);
+ }
+
+ if (settings->getOptionBool("Behavior/DialogStatus"))
+ {
+ QRect g = settings->getOptionRaw("DialogStatus/MainW", QRect(-999, -999, 999, 999)).toRect();
+ if (g != QRect(-999, -999, 999, 999))
+ setGeometry(g);
+ }
+
+ 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);
+ const QStringList &qpp = clp->values("plugin");
+ std::vector<std::string> pp;
+ for (auto &s : qpp)
+ pp.push_back(s.toStdString());
+ pmgr->scanPlugins(pp);
+ settingsw->registerPluginOption(pmgr);
+ settingsw->updatePluginList(pmgr);
+ pmgr->initPlugins();
+
+ settingsw->registerExtraMidiOptions();
+
+ QVariant *dinif_v = static_cast<QVariant *>(settings->getOptionCustom("Midi/DeviceInitializationFiles"));
+ QList<QVariant> devinif_list = dinif_v->toList();
+ delete dinif_v;
+ QMap<QString, QString> devinif_map;
+ for (auto &i : devinif_list)
+ {
+ QPair<QString, QString> p = i.value<QPair<QString, QString>>();
+ devinif_map[p.first] = p.second;
+ }
+ auto rtdev = qmpRtMidiManager::getDevices();
+ for (auto &i : rtdev)
+ {
+ if (devinif_map.contains(QString(i.second.c_str())))
+ i.first->setInitializerFile(devinif_map[QString(i.second.c_str())].toStdString().c_str());
+ }
+ chnlw->selectDefaultDevice();
+
+ ui->vsMasterVol->setValue(settings->getOptionRaw("FluidSynth/Gain", 50).toInt());
+ connect(timer, &QTimer::timeout, this, &qmpMainWindow::updateWidgets);
+ connect(timer, &QTimer::timeout, infow, &qmpInfoWindow::updateInfo);
+ ui->pbNext->setIcon(QIcon(getThemedIcon(":/img/next.svg")));
+ ui->pbPrev->setIcon(QIcon(getThemedIcon(":/img/prev.svg")));
+ ui->pbPlayPause->setIcon(QIcon(getThemedIcon(":/img/play.svg")));
+ ui->pbStop->setIcon(QIcon(getThemedIcon(":/img/stop.svg")));
+ ui->pbSettings->setIcon(QIcon(getThemedIcon(":/img/settings.svg")));
+ ui->pbAdd->setIcon(QIcon(getThemedIcon(":/img/open.svg")));
+ if (argfiles.size())
+ on_pbPlayPause_clicked();
+ setupWidget();
+ settingsw->postInit();
}
int qmpMainWindow::parseArgs()
{
- bool loadfolder=clp->isSet("load-all-files");
- const QStringList &args=clp->positionalArguments();
- for(int i=0;i<args.size();++i)
- {
- if(QFileInfo(args.at(i)).exists())
- {
- if(loadfolder||settings->getOptionBool("Behavior/LoadFolder"))
- {
- QDirIterator di(QFileInfo(args.at(i)).absolutePath());
- while(di.hasNext())
- {
- QString c=di.next();
- argfiles.push_back(c);
- }
- }
- else
- argfiles.push_back(args.at(i));
- }
- }
- return 0;
+ bool loadfolder = clp->isSet("load-all-files");
+ const QStringList &args = clp->positionalArguments();
+ for (int i = 0; i < args.size(); ++i)
+ {
+ if (QFileInfo(args.at(i)).exists())
+ {
+ if (loadfolder || settings->getOptionBool("Behavior/LoadFolder"))
+ {
+ QDirIterator di(QFileInfo(args.at(i)).absolutePath());
+ while (di.hasNext())
+ {
+ QString c = di.next();
+ argfiles.push_back(c);
+ }
+ }
+ else
+ argfiles.push_back(args.at(i));
+ }
+ }
+ return 0;
}
void qmpMainWindow::closeEvent(QCloseEvent *event)
{
- if(settings->getOptionBool("Behavior/DialogStatus"))
- {
- settings->setOptionRaw("DialogStatus/MainW",geometry());
- }
- on_pbStop_clicked();fin=true;
- for(auto i=mfunc.begin();i!=mfunc.end();++i)
- {
- i->second.i()->close();
- i->second.setAssignedControl((QReflectiveAction*)nullptr),
- i->second.setAssignedControl((QReflectivePushButton*)nullptr);
- }
- efxw->close();chnlw->close();
- plistw->close();infow->close();
- settingsw->close();
- event->accept();
+ if (settings->getOptionBool("Behavior/DialogStatus"))
+ {
+ settings->setOptionRaw("DialogStatus/MainW", geometry());
+ }
+ on_pbStop_clicked();
+ fin = true;
+ for (auto i = mfunc.begin(); i != mfunc.end(); ++i)
+ {
+ i->second.i()->close();
+ i->second.setAssignedControl((QReflectiveAction *)nullptr),
+ i->second.setAssignedControl((QReflectivePushButton *)nullptr);
+ }
+ efxw->close();
+ chnlw->close();
+ plistw->close();
+ infow->close();
+ settingsw->close();
+ event->accept();
}
void qmpMainWindow::dropEvent(QDropEvent *event)
{
- QList<QUrl> l=event->mimeData()->urls();
- QStringList sl;
- for(int i=0;i<l.size();++i)
- sl.push_back(l.at(i).toLocalFile());
- plistw->insertItems(sl);
- switchTrack(plistw->getLastItem());
+ QList<QUrl> l = event->mimeData()->urls();
+ QStringList sl;
+ for (int i = 0; i < l.size(); ++i)
+ sl.push_back(l.at(i).toLocalFile());
+ plistw->insertItems(sl);
+ switchTrack(plistw->getLastItem());
}
void qmpMainWindow::dragEnterEvent(QDragEnterEvent *event)
{
- //if(event->mimeData()->hasFormat("application/x-midi"))
- event->acceptProposedAction();
+ //if(event->mimeData()->hasFormat("application/x-midi"))
+ event->acceptProposedAction();
}
void qmpMainWindow::updateWidgets()
{
- setFuncEnabled("Render",stopped);setFuncEnabled("ReloadSynth",stopped);
- if(player->isFinished()&&playerTh)
- {
- if(!plistw->getRepeat())
- {
- timer->stop();stopped=true;playing=false;
- invokeCallback("main.stop",nullptr);
- setFuncEnabled("Render",stopped);setFuncEnabled("ReloadSynth",stopped);
- player->playerDeinit();
- auto f=std::async([this]{playerTh->join();});
- while(f.wait_for(std::chrono::milliseconds(100))==std::future_status::timeout)
- {
- QApplication::processEvents();
- ui->lbCurPoly->setText(QString("%1").arg(internalfluid->getPolyphone(),5,10,QChar('0')));
- ui->lbMaxPoly->setText(QString("%1").arg(internalfluid->getMaxPolyphone(),5,10,QChar('0')));
- }
- delete playerTh;playerTh=nullptr;
- player->playerPanic(true);
- chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
- ui->pbPlayPause->setIcon(QIcon(getThemedIcon(":/img/play.svg")));
- ui->hsTimer->setValue(0);
- ui->lbCurPoly->setText("00000");ui->lbMaxPoly->setText("00000");
- ui->lbCurTime->setText("00:00");
- }
- else
- switchTrack(plistw->getNextItem(),false);
- }
- if(renderTh)
- {
- if(fluidrenderer->isFinished())
- {
- renderTh->join();timer->stop();
- ui->centralWidget->setEnabled(true);
- delete renderTh;renderTh=nullptr;
- fluidrenderer->renderDeinit();
- delete fluidrenderer;fluidrenderer=nullptr;
- }
- }
- while(!player->isFinished()&&player->getTCeptr()>player->getStamp(ui->hsTimer->value())
- &&ui->hsTimer->value()<100&&!dragging)
- ui->hsTimer->setValue(ui->hsTimer->value()+1);
- if(playing)
- {
- std::chrono::duration<double> elapsed=
- std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now()-st);
- char ts[100];
- sprintf(ts,"%02d:%02d",(int)(elapsed.count()+offset)/60,(int)(elapsed.count()+offset)%60);
- ui->lbCurTime->setText(ts);
- ui->lbCurPoly->setText(QString("%1").arg(internalfluid->getPolyphone(),5,10,QChar('0')));
- ui->lbMaxPoly->setText(QString("%1").arg(internalfluid->getMaxPolyphone(),5,10,QChar('0')));
- }
-}
-
-QString qmpMainWindow::getFileName(){return ui->lbFileName->text();}
-void qmpMainWindow::switchTrack(QString s,bool interrupt)
-{
- stopped=false;playing=true;
- setFuncEnabled("Render",stopped);setFuncEnabled("ReloadSynth",stopped);
- ui->pbPlayPause->setIcon(QIcon(getThemedIcon(":/img/pause.svg")));
- if(interrupt)
- {
- player->playerDeinit();
- player->playerPanic();
- }
- invokeCallback("main.stop",nullptr);
- if(playerTh)
- {
- auto f=std::async([this]{playerTh->join();});
- while(f.wait_for(std::chrono::milliseconds(100))==std::future_status::timeout)
- {
- QApplication::processEvents();
- ui->lbCurPoly->setText(QString("%1").arg(internalfluid->getPolyphone(),5,10,QChar('0')));
- ui->lbMaxPoly->setText(QString("%1").arg(internalfluid->getMaxPolyphone(),5,10,QChar('0')));
- }
- delete playerTh;playerTh=nullptr;
- }
- timer->stop();
- player->playerPanic(true);
- ui->hsTimer->setValue(0);
- 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();
- if(!loadFile(fns))return;
- char ts[100];
- sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
- ui->lbFinTime->setText(ts);
- player->playerInit();
- invokeCallback("main.start",nullptr);
- internalfluid->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
- playerTh=new std::thread([this]{
- player->playerThread();
- if(settings->getOptionBool("Midi/WaitVoice")&&player->isFinished())
- while(internalfluid->getPolyphone()>0)
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
- });
+ setFuncEnabled("Render", stopped);
+ setFuncEnabled("ReloadSynth", stopped);
+ if (player->isFinished() && playerTh)
+ {
+ if (!plistw->getRepeat())
+ {
+ timer->stop();
+ stopped = true;
+ playing = false;
+ invokeCallback("main.stop", nullptr);
+ setFuncEnabled("Render", stopped);
+ setFuncEnabled("ReloadSynth", stopped);
+ player->playerDeinit();
+ auto f = std::async([this] {playerTh->join();});
+ while (f.wait_for(std::chrono::milliseconds(100)) == std::future_status::timeout)
+ {
+ QApplication::processEvents();
+ ui->lbCurPoly->setText(QString("%1").arg(internalfluid->getPolyphone(), 5, 10, QChar('0')));
+ ui->lbMaxPoly->setText(QString("%1").arg(internalfluid->getMaxPolyphone(), 5, 10, QChar('0')));
+ }
+ delete playerTh;
+ playerTh = nullptr;
+ player->playerPanic(true);
+ chnlw->on_pbUnmute_clicked();
+ chnlw->on_pbUnsolo_clicked();
+ ui->pbPlayPause->setIcon(QIcon(getThemedIcon(":/img/play.svg")));
+ ui->hsTimer->setValue(0);
+ ui->lbCurPoly->setText("00000");
+ ui->lbMaxPoly->setText("00000");
+ ui->lbCurTime->setText("00:00");
+ }
+ else
+ switchTrack(plistw->getNextItem(), false);
+ }
+ if (renderTh)
+ {
+ if (fluidrenderer->isFinished())
+ {
+ renderTh->join();
+ timer->stop();
+ ui->centralWidget->setEnabled(true);
+ delete renderTh;
+ renderTh = nullptr;
+ fluidrenderer->renderDeinit();
+ delete fluidrenderer;
+ fluidrenderer = nullptr;
+ }
+ }
+ while (!player->isFinished() && player->getTCeptr() > player->getStamp(ui->hsTimer->value())
+ && ui->hsTimer->value() < 100 && !dragging)
+ ui->hsTimer->setValue(ui->hsTimer->value() + 1);
+ if (playing)
+ {
+ std::chrono::duration<double> elapsed =
+ std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - st);
+ char ts[100];
+ sprintf(ts, "%02d:%02d", (int)(elapsed.count() + offset) / 60, (int)(elapsed.count() + offset) % 60);
+ ui->lbCurTime->setText(ts);
+ ui->lbCurPoly->setText(QString("%1").arg(internalfluid->getPolyphone(), 5, 10, QChar('0')));
+ ui->lbMaxPoly->setText(QString("%1").arg(internalfluid->getMaxPolyphone(), 5, 10, QChar('0')));
+ }
+}
+
+QString qmpMainWindow::getFileName()
+{
+ return ui->lbFileName->text();
+}
+void qmpMainWindow::switchTrack(QString s, bool interrupt)
+{
+ stopped = false;
+ playing = true;
+ setFuncEnabled("Render", stopped);
+ setFuncEnabled("ReloadSynth", stopped);
+ ui->pbPlayPause->setIcon(QIcon(getThemedIcon(":/img/pause.svg")));
+ if (interrupt)
+ {
+ player->playerDeinit();
+ player->playerPanic();
+ }
+ invokeCallback("main.stop", nullptr);
+ if (playerTh)
+ {
+ auto f = std::async([this] {playerTh->join();});
+ while (f.wait_for(std::chrono::milliseconds(100)) == std::future_status::timeout)
+ {
+ QApplication::processEvents();
+ ui->lbCurPoly->setText(QString("%1").arg(internalfluid->getPolyphone(), 5, 10, QChar('0')));
+ ui->lbMaxPoly->setText(QString("%1").arg(internalfluid->getMaxPolyphone(), 5, 10, QChar('0')));
+ }
+ delete playerTh;
+ playerTh = nullptr;
+ }
+ timer->stop();
+ player->playerPanic(true);
+ ui->hsTimer->setValue(0);
+ 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();
+ if (!loadFile(fns))
+ return;
+ char ts[100];
+ sprintf(ts, "%02d:%02d", (int)player->getFtime() / 60, (int)player->getFtime() % 60);
+ ui->lbFinTime->setText(ts);
+ player->playerInit();
+ invokeCallback("main.start", nullptr);
+ internalfluid->setGain(ui->vsMasterVol->value() / 250.);
+ efxw->sendEfxChange();
+ playerTh = new std::thread([this]
+ {
+ player->playerThread();
+ if (settings->getOptionBool("Midi/WaitVoice") && player->isFinished())
+ while (internalfluid->getPolyphone() > 0)
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ });
#ifdef _WIN32
- SetThreadPriority((void*)playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+ SetThreadPriority((void *)playerTh->native_handle(), THREAD_PRIORITY_TIME_CRITICAL);
#endif
- st=std::chrono::steady_clock::now();offset=0;
- timer->start(UPDATE_INTERVAL);
+ st = std::chrono::steady_clock::now();
+ offset = 0;
+ timer->start(UPDATE_INTERVAL);
}
std::string qmpMainWindow::getTitle()
{
- if(settings->getOptionEnumIntOptName("Midi/TextEncoding")=="Unicode")
- return std::string(player->getTitle());
- return QTextCodec::codecForName(
- settings->getOptionEnumIntOptName("Midi/TextEncoding").c_str())->
- toUnicode(player->getTitle()).toStdString();
+ if (settings->getOptionEnumIntOptName("Midi/TextEncoding") == "Unicode")
+ return std::string(player->getTitle());
+ return QTextCodec::codecForName(
+ settings->getOptionEnumIntOptName("Midi/TextEncoding").c_str())->
+ toUnicode(player->getTitle()).toStdString();
}
std::wstring qmpMainWindow::getWTitle()
{
- if(settings->getOptionEnumIntOptName("Midi/TextEncoding")=="Unicode")
- return QString(player->getTitle()).toStdWString();
- return QTextCodec::codecForName(
- settings->getOptionEnumIntOptName("Midi/TextEncoding").c_str())->
- toUnicode(player->getTitle()).toStdWString();
-}
-
-void qmpMainWindow::playerSetup(IFluidSettings* fs)
-{
- fs->setOptStr("audio.driver",settings->getOptionEnumIntOptName("FluidSynth/AudioDriver").c_str());
- fs->setOptInt("audio.period-size",settings->getOptionInt("FluidSynth/BufSize"));
- fs->setOptInt("audio.periods",settings->getOptionInt("FluidSynth/BufCnt"));
- fs->setOptStr("audio.sample-format",settings->getOptionEnumIntOptName("FluidSynth/SampleFormat").c_str());
- fs->setOptNum("synth.sample-rate",settings->getOptionInt("FluidSynth/SampleRate"));
- fs->setOptInt("synth.polyphony",settings->getOptionInt("FluidSynth/Polyphony"));
- fs->setOptInt("synth.cpu-cores",settings->getOptionInt("FluidSynth/Threads"));
- std::string bsmode;
- if(settings->getOptionBool("FluidSynth/AutoBS")&&player->getFileStandard())
- switch(player->getFileStandard())
- {
- case 1:bsmode="gm";break;
- case 2:bsmode="mma";break;
- case 3:bsmode="gs";break;
- case 4:bsmode="xg";break;
- }
- else
- {
- bsmode=settings->getOptionEnumIntOptName("FluidSynth/BankSelect");
- std::transform(bsmode.begin(),bsmode.end(),bsmode.begin(),[](char i){return tolower(i);});
- }
- fs->setOptStr("synth.midi-bank-select",bsmode.c_str());
- player->sendSysX(settings->getOptionBool("Midi/SendSysEx"));
+ if (settings->getOptionEnumIntOptName("Midi/TextEncoding") == "Unicode")
+ return QString(player->getTitle()).toStdWString();
+ return QTextCodec::codecForName(
+ settings->getOptionEnumIntOptName("Midi/TextEncoding").c_str())->
+ toUnicode(player->getTitle()).toStdWString();
+}
+
+void qmpMainWindow::playerSetup(IFluidSettings *fs)
+{
+ fs->setOptStr("audio.driver", settings->getOptionEnumIntOptName("FluidSynth/AudioDriver").c_str());
+ fs->setOptInt("audio.period-size", settings->getOptionInt("FluidSynth/BufSize"));
+ fs->setOptInt("audio.periods", settings->getOptionInt("FluidSynth/BufCnt"));
+ fs->setOptStr("audio.sample-format", settings->getOptionEnumIntOptName("FluidSynth/SampleFormat").c_str());
+ fs->setOptNum("synth.sample-rate", settings->getOptionInt("FluidSynth/SampleRate"));
+ fs->setOptInt("synth.polyphony", settings->getOptionInt("FluidSynth/Polyphony"));
+ fs->setOptInt("synth.cpu-cores", settings->getOptionInt("FluidSynth/Threads"));
+ std::string bsmode;
+ if (settings->getOptionBool("FluidSynth/AutoBS") && player->getFileStandard())
+ switch (player->getFileStandard())
+ {
+ case 1:
+ bsmode = "gm";
+ break;
+ case 2:
+ bsmode = "mma";
+ break;
+ case 3:
+ bsmode = "gs";
+ break;
+ case 4:
+ bsmode = "xg";
+ break;
+ }
+ else
+ {
+ bsmode = settings->getOptionEnumIntOptName("FluidSynth/BankSelect");
+ std::transform(bsmode.begin(), bsmode.end(), bsmode.begin(), [](char i)
+ {
+ return tolower(i);
+ });
+ }
+ fs->setOptStr("synth.midi-bank-select", bsmode.c_str());
+ player->sendSysX(settings->getOptionBool("Midi/SendSysEx"));
}
void qmpMainWindow::loadSoundFont(IFluidSettings *fs)
{
- QVariant *data=static_cast<QVariant*>(settings->getOptionCustom("FluidSynth/SoundFonts"));
- QList<QVariant> sflist=data->toList();
- for(auto i=sflist.rbegin();i!=sflist.rend();++i)
- {
- if(i->toString().startsWith('#'))continue;
- QString sf=i->toString();
+ QVariant *data = static_cast<QVariant *>(settings->getOptionCustom("FluidSynth/SoundFonts"));
+ QList<QVariant> sflist = data->toList();
+ for (auto i = sflist.rbegin(); i != sflist.rend(); ++i)
+ {
+ if (i->toString().startsWith('#'))
+ continue;
+ QString sf = i->toString();
#ifdef _WIN32
- char* c=wcsto8bit(sf.toStdWString().c_str());
- fs->loadSFont(c);
- free(c);
+ char *c = wcsto8bit(sf.toStdWString().c_str());
+ fs->loadSFont(c);
+ free(c);
#else
- fs->loadSFont(sf.toStdString().c_str());
+ fs->loadSFont(sf.toStdString().c_str());
#endif
- }
- delete data;
+ }
+ delete data;
}
int qmpMainWindow::loadFile(QString fns)
{
#ifdef _WIN32
- char* c=wcsto8bit(fns.toStdWString().c_str());
+ char *c = wcsto8bit(fns.toStdWString().c_str());
#else
- std::string s=fns.toStdString();
- const char* c=s.c_str();
+ std::string s = fns.toStdString();
+ const char *c = s.c_str();
#endif
- int ret=1;
- invokeCallback("main.reset",nullptr);
- if(!player->playerLoadFile(c))
- {QMessageBox::critical(this,tr("Error"),tr("%1 is not a valid midi file.").arg(fns));ret=0;}
+ int ret = 1;
+ invokeCallback("main.reset", nullptr);
+ if (!player->playerLoadFile(c))
+ {
+ QMessageBox::critical(this, tr("Error"), tr("%1 is not a valid midi file.").arg(fns));
+ ret = 0;
+ }
#ifdef _WIN32
- free(c);
+ free(c);
#endif
- return ret;
+ return ret;
}
void qmpMainWindow::registerMidiOptions()
{
- settings->registerOptionBool("MIDI","Disable MIDI Mapping","Midi/DisableMapping",false);
- settings->registerOptionBool("MIDI","Send system exclusive messages","Midi/SendSysEx",true);
- settings->registerOptionBool("MIDI","Wait for remaining voice before stopping","Midi/WaitVoice",true);
- settings->registerOptionEnumInt("MIDI","Text encoding","Midi/TextEncoding",{"Unicode","Big5","Big5-HKSCS","CP949","EUC-JP","EUC-KR","GB18030","KOI8-R","KOI8-U","Macintosh","Shift-JIS"},0);
+ settings->registerOptionBool("MIDI", "Disable MIDI Mapping", "Midi/DisableMapping", false);
+ settings->registerOptionBool("MIDI", "Send system exclusive messages", "Midi/SendSysEx", true);
+ settings->registerOptionBool("MIDI", "Wait for remaining voice before stopping", "Midi/WaitVoice", true);
+ settings->registerOptionEnumInt("MIDI", "Text encoding", "Midi/TextEncoding", {"Unicode", "Big5", "Big5-HKSCS", "CP949", "EUC-JP", "EUC-KR", "GB18030", "KOI8-R", "KOI8-U", "Macintosh", "Shift-JIS"}, 0);
}
void qmpMainWindow::registerBehaviorOptions()
{
- settings->registerOptionBool("Behavior","Restore last playlist on startup","Behavior/RestorePlaylist",false);
- settings->registerOptionBool("Behavior","Add files in the same folder to playlist","Behavior/LoadFolder",false);
- settings->registerOptionBool("Behavior","Save dialog status","Behavior/DialogStatus",false);
- settings->registerOptionBool("Behavior","Show labels beside icon in toolbar buttons","Behavior/ShowButtonLabel",false);
- settings->registerOptionEnumInt("Behavior","Icon Theme","Behavior/IconTheme",{"Auto","Dark","Light"},0);
+ settings->registerOptionBool("Behavior", "Restore last playlist on startup", "Behavior/RestorePlaylist", false);
+ settings->registerOptionBool("Behavior", "Add files in the same folder to playlist", "Behavior/LoadFolder", false);
+ settings->registerOptionBool("Behavior", "Save dialog status", "Behavior/DialogStatus", false);
+ settings->registerOptionBool("Behavior", "Show labels beside icon in toolbar buttons", "Behavior/ShowButtonLabel", false);
+ settings->registerOptionEnumInt("Behavior", "Icon Theme", "Behavior/IconTheme", {"Auto", "Dark", "Light"}, 0);
}
void qmpMainWindow::on_pbPlayPause_clicked()
{
- playing=!playing;
- if(stopped)
- {
- QString fns=plistw->getFirstItem();
- if(!fns.length())
- {
- if(!plistw->on_pbAdd_clicked()){playing=false;return;}
- fns=plistw->getFirstItem();
- if(!fns.length())return(void)(playing=false);
- }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();
- if(!loadFile(fns))return;
- char ts[100];
- sprintf(ts,"%02d:%02d",(int)player->getFtime()/60,(int)player->getFtime()%60);
- ui->lbFinTime->setText(ts);
- player->playerInit();
- invokeCallback("main.start",nullptr);
- internalfluid->setGain(ui->vsMasterVol->value()/250.);efxw->sendEfxChange();
- playerTh=new std::thread([this]{
- player->playerThread();
- if(settings->getOptionBool("Midi/WaitVoice")&&player->isFinished())
- while(internalfluid->getPolyphone()>0)
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
- });
+ playing = !playing;
+ if (stopped)
+ {
+ QString fns = plistw->getFirstItem();
+ if (!fns.length())
+ {
+ if (!plistw->on_pbAdd_clicked())
+ {
+ playing = false;
+ return;
+ }
+ fns = plistw->getFirstItem();
+ if (!fns.length())
+ return (void)(playing = false);
+ }
+ 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();
+ if (!loadFile(fns))
+ return;
+ char ts[100];
+ sprintf(ts, "%02d:%02d", (int)player->getFtime() / 60, (int)player->getFtime() % 60);
+ ui->lbFinTime->setText(ts);
+ player->playerInit();
+ invokeCallback("main.start", nullptr);
+ internalfluid->setGain(ui->vsMasterVol->value() / 250.);
+ efxw->sendEfxChange();
+ playerTh = new std::thread([this]
+ {
+ player->playerThread();
+ if (settings->getOptionBool("Midi/WaitVoice") && player->isFinished())
+ while (internalfluid->getPolyphone() > 0)
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ });
#ifdef _WIN32
- SetThreadPriority((void*)playerTh->native_handle(),THREAD_PRIORITY_TIME_CRITICAL);
+ SetThreadPriority((void *)playerTh->native_handle(), THREAD_PRIORITY_TIME_CRITICAL);
#endif
- st=std::chrono::steady_clock::now();offset=0;
- timer->start(UPDATE_INTERVAL);
- stopped=false;
- }
- else
- {
- if(!playing)
- {
- player->playerPanic();
- offset=ui->hsTimer->value()/100.*player->getFtime();
- }
- else
- {
- st=std::chrono::steady_clock::now();
- player->setResumed();
- }
- player->setTCpaused(!playing);
- invokeCallback("main.pause",nullptr);
- }
- ui->pbPlayPause->setIcon(QIcon(getThemedIcon(playing?":/img/pause.svg":":/img/play.svg")));
+ st = std::chrono::steady_clock::now();
+ offset = 0;
+ timer->start(UPDATE_INTERVAL);
+ stopped = false;
+ }
+ else
+ {
+ if (!playing)
+ {
+ player->playerPanic();
+ offset = ui->hsTimer->value() / 100.*player->getFtime();
+ }
+ else
+ {
+ st = std::chrono::steady_clock::now();
+ player->setResumed();
+ }
+ player->setTCpaused(!playing);
+ invokeCallback("main.pause", nullptr);
+ }
+ ui->pbPlayPause->setIcon(QIcon(getThemedIcon(playing ? ":/img/pause.svg" : ":/img/play.svg")));
}
void qmpMainWindow::on_hsTimer_sliderPressed()
{
- dragging=true;
+ dragging = true;
}
void qmpMainWindow::on_hsTimer_sliderReleased()
{
- dragging=false;
- if(playing)
- {
- if(ui->hsTimer->value()==100){on_pbNext_clicked();return;}
- player->playerPanic();
- player->setTCeptr(player->getStamp(ui->hsTimer->value()),ui->hsTimer->value());
- offset=ui->hsTimer->value()/100.*player->getFtime();
- st=std::chrono::steady_clock::now();
- }
- else
- {
- if(stopped){ui->hsTimer->setValue(0);return;}
- 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);
- }
- invokeCallback("main.seek",nullptr);
-}
-
-uint32_t qmpMainWindow::getPlaybackPercentage(){return ui->hsTimer->value();}
+ dragging = false;
+ if (playing)
+ {
+ if (ui->hsTimer->value() == 100)
+ {
+ on_pbNext_clicked();
+ return;
+ }
+ player->playerPanic();
+ player->setTCeptr(player->getStamp(ui->hsTimer->value()), ui->hsTimer->value());
+ offset = ui->hsTimer->value() / 100.*player->getFtime();
+ st = std::chrono::steady_clock::now();
+ }
+ else
+ {
+ if (stopped)
+ {
+ ui->hsTimer->setValue(0);
+ return;
+ }
+ 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);
+ }
+ invokeCallback("main.seek", nullptr);
+}
+
+uint32_t qmpMainWindow::getPlaybackPercentage()
+{
+ return ui->hsTimer->value();
+}
void qmpMainWindow::playerSeek(uint32_t percentage)
{
- if(percentage>100)percentage=100;
- if(percentage<0)percentage=0;
- invokeCallback("main.seek",nullptr);
- if(playing)
- {
- if(percentage==100){on_pbNext_clicked();return;}
- player->playerPanic();ui->hsTimer->setValue(percentage);
- player->setTCeptr(player->getStamp(percentage),percentage);
- offset=percentage/100.*player->getFtime();
- st=std::chrono::steady_clock::now();
- }
- else
- {
- if(stopped){ui->hsTimer->setValue(0);return;}
- player->setTCeptr(player->getStamp(percentage),percentage);
- offset=percentage/100.*player->getFtime();ui->hsTimer->setValue(percentage);
- char ts[100];
- sprintf(ts,"%02d:%02d",(int)(offset)/60,(int)(offset)%60);
- ui->lbCurTime->setText(ts);
- }
+ if (percentage > 100)
+ percentage = 100;
+ if (percentage < 0)
+ percentage = 0;
+ invokeCallback("main.seek", nullptr);
+ if (playing)
+ {
+ if (percentage == 100)
+ {
+ on_pbNext_clicked();
+ return;
+ }
+ player->playerPanic();
+ ui->hsTimer->setValue(percentage);
+ player->setTCeptr(player->getStamp(percentage), percentage);
+ offset = percentage / 100.*player->getFtime();
+ st = std::chrono::steady_clock::now();
+ }
+ else
+ {
+ if (stopped)
+ {
+ ui->hsTimer->setValue(0);
+ return;
+ }
+ player->setTCeptr(player->getStamp(percentage), percentage);
+ offset = percentage / 100.*player->getFtime();
+ ui->hsTimer->setValue(percentage);
+ char ts[100];
+ sprintf(ts, "%02d:%02d", (int)(offset) / 60, (int)(offset) % 60);
+ ui->lbCurTime->setText(ts);
+ }
}
void qmpMainWindow::on_vsMasterVol_valueChanged()
{
- if(!stopped)internalfluid->setGain(ui->vsMasterVol->value()/250.);
- settings->setOptionRaw("FluidSynth/Gain",ui->vsMasterVol->value());
+ if (!stopped)
+ internalfluid->setGain(ui->vsMasterVol->value() / 250.);
+ settings->setOptionRaw("FluidSynth/Gain", ui->vsMasterVol->value());
}
void qmpMainWindow::on_pbStop_clicked()
{
- if(!stopped)
- {
- timer->stop();stopped=true;playing=false;
- invokeCallback("main.stop",nullptr);
- player->playerDeinit();
- setFuncEnabled("Render",stopped);setFuncEnabled("ReloadSynth",stopped);
- player->playerPanic(true);
- if(playerTh){playerTh->join();delete playerTh;playerTh=nullptr;}
- chnlw->on_pbUnmute_clicked();chnlw->on_pbUnsolo_clicked();
- ui->pbPlayPause->setIcon(QIcon(getThemedIcon(":/img/play.svg")));
- ui->hsTimer->setValue(0);
- ui->lbCurPoly->setText("00000");ui->lbMaxPoly->setText("00000");
- ui->lbCurTime->setText("00:00");
- }
+ if (!stopped)
+ {
+ timer->stop();
+ stopped = true;
+ playing = false;
+ invokeCallback("main.stop", nullptr);
+ player->playerDeinit();
+ setFuncEnabled("Render", stopped);
+ setFuncEnabled("ReloadSynth", stopped);
+ player->playerPanic(true);
+ if (playerTh)
+ {
+ playerTh->join();
+ delete playerTh;
+ playerTh = nullptr;
+ }
+ chnlw->on_pbUnmute_clicked();
+ chnlw->on_pbUnsolo_clicked();
+ ui->pbPlayPause->setIcon(QIcon(getThemedIcon(":/img/play.svg")));
+ ui->hsTimer->setValue(0);
+ ui->lbCurPoly->setText("00000");
+ ui->lbMaxPoly->setText("00000");
+ ui->lbCurTime->setText("00:00");
+ }
}
void qmpMainWindow::dialogClosed()
{
- if(!settingsw->isVisible())ui->pbSettings->setChecked(false);
+ if (!settingsw->isVisible())
+ ui->pbSettings->setChecked(false);
}
void qmpMainWindow::on_pbPrev_clicked()
{
- switchTrack(plistw->getPrevItem());
+ switchTrack(plistw->getPrevItem());
}
void qmpMainWindow::on_pbNext_clicked()
{
- switchTrack(plistw->getNextItem());
+ switchTrack(plistw->getNextItem());
}
void qmpMainWindow::selectionChanged()
{
- switchTrack(plistw->getSelectedItem());
+ switchTrack(plistw->getSelectedItem());
}
void qmpMainWindow::on_lbFileName_customContextMenuRequested(const QPoint &pos)
{
- QMenu menu(ui->lbFileName);
- menu.addActions(ui->lbFileName->actions());
- menu.exec(this->pos()+ui->lbFileName->pos()+pos);
+ QMenu menu(ui->lbFileName);
+ menu.addActions(ui->lbFileName->actions());
+ menu.exec(this->pos() + ui->lbFileName->pos() + pos);
}
void qmpMainWindow::onfnChanged()
{
- if(!ui->lbFileName->text().length())return;
- QFont f=ui->lbFileName->font();f.setPointSize(18);
- QFontMetrics fm(f);
- QSize size=fm.size(0,ui->lbFileName->text());
- double fw=ui->lbFileName->width()/(double)size.width();
- double fh=ui->lbFileName->height()/(double)size.height();
- double ps=floor(f.pointSizeF()*(fw<fh?fw:fh));if(ps<6)ps=6;
- f.setPointSizeF(ps>18?18:ps);
- ui->lbFileName->setFont(f);
+ if (!ui->lbFileName->text().length())
+ return;
+ QFont f = ui->lbFileName->font();
+ f.setPointSize(18);
+ QFontMetrics fm(f);
+ QSize size = fm.size(0, ui->lbFileName->text());
+ double fw = ui->lbFileName->width() / (double)size.width();
+ double fh = ui->lbFileName->height() / (double)size.height();
+ double ps = floor(f.pointSizeF() * (fw < fh ? fw : fh));
+ if (ps < 6)
+ ps = 6;
+ f.setPointSizeF(ps > 18 ? 18 : ps);
+ ui->lbFileName->setFont(f);
}
-int qmpMainWindow::registerUIHook(std::string e,ICallBack *callback,void* userdat)
+int qmpMainWindow::registerUIHook(std::string e, ICallBack *callback, void *userdat)
{
- std::map<int,std::pair<qmpCallBack,void*>>& m=muicb[e];
- int id=0;
- if(m.size())id=m.rbegin()->first+1;
- m[id]=std::make_pair(qmpCallBack(callback),userdat);
- return id;
+ std::map<int, std::pair<qmpCallBack, void *>> &m = muicb[e];
+ int id = 0;
+ if (m.size())
+ id = m.rbegin()->first + 1;
+ m[id] = std::make_pair(qmpCallBack(callback), userdat);
+ return id;
}
-int qmpMainWindow::registerUIHook(std::string e,callback_t callback,void *userdat)
+int qmpMainWindow::registerUIHook(std::string e, callback_t callback, void *userdat)
{
- std::map<int,std::pair<qmpCallBack,void*>>& m=muicb[e];
- int id=0;
- if(m.size())id=m.rbegin()->first+1;
- m[id]=std::make_pair(qmpCallBack(callback),userdat);
- return id;
+ std::map<int, std::pair<qmpCallBack, void *>> &m = muicb[e];
+ int id = 0;
+ if (m.size())
+ id = m.rbegin()->first + 1;
+ m[id] = std::make_pair(qmpCallBack(callback), userdat);
+ return id;
}
-void qmpMainWindow::unregisterUIHook(std::string e,int hook)
+void qmpMainWindow::unregisterUIHook(std::string e, int hook)
{
- std::map<int,std::pair<qmpCallBack,void*>>& m=muicb[e];
- m.erase(hook);
+ std::map<int, std::pair<qmpCallBack, void *>> &m = muicb[e];
+ m.erase(hook);
}
-void qmpMainWindow::registerFunctionality(qmpFuncBaseIntf *i,std::string name,std::string desc,const char *icon,int iconlen,bool checkable)
+void qmpMainWindow::registerFunctionality(qmpFuncBaseIntf *i, std::string name, std::string desc, const char *icon, int iconlen, bool checkable)
{
- if(mfunc.find(name)!=mfunc.end())return;
- mfunc[name]=qmpFuncPrivate(i,desc,icon,iconlen,checkable);
+ if (mfunc.find(name) != mfunc.end())
+ return;
+ mfunc[name] = qmpFuncPrivate(i, desc, icon, iconlen, checkable);
}
void qmpMainWindow::unregisterFunctionality(std::string name)
{
- mfunc.erase(name);
- for(auto i=enabled_actions.begin();i!=enabled_actions.end();++i)
- if(*i==name){enabled_actions.erase(i);break;}
- for(auto i=enabled_buttons.begin();i!=enabled_buttons.end();++i)
- if(*i==name){enabled_buttons.erase(i);break;}
- setupWidget();
+ mfunc.erase(name);
+ for (auto i = enabled_actions.begin(); i != enabled_actions.end(); ++i)
+ if (*i == name)
+ {
+ enabled_actions.erase(i);
+ break;
+ }
+ for (auto i = enabled_buttons.begin(); i != enabled_buttons.end(); ++i)
+ if (*i == name)
+ {
+ enabled_buttons.erase(i);
+ break;
+ }
+ setupWidget();
}
-void qmpMainWindow::setFuncState(std::string name,bool state)
-{mfunc[name].setChecked(state);}
-void qmpMainWindow::setFuncEnabled(std::string name,bool enable)
-{mfunc[name].setEnabled(enable);}
+void qmpMainWindow::setFuncState(std::string name, bool state)
+{
+ mfunc[name].setChecked(state);
+}
+void qmpMainWindow::setFuncEnabled(std::string name, bool enable)
+{
+ mfunc[name].setEnabled(enable);
+}
bool qmpMainWindow::isDarkTheme()
{
- if(!settings->getOptionEnumInt("Behavior/IconTheme"))
- {
- return ui->centralWidget->palette().color(QPalette::Background).lightness()<128;
- }
- else return 2-settings->getOptionEnumInt("Behavior/IconTheme");
+ if (!settings->getOptionEnumInt("Behavior/IconTheme"))
+ {
+ return ui->centralWidget->palette().color(QPalette::Background).lightness() < 128;
+ }
+ else return 2 - settings->getOptionEnumInt("Behavior/IconTheme");
}
void qmpMainWindow::startRender()
{
#ifdef _WIN32
- char* ofstr=wcsto8bit((plistw->getSelectedItem()+QString(".wav")).toStdWString().c_str());
- char* ifstr=wcsto8bit(plistw->getSelectedItem().toStdWString().c_str());
- fluidrenderer=new qmpFileRendererFluid(ifstr,ofstr);
- playerSetup(fluidrenderer);
- fluidrenderer->renderInit();
- free(ofstr);free(ifstr);
+ char *ofstr = wcsto8bit((plistw->getSelectedItem() + QString(".wav")).toStdWString().c_str());
+ char *ifstr = wcsto8bit(plistw->getSelectedItem().toStdWString().c_str());
+ fluidrenderer = new qmpFileRendererFluid(ifstr, ofstr);
+ playerSetup(fluidrenderer);
+ fluidrenderer->renderInit();
+ free(ofstr);
+ free(ifstr);
#else
- fluidrenderer=new qmpFileRendererFluid(
- plistw->getSelectedItem().toStdString().c_str(),
- (plistw->getSelectedItem()+QString(".wav")).toStdString().c_str()
- );
- playerSetup(fluidrenderer);
- fluidrenderer->renderInit();
+ fluidrenderer = new qmpFileRendererFluid(
+ plistw->getSelectedItem().toStdString().c_str(),
+ (plistw->getSelectedItem() + QString(".wav")).toStdString().c_str()
+ );
+ playerSetup(fluidrenderer);
+ fluidrenderer->renderInit();
#endif
- loadSoundFont(fluidrenderer);
- ui->centralWidget->setEnabled(false);
- fluidrenderer->setGain(ui->vsMasterVol->value()/250.);
- efxw->sendEfxChange(fluidrenderer);timer->start(UPDATE_INTERVAL);
- renderTh=new std::thread(&qmpFileRendererFluid::renderWorker,fluidrenderer);
+ loadSoundFont(fluidrenderer);
+ ui->centralWidget->setEnabled(false);
+ fluidrenderer->setGain(ui->vsMasterVol->value() / 250.);
+ efxw->sendEfxChange(fluidrenderer);
+ timer->start(UPDATE_INTERVAL);
+ renderTh = new std::thread(&qmpFileRendererFluid::renderWorker, fluidrenderer);
}
void qmpMainWindow::reloadSynth()
{
- ui->centralWidget->setEnabled(false);
- std::future<void> f=std::async(std::launch::async,
- [this]
- {
- internalfluid->deviceDeinit(true);
- playerSetup(internalfluid);
- internalfluid->deviceInit();
- loadSoundFont(internalfluid);
- }
- );
- while(f.wait_for(std::chrono::milliseconds(100))==std::future_status::timeout)
- QApplication::processEvents();
- ui->centralWidget->setEnabled(true);
+ ui->centralWidget->setEnabled(false);
+ std::future<void> f = std::async(std::launch::async,
+ [this]
+ {
+ internalfluid->deviceDeinit(true);
+ playerSetup(internalfluid);
+ internalfluid->deviceInit();
+ loadSoundFont(internalfluid);
+ }
+ );
+ while (f.wait_for(std::chrono::milliseconds(100)) == std::future_status::timeout)
+ QApplication::processEvents();
+ ui->centralWidget->setEnabled(true);
}
-std::map<std::string,qmpFuncPrivate>& qmpMainWindow::getFunc()
-{return mfunc;}
+std::map<std::string, qmpFuncPrivate> &qmpMainWindow::getFunc()
+{
+ return mfunc;
+}
void qmpMainWindow::setupWidget()
{
- for(auto i=mfunc.begin();i!=mfunc.end();++i)
- {
- i->second.setAssignedControl(static_cast<QReflectiveAction*>(nullptr));
- i->second.setAssignedControl(static_cast<QReflectivePushButton*>(nullptr));
- }
- QVariant *v=static_cast<QVariant*>(settings->getOptionCustom("Behavior/Toolbar"));
- enabled_buttons.clear();
- for(auto i:v->toList())
- enabled_buttons.push_back(i.toString().toStdString());
- delete v;
- v=static_cast<QVariant*>(settings->getOptionCustom("Behavior/Actions"));
- enabled_actions.clear();
- for(auto i:v->toList())
- enabled_actions.push_back(i.toString().toStdString());
- delete v;
- QList<QWidget*>w=ui->buttonwidget->findChildren<QWidget*>("",Qt::FindDirectChildrenOnly);
- qDeleteAll(w);
- QList<QAction*>a=ui->lbFileName->actions();
- for(int i=0;i<a.size();++i)
- {
- ui->lbFileName->removeAction(a[i]);
- delete a[i];
- }
- for(unsigned i=0;i<enabled_buttons.size();++i)
- {
- if(mfunc.find(enabled_buttons[i])==mfunc.end())continue;
- QReflectivePushButton *pb=new QReflectivePushButton(
- mfunc[enabled_buttons[i]].icon(),
- tr(mfunc[enabled_buttons[i]].desc().c_str()),
- enabled_buttons[i]
- );
- setButtonHeight(pb,32);
- //!!TODO
- if(settings->getOptionBool("Behavior/ShowButtonLabel"))
- {
- pb->setText(tr(mfunc[enabled_buttons[i]].desc().c_str()));
- pb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
- }
- else
- setButtonWidth(pb,32);
- pb->setIconSize(QSize(16,16));
- ui->buttonwidget->layout()->addWidget(pb);
- mfunc[enabled_buttons[i]].setAssignedControl(pb);
- connect(pb,&QReflectivePushButton::onClick,this,&qmpMainWindow::funcReflector);
- }
- for(unsigned i=0;i<enabled_actions.size();++i)
- {
- if(mfunc.find(enabled_actions[i])==mfunc.end())continue;
- QReflectiveAction *a=new QReflectiveAction(
- mfunc[enabled_actions[i]].icon(),
- tr(mfunc[enabled_actions[i]].desc().c_str()),
- enabled_actions[i]
- );
- ui->lbFileName->addAction(a);
- mfunc[enabled_actions[i]].setAssignedControl(a);
- connect(a,&QReflectiveAction::onClick,this,&qmpMainWindow::funcReflector);
- }
- ui->buttonwidget->layout()->setAlignment(Qt::AlignLeft);
-}
-
-void qmpMainWindow::invokeCallback(std::string cat,void* callerdat)
-{
- std::map<int,std::pair<qmpCallBack,void*>> *mp;
- mp=&muicb[cat];
- for(auto&i:*mp)
- i.second.first(callerdat,i.second.second);
+ for (auto i = mfunc.begin(); i != mfunc.end(); ++i)
+ {
+ i->second.setAssignedControl(static_cast<QReflectiveAction *>(nullptr));
+ i->second.setAssignedControl(static_cast<QReflectivePushButton *>(nullptr));
+ }
+ QVariant *v = static_cast<QVariant *>(settings->getOptionCustom("Behavior/Toolbar"));
+ enabled_buttons.clear();
+ for (auto i : v->toList())
+ enabled_buttons.push_back(i.toString().toStdString());
+ delete v;
+ v = static_cast<QVariant *>(settings->getOptionCustom("Behavior/Actions"));
+ enabled_actions.clear();
+ for (auto i : v->toList())
+ enabled_actions.push_back(i.toString().toStdString());
+ delete v;
+ QList<QWidget *>w = ui->buttonwidget->findChildren<QWidget *>("", Qt::FindDirectChildrenOnly);
+ qDeleteAll(w);
+ QList<QAction *>a = ui->lbFileName->actions();
+ for (int i = 0; i < a.size(); ++i)
+ {
+ ui->lbFileName->removeAction(a[i]);
+ delete a[i];
+ }
+ for (unsigned i = 0; i < enabled_buttons.size(); ++i)
+ {
+ if (mfunc.find(enabled_buttons[i]) == mfunc.end())
+ continue;
+ QReflectivePushButton *pb = new QReflectivePushButton(
+ mfunc[enabled_buttons[i]].icon(),
+ tr(mfunc[enabled_buttons[i]].desc().c_str()),
+ enabled_buttons[i]
+ );
+ setButtonHeight(pb, 32);
+ //!!TODO
+ if (settings->getOptionBool("Behavior/ShowButtonLabel"))
+ {
+ pb->setText(tr(mfunc[enabled_buttons[i]].desc().c_str()));
+ pb->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ }
+ else
+ setButtonWidth(pb, 32);
+ pb->setIconSize(QSize(16, 16));
+ ui->buttonwidget->layout()->addWidget(pb);
+ mfunc[enabled_buttons[i]].setAssignedControl(pb);
+ connect(pb, &QReflectivePushButton::onClick, this, &qmpMainWindow::funcReflector);
+ }
+ for (unsigned i = 0; i < enabled_actions.size(); ++i)
+ {
+ if (mfunc.find(enabled_actions[i]) == mfunc.end())
+ continue;
+ QReflectiveAction *a = new QReflectiveAction(
+ mfunc[enabled_actions[i]].icon(),
+ tr(mfunc[enabled_actions[i]].desc().c_str()),
+ enabled_actions[i]
+ );
+ ui->lbFileName->addAction(a);
+ mfunc[enabled_actions[i]].setAssignedControl(a);
+ connect(a, &QReflectiveAction::onClick, this, &qmpMainWindow::funcReflector);
+ }
+ ui->buttonwidget->layout()->setAlignment(Qt::AlignLeft);
+}
+
+void qmpMainWindow::invokeCallback(std::string cat, void *callerdat)
+{
+ std::map<int, std::pair<qmpCallBack, void *>> *mp;
+ mp = &muicb[cat];
+ for (auto &i : *mp)
+ i.second.first(callerdat, i.second.second);
}
void qmpMainWindow::on_pbSettings_clicked()
{
- if(ui->pbSettings->isChecked())settingsw->show();else settingsw->close();
+ if (ui->pbSettings->isChecked())
+ settingsw->show();
+ else settingsw->close();
}
void qmpMainWindow::funcReflector(std::string reflt)
{
- if(mfunc[reflt].isCheckable())
- {
- mfunc[reflt].setChecked(!mfunc[reflt].isChecked());
- if(mfunc[reflt].isChecked())
- mfunc[reflt].i()->show();
- else
- mfunc[reflt].i()->close();
- }
- else mfunc[reflt].i()->show();
+ if (mfunc[reflt].isCheckable())
+ {
+ mfunc[reflt].setChecked(!mfunc[reflt].isChecked());
+ if (mfunc[reflt].isChecked())
+ mfunc[reflt].i()->show();
+ else
+ mfunc[reflt].i()->close();
+ }
+ else mfunc[reflt].i()->show();
}
void qmpMainWindow::on_pushButton_clicked()
{
- helpw->show();
+ helpw->show();
}
-qmpFuncPrivate::qmpFuncPrivate(qmpFuncBaseIntf *i,std::string _desc,const char *icon,int iconlen,bool checkable):
- _i(i),des(_desc),_checkable(checkable)
+qmpFuncPrivate::qmpFuncPrivate(qmpFuncBaseIntf *i, std::string _desc, const char *icon, int iconlen, bool checkable):
+ _i(i), des(_desc), _checkable(checkable)
{
- if(icon)
- {
- QImage img;
- if(icon[0]==':'&&icon[1]=='/'||icon[0]=='q'&&icon[1]=='r'&&icon[2]=='c')
- img=QImage(QString(icon));
- else
- img.loadFromData((uchar*)icon,iconlen);
- QPixmap pixm;pixm.convertFromImage(img);
- _icon=QIcon(pixm);
- }else _icon=QIcon();
- checked=false;
- asgna=nullptr;asgnb=nullptr;
+ if (icon)
+ {
+ QImage img;
+ if (icon[0] == ':' && icon[1] == '/' || icon[0] == 'q' && icon[1] == 'r' && icon[2] == 'c')
+ img = QImage(QString(icon));
+ else
+ img.loadFromData((uchar *)icon, iconlen);
+ QPixmap pixm;
+ pixm.convertFromImage(img);
+ _icon = QIcon(pixm);
+ }
+ else _icon = QIcon();
+ checked = false;
+ asgna = nullptr;
+ asgnb = nullptr;
}
void qmpMainWindow::on_pbAdd_clicked()
{
- if(plistw->on_pbAdd_clicked())
- switchTrack(plistw->getLastItem());
+ if (plistw->on_pbAdd_clicked())
+ switchTrack(plistw->getLastItem());
}
diff --git a/qmidiplayer-desktop/qmpmainwindow.hpp b/qmidiplayer-desktop/qmpmainwindow.hpp
index d98029d..28fb82c 100644
--- a/qmidiplayer-desktop/qmpmainwindow.hpp
+++ b/qmidiplayer-desktop/qmpmainwindow.hpp
@@ -33,79 +33,122 @@
#define getThemedIcon(x) (qmpMainWindow::getInstance()->isDarkTheme()?QString(x).insert(QString(x).lastIndexOf('.'),"_i"):QString(x))
#define getThemedIconc(x) ((qmpMainWindow::getInstance()->isDarkTheme()?QString(x).insert(QString(x).lastIndexOf('.'),"_i"):QString(x)).toStdString().c_str())
-namespace Ui {
- class qmpMainWindow;
+namespace Ui
+{
+class qmpMainWindow;
}
-class QClickableSlider:public QSlider
+class QClickableSlider : public QSlider
{
- Q_OBJECT
- public:
- explicit QClickableSlider(QWidget *parent=0):QSlider(parent){}
- protected:
- void mouseReleaseEvent(QMouseEvent *e)
- {
- QSlider::mouseReleaseEvent(e);
- if(e->buttons()^Qt::LeftButton)
- {
- double p=e->pos().x()/(double)width();
- setValue(p*(maximum()-minimum())+minimum());
- emit sliderReleased();
- }
- }
+ Q_OBJECT
+public:
+ explicit QClickableSlider(QWidget *parent = 0) : QSlider(parent) {}
+protected:
+ void mouseReleaseEvent(QMouseEvent *e)
+ {
+ QSlider::mouseReleaseEvent(e);
+ if (e->buttons()^Qt::LeftButton)
+ {
+ double p = e->pos().x() / (double)width();
+ setValue(p * (maximum() - minimum()) + minimum());
+ emit sliderReleased();
+ }
+ }
};
-class QReflectiveAction:public QAction
+class QReflectiveAction : public QAction
{
- Q_OBJECT
- private:
- std::string reflt;
- signals:
- void onClick(std::string s);
- public:
- explicit QReflectiveAction(const QIcon& icon,const QString& text,const std::string& ref):
- QAction(icon,text,nullptr),reflt(ref){
- connect(this,&QAction::triggered,std::bind(&QReflectiveAction::onClick,this,reflt));
- }
+ Q_OBJECT
+private:
+ std::string reflt;
+signals:
+ void onClick(std::string s);
+public:
+ explicit QReflectiveAction(const QIcon &icon, const QString &text, const std::string &ref):
+ QAction(icon, text, nullptr), reflt(ref)
+ {
+ connect(this, &QAction::triggered, std::bind(&QReflectiveAction::onClick, this, reflt));
+ }
};
-class QReflectivePushButton:public QPushButton
+class QReflectivePushButton : public QPushButton
{
- Q_OBJECT
- private:
- std::string reflt;
- signals:
- void onClick(std::string s);
- public:
- explicit QReflectivePushButton(const QIcon& icon,const QString& text,const std::string& ref):
- QPushButton(icon,""),reflt(ref){
- connect(this,&QPushButton::clicked,std::bind(&QReflectivePushButton::onClick,this,reflt));
- setToolTip(text);
- }
+ Q_OBJECT
+private:
+ std::string reflt;
+signals:
+ void onClick(std::string s);
+public:
+ explicit QReflectivePushButton(const QIcon &icon, const QString &text, const std::string &ref):
+ QPushButton(icon, QString()), reflt(ref)
+ {
+ connect(this, &QPushButton::clicked, std::bind(&QReflectivePushButton::onClick, this, reflt));
+ setToolTip(text);
+ }
};
class qmpFuncPrivate
{
- private:
- qmpFuncBaseIntf* _i=nullptr;
- QIcon _icon;
- std::string des;
- bool _checkable,checked;
- QReflectiveAction* asgna=nullptr;
- QReflectivePushButton* asgnb=nullptr;
- public:
- qmpFuncPrivate(){}
- qmpFuncPrivate(qmpFuncBaseIntf* i,std::string _desc,const char* icon,int iconlen,bool checkable);
- ~qmpFuncPrivate(){asgna=nullptr;asgnb=nullptr;}
- qmpFuncBaseIntf* i(){return _i;}
- void setAssignedControl(QReflectiveAction* a){asgna=a;if(!a)return;asgna->setCheckable(_checkable);asgna->setChecked(checked);}
- void setAssignedControl(QReflectivePushButton* a){asgnb=a;if(!a)return;asgnb->setCheckable(_checkable);asgnb->setChecked(checked);}
- const QIcon& icon(){return _icon;}
- const std::string& desc(){return des;}
- bool isCheckable(){return _checkable;}
- bool isChecked(){return checked;}
- void setEnabled(bool e){if(asgna)asgna->setEnabled(e);if(asgnb)asgnb->setEnabled(e);}
- void setChecked(bool _c){checked=_c;if(asgna)asgna->setChecked(checked);if(asgnb)asgnb->setChecked(checked);}
+private:
+ qmpFuncBaseIntf *_i = nullptr;
+ QIcon _icon;
+ std::string des;
+ bool _checkable, checked;
+ QReflectiveAction *asgna = nullptr;
+ QReflectivePushButton *asgnb = nullptr;
+public:
+ qmpFuncPrivate() {}
+ qmpFuncPrivate(qmpFuncBaseIntf *i, std::string _desc, const char *icon, int iconlen, bool checkable);
+ ~qmpFuncPrivate()
+ {
+ asgna = nullptr;
+ asgnb = nullptr;
+ }
+ qmpFuncBaseIntf *i()
+ {
+ return _i;
+ }
+ void setAssignedControl(QReflectiveAction *a)
+ {
+ asgna = a;
+ if (!a)return;
+ asgna->setCheckable(_checkable);
+ asgna->setChecked(checked);
+ }
+ void setAssignedControl(QReflectivePushButton *a)
+ {
+ asgnb = a;
+ if (!a)return;
+ asgnb->setCheckable(_checkable);
+ asgnb->setChecked(checked);
+ }
+ const QIcon &icon()
+ {
+ return _icon;
+ }
+ const std::string &desc()
+ {
+ return des;
+ }
+ bool isCheckable()
+ {
+ return _checkable;
+ }
+ bool isChecked()
+ {
+ return checked;
+ }
+ void setEnabled(bool e)
+ {
+ if (asgna)asgna->setEnabled(e);
+ if (asgnb)asgnb->setEnabled(e);
+ }
+ void setChecked(bool _c)
+ {
+ checked = _c;
+ if (asgna)asgna->setChecked(checked);
+ if (asgnb)asgnb->setChecked(checked);
+ }
};
class qmpRenderFunc;
@@ -114,144 +157,196 @@ class qmpReloadSynthFunc;
class qmpCallBack
{
- private:
- int t;
- ICallBack* cbc;
- callback_t cbf;
- public:
- qmpCallBack(){t=-1;cbc=nullptr;cbf=nullptr;}
- qmpCallBack(ICallBack* _cb){t=0;cbc=_cb;cbf=nullptr;}
- qmpCallBack(callback_t _cb){t=1;cbf=_cb;cbc=nullptr;}
- void operator ()(void* cbd,void* usrd)
- {
- if(t<0)return;
- if(t)cbf(cbd,usrd);
- else cbc->callBack(cbd,usrd);
- }
+private:
+ int t;
+ ICallBack *cbc;
+ callback_t cbf;
+public:
+ qmpCallBack()
+ {
+ t = -1;
+ cbc = nullptr;
+ cbf = nullptr;
+ }
+ qmpCallBack(ICallBack *_cb)
+ {
+ t = 0;
+ cbc = _cb;
+ cbf = nullptr;
+ }
+ qmpCallBack(callback_t _cb)
+ {
+ t = 1;
+ cbf = _cb;
+ cbc = nullptr;
+ }
+ void operator()(void *cbd, void *usrd)
+ {
+ if (t < 0)return;
+ if (t)cbf(cbd, usrd);
+ else cbc->callBack(cbd, usrd);
+ }
};
-class qmpMainWindow:public QMainWindow
+class qmpMainWindow: public QMainWindow
{
- Q_OBJECT
+ Q_OBJECT
- public:
- explicit qmpMainWindow(QCommandLineParser *clp,QWidget *parent=nullptr);
- void init();
- void closeEvent(QCloseEvent *event);
- void dropEvent(QDropEvent *event);
- void dragEnterEvent(QDragEnterEvent *event);
- ~qmpMainWindow();
- CMidiPlayer* getPlayer(){return player;}
- qmpMidiOutFluid* getFluid(){return internalfluid;}
- qmpSettings* getSettings(){return settings.get();}
- QTimer* getTimer(){return timer;}
- bool isFinalizing(){return fin;}
- QString getFileName();
- void switchTrack(QString s,bool interrupt=true);
- std::string getTitle();
- std::wstring getWTitle();
- uint32_t getPlaybackPercentage();
- void playerSeek(uint32_t percentage);
- 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);
- int registerUIHook(std::string e,callback_t callback,void* userdat);
- void unregisterUIHook(std::string e,int hook);
- void setFuncState(std::string name,bool state);
- void setFuncEnabled(std::string name,bool enable);
- bool isDarkTheme();
- void startRender();
- void reloadSynth();
- void setupWidget();
- void invokeCallback(std::string cat,void *callerdat);
- std::map<std::string,qmpFuncPrivate>& getFunc();
+public:
+ explicit qmpMainWindow(QCommandLineParser *clp, QWidget *parent = nullptr);
+ void init();
+ void closeEvent(QCloseEvent *event);
+ void dropEvent(QDropEvent *event);
+ void dragEnterEvent(QDragEnterEvent *event);
+ ~qmpMainWindow();
+ CMidiPlayer *getPlayer()
+ {
+ return player;
+ }
+ qmpMidiOutFluid *getFluid()
+ {
+ return internalfluid;
+ }
+ qmpSettings *getSettings()
+ {
+ return settings.get();
+ }
+ QTimer *getTimer()
+ {
+ return timer;
+ }
+ bool isFinalizing()
+ {
+ return fin;
+ }
+ QString getFileName();
+ void switchTrack(QString s, bool interrupt = true);
+ std::string getTitle();
+ std::wstring getWTitle();
+ uint32_t getPlaybackPercentage();
+ void playerSeek(uint32_t percentage);
+ 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);
+ int registerUIHook(std::string e, callback_t callback, void *userdat);
+ void unregisterUIHook(std::string e, int hook);
+ void setFuncState(std::string name, bool state);
+ void setFuncEnabled(std::string name, bool enable);
+ bool isDarkTheme();
+ void startRender();
+ void reloadSynth();
+ void setupWidget();
+ void invokeCallback(std::string cat, void *callerdat);
+ std::map<std::string, qmpFuncPrivate> &getFunc();
- private slots:
- void on_pbPlayPause_clicked();
- void updateWidgets();
- void on_hsTimer_sliderPressed();
- void on_hsTimer_sliderReleased();
- void on_vsMasterVol_valueChanged();
- void on_pbStop_clicked();
- void on_pbPrev_clicked();
- void on_pbNext_clicked();
- void on_lbFileName_customContextMenuRequested(const QPoint &pos);
- void on_pbSettings_clicked();
- void funcReflector(std::string reflt);
- void on_pushButton_clicked();
- void on_pbAdd_clicked();
+private slots:
+ void on_pbPlayPause_clicked();
+ void updateWidgets();
+ void on_hsTimer_sliderPressed();
+ void on_hsTimer_sliderReleased();
+ void on_vsMasterVol_valueChanged();
+ void on_pbStop_clicked();
+ void on_pbPrev_clicked();
+ void on_pbNext_clicked();
+ void on_lbFileName_customContextMenuRequested(const QPoint &pos);
+ void on_pbSettings_clicked();
+ void funcReflector(std::string reflt);
+ void on_pushButton_clicked();
+ void on_pbAdd_clicked();
- public slots:
- void dialogClosed();
- void selectionChanged();
+public slots:
+ void dialogClosed();
+ void selectionChanged();
- private:
- Ui::qmpMainWindow *ui;
- QTimer *timer;
- bool playing,stopped,dragging,fin;
- std::thread *playerTh=nullptr;
- std::thread *renderTh=nullptr;
- std::chrono::steady_clock::time_point st;
- double offset;
- CMidiPlayer *player;
- qmpMidiOutFluid *internalfluid;
- qmpFileRendererFluid *fluidrenderer;
- qmpPluginManager *pmgr;
- QPointer<qmpPlistWindow> plistw;
- QPointer<qmpChannelsWindow> chnlw;
- QPointer<qmpEfxWindow> efxw;
- QPointer<qmpInfoWindow> infow;
- QPointer<qmpHelpWindow> helpw;
- std::unique_ptr<qmpSettings> settings;
- QPointer<qmpSettingsWindow> settingsw;
- std::map<std::string,qmpFuncPrivate> mfunc;
- std::unordered_map<std::string,std::map<int,std::pair<qmpCallBack,void*>>> muicb;
- qmpRenderFunc* renderf;
- qmpPanicFunc* panicf;
- qmpReloadSynthFunc* reloadsynf;
- std::vector<std::string> enabled_buttons,enabled_actions;
- std::vector<QString> argfiles;
- QCommandLineParser *clp;
+private:
+ Ui::qmpMainWindow *ui;
+ QTimer *timer;
+ bool playing, stopped, dragging, fin;
+ std::thread *playerTh = nullptr;
+ std::thread *renderTh = nullptr;
+ std::chrono::steady_clock::time_point st;
+ double offset;
+ CMidiPlayer *player;
+ qmpMidiOutFluid *internalfluid;
+ qmpFileRendererFluid *fluidrenderer;
+ qmpPluginManager *pmgr;
+ QPointer<qmpPlistWindow> plistw;
+ QPointer<qmpChannelsWindow> chnlw;
+ QPointer<qmpEfxWindow> efxw;
+ QPointer<qmpInfoWindow> infow;
+ QPointer<qmpHelpWindow> helpw;
+ std::unique_ptr<qmpSettings> settings;
+ QPointer<qmpSettingsWindow> settingsw;
+ std::map<std::string, qmpFuncPrivate> mfunc;
+ std::unordered_map<std::string, std::map<int, std::pair<qmpCallBack, void *>>> muicb;
+ qmpRenderFunc *renderf;
+ qmpPanicFunc *panicf;
+ qmpReloadSynthFunc *reloadsynf;
+ std::vector<std::string> enabled_buttons, enabled_actions;
+ std::vector<QString> argfiles;
+ QCommandLineParser *clp;
- void onfnChanged();
- void playerSetup(IFluidSettings *fs);
- void loadSoundFont(IFluidSettings *fs);
- int loadFile(QString fns);
- void registerMidiOptions();
- void registerBehaviorOptions();
+ void onfnChanged();
+ void playerSetup(IFluidSettings *fs);
+ void loadSoundFont(IFluidSettings *fs);
+ int loadFile(QString fns);
+ void registerMidiOptions();
+ void registerBehaviorOptions();
- private:
- static qmpMainWindow* ref;
- public: static qmpMainWindow* getInstance(){return ref;}
+private:
+ static qmpMainWindow *ref;
+public:
+ static qmpMainWindow *getInstance()
+ {
+ return ref;
+ }
};
-class qmpRenderFunc:public qmpFuncBaseIntf
+class qmpRenderFunc: public qmpFuncBaseIntf
{
- private:
- qmpMainWindow *p;
- public:
- qmpRenderFunc(qmpMainWindow *par){p=par;}
- void show(){p->startRender();}
- void close(){}
+private:
+ qmpMainWindow *p;
+public:
+ qmpRenderFunc(qmpMainWindow *par)
+ {
+ p = par;
+ }
+ void show()
+ {
+ p->startRender();
+ }
+ void close() {}
};
-class qmpPanicFunc:public qmpFuncBaseIntf
+class qmpPanicFunc: public qmpFuncBaseIntf
{
- private:
- qmpMainWindow *p;
- public:
- qmpPanicFunc(qmpMainWindow *par){p=par;}
- void show(){p->getPlayer()->playerPanic();}
- void close(){}
+private:
+ qmpMainWindow *p;
+public:
+ qmpPanicFunc(qmpMainWindow *par)
+ {
+ p = par;
+ }
+ void show()
+ {
+ p->getPlayer()->playerPanic();
+ }
+ void close() {}
};
-class qmpReloadSynthFunc:public qmpFuncBaseIntf
+class qmpReloadSynthFunc: public qmpFuncBaseIntf
{
- private:
- qmpMainWindow *p;
- public:
- qmpReloadSynthFunc(qmpMainWindow *par){p=par;}
- void show(){p->reloadSynth();}
- void close(){}
+private:
+ qmpMainWindow *p;
+public:
+ qmpReloadSynthFunc(qmpMainWindow *par)
+ {
+ p = par;
+ }
+ void show()
+ {
+ p->reloadSynth();
+ }
+ void close() {}
};
#endif // QMPMAINWINDOW_H
diff --git a/qmidiplayer-desktop/qmpplistwindow.cpp b/qmidiplayer-desktop/qmpplistwindow.cpp
index 5b46fb6..55cc980 100644
--- a/qmidiplayer-desktop/qmpplistwindow.cpp
+++ b/qmidiplayer-desktop/qmpplistwindow.cpp
@@ -13,340 +13,378 @@
#define setButtonHeight(x,h) {x->setMaximumHeight(h*(logicalDpiY()/96.));x->setMinimumHeight(h*(logicalDpiY()/96.));}
qmpPlistWindow::qmpPlistWindow(QWidget *parent):
- QWidget(parent,Qt::Dialog),
- ui(new Ui::qmpPlistWindow)
+ QWidget(parent, Qt::Dialog),
+ ui(new Ui::qmpPlistWindow)
{
- ui->setupUi(this);
- setButtonHeight(ui->pbAdd,36);setButtonHeight(ui->pbAddFolder,36);
- setButtonHeight(ui->pbClear,36);setButtonHeight(ui->pbLoad,36);
- setButtonHeight(ui->pbRemove,36);setButtonHeight(ui->pbRepeat,36);
- setButtonHeight(ui->pbSave,36);setButtonHeight(ui->pbShuffle,36);
- connect(this,&qmpPlistWindow::selectionChanging,(qmpMainWindow*)parent,&qmpMainWindow::selectionChanged);
- repeat=0;shuffle=0;
- settings=qmpMainWindow::getInstance()->getSettings();
- if(settings->getOptionBool("Behavior/RestorePlaylist"))
- {
- QSettings* plist=new QSettings(QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ConfigLocation)+QString("/qmpplist"),
- QSettings::IniFormat);
- int fc=plist->value("Playlist/FileCount",0).toInt();
- ui->lwFiles->clear();for(int i=0;i<fc;++i)
- ui->lwFiles->addItem(plist->value("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),"").toString());
- repeat=plist->value("Playlist/Repeat",0).toInt();
- shuffle=plist->value("Playlist/Shuffle",0).toInt();
- switch(shuffle)
- {
- case 1:
- ui->pbShuffle->setIcon(QIcon(getThemedIcon(":/img/shuffle.svg")));
- ui->pbShuffle->setText("Shuffle On");
- break;
- case 0:
- default:
- ui->pbShuffle->setIcon(QIcon(getThemedIcon(":/img/shuffle-off.svg")));
- ui->pbShuffle->setText("Shuffle Off");
- break;
- }
- switch(repeat)
- {
- case 0:
- ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-non.svg")));
- ui->pbRepeat->setText("Repeat Off");
- break;
- case 1:
- ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-one.svg")));
- ui->pbRepeat->setText("Repeat One");
- break;
- case 2:
- ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-all.svg")));
- ui->pbRepeat->setText("Repeat All");
- break;
- }
- delete plist;
- }
- ui->pbAdd->setIcon(QIcon(getThemedIcon(":/img/add.svg")));
- ui->pbRemove->setIcon(QIcon(getThemedIcon(":/img/remove.svg")));
- ui->pbClear->setIcon(QIcon(getThemedIcon(":/img/clear.svg")));
- ui->pbAddFolder->setIcon(QIcon(getThemedIcon(":/img/addfolder.svg")));
- ui->pbSave->setIcon(QIcon(getThemedIcon(":/img/save.svg")));
- ui->pbLoad->setIcon(QIcon(getThemedIcon(":/img/load.svg")));
- qmpMainWindow::getInstance()->registerFunctionality(
- plistf=new qmpPlistFunc(this),
- std::string("Playlist"),
- tr("Playlist").toStdString(),
- getThemedIconc(":/img/list.svg"),
- 0,
- true
- );
- if(settings->getOptionRaw("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999))
- setGeometry(settings->getOptionRaw("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect());
- if(settings->getOptionRaw("DialogStatus/PListWShown",0).toInt())
- {show();qmpMainWindow::getInstance()->setFuncState("Playlist",true);}
+ ui->setupUi(this);
+ setButtonHeight(ui->pbAdd, 36);
+ setButtonHeight(ui->pbAddFolder, 36);
+ setButtonHeight(ui->pbClear, 36);
+ setButtonHeight(ui->pbLoad, 36);
+ setButtonHeight(ui->pbRemove, 36);
+ setButtonHeight(ui->pbRepeat, 36);
+ setButtonHeight(ui->pbSave, 36);
+ setButtonHeight(ui->pbShuffle, 36);
+ connect(this, &qmpPlistWindow::selectionChanging, (qmpMainWindow *)parent, &qmpMainWindow::selectionChanged);
+ repeat = 0;
+ shuffle = 0;
+ settings = qmpMainWindow::getInstance()->getSettings();
+ if (settings->getOptionBool("Behavior/RestorePlaylist"))
+ {
+ QSettings *plist = new QSettings(QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ConfigLocation) + QString("/qmpplist"),
+ QSettings::IniFormat);
+ int fc = plist->value("Playlist/FileCount", 0).toInt();
+ ui->lwFiles->clear();
+ for (int i = 0; i < fc; ++i)
+ ui->lwFiles->addItem(plist->value("Playlist/File" + QString("%1").arg(i, 5, 10, QChar('0')), "").toString());
+ repeat = plist->value("Playlist/Repeat", 0).toInt();
+ shuffle = plist->value("Playlist/Shuffle", 0).toInt();
+ switch (shuffle)
+ {
+ case 1:
+ ui->pbShuffle->setIcon(QIcon(getThemedIcon(":/img/shuffle.svg")));
+ ui->pbShuffle->setText("Shuffle On");
+ break;
+ case 0:
+ default:
+ ui->pbShuffle->setIcon(QIcon(getThemedIcon(":/img/shuffle-off.svg")));
+ ui->pbShuffle->setText("Shuffle Off");
+ break;
+ }
+ switch (repeat)
+ {
+ case 0:
+ ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-non.svg")));
+ ui->pbRepeat->setText("Repeat Off");
+ break;
+ case 1:
+ ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-one.svg")));
+ ui->pbRepeat->setText("Repeat One");
+ break;
+ case 2:
+ ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-all.svg")));
+ ui->pbRepeat->setText("Repeat All");
+ break;
+ }
+ delete plist;
+ }
+ ui->pbAdd->setIcon(QIcon(getThemedIcon(":/img/add.svg")));
+ ui->pbRemove->setIcon(QIcon(getThemedIcon(":/img/remove.svg")));
+ ui->pbClear->setIcon(QIcon(getThemedIcon(":/img/clear.svg")));
+ ui->pbAddFolder->setIcon(QIcon(getThemedIcon(":/img/addfolder.svg")));
+ ui->pbSave->setIcon(QIcon(getThemedIcon(":/img/save.svg")));
+ ui->pbLoad->setIcon(QIcon(getThemedIcon(":/img/load.svg")));
+ qmpMainWindow::getInstance()->registerFunctionality(
+ plistf = new qmpPlistFunc(this),
+ std::string("Playlist"),
+ tr("Playlist").toStdString(),
+ getThemedIconc(":/img/list.svg"),
+ 0,
+ true
+ );
+ if (settings->getOptionRaw("DialogStatus/PListW", QRect(-999, -999, 999, 999)).toRect() != QRect(-999, -999, 999, 999))
+ setGeometry(settings->getOptionRaw("DialogStatus/PListW", QRect(-999, -999, 999, 999)).toRect());
+ if (settings->getOptionRaw("DialogStatus/PListWShown", 0).toInt())
+ {
+ show();
+ qmpMainWindow::getInstance()->setFuncState("Playlist", true);
+ }
}
qmpPlistWindow::~qmpPlistWindow()
{
- qmpMainWindow::getInstance()->unregisterFunctionality("Playlist");
- delete plistf;
- delete ui;
+ qmpMainWindow::getInstance()->unregisterFunctionality("Playlist");
+ delete plistf;
+ delete ui;
}
void qmpPlistWindow::showEvent(QShowEvent *event)
{
- if(settings->getOptionBool("Behavior/DialogStatus"))
- {
- settings->setOptionRaw("DialogStatus/PListWShown",1);
- }
- if(settings->getOptionRaw("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect()!=QRect(-999,-999,999,999))
- setGeometry(settings->getOptionRaw("DialogStatus/PListW",QRect(-999,-999,999,999)).toRect());
- event->accept();
+ if (settings->getOptionBool("Behavior/DialogStatus"))
+ {
+ settings->setOptionRaw("DialogStatus/PListWShown", 1);
+ }
+ if (settings->getOptionRaw("DialogStatus/PListW", QRect(-999, -999, 999, 999)).toRect() != QRect(-999, -999, 999, 999))
+ setGeometry(settings->getOptionRaw("DialogStatus/PListW", QRect(-999, -999, 999, 999)).toRect());
+ event->accept();
}
void qmpPlistWindow::closeEvent(QCloseEvent *event)
{
- if(settings->getOptionBool("Behavior/DialogStatus"))
- {
- settings->setOptionRaw("DialogStatus/PListW",geometry());
- }
- setVisible(false);
- if(!qmpMainWindow::getInstance()->isFinalizing())
- while(ui->lwFiles->count()>1)delete ui->lwFiles->item(0);
- if(!qmpMainWindow::getInstance()->isFinalizing()&&settings->getOptionBool("Behavior/DialogStatus"))
- {
- settings->setOptionRaw("DialogStatus/PListWShown",0);
- }
- if(qmpMainWindow::getInstance()->isFinalizing()&&settings->getOptionBool("Behavior/RestorePlaylist"))
- {
- QSettings* plist=new QSettings(QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ConfigLocation)+QString("/qmpplist"),
- QSettings::IniFormat);
- plist->setValue("Playlist/FileCount",ui->lwFiles->count());
- for(int i=0;i<ui->lwFiles->count();++i)
- plist->setValue("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),ui->lwFiles->item(i)->text());
- plist->setValue("Playlist/Repeat",repeat);
- plist->setValue("Playlist/Shuffle",shuffle);
- plist->sync();
- delete plist;
- }
- qmpMainWindow::getInstance()->setFuncState("Playlist",false);
- event->accept();
+ if (settings->getOptionBool("Behavior/DialogStatus"))
+ {
+ settings->setOptionRaw("DialogStatus/PListW", geometry());
+ }
+ setVisible(false);
+ if (!qmpMainWindow::getInstance()->isFinalizing())
+ while (ui->lwFiles->count() > 1)
+ delete ui->lwFiles->item(0);
+ if (!qmpMainWindow::getInstance()->isFinalizing() && settings->getOptionBool("Behavior/DialogStatus"))
+ {
+ settings->setOptionRaw("DialogStatus/PListWShown", 0);
+ }
+ if (qmpMainWindow::getInstance()->isFinalizing() && settings->getOptionBool("Behavior/RestorePlaylist"))
+ {
+ QSettings *plist = new QSettings(QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ConfigLocation) + QString("/qmpplist"),
+ QSettings::IniFormat);
+ plist->setValue("Playlist/FileCount", ui->lwFiles->count());
+ for (int i = 0; i < ui->lwFiles->count(); ++i)
+ plist->setValue("Playlist/File" + QString("%1").arg(i, 5, 10, QChar('0')), ui->lwFiles->item(i)->text());
+ plist->setValue("Playlist/Repeat", repeat);
+ plist->setValue("Playlist/Shuffle", shuffle);
+ plist->sync();
+ delete plist;
+ }
+ qmpMainWindow::getInstance()->setFuncState("Playlist", false);
+ event->accept();
}
void qmpPlistWindow::dropEvent(QDropEvent *event)
{
- QList<QUrl> l=event->mimeData()->urls();
- QStringList sl;
- for(int i=0;i<l.size();++i)
- sl.push_back(l.at(i).toLocalFile());
- insertItems(sl);
+ QList<QUrl> l = event->mimeData()->urls();
+ QStringList sl;
+ for (int i = 0; i < l.size(); ++i)
+ sl.push_back(l.at(i).toLocalFile());
+ insertItems(sl);
}
void qmpPlistWindow::dragEnterEvent(QDragEnterEvent *event)
{
- //if(event->mimeData()->hasFormat("application/x-midi"))
- event->acceptProposedAction();
+ //if(event->mimeData()->hasFormat("application/x-midi"))
+ event->acceptProposedAction();
}
void qmpPlistWindow::emptyList()
{
- ui->lwFiles->clear();
+ ui->lwFiles->clear();
}
void qmpPlistWindow::insertItem(QString i)
{
- ui->lwFiles->addItem(new QListWidgetItem(i));
+ ui->lwFiles->addItem(new QListWidgetItem(i));
}
void qmpPlistWindow::insertItems(QStringList il)
{
- ui->lwFiles->addItems(il);
+ ui->lwFiles->addItems(il);
}
int qmpPlistWindow::on_pbAdd_clicked()
{
- QStringList sl;
- if(settings->getOptionBool("Behavior/DialogStatus"))
- sl=QFileDialog::getOpenFileNames(this,"Add File",settings->getOptionRaw("DialogStatus/FileDialogPath","").toString(),"Midi files (*.mid *.midi)");
- else
- sl=QFileDialog::getOpenFileNames(this,"Add File","","Midi files (*.mid *.midi *.rmi)");
- if(sl.empty())return 0;
- for(int i=0;i<sl.size();++i)
- ui->lwFiles->addItem(new QListWidgetItem(sl.at(i)));
- if(!isVisible())while(ui->lwFiles->count()>1)delete ui->lwFiles->item(0);
- if(settings->getOptionBool("Behavior/DialogStatus"))
- settings->setOptionRaw("DialogStatus/FileDialogPath",
- QUrl(sl.at(0)).toString(QUrl::RemoveFilename));
- return 1;
+ QStringList sl;
+ if (settings->getOptionBool("Behavior/DialogStatus"))
+ sl = QFileDialog::getOpenFileNames(this, "Add File", settings->getOptionRaw("DialogStatus/FileDialogPath", "").toString(), "Midi files (*.mid *.midi)");
+ else
+ sl = QFileDialog::getOpenFileNames(this, "Add File", "", "Midi files (*.mid *.midi *.rmi)");
+ if (sl.empty())
+ return 0;
+ for (int i = 0; i < sl.size(); ++i)
+ ui->lwFiles->addItem(new QListWidgetItem(sl.at(i)));
+ if (!isVisible())
+ while (ui->lwFiles->count() > 1)
+ delete ui->lwFiles->item(0);
+ if (settings->getOptionBool("Behavior/DialogStatus"))
+ settings->setOptionRaw("DialogStatus/FileDialogPath",
+ QUrl(sl.at(0)).toString(QUrl::RemoveFilename));
+ return 1;
}
void qmpPlistWindow::on_pbAddFolder_clicked()
{
- QDirIterator di(QFileDialog::getExistingDirectory(this,"Add Folder"));
- while(di.hasNext())
- {
- QString c=di.next();
- if((c.endsWith(".mid")||c.endsWith(".midi")||c.endsWith(".rmi"))&&fluid_is_midifile(c.toStdString().c_str()))
- ui->lwFiles->addItem(new QListWidgetItem(c));
- }
+ QDirIterator di(QFileDialog::getExistingDirectory(this, "Add Folder"));
+ while (di.hasNext())
+ {
+ QString c = di.next();
+ if ((c.endsWith(".mid") || c.endsWith(".midi") || c.endsWith(".rmi")) && fluid_is_midifile(c.toStdString().c_str()))
+ ui->lwFiles->addItem(new QListWidgetItem(c));
+ }
}
void qmpPlistWindow::on_pbRemove_clicked()
{
- QList<QListWidgetItem*> sl=ui->lwFiles->selectedItems();
- for(int i=0;i<sl.size();++i)
- {
- ui->lwFiles->removeItemWidget(sl.at(i));
- delete sl.at(i);
- }
+ QList<QListWidgetItem *> sl = ui->lwFiles->selectedItems();
+ for (int i = 0; i < sl.size(); ++i)
+ {
+ ui->lwFiles->removeItemWidget(sl.at(i));
+ delete sl.at(i);
+ }
}
void qmpPlistWindow::on_pbClear_clicked()
{
- while(ui->lwFiles->count()>0)
- {
- QListWidgetItem *d=ui->lwFiles->item(0);
- ui->lwFiles->removeItemWidget(d);
- delete d;
- }
+ while (ui->lwFiles->count() > 0)
+ {
+ QListWidgetItem *d = ui->lwFiles->item(0);
+ ui->lwFiles->removeItemWidget(d);
+ delete d;
+ }
}
void qmpPlistWindow::on_pbRepeat_clicked()
{
- ++repeat;repeat%=3;
- switch(repeat)
- {
- case 0:
- ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-non.svg")));
- ui->pbRepeat->setText(tr("Repeat Off"));
- break;
- case 1:
- ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-one.svg")));
- ui->pbRepeat->setText(tr("Repeat One"));
- break;
- case 2:
- ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-all.svg")));
- ui->pbRepeat->setText(tr("Repeat All"));
- break;
- }
+ ++repeat;
+ repeat %= 3;
+ switch (repeat)
+ {
+ case 0:
+ ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-non.svg")));
+ ui->pbRepeat->setText(tr("Repeat Off"));
+ break;
+ case 1:
+ ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-one.svg")));
+ ui->pbRepeat->setText(tr("Repeat One"));
+ break;
+ case 2:
+ ui->pbRepeat->setIcon(QIcon(getThemedIcon(":/img/repeat-all.svg")));
+ ui->pbRepeat->setText(tr("Repeat All"));
+ break;
+ }
}
void qmpPlistWindow::on_pbShuffle_clicked()
{
- shuffle=1-shuffle;
- switch(shuffle)
- {
- case 1:
- ui->pbShuffle->setIcon(QIcon(getThemedIcon(":/img/shuffle.svg")));
- ui->pbShuffle->setText(tr("Shuffle On"));
- break;
- case 0:
- default:
- ui->pbShuffle->setIcon(QIcon(getThemedIcon(":/img/shuffle-off.svg")));
- ui->pbShuffle->setText(tr("Shuffle Off"));
- break;
- }
+ shuffle = 1 - shuffle;
+ switch (shuffle)
+ {
+ case 1:
+ ui->pbShuffle->setIcon(QIcon(getThemedIcon(":/img/shuffle.svg")));
+ ui->pbShuffle->setText(tr("Shuffle On"));
+ break;
+ case 0:
+ default:
+ ui->pbShuffle->setIcon(QIcon(getThemedIcon(":/img/shuffle-off.svg")));
+ ui->pbShuffle->setText(tr("Shuffle Off"));
+ break;
+ }
}
QString qmpPlistWindow::getFirstItem(bool a)
{
- if(ui->lwFiles->count()==0)return QString();
- int id=0;
- if(shuffle&&!a)id=rand()%ui->lwFiles->count();
- ui->lwFiles->setCurrentRow(id);
- return ui->lwFiles->item(id)->text();
+ if (ui->lwFiles->count() == 0)
+ return QString();
+ int id = 0;
+ 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();
+ 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();
}
QString qmpPlistWindow::getNextItem()
{
- if(ui->lwFiles->count()==0)return QString();
- if(repeat==1)return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
- int id=ui->lwFiles->currentRow();++id;id%=ui->lwFiles->count();
- if(shuffle)id=rand()%ui->lwFiles->count();
- ui->lwFiles->setCurrentRow(id);
- return ui->lwFiles->item(id)->text();
+ if (ui->lwFiles->count() == 0)
+ return QString();
+ if (repeat == 1)
+ return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
+ int id = ui->lwFiles->currentRow();
+ ++id;
+ id %= ui->lwFiles->count();
+ if (shuffle)
+ id = rand() % ui->lwFiles->count();
+ ui->lwFiles->setCurrentRow(id);
+ return ui->lwFiles->item(id)->text();
}
QString qmpPlistWindow::getPrevItem()
{
- if(ui->lwFiles->count()==0)return QString();
- if(repeat==1)return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
- int id=ui->lwFiles->currentRow();--id;
- id<0?id+=ui->lwFiles->count():0;
- if(shuffle)id=rand()%ui->lwFiles->count();
- ui->lwFiles->setCurrentRow(id);
- return ui->lwFiles->item(id)->text();
+ if (ui->lwFiles->count() == 0)
+ return QString();
+ if (repeat == 1)
+ return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
+ int id = ui->lwFiles->currentRow();
+ --id;
+ id < 0 ? id += ui->lwFiles->count() : 0;
+ if (shuffle)
+ id = rand() % ui->lwFiles->count();
+ ui->lwFiles->setCurrentRow(id);
+ return ui->lwFiles->item(id)->text();
}
QString qmpPlistWindow::getSelectedItem()
{
- if(ui->lwFiles->count()==0)return QString();
- return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
+ if (ui->lwFiles->count() == 0)
+ return QString();
+ return ui->lwFiles->item(ui->lwFiles->currentRow())->text();
+}
+int qmpPlistWindow::getRepeat()
+{
+ return repeat;
}
-int qmpPlistWindow::getRepeat(){return repeat;}
void qmpPlistWindow::on_lwFiles_itemDoubleClicked()
{
- emit selectionChanging();
+ emit selectionChanging();
}
void qmpPlistWindow::on_pbSave_clicked()
{
- QSettings* plist=new QSettings(QFileDialog::getSaveFileName(this,tr("Save playlist"),""),
- QSettings::IniFormat);
- plist->setValue("Playlist/FileCount",ui->lwFiles->count());
- for(int i=0;i<ui->lwFiles->count();++i)
- plist->setValue("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),ui->lwFiles->item(i)->text());
- plist->setValue("Playlist/Repeat",repeat);
- plist->setValue("Playlist/Shuffle",shuffle);
- plist->sync();
- delete plist;
+ QSettings *plist = new QSettings(QFileDialog::getSaveFileName(this, tr("Save playlist"), ""),
+ QSettings::IniFormat);
+ plist->setValue("Playlist/FileCount", ui->lwFiles->count());
+ for (int i = 0; i < ui->lwFiles->count(); ++i)
+ plist->setValue("Playlist/File" + QString("%1").arg(i, 5, 10, QChar('0')), ui->lwFiles->item(i)->text());
+ plist->setValue("Playlist/Repeat", repeat);
+ plist->setValue("Playlist/Shuffle", shuffle);
+ plist->sync();
+ delete plist;
}
void qmpPlistWindow::on_pbLoad_clicked()
{
- QSettings* plist=new QSettings(QFileDialog::getOpenFileName(this,tr("Load playlist"),""),
- QSettings::IniFormat);
- int fc=plist->value("Playlist/FileCount",0).toInt();
- if(!fc){delete plist;return;}
- ui->lwFiles->clear();for(int i=0;i<fc;++i)
- ui->lwFiles->addItem(plist->value("Playlist/File"+QString("%1").arg(i,5,10,QChar('0')),"").toString());
- repeat=plist->value("Playlist/Repeat",0).toInt();
- shuffle=plist->value("Playlist/Shuffle",0).toInt();
- switch(shuffle)
- {
- case 1:
- ui->pbShuffle->setIcon(QIcon(":/img/shuffle.svg"));
- ui->pbShuffle->setText(tr("Shuffle On"));
- break;
- case 0:
- default:
- ui->pbShuffle->setIcon(QIcon(":/img/shuffle-off.svg"));
- ui->pbShuffle->setText(tr("Shuffle Off"));
- break;
- }
- switch(repeat)
- {
- case 0:
- ui->pbRepeat->setIcon(QIcon(":/img/repeat-non.svg"));
- ui->pbRepeat->setText(tr("Repeat Off"));
- break;
- case 1:
- ui->pbRepeat->setIcon(QIcon(":/img/repeat-one.svg"));
- ui->pbRepeat->setText(tr("Repeat One"));
- break;
- case 2:
- ui->pbRepeat->setIcon(QIcon(":/img/repeat-all.svg"));
- ui->pbRepeat->setText(tr("Repeat All"));
- break;
- }
- delete plist;
+ QSettings *plist = new QSettings(QFileDialog::getOpenFileName(this, tr("Load playlist"), ""),
+ QSettings::IniFormat);
+ int fc = plist->value("Playlist/FileCount", 0).toInt();
+ if (!fc)
+ {
+ delete plist;
+ return;
+ }
+ ui->lwFiles->clear();
+ for (int i = 0; i < fc; ++i)
+ ui->lwFiles->addItem(plist->value("Playlist/File" + QString("%1").arg(i, 5, 10, QChar('0')), "").toString());
+ repeat = plist->value("Playlist/Repeat", 0).toInt();
+ shuffle = plist->value("Playlist/Shuffle", 0).toInt();
+ switch (shuffle)
+ {
+ case 1:
+ ui->pbShuffle->setIcon(QIcon(":/img/shuffle.svg"));
+ ui->pbShuffle->setText(tr("Shuffle On"));
+ break;
+ case 0:
+ default:
+ ui->pbShuffle->setIcon(QIcon(":/img/shuffle-off.svg"));
+ ui->pbShuffle->setText(tr("Shuffle Off"));
+ break;
+ }
+ switch (repeat)
+ {
+ case 0:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-non.svg"));
+ ui->pbRepeat->setText(tr("Repeat Off"));
+ break;
+ case 1:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-one.svg"));
+ ui->pbRepeat->setText(tr("Repeat One"));
+ break;
+ case 2:
+ ui->pbRepeat->setIcon(QIcon(":/img/repeat-all.svg"));
+ ui->pbRepeat->setText(tr("Repeat All"));
+ break;
+ }
+ delete plist;
}
qmpPlistFunc::qmpPlistFunc(qmpPlistWindow *par)
-{p=par;}
+{
+ p = par;
+}
void qmpPlistFunc::show()
{
- p->show();
+ p->show();
}
void qmpPlistFunc::close()
{
- p->close();
+ p->close();
}
diff --git a/qmidiplayer-desktop/qmpplistwindow.hpp b/qmidiplayer-desktop/qmpplistwindow.hpp
index afd3ae3..7d93345 100644
--- a/qmidiplayer-desktop/qmpplistwindow.hpp
+++ b/qmidiplayer-desktop/qmpplistwindow.hpp
@@ -10,63 +10,64 @@
#include <QListWidgetItem>
#include "../include/qmpcorepublic.hpp"
-namespace Ui {
- class qmpPlistWindow;
+namespace Ui
+{
+class qmpPlistWindow;
}
class qmpPlistWindow;
class qmpSettings;
-class qmpPlistFunc:public qmpFuncBaseIntf
+class qmpPlistFunc: public qmpFuncBaseIntf
{
- private:
- qmpPlistWindow* p;
- public:
- qmpPlistFunc(qmpPlistWindow *par);
- void show();
- void close();
+private:
+ qmpPlistWindow *p;
+public:
+ qmpPlistFunc(qmpPlistWindow *par);
+ void show();
+ void close();
};
-class qmpPlistWindow:public QWidget
+class qmpPlistWindow: public QWidget
{
- Q_OBJECT
+ Q_OBJECT
- public:
- explicit qmpPlistWindow(QWidget *parent=0);
- ~qmpPlistWindow();
- void showEvent(QShowEvent *event);
- void closeEvent(QCloseEvent *event);
- void dropEvent(QDropEvent *event);
- void dragEnterEvent(QDragEnterEvent *event);
- int getRepeat();
- QString getFirstItem(bool a=false);
- QString getLastItem(bool a=false);
- QString getNextItem();
- QString getPrevItem();
- QString getSelectedItem();
- void emptyList();
- void insertItem(QString i);
- void insertItems(QStringList il);
- signals:
- void selectionChanging();
+public:
+ explicit qmpPlistWindow(QWidget *parent = 0);
+ ~qmpPlistWindow();
+ void showEvent(QShowEvent *event);
+ void closeEvent(QCloseEvent *event);
+ void dropEvent(QDropEvent *event);
+ void dragEnterEvent(QDragEnterEvent *event);
+ int getRepeat();
+ QString getFirstItem(bool a = false);
+ QString getLastItem(bool a = false);
+ QString getNextItem();
+ QString getPrevItem();
+ QString getSelectedItem();
+ void emptyList();
+ void insertItem(QString i);
+ void insertItems(QStringList il);
+signals:
+ void selectionChanging();
- public slots:
- int on_pbAdd_clicked();
- private slots:
- void on_pbAddFolder_clicked();
- void on_pbRemove_clicked();
- void on_pbClear_clicked();
- void on_pbRepeat_clicked();
- void on_pbShuffle_clicked();
- void on_lwFiles_itemDoubleClicked();
- void on_pbSave_clicked();
- void on_pbLoad_clicked();
+public slots:
+ int on_pbAdd_clicked();
+private slots:
+ void on_pbAddFolder_clicked();
+ void on_pbRemove_clicked();
+ void on_pbClear_clicked();
+ void on_pbRepeat_clicked();
+ void on_pbShuffle_clicked();
+ void on_lwFiles_itemDoubleClicked();
+ void on_pbSave_clicked();
+ void on_pbLoad_clicked();
- private:
- qmpPlistFunc* plistf;
- Ui::qmpPlistWindow *ui;
- int shuffle,repeat;//rep 0=off 1=one 2=all
- qmpSettings* settings;
+private:
+ qmpPlistFunc *plistf;
+ Ui::qmpPlistWindow *ui;
+ int shuffle, repeat; //rep 0=off 1=one 2=all
+ qmpSettings *settings;
};
#endif // QMPPLISTWINDOW_H
diff --git a/qmidiplayer-desktop/qmpplugin.cpp b/qmidiplayer-desktop/qmpplugin.cpp
index 9cd1f35..cdea00c 100644
--- a/qmidiplayer-desktop/qmpplugin.cpp
+++ b/qmidiplayer-desktop/qmpplugin.cpp
@@ -9,265 +9,461 @@
#include "qmpplugin.hpp"
#include "qmpmainwindow.hpp"
#include "qmpsettingswindow.hpp"
-qmpPluginAPIImpl* qmpPluginManager::pluginAPI=nullptr;
-qmpMainWindow* qmpPluginManager::mainwindow=nullptr;
+qmpPluginAPIImpl *qmpPluginManager::pluginAPI = nullptr;
+qmpMainWindow *qmpPluginManager::mainwindow = nullptr;
#ifdef _WIN32
#include <codecvt>
#include <locale>
std::string wstr2str(std::wstring s)
{
- std::wstring_convert<std::codecvt_utf8<wchar_t>,wchar_t> wsc;
- return wsc.to_bytes(s);
+ std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> wsc;
+ return wsc.to_bytes(s);
}
void qmpPluginManager::scanPlugins(const std::vector<std::string> &pp)
{
- QDirIterator *dir;
- std::vector<std::wstring> cpluginpaths;
- std::wstring_convert<std::codecvt_utf8<wchar_t>,wchar_t> wsc;
- for(auto p:pp)cpluginpaths.push_back(wsc.from_bytes(p));
- dir=new QDirIterator(QCoreApplication::applicationDirPath()+"/plugins/");
- while(dir->hasNext())
- {
- dir->next();
- if(dir->fileInfo().suffix()=="dll")
- cpluginpaths.push_back(QCoreApplication::applicationDirPath().toStdWString()+std::wstring(L"/plugins/")+dir->fileName().toStdWString());
- }
- delete dir;
- for(unsigned i=0;i<cpluginpaths.size();++i)
- {
- HMODULE hso=LoadLibraryW(cpluginpaths[i].c_str());
- if(!hso){fprintf(stderr,"Error while loading library: %d\n",GetLastError());continue;}
- FARPROC hndi=GetProcAddress(hso,"qmpPluginGetInterface");
- if(!hndi){fprintf(stderr,"plugin %s doesn't seem to be a qmidiplayer plugin.\n",wstr2str(cpluginpaths[i]).c_str());continue;}
- FARPROC hndiv=GetProcAddress(hso,"qmpPluginGetAPIRev");
- if(!hndiv){fprintf(stderr,"plugin %s is incompatible with this version of qmidiplayer.\n",wstr2str(cpluginpaths[i]).c_str());continue;}
- qmpPluginAPIRevEntry getv=(qmpPluginAPIRevEntry)hndiv;
- if(strcmp(getv(),QMP_PLUGIN_API_REV))
- {fprintf(stderr,"plugin %s is incompatible with this version of qmidiplayer.\n",wstr2str(cpluginpaths[i]).c_str());continue;}
- qmpPluginEntry e=(qmpPluginEntry)hndi;
- qmpPluginIntf* intf=e(pluginAPI);
- plugins.push_back(qmpPlugin(std::string(intf->pluginGetName()),std::string(intf->pluginGetVersion()),wstr2str(cpluginpaths[i]),intf));
- }
+ QDirIterator *dir;
+ std::vector<std::wstring> cpluginpaths;
+ std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> wsc;
+ for (auto p : pp)
+ cpluginpaths.push_back(wsc.from_bytes(p));
+ dir = new QDirIterator(QCoreApplication::applicationDirPath() + "/plugins/");
+ while (dir->hasNext())
+ {
+ dir->next();
+ if (dir->fileInfo().suffix() == "dll")
+ cpluginpaths.push_back(QCoreApplication::applicationDirPath().toStdWString() + std::wstring(L"/plugins/") + dir->fileName().toStdWString());
+ }
+ delete dir;
+ for (unsigned i = 0; i < cpluginpaths.size(); ++i)
+ {
+ HMODULE hso = LoadLibraryW(cpluginpaths[i].c_str());
+ if (!hso)
+ {
+ fprintf(stderr, "Error while loading library: %d\n", GetLastError());
+ continue;
+ }
+ FARPROC hndi = GetProcAddress(hso, "qmpPluginGetInterface");
+ if (!hndi)
+ {
+ fprintf(stderr, "plugin %s doesn't seem to be a qmidiplayer plugin.\n", wstr2str(cpluginpaths[i]).c_str());
+ continue;
+ }
+ FARPROC hndiv = GetProcAddress(hso, "qmpPluginGetAPIRev");
+ if (!hndiv)
+ {
+ fprintf(stderr, "plugin %s is incompatible with this version of qmidiplayer.\n", wstr2str(cpluginpaths[i]).c_str());
+ continue;
+ }
+ qmpPluginAPIRevEntry getv = (qmpPluginAPIRevEntry)hndiv;
+ if (strcmp(getv(), QMP_PLUGIN_API_REV))
+ {
+ fprintf(stderr, "plugin %s is incompatible with this version of qmidiplayer.\n", wstr2str(cpluginpaths[i]).c_str());
+ continue;
+ }
+ qmpPluginEntry e = (qmpPluginEntry)hndi;
+ qmpPluginIntf *intf = e(pluginAPI);
+ plugins.push_back(qmpPlugin(std::string(intf->pluginGetName()), std::string(intf->pluginGetVersion()), wstr2str(cpluginpaths[i]), intf));
+ }
}
#else
void qmpPluginManager::scanPlugins(const std::vector<std::string> &pp)
{
- QDirIterator *dir;
- std::vector<std::string> cpluginpaths(pp);
+ QDirIterator *dir;
+ std::vector<std::string> cpluginpaths(pp);
#ifdef NON_PORTABLE
- QString pdir=QString(QT_STRINGIFY(INSTALL_PREFIX))+"/lib/qmidiplayer/";
- dir=new QDirIterator(pdir);
- while(dir->hasNext())
- {
- dir->next();
- if(dir->fileInfo().suffix()=="so")
- cpluginpaths.push_back((pdir+dir->fileName()).toStdString());
- }
- delete dir;
+ QString pdir = QString(QT_STRINGIFY(INSTALL_PREFIX)) + "/lib/qmidiplayer/";
+ dir = new QDirIterator(pdir);
+ while (dir->hasNext())
+ {
+ dir->next();
+ if (dir->fileInfo().suffix() == "so")
+ cpluginpaths.push_back((pdir + dir->fileName()).toStdString());
+ }
+ delete dir;
#endif
- dir=new QDirIterator(QCoreApplication::applicationDirPath()+"/plugins/");
- while(dir->hasNext())
- {
- dir->next();
- if(dir->fileInfo().suffix()=="so")
- cpluginpaths.push_back(QCoreApplication::applicationDirPath().toStdString()+std::string("/plugins/")+dir->fileName().toStdString());
- }
- delete dir;
- for(unsigned i=0;i<cpluginpaths.size();++i)
- {
- void* hso=dlopen(cpluginpaths[i].c_str(),RTLD_LAZY);
- if(!hso){fprintf(stderr,"%s\n",dlerror());continue;}
- void* hndi=dlsym(hso,"qmpPluginGetInterface");
- if(!hndi){fprintf(stderr,"file %s doesn't seem to be a qmidiplayer plugin.\n",cpluginpaths[i].c_str());continue;}
- void* hndiv=dlsym(hso,"qmpPluginGetAPIRev");
- if(!hndiv){fprintf(stderr,"file %s is incompatible with this version of qmidiplayer.\n",cpluginpaths[i].c_str());continue;}
- qmpPluginAPIRevEntry getv=(qmpPluginAPIRevEntry)hndiv;
- if(strcmp(getv(),QMP_PLUGIN_API_REV))
- {fprintf(stderr,"file %s is incompatible with this version of qmidiplayer.\n",cpluginpaths[i].c_str());continue;}
- qmpPluginEntry e=(qmpPluginEntry)hndi;
- qmpPluginIntf* intf=e(pluginAPI);
- plugins.push_back(qmpPlugin(std::string(intf->pluginGetName()),std::string(intf->pluginGetVersion()),std::string(cpluginpaths[i]),intf));
- }
+ dir = new QDirIterator(QCoreApplication::applicationDirPath() + "/plugins/");
+ while (dir->hasNext())
+ {
+ dir->next();
+ if (dir->fileInfo().suffix() == "so")
+ cpluginpaths.push_back(QCoreApplication::applicationDirPath().toStdString() + std::string("/plugins/") + dir->fileName().toStdString());
+ }
+ delete dir;
+ for (unsigned i = 0; i < cpluginpaths.size(); ++i)
+ {
+ void *hso = dlopen(cpluginpaths[i].c_str(), RTLD_LAZY);
+ if (!hso)
+ {
+ fprintf(stderr, "%s\n", dlerror());
+ continue;
+ }
+ void *hndi = dlsym(hso, "qmpPluginGetInterface");
+ if (!hndi)
+ {
+ fprintf(stderr, "file %s doesn't seem to be a qmidiplayer plugin.\n", cpluginpaths[i].c_str());
+ continue;
+ }
+ void *hndiv = dlsym(hso, "qmpPluginGetAPIRev");
+ if (!hndiv)
+ {
+ fprintf(stderr, "file %s is incompatible with this version of qmidiplayer.\n", cpluginpaths[i].c_str());
+ continue;
+ }
+ qmpPluginAPIRevEntry getv = (qmpPluginAPIRevEntry)hndiv;
+ if (strcmp(getv(), QMP_PLUGIN_API_REV))
+ {
+ fprintf(stderr, "file %s is incompatible with this version of qmidiplayer.\n", cpluginpaths[i].c_str());
+ continue;
+ }
+ qmpPluginEntry e = (qmpPluginEntry)hndi;
+ qmpPluginIntf *intf = e(pluginAPI);
+ plugins.push_back(qmpPlugin(std::string(intf->pluginGetName()), std::string(intf->pluginGetVersion()), std::string(cpluginpaths[i]), intf));
+ }
}
#endif
qmpPluginManager::qmpPluginManager()
{
- mainwindow=qmpMainWindow::getInstance();
- pluginAPI=new qmpPluginAPIImpl();
+ mainwindow = qmpMainWindow::getInstance();
+ pluginAPI = new qmpPluginAPIImpl();
}
qmpPluginManager::~qmpPluginManager()
{
- for(unsigned i=0;i<plugins.size();++i)
- {
- if(plugins[i].initialized)plugins[i].pinterface->deinit();
- delete plugins[i].pinterface;
- }
- mainwindow=nullptr;delete pluginAPI;
+ for (unsigned i = 0; i < plugins.size(); ++i)
+ {
+ if (plugins[i].initialized)
+ plugins[i].pinterface->deinit();
+ delete plugins[i].pinterface;
+ }
+ mainwindow = nullptr;
+ delete pluginAPI;
}
std::vector<qmpPlugin> *qmpPluginManager::getPlugins()
{
- return &plugins;
+ return &plugins;
}
void qmpPluginManager::initPlugins()
{
- for(unsigned i=0;i<plugins.size();++i)
- {
- if(!plugins[i].enabled)continue;
- fprintf(stderr,"Loaded plugin: %s\n",plugins[i].path.c_str());
- plugins[i].pinterface->init();plugins[i].initialized=true;
- }
+ for (unsigned i = 0; i < plugins.size(); ++i)
+ {
+ if (!plugins[i].enabled)
+ continue;
+ fprintf(stderr, "Loaded plugin: %s\n", plugins[i].path.c_str());
+ plugins[i].pinterface->init();
+ plugins[i].initialized = true;
+ }
}
void qmpPluginManager::deinitPlugins()
{
- for(unsigned i=0;i<plugins.size();++i)
- {
- if(plugins[i].initialized)plugins[i].pinterface->deinit();
- plugins[i].enabled=plugins[i].initialized=false;
- }
+ for (unsigned i = 0; i < plugins.size(); ++i)
+ {
+ if (plugins[i].initialized)
+ plugins[i].pinterface->deinit();
+ plugins[i].enabled = plugins[i].initialized = false;
+ }
}
-qmpPluginAPIImpl::qmpPluginAPIImpl(){}
-qmpPluginAPIImpl::~qmpPluginAPIImpl(){}
+qmpPluginAPIImpl::qmpPluginAPIImpl() {}
+qmpPluginAPIImpl::~qmpPluginAPIImpl() {}
#define qmw qmpPluginManager::mainwindow
uint32_t qmpPluginAPIImpl::getDivision()
-{return qmw&&qmw->getPlayer()?qmw->getPlayer()->getDivision():0;}
+{
+ return qmw && qmw->getPlayer() ? qmw->getPlayer()->getDivision() : 0;
+}
uint32_t qmpPluginAPIImpl::getRawTempo()
-{return qmw&&qmw->getPlayer()?qmw->getPlayer()->getRawTempo():0;}
+{
+ return qmw && qmw->getPlayer() ? qmw->getPlayer()->getRawTempo() : 0;
+}
double qmpPluginAPIImpl::getRealTempo()
-{return qmw&&qmw->getPlayer()?qmw->getPlayer()->getTempo():0;}
+{
+ return qmw && qmw->getPlayer() ? qmw->getPlayer()->getTempo() : 0;
+}
uint32_t qmpPluginAPIImpl::getTimeSig()
-{int n,d=0,t;qmw&&qmw->getPlayer()?qmw->getPlayer()->getCurrentTimeSignature(&n,&t):void(0);for(;t>>=1;++d);return n<<8|d;}
+{
+ int n, d = 0, t;
+ qmw &&qmw->getPlayer() ? qmw->getPlayer()->getCurrentTimeSignature(&n, &t) : void(0);
+ for (; t >>= 1; ++d);
+ return n << 8 | d;
+}
int qmpPluginAPIImpl::getKeySig()
-{return qmw&&qmw->getPlayer()?qmw->getPlayer()->getCurrentKeySignature():0;}
+{
+ return qmw && qmw->getPlayer() ? qmw->getPlayer()->getCurrentKeySignature() : 0;
+}
uint32_t qmpPluginAPIImpl::getNoteCount()
-{return qmw&&qmw->getPlayer()?qmw->getPlayer()->getFileNoteCount():0;}
+{
+ return qmw && qmw->getPlayer() ? qmw->getPlayer()->getFileNoteCount() : 0;
+}
uint32_t qmpPluginAPIImpl::getMaxTick()
-{return qmw&&qmw->getPlayer()?qmw->getPlayer()->getMaxTick():0;}
+{
+ return qmw && qmw->getPlayer() ? qmw->getPlayer()->getMaxTick() : 0;
+}
uint32_t qmpPluginAPIImpl::getCurrentPolyphone()
-{return qmw&&qmw->getPlayer()?qmw->getFluid()->getPolyphone():0;}
+{
+ return qmw && qmw->getPlayer() ? qmw->getFluid()->getPolyphone() : 0;
+}
uint32_t qmpPluginAPIImpl::getMaxPolyphone()
-{return qmw&&qmw->getPlayer()?qmw->getFluid()->getMaxPolyphone():0;}
+{
+ return qmw && qmw->getPlayer() ? qmw->getFluid()->getMaxPolyphone() : 0;
+}
uint32_t qmpPluginAPIImpl::getCurrentTimeStamp()
-{return qmw&&qmw->getPlayer()?qmw->getPlayer()->getTick():0;}
+{
+ return qmw && qmw->getPlayer() ? qmw->getPlayer()->getTick() : 0;
+}
uint32_t qmpPluginAPIImpl::getCurrentPlaybackPercentage()
-{return qmw?qmw->getPlaybackPercentage():0;}
-int qmpPluginAPIImpl::getChannelCC(int ch,int cc)
-{return qmw&&qmw->getPlayer()?qmw->getPlayer()->getCC(ch,cc):0;}
+{
+ return qmw ? qmw->getPlaybackPercentage() : 0;
+}
+int qmpPluginAPIImpl::getChannelCC(int ch, int cc)
+{
+ return qmw && qmw->getPlayer() ? qmw->getPlayer()->getCC(ch, cc) : 0;
+}
int qmpPluginAPIImpl::getChannelPreset(int ch)
{
- uint16_t b;uint8_t p;std::string nm;
- if(qmw&&qmw->getPlayer())
- {
- if(qmw->getPlayer()->getChannelOutputDevice(ch)->getChannelPreset(ch,&b,&p,nm))return p;
- return qmw->getPlayer()->getCC(ch,128);
- }
- return 0;
+ uint16_t b;
+ uint8_t p;
+ std::string nm;
+ if (qmw && qmw->getPlayer())
+ {
+ if (qmw->getPlayer()->getChannelOutputDevice(ch)->getChannelPreset(ch, &b, &p, nm))
+ return p;
+ return qmw->getPlayer()->getCC(ch, 128);
+ }
+ return 0;
}
void qmpPluginAPIImpl::playerSeek(uint32_t percentage)
-{if(qmw)qmw->playerSeek(percentage);}
+{
+ if (qmw)
+ qmw->playerSeek(percentage);
+}
double qmpPluginAPIImpl::getPitchBend(int ch)
-{return qmw&&qmw->getPlayer()?qmw->getPlayer()->getPitchBend(ch):0;}
-void qmpPluginAPIImpl::getPitchBendRaw(int ch,uint32_t *pb,uint32_t *pbr)
{
- if(qmw&&qmw->getPlayer())
- qmw->getPlayer()->getPitchBendRaw(ch,pb,pbr);
+ return qmw && qmw->getPlayer() ? qmw->getPlayer()->getPitchBend(ch) : 0;
+}
+void qmpPluginAPIImpl::getPitchBendRaw(int ch, uint32_t *pb, uint32_t *pbr)
+{
+ if (qmw && qmw->getPlayer())
+ qmw->getPlayer()->getPitchBendRaw(ch, pb, pbr);
}
bool qmpPluginAPIImpl::getChannelMask(int ch)
-{return qmw&&qmw->getPlayer()?qmw->getPlayer()->getChannelMask(ch):false;}
+{
+ return qmw && qmw->getPlayer() ? qmw->getPlayer()->getChannelMask(ch) : false;
+}
std::string qmpPluginAPIImpl::getTitle()
-{return qmw?qmw->getTitle():"";}
+{
+ return qmw ? qmw->getTitle() : "";
+}
std::wstring qmpPluginAPIImpl::getWTitle()
-{return qmw?qmw->getWTitle():L"";}
+{
+ return qmw ? qmw->getWTitle() : L"";
+}
std::string qmpPluginAPIImpl::getChannelPresetString(int ch)
{
- uint16_t b;uint8_t p;char ret[320];ret[0]=0;
- std::string nm;
- if(qmw&&qmw->getPlayer())
- {
- int r=qmw->getPlayer()->getChannelOutputDevice(ch)->getChannelPreset(ch,&b,&p,nm);
- if(!r)
- {
- b=qmw->getPlayer()->getCC(ch,0)<<7|qmw->getPlayer()->getCC(ch,32);
- p=qmw->getPlayer()->getCC(ch,128);
- nm=qmw->getPlayer()->getChannelOutputDevice(ch)->getPresetName(b,p);
- }
- snprintf(ret,320,"%03d:%03d %s",b,p,nm.c_str());
- }
- return std::string(ret);
-}
-bool qmpPluginAPIImpl::isDarkTheme(){return qmw?qmw->isDarkTheme():false;}
-void* qmpPluginAPIImpl::getMainWindow(){return (void*)qmw;}
+ uint16_t b;
+ uint8_t p;
+ char ret[320];
+ ret[0] = 0;
+ std::string nm;
+ if (qmw && qmw->getPlayer())
+ {
+ int r = qmw->getPlayer()->getChannelOutputDevice(ch)->getChannelPreset(ch, &b, &p, nm);
+ if (!r)
+ {
+ b = qmw->getPlayer()->getCC(ch, 0) << 7 | qmw->getPlayer()->getCC(ch, 32);
+ p = qmw->getPlayer()->getCC(ch, 128);
+ nm = qmw->getPlayer()->getChannelOutputDevice(ch)->getPresetName(b, p);
+ }
+ snprintf(ret, 320, "%03d:%03d %s", b, p, nm.c_str());
+ }
+ return std::string(ret);
+}
+bool qmpPluginAPIImpl::isDarkTheme()
+{
+ return qmw ? qmw->isDarkTheme() : false;
+}
+void *qmpPluginAPIImpl::getMainWindow()
+{
+ return (void *)qmw;
+}
-void qmpPluginAPIImpl::discardCurrentEvent(){if(qmw&&qmw->getPlayer())qmw->getPlayer()->discardCurrentEvent();}
-void qmpPluginAPIImpl::commitEventChange(SEvent d){if(qmw&&qmw->getPlayer())qmw->getPlayer()->commitEventChange(d);}
-void qmpPluginAPIImpl::callEventReaderCB(SEvent d){if(qmw&&qmw->getPlayer())qmw->getPlayer()->callEventReaderCB(d);}
-void qmpPluginAPIImpl::setFuncState(std::string name,bool state){if(qmw)qmw->setFuncState(name,state);}
-void qmpPluginAPIImpl::setFuncEnabled(std::string name,bool enable){if(qmw)qmw->setFuncEnabled(name,enable);}
+void qmpPluginAPIImpl::discardCurrentEvent()
+{
+ if (qmw && qmw->getPlayer())
+ qmw->getPlayer()->discardCurrentEvent();
+}
+void qmpPluginAPIImpl::commitEventChange(SEvent d)
+{
+ if (qmw && qmw->getPlayer())
+ qmw->getPlayer()->commitEventChange(d);
+}
+void qmpPluginAPIImpl::callEventReaderCB(SEvent d)
+{
+ if (qmw && qmw->getPlayer())
+ qmw->getPlayer()->callEventReaderCB(d);
+}
+void qmpPluginAPIImpl::setFuncState(std::string name, bool state)
+{
+ if (qmw)
+ qmw->setFuncState(name, state);
+}
+void qmpPluginAPIImpl::setFuncEnabled(std::string name, bool enable)
+{
+ if (qmw)
+ qmw->setFuncEnabled(name, enable);
+}
void qmpPluginAPIImpl::registerMidiOutDevice(qmpMidiOutDevice *dev, std::string name)
-{qmw->getPlayer()->registerMidiOutDevice(dev,name);}
+{
+ qmw->getPlayer()->registerMidiOutDevice(dev, name);
+}
void qmpPluginAPIImpl::unregisterMidiOutDevice(std::string name)
-{qmw->getPlayer()->unregisterMidiOutDevice(name);}
-int qmpPluginAPIImpl::registerEventHandlerIntf(ICallBack *cb,void *userdata)
-{return qmw->getPlayer()->setEventHandlerCB(cb,userdata);}
+{
+ qmw->getPlayer()->unregisterMidiOutDevice(name);
+}
+int qmpPluginAPIImpl::registerEventHandlerIntf(ICallBack *cb, void *userdata)
+{
+ return qmw->getPlayer()->setEventHandlerCB(cb, userdata);
+}
void qmpPluginAPIImpl::unregisterEventHandlerIntf(int intfhandle)
-{qmw->getPlayer()->unsetEventHandlerCB(intfhandle);}
-int qmpPluginAPIImpl::registerEventReaderIntf(ICallBack *cb,void *userdata)
-{return qmw->getPlayer()->setEventReaderCB(cb,userdata);}
+{
+ qmw->getPlayer()->unsetEventHandlerCB(intfhandle);
+}
+int qmpPluginAPIImpl::registerEventReaderIntf(ICallBack *cb, void *userdata)
+{
+ return qmw->getPlayer()->setEventReaderCB(cb, userdata);
+}
void qmpPluginAPIImpl::unregisterEventReaderIntf(int intfhandle)
-{qmw->getPlayer()->unsetEventReaderCB(intfhandle);}
-int qmpPluginAPIImpl::registerUIHook(std::string e,ICallBack* cb,void* userdat)
-{return qmw->registerUIHook(e,cb,userdat);}
-int qmpPluginAPIImpl::registerUIHook(std::string e,callback_t cb,void* userdat)
-{return qmw->registerUIHook(e,cb,userdat);}
-void qmpPluginAPIImpl::unregisterUIHook(std::string e,int hook)
-{qmw->unregisterUIHook(e,hook);}
-void qmpPluginAPIImpl::registerFunctionality(qmpFuncBaseIntf *i,std::string name,std::string desc,const char *icon,int iconlen,bool checkable)
-{qmw->registerFunctionality(i,name,desc,icon,iconlen,checkable);}
+{
+ qmw->getPlayer()->unsetEventReaderCB(intfhandle);
+}
+int qmpPluginAPIImpl::registerUIHook(std::string e, ICallBack *cb, void *userdat)
+{
+ return qmw->registerUIHook(e, cb, userdat);
+}
+int qmpPluginAPIImpl::registerUIHook(std::string e, callback_t cb, void *userdat)
+{
+ return qmw->registerUIHook(e, cb, userdat);
+}
+void qmpPluginAPIImpl::unregisterUIHook(std::string e, int hook)
+{
+ qmw->unregisterUIHook(e, hook);
+}
+void qmpPluginAPIImpl::registerFunctionality(qmpFuncBaseIntf *i, std::string name, std::string desc, const char *icon, int iconlen, bool checkable)
+{
+ qmw->registerFunctionality(i, name, desc, icon, iconlen, checkable);
+}
void qmpPluginAPIImpl::unregisterFunctionality(std::string name)
-{qmw->unregisterFunctionality(name);}
-int qmpPluginAPIImpl::registerFileReadFinishedHandlerIntf(ICallBack* cb,void* userdata)
-{return qmw->getPlayer()->setFileReadFinishedCB(cb,userdata);}
+{
+ qmw->unregisterFunctionality(name);
+}
+int qmpPluginAPIImpl::registerFileReadFinishedHandlerIntf(ICallBack *cb, void *userdata)
+{
+ return qmw->getPlayer()->setFileReadFinishedCB(cb, userdata);
+}
void qmpPluginAPIImpl::unregisterFileReadFinishedHandlerIntf(int intfhandle)
-{qmw->getPlayer()->unsetFileReadFinishedCB(intfhandle);}
-void qmpPluginAPIImpl::registerFileReader(qmpFileReader* reader,std::string name)
-{qmw->getPlayer()->registerReader(reader,name);}
+{
+ qmw->getPlayer()->unsetFileReadFinishedCB(intfhandle);
+}
+void qmpPluginAPIImpl::registerFileReader(qmpFileReader *reader, std::string name)
+{
+ qmw->getPlayer()->registerReader(reader, name);
+}
void qmpPluginAPIImpl::unregisterFileReader(std::string name)
-{qmw->getPlayer()->unregisterReader(name);}
-int qmpPluginAPIImpl::registerEventHandler(callback_t cb,void *userdata,bool post)
-{return qmw->getPlayer()->registerEventHandler(cb,userdata,post);}
+{
+ qmw->getPlayer()->unregisterReader(name);
+}
+int qmpPluginAPIImpl::registerEventHandler(callback_t cb, void *userdata, bool post)
+{
+ return qmw->getPlayer()->registerEventHandler(cb, userdata, post);
+}
void qmpPluginAPIImpl::unregisterEventHandler(int id)
-{qmw->getPlayer()->unregisterEventHandler(id);}
-int qmpPluginAPIImpl::registerEventReadHandler(callback_t cb,void *userdata)
-{return qmw->getPlayer()->registerEventReadHandler(cb,userdata);}
+{
+ qmw->getPlayer()->unregisterEventHandler(id);
+}
+int qmpPluginAPIImpl::registerEventReadHandler(callback_t cb, void *userdata)
+{
+ return qmw->getPlayer()->registerEventReadHandler(cb, userdata);
+}
void qmpPluginAPIImpl::unregisterEventReadHandler(int id)
-{qmw->getPlayer()->unregisterEventReadHandler(id);}
-int qmpPluginAPIImpl::registerFileReadFinishHook(callback_t cb,void *userdata)
-{return qmw->getPlayer()->registerFileReadFinishHook(cb,userdata);}
+{
+ qmw->getPlayer()->unregisterEventReadHandler(id);
+}
+int qmpPluginAPIImpl::registerFileReadFinishHook(callback_t cb, void *userdata)
+{
+ return qmw->getPlayer()->registerFileReadFinishHook(cb, userdata);
+}
void qmpPluginAPIImpl::unregisterFileReadFinishHook(int id)
-{qmw->getPlayer()->unregisterFileReadFinishHook(id);}
+{
+ qmw->getPlayer()->unregisterFileReadFinishHook(id);
+}
-void qmpPluginAPIImpl::registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval)
-{qmw->getSettings()->registerOptionInt(tab,desc,key,min,max,defaultval);}
-int qmpPluginAPIImpl::getOptionInt(std::string key){return qmw->getSettings()->getOptionInt(key);}
-void qmpPluginAPIImpl::setOptionInt(std::string key,int val){qmw->getSettings()->setOptionInt(key,val);}
-void qmpPluginAPIImpl::registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min,unsigned max,unsigned defaultval)
-{qmw->getSettings()->registerOptionUint(tab,desc,key,min,max,defaultval);}
-unsigned qmpPluginAPIImpl::getOptionUint(std::string key){return qmw->getSettings()->getOptionUint(key);}
-void qmpPluginAPIImpl::setOptionUint(std::string key,unsigned val){qmw->getSettings()->setOptionUint(key,val);}
-void qmpPluginAPIImpl::registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval)
-{qmw->getSettings()->registerOptionBool(tab,desc,key,defaultval);}
-bool qmpPluginAPIImpl::getOptionBool(std::string key){return qmw->getSettings()->getOptionBool(key);}
-void qmpPluginAPIImpl::setOptionBool(std::string key,bool val){qmw->getSettings()->setOptionBool(key,val);}
-void qmpPluginAPIImpl::registerOptionDouble(std::string tab,std::string desc,std::string key,double min,double max,double defaultval)
-{qmw->getSettings()->registerOptionDouble(tab,desc,key,min,max,defaultval);}
-double qmpPluginAPIImpl::getOptionDouble(std::string key){return qmw->getSettings()->getOptionDouble(key);}
-void qmpPluginAPIImpl::setOptionDouble(std::string key,double val){qmw->getSettings()->setOptionDouble(key,val);}
-void qmpPluginAPIImpl::registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool ispath)
-{qmw->getSettings()->registerOptionString(tab,desc,key,defaultval,ispath);}
-std::string qmpPluginAPIImpl::getOptionString(std::string key){return qmw->getSettings()->getOptionString(key);}
-void qmpPluginAPIImpl::setOptionString(std::string key,std::string val){return qmw->getSettings()->setOptionString(key,val);}
-void qmpPluginAPIImpl::registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> options,int defaultval)
-{qmw->getSettings()->registerOptionEnumInt(tab,desc,key,options,defaultval);}
-int qmpPluginAPIImpl::getOptionEnumInt(std::string key){return qmw->getSettings()->getOptionEnumInt(key);}
-void qmpPluginAPIImpl::setOptionEnumInt(std::string key,int val){return qmw->getSettings()->setOptionEnumInt(key,val);}
+void qmpPluginAPIImpl::registerOptionInt(std::string tab, std::string desc, std::string key, int min, int max, int defaultval)
+{
+ qmw->getSettings()->registerOptionInt(tab, desc, key, min, max, defaultval);
+}
+int qmpPluginAPIImpl::getOptionInt(std::string key)
+{
+ return qmw->getSettings()->getOptionInt(key);
+}
+void qmpPluginAPIImpl::setOptionInt(std::string key, int val)
+{
+ qmw->getSettings()->setOptionInt(key, val);
+}
+void qmpPluginAPIImpl::registerOptionUint(std::string tab, std::string desc, std::string key, unsigned min, unsigned max, unsigned defaultval)
+{
+ qmw->getSettings()->registerOptionUint(tab, desc, key, min, max, defaultval);
+}
+unsigned qmpPluginAPIImpl::getOptionUint(std::string key)
+{
+ return qmw->getSettings()->getOptionUint(key);
+}
+void qmpPluginAPIImpl::setOptionUint(std::string key, unsigned val)
+{
+ qmw->getSettings()->setOptionUint(key, val);
+}
+void qmpPluginAPIImpl::registerOptionBool(std::string tab, std::string desc, std::string key, bool defaultval)
+{
+ qmw->getSettings()->registerOptionBool(tab, desc, key, defaultval);
+}
+bool qmpPluginAPIImpl::getOptionBool(std::string key)
+{
+ return qmw->getSettings()->getOptionBool(key);
+}
+void qmpPluginAPIImpl::setOptionBool(std::string key, bool val)
+{
+ qmw->getSettings()->setOptionBool(key, val);
+}
+void qmpPluginAPIImpl::registerOptionDouble(std::string tab, std::string desc, std::string key, double min, double max, double defaultval)
+{
+ qmw->getSettings()->registerOptionDouble(tab, desc, key, min, max, defaultval);
+}
+double qmpPluginAPIImpl::getOptionDouble(std::string key)
+{
+ return qmw->getSettings()->getOptionDouble(key);
+}
+void qmpPluginAPIImpl::setOptionDouble(std::string key, double val)
+{
+ qmw->getSettings()->setOptionDouble(key, val);
+}
+void qmpPluginAPIImpl::registerOptionString(std::string tab, std::string desc, std::string key, std::string defaultval, bool ispath)
+{
+ qmw->getSettings()->registerOptionString(tab, desc, key, defaultval, ispath);
+}
+std::string qmpPluginAPIImpl::getOptionString(std::string key)
+{
+ return qmw->getSettings()->getOptionString(key);
+}
+void qmpPluginAPIImpl::setOptionString(std::string key, std::string val)
+{
+ return qmw->getSettings()->setOptionString(key, val);
+}
+void qmpPluginAPIImpl::registerOptionEnumInt(std::string tab, std::string desc, std::string key, std::vector<std::string> options, int defaultval)
+{
+ qmw->getSettings()->registerOptionEnumInt(tab, desc, key, options, defaultval);
+}
+int qmpPluginAPIImpl::getOptionEnumInt(std::string key)
+{
+ return qmw->getSettings()->getOptionEnumInt(key);
+}
+void qmpPluginAPIImpl::setOptionEnumInt(std::string key, int val)
+{
+ return qmw->getSettings()->setOptionEnumInt(key, val);
+}
diff --git a/qmidiplayer-desktop/qmpplugin.hpp b/qmidiplayer-desktop/qmpplugin.hpp
index 99dedcd..778f90f 100644
--- a/qmidiplayer-desktop/qmpplugin.hpp
+++ b/qmidiplayer-desktop/qmpplugin.hpp
@@ -7,104 +7,110 @@
#include "../include/qmpcorepublic.hpp"
struct qmpPlugin
{
- std::string name,version,path;
- qmpPluginIntf* pinterface;
- bool enabled,initialized;
- qmpPlugin(std::string _n,std::string _v,std::string _p,qmpPluginIntf* _i)
- {name=_n;version=_v;path=_p;pinterface=_i;enabled=initialized=false;}
+ std::string name, version, path;
+ qmpPluginIntf *pinterface;
+ bool enabled, initialized;
+ qmpPlugin(std::string _n, std::string _v, std::string _p, qmpPluginIntf *_i)
+ {
+ name = _n;
+ version = _v;
+ path = _p;
+ pinterface = _i;
+ enabled = initialized = false;
+ }
};
class qmpMainWindow;
class qmpSettings;
-class qmpPluginAPIImpl:public qmpPluginAPI
+class qmpPluginAPIImpl: public qmpPluginAPI
{
public:
- qmpPluginAPIImpl();
- ~qmpPluginAPIImpl();
- uint32_t getDivision();
- uint32_t getRawTempo();
- double getRealTempo();
- uint32_t getTimeSig();
- int getKeySig();
- uint32_t getNoteCount();
- uint32_t getMaxTick();
- uint32_t getCurrentPolyphone();
- uint32_t getMaxPolyphone();
- uint32_t getCurrentTimeStamp();
- uint32_t getCurrentPlaybackPercentage();
- int getChannelCC(int ch,int cc);
- int getChannelPreset(int ch);
- void playerSeek(uint32_t percentage);
- double getPitchBend(int ch);
- void getPitchBendRaw(int ch,uint32_t *pb,uint32_t *pbr);
- bool getChannelMask(int ch);
- std::string getTitle();
- std::wstring getWTitle();
- std::string getChannelPresetString(int ch);
- bool isDarkTheme();
- void* getMainWindow();
+ qmpPluginAPIImpl();
+ ~qmpPluginAPIImpl();
+ uint32_t getDivision();
+ uint32_t getRawTempo();
+ double getRealTempo();
+ uint32_t getTimeSig();
+ int getKeySig();
+ uint32_t getNoteCount();
+ uint32_t getMaxTick();
+ uint32_t getCurrentPolyphone();
+ uint32_t getMaxPolyphone();
+ uint32_t getCurrentTimeStamp();
+ uint32_t getCurrentPlaybackPercentage();
+ int getChannelCC(int ch, int cc);
+ int getChannelPreset(int ch);
+ void playerSeek(uint32_t percentage);
+ double getPitchBend(int ch);
+ void getPitchBendRaw(int ch, uint32_t *pb, uint32_t *pbr);
+ bool getChannelMask(int ch);
+ std::string getTitle();
+ std::wstring getWTitle();
+ std::string getChannelPresetString(int ch);
+ bool isDarkTheme();
+ void *getMainWindow();
- void discardCurrentEvent();
- void commitEventChange(SEvent d);
- void callEventReaderCB(SEvent d);
- void setFuncState(std::string name,bool state);
- void setFuncEnabled(std::string name,bool enable);
+ void discardCurrentEvent();
+ void commitEventChange(SEvent d);
+ void callEventReaderCB(SEvent d);
+ void setFuncState(std::string name, bool state);
+ void setFuncEnabled(std::string name, bool enable);
- 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* cb,void* userdat);
- int registerUIHook(std::string e,callback_t cb,void* userdat);
- void unregisterUIHook(std::string e,int hook);
- void registerMidiOutDevice(qmpMidiOutDevice* dev,std::string name);
- void unregisterMidiOutDevice(std::string name);
- int registerEventReaderIntf(ICallBack* cb,void* userdata);
- void unregisterEventReaderIntf(int intfhandle);
- int registerEventHandlerIntf(ICallBack* cb,void* userdata);
- void unregisterEventHandlerIntf(int intfhandle);
- int registerFileReadFinishedHandlerIntf(ICallBack* cb,void* userdata);
- void unregisterFileReadFinishedHandlerIntf(int intfhandle);
- int registerEventHandler(callback_t cb,void *userdata,bool post=false);
- void unregisterEventHandler(int id);
- int registerEventReadHandler(callback_t cb,void *userdata);
- void unregisterEventReadHandler(int id);
- int registerFileReadFinishHook(callback_t cb,void *userdata);
- void unregisterFileReadFinishHook(int id);
- void registerFileReader(qmpFileReader* reader,std::string name);
- void unregisterFileReader(std::string name);
+ 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 *cb, void *userdat);
+ int registerUIHook(std::string e, callback_t cb, void *userdat);
+ void unregisterUIHook(std::string e, int hook);
+ void registerMidiOutDevice(qmpMidiOutDevice *dev, std::string name);
+ void unregisterMidiOutDevice(std::string name);
+ int registerEventReaderIntf(ICallBack *cb, void *userdata);
+ void unregisterEventReaderIntf(int intfhandle);
+ int registerEventHandlerIntf(ICallBack *cb, void *userdata);
+ void unregisterEventHandlerIntf(int intfhandle);
+ int registerFileReadFinishedHandlerIntf(ICallBack *cb, void *userdata);
+ void unregisterFileReadFinishedHandlerIntf(int intfhandle);
+ int registerEventHandler(callback_t cb, void *userdata, bool post = false);
+ void unregisterEventHandler(int id);
+ int registerEventReadHandler(callback_t cb, void *userdata);
+ void unregisterEventReadHandler(int id);
+ int registerFileReadFinishHook(callback_t cb, void *userdata);
+ void unregisterFileReadFinishHook(int id);
+ void registerFileReader(qmpFileReader *reader, std::string name);
+ void unregisterFileReader(std::string name);
- void registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval);
- int getOptionInt(std::string key);
- void setOptionInt(std::string key,int val);
- void registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min,unsigned max,unsigned defaultval);
- unsigned getOptionUint(std::string key);
- void setOptionUint(std::string key,unsigned val);
- void registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval);
- bool getOptionBool(std::string key);
- void setOptionBool(std::string key,bool val);
- void registerOptionDouble(std::string tab,std::string desc,std::string key,double min,double max,double defaultval);
- double getOptionDouble(std::string key);
- void setOptionDouble(std::string key,double val);
- void registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool ispath=false);
- std::string getOptionString(std::string key);
- void setOptionString(std::string key,std::string val);
- void registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> options,int defaultval);
- int getOptionEnumInt(std::string key);
- void setOptionEnumInt(std::string key,int val);
+ void registerOptionInt(std::string tab, std::string desc, std::string key, int min, int max, int defaultval);
+ int getOptionInt(std::string key);
+ void setOptionInt(std::string key, int val);
+ void registerOptionUint(std::string tab, std::string desc, std::string key, unsigned min, unsigned max, unsigned defaultval);
+ unsigned getOptionUint(std::string key);
+ void setOptionUint(std::string key, unsigned val);
+ void registerOptionBool(std::string tab, std::string desc, std::string key, bool defaultval);
+ bool getOptionBool(std::string key);
+ void setOptionBool(std::string key, bool val);
+ void registerOptionDouble(std::string tab, std::string desc, std::string key, double min, double max, double defaultval);
+ double getOptionDouble(std::string key);
+ void setOptionDouble(std::string key, double val);
+ void registerOptionString(std::string tab, std::string desc, std::string key, std::string defaultval, bool ispath = false);
+ std::string getOptionString(std::string key);
+ void setOptionString(std::string key, std::string val);
+ void registerOptionEnumInt(std::string tab, std::string desc, std::string key, std::vector<std::string> options, int defaultval);
+ int getOptionEnumInt(std::string key);
+ void setOptionEnumInt(std::string key, int val);
};
class qmpPluginManager
{
- private:
- std::vector<qmpPlugin> plugins;
- static qmpPluginAPIImpl* pluginAPI;
- static qmpMainWindow* mainwindow;
- static qmpSettings* settings;
- public:
- qmpPluginManager();
- ~qmpPluginManager();
- std::vector<qmpPlugin> *getPlugins();
- void scanPlugins(const std::vector<std::string> &pp);
- void initPlugins();
- void deinitPlugins();
- friend class qmpPluginAPIImpl;
- friend class qmpMainWindow;
+private:
+ std::vector<qmpPlugin> plugins;
+ static qmpPluginAPIImpl *pluginAPI;
+ static qmpMainWindow *mainwindow;
+ static qmpSettings *settings;
+public:
+ qmpPluginManager();
+ ~qmpPluginManager();
+ std::vector<qmpPlugin> *getPlugins();
+ void scanPlugins(const std::vector<std::string> &pp);
+ void initPlugins();
+ void deinitPlugins();
+ friend class qmpPluginAPIImpl;
+ friend class qmpMainWindow;
};
#endif // QMPPLUGIN_H
diff --git a/qmidiplayer-desktop/qmppresetselect.cpp b/qmidiplayer-desktop/qmppresetselect.cpp
index 821eced..51bb7d4 100644
--- a/qmidiplayer-desktop/qmppresetselect.cpp
+++ b/qmidiplayer-desktop/qmppresetselect.cpp
@@ -4,132 +4,153 @@
#include "qmpmainwindow.hpp"
qmpPresetSelector::qmpPresetSelector(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::qmpPresetSelector)
+ QDialog(parent),
+ ui(new Ui::qmpPresetSelector)
{
- ui->setupUi(this);
+ ui->setupUi(this);
}
qmpPresetSelector::~qmpPresetSelector()
{
- delete ui;
+ delete ui;
}
void qmpPresetSelector::showEvent(QShowEvent *e)
{
- memset(presets,0,sizeof(presets));
- if(!qmpMainWindow::getInstance()->getFluid()->getSFCount())return e->ignore();
- ui->lwBankSelect->clear();
- ui->lwPresetSelect->clear();
- e->accept();
+ memset(presets, 0, sizeof(presets));
+ if (!qmpMainWindow::getInstance()->getFluid()->getSFCount())
+ return e->ignore();
+ ui->lwBankSelect->clear();
+ ui->lwPresetSelect->clear();
+ e->accept();
}
void qmpPresetSelector::setupWindow(int chid)
{
- CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
- ch=chid;int r;char name[256];
- uint16_t b;uint8_t p;
- std::string pstname;
- sprintf(name,"Preset Selection - Channel #%d",ch+1);
- setWindowTitle(name);
- r=plyr->getChannelOutputDevice(ch)->getChannelPreset(ch,&b,&p,pstname);
- if(!r){b=plyr->getCC(ch,0)<<7|plyr->getCC(ch,32);p=plyr->getCC(ch,128);}
- ui->lwBankSelect->blockSignals(true);
- ui->lwBankSelect->clear();
- ui->lwPresetSelect->clear();
- ui->lwBankSelect->blockSignals(false);
- if(plyr->getChannelOutputDevice(ch)->getBankList().empty()){
- ui->lwPresetSelect->setEnabled(false);
- ui->lwBankSelect->setEnabled(false);
- ui->spCustomLSB->setEnabled(true);
- ui->spCustomMSB->setEnabled(true);
- ui->spCustomPC->setEnabled(true);
- ui->spCustomMSB->setValue(plyr->getCC(chid,0));
- ui->spCustomLSB->setValue(plyr->getCC(chid,32));
- ui->spCustomPC->setValue(p);
- }
- else{
- ui->lwPresetSelect->setEnabled(true);
- ui->lwBankSelect->setEnabled(true);
- ui->spCustomLSB->setEnabled(false);
- ui->spCustomMSB->setEnabled(false);
- ui->spCustomPC->setEnabled(false);
- ui->lwBankSelect->blockSignals(true);
- for(auto&i:plyr->getChannelOutputDevice(ch)->getBankList())
- {
- snprintf(name,256,"%03d %s",i.first,i.second.c_str());
- ui->lwBankSelect->addItem(name);
- if(i.first==b)ui->lwBankSelect->setCurrentRow(ui->lwBankSelect->count()-1);
- }
- ui->lwBankSelect->blockSignals(false);
- for(auto&i:plyr->getChannelOutputDevice(ch)->getPresets(b))
- {
- snprintf(name,256,"%03d %s",i.first,i.second.c_str());
- ui->lwPresetSelect->addItem(name);
- if(i.first==p)ui->lwPresetSelect->setCurrentRow(ui->lwPresetSelect->count()-1);
- }
- }
+ CMidiPlayer *plyr = qmpMainWindow::getInstance()->getPlayer();
+ ch = chid;
+ int r;
+ char name[256];
+ uint16_t b;
+ uint8_t p;
+ std::string pstname;
+ sprintf(name, "Preset Selection - Channel #%d", ch + 1);
+ setWindowTitle(name);
+ r = plyr->getChannelOutputDevice(ch)->getChannelPreset(ch, &b, &p, pstname);
+ if (!r)
+ {
+ b = plyr->getCC(ch, 0) << 7 | plyr->getCC(ch, 32);
+ p = plyr->getCC(ch, 128);
+ }
+ ui->lwBankSelect->blockSignals(true);
+ ui->lwBankSelect->clear();
+ ui->lwPresetSelect->clear();
+ ui->lwBankSelect->blockSignals(false);
+ if (plyr->getChannelOutputDevice(ch)->getBankList().empty())
+ {
+ ui->lwPresetSelect->setEnabled(false);
+ ui->lwBankSelect->setEnabled(false);
+ ui->spCustomLSB->setEnabled(true);
+ ui->spCustomMSB->setEnabled(true);
+ ui->spCustomPC->setEnabled(true);
+ ui->spCustomMSB->setValue(plyr->getCC(chid, 0));
+ ui->spCustomLSB->setValue(plyr->getCC(chid, 32));
+ ui->spCustomPC->setValue(p);
+ }
+ else
+ {
+ ui->lwPresetSelect->setEnabled(true);
+ ui->lwBankSelect->setEnabled(true);
+ ui->spCustomLSB->setEnabled(false);
+ ui->spCustomMSB->setEnabled(false);
+ ui->spCustomPC->setEnabled(false);
+ ui->lwBankSelect->blockSignals(true);
+ for (auto &i : plyr->getChannelOutputDevice(ch)->getBankList())
+ {
+ snprintf(name, 256, "%03d %s", i.first, i.second.c_str());
+ ui->lwBankSelect->addItem(name);
+ if (i.first == b)
+ ui->lwBankSelect->setCurrentRow(ui->lwBankSelect->count() - 1);
+ }
+ ui->lwBankSelect->blockSignals(false);
+ for (auto &i : plyr->getChannelOutputDevice(ch)->getPresets(b))
+ {
+ snprintf(name, 256, "%03d %s", i.first, i.second.c_str());
+ ui->lwPresetSelect->addItem(name);
+ if (i.first == p)
+ ui->lwPresetSelect->setCurrentRow(ui->lwPresetSelect->count() - 1);
+ }
+ }
}
void qmpPresetSelector::on_pbCancel_clicked()
{
- close();
+ close();
}
void qmpPresetSelector::on_pbOk_clicked()
{
- CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
- if(plyr->getChannelOutput(ch)){
- if(ui->spCustomMSB->isEnabled())
- plyr->setChannelPreset(ch,(ui->spCustomMSB->value()<<7)|ui->spCustomLSB->value(),ui->spCustomPC->value());
- else
- {
- if(!ui->lwBankSelect->currentItem()||!ui->lwPresetSelect->currentItem())return (void)close();
- int b=ui->lwBankSelect->currentItem()->text().split(' ').first().toInt();
- int p=ui->lwPresetSelect->currentItem()->text().split(' ').first().toInt();
- plyr->setChannelPreset(ch,b,p);
- }
- }
- else{
- if(!ui->lwBankSelect->currentItem()||!ui->lwPresetSelect->currentItem())return (void)close();
- int b,p;
- b=ui->lwBankSelect->currentItem()->text().toInt();
- p=ui->lwPresetSelect->currentItem()->text().split(' ').first().toInt();
- std::string s=qmpMainWindow::getInstance()->getSettings()->getOptionEnumIntOptName("FluidSynth/BankSelect");
- if(s=="XG"){
- if(b==128)b=127<<7;
- }
- else if(s=="GS")b<<=7;
- plyr->setChannelPreset(ch,b,p);
- }
- qmpMainWindow::getInstance()->invokeCallback("preset.set",nullptr);
- close();
+ CMidiPlayer *plyr = qmpMainWindow::getInstance()->getPlayer();
+ if (plyr->getChannelOutput(ch))
+ {
+ if (ui->spCustomMSB->isEnabled())
+ plyr->setChannelPreset(ch, (ui->spCustomMSB->value() << 7) | ui->spCustomLSB->value(), ui->spCustomPC->value());
+ else
+ {
+ if (!ui->lwBankSelect->currentItem() || !ui->lwPresetSelect->currentItem())
+ return (void)close();
+ int b = ui->lwBankSelect->currentItem()->text().split(' ').first().toInt();
+ int p = ui->lwPresetSelect->currentItem()->text().split(' ').first().toInt();
+ plyr->setChannelPreset(ch, b, p);
+ }
+ }
+ else
+ {
+ if (!ui->lwBankSelect->currentItem() || !ui->lwPresetSelect->currentItem())
+ return (void)close();
+ int b, p;
+ b = ui->lwBankSelect->currentItem()->text().toInt();
+ p = ui->lwPresetSelect->currentItem()->text().split(' ').first().toInt();
+ std::string s = qmpMainWindow::getInstance()->getSettings()->getOptionEnumIntOptName("FluidSynth/BankSelect");
+ if (s == "XG")
+ {
+ if (b == 128)
+ b = 127 << 7;
+ }
+ else if (s == "GS")
+ b <<= 7;
+ plyr->setChannelPreset(ch, b, p);
+ }
+ qmpMainWindow::getInstance()->invokeCallback("preset.set", nullptr);
+ close();
}
void qmpPresetSelector::on_lwPresetSelect_itemDoubleClicked()
{
- on_pbOk_clicked();
+ on_pbOk_clicked();
}
void qmpPresetSelector::on_lwBankSelect_currentRowChanged()
{
- ui->lwPresetSelect->clear();
- if(!ui->lwBankSelect->currentItem())return;
- char name[256];int b;
- sscanf(ui->lwBankSelect->currentItem()->text().toStdString().c_str(),"%d",&b);
- CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer();
- for(auto&i:plyr->getChannelOutputDevice(ch)->getPresets(b))
- {
- snprintf(name,256,"%03d %s",i.first,i.second.c_str());
- ui->lwPresetSelect->addItem(name);
- }
+ ui->lwPresetSelect->clear();
+ if (!ui->lwBankSelect->currentItem())
+ return;
+ char name[256];
+ int b;
+ sscanf(ui->lwBankSelect->currentItem()->text().toStdString().c_str(), "%d", &b);
+ CMidiPlayer *plyr = qmpMainWindow::getInstance()->getPlayer();
+ for (auto &i : plyr->getChannelOutputDevice(ch)->getPresets(b))
+ {
+ snprintf(name, 256, "%03d %s", i.first, i.second.c_str());
+ ui->lwPresetSelect->addItem(name);
+ }
}
void qmpPresetSelector::on_buttonBox_accepted()
{
- on_pbOk_clicked();
+ on_pbOk_clicked();
}
void qmpPresetSelector::on_buttonBox_rejected()
{
- on_pbCancel_clicked();
+ on_pbCancel_clicked();
}
diff --git a/qmidiplayer-desktop/qmppresetselect.hpp b/qmidiplayer-desktop/qmppresetselect.hpp
index 0186578..6eaf2bf 100644
--- a/qmidiplayer-desktop/qmppresetselect.hpp
+++ b/qmidiplayer-desktop/qmppresetselect.hpp
@@ -4,36 +4,37 @@
#include <QDialog>
#include <QShowEvent>
-namespace Ui {
- class qmpPresetSelector;
+namespace Ui
+{
+class qmpPresetSelector;
}
-class qmpPresetSelector:public QDialog
+class qmpPresetSelector: public QDialog
{
- Q_OBJECT
+ Q_OBJECT
- public:
- explicit qmpPresetSelector(QWidget *parent = 0);
- ~qmpPresetSelector();
- void showEvent(QShowEvent* e);
- void setupWindow(int chid);
+public:
+ explicit qmpPresetSelector(QWidget *parent = 0);
+ ~qmpPresetSelector();
+ void showEvent(QShowEvent *e);
+ void setupWindow(int chid);
- private slots:
+private slots:
- void on_lwBankSelect_currentRowChanged();
+ void on_lwBankSelect_currentRowChanged();
- void on_lwPresetSelect_itemDoubleClicked();
+ void on_lwPresetSelect_itemDoubleClicked();
- void on_buttonBox_accepted();
+ void on_buttonBox_accepted();
- void on_buttonBox_rejected();
+ void on_buttonBox_rejected();
- private:
- Ui::qmpPresetSelector *ui;
- char presets[129][128][24];
- void on_pbCancel_clicked();
- void on_pbOk_clicked();
- int ch;
+private:
+ Ui::qmpPresetSelector *ui;
+ char presets[129][128][24];
+ void on_pbCancel_clicked();
+ void on_pbOk_clicked();
+ int ch;
};
#endif // QMPPRESETSELECT_H
diff --git a/qmidiplayer-desktop/qmpsettings.cpp b/qmidiplayer-desktop/qmpsettings.cpp
index cdc96b8..8ba0d5e 100644
--- a/qmidiplayer-desktop/qmpsettings.cpp
+++ b/qmidiplayer-desktop/qmpsettings.cpp
@@ -4,245 +4,245 @@
#define QMP_CONFIGURATION_FILE_REV 1
-QSettings* qmpSettings::settings=nullptr;
+QSettings *qmpSettings::settings = nullptr;
qmpSettings::qmpSettings()
{
- qRegisterMetaTypeStreamOperators<QPair<QString,QString>>();
- QString confpath=QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ConfigLocation)+QString("/qmprc");
- settings=new QSettings(confpath,QSettings::IniFormat);
- if(settings->value("ConfigurationFileRevision").toInt()!=QMP_CONFIGURATION_FILE_REV&&
- QFile::exists(confpath))
- {
- qWarning("Your current configuration file is not compatible with this version of QMidiPlayer. "
- "QMidiPlayer will start with its default configuration. A backup of the old configuration "
- "is automatically saved as qmprc.old.");
- QFile::remove(confpath+".old");
- QFile::copy(confpath,confpath+".old");
- settings->clear();
- settings->setValue("ConfigurationFileRevision",QMP_CONFIGURATION_FILE_REV);
- }
+ qRegisterMetaTypeStreamOperators<QPair<QString, QString>>();
+ QString confpath = QStandardPaths::writableLocation(QStandardPaths::StandardLocation::ConfigLocation) + QString("/qmprc");
+ settings = new QSettings(confpath, QSettings::IniFormat);
+ if (settings->value("ConfigurationFileRevision").toInt() != QMP_CONFIGURATION_FILE_REV &&
+ QFile::exists(confpath))
+ {
+ qWarning("Your current configuration file is not compatible with this version of QMidiPlayer. "
+ "QMidiPlayer will start with its default configuration. A backup of the old configuration "
+ "is automatically saved as qmprc.old.");
+ QFile::remove(confpath + ".old");
+ QFile::copy(confpath, confpath + ".old");
+ settings->clear();
+ settings->setValue("ConfigurationFileRevision", QMP_CONFIGURATION_FILE_REV);
+ }
}
qmpSettings::~qmpSettings()
{
- delete settings;
- settings=nullptr;
+ delete settings;
+ settings = nullptr;
}
-void qmpSettings::registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval)
+void qmpSettings::registerOptionInt(std::string tab, std::string desc, std::string key, int min, int max, int defaultval)
{
- optionlist.push_back(key);
- options[key]=qmpOption(tab,desc,qmpOption::ParameterType::parameter_int,nullptr,defaultval,min,max);
+ optionlist.push_back(key);
+ options[key] = qmpOption(tab, desc, qmpOption::ParameterType::parameter_int, nullptr, defaultval, min, max);
}
int qmpSettings::getOptionInt(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_int)
- return settings->value(QString(key.c_str()),options[key].defaultval).toInt();
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
- return options[key].defaultval.toInt();
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_int)
+ return settings->value(QString(key.c_str()), options[key].defaultval).toInt();
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
+ return options[key].defaultval.toInt();
}
-void qmpSettings::setOptionInt(std::string key,int val)
+void qmpSettings::setOptionInt(std::string key, int val)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_int)
- settings->setValue(QString(key.c_str()),val);
- else
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
- //call qmpSettingsWindow::load(key)?
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_int)
+ settings->setValue(QString(key.c_str()), val);
+ else
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
+ //call qmpSettingsWindow::load(key)?
}
-void qmpSettings::registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min, unsigned max,unsigned defaultval)
+void qmpSettings::registerOptionUint(std::string tab, std::string desc, std::string key, unsigned min, unsigned max, unsigned defaultval)
{
- optionlist.push_back(key);
- options[key]=qmpOption(tab,desc,qmpOption::ParameterType::parameter_uint,nullptr,defaultval,min,max);
+ optionlist.push_back(key);
+ options[key] = qmpOption(tab, desc, qmpOption::ParameterType::parameter_uint, nullptr, defaultval, min, max);
}
unsigned qmpSettings::getOptionUint(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_uint)
- return settings->value(QString(key.c_str()),options[key].defaultval).toUInt();
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
- return options[key].defaultval.toUInt();
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_uint)
+ return settings->value(QString(key.c_str()), options[key].defaultval).toUInt();
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
+ return options[key].defaultval.toUInt();
}
-void qmpSettings::setOptionUint(std::string key,unsigned val)
+void qmpSettings::setOptionUint(std::string key, unsigned val)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_uint)
- settings->setValue(QString(key.c_str()),val);
- else
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_uint)
+ settings->setValue(QString(key.c_str()), val);
+ else
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
}
-void qmpSettings::registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval)
+void qmpSettings::registerOptionBool(std::string tab, std::string desc, std::string key, bool defaultval)
{
- optionlist.push_back(key);
- options[key]=qmpOption(tab,desc,qmpOption::ParameterType::parameter_bool,nullptr,defaultval);
+ optionlist.push_back(key);
+ options[key] = qmpOption(tab, desc, qmpOption::ParameterType::parameter_bool, nullptr, defaultval);
}
bool qmpSettings::getOptionBool(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_bool)
- return settings->value(QString(key.c_str()),options[key].defaultval).toBool();
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
- return options[key].defaultval.toBool();
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_bool)
+ return settings->value(QString(key.c_str()), options[key].defaultval).toBool();
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
+ return options[key].defaultval.toBool();
}
-void qmpSettings::setOptionBool(std::string key,bool val)
+void qmpSettings::setOptionBool(std::string key, bool val)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_bool)
- settings->setValue(QString(key.c_str()),val);
- else
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_bool)
+ settings->setValue(QString(key.c_str()), val);
+ else
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
}
void qmpSettings::registerOptionDouble(std::string tab, std::string desc, std::string key, double min, double max, double defaultval)
{
- optionlist.push_back(key);
- options[key]=qmpOption(tab,desc,qmpOption::ParameterType::parameter_double,nullptr,defaultval,min,max);
+ optionlist.push_back(key);
+ options[key] = qmpOption(tab, desc, qmpOption::ParameterType::parameter_double, nullptr, defaultval, min, max);
}
double qmpSettings::getOptionDouble(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_double)
- return settings->value(QString(key.c_str()),options[key].defaultval).toDouble();
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
- return options[key].defaultval.toDouble();
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_double)
+ return settings->value(QString(key.c_str()), options[key].defaultval).toDouble();
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
+ return options[key].defaultval.toDouble();
}
-void qmpSettings::setOptionDouble(std::string key,double val)
+void qmpSettings::setOptionDouble(std::string key, double val)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_double)
- settings->setValue(QString(key.c_str()),val);
- else
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_double)
+ settings->setValue(QString(key.c_str()), val);
+ else
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
}
-void qmpSettings::registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool is_url)
+void qmpSettings::registerOptionString(std::string tab, std::string desc, std::string key, std::string defaultval, bool is_url)
{
- optionlist.push_back(key);
- options[key]=qmpOption(tab,desc,
- is_url?qmpOption::ParameterType::parameter_url:qmpOption::ParameterType::parameter_str,
- nullptr,QString(defaultval.c_str()));
+ optionlist.push_back(key);
+ options[key] = qmpOption(tab, desc,
+ is_url ? qmpOption::ParameterType::parameter_url : qmpOption::ParameterType::parameter_str,
+ nullptr, QString(defaultval.c_str()));
}
std::string qmpSettings::getOptionString(std::string key)
{
- if(options.find(key)!=options.end()&&
- (options[key].type==qmpOption::ParameterType::parameter_str||options[key].type==qmpOption::ParameterType::parameter_url))
- return settings->value(QString(key.c_str()),options[key].defaultval).toString().toStdString();
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
- return options[key].defaultval.toString().toStdString();
+ if (options.find(key) != options.end() &&
+ (options[key].type == qmpOption::ParameterType::parameter_str || options[key].type == qmpOption::ParameterType::parameter_url))
+ return settings->value(QString(key.c_str()), options[key].defaultval).toString().toStdString();
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
+ return options[key].defaultval.toString().toStdString();
}
-void qmpSettings::setOptionString(std::string key,std::string val)
+void qmpSettings::setOptionString(std::string key, std::string val)
{
- if(options.find(key)!=options.end()&&
- (options[key].type==qmpOption::ParameterType::parameter_str||options[key].type==qmpOption::ParameterType::parameter_url))
- settings->setValue(QString(key.c_str()),QString(val.c_str()));
- else
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
+ if (options.find(key) != options.end() &&
+ (options[key].type == qmpOption::ParameterType::parameter_str || options[key].type == qmpOption::ParameterType::parameter_url))
+ settings->setValue(QString(key.c_str()), QString(val.c_str()));
+ else
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
}
-void qmpSettings::registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> enumlist,int defaultval)
+void qmpSettings::registerOptionEnumInt(std::string tab, std::string desc, std::string key, std::vector<std::string> enumlist, int defaultval)
{
- optionlist.push_back(key);
- options[key]=qmpOption(tab,desc,qmpOption::ParameterType::parameter_enum,nullptr,defaultval);
- options[key].enumlist=enumlist;
+ optionlist.push_back(key);
+ options[key] = qmpOption(tab, desc, qmpOption::ParameterType::parameter_enum, nullptr, defaultval);
+ options[key].enumlist = enumlist;
}
int qmpSettings::getOptionEnumInt(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_enum)
- {
- std::string curitm=settings->value(QString(key.c_str()),options[key].defaultval).toString().toStdString();
- auto curidx=std::find(options[key].enumlist.begin(),options[key].enumlist.end(),curitm);
- if(curidx!=options[key].enumlist.end())
- return static_cast<int>(curidx-options[key].enumlist.begin());
- else
- {
- qWarning("Invalid value set for option \"%s\".",key.c_str());
- return options[key].defaultval.toInt();
- }
- }
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
- return options[key].defaultval.toInt();
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_enum)
+ {
+ std::string curitm = settings->value(QString(key.c_str()), options[key].defaultval).toString().toStdString();
+ auto curidx = std::find(options[key].enumlist.begin(), options[key].enumlist.end(), curitm);
+ if (curidx != options[key].enumlist.end())
+ return static_cast<int>(curidx - options[key].enumlist.begin());
+ else
+ {
+ qWarning("Invalid value set for option \"%s\".", key.c_str());
+ return options[key].defaultval.toInt();
+ }
+ }
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
+ return options[key].defaultval.toInt();
}
std::string qmpSettings::getOptionEnumIntOptName(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_enum)
- {
- std::string curitm=settings->value(QString(key.c_str()),options[key].defaultval).toString().toStdString();
- auto curidx=std::find(options[key].enumlist.begin(),options[key].enumlist.end(),curitm);
- if(curidx!=options[key].enumlist.end())
- return curitm;
- else
- {
- qWarning("Invalid value set for option \"%s\".",key.c_str());
- return options[key].enumlist[static_cast<size_t>(options[key].defaultval.toInt())];
- }
- }
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
- return options[key].enumlist[static_cast<size_t>(options[key].defaultval.toInt())];
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_enum)
+ {
+ std::string curitm = settings->value(QString(key.c_str()), options[key].defaultval).toString().toStdString();
+ auto curidx = std::find(options[key].enumlist.begin(), options[key].enumlist.end(), curitm);
+ if (curidx != options[key].enumlist.end())
+ return curitm;
+ else
+ {
+ qWarning("Invalid value set for option \"%s\".", key.c_str());
+ return options[key].enumlist[static_cast<size_t>(options[key].defaultval.toInt())];
+ }
+ }
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
+ return options[key].enumlist[static_cast<size_t>(options[key].defaultval.toInt())];
}
-void qmpSettings::setOptionEnumInt(std::string key,int val)
+void qmpSettings::setOptionEnumInt(std::string key, int val)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_enum)
- {
- if(static_cast<size_t>(val)<options[key].enumlist.size())
- settings->setValue(QString(key.c_str()),QString(options[key].enumlist[static_cast<size_t>(val)].c_str()));
- else
- qWarning("Trying to set invalid value for option \"%s\".",key.c_str());
- }
- else
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_enum)
+ {
+ if (static_cast<size_t>(val) < options[key].enumlist.size())
+ settings->setValue(QString(key.c_str()), QString(options[key].enumlist[static_cast<size_t>(val)].c_str()));
+ else
+ qWarning("Trying to set invalid value for option \"%s\".", key.c_str());
+ }
+ else
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
}
-void qmpSettings::setOptionEnumIntOptName(std::string key,std::string valname)
+void qmpSettings::setOptionEnumIntOptName(std::string key, std::string valname)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOption::ParameterType::parameter_enum)
- {
- auto curidx=std::find(options[key].enumlist.begin(),options[key].enumlist.end(),valname);
- if(curidx!=options[key].enumlist.end())
- settings->setValue(QString(key.c_str()),QString(valname.c_str()));
- else
- qWarning("Trying to set invalid value for option \"%s\".",key.c_str());
- }
- else
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
+ if (options.find(key) != options.end() && options[key].type == qmpOption::ParameterType::parameter_enum)
+ {
+ auto curidx = std::find(options[key].enumlist.begin(), options[key].enumlist.end(), valname);
+ if (curidx != options[key].enumlist.end())
+ settings->setValue(QString(key.c_str()), QString(valname.c_str()));
+ else
+ qWarning("Trying to set invalid value for option \"%s\".", key.c_str());
+ }
+ else
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
}
-void qmpSettings::registerOptionCustom(std::string tab,std::string desc,std::string key,void* widget, void* defaultval,std::function<void*()> save_func,std::function<void(void*)> load_func)
+void qmpSettings::registerOptionCustom(std::string tab, std::string desc, std::string key, void *widget, void *defaultval, std::function<void *()> save_func, std::function<void(void *)> load_func)
{
- optionlist.push_back(key);
- options[key]=qmpOption(tab,desc,qmpOption::parameter_custom,
- static_cast<QWidget*>(widget),
- *static_cast<QVariant*>(defaultval),
- QVariant(),QVariant(),save_func,load_func);
+ optionlist.push_back(key);
+ options[key] = qmpOption(tab, desc, qmpOption::parameter_custom,
+ static_cast<QWidget *>(widget),
+ *static_cast<QVariant *>(defaultval),
+ QVariant(), QVariant(), save_func, load_func);
}
-void* qmpSettings::getOptionCustom(std::string key)
+void *qmpSettings::getOptionCustom(std::string key)
{
- if(options.find(key)!=options.end()||options[key].type!=qmpOption::ParameterType::parameter_custom)
- return static_cast<void*>(new QVariant(settings->value(QString(key.c_str()),options[key].defaultval)));
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
- return nullptr;
+ if (options.find(key) != options.end() || options[key].type != qmpOption::ParameterType::parameter_custom)
+ return static_cast<void *>(new QVariant(settings->value(QString(key.c_str()), options[key].defaultval)));
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
+ return nullptr;
}
-void qmpSettings::setOptionCustom(std::string key,void *val)
+void qmpSettings::setOptionCustom(std::string key, void *val)
{
- if(options.find(key)!=options.end()||options[key].type!=qmpOption::ParameterType::parameter_custom)
- settings->setValue(QString(key.c_str()),*static_cast<QVariant*>(val));
- else
- qWarning("Unregistered option or mismatching option type: %s.",key.c_str());
+ if (options.find(key) != options.end() || options[key].type != qmpOption::ParameterType::parameter_custom)
+ settings->setValue(QString(key.c_str()), *static_cast<QVariant *>(val));
+ else
+ qWarning("Unregistered option or mismatching option type: %s.", key.c_str());
}
-void qmpSettings::setOptionRaw(QString key,QVariant val)
+void qmpSettings::setOptionRaw(QString key, QVariant val)
{
- settings->setValue(key,val);
+ settings->setValue(key, val);
}
-QVariant qmpSettings::getOptionRaw(QString key,QVariant defval)
+QVariant qmpSettings::getOptionRaw(QString key, QVariant defval)
{
- return settings->value(key,defval);
+ return settings->value(key, defval);
}
-QDataStream &operator<<(QDataStream &out,const QPair<QString,QString> &o)
+QDataStream &operator<<(QDataStream &out, const QPair<QString, QString> &o)
{
- out<<o.first<<o.second;
- return out;
+ out << o.first << o.second;
+ return out;
}
-QDataStream &operator>>(QDataStream &in,QPair<QString,QString> &o)
+QDataStream &operator>>(QDataStream &in, QPair<QString, QString> &o)
{
- in>>o.first>>o.second;
- return in;
+ in >> o.first >> o.second;
+ return in;
}
diff --git a/qmidiplayer-desktop/qmpsettings.hpp b/qmidiplayer-desktop/qmpsettings.hpp
index ff46970..2fb894f 100644
--- a/qmidiplayer-desktop/qmpsettings.hpp
+++ b/qmidiplayer-desktop/qmpsettings.hpp
@@ -10,79 +10,80 @@
struct qmpOption
{
- enum ParameterType{
- parameter_int=0,
- parameter_uint,
- parameter_bool,
- parameter_double,
- parameter_str,
- parameter_enum,
- parameter_url,
- parameter_custom=0x100
- };
+ enum ParameterType
+ {
+ parameter_int = 0,
+ parameter_uint,
+ parameter_bool,
+ parameter_double,
+ parameter_str,
+ parameter_enum,
+ parameter_url,
+ parameter_custom = 0x100
+ };
- std::string tab;
- std::string desc;
- ParameterType type;
- QWidget* widget;
- QVariant defaultval,minv,maxv;
- std::function<void*()> save_func;
- std::function<void(void*)> load_func;
- std::vector<std::string> enumlist;
+ std::string tab;
+ std::string desc;
+ ParameterType type;
+ QWidget *widget;
+ QVariant defaultval, minv, maxv;
+ std::function<void *()> save_func;
+ std::function<void(void *)> load_func;
+ std::vector<std::string> enumlist;
- qmpOption():widget(nullptr){}
- qmpOption(std::string _tab,std::string _desc,
- ParameterType _t,QWidget* _w=nullptr,
- QVariant _def=QVariant(),QVariant _min=QVariant(),QVariant _max=QVariant(),
- std::function<void*()> _save=nullptr,std::function<void(void*)> _load=nullptr):
- tab(_tab),
- desc(_desc),
- type(_t),
- widget(_w),
- defaultval(_def),
- minv(_min),
- maxv(_max),
- save_func(_save),
- load_func(_load){}
+ qmpOption(): widget(nullptr) {}
+ qmpOption(std::string _tab, std::string _desc,
+ ParameterType _t, QWidget *_w = nullptr,
+ QVariant _def = QVariant(), QVariant _min = QVariant(), QVariant _max = QVariant(),
+ std::function<void *()> _save = nullptr, std::function<void(void *)> _load = nullptr):
+ tab(_tab),
+ desc(_desc),
+ type(_t),
+ widget(_w),
+ defaultval(_def),
+ minv(_min),
+ maxv(_max),
+ save_func(_save),
+ load_func(_load) {}
};
class qmpSettings
{
- public:
- qmpSettings();
- ~qmpSettings();
- void registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval);
- int getOptionInt(std::string key);
- void setOptionInt(std::string key,int val);
- void registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min,unsigned max,unsigned defaultval);
- unsigned getOptionUint(std::string key);
- void setOptionUint(std::string key,unsigned val);
- void registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval);
- bool getOptionBool(std::string key);
- void setOptionBool(std::string key,bool val);
- void registerOptionDouble(std::string tab,std::string desc,std::string key,double min,double max,double defaultval);
- double getOptionDouble(std::string key);
- void setOptionDouble(std::string key,double val);
- void registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool is_url);
- std::string getOptionString(std::string key);
- void setOptionString(std::string key,std::string val);
- void registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> enumlist,int defaultval);
- int getOptionEnumInt(std::string key);
- std::string getOptionEnumIntOptName(std::string key);
- void setOptionEnumInt(std::string key,int val);
- void setOptionEnumIntOptName(std::string key,std::string valname);
- void registerOptionCustom(std::string tab,std::string desc,std::string key,void* widget,void* defaultval,std::function<void*()> save_func,std::function<void(void*)> load_func);
- void* getOptionCustom(std::string key);
- void setOptionCustom(std::string key,void* val);
+public:
+ qmpSettings();
+ ~qmpSettings();
+ void registerOptionInt(std::string tab, std::string desc, std::string key, int min, int max, int defaultval);
+ int getOptionInt(std::string key);
+ void setOptionInt(std::string key, int val);
+ void registerOptionUint(std::string tab, std::string desc, std::string key, unsigned min, unsigned max, unsigned defaultval);
+ unsigned getOptionUint(std::string key);
+ void setOptionUint(std::string key, unsigned val);
+ void registerOptionBool(std::string tab, std::string desc, std::string key, bool defaultval);
+ bool getOptionBool(std::string key);
+ void setOptionBool(std::string key, bool val);
+ void registerOptionDouble(std::string tab, std::string desc, std::string key, double min, double max, double defaultval);
+ double getOptionDouble(std::string key);
+ void setOptionDouble(std::string key, double val);
+ void registerOptionString(std::string tab, std::string desc, std::string key, std::string defaultval, bool is_url);
+ std::string getOptionString(std::string key);
+ void setOptionString(std::string key, std::string val);
+ void registerOptionEnumInt(std::string tab, std::string desc, std::string key, std::vector<std::string> enumlist, int defaultval);
+ int getOptionEnumInt(std::string key);
+ std::string getOptionEnumIntOptName(std::string key);
+ void setOptionEnumInt(std::string key, int val);
+ void setOptionEnumIntOptName(std::string key, std::string valname);
+ void registerOptionCustom(std::string tab, std::string desc, std::string key, void *widget, void *defaultval, std::function<void *()> save_func, std::function<void(void *)> load_func);
+ void *getOptionCustom(std::string key);
+ void setOptionCustom(std::string key, void *val);
- void setOptionRaw(QString key,QVariant val);
- QVariant getOptionRaw(QString key,QVariant defval=QVariant());
+ void setOptionRaw(QString key, QVariant val);
+ QVariant getOptionRaw(QString key, QVariant defval = QVariant());
- private:
- static QSettings *settings;
- std::map<std::string,qmpOption> options;
- std::vector<std::string> optionlist;
+private:
+ static QSettings *settings;
+ std::map<std::string, qmpOption> options;
+ std::vector<std::string> optionlist;
- friend class qmpSettingsWindow;
+ friend class qmpSettingsWindow;
};
#endif
diff --git a/qmidiplayer-desktop/qmpsettingswindow.cpp b/qmidiplayer-desktop/qmpsettingswindow.cpp
index 8d4a964..03e4cd1 100644
--- a/qmidiplayer-desktop/qmpsettingswindow.cpp
+++ b/qmidiplayer-desktop/qmpsettingswindow.cpp
@@ -12,568 +12,593 @@
#include "ui_qmpsettingswindow.h"
#include "qmpmainwindow.hpp"
-qmpSettingsWindow::qmpSettingsWindow(qmpSettings *qmpsettings,QWidget *parent) :
- QDialog(parent),
- ui(new Ui::qmpSettingsWindow)
+qmpSettingsWindow::qmpSettingsWindow(qmpSettings *qmpsettings, QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::qmpSettingsWindow)
{
- ui->setupUi(this);customOptions.clear();customOptPages.clear();
- connect(this,&qmpSettingsWindow::dialogClosing,(qmpMainWindow*)parent,&qmpMainWindow::dialogClosed);
- settings=qmpsettings;
- cwt=new qmpCustomizeWindow(this);
- cwa=new qmpCustomizeWindow(this);
- dps=new qmpDevPropDialog(this);
- devpriod=new qmpDevicePriorityDialog(this);
+ ui->setupUi(this);
+ customOptions.clear();
+ customOptPages.clear();
+ connect(this, &qmpSettingsWindow::dialogClosing, (qmpMainWindow *)parent, &qmpMainWindow::dialogClosed);
+ settings = qmpsettings;
+ cwt = new qmpCustomizeWindow(this);
+ cwa = new qmpCustomizeWindow(this);
+ dps = new qmpDevPropDialog(this);
+ devpriod = new qmpDevicePriorityDialog(this);
}
qmpSettingsWindow::~qmpSettingsWindow()
{
- delete ui;
+ delete ui;
}
void qmpSettingsWindow::closeEvent(QCloseEvent *event)
{
- setVisible(false);
- loadOption();
- emit dialogClosing();
- event->accept();
+ setVisible(false);
+ loadOption();
+ emit dialogClosing();
+ event->accept();
}
void qmpSettingsWindow::hideEvent(QHideEvent *event)
{
- emit dialogClosing();
- event->accept();
+ emit dialogClosing();
+ event->accept();
}
void qmpSettingsWindow::on_buttonBox_accepted()
{
- saveOption();
- qmpMainWindow::getInstance()->setupWidget();
- emit dialogClosing();
+ saveOption();
+ qmpMainWindow::getInstance()->setupWidget();
+ emit dialogClosing();
}
void qmpSettingsWindow::on_buttonBox_rejected()
{
- loadOption();
- emit dialogClosing();
+ loadOption();
+ emit dialogClosing();
}
void qmpSettingsWindow::updatePluginList(qmpPluginManager *pmgr)
{
- std::vector<qmpPlugin> *plugins=pmgr->getPlugins();
- QVariant *data=static_cast<QVariant*>(settings->getOptionCustom("DisabledPlugins"));
- QList<QVariant> disabled_plugins_l=static_cast<QVariant*>(data)->toList();
- delete data;
- std::set<std::string> disabled_plugins_s;
- for(auto &i:disabled_plugins_l)
- disabled_plugins_s.insert(i.toString().toStdString());
- for(unsigned i=0;i<plugins->size();++i)
- {
- bool enabled=disabled_plugins_s.find(plugins->at(i).name)==disabled_plugins_s.end();
- plugins->at(i).enabled=enabled;
- }
+ std::vector<qmpPlugin> *plugins = pmgr->getPlugins();
+ QVariant *data = static_cast<QVariant *>(settings->getOptionCustom("DisabledPlugins"));
+ QList<QVariant> disabled_plugins_l = static_cast<QVariant *>(data)->toList();
+ delete data;
+ std::set<std::string> disabled_plugins_s;
+ for (auto &i : disabled_plugins_l)
+ disabled_plugins_s.insert(i.toString().toStdString());
+ for (unsigned i = 0; i < plugins->size(); ++i)
+ {
+ bool enabled = disabled_plugins_s.find(plugins->at(i).name) == disabled_plugins_s.end();
+ plugins->at(i).enabled = enabled;
+ }
}
void qmpSettingsWindow::postInit()
{
- setupWidgets();
- int sf=0;
- QVariant *data=static_cast<QVariant*>(settings->getOptionCustom("FluidSynth/SoundFonts"));
- for(auto i:data->toList())
- if(!i.toString().startsWith('#'))
- {
- sf=1;
- break;
- }
- delete data;
- std::string selecteddev;
- std::vector<std::string> devs=qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices();
- std::set<std::string> devset;
- for(auto dev:devs)devset.insert(dev);
- QVariant *devpriov=static_cast<QVariant*>(qmpMainWindow::getInstance()->getSettings()->getOptionCustom("Midi/DevicePriority"));
- QList<QVariant> devprio=devpriov->toList();
- delete devpriov;
- for(auto &setdev:devprio)
- if(devset.find(setdev.toString().toStdString())!=devset.end())
- {
- selecteddev=setdev.toString().toStdString();
- break;
- }
- if(selecteddev=="Internal FluidSynth"&&!sf)
- {
- if(QMessageBox::question(this,
- tr("No soundfont loaded"),
- tr("Internal fluidsynth is the only available MIDI output but it has no soundfont set. "
- "Would you like to setup soundfonts now? You may have to reload the internal synth afterwards."))==QMessageBox::Yes)
- {
- show();
- ui->tabWidget->setCurrentWidget(qobject_cast<QWidget*>(pageForTab("SoundFonts")->parent()));
- }
- }
+ setupWidgets();
+ int sf = 0;
+ QVariant *data = static_cast<QVariant *>(settings->getOptionCustom("FluidSynth/SoundFonts"));
+ for (auto i : data->toList())
+ if (!i.toString().startsWith('#'))
+ {
+ sf = 1;
+ break;
+ }
+ delete data;
+ std::string selecteddev;
+ std::vector<std::string> devs = qmpMainWindow::getInstance()->getPlayer()->getMidiOutDevices();
+ std::set<std::string> devset;
+ for (auto dev : devs)
+ devset.insert(dev);
+ QVariant *devpriov = static_cast<QVariant *>(qmpMainWindow::getInstance()->getSettings()->getOptionCustom("Midi/DevicePriority"));
+ QList<QVariant> devprio = devpriov->toList();
+ delete devpriov;
+ for (auto &setdev : devprio)
+ if (devset.find(setdev.toString().toStdString()) != devset.end())
+ {
+ selecteddev = setdev.toString().toStdString();
+ break;
+ }
+ if (selecteddev == "Internal FluidSynth" && !sf)
+ {
+ if (QMessageBox::question(this,
+ tr("No soundfont loaded"),
+ tr("Internal fluidsynth is the only available MIDI output but it has no soundfont set. "
+ "Would you like to setup soundfonts now? You may have to reload the internal synth afterwards.")) == QMessageBox::Yes)
+ {
+ show();
+ ui->tabWidget->setCurrentWidget(qobject_cast<QWidget *>(pageForTab("SoundFonts")->parent()));
+ }
+ }
}
void qmpSettingsWindow::registerCustomizeWidgetOptions()
{
- QPushButton *pbCustomizeToolbar=new QPushButton(tr("Customize..."));
- QPushButton *pbCustomizeActions=new QPushButton(tr("Customize..."));
- QVariant toolbar_def_val=QList<QVariant>({"Channel","Playlist","Effects","Visualization"});
- QVariant actions_def_val=QList<QVariant>({"FileInfo","Render","Panic","ReloadSynth"});
- settings->registerOptionCustom("Behavior","Customize toolbar","Behavior/Toolbar",pbCustomizeToolbar,&toolbar_def_val,std::bind(&qmpCustomizeWindow::save,cwt),std::bind(&qmpCustomizeWindow::load,cwt,std::placeholders::_1));
- settings->registerOptionCustom("Behavior","Customize actions","Behavior/Actions",pbCustomizeActions,&actions_def_val,std::bind(&qmpCustomizeWindow::save,cwa),std::bind(&qmpCustomizeWindow::load,cwa,std::placeholders::_1));
- connect(pbCustomizeToolbar,&QPushButton::clicked,[this]{loadOption("Behavior/Toolbar");cwt->show();});
- connect(pbCustomizeActions,&QPushButton::clicked,[this]{loadOption("Behavior/Actions");cwa->show();});
- connect(cwt,&QDialog::accepted,[this]{saveOption("Behavior/Toolbar");qmpMainWindow::getInstance()->setupWidget();});
- connect(cwa,&QDialog::accepted,[this]{saveOption("Behavior/Actions");qmpMainWindow::getInstance()->setupWidget();});
- connect(cwt,&QDialog::rejected,[this]{loadOption("Behavior/Toolbar");});
- connect(cwa,&QDialog::rejected,[this]{loadOption("Behavior/Actions");});
- qmpMainWindow::getInstance()->setupWidget();
+ QPushButton *pbCustomizeToolbar = new QPushButton(tr("Customize..."));
+ QPushButton *pbCustomizeActions = new QPushButton(tr("Customize..."));
+ QVariant toolbar_def_val = QList<QVariant>({"Channel", "Playlist", "Effects", "Visualization"});
+ QVariant actions_def_val = QList<QVariant>({"FileInfo", "Render", "Panic", "ReloadSynth"});
+ settings->registerOptionCustom("Behavior", "Customize toolbar", "Behavior/Toolbar", pbCustomizeToolbar, &toolbar_def_val, std::bind(&qmpCustomizeWindow::save, cwt), std::bind(&qmpCustomizeWindow::load, cwt, std::placeholders::_1));
+ settings->registerOptionCustom("Behavior", "Customize actions", "Behavior/Actions", pbCustomizeActions, &actions_def_val, std::bind(&qmpCustomizeWindow::save, cwa), std::bind(&qmpCustomizeWindow::load, cwa, std::placeholders::_1));
+ connect(pbCustomizeToolbar, &QPushButton::clicked, [this] {loadOption("Behavior/Toolbar"); cwt->show();});
+ connect(pbCustomizeActions, &QPushButton::clicked, [this] {loadOption("Behavior/Actions"); cwa->show();});
+ connect(cwt, &QDialog::accepted, [this] {saveOption("Behavior/Toolbar"); qmpMainWindow::getInstance()->setupWidget();});
+ connect(cwa, &QDialog::accepted, [this] {saveOption("Behavior/Actions"); qmpMainWindow::getInstance()->setupWidget();});
+ connect(cwt, &QDialog::rejected, [this] {loadOption("Behavior/Toolbar");});
+ connect(cwa, &QDialog::rejected, [this] {loadOption("Behavior/Actions");});
+ qmpMainWindow::getInstance()->setupWidget();
}
void qmpSettingsWindow::registerSoundFontOption()
{
- QWidget *sfpanel=new QWidget();
- sfpanel->setLayout(new QVBoxLayout);
- sfpanel->layout()->setMargin(0);
- QTableWidget *twsf=new QTableWidget();
- twsf->setColumnCount(2);
- twsf->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);
- twsf->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
- twsf->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows);
- twsf->setHorizontalHeaderLabels({tr("E"),tr("Path")});
- twsf->setHorizontalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
- twsf->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
- sfpanel->layout()->addWidget(twsf);
- QWidget *controls=new QWidget();
- controls->setLayout(new QHBoxLayout);
- controls->layout()->setMargin(0);
- QPushButton *pbsfadd=new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_DialogOpenButton),QString());
- QPushButton *pbsfrem=new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_DialogDiscardButton),QString());
- QPushButton *pbsfmup=new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_ArrowUp),QString());
- QPushButton *pbsfmdn=new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_ArrowDown),QString());
- controls->layout()->addWidget(pbsfadd);
- controls->layout()->addWidget(pbsfrem);
- controls->layout()->addWidget(pbsfmup);
- controls->layout()->addWidget(pbsfmdn);
- sfpanel->layout()->addWidget(controls);
+ QWidget *sfpanel = new QWidget();
+ sfpanel->setLayout(new QVBoxLayout);
+ sfpanel->layout()->setMargin(0);
+ QTableWidget *twsf = new QTableWidget();
+ twsf->setColumnCount(2);
+ twsf->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);
+ twsf->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
+ twsf->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows);
+ twsf->setHorizontalHeaderLabels({tr("E"), tr("Path")});
+ twsf->setHorizontalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
+ twsf->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
+ sfpanel->layout()->addWidget(twsf);
+ QWidget *controls = new QWidget();
+ controls->setLayout(new QHBoxLayout);
+ controls->layout()->setMargin(0);
+ QPushButton *pbsfadd = new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_DialogOpenButton), QString());
+ QPushButton *pbsfrem = new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_DialogDiscardButton), QString());
+ QPushButton *pbsfmup = new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_ArrowUp), QString());
+ QPushButton *pbsfmdn = new QPushButton(style()->standardIcon(QStyle::StandardPixmap::SP_ArrowDown), QString());
+ controls->layout()->addWidget(pbsfadd);
+ controls->layout()->addWidget(pbsfrem);
+ controls->layout()->addWidget(pbsfmup);
+ controls->layout()->addWidget(pbsfmdn);
+ sfpanel->layout()->addWidget(controls);
- connect(pbsfadd,&QPushButton::clicked,[twsf,this]{
- QStringList sl=QFileDialog::getOpenFileNames(this,"Add File","","SoundFont files (*.sf2)");
- for(int i=0;i<sl.size();++i){
- twsf->insertRow(twsf->rowCount());
- QTableWidgetItem *sfn,*sfe;
- twsf->setItem(twsf->rowCount()-1,1,sfn=new QTableWidgetItem(sl[i]));
- twsf->setItem(twsf->rowCount()-1,0,sfe=new QTableWidgetItem());
- sfe->setCheckState(Qt::CheckState::Unchecked);
- sfn->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable);
- sfe->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable|Qt::ItemFlag::ItemIsUserCheckable);
- }
- });
- connect(pbsfrem,&QPushButton::clicked,[twsf]{
- QList<QTableWidgetItem*> sl=twsf->selectedItems();
- for(int i=0;i<sl.size();++i)
- twsf->removeRow(twsf->row(sl[i]));
- });
- connect(pbsfmup,&QPushButton::clicked,[twsf]{
- int cid=twsf->currentRow();if(!cid)return;
- QTableWidgetItem *ci=twsf->takeItem(cid,1);
- QTableWidgetItem *ce=twsf->takeItem(cid,0);
- twsf->removeRow(cid);
- twsf->insertRow(cid-1);
- twsf->setItem(cid-1,0,ce);
- twsf->setItem(cid-1,1,ci);
- twsf->setCurrentCell(cid-1,1);
- });
- connect(pbsfmdn,&QPushButton::clicked,[twsf]{
- int cid=twsf->currentRow();if(cid==twsf->rowCount()-1)return;
- QTableWidgetItem *ci=twsf->takeItem(cid,1);
- QTableWidgetItem *ce=twsf->takeItem(cid,0);
- twsf->removeRow(cid);
- twsf->insertRow(cid+1);
- twsf->setItem(cid+1,0,ce);
- twsf->setItem(cid+1,1,ci);
- twsf->setCurrentCell(cid+1,1);
- });
+ connect(pbsfadd, &QPushButton::clicked, [twsf, this]
+ {
+ QStringList sl = QFileDialog::getOpenFileNames(this, "Add File", "", "SoundFont files (*.sf2)");
+ for (int i = 0; i < sl.size(); ++i)
+ {
+ twsf->insertRow(twsf->rowCount());
+ QTableWidgetItem *sfn, *sfe;
+ twsf->setItem(twsf->rowCount() - 1, 1, sfn = new QTableWidgetItem(sl[i]));
+ twsf->setItem(twsf->rowCount() - 1, 0, sfe = new QTableWidgetItem());
+ sfe->setCheckState(Qt::CheckState::Unchecked);
+ sfn->setFlags(Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable);
+ sfe->setFlags(Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsUserCheckable);
+ }
+ });
+ connect(pbsfrem, &QPushButton::clicked, [twsf]
+ {
+ QList<QTableWidgetItem *> sl = twsf->selectedItems();
+ for (int i = 0; i < sl.size(); ++i)
+ twsf->removeRow(twsf->row(sl[i]));
+ });
+ connect(pbsfmup, &QPushButton::clicked, [twsf]
+ {
+ int cid = twsf->currentRow();
+ if (!cid)
+ return;
+ QTableWidgetItem *ci = twsf->takeItem(cid, 1);
+ QTableWidgetItem *ce = twsf->takeItem(cid, 0);
+ twsf->removeRow(cid);
+ twsf->insertRow(cid - 1);
+ twsf->setItem(cid - 1, 0, ce);
+ twsf->setItem(cid - 1, 1, ci);
+ twsf->setCurrentCell(cid - 1, 1);
+ });
+ connect(pbsfmdn, &QPushButton::clicked, [twsf]
+ {
+ int cid = twsf->currentRow(); if (cid == twsf->rowCount() - 1)
+ return;
+ QTableWidgetItem *ci = twsf->takeItem(cid, 1);
+ QTableWidgetItem *ce = twsf->takeItem(cid, 0);
+ twsf->removeRow(cid);
+ twsf->insertRow(cid + 1);
+ twsf->setItem(cid + 1, 0, ce);
+ twsf->setItem(cid + 1, 1, ci);
+ twsf->setCurrentCell(cid + 1, 1);
+ });
- QVariant sf_def_val=QList<QVariant>();
- auto save_func=[twsf]()->void*{
- QList<QVariant> sflist;
- for(int i=0;i<twsf->rowCount();++i)
- {
- QString sfs=twsf->item(i,1)->text();
- if(twsf->item(i,0)->checkState()==Qt::CheckState::Unchecked)
- sfs="#"+sfs;
- sflist.push_back(sfs);
- }
- return new QVariant(sflist);
- };
- auto load_func=[twsf](void* data){
- QList<QVariant> sflist=static_cast<QVariant*>(data)->toList();
- twsf->clearContents();
- twsf->setRowCount(0);
- for(int i=0;i<sflist.size();++i)
- {
- twsf->insertRow(i);
- QTableWidgetItem *sfn,*sfe;
- QString sf=sflist[i].toString();
- bool enabled=!sf.startsWith('#');
- if(!enabled)sf=sf.mid(1);
- twsf->setItem(i,1,sfn=new QTableWidgetItem(sf));
- twsf->setItem(i,0,sfe=new QTableWidgetItem());
- sfn->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable);
- sfe->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable|Qt::ItemFlag::ItemIsUserCheckable);
- sfe->setCheckState(enabled?Qt::CheckState::Checked:Qt::CheckState::Unchecked);
- }
- };
- settings->registerOptionCustom("SoundFonts","","FluidSynth/SoundFonts",sfpanel,&sf_def_val,save_func,load_func);
+ QVariant sf_def_val = QList<QVariant>();
+ auto save_func = [twsf]()->void *
+ {
+ QList<QVariant> sflist;
+ for (int i = 0; i < twsf->rowCount(); ++i)
+ {
+ QString sfs = twsf->item(i, 1)->text();
+ if (twsf->item(i, 0)->checkState() == Qt::CheckState::Unchecked)
+ sfs = "#" + sfs;
+ sflist.push_back(sfs);
+ }
+ return new QVariant(sflist);
+ };
+ auto load_func = [twsf](void *data)
+ {
+ QList<QVariant> sflist = static_cast<QVariant *>(data)->toList();
+ twsf->clearContents();
+ twsf->setRowCount(0);
+ for (int i = 0; i < sflist.size(); ++i)
+ {
+ twsf->insertRow(i);
+ QTableWidgetItem *sfn, *sfe;
+ QString sf = sflist[i].toString();
+ bool enabled = !sf.startsWith('#');
+ if (!enabled)
+ sf = sf.mid(1);
+ twsf->setItem(i, 1, sfn = new QTableWidgetItem(sf));
+ twsf->setItem(i, 0, sfe = new QTableWidgetItem());
+ sfn->setFlags(Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable);
+ sfe->setFlags(Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsUserCheckable);
+ sfe->setCheckState(enabled ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
+ }
+ };
+ settings->registerOptionCustom("SoundFonts", "", "FluidSynth/SoundFonts", sfpanel, &sf_def_val, save_func, load_func);
}
void qmpSettingsWindow::registerPluginOption(qmpPluginManager *pmgr)
{
- QTableWidget *twplugins=new QTableWidget();
- twplugins->setColumnCount(4);
- twplugins->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);
- twplugins->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
- twplugins->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows);
- twplugins->setHorizontalHeaderLabels({tr("E"),tr("Plugin Name"),tr("Version"),tr("Path")});
- twplugins->setHorizontalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
- twplugins->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
- QVariant ep_def_val=QList<QVariant>();
- auto save_func=[twplugins,this]()->void*{
- QVariant *data=static_cast<QVariant*>(settings->getOptionCustom("DisabledPlugins"));
- QList<QVariant> disabled_plugins_ol=static_cast<QVariant*>(data)->toList();
- delete data;
- std::set<std::string> disabled_plugins_s;
- for(auto &i:disabled_plugins_ol)
- disabled_plugins_s.insert(i.toString().toStdString());
- for(int i=0;i<twplugins->rowCount();++i)
- {
- QString pn=twplugins->item(i,1)->text();
- if(twplugins->item(i,0)->checkState()==Qt::CheckState::Unchecked)
- disabled_plugins_s.insert(pn.toStdString());
- else
- disabled_plugins_s.erase(pn.toStdString());
- }
- QList<QVariant> disabled_plugins;
- for(auto &i:disabled_plugins_s)
- disabled_plugins.push_back(QString(i.c_str()));
- return new QVariant(disabled_plugins);
- };
- auto load_func=[twplugins,pmgr](void* data){
- QList<QVariant> disabled_plugins_l=static_cast<QVariant*>(data)->toList();
- std::set<std::string> disabled_plugins;
- for(auto i:disabled_plugins_l)
- disabled_plugins.insert(i.toString().toStdString());
+ QTableWidget *twplugins = new QTableWidget();
+ twplugins->setColumnCount(4);
+ twplugins->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);
+ twplugins->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
+ twplugins->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows);
+ twplugins->setHorizontalHeaderLabels({tr("E"), tr("Plugin Name"), tr("Version"), tr("Path")});
+ twplugins->setHorizontalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
+ twplugins->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
+ QVariant ep_def_val = QList<QVariant>();
+ auto save_func = [twplugins, this]()->void *
+ {
+ QVariant *data = static_cast<QVariant *>(settings->getOptionCustom("DisabledPlugins"));
+ QList<QVariant> disabled_plugins_ol = static_cast<QVariant *>(data)->toList();
+ delete data;
+ std::set<std::string> disabled_plugins_s;
+ for (auto &i : disabled_plugins_ol)
+ disabled_plugins_s.insert(i.toString().toStdString());
+ for (int i = 0; i < twplugins->rowCount(); ++i)
+ {
+ QString pn = twplugins->item(i, 1)->text();
+ if (twplugins->item(i, 0)->checkState() == Qt::CheckState::Unchecked)
+ disabled_plugins_s.insert(pn.toStdString());
+ else
+ disabled_plugins_s.erase(pn.toStdString());
+ }
+ QList<QVariant> disabled_plugins;
+ for (auto &i : disabled_plugins_s)
+ disabled_plugins.push_back(QString(i.c_str()));
+ return new QVariant(disabled_plugins);
+ };
+ auto load_func = [twplugins, pmgr](void *data)
+ {
+ QList<QVariant> disabled_plugins_l = static_cast<QVariant *>(data)->toList();
+ std::set<std::string> disabled_plugins;
+ for (auto i : disabled_plugins_l)
+ disabled_plugins.insert(i.toString().toStdString());
- twplugins->clearContents();
- twplugins->setRowCount(0);
+ twplugins->clearContents();
+ twplugins->setRowCount(0);
- std::vector<qmpPlugin> *plugins=pmgr->getPlugins();
- for(int i=0;static_cast<size_t>(i)<plugins->size();++i)
- {
- twplugins->insertRow(i);
- qmpPlugin &p=plugins->at(static_cast<size_t>(i));
- QTableWidgetItem *icb;
- twplugins->setItem(i,0,icb=new QTableWidgetItem());
- bool enabled=disabled_plugins.find(p.name)==disabled_plugins.end();
- icb->setCheckState(enabled?Qt::CheckState::Checked:Qt::CheckState::Unchecked);
- icb->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable|Qt::ItemFlag::ItemIsUserCheckable);
- twplugins->setItem(i,1,new QTableWidgetItem(p.name.c_str()));
- twplugins->setItem(i,2,new QTableWidgetItem(p.version.c_str()));
- twplugins->setItem(i,3,new QTableWidgetItem(p.path.c_str()));
- for(int j=1;j<=3;++j)
- twplugins->item(i,j)->setFlags(Qt::ItemFlag::ItemIsEnabled|Qt::ItemFlag::ItemIsSelectable);
- }
- };
- settings->registerOptionCustom("Plugins","","DisabledPlugins",twplugins,&ep_def_val,save_func,load_func);
+ std::vector<qmpPlugin> *plugins = pmgr->getPlugins();
+ for (int i = 0; static_cast<size_t>(i) < plugins->size(); ++i)
+ {
+ twplugins->insertRow(i);
+ qmpPlugin &p = plugins->at(static_cast<size_t>(i));
+ QTableWidgetItem *icb;
+ twplugins->setItem(i, 0, icb = new QTableWidgetItem());
+ bool enabled = disabled_plugins.find(p.name) == disabled_plugins.end();
+ icb->setCheckState(enabled ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
+ icb->setFlags(Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsUserCheckable);
+ twplugins->setItem(i, 1, new QTableWidgetItem(p.name.c_str()));
+ twplugins->setItem(i, 2, new QTableWidgetItem(p.version.c_str()));
+ twplugins->setItem(i, 3, new QTableWidgetItem(p.path.c_str()));
+ for (int j = 1; j <= 3; ++j)
+ twplugins->item(i, j)->setFlags(Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable);
+ }
+ };
+ settings->registerOptionCustom("Plugins", "", "DisabledPlugins", twplugins, &ep_def_val, save_func, load_func);
}
void qmpSettingsWindow::registerExtraMidiOptions()
{
- QPushButton *pbDevPrio=new QPushButton("...");
- connect(pbDevPrio,&QPushButton::clicked,[this]{loadOption("Midi/DevicePriority");devpriod->show();});
- connect(devpriod,&QDialog::accepted,[this]{saveOption("Midi/DevicePriority");});
- connect(devpriod,&QDialog::rejected,[this]{loadOption("Midi/DevicePriority");});
- QVariant devprio_def_val=QList<QVariant>({"Internal FluidSynth"});
- settings->registerOptionCustom("MIDI","Select MIDI output devices","Midi/DevicePriority",pbDevPrio,&devprio_def_val,std::bind(&qmpDevicePriorityDialog::save,devpriod),std::bind(&qmpDevicePriorityDialog::load,devpriod,std::placeholders::_1));
+ QPushButton *pbDevPrio = new QPushButton("...");
+ connect(pbDevPrio, &QPushButton::clicked, [this] {loadOption("Midi/DevicePriority"); devpriod->show();});
+ connect(devpriod, &QDialog::accepted, [this] {saveOption("Midi/DevicePriority");});
+ connect(devpriod, &QDialog::rejected, [this] {loadOption("Midi/DevicePriority");});
+ QVariant devprio_def_val = QList<QVariant>({"Internal FluidSynth"});
+ settings->registerOptionCustom("MIDI", "Select MIDI output devices", "Midi/DevicePriority", pbDevPrio, &devprio_def_val, std::bind(&qmpDevicePriorityDialog::save, devpriod), std::bind(&qmpDevicePriorityDialog::load, devpriod, std::placeholders::_1));
- QPushButton *pbDevProp=new QPushButton("...");
- connect(pbDevProp,&QPushButton::clicked,[this]{loadOption("Midi/DeviceInitializationFiles");dps->show();});
- connect(dps,&QDialog::accepted,[this]{saveOption("Midi/DeviceInitializationFiles");});
- connect(dps,&QDialog::rejected,[this]{loadOption("Midi/DeviceInitializationFiles");});
- QVariant devprop_def_val=QList<QVariant>({});
- settings->registerOptionCustom("MIDI","External MIDI device setup","Midi/DeviceInitializationFiles",pbDevProp,&devprop_def_val,std::bind(&qmpDevPropDialog::save,dps),std::bind(&qmpDevPropDialog::load,dps,std::placeholders::_1));
+ QPushButton *pbDevProp = new QPushButton("...");
+ connect(pbDevProp, &QPushButton::clicked, [this] {loadOption("Midi/DeviceInitializationFiles"); dps->show();});
+ connect(dps, &QDialog::accepted, [this] {saveOption("Midi/DeviceInitializationFiles");});
+ connect(dps, &QDialog::rejected, [this] {loadOption("Midi/DeviceInitializationFiles");});
+ QVariant devprop_def_val = QList<QVariant>({});
+ settings->registerOptionCustom("MIDI", "External MIDI device setup", "Midi/DeviceInitializationFiles", pbDevProp, &devprop_def_val, std::bind(&qmpDevPropDialog::save, dps), std::bind(&qmpDevPropDialog::load, dps, std::placeholders::_1));
}
void qmpSettingsWindow::saveOption(std::string key)
{
- auto save_opt=[this](std::string& key)->QVariant
- {
- qmpOption &o=settings->options[key];
- QVariant ret;
- switch(o.type)
- {
- case qmpOption::ParameterType::parameter_int:
- {
- QSpinBox *sb=qobject_cast<QSpinBox*>(o.widget);
- if(sb)
- ret=sb->value();
- }
- break;
- case qmpOption::ParameterType::parameter_uint:
- {
- QHexSpinBox *sb=qobject_cast<QHexSpinBox*>(o.widget);
- if(sb)
- {
- int val=sb->value();
- ret=reinterpret_cast<unsigned&>(val);
- }
- }
- break;
- case qmpOption::ParameterType::parameter_bool:
- {
- QCheckBox *cb=qobject_cast<QCheckBox*>(o.widget);
- if(cb)
- ret=cb->isChecked();
- }
- break;
- case qmpOption::ParameterType::parameter_double:
- {
- QDoubleSpinBox *sb=qobject_cast<QDoubleSpinBox*>(o.widget);
- if(sb)
- ret=sb->value();
- }
- break;
- case qmpOption::ParameterType::parameter_str:
- {
- QLineEdit *le=qobject_cast<QLineEdit*>(o.widget);
- if(le)
- ret=le->text();
- }
- break;
- case qmpOption::ParameterType::parameter_enum:
- {
- QComboBox *cb=qobject_cast<QComboBox*>(o.widget);
- if(cb)
- ret=cb->currentText();
- }
- break;
- case qmpOption::ParameterType::parameter_url:
- {
- QFileEdit *fe=qobject_cast<QFileEdit*>(o.widget);
- if(fe)
- ret=fe->text();
- }
- break;
- default:
- if(o.save_func)
- {
- QVariant* var=static_cast<QVariant*>(o.save_func());
- ret=QVariant(*var);
- delete var;
- }
- break;
- }
- return ret;
- };
- if(key.length())
- {
- QVariant r=save_opt(key);
- if(r.isValid())
- settings->settings->setValue(QString(key.c_str()),r);
- }
- else for(std::string& key:settings->optionlist)
- {
- QVariant r=save_opt(key);
- if(r.isValid())
- settings->settings->setValue(QString(key.c_str()),r);
- }
- settings->settings->sync();
+ auto save_opt = [this](std::string & key)->QVariant
+ {
+ qmpOption &o = settings->options[key];
+ QVariant ret;
+ switch (o.type)
+ {
+ case qmpOption::ParameterType::parameter_int:
+ {
+ QSpinBox *sb = qobject_cast<QSpinBox *>(o.widget);
+ if (sb)
+ ret = sb->value();
+ }
+ break;
+ case qmpOption::ParameterType::parameter_uint:
+ {
+ QHexSpinBox *sb = qobject_cast<QHexSpinBox *>(o.widget);
+ if (sb)
+ {
+ int val = sb->value();
+ ret = reinterpret_cast<unsigned &>(val);
+ }
+ }
+ break;
+ case qmpOption::ParameterType::parameter_bool:
+ {
+ QCheckBox *cb = qobject_cast<QCheckBox *>(o.widget);
+ if (cb)
+ ret = cb->isChecked();
+ }
+ break;
+ case qmpOption::ParameterType::parameter_double:
+ {
+ QDoubleSpinBox *sb = qobject_cast<QDoubleSpinBox *>(o.widget);
+ if (sb)
+ ret = sb->value();
+ }
+ break;
+ case qmpOption::ParameterType::parameter_str:
+ {
+ QLineEdit *le = qobject_cast<QLineEdit *>(o.widget);
+ if (le)
+ ret = le->text();
+ }
+ break;
+ case qmpOption::ParameterType::parameter_enum:
+ {
+ QComboBox *cb = qobject_cast<QComboBox *>(o.widget);
+ if (cb)
+ ret = cb->currentText();
+ }
+ break;
+ case qmpOption::ParameterType::parameter_url:
+ {
+ QFileEdit *fe = qobject_cast<QFileEdit *>(o.widget);
+ if (fe)
+ ret = fe->text();
+ }
+ break;
+ default:
+ if (o.save_func)
+ {
+ QVariant *var = static_cast<QVariant *>(o.save_func());
+ ret = QVariant(*var);
+ delete var;
+ }
+ break;
+ }
+ return ret;
+ };
+ if (key.length())
+ {
+ QVariant r = save_opt(key);
+ if (r.isValid())
+ settings->settings->setValue(QString(key.c_str()), r);
+ }
+ else for (std::string &key : settings->optionlist)
+ {
+ QVariant r = save_opt(key);
+ if (r.isValid())
+ settings->settings->setValue(QString(key.c_str()), r);
+ }
+ settings->settings->sync();
}
void qmpSettingsWindow::loadOption(std::string key)
{
- auto load_opt=[this](std::string& key)
- {
- qmpOption &o=settings->options[key];
- switch(o.type)
- {
- case qmpOption::ParameterType::parameter_int:
- {
- QSpinBox *sb=qobject_cast<QSpinBox*>(o.widget);
- if(sb)
- sb->setValue(settings->getOptionInt(key));
- }
- break;
- case qmpOption::ParameterType::parameter_uint:
- {
- QHexSpinBox *sb=qobject_cast<QHexSpinBox*>(o.widget);
- if(sb)
- sb->setValue(settings->getOptionUint(key));
- }
- break;
- case qmpOption::ParameterType::parameter_bool:
- {
- QCheckBox *cb=qobject_cast<QCheckBox*>(o.widget);
- if(cb)
- cb->setChecked(settings->getOptionBool(key));
- }
- break;
- case qmpOption::ParameterType::parameter_double:
- {
- QDoubleSpinBox *sb=qobject_cast<QDoubleSpinBox*>(o.widget);
- if(sb)
- sb->setValue(settings->getOptionDouble(key));
- }
- break;
- case qmpOption::ParameterType::parameter_str:
- {
- QLineEdit *le=qobject_cast<QLineEdit*>(o.widget);
- if(le)
- le->setText(QString(settings->getOptionString(key).c_str()));
- }
- break;
- case qmpOption::ParameterType::parameter_enum:
- {
- QComboBox *cb=qobject_cast<QComboBox*>(o.widget);
- if(cb)
- cb->setCurrentIndex(settings->getOptionEnumInt(key));
- }
- break;
- case qmpOption::ParameterType::parameter_url:
- {
- QFileEdit *fe=qobject_cast<QFileEdit*>(o.widget);
- if(fe)
- fe->setText(QString(settings->getOptionString(key).c_str()));
- }
- break;
- default:
- if(o.load_func)
- {
- void *var=settings->getOptionCustom(key);
- o.load_func(var);
- delete static_cast<QVariant*>(var);
- }
- break;
- }
- };
- if(key.length())load_opt(key);
- else for(std::string& key:settings->optionlist)
- load_opt(key);
+ auto load_opt = [this](std::string & key)
+ {
+ qmpOption &o = settings->options[key];
+ switch (o.type)
+ {
+ case qmpOption::ParameterType::parameter_int:
+ {
+ QSpinBox *sb = qobject_cast<QSpinBox *>(o.widget);
+ if (sb)
+ sb->setValue(settings->getOptionInt(key));
+ }
+ break;
+ case qmpOption::ParameterType::parameter_uint:
+ {
+ QHexSpinBox *sb = qobject_cast<QHexSpinBox *>(o.widget);
+ if (sb)
+ sb->setValue(settings->getOptionUint(key));
+ }
+ break;
+ case qmpOption::ParameterType::parameter_bool:
+ {
+ QCheckBox *cb = qobject_cast<QCheckBox *>(o.widget);
+ if (cb)
+ cb->setChecked(settings->getOptionBool(key));
+ }
+ break;
+ case qmpOption::ParameterType::parameter_double:
+ {
+ QDoubleSpinBox *sb = qobject_cast<QDoubleSpinBox *>(o.widget);
+ if (sb)
+ sb->setValue(settings->getOptionDouble(key));
+ }
+ break;
+ case qmpOption::ParameterType::parameter_str:
+ {
+ QLineEdit *le = qobject_cast<QLineEdit *>(o.widget);
+ if (le)
+ le->setText(QString(settings->getOptionString(key).c_str()));
+ }
+ break;
+ case qmpOption::ParameterType::parameter_enum:
+ {
+ QComboBox *cb = qobject_cast<QComboBox *>(o.widget);
+ if (cb)
+ cb->setCurrentIndex(settings->getOptionEnumInt(key));
+ }
+ break;
+ case qmpOption::ParameterType::parameter_url:
+ {
+ QFileEdit *fe = qobject_cast<QFileEdit *>(o.widget);
+ if (fe)
+ fe->setText(QString(settings->getOptionString(key).c_str()));
+ }
+ break;
+ default:
+ if (o.load_func)
+ {
+ void *var = settings->getOptionCustom(key);
+ o.load_func(var);
+ delete static_cast<QVariant *>(var);
+ }
+ break;
+ }
+ };
+ if (key.length())
+ load_opt(key);
+ else for (std::string &key : settings->optionlist)
+ load_opt(key);
}
void qmpSettingsWindow::setupWidgets()
{
- for(std::string& key:settings->optionlist)
- {
- if(!settings->options[key].desc.length()&&settings->options[key].type!=qmpOption::ParameterType::parameter_custom)
- continue;
- QWidget *optw=nullptr;
- qmpOption &o=settings->options[key];
- switch(o.type)
- {
- case qmpOption::ParameterType::parameter_int:
- {
- QSpinBox *sb=new QSpinBox;
- sb->setMinimum(o.minv.toInt());
- sb->setMaximum(o.maxv.toInt());
- sb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);
- optw=sb;
- }
- break;
- case qmpOption::ParameterType::parameter_uint:
- {
- QHexSpinBox *sb=new QHexSpinBox;
- sb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);
- optw=sb;
- }
- break;
- case qmpOption::ParameterType::parameter_bool:
- {
- QCheckBox *cb=new QCheckBox(QString(o.desc.c_str()));
- cb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
- optw=cb;
- }
- break;
- case qmpOption::ParameterType::parameter_double:
- {
- QDoubleSpinBox *sb=new QDoubleSpinBox;
- sb->setMinimum(o.minv.toDouble());
- sb->setMaximum(o.maxv.toDouble());
- sb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);
- optw=sb;
- }
- break;
- case qmpOption::ParameterType::parameter_str:
- {
- QLineEdit* te=new QLineEdit();
- te->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);
- optw=te;
- }
- break;
- case qmpOption::ParameterType::parameter_enum:
- {
- QComboBox* cb=new QComboBox();
- for(std::string& item:o.enumlist)cb->addItem(QString(item.c_str()));
- cb->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);
- optw=cb;
- }
- break;
- case qmpOption::ParameterType::parameter_url:
- {
- QFileEdit* fe=new QFileEdit();
- fe->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);
- optw=fe;
- }
- break;
- default:
- optw=o.widget;
- break;
- }
- o.widget=optw;
- QGridLayout* page=pageForTab(o.tab);
- if(o.type==qmpOption::ParameterType::parameter_bool||
- (o.type==qmpOption::parameter_custom&&!o.desc.length()))
- {
- int row=page->rowCount();
- page->addWidget(o.widget,row,0,1,2);
- }
- else
- {
- QLabel* lb=new QLabel(o.desc.c_str(),page->parentWidget());
- lb->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
- int row=page->rowCount();
- page->addWidget(lb,row,0);
- page->addWidget(o.widget,row,1);
- }
- }
- loadOption();
+ for (std::string &key : settings->optionlist)
+ {
+ if (!settings->options[key].desc.length() && settings->options[key].type != qmpOption::ParameterType::parameter_custom)
+ continue;
+ QWidget *optw = nullptr;
+ qmpOption &o = settings->options[key];
+ switch (o.type)
+ {
+ case qmpOption::ParameterType::parameter_int:
+ {
+ QSpinBox *sb = new QSpinBox;
+ sb->setMinimum(o.minv.toInt());
+ sb->setMaximum(o.maxv.toInt());
+ sb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ optw = sb;
+ }
+ break;
+ case qmpOption::ParameterType::parameter_uint:
+ {
+ QHexSpinBox *sb = new QHexSpinBox;
+ sb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ optw = sb;
+ }
+ break;
+ case qmpOption::ParameterType::parameter_bool:
+ {
+ QCheckBox *cb = new QCheckBox(QString(o.desc.c_str()));
+ cb->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ optw = cb;
+ }
+ break;
+ case qmpOption::ParameterType::parameter_double:
+ {
+ QDoubleSpinBox *sb = new QDoubleSpinBox;
+ sb->setMinimum(o.minv.toDouble());
+ sb->setMaximum(o.maxv.toDouble());
+ sb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ optw = sb;
+ }
+ break;
+ case qmpOption::ParameterType::parameter_str:
+ {
+ QLineEdit *te = new QLineEdit();
+ te->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ optw = te;
+ }
+ break;
+ case qmpOption::ParameterType::parameter_enum:
+ {
+ QComboBox *cb = new QComboBox();
+ for (std::string &item : o.enumlist)
+ cb->addItem(QString(item.c_str()));
+ cb->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ optw = cb;
+ }
+ break;
+ case qmpOption::ParameterType::parameter_url:
+ {
+ QFileEdit *fe = new QFileEdit();
+ fe->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ optw = fe;
+ }
+ break;
+ default:
+ optw = o.widget;
+ break;
+ }
+ o.widget = optw;
+ QGridLayout *page = pageForTab(o.tab);
+ if (o.type == qmpOption::ParameterType::parameter_bool ||
+ (o.type == qmpOption::parameter_custom && !o.desc.length()))
+ {
+ int row = page->rowCount();
+ page->addWidget(o.widget, row, 0, 1, 2);
+ }
+ else
+ {
+ QLabel *lb = new QLabel(o.desc.c_str(), page->parentWidget());
+ lb->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ int row = page->rowCount();
+ page->addWidget(lb, row, 0);
+ page->addWidget(o.widget, row, 1);
+ }
+ }
+ loadOption();
}
-QGridLayout* qmpSettingsWindow::pageForTab(std::string tab)
+QGridLayout *qmpSettingsWindow::pageForTab(std::string tab)
{
- if(customOptPages.find(tab)!=customOptPages.end())
- return customOptPages[tab];
- QWidget* w=new QWidget;
- QGridLayout* page=new QGridLayout(w);
- w->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
- ui->tabWidget->addTab(w,QString(tab.c_str()));
- customOptPages[tab]=page;
- return page;
+ if (customOptPages.find(tab) != customOptPages.end())
+ return customOptPages[tab];
+ QWidget *w = new QWidget;
+ QGridLayout *page = new QGridLayout(w);
+ w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ ui->tabWidget->addTab(w, QString(tab.c_str()));
+ customOptPages[tab] = page;
+ return page;
}
-QFileEdit::QFileEdit(QWidget *par):QWidget(par)
+QFileEdit::QFileEdit(QWidget *par): QWidget(par)
{
- QHBoxLayout *layout=new QHBoxLayout(this);
- layout->setMargin(0);
- le=new QLineEdit(this);
- layout->addWidget(le);
- tb=new QToolButton(this);
- tb->setText("...");
- layout->addWidget(tb);
- connect(tb,&QToolButton::clicked,this,&QFileEdit::chooseFile);
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->setMargin(0);
+ le = new QLineEdit(this);
+ layout->addWidget(le);
+ tb = new QToolButton(this);
+ tb->setText("...");
+ layout->addWidget(tb);
+ connect(tb, &QToolButton::clicked, this, &QFileEdit::chooseFile);
+}
+QString QFileEdit::text()
+{
+ return le->text();
+}
+void QFileEdit::setText(const QString &s)
+{
+ le->setText(s);
}
-QString QFileEdit::text(){return le->text();}
-void QFileEdit::setText(const QString& s){le->setText(s);}
void QFileEdit::chooseFile()
{
- QString s=QFileDialog::getOpenFileName(nullptr,tr("Select a file"),QFileInfo(text()).dir().absolutePath());
- if(s.length())setText(s);
+ QString s = QFileDialog::getOpenFileName(nullptr, tr("Select a file"), QFileInfo(text()).dir().absolutePath());
+ if (s.length())
+ setText(s);
}
diff --git a/qmidiplayer-desktop/qmpsettingswindow.hpp b/qmidiplayer-desktop/qmpsettingswindow.hpp
index 5243ca9..c564c01 100644
--- a/qmidiplayer-desktop/qmpsettingswindow.hpp
+++ b/qmidiplayer-desktop/qmpsettingswindow.hpp
@@ -17,98 +17,108 @@
#include "qmpcustomizewindow.hpp"
#include "qmpdevpropdialog.hpp"
-namespace Ui {
- class qmpSettingsWindow;
+namespace Ui
+{
+class qmpSettingsWindow;
}
class QLineEdit;
class QToolButton;
-class QFileEdit:public QWidget
+class QFileEdit : public QWidget
{
- Q_OBJECT
- private:
- QLineEdit *le;
- QToolButton *tb;
- private slots:
- void chooseFile();
- public:
- QFileEdit(QWidget* par=nullptr);
- QString text();
- void setText(const QString& s);
+ Q_OBJECT
+private:
+ QLineEdit *le;
+ QToolButton *tb;
+private slots:
+ void chooseFile();
+public:
+ QFileEdit(QWidget *par = nullptr);
+ QString text();
+ void setText(const QString &s);
};
-class QHexSpinBox:public QSpinBox
+class QHexSpinBox: public QSpinBox
{
- Q_OBJECT
- public:
- QHexSpinBox(QWidget *parent=0):QSpinBox(parent)
- {
- setPrefix("0x");
- setDisplayIntegerBase(16);
- setRange(-0x80000000,0x7FFFFFFF);
- }
- protected:
- QString textFromValue(int value)const
- {
- return QString::number(u(value),16).toUpper();
- }
- int valueFromText(const QString &text)const
- {
- return i(text.toUInt(nullptr,16));
- }
- QValidator::State validate(QString &input,int &pos)const
- {
- QString t=input;
- if(t.startsWith("0x"))t.remove(0,2);
- pos-=t.size()-t.trimmed().size();t=t.trimmed();
- if(t.isEmpty())return QValidator::Intermediate;
- input=QString("0x")+t.toUpper();
- bool okay;t.toUInt(&okay,16);
- if(!okay)return QValidator::Invalid;
- return QValidator::Acceptable;
- }
- inline unsigned int u(int i)const
- {return reinterpret_cast<unsigned&>(i);}
- inline int i(unsigned int u)const
- {return reinterpret_cast<int&>(u);}
+ Q_OBJECT
+public:
+ QHexSpinBox(QWidget *parent = nullptr) : QSpinBox(parent)
+ {
+ setPrefix("0x");
+ setDisplayIntegerBase(16);
+ setRange(-0x80000000, 0x7FFFFFFF);
+ }
+protected:
+ QString textFromValue(int value)const
+ {
+ return QString::number(u(value), 16).toUpper();
+ }
+ int valueFromText(const QString &text)const
+ {
+ return i(text.toUInt(nullptr, 16));
+ }
+ QValidator::State validate(QString &input, int &pos)const
+ {
+ QString t = input;
+ if (t.startsWith("0x"))
+ t.remove(0, 2);
+ pos -= t.size() - t.trimmed().size();
+ t = t.trimmed();
+ if (t.isEmpty())
+ return QValidator::Intermediate;
+ input = QString("0x") + t.toUpper();
+ bool okay;
+ t.toUInt(&okay, 16);
+ if (!okay)
+ return QValidator::Invalid;
+ return QValidator::Acceptable;
+ }
+ inline unsigned int u(int i)const
+ {
+ return reinterpret_cast<unsigned &>(i);
+ }
+ inline int i(unsigned int u)const
+ {
+ return reinterpret_cast<int &>(u);
+ }
};
class qmpDevicePriorityDialog;
-class qmpSettingsWindow:public QDialog
+class qmpSettingsWindow : public QDialog
{
- Q_OBJECT
+ Q_OBJECT
- public:
- explicit qmpSettingsWindow(qmpSettings *qmpsettings,QWidget *parent=nullptr);
- ~qmpSettingsWindow();
- void closeEvent(QCloseEvent *event);
- void hideEvent(QHideEvent *event);
- void updatePluginList(qmpPluginManager *pmgr);
- void postInit();
- void registerCustomizeWidgetOptions();
- void registerSoundFontOption();
- void registerPluginOption(qmpPluginManager *pmgr);
- void registerExtraMidiOptions();
- signals:
- void dialogClosing();
+public:
+ explicit qmpSettingsWindow(qmpSettings *qmpsettings, QWidget *parent = nullptr);
+ ~qmpSettingsWindow();
+ void closeEvent(QCloseEvent *event);
+ void hideEvent(QHideEvent *event);
+ void updatePluginList(qmpPluginManager *pmgr);
+ void postInit();
+ void registerCustomizeWidgetOptions();
+ void registerSoundFontOption();
+ void registerPluginOption(qmpPluginManager *pmgr);
+ void registerExtraMidiOptions();
+signals:
+ void dialogClosing();
- private slots:
- void on_buttonBox_accepted();
- void on_buttonBox_rejected();
+private slots:
+ void on_buttonBox_accepted();
+ void on_buttonBox_rejected();
- private:
- Ui::qmpSettingsWindow *ui;
- std::map<std::string,qmpOption> customOptions;
- std::map<std::string,QGridLayout*> customOptPages;
- void saveOption(std::string key=std::string());
- void loadOption(std::string key=std::string());
- void setupWidgets();
- QGridLayout* pageForTab(std::string tab);
- qmpCustomizeWindow *cwt,*cwa;
- qmpDevPropDialog *dps;
- qmpDevicePriorityDialog *devpriod;
- qmpSettings *settings;
+private:
+ Ui::qmpSettingsWindow *ui;
+ std::map<std::string, qmpOption> customOptions;
+ std::map<std::string, QGridLayout *> customOptPages;
+ void saveOption(std::string key = std::string());
+ void loadOption(std::string key = std::string());
+ void setupWidgets();
+ QGridLayout *pageForTab(std::string tab);
+ qmpCustomizeWindow *cwt, *cwa;
+ qmpDevPropDialog *dps;
+ qmpDevicePriorityDialog *devpriod;
+ qmpSettings *settings;
};
#endif // QMPSETTINGSWINDOW_H
diff --git a/qmidiplayer-lite/main.cpp b/qmidiplayer-lite/main.cpp
index 1a87b33..f0f9af6 100644
--- a/qmidiplayer-lite/main.cpp
+++ b/qmidiplayer-lite/main.cpp
@@ -5,11 +5,11 @@
int main(int argc, char *argv[])
{
- QApplication app(argc, argv);
- qmlRegisterType<CQMPCoreWrapper>("org.chrisoft.qmpcore",1,0,"CQMPCoreWrapper");
+ QApplication app(argc, argv);
+ qmlRegisterType<CQMPCoreWrapper>("org.chrisoft.qmpcore", 1, 0, "CQMPCoreWrapper");
- QQmlApplicationEngine engine;
- engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
- return app.exec();
+ return app.exec();
}
diff --git a/qmidiplayer-lite/qmpcorewrapper.hpp b/qmidiplayer-lite/qmpcorewrapper.hpp
index 090edc7..07dff65 100644
--- a/qmidiplayer-lite/qmpcorewrapper.hpp
+++ b/qmidiplayer-lite/qmpcorewrapper.hpp
@@ -5,56 +5,66 @@
#include <thread>
#include <fluidsynth.h>
#include "../core/qmpmidiplay.hpp"
-class CQMPCoreWrapper:public QObject
+class CQMPCoreWrapper: public QObject
{
- Q_OBJECT
+ Q_OBJECT
private:
- CMidiPlayer *mp;
- std::thread *playerTh;
- int curprog;
+ CMidiPlayer *mp;
+ std::thread *playerTh;
+ int curprog;
public:
- explicit CQMPCoreWrapper(QObject* parent=0):QObject(parent)
- {
- mp=new CMidiPlayer();
- }
- ~CQMPCoreWrapper(){delete mp;}
- Q_INVOKABLE void initFluidSynth(QUrl sfpath)
- {
- mp->fluid()->setOptStr("audio.driver","pulseaudio");
- mp->fluid()->deviceInit();
- mp->fluid()->loadSFont(sfpath.toLocalFile().toStdString().c_str());
- for(int i=0;i<16;++i)
- mp->setChannelOutput(i,0);
- }
- Q_INVOKABLE void deinitFluidSynth()
- {
- mp->fluid()->deviceDeinit();
- }
- 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;
- mp->playerPanic();
- }
- 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;
- }
+ explicit CQMPCoreWrapper(QObject *parent = 0): QObject(parent)
+ {
+ mp = new CMidiPlayer();
+ }
+ ~CQMPCoreWrapper()
+ {
+ delete mp;
+ }
+ Q_INVOKABLE void initFluidSynth(QUrl sfpath)
+ {
+ mp->fluid()->setOptStr("audio.driver", "pulseaudio");
+ mp->fluid()->deviceInit();
+ mp->fluid()->loadSFont(sfpath.toLocalFile().toStdString().c_str());
+ for (int i = 0; i < 16; ++i)
+ mp->setChannelOutput(i, 0);
+ }
+ Q_INVOKABLE void deinitFluidSynth()
+ {
+ mp->fluid()->deviceDeinit();
+ }
+ 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;
+ mp->playerPanic();
+ }
+ 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/qmidiplayer-lite/qmpmidiplay.cpp b/qmidiplayer-lite/qmpmidiplay.cpp
index baec9a2..017de20 100644
--- a/qmidiplayer-lite/qmpmidiplay.cpp
+++ b/qmidiplayer-lite/qmpmidiplay.cpp
@@ -9,398 +9,531 @@ uint64_t pf;
#endif
void CMidiPlayer::fluidPreInitialize()
{
- settings=new_fluid_settings();
+ 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);
+ 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);
- }
- }
+ 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;
+ 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;
- }
+ 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;
- }
+ 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);
+ 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
+ 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));
+ w32usleep((midiFile->getEvent(tceptr)->time - ct) * (dpt / 1000));
#else
- std::this_thread::sleep_for(std::chrono::nanoseconds(midiFile->getEvent(tceptr)->time-ct)*dpt);
+ 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;
+ 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;
- }
+ 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();
- }
+ 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;
+ midiFile = NULL;
+ resumed = false;
+ singleInstance = singleInst;
+ settings = NULL;
+ synth = NULL;
+ adriver = NULL;
+ waitvoice = true;
#ifdef _WIN32
- QueryPerformanceFrequency((LARGE_INTEGER*)&pf);
- timeBeginPeriod(1);
+ QueryPerformanceFrequency((LARGE_INTEGER *)&pf);
+ timeBeginPeriod(1);
#endif
}
CMidiPlayer::~CMidiPlayer()
{
- if(singleInstance)fluidDeinitialize();
+ if (singleInstance)fluidDeinitialize();
#ifdef _WIN32
- timeEndPeriod(1);
+ 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);
+ 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)
+bool CMidiPlayer::playerLoadFile(const char *fn)
{
- midiFile=new CMidiFile(fn);
- if(!midiFile->isValid())return false;
- divs=midiFile->getDivision();
- fileTimer1Pass();
- fileTimer2Pass();
- return true;
+ 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();
+ 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();
+ tceptr = 0;
+ tcstop = 1;
+ tcpaused = 0;
+ delete midiFile;
+ midiFile = NULL;
+ if (!singleInstance)fluidDeinitialize();
}
void CMidiPlayer::playerThread()
{
- playEvents();
+ playEvents();
}
-void CMidiPlayer::rendererLoadFile(const char* ofn)
+void CMidiPlayer::rendererLoadFile(const char *ofn)
{
- settings=new_fluid_settings();
- fluid_settings_setstr(settings,"audio.file.name",ofn);
+ settings = new_fluid_settings();
+ fluid_settings_setstr(settings, "audio.file.name", ofn);
}
-void CMidiPlayer::rendererInit(const char* fn)
+void CMidiPlayer::rendererInit(const char *fn)
{
- finished=0;
- synth=new_fluid_synth(settings);
- player=new_fluid_player(synth);
- fluid_player_add(player,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;
+ 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;
+ 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::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)
+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);
+ 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)
+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);
+ 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);}
+{
+ 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;}
+{
+ 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);
+ 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)
+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);
+ 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)
+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);
+ 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)
+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);
+ 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;
}
-fluid_settings_t* CMidiPlayer::getFluidSettings(){return settings;}
void CMidiPlayer::pushSoundFont(const char *sf)
-{fluid_synth_sfload(synth,sf,1);}
+{
+ 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;}
+{
+ 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/qmidiplayer-lite/qmpmidiplay.hpp b/qmidiplayer-lite/qmpmidiplay.hpp
index fafd677..e2ef047 100644
--- a/qmidiplayer-lite/qmpmidiplay.hpp
+++ b/qmidiplayer-lite/qmpmidiplay.hpp
@@ -7,131 +7,144 @@
#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;
- }
+ 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;
+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();
+ 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;
+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 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();
+ 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);
+ //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();
+ 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 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);
+ 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);
+ fluid_settings_t *getFluidSettings();
+ void pushSoundFont(const char *sf);
+ int getSFCount();
+ fluid_sfont_t *getSFPtr(int sfid);
};
#endif
diff --git a/qmidiplayer-lite/qmpmidiread.cpp b/qmidiplayer-lite/qmpmidiread.cpp
index 0bcf597..227aa7d 100644
--- a/qmidiplayer-lite/qmpmidiread.cpp
+++ b/qmidiplayer-lite/qmpmidiread.cpp
@@ -8,233 +8,348 @@
#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;
+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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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.");
- }*/
+ 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 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;}
+ 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;}
+ 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;
+}
diff --git a/sample-plugin/sampleplugin.cpp b/sample-plugin/sampleplugin.cpp
index baf2786..6ca9b3e 100644
--- a/sample-plugin/sampleplugin.cpp
+++ b/sample-plugin/sampleplugin.cpp
@@ -1,11 +1,27 @@
#include <cstdio>
#include "sampleplugin.hpp"
-qmpSamplePlugin::qmpSamplePlugin(qmpPluginAPI* _api){api=_api;}
-qmpSamplePlugin::~qmpSamplePlugin(){api=nullptr;}
+qmpSamplePlugin::qmpSamplePlugin(qmpPluginAPI *_api)
+{
+ api = _api;
+}
+qmpSamplePlugin::~qmpSamplePlugin()
+{
+ api = nullptr;
+}
void qmpSamplePlugin::init()
-{fputs("Hello world from plugin init!\n",stderr);}
+{
+ fputs("Hello world from plugin init!\n", stderr);
+}
void qmpSamplePlugin::deinit()
-{fputs("Bye!\n",stderr);}
-const char* qmpSamplePlugin::pluginGetName(){return "QMidiPlayer Sample Plugin";}
-const char* qmpSamplePlugin::pluginGetVersion(){return "0.0.0";}
+{
+ fputs("Bye!\n", stderr);
+}
+const char *qmpSamplePlugin::pluginGetName()
+{
+ return "QMidiPlayer Sample Plugin";
+}
+const char *qmpSamplePlugin::pluginGetVersion()
+{
+ return "0.0.0";
+}
diff --git a/sample-plugin/sampleplugin.hpp b/sample-plugin/sampleplugin.hpp
index ffb3d77..7c981c1 100644
--- a/sample-plugin/sampleplugin.hpp
+++ b/sample-plugin/sampleplugin.hpp
@@ -3,24 +3,28 @@
#include "../include/qmpcorepublic.hpp"
-class qmpSamplePlugin:public qmpPluginIntf
+class qmpSamplePlugin: public qmpPluginIntf
{
- private:
- qmpPluginAPI* api;
- public:
- qmpSamplePlugin(qmpPluginAPI* _api);
- ~qmpSamplePlugin();
- void init();
- void deinit();
- const char* pluginGetName();
- const char* pluginGetVersion();
+private:
+ qmpPluginAPI *api;
+public:
+ qmpSamplePlugin(qmpPluginAPI *_api);
+ ~qmpSamplePlugin();
+ void init();
+ void deinit();
+ const char *pluginGetName();
+ const char *pluginGetVersion();
};
-extern "C"{
- EXPORTSYM qmpPluginIntf* qmpPluginGetInterface(qmpPluginAPI* api)
- {return new qmpSamplePlugin(api);}
- EXPORTSYM const char* qmpPluginGetAPIRev()
- {return QMP_PLUGIN_API_REV;}
+extern "C" {
+ EXPORTSYM qmpPluginIntf *qmpPluginGetInterface(qmpPluginAPI *api)
+ {
+ return new qmpSamplePlugin(api);
+ }
+ EXPORTSYM const char *qmpPluginGetAPIRev()
+ {
+ return QMP_PLUGIN_API_REV;
+ }
}
#endif // SAMPLEPLUGIN_H
diff --git a/simple-visualization/qmpkeyboardwindow.cpp b/simple-visualization/qmpkeyboardwindow.cpp
index 2c5e70a..b33bb4b 100644
--- a/simple-visualization/qmpkeyboardwindow.cpp
+++ b/simple-visualization/qmpkeyboardwindow.cpp
@@ -6,66 +6,69 @@
#include "qmppianowidget.hpp"
#include "qmpkeyboardwindow.hpp"
-qmpKeyboardWindow::qmpKeyboardWindow(qmpPluginAPI *_api,QWidget *parent):
- QWidget(parent,Qt::Dialog),api(_api)
+qmpKeyboardWindow::qmpKeyboardWindow(qmpPluginAPI *_api, QWidget *parent):
+ QWidget(parent, Qt::Dialog), api(_api)
{
- setWindowTitle("Keyboard");
- QGridLayout *grid;
- setLayout(grid=new QGridLayout());
- for(int ch=0;ch<16;++ch)
- {
- grid->addWidget(lb[ch]=new QLabel,ch,0);
- grid->addWidget(pw[ch]=new qmpPianoWidget(this),ch,1);
- lb[ch]->setFont(QFontDatabase::systemFont(QFontDatabase::SystemFont::FixedFont));
- pw[ch]->setSizePolicy(QSizePolicy::Policy::Expanding,QSizePolicy::Policy::Preferred);
- QPalette p=palette();
- p.setColor(QPalette::ColorRole::Highlight,api->getOptionUint("Keyboard/acolor"+std::to_string(ch)));
- p.setColor(QPalette::ColorRole::Base,api->getOptionUint("Keyboard/bcolor"+std::to_string(ch)));
- pw[ch]->setPalette(p);
- }
- hide();
- eh=api->registerEventHandler(
- [this](const void* ee,void*){
- const SEvent *e=(const SEvent*)ee;
- int ch=e->type&0xF;
- if((e->type&0xF0)==0x80||((e->type&0xF0)==0x90&&e->p2==0))
- emit keystateupdated(ch,e->p1,false);
- if((e->type&0xF0)==0x90&&e->p2>0)
- emit keystateupdated(ch,e->p1,e->p2>0);
- if((e->type&0xF0)==0xB0||(e->type&0xF0)==0xC0)
- lb[ch]->setText(
- QString::fromStdString(api->getChannelPresetString(ch))+
- QString("\nch:%1 v:0x%2 p:0x%3 e:0x%4")
- .arg(ch+1,2,10,QChar('0'))
- .arg(api->getChannelCC(ch,0x7),2,16,QChar('0'))
- .arg(api->getChannelCC(ch,0xa),2,16,QChar('0'))
- .arg(api->getChannelCC(ch,0xb),2,16,QChar('0')));
- }
- ,nullptr,true);
- connect(this,&qmpKeyboardWindow::keystateupdated,this,&qmpKeyboardWindow::onkeystatesupdate);
+ setWindowTitle("Keyboard");
+ QGridLayout *grid;
+ setLayout(grid = new QGridLayout());
+ for (int ch = 0; ch < 16; ++ch)
+ {
+ grid->addWidget(lb[ch] = new QLabel, ch, 0);
+ grid->addWidget(pw[ch] = new qmpPianoWidget(this), ch, 1);
+ lb[ch]->setFont(QFontDatabase::systemFont(QFontDatabase::SystemFont::FixedFont));
+ pw[ch]->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Preferred);
+ QPalette p = palette();
+ p.setColor(QPalette::ColorRole::Highlight, api->getOptionUint("Keyboard/acolor" + std::to_string(ch)));
+ p.setColor(QPalette::ColorRole::Base, api->getOptionUint("Keyboard/bcolor" + std::to_string(ch)));
+ pw[ch]->setPalette(p);
+ }
+ hide();
+ eh = api->registerEventHandler(
+ [this](const void *ee, void *)
+ {
+ const SEvent *e = (const SEvent *)ee;
+ int ch = e->type & 0xF;
+ if ((e->type & 0xF0) == 0x80 || ((e->type & 0xF0) == 0x90 && e->p2 == 0))
+ emit keystateupdated(ch, e->p1, false);
+ if ((e->type & 0xF0) == 0x90 && e->p2 > 0)
+ emit keystateupdated(ch, e->p1, e->p2 > 0);
+ if ((e->type & 0xF0) == 0xB0 || (e->type & 0xF0) == 0xC0)
+ lb[ch]->setText(
+ QString::fromStdString(api->getChannelPresetString(ch)) +
+ QString("\nch:%1 v:0x%2 p:0x%3 e:0x%4")
+ .arg(ch + 1, 2, 10, QChar('0'))
+ .arg(api->getChannelCC(ch, 0x7), 2, 16, QChar('0'))
+ .arg(api->getChannelCC(ch, 0xa), 2, 16, QChar('0'))
+ .arg(api->getChannelCC(ch, 0xb), 2, 16, QChar('0')));
+ }
+ , nullptr, true);
+ connect(this, &qmpKeyboardWindow::keystateupdated, this, &qmpKeyboardWindow::onkeystatesupdate);
}
qmpKeyboardWindow::~qmpKeyboardWindow()
{
- api->unregisterEventHandler(eh);
+ api->unregisterEventHandler(eh);
}
void qmpKeyboardWindow::closeEvent(QCloseEvent *event)
{
- api->setFuncState("Keyboard",false);
- event->accept();
+ api->setFuncState("Keyboard", false);
+ event->accept();
+}
+void qmpKeyboardWindow::onkeystatesupdate(int ch, int key, bool state)
+{
+ pw[ch]->setKeyState(key, state);
}
-void qmpKeyboardWindow::onkeystatesupdate(int ch,int key,bool state)
-{pw[ch]->setKeyState(key,state);}
void qmpKeyboardWindow::resetAll()
{
- for(int ch=0;ch<16;++ch)
- {
- pw[ch]->reset();
- lb[ch]->setText(
- QString::fromStdString(api->getChannelPresetString(ch))+
- QString("\nch:%1 v:0x%2 p:0x%3 e:0x%4")
- .arg(ch+1,2,10,QChar('0'))
- .arg(api->getChannelCC(ch,0x7),2,16,QChar('0'))
- .arg(api->getChannelCC(ch,0xa),2,16,QChar('0'))
- .arg(api->getChannelCC(ch,0xb),2,16,QChar('0')));
- }
+ for (int ch = 0; ch < 16; ++ch)
+ {
+ pw[ch]->reset();
+ lb[ch]->setText(
+ QString::fromStdString(api->getChannelPresetString(ch)) +
+ QString("\nch:%1 v:0x%2 p:0x%3 e:0x%4")
+ .arg(ch + 1, 2, 10, QChar('0'))
+ .arg(api->getChannelCC(ch, 0x7), 2, 16, QChar('0'))
+ .arg(api->getChannelCC(ch, 0xa), 2, 16, QChar('0'))
+ .arg(api->getChannelCC(ch, 0xb), 2, 16, QChar('0')));
+ }
}
diff --git a/simple-visualization/qmpkeyboardwindow.hpp b/simple-visualization/qmpkeyboardwindow.hpp
index 65ad266..b540cca 100644
--- a/simple-visualization/qmpkeyboardwindow.hpp
+++ b/simple-visualization/qmpkeyboardwindow.hpp
@@ -7,24 +7,24 @@
class QLabel;
class qmpPianoWidget;
-class qmpKeyboardWindow:public QWidget
+class qmpKeyboardWindow: public QWidget
{
- Q_OBJECT
- private:
- qmpPianoWidget *pw[16];
- QLabel *lb[16];
- qmpPluginAPI *api;
- int eh;
- public:
- qmpKeyboardWindow(qmpPluginAPI *_api,QWidget *parent);
- ~qmpKeyboardWindow();
- void resetAll();
- protected:
- void closeEvent(QCloseEvent *event);
- signals:
- void keystateupdated(int ch,int key,bool state);
- public slots:
- void onkeystatesupdate(int ch,int key,bool state);
+ Q_OBJECT
+private:
+ qmpPianoWidget *pw[16];
+ QLabel *lb[16];
+ qmpPluginAPI *api;
+ int eh;
+public:
+ qmpKeyboardWindow(qmpPluginAPI *_api, QWidget *parent);
+ ~qmpKeyboardWindow();
+ void resetAll();
+protected:
+ void closeEvent(QCloseEvent *event);
+signals:
+ void keystateupdated(int ch, int key, bool state);
+public slots:
+ void onkeystatesupdate(int ch, int key, bool state);
};
#endif
diff --git a/simple-visualization/qmppianowidget.cpp b/simple-visualization/qmppianowidget.cpp
index daeff25..05a84ed 100644
--- a/simple-visualization/qmppianowidget.cpp
+++ b/simple-visualization/qmppianowidget.cpp
@@ -4,82 +4,83 @@
qmpPianoWidget::qmpPianoWidget(QWidget *parent) : QWidget(parent)
{
- memset(keystates,0,sizeof(keystates));
- QPalette p=palette();
- p.setColor(QPalette::ColorRole::Highlight,0xff66cc);
- p.setColor(QPalette::ColorRole::Base,0x66ccff);
- setPalette(p);
+ memset(keystates, 0, sizeof(keystates));
+ QPalette p = palette();
+ p.setColor(QPalette::ColorRole::Highlight, 0xff66cc);
+ p.setColor(QPalette::ColorRole::Base, 0x66ccff);
+ setPalette(p);
}
-void qmpPianoWidget::setKeyState(int key,bool state)
+void qmpPianoWidget::setKeyState(int key, bool state)
{
- keystates[key]=state;
- update();
+ keystates[key] = state;
+ update();
}
void qmpPianoWidget::reset()
{
- memset(keystates,0,sizeof(keystates));
- update();
+ memset(keystates, 0, sizeof(keystates));
+ update();
}
QSize qmpPianoWidget::minimumSizeHint()const
{
- return QSize(320,22);
+ return QSize(320, 22);
}
bool qmpPianoWidget::hasHeightForWidth()const
{
- return true;
+ return true;
}
int qmpPianoWidget::heightForWidth(int w)const
{
- return w*22/320;
+ return w * 22 / 320;
}
void qmpPianoWidget::paintEvent(QPaintEvent *event)
{
- Q_UNUSED(event)
- for(int i=0;i<128;++i)
- {
- QRectF r=getKeyRect(i);
- QColor activeColor=palette().color(QPalette::ColorRole::Highlight);
- QColor inactiveColor=palette().color(QPalette::ColorRole::Base);
- if(i/12%2)
- {
- if(inactiveColor.valueF()>0.5)
- inactiveColor=inactiveColor.darker(112);
- else
- inactiveColor=inactiveColor.lighter(112);
- }
- paintKey(r,keystates[i]?activeColor:inactiveColor);
- }
+ Q_UNUSED(event)
+ for (int i = 0; i < 128; ++i)
+ {
+ QRectF r = getKeyRect(i);
+ QColor activeColor = palette().color(QPalette::ColorRole::Highlight);
+ QColor inactiveColor = palette().color(QPalette::ColorRole::Base);
+ if (i / 12 % 2)
+ {
+ if (inactiveColor.valueF() > 0.5)
+ inactiveColor = inactiveColor.darker(112);
+ else
+ inactiveColor = inactiveColor.lighter(112);
+ }
+ paintKey(r, keystates[i] ? activeColor : inactiveColor);
+ }
}
QRectF qmpPianoWidget::getKeyRect(int key)
{
- int octave=key/12;key%=12;
- bool is_black=(key<5&&(key&1))||(key>5&&((key&1)^1));
- double key_width=width()/75.;
- QRectF ret(0,0,key_width,height()/2.);
- if(!is_black)
- {
- ret.moveTop(height()/2.);
- int shift=(key+(key>=5))>>1;
- ret.moveLeft((octave*7+shift)*key_width);
- }
- else
- ret.moveLeft((octave*7+(key+(key>=5))/2.)*key_width);
- return ret;
+ int octave = key / 12;
+ key %= 12;
+ bool is_black = (key < 5 && (key & 1)) || (key > 5 && ((key & 1) ^ 1));
+ double key_width = width() / 75.;
+ QRectF ret(0, 0, key_width, height() / 2.);
+ if (!is_black)
+ {
+ ret.moveTop(height() / 2.);
+ int shift = (key + (key >= 5)) >> 1;
+ ret.moveLeft((octave * 7 + shift)*key_width);
+ }
+ else
+ ret.moveLeft((octave * 7 + (key + (key >= 5)) / 2.)*key_width);
+ return ret;
}
-void qmpPianoWidget::paintKey(QRectF keyrect,QColor keycolor)
+void qmpPianoWidget::paintKey(QRectF keyrect, QColor keycolor)
{
- QColor bordercolor(keycolor);
- if(keycolor.valueF()>0.5)
- bordercolor=bordercolor.darker(150);
- else
- bordercolor=bordercolor.lighter(150);
- QPainter *p=new QPainter(this);
- p->setPen(bordercolor);
- p->setBrush(QBrush(keycolor));
- p->drawRect(keyrect.adjusted(1,1,-1,-1));
- delete p;
+ QColor bordercolor(keycolor);
+ if (keycolor.valueF() > 0.5)
+ bordercolor = bordercolor.darker(150);
+ else
+ bordercolor = bordercolor.lighter(150);
+ QPainter *p = new QPainter(this);
+ p->setPen(bordercolor);
+ p->setBrush(QBrush(keycolor));
+ p->drawRect(keyrect.adjusted(1, 1, -1, -1));
+ delete p;
}
diff --git a/simple-visualization/qmppianowidget.hpp b/simple-visualization/qmppianowidget.hpp
index cca643c..aec034d 100644
--- a/simple-visualization/qmppianowidget.hpp
+++ b/simple-visualization/qmppianowidget.hpp
@@ -6,22 +6,22 @@
class qmpPianoWidget : public QWidget
{
- Q_OBJECT
- public:
- explicit qmpPianoWidget(QWidget *parent = nullptr);
- void setKeyState(int key,bool state);
- void reset();
- QSize minimumSizeHint()const override;
- bool hasHeightForWidth()const override;
- int heightForWidth(int w)const override;
+ Q_OBJECT
+public:
+ explicit qmpPianoWidget(QWidget *parent = nullptr);
+ void setKeyState(int key, bool state);
+ void reset();
+ QSize minimumSizeHint()const override;
+ bool hasHeightForWidth()const override;
+ int heightForWidth(int w)const override;
- protected:
- void paintEvent(QPaintEvent *event)override;
+protected:
+ void paintEvent(QPaintEvent *event)override;
- private:
- bool keystates[128];
- QRectF getKeyRect(int key);
- void paintKey(QRectF keyrect,QColor keycolor);
+private:
+ bool keystates[128];
+ QRectF getKeyRect(int key);
+ void paintKey(QRectF keyrect, QColor keycolor);
};
#endif // QMPPIANOWIDGET_HPP
diff --git a/simple-visualization/simplevisualization.cpp b/simple-visualization/simplevisualization.cpp
index b93af30..0c3a5b9 100644
--- a/simple-visualization/simplevisualization.cpp
+++ b/simple-visualization/simplevisualization.cpp
@@ -1,33 +1,51 @@
#include "simplevisualization.hpp"
#include "qmpkeyboardwindow.hpp"
-qmpSimpleVisualization::qmpSimpleVisualization(qmpPluginAPI *_api){api=_api;}
-void qmpSimpleVisualization::show(){p->show();}
-void qmpSimpleVisualization::close(){p->close();}
+qmpSimpleVisualization::qmpSimpleVisualization(qmpPluginAPI *_api)
+{
+ api = _api;
+}
+void qmpSimpleVisualization::show()
+{
+ p->show();
+}
+void qmpSimpleVisualization::close()
+{
+ p->close();
+}
void qmpSimpleVisualization::init()
{
- api->registerFunctionality(this,"Keyboard","Keyboard",api->isDarkTheme()?":/img/visualization_i.svg":":/img/visualization.svg",0,true);
- for(int i=0;i<16;++i)
- {
- api->registerOptionUint("","","Keyboard/acolor"+std::to_string(i),0,0xffffff,0xffff66cc);
- api->registerOptionUint("","","Keyboard/bcolor"+std::to_string(i),0,0xffffff,0xff66ccff);
- }
- p=new qmpKeyboardWindow(api,(QWidget*)api->getMainWindow());
- auto refreshfn=[this](const void*,void*){this->p->resetAll();};
- uihs=api->registerUIHook("main.stop",refreshfn,nullptr);
- uihsk=api->registerUIHook("main.seek",refreshfn,nullptr);
- uihsk=api->registerUIHook("preset.set",refreshfn,nullptr);
- uihsk=api->registerUIHook("channel.ccchange",refreshfn,nullptr);
+ api->registerFunctionality(this, "Keyboard", "Keyboard", api->isDarkTheme() ? ":/img/visualization_i.svg" : ":/img/visualization.svg", 0, true);
+ for (int i = 0; i < 16; ++i)
+ {
+ api->registerOptionUint("", "", "Keyboard/acolor" + std::to_string(i), 0, 0xffffff, 0xffff66cc);
+ api->registerOptionUint("", "", "Keyboard/bcolor" + std::to_string(i), 0, 0xffffff, 0xff66ccff);
+ }
+ p = new qmpKeyboardWindow(api, (QWidget *)api->getMainWindow());
+ auto refreshfn = [this](const void *, void *)
+ {
+ this->p->resetAll();
+ };
+ uihs = api->registerUIHook("main.stop", refreshfn, nullptr);
+ uihsk = api->registerUIHook("main.seek", refreshfn, nullptr);
+ uihsk = api->registerUIHook("preset.set", refreshfn, nullptr);
+ uihsk = api->registerUIHook("channel.ccchange", refreshfn, nullptr);
}
void qmpSimpleVisualization::deinit()
{
- if(!api)return;close();
- api->unregisterFunctionality("Keyboard");
- api->unregisterUIHook("main.stop",uihs);
- api->unregisterUIHook("main.seek",uihsk);
- delete p;
+ if (!api)
+ return;
+ close();
+ api->unregisterFunctionality("Keyboard");
+ api->unregisterUIHook("main.stop", uihs);
+ api->unregisterUIHook("main.seek", uihsk);
+ delete p;
+}
+const char *qmpSimpleVisualization::pluginGetName()
+{
+ return "QMidiPlayer Simple Visualization Plugin";
+}
+const char *qmpSimpleVisualization::pluginGetVersion()
+{
+ return PLUGIN_VERSION;
}
-const char* qmpSimpleVisualization::pluginGetName()
-{return "QMidiPlayer Simple Visualization Plugin";}
-const char* qmpSimpleVisualization::pluginGetVersion()
-{return PLUGIN_VERSION;}
diff --git a/simple-visualization/simplevisualization.hpp b/simple-visualization/simplevisualization.hpp
index 58b02ac..6d09cb6 100644
--- a/simple-visualization/simplevisualization.hpp
+++ b/simple-visualization/simplevisualization.hpp
@@ -4,28 +4,32 @@
#include "../include/qmpcorepublic.hpp"
class qmpKeyboardWindow;
-class qmpSimpleVisualization:public qmpPluginIntf,public qmpFuncBaseIntf
+class qmpSimpleVisualization: public qmpPluginIntf, public qmpFuncBaseIntf
{
- private:
- qmpPluginAPI* api;
- qmpKeyboardWindow *p;
- int uihs;
- int uihsk;
- public:
- qmpSimpleVisualization(qmpPluginAPI* _api);
- void show();
- void close();
- void init();
- void deinit();
- const char* pluginGetName();
- const char* pluginGetVersion();
+private:
+ qmpPluginAPI *api;
+ qmpKeyboardWindow *p;
+ int uihs;
+ int uihsk;
+public:
+ qmpSimpleVisualization(qmpPluginAPI *_api);
+ void show();
+ void close();
+ void init();
+ void deinit();
+ const char *pluginGetName();
+ const char *pluginGetVersion();
};
-extern "C"{
- EXPORTSYM qmpPluginIntf* qmpPluginGetInterface(qmpPluginAPI* api)
- {return new qmpSimpleVisualization(api);}
- EXPORTSYM const char* qmpPluginGetAPIRev()
- {return QMP_PLUGIN_API_REV;}
+extern "C" {
+ EXPORTSYM qmpPluginIntf *qmpPluginGetInterface(qmpPluginAPI *api)
+ {
+ return new qmpSimpleVisualization(api);
+ }
+ EXPORTSYM const char *qmpPluginGetAPIRev()
+ {
+ return QMP_PLUGIN_API_REV;
+ }
}
#endif // SIMPLEVISUALIZATION_HPP
diff --git a/visualization/extrasmeltutils.cpp b/visualization/extrasmeltutils.cpp
index 2d0a807..ec9f021 100644
--- a/visualization/extrasmeltutils.cpp
+++ b/visualization/extrasmeltutils.cpp
@@ -3,367 +3,494 @@
#include <algorithm>
#include <smcolor.hpp>
#include "extrasmeltutils.hpp"
-SMELT* smEntity3DBuffer::sm=nullptr;
-SMELT* smParticle::sm=nullptr;
-SMELT* smParticleSystem::sm=nullptr;
-smVertex makeVertex(float x,float y,float z,DWORD color,float tx,float ty)
-{smVertex v;v.x=x;v.y=y;v.z=z;v.col=color;v.tx=tx;v.ty=ty;return v;}
-void smEntity3D::addVertices(size_t n,...)
-{
- va_list vl;va_start(vl,n);
- for(int i=0;i<n;++i)
- {
- smVertex v=va_arg(vl,smVertex);
- vertices.push_back(v);
- }
- va_end(vl);
-}
-void smEntity3D::addIndices(size_t n,...)
-{
- va_list vl;va_start(vl,n);
- for(int i=0;i<n;++i)
- {
- int idx=va_arg(vl,int);
- indices.push_back((WORD)idx);
- }
- va_end(vl);
+SMELT *smEntity3DBuffer::sm = nullptr;
+SMELT *smParticle::sm = nullptr;
+SMELT *smParticleSystem::sm = nullptr;
+smVertex makeVertex(float x, float y, float z, DWORD color, float tx, float ty)
+{
+ smVertex v;
+ v.x = x;
+ v.y = y;
+ v.z = z;
+ v.col = color;
+ v.tx = tx;
+ v.ty = ty;
+ return v;
+}
+void smEntity3D::addVertices(size_t n, ...)
+{
+ va_list vl;
+ va_start(vl, n);
+ for (int i = 0; i < n; ++i)
+ {
+ smVertex v = va_arg(vl, smVertex);
+ vertices.push_back(v);
+ }
+ va_end(vl);
+}
+void smEntity3D::addIndices(size_t n, ...)
+{
+ va_list vl;
+ va_start(vl, n);
+ for (int i = 0; i < n; ++i)
+ {
+ int idx = va_arg(vl, int);
+ indices.push_back((WORD)idx);
+ }
+ va_end(vl);
}
smVertex smEntity3D::vertex(size_t idx)const
{
- if(idx>0&&idx<vertices.size())return vertices[idx];
- return smVertex();
+ if (idx > 0 && idx < vertices.size())
+ return vertices[idx];
+ return smVertex();
}
WORD smEntity3D::index(size_t idx)const
{
- if(idx>0&&idx<indices.size())return indices[idx];
- return 0;
+ if (idx > 0 && idx < indices.size())
+ return indices[idx];
+ return 0;
}
-void smEntity3D::setVertex(size_t idx,smVertex v)
+void smEntity3D::setVertex(size_t idx, smVertex v)
{
- if(idx>0&&idx<vertices.size())vertices[idx]=v;
+ if (idx > 0 && idx < vertices.size())
+ vertices[idx] = v;
}
-void smEntity3D::setIndex(size_t idx,WORD i)
+void smEntity3D::setIndex(size_t idx, WORD i)
{
- if(idx>0&&idx<indices.size())indices[idx]=i;
+ if (idx > 0 && idx < indices.size())
+ indices[idx] = i;
}
-smEntity3D smEntity3D::cube(smvec3d a,smvec3d b,DWORD color,int faces)
-{
- smEntity3D ret;
- ret.addVertices(8,
- makeVertex(a.x,a.y,a.z,color,0,0),makeVertex(b.x,a.y,a.z,color,0,0),
- makeVertex(b.x,b.y,a.z,color,0,0),makeVertex(a.x,b.y,a.z,color,0,0),
- makeVertex(a.x,a.y,b.z,color,0,0),makeVertex(b.x,a.y,b.z,color,0,0),
- makeVertex(b.x,b.y,b.z,color,0,0),makeVertex(a.x,b.y,b.z,color,0,0));
- if(faces&0x1)//a.z
- ret.addIndices(6, 0,1,3, 1,2,3);
- if(faces&0x2)//b.z
- ret.addIndices(6, 4,5,7, 5,6,7);
- if(faces&0x4)//a.x
- ret.addIndices(6, 0,3,7, 0,4,7);
- if(faces&0x8)//b.x
- ret.addIndices(6, 1,2,6, 1,5,6);
- if(faces&0x10)//a.y
- ret.addIndices(6, 0,1,4, 1,4,5);
- if(faces&0x20)//b.y
- ret.addIndices(6, 2,3,7, 2,6,7);
- return ret;
+smEntity3D smEntity3D::cube(smvec3d a, smvec3d b, DWORD color, int faces)
+{
+ smEntity3D ret;
+ ret.addVertices(8,
+ makeVertex(a.x, a.y, a.z, color, 0, 0), makeVertex(b.x, a.y, a.z, color, 0, 0),
+ makeVertex(b.x, b.y, a.z, color, 0, 0), makeVertex(a.x, b.y, a.z, color, 0, 0),
+ makeVertex(a.x, a.y, b.z, color, 0, 0), makeVertex(b.x, a.y, b.z, color, 0, 0),
+ makeVertex(b.x, b.y, b.z, color, 0, 0), makeVertex(a.x, b.y, b.z, color, 0, 0));
+ if (faces & 0x1) //a.z
+ ret.addIndices(6, 0, 1, 3, 1, 2, 3);
+ if (faces & 0x2) //b.z
+ ret.addIndices(6, 4, 5, 7, 5, 6, 7);
+ if (faces & 0x4) //a.x
+ ret.addIndices(6, 0, 3, 7, 0, 4, 7);
+ if (faces & 0x8) //b.x
+ ret.addIndices(6, 1, 2, 6, 1, 5, 6);
+ if (faces & 0x10) //a.y
+ ret.addIndices(6, 0, 1, 4, 1, 4, 5);
+ if (faces & 0x20) //b.y
+ ret.addIndices(6, 2, 3, 7, 2, 6, 7);
+ return ret;
}
smEntity3DBuffer::smEntity3DBuffer()
{
- sm=smGetInterface(SMELT_APILEVEL);
- vertices.clear();indices.clear();
+ sm = smGetInterface(SMELT_APILEVEL);
+ vertices.clear();
+ indices.clear();
}
-void smEntity3DBuffer::addTransformedEntity(smEntity3D *entity,smMatrix t,smvec3d p)
+void smEntity3DBuffer::addTransformedEntity(smEntity3D *entity, smMatrix t, smvec3d p)
{
- if(entity->vertices.size()+vertices.size()>4000)drawBatch();
- for(unsigned i=0;i<entity->indices.size();++i)
- indices.push_back(entity->indices[i]+vertices.size());
- for(unsigned i=0;i<entity->vertices.size();++i)
- {
- smvec3d tp=smvec3d(entity->vertices[i].x,entity->vertices[i].y,entity->vertices[i].z);
- tp=t*tp;tp=tp+p;vertices.push_back(makeVertex(tp.x,tp.y,tp.z,entity->vertices[i].col,entity->vertices[i].tx,entity->vertices[i].ty));
- }
+ if (entity->vertices.size() + vertices.size() > 4000)
+ drawBatch();
+ for (unsigned i = 0; i < entity->indices.size(); ++i)
+ indices.push_back(entity->indices[i] + vertices.size());
+ for (unsigned i = 0; i < entity->vertices.size(); ++i)
+ {
+ smvec3d tp = smvec3d(entity->vertices[i].x, entity->vertices[i].y, entity->vertices[i].z);
+ tp = t * tp;
+ tp = tp + p;
+ vertices.push_back(makeVertex(tp.x, tp.y, tp.z, entity->vertices[i].col, entity->vertices[i].tx, entity->vertices[i].ty));
+ }
}
void smEntity3DBuffer::drawBatch()
{
- if(!vertices.size())return;
- sm->smDrawCustomIndexedVertices(&vertices[0],&indices[0],vertices.size(),indices.size(),BLEND_ALPHABLEND,0);
- vertices.clear();indices.clear();
+ if (!vertices.size())
+ return;
+ sm->smDrawCustomIndexedVertices(&vertices[0], &indices[0], vertices.size(), indices.size(), BLEND_ALPHABLEND, 0);
+ vertices.clear();
+ indices.clear();
}
smParticle::smParticle()
-{sm=smGetInterface(SMELT_APILEVEL);dead=false;clifespan=0;}
-smParticle::~smParticle(){sm->smRelease();}
+{
+ sm = smGetInterface(SMELT_APILEVEL);
+ dead = false;
+ clifespan = 0;
+}
+smParticle::~smParticle()
+{
+ sm->smRelease();
+}
void smParticle::render()
-{sm->smRenderQuad(&q);}
+{
+ sm->smRenderQuad(&q);
+}
void smParticle::update()
{
- clifespan+=sm->smGetDelta();if(clifespan>lifespan){dead=true;return;}
- vel=vel+accel;pos=pos+vel;rotv=rotv+rota;rot=rot+rotv;
- size=clifespan/lifespan*(finalsize-initsize)+initsize;
- smColorRGBA fc(finalcolor),ic(initcolor),cc;
- cc.a=clifespan/lifespan*(fc.a-ic.a)+ic.a;
- cc.r=clifespan/lifespan*(fc.r-ic.r)+ic.r;
- cc.g=clifespan/lifespan*(fc.g-ic.g)+ic.g;
- cc.b=clifespan/lifespan*(fc.b-ic.b)+ic.b;
- color=cc.getHWColor();
- for(int i=0;i<4;++i)q.v[i].col=color;
- smMatrix m;m.loadIdentity();
- if(lookat)m.lookat(pos,lookatpos,smvec3d(0,0,1));else
- {m.rotate(rot.x,1,0,0);m.rotate(rot.y,0,1,0);m.rotate(rot.z,0,0,1);}
- smvec3d v0=m*smvec3d(-size,-size,0),v1=m*smvec3d(size,-size,0);
- smvec3d v2=m*smvec3d(size,size,0),v3=m*smvec3d(-size,size,0);
- q.v[0].x=v0.x+pos.x;q.v[0].y=v0.y+pos.y;q.v[0].z=v0.z+pos.z;
- q.v[1].x=v1.x+pos.x;q.v[1].y=v1.y+pos.y;q.v[1].z=v1.z+pos.z;
- q.v[2].x=v2.x+pos.x;q.v[2].y=v2.y+pos.y;q.v[2].z=v2.z+pos.z;
- q.v[3].x=v3.x+pos.x;q.v[3].y=v3.y+pos.y;q.v[3].z=v3.z+pos.z;
+ clifespan += sm->smGetDelta();
+ if (clifespan > lifespan)
+ {
+ dead = true;
+ return;
+ }
+ vel = vel + accel;
+ pos = pos + vel;
+ rotv = rotv + rota;
+ rot = rot + rotv;
+ size = clifespan / lifespan * (finalsize - initsize) + initsize;
+ smColorRGBA fc(finalcolor), ic(initcolor), cc;
+ cc.a = clifespan / lifespan * (fc.a - ic.a) + ic.a;
+ cc.r = clifespan / lifespan * (fc.r - ic.r) + ic.r;
+ cc.g = clifespan / lifespan * (fc.g - ic.g) + ic.g;
+ cc.b = clifespan / lifespan * (fc.b - ic.b) + ic.b;
+ color = cc.getHWColor();
+ for (int i = 0; i < 4; ++i)
+ q.v[i].col = color;
+ smMatrix m;
+ m.loadIdentity();
+ if (lookat)
+ m.lookat(pos, lookatpos, smvec3d(0, 0, 1));
+ else
+ {
+ m.rotate(rot.x, 1, 0, 0);
+ m.rotate(rot.y, 0, 1, 0);
+ m.rotate(rot.z, 0, 0, 1);
+ }
+ smvec3d v0 = m * smvec3d(-size, -size, 0), v1 = m * smvec3d(size, -size, 0);
+ smvec3d v2 = m * smvec3d(size, size, 0), v3 = m * smvec3d(-size, size, 0);
+ q.v[0].x = v0.x + pos.x;
+ q.v[0].y = v0.y + pos.y;
+ q.v[0].z = v0.z + pos.z;
+ q.v[1].x = v1.x + pos.x;
+ q.v[1].y = v1.y + pos.y;
+ q.v[1].z = v1.z + pos.z;
+ q.v[2].x = v2.x + pos.x;
+ q.v[2].y = v2.y + pos.y;
+ q.v[2].z = v2.z + pos.z;
+ q.v[3].x = v3.x + pos.x;
+ q.v[3].y = v3.y + pos.y;
+ q.v[3].z = v3.z + pos.z;
}
smParticleSystem::smParticleSystem()
-{sm=smGetInterface(SMELT_APILEVEL);particles.clear();posGenerator=nullptr;active=false;}
+{
+ sm = smGetInterface(SMELT_APILEVEL);
+ particles.clear();
+ posGenerator = nullptr;
+ active = false;
+}
smParticleSystem::~smParticleSystem()
-{for(unsigned i=0;i<particles.size();++i)delete particles[i];particles.clear();}
+{
+ for (unsigned i = 0; i < particles.size(); ++i)
+ delete particles[i];
+ particles.clear();
+}
void smParticleSystem::setParticleSystemInfo(smParticleSystemInfo _psinfo)
-{psinfo=_psinfo;}
-void smParticleSystem::setPos(smvec3d _pos){pos=_pos;}
+{
+ psinfo = _psinfo;
+}
+void smParticleSystem::setPos(smvec3d _pos)
+{
+ pos = _pos;
+}
void smParticleSystem::setPSEmissionPosGen(smPSEmissionPositionGenerator *_gen)
-{posGenerator=_gen;}
-void smParticleSystem::setPSLookAt(smvec3d at){lookat=true;lookatpos=at;}
-void smParticleSystem::unsetPSLookAt(){lookat=false;}
+{
+ posGenerator = _gen;
+}
+void smParticleSystem::setPSLookAt(smvec3d at)
+{
+ lookat = true;
+ lookatpos = at;
+}
+void smParticleSystem::unsetPSLookAt()
+{
+ lookat = false;
+}
void smParticleSystem::startPS()
-{active=true;nemdelay=0;re.setSeed(time(nullptr));}
+{
+ active = true;
+ nemdelay = 0;
+ re.setSeed(time(nullptr));
+}
void smParticleSystem::stopPS()
-{active=false;}
+{
+ active = false;
+}
void smParticleSystem::updatePS()
{
- cemdelay+=sm->smGetDelta();
- if(active&&cemdelay>nemdelay&&(int)particles.size()<psinfo.maxcount)
- {
- int ec=re.nextInt(psinfo.emissioncount-psinfo.ecvar,psinfo.emissioncount+psinfo.ecvar);
- for(int i=0;i<ec;++i)
- {
- smParticle *p=new smParticle();
- p->pos=pos+(posGenerator?posGenerator->genPos():smvec3d(0,0,0));
- p->vel=smvec3d(
- re.nextDouble(psinfo.vel.x-psinfo.velvar.x,psinfo.vel.x+psinfo.velvar.x),
- re.nextDouble(psinfo.vel.y-psinfo.velvar.y,psinfo.vel.y+psinfo.velvar.y),
- re.nextDouble(psinfo.vel.z-psinfo.velvar.z,psinfo.vel.z+psinfo.velvar.z));
- p->accel=smvec3d(
- re.nextDouble(psinfo.acc.x-psinfo.accvar.x,psinfo.acc.x+psinfo.accvar.x),
- re.nextDouble(psinfo.acc.y-psinfo.accvar.y,psinfo.acc.y+psinfo.accvar.y),
- re.nextDouble(psinfo.acc.z-psinfo.accvar.z,psinfo.acc.z+psinfo.accvar.z));
- p->rotv=smvec3d(
- re.nextDouble(psinfo.rotv.x-psinfo.rotvvar.x,psinfo.rotv.x+psinfo.rotvvar.x),
- re.nextDouble(psinfo.rotv.y-psinfo.rotvvar.y,psinfo.rotv.y+psinfo.rotvvar.y),
- re.nextDouble(psinfo.rotv.z-psinfo.rotvvar.z,psinfo.rotv.z+psinfo.rotvvar.z));
- p->rota=smvec3d(
- re.nextDouble(psinfo.rota.x-psinfo.rotavar.x,psinfo.rota.x+psinfo.rotavar.x),
- re.nextDouble(psinfo.rota.y-psinfo.rotavar.y,psinfo.rota.y+psinfo.rotavar.y),
- re.nextDouble(psinfo.rota.z-psinfo.rotavar.z,psinfo.rota.z+psinfo.rotavar.z));
- p->rot=smvec3d(0,0,0);if(lookat)p->lookat=true,p->lookatpos=lookatpos;else p->lookat=false;
- p->lifespan=re.nextDouble(psinfo.lifespan-psinfo.lifespanvar,psinfo.lifespan+psinfo.lifespanvar);
- p->initsize=re.nextDouble(psinfo.initsize-psinfo.initsizevar,psinfo.initsize+psinfo.initsizevar);
- p->finalsize=re.nextDouble(psinfo.finalsize-psinfo.finalsizevar,psinfo.finalsize+psinfo.finalsizevar);
- p->size=p->initsize;
- p->initcolor=ARGB(
- re.nextInt(GETA(psinfo.initcolor)-GETA(psinfo.initcolorvar),GETA(psinfo.initcolor)+GETA(psinfo.initcolorvar)),
- re.nextInt(GETR(psinfo.initcolor)-GETR(psinfo.initcolorvar),GETR(psinfo.initcolor)+GETR(psinfo.initcolorvar)),
- re.nextInt(GETG(psinfo.initcolor)-GETG(psinfo.initcolorvar),GETG(psinfo.initcolor)+GETG(psinfo.initcolorvar)),
- re.nextInt(GETB(psinfo.initcolor)-GETB(psinfo.initcolorvar),GETB(psinfo.initcolor)+GETB(psinfo.initcolorvar)));
- p->finalcolor=ARGB(
- re.nextInt(GETA(psinfo.finalcolor)-GETA(psinfo.finalcolorvar),GETA(psinfo.finalcolor)+GETA(psinfo.finalcolorvar)),
- re.nextInt(GETR(psinfo.finalcolor)-GETR(psinfo.finalcolorvar),GETR(psinfo.finalcolor)+GETR(psinfo.finalcolorvar)),
- re.nextInt(GETG(psinfo.finalcolor)-GETG(psinfo.finalcolorvar),GETG(psinfo.finalcolor)+GETG(psinfo.finalcolorvar)),
- re.nextInt(GETB(psinfo.finalcolor)-GETB(psinfo.finalcolorvar),GETB(psinfo.finalcolor)+GETB(psinfo.finalcolorvar)));
- p->color=p->initcolor;p->q.tex=psinfo.texture;p->q.blend=psinfo.blend;
- p->q.v[0].tx=p->q.v[3].tx=0;p->q.v[0].ty=p->q.v[1].ty=0;
- p->q.v[1].tx=p->q.v[2].tx=1;p->q.v[2].ty=p->q.v[3].ty=1;
- particles.push_back(p);
- }
- cemdelay=0;
- nemdelay=re.nextDouble(psinfo.emissiondelay-psinfo.edvar,psinfo.emissiondelay+psinfo.edvar);
- }
- for(unsigned i=0,j;i<particles.size()&&!particles[i]->dead;++i)
- {
- particles[i]->update();
- if(particles[i]->dead)
- {
- for(j=particles.size()-1;j>i&&particles[j]->dead;--j);
- std::swap(particles[i],particles[j]);
- }
- }
- while(!particles.empty()&&particles.back()->dead)
- {delete particles.back();particles.back()=nullptr;particles.pop_back();}
+ cemdelay += sm->smGetDelta();
+ if (active && cemdelay > nemdelay && (int)particles.size() < psinfo.maxcount)
+ {
+ int ec = re.nextInt(psinfo.emissioncount - psinfo.ecvar, psinfo.emissioncount + psinfo.ecvar);
+ for (int i = 0; i < ec; ++i)
+ {
+ smParticle *p = new smParticle();
+ p->pos = pos + (posGenerator ? posGenerator->genPos() : smvec3d(0, 0, 0));
+ p->vel = smvec3d(
+ re.nextDouble(psinfo.vel.x - psinfo.velvar.x, psinfo.vel.x + psinfo.velvar.x),
+ re.nextDouble(psinfo.vel.y - psinfo.velvar.y, psinfo.vel.y + psinfo.velvar.y),
+ re.nextDouble(psinfo.vel.z - psinfo.velvar.z, psinfo.vel.z + psinfo.velvar.z));
+ p->accel = smvec3d(
+ re.nextDouble(psinfo.acc.x - psinfo.accvar.x, psinfo.acc.x + psinfo.accvar.x),
+ re.nextDouble(psinfo.acc.y - psinfo.accvar.y, psinfo.acc.y + psinfo.accvar.y),
+ re.nextDouble(psinfo.acc.z - psinfo.accvar.z, psinfo.acc.z + psinfo.accvar.z));
+ p->rotv = smvec3d(
+ re.nextDouble(psinfo.rotv.x - psinfo.rotvvar.x, psinfo.rotv.x + psinfo.rotvvar.x),
+ re.nextDouble(psinfo.rotv.y - psinfo.rotvvar.y, psinfo.rotv.y + psinfo.rotvvar.y),
+ re.nextDouble(psinfo.rotv.z - psinfo.rotvvar.z, psinfo.rotv.z + psinfo.rotvvar.z));
+ p->rota = smvec3d(
+ re.nextDouble(psinfo.rota.x - psinfo.rotavar.x, psinfo.rota.x + psinfo.rotavar.x),
+ re.nextDouble(psinfo.rota.y - psinfo.rotavar.y, psinfo.rota.y + psinfo.rotavar.y),
+ re.nextDouble(psinfo.rota.z - psinfo.rotavar.z, psinfo.rota.z + psinfo.rotavar.z));
+ p->rot = smvec3d(0, 0, 0);
+ if (lookat)
+ p->lookat = true, p->lookatpos = lookatpos;
+ else p->lookat = false;
+ p->lifespan = re.nextDouble(psinfo.lifespan - psinfo.lifespanvar, psinfo.lifespan + psinfo.lifespanvar);
+ p->initsize = re.nextDouble(psinfo.initsize - psinfo.initsizevar, psinfo.initsize + psinfo.initsizevar);
+ p->finalsize = re.nextDouble(psinfo.finalsize - psinfo.finalsizevar, psinfo.finalsize + psinfo.finalsizevar);
+ p->size = p->initsize;
+ p->initcolor = ARGB(
+ re.nextInt(GETA(psinfo.initcolor) - GETA(psinfo.initcolorvar), GETA(psinfo.initcolor) + GETA(psinfo.initcolorvar)),
+ re.nextInt(GETR(psinfo.initcolor) - GETR(psinfo.initcolorvar), GETR(psinfo.initcolor) + GETR(psinfo.initcolorvar)),
+ re.nextInt(GETG(psinfo.initcolor) - GETG(psinfo.initcolorvar), GETG(psinfo.initcolor) + GETG(psinfo.initcolorvar)),
+ re.nextInt(GETB(psinfo.initcolor) - GETB(psinfo.initcolorvar), GETB(psinfo.initcolor) + GETB(psinfo.initcolorvar)));
+ p->finalcolor = ARGB(
+ re.nextInt(GETA(psinfo.finalcolor) - GETA(psinfo.finalcolorvar), GETA(psinfo.finalcolor) + GETA(psinfo.finalcolorvar)),
+ re.nextInt(GETR(psinfo.finalcolor) - GETR(psinfo.finalcolorvar), GETR(psinfo.finalcolor) + GETR(psinfo.finalcolorvar)),
+ re.nextInt(GETG(psinfo.finalcolor) - GETG(psinfo.finalcolorvar), GETG(psinfo.finalcolor) + GETG(psinfo.finalcolorvar)),
+ re.nextInt(GETB(psinfo.finalcolor) - GETB(psinfo.finalcolorvar), GETB(psinfo.finalcolor) + GETB(psinfo.finalcolorvar)));
+ p->color = p->initcolor;
+ p->q.tex = psinfo.texture;
+ p->q.blend = psinfo.blend;
+ p->q.v[0].tx = p->q.v[3].tx = 0;
+ p->q.v[0].ty = p->q.v[1].ty = 0;
+ p->q.v[1].tx = p->q.v[2].tx = 1;
+ p->q.v[2].ty = p->q.v[3].ty = 1;
+ particles.push_back(p);
+ }
+ cemdelay = 0;
+ nemdelay = re.nextDouble(psinfo.emissiondelay - psinfo.edvar, psinfo.emissiondelay + psinfo.edvar);
+ }
+ for (unsigned i = 0, j; i < particles.size() && !particles[i]->dead; ++i)
+ {
+ particles[i]->update();
+ if (particles[i]->dead)
+ {
+ for (j = particles.size() - 1; j > i && particles[j]->dead; --j);
+ std::swap(particles[i], particles[j]);
+ }
+ }
+ while (!particles.empty() && particles.back()->dead)
+ {
+ delete particles.back();
+ particles.back() = nullptr;
+ particles.pop_back();
+ }
}
void smParticleSystem::renderPS()
-{for(unsigned i=0;i<particles.size();++i)particles[i]->render();}
+{
+ for (unsigned i = 0; i < particles.size(); ++i)
+ particles[i]->render();
+}
smColor::smColor()
-{r=g=b=h=s=v=a=0;}
+{
+ r = g = b = h = s = v = a = 0;
+}
void smColor::update_rgb()
{
- auto f=[this](float n){
- float k=fmodf(n+6.0f*this->h,6.0f);
- return this->v-this->v*this->s*max(0.0f,min(1.0f,min(k,4.0f-k)));
- };
- r=f(5);
- g=f(3);
- b=f(1);
+ auto f = [this](float n)
+ {
+ float k = fmodf(n + 6.0f * this->h, 6.0f);
+ return this->v - this->v * this->s * max(0.0f, min(1.0f, min(k, 4.0f - k)));
+ };
+ r = f(5);
+ g = f(3);
+ b = f(1);
}
void smColor::update_hsv()
{
- v=max(r,max(g,b));
- float vm=min(r,min(g,b));
- float chroma=v-vm;
- if(v-vm<EPSF)h=0;
- else if(v-r<EPSF)h=(0.0f+(g-b)/chroma)/6.0f;
- else if(v-g<EPSF)h=(2.0f+(b-r)/chroma)/6.0f;
- else if(v-b<EPSF)h=(4.0f+(r-g)/chroma)/6.0f;
- if(v<EPSF)s=0;else s=chroma/v;
+ v = max(r, max(g, b));
+ float vm = min(r, min(g, b));
+ float chroma = v - vm;
+ if (v - vm < EPSF)
+ h = 0;
+ else if (v - r < EPSF)
+ h = (0.0f + (g - b) / chroma) / 6.0f;
+ else if (v - g < EPSF)
+ h = (2.0f + (b - r) / chroma) / 6.0f;
+ else if (v - b < EPSF)
+ h = (4.0f + (r - g) / chroma) / 6.0f;
+ if (v < EPSF)
+ s = 0;
+ else s = chroma / v;
}
void smColor::clamp(bool hsv)
{
- if(hsv)
- {
- h=min(1.0f,max(0.0f,h));
- s=min(1.0f,max(0.0f,s));
- v=min(1.0f,max(0.0f,v));
- update_rgb();
- }
- else
- {
- r=min(1.0f,max(0.0f,r));
- g=min(1.0f,max(0.0f,g));
- b=min(1.0f,max(0.0f,b));
- update_hsv();
- }
+ if (hsv)
+ {
+ h = min(1.0f, max(0.0f, h));
+ s = min(1.0f, max(0.0f, s));
+ v = min(1.0f, max(0.0f, v));
+ update_rgb();
+ }
+ else
+ {
+ r = min(1.0f, max(0.0f, r));
+ g = min(1.0f, max(0.0f, g));
+ b = min(1.0f, max(0.0f, b));
+ update_hsv();
+ }
}
float smColor::alpha()const
-{return a;}
+{
+ return a;
+}
float smColor::red()const
-{return r;}
+{
+ return r;
+}
float smColor::green()const
-{return g;}
+{
+ return g;
+}
float smColor::blue()const
-{return b;}
+{
+ return b;
+}
float smColor::hue()const
-{return h;}
+{
+ return h;
+}
float smColor::saturation()const
-{return s;}
+{
+ return s;
+}
float smColor::hslSaturation()const
{
- float l=lightness();
- if(fabsf(l)<EPSF||fabsf(l-1)<EPSF)return 0;
- return (v-l)/min(l,1-l);
+ float l = lightness();
+ if (fabsf(l) < EPSF || fabsf(l - 1) < EPSF)
+ return 0;
+ return (v - l) / min(l, 1 - l);
}
float smColor::value()const
-{return v;}
+{
+ return v;
+}
float smColor::lightness()const
-{return v-v*s/2;}
+{
+ return v - v * s / 2;
+}
void smColor::setAlpha(float alpha)
-{a=alpha;}
+{
+ a = alpha;
+}
void smColor::setRed(float red)
{
- if(fabsf(r-red)>EPSF)
- {
- r=red;
- update_hsv();
- }
+ if (fabsf(r - red) > EPSF)
+ {
+ r = red;
+ update_hsv();
+ }
}
void smColor::setGreen(float green)
{
- if(fabsf(g-green)>EPSF)
- {
- g=green;
- update_hsv();
- }
+ if (fabsf(g - green) > EPSF)
+ {
+ g = green;
+ update_hsv();
+ }
}
void smColor::setBlue(float blue)
{
- if(fabsf(b-blue)>EPSF)
- {
- b=blue;
- update_hsv();
- }
+ if (fabsf(b - blue) > EPSF)
+ {
+ b = blue;
+ update_hsv();
+ }
}
void smColor::setHue(float hue)
{
- if(fabsf(h-hue)>EPSF)
- {
- h=hue;
- update_rgb();
- }
+ if (fabsf(h - hue) > EPSF)
+ {
+ h = hue;
+ update_rgb();
+ }
}
void smColor::setSaturation(float saturation)
{
- if(fabsf(s-saturation)>EPSF)
- {
- s=saturation;
- update_rgb();
- }
+ if (fabsf(s - saturation) > EPSF)
+ {
+ s = saturation;
+ update_rgb();
+ }
}
void smColor::setHSLSaturation(float saturation)
{
- float ss=hslSaturation();
- float l=lightness();
- if(fabsf(ss-saturation)>EPSF)
- {
- ss=saturation;
- v=l+ss*min(l,1-l);
- if(v<EPSF)s=0;
- else s=2-2*l/v;
- update_rgb();
- }
+ float ss = hslSaturation();
+ float l = lightness();
+ if (fabsf(ss - saturation) > EPSF)
+ {
+ ss = saturation;
+ v = l + ss * min(l, 1 - l);
+ if (v < EPSF)
+ s = 0;
+ else s = 2 - 2 * l / v;
+ update_rgb();
+ }
}
void smColor::setValue(float value)
{
- if(fabsf(v-value)>EPSF)
- {
- v=value;
- update_rgb();
- }
+ if (fabsf(v - value) > EPSF)
+ {
+ v = value;
+ update_rgb();
+ }
}
void smColor::setLightness(float lightness)
{
- float ss=hslSaturation();
- float l=this->lightness();
- if(fabsf(l-lightness)>EPSF)
- {
- l=lightness;
- v=l+ss*min(l,1-l);
- if(v<EPSF)s=0;
- else s=2-2*l/v;
- update_rgb();
- }
+ float ss = hslSaturation();
+ float l = this->lightness();
+ if (fabsf(l - lightness) > EPSF)
+ {
+ l = lightness;
+ v = l + ss * min(l, 1 - l);
+ if (v < EPSF)
+ s = 0;
+ else s = 2 - 2 * l / v;
+ update_rgb();
+ }
}
smColor smColor::lighter(int factor)
{
- smColor ret(*this);
- ret.setValue(v*(factor/100.0f));
- ret.clamp(true);
- return ret;
+ smColor ret(*this);
+ ret.setValue(v * (factor / 100.0f));
+ ret.clamp(true);
+ return ret;
}
smColor smColor::darker(int factor)
{
- smColor ret(*this);
- ret.setValue(factor?(v/(factor/100.0f)):1.);
- ret.clamp(true);
- return ret;
+ smColor ret(*this);
+ ret.setValue(factor ? (v / (factor / 100.0f)) : 1.);
+ ret.clamp(true);
+ return ret;
}
uint32_t smColor::toHWColor()
{
- return RGBA(r*255,g*255,b*255,a*255);
+ return RGBA(r * 255, g * 255, b * 255, a * 255);
}
smColor smColor::fromHWColor(uint32_t color)
{
- smColor ret;
- ret.r=GETR(color)/255.0f;
- ret.g=GETG(color)/255.0f;
- ret.b=GETB(color)/255.0f;
- ret.a=GETA(color)/255.0f;
- ret.update_hsv();
- return ret;
+ smColor ret;
+ ret.r = GETR(color) / 255.0f;
+ ret.g = GETG(color) / 255.0f;
+ ret.b = GETB(color) / 255.0f;
+ ret.a = GETA(color) / 255.0f;
+ ret.update_hsv();
+ return ret;
}
diff --git a/visualization/extrasmeltutils.hpp b/visualization/extrasmeltutils.hpp
index 3cea3fc..ca36415 100644
--- a/visualization/extrasmeltutils.hpp
+++ b/visualization/extrasmeltutils.hpp
@@ -13,134 +13,152 @@
#define EPSF 1e-6f
class smEntity3D
{
- friend class smEntity3DBuffer;
- private:
- std::vector<smVertex> vertices;
- std::vector<WORD> indices;
- public:
- smEntity3D(){vertices.clear();indices.clear();}
- void addVertices(size_t n,...);
- void addIndices(size_t n,...);
- smVertex vertex(size_t idx)const;
- WORD index(size_t idx)const;
- void setVertex(size_t idx,smVertex v);
- void setIndex(size_t idx,WORD i);
- static smEntity3D cube(smvec3d tl,smvec3d br,DWORD color,int faces=63);
+ friend class smEntity3DBuffer;
+private:
+ std::vector<smVertex> vertices;
+ std::vector<WORD> indices;
+public:
+ smEntity3D()
+ {
+ vertices.clear();
+ indices.clear();
+ }
+ void addVertices(size_t n, ...);
+ void addIndices(size_t n, ...);
+ smVertex vertex(size_t idx)const;
+ WORD index(size_t idx)const;
+ void setVertex(size_t idx, smVertex v);
+ void setIndex(size_t idx, WORD i);
+ static smEntity3D cube(smvec3d tl, smvec3d br, DWORD color, int faces = 63);
};
class smEntity3DBuffer
{
- private:
- std::vector<smVertex> vertices;
- std::vector<WORD> indices;
- static SMELT* sm;
- public:
- smEntity3DBuffer();
- ~smEntity3DBuffer(){sm->smRelease();}
- void addTransformedEntity(smEntity3D *entity,smMatrix t,smvec3d p);
- void drawBatch();
+private:
+ std::vector<smVertex> vertices;
+ std::vector<WORD> indices;
+ static SMELT *sm;
+public:
+ smEntity3DBuffer();
+ ~smEntity3DBuffer()
+ {
+ sm->smRelease();
+ }
+ void addTransformedEntity(smEntity3D *entity, smMatrix t, smvec3d p);
+ void drawBatch();
};
class smColor
{
- private:
- float r,g,b,h,s,v,a;
- void update_rgb();
- void update_hsv();
- public:
- smColor();
- void clamp(bool hsv);
- float alpha()const;
- float red()const;
- float green()const;
- float blue()const;
- float hue()const;
- float saturation()const;
- float hslSaturation()const;
- float value()const;
- float lightness()const;
- void setAlpha(float alpha);
- void setRed(float red);
- void setGreen(float green);
- void setBlue(float blue);
- void setHue(float hue);
- void setSaturation(float saturation);
- void setHSLSaturation(float saturation);
- void setValue(float value);
- void setLightness(float lightness);
- smColor lighter(int factor);
- smColor darker(int factor);
- uint32_t toHWColor();
- static smColor fromHWColor(uint32_t color);
+private:
+ float r, g, b, h, s, v, a;
+ void update_rgb();
+ void update_hsv();
+public:
+ smColor();
+ void clamp(bool hsv);
+ float alpha()const;
+ float red()const;
+ float green()const;
+ float blue()const;
+ float hue()const;
+ float saturation()const;
+ float hslSaturation()const;
+ float value()const;
+ float lightness()const;
+ void setAlpha(float alpha);
+ void setRed(float red);
+ void setGreen(float green);
+ void setBlue(float blue);
+ void setHue(float hue);
+ void setSaturation(float saturation);
+ void setHSLSaturation(float saturation);
+ void setValue(float value);
+ void setLightness(float lightness);
+ smColor lighter(int factor);
+ smColor darker(int factor);
+ uint32_t toHWColor();
+ static smColor fromHWColor(uint32_t color);
};
class smPSEmissionPositionGenerator
{
- public:
- virtual smvec3d genPos(){return smvec3d(0,0,0);}
+public:
+ virtual smvec3d genPos()
+ {
+ return smvec3d(0, 0, 0);
+ }
};
-class smXLinePSGenerator:public smPSEmissionPositionGenerator
+class smXLinePSGenerator: public smPSEmissionPositionGenerator
{
- private:
- smRandomEngine re;
- double var;
- public:
- smXLinePSGenerator(double _var){re.setSeed(time(nullptr));var=_var;}
- smvec3d genPos(){return smvec3d(re.nextDouble(-var,var),0,0);}
+private:
+ smRandomEngine re;
+ double var;
+public:
+ smXLinePSGenerator(double _var)
+ {
+ re.setSeed(time(nullptr));
+ var = _var;
+ }
+ smvec3d genPos()
+ {
+ return smvec3d(re.nextDouble(-var, var), 0, 0);
+ }
};
class smParticleSystemInfo
{
- public:
- smvec3d vel,velvar,acc,accvar;
- smvec3d rotv,rotvvar,rota,rotavar;
- double lifespan,lifespanvar;
- int maxcount,emissioncount,ecvar;
- double emissiondelay,edvar;
- double initsize,initsizevar;
- double finalsize,finalsizevar;
- DWORD initcolor,initcolorvar;
- DWORD finalcolor,finalcolorvar;
- SMTEX texture;int blend;
+public:
+ smvec3d vel, velvar, acc, accvar;
+ smvec3d rotv, rotvvar, rota, rotavar;
+ double lifespan, lifespanvar;
+ int maxcount, emissioncount, ecvar;
+ double emissiondelay, edvar;
+ double initsize, initsizevar;
+ double finalsize, finalsizevar;
+ DWORD initcolor, initcolorvar;
+ DWORD finalcolor, finalcolorvar;
+ SMTEX texture;
+ int blend;
};
class smParticle
{
- friend class smParticleSystem;
- private:
- static SMELT* sm;
- smvec3d pos,rot,lookatpos;
- smvec3d vel,accel,rotv,rota;
- double lifespan,clifespan;
- double initsize,finalsize,size;
- DWORD color,initcolor,finalcolor;
- smQuad q;
- bool dead,lookat;
- public:
- smParticle();
- ~smParticle();
- void render();
- void update();
+ friend class smParticleSystem;
+private:
+ static SMELT *sm;
+ smvec3d pos, rot, lookatpos;
+ smvec3d vel, accel, rotv, rota;
+ double lifespan, clifespan;
+ double initsize, finalsize, size;
+ DWORD color, initcolor, finalcolor;
+ smQuad q;
+ bool dead, lookat;
+public:
+ smParticle();
+ ~smParticle();
+ void render();
+ void update();
};
class smParticleSystem
{
- private:
- static SMELT* sm;
- std::vector<smParticle*> particles;
- smParticleSystemInfo psinfo;
- smvec3d pos,lookatpos;
- smRandomEngine re;
- smPSEmissionPositionGenerator* posGenerator;
- bool active,lookat;
- double cemdelay,nemdelay;
- public:
- smParticleSystem();
- ~smParticleSystem();
- void setParticleSystemInfo(smParticleSystemInfo _psinfo);
- void setPos(smvec3d _pos);
- void setPSEmissionPosGen(smPSEmissionPositionGenerator* _gen);
- void setPSLookAt(smvec3d at);
- void unsetPSLookAt();
- void startPS();
- void stopPS();
- void updatePS();
- void renderPS();
+private:
+ static SMELT *sm;
+ std::vector<smParticle *> particles;
+ smParticleSystemInfo psinfo;
+ smvec3d pos, lookatpos;
+ smRandomEngine re;
+ smPSEmissionPositionGenerator *posGenerator;
+ bool active, lookat;
+ double cemdelay, nemdelay;
+public:
+ smParticleSystem();
+ ~smParticleSystem();
+ void setParticleSystemInfo(smParticleSystemInfo _psinfo);
+ void setPos(smvec3d _pos);
+ void setPSEmissionPosGen(smPSEmissionPositionGenerator *_gen);
+ void setPSLookAt(smvec3d at);
+ void unsetPSLookAt();
+ void startPS();
+ void stopPS();
+ void updatePS();
+ void renderPS();
};
-extern smVertex makeVertex(float x,float y,float z,DWORD color,float tx,float ty);
+extern smVertex makeVertex(float x, float y, float z, DWORD color, float tx, float ty);
#endif // EXTRASMELTUTILS_H
diff --git a/visualization/qmpvirtualpiano3d.cpp b/visualization/qmpvirtualpiano3d.cpp
index 0fbf75f..4ee7460 100644
--- a/visualization/qmpvirtualpiano3d.cpp
+++ b/visualization/qmpvirtualpiano3d.cpp
@@ -1,219 +1,249 @@
#include <cstring>
#include "qmpvirtualpiano3d.hpp"
#define configureVertex(v,sub,_x,_y,_z) v[sub].x=_x,v[sub].y=_y,v[sub].z=_z;
-const double gap[]={WK_TALWIDTH/2*0.92,WK_TALWIDTH/2*1.23,WK_TALWIDTH/2*1.2,
- WK_TALWIDTH/2*0.95,WK_TALWIDTH*1.1,WK_TALWIDTH/2*0.95,
- WK_TALWIDTH/2*1.2,WK_TALWIDTH/2*1.15,WK_TALWIDTH/2*1,
- WK_TALWIDTH/2*1.3,WK_TALWIDTH/2*0.85,WK_TALWIDTH*1.1};
+const double gap[] = {WK_TALWIDTH / 2 * 0.92, WK_TALWIDTH / 2 * 1.23, WK_TALWIDTH / 2 * 1.2,
+ WK_TALWIDTH / 2 * 0.95, WK_TALWIDTH * 1.1, WK_TALWIDTH / 2 * 0.95,
+ WK_TALWIDTH / 2 * 1.2, WK_TALWIDTH / 2 * 1.15, WK_TALWIDTH / 2 * 1,
+ WK_TALWIDTH / 2 * 1.3, WK_TALWIDTH / 2 * 0.85, WK_TALWIDTH * 1.1
+ };
qmpVirtualPiano3D::qmpVirtualPiano3D()
{
- ebuf=new smEntity3DBuffer();buildKeys();memset(traveld,0,sizeof(traveld));
+ ebuf = new smEntity3DBuffer();
+ buildKeys();
+ memset(traveld, 0, sizeof(traveld));
}
qmpVirtualPiano3D::~qmpVirtualPiano3D()
{
- delete wkcf;delete wkeb;delete wkd;delete wkg;delete wka;delete bk;
- wkcf=wkeb=wkd=wkg=wka=bk=nullptr;delete ebuf;ebuf=nullptr;
+ delete wkcf;
+ delete wkeb;
+ delete wkd;
+ delete wkg;
+ delete wka;
+ delete bk;
+ wkcf = wkeb = wkd = wkg = wka = bk = nullptr;
+ delete ebuf;
+ ebuf = nullptr;
}
void qmpVirtualPiano3D::render(smvec3d p)
{
- p.x-=WK_TALWIDTH*37*1.075;
- for(int i=0;i<128;++i)
- {
- smMatrix m;m.loadIdentity();m.rotate(-0.2*traveld[i],1,0,0);
- switch(i%12)
- {
- case 0:case 5:
- if(wkcf)ebuf->addTransformedEntity(wkcf,m,p);
- break;
- case 2:
- if(wkd)ebuf->addTransformedEntity(wkd,m,p);
- break;
- case 4:case 11:
- if(wkeb)ebuf->addTransformedEntity(wkeb,m,p);
- break;
- case 7:
- if(wkg)ebuf->addTransformedEntity(wkg,m,p);
- break;
- case 9:
- if(wka)ebuf->addTransformedEntity(wka,m,p);
- break;
- case 1:case 3:case 6:case 8:case 10:
- if(bk)ebuf->addTransformedEntity(bk,m,p);
- break;
- }
- p.x+=gap[i%12];
- }
- ebuf->drawBatch();
+ p.x -= WK_TALWIDTH * 37 * 1.075;
+ for (int i = 0; i < 128; ++i)
+ {
+ smMatrix m;
+ m.loadIdentity();
+ m.rotate(-0.2 * traveld[i], 1, 0, 0);
+ switch (i % 12)
+ {
+ case 0:
+ case 5:
+ if (wkcf)
+ ebuf->addTransformedEntity(wkcf, m, p);
+ break;
+ case 2:
+ if (wkd)
+ ebuf->addTransformedEntity(wkd, m, p);
+ break;
+ case 4:
+ case 11:
+ if (wkeb)
+ ebuf->addTransformedEntity(wkeb, m, p);
+ break;
+ case 7:
+ if (wkg)
+ ebuf->addTransformedEntity(wkg, m, p);
+ break;
+ case 9:
+ if (wka)
+ ebuf->addTransformedEntity(wka, m, p);
+ break;
+ case 1:
+ case 3:
+ case 6:
+ case 8:
+ case 10:
+ if (bk)
+ ebuf->addTransformedEntity(bk, m, p);
+ break;
+ }
+ p.x += gap[i % 12];
+ }
+ ebuf->drawBatch();
+}
+void qmpVirtualPiano3D::setKeyTravelDist(int k, double td)
+{
+ traveld[k] = td;
}
-void qmpVirtualPiano3D::setKeyTravelDist(int k,double td)
-{traveld[k]=td;}
void qmpVirtualPiano3D::buildKeys()
{
- wkcf=new smEntity3D();wkeb=new smEntity3D();wkd=new smEntity3D();
- wkg=new smEntity3D();wka=new smEntity3D();bk=new smEntity3D();
- wkcf->addVertices(19,
- makeVertex(-WK_TALWIDTH/2,0,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_PREWIDTH,0,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_PREWIDTH,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN+WK_WING,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN+WK_WING,WK_HEIGHT,0xFFFFFFFF,0,0),////
- makeVertex(-WK_TALWIDTH/2,0,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_PREWIDTH,0,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_PREWIDTH,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,0,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_PREWIDTH,0,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_PREWIDTH,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,0,0xFFCCCCCC,0,0));
- wkcf->addIndices(48,
- 0,1,3, 1,2,3, 3,4,6, 4,5,6,
- 7,8,13, 8,13,14, 8,14,15, 8,9,15,
- 9,10,15, 10,15,16, 10,11,17, 10,16,17,
- 11,12,18, 11,17,18, 18,12,13, 12,13,7);
+ wkcf = new smEntity3D();
+ wkeb = new smEntity3D();
+ wkd = new smEntity3D();
+ wkg = new smEntity3D();
+ wka = new smEntity3D();
+ bk = new smEntity3D();
+ wkcf->addVertices(19,
+ makeVertex(-WK_TALWIDTH / 2, 0, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_PREWIDTH, 0, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_PREWIDTH, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN + WK_WING, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN + WK_WING, WK_HEIGHT, 0xFFFFFFFF, 0, 0), ////
+ makeVertex(-WK_TALWIDTH / 2, 0, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_PREWIDTH, 0, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_PREWIDTH, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, 0, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_PREWIDTH, 0, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_PREWIDTH, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, 0, 0xFFCCCCCC, 0, 0));
+ wkcf->addIndices(48,
+ 0, 1, 3, 1, 2, 3, 3, 4, 6, 4, 5, 6,
+ 7, 8, 13, 8, 13, 14, 8, 14, 15, 8, 9, 15,
+ 9, 10, 15, 10, 15, 16, 10, 11, 17, 10, 16, 17,
+ 11, 12, 18, 11, 17, 18, 18, 12, 13, 12, 13, 7);
- wkeb->addVertices(19,
- makeVertex( WK_TALWIDTH/2,0,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2-WK_PREWIDTH,0,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2-WK_PREWIDTH,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN+WK_WING,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN+WK_WING,WK_HEIGHT,0xFFFFFFFF,0,0),////
- makeVertex( WK_TALWIDTH/2,0,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2-WK_PREWIDTH,0,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2-WK_PREWIDTH,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,0,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2-WK_PREWIDTH,0,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2-WK_PREWIDTH,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,0,0xFFCCCCCC,0,0));
- wkeb->addIndices(48,
- 0,1,3, 1,2,3, 3,4,6, 4,5,6,
- 7,8,13, 8,13,14, 8,14,15, 8,9,15,
- 9,10,15, 10,15,16, 10,11,17, 10,16,17,
- 11,12,18, 11,17,18, 18,12,13, 12,13,7);
+ wkeb->addVertices(19,
+ makeVertex(WK_TALWIDTH / 2, 0, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_PREWIDTH, 0, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_PREWIDTH, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN + WK_WING, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN + WK_WING, WK_HEIGHT, 0xFFFFFFFF, 0, 0), ////
+ makeVertex(WK_TALWIDTH / 2, 0, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_PREWIDTH, 0, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_PREWIDTH, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, 0, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_PREWIDTH, 0, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_PREWIDTH, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, 0, 0xFFCCCCCC, 0, 0));
+ wkeb->addIndices(48,
+ 0, 1, 3, 1, 2, 3, 3, 4, 6, 4, 5, 6,
+ 7, 8, 13, 8, 13, 14, 8, 14, 15, 8, 9, 15,
+ 9, 10, 15, 10, 15, 16, 10, 11, 17, 10, 16, 17,
+ 11, 12, 18, 11, 17, 18, 18, 12, 13, 12, 13, 7);
- wkd->addVertices(24,
- makeVertex(-WK_TALWIDTH/2+(WK_TALWIDTH-WK_PREWIDTH)/2,0,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2-(WK_TALWIDTH-WK_PREWIDTH)/2,0,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2-(WK_TALWIDTH-WK_PREWIDTH)/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2+(WK_TALWIDTH-WK_PREWIDTH)/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN+WK_WING,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN+WK_WING,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),////
- makeVertex(-WK_TALWIDTH/2+(WK_TALWIDTH-WK_PREWIDTH)/2,0,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2-(WK_TALWIDTH-WK_PREWIDTH)/2,0,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2-(WK_TALWIDTH-WK_PREWIDTH)/2,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+(WK_TALWIDTH-WK_PREWIDTH)/2,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),////
- makeVertex(-WK_TALWIDTH/2+(WK_TALWIDTH-WK_PREWIDTH)/2,0,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2-(WK_TALWIDTH-WK_PREWIDTH)/2,0,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2-(WK_TALWIDTH-WK_PREWIDTH)/2,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+(WK_TALWIDTH-WK_PREWIDTH)/2,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,0,0xFFCCCCCC,0,0));
- wkd->addIndices(60,
- 0,1,2, 0,2,3, 4,5,6, 4,6,7,
- 8,9,16, 9,16,17, 9,10,18, 9,17,18,
- 10,12,18, 12,18,19, 12,13,20, 12,19,20,
- 13,14,21, 13,20,21, 14,15,21, 15,21,22,
- 15,11,22, 11,22,23, 11,23,8, 23,16,8);
+ wkd->addVertices(24,
+ makeVertex(-WK_TALWIDTH / 2 + (WK_TALWIDTH - WK_PREWIDTH) / 2, 0, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - (WK_TALWIDTH - WK_PREWIDTH) / 2, 0, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - (WK_TALWIDTH - WK_PREWIDTH) / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + (WK_TALWIDTH - WK_PREWIDTH) / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN + WK_WING, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN + WK_WING, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0), ////
+ makeVertex(-WK_TALWIDTH / 2 + (WK_TALWIDTH - WK_PREWIDTH) / 2, 0, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - (WK_TALWIDTH - WK_PREWIDTH) / 2, 0, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - (WK_TALWIDTH - WK_PREWIDTH) / 2, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + (WK_TALWIDTH - WK_PREWIDTH) / 2, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0), ////
+ makeVertex(-WK_TALWIDTH / 2 + (WK_TALWIDTH - WK_PREWIDTH) / 2, 0, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - (WK_TALWIDTH - WK_PREWIDTH) / 2, 0, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - (WK_TALWIDTH - WK_PREWIDTH) / 2, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + (WK_TALWIDTH - WK_PREWIDTH) / 2, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0));
+ wkd->addIndices(60,
+ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7,
+ 8, 9, 16, 9, 16, 17, 9, 10, 18, 9, 17, 18,
+ 10, 12, 18, 12, 18, 19, 12, 13, 20, 12, 19, 20,
+ 13, 14, 21, 13, 20, 21, 14, 15, 21, 15, 21, 22,
+ 15, 11, 22, 11, 22, 23, 11, 23, 8, 23, 16, 8);
- wkg->addVertices(24,
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12,0,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12+WK_PREWIDTH,0,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12+WK_PREWIDTH,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN+WK_WING,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN+WK_WING,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),////
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12,0,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12+WK_PREWIDTH,0,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12+WK_PREWIDTH,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),////
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12,0,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12+WK_PREWIDTH,0,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12+WK_PREWIDTH,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2+WK_WING+WK_TALWIDTH/12,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,0,0xFFCCCCCC,0,0));
- wkg->addIndices(60,
- 0,1,2, 0,2,3, 4,5,6, 4,6,7,
- 8,9,16, 9,16,17, 9,10,18, 9,17,18,
- 10,12,18, 12,18,19, 12,13,20, 12,19,20,
- 13,14,21, 13,20,21, 14,15,21, 15,21,22,
- 15,11,22, 11,22,23, 11,23,8, 23,16,8);
+ wkg->addVertices(24,
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12, 0, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12 + WK_PREWIDTH, 0, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12 + WK_PREWIDTH, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN + WK_WING, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN + WK_WING, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0), ////
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12, 0, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12 + WK_PREWIDTH, 0, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12 + WK_PREWIDTH, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0), ////
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12, 0, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12 + WK_PREWIDTH, 0, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12 + WK_PREWIDTH, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2 + WK_WING + WK_TALWIDTH / 12, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0));
+ wkg->addIndices(60,
+ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7,
+ 8, 9, 16, 9, 16, 17, 9, 10, 18, 9, 17, 18,
+ 10, 12, 18, 12, 18, 19, 12, 13, 20, 12, 19, 20,
+ 13, 14, 21, 13, 20, 21, 14, 15, 21, 15, 21, 22,
+ 15, 11, 22, 11, 22, 23, 11, 23, 8, 23, 16, 8);
- wka->addVertices(24,
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24-WK_PREWIDTH,0,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24,0,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24-WK_PREWIDTH,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN+WK_WING,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN+WK_WING,WK_HEIGHT,0xFFFFFFFF,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFFFFFFF,0,0),////
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24-WK_PREWIDTH,0,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24,0,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24-WK_PREWIDTH,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,WK_HEIGHT,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,WK_HEIGHT,0xFFCCCCCC,0,0),////
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24-WK_PREWIDTH,0,0,0xFFCCCCCC,0,0),
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24,0,0,0xFFCCCCCC,0,0),
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex(WK_TALWIDTH/2-WK_WING-WK_TALWIDTH/24-WK_PREWIDTH,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN,0,0xFFCCCCCC,0,0),
- makeVertex( WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN+WK_TALLEN,0,0xFFCCCCCC,0,0),
- makeVertex(-WK_TALWIDTH/2,WK_PRELEN,0,0xFFCCCCCC,0,0));
- wka->addIndices(60,
- 0,1,2, 0,2,3, 4,5,6, 4,6,7,
- 8,9,16, 9,16,17, 9,10,18, 9,17,18,
- 10,12,18, 12,18,19, 12,13,20, 12,19,20,
- 13,14,21, 13,20,21, 14,15,21, 15,21,22,
- 15,11,22, 11,22,23, 11,23,8, 23,16,8);
+ wka->addVertices(24,
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24 - WK_PREWIDTH, 0, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24, 0, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24 - WK_PREWIDTH, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN + WK_WING, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN + WK_WING, WK_HEIGHT, 0xFFFFFFFF, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFFFFFFF, 0, 0), ////
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24 - WK_PREWIDTH, 0, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24, 0, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24 - WK_PREWIDTH, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, WK_HEIGHT, 0xFFCCCCCC, 0, 0), ////
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24 - WK_PREWIDTH, 0, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24, 0, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2 - WK_WING - WK_TALWIDTH / 24 - WK_PREWIDTH, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN + WK_TALLEN, 0, 0xFFCCCCCC, 0, 0),
+ makeVertex(-WK_TALWIDTH / 2, WK_PRELEN, 0, 0xFFCCCCCC, 0, 0));
+ wka->addIndices(60,
+ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7,
+ 8, 9, 16, 9, 16, 17, 9, 10, 18, 9, 17, 18,
+ 10, 12, 18, 12, 18, 19, 12, 13, 20, 12, 19, 20,
+ 13, 14, 21, 13, 20, 21, 14, 15, 21, 15, 21, 22,
+ 15, 11, 22, 11, 22, 23, 11, 23, 8, 23, 16, 8);
- bk->addVertices(10,
- makeVertex(-BK_WIDTH/2,0,BK_HEIGHT+BK_BOTTOM,0xFF000000,0,0),
- makeVertex( BK_WIDTH/2,0,BK_HEIGHT+BK_BOTTOM,0xFF000000,0,0),
- makeVertex( BK_WIDTH/2,BK_PRELEN,BK_HEIGHT+BK_BOTTOM,0xFF000000,0,0),
- makeVertex(-BK_WIDTH/2,BK_PRELEN,BK_HEIGHT+BK_BOTTOM,0xFF000000,0,0),
- makeVertex(-BK_WIDTH/2,WK_PRELEN*0.995,BK_DBOTTOM+BK_BOTTOM,0xFF000000,0,0),
- makeVertex( BK_WIDTH/2,WK_PRELEN*0.995,BK_DBOTTOM+BK_BOTTOM,0xFF000000,0,0),
- makeVertex( BK_WIDTH/2,WK_PRELEN*0.995,BK_BOTTOM,0xFF000000,0,0),
- makeVertex(-BK_WIDTH/2,WK_PRELEN*0.995,BK_BOTTOM,0xFF000000,0,0),
- makeVertex(-BK_WIDTH/2,0,BK_BOTTOM,0xFF000000,0,0),
- makeVertex( BK_WIDTH/2,0,BK_BOTTOM,0xFF000000,0,0));
- bk->addIndices(48,
- 0,1,3, 1,2,3, 2,3,4, 2,4,5,
- 4,5,7, 5,6,7, 6,7,8, 6,8,9,
- 0,1,8, 1,8,9, 2,5,6, 2,6,9,
- 2,9,1, 3,4,7, 3,7,8, 3,8,0);
+ bk->addVertices(10,
+ makeVertex(-BK_WIDTH / 2, 0, BK_HEIGHT + BK_BOTTOM, 0xFF000000, 0, 0),
+ makeVertex(BK_WIDTH / 2, 0, BK_HEIGHT + BK_BOTTOM, 0xFF000000, 0, 0),
+ makeVertex(BK_WIDTH / 2, BK_PRELEN, BK_HEIGHT + BK_BOTTOM, 0xFF000000, 0, 0),
+ makeVertex(-BK_WIDTH / 2, BK_PRELEN, BK_HEIGHT + BK_BOTTOM, 0xFF000000, 0, 0),
+ makeVertex(-BK_WIDTH / 2, WK_PRELEN * 0.995, BK_DBOTTOM + BK_BOTTOM, 0xFF000000, 0, 0),
+ makeVertex(BK_WIDTH / 2, WK_PRELEN * 0.995, BK_DBOTTOM + BK_BOTTOM, 0xFF000000, 0, 0),
+ makeVertex(BK_WIDTH / 2, WK_PRELEN * 0.995, BK_BOTTOM, 0xFF000000, 0, 0),
+ makeVertex(-BK_WIDTH / 2, WK_PRELEN * 0.995, BK_BOTTOM, 0xFF000000, 0, 0),
+ makeVertex(-BK_WIDTH / 2, 0, BK_BOTTOM, 0xFF000000, 0, 0),
+ makeVertex(BK_WIDTH / 2, 0, BK_BOTTOM, 0xFF000000, 0, 0));
+ bk->addIndices(48,
+ 0, 1, 3, 1, 2, 3, 2, 3, 4, 2, 4, 5,
+ 4, 5, 7, 5, 6, 7, 6, 7, 8, 6, 8, 9,
+ 0, 1, 8, 1, 8, 9, 2, 5, 6, 2, 6, 9,
+ 2, 9, 1, 3, 4, 7, 3, 7, 8, 3, 8, 0);
}
diff --git a/visualization/qmpvirtualpiano3d.hpp b/visualization/qmpvirtualpiano3d.hpp
index cecd992..d00212a 100644
--- a/visualization/qmpvirtualpiano3d.hpp
+++ b/visualization/qmpvirtualpiano3d.hpp
@@ -16,15 +16,15 @@
#define BK_DBOTTOM 1.
class qmpVirtualPiano3D
{
- private:
- smEntity3D *wkcf,*wkeb,*wkd,*wkg,*wka,*bk;
- smEntity3DBuffer *ebuf;
- void buildKeys();
- double traveld[128];
- public:
- qmpVirtualPiano3D();
- ~qmpVirtualPiano3D();
- void render(smvec3d p);
- void setKeyTravelDist(int k,double td);
+private:
+ smEntity3D *wkcf, *wkeb, *wkd, *wkg, *wka, *bk;
+ smEntity3DBuffer *ebuf;
+ void buildKeys();
+ double traveld[128];
+public:
+ qmpVirtualPiano3D();
+ ~qmpVirtualPiano3D();
+ void render(smvec3d p);
+ void setKeyTravelDist(int k, double td);
};
#endif // QMPVIRTUALPIANO3D_H
diff --git a/visualization/qmpvisualization.cpp b/visualization/qmpvisualization.cpp
index 09f80d6..0f73b8a 100644
--- a/visualization/qmpvisualization.cpp
+++ b/visualization/qmpvisualization.cpp
@@ -6,1018 +6,1341 @@
#include <set>
#include "qmpvisualization.hpp"
-int viewdist=100;
-int notestretch=100;//length of quarter note
-int minnotelength=100;
-int noteappearance=1,showpiano=1,stairpiano=1,savevp=1,showlabel=1;
-int wwidth=800,wheight=600,wsupersample=1,wmultisample=0,showparticle=1;
-int horizontal=1,flat=0,osdpos=0,fontsize=16,showmeasure=1;
-int fov=60,vsync=1,tfps=60,usespectrum=0;
-DWORD chkrtint=0xFF999999;
-const wchar_t* minors=L"abebbbf c g d a e b f#c#g#d#a#";
-const wchar_t* majors=L"CbGbDbAbEbBbF C G D A E B F#C#";
-double fpoffsets[]={1,18,28,50,55,82,98,109,130,137,161,164,191};
-double froffsets[]={0,18,33,50,65,82,98,113,130,145,161,176,191};
-DWORD iccolors[]={0XFFFF0000,0XFFFF8000,0XFFFFBF00,0XFFF0F000,
- 0XFFB2EE00,0XFF80FF00,0XFF00FF00,0XFF00EEB2,
- 0XFF00EEEE,0XFF333333,0XFF00BFFF,0XFF007FFF,
- 0XFF0000FF,0XFF7F00FF,0XFFBF00FF,0XFFFF00BF};
-DWORD accolors[]={0XFFFF9999,0XFFFFCC99,0XFFFFF4D4,0XFFFFFFDD,
- 0XFFF0FFC2,0XFFDDFFBB,0XFFBBFFBB,0XFFAAFFEA,
- 0XFFBBFFFF,0XFF999999,0XFF99EEFF,0XFF99CCFF,
- 0XFF9999FF,0XFFCC99FF,0XFFEE99FF,0XFFFF99EE};
+int viewdist = 100;
+int notestretch = 100; //length of quarter note
+int minnotelength = 100;
+int noteappearance = 1, showpiano = 1, stairpiano = 1, savevp = 1, showlabel = 1;
+int wwidth = 800, wheight = 600, wsupersample = 1, wmultisample = 0, showparticle = 1;
+int horizontal = 1, flat = 0, osdpos = 0, fontsize = 16, showmeasure = 1;
+int fov = 60, vsync = 1, tfps = 60, usespectrum = 0;
+DWORD chkrtint = 0xFF999999;
+const wchar_t *minors = L"abebbbf c g d a e b f#c#g#d#a#";
+const wchar_t *majors = L"CbGbDbAbEbBbF C G D A E B F#C#";
+double fpoffsets[] = {1, 18, 28, 50, 55, 82, 98, 109, 130, 137, 161, 164, 191};
+double froffsets[] = {0, 18, 33, 50, 65, 82, 98, 113, 130, 145, 161, 176, 191};
+DWORD iccolors[] = {0XFFFF0000, 0XFFFF8000, 0XFFFFBF00, 0XFFF0F000,
+ 0XFFB2EE00, 0XFF80FF00, 0XFF00FF00, 0XFF00EEB2,
+ 0XFF00EEEE, 0XFF333333, 0XFF00BFFF, 0XFF007FFF,
+ 0XFF0000FF, 0XFF7F00FF, 0XFFBF00FF, 0XFFFF00BF
+ };
+DWORD accolors[] = {0XFFFF9999, 0XFFFFCC99, 0XFFFFF4D4, 0XFFFFFFDD,
+ 0XFFF0FFC2, 0XFFDDFFBB, 0XFFBBFFBB, 0XFFAAFFEA,
+ 0XFFBBFFFF, 0XFF999999, 0XFF99EEFF, 0XFF99CCFF,
+ 0XFF9999FF, 0XFFCC99FF, 0XFFEE99FF, 0XFFFF99EE
+ };
-std::set<BYTE> sustaininst={16,17,18,19,20,21,22,23,
- 40,41,42,43,44,45,48,49,
- 50,51,52,53,54,56,57,58,
- 59,60,61,62,63,64,65,66,
- 67,68,69,70,71,72,73,74,
- 75,76,77,78,79,80,81,82,
- 83,84,85,86,87,89,90,91,
- 92,93,94,95,97,101,109,110,111};
+std::set<BYTE> sustaininst = {16, 17, 18, 19, 20, 21, 22, 23,
+ 40, 41, 42, 43, 44, 45, 48, 49,
+ 50, 51, 52, 53, 54, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66,
+ 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 89, 90, 91,
+ 92, 93, 94, 95, 97, 101, 109, 110, 111
+ };
-bool cmp(MidiVisualEvent* a,MidiVisualEvent* b)
+bool cmp(MidiVisualEvent *a, MidiVisualEvent *b)
{
- if(a->tcs<b->tcs)return true;if(a->tcs>b->tcs)return false;
- if(a->tce<b->tce)return true;return false;
+ if (a->tcs < b->tcs)
+ return true;
+ if (a->tcs > b->tcs)
+ return false;
+ if (a->tce < b->tce)
+ return true;
+ return false;
}
void qmpVisualization::showThread()
{
- wwidth=api->getOptionInt("Visualization/wwidth");
- wheight=api->getOptionInt("Visualization/wheight");
- wsupersample=api->getOptionInt("Visualization/supersampling");
- wmultisample=api->getOptionInt("Visualization/multisampling");
- fov=api->getOptionInt("Visualization/fov");
- noteappearance=api->getOptionBool("Visualization/3dnotes");
- showpiano=api->getOptionBool("Visualization/showpiano");
- stairpiano=api->getOptionBool("Visualization/stairpiano");
- showlabel=api->getOptionBool("Visualization/showlabel");
- showparticle=api->getOptionBool("Visualization/showparticle");
- horizontal=api->getOptionBool("Visualization/horizontal");
- flat=api->getOptionBool("Visualization/flat");
- showmeasure=api->getOptionBool("Visualization/showmeasure");
- savevp=api->getOptionBool("Visualization/savevp");
- vsync=api->getOptionBool("Visualization/vsync");
- tfps=api->getOptionInt("Visualization/tfps");
- osdpos=api->getOptionEnumInt("Visualization/osdpos");
- fontsize=api->getOptionInt("Visualization/fontsize");
- viewdist=api->getOptionInt("Visualization/viewdist");
- notestretch=api->getOptionInt("Visualization/notestretch");
- minnotelength=api->getOptionInt("Visualization/minnotelen");
- chkrtint=api->getOptionUint("Visualization/chkrtint");
- usespectrum=api->getOptionBool("Visualization/usespectrum");
- for(int i=0;i<16;++i)
- {
- accolors[i]=api->getOptionUint("Visualization/chActiveColor"+std::to_string(i));
- iccolors[i]=api->getOptionUint("Visualization/chInactiveColor"+std::to_string(i));
- }
- sm=smGetInterface(SMELT_APILEVEL);
- sm->smVidMode(wwidth,wheight,true,!hidewindow);
- sm->smUpdateFunc(h);sm->smQuitFunc(closeh);
- sm->smWinTitle("QMidiPlayer Visualization");
- sm->smSetFPS(vsync?FPS_VSYNC:tfps);
- sm->smNoSuspend(true);
- sm->smInit();shouldclose=false;
- sm->smTextureOpt(TPOT_POT,TFLT_LINEAR);
- chequer=sm->smTextureLoad("chequerboard.png");if(!chequer)
- chequer=sm->smTextureLoad("/usr/share/qmidiplayer/img/chequerboard.png");
- pianotex=sm->smTextureLoad("kb_128.png");if(!pianotex)
- pianotex=sm->smTextureLoad("/usr/share/qmidiplayer/img/kb_128.png");
- particletex=sm->smTextureLoad("particle.png");if(!particletex)
- particletex=sm->smTextureLoad("/usr/share/qmidiplayer/img/particle.png");
- bgtex=sm->smTextureLoad(api->getOptionString("Visualization/background").c_str());
- if(rendermode)
- fbcont=new DWORD[wwidth*wheight];
- if(showparticle&&!horizontal)
- {
- smParticleSystemInfo psinfo;
- psinfo.acc=smvec3d(0,0,-0.05);psinfo.accvar=smvec3d(0,0,0.005);
- psinfo.vel=smvec3d(0,0,0.5);psinfo.velvar=smvec3d(0.1,0.1,0.2);
- psinfo.rotv=psinfo.rota=psinfo.rotavar=smvec3d(0,0,0);psinfo.rotvvar=smvec3d(0.04,0.04,0.04);
- psinfo.lifespan=1;psinfo.lifespanvar=0.5;psinfo.maxcount=1000;psinfo.emissioncount=5;psinfo.ecvar=2;
- psinfo.emissiondelay=0.1;psinfo.edvar=0;psinfo.initsize=0.8;psinfo.initsizevar=0.1;
- psinfo.finalsize=0.1;psinfo.finalsizevar=0.05;psinfo.initcolor=0xFFFFFFFF;psinfo.finalcolor=0x00FFFFFF;
- psinfo.initcolorvar=psinfo.finalcolorvar=0;psinfo.texture=particletex;psinfo.blend=BLEND_ALPHAADD;
- psepg=new smXLinePSGenerator(.6);
- for(int i=0;i<16;++i)for(int j=0;j<128;++j)
- {
- pss[i][j]=new smParticleSystem();
- pss[i][j]->setPSEmissionPosGen(psepg);
- psinfo.initcolor=accolors[i];psinfo.finalcolor=SETA(accolors[i],0);
- pss[i][j]->setParticleSystemInfo(psinfo);
- pss[i][j]->setPos(smvec3d(0.756*((double)j-64)+.48,(stairpiano?(56-i*7.):(64-i*8.)),stairpiano*i*2+0.1));
- }
- }else memset(pss,0,sizeof(pss));
- if(showpiano&&!horizontal)for(int i=0;i<16;++i)p3d[i]=new qmpVirtualPiano3D();
- memset(traveld,0,sizeof(traveld));
- nebuf=new smEntity3DBuffer();
- tdscn=sm->smTargetCreate(wwidth*wsupersample,wheight*wsupersample,wmultisample);
- tdparticles=sm->smTargetCreate(wwidth*wsupersample,wheight*wsupersample,wmultisample);
- if(!api->getOptionString("Visualization/font2").length()||!font.loadTTF(api->getOptionString("Visualization/font2").c_str(),fontsize))
- if(!font.loadTTF("/usr/share/fonts/truetype/freefont/FreeMono.ttf",fontsize))
- if(!font.loadTTF("/usr/share/fonts/gnu-free/FreeMono.otf",fontsize))
- if(!font.loadTTF((std::string(getenv("windir")?getenv("windir"):"")+"/Fonts/cour.ttf").c_str(),fontsize))
- fprintf(stderr,"W: Font load failed.\n");
- if(!api->getOptionString("Visualization/font2").length()||!fonthdpi.loadTTF(api->getOptionString("Visualization/font2").c_str(),180))
- if(!fonthdpi.loadTTF("/usr/share/fonts/truetype/freefont/FreeMono.ttf",180))
- if(!fonthdpi.loadTTF("/usr/share/fonts/gnu-free/FreeMono.otf",180))
- if(!fonthdpi.loadTTF((std::string(getenv("windir")?getenv("windir"):"")+"/Fonts/cour.ttf").c_str(),180))
- fprintf(stderr,"W: Font load failed.\n");
- if(!api->getOptionString("Visualization/font1").length()||!font2.loadTTF(api->getOptionString("Visualization/font1").c_str(),fontsize))
- if(!font2.loadTTF("/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",fontsize))
- if(!font2.loadTTF("/usr/share/fonts/wenquanyi/wqy-microhei/wqy-microhei.ttc",fontsize))
- if(!font2.loadTTF((std::string(getenv("windir")?getenv("windir"):"")+"/Fonts/msyh.ttc").c_str(),fontsize))
- if(!font2.loadTTF((std::string(getenv("windir")?getenv("windir"):"")+"/Fonts/segoeui.ttf").c_str(),fontsize))
- fprintf(stderr,"W: Font load failed.\n");
- if(pos[0]<-1e8)
- {
- if(horizontal)
- {
- pos[0]=-20;pos[1]=45;pos[2]=0;
- rot[0]=0;rot[1]=90;rot[2]=90;
- }
- else
- {
- pos[0]=0;pos[1]=120;pos[2]=70;
- rot[0]=0;rot[1]=75;rot[2]=90;
- }
- }
- debug=false;
- ctk=api->getCurrentTimeStamp();
- lst=std::chrono::steady_clock::now();
- sm->smMainLoop();
- sm->smFinale();
+ wwidth = api->getOptionInt("Visualization/wwidth");
+ wheight = api->getOptionInt("Visualization/wheight");
+ wsupersample = api->getOptionInt("Visualization/supersampling");
+ wmultisample = api->getOptionInt("Visualization/multisampling");
+ fov = api->getOptionInt("Visualization/fov");
+ noteappearance = api->getOptionBool("Visualization/3dnotes");
+ showpiano = api->getOptionBool("Visualization/showpiano");
+ stairpiano = api->getOptionBool("Visualization/stairpiano");
+ showlabel = api->getOptionBool("Visualization/showlabel");
+ showparticle = api->getOptionBool("Visualization/showparticle");
+ horizontal = api->getOptionBool("Visualization/horizontal");
+ flat = api->getOptionBool("Visualization/flat");
+ showmeasure = api->getOptionBool("Visualization/showmeasure");
+ savevp = api->getOptionBool("Visualization/savevp");
+ vsync = api->getOptionBool("Visualization/vsync");
+ tfps = api->getOptionInt("Visualization/tfps");
+ osdpos = api->getOptionEnumInt("Visualization/osdpos");
+ fontsize = api->getOptionInt("Visualization/fontsize");
+ viewdist = api->getOptionInt("Visualization/viewdist");
+ notestretch = api->getOptionInt("Visualization/notestretch");
+ minnotelength = api->getOptionInt("Visualization/minnotelen");
+ chkrtint = api->getOptionUint("Visualization/chkrtint");
+ usespectrum = api->getOptionBool("Visualization/usespectrum");
+ for (int i = 0; i < 16; ++i)
+ {
+ accolors[i] = api->getOptionUint("Visualization/chActiveColor" + std::to_string(i));
+ iccolors[i] = api->getOptionUint("Visualization/chInactiveColor" + std::to_string(i));
+ }
+ sm = smGetInterface(SMELT_APILEVEL);
+ sm->smVidMode(wwidth, wheight, true, !hidewindow);
+ sm->smUpdateFunc(h);
+ sm->smQuitFunc(closeh);
+ sm->smWinTitle("QMidiPlayer Visualization");
+ sm->smSetFPS(vsync ? FPS_VSYNC : tfps);
+ sm->smNoSuspend(true);
+ sm->smInit();
+ shouldclose = false;
+ sm->smTextureOpt(TPOT_POT, TFLT_LINEAR);
+ chequer = sm->smTextureLoad("chequerboard.png");
+ if (!chequer)
+ chequer = sm->smTextureLoad("/usr/share/qmidiplayer/img/chequerboard.png");
+ pianotex = sm->smTextureLoad("kb_128.png");
+ if (!pianotex)
+ pianotex = sm->smTextureLoad("/usr/share/qmidiplayer/img/kb_128.png");
+ particletex = sm->smTextureLoad("particle.png");
+ if (!particletex)
+ particletex = sm->smTextureLoad("/usr/share/qmidiplayer/img/particle.png");
+ bgtex = sm->smTextureLoad(api->getOptionString("Visualization/background").c_str());
+ if (rendermode)
+ fbcont = new DWORD[wwidth * wheight];
+ if (showparticle && !horizontal)
+ {
+ smParticleSystemInfo psinfo;
+ psinfo.acc = smvec3d(0, 0, -0.05);
+ psinfo.accvar = smvec3d(0, 0, 0.005);
+ psinfo.vel = smvec3d(0, 0, 0.5);
+ psinfo.velvar = smvec3d(0.1, 0.1, 0.2);
+ psinfo.rotv = psinfo.rota = psinfo.rotavar = smvec3d(0, 0, 0);
+ psinfo.rotvvar = smvec3d(0.04, 0.04, 0.04);
+ psinfo.lifespan = 1;
+ psinfo.lifespanvar = 0.5;
+ psinfo.maxcount = 1000;
+ psinfo.emissioncount = 5;
+ psinfo.ecvar = 2;
+ psinfo.emissiondelay = 0.1;
+ psinfo.edvar = 0;
+ psinfo.initsize = 0.8;
+ psinfo.initsizevar = 0.1;
+ psinfo.finalsize = 0.1;
+ psinfo.finalsizevar = 0.05;
+ psinfo.initcolor = 0xFFFFFFFF;
+ psinfo.finalcolor = 0x00FFFFFF;
+ psinfo.initcolorvar = psinfo.finalcolorvar = 0;
+ psinfo.texture = particletex;
+ psinfo.blend = BLEND_ALPHAADD;
+ psepg = new smXLinePSGenerator(.6);
+ for (int i = 0; i < 16; ++i)
+ for (int j = 0; j < 128; ++j)
+ {
+ pss[i][j] = new smParticleSystem();
+ pss[i][j]->setPSEmissionPosGen(psepg);
+ psinfo.initcolor = accolors[i];
+ psinfo.finalcolor = SETA(accolors[i], 0);
+ pss[i][j]->setParticleSystemInfo(psinfo);
+ pss[i][j]->setPos(smvec3d(0.756 * ((double)j - 64) + .48, (stairpiano ? (56 - i * 7.) : (64 - i * 8.)), stairpiano * i * 2 + 0.1));
+ }
+ }
+ else memset(pss, 0, sizeof(pss));
+ if (showpiano && !horizontal)
+ for (int i = 0; i < 16; ++i)
+ p3d[i] = new qmpVirtualPiano3D();
+ memset(traveld, 0, sizeof(traveld));
+ nebuf = new smEntity3DBuffer();
+ tdscn = sm->smTargetCreate(wwidth * wsupersample, wheight * wsupersample, wmultisample);
+ tdparticles = sm->smTargetCreate(wwidth * wsupersample, wheight * wsupersample, wmultisample);
+ if (!api->getOptionString("Visualization/font2").length() || !font.loadTTF(api->getOptionString("Visualization/font2").c_str(), fontsize))
+ if (!font.loadTTF("/usr/share/fonts/truetype/freefont/FreeMono.ttf", fontsize))
+ if (!font.loadTTF("/usr/share/fonts/gnu-free/FreeMono.otf", fontsize))
+ if (!font.loadTTF((std::string(getenv("windir") ? getenv("windir") : "") + "/Fonts/cour.ttf").c_str(), fontsize))
+ fprintf(stderr, "W: Font load failed.\n");
+ if (!api->getOptionString("Visualization/font2").length() || !fonthdpi.loadTTF(api->getOptionString("Visualization/font2").c_str(), 180))
+ if (!fonthdpi.loadTTF("/usr/share/fonts/truetype/freefont/FreeMono.ttf", 180))
+ if (!fonthdpi.loadTTF("/usr/share/fonts/gnu-free/FreeMono.otf", 180))
+ if (!fonthdpi.loadTTF((std::string(getenv("windir") ? getenv("windir") : "") + "/Fonts/cour.ttf").c_str(), 180))
+ fprintf(stderr, "W: Font load failed.\n");
+ if (!api->getOptionString("Visualization/font1").length() || !font2.loadTTF(api->getOptionString("Visualization/font1").c_str(), fontsize))
+ if (!font2.loadTTF("/usr/share/fonts/truetype/wqy/wqy-microhei.ttc", fontsize))
+ if (!font2.loadTTF("/usr/share/fonts/wenquanyi/wqy-microhei/wqy-microhei.ttc", fontsize))
+ if (!font2.loadTTF((std::string(getenv("windir") ? getenv("windir") : "") + "/Fonts/msyh.ttc").c_str(), fontsize))
+ if (!font2.loadTTF((std::string(getenv("windir") ? getenv("windir") : "") + "/Fonts/segoeui.ttf").c_str(), fontsize))
+ fprintf(stderr, "W: Font load failed.\n");
+ if (pos[0] < -1e8)
+ {
+ if (horizontal)
+ {
+ pos[0] = -20;
+ pos[1] = 45;
+ pos[2] = 0;
+ rot[0] = 0;
+ rot[1] = 90;
+ rot[2] = 90;
+ }
+ else
+ {
+ pos[0] = 0;
+ pos[1] = 120;
+ pos[2] = 70;
+ rot[0] = 0;
+ rot[1] = 75;
+ rot[2] = 90;
+ }
+ }
+ debug = false;
+ ctk = api->getCurrentTimeStamp();
+ lst = std::chrono::steady_clock::now();
+ sm->smMainLoop();
+ sm->smFinale();
}
void qmpVisualization::show()
{
- rendererTh=new std::thread(&qmpVisualization::showThread,this);
+ rendererTh = new std::thread(&qmpVisualization::showThread, this);
}
void qmpVisualization::close()
{
- shouldclose=true;
- if(rendererTh)
- {
- rendererTh->join();
- delete rendererTh;
- rendererTh=nullptr;
- }else return;
+ shouldclose = true;
+ if (rendererTh)
+ {
+ rendererTh->join();
+ delete rendererTh;
+ rendererTh = nullptr;
+ }
+ else return;
- if(showpiano&&!horizontal)for(int i=0;i<16;++i)delete p3d[i];
- if(showparticle&&!horizontal)for(int i=0;i>16;++i)for(int j=0;j<128;++j){delete pss[i][j];pss[i][j]=0;}
- delete nebuf;
- if(savevp)
- {
- api->setOptionDouble("Visualization/px",pos[0]);
- api->setOptionDouble("Visualization/py",pos[1]);
- api->setOptionDouble("Visualization/pz",pos[2]);
- api->setOptionDouble("Visualization/rx",rot[0]);
- api->setOptionDouble("Visualization/ry",rot[1]);
- api->setOptionDouble("Visualization/rz",rot[2]);
- }
- if(rendermode)
- delete[] fbcont;
- font.releaseTTF();
- font2.releaseTTF();
- fonthdpi.releaseTTF();
- sm->smTextureFree(chequer);
- sm->smTextureFree(pianotex);
- sm->smTextureFree(particletex);
- if(bgtex)sm->smTextureFree(bgtex);
- sm->smTargetFree(tdscn);
- sm->smTargetFree(tdparticles);
- sm->smRelease();
+ if (showpiano && !horizontal)
+ for (int i = 0; i < 16; ++i)
+ delete p3d[i];
+ if (showparticle && !horizontal)
+ for (int i = 0; i > 16; ++i)
+ for (int j = 0; j < 128; ++j)
+ {
+ delete pss[i][j];
+ pss[i][j] = 0;
+ }
+ delete nebuf;
+ if (savevp)
+ {
+ api->setOptionDouble("Visualization/px", pos[0]);
+ api->setOptionDouble("Visualization/py", pos[1]);
+ api->setOptionDouble("Visualization/pz", pos[2]);
+ api->setOptionDouble("Visualization/rx", rot[0]);
+ api->setOptionDouble("Visualization/ry", rot[1]);
+ api->setOptionDouble("Visualization/rz", rot[2]);
+ }
+ if (rendermode)
+ delete[] fbcont;
+ font.releaseTTF();
+ font2.releaseTTF();
+ fonthdpi.releaseTTF();
+ sm->smTextureFree(chequer);
+ sm->smTextureFree(pianotex);
+ sm->smTextureFree(particletex);
+ if (bgtex)
+ sm->smTextureFree(bgtex);
+ sm->smTargetFree(tdscn);
+ sm->smTargetFree(tdparticles);
+ sm->smRelease();
}
void qmpVisualization::reset()
{
- for(unsigned i=0;i<pool.size();++i)delete pool[i];
- pool.clear();elb=ctk=lstk=cfr=0;tspool.clear();
- cts=0x0402;cks=0;ctp=500000;
- for(int i=0;i<16;++i)
- {cpbr[i]=2;cpw[i]=8192;}
- for(int i=0;i<16;++i)for(int j=0;j<128;++j)
- {
- if(showparticle&&!horizontal&&pss[i][j])pss[i][j]->stopPS();
- while(!pendingt[i][j].empty())pendingt[i][j].pop();
- while(!pendingv[i][j].empty())pendingv[i][j].pop();
- }
+ for (unsigned i = 0; i < pool.size(); ++i)
+ delete pool[i];
+ pool.clear();
+ elb = ctk = lstk = cfr = 0;
+ tspool.clear();
+ cts = 0x0402;
+ cks = 0;
+ ctp = 500000;
+ for (int i = 0; i < 16; ++i)
+ {
+ cpbr[i] = 2;
+ cpw[i] = 8192;
+ }
+ for (int i = 0; i < 16; ++i)
+ for (int j = 0; j < 128; ++j)
+ {
+ if (showparticle && !horizontal && pss[i][j])
+ pss[i][j]->stopPS();
+ while (!pendingt[i][j].empty())
+ pendingt[i][j].pop();
+ while (!pendingv[i][j].empty())
+ pendingv[i][j].pop();
+ }
}
-void qmpVisualization::switchToRenderMode(void(*frameCallback)(void*,size_t,uint32_t,uint32_t),bool _hidewindow)
+void qmpVisualization::switchToRenderMode(void(*frameCallback)(void *, size_t, uint32_t, uint32_t), bool _hidewindow)
{
- rendermode=true;
- framecb=frameCallback;
- hidewindow=_hidewindow;
+ rendermode = true;
+ framecb = frameCallback;
+ hidewindow = _hidewindow;
+}
+void qmpVisualization::start()
+{
+ playing = true;
+}
+void qmpVisualization::stop()
+{
+ playing = false;
+}
+void qmpVisualization::pause()
+{
+ playing = !playing;
}
-void qmpVisualization::start(){playing=true;}
-void qmpVisualization::stop(){playing=false;}
-void qmpVisualization::pause(){playing=!playing;}
void qmpVisualization::updateVisualization3D()
{
- smQuad q;
- if(!rendermode)
- {
- if(sm->smGetKeyState(SMK_D))pos[0]+=cos(smMath::deg2rad(rot[2]-90)),pos[1]+=sin(smMath::deg2rad(rot[2]-90));
- if(sm->smGetKeyState(SMK_A))pos[0]-=cos(smMath::deg2rad(rot[2]-90)),pos[1]-=sin(smMath::deg2rad(rot[2]-90));
- if(sm->smGetKeyState(SMK_S))pos[0]+=cos(smMath::deg2rad(rot[2])),pos[1]+=sin(smMath::deg2rad(rot[2]));
- if(sm->smGetKeyState(SMK_W))pos[0]-=cos(smMath::deg2rad(rot[2])),pos[1]-=sin(smMath::deg2rad(rot[2]));
- if(sm->smGetKeyState(SMK_Q))pos[2]+=1;
- if(sm->smGetKeyState(SMK_E))pos[2]-=1;
- if(sm->smGetKeyState(SMK_R))
- {
- if(horizontal)
- {
- pos[0]=-20;pos[1]=45;pos[2]=0;
- rot[0]=0;rot[1]=90;rot[2]=90;
- }
- else
- {
- pos[0]=0;pos[1]=120;pos[2]=70;
- rot[0]=0;rot[1]=75;rot[2]=90;
- }
- }
- if(sm->smGetKeyState(SMK_LBUTTON)==SMKST_HIT)
- sm->smSetMouseGrab(true),sm->smGetMouse2f(&lastx,&lasty);
- if(sm->smGetKeyState(SMK_LBUTTON)==SMKST_KEEP)
- {
- float x,y;
- sm->smGetMouse2f(&x,&y);
- rot[1]-=(y-lasty)*0.01;
- rot[2]+=(x-lastx)*0.01;
- while(rot[1]>360)rot[1]-=360;
- while(rot[1]<0)rot[1]+=360;
- while(rot[2]>360)rot[2]-=360;
- while(rot[2]<0)rot[2]+=360;
- }
- if(sm->smGetKeyState(SMK_LBUTTON)==SMKST_RELEASE)
- {
- sm->smSetMouseGrab(false);
- sm->smSetMouse2f(wwidth/2,wheight/2);
- }
- if(sm->smGetKeyState(SMK_I))rot[1]+=1;
- if(sm->smGetKeyState(SMK_K))rot[1]-=1;
- if(sm->smGetKeyState(SMK_L))rot[0]+=1;
- if(sm->smGetKeyState(SMK_J))rot[0]-=1;
- if(sm->smGetKeyState(SMK_U))rot[2]+=1;
- if(sm->smGetKeyState(SMK_O))rot[2]-=1;
- }
- for(int i=0;i<4;++i)
- {q.v[i].col=chkrtint;q.v[i].z=(showpiano&&!horizontal)?-5:0;}
- q.tex=chequer;q.blend=BLEND_ALPHABLEND;
- q.v[0].x=q.v[3].x=-120;q.v[1].x=q.v[2].x=120;
- q.v[0].y=q.v[1].y=-120;q.v[2].y=q.v[3].y=120;
- if(horizontal)
- {
- for(int i=0;i<4;++i)q.v[i].x=-20;
- q.v[0].y=q.v[3].y=-120;q.v[1].y=q.v[2].y=120;
- q.v[0].z=q.v[1].z=-120;q.v[2].z=q.v[3].z=120;
- }
- q.v[0].tx=q.v[3].tx=0;q.v[1].tx=q.v[2].tx=30;
- q.v[0].ty=q.v[1].ty=0;q.v[2].ty=q.v[3].ty=30;
- sm->smRenderBegin3D(fov,true,tdscn);
- sm->sm3DCamera6f2v(pos,rot);
- sm->smClrscr(0,1,1);
- sm->smRenderQuad(&q);
- double lpt=(double)notestretch/api->getDivision()/10.*(horizontal?0.25:1);
- memcpy(lastnotestatus,notestatus,sizeof(notestatus));
- memset(notestatus,0,sizeof(notestatus));
- for(uint32_t i=elb;i<pool.size();++i)
- {
- if(((double)pool[i]->tcs-ctk)*lpt>viewdist*2)break;
- if(fabs((double)pool[i]->tcs-ctk)*lpt<viewdist*2||fabs((double)pool[i]->tce-ctk)*lpt<viewdist*2)
- {
- if(pool[i]->ch==999){
- smvec3d a(0.63*(-64)+.1-10,(stairpiano?(56-0*7.):(64-0*8.))+10,((double)pool[i]->tcs-ctk)*lpt-minnotelength*.005);
- smvec3d b(0.63*64+.7+10,(stairpiano?(56-15*7.):(64-15*8.))+.4-10,((double)pool[i]->tcs-ctk)*lpt+minnotelength*.005);
- if(horizontal){
- a=smvec3d(((double)pool[i]->tcs-ctk)*lpt-20-minnotelength*.001,(16- 0*2.)+2.4,0.63*(-64)+.1);
- b=smvec3d(((double)pool[i]->tcs-ctk)*lpt-20+minnotelength*.001,(16-15*2.)+0.4,0.63*64+.7);
- }
- smMatrix I;I.loadIdentity();
- smEntity3D c=smEntity3D::cube(a,b,0xFF000000,horizontal?51:60);
- if(stairpiano&&showpiano&&!horizontal)
- {
- std::vector<size_t> il={2,3,6,7};
- for(size_t ti:il)
- {
- smVertex t=c.vertex(ti);
- t.z+=30;
- c.setVertex(ti,t);
- }
- }
- if(showmeasure)
- nebuf->addTransformedEntity(&c,I,smvec3d(0,0,0));
- continue;
- }
- if(pool[i]->ch>=990)continue;
- if(api->getChannelMask(pool[i]->ch))continue;
- smvec3d a(0.63*((double)pool[i]->key-64)+.1,(stairpiano?(56-pool[i]->ch*7.):(64-pool[i]->ch*8.)),((double)pool[i]->tce-ctk)*lpt+(stairpiano&&showpiano&&!horizontal)*pool[i]->ch*2.);
- smvec3d b(0.63*((double)pool[i]->key-64)+.7,(stairpiano?(56-pool[i]->ch*7.):(64-pool[i]->ch*8.))+.4,((double)pool[i]->tcs-ctk)*lpt+(stairpiano&&showpiano&&!horizontal)*pool[i]->ch*2.);
- bool isnoteon=pool[i]->tcs<=ctk&&pool[i]->tce>=ctk;
- double pb=((int)cpw[pool[i]->ch]-8192)/8192.*cpbr[pool[i]->ch];
- if(isnoteon)
- {
- a.x=0.63*((double)pool[i]->key-64+pb)+.1;
- b.x=0.63*((double)pool[i]->key-64+pb)+.7;
- }
- notestatus[pool[i]->ch][pool[i]->key]|=isnoteon;a.x*=1.2;b.x*=1.2;
- if(horizontal)
- {
- a=smvec3d(((double)pool[i]->tcs-ctk)*lpt-20,(16-pool[i]->ch*2.),0.63*((double)pool[i]->key-64)+.1);
- b=smvec3d(((double)pool[i]->tce-ctk)*lpt-20,(16-pool[i]->ch*2.)+.4,0.63*((double)pool[i]->key-64)+.7);
- if(isnoteon)
- {
- a.z=0.63*((double)pool[i]->key-64+pb)+.1;
- b.z=0.63*((double)pool[i]->key-64+pb)+.7;
- }
- }
- if(showparticle&&!horizontal)
- {
- if(notestatus[pool[i]->ch][pool[i]->key]&&!lastnotestatus[pool[i]->ch][pool[i]->key])
- {
- pss[pool[i]->ch][pool[i]->key]->startPS();
- pss[pool[i]->ch][pool[i]->key]->setPos(smvec3d(0.756*((double)pool[i]->key-64)+.48,(stairpiano?(56-pool[i]->ch*7.):(64-pool[i]->ch*8.)),stairpiano*pool[i]->ch*2+0.1));
- }
- else pss[pool[i]->ch][pool[i]->key]->stopPS();
- }
- if(((double)pool[i]->tce-pool[i]->tcs)*lpt<minnotelength*(horizontal?0.0025:0.01))
- {
- if(horizontal)
- a.x=((double)pool[i]->tcs-ctk)*lpt-minnotelength/400.-20;
- else
- a.z=((double)pool[i]->tcs-ctk)*lpt-minnotelength/100.+stairpiano*pool[i]->ch*2;
- }
- if(usespectrum)
- {
- if(notestatus[pool[i]->ch][pool[i]->key]&&!lastnotestatus[pool[i]->ch][pool[i]->key])
- spectra[pool[i]->ch][pool[i]->key]=pool[i]->vel*(api->getChannelCC(pool[i]->ch,7)/127.);
- }
- else
- {
- smColor col=smColor::fromHWColor(isnoteon?accolors[pool[i]->ch]:iccolors[pool[i]->ch]);
- drawCube(a,b,col.lighter(37+pool[i]->vel/2).toHWColor(),0);
- }
- }
- }
- if(usespectrum&&playing)
- for(int i=0;i<16;++i)for(int j=0;j<128;++j)
- {
- if(sustaininst.find(api->getChannelPreset(i))!=sustaininst.end())
- {
- if(!notestatus[i][j]&&spectra[i][j])
- spectra[i][j]=.95*spectra[i][j];
- }else if(spectra[i][j])spectra[i][j]=.95*spectra[i][j];
- if(spectrar[i][j]<spectra[i][j]*0.9)spectrar[i][j]+=spectra[i][j]*0.2;
- else spectrar[i][j]=spectra[i][j];
- if(spectrar[i][j])
- {
- double pb=((int)cpw[i]-8192)/8192.*cpbr[i];
- smvec3d a(0.756*((double)j-64+pb)+.12,
- (stairpiano?(56-i*7.):(64-i*8.)),
- spectrar[i][j]*1.2*(1+0.02*sin(sm->smGetTime()*32))+(stairpiano&&showpiano&&!horizontal)*i*2.);
- smvec3d b(0.756*((double)j-64+pb)+.84,
- (stairpiano?(56-i*7.):(64-i*8.))+.4,
- (stairpiano&&showpiano&&!horizontal)*i*2.);
- drawCube(a,b,SETA(iccolors[i],204),0);
- }
- }
- nebuf->drawBatch();
- if(showpiano&&!horizontal)
- for(int i=0;i<16;++i)
- {
- for(int j=0;j<128;++j)
- {
- if(notestatus[i][j])
- if(traveld[i][j]<10)traveld[i][j]+=2;else traveld[i][j]=10;
- else
- if(traveld[i][j]>0)traveld[i][j]-=2;else traveld[i][j]=0;
- p3d[i]->setKeyTravelDist(j,traveld[i][j]/10.);
- }
- double pb=((int)cpw[i]-8192)/8192.*cpbr[i];
- p3d[i]->render(smvec3d(0.756*pb,stairpiano?55-i*7:62-i*8,stairpiano*i*2));
- }
- for(int i=0;i<16;++i)
- if(showlabel)
- {
- std::string s=api->getChannelPresetString(i);
- wchar_t ws[1024];mbstowcs(ws,s.c_str(),1024);
- fonthdpi.updateString(ws);
- fonthdpi.render(-49,stairpiano?56-i*7:63-i*8,stairpiano*i*2+0.1,0xFFFFFFFF,ALIGN_RIGHT,.008,0.01);
- fonthdpi.render(-49.05,stairpiano?56.05-i*7:63.05-i*8,stairpiano*i*2+0.2,0xFF000000,ALIGN_RIGHT,.008,0.01);
- }
- while(pool.size()&&elb<pool.size()&&((double)ctk-pool[elb]->tce)*lpt>viewdist*2)++elb;
- sm->smRenderEnd();
- if(showparticle&&!horizontal)
- {
- sm->smRenderBegin3D(fov,false,tdparticles);
- sm->sm3DCamera6f2v(pos,rot);
- sm->smClrscr(0,1,1);
- for(int i=0;i<16;++i)for(int j=0;j<128;++j)
- {
- pss[i][j]->setPSLookAt(smvec3d(pos[0],pos[1],pos[2]));
- pss[i][j]->updatePS();pss[i][j]->renderPS();
- }
- sm->smRenderEnd();
- }
+ smQuad q;
+ if (!rendermode)
+ {
+ if (sm->smGetKeyState(SMK_D))
+ pos[0] += cos(smMath::deg2rad(rot[2] - 90)), pos[1] += sin(smMath::deg2rad(rot[2] - 90));
+ if (sm->smGetKeyState(SMK_A))
+ pos[0] -= cos(smMath::deg2rad(rot[2] - 90)), pos[1] -= sin(smMath::deg2rad(rot[2] - 90));
+ if (sm->smGetKeyState(SMK_S))
+ pos[0] += cos(smMath::deg2rad(rot[2])), pos[1] += sin(smMath::deg2rad(rot[2]));
+ if (sm->smGetKeyState(SMK_W))
+ pos[0] -= cos(smMath::deg2rad(rot[2])), pos[1] -= sin(smMath::deg2rad(rot[2]));
+ if (sm->smGetKeyState(SMK_Q))
+ pos[2] += 1;
+ if (sm->smGetKeyState(SMK_E))
+ pos[2] -= 1;
+ if (sm->smGetKeyState(SMK_R))
+ {
+ if (horizontal)
+ {
+ pos[0] = -20;
+ pos[1] = 45;
+ pos[2] = 0;
+ rot[0] = 0;
+ rot[1] = 90;
+ rot[2] = 90;
+ }
+ else
+ {
+ pos[0] = 0;
+ pos[1] = 120;
+ pos[2] = 70;
+ rot[0] = 0;
+ rot[1] = 75;
+ rot[2] = 90;
+ }
+ }
+ if (sm->smGetKeyState(SMK_LBUTTON) == SMKST_HIT)
+ sm->smSetMouseGrab(true), sm->smGetMouse2f(&lastx, &lasty);
+ if (sm->smGetKeyState(SMK_LBUTTON) == SMKST_KEEP)
+ {
+ float x, y;
+ sm->smGetMouse2f(&x, &y);
+ rot[1] -= (y - lasty) * 0.01;
+ rot[2] += (x - lastx) * 0.01;
+ while (rot[1] > 360)
+ rot[1] -= 360;
+ while (rot[1] < 0)
+ rot[1] += 360;
+ while (rot[2] > 360)
+ rot[2] -= 360;
+ while (rot[2] < 0)
+ rot[2] += 360;
+ }
+ if (sm->smGetKeyState(SMK_LBUTTON) == SMKST_RELEASE)
+ {
+ sm->smSetMouseGrab(false);
+ sm->smSetMouse2f(wwidth / 2, wheight / 2);
+ }
+ if (sm->smGetKeyState(SMK_I))
+ rot[1] += 1;
+ if (sm->smGetKeyState(SMK_K))
+ rot[1] -= 1;
+ if (sm->smGetKeyState(SMK_L))
+ rot[0] += 1;
+ if (sm->smGetKeyState(SMK_J))
+ rot[0] -= 1;
+ if (sm->smGetKeyState(SMK_U))
+ rot[2] += 1;
+ if (sm->smGetKeyState(SMK_O))
+ rot[2] -= 1;
+ }
+ for (int i = 0; i < 4; ++i)
+ {
+ q.v[i].col = chkrtint;
+ q.v[i].z = (showpiano && !horizontal) ? -5 : 0;
+ }
+ q.tex = chequer;
+ q.blend = BLEND_ALPHABLEND;
+ q.v[0].x = q.v[3].x = -120;
+ q.v[1].x = q.v[2].x = 120;
+ q.v[0].y = q.v[1].y = -120;
+ q.v[2].y = q.v[3].y = 120;
+ if (horizontal)
+ {
+ for (int i = 0; i < 4; ++i)
+ q.v[i].x = -20;
+ q.v[0].y = q.v[3].y = -120;
+ q.v[1].y = q.v[2].y = 120;
+ q.v[0].z = q.v[1].z = -120;
+ q.v[2].z = q.v[3].z = 120;
+ }
+ q.v[0].tx = q.v[3].tx = 0;
+ q.v[1].tx = q.v[2].tx = 30;
+ q.v[0].ty = q.v[1].ty = 0;
+ q.v[2].ty = q.v[3].ty = 30;
+ sm->smRenderBegin3D(fov, true, tdscn);
+ sm->sm3DCamera6f2v(pos, rot);
+ sm->smClrscr(0, 1, 1);
+ sm->smRenderQuad(&q);
+ double lpt = (double)notestretch / api->getDivision() / 10.*(horizontal ? 0.25 : 1);
+ memcpy(lastnotestatus, notestatus, sizeof(notestatus));
+ memset(notestatus, 0, sizeof(notestatus));
+ for (uint32_t i = elb; i < pool.size(); ++i)
+ {
+ if (((double)pool[i]->tcs - ctk)*lpt > viewdist * 2)
+ break;
+ if (fabs((double)pool[i]->tcs - ctk)*lpt < viewdist * 2 || fabs((double)pool[i]->tce - ctk)*lpt < viewdist * 2)
+ {
+ if (pool[i]->ch == 999)
+ {
+ smvec3d a(0.63 * (-64) + .1 - 10, (stairpiano ? (56 - 0 * 7.) : (64 - 0 * 8.)) + 10, ((double)pool[i]->tcs - ctk)*lpt - minnotelength * .005);
+ smvec3d b(0.63 * 64 + .7 + 10, (stairpiano ? (56 - 15 * 7.) : (64 - 15 * 8.)) + .4 - 10, ((double)pool[i]->tcs - ctk)*lpt + minnotelength * .005);
+ if (horizontal)
+ {
+ a = smvec3d(((double)pool[i]->tcs - ctk) * lpt - 20 - minnotelength * .001, (16 - 0 * 2.) + 2.4, 0.63 * (-64) + .1);
+ b = smvec3d(((double)pool[i]->tcs - ctk) * lpt - 20 + minnotelength * .001, (16 - 15 * 2.) + 0.4, 0.63 * 64 + .7);
+ }
+ smMatrix I;
+ I.loadIdentity();
+ smEntity3D c = smEntity3D::cube(a, b, 0xFF000000, horizontal ? 51 : 60);
+ if (stairpiano && showpiano && !horizontal)
+ {
+ std::vector<size_t> il = {2, 3, 6, 7};
+ for (size_t ti : il)
+ {
+ smVertex t = c.vertex(ti);
+ t.z += 30;
+ c.setVertex(ti, t);
+ }
+ }
+ if (showmeasure)
+ nebuf->addTransformedEntity(&c, I, smvec3d(0, 0, 0));
+ continue;
+ }
+ if (pool[i]->ch >= 990)
+ continue;
+ if (api->getChannelMask(pool[i]->ch))
+ continue;
+ smvec3d a(0.63 * ((double)pool[i]->key - 64) + .1, (stairpiano ? (56 - pool[i]->ch * 7.) : (64 - pool[i]->ch * 8.)), ((double)pool[i]->tce - ctk)*lpt + (stairpiano && showpiano && !horizontal)*pool[i]->ch * 2.);
+ smvec3d b(0.63 * ((double)pool[i]->key - 64) + .7, (stairpiano ? (56 - pool[i]->ch * 7.) : (64 - pool[i]->ch * 8.)) + .4, ((double)pool[i]->tcs - ctk)*lpt + (stairpiano && showpiano && !horizontal)*pool[i]->ch * 2.);
+ bool isnoteon = pool[i]->tcs <= ctk && pool[i]->tce >= ctk;
+ double pb = ((int)cpw[pool[i]->ch] - 8192) / 8192.*cpbr[pool[i]->ch];
+ if (isnoteon)
+ {
+ a.x = 0.63 * ((double)pool[i]->key - 64 + pb) + .1;
+ b.x = 0.63 * ((double)pool[i]->key - 64 + pb) + .7;
+ }
+ notestatus[pool[i]->ch][pool[i]->key] |= isnoteon;
+ a.x *= 1.2;
+ b.x *= 1.2;
+ if (horizontal)
+ {
+ a = smvec3d(((double)pool[i]->tcs - ctk) * lpt - 20, (16 - pool[i]->ch * 2.), 0.63 * ((double)pool[i]->key - 64) + .1);
+ b = smvec3d(((double)pool[i]->tce - ctk) * lpt - 20, (16 - pool[i]->ch * 2.) + .4, 0.63 * ((double)pool[i]->key - 64) + .7);
+ if (isnoteon)
+ {
+ a.z = 0.63 * ((double)pool[i]->key - 64 + pb) + .1;
+ b.z = 0.63 * ((double)pool[i]->key - 64 + pb) + .7;
+ }
+ }
+ if (showparticle && !horizontal)
+ {
+ if (notestatus[pool[i]->ch][pool[i]->key] && !lastnotestatus[pool[i]->ch][pool[i]->key])
+ {
+ pss[pool[i]->ch][pool[i]->key]->startPS();
+ pss[pool[i]->ch][pool[i]->key]->setPos(smvec3d(0.756 * ((double)pool[i]->key - 64) + .48, (stairpiano ? (56 - pool[i]->ch * 7.) : (64 - pool[i]->ch * 8.)), stairpiano * pool[i]->ch * 2 + 0.1));
+ }
+ else pss[pool[i]->ch][pool[i]->key]->stopPS();
+ }
+ if (((double)pool[i]->tce - pool[i]->tcs)*lpt < minnotelength * (horizontal ? 0.0025 : 0.01))
+ {
+ if (horizontal)
+ a.x = ((double)pool[i]->tcs - ctk) * lpt - minnotelength / 400. - 20;
+ else
+ a.z = ((double)pool[i]->tcs - ctk) * lpt - minnotelength / 100. + stairpiano * pool[i]->ch * 2;
+ }
+ if (usespectrum)
+ {
+ if (notestatus[pool[i]->ch][pool[i]->key] && !lastnotestatus[pool[i]->ch][pool[i]->key])
+ spectra[pool[i]->ch][pool[i]->key] = pool[i]->vel * (api->getChannelCC(pool[i]->ch, 7) / 127.);
+ }
+ else
+ {
+ smColor col = smColor::fromHWColor(isnoteon ? accolors[pool[i]->ch] : iccolors[pool[i]->ch]);
+ drawCube(a, b, col.lighter(37 + pool[i]->vel / 2).toHWColor(), 0);
+ }
+ }
+ }
+ if (usespectrum && playing)
+ for (int i = 0; i < 16; ++i)
+ for (int j = 0; j < 128; ++j)
+ {
+ if (sustaininst.find(api->getChannelPreset(i)) != sustaininst.end())
+ {
+ if (!notestatus[i][j] && spectra[i][j])
+ spectra[i][j] = .95 * spectra[i][j];
+ }
+ else if (spectra[i][j])
+ spectra[i][j] = .95 * spectra[i][j];
+ if (spectrar[i][j] < spectra[i][j] * 0.9)
+ spectrar[i][j] += spectra[i][j] * 0.2;
+ else spectrar[i][j] = spectra[i][j];
+ if (spectrar[i][j])
+ {
+ double pb = ((int)cpw[i] - 8192) / 8192.*cpbr[i];
+ smvec3d a(0.756 * ((double)j - 64 + pb) + .12,
+ (stairpiano ? (56 - i * 7.) : (64 - i * 8.)),
+ spectrar[i][j] * 1.2 * (1 + 0.02 * sin(sm->smGetTime() * 32)) + (stairpiano && showpiano && !horizontal)*i * 2.);
+ smvec3d b(0.756 * ((double)j - 64 + pb) + .84,
+ (stairpiano ? (56 - i * 7.) : (64 - i * 8.)) + .4,
+ (stairpiano && showpiano && !horizontal)*i * 2.);
+ drawCube(a, b, SETA(iccolors[i], 204), 0);
+ }
+ }
+ nebuf->drawBatch();
+ if (showpiano && !horizontal)
+ for (int i = 0; i < 16; ++i)
+ {
+ for (int j = 0; j < 128; ++j)
+ {
+ if (notestatus[i][j])
+ if (traveld[i][j] < 10)
+ traveld[i][j] += 2;
+ else traveld[i][j] = 10;
+ else if (traveld[i][j] > 0)
+ traveld[i][j] -= 2;
+ else traveld[i][j] = 0;
+ p3d[i]->setKeyTravelDist(j, traveld[i][j] / 10.);
+ }
+ double pb = ((int)cpw[i] - 8192) / 8192.*cpbr[i];
+ p3d[i]->render(smvec3d(0.756 * pb, stairpiano ? 55 - i * 7 : 62 - i * 8, stairpiano * i * 2));
+ }
+ for (int i = 0; i < 16; ++i)
+ if (showlabel)
+ {
+ std::string s = api->getChannelPresetString(i);
+ wchar_t ws[1024];
+ mbstowcs(ws, s.c_str(), 1024);
+ fonthdpi.updateString(ws);
+ fonthdpi.render(-49, stairpiano ? 56 - i * 7 : 63 - i * 8, stairpiano * i * 2 + 0.1, 0xFFFFFFFF, ALIGN_RIGHT, .008, 0.01);
+ fonthdpi.render(-49.05, stairpiano ? 56.05 - i * 7 : 63.05 - i * 8, stairpiano * i * 2 + 0.2, 0xFF000000, ALIGN_RIGHT, .008, 0.01);
+ }
+ while (pool.size() && elb < pool.size() && ((double)ctk - pool[elb]->tce)*lpt > viewdist * 2)++elb;
+ sm->smRenderEnd();
+ if (showparticle && !horizontal)
+ {
+ sm->smRenderBegin3D(fov, false, tdparticles);
+ sm->sm3DCamera6f2v(pos, rot);
+ sm->smClrscr(0, 1, 1);
+ for (int i = 0; i < 16; ++i)
+ for (int j = 0; j < 128; ++j)
+ {
+ pss[i][j]->setPSLookAt(smvec3d(pos[0], pos[1], pos[2]));
+ pss[i][j]->updatePS();
+ pss[i][j]->renderPS();
+ }
+ sm->smRenderEnd();
+ }
}
void qmpVisualization::updateVisualization2D()
{
- double lpt=-(double)notestretch/api->getDivision()/2.;
- memset(notestatus,0,sizeof(notestatus));
- double notew=wwidth/128,nh=showpiano?wwidth/2048.*172.:0;
- if(horizontal){notew=wheight/128;nh=showpiano?wheight/2048.*172.:0;lpt=-lpt;}
- smQuad nq;nq.blend=BLEND_ALPHABLEND;nq.tex=0;
- for(int i=0;i<4;++i)nq.v[i].z=0,nq.v[i].tx=nq.v[i].ty=0;
- for(uint32_t i=elb;i<pool.size();++i)
- {
- bool upperbound=((double)pool[i]->tcs-ctk)*lpt+wheight-nh<0;
- bool lowerbound=fabs((double)pool[i]->tce-ctk)*lpt+wheight-nh<wheight;
- if(horizontal)
- {
- upperbound=((double)pool[i]->tcs-ctk)*lpt+nh>wwidth;
- lowerbound=fabs((double)pool[i]->tce-ctk)*lpt+nh>0;
- }
- if(upperbound)break;
- if(!upperbound||lowerbound)
- {
- if(pool[i]->ch==999){
- smvec2d a(0,((double)pool[i]->tcs-ctk)*lpt+wheight-nh-minnotelength*0.02);
- smvec2d b(wwidth,((double)pool[i]->tcs-ctk)*lpt+wheight-nh);
- if(horizontal)
- {
- a=smvec2d(((double)pool[i]->tcs-ctk)*lpt+nh-minnotelength*0.02,0);
- b=smvec2d(((double)pool[i]->tcs-ctk)*lpt+nh,wheight);
- }
- nq.v[0].x=nq.v[3].x=a.x;nq.v[0].y=nq.v[1].y=a.y;
- nq.v[1].x=nq.v[2].x=b.x;nq.v[2].y=nq.v[3].y=b.y;
- for(int j=0;j<4;++j)nq.v[j].col=0xC0000000;
- if(showmeasure)sm->smRenderQuad(&nq);
- continue;
- }
- if(pool[i]->ch>=990)continue;
- if(api->getChannelMask(pool[i]->ch))continue;
- smvec2d a((froffsets[12]*(pool[i]->key/12)+froffsets[pool[i]->key%12])*wwidth/2048.,((double)pool[i]->tce-ctk)*lpt+wheight-nh);
- smvec2d b(a.x+notew*0.9,((double)pool[i]->tcs-ctk)*lpt+wheight-nh);
- if(horizontal)
- {
- a=smvec2d(((double)pool[i]->tce-ctk)*lpt+nh,(froffsets[12]*(pool[i]->key/12)+froffsets[pool[i]->key%12])*wheight/2048.);
- b=smvec2d(((double)pool[i]->tcs-ctk)*lpt+nh,a.y+notew*0.9);
- }
- bool isnoteon=pool[i]->tcs<=ctk&&pool[i]->tce>=ctk;
- if(isnoteon)
- {
- double pb=((int)cpw[pool[i]->ch]-8192)/8192.*cpbr[pool[i]->ch];
- uint32_t newkey=pool[i]->key+(int)floor(pb);
- double fpb=pb-floor(pb);
- if(horizontal)
- {
- a.y=(froffsets[12]*(newkey/12)+froffsets[newkey%12])*wheight/2048.+notew*fpb;
- b.y=a.y+notew*0.9;
- }
- else
- {
- a.x=(froffsets[12]*(newkey/12)+froffsets[newkey%12])*wwidth/2048.+notew*fpb;
- b.x=a.x+notew*0.9;
- }
- }
- if(horizontal)a.y=wheight-a.y,b.y=wheight-b.y;
- notestatus[pool[i]->ch][pool[i]->key]|=isnoteon;
- if(horizontal)
- {
- if(((double)pool[i]->tce-pool[i]->tcs)*lpt<minnotelength*0.04)
- a.x=((double)pool[i]->tcs-ctk)*lpt+nh-minnotelength*0.04;
- }
- else
- {
- if(((double)pool[i]->tcs-pool[i]->tce)*lpt<minnotelength*0.04)
- a.y=((double)pool[i]->tcs-ctk)*lpt+wheight-nh-minnotelength*0.04;
- }
- nq.v[0].x=nq.v[3].x=a.x;nq.v[0].y=nq.v[1].y=a.y;
- nq.v[1].x=nq.v[2].x=b.x;nq.v[2].y=nq.v[3].y=b.y;
- for(int j=0;j<4;++j)
- nq.v[j].col=SETA(isnoteon?accolors[pool[i]->ch]:iccolors[pool[i]->ch],int(pool[i]->vel*1.6+(isnoteon?52:32)));
- if(usespectrum)
- {
- if(notestatus[pool[i]->ch][pool[i]->key]&&!lastnotestatus[pool[i]->ch][pool[i]->key])
- spectra[pool[i]->ch][pool[i]->key]=pool[i]->vel*(api->getChannelCC(pool[i]->ch,7)/127.);
- }else sm->smRenderQuad(&nq);
- }
- }
- if(horizontal)
- while(pool.size()&&elb<pool.size()&&fabs((double)pool[elb]->tce-ctk)*lpt+nh<0)++elb;
- else
- while(pool.size()&&elb<pool.size()&&fabs((double)pool[elb]->tce-ctk)*lpt+wheight-nh>wheight)++elb;
- smQuad q;
- q.tex=pianotex;q.blend=BLEND_ALPHABLEND;
- for(int i=0;i<4;++i)q.v[i].col=0xFFFFFFFF,q.v[i].z=0;
- q.v[0].ty=q.v[3].ty=0;q.v[1].ty=q.v[2].ty=172./256.;
- q.v[0].tx=q.v[1].tx=0;q.v[2].tx=q.v[3].tx=1.;
- q.v[0].x=q.v[1].x=0;q.v[2].x=q.v[3].x=wwidth;
- q.v[0].y=q.v[3].y=wheight-nh;q.v[1].y=q.v[2].y=wheight;
- if(horizontal)
- {
- q.v[0].tx=q.v[3].tx=0;q.v[1].tx=q.v[2].tx=1;
- q.v[0].ty=q.v[1].ty=0;q.v[2].ty=q.v[3].ty=172./256.;
- q.v[0].x=q.v[1].x=nh;q.v[2].x=q.v[3].x=0;
- q.v[0].y=q.v[3].y=wheight;q.v[1].y=q.v[2].y=0;
- }
- sm->smRenderQuad(&q);
- for(int i=0,j;i<128;++i)
- {
- DWORD c=0;for(j=0;j<16;++j)if(notestatus[j][i]){c=SETA(iccolors[j],0xFF);break;}
- if(horizontal)
- {
- q.v[0].y=q.v[1].y=(fpoffsets[12]*(i/12)+fpoffsets[i%12])*wheight/2048.;
- q.v[2].y=q.v[3].y=q.v[0].y;
- q.v[0].x=q.v[3].x=nh;q.v[1].x=q.v[2].x=0;
- }
- else
- {
- q.v[0].x=q.v[1].x=(fpoffsets[12]*(i/12)+fpoffsets[i%12])*wwidth/2048.;
- q.v[2].x=q.v[3].x=q.v[0].x;
- q.v[0].y=q.v[3].y=wheight-nh;q.v[1].y=q.v[2].y=wheight;
- }
- if(!c)continue;for(int j=0;j<4;++j)q.v[j].col=c;
- switch(i%12)
- {
- case 1:case 3:case 6:case 8:case 10:
- if(horizontal)
- {
- q.v[1].x=q.v[2].x=nh-115*wheight/2048.;
- q.v[2].y+=15.*wheight/2048;q.v[3].y+=15.*wheight/2048;
- }
- else
- {
- q.v[1].y=q.v[2].y=wheight-nh+115*wwidth/2048.;
- q.v[2].x+=15.*wwidth/2048;q.v[3].x+=15.*wwidth/2048;
- }
- q.v[0].ty=q.v[1].ty=1.;q.v[2].ty=q.v[3].ty=1.-15/256.;
- q.v[0].tx=q.v[3].tx=1344/2048.;q.v[1].tx=q.v[2].tx=1459/2048.;
- break;
- case 0:
- if(horizontal)
- {q.v[2].y+=27.*wheight/2048;q.v[3].y+=27.*wheight/2048;}
- else
- {q.v[2].x+=27.*wwidth/2048;q.v[3].x+=27.*wwidth/2048;}
- q.v[0].ty=q.v[1].ty=1.;q.v[2].ty=q.v[3].ty=1.-27/256.;
- q.v[0].tx=q.v[3].tx=0/2048.;q.v[1].tx=q.v[2].tx=172/2048.;
- break;
- case 2:
- if(horizontal)
- {q.v[2].y+=29.*wheight/2048;q.v[3].y+=29.*wheight/2048;}
- else
- {q.v[2].x+=29.*wwidth/2048;q.v[3].x+=29.*wwidth/2048;}
- q.v[0].ty=q.v[1].ty=1.;q.v[2].ty=q.v[3].ty=1.-29/256.;
- q.v[0].tx=q.v[3].tx=192/2048.;q.v[1].tx=q.v[2].tx=364/2048.;
- break;
- case 4:
- if(horizontal)
- {q.v[2].y+=28.*wheight/2048;q.v[3].y+=28.*wheight/2048;}
- else
- {q.v[2].x+=28.*wwidth/2048;q.v[3].x+=28.*wwidth/2048;}
- q.v[0].ty=q.v[1].ty=1.;q.v[2].ty=q.v[3].ty=1.-28/256.;
- q.v[0].tx=q.v[3].tx=384/2048.;q.v[1].tx=q.v[2].tx=556/2048.;
- break;
- case 5:
- if(horizontal)
- {q.v[2].y+=28.*wheight/2048;q.v[3].y+=28.*wheight/2048;}
- else
- {q.v[2].x+=28.*wwidth/2048;q.v[3].x+=28.*wwidth/2048;}
- q.v[0].ty=q.v[1].ty=1.;q.v[2].ty=q.v[3].ty=1.-28/256.;
- q.v[0].tx=q.v[3].tx=576/2048.;q.v[1].tx=q.v[2].tx=748/2048.;
- break;
- case 7:
- if(horizontal)
- {q.v[2].y+=29.*wheight/2048;q.v[3].y+=29.*wheight/2048;}
- else
- {q.v[2].x+=29.*wwidth/2048;q.v[3].x+=29.*wwidth/2048;}
- q.v[0].ty=q.v[1].ty=1.;q.v[2].ty=q.v[3].ty=1.-29/256.;
- q.v[0].tx=q.v[3].tx=768/2048.;q.v[1].tx=q.v[2].tx=940/2048.;
- break;
- case 9:
- if(horizontal)
- {q.v[2].y+=28.*wheight/2048;q.v[3].y+=28.*wheight/2048;}
- else
- {q.v[2].x+=28.*wwidth/2048;q.v[3].x+=28.*wwidth/2048;}
- q.v[0].ty=q.v[1].ty=1.;q.v[2].ty=q.v[3].ty=1.-28/256.;
- q.v[0].tx=q.v[3].tx=960/2048.;q.v[1].tx=q.v[2].tx=1132/2048.;
- break;
- case 11:
- if(horizontal)
- {q.v[2].y+=28.*wheight/2048;q.v[3].y+=28.*wheight/2048;}
- else
- {q.v[2].x+=28.*wwidth/2048;q.v[3].x+=28.*wwidth/2048;}
- q.v[0].ty=q.v[1].ty=1.;q.v[2].ty=q.v[3].ty=1.-28/256.;
- q.v[0].tx=q.v[3].tx=1152/2048.;q.v[1].tx=q.v[2].tx=1324/2048.;
- break;
- }
- if(horizontal)for(int j=0;j<4;++j)q.v[j].y=wheight-q.v[j].y;
- sm->smRenderQuad(&q);
- }
- if(usespectrum&&playing)
- for(int i=0;i<16;++i)for(int j=0;j<128;++j)
- {
- if(sustaininst.find(api->getChannelPreset(i))!=sustaininst.end())
- {
- if(!notestatus[i][j]&&spectra[i][j])
- spectra[i][j]=.95*spectra[i][j];
- }else if(spectra[i][j])spectra[i][j]=.95*spectra[i][j];
- if(spectrar[i][j]<spectra[i][j]*0.9)spectrar[i][j]+=spectra[i][j]*0.2;
- else spectrar[i][j]=spectra[i][j];
- if(spectrar[i][j])
- {
- smvec2d a((froffsets[12]*(j/12)+froffsets[j%12])*wwidth/2048.,spectrar[i][j]/-128.*(wheight-nh)*(1+0.02*sin(sm->smGetTime()*32))+wheight-nh);
- smvec2d b(a.x+notew*0.9,lpt+wheight-nh);
- double pb=((int)cpw[i]-8192)/8192.*cpbr[i];
- uint32_t newkey=j+(int)floor(pb);
- double fpb=pb-floor(pb);
- if(horizontal)
- {
- a=smvec2d(spectrar[i][j]/128.*(wwidth-nh)*(1+0.02*sin(sm->smGetTime()*32))+nh,(froffsets[12]*(j/12)+froffsets[j%12])*wheight/2048.);
- b=smvec2d(nh,a.y+notew*0.9);
- a.y=(froffsets[12]*(newkey/12)+froffsets[newkey%12])*wheight/2048.+notew*fpb;
- b.y=a.y+notew*0.9;
- a.y=wheight-a.y;b.y=wheight-b.y;
- }
- else
- {
- a.x=(froffsets[12]*(newkey/12)+froffsets[newkey%12])*wwidth/2048.+notew*fpb;
- b.x=a.x+notew*0.9;
- }
- nq.v[0].x=nq.v[3].x=a.x;nq.v[0].y=nq.v[1].y=a.y;
- nq.v[1].x=nq.v[2].x=b.x;nq.v[2].y=nq.v[3].y=b.y;for(int j=0;j<4;++j)
- nq.v[j].col=SETA(iccolors[i],204);
- sm->smRenderQuad(&nq);
- }
- }
+ double lpt = -(double)notestretch / api->getDivision() / 2.;
+ memset(notestatus, 0, sizeof(notestatus));
+ double notew = wwidth / 128, nh = showpiano ? wwidth / 2048.*172. : 0;
+ if (horizontal)
+ {
+ notew = wheight / 128;
+ nh = showpiano ? wheight / 2048.*172. : 0;
+ lpt = -lpt;
+ }
+ smQuad nq;
+ nq.blend = BLEND_ALPHABLEND;
+ nq.tex = 0;
+ for (int i = 0; i < 4; ++i)
+ nq.v[i].z = 0, nq.v[i].tx = nq.v[i].ty = 0;
+ for (uint32_t i = elb; i < pool.size(); ++i)
+ {
+ bool upperbound = ((double)pool[i]->tcs - ctk) * lpt + wheight - nh < 0;
+ bool lowerbound = fabs((double)pool[i]->tce - ctk) * lpt + wheight - nh < wheight;
+ if (horizontal)
+ {
+ upperbound = ((double)pool[i]->tcs - ctk) * lpt + nh > wwidth;
+ lowerbound = fabs((double)pool[i]->tce - ctk) * lpt + nh > 0;
+ }
+ if (upperbound)
+ break;
+ if (!upperbound || lowerbound)
+ {
+ if (pool[i]->ch == 999)
+ {
+ smvec2d a(0, ((double)pool[i]->tcs - ctk)*lpt + wheight - nh - minnotelength * 0.02);
+ smvec2d b(wwidth, ((double)pool[i]->tcs - ctk)*lpt + wheight - nh);
+ if (horizontal)
+ {
+ a = smvec2d(((double)pool[i]->tcs - ctk) * lpt + nh - minnotelength * 0.02, 0);
+ b = smvec2d(((double)pool[i]->tcs - ctk) * lpt + nh, wheight);
+ }
+ nq.v[0].x = nq.v[3].x = a.x;
+ nq.v[0].y = nq.v[1].y = a.y;
+ nq.v[1].x = nq.v[2].x = b.x;
+ nq.v[2].y = nq.v[3].y = b.y;
+ for (int j = 0; j < 4; ++j)
+ nq.v[j].col = 0xC0000000;
+ if (showmeasure)
+ sm->smRenderQuad(&nq);
+ continue;
+ }
+ if (pool[i]->ch >= 990)
+ continue;
+ if (api->getChannelMask(pool[i]->ch))
+ continue;
+ smvec2d a((froffsets[12] * (pool[i]->key / 12) + froffsets[pool[i]->key % 12])*wwidth / 2048., ((double)pool[i]->tce - ctk)*lpt + wheight - nh);
+ smvec2d b(a.x + notew * 0.9, ((double)pool[i]->tcs - ctk)*lpt + wheight - nh);
+ if (horizontal)
+ {
+ a = smvec2d(((double)pool[i]->tce - ctk) * lpt + nh, (froffsets[12] * (pool[i]->key / 12) + froffsets[pool[i]->key % 12]) * wheight / 2048.);
+ b = smvec2d(((double)pool[i]->tcs - ctk) * lpt + nh, a.y + notew * 0.9);
+ }
+ bool isnoteon = pool[i]->tcs <= ctk && pool[i]->tce >= ctk;
+ if (isnoteon)
+ {
+ double pb = ((int)cpw[pool[i]->ch] - 8192) / 8192.*cpbr[pool[i]->ch];
+ uint32_t newkey = pool[i]->key + (int)floor(pb);
+ double fpb = pb - floor(pb);
+ if (horizontal)
+ {
+ a.y = (froffsets[12] * (newkey / 12) + froffsets[newkey % 12]) * wheight / 2048. + notew * fpb;
+ b.y = a.y + notew * 0.9;
+ }
+ else
+ {
+ a.x = (froffsets[12] * (newkey / 12) + froffsets[newkey % 12]) * wwidth / 2048. + notew * fpb;
+ b.x = a.x + notew * 0.9;
+ }
+ }
+ if (horizontal)
+ a.y = wheight - a.y, b.y = wheight - b.y;
+ notestatus[pool[i]->ch][pool[i]->key] |= isnoteon;
+ if (horizontal)
+ {
+ if (((double)pool[i]->tce - pool[i]->tcs)*lpt < minnotelength * 0.04)
+ a.x = ((double)pool[i]->tcs - ctk) * lpt + nh - minnotelength * 0.04;
+ }
+ else
+ {
+ if (((double)pool[i]->tcs - pool[i]->tce)*lpt < minnotelength * 0.04)
+ a.y = ((double)pool[i]->tcs - ctk) * lpt + wheight - nh - minnotelength * 0.04;
+ }
+ nq.v[0].x = nq.v[3].x = a.x;
+ nq.v[0].y = nq.v[1].y = a.y;
+ nq.v[1].x = nq.v[2].x = b.x;
+ nq.v[2].y = nq.v[3].y = b.y;
+ for (int j = 0; j < 4; ++j)
+ nq.v[j].col = SETA(isnoteon ? accolors[pool[i]->ch] : iccolors[pool[i]->ch], int(pool[i]->vel * 1.6 + (isnoteon ? 52 : 32)));
+ if (usespectrum)
+ {
+ if (notestatus[pool[i]->ch][pool[i]->key] && !lastnotestatus[pool[i]->ch][pool[i]->key])
+ spectra[pool[i]->ch][pool[i]->key] = pool[i]->vel * (api->getChannelCC(pool[i]->ch, 7) / 127.);
+ }
+ else sm->smRenderQuad(&nq);
+ }
+ }
+ if (horizontal)
+ while (pool.size() && elb < pool.size() && fabs((double)pool[elb]->tce - ctk)*lpt + nh < 0)++elb;
+ else
+ while (pool.size() && elb < pool.size() && fabs((double)pool[elb]->tce - ctk)*lpt + wheight - nh > wheight)++elb;
+ smQuad q;
+ q.tex = pianotex;
+ q.blend = BLEND_ALPHABLEND;
+ for (int i = 0; i < 4; ++i)
+ q.v[i].col = 0xFFFFFFFF, q.v[i].z = 0;
+ q.v[0].ty = q.v[3].ty = 0;
+ q.v[1].ty = q.v[2].ty = 172. / 256.;
+ q.v[0].tx = q.v[1].tx = 0;
+ q.v[2].tx = q.v[3].tx = 1.;
+ q.v[0].x = q.v[1].x = 0;
+ q.v[2].x = q.v[3].x = wwidth;
+ q.v[0].y = q.v[3].y = wheight - nh;
+ q.v[1].y = q.v[2].y = wheight;
+ if (horizontal)
+ {
+ q.v[0].tx = q.v[3].tx = 0;
+ q.v[1].tx = q.v[2].tx = 1;
+ q.v[0].ty = q.v[1].ty = 0;
+ q.v[2].ty = q.v[3].ty = 172. / 256.;
+ q.v[0].x = q.v[1].x = nh;
+ q.v[2].x = q.v[3].x = 0;
+ q.v[0].y = q.v[3].y = wheight;
+ q.v[1].y = q.v[2].y = 0;
+ }
+ sm->smRenderQuad(&q);
+ for (int i = 0, j; i < 128; ++i)
+ {
+ DWORD c = 0;
+ for (j = 0; j < 16; ++j)
+ if (notestatus[j][i])
+ {
+ c = SETA(iccolors[j], 0xFF);
+ break;
+ }
+ if (horizontal)
+ {
+ q.v[0].y = q.v[1].y = (fpoffsets[12] * (i / 12) + fpoffsets[i % 12]) * wheight / 2048.;
+ q.v[2].y = q.v[3].y = q.v[0].y;
+ q.v[0].x = q.v[3].x = nh;
+ q.v[1].x = q.v[2].x = 0;
+ }
+ else
+ {
+ q.v[0].x = q.v[1].x = (fpoffsets[12] * (i / 12) + fpoffsets[i % 12]) * wwidth / 2048.;
+ q.v[2].x = q.v[3].x = q.v[0].x;
+ q.v[0].y = q.v[3].y = wheight - nh;
+ q.v[1].y = q.v[2].y = wheight;
+ }
+ if (!c)
+ continue;
+ for (int j = 0; j < 4; ++j)
+ q.v[j].col = c;
+ switch (i % 12)
+ {
+ case 1:
+ case 3:
+ case 6:
+ case 8:
+ case 10:
+ if (horizontal)
+ {
+ q.v[1].x = q.v[2].x = nh - 115 * wheight / 2048.;
+ q.v[2].y += 15.*wheight / 2048;
+ q.v[3].y += 15.*wheight / 2048;
+ }
+ else
+ {
+ q.v[1].y = q.v[2].y = wheight - nh + 115 * wwidth / 2048.;
+ q.v[2].x += 15.*wwidth / 2048;
+ q.v[3].x += 15.*wwidth / 2048;
+ }
+ q.v[0].ty = q.v[1].ty = 1.;
+ q.v[2].ty = q.v[3].ty = 1. - 15 / 256.;
+ q.v[0].tx = q.v[3].tx = 1344 / 2048.;
+ q.v[1].tx = q.v[2].tx = 1459 / 2048.;
+ break;
+ case 0:
+ if (horizontal)
+ {
+ q.v[2].y += 27.*wheight / 2048;
+ q.v[3].y += 27.*wheight / 2048;
+ }
+ else
+ {
+ q.v[2].x += 27.*wwidth / 2048;
+ q.v[3].x += 27.*wwidth / 2048;
+ }
+ q.v[0].ty = q.v[1].ty = 1.;
+ q.v[2].ty = q.v[3].ty = 1. - 27 / 256.;
+ q.v[0].tx = q.v[3].tx = 0 / 2048.;
+ q.v[1].tx = q.v[2].tx = 172 / 2048.;
+ break;
+ case 2:
+ if (horizontal)
+ {
+ q.v[2].y += 29.*wheight / 2048;
+ q.v[3].y += 29.*wheight / 2048;
+ }
+ else
+ {
+ q.v[2].x += 29.*wwidth / 2048;
+ q.v[3].x += 29.*wwidth / 2048;
+ }
+ q.v[0].ty = q.v[1].ty = 1.;
+ q.v[2].ty = q.v[3].ty = 1. - 29 / 256.;
+ q.v[0].tx = q.v[3].tx = 192 / 2048.;
+ q.v[1].tx = q.v[2].tx = 364 / 2048.;
+ break;
+ case 4:
+ if (horizontal)
+ {
+ q.v[2].y += 28.*wheight / 2048;
+ q.v[3].y += 28.*wheight / 2048;
+ }
+ else
+ {
+ q.v[2].x += 28.*wwidth / 2048;
+ q.v[3].x += 28.*wwidth / 2048;
+ }
+ q.v[0].ty = q.v[1].ty = 1.;
+ q.v[2].ty = q.v[3].ty = 1. - 28 / 256.;
+ q.v[0].tx = q.v[3].tx = 384 / 2048.;
+ q.v[1].tx = q.v[2].tx = 556 / 2048.;
+ break;
+ case 5:
+ if (horizontal)
+ {
+ q.v[2].y += 28.*wheight / 2048;
+ q.v[3].y += 28.*wheight / 2048;
+ }
+ else
+ {
+ q.v[2].x += 28.*wwidth / 2048;
+ q.v[3].x += 28.*wwidth / 2048;
+ }
+ q.v[0].ty = q.v[1].ty = 1.;
+ q.v[2].ty = q.v[3].ty = 1. - 28 / 256.;
+ q.v[0].tx = q.v[3].tx = 576 / 2048.;
+ q.v[1].tx = q.v[2].tx = 748 / 2048.;
+ break;
+ case 7:
+ if (horizontal)
+ {
+ q.v[2].y += 29.*wheight / 2048;
+ q.v[3].y += 29.*wheight / 2048;
+ }
+ else
+ {
+ q.v[2].x += 29.*wwidth / 2048;
+ q.v[3].x += 29.*wwidth / 2048;
+ }
+ q.v[0].ty = q.v[1].ty = 1.;
+ q.v[2].ty = q.v[3].ty = 1. - 29 / 256.;
+ q.v[0].tx = q.v[3].tx = 768 / 2048.;
+ q.v[1].tx = q.v[2].tx = 940 / 2048.;
+ break;
+ case 9:
+ if (horizontal)
+ {
+ q.v[2].y += 28.*wheight / 2048;
+ q.v[3].y += 28.*wheight / 2048;
+ }
+ else
+ {
+ q.v[2].x += 28.*wwidth / 2048;
+ q.v[3].x += 28.*wwidth / 2048;
+ }
+ q.v[0].ty = q.v[1].ty = 1.;
+ q.v[2].ty = q.v[3].ty = 1. - 28 / 256.;
+ q.v[0].tx = q.v[3].tx = 960 / 2048.;
+ q.v[1].tx = q.v[2].tx = 1132 / 2048.;
+ break;
+ case 11:
+ if (horizontal)
+ {
+ q.v[2].y += 28.*wheight / 2048;
+ q.v[3].y += 28.*wheight / 2048;
+ }
+ else
+ {
+ q.v[2].x += 28.*wwidth / 2048;
+ q.v[3].x += 28.*wwidth / 2048;
+ }
+ q.v[0].ty = q.v[1].ty = 1.;
+ q.v[2].ty = q.v[3].ty = 1. - 28 / 256.;
+ q.v[0].tx = q.v[3].tx = 1152 / 2048.;
+ q.v[1].tx = q.v[2].tx = 1324 / 2048.;
+ break;
+ }
+ if (horizontal)
+ for (int j = 0; j < 4; ++j)
+ q.v[j].y = wheight - q.v[j].y;
+ sm->smRenderQuad(&q);
+ }
+ if (usespectrum && playing)
+ for (int i = 0; i < 16; ++i)
+ for (int j = 0; j < 128; ++j)
+ {
+ if (sustaininst.find(api->getChannelPreset(i)) != sustaininst.end())
+ {
+ if (!notestatus[i][j] && spectra[i][j])
+ spectra[i][j] = .95 * spectra[i][j];
+ }
+ else if (spectra[i][j])
+ spectra[i][j] = .95 * spectra[i][j];
+ if (spectrar[i][j] < spectra[i][j] * 0.9)
+ spectrar[i][j] += spectra[i][j] * 0.2;
+ else spectrar[i][j] = spectra[i][j];
+ if (spectrar[i][j])
+ {
+ smvec2d a((froffsets[12] * (j / 12) + froffsets[j % 12])*wwidth / 2048., spectrar[i][j] / -128.*(wheight - nh) * (1 + 0.02 * sin(sm->smGetTime() * 32)) + wheight - nh);
+ smvec2d b(a.x + notew * 0.9, lpt + wheight - nh);
+ double pb = ((int)cpw[i] - 8192) / 8192.*cpbr[i];
+ uint32_t newkey = j + (int)floor(pb);
+ double fpb = pb - floor(pb);
+ if (horizontal)
+ {
+ a = smvec2d(spectrar[i][j] / 128.*(wwidth - nh) * (1 + 0.02 * sin(sm->smGetTime() * 32)) + nh, (froffsets[12] * (j / 12) + froffsets[j % 12]) * wheight / 2048.);
+ b = smvec2d(nh, a.y + notew * 0.9);
+ a.y = (froffsets[12] * (newkey / 12) + froffsets[newkey % 12]) * wheight / 2048. + notew * fpb;
+ b.y = a.y + notew * 0.9;
+ a.y = wheight - a.y;
+ b.y = wheight - b.y;
+ }
+ else
+ {
+ a.x = (froffsets[12] * (newkey / 12) + froffsets[newkey % 12]) * wwidth / 2048. + notew * fpb;
+ b.x = a.x + notew * 0.9;
+ }
+ nq.v[0].x = nq.v[3].x = a.x;
+ nq.v[0].y = nq.v[1].y = a.y;
+ nq.v[1].x = nq.v[2].x = b.x;
+ nq.v[2].y = nq.v[3].y = b.y;
+ for (int j = 0; j < 4; ++j)
+ nq.v[j].col = SETA(iccolors[i], 204);
+ sm->smRenderQuad(&nq);
+ }
+ }
}
bool qmpVisualization::update()
{
- smQuad q;
- if(!rendermode)
- {
- if(sm->smGetKeyState(SMK_RIGHT)==SMKST_HIT)
- api->playerSeek(api->getCurrentPlaybackPercentage()+(sm->smGetKeyState(SMK_SHIFT)?5:1));
- if(sm->smGetKeyState(SMK_LEFT)==SMKST_HIT)
- api->playerSeek(api->getCurrentPlaybackPercentage()-(sm->smGetKeyState(SMK_SHIFT)?5:1));
- if(sm->smGetKeyState(SMK_B)==SMKST_HIT)
- debug^=1;
- }
- if(playing)
- {
- if(rendermode)
- {
- ctk=1e6*(cfr)/tfps/ctp*api->getDivision()+lstk;
- ++cfr;
- }
- else
- ctk=lstk+std::chrono::duration_cast<std::chrono::duration<double,std::micro>>(std::chrono::steady_clock::now()-lst).count()/api->getRawTempo()*api->getDivision();
- }
- if(!flat)
- updateVisualization3D();
- sm->smRenderBegin2D();
- sm->smClrscr(0xFF666666);q.blend=BLEND_ALPHABLEND;
- for(int i=0;i<4;++i){q.v[i].col=0xFFFFFFFF;q.v[i].z=0;}
- if(bgtex)
- {
- q.tex=bgtex;
- q.v[0].x=q.v[3].x=0;q.v[1].x=q.v[2].x=wwidth;
- q.v[0].y=q.v[1].y=0;q.v[2].y=q.v[3].y=wheight;
- q.v[0].tx=q.v[3].tx=0;q.v[1].tx=q.v[2].tx=1;
- q.v[0].ty=q.v[1].ty=0;q.v[2].ty=q.v[3].ty=1;
- sm->smRenderQuad(&q);
- }
- if(flat)
- updateVisualization2D();
- else
- {
- q.tex=sm->smTargetTexture(tdscn);
- q.v[0].tx=q.v[3].tx=0;q.v[1].tx=q.v[2].tx=1;
- q.v[0].ty=q.v[1].ty=0;q.v[2].ty=q.v[3].ty=1;
- q.v[0].x=q.v[1].x=0;q.v[2].x=q.v[3].x=wwidth;
- q.v[0].y=q.v[3].y=0;q.v[1].y=q.v[2].y=wheight;
- sm->smRenderQuad(&q);
- if(showparticle&&!horizontal)
- {
- q.tex=sm->smTargetTexture(tdparticles);
- sm->smRenderQuad(&q);
- }
- }
- if(osdpos==4){sm->smRenderEnd();return shouldclose;}
- uint32_t ltpc=~0u;
- for(uint32_t i=elb;i<pool.size();++i)
- {
- if(pool[i]->tcs>ctk)break;
- if(pool[i]->ch==998)cts=pool[i]->key;
- if(pool[i]->ch==997)cks=pool[i]->key;
- if(pool[i]->ch==996)
- ltpc=i;
- if(pool[i]->ch==995)cpbr[pool[i]->vel]=pool[i]->key;
- if(pool[i]->ch==994)cpw[pool[i]->vel]=pool[i]->key;
- }
- if(~ltpc&&ctp!=pool[ltpc]->key)
- {
- ctp=pool[ltpc]->key;
- if(rendermode)
- {
- lstk=pool[ltpc]->tcs;
- cfr=1;
- }
- }
- int t,r;t=cks;r=(int8_t)((t>>8)&0xFF)+7;t&=0xFF;
- std::wstring ts(t?minors:majors,2*r,2);
- int step=int(1.33*fontsize);
- int xp=(osdpos&1)?wwidth-step-1:1;
- int yp=osdpos<2?wheight-step*5-4:step+4;
- int align=osdpos&1?ALIGN_RIGHT:ALIGN_LEFT;
- font2.updateString(L"Title: %ls",api->getWTitle().c_str());
- font2.render(xp,yp,0.5,0xFFFFFFFF,align);
- font2.render(xp-1,yp-1,0.5,0xFF000000,align);
- font.updateString(L"Time Sig: %d/%d",cts>>8,1<<(cts&0xFF));
- font.render(xp,yp+=step,0.5,0xFFFFFFFF,align);
- font.render(xp-1,yp-1,0.5,0xFF000000,align);
- font.updateString(L"Key Sig: %ls",ts.c_str());
- font.render(xp,yp+=step,0.5,0xFFFFFFFF,align);
- font.render(xp-1,yp-1,0.5,0xFF000000,align);
- font.updateString(L"Tempo: %.2f",60./(ctp/1e6));
- font.render(xp,yp+=step,0.5,0xFFFFFFFF,align);
- font.render(xp-1,yp-1,0.5,0xFF000000,align);
- font.updateString(L"Current tick: %d",ctk);
- font.render(xp,yp+=step,0.5,0xFFFFFFFF,align);
- font.render(xp-1,yp-1,0.5,0xFF000000,align);
- if(!rendermode)
- {
- font.updateString(L"FPS: %.2f",sm->smGetFPS());
- font.render(xp,yp+=step,0.5,0xFFFFFFFF,align);
- font.render(xp-1,yp-1,0.5,0xFF000000,align);
- }
- if(debug)
- {
- int dosdpos=(osdpos+1)%4;
- xp=(dosdpos&1)?wwidth-step-1:1;
- yp=dosdpos<2?wheight-step*5-4:step+4;
- align=dosdpos&1?ALIGN_RIGHT:ALIGN_LEFT;
- std::string tstr;
- tstr=std::string(sm->smGetOSInfo());
- font.updateString(L"OS: %ls",std::wstring({std::begin(tstr),std::end(tstr)}).c_str());
- font.render(xp,yp,0.5,0xFFFFFFFF,align);
- font.render(xp-1,yp-1,0.5,0xFF000000,align);
- tstr=std::string(sm->smGetCPUModel());
- font.updateString(L"CPU: %ls",std::wstring({std::begin(tstr),std::end(tstr)}).c_str());
- font.render(xp,yp+=step,0.5,0xFFFFFFFF,align);
- font.render(xp-1,yp-1,0.5,0xFF000000,align);
- tstr=std::string(sm->smGetDispDriver());
- font.updateString(L"Display %ls",std::wstring({std::begin(tstr),std::end(tstr)}).c_str());
- font.render(xp,yp+=3*step,0.5,0xFFFFFFFF,align);
- font.render(xp-1,yp-1,0.5,0xFF000000,align);
- }
- sm->smRenderEnd();
- if(rendermode)
- {
- if(ctk>api->getMaxTick())
- framecb(nullptr,0,ctk,api->getMaxTick());
- else
- {
- sm->smPixelCopy(0,0,wwidth,wheight,4*wwidth*wheight,fbcont);
- framecb(fbcont,4*wwidth*wheight,ctk,api->getMaxTick());
- }
- }
- return shouldclose;
+ smQuad q;
+ if (!rendermode)
+ {
+ if (sm->smGetKeyState(SMK_RIGHT) == SMKST_HIT)
+ api->playerSeek(api->getCurrentPlaybackPercentage() + (sm->smGetKeyState(SMK_SHIFT) ? 5 : 1));
+ if (sm->smGetKeyState(SMK_LEFT) == SMKST_HIT)
+ api->playerSeek(api->getCurrentPlaybackPercentage() - (sm->smGetKeyState(SMK_SHIFT) ? 5 : 1));
+ if (sm->smGetKeyState(SMK_B) == SMKST_HIT)
+ debug ^= 1;
+ }
+ if (playing)
+ {
+ if (rendermode)
+ {
+ ctk = 1e6 * (cfr) / tfps / ctp * api->getDivision() + lstk;
+ ++cfr;
+ }
+ else
+ ctk = lstk + std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(std::chrono::steady_clock::now() - lst).count() / api->getRawTempo() * api->getDivision();
+ }
+ if (!flat)
+ updateVisualization3D();
+ sm->smRenderBegin2D();
+ sm->smClrscr(0xFF666666);
+ q.blend = BLEND_ALPHABLEND;
+ for (int i = 0; i < 4; ++i)
+ {
+ q.v[i].col = 0xFFFFFFFF;
+ q.v[i].z = 0;
+ }
+ if (bgtex)
+ {
+ q.tex = bgtex;
+ q.v[0].x = q.v[3].x = 0;
+ q.v[1].x = q.v[2].x = wwidth;
+ q.v[0].y = q.v[1].y = 0;
+ q.v[2].y = q.v[3].y = wheight;
+ q.v[0].tx = q.v[3].tx = 0;
+ q.v[1].tx = q.v[2].tx = 1;
+ q.v[0].ty = q.v[1].ty = 0;
+ q.v[2].ty = q.v[3].ty = 1;
+ sm->smRenderQuad(&q);
+ }
+ if (flat)
+ updateVisualization2D();
+ else
+ {
+ q.tex = sm->smTargetTexture(tdscn);
+ q.v[0].tx = q.v[3].tx = 0;
+ q.v[1].tx = q.v[2].tx = 1;
+ q.v[0].ty = q.v[1].ty = 0;
+ q.v[2].ty = q.v[3].ty = 1;
+ q.v[0].x = q.v[1].x = 0;
+ q.v[2].x = q.v[3].x = wwidth;
+ q.v[0].y = q.v[3].y = 0;
+ q.v[1].y = q.v[2].y = wheight;
+ sm->smRenderQuad(&q);
+ if (showparticle && !horizontal)
+ {
+ q.tex = sm->smTargetTexture(tdparticles);
+ sm->smRenderQuad(&q);
+ }
+ }
+ if (osdpos == 4)
+ {
+ sm->smRenderEnd();
+ return shouldclose;
+ }
+ uint32_t ltpc = ~0u;
+ for (uint32_t i = elb; i < pool.size(); ++i)
+ {
+ if (pool[i]->tcs > ctk)
+ break;
+ if (pool[i]->ch == 998)
+ cts = pool[i]->key;
+ if (pool[i]->ch == 997)
+ cks = pool[i]->key;
+ if (pool[i]->ch == 996)
+ ltpc = i;
+ if (pool[i]->ch == 995)
+ cpbr[pool[i]->vel] = pool[i]->key;
+ if (pool[i]->ch == 994)
+ cpw[pool[i]->vel] = pool[i]->key;
+ }
+ if (~ltpc && ctp != pool[ltpc]->key)
+ {
+ ctp = pool[ltpc]->key;
+ if (rendermode)
+ {
+ lstk = pool[ltpc]->tcs;
+ cfr = 1;
+ }
+ }
+ int t, r;
+ t = cks;
+ r = (int8_t)((t >> 8) & 0xFF) + 7;
+ t &= 0xFF;
+ std::wstring ts(t ? minors : majors, 2 * r, 2);
+ int step = int(1.33 * fontsize);
+ int xp = (osdpos & 1) ? wwidth - step - 1 : 1;
+ int yp = osdpos < 2 ? wheight - step * 5 - 4 : step + 4;
+ int align = osdpos & 1 ? ALIGN_RIGHT : ALIGN_LEFT;
+ font2.updateString(L"Title: %ls", api->getWTitle().c_str());
+ font2.render(xp, yp, 0.5, 0xFFFFFFFF, align);
+ font2.render(xp - 1, yp - 1, 0.5, 0xFF000000, align);
+ font.updateString(L"Time Sig: %d/%d", cts >> 8, 1 << (cts & 0xFF));
+ font.render(xp, yp += step, 0.5, 0xFFFFFFFF, align);
+ font.render(xp - 1, yp - 1, 0.5, 0xFF000000, align);
+ font.updateString(L"Key Sig: %ls", ts.c_str());
+ font.render(xp, yp += step, 0.5, 0xFFFFFFFF, align);
+ font.render(xp - 1, yp - 1, 0.5, 0xFF000000, align);
+ font.updateString(L"Tempo: %.2f", 60. / (ctp / 1e6));
+ font.render(xp, yp += step, 0.5, 0xFFFFFFFF, align);
+ font.render(xp - 1, yp - 1, 0.5, 0xFF000000, align);
+ font.updateString(L"Current tick: %d", ctk);
+ font.render(xp, yp += step, 0.5, 0xFFFFFFFF, align);
+ font.render(xp - 1, yp - 1, 0.5, 0xFF000000, align);
+ if (!rendermode)
+ {
+ font.updateString(L"FPS: %.2f", sm->smGetFPS());
+ font.render(xp, yp += step, 0.5, 0xFFFFFFFF, align);
+ font.render(xp - 1, yp - 1, 0.5, 0xFF000000, align);
+ }
+ if (debug)
+ {
+ int dosdpos = (osdpos + 1) % 4;
+ xp = (dosdpos & 1) ? wwidth - step - 1 : 1;
+ yp = dosdpos < 2 ? wheight - step * 5 - 4 : step + 4;
+ align = dosdpos & 1 ? ALIGN_RIGHT : ALIGN_LEFT;
+ std::string tstr;
+ tstr = std::string(sm->smGetOSInfo());
+ font.updateString(L"OS: %ls", std::wstring({std::begin(tstr), std::end(tstr)}).c_str());
+ font.render(xp, yp, 0.5, 0xFFFFFFFF, align);
+ font.render(xp - 1, yp - 1, 0.5, 0xFF000000, align);
+ tstr = std::string(sm->smGetCPUModel());
+ font.updateString(L"CPU: %ls", std::wstring({std::begin(tstr), std::end(tstr)}).c_str());
+ font.render(xp, yp += step, 0.5, 0xFFFFFFFF, align);
+ font.render(xp - 1, yp - 1, 0.5, 0xFF000000, align);
+ tstr = std::string(sm->smGetDispDriver());
+ font.updateString(L"Display %ls", std::wstring({std::begin(tstr), std::end(tstr)}).c_str());
+ font.render(xp, yp += 3 * step, 0.5, 0xFFFFFFFF, align);
+ font.render(xp - 1, yp - 1, 0.5, 0xFF000000, align);
+ }
+ sm->smRenderEnd();
+ if (rendermode)
+ {
+ if (ctk > api->getMaxTick())
+ framecb(nullptr, 0, ctk, api->getMaxTick());
+ else
+ {
+ sm->smPixelCopy(0, 0, wwidth, wheight, 4 * wwidth * wheight, fbcont);
+ framecb(fbcont, 4 * wwidth * wheight, ctk, api->getMaxTick());
+ }
+ }
+ return shouldclose;
}
-void qmpVisualization::drawCube(smvec3d a,smvec3d b,DWORD col,SMTEX tex,int faces)
+void qmpVisualization::drawCube(smvec3d a, smvec3d b, DWORD col, SMTEX tex, int faces)
{
- smQuad q;q.blend=BLEND_ALPHABLEND;
- q.tex=tex;for(int i=0;i<4;++i)q.v[i].col=col;
- if(noteappearance==1)
- {
- smMatrix I;I.loadIdentity();smEntity3D c=smEntity3D::cube(a,b,col,faces);
- nebuf->addTransformedEntity(&c,I,smvec3d(0,0,0));
- }
- else
- {
- q.v[0].x=a.x;q.v[0].y=b.y;q.v[0].z=a.z;
- q.v[1].x=b.x;q.v[1].y=b.y;q.v[1].z=a.z;
- q.v[2].x=b.x;q.v[2].y=b.y;q.v[2].z=b.z;
- q.v[3].x=a.x;q.v[3].y=b.y;q.v[3].z=b.z;
- sm->smRenderQuad(&q);
- }
+ smQuad q;
+ q.blend = BLEND_ALPHABLEND;
+ q.tex = tex;
+ for (int i = 0; i < 4; ++i)
+ q.v[i].col = col;
+ if (noteappearance == 1)
+ {
+ smMatrix I;
+ I.loadIdentity();
+ smEntity3D c = smEntity3D::cube(a, b, col, faces);
+ nebuf->addTransformedEntity(&c, I, smvec3d(0, 0, 0));
+ }
+ else
+ {
+ q.v[0].x = a.x;
+ q.v[0].y = b.y;
+ q.v[0].z = a.z;
+ q.v[1].x = b.x;
+ q.v[1].y = b.y;
+ q.v[1].z = a.z;
+ q.v[2].x = b.x;
+ q.v[2].y = b.y;
+ q.v[2].z = b.z;
+ q.v[3].x = a.x;
+ q.v[3].y = b.y;
+ q.v[3].z = b.z;
+ sm->smRenderQuad(&q);
+ }
}
-qmpVisualization* qmpVisualization::inst=nullptr;
+qmpVisualization *qmpVisualization::inst = nullptr;
-qmpVisualization::qmpVisualization(qmpPluginAPI* _api)
+qmpVisualization::qmpVisualization(qmpPluginAPI *_api)
{
- api=_api;
- inst=this;
- rendermode=false;
- hidewindow=false;
+ api = _api;
+ inst = this;
+ rendermode = false;
+ hidewindow = false;
}
qmpVisualization::~qmpVisualization()
{
- api=nullptr;
- inst=nullptr;
+ api = nullptr;
+ inst = nullptr;
}
void qmpVisualization::init()
{
- h=new CMidiVisualHandler(this);
- closeh=new CloseHandler(this);
- rendererTh=nullptr;playing=false;
- memset(rpnid,0xFF,sizeof(rpnid));
- memset(rpnval,0xFF,sizeof(rpnval));
- memset(spectra,0,sizeof(spectra));
- memset(spectrar,0,sizeof(spectrar));
- api->registerFunctionality(this,"Visualization","Visualization",api->isDarkTheme()?":/img/visualization_i.svg":":/img/visualization.svg",0,true);
- uihb=api->registerUIHook("main.start",[this](const void*,void*){this->start();},nullptr);
- uihs=api->registerUIHook("main.stop",[this](const void*,void*){this->stop();},nullptr);
- uihp=api->registerUIHook("main.pause",[this](const void*,void*){this->pause();},nullptr);
- uihr=api->registerUIHook("main.reset",[this](const void*,void*){this->reset();},nullptr);
- uihk=api->registerUIHook("main.seek",[this](const void*,void*){
- cts=api->getTimeSig();
- cks=api->getKeySig();
- ctp=api->getRawTempo();
- for(int i=0;i<16;++i)
- api->getPitchBendRaw(i,&cpw[i],&cpbr[i]);
- },nullptr);
- herh=api->registerEventReadHandler(
- [this](const void *ee,void*){
- const SEvent* e=(const SEvent*)ee;
- switch(e->type&0xF0)
- {
- case 0x80:
- this->pushNoteOff(e->time,e->type&0x0F,e->p1);
- break;
- case 0x90:
- if(e->p2)
- this->pushNoteOn(e->time,e->type&0x0F,e->p1,e->p2);
- else
- this->pushNoteOff(e->time,e->type&0x0F,e->p1);
- break;
- case 0xB0:
- if(e->p1==100)rpnid[e->type&0x0F]=e->p2;
- if(e->p1==6)rpnval[e->type&0x0F]=e->p2;
- if(~rpnid[e->type&0x0F]&&~rpnval[e->type&0x0F])
- {
- if(rpnid[e->type&0x0F]==0)
- this->pool.push_back(new MidiVisualEvent{e->time,e->time,rpnval[e->type&0x0F],e->type&0x0Fu,995});
- rpnval[e->type&0x0F]=~0u;
- }
- break;
- case 0xE0:
- this->pool.push_back(new MidiVisualEvent{e->time,e->time,(e->p1|(e->p2<<7))&0x3FFFu,e->type&0x0Fu,994});
- break;
- case 0xF0:
- if(e->type==0xFF&&e->p1==0x58)
- {
- this->tspool.push_back(std::make_pair(e->time,(e->str[0]<<24)|(e->str[1]<<16)));
- this->pool.push_back(new MidiVisualEvent{e->time,e->time,(e->str[0]&0xffu)<<8|(e->str[1]&0xffu),0,998});
- }
- else if(e->type==0xFF&&e->p1==0x59)
- this->pool.push_back(new MidiVisualEvent{e->time,e->time,(e->str[0]&0xffu)<<8|(e->str[1]&0xffu),0,997});
- else if(e->type==0xFF&&e->p1==0x51)
- this->pool.push_back(new MidiVisualEvent{e->time,e->time,(e->str[0]&0xffu)<<16|(e->str[1]&0xffu)<<8|(e->str[2]&0xffu),0,996});
- break;
- }
- }
- ,nullptr);
- heh=api->registerEventHandler(
- [this](const void*,void*){
- if(this->ctk>this->api->getCurrentTimeStamp()+this->api->getDivision()/3)
- this->elb=0;
- /*if(abs((int)this->ctk-(int)this->api->getCurrentTimeStamp())>this->api->getDivision()/4)
- fprintf(stderr,"Visualization: out of sync! %u vs %u ad: %u\n",this->ctk,this->api->getCurrentTimeStamp());*/
- this->ctk=this->api->getCurrentTimeStamp();
- this->lstk=this->ctk;
- this->lst=std::chrono::steady_clock::now();
- }
- ,nullptr);
- hfrf=api->registerFileReadFinishHook(
- [this](const void*,void*){
- memset(rpnval,0xFF,sizeof(rpnval));
- memset(rpnid,0xFF,sizeof(rpnid));
- std::sort(this->tspool.begin(),this->tspool.end());
- for(uint32_t tk=0,n=4,s=0;tk<=this->api->getMaxTick();){
- while(tk<(s>=this->tspool.size()?this->api->getMaxTick():this->tspool[s].first)){
- this->pool.push_back(new MidiVisualEvent{tk,tk,0,0,999});
- tk+=n*this->api->getDivision();
- }
- tk=(s>=this->tspool.size()?this->api->getMaxTick():this->tspool[s].first);
- if(tk==this->api->getMaxTick()){
- this->pool.push_back(new MidiVisualEvent{tk,tk,0,0,999});
- ++tk;break;
- }
- else n=this->tspool[s++].second>>24;
- }
- std::sort(this->pool.begin(),this->pool.end(),cmp);
- }
- ,nullptr);
- api->registerOptionBool("Visualization-Appearance","Show Piano","Visualization/showpiano",true);
- api->registerOptionBool("Visualization-Appearance","3D Notes","Visualization/3dnotes",true);
- api->registerOptionBool("Visualization-Appearance","Arrange channels on a stair","Visualization/stairpiano",true);
- api->registerOptionBool("Visualization-Appearance","Show channel labels","Visualization/showlabel",true);
- api->registerOptionBool("Visualization-Appearance","Show Particles","Visualization/showparticle",false);
- api->registerOptionBool("Visualization-Appearance","Horizontal Visualization","Visualization/horizontal",false);
- api->registerOptionBool("Visualization-Appearance","2D Visualization","Visualization/flat",false);
- api->registerOptionBool("Visualization-Appearance","Show Measure Indicator","Visualization/showmeasure",true);
- api->registerOptionBool("Visualization-Appearance","Use spectrum instead of piano roll","Visualization/usespectrum",false);
- api->registerOptionBool("Visualization-Video","Enable VSync","Visualization/vsync",true);
- api->registerOptionBool("Visualization-Video","Save Viewport","Visualization/savevp",true);
- api->registerOptionInt("Visualization-Video","Window Width","Visualization/wwidth",320,3200,800);
- api->registerOptionInt("Visualization-Video","Window Height","Visualization/wheight",320,3200,600);
- api->registerOptionInt("Visualization-Video","Target FPS","Visualization/tfps",5,1000,60);
- api->registerOptionInt("Visualization-Video","Supersampling","Visualization/supersampling",1,16,0);
- api->registerOptionInt("Visualization-Video","Multisampling","Visualization/multisampling",0,16,0);
- api->registerOptionInt("Visualization-Video","FOV","Visualization/fov",30,180,60);
- std::vector<std::string> tv;tv.push_back("Bottom left");tv.push_back("Bottom right");tv.push_back("Top left");tv.push_back("Top right");tv.push_back("Hidden");
- api->registerOptionEnumInt("Visualization-Video","OSD Position","Visualization/osdpos",tv,0);
- api->registerOptionInt("Visualization-Video","Font Size","Visualization/fontsize",6,180,16);
- api->registerOptionString("Visualization-Video","Custom Sans Font","Visualization/font1","",true);
- api->registerOptionString("Visualization-Video","Custom Monospace Font","Visualization/font2","",true);
- api->registerOptionInt("Visualization-Appearance","View distance","Visualization/viewdist",20,1000,100);
- api->registerOptionInt("Visualization-Appearance","Note stretch","Visualization/notestretch",20,500,100);
- api->registerOptionInt("Visualization-Appearance","Minimum note length","Visualization/minnotelen",20,500,100);
- api->registerOptionUint("Visualization-Appearance","Chequer board tint (AARRGGBB)","Visualization/chkrtint",0,0xFFFFFFFF,0xFF999999);
- api->registerOptionString("Visualization-Appearance","Background Image","Visualization/background","",true);
- api->registerOptionDouble("","","Visualization/px",-999999999,999999999,-1e9);
- api->registerOptionDouble("","","Visualization/py",-999999999,999999999,-1e9);
- api->registerOptionDouble("","","Visualization/pz",-999999999,999999999,-1e9);
- api->registerOptionDouble("","","Visualization/rx",-999999999,999999999,-1e9);
- api->registerOptionDouble("","","Visualization/ry",-999999999,999999999,-1e9);
- api->registerOptionDouble("","","Visualization/rz",-999999999,999999999,-1e9);
- for(int i=0;i<16;++i)
- {
- api->registerOptionUint("","","Visualization/chActiveColor"+std::to_string(i),0,0xFFFFFFFF,accolors[i]);
- api->registerOptionUint("","","Visualization/chInactiveColor"+std::to_string(i),0,0xFFFFFFFF,iccolors[i]);
- }
- wwidth=api->getOptionInt("Visualization/wwidth");
- wheight=api->getOptionInt("Visualization/wheight");
- wsupersample=api->getOptionInt("Visualization/supersampling");
- wmultisample=api->getOptionInt("Visualization/multisampling");
- fov=api->getOptionInt("Visualization/fov");
- noteappearance=api->getOptionBool("Visualization/3dnotes");
- showpiano=api->getOptionBool("Visualization/showpiano");
- stairpiano=api->getOptionBool("Visualization/stairpiano");
- showlabel=api->getOptionBool("Visualization/showlabel");
- showparticle=api->getOptionBool("Visualization/showparticle");
- horizontal=api->getOptionBool("Visualization/horizontal");
- flat=api->getOptionBool("Visualization/flat");
- savevp=api->getOptionBool("Visualization/savevp");
- vsync=api->getOptionBool("Visualization/vsync");
- tfps=api->getOptionInt("Visualization/tfps");
- osdpos=api->getOptionEnumInt("Visualization/osdpos");
- fontsize=api->getOptionInt("Visualization/fontsize");
- viewdist=api->getOptionInt("Visualization/viewdist");
- notestretch=api->getOptionInt("Visualization/notestretch");
- minnotelength=api->getOptionInt("Visualization/minnotelen");
- chkrtint=api->getOptionUint("Visualization/chkrtint");
- for(int i=0;i<16;++i)
- {
- accolors[i]=api->getOptionUint("Visualization/chActiveColor"+std::to_string(i));
- iccolors[i]=api->getOptionUint("Visualization/chInactiveColor"+std::to_string(i));
- }
- if(savevp)
- {
- pos[0]=api->getOptionDouble("Visualization/px");
- pos[1]=api->getOptionDouble("Visualization/py");
- pos[2]=api->getOptionDouble("Visualization/pz");
- rot[0]=api->getOptionDouble("Visualization/rx");
- rot[1]=api->getOptionDouble("Visualization/ry");
- rot[2]=api->getOptionDouble("Visualization/rz");
- }
- memset(pss,0,sizeof(pss));
+ h = new CMidiVisualHandler(this);
+ closeh = new CloseHandler(this);
+ rendererTh = nullptr;
+ playing = false;
+ memset(rpnid, 0xFF, sizeof(rpnid));
+ memset(rpnval, 0xFF, sizeof(rpnval));
+ memset(spectra, 0, sizeof(spectra));
+ memset(spectrar, 0, sizeof(spectrar));
+ api->registerFunctionality(this, "Visualization", "Visualization", api->isDarkTheme() ? ":/img/visualization_i.svg" : ":/img/visualization.svg", 0, true);
+ uihb = api->registerUIHook("main.start", [this](const void *, void *)
+ {
+ this->start();
+ }, nullptr);
+ uihs = api->registerUIHook("main.stop", [this](const void *, void *)
+ {
+ this->stop();
+ }, nullptr);
+ uihp = api->registerUIHook("main.pause", [this](const void *, void *)
+ {
+ this->pause();
+ }, nullptr);
+ uihr = api->registerUIHook("main.reset", [this](const void *, void *)
+ {
+ this->reset();
+ }, nullptr);
+ uihk = api->registerUIHook("main.seek", [this](const void *, void *)
+ {
+ cts = api->getTimeSig();
+ cks = api->getKeySig();
+ ctp = api->getRawTempo();
+ for (int i = 0; i < 16; ++i)
+ api->getPitchBendRaw(i, &cpw[i], &cpbr[i]);
+ }, nullptr);
+ herh = api->registerEventReadHandler(
+ [this](const void *ee, void *)
+ {
+ const SEvent *e = (const SEvent *)ee;
+ switch (e->type & 0xF0)
+ {
+ case 0x80:
+ this->pushNoteOff(e->time, e->type & 0x0F, e->p1);
+ break;
+ case 0x90:
+ if (e->p2)
+ this->pushNoteOn(e->time, e->type & 0x0F, e->p1, e->p2);
+ else
+ this->pushNoteOff(e->time, e->type & 0x0F, e->p1);
+ break;
+ case 0xB0:
+ if (e->p1 == 100)
+ rpnid[e->type & 0x0F] = e->p2;
+ if (e->p1 == 6)
+ rpnval[e->type & 0x0F] = e->p2;
+ if (~rpnid[e->type & 0x0F] && ~rpnval[e->type & 0x0F])
+ {
+ if (rpnid[e->type & 0x0F] == 0)
+ this->pool.push_back(new MidiVisualEvent{e->time, e->time, rpnval[e->type & 0x0F], e->type & 0x0Fu, 995});
+ rpnval[e->type & 0x0F] = ~0u;
+ }
+ break;
+ case 0xE0:
+ this->pool.push_back(new MidiVisualEvent{e->time, e->time, (e->p1 | (e->p2 << 7)) & 0x3FFFu, e->type & 0x0Fu, 994});
+ break;
+ case 0xF0:
+ if (e->type == 0xFF && e->p1 == 0x58)
+ {
+ this->tspool.push_back(std::make_pair(e->time, (e->str[0] << 24) | (e->str[1] << 16)));
+ this->pool.push_back(new MidiVisualEvent{e->time, e->time, (e->str[0] & 0xffu) << 8 | (e->str[1] & 0xffu), 0, 998});
+ }
+ else if (e->type == 0xFF && e->p1 == 0x59)
+ this->pool.push_back(new MidiVisualEvent{e->time, e->time, (e->str[0] & 0xffu) << 8 | (e->str[1] & 0xffu), 0, 997});
+ else if (e->type == 0xFF && e->p1 == 0x51)
+ this->pool.push_back(new MidiVisualEvent{e->time, e->time, (e->str[0] & 0xffu) << 16 | (e->str[1] & 0xffu) << 8 | (e->str[2] & 0xffu), 0, 996});
+ break;
+ }
+ }
+ , nullptr);
+ heh = api->registerEventHandler(
+ [this](const void *, void *)
+ {
+ if (this->ctk > this->api->getCurrentTimeStamp() + this->api->getDivision() / 3)
+ this->elb = 0;
+ /*if(abs((int)this->ctk-(int)this->api->getCurrentTimeStamp())>this->api->getDivision()/4)
+ fprintf(stderr,"Visualization: out of sync! %u vs %u ad: %u\n",this->ctk,this->api->getCurrentTimeStamp());*/
+ this->ctk = this->api->getCurrentTimeStamp();
+ this->lstk = this->ctk;
+ this->lst = std::chrono::steady_clock::now();
+ }
+ , nullptr);
+ hfrf = api->registerFileReadFinishHook(
+ [this](const void *, void *)
+ {
+ memset(rpnval, 0xFF, sizeof(rpnval));
+ memset(rpnid, 0xFF, sizeof(rpnid));
+ std::sort(this->tspool.begin(), this->tspool.end());
+ for (uint32_t tk = 0, n = 4, s = 0; tk <= this->api->getMaxTick();)
+ {
+ while (tk < (s >= this->tspool.size() ? this->api->getMaxTick() : this->tspool[s].first))
+ {
+ this->pool.push_back(new MidiVisualEvent{tk, tk, 0, 0, 999});
+ tk += n * this->api->getDivision();
+ }
+ tk = (s >= this->tspool.size() ? this->api->getMaxTick() : this->tspool[s].first);
+ if (tk == this->api->getMaxTick())
+ {
+ this->pool.push_back(new MidiVisualEvent{tk, tk, 0, 0, 999});
+ ++tk;
+ break;
+ }
+ else n = this->tspool[s++].second >> 24;
+ }
+ std::sort(this->pool.begin(), this->pool.end(), cmp);
+ }
+ , nullptr);
+ api->registerOptionBool("Visualization-Appearance", "Show Piano", "Visualization/showpiano", true);
+ api->registerOptionBool("Visualization-Appearance", "3D Notes", "Visualization/3dnotes", true);
+ api->registerOptionBool("Visualization-Appearance", "Arrange channels on a stair", "Visualization/stairpiano", true);
+ api->registerOptionBool("Visualization-Appearance", "Show channel labels", "Visualization/showlabel", true);
+ api->registerOptionBool("Visualization-Appearance", "Show Particles", "Visualization/showparticle", false);
+ api->registerOptionBool("Visualization-Appearance", "Horizontal Visualization", "Visualization/horizontal", false);
+ api->registerOptionBool("Visualization-Appearance", "2D Visualization", "Visualization/flat", false);
+ api->registerOptionBool("Visualization-Appearance", "Show Measure Indicator", "Visualization/showmeasure", true);
+ api->registerOptionBool("Visualization-Appearance", "Use spectrum instead of piano roll", "Visualization/usespectrum", false);
+ api->registerOptionBool("Visualization-Video", "Enable VSync", "Visualization/vsync", true);
+ api->registerOptionBool("Visualization-Video", "Save Viewport", "Visualization/savevp", true);
+ api->registerOptionInt("Visualization-Video", "Window Width", "Visualization/wwidth", 320, 3200, 800);
+ api->registerOptionInt("Visualization-Video", "Window Height", "Visualization/wheight", 320, 3200, 600);
+ api->registerOptionInt("Visualization-Video", "Target FPS", "Visualization/tfps", 5, 1000, 60);
+ api->registerOptionInt("Visualization-Video", "Supersampling", "Visualization/supersampling", 1, 16, 0);
+ api->registerOptionInt("Visualization-Video", "Multisampling", "Visualization/multisampling", 0, 16, 0);
+ api->registerOptionInt("Visualization-Video", "FOV", "Visualization/fov", 30, 180, 60);
+ std::vector<std::string> tv;
+ tv.push_back("Bottom left");
+ tv.push_back("Bottom right");
+ tv.push_back("Top left");
+ tv.push_back("Top right");
+ tv.push_back("Hidden");
+ api->registerOptionEnumInt("Visualization-Video", "OSD Position", "Visualization/osdpos", tv, 0);
+ api->registerOptionInt("Visualization-Video", "Font Size", "Visualization/fontsize", 6, 180, 16);
+ api->registerOptionString("Visualization-Video", "Custom Sans Font", "Visualization/font1", "", true);
+ api->registerOptionString("Visualization-Video", "Custom Monospace Font", "Visualization/font2", "", true);
+ api->registerOptionInt("Visualization-Appearance", "View distance", "Visualization/viewdist", 20, 1000, 100);
+ api->registerOptionInt("Visualization-Appearance", "Note stretch", "Visualization/notestretch", 20, 500, 100);
+ api->registerOptionInt("Visualization-Appearance", "Minimum note length", "Visualization/minnotelen", 20, 500, 100);
+ api->registerOptionUint("Visualization-Appearance", "Chequer board tint (AARRGGBB)", "Visualization/chkrtint", 0, 0xFFFFFFFF, 0xFF999999);
+ api->registerOptionString("Visualization-Appearance", "Background Image", "Visualization/background", "", true);
+ api->registerOptionDouble("", "", "Visualization/px", -999999999, 999999999, -1e9);
+ api->registerOptionDouble("", "", "Visualization/py", -999999999, 999999999, -1e9);
+ api->registerOptionDouble("", "", "Visualization/pz", -999999999, 999999999, -1e9);
+ api->registerOptionDouble("", "", "Visualization/rx", -999999999, 999999999, -1e9);
+ api->registerOptionDouble("", "", "Visualization/ry", -999999999, 999999999, -1e9);
+ api->registerOptionDouble("", "", "Visualization/rz", -999999999, 999999999, -1e9);
+ for (int i = 0; i < 16; ++i)
+ {
+ api->registerOptionUint("", "", "Visualization/chActiveColor" + std::to_string(i), 0, 0xFFFFFFFF, accolors[i]);
+ api->registerOptionUint("", "", "Visualization/chInactiveColor" + std::to_string(i), 0, 0xFFFFFFFF, iccolors[i]);
+ }
+ wwidth = api->getOptionInt("Visualization/wwidth");
+ wheight = api->getOptionInt("Visualization/wheight");
+ wsupersample = api->getOptionInt("Visualization/supersampling");
+ wmultisample = api->getOptionInt("Visualization/multisampling");
+ fov = api->getOptionInt("Visualization/fov");
+ noteappearance = api->getOptionBool("Visualization/3dnotes");
+ showpiano = api->getOptionBool("Visualization/showpiano");
+ stairpiano = api->getOptionBool("Visualization/stairpiano");
+ showlabel = api->getOptionBool("Visualization/showlabel");
+ showparticle = api->getOptionBool("Visualization/showparticle");
+ horizontal = api->getOptionBool("Visualization/horizontal");
+ flat = api->getOptionBool("Visualization/flat");
+ savevp = api->getOptionBool("Visualization/savevp");
+ vsync = api->getOptionBool("Visualization/vsync");
+ tfps = api->getOptionInt("Visualization/tfps");
+ osdpos = api->getOptionEnumInt("Visualization/osdpos");
+ fontsize = api->getOptionInt("Visualization/fontsize");
+ viewdist = api->getOptionInt("Visualization/viewdist");
+ notestretch = api->getOptionInt("Visualization/notestretch");
+ minnotelength = api->getOptionInt("Visualization/minnotelen");
+ chkrtint = api->getOptionUint("Visualization/chkrtint");
+ for (int i = 0; i < 16; ++i)
+ {
+ accolors[i] = api->getOptionUint("Visualization/chActiveColor" + std::to_string(i));
+ iccolors[i] = api->getOptionUint("Visualization/chInactiveColor" + std::to_string(i));
+ }
+ if (savevp)
+ {
+ pos[0] = api->getOptionDouble("Visualization/px");
+ pos[1] = api->getOptionDouble("Visualization/py");
+ pos[2] = api->getOptionDouble("Visualization/pz");
+ rot[0] = api->getOptionDouble("Visualization/rx");
+ rot[1] = api->getOptionDouble("Visualization/ry");
+ rot[2] = api->getOptionDouble("Visualization/rz");
+ }
+ memset(pss, 0, sizeof(pss));
}
void qmpVisualization::deinit()
{
- if(!api)return;close();tspool.clear();
- for(unsigned i=0;i<pool.size();++i)delete pool[i];pool.clear();
- api->unregisterUIHook("main.start",uihb);
- api->unregisterUIHook("main.stop",uihs);
- api->unregisterUIHook("main.pause",uihp);
- api->unregisterUIHook("main.reset",uihr);
- api->unregisterFunctionality("Visualization");
- api->unregisterEventReadHandler(herh);
- api->unregisterEventHandler(heh);
- api->unregisterFileReadFinishHook(hfrf);
- delete h;delete closeh;
+ if (!api)
+ return;
+ close();
+ tspool.clear();
+ for (unsigned i = 0; i < pool.size(); ++i)
+ delete pool[i];
+ pool.clear();
+ api->unregisterUIHook("main.start", uihb);
+ api->unregisterUIHook("main.stop", uihs);
+ api->unregisterUIHook("main.pause", uihp);
+ api->unregisterUIHook("main.reset", uihr);
+ api->unregisterFunctionality("Visualization");
+ api->unregisterEventReadHandler(herh);
+ api->unregisterEventHandler(heh);
+ api->unregisterFileReadFinishHook(hfrf);
+ delete h;
+ delete closeh;
+}
+const char *qmpVisualization::pluginGetName()
+{
+ return "QMidiPlayer Default Visualization Plugin";
+}
+const char *qmpVisualization::pluginGetVersion()
+{
+ return PLUGIN_VERSION;
}
-const char* qmpVisualization::pluginGetName()
-{return "QMidiPlayer Default Visualization Plugin";}
-const char* qmpVisualization::pluginGetVersion()
-{return PLUGIN_VERSION;}
qmpVisualization *qmpVisualization::instance()
-{return inst;}
+{
+ return inst;
+}
-void qmpVisualization::pushNoteOn(uint32_t tc,uint32_t ch,uint32_t key,uint32_t vel)
+void qmpVisualization::pushNoteOn(uint32_t tc, uint32_t ch, uint32_t key, uint32_t vel)
{
- pendingt[ch][key].push(tc);
- pendingv[ch][key].push(vel);
+ pendingt[ch][key].push(tc);
+ pendingv[ch][key].push(vel);
}
-void qmpVisualization::pushNoteOff(uint32_t tc,uint32_t ch,uint32_t key)
+void qmpVisualization::pushNoteOff(uint32_t tc, uint32_t ch, uint32_t key)
{
- if(pendingt[ch][key].size()<1)return;
- MidiVisualEvent *ne=new MidiVisualEvent();
- ne->tcs=pendingt[ch][key].top();pendingt[ch][key].pop();
- ne->tce=tc;ne->ch=ch;ne->key=key;
- ne->vel=pendingv[ch][key].top();pendingv[ch][key].pop();
- pool.push_back(ne);
+ if (pendingt[ch][key].size() < 1)
+ return;
+ MidiVisualEvent *ne = new MidiVisualEvent();
+ ne->tcs = pendingt[ch][key].top();
+ pendingt[ch][key].pop();
+ ne->tce = tc;
+ ne->ch = ch;
+ ne->key = key;
+ ne->vel = pendingv[ch][key].top();
+ pendingv[ch][key].pop();
+ pool.push_back(ne);
}
diff --git a/visualization/qmpvisualization.hpp b/visualization/qmpvisualization.hpp
index 8a8d832..c0bc067 100644
--- a/visualization/qmpvisualization.hpp
+++ b/visualization/qmpvisualization.hpp
@@ -15,105 +15,121 @@
class qmpVisualization;
struct MidiVisualEvent
{
- uint32_t tcs,tce;
- uint32_t key,vel;
- uint32_t ch;
+ uint32_t tcs, tce;
+ uint32_t key, vel;
+ uint32_t ch;
};
-class qmpVisualization:public qmpPluginIntf,public qmpFuncBaseIntf
+class qmpVisualization: public qmpPluginIntf, public qmpFuncBaseIntf
{
- friend class CloseHandler;
- private:
- qmpPluginAPI* api;
- std::thread* rendererTh;
- std::vector<MidiVisualEvent*>pool;
- smHandler *h,*closeh;
- std::stack<uint32_t> pendingt[16][128],pendingv[16][128];
- SMELT *sm;
- SMTRG tdscn,tdparticles;
- SMTEX chequer,bgtex,particletex,pianotex;
- smTTFont font,font2,fonthdpi;
- qmpVirtualPiano3D* p3d[16];
- smEntity3DBuffer* nebuf;
- smParticleSystem* pss[16][128];
- smPSEmissionPositionGenerator* psepg;
- float pos[3],rot[3],lastx,lasty;
- uint32_t ctc,ctk,elb,lstk,cfr;
- uint32_t cts,cks,ctp,cpbr[16],cpw[16];
- uint32_t rpnid[16],rpnval[16];
- std::chrono::steady_clock::time_point lst;
- double etps;
- bool shouldclose,playing,debug;
- bool rendermode,hidewindow;
- int herh,heh,hfrf;
- int uihb,uihs,uihp,uihr,uihk;
- void(*framecb)(void*,size_t,uint32_t,uint32_t);
- DWORD* fbcont;
- std::vector<std::pair<uint32_t,uint32_t>>tspool;
- int traveld[16][128];bool notestatus[16][128],lastnotestatus[16][128];
- int spectra[16][128],spectrar[16][128];
- void drawCube(smvec3d a,smvec3d b,DWORD col,SMTEX tex,int faces=63);
- void showThread();
- void pushNoteOn(uint32_t tc,uint32_t ch,uint32_t key,uint32_t vel);
- void pushNoteOff(uint32_t tc,uint32_t ch,uint32_t key);
- void updateVisualization3D();
- void updateVisualization2D();
+ friend class CloseHandler;
+private:
+ qmpPluginAPI *api;
+ std::thread *rendererTh;
+ std::vector<MidiVisualEvent *>pool;
+ smHandler *h, *closeh;
+ std::stack<uint32_t> pendingt[16][128], pendingv[16][128];
+ SMELT *sm;
+ SMTRG tdscn, tdparticles;
+ SMTEX chequer, bgtex, particletex, pianotex;
+ smTTFont font, font2, fonthdpi;
+ qmpVirtualPiano3D *p3d[16];
+ smEntity3DBuffer *nebuf;
+ smParticleSystem *pss[16][128];
+ smPSEmissionPositionGenerator *psepg;
+ float pos[3], rot[3], lastx, lasty;
+ uint32_t ctc, ctk, elb, lstk, cfr;
+ uint32_t cts, cks, ctp, cpbr[16], cpw[16];
+ uint32_t rpnid[16], rpnval[16];
+ std::chrono::steady_clock::time_point lst;
+ double etps;
+ bool shouldclose, playing, debug;
+ bool rendermode, hidewindow;
+ int herh, heh, hfrf;
+ int uihb, uihs, uihp, uihr, uihk;
+ void(*framecb)(void *, size_t, uint32_t, uint32_t);
+ DWORD *fbcont;
+ std::vector<std::pair<uint32_t, uint32_t>>tspool;
+ int traveld[16][128];
+ bool notestatus[16][128], lastnotestatus[16][128];
+ int spectra[16][128], spectrar[16][128];
+ void drawCube(smvec3d a, smvec3d b, DWORD col, SMTEX tex, int faces = 63);
+ void showThread();
+ void pushNoteOn(uint32_t tc, uint32_t ch, uint32_t key, uint32_t vel);
+ void pushNoteOff(uint32_t tc, uint32_t ch, uint32_t key);
+ void updateVisualization3D();
+ void updateVisualization2D();
- static qmpVisualization* inst;
- public:
- qmpVisualization(qmpPluginAPI* _api);
- ~qmpVisualization();
- void show();
- void close();
- bool update();
- void start();
- void stop();
- void pause();
- void reset();
- void switchToRenderMode(void(*frameCallback)(void*,size_t,uint32_t,uint32_t),bool _hidewindow);
+ static qmpVisualization *inst;
+public:
+ qmpVisualization(qmpPluginAPI *_api);
+ ~qmpVisualization();
+ void show();
+ void close();
+ bool update();
+ void start();
+ void stop();
+ void pause();
+ void reset();
+ void switchToRenderMode(void(*frameCallback)(void *, size_t, uint32_t, uint32_t), bool _hidewindow);
- void init();
- void deinit();
- const char* pluginGetName();
- const char* pluginGetVersion();
+ void init();
+ void deinit();
+ const char *pluginGetName();
+ const char *pluginGetVersion();
- static qmpVisualization* instance();
+ static qmpVisualization *instance();
};
-class CMidiVisualHandler:public smHandler
+class CMidiVisualHandler: public smHandler
{
- private:
- qmpVisualization *p;
- public:
- CMidiVisualHandler(qmpVisualization* par){p=par;}
- bool handlerFunc(){return p->update();}
+private:
+ qmpVisualization *p;
+public:
+ CMidiVisualHandler(qmpVisualization *par)
+ {
+ p = par;
+ }
+ bool handlerFunc()
+ {
+ return p->update();
+ }
};
-class CloseHandler:public smHandler
+class CloseHandler: public smHandler
{
- private:
- qmpVisualization *p;
- public:
- CloseHandler(qmpVisualization* par){p=par;}
- public:
- bool handlerFunc()
- {
- std::thread ([this]{
- p->api->setFuncState("Visualization",false);
- p->close();}).detach();
- return false;
- }
+private:
+ qmpVisualization *p;
+public:
+ CloseHandler(qmpVisualization *par)
+ {
+ p = par;
+ }
+public:
+ bool handlerFunc()
+ {
+ std::thread([this]
+ {
+ p->api->setFuncState("Visualization", false);
+ p->close();
+ }).detach();
+ return false;
+ }
};
-extern "C"{
- EXPORTSYM qmpPluginIntf* qmpPluginGetInterface(qmpPluginAPI* api)
- {return new qmpVisualization(api);}
- EXPORTSYM const char* qmpPluginGetAPIRev()
- {return QMP_PLUGIN_API_REV;}
- EXPORTSYM void switchToRenderMode(void(*frameCallback)(void*,size_t,uint32_t,uint32_t),bool hidewindow)
- {
- if(qmpVisualization::instance())
- qmpVisualization::instance()->switchToRenderMode(frameCallback,hidewindow);
- }
+extern "C" {
+ EXPORTSYM qmpPluginIntf *qmpPluginGetInterface(qmpPluginAPI *api)
+ {
+ return new qmpVisualization(api);
+ }
+ EXPORTSYM const char *qmpPluginGetAPIRev()
+ {
+ return QMP_PLUGIN_API_REV;
+ }
+ EXPORTSYM void switchToRenderMode(void(*frameCallback)(void *, size_t, uint32_t, uint32_t), bool hidewindow)
+ {
+ if (qmpVisualization::instance())
+ qmpVisualization::instance()->switchToRenderMode(frameCallback, hidewindow);
+ }
}
#endif // QMPVISUALIZATION_H
diff --git a/visualization/renderer/main.cpp b/visualization/renderer/main.cpp
index c651c54..7f25578 100644
--- a/visualization/renderer/main.cpp
+++ b/visualization/renderer/main.cpp
@@ -4,44 +4,46 @@
#include "qmpvisrendercore.hpp"
#include "qmpsettingsro.hpp"
-int main(int argc,char **argv)
+int main(int argc, char **argv)
{
- QCoreApplication::setApplicationName("qmpvisrender");
- QCoreApplication::setApplicationVersion("0.0.0");
- QCoreApplication a(argc,argv);
- QCommandLineParser clp;
- clp.setApplicationDescription("Renderer a visualization of a midi file.");
- clp.addHelpOption();
- clp.addVersionOption();
- clp.addOption({{"f","output-file"},"File name of the output file.","filename","output.mp4"});
- clp.addOption({
- "receiver",
- "Specify a program and its arguments to process the rendered frames. Supports parameter substitution. See documentation for details.",
- "command",
- "ffmpeg %i -vf vflip -pix_fmt yuv420p -c:v libx264 -preset slow -crf 22 %o"
- });
- clp.addOption({
- {"e","receiver-execution"},
- "Execution mode of the receiver command. Valid options are 'one-shot' and 'per-frame'",
- "mode",
- "one-shot"
- });
- clp.addOption({{"s","show-window"},"Do not hide the visualization window."});
- clp.addOption({{"c","config"},"Load options from the configuration file.","qmprc file"});
- clp.addOption({{"o","option"},"Set option for the visualization module.","key-value pair"});
- clp.addOption({"list-options","Show a list of recognized options and quit."});
- clp.addPositionalArgument("file","MIDI file to render");
- clp.process(a.arguments());
- qmpVisRenderCore core(&clp);
- if(clp.positionalArguments().empty()&&!clp.isSet("list-options"))
- clp.showHelp(1);
- core.loadSettings();
- if(!core.loadVisualizationLibrary())
- return 1;
- if(clp.positionalArguments().size())
- core.setMIDIFile(clp.positionalArguments().front().toStdString().c_str());
- core.startRender();
- int retval=a.exec();
- core.unloadVisualizationLibrary();
- return retval;
+ QCoreApplication::setApplicationName("qmpvisrender");
+ QCoreApplication::setApplicationVersion("0.0.0");
+ QCoreApplication a(argc, argv);
+ QCommandLineParser clp;
+ clp.setApplicationDescription("Renderer a visualization of a midi file.");
+ clp.addHelpOption();
+ clp.addVersionOption();
+ clp.addOption({{"f", "output-file"}, "File name of the output file.", "filename", "output.mp4"});
+ clp.addOption(
+ {
+ "receiver",
+ "Specify a program and its arguments to process the rendered frames. Supports parameter substitution. See documentation for details.",
+ "command",
+ "ffmpeg %i -vf vflip -pix_fmt yuv420p -c:v libx264 -preset slow -crf 22 %o"
+ });
+ clp.addOption(
+ {
+ {"e", "receiver-execution"},
+ "Execution mode of the receiver command. Valid options are 'one-shot' and 'per-frame'",
+ "mode",
+ "one-shot"
+ });
+ clp.addOption({{"s", "show-window"}, "Do not hide the visualization window."});
+ clp.addOption({{"c", "config"}, "Load options from the configuration file.", "qmprc file"});
+ clp.addOption({{"o", "option"}, "Set option for the visualization module.", "key-value pair"});
+ clp.addOption({"list-options", "Show a list of recognized options and quit."});
+ clp.addPositionalArgument("file", "MIDI file to render");
+ clp.process(a.arguments());
+ qmpVisRenderCore core(&clp);
+ if (clp.positionalArguments().empty() && !clp.isSet("list-options"))
+ clp.showHelp(1);
+ core.loadSettings();
+ if (!core.loadVisualizationLibrary())
+ return 1;
+ if (clp.positionalArguments().size())
+ core.setMIDIFile(clp.positionalArguments().front().toStdString().c_str());
+ core.startRender();
+ int retval = a.exec();
+ core.unloadVisualizationLibrary();
+ return retval;
}
diff --git a/visualization/renderer/qmppluginapistub.cpp b/visualization/renderer/qmppluginapistub.cpp
index 1be4880..b84a2b6 100644
--- a/visualization/renderer/qmppluginapistub.cpp
+++ b/visualization/renderer/qmppluginapistub.cpp
@@ -6,197 +6,245 @@
#include <QTextCodec>
qmpPluginAPIStub::qmpPluginAPIStub(qmpVisRenderCore *_core):
- core(_core)
+ core(_core)
{
}
qmpPluginAPIStub::~qmpPluginAPIStub()
{
- core=nullptr;
+ core = nullptr;
}
uint32_t qmpPluginAPIStub::getDivision()
{
- return core->player->getDivision();
+ return core->player->getDivision();
+}
+uint32_t qmpPluginAPIStub::getRawTempo()
+{
+ return 0;
+}
+double qmpPluginAPIStub::getRealTempo()
+{
+ return 0;
+}
+uint32_t qmpPluginAPIStub::getTimeSig()
+{
+ return 0;
+}
+int qmpPluginAPIStub::getKeySig()
+{
+ return 0;
+}
+uint32_t qmpPluginAPIStub::getNoteCount()
+{
+ return 0;
}
-uint32_t qmpPluginAPIStub::getRawTempo(){return 0;}
-double qmpPluginAPIStub::getRealTempo(){return 0;}
-uint32_t qmpPluginAPIStub::getTimeSig(){return 0;}
-int qmpPluginAPIStub::getKeySig(){return 0;}
-uint32_t qmpPluginAPIStub::getNoteCount(){return 0;}
uint32_t qmpPluginAPIStub::getMaxTick()
{
- return core->player->getMaxTick();
-}
-uint32_t qmpPluginAPIStub::getCurrentPolyphone(){return 0;}
-uint32_t qmpPluginAPIStub::getMaxPolyphone(){return 0;}
-uint32_t qmpPluginAPIStub::getCurrentTimeStamp(){return 0;}
-uint32_t qmpPluginAPIStub::getCurrentPlaybackPercentage(){return 0;}
-int qmpPluginAPIStub::getChannelCC(int ch, int cc){return 0;}
-int qmpPluginAPIStub::getChannelPreset(int ch){return 0;}
-void qmpPluginAPIStub::playerSeek(uint32_t percentage){}
-double qmpPluginAPIStub::getPitchBend(int ch){return 0;}
-void qmpPluginAPIStub::getPitchBendRaw(int ch,uint32_t *pb,uint32_t *pbr){}
-bool qmpPluginAPIStub::getChannelMask(int ch){return 0;}
+ return core->player->getMaxTick();
+}
+uint32_t qmpPluginAPIStub::getCurrentPolyphone()
+{
+ return 0;
+}
+uint32_t qmpPluginAPIStub::getMaxPolyphone()
+{
+ return 0;
+}
+uint32_t qmpPluginAPIStub::getCurrentTimeStamp()
+{
+ return 0;
+}
+uint32_t qmpPluginAPIStub::getCurrentPlaybackPercentage()
+{
+ return 0;
+}
+int qmpPluginAPIStub::getChannelCC(int ch, int cc)
+{
+ return 0;
+}
+int qmpPluginAPIStub::getChannelPreset(int ch)
+{
+ return 0;
+}
+void qmpPluginAPIStub::playerSeek(uint32_t percentage) {}
+double qmpPluginAPIStub::getPitchBend(int ch)
+{
+ return 0;
+}
+void qmpPluginAPIStub::getPitchBendRaw(int ch, uint32_t *pb, uint32_t *pbr) {}
+bool qmpPluginAPIStub::getChannelMask(int ch)
+{
+ return 0;
+}
std::string qmpPluginAPIStub::getTitle()
{
- if(core->settings()->getOptionEnumIntOptName("Midi/TextEncoding")=="Unicode")
- return std::string(core->player->getTitle());
- return QTextCodec::codecForName(
- core->settings()->getOptionEnumIntOptName("Midi/TextEncoding").c_str())->
- toUnicode(core->player->getTitle()).toStdString();
+ if (core->settings()->getOptionEnumIntOptName("Midi/TextEncoding") == "Unicode")
+ return std::string(core->player->getTitle());
+ return QTextCodec::codecForName(
+ core->settings()->getOptionEnumIntOptName("Midi/TextEncoding").c_str())->
+ toUnicode(core->player->getTitle()).toStdString();
}
std::wstring qmpPluginAPIStub::getWTitle()
{
- if(core->settings()->getOptionEnumIntOptName("Midi/TextEncoding")=="Unicode")
- return QString(core->player->getTitle()).toStdWString();
- return QTextCodec::codecForName(
- core->settings()->getOptionEnumIntOptName("Midi/TextEncoding").c_str())->
- toUnicode(core->player->getTitle()).toStdWString();
-}
-std::string qmpPluginAPIStub::getChannelPresetString(int ch){return std::string();}
-bool qmpPluginAPIStub::isDarkTheme(){return false;}
-void *qmpPluginAPIStub::getMainWindow(){return nullptr;}
-void qmpPluginAPIStub::discardCurrentEvent(){}
-void qmpPluginAPIStub::commitEventChange(SEvent d){}
-void qmpPluginAPIStub::callEventReaderCB(SEvent d){}
-void qmpPluginAPIStub::setFuncState(std::string name,bool state){}
+ if (core->settings()->getOptionEnumIntOptName("Midi/TextEncoding") == "Unicode")
+ return QString(core->player->getTitle()).toStdWString();
+ return QTextCodec::codecForName(
+ core->settings()->getOptionEnumIntOptName("Midi/TextEncoding").c_str())->
+ toUnicode(core->player->getTitle()).toStdWString();
+}
+std::string qmpPluginAPIStub::getChannelPresetString(int ch)
+{
+ return std::string();
+}
+bool qmpPluginAPIStub::isDarkTheme()
+{
+ return false;
+}
+void *qmpPluginAPIStub::getMainWindow()
+{
+ return nullptr;
+}
+void qmpPluginAPIStub::discardCurrentEvent() {}
+void qmpPluginAPIStub::commitEventChange(SEvent d) {}
+void qmpPluginAPIStub::callEventReaderCB(SEvent d) {}
+void qmpPluginAPIStub::setFuncState(std::string name, bool state) {}
void qmpPluginAPIStub::setFuncEnabled(std::string name, bool enable)
{}
void qmpPluginAPIStub::registerFunctionality(qmpFuncBaseIntf *i, std::string name, std::string desc, const char *icon, int iconlen, bool checkable)
{
- if(name=="Visualization")
- core->vf=i;
+ if (name == "Visualization")
+ core->vf = i;
}
void qmpPluginAPIStub::unregisterFunctionality(std::string name)
{
- if(name=="Visualization")
- core->vf=nullptr;
+ if (name == "Visualization")
+ core->vf = nullptr;
}
-int qmpPluginAPIStub::registerUIHook(std::string e, ICallBack *cb, void *userdat){}
+int qmpPluginAPIStub::registerUIHook(std::string e, ICallBack *cb, void *userdat) {}
int qmpPluginAPIStub::registerUIHook(std::string e, callback_t cb, void *userdat)
{
- if(e=="main.start")
- core->startcb=cb;
- if(e=="main.reset")
- core->resetcb=cb;
- return 0;
+ if (e == "main.start")
+ core->startcb = cb;
+ if (e == "main.reset")
+ core->resetcb = cb;
+ return 0;
}
void qmpPluginAPIStub::unregisterUIHook(std::string e, int hook)
{
- if(e=="main.start")
- core->startcb=nullptr;
- if(e=="main.reset")
- core->resetcb=nullptr;
+ if (e == "main.start")
+ core->startcb = nullptr;
+ if (e == "main.reset")
+ core->resetcb = nullptr;
}
-void qmpPluginAPIStub::registerMidiOutDevice(qmpMidiOutDevice *dev, std::string name){}
-void qmpPluginAPIStub::unregisterMidiOutDevice(std::string name){}
+void qmpPluginAPIStub::registerMidiOutDevice(qmpMidiOutDevice *dev, std::string name) {}
+void qmpPluginAPIStub::unregisterMidiOutDevice(std::string name) {}
-int qmpPluginAPIStub::registerEventReaderIntf(ICallBack *cb, void *userdata){}
-void qmpPluginAPIStub::unregisterEventReaderIntf(int intfhandle){}
-int qmpPluginAPIStub::registerEventHandlerIntf(ICallBack *cb, void *userdata){}
-void qmpPluginAPIStub::unregisterEventHandlerIntf(int intfhandle){}
-int qmpPluginAPIStub::registerFileReadFinishedHandlerIntf(ICallBack *cb, void *userdata){}
-void qmpPluginAPIStub::unregisterFileReadFinishedHandlerIntf(int intfhandle){}
+int qmpPluginAPIStub::registerEventReaderIntf(ICallBack *cb, void *userdata) {}
+void qmpPluginAPIStub::unregisterEventReaderIntf(int intfhandle) {}
+int qmpPluginAPIStub::registerEventHandlerIntf(ICallBack *cb, void *userdata) {}
+void qmpPluginAPIStub::unregisterEventHandlerIntf(int intfhandle) {}
+int qmpPluginAPIStub::registerFileReadFinishedHandlerIntf(ICallBack *cb, void *userdata) {}
+void qmpPluginAPIStub::unregisterFileReadFinishedHandlerIntf(int intfhandle) {}
-int qmpPluginAPIStub::registerEventHandler(callback_t cb, void *userdata, bool post){}
-void qmpPluginAPIStub::unregisterEventHandler(int id){}
+int qmpPluginAPIStub::registerEventHandler(callback_t cb, void *userdata, bool post) {}
+void qmpPluginAPIStub::unregisterEventHandler(int id) {}
int qmpPluginAPIStub::registerEventReadHandler(callback_t cb, void *userdata)
{
- return core->player->registerEventReadHandler(cb,userdata);
+ return core->player->registerEventReadHandler(cb, userdata);
}
void qmpPluginAPIStub::unregisterEventReadHandler(int id)
{
- core->player->unregisterEventReadHandler(id);
+ core->player->unregisterEventReadHandler(id);
}
int qmpPluginAPIStub::registerFileReadFinishHook(callback_t cb, void *userdata)
{
- return core->player->registerFileReadFinishHook(cb,userdata);
+ return core->player->registerFileReadFinishHook(cb, userdata);
}
void qmpPluginAPIStub::unregisterFileReadFinishHook(int id)
{
- core->player->unregisterFileReadFinishHook(id);
+ core->player->unregisterFileReadFinishHook(id);
}
-void qmpPluginAPIStub::registerFileReader(qmpFileReader *reader, std::string name){}
-void qmpPluginAPIStub::unregisterFileReader(std::string name){}
+void qmpPluginAPIStub::registerFileReader(qmpFileReader *reader, std::string name) {}
+void qmpPluginAPIStub::unregisterFileReader(std::string name) {}
void qmpPluginAPIStub::registerOptionInt(std::string tab, std::string desc, std::string key, int min, int max, int defaultval)
{
- core->settings()->registerOptionInt(tab,desc,key,min,max,defaultval);
+ core->settings()->registerOptionInt(tab, desc, key, min, max, defaultval);
}
int qmpPluginAPIStub::getOptionInt(std::string key)
{
- return core->settings()->getOptionInt(key);
+ return core->settings()->getOptionInt(key);
}
void qmpPluginAPIStub::setOptionInt(std::string key, int val)
{
- core->settings()->setOptionInt(key,val);
+ core->settings()->setOptionInt(key, val);
}
void qmpPluginAPIStub::registerOptionUint(std::string tab, std::string desc, std::string key, unsigned min, unsigned max, unsigned defaultval)
{
- core->settings()->registerOptionUint(tab,desc,key,min,max,defaultval);
+ core->settings()->registerOptionUint(tab, desc, key, min, max, defaultval);
}
unsigned qmpPluginAPIStub::getOptionUint(std::string key)
{
- return core->settings()->getOptionUint(key);
+ return core->settings()->getOptionUint(key);
}
void qmpPluginAPIStub::setOptionUint(std::string key, unsigned val)
{
- return core->settings()->setOptionUint(key,val);
+ return core->settings()->setOptionUint(key, val);
}
void qmpPluginAPIStub::registerOptionBool(std::string tab, std::string desc, std::string key, bool defaultval)
{
- core->settings()->registerOptionBool(tab,desc,key,defaultval);
+ core->settings()->registerOptionBool(tab, desc, key, defaultval);
}
bool qmpPluginAPIStub::getOptionBool(std::string key)
{
- return core->settings()->getOptionBool(key);
+ return core->settings()->getOptionBool(key);
}
void qmpPluginAPIStub::setOptionBool(std::string key, bool val)
{
- core->settings()->setOptionBool(key,val);
+ core->settings()->setOptionBool(key, val);
}
void qmpPluginAPIStub::registerOptionDouble(std::string tab, std::string desc, std::string key, double min, double max, double defaultval)
{
- core->settings()->registerOptionDouble(tab,desc,key,min,max,defaultval);
+ core->settings()->registerOptionDouble(tab, desc, key, min, max, defaultval);
}
double qmpPluginAPIStub::getOptionDouble(std::string key)
{
- return core->settings()->getOptionDouble(key);
+ return core->settings()->getOptionDouble(key);
}
void qmpPluginAPIStub::setOptionDouble(std::string key, double val)
{
- core->settings()->setOptionDouble(key,val);
+ core->settings()->setOptionDouble(key, val);
}
void qmpPluginAPIStub::registerOptionString(std::string tab, std::string desc, std::string key, std::string defaultval, bool ispath)
{
- core->settings()->registerOptionString(tab,desc,key,defaultval,ispath);
+ core->settings()->registerOptionString(tab, desc, key, defaultval, ispath);
}
std::string qmpPluginAPIStub::getOptionString(std::string key)
{
- return core->settings()->getOptionString(key);
+ return core->settings()->getOptionString(key);
}
void qmpPluginAPIStub::setOptionString(std::string key, std::string val)
{
- core->settings()->setOptionString(key,val);
+ core->settings()->setOptionString(key, val);
}
void qmpPluginAPIStub::registerOptionEnumInt(std::string tab, std::string desc, std::string key, std::vector<std::string> options, int defaultval)
{
- core->settings()->registerOptionEnumInt(tab,desc,key,options,defaultval);
+ core->settings()->registerOptionEnumInt(tab, desc, key, options, defaultval);
}
int qmpPluginAPIStub::getOptionEnumInt(std::string key)
{
- return core->settings()->getOptionEnumInt(key);
+ return core->settings()->getOptionEnumInt(key);
}
void qmpPluginAPIStub::setOptionEnumInt(std::string key, int val)
{
- core->settings()->setOptionEnumInt(key,val);
+ core->settings()->setOptionEnumInt(key, val);
}
diff --git a/visualization/renderer/qmppluginapistub.hpp b/visualization/renderer/qmppluginapistub.hpp
index d96cfca..4a9024d 100644
--- a/visualization/renderer/qmppluginapistub.hpp
+++ b/visualization/renderer/qmppluginapistub.hpp
@@ -4,82 +4,82 @@
#include "qmpcorepublic.hpp"
class qmpVisRenderCore;
-class qmpPluginAPIStub:public qmpPluginAPI
+class qmpPluginAPIStub: public qmpPluginAPI
{
public:
- qmpPluginAPIStub(qmpVisRenderCore *_core);
- ~qmpPluginAPIStub();
- uint32_t getDivision();
- uint32_t getRawTempo();
- double getRealTempo();
- uint32_t getTimeSig();
- int getKeySig();
- uint32_t getNoteCount();
- uint32_t getMaxTick();
- uint32_t getCurrentPolyphone();
- uint32_t getMaxPolyphone();
- uint32_t getCurrentTimeStamp();
- uint32_t getCurrentPlaybackPercentage();
- int getChannelCC(int ch,int cc);
- int getChannelPreset(int ch);
- void playerSeek(uint32_t percentage);
- double getPitchBend(int ch);
- void getPitchBendRaw(int ch,uint32_t *pb,uint32_t *pbr);
- bool getChannelMask(int ch);
- std::string getTitle();
- std::wstring getWTitle();
- std::string getChannelPresetString(int ch);
- bool isDarkTheme();
- void* getMainWindow();
+ qmpPluginAPIStub(qmpVisRenderCore *_core);
+ ~qmpPluginAPIStub();
+ uint32_t getDivision();
+ uint32_t getRawTempo();
+ double getRealTempo();
+ uint32_t getTimeSig();
+ int getKeySig();
+ uint32_t getNoteCount();
+ uint32_t getMaxTick();
+ uint32_t getCurrentPolyphone();
+ uint32_t getMaxPolyphone();
+ uint32_t getCurrentTimeStamp();
+ uint32_t getCurrentPlaybackPercentage();
+ int getChannelCC(int ch, int cc);
+ int getChannelPreset(int ch);
+ void playerSeek(uint32_t percentage);
+ double getPitchBend(int ch);
+ void getPitchBendRaw(int ch, uint32_t *pb, uint32_t *pbr);
+ bool getChannelMask(int ch);
+ std::string getTitle();
+ std::wstring getWTitle();
+ std::string getChannelPresetString(int ch);
+ bool isDarkTheme();
+ void *getMainWindow();
- void discardCurrentEvent();
- void commitEventChange(SEvent d);
- void callEventReaderCB(SEvent d);
- void setFuncState(std::string name,bool state);
- void setFuncEnabled(std::string name,bool enable);
+ void discardCurrentEvent();
+ void commitEventChange(SEvent d);
+ void callEventReaderCB(SEvent d);
+ void setFuncState(std::string name, bool state);
+ void setFuncEnabled(std::string name, bool enable);
- 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* cb,void* userdat);
- int registerUIHook(std::string e,callback_t cb,void* userdat);
- void unregisterUIHook(std::string e,int hook);
- void registerMidiOutDevice(qmpMidiOutDevice* dev,std::string name);
- void unregisterMidiOutDevice(std::string name);
- int registerEventReaderIntf(ICallBack* cb,void* userdata);
- void unregisterEventReaderIntf(int intfhandle);
- int registerEventHandlerIntf(ICallBack* cb,void* userdata);
- void unregisterEventHandlerIntf(int intfhandle);
- int registerFileReadFinishedHandlerIntf(ICallBack* cb,void* userdata);
- void unregisterFileReadFinishedHandlerIntf(int intfhandle);
- int registerEventHandler(callback_t cb,void *userdata,bool post=false);
- void unregisterEventHandler(int id);
- int registerEventReadHandler(callback_t cb,void *userdata);
- void unregisterEventReadHandler(int id);
- int registerFileReadFinishHook(callback_t cb,void *userdata);
- void unregisterFileReadFinishHook(int id);
- void registerFileReader(qmpFileReader* reader,std::string name);
- void unregisterFileReader(std::string name);
+ 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 *cb, void *userdat);
+ int registerUIHook(std::string e, callback_t cb, void *userdat);
+ void unregisterUIHook(std::string e, int hook);
+ void registerMidiOutDevice(qmpMidiOutDevice *dev, std::string name);
+ void unregisterMidiOutDevice(std::string name);
+ int registerEventReaderIntf(ICallBack *cb, void *userdata);
+ void unregisterEventReaderIntf(int intfhandle);
+ int registerEventHandlerIntf(ICallBack *cb, void *userdata);
+ void unregisterEventHandlerIntf(int intfhandle);
+ int registerFileReadFinishedHandlerIntf(ICallBack *cb, void *userdata);
+ void unregisterFileReadFinishedHandlerIntf(int intfhandle);
+ int registerEventHandler(callback_t cb, void *userdata, bool post = false);
+ void unregisterEventHandler(int id);
+ int registerEventReadHandler(callback_t cb, void *userdata);
+ void unregisterEventReadHandler(int id);
+ int registerFileReadFinishHook(callback_t cb, void *userdata);
+ void unregisterFileReadFinishHook(int id);
+ void registerFileReader(qmpFileReader *reader, std::string name);
+ void unregisterFileReader(std::string name);
- void registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval);
- int getOptionInt(std::string key);
- void setOptionInt(std::string key,int val);
- void registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min,unsigned max,unsigned defaultval);
- unsigned getOptionUint(std::string key);
- void setOptionUint(std::string key,unsigned val);
- void registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval);
- bool getOptionBool(std::string key);
- void setOptionBool(std::string key,bool val);
- void registerOptionDouble(std::string tab,std::string desc,std::string key,double min,double max,double defaultval);
- double getOptionDouble(std::string key);
- void setOptionDouble(std::string key,double val);
- void registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool ispath=false);
- std::string getOptionString(std::string key);
- void setOptionString(std::string key,std::string val);
- void registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> options,int defaultval);
- int getOptionEnumInt(std::string key);
- void setOptionEnumInt(std::string key,int val);
+ void registerOptionInt(std::string tab, std::string desc, std::string key, int min, int max, int defaultval);
+ int getOptionInt(std::string key);
+ void setOptionInt(std::string key, int val);
+ void registerOptionUint(std::string tab, std::string desc, std::string key, unsigned min, unsigned max, unsigned defaultval);
+ unsigned getOptionUint(std::string key);
+ void setOptionUint(std::string key, unsigned val);
+ void registerOptionBool(std::string tab, std::string desc, std::string key, bool defaultval);
+ bool getOptionBool(std::string key);
+ void setOptionBool(std::string key, bool val);
+ void registerOptionDouble(std::string tab, std::string desc, std::string key, double min, double max, double defaultval);
+ double getOptionDouble(std::string key);
+ void setOptionDouble(std::string key, double val);
+ void registerOptionString(std::string tab, std::string desc, std::string key, std::string defaultval, bool ispath = false);
+ std::string getOptionString(std::string key);
+ void setOptionString(std::string key, std::string val);
+ void registerOptionEnumInt(std::string tab, std::string desc, std::string key, std::vector<std::string> options, int defaultval);
+ int getOptionEnumInt(std::string key);
+ void setOptionEnumInt(std::string key, int val);
private:
- qmpVisRenderCore* core;
+ qmpVisRenderCore *core;
};
#endif // QMPPLUGINAPISTUB_HPP
diff --git a/visualization/renderer/qmpsettingsro.cpp b/visualization/renderer/qmpsettingsro.cpp
index 034f073..67dc257 100644
--- a/visualization/renderer/qmpsettingsro.cpp
+++ b/visualization/renderer/qmpsettingsro.cpp
@@ -9,218 +9,218 @@ qmpSettingsRO::qmpSettingsRO()
{
}
-void qmpSettingsRO::registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval)
+void qmpSettingsRO::registerOptionInt(std::string tab, std::string desc, std::string key, int min, int max, int defaultval)
{
- Q_UNUSED(tab)
- optionlist.push_back(key);
- options[key]=qmpOptionR(desc,qmpOptionR::ParameterType::parameter_int,defaultval,min,max);
+ Q_UNUSED(tab)
+ optionlist.push_back(key);
+ options[key] = qmpOptionR(desc, qmpOptionR::ParameterType::parameter_int, defaultval, min, max);
}
int qmpSettingsRO::getOptionInt(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_int)
- return settings.value(QString(key.c_str()),options[key].defaultval).toInt();
- return options[key].defaultval.toInt();
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_int)
+ return settings.value(QString(key.c_str()), options[key].defaultval).toInt();
+ return options[key].defaultval.toInt();
}
-void qmpSettingsRO::setOptionInt(std::string key,int val)
+void qmpSettingsRO::setOptionInt(std::string key, int val)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_int)
- settings.insert(QString(key.c_str()),val);
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_int)
+ settings.insert(QString(key.c_str()), val);
}
-void qmpSettingsRO::registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min,unsigned max,unsigned defaultval)
+void qmpSettingsRO::registerOptionUint(std::string tab, std::string desc, std::string key, unsigned min, unsigned max, unsigned defaultval)
{
- Q_UNUSED(tab)
- optionlist.push_back(key);
- options[key]=qmpOptionR(desc,qmpOptionR::ParameterType::parameter_uint,defaultval,min,max);
+ Q_UNUSED(tab)
+ optionlist.push_back(key);
+ options[key] = qmpOptionR(desc, qmpOptionR::ParameterType::parameter_uint, defaultval, min, max);
}
unsigned qmpSettingsRO::getOptionUint(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_uint)
- return settings.value(QString(key.c_str()),options[key].defaultval).toUInt();
- return options[key].defaultval.toUInt();
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_uint)
+ return settings.value(QString(key.c_str()), options[key].defaultval).toUInt();
+ return options[key].defaultval.toUInt();
}
-void qmpSettingsRO::setOptionUint(std::string key,unsigned val)
+void qmpSettingsRO::setOptionUint(std::string key, unsigned val)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_uint)
- settings.insert(QString(key.c_str()),val);
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_uint)
+ settings.insert(QString(key.c_str()), val);
}
-void qmpSettingsRO::registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval)
+void qmpSettingsRO::registerOptionBool(std::string tab, std::string desc, std::string key, bool defaultval)
{
- Q_UNUSED(tab)
- optionlist.push_back(key);
- options[key]=qmpOptionR(desc,qmpOptionR::ParameterType::parameter_bool,defaultval);
+ Q_UNUSED(tab)
+ optionlist.push_back(key);
+ options[key] = qmpOptionR(desc, qmpOptionR::ParameterType::parameter_bool, defaultval);
}
bool qmpSettingsRO::getOptionBool(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_bool)
- return settings.value(QString(key.c_str()),options[key].defaultval).toBool();
- return options[key].defaultval.toBool();
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_bool)
+ return settings.value(QString(key.c_str()), options[key].defaultval).toBool();
+ return options[key].defaultval.toBool();
}
-void qmpSettingsRO::setOptionBool(std::string key,bool val)
+void qmpSettingsRO::setOptionBool(std::string key, bool val)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_bool)
- settings.insert(QString(key.c_str()),val);
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_bool)
+ settings.insert(QString(key.c_str()), val);
}
-void qmpSettingsRO::registerOptionDouble(std::string tab,std::string desc,std::string key,double min,double max,double defaultval)
+void qmpSettingsRO::registerOptionDouble(std::string tab, std::string desc, std::string key, double min, double max, double defaultval)
{
- Q_UNUSED(tab)
- optionlist.push_back(key);
- options[key]=qmpOptionR(desc,qmpOptionR::ParameterType::parameter_double,defaultval,min,max);
+ Q_UNUSED(tab)
+ optionlist.push_back(key);
+ options[key] = qmpOptionR(desc, qmpOptionR::ParameterType::parameter_double, defaultval, min, max);
}
double qmpSettingsRO::getOptionDouble(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_double)
- return settings.value(QString(key.c_str()),options[key].defaultval).toDouble();
- return options[key].defaultval.toDouble();
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_double)
+ return settings.value(QString(key.c_str()), options[key].defaultval).toDouble();
+ return options[key].defaultval.toDouble();
}
-void qmpSettingsRO::setOptionDouble(std::string key,double val)
+void qmpSettingsRO::setOptionDouble(std::string key, double val)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_double)
- settings.insert(QString(key.c_str()),val);
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_double)
+ settings.insert(QString(key.c_str()), val);
}
-void qmpSettingsRO::registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool is_url)
+void qmpSettingsRO::registerOptionString(std::string tab, std::string desc, std::string key, std::string defaultval, bool is_url)
{
- Q_UNUSED(tab)
- optionlist.push_back(key);
- options[key]=qmpOptionR(desc,
- is_url?qmpOptionR::ParameterType::parameter_url:qmpOptionR::ParameterType::parameter_str,
- QString(defaultval.c_str()));
+ Q_UNUSED(tab)
+ optionlist.push_back(key);
+ options[key] = qmpOptionR(desc,
+ is_url ? qmpOptionR::ParameterType::parameter_url : qmpOptionR::ParameterType::parameter_str,
+ QString(defaultval.c_str()));
}
std::string qmpSettingsRO::getOptionString(std::string key)
{
- if(options.find(key)!=options.end()&&
- (options[key].type==qmpOptionR::ParameterType::parameter_str||options[key].type==qmpOptionR::ParameterType::parameter_url))
- return settings.value(QString(key.c_str()),options[key].defaultval).toString().toStdString();
- return options[key].defaultval.toString().toStdString();
+ if (options.find(key) != options.end() &&
+ (options[key].type == qmpOptionR::ParameterType::parameter_str || options[key].type == qmpOptionR::ParameterType::parameter_url))
+ return settings.value(QString(key.c_str()), options[key].defaultval).toString().toStdString();
+ return options[key].defaultval.toString().toStdString();
}
-void qmpSettingsRO::setOptionString(std::string key,std::string val)
+void qmpSettingsRO::setOptionString(std::string key, std::string val)
{
- if(options.find(key)!=options.end()&&
- (options[key].type==qmpOptionR::ParameterType::parameter_str||options[key].type==qmpOptionR::ParameterType::parameter_url))
- settings.insert(QString(key.c_str()),QString(val.c_str()));
+ if (options.find(key) != options.end() &&
+ (options[key].type == qmpOptionR::ParameterType::parameter_str || options[key].type == qmpOptionR::ParameterType::parameter_url))
+ settings.insert(QString(key.c_str()), QString(val.c_str()));
}
-void qmpSettingsRO::registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> enumlist,int defaultval)
+void qmpSettingsRO::registerOptionEnumInt(std::string tab, std::string desc, std::string key, std::vector<std::string> enumlist, int defaultval)
{
- Q_UNUSED(tab)
- optionlist.push_back(key);
- options[key]=qmpOptionR(desc,qmpOptionR::ParameterType::parameter_enum,defaultval);
- options[key].enumlist=enumlist;
+ Q_UNUSED(tab)
+ optionlist.push_back(key);
+ options[key] = qmpOptionR(desc, qmpOptionR::ParameterType::parameter_enum, defaultval);
+ options[key].enumlist = enumlist;
}
int qmpSettingsRO::getOptionEnumInt(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_enum)
- {
- std::string curitm=settings.value(QString(key.c_str()),options[key].defaultval).toString().toStdString();
- auto curidx=std::find(options[key].enumlist.begin(),options[key].enumlist.end(),curitm);
- if(curidx!=options[key].enumlist.end())
- return static_cast<int>(curidx-options[key].enumlist.begin());
- else
- {
- return options[key].defaultval.toInt();
- }
- }
- return options[key].defaultval.toInt();
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_enum)
+ {
+ std::string curitm = settings.value(QString(key.c_str()), options[key].defaultval).toString().toStdString();
+ auto curidx = std::find(options[key].enumlist.begin(), options[key].enumlist.end(), curitm);
+ if (curidx != options[key].enumlist.end())
+ return static_cast<int>(curidx - options[key].enumlist.begin());
+ else
+ {
+ return options[key].defaultval.toInt();
+ }
+ }
+ return options[key].defaultval.toInt();
}
std::string qmpSettingsRO::getOptionEnumIntOptName(std::string key)
{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_enum)
- {
- std::string curitm=settings.value(QString(key.c_str()),options[key].defaultval).toString().toStdString();
- auto curidx=std::find(options[key].enumlist.begin(),options[key].enumlist.end(),curitm);
- if(curidx!=options[key].enumlist.end())
- return curitm;
- else
- {
- return options[key].enumlist[static_cast<size_t>(options[key].defaultval.toInt())];
- }
- }
- return options[key].enumlist[static_cast<size_t>(options[key].defaultval.toInt())];
-}
-void qmpSettingsRO::setOptionEnumInt(std::string key,int val)
-{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_enum)
- {
- if(static_cast<size_t>(val)<options[key].enumlist.size())
- settings.insert(QString(key.c_str()),QString(options[key].enumlist[static_cast<size_t>(val)].c_str()));
- }
-}
-void qmpSettingsRO::setOptionEnumIntOptName(std::string key,std::string valname)
-{
- if(options.find(key)!=options.end()&&options[key].type==qmpOptionR::ParameterType::parameter_enum)
- {
- auto curidx=std::find(options[key].enumlist.begin(),options[key].enumlist.end(),valname);
- if(curidx!=options[key].enumlist.end())
- settings.insert(QString(key.c_str()),QString(valname.c_str()));
- }
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_enum)
+ {
+ std::string curitm = settings.value(QString(key.c_str()), options[key].defaultval).toString().toStdString();
+ auto curidx = std::find(options[key].enumlist.begin(), options[key].enumlist.end(), curitm);
+ if (curidx != options[key].enumlist.end())
+ return curitm;
+ else
+ {
+ return options[key].enumlist[static_cast<size_t>(options[key].defaultval.toInt())];
+ }
+ }
+ return options[key].enumlist[static_cast<size_t>(options[key].defaultval.toInt())];
+}
+void qmpSettingsRO::setOptionEnumInt(std::string key, int val)
+{
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_enum)
+ {
+ if (static_cast<size_t>(val) < options[key].enumlist.size())
+ settings.insert(QString(key.c_str()), QString(options[key].enumlist[static_cast<size_t>(val)].c_str()));
+ }
+}
+void qmpSettingsRO::setOptionEnumIntOptName(std::string key, std::string valname)
+{
+ if (options.find(key) != options.end() && options[key].type == qmpOptionR::ParameterType::parameter_enum)
+ {
+ auto curidx = std::find(options[key].enumlist.begin(), options[key].enumlist.end(), valname);
+ if (curidx != options[key].enumlist.end())
+ settings.insert(QString(key.c_str()), QString(valname.c_str()));
+ }
}
void qmpSettingsRO::load(const char *path)
{
- QScopedPointer<QSettings> qsettings(new QSettings(path,QSettings::Format::IniFormat));
- settings.clear();
- for(QString&k:qsettings->allKeys())
- {
- settings.insert(k,qsettings->value(k));
- }
+ QScopedPointer<QSettings> qsettings(new QSettings(path, QSettings::Format::IniFormat));
+ settings.clear();
+ for (QString &k : qsettings->allKeys())
+ {
+ settings.insert(k, qsettings->value(k));
+ }
}
void qmpSettingsRO::setopt(std::string key, std::string val)
{
- settings.insert(QString(key.c_str()),QString(val.c_str()));
- if(key.find("Visualization/")!=0)
- settings.insert("Visualization/"+QString(key.c_str()),QString(val.c_str()));
+ settings.insert(QString(key.c_str()), QString(val.c_str()));
+ if (key.find("Visualization/") != 0)
+ settings.insert("Visualization/" + QString(key.c_str()), QString(val.c_str()));
}
void qmpSettingsRO::listopt()
{
- for(auto&k:optionlist)
- {
- printf("Option key: %s\n",k.c_str());
- if(options[k].desc.length())
- printf("Description: %s\n",options[k].desc.c_str());
- switch(options[k].type)
- {
- case qmpOptionR::ParameterType::parameter_int:
- printf("Type: int\n");
- printf("Range: [%d,%d]\n",options[k].minv.toInt(),options[k].maxv.toInt());
- printf("Default value: %d\n",options[k].defaultval.toInt());
- break;
- case qmpOptionR::ParameterType::parameter_uint:
- printf("Type: uint\n");
- printf("Range: [%u,%u]\n",options[k].minv.toUInt(),options[k].maxv.toUInt());
- printf("Default value: %u\n",options[k].defaultval.toUInt());
- break;
- case qmpOptionR::ParameterType::parameter_double:
- printf("Type: double\n");
- printf("Range: [%.2f,%.2f]\n",options[k].minv.toDouble(),options[k].maxv.toDouble());
- printf("Default value: %.f2\n",options[k].defaultval.toDouble());
- break;
- case qmpOptionR::ParameterType::parameter_bool:
- printf("Type: bool\n");
- printf("Default value: %s\n",options[k].defaultval.toBool()?"true":"false");
- break;
- case qmpOptionR::ParameterType::parameter_str:
- printf("Type: str\n");
- printf("Default value: %s\n",options[k].defaultval.toString().toStdString().c_str());
- break;
- case qmpOptionR::ParameterType::parameter_url:
- printf("Type: url\n");
- printf("Default value: %s\n",options[k].defaultval.toString().toStdString().c_str());
- break;
- case qmpOptionR::ParameterType::parameter_enum:
- printf("Type: enum\n");
- printf("Possible values: ");
- for(size_t i=0;i<options[k].enumlist.size();++i)
- printf("%s%s",options[k].enumlist[i].c_str(),i==options[k].enumlist.size()-1?"\n":", ");
- printf("Default value: %s\n",options[k].enumlist[options[k].defaultval.toInt()].c_str());
- break;
- default:
- printf("Type: unknown\n");
- }
- puts("");
- }
+ for (auto &k : optionlist)
+ {
+ printf("Option key: %s\n", k.c_str());
+ if (options[k].desc.length())
+ printf("Description: %s\n", options[k].desc.c_str());
+ switch (options[k].type)
+ {
+ case qmpOptionR::ParameterType::parameter_int:
+ printf("Type: int\n");
+ printf("Range: [%d,%d]\n", options[k].minv.toInt(), options[k].maxv.toInt());
+ printf("Default value: %d\n", options[k].defaultval.toInt());
+ break;
+ case qmpOptionR::ParameterType::parameter_uint:
+ printf("Type: uint\n");
+ printf("Range: [%u,%u]\n", options[k].minv.toUInt(), options[k].maxv.toUInt());
+ printf("Default value: %u\n", options[k].defaultval.toUInt());
+ break;
+ case qmpOptionR::ParameterType::parameter_double:
+ printf("Type: double\n");
+ printf("Range: [%.2f,%.2f]\n", options[k].minv.toDouble(), options[k].maxv.toDouble());
+ printf("Default value: %.f2\n", options[k].defaultval.toDouble());
+ break;
+ case qmpOptionR::ParameterType::parameter_bool:
+ printf("Type: bool\n");
+ printf("Default value: %s\n", options[k].defaultval.toBool() ? "true" : "false");
+ break;
+ case qmpOptionR::ParameterType::parameter_str:
+ printf("Type: str\n");
+ printf("Default value: %s\n", options[k].defaultval.toString().toStdString().c_str());
+ break;
+ case qmpOptionR::ParameterType::parameter_url:
+ printf("Type: url\n");
+ printf("Default value: %s\n", options[k].defaultval.toString().toStdString().c_str());
+ break;
+ case qmpOptionR::ParameterType::parameter_enum:
+ printf("Type: enum\n");
+ printf("Possible values: ");
+ for (size_t i = 0; i < options[k].enumlist.size(); ++i)
+ printf("%s%s", options[k].enumlist[i].c_str(), i == options[k].enumlist.size() - 1 ? "\n" : ", ");
+ printf("Default value: %s\n", options[k].enumlist[options[k].defaultval.toInt()].c_str());
+ break;
+ default:
+ printf("Type: unknown\n");
+ }
+ puts("");
+ }
}
diff --git a/visualization/renderer/qmpsettingsro.hpp b/visualization/renderer/qmpsettingsro.hpp
index c5dd8af..1a3927b 100644
--- a/visualization/renderer/qmpsettingsro.hpp
+++ b/visualization/renderer/qmpsettingsro.hpp
@@ -10,66 +10,67 @@
struct qmpOptionR
{
- enum ParameterType{
- parameter_int=0,
- parameter_uint,
- parameter_bool,
- parameter_double,
- parameter_str,
- parameter_enum,
- parameter_url,
- parameter_custom=0x100
- };
+ enum ParameterType
+ {
+ parameter_int = 0,
+ parameter_uint,
+ parameter_bool,
+ parameter_double,
+ parameter_str,
+ parameter_enum,
+ parameter_url,
+ parameter_custom = 0x100
+ };
- std::string desc;
- ParameterType type;
- QVariant defaultval,minv,maxv;
- std::vector<std::string> enumlist;
+ std::string desc;
+ ParameterType type;
+ QVariant defaultval, minv, maxv;
+ std::vector<std::string> enumlist;
- qmpOptionR(){}
- qmpOptionR(
- std::string _desc,
- ParameterType _t,QVariant _def=QVariant(),
- QVariant _min=QVariant(),QVariant _max=QVariant()):
- desc(_desc),
- type(_t),
- defaultval(_def),
- minv(_min),
- maxv(_max){}
+ qmpOptionR() {}
+ qmpOptionR(
+ std::string _desc,
+ ParameterType _t, QVariant _def = QVariant(),
+ QVariant _min = QVariant(), QVariant _max = QVariant()):
+ desc(_desc),
+ type(_t),
+ defaultval(_def),
+ minv(_min),
+ maxv(_max) {}
};
class qmpSettingsRO
{
public:
- qmpSettingsRO();
- void registerOptionInt(std::string tab,std::string desc,std::string key,int min,int max,int defaultval);
- int getOptionInt(std::string key);
- void setOptionInt(std::string key,int val);
- void registerOptionUint(std::string tab,std::string desc,std::string key,unsigned min,unsigned max,unsigned defaultval);
- unsigned getOptionUint(std::string key);
- void setOptionUint(std::string key,unsigned val);
- void registerOptionBool(std::string tab,std::string desc,std::string key,bool defaultval);
- bool getOptionBool(std::string key);
- void setOptionBool(std::string key,bool val);
- void registerOptionDouble(std::string tab,std::string desc,std::string key,double min,double max,double defaultval);
- double getOptionDouble(std::string key);
- void setOptionDouble(std::string key,double val);
- void registerOptionString(std::string tab,std::string desc,std::string key,std::string defaultval,bool is_url);
- std::string getOptionString(std::string key);
- void setOptionString(std::string key,std::string val);
- void registerOptionEnumInt(std::string tab,std::string desc,std::string key,std::vector<std::string> enumlist,int defaultval);
- int getOptionEnumInt(std::string key);
- std::string getOptionEnumIntOptName(std::string key);
- void setOptionEnumInt(std::string key,int val);
- void setOptionEnumIntOptName(std::string key,std::string valname);
+ qmpSettingsRO();
+ void registerOptionInt(std::string tab, std::string desc, std::string key, int min, int max, int defaultval);
+ int getOptionInt(std::string key);
+ void setOptionInt(std::string key, int val);
+ void registerOptionUint(std::string tab, std::string desc, std::string key, unsigned min, unsigned max, unsigned defaultval);
+ unsigned getOptionUint(std::string key);
+ void setOptionUint(std::string key, unsigned val);
+ void registerOptionBool(std::string tab, std::string desc, std::string key, bool defaultval);
+ bool getOptionBool(std::string key);
+ void setOptionBool(std::string key, bool val);
+ void registerOptionDouble(std::string tab, std::string desc, std::string key, double min, double max, double defaultval);
+ double getOptionDouble(std::string key);
+ void setOptionDouble(std::string key, double val);
+ void registerOptionString(std::string tab, std::string desc, std::string key, std::string defaultval, bool is_url);
+ std::string getOptionString(std::string key);
+ void setOptionString(std::string key, std::string val);
+ void registerOptionEnumInt(std::string tab, std::string desc, std::string key, std::vector<std::string> enumlist, int defaultval);
+ int getOptionEnumInt(std::string key);
+ std::string getOptionEnumIntOptName(std::string key);
+ void setOptionEnumInt(std::string key, int val);
+ void setOptionEnumIntOptName(std::string key, std::string valname);
- void load(const char* path);
- void setopt(std::string key,std::string val);
- void listopt();
+ void load(const char *path);
+ void setopt(std::string key, std::string val);
+ void listopt();
private:
- std::map<std::string,qmpOptionR> options;
- std::vector<std::string> optionlist;
- QVariantMap settings;
+ std::map<std::string, qmpOptionR> options;
+ std::vector<std::string> optionlist;
+ QVariantMap settings;
};
#endif
diff --git a/visualization/renderer/qmpvisrendercore.cpp b/visualization/renderer/qmpvisrendercore.cpp
index b12ed91..9d58206 100644
--- a/visualization/renderer/qmpvisrendercore.cpp
+++ b/visualization/renderer/qmpvisrendercore.cpp
@@ -19,262 +19,271 @@
#include <QCommandLineParser>
#include <QDebug>
#include <QThread>
-qmpVisRenderCore *qmpVisRenderCore::inst=nullptr;
+qmpVisRenderCore *qmpVisRenderCore::inst = nullptr;
-qmpVisRenderCore::qmpVisRenderCore(QCommandLineParser *_clp):QObject(nullptr),clp(_clp)
+qmpVisRenderCore::qmpVisRenderCore(QCommandLineParser *_clp): QObject(nullptr), clp(_clp)
{
- inst=this;
- player=new CMidiPlayer();
- api=new qmpPluginAPIStub(this);
- msettings=new qmpSettingsRO();
- frameno=0;
- msettings->registerOptionEnumInt("MIDI","Text encoding","Midi/TextEncoding",{"Unicode","Big5","Big5-HKSCS","CP949","EUC-JP","EUC-KR","GB18030","KOI8-R","KOI8-U","Macintosh","Shift-JIS"},0);
+ inst = this;
+ player = new CMidiPlayer();
+ api = new qmpPluginAPIStub(this);
+ msettings = new qmpSettingsRO();
+ frameno = 0;
+ msettings->registerOptionEnumInt("MIDI", "Text encoding", "Midi/TextEncoding", {"Unicode", "Big5", "Big5-HKSCS", "CP949", "EUC-JP", "EUC-KR", "GB18030", "KOI8-R", "KOI8-U", "Macintosh", "Shift-JIS"}, 0);
}
bool qmpVisRenderCore::loadVisualizationLibrary()
{
#ifdef _WIN32
- std::vector<std::wstring> libpath={
- QCoreApplication::applicationDirPath().toStdWString()+L"/plugins/libvisualization.dll",
- L"libvisualization.dll",
- L"../libvisualization.dll"//for debugging only...?
- };
+ std::vector<std::wstring> libpath =
+ {
+ QCoreApplication::applicationDirPath().toStdWString() + L"/plugins/libvisualization.dll",
+ L"libvisualization.dll",
+ L"../libvisualization.dll"//for debugging only...?
+ };
#else
- std::vector<std::string> libpath={
- QCoreApplication::applicationDirPath().toStdString()+"/plugins/libvisualization.so",
- QT_STRINGIFY(INSTALL_PREFIX)+std::string("/lib/qmidiplayer/libvisualization.so"),
- "../libvisualization.so"//for debugging only
- };
+ std::vector<std::string> libpath =
+ {
+ QCoreApplication::applicationDirPath().toStdString() + "/plugins/libvisualization.so",
+ QT_STRINGIFY(INSTALL_PREFIX) + std::string("/lib/qmidiplayer/libvisualization.so"),
+ "../libvisualization.so"//for debugging only
+ };
#endif
- for(auto&l:libpath)
- {
- mp=dlopen(l.c_str(),RTLD_LAZY);
- if(mp)break;
- }
- if(!mp)
- {
- fprintf(stderr,"failed to load the visualization module!\n");
- return false;
- }
- GetInterface_func getintf=reinterpret_cast<GetInterface_func>(dlsym(mp,"qmpPluginGetInterface"));
- SwitchMode_func switchmode=reinterpret_cast<SwitchMode_func>(dlsym(mp,"switchToRenderMode"));
- vf=nullptr;
- vp=getintf(api);
- switchmode(&qmpVisRenderCore::framefunc,!clp->isSet("show-window"));
- vp->init();
- resetcb(nullptr,nullptr);
- if(clp->isSet("list-options"))
- {
- msettings->listopt();
- exit(0);
- }
- return true;
+ for (auto &l : libpath)
+ {
+ mp = dlopen(l.c_str(), RTLD_LAZY);
+ if (mp)
+ break;
+ }
+ if (!mp)
+ {
+ fprintf(stderr, "failed to load the visualization module!\n");
+ return false;
+ }
+ GetInterface_func getintf = reinterpret_cast<GetInterface_func>(dlsym(mp, "qmpPluginGetInterface"));
+ SwitchMode_func switchmode = reinterpret_cast<SwitchMode_func>(dlsym(mp, "switchToRenderMode"));
+ vf = nullptr;
+ vp = getintf(api);
+ switchmode(&qmpVisRenderCore::framefunc, !clp->isSet("show-window"));
+ vp->init();
+ resetcb(nullptr, nullptr);
+ if (clp->isSet("list-options"))
+ {
+ msettings->listopt();
+ exit(0);
+ }
+ return true;
}
void qmpVisRenderCore::unloadVisualizationLibrary()
{
- vp->deinit();
- dlclose(mp);
+ vp->deinit();
+ dlclose(mp);
}
void qmpVisRenderCore::loadSettings()
{
- if(clp->isSet("config"))
- msettings->load(clp->value("config").toStdString().c_str());
- for(auto &o:clp->values("option"))
- {
- int sp=o.indexOf('=');
- if(!~sp)
- {
- qDebug("invalid option pair: %s",o.toStdString().c_str());
- continue;
- }
- QString key=o.left(sp);
- QString value=o.mid(sp+1);
- msettings->setopt(key.toStdString(),value.toStdString());
- }
+ if (clp->isSet("config"))
+ msettings->load(clp->value("config").toStdString().c_str());
+ for (auto &o : clp->values("option"))
+ {
+ int sp = o.indexOf('=');
+ if (!~sp)
+ {
+ qDebug("invalid option pair: %s", o.toStdString().c_str());
+ continue;
+ }
+ QString key = o.left(sp);
+ QString value = o.mid(sp + 1);
+ msettings->setopt(key.toStdString(), value.toStdString());
+ }
}
void qmpVisRenderCore::setMIDIFile(const char *url)
{
- player->playerLoadFile(url);
+ player->playerLoadFile(url);
}
void qmpVisRenderCore::startRender()
{
- assert(vf);
- subst={
- {'w',QString::number(msettings->getOptionInt("Visualization/wwidth"))},
- {'h',QString::number(msettings->getOptionInt("Visualization/wheight"))},
- {'r',QString::number(msettings->getOptionInt("Visualization/tfps"))},
- {'i',
- QStringList()
- <<"-f"<<"rawvideo"
- <<"-pixel_format"<<"rgba"
- <<"-video_size"<<QString("%1x%2").arg(msettings->getOptionInt("Visualization/wwidth")).arg(msettings->getOptionInt("Visualization/wheight"))
- <<"-framerate"<<QString::number(msettings->getOptionInt("Visualization/tfps"))
- <<"-i"<<"pipe:"
- },
- {'o',clp->value("output-file")}
- };
- if(clp->value("receiver-execution")=="per-frame")
- {
- subst['o']=clp->value("output-file").replace("%f",QString("%1").arg(frameno,6,10,QChar('0')));
- oneshot=false;
- }
- else
- {
- oneshot=true;
- if(clp->value("receiver-execution")!="one-shot")
- qWarning("Invalid value set for --receiver-execution. Using default value.");
- }
- rxproc=new QProcess();
- QStringList arguments=process_arguments(clp->value("receiver"),subst);
- assert(arguments.length()>0);
- rxproc->setProgram(arguments.front());
- arguments.pop_front();
- rxproc->setArguments(arguments);
- frameconn=connect(this,&qmpVisRenderCore::frameRendered,this,
- [this](void* px,size_t sz,uint32_t c,uint32_t t)
- {
- if(sz)
- {
- if(!oneshot)
- {
- subst['f']=QString("%1").arg(frameno,6,10,QChar('0'));
- subst['o']=clp->value("output-file").replace("%f",QString("%1").arg(frameno,6,10,QChar('0')));
- frameno++;
- QStringList arguments=process_arguments(clp->value("receiver"),subst);
- arguments.pop_front();
- rxproc->setArguments(arguments);
- rxproc->start();
- rxproc->waitForStarted();
- }
- if(!rxproc->isOpen())return;
- rxproc->write(static_cast<const char*>(px),static_cast<qint64>(sz));
- while(rxproc->bytesToWrite()>(oneshot?(1<<26):0))
- rxproc->waitForBytesWritten();
- if(!oneshot)
- {
- rxproc->closeWriteChannel();
- rxproc->waitForFinished(-1);
- }
- }
- fprintf(stderr,"Rendered tick %u of %u, %.2f%% done.\r",c,t,std::min(100.,100.*c/t));
- if(c>t)
- {
- this->rxproc->closeWriteChannel();
- disconnect(frameconn);
- qApp->exit(0);
- }
- },Qt::ConnectionType::BlockingQueuedConnection);
- connect(rxproc,QOverload<int,QProcess::ExitStatus>::of(&QProcess::finished),
- [this](int x,QProcess::ExitStatus st){
- qDebug("%s",this->rxproc->readAllStandardError().data());
- if(oneshot)
- {
- disconnect(frameconn);
- if(x||st==QProcess::ExitStatus::CrashExit)
- qApp->exit(1);
- else
- qApp->exit(0);
- }
- });
- QMetaObject::invokeMethod(this,[this](){
- if(oneshot)
- rxproc->start();
- vf->show();
- startcb(nullptr,nullptr);
- },Qt::ConnectionType::QueuedConnection);
+ assert(vf);
+ subst =
+ {
+ {'w', QString::number(msettings->getOptionInt("Visualization/wwidth"))},
+ {'h', QString::number(msettings->getOptionInt("Visualization/wheight"))},
+ {'r', QString::number(msettings->getOptionInt("Visualization/tfps"))},
+ {
+ 'i',
+ QStringList()
+ << "-f" << "rawvideo"
+ << "-pixel_format" << "rgba"
+ << "-video_size" << QString("%1x%2").arg(msettings->getOptionInt("Visualization/wwidth")).arg(msettings->getOptionInt("Visualization/wheight"))
+ << "-framerate" << QString::number(msettings->getOptionInt("Visualization/tfps"))
+ << "-i" << "pipe:"
+ },
+ {'o', clp->value("output-file")}
+ };
+ if (clp->value("receiver-execution") == "per-frame")
+ {
+ subst['o'] = clp->value("output-file").replace("%f", QString("%1").arg(frameno, 6, 10, QChar('0')));
+ oneshot = false;
+ }
+ else
+ {
+ oneshot = true;
+ if (clp->value("receiver-execution") != "one-shot")
+ qWarning("Invalid value set for --receiver-execution. Using default value.");
+ }
+ rxproc = new QProcess();
+ QStringList arguments = process_arguments(clp->value("receiver"), subst);
+ assert(arguments.length() > 0);
+ rxproc->setProgram(arguments.front());
+ arguments.pop_front();
+ rxproc->setArguments(arguments);
+ frameconn = connect(this, &qmpVisRenderCore::frameRendered, this,
+ [this](void *px, size_t sz, uint32_t c, uint32_t t)
+ {
+ if (sz)
+ {
+ if (!oneshot)
+ {
+ subst['f'] = QString("%1").arg(frameno, 6, 10, QChar('0'));
+ subst['o'] = clp->value("output-file").replace("%f", QString("%1").arg(frameno, 6, 10, QChar('0')));
+ frameno++;
+ QStringList arguments = process_arguments(clp->value("receiver"), subst);
+ arguments.pop_front();
+ rxproc->setArguments(arguments);
+ rxproc->start();
+ rxproc->waitForStarted();
+ }
+ if (!rxproc->isOpen())
+ return;
+ rxproc->write(static_cast<const char *>(px), static_cast<qint64>(sz));
+ while (rxproc->bytesToWrite() > (oneshot ? (1 << 26) : 0))
+ rxproc->waitForBytesWritten();
+ if (!oneshot)
+ {
+ rxproc->closeWriteChannel();
+ rxproc->waitForFinished(-1);
+ }
+ }
+ fprintf(stderr, "Rendered tick %u of %u, %.2f%% done.\r", c, t, std::min(100., 100.*c / t));
+ if (c > t)
+ {
+ this->rxproc->closeWriteChannel();
+ disconnect(frameconn);
+ qApp->exit(0);
+ }
+ }, Qt::ConnectionType::BlockingQueuedConnection);
+ connect(rxproc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
+ [this](int x, QProcess::ExitStatus st)
+ {
+ qDebug("%s", this->rxproc->readAllStandardError().data());
+ if (oneshot)
+ {
+ disconnect(frameconn);
+ if (x || st == QProcess::ExitStatus::CrashExit)
+ qApp->exit(1);
+ else
+ qApp->exit(0);
+ }
+ });
+ QMetaObject::invokeMethod(this, [this]()
+ {
+ if (oneshot)
+ rxproc->start();
+ vf->show();
+ startcb(nullptr, nullptr);
+ }, Qt::ConnectionType::QueuedConnection);
}
-QStringList qmpVisRenderCore::process_arguments(QString a,QMap<QChar,QVariant> subst)
+QStringList qmpVisRenderCore::process_arguments(QString a, QMap<QChar, QVariant> subst)
{
- QStringList ret;
- QString buf;
- bool escaped=false;
- bool substi=false;
- for(int i=0;i<a.length();++i)
- {
- if(a[i]=='%')
- {
- if(escaped)
- {
- buf+='%';
- escaped=false;
- }
- else if(substi)
- {
- buf+='%';
- substi=false;
- }
- else substi=true;
- }
- else if(a[i]=='\\')
- {
- if(substi)
- {
- buf+='%';
- substi=false;
- }
- if(escaped)
- {
- buf+='\\';
- escaped=false;
- }
- else escaped=true;
- }
- else if(a[i]==' ')
- {
- if(substi)
- {
- buf+='%';
- substi=false;
- }
- if(escaped)buf+=' ';
- else
- {
- if(buf.length())
- ret.append(buf);
- buf.clear();
- }
- escaped=false;
- }
- else
- {
- if(substi&&subst.contains(a[i]))
- {
- if(subst[a[i]].canConvert(QMetaType::QString))
- buf+=subst[a[i]].toString();
- else
- {
- if(buf.length())
- {
- ret.append(buf);
- buf.clear();
- }
- for(auto &it:subst[a[i]].toStringList())
- ret.append(it);
- }
- substi=false;
- }
- else
- {
- if(escaped)
- {
- buf+='\\';
- escaped=false;
- }
- buf+=a[i];
- }
- }
- }
- if(buf.length())
- ret.append(buf);
- return ret;
+ QStringList ret;
+ QString buf;
+ bool escaped = false;
+ bool substi = false;
+ for (int i = 0; i < a.length(); ++i)
+ {
+ if (a[i] == '%')
+ {
+ if (escaped)
+ {
+ buf += '%';
+ escaped = false;
+ }
+ else if (substi)
+ {
+ buf += '%';
+ substi = false;
+ }
+ else substi = true;
+ }
+ else if (a[i] == '\\')
+ {
+ if (substi)
+ {
+ buf += '%';
+ substi = false;
+ }
+ if (escaped)
+ {
+ buf += '\\';
+ escaped = false;
+ }
+ else escaped = true;
+ }
+ else if (a[i] == ' ')
+ {
+ if (substi)
+ {
+ buf += '%';
+ substi = false;
+ }
+ if (escaped)
+ buf += ' ';
+ else
+ {
+ if (buf.length())
+ ret.append(buf);
+ buf.clear();
+ }
+ escaped = false;
+ }
+ else
+ {
+ if (substi && subst.contains(a[i]))
+ {
+ if (subst[a[i]].canConvert(QMetaType::QString))
+ buf += subst[a[i]].toString();
+ else
+ {
+ if (buf.length())
+ {
+ ret.append(buf);
+ buf.clear();
+ }
+ for (auto &it : subst[a[i]].toStringList())
+ ret.append(it);
+ }
+ substi = false;
+ }
+ else
+ {
+ if (escaped)
+ {
+ buf += '\\';
+ escaped = false;
+ }
+ buf += a[i];
+ }
+ }
+ }
+ if (buf.length())
+ ret.append(buf);
+ return ret;
}
-void qmpVisRenderCore::framefunc(void *px, size_t sz,uint32_t curf,uint32_t totf)
+void qmpVisRenderCore::framefunc(void *px, size_t sz, uint32_t curf, uint32_t totf)
{
- emit inst->frameRendered(px,sz,curf,totf);
+ emit inst->frameRendered(px, sz, curf, totf);
}
diff --git a/visualization/renderer/qmpvisrendercore.hpp b/visualization/renderer/qmpvisrendercore.hpp
index 71eeaed..ba978f4 100644
--- a/visualization/renderer/qmpvisrendercore.hpp
+++ b/visualization/renderer/qmpvisrendercore.hpp
@@ -15,44 +15,47 @@ class QCommandLineParser;
class QProcess;
-class qmpVisRenderCore:public QObject
+class qmpVisRenderCore: public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- qmpVisRenderCore(QCommandLineParser *_clp);
- bool loadVisualizationLibrary();
- void unloadVisualizationLibrary();
- void loadSettings();
- void setMIDIFile(const char* url);
- void startRender();
-
- qmpSettingsRO* settings(){return msettings;}
+ qmpVisRenderCore(QCommandLineParser *_clp);
+ bool loadVisualizationLibrary();
+ void unloadVisualizationLibrary();
+ void loadSettings();
+ void setMIDIFile(const char *url);
+ void startRender();
+
+ qmpSettingsRO *settings()
+ {
+ return msettings;
+ }
signals:
- void frameRendered(void* px,size_t sz,uint32_t current_tick,uint32_t total_ticks);
+ void frameRendered(void *px, size_t sz, uint32_t current_tick, uint32_t total_ticks);
private:
- qmpPluginIntf *vp;
- qmpFuncBaseIntf *vf;
- callback_t startcb;
- callback_t resetcb;
- void *mp;
- qmpPluginAPIStub *api;
- CMidiPlayer *player;
- qmpSettingsRO *msettings;
- QProcess *rxproc;
- QMap<QChar,QVariant> subst;
- QCommandLineParser *clp;
- QStringList process_arguments(QString a, QMap<QChar,QVariant> subst);
- int frameno;
- bool oneshot;
- QMetaObject::Connection frameconn;
- typedef qmpPluginIntf*(*GetInterface_func)(qmpPluginAPI*);
- typedef void(*SwitchMode_func)(void(*frameCallback)(void*,size_t,uint32_t,uint32_t),bool hidewindow);
-
- friend class qmpPluginAPIStub;
- static void framefunc(void* px, size_t sz, uint32_t curf, uint32_t totf);
- static qmpVisRenderCore *inst;
+ qmpPluginIntf *vp;
+ qmpFuncBaseIntf *vf;
+ callback_t startcb;
+ callback_t resetcb;
+ void *mp;
+ qmpPluginAPIStub *api;
+ CMidiPlayer *player;
+ qmpSettingsRO *msettings;
+ QProcess *rxproc;
+ QMap<QChar, QVariant> subst;
+ QCommandLineParser *clp;
+ QStringList process_arguments(QString a, QMap<QChar, QVariant> subst);
+ int frameno;
+ bool oneshot;
+ QMetaObject::Connection frameconn;
+ typedef qmpPluginIntf *(*GetInterface_func)(qmpPluginAPI *);
+ typedef void(*SwitchMode_func)(void(*frameCallback)(void *, size_t, uint32_t, uint32_t), bool hidewindow);
+
+ friend class qmpPluginAPIStub;
+ static void framefunc(void *px, size_t sz, uint32_t curf, uint32_t totf);
+ static qmpVisRenderCore *inst;
};
#endif // QMPVISRENDERCORE_HPP