aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2019-11-26 15:47:38 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2019-11-26 15:47:38 +0800
commit62393aa7b9069274459d00024fc2b238b0044eb6 (patch)
tree00ed1ee70e3103e6fcb3375734bc93097691d54d
parent9c2eb04f6baadf33f60bf4af35caec77aebf48ff (diff)
downloadQMidiPlayer-62393aa7b9069274459d00024fc2b238b0044eb6.tar.xz
We're now in bug squashing mode!
You can now specify control initial values for each individual channels. Added build instructions for the folks out there rocking a more superior operating system.
-rw-r--r--INSTALL.md21
-rw-r--r--core/qmpmidioutfluid.cpp2
-rw-r--r--core/qmpmidioutfluid.hpp2
-rw-r--r--core/qmpmidioutrtmidi.cpp20
-rw-r--r--core/qmpmidioutrtmidi.hpp3
-rw-r--r--core/qmpmidiplay.cpp2
-rw-r--r--doc/SD-80_SD-90_Native.devinit3
-rw-r--r--include/qmpcorepublic.hpp2
8 files changed, 48 insertions, 7 deletions
diff --git a/INSTALL.md b/INSTALL.md
index 028c06d..46609ec 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -27,3 +27,24 @@ Currently I use [mxe](https://mxe.cc) for Windows builds.
If you are using msvc, I would recommend trying out [this fork](https://github.com/chirs241097/fluidsynth-sans-glib/)
of fluidsynth to reduce your potential pain when building QMidiPlayer.
+## Building QMidiPlayer with mxe in Windows Subsystem for Linux
+
+First get mxe working using their [instructions](https://mxe.cc/#tutorial), then:
+```
+make cmake qt5 glfw3 glew devil zlib freetype fluidsynth
+```
+
+Proceed with normal instructions for Linux with tools replaced by those
+provided by mxe. You have to build and install RtMidi yourself.
+
+At the moment there are some issues with mxe that may cause a
+build failure:
+ - A cmake file installed by glfw3 refers to a wrong file. Open
+ mxe/usr/x86_64-w64-mingw32.shared/lib/cmake/glfw3/glfw3Targets-release.cmake
+ ane add the missing dots for a temporary workaround. Also glfw3.dll
+ should be in bin, not in lib.
+ - It seems that GLEW can't tell Windows shared libraries from static
+ libraries. Check the function __glew_set_find_library_suffix in
+ FindGLEW.cmake and make sure the section for WIN32 makes sense.
+
+This list may change whenever mxe updates. You are on your own to figure them out.
diff --git a/core/qmpmidioutfluid.cpp b/core/qmpmidioutfluid.cpp
index 4fcdd21..87c1207 100644
--- a/core/qmpmidioutfluid.cpp
+++ b/core/qmpmidioutfluid.cpp
@@ -156,7 +156,7 @@ bool qmpMidiOutFluid::getChannelPreset(int ch,uint16_t *bank,uint8_t *preset,std
presetname=fluid_preset_get_name(chpreset);
return true;
}
-uint8_t qmpMidiOutFluid::getInitialCCValue(uint8_t cc)
+uint8_t qmpMidiOutFluid::getInitialCCValue(uint8_t cc,uint8_t)
{
switch(cc)
{
diff --git a/core/qmpmidioutfluid.hpp b/core/qmpmidioutfluid.hpp
index 6cd2058..9c84264 100644
--- a/core/qmpmidioutfluid.hpp
+++ b/core/qmpmidioutfluid.hpp
@@ -44,7 +44,7 @@ class qmpMidiOutFluid:public qmpMidiOutDevice,public IFluidSettings
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 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);
diff --git a/core/qmpmidioutrtmidi.cpp b/core/qmpmidioutrtmidi.cpp
index eeda04b..76b12e6 100644
--- a/core/qmpmidioutrtmidi.cpp
+++ b/core/qmpmidioutrtmidi.cpp
@@ -26,6 +26,7 @@ qmpDeviceInitializer* qmpDeviceInitializer::parse(const char* path)
{
qmpDeviceInitializer *ret=new qmpDeviceInitializer();
ret->initseq.eventList.clear();
+ memset(ret->sinitv,0xFF,sizeof(ret->sinitv));
bool st_inmapping=false;
char buf[1024];
@@ -90,6 +91,8 @@ qmpDeviceInitializer* qmpDeviceInitializer::parse(const char* path)
}
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());
@@ -118,6 +121,8 @@ qmpDeviceInitializer* qmpDeviceInitializer::parse(const char* path)
}
else if(tok.front()=="IV")
{
+ if(st_inmapping)
+ err("invalid command")
int ci=0;
tok.pop_front();
for(auto&tk:tok)
@@ -134,6 +139,15 @@ qmpDeviceInitializer* qmpDeviceInitializer::parse(const char* path)
}
}
}
+ 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()==']')
@@ -298,9 +312,11 @@ bool qmpMidiOutRtMidi::getChannelPreset(int ch,uint16_t *bank,uint8_t *preset,st
//This ain't a state-tracking device
return false;
}
-uint8_t qmpMidiOutRtMidi::getInitialCCValue(uint8_t cc)
+uint8_t qmpMidiOutRtMidi::getInitialCCValue(uint8_t cc,uint8_t ch)
{
- if(!devinit)return 0;//Nope!
+ if(!devinit||cc>=130)return 0;//Nope!
+ if(ch<16&&devinit->sinitv[ch][cc]!=0xFF)
+ return devinit->sinitv[ch][cc];
return devinit->initv[cc];
}
void qmpMidiOutRtMidi::setInitializerFile(const char* path)
diff --git a/core/qmpmidioutrtmidi.hpp b/core/qmpmidioutrtmidi.hpp
index 2c9195c..45662ba 100644
--- a/core/qmpmidioutrtmidi.hpp
+++ b/core/qmpmidioutrtmidi.hpp
@@ -14,6 +14,7 @@ struct qmpDeviceInitializer
};
std::unordered_map<uint16_t,BankStore> banks;
uint8_t initv[130];
+ uint8_t sinitv[16][130];
static qmpDeviceInitializer* parse(const char* path);
};
@@ -42,7 +43,7 @@ public:
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 getInitialCCValue(uint8_t cc,uint8_t ch);
void setInitializerFile(const char* path);
};
diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp
index 89fdf84..c24b0c9 100644
--- a/core/qmpmidiplay.cpp
+++ b/core/qmpmidiplay.cpp
@@ -453,7 +453,7 @@ bool CMidiPlayer::getChannelMask(int ch)
int CMidiPlayer::getCC(int ch,int id)
{
if(chstatus[ch][id]==0xff)
- return getChannelOutputDevice(ch)->getInitialCCValue(id);
+ return getChannelOutputDevice(ch)->getInitialCCValue(uint8_t(id),uint8_t(ch));
return chstatus[ch][id];
}
void CMidiPlayer::setCC(int ch,int id,int val)
diff --git a/doc/SD-80_SD-90_Native.devinit b/doc/SD-80_SD-90_Native.devinit
index 3bf37d0..d9a5717 100644
--- a/doc/SD-80_SD-90_Native.devinit
+++ b/doc/SD-80_SD-90_Native.devinit
@@ -16,6 +16,9 @@ C FF 01 00
# 00 01 02~06 07 08 09 10 11 12~70 71~78 79~90 91 92~127 PC PBR
IV 60 00 00,5 64 00 00 40 64 00,59 40,8 00,12 28 00,36 00 02
+# bank selection for channel #10
+SIV 09 00 68
+
MAP EDIROL Studio Canvas Native Map
[80:0:Special 1]
000=D.L.A.Pad
diff --git a/include/qmpcorepublic.hpp b/include/qmpcorepublic.hpp
index eda8933..963eff1 100644
--- a/include/qmpcorepublic.hpp
+++ b/include/qmpcorepublic.hpp
@@ -98,7 +98,7 @@ class qmpMidiOutDevice
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)=0;
+ virtual uint8_t getInitialCCValue(uint8_t cc,uint8_t ch)=0;
virtual ~qmpMidiOutDevice(){}
};
//Main plugin interface.