From cd09a7e8a42c8f3617cfe3c57eed3b96bcfd2ec5 Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Mon, 11 Apr 2016 23:03:00 +0800 Subject: Flower Night. --- ChangeLog | 3 ++ core/qmpmidimapperrtmidi.cpp | 6 ++++ core/qmpmidimappers.hpp | 1 + core/qmpmidiplay.cpp | 78 +++++++++++++++++++++++++++++++++++--------- core/qmpmidiplay.hpp | 2 +- debian/changelog | 7 ++++ 6 files changed, 81 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index a021393..e89171c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2016-04-11 0.7.1 beta +Sanitise MIDI mapping functionality. + 2016-04-10 0.7.1 beta Implement output mapping related options. Fixed several stupid mistakes and typos. diff --git a/core/qmpmidimapperrtmidi.cpp b/core/qmpmidimapperrtmidi.cpp index 10f830e..7d6cdac 100644 --- a/core/qmpmidimapperrtmidi.cpp +++ b/core/qmpmidimapperrtmidi.cpp @@ -86,3 +86,9 @@ void qmpMidiMapperRtMidi::sysEx(int iid,int length,const char *data) std::vectormessage(data,data+length); ports[iid]->sendMessage(&message); } +void qmpMidiMapperRtMidi::panic(int iid,int ch) +{ + //maybe all notes off is more close to panic? + ctrlChange(iid,ch,120,0); + //ctrlChange(iid,ch,123,0); +} diff --git a/core/qmpmidimappers.hpp b/core/qmpmidimappers.hpp index 156caaa..334a2d2 100644 --- a/core/qmpmidimappers.hpp +++ b/core/qmpmidimappers.hpp @@ -17,6 +17,7 @@ public: void progChange(int iid,int ch,int val); void pitchBend(int iid,int ch,int val); void sysEx(int iid,int length,const char* data); + void panic(int iid,int ch); int enumDevices(); std::string deviceName(int id); }; diff --git a/core/qmpmidiplay.cpp b/core/qmpmidiplay.cpp index 2ea0873..6b0c16f 100644 --- a/core/qmpmidiplay.cpp +++ b/core/qmpmidiplay.cpp @@ -70,12 +70,14 @@ void CMidiPlayer::processEvent(const SEvent *e) if(rpnid==0)fluid_synth_pitch_wheel_sens(synth,e->type&0x0F,rpnval); rpnid=rpnval=-1; } + chstatus[e->type&0x0F][e->p1]=e->p2; if(mappedoutput[e->type&0x0F]) mapper->ctrlChange(mappedoutput[e->type&0x0F]-1,e->type&0x0F,e->p1,e->p2); else fluid_synth_cc(synth,e->type&0x0F,e->p1,e->p2); break; case 0xC0://PC + chstatus[e->type&0x0F][128]=e->p1; if(mappedoutput[e->type&0x0F]) mapper->progChange(mappedoutput[e->type&0x0F]-1,e->type&0x0F,e->p1); else @@ -280,6 +282,7 @@ void CMidiPlayer::playerPanic(bool reset) fluid_synth_cc(synth,i,10,64); fluid_synth_cc(synth,i,11,127); } + //all sounds off causes the minus polyphone bug... for(int i=0;i<16;++i)fluid_synth_all_notes_off(synth,i); } bool CMidiPlayer::playerLoadFile(const char* fn) @@ -295,7 +298,12 @@ 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; + sendSysEx=true;rpnid=rpnval=-1;memset(chstatus,0,sizeof(chstatus)); + for(int i=0;i<16;++i) + chstatus[i][7]=100,chstatus[i][11]=127, + chstatus[i][10]=chstatus[i][71]=chstatus[i][72]= + chstatus[i][73]=chstatus[i][74]=chstatus[i][75]= + chstatus[i][76]=chstatus[i][77]=chstatus[i][78]=64; if(!singleInstance)fluidPreInitialize(); } void CMidiPlayer::playerDeinit() @@ -375,17 +383,38 @@ void CMidiPlayer::setMaxPolyphone(int p){if(synth)fluid_synth_set_polyphony(synt 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,"")); + if(mappedoutput[ch]) + { + *b=((int)chstatus[ch][0]<<7)|chstatus[ch][32]; + *p=chstatus[ch][128]; + strcpy(name,""); + } + else + { + 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) { if(!synth)return; - fluid_synth_bank_select(synth,ch,b); - fluid_synth_program_change(synth,ch,p); + chstatus[ch][0]=b;//!!FIXME: This is not correct... + chstatus[ch][128]=p; + if(mappedoutput[ch]) + { + //external device mode? + mapper->ctrlChange(mappedoutput[ch]-1,ch,0,b); + mapper->ctrlChange(mappedoutput[ch]-1,ch,32,b); + mapper->progChange(mappedoutput[ch]-1,ch,p); + } + else + { + 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) @@ -394,10 +423,21 @@ 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;} -void CMidiPlayer::setCC(int ch, int id, int val) -{synth?fluid_synth_cc(synth,ch,id,val):0;} +int CMidiPlayer::getCC(int ch,int id) +{ + int ret=0; + if(mappedoutput[ch]) + ret=chstatus[ch][id]; + else + if(synth)fluid_synth_get_cc(synth,ch,id,&ret); + return ret; +} +void CMidiPlayer::setCC(int ch,int id,int val) +{ + if(!synth)return; + mappedoutput[ch]?mapper->ctrlChange(mappedoutput[ch]-1,ch,id,val): + (void)fluid_synth_cc(synth,ch,id,val); +} void CMidiPlayer::getReverbPara(double *r,double *d,double *w,double *l) { if(!synth)return; @@ -443,14 +483,22 @@ void CMidiPlayer::setChannelOutput(int ch,int devid) if(devid>0) { if(!deviceusage[devid-1])deviceiid[devid]=newoutput=mapper->deviceInit(devid-1); - ++deviceusage[deviceiid[devid]]; + ++deviceusage[deviceiid[devid]];mapper->progChange(deviceiid[devid],ch,chstatus[ch][128]); + for(int i=0;i<128;++i)if(i!=100&&i!=101)mapper->ctrlChange(deviceiid[devid],ch,i,chstatus[ch][i]); + } + else + { + fluid_synth_bank_select(synth,ch,chstatus[ch][0]); + fluid_synth_program_change(synth,ch,chstatus[ch][128]); + for(int i=0;i<128;++i)if(i!=100&&i!=101&&i!=0&&i!=32) + fluid_synth_cc(synth,ch,i,chstatus[ch][i]); } mappedoutput[ch]=devid?deviceiid[devid]+1:0; if(origoutput>0) { - --deviceusage[origoutput-1]; + --deviceusage[origoutput-1];mapper->panic(origoutput-1,ch); if(!deviceusage[origoutput-1])mapper->deviceDeinit(origoutput-1); - } + }else fluid_synth_all_notes_off(synth,ch); } uint8_t* CMidiPlayer::getChstates(){return chstate;} void CMidiPlayer::setNoteOnCallBack(CMidiCallBack *cb,void *userdata) diff --git a/core/qmpmidiplay.hpp b/core/qmpmidiplay.hpp index 4592ea0..15fcd89 100644 --- a/core/qmpmidiplay.hpp +++ b/core/qmpmidiplay.hpp @@ -79,7 +79,7 @@ class CMidiPlayer uint32_t finished,resumed; qmpMidiMapperRtMidi *mapper; int mappedoutput[16],deviceusage[16],deviceiid[128]; - uint8_t chstate[16]; + uint8_t chstate[16],chstatus[16][130];//0..127: cc 128: pc CMidiCallBack *noteOnCB; void* noteOnCBUserData; diff --git a/debian/changelog b/debian/changelog index b19c3e4..781bf5c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +qmidiplayer (0.7.1-2) UNRELEASED; urgency=low + + * New upstream release. + + -- chrisoft Mon, 11 Apr 2016 22:58:47 +0800 + + qmidiplayer (0.7.1-1) UNRELEASED; urgency=low * New upstream release. -- cgit v1.2.3