diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | core/qmpmidioutfluid.cpp | 76 | ||||
-rw-r--r-- | core/qmpmidioutfluid.hpp | 10 | ||||
-rw-r--r-- | core/qmpmidioutrtmidi.cpp | 151 | ||||
-rw-r--r-- | core/qmpmidioutrtmidi.hpp | 19 | ||||
-rw-r--r-- | core/qmpmidiplay.cpp | 19 | ||||
-rw-r--r-- | core/qmpmidiplay.hpp | 2 | ||||
-rw-r--r-- | core/qmpmidiread.cpp | 11 | ||||
-rw-r--r-- | include/qmpcorepublic.hpp | 7 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpchanneleditor.cpp | 6 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpchannelswindow.cpp | 9 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmpplugin.cpp | 13 | ||||
-rw-r--r-- | qmidiplayer-desktop/qmppresetselect.cpp | 52 | ||||
-rw-r--r-- | visualization/visualization.pro | 4 |
14 files changed, 316 insertions, 75 deletions
@@ -1,3 +1,15 @@ +2019-06-16 0.8.7 indev +Inital implementation of the device properties API. + +Added new interfaces to qmpMidiOutDevice. +Implemented the new interfaces for qmpMidiOutFluid. +Initial infra for device initialization file parsing. +Move to the new interfaces for getting list of presets. +Use DevIL instead of CxImage. + +External output devices are broken now but that is for +another commit. + 2019-05-26 0.8.7 indev New flag field in SEvent. Further type usage corrections. diff --git a/core/qmpmidioutfluid.cpp b/core/qmpmidioutfluid.cpp index bb8f290..414cb3a 100644 --- a/core/qmpmidioutfluid.cpp +++ b/core/qmpmidioutfluid.cpp @@ -1,6 +1,6 @@ #include <cstdio> #include <cstring> -#include <map> +#include <algorithm> #include "qmpmidioutfluid.hpp" qmpMidiOutFluid::qmpMidiOutFluid() { @@ -30,6 +30,7 @@ void qmpMidiOutFluid::deviceInit() } 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) @@ -38,6 +39,7 @@ void qmpMidiOutFluid::deviceDeinit(bool freshsettings) delete_fluid_audio_driver(adriver); delete_fluid_synth(synth); synth=nullptr;adriver=nullptr; + bnk.clear();pst.clear(); if(freshsettings) { delete_fluid_settings(settings); @@ -117,6 +119,54 @@ 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(int 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 ""; + 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) +{ + 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); @@ -132,29 +182,33 @@ void qmpMidiOutFluid::setOptNum(const char *opt,double val) void qmpMidiOutFluid::loadSFont(const char *path) { if(synth)fluid_synth_sfload(synth,path,1); + update_preset_list(); } int qmpMidiOutFluid::getSFCount() { return synth?fluid_synth_sfcount(synth):0; } -std::vector<std::pair<std::pair<int,int>,std::string>> qmpMidiOutFluid::listPresets() +void qmpMidiOutFluid::update_preset_list() { - std::vector<std::pair<std::pair<int,int>,std::string>> ret; - std::map<std::pair<int,int>,std::string> pmap; + 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)) - pmap[std::make_pair( - fluid_preset_get_banknum(preset), - fluid_preset_get_num(preset) - )]=fluid_preset_get_name(preset); + { + 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]=" "; + } } - for(auto i=pmap.begin();i!=pmap.end();++i) - ret.push_back(std::make_pair(i->first,i->second)); - return ret; + std::sort(bnk.begin(),bnk.end()); + bnk.erase(std::unique(bnk.begin(),bnk.end()),bnk.end()); } int qmpMidiOutFluid::getPolyphone() { diff --git a/core/qmpmidioutfluid.hpp b/core/qmpmidioutfluid.hpp index 963f9df..72197e7 100644 --- a/core/qmpmidioutfluid.hpp +++ b/core/qmpmidioutfluid.hpp @@ -3,6 +3,7 @@ #include <string> #include <utility> #include <vector> +#include <unordered_map> #include "../include/qmpcorepublic.hpp" #include <fluidsynth.h> class IFluidSettings @@ -22,6 +23,9 @@ class qmpMidiOutFluid:public qmpMidiOutDevice,public IFluidSettings 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; + void update_preset_list(); public: qmpMidiOutFluid(); ~qmpMidiOutFluid(); @@ -36,13 +40,17 @@ class qmpMidiOutFluid:public qmpMidiOutDevice,public IFluidSettings 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(int 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); //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(); - std::vector<std::pair<std::pair<int,int>,std::string>> listPresets(); int getPolyphone(); int getMaxPolyphone(); diff --git a/core/qmpmidioutrtmidi.cpp b/core/qmpmidioutrtmidi.cpp index 2d6d41f..0ff2c86 100644 --- a/core/qmpmidioutrtmidi.cpp +++ b/core/qmpmidioutrtmidi.cpp @@ -1,8 +1,144 @@ +#include <cctype> #include <cstdio> #include <cstring> +#include <deque> #include <vector> #include RT_MIDI_H #include "qmpmidioutrtmidi.hpp" + +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; + } +} + +qmpDeviceInitializer* qmpDeviceInitializer::parse(const char* path) +{ + qmpDeviceInitializer *ret=new qmpDeviceInitializer(); + ret->initseq.eventList.clear(); + FILE* f=fopen(path, "r"); + if(!f)return nullptr; + + bool st_inmapping=false; + char buf[1024]; + int ln=0; + int cmsb=-1,clsb=-1; + + //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; + }; +#define err(e) {delete ret;return fprintf(stderr,"line %d: %s",ln,e),nullptr;} + 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(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") + { + 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; + } + } + } + } +#undef err + + fclose(f); + return ret; +} + qmpMidiOutRtMidi::qmpMidiOutRtMidi(unsigned _portid) { portid=_portid; @@ -91,6 +227,21 @@ void qmpMidiOutRtMidi::onUnmapped(uint8_t ch,int refcnt) panic(ch); if(!refcnt&&outport)outport->closePort(); } +std::vector<std::pair<uint16_t,std::string>> qmpMidiOutRtMidi::getBankList() +{ +} +std::vector<std::pair<uint8_t,std::string>> qmpMidiOutRtMidi::getPresets(int bank) +{ +} +std::string qmpMidiOutRtMidi::getPresetName(uint16_t bank,uint8_t preset) +{ +} +bool qmpMidiOutRtMidi::getChannelPreset(int ch,uint16_t *bank,uint8_t *preset,std::string &presetname) +{ +} +uint8_t qmpMidiOutRtMidi::getInitialCCValue(uint8_t cc) +{ +} RtMidiOut* qmpRtMidiManager::dummy=nullptr; void qmpRtMidiManager::createDevices() diff --git a/core/qmpmidioutrtmidi.hpp b/core/qmpmidioutrtmidi.hpp index 48ee0cf..23adec6 100644 --- a/core/qmpmidioutrtmidi.hpp +++ b/core/qmpmidioutrtmidi.hpp @@ -1,9 +1,23 @@ #ifndef QMPMIDIMAPPERS_H #define QMPMIDIMAPPERS_H +#include <unordered_map> #include <vector> #define QMP_MAIN #include "../include/qmpcorepublic.hpp" #include RT_MIDI_H +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]; + + static qmpDeviceInitializer* parse(const char* path); +}; class qmpMidiOutRtMidi:public qmpMidiOutDevice { private: @@ -22,6 +36,11 @@ public: 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(int 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); }; class qmpRtMidiManager { diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp index 28ca9e7..bbf1c3a 100644 --- a/core/qmpmidiplay.cpp +++ b/core/qmpmidiplay.cpp @@ -241,7 +241,7 @@ void CMidiPlayer::fileTimer2Pass() memset(ccc,0,sizeof(ccc));memset(rpnid,0xFF,sizeof(rpnid));memset(rpnval,0xFF,sizeof(rpnval)); for(int i=0;i<16;++i) { - ccc[i][7]=100;ccc[i][8]=64;ccc[i][10]=64;ccc[i][11]=127; + ccc[i][7]=100;ccc[i][8]=64;ccc[i][10]=64; 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; @@ -427,19 +427,6 @@ uint32_t CMidiPlayer::isFinished(){return finished;} void CMidiPlayer::setResumed(){resumed=true;} void CMidiPlayer::setWaitVoice(bool wv){waitvoice=wv;} -void CMidiPlayer::getChannelPreset(int ch,int *b,int *p,char *name) -{ - if(mappedoutput[ch]) - { - *b=((int)chstatus[ch][0]<<7)|chstatus[ch][32]; - *p=chstatus[ch][128]; - strcpy(name,""); - } - else - { - internalFluid->getChannelInfo(ch,b,p,name); - } -} void CMidiPlayer::setChannelPreset(int ch,int b,int p) { chstatus[ch][128]=p; @@ -510,6 +497,10 @@ 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]; diff --git a/core/qmpmidiplay.hpp b/core/qmpmidiplay.hpp index f42c98b..da9e9ef 100644 --- a/core/qmpmidiplay.hpp +++ b/core/qmpmidiplay.hpp @@ -141,7 +141,6 @@ class CMidiPlayer void sendSysX(bool send); 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); bool getChannelMask(int ch); @@ -154,6 +153,7 @@ class CMidiPlayer void unregisterMidiOutDevice(std::string name); std::vector<std::string> getMidiOutDevices(); int getChannelOutput(int ch); + qmpMidiOutDevice* getChannelOutputDevice(int ch); void setChannelOutput(int ch,int outid); uint8_t* getChstates(); int setEventHandlerCB(ICallBack *cb,void *userdata); diff --git a/core/qmpmidiread.cpp b/core/qmpmidiread.cpp index 7f5bdfc..48a149d 100644 --- a/core/qmpmidiread.cpp +++ b/core/qmpmidiread.cpp @@ -94,7 +94,8 @@ int CSMFReader::read_event()//returns 0 if End of Track encountered 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); - if(str)str[len]='\0'; + std::string sstr; + if(str){str[len]='\0';sstr=std::string(str,len);} switch(metatype) { case 0x00://Sequence Number @@ -108,24 +109,24 @@ int CSMFReader::read_event()//returns 0 if End of Track encountered return 0; case 0x51://Set Tempo assert(len==3); - curTrack->appendEvent(SEvent(curid,curt,type,metatype,0,str)); + 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,str)); + 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,str)); + 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,str)); + curTrack->appendEvent(SEvent(curid,curt,type,metatype,0,sstr)); if(str&&metatype==0x03&&!ret->title) { ret->title=new char[len+8]; diff --git a/include/qmpcorepublic.hpp b/include/qmpcorepublic.hpp index a4949ac..34e4ea6 100644 --- a/include/qmpcorepublic.hpp +++ b/include/qmpcorepublic.hpp @@ -24,6 +24,8 @@ struct SEvent 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 @@ -92,6 +94,11 @@ class qmpMidiOutDevice 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(int 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)=0; virtual ~qmpMidiOutDevice(){} }; //Main plugin interface. diff --git a/qmidiplayer-desktop/qmpchanneleditor.cpp b/qmidiplayer-desktop/qmpchanneleditor.cpp index 206a2fa..71dd455 100644 --- a/qmidiplayer-desktop/qmpchanneleditor.cpp +++ b/qmidiplayer-desktop/qmpchanneleditor.cpp @@ -25,9 +25,9 @@ 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(); - int b,p; - player->getChannelPreset(ch,&b,&p,str); - ui->lbPresetName->setText(str); + uint16_t b;uint8_t p;std::string pstn; + player->getChannelOutputDevice(ch)->getChannelPreset(ch,&b,&p,pstn); + 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)); diff --git a/qmidiplayer-desktop/qmpchannelswindow.cpp b/qmidiplayer-desktop/qmpchannelswindow.cpp index 8968bed..5a6a2de 100644 --- a/qmidiplayer-desktop/qmpchannelswindow.cpp +++ b/qmidiplayer-desktop/qmpchannelswindow.cpp @@ -153,10 +153,11 @@ void qmpChannelsWindow::channelWindowsUpdate() } for(int i=0;i<16;++i) { - char data[128],nm[256]; - int b,p; - qmpMainWindow::getInstance()->getPlayer()->getChannelPreset(i,&b,&p,nm); - sprintf(data,"%03d:%03d %s",b,p,nm); + char data[128]; + std::string nm; + uint16_t b;uint8_t p; + qmpMainWindow::getInstance()->getPlayer()->getChannelOutputDevice(i)->getChannelPreset(i,&b,&p,nm); + sprintf(data,"%03d:%03d %s",b,p,nm.c_str()); if(fused) { if(strcmp((ui->twChannels->item(i,4))-> diff --git a/qmidiplayer-desktop/qmpplugin.cpp b/qmidiplayer-desktop/qmpplugin.cpp index 8655dff..2339625 100644 --- a/qmidiplayer-desktop/qmpplugin.cpp +++ b/qmidiplayer-desktop/qmpplugin.cpp @@ -153,11 +153,11 @@ int qmpPluginAPI::getChannelCC(int ch,int cc) {return qmw&&qmw->getPlayer()?qmw->getPlayer()->getCC(ch,cc):0;} int qmpPluginAPI::getChannelPreset(int ch) { - int b,p;char nm[256]; + uint16_t b;uint8_t p;std::string nm; if(qmw&&qmw->getPlayer()) { - qmw->getPlayer()->getChannelPreset(ch,&b,&p,nm); - return p; + if(qmw->getPlayer()->getChannelOutputDevice(ch)->getChannelPreset(ch,&b,&p,nm))return p; + return qmw->getPlayer()->getCC(ch,128); } return 0; } @@ -173,11 +173,12 @@ std::wstring qmpPluginAPI::getWTitle() {return qmw?qmw->getWTitle():L"";} std::string qmpPluginAPI::getChannelPresetString(int ch) { - int b,p;char nm[256],ret[320];ret[0]=0; + uint16_t b;uint8_t p;char ret[320];ret[0]=0; + std::string nm; if(qmw&&qmw->getPlayer()) { - qmw->getPlayer()->getChannelPreset(ch,&b,&p,nm); - snprintf(ret,320,"%03d:%03d %s",b,p,nm); + qmw->getPlayer()->getChannelOutputDevice(ch)->getChannelPreset(ch,&b,&p,nm); + snprintf(ret,320,"%03d:%03d %s",b,p,nm.c_str()); } return std::string(ret); } diff --git a/qmidiplayer-desktop/qmppresetselect.cpp b/qmidiplayer-desktop/qmppresetselect.cpp index 8afea2b..a32aa99 100644 --- a/qmidiplayer-desktop/qmppresetselect.cpp +++ b/qmidiplayer-desktop/qmppresetselect.cpp @@ -20,29 +20,25 @@ void qmpPresetSelector::showEvent(QShowEvent *e) memset(presets,0,sizeof(presets)); CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer(); if(!plyr->fluid()->getSFCount())return e->ignore(); - std::vector<std::pair<std::pair<int,int>,std::string>> - presetlist=plyr->fluid()->listPresets(); - for(auto &i:presetlist) - strcpy(presets[i.first.first][i.first.second],i.second.c_str()); ui->lwBankSelect->clear(); ui->lwPresetSelect->clear(); - for(int i=0;i<=128;++i) - { - int b=0; - for(int j=0;j<128;++j)if(strlen(presets[i][j])){b=1;break;} - if(b)ui->lwBankSelect->addItem(QString::number(i)); - } e->accept(); } void qmpPresetSelector::setupWindow(int chid) { CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer(); if(!plyr->fluid()->getSFCount())return; - ch=chid;int b=0,p=0,r;char name[256]; + 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); - plyr->getChannelPreset(chid,&b,&p,name); - if(plyr->getChannelOutput(chid)){ + r=plyr->getChannelOutputDevice(ch)->getChannelPreset(ch,&b,&p,pstname); + 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); @@ -58,21 +54,20 @@ void qmpPresetSelector::setupWindow(int chid) ui->spCustomLSB->setEnabled(false); ui->spCustomMSB->setEnabled(false); ui->spCustomPC->setEnabled(false); - for(int i=0;i<ui->lwBankSelect->count();++i){ - sscanf(ui->lwBankSelect->item(i)->text().toStdString().c_str(),"%3d",&r); - if(r==b){ui->lwBankSelect->setCurrentRow(i);break;} + 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); } - r=0; - ui->lwPresetSelect->clear(); - for(int i=0,cr=0;i<128;++i) - if(strlen(presets[b][i])) + ui->lwBankSelect->blockSignals(false); + for(auto&i:plyr->getChannelOutputDevice(ch)->getPresets(b)) { - sprintf(name,"%03d %s",i,presets[b][i]); - if(i==p)r=cr; + snprintf(name,256,"%03d %s",i.first,i.second.c_str()); ui->lwPresetSelect->addItem(name); - cr++; + if(i.first==p)ui->lwPresetSelect->setCurrentRow(ui->lwPresetSelect->count()-1); } - ui->lwPresetSelect->setCurrentRow(r); } } @@ -109,14 +104,15 @@ void qmpPresetSelector::on_lwPresetSelect_itemDoubleClicked() void qmpPresetSelector::on_lwBankSelect_currentRowChanged() { + fprintf(stderr,"bs cr changed\n"); ui->lwPresetSelect->clear(); if(!ui->lwBankSelect->currentItem())return; - char name[30];int b; + char name[256];int b; sscanf(ui->lwBankSelect->currentItem()->text().toStdString().c_str(),"%d",&b); - for(int i=0;i<128;++i) - if(strlen(presets[b][i])) + CMidiPlayer *plyr=qmpMainWindow::getInstance()->getPlayer(); + for(auto&i:plyr->getChannelOutputDevice(ch)->getPresets(b)) { - sprintf(name,"%03d %s",i,presets[b][i]); + snprintf(name,256,"%03d %s",i.first,i.second.c_str()); ui->lwPresetSelect->addItem(name); } } diff --git a/visualization/visualization.pro b/visualization/visualization.pro index 646e301..892680e 100644 --- a/visualization/visualization.pro +++ b/visualization/visualization.pro @@ -36,12 +36,12 @@ unix { INCLUDEPATH += /home/chrisoft/devel/SMELT/include/ /usr/include/freetype2 LIBS += -L/home/chrisoft/devel/SMELT/smelt/glfw/ LIBS += -L/home/chrisoft/devel/SMELT/extensions/ - LIBS += -lstdc++ -lfreetype -lz -lsmeltext -lsmelt-dumb -lCxImage -ljpeg -lpng -lglfw -lGLEW -lGL + LIBS += -lstdc++ -lfreetype -lz -lsmeltext -lsmelt-dumb -lIL -ljpeg -lpng -lglfw -lGLEW -lGL }else{ INCLUDEPATH += $$(SMELT_DIR)/include/ /usr/include/freetype2 LIBS += -L$$(SMELT_DIR)/smelt/glfw/ LIBS += -L$$(SMELT_DIR)/extensions/ - LIBS += -lstdc++ -lfreetype -lz -lsmeltext -lsmelt-dumb -lCxImage -ljpeg -lpng -lglfw -lGLEW -lGL + LIBS += -lstdc++ -lfreetype -lz -lsmeltext -lsmelt-dumb -lIL -ljpeg -lpng -lglfw -lGLEW -lGL } } win32 { |