diff options
author | Florian Jung <flo@windfisch.org> | 2011-06-28 12:38:56 +0000 |
---|---|---|
committer | Florian Jung <flo@windfisch.org> | 2011-06-28 12:38:56 +0000 |
commit | 1ee2c8cb621fdc9b165b891f6d8d4607dadabf9b (patch) | |
tree | 27174350316c57d48f8ecaad54f7919f0ba106e1 /muse2/synti | |
parent | 2f4a98c62adf7241944ea7949d4b6a50d4b4af36 (diff) | |
parent | 933aeb536f3d90eb38bc96308de628eeedd81755 (diff) |
merged with current trunk. i hope this works...
Diffstat (limited to 'muse2/synti')
50 files changed, 1637 insertions, 5440 deletions
diff --git a/muse2/synti/deicsonze/common_defs.h b/muse2/synti/deicsonze/common_defs.h new file mode 100644 index 00000000..3c433e2a --- /dev/null +++ b/muse2/synti/deicsonze/common_defs.h @@ -0,0 +1,10 @@ +#ifndef __DEICSONZE_UNIQUE_ID_H +#define __DEICSONZE_UNIQUE_ID_H + +// Make sure this number is unique among all the MESS synths. +#define DEICSONZE_UNIQUE_ID 5 + +//#define DEICSONZE_DEBUG + +#endif + diff --git a/muse2/synti/deicsonze/deicsonze.cpp b/muse2/synti/deicsonze/deicsonze.cpp index 1da9fbc4..b723e925 100644 --- a/muse2/synti/deicsonze/deicsonze.cpp +++ b/muse2/synti/deicsonze/deicsonze.cpp @@ -37,6 +37,7 @@ #include "muse/midi.h" #include "libsynti/mess.h" +//#include "common_defs.h" #include "deicsonze.h" #include "plugin.h" @@ -91,6 +92,9 @@ DeicsOnze::DeicsOnze() : Mess(2) { waveTable[W8][i] = (float)(i<RESOLUTION/2?sin(t)*sin(t):0.0);} } + initBuffer = 0; + initLen = 0; + //alloc temp buffers chorus and reverb tempInputChorus = (float**) malloc(sizeof(float*)*NBRFXINPUTS); for(int i = 0; i < NBRFXINPUTS; i++) @@ -236,6 +240,9 @@ DeicsOnze::DeicsOnze() : Mess(2) { DeicsOnze::~DeicsOnze() { + if(_gui) + delete _gui; // p4.0.27 + //if (--useCount == 0) //delete[] sine_table; //dealloc temp buffers chorus and reverb @@ -251,8 +258,18 @@ DeicsOnze::~DeicsOnze() free(tempInputDelay); for(int i = 0; i < NBRFXOUTPUTS; i++) free(tempOutputDelay[i]); free(tempOutputDelay); + + if (initBuffer) + delete [] initBuffer; } +int DeicsOnze::oldMidiStateHeader(const unsigned char** data) const +{ + unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, DEICSONZE_UNIQUE_ID}; + *data = &d[0]; + return 2; +} + //--------------------------------------------------------- // getSinusWaveTable //--------------------------------------------------------- @@ -2266,9 +2283,23 @@ void DeicsOnze::writeConfiguration(AL::Xml* xml) { } //--------------------------------------------------------- +// getInitBuffer +//--------------------------------------------------------- +void DeicsOnze::setupInitBuffer(int len) +{ + if (len > initLen) { + if (initBuffer) + delete [] initBuffer; + initBuffer = new unsigned char[len]; + initLen = len; + } +} + +//--------------------------------------------------------- // getInitData //--------------------------------------------------------- -void DeicsOnze::getInitData(int* length, const unsigned char** data) const { +//void DeicsOnze::getInitData(int* length, const unsigned char** data) const { +void DeicsOnze::getInitData(int* length, const unsigned char** data) { //write the set in a temporary file and in a QByteArray QTemporaryFile file; file.open(); @@ -2284,141 +2315,150 @@ void DeicsOnze::getInitData(int* length, const unsigned char** data) const { //save the set *length = NUM_CONFIGLENGTH + //*length = 2 + NUM_CONFIGLENGTH // 2 for Header ///+ (_pluginIReverb?sizeof(float)*_pluginIReverb->plugin()->parameter():0) + (_pluginIReverb?sizeof(float)*_pluginIReverb->plugin()->controlInPorts():0) ///+ (_pluginIChorus?sizeof(float)*_pluginIChorus->plugin()->parameter():0) + (_pluginIChorus?sizeof(float)*_pluginIChorus->plugin()->controlInPorts():0) + baComp.size(); - unsigned char* buffer = new unsigned char[*length]; + ///unsigned char* buffer = new unsigned char[*length]; + setupInitBuffer(*length); + //save init data - buffer[0]=SYSEX_INIT_DATA; - buffer[1]=SYSEX_INIT_DATA_VERSION; + + ///buffer[0]=SYSEX_INIT_DATA; + initBuffer[0]=MUSE_SYNTH_SYSEX_MFG_ID; + initBuffer[1]=DEICSONZE_UNIQUE_ID; + initBuffer[2]=SYSEX_INIT_DATA; + initBuffer[3]=SYSEX_INIT_DATA_VERSION; //save global data - buffer[NUM_MASTERVOL] = (unsigned char) getMasterVol(); + initBuffer[NUM_MASTERVOL] = (unsigned char) getMasterVol(); for(int c = 0; c < NBRCHANNELS; c++) { - buffer[NUM_CHANNEL_ENABLE + c] = (unsigned char) getChannelEnable(c); - buffer[NUM_CHANNEL_VOL + c] = (unsigned char) getChannelVol(c); - buffer[NUM_CHANNEL_PAN + c] = (unsigned char) getChannelPan(c); + initBuffer[NUM_CHANNEL_ENABLE + c] = (unsigned char) getChannelEnable(c); + initBuffer[NUM_CHANNEL_VOL + c] = (unsigned char) getChannelVol(c); + initBuffer[NUM_CHANNEL_PAN + c] = (unsigned char) getChannelPan(c); int b = getChannelBrightness(c); - buffer[NUM_CHANNEL_BRIGHTNESS + 2*c] = (unsigned char) (b%256); - buffer[NUM_CHANNEL_BRIGHTNESS + 2*c + 1] = (unsigned char) (b/256); - buffer[NUM_CHANNEL_MODULATION + c] = + initBuffer[NUM_CHANNEL_BRIGHTNESS + 2*c] = (unsigned char) (b%256); + initBuffer[NUM_CHANNEL_BRIGHTNESS + 2*c + 1] = (unsigned char) (b/256); + initBuffer[NUM_CHANNEL_MODULATION + c] = (unsigned char) getChannelModulation(c); - buffer[NUM_CHANNEL_DETUNE + c] = + initBuffer[NUM_CHANNEL_DETUNE + c] = (unsigned char) getChannelDetune(c) + MAXCHANNELDETUNE; - buffer[NUM_CHANNEL_ATTACK + c] = (unsigned char) getChannelAttack(c); - buffer[NUM_CHANNEL_RELEASE + c] = (unsigned char) getChannelRelease(c); - buffer[NUM_CHANNEL_REVERB + c] = (unsigned char) getChannelReverb(c); - buffer[NUM_CHANNEL_CHORUS + c] = (unsigned char) getChannelChorus(c); - buffer[NUM_CHANNEL_DELAY + c] = (unsigned char) getChannelDelay(c); - buffer[NUM_CURRENTPROG + c] = (unsigned char) _preset[c]->prog; - buffer[NUM_CURRENTLBANK + c] = + initBuffer[NUM_CHANNEL_ATTACK + c] = (unsigned char) getChannelAttack(c); + initBuffer[NUM_CHANNEL_RELEASE + c] = (unsigned char) getChannelRelease(c); + initBuffer[NUM_CHANNEL_REVERB + c] = (unsigned char) getChannelReverb(c); + initBuffer[NUM_CHANNEL_CHORUS + c] = (unsigned char) getChannelChorus(c); + initBuffer[NUM_CHANNEL_DELAY + c] = (unsigned char) getChannelDelay(c); + initBuffer[NUM_CURRENTPROG + c] = (unsigned char) _preset[c]->prog; + initBuffer[NUM_CURRENTLBANK + c] = (unsigned char) _preset[c]->_subcategory->_lbank; - buffer[NUM_CURRENTHBANK + c] = + initBuffer[NUM_CURRENTHBANK + c] = (unsigned char) _preset[c]->_subcategory->_category->_hbank; - buffer[NUM_NBRVOICES + c] = (unsigned char) getNbrVoices(c); + initBuffer[NUM_NBRVOICES + c] = (unsigned char) getNbrVoices(c); } - buffer[NUM_SAVEONLYUSED]=(unsigned char) _saveOnlyUsed; - buffer[NUM_SAVECONFIG]=(unsigned char) _saveConfig; + initBuffer[NUM_SAVEONLYUSED]=(unsigned char) _saveOnlyUsed; + initBuffer[NUM_SAVECONFIG]=(unsigned char) _saveConfig; //save config data if(_saveConfig) { - buffer[NUM_QUALITY]=(unsigned char)_global.quality; - buffer[NUM_FILTER]=(unsigned char)getFilter(); - buffer[NUM_FONTSIZE]=(unsigned char)_global.fontSize; - buffer[NUM_RED_TEXT]=(unsigned char)_gui->tColor->red(); - buffer[NUM_GREEN_TEXT]=(unsigned char)_gui->tColor->green(); - buffer[NUM_BLUE_TEXT]=(unsigned char)_gui->tColor->blue(); - buffer[NUM_RED_BACKGROUND]=(unsigned char)_gui->bColor->red(); - buffer[NUM_GREEN_BACKGROUND]=(unsigned char)_gui->bColor->green(); - buffer[NUM_BLUE_BACKGROUND]=(unsigned char)_gui->bColor->blue(); - buffer[NUM_RED_EDITTEXT]=(unsigned char)_gui->etColor->red(); - buffer[NUM_GREEN_EDITTEXT]=(unsigned char)_gui->etColor->green(); - buffer[NUM_BLUE_EDITTEXT]=(unsigned char)_gui->etColor->blue(); - buffer[NUM_RED_EDITBACKGROUND]=(unsigned char)_gui->ebColor->red(); - buffer[NUM_GREEN_EDITBACKGROUND]=(unsigned char)_gui->ebColor->green(); - buffer[NUM_BLUE_EDITBACKGROUND]=(unsigned char)_gui->ebColor->blue(); - buffer[NUM_ISINITSET]=(unsigned char)_isInitSet; - strncpy((char*)&buffer[NUM_INITSETPATH], + initBuffer[NUM_QUALITY]=(unsigned char)_global.quality; + initBuffer[NUM_FILTER]=(unsigned char)getFilter(); + initBuffer[NUM_FONTSIZE]=(unsigned char)_global.fontSize; + initBuffer[NUM_RED_TEXT]=(unsigned char)_gui->tColor->red(); + initBuffer[NUM_GREEN_TEXT]=(unsigned char)_gui->tColor->green(); + initBuffer[NUM_BLUE_TEXT]=(unsigned char)_gui->tColor->blue(); + initBuffer[NUM_RED_BACKGROUND]=(unsigned char)_gui->bColor->red(); + initBuffer[NUM_GREEN_BACKGROUND]=(unsigned char)_gui->bColor->green(); + initBuffer[NUM_BLUE_BACKGROUND]=(unsigned char)_gui->bColor->blue(); + initBuffer[NUM_RED_EDITTEXT]=(unsigned char)_gui->etColor->red(); + initBuffer[NUM_GREEN_EDITTEXT]=(unsigned char)_gui->etColor->green(); + initBuffer[NUM_BLUE_EDITTEXT]=(unsigned char)_gui->etColor->blue(); + initBuffer[NUM_RED_EDITBACKGROUND]=(unsigned char)_gui->ebColor->red(); + initBuffer[NUM_GREEN_EDITBACKGROUND]=(unsigned char)_gui->ebColor->green(); + initBuffer[NUM_BLUE_EDITBACKGROUND]=(unsigned char)_gui->ebColor->blue(); + initBuffer[NUM_ISINITSET]=(unsigned char)_isInitSet; + strncpy((char*)&initBuffer[NUM_INITSETPATH], _initSetPath.toLatin1().constData(), MAXSTRLENGTHINITSETPATH); - buffer[NUM_ISBACKGROUNDPIX]=(unsigned char)_isBackgroundPix; - strncpy((char*)&buffer[NUM_BACKGROUNDPIXPATH], + initBuffer[NUM_ISBACKGROUNDPIX]=(unsigned char)_isBackgroundPix; + strncpy((char*)&initBuffer[NUM_BACKGROUNDPIXPATH], _backgroundPixPath.toLatin1().constData(), MAXSTRLENGTHBACKGROUNDPIXPATH); } //FX //reverb - buffer[NUM_IS_REVERB_ON]=(unsigned char)_global.isReverbActivated; - buffer[NUM_REVERB_RETURN]=(unsigned char)getReverbReturn(); - buffer[NUM_REVERB_PARAM_NBR]= + initBuffer[NUM_IS_REVERB_ON]=(unsigned char)_global.isReverbActivated; + initBuffer[NUM_REVERB_RETURN]=(unsigned char)getReverbReturn(); + initBuffer[NUM_REVERB_PARAM_NBR]= ///(_pluginIReverb?(unsigned char)_pluginIReverb->plugin()->parameter() : 0); (_pluginIReverb?(unsigned char)_pluginIReverb->plugin()->controlInPorts() : 0); - strncpy((char*)&buffer[NUM_REVERB_LIB], + strncpy((char*)&initBuffer[NUM_REVERB_LIB], (_pluginIReverb? _pluginIReverb->plugin()->lib().toLatin1().constData() : "\0"), MAXSTRLENGTHFXLIB); - strncpy((char*)&buffer[NUM_REVERB_LABEL], + strncpy((char*)&initBuffer[NUM_REVERB_LABEL], (_pluginIReverb? _pluginIReverb->plugin()->label().toLatin1().constData() : "\0"), MAXSTRLENGTHFXLABEL); //chorus - buffer[NUM_IS_CHORUS_ON]=(unsigned char)_global.isChorusActivated; - buffer[NUM_CHORUS_RETURN]=(unsigned char)getChorusReturn(); - buffer[NUM_CHORUS_PARAM_NBR]= + initBuffer[NUM_IS_CHORUS_ON]=(unsigned char)_global.isChorusActivated; + initBuffer[NUM_CHORUS_RETURN]=(unsigned char)getChorusReturn(); + initBuffer[NUM_CHORUS_PARAM_NBR]= ///(_pluginIChorus?(unsigned char)_pluginIChorus->plugin()->parameter() : 0); (_pluginIChorus?(unsigned char)_pluginIChorus->plugin()->controlInPorts() : 0); - strncpy((char*)&buffer[NUM_CHORUS_LIB], + strncpy((char*)&initBuffer[NUM_CHORUS_LIB], (_pluginIChorus? _pluginIChorus->plugin()->lib().toLatin1().constData() : "\0"), MAXSTRLENGTHFXLIB); - strncpy((char*)&buffer[NUM_CHORUS_LABEL], + strncpy((char*)&initBuffer[NUM_CHORUS_LABEL], (_pluginIChorus? _pluginIChorus->plugin()->label().toLatin1().constData() : "\0"), MAXSTRLENGTHFXLABEL); //delay - buffer[NUM_IS_DELAY_ON]=(unsigned char)_global.isDelayActivated; - buffer[NUM_DELAY_RETURN]=(unsigned char)getDelayReturn(); + initBuffer[NUM_IS_DELAY_ON]=(unsigned char)_global.isDelayActivated; + initBuffer[NUM_DELAY_RETURN]=(unsigned char)getDelayReturn(); //save FX parameters //reverb - for(int i = 0; i < (int)buffer[NUM_REVERB_PARAM_NBR]; i++) { + for(int i = 0; i < (int)initBuffer[NUM_REVERB_PARAM_NBR]; i++) { float val = (float)getReverbParam(i); - memcpy(&buffer[NUM_CONFIGLENGTH + sizeof(float)*i], &val, sizeof(float)); + memcpy(&initBuffer[NUM_CONFIGLENGTH + sizeof(float)*i], &val, sizeof(float)); } //chorus - for(int i = 0; i < (int)buffer[NUM_CHORUS_PARAM_NBR]; i++) { + for(int i = 0; i < (int)initBuffer[NUM_CHORUS_PARAM_NBR]; i++) { float val = (float)getChorusParam(i); - memcpy(&buffer[NUM_CONFIGLENGTH - + sizeof(float)*(int)buffer[NUM_REVERB_PARAM_NBR] + memcpy(&initBuffer[NUM_CONFIGLENGTH + + sizeof(float)*(int)initBuffer[NUM_REVERB_PARAM_NBR] + sizeof(float)*i], &val, sizeof(float)); } //delay float delayfloat; delayfloat = getDelayBPM(); - memcpy(&buffer[NUM_DELAY_BPM], &delayfloat, 4); + memcpy(&initBuffer[NUM_DELAY_BPM], &delayfloat, 4); delayfloat = getDelayBeatRatio(); - memcpy(&buffer[NUM_DELAY_BEATRATIO], &delayfloat, sizeof(float)); + memcpy(&initBuffer[NUM_DELAY_BEATRATIO], &delayfloat, sizeof(float)); delayfloat = getDelayFeedback(); - memcpy(&buffer[NUM_DELAY_FEEDBACK], &delayfloat, sizeof(float)); + memcpy(&initBuffer[NUM_DELAY_FEEDBACK], &delayfloat, sizeof(float)); delayfloat = getDelayLFOFreq(); - memcpy(&buffer[NUM_DELAY_LFO_FREQ], &delayfloat, sizeof(float)); + memcpy(&initBuffer[NUM_DELAY_LFO_FREQ], &delayfloat, sizeof(float)); delayfloat = getDelayLFODepth(); - memcpy(&buffer[NUM_DELAY_LFO_DEPTH], &delayfloat, sizeof(float)); + memcpy(&initBuffer[NUM_DELAY_LFO_DEPTH], &delayfloat, sizeof(float)); //save set data int offset = NUM_CONFIGLENGTH - + sizeof(float)*(int)buffer[NUM_REVERB_PARAM_NBR] - + sizeof(float)*(int)buffer[NUM_CHORUS_PARAM_NBR]; + + sizeof(float)*(int)initBuffer[NUM_REVERB_PARAM_NBR] + + sizeof(float)*(int)initBuffer[NUM_CHORUS_PARAM_NBR]; for(int i = offset; i < *length; i++) - buffer[i]=(unsigned char)baComp.at(i - offset); + initBuffer[i]=(unsigned char)baComp.at(i - offset); - *data=buffer; + ///*data=buffer; + *data=initBuffer; } //--------------------------------------------------------- // parseInitData //--------------------------------------------------------- void DeicsOnze::parseInitData(int length, const unsigned char* data) { - if(data[1]==SYSEX_INIT_DATA_VERSION) { + ///if(data[1]==SYSEX_INIT_DATA_VERSION) { + if(data[3]==SYSEX_INIT_DATA_VERSION) { //load global parameters //master volume setMasterVol(data[NUM_MASTERVOL]); @@ -2600,7 +2640,7 @@ void DeicsOnze::parseInitData(int length, const unsigned char* data) { (const char*)&data[NUM_REVERB_LABEL]); if(p) { initPluginReverb(p); - //for(int i = 0; i < _pluginIReverb->plugin()->parameter(); i++) { + ///for(int i = 0; i < _pluginIReverb->plugin()->parameter(); i++) { for(int i = 0; i < (int)_pluginIReverb->plugin()->controlInPorts(); i++) { float val; memcpy(&val, &data[NUM_CONFIGLENGTH + sizeof(float)*i], sizeof(float)); @@ -2630,7 +2670,7 @@ void DeicsOnze::parseInitData(int length, const unsigned char* data) { (const char*)&data[NUM_CHORUS_LABEL]); if(p) { initPluginChorus(p); - //for(int i = 0; i < _pluginIChorus->plugin()->parameter(); i++) { + ///for(int i = 0; i < _pluginIChorus->plugin()->parameter(); i++) { for(int i = 0; i < (int)_pluginIChorus->plugin()->controlInPorts(); i++) { float val; memcpy(&val, &data[NUM_CONFIGLENGTH @@ -2788,87 +2828,123 @@ bool DeicsOnze::sysex(int length, const unsigned char* data) { return false; } bool DeicsOnze::sysex(int length, const unsigned char* data, bool fromGui) { - int cmd=data[0]; + + if(length < 3 || data[0] != MUSE_SYNTH_SYSEX_MFG_ID + || data[1] != DEICSONZE_UNIQUE_ID) + { + #ifdef DEICSONZE_DEBUG + printf("MusE DeicsOnze: Unknown sysex header\n"); + #endif + return false; + } + + int l = length - 2; + const unsigned char* d = data + 2; + ///int cmd=data[0]; + int cmd=d[0]; int index; float f; switch(cmd) { case SYSEX_INIT_DATA: parseInitData(length, data); + //parseInitData(l, d); break; case SYSEX_MASTERVOL: - setMasterVol((int)data[1]); + ///setMasterVol((int)data[1]); + setMasterVol((int)d[1]); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; //case SYSEX_CHANNELNUM: - //_global.channelNum = (char)data[1]; + ///_global.channelNum = (char)data[1]; + //_global.channelNum = (char)d[1]; //if(!fromGui) { - // MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + /// MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + // MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); // _gui->writeEvent(evSysex); //} //break; case SYSEX_QUALITY: - setQuality((Quality)data[1]); + ///setQuality((Quality)data[1]); + setQuality((Quality)d[1]); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_FILTER: - setFilter((bool)data[1]); + ///setFilter((bool)data[1]); + setFilter((bool)d[1]); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_FONTSIZE: - _global.fontSize = (int)data[1]; + ///_global.fontSize = (int)data[1]; + _global.fontSize = (int)d[1]; if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_SAVECONFIG: - _saveConfig = (bool)data[1]; + ///_saveConfig = (bool)data[1]; + _saveConfig = (bool)d[1]; if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_SAVEONLYUSED: - _saveOnlyUsed = (bool)data[1]; + ///_saveOnlyUsed = (bool)data[1]; + _saveOnlyUsed = (bool)d[1]; if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_ISINITSET: - _isInitSet = (bool)data[1]; + ///_isInitSet = (bool)data[1]; + _isInitSet = (bool)d[1]; if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_INITSETPATH: - _initSetPath = (char*)&data[1]; + ///_initSetPath = (char*)&data[1]; + _initSetPath = (char*)&d[1]; if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_ISBACKGROUNDPIX: - _isBackgroundPix = (bool)data[1]; + ///_isBackgroundPix = (bool)data[1]; + _isBackgroundPix = (bool)d[1]; if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_BACKGROUNDPIXPATH: - _backgroundPixPath = (char*)&data[1]; + ///_backgroundPixPath = (char*)&data[1]; + _backgroundPixPath = (char*)&d[1]; if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; @@ -2876,112 +2952,142 @@ bool DeicsOnze::sysex(int length, const unsigned char* data, bool fromGui) { resetVoices(); break; case SYSEX_CHORUSACTIV: - _global.isChorusActivated = (bool)data[1]; + ///_global.isChorusActivated = (bool)data[1]; + _global.isChorusActivated = (bool)d[1]; if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_CHORUSPARAM: - index = (int)data[1]; - memcpy(&f, &data[2], sizeof(float)); + ///index = (int)data[1]; + ///memcpy(&f, &data[2], sizeof(float)); + index = (int)d[1]; + memcpy(&f, &d[2], sizeof(float)); setChorusParam(index, (double)f); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_REVERBACTIV: - _global.isReverbActivated = (bool)data[1]; + ///_global.isReverbActivated = (bool)data[1]; + _global.isReverbActivated = (bool)d[1]; if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_REVERBPARAM: - index = (int)data[1]; - memcpy(&f, &data[2], sizeof(float)); + ///index = (int)data[1]; + ///memcpy(&f, &data[2], sizeof(float)); + index = (int)d[1]; + memcpy(&f, &d[2], sizeof(float)); setReverbParam(index, (double)f); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_DELAYACTIV: - _global.isDelayActivated = (bool)data[1]; + ///_global.isDelayActivated = (bool)data[1]; + _global.isDelayActivated = (bool)d[1]; if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_CHORUSRETURN: - setChorusReturn((int)data[1]); + ///setChorusReturn((int)data[1]); + setChorusReturn((int)d[1]); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_REVERBRETURN: - setReverbReturn((int)data[1]); + ///setReverbReturn((int)data[1]); + setReverbReturn((int)d[1]); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_DELAYRETURN: - setDelayReturn((int)data[1]); + ///setDelayReturn((int)data[1]); + setDelayReturn((int)d[1]); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_SELECTREVERB: Plugin* pluginReverb; - memcpy(&pluginReverb, &data[1], sizeof(Plugin*)); + ///memcpy(&pluginReverb, &data[1], sizeof(Plugin*)); + memcpy(&pluginReverb, &d[1], sizeof(Plugin*)); initPluginReverb(pluginReverb); break; case SYSEX_SELECTCHORUS: Plugin* pluginChorus; - memcpy(&pluginChorus, &data[1], sizeof(Plugin*)); + ///memcpy(&pluginChorus, &data[1], sizeof(Plugin*)); + memcpy(&pluginChorus, &d[1], sizeof(Plugin*)); initPluginChorus(pluginChorus); break; case SYSEX_DELAYBPM: - memcpy(&f, &data[1], sizeof(float)); + ///memcpy(&f, &data[1], sizeof(float)); + memcpy(&f, &d[1], sizeof(float)); setDelayBPM(f); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_DELAYBEATRATIO: - memcpy(&f, &data[1], sizeof(float)); + ///memcpy(&f, &data[1], sizeof(float)); + memcpy(&f, &d[1], sizeof(float)); setDelayBeatRatio(f); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_DELAYFEEDBACK: - memcpy(&f, &data[1], sizeof(float)); + ///memcpy(&f, &data[1], sizeof(float)); + memcpy(&f, &d[1], sizeof(float)); setDelayFeedback(f); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_DELAYLFOFREQ: - memcpy(&f, &data[1], sizeof(float)); + ///memcpy(&f, &data[1], sizeof(float)); + memcpy(&f, &d[1], sizeof(float)); setDelayLFOFreq(f); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; case SYSEX_DELAYLFODEPTH: - memcpy(&f, &data[1], sizeof(float)); + ///memcpy(&f, &data[1], sizeof(float)); + memcpy(&f, &d[1], sizeof(float)); setDelayLFODepth(f); if(!fromGui) { - MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + ///MidiPlayEvent evSysex(0, 0, ME_SYSEX, data, length); + MidiPlayEvent evSysex(0, 0, ME_SYSEX, d, l); _gui->writeEvent(evSysex); } break; @@ -3728,7 +3834,7 @@ const MidiPatch* DeicsOnze::getPatchInfo(int /*ch*/, const MidiPatch* p) const { */ //--------------------------------------------------------- int DeicsOnze::getControllerInfo(int index, const char** name, - int* controller, int* min, int* max) + int* controller, int* min, int* max, int* initval) const { if (index >= nbrCtrl) { return 0; @@ -3738,6 +3844,7 @@ int DeicsOnze::getControllerInfo(int index, const char** name, *controller = _ctrl[index].num; *min = _ctrl[index].min; *max = _ctrl[index].max; + *initval = 0; // p4.0.27 FIXME NOTE TODO return (index +1); } @@ -3975,10 +4082,32 @@ inline double plusMod(double x, double y) { //--------------------------------------------------------- +// processMessages +// Called from host always, even if output path is unconnected. +//--------------------------------------------------------- + +void DeicsOnze::processMessages() +{ + //Process messages from the gui + while (_gui->fifoSize()) { + MidiPlayEvent ev = _gui->readEvent(); + if (ev.type() == ME_SYSEX) { + sysex(ev.len(), ev.data(), true); + sendEvent(ev); + } + else if (ev.type() == ME_CONTROLLER) { + setController(ev.channel(), ev.dataA(), ev.dataB(), true); + sendEvent(ev); + } + } +} + +//--------------------------------------------------------- // write // synthesize n samples into buffer+offset //--------------------------------------------------------- void DeicsOnze::process(float** buffer, int offset, int n) { + /* //Process messages from the gui while (_gui->fifoSize()) { MidiPlayEvent ev = _gui->readEvent(); @@ -3991,6 +4120,8 @@ void DeicsOnze::process(float** buffer, int offset, int n) { sendEvent(ev); } } + */ + float* leftOutput = buffer[0] + offset; float* rightOutput = buffer[1] + offset; diff --git a/muse2/synti/deicsonze/deicsonze.h b/muse2/synti/deicsonze/deicsonze.h index dc7c533d..bd79b7fb 100644 --- a/muse2/synti/deicsonze/deicsonze.h +++ b/muse2/synti/deicsonze/deicsonze.h @@ -33,6 +33,7 @@ #include <list> +#include "common_defs.h" #include "deicsonzepreset.h" #include "deicsonzegui.h" #include "deicsonzeplugin.h" @@ -99,7 +100,8 @@ #define SYSEX_INIT_DATA 1 #define SYSEX_INIT_DATA_VERSION 1 -#define SAVEINITLENGTH 2 +///#define SAVEINITLENGTH 2 +#define SAVEINITLENGTH 4 // MFG ID, synth ID, init data command, init data version #define DEICSONZECONFIGURATIONSTR "deicsOnzeConfiguation" #define SYSEX_MASTERVOL 4 @@ -432,6 +434,9 @@ struct Global { class DeicsOnze : public Mess { DeicsOnzeGui* _gui; + + unsigned char* initBuffer; + int initLen; static int useCount; static float waveTable[NBRWAVES][RESOLUTION]; @@ -439,6 +444,7 @@ class DeicsOnze : public Mess { private: void parseInitData(int length, const unsigned char* data); void loadConfiguration(QString fileName); + void setupInitBuffer(int len); public: float** tempInputChorus; @@ -577,16 +583,20 @@ class DeicsOnze : public Mess { bool setController(int ch, int ctrl, int val, bool fromGui); virtual bool setController(int ch, int ctrl, int val); bool sysex(int length, const unsigned char* data, bool fromGui); - virtual bool sysex(int length, const unsigned char* data); + virtual bool sysex(int l, const unsigned char* d); virtual const char* getPatchName(int ch, int number, int) const; virtual const MidiPatch* getPatchInfo(int, const MidiPatch *) const; virtual int getControllerInfo(int arg1, const char** arg2, - int* arg3, int* arg4, int* arg5); - virtual void getInitData(int* length, const unsigned char** data) const; + int* arg3, int* arg4, int* arg5, int* arg6) const; + ///virtual void getInitData(int* length, const unsigned char** data) const; + virtual void getInitData(int* length, const unsigned char** data); + // This is only a kludge required to support old songs' midistates. Do not use in any new synth. + virtual int oldMidiStateHeader(const unsigned char** data) const; virtual bool playNote(int channel, int pitch, int velo); + virtual void processMessages(); virtual void process(float** buffer, int offset, int n); // GUI interface routines @@ -600,7 +610,7 @@ class DeicsOnze : public Mess { virtual void setNativeGeometry(int, int, int, int); DeicsOnze(); - ~DeicsOnze(); + virtual ~DeicsOnze(); }; diff --git a/muse2/synti/deicsonze/deicsonzegui.cpp b/muse2/synti/deicsonze/deicsonzegui.cpp index 3cae14f8..4cb78764 100644 --- a/muse2/synti/deicsonze/deicsonzegui.cpp +++ b/muse2/synti/deicsonze/deicsonzegui.cpp @@ -40,6 +40,7 @@ #include "muse/midictrl.h" #include "config.h" +#include "common_defs.h" #include "deicsonzegui.h" #include "plugin.h" @@ -483,9 +484,11 @@ void DeicsOnzeGui::setChangeChannel(int c) { // setPanic //----------------------------------------------------------- void DeicsOnzeGui::setPanic() { - unsigned char* message = new unsigned char[1]; - message[0]=SYSEX_PANIC; - sendSysex(message, 1); + unsigned char message[3]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_PANIC; + sendSysex(message, 3); } //----------------------------------------------------------- @@ -517,10 +520,12 @@ void DeicsOnzeGui::setNbrVoices(int nv) { // setMidiInCh //---------------------------------------------------------- //void DeicsOnzeGui::setMidiInCh(int m) { -// unsigned char* message = new unsigned char[2]; -// message[0]=SYSEX_CHANNELNUM; -// message[1]=(unsigned char)(m-1); -// sendSysex(message, 2); +// unsigned char message[4]; +// message[0]=MUSE_SYNTH_SYSEX_MFG_ID; +// message[1]=DEICSONZE_UNIQUE_ID; +// message[2]=SYSEX_CHANNELNUM; +// message[3]=(unsigned char)(m-1); +// sendSysex(message, 4); //} //----------------------------------------------------------- @@ -625,57 +630,69 @@ void DeicsOnzeGui::loadConfiguration() { // setQuality //----------------------------------------------------------- void DeicsOnzeGui::setQuality(const QString& q) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_QUALITY; - message[1]=(unsigned char)(q=="High"? + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_QUALITY; + message[3]=(unsigned char)(q=="High"? high:(q=="Middle"? middle:(q=="Low"?low:ultralow))); - sendSysex(message, 2); + sendSysex(message, 4); } //----------------------------------------------------------- // setFilter //----------------------------------------------------------- void DeicsOnzeGui::setFilter(bool f) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_FILTER; - message[1]=(unsigned char)f; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_FILTER; + message[3]=(unsigned char)f; + sendSysex(message, 4); } //----------------------------------------------------------- // setFontSize //----------------------------------------------------------- void DeicsOnzeGui::setFontSize(int fs) { applyFontSize(fs); - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_FONTSIZE; - message[1]=(unsigned char)fs; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_FONTSIZE; + message[3]=(unsigned char)fs; + sendSysex(message, 4); } //----------------------------------------------------------- // setSaveOnlyUsed //----------------------------------------------------------- void DeicsOnzeGui::setSaveOnlyUsed(bool sou) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_SAVEONLYUSED; - message[1]=(unsigned char)sou; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_SAVEONLYUSED; + message[3]=(unsigned char)sou; + sendSysex(message, 4); updateSaveOnlyUsed(sou); } void DeicsOnzeGui::setSaveOnlyUsedComp(bool souc) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_SAVEONLYUSED; - message[1]=(unsigned char)!souc; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_SAVEONLYUSED; + message[3]=(unsigned char)!souc; + sendSysex(message, 4); updateSaveOnlyUsed(!souc); } //----------------------------------------------------------- // setSaveConfig //----------------------------------------------------------- void DeicsOnzeGui::setSaveConfig(bool ssc) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_SAVECONFIG; - message[1]=(unsigned char)ssc; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_SAVECONFIG; + message[3]=(unsigned char)ssc; + sendSysex(message, 4); } //----------------------------------------------------------- // setColor @@ -1524,6 +1541,7 @@ void DeicsOnzeGui::processEvent(const MidiPlayEvent& ev) { else if (ev.type() == ME_SYSEX) { //printf("ME_SYSEX\n"); unsigned char* data = ev.data(); + int cmd = *data; float f; switch (cmd) { @@ -2489,16 +2507,20 @@ void DeicsOnzeGui::setProg(int pr) {//must be changed with SysEx void DeicsOnzeGui::setIsInitSet(bool b) { initSetPathLineEdit->setEnabled(b); initSetBrowsePushButton->setEnabled(b); - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_ISINITSET; - message[1]=(unsigned char)b; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_ISINITSET; + message[3]=(unsigned char)b; + sendSysex(message, 4); } void DeicsOnzeGui::setInitSetPath(const QString& s) { - unsigned char* message = new unsigned char[1+MAXSTRLENGTHINITSETPATH]; - message[0]=SYSEX_INITSETPATH; - strncpy((char*)&message[1], s.toAscii().data(), MAXSTRLENGTHINITSETPATH); - sendSysex(message, 1+MAXSTRLENGTHINITSETPATH); + unsigned char message[3+MAXSTRLENGTHINITSETPATH]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_INITSETPATH; + strncpy((char*)&message[3], s.toAscii().data(), MAXSTRLENGTHINITSETPATH); + sendSysex(message, 3+MAXSTRLENGTHINITSETPATH); } void DeicsOnzeGui::setBrowseInitSetPath() { QString fileName = @@ -2522,18 +2544,22 @@ void DeicsOnzeGui::setIsBackgroundPix(bool b) { else setBackgroundColor(reinterpret_cast<const QColor &>(*bColor)); imagePathLineEdit->setEnabled(b); imageBrowsePushButton->setEnabled(b); - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_ISBACKGROUNDPIX; - message[1]=(unsigned char)b; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_ISBACKGROUNDPIX; + message[3]=(unsigned char)b; + sendSysex(message, 4); } void DeicsOnzeGui::setBackgroundPixPath(const QString& s) { applyBackgroundPix(); - unsigned char* message = new unsigned char[1+MAXSTRLENGTHBACKGROUNDPIXPATH]; - message[0]=SYSEX_BACKGROUNDPIXPATH; - strncpy((char*)&message[1], s.toAscii().data(), + unsigned char message[3+MAXSTRLENGTHBACKGROUNDPIXPATH]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_BACKGROUNDPIXPATH; + strncpy((char*)&message[3], s.toAscii().data(), MAXSTRLENGTHBACKGROUNDPIXPATH); - sendSysex(message, 1+MAXSTRLENGTHBACKGROUNDPIXPATH); + sendSysex(message, 3+MAXSTRLENGTHBACKGROUNDPIXPATH); } void DeicsOnzeGui::setBrowseBackgroundPixPath() { QString fileName = @@ -2553,87 +2579,111 @@ void DeicsOnzeGui::setBrowseBackgroundPixPath() { // FX //----------------------------------------------------------- void DeicsOnzeGui::setChorusActiv(bool a) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_CHORUSACTIV; - message[1]=(unsigned char)a; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_CHORUSACTIV; + message[3]=(unsigned char)a; + sendSysex(message, 4); } void DeicsOnzeGui::setChannelChorus(int c) { sendController(_currentChannel, CTRL_CHORUS_SEND, c); } void DeicsOnzeGui::setChorusReturn(int val) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_CHORUSRETURN; - message[1]=(unsigned char)val; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_CHORUSRETURN; + message[3]=(unsigned char)val; + sendSysex(message, 4); } void DeicsOnzeGui::setSelectChorusPlugin() { Plugin* pluginChorus = PluginDialog::getPlugin(this); if(pluginChorus) { - unsigned char* message = new unsigned char[1+sizeof(Plugin*)]; - message[0]=SYSEX_SELECTCHORUS; - memcpy(&message[1], &pluginChorus, sizeof(Plugin*)); - sendSysex(message, 1+sizeof(Plugin*)); + unsigned char message[3+sizeof(Plugin*)]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_SELECTCHORUS; + memcpy(&message[3], &pluginChorus, sizeof(Plugin*)); + sendSysex(message, 3+sizeof(Plugin*)); } } /*void DeicsOnzeGui::setPanChorus1(double i) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_CHORUS1PAN; - message[1]=(unsigned char)(i*(double)MAXCHORUSPARAM); - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_CHORUS1PAN; + message[3]=(unsigned char)(i*(double)MAXCHORUSPARAM); + sendSysex(message, 4); } void DeicsOnzeGui::setLFOFreqChorus1(double i) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_CHORUS1LFOFREQ; - message[1]=(unsigned char)(i*(double)MAXCHORUSPARAM); - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_CHORUS1LFOFREQ; + message[3]=(unsigned char)(i*(double)MAXCHORUSPARAM); + sendSysex(message, 4); } void DeicsOnzeGui::setDepthChorus1(double i) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_CHORUS1DEPTH; - message[1]=(unsigned char)(i*(double)MAXCHORUSPARAM); - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_CHORUS1DEPTH; + message[3]=(unsigned char)(i*(double)MAXCHORUSPARAM); + sendSysex(message, 4); } void DeicsOnzeGui::setPanChorus2(double i) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_CHORUS2PAN; - message[1]=(unsigned char)(i*(double)MAXCHORUSPARAM); - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_CHORUS2PAN; + message[3]=(unsigned char)(i*(double)MAXCHORUSPARAM); + sendSysex(message, 4); } void DeicsOnzeGui::setLFOFreqChorus2(double i) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_CHORUS2LFOFREQ; - message[1]=(unsigned char)(i*(double)MAXCHORUSPARAM); - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_CHORUS2LFOFREQ; + message[3]=(unsigned char)(i*(double)MAXCHORUSPARAM); + sendSysex(message, 4); } void DeicsOnzeGui::setDepthChorus2(double i) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_CHORUS2DEPTH; - message[1]=(unsigned char)(i*(double)MAXCHORUSPARAM); - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_CHORUS2DEPTH; + message[3]=(unsigned char)(i*(double)MAXCHORUSPARAM); + sendSysex(message, 4); }*/ void DeicsOnzeGui::setReverbActiv(bool a) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_REVERBACTIV; - message[1]=(unsigned char)a; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_REVERBACTIV; + message[3]=(unsigned char)a; + sendSysex(message, 4); } void DeicsOnzeGui::setChannelReverb(int r) { sendController(_currentChannel, CTRL_REVERB_SEND, r); } void DeicsOnzeGui::setReverbReturn(int val) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_REVERBRETURN; - message[1]=(unsigned char)val; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_REVERBRETURN; + message[3]=(unsigned char)val; + sendSysex(message, 4); } void DeicsOnzeGui::setSelectReverbPlugin() { Plugin* pluginReverb = PluginDialog::getPlugin(this); if(pluginReverb) { - unsigned char* message = new unsigned char[1+sizeof(Plugin*)]; - message[0]=SYSEX_SELECTREVERB; - memcpy(&message[1], &pluginReverb, sizeof(Plugin*)); - sendSysex(message, 1+sizeof(Plugin*)); + unsigned char message[3+sizeof(Plugin*)]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_SELECTREVERB; + memcpy(&message[3], &pluginReverb, sizeof(Plugin*)); + sendSysex(message, 3+sizeof(Plugin*)); } } @@ -2674,10 +2724,12 @@ void DeicsOnzeGui::setMasterVolKnob(double mv) { setMasterVol((int)(mv*(double)MAXMASTERVOLUME)); } void DeicsOnzeGui::setMasterVol(int mv) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_MASTERVOL; - message[1]=(unsigned char)mv; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_MASTERVOL; + message[3]=(unsigned char)mv; + sendSysex(message, 4); } void DeicsOnzeGui::setFeedback(int f) {sendController(_currentChannel, CTRL_FEEDBACK, f);} @@ -3051,91 +3103,117 @@ void DeicsOnzeGui::setWaveForm4(int w) { // set delay //-------------------------------------------------------------- void DeicsOnzeGui::setActivDelay(bool a) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_DELAYACTIV; - message[1]=(unsigned char)a; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_DELAYACTIV; + message[3]=(unsigned char)a; + sendSysex(message, 4); } void DeicsOnzeGui::setDelayReturn(int r) { - unsigned char* message = new unsigned char[2]; - message[0]=SYSEX_DELAYRETURN; - message[1]=(unsigned char)r; - sendSysex(message, 2); + unsigned char message[4]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_DELAYRETURN; + message[3]=(unsigned char)r; + sendSysex(message, 4); } void DeicsOnzeGui::setChannelDelay(int d) { sendController(_currentChannel, CTRL_VARIATION_SEND, (unsigned char)d); } //void DeicsOnzeGui::setDelayTime(int t) { -// unsigned char* message = new unsigned char[2]; -// message[0]=SYSEX_DELAYTIME; -// message[1]=(unsigned char)t; -// sendSysex(message, 2); +// unsigned char message[4]; +// message[0]=MUSE_SYNTH_SYSEX_MFG_ID; +// message[1]=DEICSONZE_UNIQUE_ID; +// message[2]=SYSEX_DELAYTIME; +// message[3]=(unsigned char)t; +// sendSysex(message, 4); // updateDelayTime(t); //} void DeicsOnzeGui::setDelayBPM(double t) { //int it = (int)(((t - MINDELAYTIME) / (MAXDELAYTIME - MINDELAYTIME))*255.0); - unsigned char* message = new unsigned char[sizeof(float)+1]; - message[0]=SYSEX_DELAYBPM; + unsigned char message[sizeof(float)+3]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_DELAYBPM; float f = (float)t; - memcpy(&message[1], &f, sizeof(float)); - message[1]=(unsigned char)f; - sendSysex(message, sizeof(float)+1); + ///memcpy(&message[1], &f, sizeof(float)); + memcpy(&message[3], &f, sizeof(float)); + ///message[1]=(unsigned char)f; + message[3]=(unsigned char)f; + sendSysex(message, sizeof(float)+3); //updateDelayTime(it); } void DeicsOnzeGui::setDelayBeatRatio(double t) { - unsigned char* message = new unsigned char[sizeof(float)+1]; - message[0]=SYSEX_DELAYBEATRATIO; + unsigned char message[sizeof(float)+3]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_DELAYBEATRATIO; float f = (float)t; - memcpy(&message[1], &f, sizeof(float)); - message[1]=(unsigned char)f; - sendSysex(message, sizeof(float)+1); + ///memcpy(&message[1], &f, sizeof(float)); + memcpy(&message[3], &f, sizeof(float)); + ///message[1]=(unsigned char)f; + message[3]=(unsigned char)f; + sendSysex(message, sizeof(float)+3); } //void DeicsOnzeGui::setDelayFeedback(int f) { -// unsigned char* message = new unsigned char[2]; -// message[0]=SYSEX_DELAYFEEDBACK; -// message[1]=(unsigned char)f; -// sendSysex(message, 2); +// unsigned char message[4]; +// message[0]=MUSE_SYNTH_SYSEX_MFG_ID; +// message[1]=DEICSONZE_UNIQUE_ID; +// message[2]=SYSEX_DELAYFEEDBACK; +// message[3]=(unsigned char)f; +// sendSysex(message, 4); // updateDelayFeedback(f); //} void DeicsOnzeGui::setDelayFeedback(double t) { //int idf = (int)(f*128.0+128.0); - unsigned char* message = new unsigned char[sizeof(float)+1]; - message[0]=SYSEX_DELAYFEEDBACK; + unsigned char message[sizeof(float)+3]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_DELAYFEEDBACK; float f = (float)t; - memcpy(&message[1], &f, sizeof(float)); - sendSysex(message, sizeof(float)+1); + memcpy(&message[3], &f, sizeof(float)); + sendSysex(message, sizeof(float)+3); //updateDelayFeedback(idf); } //void DeicsOnzeGui::setDelayPanLFOFreq(int pf) { -// unsigned char* message = new unsigned char[2]; -// message[0]=SYSEX_DELAYLFOFREQ; -// message[1]=(unsigned char)pf; -// sendSysex(message, 2); +// unsigned char message[4]; +// message[0]=MUSE_SYNTH_SYSEX_MFG_ID; +// message[1]=DEICSONZE_UNIQUE_ID; +// message[2]=SYSEX_DELAYLFOFREQ; +// message[3]=(unsigned char)pf; +// sendSysex(message, 4); // updateDelayPanLFOFreq(pf); //} void DeicsOnzeGui::setDelayPanLFOFreq(double pf) { //int ipf = (int)(((pf - MINFREQ) / (MAXFREQ - MINFREQ))*255.0); - unsigned char* message = new unsigned char[sizeof(float)+1]; - message[0]=SYSEX_DELAYLFOFREQ; + unsigned char message[sizeof(float)+3]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_DELAYLFOFREQ; float f = (float)pf; - memcpy(&message[1], &f, sizeof(float)); - sendSysex(message, sizeof(float)+1); + memcpy(&message[3], &f, sizeof(float)); + sendSysex(message, sizeof(float)+3); //updateDelayPanLFOFreq(ipf); } //void DeicsOnzeGui::setDelayPanLFODepth(int pd) { -// unsigned char* message = new unsigned char[2]; -// message[0]=SYSEX_DELAYLFODEPTH; -// message[1]=(unsigned char)pd; -// sendSysex(message, 2); +// unsigned char message[4]; +// message[0]=MUSE_SYNTH_SYSEX_MFG_ID; +// message[1]=DEICSONZE_UNIQUE_ID; +// message[2]=SYSEX_DELAYLFODEPTH; +// message[3]=(unsigned char)pd; +// sendSysex(message, 4); // updateDelayPanLFODepth(pd); //} void DeicsOnzeGui::setDelayPanLFODepth(double pd) { //int ipd = (int)(pd*255.0); - unsigned char* message = new unsigned char[sizeof(float)+1]; - message[0]=SYSEX_DELAYLFODEPTH; + unsigned char message[sizeof(float)+3]; + message[0]=MUSE_SYNTH_SYSEX_MFG_ID; + message[1]=DEICSONZE_UNIQUE_ID; + message[2]=SYSEX_DELAYLFODEPTH; float f = (float)pd; - memcpy(&message[1], &f, sizeof(float)); - sendSysex(message, sizeof(float)+1); + memcpy(&message[3], &f, sizeof(float)); + sendSysex(message, sizeof(float)+3); //updateDelayPanLFODepth(ipd); } @@ -4339,7 +4417,9 @@ void DeicsOnzeGui::updateBackgroundPixPath(QString s) { imagePathLineEdit->blockSignals(false); } void DeicsOnzeGui::applyBackgroundPix() { + #ifdef DEICSONZE_DEBUG printf("applyBackgroundPix\n"); + #endif QPalette p = this->palette(); QPixmap pixmap = QPixmap(imagePathLineEdit->text()); p.setBrush((this)->backgroundRole(), QBrush(pixmap)); diff --git a/muse2/synti/fluid/common_defs.h b/muse2/synti/fluid/common_defs.h new file mode 100644 index 00000000..6aa62bc0 --- /dev/null +++ b/muse2/synti/fluid/common_defs.h @@ -0,0 +1,12 @@ +#ifndef __FLUID_UNIQUE_ID_H +#define __FLUID_UNIQUE_ID_H + +// Make sure this number is unique among all the MESS synths. +#define FLUID_UNIQUE_ID 0 + +//#define FLUID_DEBUG + +enum SfOp { SF_REPLACE = 1, SF_ADD, SF_REMOVE }; + +#endif + diff --git a/muse2/synti/fluid/fluid.cpp b/muse2/synti/fluid/fluid.cpp index ad3d06a6..c06e672e 100644 --- a/muse2/synti/fluid/fluid.cpp +++ b/muse2/synti/fluid/fluid.cpp @@ -28,6 +28,7 @@ #include "muse/midictrl.h" +//#include "common_defs.h" #include "muse/midi.h" #include "fluid.h" #include "fluidgui.h" @@ -186,7 +187,6 @@ bool ISynth::sysex(int len, const unsigned char* data) } } } - //--------------------------------------------- // Universal Realtime //--------------------------------------------- @@ -194,55 +194,68 @@ bool ISynth::sysex(int len, const unsigned char* data) else if (data[0] == 0x7f) { if (data[1] == 0x7f) { // device Id if ((data[2] == 0x4) && (data[3] == 0x1)) { + if(len == 6) + { float v = (data[5]*128 + data[4])/32767.0; fluid_synth_set_gain(_fluidsynth, v); return false; } + } } } - //--------------------------------------------- // MusE Soft Synth //--------------------------------------------- - else if (data[0] == 0x7c) { + else if (data[0] == MUSE_SYNTH_SYSEX_MFG_ID) { int n = len - 3; if (n < 1) { + #ifdef FS_DEBUG printf("fluid: bad sysEx:\n"); + #endif return false; } char buffer[n+1]; memcpy(buffer, (char*)data+3, n); buffer[n] = 0; - if (data[1] == 0) { // fluid - if (data[2] == 1) { // load sound font + if (data[1] == FLUID_UNIQUE_ID) { // fluid + //if (data[2] == 1) { // load sound font + if (data[2] == SF_REPLACE) { // load sound font sysexSoundFont(SF_REPLACE, buffer); return false; } - else if (data[2] == 2) { // load sound font + //else if (data[2] == 2) { // load sound font + else if (data[2] == SF_ADD) { // load sound font sysexSoundFont(SF_ADD, buffer); return false; } - else if (data[2] == 3) { // load sound font + //else if (data[2] == 3) { // load sound font + else if (data[2] == SF_REMOVE) { // load sound font sysexSoundFont(SF_REMOVE, buffer); return false; } } } + else if (data[0] == 0x41) { // roland - if (data[1] == 0x10 && data[2] == 0x42 && data[3] == 0x12 - && data[4] == 0x40 && data[5] == 00 && data[6] == 0x7f - && data[7] == 0x41) { - // gs on - gmOn(true); - return false; - } - } - } + if (data[1] == 0x10 && data[2] == 0x42 && data[3] == 0x12) + { + if (len == 8) { + if(data[4] == 0x40 && data[5] == 00 && data[6] == 0x7f && data[7] == 0x41) { + // gs on + gmOn(true); + return false; + } + } + } + } + } + #ifdef FS_DEBUG printf("fluid: unknown sysex received, len %d:\n", len); for (int i = 0; i < len; ++i) printf("%02x ", data[i]); printf("\n"); + #endif return false; } @@ -292,6 +305,8 @@ void ISynth::showNativeGui(bool flag) ISynth::~ISynth() { + if(gui) + delete gui; // p4.0.27 // TODO delete settings if (_fluidsynth) delete_fluid_synth(_fluidsynth); @@ -390,7 +405,9 @@ const char* ISynth::getPatchName(int /*ch*/, int val, int, bool /*drum*/) const const char* name = "<unknown>"; if (_busy) { + //#ifdef FS_DEBUG printf("fluid: getPatchName(): busy!\n"); + //#endif return name; } fluid_font = fluid_synth_get_sfont_by_id(_fluidsynth, hbank); @@ -399,8 +416,12 @@ const char* ISynth::getPatchName(int /*ch*/, int val, int, bool /*drum*/) const if (preset) name = (*preset->get_name)(preset); else + { + //#ifdef FS_DEBUG fprintf(stderr, "no fluid preset for bank %d prog %d\n", lbank, prog); + //#endif + } } else fprintf(stderr, "ISynth::getPatchName(): no fluid font id=%d found\n", hbank); @@ -414,7 +435,9 @@ const char* ISynth::getPatchName(int /*ch*/, int val, int, bool /*drum*/) const const MidiPatch* ISynth::getPatchInfo(int ch, const MidiPatch* p) const { if (_busy) { + //#ifdef FS_DEBUG printf("fluid: getPatchInfo(): busy!\n"); + //#endif return 0; } if (p == 0) { @@ -459,13 +482,14 @@ void ISynth::getInitData(int* len, const unsigned char** data) if (initBuffer) delete [] initBuffer; initBuffer = new unsigned char[n]; + initLen = n; // p4.0.27 Tim. } - initBuffer[0] = 0x7c; - initBuffer[1] = 0x00; + initBuffer[0] = MUSE_SYNTH_SYSEX_MFG_ID; + initBuffer[1] = FLUID_UNIQUE_ID; initBuffer[2] = SF_REPLACE; strcpy((char*)(initBuffer+3), sfont); *len = n; - *data = initBuffer; + *data = (unsigned char*)initBuffer; } //--------------------------------------------------------- @@ -482,11 +506,15 @@ void ISynth::sysexSoundFont(SfOp op, const char* data) case SF_REPLACE: case SF_ADD: if (sfont && (strcmp(sfont, data) == 0)) { + #ifdef FS_DEBUG fprintf(stderr, "fluid: font already loaded\n"); + #endif break; } if (_busy) { + //#ifdef FS_DEBUG fprintf(stderr, "fluid: busy!\n"); + //#endif break; } _busy = true; @@ -528,18 +556,35 @@ void ISynth::noRTHelper() } int id = getFontId(); if (id != -1) { + #ifdef FS_DEBUG fprintf(stderr, "ISynth: unload old font\n"); + #endif fluid_synth_sfunload(synth(), (unsigned)id, true); } - int rv = fluid_synth_sfload(synth(), getFont(), true); + const char* fontname = getFont(); + int rv = fluid_synth_sfload(synth(), fontname, true); if (rv == -1) { fprintf(stderr, "ISynth: sfload %s failed\n", fluid_synth_error(synth())); } else { setFontId(rv); + + // Inform the gui. p4.0.27 Tim + int slen = strlen(fontname); + int n = slen + 2; + unsigned char d[n]; + d[0] = FS_SEND_SOUNDFONT_NAME; + if(slen != 0) + memcpy(d + 1, fontname, slen); + d[1 + slen] = 0; + MidiPlayEvent ev(0,0, ME_SYSEX, d, n); + gui->writeEvent(ev); + + #ifdef FS_DEBUG fprintf(stderr, "ISynth: sfont %s loaded as %d\n ", getFont(), rv); + #endif } fluid_synth_set_gain(synth(), 1.0); //? _busy = false; diff --git a/muse2/synti/fluid/fluid.h b/muse2/synti/fluid/fluid.h index e80f1463..02b111e4 100644 --- a/muse2/synti/fluid/fluid.h +++ b/muse2/synti/fluid/fluid.h @@ -20,8 +20,9 @@ #include <list> #include <fluidsynth.h> #include "libsynti/mess.h" +#include "common_defs.h" -enum SfOp { SF_REPLACE = 1, SF_ADD, SF_REMOVE }; +//enum SfOp { SF_REPLACE = 1, SF_ADD, SF_REMOVE }; class FLUIDGui; //--------------------------------------------------------- @@ -73,8 +74,12 @@ class ISynth : public Mess { public: ISynth(); - ~ISynth(); + virtual ~ISynth(); + // This is only a kludge required to support old songs' midistates. Do not use in any new synth. + // Note for Fluid, do nothing because unlike other synths, Fluid already had correct sysex headers. + //virtual int oldMidiStateHeader(const unsigned char** data) const; + fluid_synth_t* synth() { return _fluidsynth; } const fluid_synth_t* synth() const { return _fluidsynth; } char* getFont() const { return sfont; } diff --git a/muse2/synti/fluid/fluidgui.cpp b/muse2/synti/fluid/fluidgui.cpp index af8d937c..1f948a7d 100644 --- a/muse2/synti/fluid/fluidgui.cpp +++ b/muse2/synti/fluid/fluidgui.cpp @@ -15,9 +15,12 @@ #include <QFileDialog> #include <QFileInfo> #include <QMessageBox> +#include <QSocketNotifier> +#include "common_defs.h" #include "fluidgui.h" #include "muse/midi.h" +#include "muse/mpevent.h" #include "muse/icons.h" //--------------------------------------------------------- @@ -28,6 +31,10 @@ FLUIDGui::FLUIDGui() : QDialog(0, Qt::Window), MessGui() { setupUi(this); + //Connect socketnotifier to fifo + QSocketNotifier* s = new QSocketNotifier(readFd, QSocketNotifier::Read); + connect(s, SIGNAL(activated(int)), SLOT(readMessage(int))); + fdialogButton->setIcon(QIcon(*openIcon)); connect(fdialogButton, SIGNAL(clicked()), SLOT(soundFontFileDialog())); connect(loadButton, SIGNAL(clicked()), SLOT(loadFont())); @@ -60,9 +67,9 @@ void FLUIDGui::loadFont() int len = strlen(path) + 1 + 3; unsigned char buffer[len]; int k = 0; - buffer[k++] = 0x7c; - buffer[k++] = 0x00; // fluid - buffer[k++] = 0x01; // load sound font + buffer[k++] = MUSE_SYNTH_SYSEX_MFG_ID; + buffer[k++] = FLUID_UNIQUE_ID; // fluid + buffer[k++] = SF_REPLACE; // load sound font strcpy((char*)(&buffer[k]), path); sendSysex(buffer, len); } @@ -80,3 +87,40 @@ void FLUIDGui::soundFontFileDialog() } } +void FLUIDGui::processEvent(const MidiPlayEvent& ev) +{ + // p4.0.27 + if (ev.type() == ME_SYSEX) { + const unsigned char* data = ev.data(); + switch (*data) { + case FS_SEND_SOUNDFONT_NAME: { + //const char* filename = data+1; + //pathEntry->setText(QString(filename)); + pathEntry->setText((const char*)(data+1)); + break; + } + default: + #ifdef FS_DEBUG + printf("FLUIDGui::processEvent() : Unknown Sysex received: %d\n", ev.type()); + #endif + break; + } + } + else + { + #ifdef FS_DEBUG + printf("FLUIDGui::processEvent - unknown event of type %dreceived from synth.\n", ev.type()); + #endif + } +} + +//--------------------------------------------------------- +// readMessage +//--------------------------------------------------------- + +void FLUIDGui::readMessage(int) + { + MessGui::readMessage(); // p4.0.27 + } + + diff --git a/muse2/synti/fluid/fluidgui.h b/muse2/synti/fluid/fluidgui.h index 3e564538..2752567f 100644 --- a/muse2/synti/fluid/fluidgui.h +++ b/muse2/synti/fluid/fluidgui.h @@ -12,6 +12,10 @@ #include "ui_fluidguibase.h" #include "libsynti/gui.h" +#define FS_SEND_SOUNDFONT_NAME 1 + +//#define FS_DEBUG + class QDialog; //--------------------------------------------------------- @@ -23,11 +27,13 @@ class FLUIDGui : public QDialog, public Ui::FLUIDGuiBase, public MessGui { Q_OBJECT private slots: + void readMessage(int); void soundFontFileDialog(); void loadFont(); public: FLUIDGui(); + virtual void processEvent(const MidiPlayEvent&); }; #endif diff --git a/muse2/synti/fluidsynth/common_defs.h b/muse2/synti/fluidsynth/common_defs.h new file mode 100644 index 00000000..f1f4007d --- /dev/null +++ b/muse2/synti/fluidsynth/common_defs.h @@ -0,0 +1,8 @@ +#ifndef __FLUIDSYNTH_UNIQUE_ID_H +#define __FLUIDSYNTH_UNIQUE_ID_H + +// Make sure this number is unique among all the MESS synths. +#define FLUIDSYNTH_UNIQUE_ID 3 + +#endif + diff --git a/muse2/synti/fluidsynth/fluidsynthgui.cpp b/muse2/synti/fluidsynth/fluidsynthgui.cpp index 2e91515f..6dda43bd 100644 --- a/muse2/synti/fluidsynth/fluidsynthgui.cpp +++ b/muse2/synti/fluidsynth/fluidsynthgui.cpp @@ -22,6 +22,7 @@ #include "muse/midi.h" #include "icons.h" +#include "common_defs.h" /* #include "muse/debug.h" @@ -183,10 +184,14 @@ void FluidSynthGui::loadClicked() void FluidSynthGui::sendLastdir(QString dir) { - int l = dir.length()+2; + //int l = dir.length()+2; + int l = dir.length()+4; byte data[l]; - data[0] = FS_LASTDIR_CHANGE; - memcpy(data+1, dir.toLatin1(), dir.length()+1); + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_LASTDIR_CHANGE; + //memcpy(data+1, dir.toLatin1(), dir.length()+1); + memcpy(data+3, dir.toLatin1(), dir.length()+1); sendSysex(data,l); } @@ -197,11 +202,15 @@ void FluidSynthGui::sendLastdir(QString dir) void FluidSynthGui::sendLoadFont(QString filename) { - int l = filename.length()+3; + //int l = filename.length()+3; + int l = filename.length()+5; byte data[l]; - data[0] = FS_PUSH_FONT; - data[1] = FS_UNSPECIFIED_ID; - memcpy(data+2, filename.toLatin1(), filename.length()+1); + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_PUSH_FONT; + data[3] = FS_UNSPECIFIED_ID; + //memcpy(data+2, filename.toLatin1(), filename.length()+1); + memcpy(data+4, filename.toLatin1(), filename.length()+1); sendSysex(data,l); } @@ -446,9 +455,13 @@ void FluidSynthGui::changeGain(int value) //--------------------------------------------------------- void FluidSynthGui::dumpInfo() { - byte data[1]; - data[0] = FS_DUMP_INFO; - sendSysex(data, 1); + //byte data[1]; + byte data[3]; + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_DUMP_INFO; + //sendSysex(data, 1); + sendSysex(data, 3); } //--------------------------------------------------------- @@ -581,11 +594,15 @@ int FluidSynthGui::getSoundFontId(QString q) void FluidSynthGui::sendChannelChange(byte font_id, byte channel) { - byte data[3]; - data[0] = FS_SOUNDFONT_CHANNEL_SET; - data[1] = font_id; - data[2] = channel; - sendSysex(data, 3); + //byte data[3]; + byte data[5]; + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_SOUNDFONT_CHANNEL_SET; + data[3] = font_id; + data[4] = channel; + //sendSysex(data, 3); + sendSysex(data, 5); } //--------------------------------------------------------- @@ -594,21 +611,29 @@ void FluidSynthGui::sendChannelChange(byte font_id, byte channel) //--------------------------------------------------------- void FluidSynthGui::sendDrumChannelChange(byte onoff, byte channel) { - byte data[3]; - data[0] = FS_DRUMCHANNEL_SET; - data[1] = onoff; - data[2] = channel; - sendSysex(data, 3); + //byte data[3]; + byte data[5]; + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_DRUMCHANNEL_SET; + data[3] = onoff; + data[4] = channel; + //sendSysex(data, 3); + sendSysex(data, 5); if (FS_DEBUG) printf("Sent FS_DRUMCHANNEL_SET for channel %d, status: %d\n", channel, onoff); } void FluidSynthGui::popClicked() { - byte data[2]; - data[0] = FS_SOUNDFONT_POP; - data[1] = currentlySelectedFont; - sendSysex(data,2); + //byte data[2]; + byte data[4]; + data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + data[1] = FLUIDSYNTH_UNIQUE_ID; + data[2] = FS_SOUNDFONT_POP; + data[3] = currentlySelectedFont; + //sendSysex(data,2); + sendSysex(data,4); } void FluidSynthGui::sfItemClicked(QTreeWidgetItem* item, int /*col*/) diff --git a/muse2/synti/fluidsynth/fluidsynthgui.h b/muse2/synti/fluidsynth/fluidsynthgui.h index 5b39723e..373a2343 100644 --- a/muse2/synti/fluidsynth/fluidsynthgui.h +++ b/muse2/synti/fluidsynth/fluidsynthgui.h @@ -46,7 +46,8 @@ struct FluidChannel; #define FS_SFDATALEN 1 #define FS_VERSION_MAJOR 0 #define FS_VERSION_MINOR 4 -#define FS_INIT_DATA_HEADER_SIZE 4 +//#define FS_INIT_DATA_HEADER_SIZE 4 +#define FS_INIT_DATA_HEADER_SIZE 6 // Including MFG + synth IDs #define FS_INIT_CHANNEL_SECTION 255 // Predefined init-values for fluidsynth diff --git a/muse2/synti/fluidsynth/fluidsynti.cpp b/muse2/synti/fluidsynth/fluidsynti.cpp index aadc92ef..35ee16df 100644 --- a/muse2/synti/fluidsynth/fluidsynti.cpp +++ b/muse2/synti/fluidsynth/fluidsynti.cpp @@ -12,6 +12,7 @@ #include <QFileInfo> +//#include "common_defs.h" #include "fluidsynti.h" #include "muse/midi.h" @@ -65,6 +66,7 @@ QString *projPathPtr; // FluidSynth::FluidSynth(int sr, pthread_mutex_t *_Globalsfloader_mutex) : Mess(2) { + gui = 0; setSampleRate(sr); fluid_settings_t* s = new_fluid_settings(); fluid_settings_setnum(s, (char*) "synth.sample-rate", float(sampleRate())); @@ -85,19 +87,18 @@ FluidSynth::FluidSynth(int sr, pthread_mutex_t *_Globalsfloader_mutex) : Mess(2) //pthread_mutex_init(&_sfloader_mutex,NULL); _sfloader_mutex = _Globalsfloader_mutex; -/* - buffer = 0; - bufferlen = 0; - */ + initBuffer = 0; + initLen = 0; } FluidSynth::~FluidSynth() { int err = delete_fluid_synth (fluidsynth); - delete gui; + if(gui) + delete gui; -/* if (buffer) - delete [] buffer;*/ + if (initBuffer) + delete [] initBuffer; if (err == -1) { std::cerr << DEBUG_ARGS << "error while destroying synth: " << fluid_synth_error(fluidsynth) << std::endl; return; @@ -141,6 +142,13 @@ bool FluidSynth::init(const char* name) return false; } +int FluidSynth::oldMidiStateHeader(const unsigned char** data) const +{ + unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, FLUIDSYNTH_UNIQUE_ID}; + *data = &d[0]; + return 2; +} + //--------------------------------------------------------- // processMessages // Called from host always, even if output path is unconnected. @@ -207,7 +215,7 @@ void FluidSynth::process(float** ports, int offset, int len) // getInitData // Prepare data that will restore the synth's state on load //--------------------------------------------------------- -void FluidSynth::getInitData(int* n, const unsigned char** data) const +void FluidSynth::getInitData(int* n, const unsigned char** data) { //printf("projPathPtr "); @@ -250,16 +258,29 @@ void FluidSynth::getInitData(int* n, const unsigned char** data) const if (FS_DEBUG) printf("Total length of init sysex: %d\n", len); - byte* d = new byte[len]; + + //byte* d = new byte[len]; + if (len > initLen) { + if (initBuffer) + delete [] initBuffer; + initBuffer = new byte[len]; + initLen = len; + } // Header: - d[0] = FS_INIT_DATA; - d[1] = FS_VERSION_MAJOR; - d[2] = FS_VERSION_MINOR; - d[3] = stack.size(); + //d[0] = FS_INIT_DATA; + //d[1] = FS_VERSION_MAJOR; + //d[2] = FS_VERSION_MINOR; + //d[3] = stack.size(); + initBuffer[0] = MUSE_SYNTH_SYSEX_MFG_ID; + initBuffer[1] = FLUIDSYNTH_UNIQUE_ID; + initBuffer[2] = FS_INIT_DATA; + initBuffer[3] = FS_VERSION_MAJOR; + initBuffer[4] = FS_VERSION_MINOR; + initBuffer[5] = stack.size(); //Lastdir: - byte* chptr = d + FS_INIT_DATA_HEADER_SIZE; + byte* chptr = initBuffer + FS_INIT_DATA_HEADER_SIZE; memcpy(chptr, lastdir.c_str(), strlen(lastdir.c_str())+1); //For each font... @@ -298,14 +319,14 @@ void FluidSynth::getInitData(int* n, const unsigned char** data) const *chptr = cho_on; chptr++; if (FS_DEBUG) { for (int i=0; i<len; i++) - printf("%c ", d[i]); + printf("%c ", initBuffer[i]); printf("\n"); for (int i=0; i<len; i++) - printf("%x ", d[i]); + printf("%x ", initBuffer[i]); printf("\n"); } // Give values to host: - *data = d; + *data = (unsigned char*)initBuffer; *n = len; } @@ -313,7 +334,7 @@ void FluidSynth::getInitData(int* n, const unsigned char** data) const // parseInitData //----------------------------------- void FluidSynth::parseInitData(int n, const byte* d) - { +{ printf("projPathPtr "); std::cout << *projPathPtr->toAscii().data() << std::endl; @@ -329,6 +350,7 @@ void FluidSynth::parseInitData(int n, const byte* d) byte version_major, version_minor; version_major = d[1]; version_minor = d[2]; + //version_major = d[3]; version_minor = d[4]; // Check which version of the initdata we're using and if it's OK if (!(version_major == FS_VERSION_MAJOR && version_minor == FS_VERSION_MINOR)) { @@ -337,9 +359,9 @@ void FluidSynth::parseInitData(int n, const byte* d) } if (version_major == 0 && version_minor == 1) { - sendError("Initialization data created with different version of FluidSynth Mess, will be ignored."); - return; - } + sendError("Initialization data created with different version of FluidSynth Mess, will be ignored."); + return; + } if (version_major == 0 && version_minor <= 2) { load_drumchannels = false; @@ -351,8 +373,10 @@ void FluidSynth::parseInitData(int n, const byte* d) } byte nr_of_fonts = d[3]; + //byte nr_of_fonts = d[5]; nrOfSoundfonts = nr_of_fonts; //"Global" counter const byte* chptr = (d + 4); + //const byte* chptr = (d + FS_INIT_DATA_HEADER_SIZE); //Get lastdir: lastdir = std::string((char*)chptr); @@ -365,7 +389,7 @@ void FluidSynth::parseInitData(int n, const byte* d) for (int i=0; i<nr_of_fonts; i++) { fonts[i].filename = (char*)(chptr); chptr+=(strlen(fonts[i].filename.c_str())+1); - QByteArray ba = projPathPtr->toAscii(); + QByteArray ba = projPathPtr->toAscii(); if (QFileInfo(fonts[i].filename.c_str()).isRelative()) { printf("path is relative, we append full path!\n"); @@ -413,7 +437,7 @@ void FluidSynth::parseInitData(int n, const byte* d) for (int i=0; i<nrOfSoundfonts; i++) { pushSoundfont(fonts[i].filename.c_str(), fonts[i].extid); } - } +} //--------------------------------------------------------- @@ -464,19 +488,29 @@ bool FluidSynth::processEvent(const MidiPlayEvent& ev) bool FluidSynth::sysex(int n, const unsigned char* d) { - switch(*d) { + if(n < 3 || d[0] != MUSE_SYNTH_SYSEX_MFG_ID + || d[1] != FLUIDSYNTH_UNIQUE_ID) + { + if (FS_DEBUG) + printf("MusE FluidSynth: Unknown sysex header\n"); + return false; + } + + //switch(*d) { + const unsigned char* chrptr = d + 2; + switch(*chrptr) { case FS_LASTDIR_CHANGE: { - lastdir = std::string((char*)(d+1)); + lastdir = std::string((char*)(chrptr+1)); sendLastdir(lastdir.c_str()); break; } case FS_PUSH_FONT: { - int extid = d[1]; + int extid = chrptr[1]; if (FS_DEBUG) - printf("Client: Got push font %s, id: %d\n",(d+1), extid); + printf("Client: Got push font %s, id: %d\n",(chrptr+1), extid); - const char* filename = (const char*)(d+2); + const char* filename = (const char*)(chrptr+2); if (!pushSoundfont(filename, extid)) sendError("Could not load soundfont "); break; @@ -486,19 +520,19 @@ bool FluidSynth::sysex(int n, const unsigned char* d) break; } case FS_SOUNDFONT_CHANNEL_SET: { - sfChannelChange(*(d+1), *(d+2)); + sfChannelChange(*(chrptr+1), *(chrptr+2)); break; } case FS_INIT_DATA: { - parseInitData(n,d); + parseInitData(n - 2, chrptr); break; } case FS_SOUNDFONT_POP: - popSoundfont(*(d+1)); + popSoundfont(*(chrptr+1)); break; case FS_DRUMCHANNEL_SET: { - byte onoff = (*(d+1)); - byte channel = (*(d+2)); + byte onoff = (*(chrptr+1)); + byte channel = (*(chrptr+2)); channels[channel].drumchannel = onoff; if (FS_DEBUG) printf("Client: Set drumchannel on chan %d to %d\n",channel, onoff); @@ -506,7 +540,7 @@ bool FluidSynth::sysex(int n, const unsigned char* d) } default: if (FS_DEBUG) - printf("FluidSynth::sysex() : unknown sysex received: %d\n",*d); + printf("FluidSynth::sysex() : unknown sysex received: %d\n",*chrptr); break; } return false; @@ -647,6 +681,7 @@ bool FluidSynth::playNote(int channel, int pitch, int velo) void FluidSynth::sendSoundFontData() { int ndatalen = 2; //2 bytes for command and length + //int ndatalen = 4; // 4 bytes for header, command and length //Calculate length in chars of all strings in the soundfontstack in one string for (std::list<FluidSoundFont>::iterator it = stack.begin(); it != stack.end(); it++) { @@ -654,11 +689,16 @@ void FluidSynth::sendSoundFontData() ndatalen += FS_SFDATALEN; //unsigned char for ID } byte ndata[ndatalen]; - *ndata = FS_SEND_SOUNDFONTDATA; //The command + *(ndata) = FS_SEND_SOUNDFONTDATA; //The command *(ndata + 1) = (unsigned char)stack.size (); //Nr of Soundfonts + //*ndata = MUSE_SYNTH_SYSEX_MFG_ID; + //*(ndata + 1) = FLUIDSYNTH_UNIQUE_ID; + //*(ndata + 2) = FS_SEND_SOUNDFONTDATA; //The command + //*(ndata + 3) = (unsigned char)stack.size (); //Nr of Soundfonts // Copy the stuff to ndatalen: char* chunk_start = (char*)(ndata + 2); + //char* chunk_start = (char*)(ndata + 4); int chunk_len, name_len; for (std::list<FluidSoundFont>::iterator it = stack.begin(); it != stack.end(); ++it) { name_len = strlen(it->name.c_str()) + 1; @@ -675,12 +715,18 @@ void FluidSynth::sendSoundFontData() //--------------------------------------------------------- void FluidSynth::sendChannelData() { - int chunk_size = 2; + ///int chunk_size = 2; + int const chunk_size = 2; int chdata_length = (chunk_size * FS_MAX_NR_OF_CHANNELS) +1 ; //Command and the 2 channels * 16 + //int chdata_length = (chunk_size * FS_MAX_NR_OF_CHANNELS) +3 ; // Header, command and the 2 channels * 16 byte chdata[chdata_length]; byte* chdptr; chdata[0] = FS_SEND_CHANNELINFO; + //chdata[0] = MUSE_SYNTH_SYSEX_MFG_ID; + //chdata[1] = FLUIDSYNTH_UNIQUE_ID; + //chdata[2] = FS_SEND_CHANNELINFO; chdptr = (chdata + 1); + //chdptr = (chdata + 3); for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) { *(chdptr) = channels[i].font_extid; //Font external id *(chdptr+1) = i; //Channel nr @@ -690,10 +736,16 @@ void FluidSynth::sendChannelData() // Send drum channel info afterwards (later addition, not very neat, but works...) int drumchdata_length = FS_MAX_NR_OF_CHANNELS + 1; //1 byte for the command, one byte for each channel - byte drumchdata[drumchdata_length ]; - byte* drumchdataptr = drumchdata; + //int drumchdata_length = FS_MAX_NR_OF_CHANNELS + 3; // 2 bytes for header, 1 byte for the command, one byte for each channel + byte drumchdata[drumchdata_length]; *drumchdata = FS_SEND_DRUMCHANNELINFO; - + //drumchdata[0] = MUSE_SYNTH_SYSEX_MFG_ID; + //drumchdata[1] = FLUIDSYNTH_UNIQUE_ID; + //drumchdata[2] = FS_SEND_DRUMCHANNELINFO; + + byte* drumchdataptr = drumchdata; + //byte* drumchdataptr = drumchdata + 3; + for (int i=0; i<FS_MAX_NR_OF_CHANNELS; i++) { drumchdataptr++; *drumchdataptr = channels[i].drumchannel; @@ -986,9 +1038,14 @@ int FluidSynth::getControllerInfo(int id, const char** name, int* controller, in void FluidSynth::sendError(const char *errorMessage) { int len = 2 + strlen(errorMessage); + //int len = 4 + strlen(errorMessage); unsigned char data[len]; *data = FS_ERROR; + //data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + //data[1] = FLUIDSYNTH_UNIQUE_ID; + //data[2] = FS_ERROR; memcpy(data + 1, errorMessage, len - 1); + //memcpy(data + 3, errorMessage, len - 3); sendSysex(len, data); } @@ -1041,9 +1098,14 @@ byte FluidSynth::getFontInternalIdByExtId(byte ext_id) void FluidSynth::sendLastdir(const char* lastdir) { int n = strlen(lastdir) + 2; + //int n = strlen(lastdir) + 4; byte d[n]; d[0] = FS_LASTDIR_CHANGE; + //d[0] = MUSE_SYNTH_SYSEX_MFG_ID; + //d[1] = FLUIDSYNTH_UNIQUE_ID; + //d[2] = FS_LASTDIR_CHANGE; memcpy(d+1,lastdir, strlen(lastdir)+1); + //memcpy(d+3,lastdir, strlen(lastdir)+1); MidiPlayEvent ev(0,0, ME_SYSEX, d, n); gui->writeEvent(ev); @@ -1289,7 +1351,7 @@ static bool mutexEnabled = false; static Mess* instantiate(int sr, QWidget*, QString* projectPathPtr, const char* name) { -printf("fluidsynth sampleRate %d\n", sr); + printf("fluidsynth sampleRate %d\n", sr); projPathPtr=projectPathPtr; if (!mutexEnabled) { diff --git a/muse2/synti/fluidsynth/fluidsynti.h b/muse2/synti/fluidsynth/fluidsynti.h index a371de9e..fde42396 100644 --- a/muse2/synti/fluidsynth/fluidsynti.h +++ b/muse2/synti/fluidsynth/fluidsynti.h @@ -20,6 +20,7 @@ //#include "libsynti/mpevent.h" #include "muse/mpevent.h" #include "muse/midictrl.h" +#include "common_defs.h" #define FS_DEBUG_DATA 0 //Turn on/off debug print of midi data sent to fluidsynth @@ -83,6 +84,9 @@ class FluidSynth : public Mess { void sfChannelChange(unsigned char font_id, unsigned char channel); void parseInitData(int n, const byte* d); + byte* initBuffer; + int initLen; + byte getFontInternalIdByExtId (byte channel); void debug(const char* msg) { if (FS_DEBUG) printf("Debug: %s\n",msg); } @@ -101,15 +105,17 @@ class FluidSynth : public Mess { public: FluidSynth(int sr, pthread_mutex_t *_Globalsfloader_mutex); - ~FluidSynth(); + virtual ~FluidSynth(); bool init(const char*); + // This is only a kludge required to support old songs' midistates. Do not use in any new synth. + virtual int oldMidiStateHeader(const unsigned char** data) const; virtual void processMessages(); virtual void process(float**, int, int); virtual bool playNote(int channel, int pitch, int velo); virtual bool sysex(int, const unsigned char*); virtual bool setController(int, int, int); void setController(int, int , int, bool); - virtual void getInitData(int*, const unsigned char**) const; + virtual void getInitData(int*, const unsigned char**); virtual const char* getPatchName(int, int, int, bool) const; virtual const MidiPatch* getPatchInfo(int i, const MidiPatch* patch) const; virtual int getControllerInfo(int, const char**, int*, int*, int*, int*) const; diff --git a/muse2/synti/libsynti/evdata.h.OLD b/muse2/synti/libsynti/evdata.h.OLD index 4e529bec..8c8b77c9 100644 --- a/muse2/synti/libsynti/evdata.h.OLD +++ b/muse2/synti/libsynti/evdata.h.OLD @@ -57,6 +57,8 @@ class EvData { } } void setData(const unsigned char* p, int l) { + if(data) + delete[] data; // p4.0.27 data = new unsigned char[l]; memcpy(data, p, l); dataLen = l; diff --git a/muse2/synti/libsynti/mess.h b/muse2/synti/libsynti/mess.h index bf9ad0de..81a3fe96 100644 --- a/muse2/synti/libsynti/mess.h +++ b/muse2/synti/libsynti/mess.h @@ -37,6 +37,10 @@ struct MidiPatch { // Mess // MusE experimental software synth // Instance virtual interface class +// NOTICE: If implementing sysex support, be sure to make a unique ID and use +// it to filter out unrecognized sysexes. Headers should be constructed as: +// MUSE_SYNTH_SYSEX_MFG_ID The MusE SoftSynth Manufacturer ID byte (0x7C) found in midi.h +// 0xNN The synth's unique ID byte //--------------------------------------------------------- class Mess { @@ -49,6 +53,9 @@ class Mess { Mess(int channels); virtual ~Mess(); + // This is only a kludge required to support old songs' midistates. Do not use in any new synth. + virtual int oldMidiStateHeader(const unsigned char** /*data*/) const { return 0; } + int channels() const { return _channels; } int sampleRate() const { return _sampleRate; } void setSampleRate(int r) { _sampleRate = r; } @@ -62,9 +69,9 @@ class Mess { virtual bool processEvent(const MidiPlayEvent&); virtual bool setController(int, int, int) { return false; } virtual bool playNote(int, int, int) { return false; } - virtual bool sysex(int, const unsigned char*) { return false; } + virtual bool sysex(int, const unsigned char*) { return false; } - virtual void getInitData(int*, const unsigned char**) const {} + virtual void getInitData(int* n, const unsigned char**) /*const*/ { *n = 0; } // No const: Synths may need to allocate member pointers. p4.0.27 Tim virtual int getControllerInfo(int, const char**, int*, int*, int*, int*) const {return 0;} virtual const char* getPatchName(int, int, int, bool) const { return "?"; } virtual const MidiPatch* getPatchInfo(int, const MidiPatch*) const { return 0; } diff --git a/muse2/synti/organ/common_defs.h b/muse2/synti/organ/common_defs.h new file mode 100644 index 00000000..31d09081 --- /dev/null +++ b/muse2/synti/organ/common_defs.h @@ -0,0 +1,8 @@ +#ifndef __ORGAN_UNIQUE_ID_H +#define __ORGAN_UNIQUE_ID_H + +// Make sure this number is unique among all the MESS synths. +#define ORGAN_UNIQUE_ID 1 + +#endif + diff --git a/muse2/synti/organ/organ.cpp b/muse2/synti/organ/organ.cpp index 56fb4db1..f3bb3b9f 100644 --- a/muse2/synti/organ/organ.cpp +++ b/muse2/synti/organ/organ.cpp @@ -17,6 +17,7 @@ //#include "libsynti/mpevent.h" #include "muse/mpevent.h" +//#include "common_defs.h" #include "organ.h" #include "organgui.h" @@ -76,7 +77,8 @@ double Organ::cb2amp(int cb) Organ::Organ(int sr) : Mess(1) { - idata = new int[NUM_CONTROLLER]; + //idata = new int[NUM_CONTROLLER]; + idata = new unsigned char[3 + NUM_CONTROLLER * sizeof(int)]; setSampleRate(sr); gui = 0; @@ -131,7 +133,8 @@ Organ::~Organ() { if (gui) delete gui; - delete idata; + //delete idata; + delete [] idata; // p4.0.27 --useCount; if (useCount == 0) { delete[] g_pulse_table; @@ -170,6 +173,13 @@ bool Organ::init(const char* name) return false; } +int Organ::oldMidiStateHeader(const unsigned char** data) const +{ + unsigned char const d[3] = {MUSE_SYNTH_SYSEX_MFG_ID, ORGAN_UNIQUE_ID, INIT_DATA_CMD}; + *data = &d[0]; + return 3; +} + //--------------------------------------------------------- // processMessages // Called from host always, even if output path is unconnected. @@ -192,7 +202,11 @@ void Organ::processMessages() sendEvent(ev); } else + { + #ifdef ORGAN_DEBUG printf("Organ::process(): unknown event\n"); + #endif + } } } @@ -404,7 +418,9 @@ bool Organ::playNote(int channel, int pitch, int velo) voices[i].harm5_accum = 0; return false; } + #ifdef ORGAN_DEBUG printf("organ: voices overflow!\n"); + #endif return false; } @@ -424,7 +440,11 @@ void Organ::noteoff(int channel, int pitch) } } if (!found) + { + #ifdef ORGAN_DEBUG printf("Organ: noteoff %d:%d not found\n", channel, pitch); + #endif + } } //--------------------------------------------------------- @@ -515,7 +535,9 @@ void Organ::setController(int ctrl, int data) setController(0, synthCtrl[i].num, synthCtrl[i].val); break; default: + #ifdef ORGAN_DEBUG fprintf(stderr, "Organ:set unknown Ctrl 0x%x to 0x%x\n", ctrl, data); + #endif return; } for (int i = 0; i < NUM_CONTROLLER; ++i) { @@ -573,37 +595,59 @@ bool Organ::setController(int channel, int ctrl, int data) //--------------------------------------------------------- bool Organ::sysex(int n, const unsigned char* data) - { +{ #ifdef ORGAN_DEBUG printf("Organ: sysex\n"); #endif - if (unsigned(n) != (NUM_INIT_CONTROLLER * sizeof(int))) { - printf("Organ: unknown sysex\n"); - return false; - } - int* s = (int*) data; - for (int i = 0; i < NUM_INIT_CONTROLLER; ++i) { - int val = *s++; - #ifdef ORGAN_DEBUG - printf("Organ: sysex before setController num:%d val:%d\n", synthCtrl[i].num, val); - #endif - setController(0, synthCtrl[i].num, val); + + // p4.0.27 + if(unsigned(n) == (3 + NUM_INIT_CONTROLLER * sizeof(int))) + { + if (data[0] == MUSE_SYNTH_SYSEX_MFG_ID) // MusE Soft Synth + { + if (data[1] == ORGAN_UNIQUE_ID) // ORGAN + { + if (data[2] == INIT_DATA_CMD) // Initialization + { + int* s = (int*)(data + 3); + for (int i = 0; i < NUM_INIT_CONTROLLER; ++i) + { + int val = *s++; + #ifdef ORGAN_DEBUG + printf("Organ: sysex before setController num:%d val:%d\n", synthCtrl[i].num, val); + #endif + setController(0, synthCtrl[i].num, val); + } + return false; } - return false; + } + } } - + #ifdef ORGAN_DEBUG + printf("Organ: unknown sysex\n"); + #endif + return false; +} //--------------------------------------------------------- // getInitData //--------------------------------------------------------- -void Organ::getInitData(int* n, const unsigned char**p) const - { - int* d = idata; +//void Organ::getInitData(int* n, const unsigned char**p) const +void Organ::getInitData(int* n, const unsigned char**p) +{ + // p4.0.27 + *n = 3 + NUM_INIT_CONTROLLER * sizeof(int); + idata[0] = MUSE_SYNTH_SYSEX_MFG_ID; // MusE Soft Synth + idata[1] = ORGAN_UNIQUE_ID; // ORGAN + idata[2] = INIT_DATA_CMD; // Initialization + int* d = (int*)&idata[3]; + + //int* d = idata; for (int i = 0; i < NUM_INIT_CONTROLLER; ++i) *d++ = synthCtrl[i].val; - *n = NUM_INIT_CONTROLLER * sizeof(int); // sizeof(idata); + //*n = NUM_INIT_CONTROLLER * sizeof(int); // sizeof(idata); *p = (unsigned char*)idata; - } +} //--------------------------------------------------------- // MESS diff --git a/muse2/synti/organ/organ.h b/muse2/synti/organ/organ.h index 60fee98a..f859ea8c 100644 --- a/muse2/synti/organ/organ.h +++ b/muse2/synti/organ/organ.h @@ -15,9 +15,11 @@ #include "muse/midictrl.h" #include "libsynti/mess.h" +#include "common_defs.h" #define RESOLUTION (16384*2) #define VOICES 128 // max polyphony +#define INIT_DATA_CMD 1 class OrganGui; @@ -149,7 +151,8 @@ class Organ : public Mess { static unsigned freq256[128]; static double cb2amp(int cb); - int* idata; // buffer for init data + //int* idata; // buffer for init data + unsigned char* idata; // buffer for init data bool brass, flute, reed; int attack0, attack1; @@ -180,7 +183,10 @@ class Organ : public Mess { virtual bool setController(int channel, int ctrl, int val); virtual int getControllerInfo(int, const char**, int*, int*, int*, int*) const; - virtual void getInitData(int*, const unsigned char**) const; + //virtual void getInitData(int*, const unsigned char**) const; + virtual void getInitData(int*, const unsigned char**); + // This is only a kludge required to support old songs' midistates. Do not use in any new synth. + virtual int oldMidiStateHeader(const unsigned char** data) const; //virtual bool guiVisible() const; //virtual void showGui(bool); @@ -193,7 +199,7 @@ class Organ : public Mess { virtual bool sysex(int, const unsigned char*); static SynthCtrl synthCtrl[]; Organ(int sampleRate); - ~Organ(); + virtual ~Organ(); bool init(const char* name); }; diff --git a/muse2/synti/organ/organgui.cpp b/muse2/synti/organ/organgui.cpp index b10ab01d..a25a8de9 100644 --- a/muse2/synti/organ/organgui.cpp +++ b/muse2/synti/organ/organgui.cpp @@ -19,6 +19,7 @@ #include <QSocketNotifier> #include <QSpinBox> +#include "common_defs.h" #include "organgui.h" #include "muse/midi.h" #include "muse/midictrl.h" @@ -134,7 +135,9 @@ void OrganGui::setParam(int param, int val) param &= 0xfff; if (param >= int(sizeof(dctrl)/sizeof(*dctrl))) { + #ifdef ORGANGUI_DEBUG fprintf(stderr, "OrganGui: set unknown Ctrl 0x%x to 0x%x\n", param, val); + #endif return; } SynthGuiCtrl* ctrl = &dctrl[param]; @@ -172,7 +175,11 @@ void OrganGui::processEvent(const MidiPlayEvent& ev) if (ev.type() == ME_CONTROLLER) setParam(ev.dataA(), ev.dataB()); else + { + #ifdef ORGANGUI_DEBUG printf("OrganGui::illegal event type received\n"); + #endif + } } //--------------------------------------------------------- diff --git a/muse2/synti/s1/s1.cpp b/muse2/synti/s1/s1.cpp index c44676ce..9c466b4a 100644 --- a/muse2/synti/s1/s1.cpp +++ b/muse2/synti/s1/s1.cpp @@ -21,6 +21,9 @@ #include "libsynti/mono.h" #define RESOLUTION 16384 +// Make sure this number is unique among all the MESS synths. +#define S1_UNIQUE_ID 6 + //--------------------------------------------------------- // S1 - simple mono demo synthesizer @@ -53,7 +56,7 @@ class S1 : public MessMono { public: S1(); - ~S1(); + virtual ~S1(); }; float* S1::wave_table; diff --git a/muse2/synti/simpledrums/CMakeLists.txt b/muse2/synti/simpledrums/CMakeLists.txt deleted file mode 100644 index 6b015f2b..00000000 --- a/muse2/synti/simpledrums/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -#============================================================================= -# MusE -# Linux Music Editor -# $Id:$ -# -# Copyright (C) 2002-2006 by Werner Schweer and others -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -#============================================================================= - -QT4_WRAP_CPP ( simpledrums_mocs simpledrumsgui.h ssplugingui.h ) -# QT4_WRAP_UI ( simpledrums_uis simpledrumsguibase.ui sspluginchooserbase.ui ) -QT4_WRAP_UI3 ( simpledrums_uis simpledrumsguibase.ui sspluginchooserbase.ui ) - -add_library ( simpledrums SHARED - simpledrums.cpp - simpledrumsgui.cpp - simpledrums.h - ssplugin.cpp - ssplugingui.cpp - ssplugin.h - common.h - ${simpledrums_mocs} - ${simpledrums_uis} - ) - -# - tell cmake to name target simpledrums.so instead of -# libsimpledrums.so -# - use precompiled header files -# -set_target_properties ( simpledrums - PROPERTIES PREFIX "" - COMPILE_FLAGS "-O6 -fvisibility=hidden -include ${PROJECT_BINARY_DIR}/all-pic.h" - ) - -target_link_libraries(simpledrums - synti -# awl - ${QT_LIBRARIES} - ) - -install_targets ( /${CMAKE_INSTALL_LIBDIR}/${MusE_INSTALL_NAME}/synthi/ simpledrums ) - diff --git a/muse2/synti/simpledrums/COPYING b/muse2/synti/simpledrums/COPYING deleted file mode 100644 index 5c3cefc2..00000000 --- a/muse2/synti/simpledrums/COPYING +++ /dev/null @@ -1,3 +0,0 @@ -COPYING ---------------------------------------- -This software is licensed under GNU GPL. diff --git a/muse2/synti/simpledrums/README b/muse2/synti/simpledrums/README deleted file mode 100644 index 9e2695dc..00000000 --- a/muse2/synti/simpledrums/README +++ /dev/null @@ -1,44 +0,0 @@ --------------------------------------- -Simpledrums v 0.2, by Mathias Lundgren --------------------------------------- - -Simpledrums is a simple MESS-synth sampler (MusE Experimental Soft -Synth) aiming at becoming a simple, tightly integrated sampler for -MusE, specifically aimed at drumsamples. - -Features: -- 16 channels/samples (1 sample/channel) -- Simple controls for each individual channel: volume, balance, noteoff-ignore, channel on/off -- Main volume -- 4 LADSPA send-effects can be used, 4 effect taps for each individual channel -- All channel parameters are controllable via the GUI, or by MusE:s controller handling (controller pane in pianoroll/drumeditor) -- All effect parameters can be controlled via the GUI, or by Sysex messages (f.ex. turn effect on/off, modify effect parameters) -- Complete synth state (fx-parameters, samples etc) is saved together with MusE project, and restored later when loaded -- Possible to save synth state to file -- Samples automatically resampled when loaded (if needed) - -That's all folks! - -------------- -Known issues: -------------- -- Not the prettiest gui in the world -- All samples are read directly into memory (no caching) -- Some obscure LADSPA-effects make SimpleSynth segfault -- More... - -------------- -Future plans: -------------- -- Fix all the known issues! ;-) -- Sample loops -- Sample offset variation w respect to note velocity -- Treble/eq-controller for each individual channel -- Treble level variation w respect to note velocity -- More... - -Mathias Lundgren, (lunar_shuttle@users.sourceforge.net), 2004 -Plugin management code based on Werner Schweers plugin management handling for MusE - -(C) Copyright Mathias Lundgren, Werner Schweer 2000-2004 -Licensed under the GNU General Public License diff --git a/muse2/synti/simpledrums/ReleaseNotes.txt b/muse2/synti/simpledrums/ReleaseNotes.txt deleted file mode 100644 index 1144321a..00000000 --- a/muse2/synti/simpledrums/ReleaseNotes.txt +++ /dev/null @@ -1,21 +0,0 @@ -RELEASE NOTES: --------------- -2005-05-07 ver 1.0 (go figure!) -- Now possible to load/save setup to file - -2004-12-13 ver 0.2 -- Support for 4 LADSPA sendeffects added -- Resampling of samples when loading (libsamplerate) -- Synth state is saved to/restored from project file -- Channel settings: balance, volume, effect tap for each sendeffect -- Effect settings: all LADSPA parameters controllable and saved to MusE project, effect master volume, effect on/off -- Support for mono + stereo samples -- Support for stereo + mono LADSPA effects -- Bugfixes, GUI-improvements etc... - -2004-11-09 ver 0.1 -- Simpledrums initial release -- 16 channels (1 sample for each channel) with parameters: volume, balance, noteoff-ignore - -(C) Copyright Mathias Lundgren, Werner Schweer 2000-2004 -Licensed under the GNU General Public License diff --git a/muse2/synti/simpledrums/common.h b/muse2/synti/simpledrums/common.h deleted file mode 100644 index e4763540..00000000 --- a/muse2/synti/simpledrums/common.h +++ /dev/null @@ -1,110 +0,0 @@ -// -// C++ Interface: common -// -// Description: -// -// -// Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 -// -// Copyright: See COPYING file that comes with this distribution -// -// -#ifndef __MUSE_TESTO_COMMON_H__ -#define __MUSE_TESTO_COMMON_H__ - -#include "muse/midictrl.h" - -#define SS_VERSIONSTRING "1.0" - -#define SS_DEBUG 0 -#define SS_DEBUG_INIT 0 -#define SS_TRACE_FUNC 0 -#define SS_DEBUG_MIDI 0 -#define SS_DEBUG_LADSPA 0 -#define SS_DEBUG_STATE 0 - -#define SS_DBG(string) if (SS_DEBUG) fprintf(stderr, "%s:%d:%s: %s\n", __FILE__ , __LINE__ , __PRETTY_FUNCTION__, string); -#define SS_DBG2(string1, string2) if (SS_DEBUG) fprintf(stderr, "%s:%d:%s: %s: %s\n", __FILE__ , __LINE__ , __PRETTY_FUNCTION__, string1, string2); -#define SS_DBG_I(string1, int) if (SS_DEBUG) fprintf(stderr, "%s:%d:%s: %s: %d\n", __FILE__ , __LINE__ , __PRETTY_FUNCTION__, string1, int); - -#define SS_TRACE_IN if (SS_TRACE_FUNC) fprintf (stderr, "->%s:%d\n", __PRETTY_FUNCTION__, __LINE__); -#define SS_TRACE_OUT if (SS_TRACE_FUNC) fprintf (stderr, "<-%s:%d\n", __PRETTY_FUNCTION__, __LINE__); -#define SS_ERROR(string) fprintf(stderr, "SimpleDrums error: %s\n", string) -#define SS_DBG_LADSPA(string1) if (SS_DEBUG_LADSPA) fprintf(stderr, "%s:%d:%s: %s\n", __FILE__ , __LINE__ , __PRETTY_FUNCTION__, string1); -#define SS_DBG_LADSPA2(string1, string2) if (SS_DEBUG_LADSPA) fprintf(stderr, "%s:%d:%s: %s: %s\n", __FILE__ , __LINE__ , __PRETTY_FUNCTION__, string1, string2); - -#define SS_SYSEX_INIT_DATA_VERSION 1 - -#define SS_NR_OF_CHANNELS 16 -#define SS_AUDIO_CHANNELS 2 -#define SS_NR_OF_SENDEFFECTS 4 - -// Controller-related: -#define SS_CHANNEL_CTRL_VOLUME 0 -#define SS_CHANNEL_CTRL_PAN 1 -#define SS_CHANNEL_CTRL_NOFF 2 -#define SS_CHANNEL_CTRL_ONOFF 3 -#define SS_CHANNEL_SENDFX1 4 -#define SS_CHANNEL_SENDFX2 5 -#define SS_CHANNEL_SENDFX3 6 -#define SS_CHANNEL_SENDFX4 7 - -#define SS_PLUGIN_RETURN 0 -#define SS_PLUGIN_ONOFF 1 - -#define SS_NR_OF_MASTER_CONTROLLERS 1 -#define SS_NR_OF_CHANNEL_CONTROLLERS 8 -#define SS_NR_OF_PLUGIN_CONTROLLERS 2 - -#define SS_NR_OF_CONTROLLERS (SS_NR_OF_MASTER_CONTROLLERS + (SS_NR_OF_CHANNELS * SS_NR_OF_CHANNEL_CONTROLLERS) + (SS_NR_OF_PLUGIN_CONTROLLERS*SS_NR_OF_SENDEFFECTS)) -#define SS_FIRST_MASTER_CONTROLLER CTRL_NRPN14_OFFSET -#define SS_FIRST_CHANNEL_CONTROLLER (SS_FIRST_MASTER_CONTROLLER + SS_NR_OF_MASTER_CONTROLLERS) -#define SS_LAST_MASTER_CONTROLLER (SS_FIRST_CHANNEL_CONTROLLER - 1) -#define SS_LAST_CHANNEL_CONTROLLER (SS_FIRST_CHANNEL_CONTROLLER -1 + (SS_NR_OF_CHANNEL_CONTROLLERS * SS_NR_OF_CHANNELS)) - -#define SS_FIRST_PLUGIN_CONTROLLER (SS_LAST_CHANNEL_CONTROLLER + 1) -#define SS_LAST_PLUGIN_CONTROLLER (SS_FIRST_PLUGIN_CONTROLLER -1 + SS_NR_OF_SENDEFFECTS*SS_NR_OF_PLUGIN_CONTROLLERS) - -#define SS_MASTER_CTRL_VOLUME SS_FIRST_MASTER_CONTROLLER - -#define SS_CHANNEL_VOLUME_CONTROLLER(int) (SS_FIRST_CHANNEL_CONTROLLER + (SS_NR_OF_CHANNEL_CONTROLLERS * int) + SS_CHANNEL_CTRL_VOLUME) -#define SS_CHANNEL_PAN_CONTROLLER(int) (SS_FIRST_CHANNEL_CONTROLLER + (SS_NR_OF_CHANNEL_CONTROLLERS * int) + SS_CHANNEL_CTRL_PAN) -#define SS_CHANNEL_NOFF_CONTROLLER(int) (SS_FIRST_CHANNEL_CONTROLLER + (SS_NR_OF_CHANNEL_CONTROLLERS * int) + SS_CHANNEL_CTRL_NOFF) -#define SS_CHANNEL_ONOFF_CONTROLLER(int) (SS_FIRST_CHANNEL_CONTROLLER + (SS_NR_OF_CHANNEL_CONTROLLERS * int) + SS_CHANNEL_CTRL_ONOFF) -#define SS_CHANNEL_SENDFX_CONTROLLER(int1,int2) (SS_FIRST_CHANNEL_CONTROLLER + (SS_NR_OF_CHANNEL_CONTROLLERS * int1) + SS_CHANNEL_SENDFX1 + int2) - -#define SS_PLUGIN_RETURNLEVEL_CONTROLLER(int) (SS_FIRST_PLUGIN_CONTROLLER + (int * SS_NR_OF_PLUGIN_CONTROLLERS)) -#define SS_PLUGIN_ONOFF_CONTROLLER(int) (SS_FIRST_PLUGIN_CONTROLLER + (int * SS_NR_OF_PLUGIN_CONTROLLERS) + 1) - -#define SS_LOWEST_NOTE 36 -#define SS_HIGHEST_NOTE (SS_LOWEST_NOTE + SS_NR_OF_CHANNELS) - -#define SS_PLUGIN_PARAM_MIN 0 -#define SS_PLUGIN_PARAM_MAX 127 - -typedef unsigned char byte; - -enum { - SS_SYSEX_LOAD_SAMPLE = 0, // gui -> synth: tell synth to load sample - SS_SYSEX_INIT_DATA, // synth reinitialization, the position of this (1) in the enum must not be changed since this value is written into proj file - SS_SYSEX_LOAD_SAMPLE_OK, // synth -> gui: tell gui sample loaded OK - SS_SYSEX_LOAD_SAMPLE_ERROR, // synth -> gui: tell gui sample ! loaded OK - SS_SYSEX_CLEAR_SAMPLE, // gui -> synth: tell synth to clear sample - SS_SYSEX_CLEAR_SAMPLE_OK, // synth->gui: confirm sample cleared OK - SS_SYSEX_LOAD_SENDEFFECT, // gui -> synth: tell synth to load laspa-effect - SS_SYSEX_LOAD_SENDEFFECT_OK,// synth->gui: plugin loaded ok - SS_SYSEX_LOAD_SENDEFFECT_ERROR, // synth->gui: plugin _not_ loaded ok - SS_SYSEX_CLEAR_SENDEFFECT, // gui->synth: clear plugin - SS_SYSEX_CLEAR_SENDEFFECT_OK,// synth->gui: plugin cleared - SS_SYSEX_SET_PLUGIN_PARAMETER, //gui->synth: set plugin parameter - SS_SYSEX_SET_PLUGIN_PARAMETER_OK, // synth->gui: set plugin parameter (update gui) - SS_SYSEX_ERRORMSG, // synth -> gui: general error message from synth - SS_SYSEX_GET_INIT_DATA, // gui->synth: request init data - SS_SYSEX_SEND_INIT_DATA // synth->gui: give gui init data - }; - -extern int SS_samplerate; -extern float SS_map_pluginparam2logdomain(int pluginparam_val); -extern int SS_map_logdomain2pluginparam(float pluginparam_log); -#endif - diff --git a/muse2/synti/simpledrums/simpledrums.cpp b/muse2/synti/simpledrums/simpledrums.cpp deleted file mode 100644 index 22f83bd4..00000000 --- a/muse2/synti/simpledrums/simpledrums.cpp +++ /dev/null @@ -1,1766 +0,0 @@ -// -// C++ Implementation: simplesynth -// -// Description: -// -// -// Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 -// -// Copyright: See COPYING file that comes with this distribution -// -// - -#include "muse/midictrl.h" -#include "muse/midi.h" -//#include "libsynti/mpevent.h" -#include "muse/mpevent.h" -#include "simpledrums.h" -#include <qstring.h> -#include <samplerate.h> - -const char* SimpleSynth::synth_state_descr[] = - { - "SS_INITIALIZING", - "SS_LOADING_SAMPLE", - "SS_CLEARING_SAMPLE", - "SS_RUNNING" - }; - -const char* SimpleSynth::channel_state_descr[] = - { - "SS_CHANNEL_INACTIVE", - "SS_SAMPLE_PLAYING" - }; - -#define SWITCH_SYNTH_STATE(state)\ -synth_state = state; \ -if (SS_DEBUG_STATE) \ - fprintf (stderr, "SS STATE: %s\n", SimpleSynth::synth_state_descr[state]); - -#define SWITCH_CHAN_STATE(ch, s)\ -channels[ch].state = s; \ -if (SS_DEBUG_STATE) \ - fprintf (stderr, "SS CHAN %d STATE: %s\n", ch, SimpleSynth::channel_state_descr[s]); - -#define SS_CHANNEL_VOLUME_QUOT 100.0 -#define SS_MASTER_VOLUME_QUOT 100.0 -int SS_samplerate; - -#define SS_LOG_MAX 0 -#define SS_LOG_MIN -10 -#define SS_LOG_OFFSET SS_LOG_MIN - - -// -// Map plugin parameter on domain [SS_PLUGIN_PARAM_MIN, SS_PLUGIN_PARAM_MAX] to domain [SS_LOG_MIN, SS_LOG_MAX] (log domain) -// -float SS_map_pluginparam2logdomain(int pluginparam_val) - { - float scale = (float) (SS_LOG_MAX - SS_LOG_MIN)/ (float) SS_PLUGIN_PARAM_MAX; - float scaled = (float) pluginparam_val * scale; - float mapped = scaled + SS_LOG_OFFSET; - return mapped; - } -// -// Map plugin parameter on domain to domain [SS_LOG_MIN, SS_LOG_MAX] to [SS_PLUGIN_PARAM_MIN, SS_PLUGIN_PARAM_MAX] (from log-> [0,127]) -// (inverse func to the above) -int SS_map_logdomain2pluginparam(float pluginparam_log) - { - float mapped = pluginparam_log - SS_LOG_OFFSET; - float scale = (float) SS_PLUGIN_PARAM_MAX / (float) (SS_LOG_MAX - SS_LOG_MIN); - int scaled = (int) round(mapped * scale); - return scaled; - } - -//--------------------------------------------------------- -// SimpleSynth -//--------------------------------------------------------- -SimpleSynth::SimpleSynth(int sr) - : Mess(SS_AUDIO_CHANNELS) - { - SS_TRACE_IN - SS_samplerate = sr; - SS_initPlugins(); - - simplesynth_ptr = this; - master_vol = 100.0 / SS_MASTER_VOLUME_QUOT; - master_vol_ctrlval = 100; - - //initialize - for (int i=0; i<SS_NR_OF_CHANNELS; i++) { - channels[i].sample = 0; - channels[i].playoffset = 0; - channels[i].noteoff_ignore = false; - channels[i].volume = (double) (100.0/SS_CHANNEL_VOLUME_QUOT ); - channels[i].volume_ctrlval = 100; - channels[i].pan = 64; - channels[i].balanceFactorL = 1.0; - channels[i].balanceFactorR = 1.0; - SWITCH_CHAN_STATE(i, SS_CHANNEL_INACTIVE); - channels[i].channel_on = false; - for (int j=0; j<SS_NR_OF_SENDEFFECTS; j++) { - channels[i].sendfxlevel[j] = 0.0; - } - } - - //Process buffer: - processBuffer[0] = new double[SS_PROCESS_BUFFER_SIZE]; //left - processBuffer[1] = new double[SS_PROCESS_BUFFER_SIZE]; //right - - //Send effects - for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) { - sendFxLineOut[i][0] = new float[SS_SENDFX_BUFFER_SIZE]; //left out - sendFxLineOut[i][1] = new float[SS_SENDFX_BUFFER_SIZE]; //right out - sendFxReturn[i][0] = new float[SS_SENDFX_BUFFER_SIZE]; //left in - sendFxReturn[i][1] = new float[SS_SENDFX_BUFFER_SIZE]; //right in - } - - for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) { - sendEffects[i].state = SS_SENDFX_OFF; - sendEffects[i].plugin = 0; - sendEffects[i].retgain = 1.0; - sendEffects[i].retgain_ctrlval = 100; - sendEffects[i].nrofparameters = 0; - } - - //Build controller list: - controllers[0].name = "Master volume"; - controllers[0].num = CTRL_NRPN14_OFFSET; - controllers[0].min = 0; - controllers[0].max = 127; - - int i=1; - for (int ch=0; ch<SS_NR_OF_CHANNELS; ch++) { - QString c1 = "Channel " + QString::number(ch + 1) + " volume"; - QString c2 = "Channel " + QString::number(ch + 1) + " pan"; - QString c3 = "Channel " + QString::number(ch + 1) + " noteoff ignore"; - QString c4 = "Channel " + QString::number(ch + 1) + " on/off"; - QString c5 = "Channel " + QString::number(ch + 1) + " fx send 1"; - QString c6 = "Channel " + QString::number(ch + 1) + " fx send 2"; - QString c7 = "Channel " + QString::number(ch + 1) + " fx send 3"; - QString c8 = "Channel " + QString::number(ch + 1) + " fx send 4"; - controllers[i].name = c1.toLatin1(); - controllers[i].num = CTRL_NRPN14_OFFSET+i; - controllers[i].min = 0; - controllers[i].max = 127; - - controllers[i+1].name = c2.toLatin1(); - controllers[i+1].num = CTRL_NRPN14_OFFSET+i+1; - controllers[i+1].min = 0; - controllers[i+1].max = 127; - - controllers[i+2].name = c3.toLatin1(); - controllers[i+2].num = CTRL_NRPN14_OFFSET+i+2; - controllers[i+2].min = 0; - controllers[i+2].max = 1; - - controllers[i+3].name = c4.toLatin1(); - controllers[i+3].num = CTRL_NRPN14_OFFSET+i+3; - controllers[i+3].min = 0; - controllers[i+3].max = 1; - - controllers[i+4].name = c5.toLatin1(); - controllers[i+4].num = CTRL_NRPN14_OFFSET+i+4; - - controllers[i+5].name = c6.toLatin1(); - controllers[i+5].num = CTRL_NRPN14_OFFSET+i+5; - - controllers[i+6].name = c7.toLatin1(); - controllers[i+6].num = CTRL_NRPN14_OFFSET+i+6; - - controllers[i+7].name = c8.toLatin1(); - controllers[i+7].num = CTRL_NRPN14_OFFSET+i+7; - - controllers[i+4].min = controllers[i+5].min = controllers[i+6].min = controllers[i+7].min = 0; - controllers[i+4].max = controllers[i+5].max = controllers[i+6].max = controllers[i+7].max = 127; - - i+=8; - } - - for (int sfx=0; sfx<SS_NR_OF_SENDEFFECTS; sfx++) { - QString c1 = "Sendfx " + QString::number(sfx) + " ret gain"; - QString c2 = "Sendfx " + QString::number(sfx) + " on/off"; - controllers[i].name = c1.toLatin1(); - controllers[i].num = CTRL_NRPN14_OFFSET+i; - controllers[i].min = 0; - controllers[i].max = 127; - - controllers[i+1].name = c2.toLatin1(); - controllers[i+1].num = CTRL_NRPN14_OFFSET+i+1; - controllers[i+1].min = 0; - controllers[i+1].max = 1; - i+=2; - } - - pthread_mutex_init(&SS_LoaderMutex, NULL); - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// ~SimpleSynth -//--------------------------------------------------------- -SimpleSynth::~SimpleSynth() - { - SS_TRACE_IN - - // Cleanup channels and samples: - SS_DBG("Cleaning up sample data"); - for (int i=0; i<SS_NR_OF_CHANNELS; i++) { - if (channels[i].sample) { - delete[] channels[i].sample->data; - delete channels[i].sample; - } - } - simplesynth_ptr = NULL; - - SS_DBG("Deleting pluginlist"); - //Cleanup plugins: - for (iPlugin i = plugins.begin(); i != plugins.end(); ++i) { - delete (*i); - } - plugins.clear(); - - SS_DBG("Deleting sendfx buffers"); - //Delete sendfx buffers: - for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) { - delete[] sendFxLineOut[i][0]; - delete[] sendFxLineOut[i][1]; - delete[] sendFxReturn[i][0]; - delete[] sendFxReturn[i][1]; - } - - //processBuffer: - SS_DBG("Deleting process buffer"); - delete[] processBuffer[0]; - delete[] processBuffer[1]; - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// nativeGuiVisible -/*! - \fn SimpleSynth::nativeGuiVisible - \brief Tells if the gui is hidden or shown - \return true/false if gui is shown/hidden - */ -//--------------------------------------------------------- -bool SimpleSynth::nativeGuiVisible() const - { - SS_TRACE_IN - bool v = gui->isVisible(); - SS_TRACE_OUT - return v; - } - -//--------------------------------------------------------- -// hasNativeGui -/*! - \fn SimpleSynth::hasNativeGui - \brief Tells if the synth has a gui or not - \return true if synth has gui, false it synth has no gui - */ -//--------------------------------------------------------- -bool SimpleSynth::hasNativeGui() const - { - SS_TRACE_IN - SS_TRACE_OUT - return true; - } - -//--------------------------------------------------------- -// playNote -/*! - \fn SimpleSynth::playNote - \brief Triggers a note on (noteoffs are noteons with velo=0) - \param channel midi channel - \param pitch note pitch - \param velo note velocity - \return false for ok, true for not ok (not sure these are handled differently, but...) - */ -//--------------------------------------------------------- -bool SimpleSynth::playNote(int /*channel*/, int pitch, int velo) - { - SS_TRACE_IN - //Don't bother about channel, we're processing every playnote! - if ((pitch >= SS_LOWEST_NOTE) && (pitch <= SS_HIGHEST_NOTE)) { - bool noteOff = (velo == 0 ? 1 : 0); - int ch = pitch - SS_LOWEST_NOTE; - if(!noteOff) { - if (channels[ch].sample) { - //Turn on the white stuff: - channels[ch].playoffset = 0; - SWITCH_CHAN_STATE(ch , SS_SAMPLE_PLAYING); - channels[ch].cur_velo = (double) velo / 127.0; - channels[ch].gain_factor = channels[ch].cur_velo * channels[ch].volume; - if (SS_DEBUG_MIDI) { - printf("Playing note %d on channel %d\n", pitch, ch); - } - } - } - else { - //Note off: - if (channels[ch].noteoff_ignore) { - if (SS_DEBUG_MIDI) { - printf("Note off on channel %d\n", ch); - } - SWITCH_CHAN_STATE(ch , SS_CHANNEL_INACTIVE); - channels[ch].playoffset = 0; - channels[ch].cur_velo = 0; - } - } - } - SS_TRACE_OUT - return false; - } - -//--------------------------------------------------------- -// processEvent -/*! - \fn SimpleSynth::processEvent - \brief All events from sequencer first shows up here and are forwarded to their correct functions - \param event The event sent from sequencer - \return false for ok, true for not ok - */ -//--------------------------------------------------------- -bool SimpleSynth::processEvent(const MidiPlayEvent& ev) - { - SS_TRACE_IN - switch(ev.type()) { - case ME_CONTROLLER: - if (SS_DEBUG_MIDI) { - printf("SimpleSynth::processEvent - Controller. Chan: %x dataA: %x dataB: %x\n", ev.channel(), ev.dataA(), ev.dataB()); - for (int i=0; i< ev.len(); i++) - printf("%x ", ev.data()[i]); - } - setController(ev.channel(), ev.dataA(), ev.dataB(), false); - return true; - case ME_NOTEON: - return playNote(ev.channel(), ev.dataA(), ev.dataB()); - case ME_NOTEOFF: - return playNote(ev.channel(), ev.dataA(), 0); - case ME_SYSEX: - //Debug print - if (SS_DEBUG_MIDI) { - printf("SimpleSynth::processEvent - Sysex received\n"); - for (int i=0; i< ev.len(); i++) - printf("%x ", ev.data()[i]); - printf("\n"); - } - return sysex(ev.len(), ev.data()); - } - return false; - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// setController -/*! - \fn SimpleSynth::setController - \brief Called from sequencer indirectly via SimpleSynth::processEvent - \brief when the synth is supposed to set a controller value - \param channel channel nr - \param id controller id - \param val value of controller - \return false for ok, true for not ok - */ -//--------------------------------------------------------- -bool SimpleSynth::setController(int channel, int id, int val) - { - SS_TRACE_IN - if (SS_DEBUG_MIDI) { - printf("SimpleSynth::setController - received controller on channel %d, id %d value %d\n", channel, id, val); - } - - // Channel controllers: - if (id >= SS_FIRST_CHANNEL_CONTROLLER && id <= SS_LAST_CHANNEL_CONTROLLER ) { - // Find out which channel we're dealing with: - id-= SS_FIRST_CHANNEL_CONTROLLER; - int ch = (id / SS_NR_OF_CHANNEL_CONTROLLERS); - id = (id % SS_NR_OF_CHANNEL_CONTROLLERS); - - switch (id) { - case SS_CHANNEL_CTRL_VOLUME: - if (SS_DEBUG_MIDI) - printf("Received channel ctrl volume %d for channel %d\n", val, ch); - channels[ch].volume_ctrlval = val; - updateVolume(ch, val); - break; - case SS_CHANNEL_CTRL_NOFF: - if (SS_DEBUG_MIDI) - printf("Received ctrl noff %d for channel %d\n", val, ch); - channels[ch].noteoff_ignore = val; - break; - case SS_CHANNEL_CTRL_PAN: - { - if (SS_DEBUG_MIDI) - printf("Received ctrl pan %d for channel %d\n", val, ch); - channels[ch].pan = val; - updateBalance(ch, val); - break; - } - case SS_CHANNEL_CTRL_ONOFF: - { - if (SS_DEBUG_MIDI) - printf("Received ctrl onoff %d for channel %d\n", val, ch); - - if (val == false && channels[ch].channel_on == true) { - SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE); - channels[ch].channel_on = val; - } - else if (val == true && channels[ch].channel_on == false) { // if it actually _was_ off: - SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE); - channels[ch].playoffset = 0; - channels[ch].channel_on = val; - } - break; - } - case SS_CHANNEL_SENDFX1: - case SS_CHANNEL_SENDFX2: - case SS_CHANNEL_SENDFX3: - case SS_CHANNEL_SENDFX4: - { - int fxid = id - SS_CHANNEL_SENDFX1; - channels[ch].sendfxlevel[fxid] = (double)val/127.0; - break; - } - - default: - if (SS_DEBUG_MIDI) - printf("Unknown controller received for channel %d. id=%d\n", ch, id); - break; - } - } - // Master controllers: - else if (id >= SS_FIRST_MASTER_CONTROLLER && id <= SS_LAST_MASTER_CONTROLLER) { - if (SS_DEBUG_MIDI) - printf("Mastervol controller received: %d\n", id); - master_vol_ctrlval = val; - master_vol = (double) master_vol_ctrlval / SS_MASTER_VOLUME_QUOT; - } - // Emmm, this one should've been there in the beginning - else if (id == CTRL_VOLUME) { - if (SS_DEBUG_MIDI) { - printf("Ctrl volume received: vol: %d\n", val); - } - master_vol_ctrlval = val; - master_vol = (double) master_vol_ctrlval / SS_MASTER_VOLUME_QUOT; - //This one can't be from the gui, update gui: - guiUpdateMasterVol(val); - } - // Plugin controllers: - else if (id >= SS_FIRST_PLUGIN_CONTROLLER && id <= SS_LAST_PLUGIN_CONTROLLER) { - - int fxid = (id - SS_FIRST_PLUGIN_CONTROLLER) / SS_NR_OF_PLUGIN_CONTROLLERS; - int cmd = (id - SS_FIRST_PLUGIN_CONTROLLER) % SS_NR_OF_PLUGIN_CONTROLLERS; - - // Plugin return-gain: - if (cmd == SS_PLUGIN_RETURN) { - if (SS_DEBUG_MIDI) - printf("Ctrl fx retgain received: fxid: %d val: %d\n", fxid, val); - sendEffects[fxid].retgain_ctrlval = val; - sendEffects[fxid].retgain = (double) val / 75.0; - } - // Plugin on/off: - else if (cmd == SS_PLUGIN_ONOFF) { - if (SS_DEBUG_MIDI) - printf("Ctrl fx onoff received: fxid: %d val: %d\n", fxid, val); - sendEffects[fxid].state = (SS_SendFXState) val; - } - } - else { - if (SS_DEBUG_MIDI) - printf("Unknown controller received: %d\n", id); - } - SS_TRACE_OUT - return false; - } - -//--------------------------------------------------------- -/*! - \fn SimpleSynth::setController - */ -//--------------------------------------------------------- -bool SimpleSynth::setController(int channel, int id, int val, bool /*fromGui*/) - { - SS_TRACE_IN - bool ret = setController(channel, id, val); //Perhaps TODO... Separate events from the gui - SS_TRACE_OUT - return ret; - } -//--------------------------------------------------------- -// sysex -/*! - \fn SimpleSynth::sysex - \brief Called from sequencer indirectly via SimpleSynth::processEvent - \param len length of the sysex data - \param data the sysex data - \return false for ok, true for not ok -*/ -//--------------------------------------------------------- -bool SimpleSynth::sysex(int /*len*/, const unsigned char* data) - { - SS_TRACE_IN - int cmd = data[0]; - switch (cmd) { - case SS_SYSEX_LOAD_SAMPLE: - { - int channel = data[1]; - //int l = data[2]; - const char* filename = (const char*)(data+3); - if (SS_DEBUG_MIDI) { - printf("Sysex cmd: load sample, filename %s, on channel: %d\n", filename, channel); - } - loadSample(channel, filename); - break; - } - case SS_SYSEX_CLEAR_SAMPLE: - { - int ch = data[1]; - clearSample(ch); - break; - } - - case SS_SYSEX_INIT_DATA: - { - parseInitData(data); - break; - } - - case SS_SYSEX_LOAD_SENDEFFECT: - { - int fxid = data[1]; - QString lib = (const char*) (data + 2); - QString label = (const char*) (data + lib.length() + 3); - if (SS_DEBUG_MIDI) { - printf("Sysex cmd load effect: %d %s %s\n", fxid, lib.toLatin1(), label.toLatin1()); - } - initSendEffect(fxid, lib, label); - break; - } - - case SS_SYSEX_CLEAR_SENDEFFECT: - { - int fxid = data[1]; - if (SS_DEBUG_MIDI) { - printf("Sysex cmd clear effect: %d\n", fxid); - } - sendEffects[fxid].state = SS_SENDFX_OFF; - cleanupPlugin(fxid); - sendEffects[fxid].plugin = 0; - break; - } - - case SS_SYSEX_SET_PLUGIN_PARAMETER: - { - int fxid = data[1]; - int parameter = data[2]; - int val = data[3]; - // Write it to the plugin: - float floatval = sendEffects[fxid].plugin->convertGuiControlValue(parameter, val); - setFxParameter(fxid, parameter, floatval); - break; - } - - case SS_SYSEX_GET_INIT_DATA: - { - int initdata_len = 0; - const byte* tmp_initdata = NULL; - byte* event_data = NULL; - - getInitData(&initdata_len, &tmp_initdata); - int totlen = initdata_len + 1; - - event_data = new byte[initdata_len + 1]; - event_data[0] = SS_SYSEX_SEND_INIT_DATA; - memcpy(event_data + 1, tmp_initdata, initdata_len); - delete[] tmp_initdata; - tmp_initdata = NULL; - - MidiPlayEvent ev(0, 0, ME_SYSEX, event_data, totlen); - gui->writeEvent(ev); - delete[] event_data; - - break; - } - - default: - if (SS_DEBUG_MIDI) - printf("Unknown sysex cmd received: %d\n", cmd); - break; - } - SS_TRACE_OUT - return false; - } - -//--------------------------------------------------------- -// getPatchName -/*! - \fn SimpleSynth::getPatchName - \brief Called from host to get names of patches - \param index - which patchnr we're about to deliver - \param drum - is it a drum track? - \return const char* with patchname - */ -//--------------------------------------------------------- -const char* SimpleSynth::getPatchName(int /*index*/, int, int, bool /*drum*/) const - { - SS_TRACE_IN - SS_TRACE_OUT - //return 0; - //return "<unknown>"; - return "SimpleSynth"; - } - -//--------------------------------------------------------- -// getPatchInfo -/*! - \fn SimpleSynth::getPatchInfo - \brief Called from host to get info about patches - \param index - which patchnr we're about to deliver - \param patch - if this one is 0, this is the first call, otherwise keep deliver the host patches... or something - \return MidiPatch with patch info for host - */ -//--------------------------------------------------------- -const MidiPatch* SimpleSynth::getPatchInfo(int index, const MidiPatch* patch) const - { - SS_TRACE_IN - index = 0; patch = 0; - SS_TRACE_OUT - return 0; - } - -//--------------------------------------------------------- -// getControllerInfo -/*! - \fn SimpleSynth::getControllerInfo - \brief Called from host to collect info about which controllers the synth supports - \param index current controller number - \param name pointer where name is stored - \param controller int pointer where muse controller number is stored - \param min int pointer where controller min value is stored - \param max int pointer where controller max value is stored - \return 0 when done, otherwise return next desired controller index - */ -//--------------------------------------------------------- -int SimpleSynth::getControllerInfo(int index, const char** name, int* controller, int* min, int* max, int* /*initval*/ ) const - { - SS_TRACE_IN - if (index >= SS_NR_OF_CONTROLLERS) { - SS_TRACE_OUT - return 0; - } - - *name = controllers[index].name.c_str(); - *controller = controllers[index].num; - *min = controllers[index].min; - *max = controllers[index].max; - - if (SS_DEBUG_MIDI) { - printf("setting controller info: index %d name %s controller %d min %d max %d\n", index, *name, *controller, *min, *max); - } - SS_TRACE_OUT - return (index +1); - } - -//--------------------------------------------------------- -// processMessages -/*! - \fn SimpleSynth::processMessages - \brief Called from host always, even if output path is unconnected - */ -//--------------------------------------------------------- -void SimpleSynth::processMessages() -{ - //Process messages from the gui - while (gui->fifoSize()) - { - MidiPlayEvent ev = gui->readEvent(); - if (ev.type() == ME_SYSEX) - { - sysex(ev.len(), ev.data()); - sendEvent(ev); - } - else if (ev.type() == ME_CONTROLLER) - { - setController(ev.channel(), ev.dataA(), ev.dataB(), true); - sendEvent(ev); - } - else - { - if(SS_DEBUG) - printf("SimpleSynth::process(): unknown event, type: %d\n", ev.type()); - } - } -} - -//--------------------------------------------------------- -// process -/*! - \fn SimpleSynth::process - \brief Realtime function where the processing actually occurs. Called from host, ONLY if output path is connected. - \param channels - audio data - \param offset - sample offset - \param len - nr of samples to process - */ -//--------------------------------------------------------- -void SimpleSynth::process(float** out, int offset, int len) - { - /* - //Process messages from the gui - while (gui->fifoSize()) { - MidiPlayEvent ev = gui->readEvent(); - if (ev.type() == ME_SYSEX) { - sysex(ev.len(), ev.data()); - sendEvent(ev); - } - else if (ev.type() == ME_CONTROLLER) { - setController(ev.channel(), ev.dataA(), ev.dataB(), true); - sendEvent(ev); - } - else { - if (SS_DEBUG) - printf("SimpleSynth::process(): unknown event, type: %d\n", ev.type()); - } - } - */ - - if (synth_state == SS_RUNNING) { - - //Temporary mix-doubles - double out1, out2; - //double ltemp, rtemp; - float* data; - // Velocity factor: - double gain_factor; - - - // Clear send-channels. Skips if fx not turned on - for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) { - if (sendEffects[i].state == SS_SENDFX_ON) { - memset(sendFxLineOut[i][0], 0, SS_SENDFX_BUFFER_SIZE * sizeof(float)); - memset(sendFxLineOut[i][1], 0, SS_SENDFX_BUFFER_SIZE * sizeof(float)); - } - } - - - memset(out[0] + offset, 0, len * sizeof(float)); - memset(out[1] + offset, 0, len * sizeof(float)); - - //Process 1 channel at a time - for (int ch=0; ch < SS_NR_OF_CHANNELS; ch++) { - // If channels is turned off, skip: - if (channels[ch].channel_on == false) - continue; - - //If sample isn't playing, skip: - if (channels[ch].state == SS_SAMPLE_PLAYING) { - memset(processBuffer[0], 0, SS_PROCESS_BUFFER_SIZE * sizeof(double)); - memset(processBuffer[1], 0, SS_PROCESS_BUFFER_SIZE * sizeof(double)); - - for (int i=0; i<len; i++) { - // Current channel sample data: - data = channels[ch].sample->data; - gain_factor = channels[ch].gain_factor; - // Current velocity factor: - - if (channels[ch].sample->channels == 2) { - // - // Stereo sample: - // - // Add from sample: - out1 = (double) (data[channels[ch].playoffset] * gain_factor * channels[ch].balanceFactorL); - out2 = (double) (data[channels[ch].playoffset + 1] * gain_factor * channels[ch].balanceFactorR); - channels[ch].playoffset += 2; - } - else { - // - // Mono sample: - // - out1 = (double) (data[channels[ch].playoffset] * gain_factor * channels[ch].balanceFactorL); - out2 = (double) (data[channels[ch].playoffset] * gain_factor * channels[ch].balanceFactorR); - channels[ch].playoffset++; - } - - processBuffer[0][i] = out1; - processBuffer[1][i] = out2; - - // If send-effects tap is on, tap signal to respective lineout channel - for (int j=0; j<SS_NR_OF_SENDEFFECTS; j++) { - if (channels[ch].sendfxlevel[j] != 0.0) { - //If the effect has 2 inputs (stereo in): - if (sendEffects[j].inputs == 2) { - sendFxLineOut[j][0][i]+= (out1 * channels[ch].sendfxlevel[j]); - sendFxLineOut[j][1][i]+= (out2 * channels[ch].sendfxlevel[j]); - } - //If the effect is mono (1 input), only use first fxLineOut - else if (sendEffects[j].inputs == 1) { - sendFxLineOut[j][0][i]+= ((out1 + out2) * channels[ch].sendfxlevel[j] / 2.0); - } - //Effects with 0 or >2 inputs are ignored - } - } - - // - // If we've reached the last sample, set state to inactive - // - if (channels[ch].playoffset >= channels[ch].sample->samples) { - SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE); - channels[ch].playoffset = 0; - break; - } - } - // Add contribution for this channel, for this frame, to final result: - for (int i=0; i<len; i++) { - out[0][i+offset]+=processBuffer[0][i]; - out[1][i+offset]+=processBuffer[1][i]; - } - } - } - // Do something funny with the sendies: - for (int j=0; j<SS_NR_OF_SENDEFFECTS; j++) { - if (sendEffects[j].state == SS_SENDFX_ON) { - sendEffects[j].plugin->process(len); - for (int i=0; i<len; i++) { - //Effect has mono output: - if (sendEffects[j].outputs == 1) { - //Add the result to both channels: - out[0][i+offset]+=((sendEffects[j].retgain * sendFxReturn[j][0][i]) / 2.0); - out[1][i+offset]+=((sendEffects[j].retgain * sendFxReturn[j][0][i]) / 2.0); - } - else if (sendEffects[j].outputs == 2) { - // Effect has stereo output - out[0][i+offset]+=(sendEffects[j].retgain * sendFxReturn[j][0][i]); - out[1][i+offset]+=(sendEffects[j].retgain * sendFxReturn[j][1][i]); - } - } - } - } - // Finally master gain: - for (int i=0; i<len; i++) { - out[0][i+offset] = (out[0][i+offset] * master_vol); - out[1][i+offset] = (out[1][i+offset] * master_vol); - } - } - } - -//--------------------------------------------------------- -// showNativeGui -/*! - \fn SimpleSynth::showNativeGui - \brief Displays or hides the gui window - \param val true or false = gui shown or hidden - */ -//--------------------------------------------------------- -void SimpleSynth::showNativeGui(bool val) - { - SS_TRACE_IN - gui->setVisible(val); - SS_TRACE_OUT - } - -//--------------------------------------------------------- -/*! - \fn SimpleSynth::init - \brief Initializes the SimpleSynth - \param name string set to caption in the gui dialog - \return true if successful, false if unsuccessful - */ -//--------------------------------------------------------- -bool SimpleSynth::init(const char* name) - { - SS_TRACE_IN - SWITCH_SYNTH_STATE(SS_INITIALIZING); - gui = new SimpleSynthGui(); - gui->show(); - gui->setCaption(name); - SWITCH_SYNTH_STATE(SS_RUNNING); - SS_TRACE_OUT - return true; - } - -//--------------------------------------------------------- -/*! - \fn SimpleSynth::getInitData - \brief Data for reinitialization of SimpleSynth when loading project - \param n - number of chars used in the data - \param data - data that is sent as a sysex to the synth on reload of project - */ -//--------------------------------------------------------- -void SimpleSynth::getInitData(int* n, const unsigned char** data) const - { - SS_TRACE_IN - // Calculate length of data - // For each channel, we need to store volume, pan, noff, onoff - int len = SS_NR_OF_CHANNEL_CONTROLLERS * SS_NR_OF_CHANNELS; - // Sampledata: filenames len - for (int i=0; i<SS_NR_OF_CHANNELS; i++) { - if (channels[i].sample) { - int filenamelen = strlen(channels[i].sample->filename.c_str()) + 2; - len+=filenamelen; - } - else - len++; //Add place for SS_NO_SAMPLE - } - len+=3; // 1 place for SS_SYSEX_INIT_DATA, 1 byte for master vol, 1 byte for version data - - // Effect data length - len++; //Add place for SS_SYSEX_INIT_DATA_VERSION, as control - - for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) { - Plugin* plugin = sendEffects[i].plugin; - if (plugin) { - int namelen = strlen(plugin->lib()) + 2; - int labelnamelen = strlen(plugin->label()) + 2; - len+=(namelen + labelnamelen); - - len+=3; //1 byte for nr of parameters, 1 byte for return gain, 1 byte for effect on/off - len+=sendEffects[i].nrofparameters; // 1 byte for each parameter value - } - else { - len++; //place for SS_NO_PLUGIN - } - } - - // First, SS_SYSEX_INIT_DATA - byte* buffer = new byte[len]; - memset(buffer, 0, len); - buffer[0] = SS_SYSEX_INIT_DATA; - buffer[1] = SS_SYSEX_INIT_DATA_VERSION; - if (SS_DEBUG_INIT) { - printf("Length of init data: %d\n", len); - printf("buffer[0] - SS_SYSEX_INIT_DATA: %d\n", SS_SYSEX_INIT_DATA); - printf("buffer[1] - SS_SYSEX_INIT_DATA_VERSION: %d\n", SS_SYSEX_INIT_DATA_VERSION); - } - int i = 2; - // All channels: - // 0 - volume ctrlval (0-127) - // 1 - pan (0-127) - // 2 - noff ignore (0-1) - // 3 - channel on/off (0-1) - // 4 - 7 - sendfx 1-4 (0-127) - // 8 - len of filename, n - // 9 - 9+n - filename - for (int ch=0; ch<SS_NR_OF_CHANNELS; ch++) { - buffer[i] = (byte) channels[ch].volume_ctrlval; - buffer[i+1] = (byte) channels[ch].pan; - buffer[i+2] = (byte) channels[ch].noteoff_ignore; - buffer[i+3] = (byte) channels[ch].channel_on; - buffer[i+4] = (byte) round(channels[ch].sendfxlevel[0] * 127.0); - buffer[i+5] = (byte) round(channels[ch].sendfxlevel[1] * 127.0); - buffer[i+6] = (byte) round(channels[ch].sendfxlevel[2] * 127.0); - buffer[i+7] = (byte) round(channels[ch].sendfxlevel[3] * 127.0); - - if (SS_DEBUG_INIT) { - printf("Channel %d:\n", ch); - printf("buffer[%d] - channels[ch].volume_ctrlval = \t%d\n", i, channels[ch].volume_ctrlval); - printf("buffer[%d] - channels[ch].pan = \t\t%d\n", i+1, channels[ch].pan); - printf("buffer[%d] - channels[ch].noteoff_ignore = \t%d\n", i+2, channels[ch].noteoff_ignore ); - printf("buffer[%d] - channels[ch].channel_on = \t%d\n", i+3, channels[ch].channel_on); - for (int j= i+4; j < i+8; j++) { - printf("buffer[%d] - channels[ch].sendfxlevel[%d]= \t%d\n", j, j-i-4, (int)round(channels[ch].sendfxlevel[j-i-4] * 127.0)); - } - } - if (channels[ch].sample) { - int filenamelen = strlen(channels[ch].sample->filename.c_str()) + 1; - buffer[i+8] = (byte) filenamelen; - memcpy((buffer+(i+9)), channels[ch].sample->filename.c_str(), filenamelen); - if (SS_DEBUG_INIT) { - printf("buffer[%d] - filenamelen: %d\n", i+8, filenamelen); - printf("buffer[%d] - buffer[%d] - filename: ", (i+9), (i+9) + filenamelen - 1); - for (int j = i+9; j< i+9+filenamelen; j++) { - printf("%c",buffer[j]); - } - printf("\n"); - } - i+= (SS_NR_OF_CHANNEL_CONTROLLERS + 1 + filenamelen); - } - else { - buffer[i+8] = SS_NO_SAMPLE; - if (SS_DEBUG_INIT) { - printf("buffer[%d]: SS_NO_SAMPLE: - %d\n", i+8, SS_NO_SAMPLE); - } - i+= (SS_NR_OF_CHANNEL_CONTROLLERS + 1); - } - } - if (SS_DEBUG_INIT) { - printf("buffer[%d]: Master vol: - %d\n", i, master_vol_ctrlval); - } - buffer[i] = master_vol_ctrlval; - *(data) = buffer; *n = len; - i++; - - //Send effects: - buffer[i] = SS_SYSEX_INIT_DATA_VERSION; //Just for check - if (SS_DEBUG_INIT) { - printf("buffer[%d]: Control value, SS_SYSEX_INIT_DATA_VERSION\n", i); - } - i++; - - for (int j=0; j<SS_NR_OF_SENDEFFECTS; j++) { - if (sendEffects[j].plugin) { - int labelnamelen = strlen(sendEffects[j].plugin->label()) + 1; - buffer[i] = labelnamelen; - memcpy((buffer+i+1), sendEffects[j].plugin->label(), labelnamelen); - if (SS_DEBUG_INIT) { - printf("buffer[%d] - labelnamelen: %d\n", i, labelnamelen); - printf("buffer[%d] - buffer[%d] - filename: ", (i+1), (i+1) + labelnamelen - 1); - for (int k = i+1; k < i+1+labelnamelen; k++) { - printf("%c",buffer[k]); - } - printf("\n"); - } - - i+=(labelnamelen + 1); - - int namelen = strlen(sendEffects[j].plugin->lib()) + 1; - buffer[i] = namelen; - memcpy((buffer+i+1), sendEffects[j].plugin->lib(), namelen); - if (SS_DEBUG_INIT) { - printf("buffer[%d] - libnamelen : %d\n", i, namelen); - printf("buffer[%d] - buffer[%d] - filename: ", (i+1), (i+1) + namelen - 1); - for (int k = i+1; k < i+1+namelen; k++) { - printf("%c",buffer[k]); - } - printf("\n"); - } - - i+=(namelen + 1); - - buffer[i]=sendEffects[j].nrofparameters; - if (SS_DEBUG_INIT) { - printf("buffer[%d]: sendEffects[%d].nrofparameters=%d\n", i, j, buffer[i]); - } - i++; - - buffer[i]=sendEffects[j].retgain_ctrlval; - if (SS_DEBUG_INIT) { - printf("buffer[%d]: sendEffects[%d].retgain_ctrlval=%d\n", i, j, buffer[i]); - } - i++; - - for (int k=0; k<sendEffects[j].nrofparameters; k++) { - //TODO: Convert to 127-scale - buffer[i] = sendEffects[j].plugin->getGuiControlValue(k); - if (SS_DEBUG_INIT) { - printf("buffer[%d]: sendEffects[%d].parameterval[%d]=%d\n", i, j, k, buffer[i]); - } - i++; - } - } - // No plugin loaded: - else { - buffer[i] = SS_NO_PLUGIN; - if (SS_DEBUG_INIT) { - printf("buffer[%d]: SS_NO_PLUGIN\n", i); - } - i++; - } - } - - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::parseInitData() - */ -void SimpleSynth::parseInitData(const unsigned char* data) - { - SS_TRACE_IN - //int len = strlen((const char*)data); - if (SS_DEBUG_INIT) { - printf("buffer[1], SS_SYSEX_INIT_DATA_VERSION=%d\n", *(data+1)); - } - const byte* ptr = data+2; - for (int ch=0; ch<SS_NR_OF_CHANNELS; ch++) { - channels[ch].volume_ctrlval = (byte) *(ptr); - - if (SS_DEBUG_INIT) { - printf("Channel %d:\n", ch); - printf("buffer[%zd] - channels[ch].volume_ctrlval = \t%d\n", ptr-data, *ptr); - printf("buffer[%zd] - channels[ch].pan = \t\t%d\n", ptr-data+1, *(ptr+1)); - printf("buffer[%zd] - channels[ch].noteoff_ignore = \t%d\n", ptr-data+2, *(ptr+2)); - printf("buffer[%zd] - channels[ch].channel_on = \t%d\n", ptr-data+3, *(ptr+3)); - } - updateVolume(ch, *(ptr)); - guiUpdateVolume(ch, *(ptr)); - - channels[ch].pan = *(ptr+1); - updateBalance(ch, *(ptr+1)); - guiUpdateBalance(ch, *(ptr+1)); - - channels[ch].noteoff_ignore = *(ptr+2); - guiUpdateNoff(ch, *(ptr+2)); - - channels[ch].channel_on = *(ptr+3); - guiUpdateChoff(ch, *(ptr+3)); - - ptr+=4; - - for (int i=0; i<4; i++) { - channels[ch].sendfxlevel[i] = (float) (*(ptr)/127.0); - guiUpdateSendFxLevel(ch, i, *(ptr)); - ptr++; - } - - bool hasSample = *(ptr); - ptr++; - - channels[ch].sample = 0; - channels[ch].playoffset = 0; - SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE); - if (SS_DEBUG_INIT) { - printf("parseInitData: channel %d, volume: %f pan: %d bfL %f bfR %f chON %d s1: %f s2: %f s3: %f s4: %f\n", - ch, - channels[ch].volume, - channels[ch].pan, - channels[ch].balanceFactorL, - channels[ch].balanceFactorR, - channels[ch].channel_on, - channels[ch].sendfxlevel[0], - channels[ch].sendfxlevel[1], - channels[ch].sendfxlevel[2], - channels[ch].sendfxlevel[3] - ); - } - if (hasSample) { - std::string filenametmp = (const char*) ptr; - ptr+= strlen(filenametmp.c_str()) + 1; - //printf("We should load %s\n", filenametmp.c_str()); - loadSample(ch, filenametmp.c_str()); - } - else { - //Clear sample - clearSample(ch); - guiNotifySampleCleared(ch); - } - } - //Master vol: - master_vol_ctrlval = *(ptr); - master_vol = (double) master_vol_ctrlval / SS_MASTER_VOLUME_QUOT; - guiUpdateMasterVol(master_vol_ctrlval); - if (SS_DEBUG_INIT) { - printf("Master vol: %d\n", master_vol_ctrlval); - } - ptr++; - - // Effects: - if (*(ptr) != SS_SYSEX_INIT_DATA_VERSION) { - fprintf(stderr, "Error loading init data - control byte not found. Skipping...\n"); - SS_TRACE_OUT - return; - } - ptr++; - - for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) { - if (SS_DEBUG_INIT) - printf("buffer[%zd] - sendeffect[%d], labelnamelen=%d\n", ptr-data, i, *ptr); - int labelnamelen = *(ptr); - - if (labelnamelen != SS_NO_PLUGIN) { - ptr++; - std::string labelnametmp = (const char*) ptr; - ptr+= labelnamelen; - - //int libnamelen = *(ptr); - ptr++; - std::string libnametmp = (const char*) ptr; - ptr+= strlen(libnametmp.c_str()) + 1; - - - initSendEffect(i, libnametmp.c_str(), labelnametmp.c_str()); - //initSendEffect(0, "cmt", "freeverb3"); - - byte params = *(ptr); - byte retgain = *(ptr+1); - ptr+=2; - - sendEffects[i].nrofparameters = params; - - sendEffects[i].retgain_ctrlval = retgain; - sendEffects[i].retgain = retgain; - sendEffects[i].retgain = (double) retgain/ 75.0; - MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_PLUGIN_RETURNLEVEL_CONTROLLER(i), retgain); - gui->writeEvent(ev); - - for (int j=0; j<params; j++) { - if (SS_DEBUG_INIT) - printf("buffer[%zd] - sendeffect[%d], parameter[%d]=%d\n", ptr-data, i, j, *ptr); - setFxParameter(i, j, sendEffects[i].plugin->convertGuiControlValue(j, *(ptr))); - ptr++; - } - } - else { - if (sendEffects[i].plugin) - cleanupPlugin(i); - ptr++; - } - } - - SS_TRACE_OUT - } - -/*! - \fn SimpleSynth::loadSample(int chno, const char* filename) - */ -bool SimpleSynth::loadSample(int chno, const char* filename) - { - SS_TRACE_IN - SS_Channel* ch = &channels[chno]; - - // Thread stuff: - SS_SampleLoader* loader = new SS_SampleLoader; - loader->channel = ch; - loader->filename = std::string(filename); - loader->ch_no = chno; - if (SS_DEBUG) { - printf("Loader filename is: %s\n", filename); - } - pthread_t sampleThread; - pthread_attr_t* attributes = (pthread_attr_t*) malloc(sizeof(pthread_attr_t)); - pthread_attr_init(attributes); - pthread_attr_setdetachstate(attributes, PTHREAD_CREATE_DETACHED); - if (pthread_create(&sampleThread, attributes, ::loadSampleThread, (void*) loader)) { - perror("creating thread failed:"); - pthread_attr_destroy(attributes); - delete loader; - return false; - } - - pthread_attr_destroy(attributes); - SS_TRACE_OUT - return true; - } - -/*! - \fn loadSampleThread(void* p) - \brief Since process needs to respond withing a certain time, loading of samples need to be done in a separate thread - */ -static void* loadSampleThread(void* p) - { - SS_TRACE_IN - pthread_mutex_lock(&SS_LoaderMutex); - - // Crit section: - SS_State prevState = synth_state; - SWITCH_SYNTH_STATE(SS_LOADING_SAMPLE); - SS_SampleLoader* loader = (SS_SampleLoader*) p; - SS_Channel* ch = loader->channel; - int ch_no = loader->ch_no; - - if (ch->sample) { - delete[] ch->sample->data; - delete ch->sample; - } - ch->sample = new SS_Sample; - SS_Sample* smp = ch->sample; - - SNDFILE* sf; - const char* filename = loader->filename.c_str(); - SF_INFO sfi; - - if (SS_DEBUG) - printf("loadSampleThread: filename = %s\n", filename); - - sf = sf_open(filename, SFM_READ, &sfi); - if (sf == 0) { - fprintf(stderr,"Error opening file: %s\n", filename); - SWITCH_SYNTH_STATE(prevState); - simplesynth_ptr->guiSendSampleLoaded(false, loader->ch_no, filename); - delete ch->sample; ch->sample = 0; - delete loader; - pthread_mutex_unlock(&SS_LoaderMutex); - SS_TRACE_OUT - pthread_exit(0); - } - - //Print some info: - if (SS_DEBUG) { - printf("Sample info:\n"); - printf("Frames: \t%ld\n", (long) sfi.frames); - printf("Channels: \t%d\n", sfi.channels); - printf("Samplerate: \t%d\n", sfi.samplerate); - } - - // - // Allocate and read the thingie - // - - // If current samplerate is the same as MusE's: - if (SS_samplerate == sfi.samplerate) { - smp->data = new float[sfi.channels * sfi.frames]; - sf_count_t n = sf_readf_float(sf, smp->data, sfi.frames); - smp->frames = sfi.frames; - smp->samples = (n * sfi.channels); - smp->channels = sfi.channels; - if (SS_DEBUG) { - printf("%ld frames read\n", (long) n); - } - } - else // otherwise, resample: - { - smp->channels = sfi.channels; - // Get new nr of frames: - double srcratio = (double) SS_samplerate/ (double) sfi.samplerate; - smp->frames = (long) floor(((double) sfi.frames * srcratio)); - smp->frames = (sfi.channels == 1 ? smp->frames * 2 : smp->frames ); // Double nr of new frames if mono->stereo - smp->samples = smp->frames * smp->channels; - - if (SS_DEBUG) { - printf("Resampling from %ld frames to %ld frames - srcration: %lf\n", (long) sfi.frames, smp->frames, srcratio); - printf("Nr of new samples: %ld\n", smp->samples); - } - - // Read to temporary: - float temp[sfi.frames * sfi.channels]; - int frames_read = sf_readf_float(sf, temp, sfi.frames); - if (frames_read != sfi.frames) { - fprintf(stderr,"Error reading sample %s\n", filename); - simplesynth_ptr->guiSendSampleLoaded(false, loader->ch_no, filename); - sf_close(sf); - SWITCH_SYNTH_STATE(prevState); - delete ch->sample; ch->sample = 0; - delete loader; - pthread_mutex_unlock(&SS_LoaderMutex); - pthread_exit(0); - SS_TRACE_OUT - } - - // Allocate mem for the new one - smp->data = new float[smp->frames * smp->channels]; - memset(smp->data, 0, sizeof(float)* smp->frames * smp->channels); - - // libsamplerate & co (secret rabbits in the code!) - SRC_DATA srcdata; - srcdata.data_in = temp; - srcdata.data_out = smp->data; - srcdata.input_frames = sfi.frames; - srcdata.output_frames = smp->frames; - srcdata.src_ratio = (double) SS_samplerate / (double) sfi.samplerate; - - if (SS_DEBUG) { - printf("Converting sample....\n"); - } - - if (src_simple(&srcdata, SRC_SINC_BEST_QUALITY, sfi.channels)) { - SS_ERROR("Error when resampling, ignoring current sample"); - //TODO: deallocate and stuff - } - else if (SS_DEBUG) { - printf("Sample converted. %ld input frames used, %ld output frames generated\n", - srcdata.input_frames_used, - srcdata.output_frames_gen); - } - } - //Just close the dam thing - sf_close(sf); - SWITCH_SYNTH_STATE(prevState); - ch->sample->filename = loader->filename; - simplesynth_ptr->guiSendSampleLoaded(true, ch_no, filename); - delete loader; - pthread_mutex_unlock(&SS_LoaderMutex); - SS_TRACE_OUT - pthread_exit(0); - } - -QString *projPathPtr; - -static Mess* instantiate(int sr, QWidget*, QString* projectPathPtr, const char* name) - { - projPathPtr = projectPathPtr; - printf("SimpleSynth sampleRate %d\n", sr); - SimpleSynth* synth = new SimpleSynth(sr); - if (!synth->init(name)) { - delete synth; - synth = 0; - } - return synth; - } - - -/*! - \fn SimpleSynth::updateBalance(int pan) - */ -void SimpleSynth::updateBalance(int ch, int val) - { - SS_TRACE_IN - channels[ch].pan = val; - - // Balance: - channels[ch].balanceFactorL = 1.0; - channels[ch].balanceFactorR = 1.0; - double offset = 0; - int dev = val - 64; - offset = (double) dev / 64.0; - if (offset < 0) { - channels[ch].balanceFactorR = 1.0 + offset; - } - else { - channels[ch].balanceFactorL = 1.0 - offset; - } - - if (SS_DEBUG_MIDI) - printf("balanceFactorL %f balanceFactorR %f\n", channels[ch].balanceFactorL, channels[ch].balanceFactorR); - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::updateVolume(int invol_ctrlval) - */ -void SimpleSynth::updateVolume(int ch, int invol_ctrlval) - { - SS_TRACE_IN - channels[ch].volume = (double)invol_ctrlval/ (double) SS_CHANNEL_VOLUME_QUOT; - channels[ch].volume_ctrlval = invol_ctrlval; - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::guiUpdateBalance(int ch, int bal) - */ -void SimpleSynth::guiUpdateBalance(int ch, int bal) - { - SS_TRACE_IN - MidiPlayEvent ev(0, 0, ch, ME_CONTROLLER, SS_CHANNEL_PAN_CONTROLLER(ch), bal); - gui->writeEvent(ev); - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::guiUpdateVolume(int ch, int val) - */ -void SimpleSynth::guiUpdateVolume(int ch, int val) - { - SS_TRACE_IN - MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_VOLUME_CONTROLLER(ch), val); - gui->writeEvent(ev); - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::guiUpdateNoff(bool b) - */ -void SimpleSynth::guiUpdateNoff(int ch, bool b) - { - SS_TRACE_IN - MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_NOFF_CONTROLLER(ch), b); - gui->writeEvent(ev); - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::guiUpdateChoff(int ch, bool b) - */ -void SimpleSynth::guiUpdateChoff(int ch, bool b) - { - SS_TRACE_IN - MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_ONOFF_CONTROLLER(ch), b); - gui->writeEvent(ev); - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::guiUpdateMasterVol(int val) - */ -void SimpleSynth::guiUpdateMasterVol(int val) - { - SS_TRACE_IN - MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_MASTER_CTRL_VOLUME, val); - gui->writeEvent(ev); - SS_TRACE_OUT - } - -/*! - \fn SimpleSynth::guiUpdateSendFxLevel(int fxid, int level) - */ -void SimpleSynth::guiUpdateSendFxLevel(int channel, int fxid, int level) - { - SS_TRACE_IN - MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_CHANNEL_SENDFX_CONTROLLER(channel, fxid), level); - gui->writeEvent(ev); - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::guiSendSampleLoaded(int ch, const char* filename) - */ -void SimpleSynth::guiSendSampleLoaded(bool success, int ch, const char* filename) - { - SS_TRACE_IN - int len = strlen(filename) + 3; //2 + filenamelen + 1; - byte out[len]; - - if (success) { - out[0] = SS_SYSEX_LOAD_SAMPLE_OK; - } - else { - out[0] = SS_SYSEX_LOAD_SAMPLE_ERROR; - } - out[1] = ch; - memcpy(out+2, filename, strlen(filename)+1); - MidiPlayEvent ev(0, 0, ME_SYSEX, out, len); - gui->writeEvent(ev); - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::guiSendError(const char* errorstring) - */ -void SimpleSynth::guiSendError(const char* errorstring) - { - SS_TRACE_IN - byte out[strlen(errorstring)+2]; - out[0] = SS_SYSEX_ERRORMSG; - memcpy(out+1, errorstring, strlen(errorstring) +1); - SS_TRACE_OUT - } - -extern "C" - { - static MESS descriptor = { - "SimpleSynth", - "SimpleSynth drums by Mathias Lundgren", // (lunar_shuttle@users.sf.net) - "0.1", //Version string - MESS_MAJOR_VERSION, MESS_MINOR_VERSION, - instantiate, - }; - // We must compile with -fvisibility=hidden to avoid namespace - // conflicts with global variables. - // Only visible symbol is "mess_descriptor". - // (TODO: all plugins should be compiled this way) - - __attribute__ ((visibility("default"))) - const MESS* mess_descriptor() { return &descriptor; } - } - - -/*! - \fn SimpleSynth::initSendEffect(int sendeffectid, QString lib, QString name) - */ -bool SimpleSynth::initSendEffect(int id, QString lib, QString name) - { - SS_TRACE_IN - bool success = false; - if (sendEffects[id].plugin) { - //Cleanup if one was already there: - cleanupPlugin(id); - } - sendEffects[id].plugin = (LadspaPlugin*) plugins.find(lib, name); - LadspaPlugin* plugin = sendEffects[id].plugin; - if (plugin) { //We found one - - sendEffects[id].inputs = plugin->inports(); - sendEffects[id].outputs = plugin->outports(); - - if (plugin->instantiate()) { - SS_DBG2("Plugin instantiated", name.toLatin1()); - SS_DBG_I("Parameters", plugin->parameter()); - SS_DBG_I("No of inputs", plugin->inports()); - SS_DBG_I("No of outputs",plugin->outports()); - SS_DBG_I("Inplace-capable", plugin->inPlaceCapable()); - - // Connect inputs/outputs: - // If single output/input, only use first channel in sendFxLineOut/sendFxReturn - SS_DBG("Connecting ports..."); - plugin->connectInport(0, sendFxLineOut[id][0]); - if (plugin->inports() == 2) - plugin->connectInport(1, sendFxLineOut[id][1]); - else if (plugin->inports() > 2) { - fprintf(stderr, "Plugin has more than 2 inputs, not supported\n"); - } - - plugin->connectOutport(0, sendFxReturn[id][0]); - if (plugin->outports() == 2) - plugin->connectOutport(1, sendFxReturn[id][1]); - else if (plugin->outports() > 2) { - fprintf(stderr, "Plugin has more than 2 outputs, not supported\n"); - } - SS_DBG("Ports connected"); - if (plugin->start()) { - sendEffects[id].state = SS_SENDFX_ON; - success = true; - - int n = plugin->parameter(); - sendEffects[id].nrofparameters = n; - - // This is not nice, but freeverb doesn't want to play until some values are set: - if (name == "freeverb3") { - setFxParameter(id, 2, 0.5); - setFxParameter(id, 3, 0.5); - setFxParameter(id, 4, 0.5); - guiUpdateFxParameter(id, 2, 0.5); - guiUpdateFxParameter(id, 3, 0.5); - guiUpdateFxParameter(id, 4, 0.5); - } - } - //TODO: cleanup if failed - } - } - //Notify gui - int len = 3; - byte out[len]; - out[0] = SS_SYSEX_LOAD_SENDEFFECT_OK; - out[1] = id; - int j=0; - for (iPlugin i = plugins.begin(); i!=plugins.end(); i++, j++) { - if ((*i)->lib() == plugin->lib() && (*i)->label() == plugin->label()) { - out[2] = j; - MidiPlayEvent ev(0, 0, ME_SYSEX, out, len); - gui->writeEvent(ev); - } - } - - if (!success) { - QString errorString = "Error loading plugin \"" + plugin->label() + "\""; - guiSendError(errorString); - } - return success; - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::setSendFxLevel(int channel, int effectid, double val) - */ -void SimpleSynth::setSendFxLevel(int channel, int effectid, double val) - { - SS_TRACE_IN - channels[channel].sendfxlevel[effectid] = val; - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::cleanupPlugin(int id) - */ -void SimpleSynth::cleanupPlugin(int id) - { - SS_TRACE_IN - LadspaPlugin* plugin = sendEffects[id].plugin; - plugin->stop(); - SS_DBG2("Stopped fx", plugin->label().toLatin1()); - sendEffects[id].nrofparameters = 0; - sendEffects[id].state = SS_SENDFX_OFF; - sendEffects[id].plugin = 0; - - byte d[2]; - d[0] = SS_SYSEX_CLEAR_SENDEFFECT_OK; - d[1] = id; - MidiPlayEvent ev(0, 0, ME_SYSEX, d, 2); - gui->writeEvent(ev); - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::setFxParameter(int fxid, int param, float val) - \brief Set fx-parameter on plugin and notify gui - */ -void SimpleSynth::setFxParameter(int fxid, int param, float val) - { - SS_TRACE_IN - LadspaPlugin* plugin = sendEffects[fxid].plugin; - if (SS_DEBUG_LADSPA) { - printf("Setting fx parameter: %f\n", val); - } - plugin->setParam(param, val); - //sendEffects[fxid].parameter[param] = val; - //guiUpdateFxParameter(fxid, param, val); - SS_TRACE_OUT - } - - - -/*! - \fn SimpleSynth::guiUpdateFxParameter(int fxid, int param, float val) - \brief Notify gui of changed fx-parameter - */ -void SimpleSynth::guiUpdateFxParameter(int fxid, int param, float val) - { - SS_TRACE_IN - LadspaPlugin* plugin = sendEffects[fxid].plugin; - float min, max; - plugin->range(param, &min, &max); - //offset: - val-= min; - - int intval = plugin->getGuiControlValue(param); - /*if (plugin->isLog(param)) { - intval = SS_map_logdomain2pluginparam(logf(val/(max - min) + min)); - } - else if (plugin->isBool(param)) { - intval = (int) val; - } - else { - float scale = SS_PLUGIN_PARAM_MAX / (max - min); - intval = (int) ((val - min) * scale); - }*/ - if (SS_DEBUG_MIDI) { - printf("Updating gui, fx parameter. fxid=%d, param=%d val=%d\n", fxid, param, intval); - } - - byte d[4]; - d[0] = SS_SYSEX_SET_PLUGIN_PARAMETER_OK; - d[1] = fxid; - d[2] = param; - d[3] = intval; - MidiPlayEvent ev(0, 0, ME_SYSEX, d, 4); - gui->writeEvent(ev); - SS_TRACE_OUT - } - - - - -/*! - \fn SimpleSynth::clearSample(int ch) - \brief Clears a sample (actually clears a channel) - */ -void SimpleSynth::clearSample(int ch) - { - SS_TRACE_IN - if (channels[ch].sample) { - if (SS_DEBUG) - printf("Clearing sample on channel %d\n", ch); - SS_State prevstate = synth_state; - SWITCH_CHAN_STATE(ch, SS_CHANNEL_INACTIVE); - SWITCH_SYNTH_STATE(SS_CLEARING_SAMPLE); - if (channels[ch].sample->data) { - delete[] channels[ch].sample->data; - channels[ch].sample->data = 0; - } - if (channels[ch].sample) { - delete channels[ch].sample; - channels[ch].sample = 0; - } - SWITCH_SYNTH_STATE(prevstate); - guiNotifySampleCleared(ch); - if (SS_DEBUG) { - printf("Clear sample - sample cleared on channel %d\n", ch); - } - } - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynth::guiNotifySampleCleared(int ch) - */ -void SimpleSynth::guiNotifySampleCleared(int ch) - { - SS_TRACE_IN - byte d[2]; - d[0] = SS_SYSEX_CLEAR_SAMPLE_OK; - d[1] = (byte) ch; - MidiPlayEvent ev(0, 0, ME_SYSEX, d, 2); - gui->writeEvent(ev); - SS_TRACE_OUT - } diff --git a/muse2/synti/simpledrums/simpledrums.h b/muse2/synti/simpledrums/simpledrums.h deleted file mode 100644 index 7f006d73..00000000 --- a/muse2/synti/simpledrums/simpledrums.h +++ /dev/null @@ -1,181 +0,0 @@ -// -// C++ Interface: simplesynth -// -// Description: -// -// -// Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 -// -// Copyright: See COPYING file that comes with this distribution -// -// -#ifndef SIMPLESYNTH_H -#define SIMPLESYNTH_H - -#include <sndfile.h> -#include <iostream> -#include <string> -#include <Qt3Support> -#include "libsynti/mess.h" -#include "common.h" -//#include "libsynti/mpevent.h" -#include "muse/mpevent.h" -#include "simpledrumsgui.h" -#include "ssplugin.h" - -#define SS_NO_SAMPLE 0 -#define SS_NO_PLUGIN 0 - -#define SS_PROCESS_BUFFER_SIZE 4096 //TODO: Add initialization method for nr of frames in each process from MusE - if nr of frames > than this, this will fail -#define SS_SENDFX_BUFFER_SIZE SS_PROCESS_BUFFER_SIZE - -enum SS_ChannelState - { - SS_CHANNEL_INACTIVE=0, - SS_SAMPLE_PLAYING, - }; - -enum SS_State - { - SS_INITIALIZING=0, - SS_LOADING_SAMPLE, - SS_CLEARING_SAMPLE, - SS_RUNNING, - }; - -enum SS_SendFXState - { - SS_SENDFX_OFF=0, - SS_SENDFX_ON - }; - -struct SS_SendFx - { - SS_SendFXState state; - LadspaPlugin* plugin; - int inputs; - int outputs; - int retgain_ctrlval; - double retgain; - int nrofparameters; - }; - -struct SS_Sample - { - float* data; - int samplerate; - int bits; - std::string filename; - long samples; - long frames; - int channels; - SF_INFO sfinfo; - }; - -struct SS_Channel - { - SS_ChannelState state; - const char* name; - SS_Sample* sample; - int playoffset; - bool noteoff_ignore; - - double volume; - int volume_ctrlval; - - double cur_velo; - double gain_factor; - - int pan; - double balanceFactorL; - double balanceFactorR; - - bool channel_on; - - //Send fx: - double sendfxlevel[SS_NR_OF_SENDEFFECTS]; - }; - -struct SS_Controller - { - std::string name; - int num; - int min, max; - }; - -struct SS_SampleLoader - { - SS_Channel* channel; - std::string filename; - int ch_no; - }; - -class SimpleSynth : public Mess - { - public: - SimpleSynth(int); - - virtual ~SimpleSynth(); - - //virtual bool guiVisible() const; - //virtual bool hasGui() const; - virtual bool nativeGuiVisible() const; - virtual bool hasNativeGui() const; - virtual bool playNote(int arg1, int arg2, int arg3); - virtual bool processEvent(const MidiPlayEvent& arg1); - virtual bool setController(int arg1, int arg2, int arg3); - virtual bool sysex(int arg1, const unsigned char* arg2); - virtual const char* getPatchName(int arg1, int arg2, int arg3, bool arg4) const; - virtual const MidiPatch* getPatchInfo(int arg1, const MidiPatch* arg2) const; - virtual int getControllerInfo(int arg1, const char** arg2, int* arg3, int* arg4, int* arg5, int* arg6) const; - virtual void processMessages(); - virtual void process(float** data, int offset, int len); - //virtual void showGui(bool arg1); - virtual void showNativeGui(bool arg1); - virtual void getInitData(int*, const unsigned char**) const; - bool init(const char* name); - void guiSendSampleLoaded(bool success, int ch, const char* filename); - void guiSendError(const char* errorstring); - - static const char* synth_state_descr[]; - static const char* channel_state_descr[]; - -private: - SimpleSynthGui* gui; - - SS_Channel channels[SS_NR_OF_CHANNELS]; - SS_Controller controllers[SS_NR_OF_CONTROLLERS]; - bool setController(int channel, int id, int val, bool fromGui); - bool loadSample(int ch_no, const char* filename); - void parseInitData(const unsigned char* data); - void updateVolume(int ch, int in_volume_ctrlval); - void updateBalance(int ch, int pan); - void guiNotifySampleCleared(int ch); - void guiUpdateBalance(int ch, int bal); - void guiUpdateVolume(int ch, int val); - void guiUpdateNoff(int ch, bool b); - void guiUpdateChoff(int ch, bool b); - void guiUpdateMasterVol(int val); - void guiUpdateFxParameter(int fxid, int param, float val); - void guiUpdateSendFxLevel(int channel, int fxid, int level); - bool initSendEffect(int sendeffectid, QString lib, QString name); - void setSendFxLevel(int channel, int effectid, double val); - void cleanupPlugin(int id); - void setFxParameter(int fxid, int param, float val); - void clearSample(int ch); - double master_vol; - int master_vol_ctrlval; - - //Send effects: - SS_SendFx sendEffects[SS_NR_OF_SENDEFFECTS]; - float* sendFxLineOut[SS_NR_OF_SENDEFFECTS][2]; //stereo output (fed into LADSPA inputs),sent from the individual channels -> LADSPA fx - float* sendFxReturn[SS_NR_OF_SENDEFFECTS][2]; //stereo inputs, from LADSPA plugins, sent from LADSPA -> SS and added to the mix - double* processBuffer[2]; - }; - -static void* loadSampleThread(void*); -static pthread_mutex_t SS_LoaderMutex; -static SS_State synth_state; -static SimpleSynth* simplesynth_ptr; - -#endif diff --git a/muse2/synti/simpledrums/simpledrumsgui.cpp b/muse2/synti/simpledrums/simpledrumsgui.cpp deleted file mode 100644 index f874a136..00000000 --- a/muse2/synti/simpledrums/simpledrumsgui.cpp +++ /dev/null @@ -1,893 +0,0 @@ -// -// C++ Implementation: testogui -// -// Description: -// -// -// Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 -// -// Copyright: See COPYING file that comes with this distribution -// -// - -#include <q3buttongroup.h> -#include <qlabel.h> -#include <q3filedialog.h> -#include <qsocketnotifier.h> -#include <qlayout.h> -#include <qtooltip.h> -#include <qlineedit.h> -#include <QtGui> -//Added by qt3to4: -#include <Q3HBoxLayout> -#include <Q3GridLayout> -#include <Q3VBoxLayout> - -#include "simpledrumsgui.h" -//#include "libsynti/mpevent.h" -#include "muse/mpevent.h" -#include "muse/midi.h" -#include "ssplugingui.h" - -#define SS_VOLUME_MIN_VALUE 0 -#define SS_VOLUME_MAX_VALUE 127 -#define SS_VOLUME_DEFAULT_VALUE 100 -#define SS_MASTERVOL_MAX_VALUE 127 -#define SS_MASTERVOL_DEFAULT_VALUE 100.0/127.0 -#define SS_SENDFX_MIN_VALUE 0 -#define SS_SENDFX_MAX_VALUE 127 - -//Gui constants: -#define SS_BTNGRP_WIDTH 50 -#define SS_BTNGRP_HEIGHT 80 -#define SS_ONOFF_WIDTH 16 -#define SS_ONOFF_HEIGHT 21 -#define SS_VOLSLDR_WIDTH (SS_BTNGRP_WIDTH - 8) -#define SS_VOLSLDR_LENGTH 120 -#define SS_PANSLDR_WIDTH (SS_BTNGRP_WIDTH - 8) -#define SS_PANSLDR_LENGTH 20 -#define SS_PANSLDR_DEFAULT_VALUE 63 -#define SS_NONOFF_LABEL_WIDTH 30 -#define SS_NONOFF_LABEL_HEIGHT 16 -#define SS_NONOFF_WIDTH SS_ONOFF_WIDTH -#define SS_NONOFF_HEIGHT SS_ONOFF_HEIGHT -#define SS_SENDFX_WIDTH ((SS_BTNGRP_WIDTH/2) - 4) -//#define SS_SENDFX_WIDTH 28 -#define SS_SENDFX_HEIGHT SS_SENDFX_WIDTH -#define SS_MASTERSLDR_WIDTH (SS_BTNGRP_WIDTH - 8) -#define SS_MASTERSLDR_HEIGHT (SS_BTNGRP_HEIGHT - 4) - - -// Sample groupbox - -#define SS_SAMPLENAME_LABEL_WIDTH 30 -#define SS_SAMPLENAME_LABEL_HEIGHT 21 -#define SS_SAMPLENAME_LABEL_XOFF 4 - -#define SS_SAMPLE_LOAD_WIDTH 15 -#define SS_SAMPLE_LOAD_HEIGHT 19 - -#define SS_SAMPLE_CLEAR_WIDTH SS_SAMPLE_LOAD_WIDTH -#define SS_SAMPLE_CLEAR_HEIGHT SS_SAMPLE_LOAD_HEIGHT - -#define SS_SAMPLENAME_LINEEDIT_WIDTH 90 -#define SS_SAMPLENAME_LINEEDIT_HEIGHT 21 - -#define SS_SAMPLE_INFO_LINE_HEIGHT 22 -#define SS_SAMPLE_INFO_LINE_WIDTH (SS_SAMPLENAME_LINEEDIT_XOFF + SS_SAMPLENAME_LINEEDIT_WIDTH) - -#define SS_GUI_WINDOW_WIDTH ((SS_NR_OF_CHANNELS +1) * SS_BTNGRP_XOFF) -#define SS_MAIN_GROUPBOX_HEIGHT 200 -#define SS_GUI_WINDOW_HEIGHT (SS_BTNGRP_HEIGHT + SS_MAIN_GROUPBOX_HEIGHT) -#define SS_MAIN_GROUPBOX_WIDTH SS_GUI_WINDOW_WIDTH - -SimpleSynthGui* simplesynthgui_ptr; - - -/*! - \fn QChannelSlider::QChannelSlider(Qt::Orientation orientation, int ch, QWidget* parent, const char* name) - */ -QChannelSlider::QChannelSlider(Qt::Orientation orientation, int ch, QWidget* parent, const char* name) - : QSlider(orientation, parent, name) - { - channel = ch; - } - - -/*! - \fn QChannelSlider::getChannel() - */ -int QChannelSlider::getChannel() - { - return channel; - } - - -/*! - \fn QChannelSlider::setChannel(int ch) - */ -void QChannelSlider::setChannel(int ch) - { - channel = ch; - } - -/*! - \fn QChannelSlider::setValue(int val) - */ -void QChannelSlider::setValue(int val) - { - val = (val > 127 ? 127 : val); - val = (val < 0 ? 0 : val); - QSlider::setValue(val); - emit valueChanged(channel, val); - } - -/*! - \fn QInvertedChannelSlider::setValue(int val) - */ -void QInvertedChannelSlider::setValue(int val) - { - int inverted = this->maxValue() - val; - inverted = (inverted > 127 ? 127 : inverted); - inverted = (inverted < 0 ? 0 : inverted); - QSlider::setValue(val); - emit valueChanged(channel, inverted); - } - -/*! - \fn QInvertedSlider::setValue(int val) - */ -void QInvertedSlider::setValue(int val) - { - int inverted = this->maxValue() - val; - inverted = (inverted > 127 ? 127 : inverted); - inverted = (inverted < 0 ? 0 : inverted); - emit invertedValueChanged(inverted); - QSlider::setValue(val); - } - - -/*! - \fn QChannelCheckbox::QChannelCheckbox(QWidget* parent, int ch, const char* name) - */ -QChannelCheckbox::QChannelCheckbox(QWidget* parent, int ch, const char* name) - : QCheckBox(parent, name) - { - channel = ch; - connect(this, SIGNAL(clicked()), SLOT(isClicked())); - } - - -/*! - \fn QChannelCheckbox::isClicked() - */ -void QChannelCheckbox::isClicked() - { - emit channelState(channel, this->isOn()); - } - -/*! - \fn QChannelButton::QChannelButton(QWidget* parent, const char* text, int ch, const char* name) - */ -QChannelButton::QChannelButton(QWidget* parent, const char* text, int ch, const char* name) - : QPushButton(parent, name), channel (ch) - { - connect(this, SIGNAL(clicked()), SLOT(isClicked())); - setText(text); - } - -/*! - \fn QChannelButton::isClicked() - */ -void QChannelButton::isClicked() - { - emit channelState(channel, this->isOn()); - } - -/*! - \fn QChannelDial() - */ -QChannelDial::QChannelDial(QWidget* parent, int ch, int fxid, const char* name) - : QDial(parent, name) - { - setTracking(true); - channel = ch; - sendfxid = fxid; - } - -/*! - \fn QChannelSlider::setValue(int val) - */ -void QChannelDial::setValue(int val) - { - QDial::setValue(val); - emit valueChanged(channel, sendfxid, val); - } - -/*! - \fn SimpleSynthGui::SimpleSynthGui() - */ -SimpleSynthGui::SimpleSynthGui() - { - SS_TRACE_IN - simplesynthgui_ptr = this; - pluginGui = new SS_PluginGui(this); - pluginGui->hide(); - - Q3VBoxLayout* mainLayout = new Q3VBoxLayout(this, 3); - Q3HBoxLayout* channelLayout = new Q3HBoxLayout(mainLayout, 1, "channellayout"); - - //this->setFixedWidth(SS_GUI_WINDOW_WIDTH); - //this->setFixedHeight(SS_GUI_WINDOW_HEIGHT); - for (int i=0; i<SS_NR_OF_CHANNELS; i++) { - channelButtonGroups[i] = new Q3ButtonGroup(this); - channelButtonGroups[i]->setMinimumSize(SS_BTNGRP_WIDTH, SS_BTNGRP_HEIGHT); - channelButtonGroups[i]->setTitle(QString::number(i + 1)); - - QString name = QString("volumeSlider"); - name.append(i + 1); - - channelLayout->add(channelButtonGroups[i]); - - Q3VBoxLayout* inchnlLayout = new Q3VBoxLayout(channelButtonGroups[i], 2, 0, "channelinternallayout"); - inchnlLayout->setAlignment(Qt::AlignHCenter); - - onOff[i] = new QChannelCheckbox(channelButtonGroups[i], i); - onOff[i]->setMinimumSize(SS_ONOFF_WIDTH, SS_ONOFF_HEIGHT); - QToolTip::add(onOff[i], "Channel " + QString::number(i + 1) + " on/off"); - inchnlLayout->add(onOff[i]); - connect(onOff[i], SIGNAL(channelState(int, bool)), SLOT(channelOnOff(int, bool))); - - volumeSliders[i] = new QInvertedChannelSlider(Qt::Vertical, i, channelButtonGroups[i], name); - volumeSliders[i]->setMinValue(SS_VOLUME_MIN_VALUE); - volumeSliders[i]->setMaxValue(SS_VOLUME_MAX_VALUE); - volumeSliders[i]->setValue(SS_VOLUME_MAX_VALUE - SS_VOLUME_DEFAULT_VALUE); - volumeSliders[i]->setMinimumSize(SS_VOLSLDR_WIDTH, SS_VOLSLDR_LENGTH); - QToolTip::add(volumeSliders[i], "Volume, channel " + QString::number(i + 1)); - setMinimumSize(SS_VOLSLDR_WIDTH, SS_VOLSLDR_LENGTH); - inchnlLayout->add(volumeSliders[i]); - connect(volumeSliders[i], SIGNAL(valueChanged(int, int)), SLOT(volumeChanged(int, int))); - - nOffLabel[i] = new QLabel(channelButtonGroups[i]); - nOffLabel[i]->setMinimumSize(SS_NONOFF_LABEL_WIDTH, SS_NONOFF_LABEL_HEIGHT); - nOffLabel[i]->setText("nOff"); - inchnlLayout->add(nOffLabel[i]); - - nOffIgnore[i] = new QChannelCheckbox(channelButtonGroups[i], i); - nOffIgnore[i]->setMinimumSize(SS_NONOFF_WIDTH, SS_NONOFF_HEIGHT); - QToolTip::add(nOffIgnore[i], "Note off ignore, channel " + QString::number(i + 1)); - inchnlLayout->add(nOffIgnore[i]); - connect(nOffIgnore[i], SIGNAL(channelState(int, bool)),SLOT(channelNoteOffIgnore(int, bool))); - - panSliders[i] = new QChannelSlider(Qt::Horizontal, i, channelButtonGroups[i]); - panSliders[i]->setRange(0, 127); - panSliders[i]->setValue(SS_PANSLDR_DEFAULT_VALUE); - panSliders[i]->setMinimumSize(SS_PANSLDR_WIDTH, SS_PANSLDR_LENGTH); - QToolTip::add(panSliders[i], "Pan, channel " + QString::number(i + 1)); - inchnlLayout->add(panSliders[i]); - connect(panSliders[i], SIGNAL(valueChanged(int, int)), SLOT(panChanged(int, int))); - - Q3GridLayout* dialGrid = new Q3GridLayout(inchnlLayout, 2, 2, 0); - sendFxDial[i][0] = new QChannelDial(channelButtonGroups[i], i, 0); - sendFxDial[i][0]->setRange(0, 127); - sendFxDial[i][0]->setMaximumSize(SS_SENDFX_WIDTH, SS_SENDFX_HEIGHT); - QToolTip::add(sendFxDial[i][0], "Fx 1 send amount"); - //inchnlLayout->add(sendFxDial[i][0]); - dialGrid->addWidget(sendFxDial[i][0], 0, 0, Qt::AlignCenter | Qt::AlignTop); - - connect(sendFxDial[i][0], SIGNAL(valueChanged(int, int, int)), SLOT(sendFxChanged(int, int, int))); - - sendFxDial[i][1] = new QChannelDial(channelButtonGroups[i], i, 1); - sendFxDial[i][1]->setRange(0, 127); - //inchnlLayout->add(sendFxDial[i][1]); - dialGrid->addWidget(sendFxDial[i][1], 0, 1, Qt::AlignCenter | Qt::AlignTop); - sendFxDial[i][1]->setMaximumSize(SS_SENDFX_WIDTH, SS_SENDFX_HEIGHT); - QToolTip::add(sendFxDial[i][1], "Fx 2 send amount"); - - connect(sendFxDial[i][1], SIGNAL(valueChanged(int, int, int)), SLOT(sendFxChanged(int, int, int))); - - sendFxDial[i][2] = new QChannelDial(channelButtonGroups[i], i, 2); - sendFxDial[i][2]->setRange(0, 127); - sendFxDial[i][2]->setMaximumSize(SS_SENDFX_WIDTH, SS_SENDFX_HEIGHT); - //inchnlLayout->add(sendFxDial[i][2]); - dialGrid->addWidget(sendFxDial[i][2], 1, 0, Qt::AlignCenter | Qt::AlignTop); - QToolTip::add(sendFxDial[i][2], "Fx 3 send amount"); - connect(sendFxDial[i][2], SIGNAL(valueChanged(int, int, int)), SLOT(sendFxChanged(int, int, int))); - - sendFxDial[i][3] = new QChannelDial(channelButtonGroups[i], i, 3); - sendFxDial[i][3]->setRange(0, 127); - sendFxDial[i][3]->setMaximumSize(SS_SENDFX_WIDTH, SS_SENDFX_HEIGHT); - QToolTip::add(sendFxDial[i][3], "Fx 4 send amount"); - - dialGrid->addWidget(sendFxDial[i][3], 1, 1, Qt::AlignCenter | Qt::AlignTop); - connect(sendFxDial[i][3], SIGNAL(valueChanged(int, int, int)), SLOT(sendFxChanged(int, int, int))); - inchnlLayout->activate(); - //channelLayout->activate(); - } - - //Master buttongroup: - masterButtonGroup = new Q3ButtonGroup(this, "masterButtonGroup"); - channelLayout->add(masterButtonGroup); - Q3VBoxLayout* mbgLayout = new Q3VBoxLayout(masterButtonGroup, 0); - mbgLayout->setAlignment(Qt::AlignCenter); - masterButtonGroup->setMinimumSize(SS_BTNGRP_WIDTH, SS_BTNGRP_HEIGHT); - masterSlider = new QInvertedSlider(Qt::Vertical, masterButtonGroup); - QToolTip::add(masterSlider, "Master volume"); - mbgLayout->add(masterSlider); - masterSlider->setRange(0, 127); - masterSlider->setValue(SS_VOLUME_MAX_VALUE - (int)(SS_MASTERVOL_DEFAULT_VALUE*SS_VOLUME_MAX_VALUE)); - masterSlider->setMinimumSize(SS_MASTERSLDR_WIDTH, SS_MASTERSLDR_HEIGHT); - connect(masterSlider, SIGNAL(invertedValueChanged(int)), SLOT(masterVolChanged(int))); - - //Main groupbox - mainGroupBox = new Q3GroupBox(this, "mainGroupBox"); - mainLayout->add(mainGroupBox); - - Q3GridLayout* mgbLayout = new Q3GridLayout(mainGroupBox, 8, 3, 1); - - int i=0; - - for (int c=0; c<2; c++) { - for (int r=0; r<SS_NR_OF_CHANNELS/2; r++) { - Q3HBoxLayout* strip = new Q3HBoxLayout;//(mgbLayout, 5); - mgbLayout->addLayout(strip, r, c); - - QLabel* channelLabel = new QLabel(QString("Ch ") + QString::number(i + 1), mainGroupBox); - strip->add(channelLabel); - - sampleNameLineEdit[i] = new QLineEdit(mainGroupBox); - sampleNameLineEdit[i]->setReadOnly(true); - strip->add(sampleNameLineEdit[i]); - - loadSampleButton[i] = new QChannelButton(mainGroupBox, "L", i); - loadSampleButton[i]->setMinimumSize(SS_SAMPLE_LOAD_WIDTH, SS_SAMPLE_LOAD_HEIGHT); - QToolTip::add(loadSampleButton[i], "Load sample on channel " + QString::number(i + 1)); - strip->add(loadSampleButton[i]); - connect(loadSampleButton[i], SIGNAL(channelState(int, bool)), SLOT(loadSampleDialogue(int))); - - clearSampleButton[i] = new QChannelButton(mainGroupBox, "C", i); - clearSampleButton[i]->setMinimumSize(SS_SAMPLE_CLEAR_WIDTH, SS_SAMPLE_CLEAR_HEIGHT); - QToolTip::add(clearSampleButton[i], "Clear sample on channel " + QString::number(i + 1)); - strip->add(clearSampleButton[i]); - connect(clearSampleButton[i], SIGNAL(channelState(int, bool)), SLOT(clearSample(int))); - - i++; - } - } - - // Right bottom panel: - Q3ButtonGroup* rbPanel= new Q3ButtonGroup(mainGroupBox, "right_bottom_panel"); - mgbLayout->addMultiCellWidget(rbPanel, 1, 8, 3, 3, Qt::AlignCenter); - Q3GridLayout* rbLayout = new Q3GridLayout(rbPanel, 6, 1, 8, 5); - openPluginsButton = new QPushButton("&Send Effects", rbPanel); - QToolTip::add(openPluginsButton, "Configure LADSPA send effects"); - connect(openPluginsButton, SIGNAL(clicked()), SLOT(openPluginButtonClicked())); - aboutButton = new QPushButton("About SimpleDrums", rbPanel); - connect(aboutButton, SIGNAL(clicked()), SLOT(aboutButtonClicked())); - QPushButton* loadButton = new QPushButton(tr("&Load setup"), rbPanel); - connect(loadButton, SIGNAL(clicked()), SLOT(loadSetup())); - QPushButton* saveButton = new QPushButton(tr("&Save setup"), rbPanel); - connect(saveButton, SIGNAL(clicked()), SLOT(saveSetup())); - - rbLayout->addWidget(openPluginsButton, 1, 1, Qt::AlignCenter | Qt::AlignVCenter); - rbLayout->addRowSpacing(2, 20); - rbLayout->addWidget(loadButton, 3, 1, Qt::AlignCenter | Qt::AlignVCenter); - rbLayout->addWidget(saveButton, 4, 1, Qt::AlignCenter | Qt::AlignVCenter); - rbLayout->addRowSpacing(5, 20); - rbLayout->addWidget(aboutButton, 6, 1, Qt::AlignCenter | Qt::AlignVCenter); - - lastDir = ""; - //Connect socketnotifier to fifo - QSocketNotifier* s = new QSocketNotifier(readFd, QSocketNotifier::Read); - connect(s, SIGNAL(activated(int)), SLOT(readMessage(int))); - SS_TRACE_OUT - - // work around for probable QT/WM interaction bug. - // for certain window managers, e.g xfce, this window is - // is displayed although not specifically set to show(); - // bug: 2811156 Softsynth GUI unclosable with XFCE4 (and a few others) - show(); - hide(); - } - -/*! - \fn SimpleSynthGui::~SimpleSynthGui() - */ -SimpleSynthGui::~SimpleSynthGui() - { - SS_TRACE_IN - simplesynthgui_ptr = 0; - delete pluginGui; - SS_TRACE_OUT - } - -/*! - \fn SimpleSynthGui::readMessage(int) - */ -void SimpleSynthGui::readMessage(int) - { - MessGui::readMessage(); - } - -/*! - \fn SimpleSynthGui::processEvent(const MidiPlayEvent& ev) - */ -void SimpleSynthGui::processEvent(const MidiPlayEvent& ev) - { - SS_TRACE_IN - if (SS_DEBUG_MIDI) { - printf("GUI received midi event\n"); - } - if (ev.type() == ME_CONTROLLER) { - int id = ev.dataA(); - int val = ev.dataB(); - - // Channel controllers: - if (id >= SS_FIRST_CHANNEL_CONTROLLER && id <= SS_LAST_CHANNEL_CONTROLLER ) { - // Find out which channel we're dealing with: - id-= SS_FIRST_CHANNEL_CONTROLLER; - int ch = (id / SS_NR_OF_CHANNEL_CONTROLLERS); - id = (id % SS_NR_OF_CHANNEL_CONTROLLERS); - - int fxid = -1; - - if (SS_DEBUG_MIDI) { - printf("GUI received midi controller - id: %d val %d channel %d\n", id, val, ch); - } - - switch(id) { - case SS_CHANNEL_CTRL_VOLUME: - volumeSliders[ch]->blockSignals(true); - volumeSliders[ch]->setValue(SS_VOLUME_MAX_VALUE - val); - volumeSliders[ch]->blockSignals(false); - break; - - case SS_CHANNEL_CTRL_PAN: - panSliders[ch]->blockSignals(true); - panSliders[ch]->setValue(val); - panSliders[ch]->blockSignals(false); - break; - - case SS_CHANNEL_CTRL_NOFF: - nOffIgnore[ch]->blockSignals(true); - nOffIgnore[ch]->setChecked(val); - nOffIgnore[ch]->blockSignals(false); - break; - - case SS_CHANNEL_CTRL_ONOFF: - onOff[ch]->blockSignals(true); - onOff[ch]->setChecked(val); - onOff[ch]->blockSignals(false); - break; - - case SS_CHANNEL_SENDFX1: - case SS_CHANNEL_SENDFX2: - case SS_CHANNEL_SENDFX3: - case SS_CHANNEL_SENDFX4: - fxid = id - SS_CHANNEL_SENDFX1; - if (SS_DEBUG_MIDI) { - printf("SimpleSynthGui::processEvent - Channel sendfx, fxid: %d, val: %d\n", fxid, val); - } - sendFxDial[ch][fxid]->blockSignals(true); - sendFxDial[ch][fxid]->setValue(val); - sendFxDial[ch][fxid]->blockSignals(false); - break; - - default: - if (SS_DEBUG_MIDI) - printf("SimpleSynthGui::processEvent - unknown controller received: %d\n", id); - } - } - // Master controllers: - else if (id >= SS_FIRST_MASTER_CONTROLLER && id <= SS_LAST_MASTER_CONTROLLER) { - if (id == SS_MASTER_CTRL_VOLUME) { - masterSlider->blockSignals(true); - masterSlider->setValue(SS_MASTERVOL_MAX_VALUE - val); - masterSlider->blockSignals(false); - } - } - else if (id>= SS_FIRST_PLUGIN_CONTROLLER && id <= SS_LAST_PLUGIN_CONTROLLER) { - int fxid = (id - SS_FIRST_PLUGIN_CONTROLLER) / SS_NR_OF_PLUGIN_CONTROLLERS; - int cmd = (id - SS_FIRST_PLUGIN_CONTROLLER) % SS_NR_OF_PLUGIN_CONTROLLERS; - - // Plugin return-gain: - if (cmd == SS_PLUGIN_RETURN) { - if (SS_DEBUG_MIDI) - printf("SimpleSynthGui::processEvent - fx retgain received: fxid: %d val: %d\n", fxid, val); - - SS_PluginFront* pf = pluginGui->getPluginFront((unsigned)fxid); - pf->setRetGain(val); - } - } - } - // - // Sysexes: - // - else if (ev.type() == ME_SYSEX) { - byte* data = ev.data(); - int cmd = *data; - switch (cmd) { - case SS_SYSEX_LOAD_SAMPLE_OK: { - int ch = *(data+1); - QString filename = (const char*) (data+2); - sampleNameLineEdit[ch]->setText(filename.section('/',-1,-1)); - if (SS_DEBUG_MIDI) { - printf("SimpleSynthGui - sample %s loaded OK on channel: %d\n", filename.toLatin1(), ch); - } - if (!onOff[ch]->isChecked()) { - onOff[ch]->blockSignals(true); - onOff[ch]->setChecked(true); - onOff[ch]->blockSignals(false); - channelOnOff(ch, true); - } - break; - } - - case SS_SYSEX_LOAD_SAMPLE_ERROR: { - //int ch = *(data+1); - const char* filename = (const char*) (data+2); - /*QMessageBox* yn = new QMessageBox("Sample not found", "Failed to load sample: " + QString(filename) + "\n" + - "Do you want to open file browser and try to locate it elsewhere?", - QMessageBox::Warning, - QMessageBox::Yes, - QMessageBox::No, - QMessageBox::NoButton, - this);*/ - /*int res = QMessageBox::warning(this, - "SimpleDrums","Failed to load sample: " + QString(filename) + "\n" + - "Do you want to open file browser and try to locate it elsewhere?", - "&Yes", "&No"); - */ - //int res = yn->exec(); - printf("Error: Sample %s not found! TODO: Fix this\n", filename); - //if (res == 0) { - // loadSampleDialogue(ch); - // } - break; - } - - case SS_SYSEX_LOAD_SENDEFFECT_OK: { - if (SS_DEBUG_MIDI) { - printf("SimpleSynthGui - sysex load sendeffect OK on fxid: %d\n", *(data+1)); - } - int fxid = *(data+1); - SS_PluginFront* pf = pluginGui->getPluginFront((unsigned)fxid); - pf->updatePluginValue(*(data+2)); - break; - } - - case SS_SYSEX_CLEAR_SENDEFFECT_OK: { - if (SS_DEBUG_MIDI) { - printf("SimpleSynthGui - sysex clear sendeffect OK on fxid: %d\n", *(data+1)); - } - SS_PluginFront* pf = pluginGui->getPluginFront((unsigned)*(data+1)); - pf->clearPluginDisplay(); - break; - } - - case SS_SYSEX_CLEAR_SAMPLE_OK: { - if (SS_DEBUG_MIDI) { - printf("SimpleSynthGui - sysex clear samle OK on channel: %d\n", *(data+1)); - } - byte ch = *(data+1); - sampleNameLineEdit[ch]->setText(""); - break; - } - - case SS_SYSEX_SET_PLUGIN_PARAMETER_OK: { - if (SS_DEBUG_MIDI) { - printf("SimpleSynthGui - plugin parameter OK on fxid: %d\n", *(data+1)); - } - SS_PluginFront* pf = pluginGui->getPluginFront((unsigned)*(data+1)); - int param = *(data+2); - int val = *(data+3); - pf->blockSignals(true); - pf->setParameterValue(param, val); - pf->blockSignals(false); - break; - } - - case SS_SYSEX_SEND_INIT_DATA: { - const unsigned initdata_len = ev.len() - 1; - byte* init_data = (data + 1); - QFileInfo fileInfo = QFileInfo(lastSavedProject); - - lastProjectDir = fileInfo.dirPath(true); - if (fileInfo.extension(false) != "sds" && fileInfo.extension(false) != "SDS") { - lastSavedProject += ".sds"; - fileInfo = QFileInfo(lastSavedProject); - } - QFile theFile(fileInfo.filePath()); - - // Write data - if (theFile.open(QIODevice::WriteOnly)) { - theFile.writeBlock((const char*)&initdata_len, sizeof(initdata_len)); // First write length - if (theFile.writeBlock((const char*)init_data, initdata_len) == -1) { - // Fatal error writing - QMessageBox msgBox("IO error", "Fatal error when writing to file. Setup not saved.", - QMessageBox::Warning, - QMessageBox::Ok, - QMessageBox::NoButton, - QMessageBox::NoButton, - this); - msgBox.exec(); - } - theFile.close(); - } - else { - // An error occured when opening - QMessageBox msgBox("IO error", "Error opening file. Setup was not saved.", QMessageBox::Warning, - QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton, this); - msgBox.exec(); - } - - break; - } - - default: - if (SS_DEBUG_MIDI) { - printf("SimpleSynthGui::processEvent - unknown sysex cmd received: %d\n", cmd); - } - break; - } - } - SS_TRACE_OUT - } - - -/*! - \fn SimpleSynthGui::volumeChanged(int val) - */ -void SimpleSynthGui::volumeChanged(int channel, int val) - { - setChannelVolume(channel, val); - } - -/*! - \fn SimpleSynthGui::panChanged(int channel, int value) - */ -void SimpleSynthGui::panChanged(int channel, int value) - { - sendController(0, SS_CHANNEL_PAN_CONTROLLER(channel), value); - } - -/*! - \fn SimpleSynthGui::channelOnOff(int channel, bool state) - */ -void SimpleSynthGui::channelOnOff(int channel, bool state) - { - sendController(0, SS_CHANNEL_ONOFF_CONTROLLER(channel), state); - } - -/*! - \fn SimpleSynthGui::channelNoteOffIgnore(bool state) - */ -void SimpleSynthGui::channelNoteOffIgnore(int channel, bool state) - { - sendController(0, SS_CHANNEL_NOFF_CONTROLLER(channel), (int) state); - } - -/*! - \fn SimpleSynthGui::sendFxChanged(int ch, int fxid, int val) - */ -void SimpleSynthGui::sendFxChanged(int ch, int fxid, int val) - { - sendController(0, SS_CHANNEL_SENDFX_CONTROLLER(ch, fxid), (int) val); - } - -/*! - \fn SimpleSynthGui::masterVolChanged(int val) - */ -void SimpleSynthGui::masterVolChanged(int val) - { - sendController(0, SS_MASTER_CTRL_VOLUME, val); - } - -/*! - \fn SimpleSynthGui::setChannelVolume(int channel, byte volume) - */ -void SimpleSynthGui::setChannelVolume(int channel, int volume) - { - //volumeSliders[channel]->setValue(SS_VOLUME_MAX_VALUE - volume); - sendController(0, SS_CHANNEL_VOLUME_CONTROLLER(channel), (int)volume); - } - - -/*! - \fn SimpleSynthGui::loadSampleDialogue(int channel) - */ -void SimpleSynthGui::loadSampleDialogue(int channel) - { - QString filename = - Q3FileDialog::getOpenFileName(lastDir, - QString("*.wav;*.WAV"), - this, - "Load sample dialog","Choose sample"); - - if (filename != QString::null) { - lastDir = filename.left(filename.findRev("/")); - - if (SS_DEBUG) - printf("lastDir = %s\n", lastDir.toLatin1()); - - int l = filename.length() + 4; - byte d[l]; - - d[0] = SS_SYSEX_LOAD_SAMPLE; - d[1] = (byte) channel; - d[2] = (byte) filename.length(); - memcpy(d+3, filename.toLatin1(), filename.length()+1); - sendSysex(d, l); - } - } - - - -/*! - \fn SimpleSynthGui::clearSample(int ch) - */ -void SimpleSynthGui::clearSample(int ch) - { - if (sampleNameLineEdit[ch]->text().length() > 0) { //OK, we've got a live one here - byte d[2]; - d[0] = SS_SYSEX_CLEAR_SAMPLE; - d[1] = (byte) ch; - sendSysex(d, 2); - } - } - -/*! - \fn SimpleSynthGui::displayPluginGui() - */ -void SimpleSynthGui::displayPluginGui() - { - pluginGui->show(); - } - -/*! - \fn SimpleSynthGui::loadEffectInvoked(int fxid, QString lib, QString label) - */ -void SimpleSynthGui::loadEffectInvoked(int fxid, QString lib, QString label) - { - int l = 4 + lib.length() + label.length(); - byte d[l]; - d[0] = SS_SYSEX_LOAD_SENDEFFECT; - d[1] = (byte) fxid; - memcpy (d+2, lib.toLatin1(), lib.length()+1); - memcpy (d+3+lib.length(), label.toLatin1(), label.length()+1); - sendSysex(d, l); - } - - -/*! - \fn SimpleSynthGui::returnLevelChanged(int fxid, int val) - */ -void SimpleSynthGui::returnLevelChanged(int fxid, int val) - { - sendController(0, SS_PLUGIN_RETURNLEVEL_CONTROLLER(fxid), val); - } - - -/*! - \fn SimpleSynthGui::toggleEffectOnOff(int fxid, int state) - */ -void SimpleSynthGui::toggleEffectOnOff(int fxid, int state) - { - sendController(0, SS_PLUGIN_ONOFF_CONTROLLER(fxid), state); - } - - -/*! - \fn SimpleSynthGui::clearPlugin(int fxid) - */ -void SimpleSynthGui::clearPlugin(int fxid) - { - byte d[2]; - d[0] = SS_SYSEX_CLEAR_SENDEFFECT; - d[1] = fxid; - sendSysex(d, 2); - } - - -/*! - \fn SimpleSynthGui::effectParameterChanged(int fxid, int parameter, int val) - */ -void SimpleSynthGui::effectParameterChanged(int fxid, int parameter, int val) - { - //printf("Gui: effectParameterChanged: %d %d %d\n", fxid, parameter, val); - int len = 4; - byte d[len]; - d[0] = SS_SYSEX_SET_PLUGIN_PARAMETER; - d[1] = (byte) fxid; - d[2] = (byte) parameter; - d[3] = (byte) val; - sendSysex(d, len); - } - - -/*! - \fn SimpleSynthGui::openPluginButtonClicked() - */ -void SimpleSynthGui::openPluginButtonClicked() - { - if (pluginGui->isShown()) - pluginGui->raise(); - else - displayPluginGui(); - } - - -/*! - \fn SimpleSynthGui::aboutButtonClicked() - */ -void SimpleSynthGui::aboutButtonClicked() - { - QString caption = "SimpleDrums ver"; - caption+= SS_VERSIONSTRING; - QString text = caption + "\n\n(C) Copyright 2000-2005 Mathias Lundgren (lunar_shuttle@users.sf.net), Werner Schweer\nPublished under the GNU Public License"; - QMessageBox msgBox(caption, text, QMessageBox::NoIcon, - QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton, this); - msgBox.exec(); - } - - - -/*! - \fn SimpleSynthGui::loadSetup() - \brief Load setup from file - */ -void SimpleSynthGui::loadSetup() - { - bool success = true; - QString filename = - Q3FileDialog::getOpenFileName(lastProjectDir, - QString("*.sds;*.SDS"), - this, - "Load setup dialog", "Choose SimpleDrums setup"); - - if (filename != QString::null) { - QFile theFile(filename); - if (theFile.open(QIODevice::ReadOnly)) { - unsigned initdata_len = 0; - if (theFile.readBlock((char*)&initdata_len, sizeof(initdata_len)) == -1) - success = false; - - byte* init_data = new byte[initdata_len]; - if (theFile.readBlock((char*)(init_data), initdata_len) == -1) - success = false; - - if (!success) { - QMessageBox msgBox("IO error", "Error opening/reading from file. Setup not loaded.", QMessageBox::Warning, - QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton, this); - msgBox.exec(); - } - else { - sendSysex(init_data, initdata_len); - } - - delete[] init_data; - } - } - } - - -/*! - \fn SimpleSynthGui::saveSetup() - \brief Save setup to file - */ -void SimpleSynthGui::saveSetup() - { - QString filename = - Q3FileDialog::getSaveFileName(lastProjectDir, - QString("*.sds;*.SDS"), - this, - "Save setup dialog", "Save SimpleDrums setup"); - - if (filename != QString::null) { - lastSavedProject = filename; - byte d[1]; - d[0] = SS_SYSEX_GET_INIT_DATA; - sendSysex(d, 1); // Makes synth send gui initdata, where rest of the saving takes place - } - } - diff --git a/muse2/synti/simpledrums/simpledrumsgui.h b/muse2/synti/simpledrums/simpledrumsgui.h deleted file mode 100644 index 47a98ca1..00000000 --- a/muse2/synti/simpledrums/simpledrumsgui.h +++ /dev/null @@ -1,212 +0,0 @@ -// -// C++ Interface: testogui -// -// Description: -// -// -// Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 -// -// Copyright: See COPYING file that comes with this distribution -// -// -#ifndef __MUSE_TESTOGUI_H__ -#define __MUSE_TESTOGUI_H__ - -#include <qslider.h> -#include <qcheckbox.h> -#include <qpushbutton.h> -#include <qdial.h> -#include <Qt3Support> -//Added by qt3to4: -#include <QLabel> - -#include "libsynti/gui.h" -#include "simpledrumsguibase.h" -#include "common.h" - - - -class Q3ButtonGroup; -class QLabel; -class SS_PluginGui; - -//-------------------------------------- -// QChannelSlider -//-------------------------------------- -class QChannelSlider: public QSlider - { - Q_OBJECT - - public: - QChannelSlider(Qt::Orientation, int ch, QWidget* paren, const char* name = 0); - int getChannel(); - void setChannel(int ch); - - public slots: - virtual void setValue(int val); - - signals: - void valueChanged(int channel, int value); - - protected: - int channel; - }; - -//-------------------------------------- -// QInvertedSlider -//-------------------------------------- -class QInvertedSlider : public QSlider - { - Q_OBJECT - public: - QInvertedSlider(Qt::Orientation o, QWidget* parent, const char* name = 0) - : QSlider(o, parent, name) {} - - public slots: - virtual void setValue(int val); - - signals: - void invertedValueChanged(int value); - }; - -//-------------------------------------- -// QInvertedChannelSlider -//-------------------------------------- -class QInvertedChannelSlider : public QChannelSlider - { - Q_OBJECT - public: - QInvertedChannelSlider(Qt::Orientation o, int channel, QWidget* parent, const char* name = 0) - : QChannelSlider(o, channel, parent, name) {}; - - public slots: - virtual void setValue(int val); - }; - - -//-------------------------------------- -// QChannelOnOff -//-------------------------------------- - -class QChannelCheckbox : public QCheckBox - { - Q_OBJECT - public: - QChannelCheckbox(QWidget* parent, int channel, const char* name = 0); - - private: - int channel; - - private slots: - void isClicked(); - - signals: - void channelState(int channel, bool state); - }; - -//-------------------------------------- -// QChannelButton -//-------------------------------------- -class QChannelButton : public QPushButton - { - Q_OBJECT - - private: - int channel; - - public: - QChannelButton(QWidget* parent, const char* text, int ch, const char* name = 0); - - private slots: - void isClicked(); - - signals: - void channelState(int channel, bool state); - - }; - -//-------------------------------------- -// QChannelDial -//-------------------------------------- -class QChannelDial : public QDial - { - Q_OBJECT - - public: - QChannelDial(QWidget* parent, int ch, int fxid, const char* name = 0); - - signals: - void valueChanged(int channel, int fxid, int val); - - public slots: - virtual void setValue(int val); - - protected: - int channel; - int sendfxid; - }; - -//-------------------------------------- -// SimpleSynthGui - the Gui -//-------------------------------------- -class SimpleSynthGui : public SimpleDrumsGuiBase, public MessGui - { - Q_OBJECT - private: - // MESS interface: - virtual void processEvent(const MidiPlayEvent& ev); - void setChannelVolume(int channel, int volume); - void displayPluginGui(); - Q3GroupBox* channelButtonGroups[SS_NR_OF_CHANNELS]; - Q3ButtonGroup* masterButtonGroup; - Q3GroupBox* mainGroupBox; - QInvertedChannelSlider* volumeSliders[SS_NR_OF_CHANNELS]; - QChannelSlider* panSliders[SS_NR_OF_CHANNELS]; - QChannelCheckbox* onOff[SS_NR_OF_CHANNELS]; - QChannelCheckbox* nOffIgnore[SS_NR_OF_CHANNELS]; - QChannelButton* loadSampleButton[SS_NR_OF_CHANNELS]; - QChannelButton* clearSampleButton[SS_NR_OF_CHANNELS]; - QLabel* nOffLabel[SS_NR_OF_CHANNELS]; - QLineEdit* sampleNameLineEdit[SS_NR_OF_CHANNELS]; - QInvertedSlider* masterSlider; - QChannelDial* sendFxDial[SS_NR_OF_CHANNELS][SS_NR_OF_SENDEFFECTS]; - - QPushButton* openPluginsButton; - QPushButton* aboutButton; - - QString lastDir; - QString lastSavedProject; - QString lastProjectDir; - SS_PluginGui* pluginGui; - - public: - SimpleSynthGui(); - virtual ~SimpleSynthGui(); - - public slots: - void loadEffectInvoked(int fxid, QString lib, QString label); - void returnLevelChanged(int fxid, int val); - void toggleEffectOnOff(int fxid, int state); - void clearPlugin(int fxid); - void effectParameterChanged(int fxid, int parameter, int val); - - private slots: - void volumeChanged(int channel, int val); - void panChanged(int channel, int value); - void channelOnOff(int channel, bool state); - void channelNoteOffIgnore(int channel, bool state); - void masterVolChanged(int val); - void loadSampleDialogue(int channel); - void readMessage(int); - void clearSample(int ch); - void sendFxChanged(int ch, int fxid, int val); - void openPluginButtonClicked(); - void aboutButtonClicked(); - void loadSetup(); - void saveSetup(); - - }; - -extern SimpleSynthGui* simplesynthgui_ptr; - -#endif diff --git a/muse2/synti/simpledrums/simpledrumsguibase.ui b/muse2/synti/simpledrums/simpledrumsguibase.ui deleted file mode 100644 index 244273a6..00000000 --- a/muse2/synti/simpledrums/simpledrumsguibase.ui +++ /dev/null @@ -1,27 +0,0 @@ -<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> -<class>SimpleDrumsGuiBase</class> -<widget class="QDialog"> - <property name="name"> - <cstring>SimpleDrumsGuiBase</cstring> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>602</width> - <height>509</height> - </rect> - </property> - <property name="paletteBackgroundColor"> - <color> - <red>194</red> - <green>194</green> - <blue>194</blue> - </color> - </property> - <property name="caption"> - <string>DrumSynth 0.1</string> - </property> -</widget> -<layoutdefaults spacing="6" margin="11"/> -</UI> diff --git a/muse2/synti/simpledrums/ssplugin.cpp b/muse2/synti/simpledrums/ssplugin.cpp deleted file mode 100644 index 4e38129e..00000000 --- a/muse2/synti/simpledrums/ssplugin.cpp +++ /dev/null @@ -1,461 +0,0 @@ -// -// C++ Implementation: plugin -// -// Description: -// -// -// (C) Copyright 2000 Werner Schweer (ws@seh.de) -// Additions/modifications: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 -// Copyright: See COPYING file that comes with this distribution -// -// - -#include <QtCore> -#include <QtGui> -#include <stdlib.h> -#include <unistd.h> -#include <dlfcn.h> -#include "ssplugin.h" -#include "common.h" - -PluginList plugins; - - -Plugin::Plugin(const QFileInfo* f) - : fi(*f) - { - } - -//--------------------------------------------------------- -// loadPluginLib -//--------------------------------------------------------- - -static void loadPluginLib(QFileInfo* fi) - { - SS_TRACE_IN - if (SS_DEBUG_LADSPA) { - printf("loadPluginLib: %s\n", fi->fileName().toLatin1()); - } - void* handle = dlopen(fi->filePath().ascii(), RTLD_NOW); - if (handle == 0) { - fprintf(stderr, "dlopen(%s) failed: %s\n", - fi->filePath().ascii(), dlerror()); - return; - } - LADSPA_Descriptor_Function ladspa = (LADSPA_Descriptor_Function)dlsym(handle, "ladspa_descriptor"); - - if (!ladspa) { - const char *txt = dlerror(); - if (txt) { - fprintf(stderr, - "Unable to find ladspa_descriptor() function in plugin " - "library file \"%s\": %s.\n" - "Are you sure this is a LADSPA plugin file?\n", - fi->filePath().ascii(), - txt); - exit(1); - } - } - const LADSPA_Descriptor* descr; - for (int i = 0;; ++i) { - descr = ladspa(i); - if (descr == NULL) - break; - plugins.push_back(new LadspaPlugin(fi, ladspa, descr)); - } - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// loadPluginDir -//--------------------------------------------------------- - -static void loadPluginDir(const QString& s) - { - SS_TRACE_IN - QDir pluginDir(s, QString("*.so"), QDir::DirsLast, QDir::Files); - if (pluginDir.exists()) { - QList<QFileInfo> list = pluginDir.entryInfoList(); - QList<QFileInfo>::iterator it=list.begin(); - QFileInfo* fi; - while((fi = &(*it))) { - loadPluginLib(fi); - ++it; - } - } - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// initPlugins -// search for LADSPA plugins -//--------------------------------------------------------- - -void SS_initPlugins() - { - SS_TRACE_IN - //loadPluginDir(museGlobalLib + QString("/plugins")); - - const char* ladspaPath = getenv("LADSPA_PATH"); - if (ladspaPath == 0) - ladspaPath = "/usr/local/lib64/ladspa:/usr/lib64/ladspa:/usr/local/lib/ladspa:/usr/lib/ladspa"; - - const char* p = ladspaPath; - while (*p != '\0') { - const char* pe = p; - while (*pe != ':' && *pe != '\0') - pe++; - - int n = pe - p; - if (n) { - char* buffer = new char[n + 1]; - strncpy(buffer, p, n); - buffer[n] = '\0'; - loadPluginDir(QString(buffer)); - delete[] buffer; - } - p = pe; - if (*p == ':') - p++; - } - SS_TRACE_OUT - } - - -//--------------------------------------------------------- -// LadspaPlugin -//--------------------------------------------------------- - -LadspaPlugin::LadspaPlugin(const QFileInfo* f, - const LADSPA_Descriptor_Function ldf, - const LADSPA_Descriptor* d) - : Plugin(f), ladspa(ldf), plugin(d) - { - SS_TRACE_IN - _inports = 0; - _outports = 0; - _parameter = 0; - handle = 0; - active = false; - controls = 0; - inputs = 0; - outputs = 0; - - for (unsigned k = 0; k < plugin->PortCount; ++k) { - LADSPA_PortDescriptor pd = d->PortDescriptors[k]; - static const int CI = LADSPA_PORT_CONTROL | LADSPA_PORT_INPUT; - if ((pd & CI) == CI) { - ++_parameter; - pIdx.push_back(k); - } - else if (pd & LADSPA_PORT_INPUT) { - ++_inports; - iIdx.push_back(k); - } - else if (pd & LADSPA_PORT_OUTPUT) { - ++_outports; - oIdx.push_back(k); - } - } - - /*if (SS_DEBUG_LADSPA) { - printf("Label: %s\tLib: %s\tPortCount: %d\n", this->label().toLatin1(), this->lib().toLatin1(), plugin->PortCount); - printf("LADSPA_PORT_CONTROL|LADSPA_PORT_INPUT: %d\t", pIdx.size()); - printf("Input ports: %d\t", iIdx.size()); - printf("Output ports: %d\n\n", oIdx.size()); - }*/ - - LADSPA_Properties properties = plugin->Properties; - _inPlaceCapable = !LADSPA_IS_INPLACE_BROKEN(properties); - if (_inports != _outports) - _inPlaceCapable = false; - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// ~LadspaPlugin -//--------------------------------------------------------- -LadspaPlugin::~LadspaPlugin() - { - SS_TRACE_IN - if (active) { - stop(); - } - if (handle) { - SS_DBG_LADSPA2("Cleaning up ", this->label().toLatin1()); - plugin->cleanup(handle); - } - - //Free ports: - if (controls) - delete controls; - if (inputs) - delete inputs; - if (outputs) - delete outputs; - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// instantiate -//--------------------------------------------------------- - -bool LadspaPlugin::instantiate() - { - bool success = false; - handle = plugin->instantiate(plugin, SS_samplerate); - success = (handle != NULL); - if (success) - SS_DBG_LADSPA2("Plugin instantiated", label().toLatin1()); - return success; - } - -//--------------------------------------------------------- -// start -// activate and connect control ports -//--------------------------------------------------------- - -bool LadspaPlugin::start() - { - SS_TRACE_IN - if (handle) { - if (plugin->activate) { - plugin->activate(handle); - SS_DBG_LADSPA("Plugin activated"); - } - active = true; - } - else { - SS_DBG_LADSPA("Error trying to activate plugin - plugin not instantiated!"); - SS_TRACE_OUT - return false; - } - - //Connect ports: - controls = new Port[_parameter]; - - for (int k = 0; k < _parameter; ++k) { - double val = defaultValue(k); - controls[k].val = val; - plugin->connect_port(handle, pIdx[k], &controls[k].val); - } - - outputs = new Port[_outports]; - inputs = new Port[_inports]; - - SS_TRACE_OUT - return true; - } - -//--------------------------------------------------------- -// stop -// deactivate -//--------------------------------------------------------- -void LadspaPlugin::stop() - { - SS_TRACE_IN - if (handle) { - SS_DBG_LADSPA2("Trying to stop plugin", label().toLatin1()); - if (plugin->deactivate) { - SS_DBG_LADSPA2("Deactivating ", label().toLatin1()); - plugin->deactivate(handle); - active = false; - } - } - else - SS_DBG_LADSPA("Warning - tried to stop plugin, but plugin was never started...\n"); - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// range -//--------------------------------------------------------- - -void LadspaPlugin::range(int i, float* min, float* max) const - { - SS_TRACE_IN - i = pIdx[i]; - LADSPA_PortRangeHint range = plugin->PortRangeHints[i]; - LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor; - if (desc & LADSPA_HINT_TOGGLED) { - *min = 0.0; - *max = 1.0; - return; - } - float m = 1.0; - if (desc & LADSPA_HINT_SAMPLE_RATE) - m = (float) SS_samplerate; - - if (desc & LADSPA_HINT_BOUNDED_BELOW) - *min = range.LowerBound * m; - else - *min = 0.0; - if (desc & LADSPA_HINT_BOUNDED_ABOVE) - *max = range.UpperBound * m; - else - *max = 1.0; - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// defaultValue -//--------------------------------------------------------- - -float LadspaPlugin::defaultValue(int k) const - { - SS_TRACE_IN - k = pIdx[k]; - LADSPA_PortRangeHint range = plugin->PortRangeHints[k]; - LADSPA_PortRangeHintDescriptor rh = range.HintDescriptor; - double val = 1.0; - if (LADSPA_IS_HINT_DEFAULT_MINIMUM(rh)) - val = range.LowerBound; - else if (LADSPA_IS_HINT_DEFAULT_LOW(rh)) - if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor)) - val = exp(fast_log10(range.LowerBound) * .75 + - log(range.UpperBound) * .25); - else - val = range.LowerBound*.75 + range.UpperBound*.25; - else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(rh)) - if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor)) - val = exp(log(range.LowerBound) * .5 + - log(range.UpperBound) * .5); - else - val = range.LowerBound*.5 + range.UpperBound*.5; - else if (LADSPA_IS_HINT_DEFAULT_HIGH(rh)) - if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor)) - val = exp(log(range.LowerBound) * .25 + - log(range.UpperBound) * .75); - else - val = range.LowerBound*.25 + range.UpperBound*.75; - else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(rh)) - val = range.UpperBound; - else if (LADSPA_IS_HINT_DEFAULT_0(rh)) - val = 0.0; - else if (LADSPA_IS_HINT_DEFAULT_1(rh)) - val = 1.0; - else if (LADSPA_IS_HINT_DEFAULT_100(rh)) - val = 100.0; - else if (LADSPA_IS_HINT_DEFAULT_440(rh)) - val = 440.0; - SS_TRACE_OUT - return val; - } - -//--------------------------------------------------------- -// find -//--------------------------------------------------------- - -Plugin* PluginList::find(const QString& file, const QString& name) - { - SS_TRACE_IN - for (iPlugin i = begin(); i != end(); ++i) { - if ((file == (*i)->lib()) && (name == (*i)->label())) { - SS_TRACE_OUT - return *i; - } - } - printf("Plugin <%s> not found\n", name.toLatin1()); - SS_TRACE_OUT - return 0; - } - -//--------------------------------------------------------- -// connectInport -//--------------------------------------------------------- -void LadspaPlugin::connectInport(int k, LADSPA_Data* datalocation) - { - SS_TRACE_IN - plugin->connect_port(handle, iIdx[k], datalocation); - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// connectOutport -//--------------------------------------------------------- -void LadspaPlugin::connectOutport(int k, LADSPA_Data* datalocation) - { - SS_TRACE_IN - plugin->connect_port(handle, oIdx[k], datalocation); - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// process -//--------------------------------------------------------- -void LadspaPlugin::process(unsigned long frames) - { - plugin->run(handle, frames); - } - -//--------------------------------------------------------- -// setParam -//--------------------------------------------------------- - -void LadspaPlugin::setParam(int k, float val) - { - SS_TRACE_IN - controls[k].val = val; - SS_TRACE_OUT - } - -//--------------------------------------------------------- -// getGuiControlValue -// scale control value to gui-slider/checkbox representation -//--------------------------------------------------------- - -int LadspaPlugin::getGuiControlValue(int param) const - { - SS_TRACE_IN - float val = getControlValue(param); - float min, max; - range(param, &min, &max); - int intval; - if (isLog(param)) { - intval = SS_map_logdomain2pluginparam(logf(val/(max - min) + min)); - } - else if (isBool(param)) { - intval = (int) val; - } - else { - float scale = SS_PLUGIN_PARAM_MAX / (max - min); - intval = (int) ((val - min) * scale); - } - SS_TRACE_OUT - return intval; - } - -//--------------------------------------------------------- -// convertGuiControlValue -// scale control value to gui-slider/checkbox representation -//--------------------------------------------------------- - -float LadspaPlugin::convertGuiControlValue(int parameter, int val) const - { - SS_TRACE_IN - float floatval = 0; - float min, max; - range(parameter, &min, &max); - - if (isLog(parameter)) { - if (val > 0) { - float logged = SS_map_pluginparam2logdomain(val); - float e = expf(logged) * (max - min); - e+=min; - floatval = e; - } - } - else if (isBool(parameter)) { - floatval = (float) val; - } - else if (isInt(parameter)) { - float scale = (max - min) / SS_PLUGIN_PARAM_MAX; - floatval = (float) round((((float) val) * scale) + min); - } - else { - float scale = (max - min) / SS_PLUGIN_PARAM_MAX; - floatval = (((float) val) * scale) + min; - } - SS_TRACE_OUT - return floatval; - } diff --git a/muse2/synti/simpledrums/ssplugin.h b/muse2/synti/simpledrums/ssplugin.h deleted file mode 100644 index 8f2b5df3..00000000 --- a/muse2/synti/simpledrums/ssplugin.h +++ /dev/null @@ -1,153 +0,0 @@ -// -// C++ Interface: plugin -// -// Description: -// -// -// (C) Copyright 2000 Werner Schweer (ws@seh.de) -// Additions/modifications: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 -// Copyright: See COPYING file that comes with this distribution -// -// - -#ifndef __PLUGIN_H__ -#define __PLUGIN_H__ - -#include <QFileInfo> -//#include <ladspa.h> -#include "muse/ladspa.h" -#include "muse/fastlog.h" -#include <math.h> - -//--------------------------------------------------------- -// Port -//--------------------------------------------------------- - -struct Port { - float val; - }; - -//--------------------------------------------------------- -// Plugin -//--------------------------------------------------------- - -class Plugin - { - protected: - QFileInfo fi; - - public: - Plugin(const QFileInfo* f); - virtual ~Plugin() {} - virtual QString label() const { return QString(); } - virtual QString name() const { return QString(); } - virtual unsigned long id() const { return 0; } - virtual QString maker() const { return QString(); } - virtual QString copyright() const { return QString(); } - virtual int parameter() const { return 0; } - virtual int inports() const { return 0; } - virtual int outports() const { return 0; } - virtual bool inPlaceCapable() const { return false; } - - virtual bool isLog(int) const { return false; } - virtual bool isBool(int) const { return false; } - virtual bool isInt(int) const { return false; } - virtual float defaultValue(int) const { return 0.0f; } - virtual void range(int, float* min, float* max) const { - *min = 0.0f; - *max = 1.0f; - } - virtual const char* getParameterName(int /*param*/) const { return ""; } //prevnt unused parameter - QString lib() const { return fi.baseName(); } - QString path() const { return fi.dirPath(); } - }; - -//--------------------------------------------------------- -// LadspaPlugin -//--------------------------------------------------------- - -class LadspaPlugin : public Plugin - { - LADSPA_Descriptor_Function ladspa; - const LADSPA_Descriptor* plugin; - LADSPA_Handle handle; - bool active; - - Port* controls; - Port* inputs; - Port* outputs; - - protected: - int _parameter; - std::vector<int> pIdx; //control port numbers - - int _inports; - std::vector<int> iIdx; //input port numbers - - int _outports; - std::vector<int> oIdx; //output port numbers - - bool _inPlaceCapable; - - public: - LadspaPlugin(const QFileInfo* f, const LADSPA_Descriptor_Function, const LADSPA_Descriptor* d); - virtual ~LadspaPlugin(); - virtual QString label() const { return QString(plugin->Label); } - virtual QString name() const { return QString(plugin->Name); } - virtual unsigned long id() const { return plugin->UniqueID; } - virtual QString maker() const { return QString(plugin->Maker); } - virtual QString copyright() const { return QString(plugin->Copyright); } - virtual int parameter() const { return _parameter; } - virtual int inports() const { return _inports; } - virtual int outports() const { return _outports; } - virtual bool inPlaceCapable() const { return _inPlaceCapable; } - const LADSPA_Descriptor* ladspaDescriptor() const { return plugin; } - virtual bool isLog(int k) const { - LADSPA_PortRangeHint r = plugin->PortRangeHints[pIdx[k]]; - return LADSPA_IS_HINT_LOGARITHMIC(r.HintDescriptor); - } - virtual bool isBool(int k) const { - return LADSPA_IS_HINT_TOGGLED(plugin->PortRangeHints[pIdx[k]].HintDescriptor); - } - virtual bool isInt(int k) const { - LADSPA_PortRangeHint r = plugin->PortRangeHints[pIdx[k]]; - return LADSPA_IS_HINT_INTEGER(r.HintDescriptor); - } - virtual void range(int i, float*, float*) const; - virtual const char* getParameterName(int i) const { - return plugin->PortNames[pIdx[i]]; - } - virtual float defaultValue(int) const; - virtual float getControlValue(int k) const { - return controls[k].val; - } - - int getGuiControlValue(int parameter) const; - float convertGuiControlValue(int parameter, int val) const; - - bool instantiate(); - bool start(); - void stop(); - void connectInport(int k, LADSPA_Data* datalocation); - void connectOutport(int k, LADSPA_Data* datalocation); - void process(unsigned long); - void setParam(int i, float val); - - }; - -//--------------------------------------------------------- -// PluginList -//--------------------------------------------------------- - -typedef std::list<Plugin*>::iterator iPlugin; - -class PluginList : public std::list<Plugin*> { - public: - Plugin* find(const QString& file, const QString& name); - PluginList() {} - }; - -extern void SS_initPlugins(); -extern PluginList plugins; - -#endif diff --git a/muse2/synti/simpledrums/sspluginchooserbase.ui b/muse2/synti/simpledrums/sspluginchooserbase.ui deleted file mode 100644 index 3ce1d10e..00000000 --- a/muse2/synti/simpledrums/sspluginchooserbase.ui +++ /dev/null @@ -1,134 +0,0 @@ -<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> -<class>SS_PluginChooserBase</class> -<widget class="QDialog"> - <property name="name"> - <cstring>SS_PluginChooserBase</cstring> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>777</width> - <height>681</height> - </rect> - </property> - <property name="caption"> - <string>SimpleDrums - Ladspa Plugin Chooser</string> - </property> - <vbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <widget class="QListView"> - <column> - <property name="text"> - <string>Name</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Label</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Inports</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Outports</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <column> - <property name="text"> - <string>Creator</string> - </property> - <property name="clickable"> - <bool>true</bool> - </property> - <property name="resizable"> - <bool>true</bool> - </property> - </column> - <property name="name"> - <cstring>effectsListView</cstring> - </property> - </widget> - <widget class="QLayoutWidget"> - <property name="name"> - <cstring>layout1</cstring> - </property> - <hbox> - <property name="name"> - <cstring>unnamed</cstring> - </property> - <spacer> - <property name="name"> - <cstring>spacer1</cstring> - </property> - <property name="orientation"> - <enum>Horizontal</enum> - </property> - <property name="sizeType"> - <enum>Expanding</enum> - </property> - <property name="sizeHint"> - <size> - <width>301</width> - <height>31</height> - </size> - </property> - </spacer> - <widget class="QPushButton"> - <property name="name"> - <cstring>cancelButton</cstring> - </property> - <property name="text"> - <string>&Cancel</string> - </property> - <property name="accel"> - <string>Alt+C</string> - </property> - </widget> - <widget class="QPushButton"> - <property name="name"> - <cstring>okButton</cstring> - </property> - <property name="text"> - <string>&OK</string> - </property> - <property name="accel"> - <string>Alt+O</string> - </property> - </widget> - </hbox> - </widget> - </vbox> -</widget> -<layoutdefaults spacing="6" margin="11"/> -</UI> diff --git a/muse2/synti/simpledrums/ssplugingui.cpp b/muse2/synti/simpledrums/ssplugingui.cpp deleted file mode 100644 index e1e8a7de..00000000 --- a/muse2/synti/simpledrums/ssplugingui.cpp +++ /dev/null @@ -1,534 +0,0 @@ -// -// C++ Implementation: ssplugingui -// -// Description: -// -// -// Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 -// -// Copyright: See COPYING file that comes with this distribution -// -// - -#include <stdlib.h> -#include <qlayout.h> -//Added by qt3to4: -#include <Q3HBoxLayout> -#include <Q3Frame> -#include <QLabel> -#include <Q3VBoxLayout> -#include <QtGui> -#include "ssplugingui.h" -#include "ssplugin.h" -#include "simpledrumsgui.h" - -#define SS_PLUGINGUI_XOFF 300 -#define SS_PLUGINGUI_YOFF 300 -#define SS_PLUGINGUI_WIDTH 450 -#define SS_PLUGINGUI_MAX_WIDTH 700 - -#define SS_PLUGINFRONT_MINWIDTH SS_PLUGINGUI_WIDTH -#define SS_PLUGINFRONT_MINHEIGHT 70 -#define SS_PLUGINFRONT_MARGIN 9 -#define SS_PLUGINFRONT_INC_PARAM 30 -#define SS_PLUGINFRONT_INC_PARAM_MIN 60 -#define SS_PLUGINGUI_HEIGHT (SS_NR_OF_SENDEFFECTS * SS_PLUGINFRONT_MINHEIGHT) - -#define SS_PLUGINCHOOSER_NAMECOL 0 -#define SS_PLUGINCHOOSER_LABELCOL 1 -#define SS_PLUGINCHOOSER_INPORTSCOL 2 -#define SS_PLUGINCHOOSER_OUTPORTSCOL 3 -#define SS_PLUGINCHOOSER_CREATORCOL 4 - - -/*! - \fn SS_PluginChooser::SS_PluginChooser(QWidget* parent, const char* name = 0) - */ -SS_PluginChooser::SS_PluginChooser(QWidget* parent, const char* name) - :SS_PluginChooserBase(parent, name) - { - SS_TRACE_IN - selectedPlugin = 0; - - for (iPlugin i=plugins.begin(); i !=plugins.end(); i++) { - //Support for only 2 or 1 inport/outports - if ( ((*i)->outports() == 2 || (*i)->outports() == 1) && ((*i)->inports() == 2 || (*i)->inports() == 1) ) { - Q3ListViewItem* tmpItem = new Q3ListViewItem(effectsListView); - tmpItem->setText(SS_PLUGINCHOOSER_NAMECOL, (*i)->name()); - tmpItem->setText(SS_PLUGINCHOOSER_LABELCOL, (*i)->label()); - tmpItem->setText(SS_PLUGINCHOOSER_INPORTSCOL, QString::number((*i)->inports())); - tmpItem->setText(SS_PLUGINCHOOSER_OUTPORTSCOL, QString::number((*i)->outports())); - tmpItem->setText(SS_PLUGINCHOOSER_CREATORCOL, (*i)->maker()); - effectsListView->insertItem(tmpItem); - } - } - connect(okButton, SIGNAL(pressed()), SLOT(okPressed())); - connect(cancelButton, SIGNAL(pressed()), SLOT(cancelPressed())); - connect(effectsListView, SIGNAL(selectionChanged(Q3ListViewItem*)), SLOT(selectionChanged(Q3ListViewItem*))); - connect(effectsListView, SIGNAL(doubleClicked(Q3ListViewItem*)), SLOT(doubleClicked(Q3ListViewItem*))); - SS_TRACE_OUT - } - -/*! - \fn SS_PluginChooser::selectionChanged(QListViewItem* item) - */ -void SS_PluginChooser::selectionChanged(Q3ListViewItem* item) - { - SS_TRACE_IN - selectedItem = item; - SS_TRACE_OUT - } - -/*! - \fn SS_PluginChooser::okPressed() - */ -void SS_PluginChooser::okPressed() - { - SS_TRACE_IN - selectedPlugin = findSelectedPlugin(); - done(QDialog::Accepted); - SS_TRACE_OUT - } - -/*! - \fn SS_PluginChooser::cancelPressed() - */ -void SS_PluginChooser::cancelPressed() - { - SS_TRACE_IN - SS_TRACE_OUT - done(QDialog::Rejected); - } - -/*! - \fn SS_PluginChooser::doubleClicked(QListViewItem* item) - */ -void SS_PluginChooser::doubleClicked(Q3ListViewItem* /*item*/) - { - SS_TRACE_IN - selectedPlugin = findSelectedPlugin(); - SS_TRACE_OUT - done(QDialog::Accepted); - } - -/*! - \fn SS_PluginChooser::getSelectedPlugin() - */ -LadspaPlugin* SS_PluginChooser::findSelectedPlugin() - { - SS_TRACE_IN - LadspaPlugin* selected = 0; - for (iPlugin i=plugins.begin(); i != plugins.end(); i++) { - if ((*i)->name() == selectedItem->text(SS_PLUGINCHOOSER_NAMECOL)) - selected = (LadspaPlugin*) (*i); - } - SS_TRACE_OUT - return selected; - } - -/*! - \fn SS_PluginFront::SS_PluginFront(QWidget* parent, const char* name = 0) - */ -SS_PluginFront::SS_PluginFront(QWidget* parent, int in_fxid, const char* name) - : Q3GroupBox(parent, name), fxid (in_fxid) - { - SS_TRACE_IN - expanded = false; - pluginChooser = 0; - plugin = 0; - expGroup = 0; - - setLineWidth(3); - setFlat(false); - setFrameStyle( Q3Frame::Box | Q3Frame::Raised ); - setFrameShape(Q3GroupBox::Box);// QFrame::Box); - setFrameShadow(Sunken); - setFocusPolicy(Qt::NoFocus); - setMinimumSize(SS_PLUGINFRONT_MINWIDTH, SS_PLUGINFRONT_MINHEIGHT); - setMaximumSize(SS_PLUGINGUI_MAX_WIDTH, SS_PLUGINFRONT_MINHEIGHT); - - Q3VBoxLayout* bigLayout = new Q3VBoxLayout(this); - bigLayout->setMargin(SS_PLUGINFRONT_MARGIN); - bigLayout->setAlignment(Qt::AlignTop); - bigLayout->setResizeMode(QLayout::SetNoConstraint); - - layout = new Q3HBoxLayout(bigLayout); - layout->setAlignment(Qt::AlignVCenter); - layout->setResizeMode(QLayout::SetNoConstraint); - - - Q3VBoxLayout* onOffLayout = new Q3VBoxLayout(layout); - onOffLayout->setMargin(SS_PLUGINFRONT_MARGIN); - onOff = new QCheckBox(this); - onOffLayout->add(new QLabel("On/Off", this)); - onOffLayout->add(onOff); - connect(onOff, SIGNAL(toggled(bool)), SLOT(onOffToggled(bool))); - - pluginName = new QLineEdit(this); - pluginName->setReadOnly(true); - layout->add(pluginName); - - loadFxButton = new QPushButton("L", this); - QRect r = loadFxButton->geometry(); - loadFxButton->setGeometry(r.x(), r.y(), 20, pluginName->geometry().height()); - loadFxButton->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); - loadFxButton->setMinimumSize(20,pluginName->geometry().height()); - loadFxButton->setMaximumSize(30,pluginName->geometry().height()); - connect(loadFxButton, SIGNAL(clicked()), SLOT(loadButton())); - layout->add(loadFxButton); - - clearFxButton = new QPushButton("C", this); - r = clearFxButton->geometry(); - clearFxButton->setGeometry(r.x(), r.y(), 20, pluginName->geometry().height()); - clearFxButton->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); - clearFxButton->setMinimumSize(20,pluginName->geometry().height()); - clearFxButton->setMaximumSize(30,pluginName->geometry().height()); - connect(clearFxButton, SIGNAL(clicked()), SLOT(clearButtonPressed())); - layout->add(clearFxButton); - - layout->addSpacing(5); - - expandButton = new QPushButton("->", this); - r = loadFxButton->geometry(); - expandButton->setGeometry(r.x(), r.y(), 20, pluginName->geometry().height()); - expandButton->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); - expandButton->setMinimumSize(20,pluginName->geometry().height()); - expandButton->setMaximumSize(30,pluginName->geometry().height()); - connect(expandButton, SIGNAL(clicked()), SLOT(expandButtonPressed())); - layout->add(expandButton); - - layout->addSpacing(5); - - Q3VBoxLayout* gainSliderLayout = new Q3VBoxLayout(layout); - gainSliderLayout->add(new QLabel("Return level", this)); - gainSliderLayout->setMargin(SS_PLUGINFRONT_MARGIN); - outGainSlider = new QSlider(Qt::Horizontal, this); - outGainSlider->setMinimumSize(100, pluginName->geometry().height()); - outGainSlider->setMaximumSize(500, pluginName->geometry().height()); - loadFxButton->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); - outGainSlider->setRange(0, 127); - outGainSlider->setValue(75); - connect(outGainSlider, SIGNAL(valueChanged(int)), SLOT(returnSliderMoved(int))); - gainSliderLayout->add(outGainSlider); - clearPluginDisplay(); - - expLayout = new Q3VBoxLayout(bigLayout, 2); - - QToolTip::add(clearFxButton, "Clear and unload effect"); - QToolTip::add(loadFxButton, "Load effect"); - QToolTip::add(expandButton, "Toggle display of effect parameters"); - QToolTip::add(onOff, "Turn effect on/off"); - SS_TRACE_OUT - } - -SS_PluginFront::~SS_PluginFront() - { - if (pluginChooser) - delete pluginChooser; - } - -/*! - \fn SS_PluginFront::clearPluginDisplay() - */ -void SS_PluginFront::clearPluginDisplay() - { - SS_TRACE_IN - if (expanded) - expandButtonPressed(); - - pluginName->setText("No plugin loaded"); - pluginName->setEnabled(false); - - onOff->setEnabled(false); - onOff->blockSignals(true); - onOff->setChecked(false); - onOff->blockSignals(false); - - clearFxButton->setEnabled(false); - expandButton->setEnabled(false); - outGainSlider->setEnabled(false); - SS_TRACE_OUT - } - -/*! - \fn SS_PluginFront::setPluginName(QString name) - */ -void SS_PluginFront::setPluginName(QString name) - { - pluginName->setText(name); - } - - -/*! - \fn SS_PluginFront::loadButton() - */ -void SS_PluginFront::loadButton() - { - SS_TRACE_IN - if (!pluginChooser) - pluginChooser = new SS_PluginChooser(this, "temppluginchooser"); - - pluginChooser->exec(); - if ((pluginChooser->result() == QDialog::Accepted) && pluginChooser->getSelectedPlugin()) { - Plugin* p = pluginChooser->getSelectedPlugin(); - //printf("Selected plugin: %s\n", pluginChooser->getSelectedPlugin()->name().toLatin1()); - emit loadPlugin(fxid, p->lib(), p->label()); - } - SS_TRACE_OUT - } - -/*! - \fn SS_PluginFront::returnSliderMoved(int val) - */ -void SS_PluginFront::returnSliderMoved(int val) - { - emit returnLevelChanged(fxid, val); - } - - -/*! - \fn SS_PluginFront::updatePluginValue(unsigned i) - */ -void SS_PluginFront::updatePluginValue(unsigned k) - { - SS_TRACE_IN - // If parameters are shown - close them - if (expanded) { - expandButtonPressed(); - } - - unsigned j=0; - if (k > plugins.size()) { - fprintf(stderr, "Internal error, tried to update plugin w range outside of list\n"); - return; - } - - iPlugin i; - for (i = plugins.begin(); j != k; i++, j++) ; - plugin = (LadspaPlugin*) *(i); - setPluginName(plugin->label()); - outGainSlider->setEnabled(true); - clearFxButton->setEnabled(true); - expandButton->setEnabled(true); - pluginName->setEnabled(true); - onOff->setEnabled(true); - onOff->setChecked(true); - SS_TRACE_OUT - } - -/*! - \fn SS_PluginFront::onOffToggled(bool state) - */ -void SS_PluginFront::onOffToggled(bool state) - { - emit fxToggled(fxid, state); - } - -/*! - \fn SS_PluginFront::sizeHint() const - */ -QSize SS_PluginFront::sizeHint() const - { - return QSize(SS_PLUGINFRONT_MINWIDTH, 50); - } - -/*! - \fn SS_PluginFront::sizePolicy() const - */ -QSizePolicy SS_PluginFront::sizePolicy() const - { - return QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - } - - -/*! - \fn SS_PluginFront::clearButtonPressed() - */ -void SS_PluginFront::clearButtonPressed() - { - // If parameters are shown - close them - if (expanded) { - expandButtonPressed(); - } - emit clearPlugin(fxid); - } - -/*! - \fn SS_PluginFront::setRetGain(int val) - */ -void SS_PluginFront::setRetGain(int val) - { - outGainSlider->blockSignals(true); - outGainSlider->setValue(val); - outGainSlider->blockSignals(false); - } - -/*! - \fn SS_PluginFront::expandButtonPressed() - */ -void SS_PluginFront::expandButtonPressed() - { - SS_TRACE_IN - int sizeIncrease = 0; - QRect pf = geometry(); - - if (!expanded) { - plugin->parameter() == 1 ? sizeIncrease = SS_PLUGINFRONT_INC_PARAM_MIN : sizeIncrease = plugin->parameter() * SS_PLUGINFRONT_INC_PARAM; - pf.setHeight(pf.height() + sizeIncrease); - setMinimumSize(QSize(pf.width(), pf.height())); - setMaximumSize(QSize(SS_PLUGINGUI_MAX_WIDTH, pf.height())); - setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); - setGeometry(pf); - emit sizeChanged(fxid, sizeIncrease); - - expanded = true; - expandButton->setText("<-"); - createPluginParameters(); - } - else { - expLayout->remove(expGroup); - expGroup->hide(); - expGroup->deleteLater(); - paramWidgets.clear(); - expGroup = 0; - plugin->parameter() == 1 ? sizeIncrease = (0-SS_PLUGINFRONT_INC_PARAM_MIN) : sizeIncrease = 0 - (plugin->parameter() * SS_PLUGINFRONT_INC_PARAM); - expandButton->setText("->"); - expanded = false; - pf.setHeight(pf.height() + sizeIncrease); - pf.setTop(pf.top() + sizeIncrease); - pf.setBottom(pf.bottom() + sizeIncrease); - setGeometry(pf); - adjustSize(); - layout->activate(); - setMinimumSize(QSize(pf.width(), pf.height())); - setMaximumSize(QSize(SS_PLUGINGUI_MAX_WIDTH, pf.height())); - setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); - emit sizeChanged(fxid, sizeIncrease); - } - SS_TRACE_OUT - } - -/*! - \fn SS_PluginFront::createPluginParameters() - */ -void SS_PluginFront::createPluginParameters() - { - SS_TRACE_IN - expGroup = new Q3ButtonGroup(this); - - expGroup->setMinimumSize(QSize(50, 50)); - expGroup->setMaximumSize(QSize(SS_PLUGINGUI_MAX_WIDTH, (plugin->parameter() * SS_PLUGINFRONT_INC_PARAM - SS_PLUGINFRONT_MARGIN))); - expGroup->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); - expLayout->add(expGroup); - expGroup->show(); - Q3VBoxLayout* expGroupLayout = new Q3VBoxLayout(expGroup, 1); - expGroupLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); - expGroupLayout->setResizeMode(QLayout::SetNoConstraint); - expGroupLayout->setMargin(SS_PLUGINFRONT_MARGIN); - - for (int i=0; i < plugin->parameter(); i++) { - Q3HBoxLayout* paramStrip = new Q3HBoxLayout(expGroupLayout, 3); - paramStrip->setAlignment(Qt::AlignLeft); - QLabel* paramName = new QLabel(plugin->getParameterName(i), expGroup); - paramName->show(); - paramName->setMinimumSize(QSize(150, 10)); - paramName->setMaximumSize(QSize(300, SS_PLUGINFRONT_INC_PARAM)); - paramName->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding)); - - paramStrip->add(paramName); - - if (plugin->isBool(i)) { - SS_ParameterCheckBox* paramCheckBox = new SS_ParameterCheckBox(expGroup, plugin, fxid, i); - paramCheckBox->setEnabled(true); - paramCheckBox->setParamValue((int) plugin->getControlValue(i)); - paramCheckBox->show(); - paramStrip->add(paramCheckBox); - connect(paramCheckBox, SIGNAL(valueChanged(int, int, int)), SLOT(parameterValueChanged(int, int, int))); - } - else { - SS_ParameterSlider* paramSlider = new SS_ParameterSlider(expGroup, plugin, fxid, i); - paramSlider->setEnabled(true); - paramSlider->show(); - paramSlider->setRange(SS_PLUGIN_PARAM_MIN, SS_PLUGIN_PARAM_MAX); - - float max, min; - plugin->range(i, &min, &max); - //int intval = 0; - paramSlider->setParamValue(plugin->getGuiControlValue(i)); - connect(paramSlider, SIGNAL(valueChanged(int, int, int)), SLOT(parameterValueChanged(int, int, int))); - paramStrip->add(paramSlider); - } - } - expLayout->activate(); - SS_TRACE_OUT - } - -/*! - \fn SS_PluginFront::parameterValueChanged(int fxid, int parameter, int val) - */ -void SS_PluginFront::parameterValueChanged(int fxid, int parameter, int val) - { - emit effectParameterChanged(fxid, parameter, val); - } - -/*! - \fn SS_PluginFront::setParameterValue(int param, float val) - */ -void SS_PluginFront::setParameterValue(int param, int val) - { - SS_TRACE_IN - int j=0; - for (SS_iParameterWidgetList i=paramWidgets.begin(); i != paramWidgets.end(); i++, j++) { - if (j == param) { - (*i)->setParamValue(val); - } - } - SS_TRACE_OUT - } - -SS_PluginGui::SS_PluginGui(QWidget* parent, const char* name) - : QDialog(parent, name, false) - { - this->setCaption("SimpleDrums LADSPA sendeffects"); - for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) { - pluginFronts[i] = 0; - } - layout = new Q3VBoxLayout(this); - - for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) { - pluginFronts[i] = new SS_PluginFront(this, i); - pluginFronts[i]->update(); - layout->add(pluginFronts[i]); - connect(pluginFronts[i], SIGNAL(loadPlugin(int, QString, QString)), simplesynthgui_ptr, SLOT(loadEffectInvoked(int, QString, QString))); - connect(pluginFronts[i], SIGNAL(returnLevelChanged(int, int)), simplesynthgui_ptr, SLOT(returnLevelChanged(int, int))); - connect(pluginFronts[i], SIGNAL(fxToggled(int, int)), simplesynthgui_ptr, SLOT(toggleEffectOnOff(int, int))); - connect(pluginFronts[i], SIGNAL(clearPlugin(int)), simplesynthgui_ptr, SLOT(clearPlugin(int))); - connect(pluginFronts[i], SIGNAL(sizeChanged(int, int)), SLOT(pluginFrontSizeChanged(int, int))); - connect(pluginFronts[i], SIGNAL(effectParameterChanged(int, int, int)), simplesynthgui_ptr, SLOT(effectParameterChanged(int, int, int))); - } - setMinimumSize(QSize(SS_PLUGINGUI_WIDTH, geometry().height())); - setMaximumSize(QSize(SS_PLUGINGUI_MAX_WIDTH, geometry().height())); - } - - -/*! - \fn SS_PluginGui::pluginFrontSizeChanged(int fxid, int val) - */ -void SS_PluginGui::pluginFrontSizeChanged(int /*fxid*/, int val) - { - QRect r = geometry(); - r.setHeight(r.height() + val); - setMinimumSize(QSize(SS_PLUGINGUI_WIDTH, r.height())); - setMaximumSize(QSize(SS_PLUGINGUI_MAX_WIDTH, r.height())); - setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); - setGeometry(r); - adjustSize(); - } - -SS_PluginFront* SS_PluginGui::getPluginFront(unsigned i) - { - SS_TRACE_IN - if (i<SS_NR_OF_SENDEFFECTS) - SS_TRACE_OUT - return pluginFronts[i]; - } diff --git a/muse2/synti/simpledrums/ssplugingui.h b/muse2/synti/simpledrums/ssplugingui.h deleted file mode 100644 index 166d8787..00000000 --- a/muse2/synti/simpledrums/ssplugingui.h +++ /dev/null @@ -1,206 +0,0 @@ -// -// C++ Interface: ssplugingui -// -// Description: -// -// -// Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 -// -// Copyright: See COPYING file that comes with this distribution -// -// - -#ifndef __SS_PLUGINGUI_H__ -#define __SS_PLUGINGUI_H__ -#include <qdialog.h> -#include <qslider.h> -#include <Q3ButtonGroup> -#include <QtGui> -//Added by qt3to4: -#include <Q3HBoxLayout> -#include <Q3VBoxLayout> -#include "sspluginchooserbase.h" -#include "common.h" -#include "ssplugin.h" - -class SS_ParameterWidget - { - protected: - int fxid; - int parameter; - - LadspaPlugin* plugin; - - public: - SS_ParameterWidget() { }; - virtual ~SS_ParameterWidget() { }; - - int getFxId() { SS_TRACE_IN SS_TRACE_OUT return fxid; } - bool isBool() { SS_TRACE_IN SS_TRACE_OUT return plugin->isBool(parameter); } - bool isLog() { SS_TRACE_IN SS_TRACE_OUT return plugin->isLog(parameter); } - bool isInt() { SS_TRACE_IN SS_TRACE_OUT return plugin->isInt(parameter); } - virtual void setParamValue(int /*val*/) { //prevent compiler warning unused parameter - printf("Virtual function - should not be called!"); }; - }; - -class SS_ParameterCheckBox : public QCheckBox, public SS_ParameterWidget - { - Q_OBJECT - - public: - SS_ParameterCheckBox(QWidget* parent, LadspaPlugin* in_plugin, int in_id, int in_parameter, const char* name = 0) - : QCheckBox(parent, name) , SS_ParameterWidget() - { - SS_TRACE_IN - plugin = in_plugin; - fxid = in_id; - parameter = in_parameter; - connect(this, SIGNAL(clicked()), SLOT(isClicked())); - SS_TRACE_OUT - } - - virtual void setParamValue(int val) { SS_TRACE_IN setChecked(val); SS_TRACE_OUT} - - private slots: - void isClicked() { SS_TRACE_IN emit valueChanged(fxid, parameter, (int)this->isOn()); SS_TRACE_OUT} - - signals: - void valueChanged(int id, int param, int val); - }; - -class SS_ParameterSlider : public QSlider, public SS_ParameterWidget - { - Q_OBJECT - - public: - SS_ParameterSlider(QWidget* parent, LadspaPlugin* in_plugin, int in_id, int in_parameter, const char* name = 0) - : QSlider(Qt::Horizontal, parent, name), SS_ParameterWidget() - { - SS_TRACE_IN - plugin = in_plugin; - fxid = in_id; - parameter = in_parameter; - SS_TRACE_OUT - } - - virtual void setParamValue(int val) { SS_TRACE_IN setValue(val); SS_TRACE_OUT} - - public slots: - virtual void setValue(int val) { SS_TRACE_IN QSlider::setValue(val); emit valueChanged(fxid, parameter, val); SS_TRACE_OUT } - - signals: - void valueChanged(int id, int param, int val); - }; - -typedef std::list<SS_ParameterWidget*> SS_ParameterWidgetList; -typedef std::list<SS_ParameterWidget*>::iterator SS_iParameterWidgetList ; - -//------------------------------- -// SS_PluginChooser -//------------------------------- -class SS_PluginChooser : public SS_PluginChooserBase -{ - Q_OBJECT - private: - LadspaPlugin* selectedPlugin; - protected: - - public: - SS_PluginChooser(QWidget* parent, const char* name=0); - LadspaPlugin* getSelectedPlugin() { SS_TRACE_IN SS_TRACE_OUT return selectedPlugin; } - - private slots: - void okPressed(); - void cancelPressed(); - void selectionChanged(Q3ListViewItem* item); - void doubleClicked(Q3ListViewItem* item); - - private: - Q3ListViewItem* selectedItem; - LadspaPlugin* findSelectedPlugin(); - -}; - -//------------------------------- -// SS_PluginGuiFront -//------------------------------- -class SS_PluginFront : public Q3GroupBox - { - Q_OBJECT - private: - Q3HBoxLayout* layout; - Q3VBoxLayout* expLayout; - QLineEdit* pluginName; - QCheckBox* onOff; - QPushButton* loadFxButton; - QPushButton* clearFxButton; - QPushButton* expandButton; - QSlider* outGainSlider; - SS_PluginChooser* pluginChooser; - LadspaPlugin* plugin; - Q3ButtonGroup* expGroup; - - int fxid; - bool expanded; - - //For effect parameters: - SS_ParameterWidgetList paramWidgets; - - protected: - - public: - SS_PluginFront(QWidget* parent, int id, const char* name = 0); - void setPluginName(QString name); - ~SS_PluginFront(); - void updatePluginValue(unsigned i); - void clearPluginDisplay(); - void setParameterValue(int param, int val); - void setRetGain(int val); - - protected: - virtual QSize sizeHint() const; - virtual QSizePolicy sizePolicy() const; - - private slots: - void loadButton(); - void returnSliderMoved(int val); - void onOffToggled(bool state); - void clearButtonPressed(); - void expandButtonPressed(); - void parameterValueChanged(int fxid, int parameter, int val); - - signals: - void loadPlugin(int fxid, QString lib, QString name); - void returnLevelChanged(int fxid, int val); - void fxToggled(int fxid, int state); - void clearPlugin(int fxid); - void sizeChanged(int fxid, int val); - void effectParameterChanged(int fxid, int param, int val); - - private: - void createPluginParameters(); - }; - - -//------------------------------- -// SS_PluginGui -// Main plugin class, dialog -//------------------------------- -class SS_PluginGui : public QDialog - { - Q_OBJECT - private: - Q3VBoxLayout* layout; - SS_PluginFront* pluginFronts[4]; - - public: - SS_PluginGui(QWidget* parent, const char* name = 0); - SS_PluginFront* getPluginFront(unsigned i); - ~SS_PluginGui() {} -private slots: - void pluginFrontSizeChanged(int fxid, int val); - }; - - -#endif - diff --git a/muse2/synti/simpledrums2/common.h b/muse2/synti/simpledrums2/common.h index e4763540..f31ca7ce 100644 --- a/muse2/synti/simpledrums2/common.h +++ b/muse2/synti/simpledrums2/common.h @@ -16,11 +16,11 @@ #define SS_VERSIONSTRING "1.0" -#define SS_DEBUG 0 +#define SS_DEBUG 0 #define SS_DEBUG_INIT 0 #define SS_TRACE_FUNC 0 #define SS_DEBUG_MIDI 0 -#define SS_DEBUG_LADSPA 0 +#define SS_DEBUG_LADSPA 0 #define SS_DEBUG_STATE 0 #define SS_DBG(string) if (SS_DEBUG) fprintf(stderr, "%s:%d:%s: %s\n", __FILE__ , __LINE__ , __PRETTY_FUNCTION__, string); @@ -34,6 +34,7 @@ #define SS_DBG_LADSPA2(string1, string2) if (SS_DEBUG_LADSPA) fprintf(stderr, "%s:%d:%s: %s: %s\n", __FILE__ , __LINE__ , __PRETTY_FUNCTION__, string1, string2); #define SS_SYSEX_INIT_DATA_VERSION 1 +#define SS_SYSEX_EFFECT_INIT_DATA_VERSION 2 // Added Jun 15 2011. Original value was SS_SYSEX_INIT_DATA_VERSION (1). p4.0.27 Tim. #define SS_NR_OF_CHANNELS 16 #define SS_AUDIO_CHANNELS 2 diff --git a/muse2/synti/simpledrums2/common_defs.h b/muse2/synti/simpledrums2/common_defs.h new file mode 100644 index 00000000..b3745a1d --- /dev/null +++ b/muse2/synti/simpledrums2/common_defs.h @@ -0,0 +1,8 @@ +#ifndef __SIMPLEDRUMS_UNIQUE_ID_H +#define __SIMPLEDRUMS_UNIQUE_ID_H + +// Make sure this number is unique among all the MESS synths. +#define SIMPLEDRUMS_UNIQUE_ID 4 + +#endif + diff --git a/muse2/synti/simpledrums2/simpledrums.cpp b/muse2/synti/simpledrums2/simpledrums.cpp index f14a0627..80f61102 100644 --- a/muse2/synti/simpledrums2/simpledrums.cpp +++ b/muse2/synti/simpledrums2/simpledrums.cpp @@ -5,6 +5,7 @@ // // // Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 +// Contributer: (C) Copyright 2011 Tim E. Real (terminator356 at users.sourceforge.net) // // Copyright: See COPYING file that comes with this distribution // @@ -14,6 +15,7 @@ #include "muse/midi.h" //#include "libsynti/mpevent.h" #include "muse/mpevent.h" +//#include "common_defs.h" #include "simpledrums.h" #include <samplerate.h> @@ -82,6 +84,9 @@ SimpleSynth::SimpleSynth(int sr) SS_samplerate = sr; SS_initPlugins(); + initBuffer = 0; + initLen = 0; + simplesynth_ptr = this; master_vol = 100.0 / SS_MASTER_VOLUME_QUOT; master_vol_ctrlval = 100; @@ -203,6 +208,9 @@ SimpleSynth::~SimpleSynth() { SS_TRACE_IN + if(gui) + delete gui; // p4.0.27 + // Cleanup channels and samples: SS_DBG("Cleaning up sample data"); for (int i=0; i<SS_NR_OF_CHANNELS; i++) { @@ -233,9 +241,21 @@ SimpleSynth::~SimpleSynth() SS_DBG("Deleting process buffer"); delete[] processBuffer[0]; delete[] processBuffer[1]; + if (initBuffer) + { + SS_DBG("Deleting init buffer"); + delete [] initBuffer; + } SS_TRACE_OUT } +int SimpleSynth::oldMidiStateHeader(const unsigned char** data) const +{ + unsigned char const d[2] = {MUSE_SYNTH_SYSEX_MFG_ID, SIMPLEDRUMS_UNIQUE_ID}; + *data = &d[0]; + return 2; +} + //--------------------------------------------------------- // nativeGuiVisible /*! @@ -299,7 +319,8 @@ bool SimpleSynth::playNote(int /*channel*/, int pitch, int velo) } else { //Note off: - if (channels[ch].noteoff_ignore) { + ///if (channels[ch].noteoff_ignore) { + if (!channels[ch].noteoff_ignore) { // p4.0.27 if (SS_DEBUG_MIDI) { printf("Note off on channel %d\n", ch); } @@ -497,8 +518,17 @@ bool SimpleSynth::setController(int channel, int id, int val, bool /*fromGui*/) \return false for ok, true for not ok */ //--------------------------------------------------------- -bool SimpleSynth::sysex(int /*len*/, const unsigned char* data) +bool SimpleSynth::sysex(int len, const unsigned char* d) + { + if(len < 3 || d[0] != MUSE_SYNTH_SYSEX_MFG_ID + || d[1] != SIMPLEDRUMS_UNIQUE_ID) { + if (SS_DEBUG_MIDI) + printf("MusE SimpleDrums: Unknown sysex header\n"); + return false; + } + + const unsigned char* data = d + 2; SS_TRACE_IN int cmd = data[0]; switch (cmd) { @@ -565,20 +595,23 @@ bool SimpleSynth::sysex(int /*len*/, const unsigned char* data) { int initdata_len = 0; const byte* tmp_initdata = NULL; - byte* event_data = NULL; + ///byte* event_data = NULL; getInitData(&initdata_len, &tmp_initdata); - int totlen = initdata_len + 1; - - event_data = new byte[initdata_len + 1]; - event_data[0] = SS_SYSEX_SEND_INIT_DATA; - memcpy(event_data + 1, tmp_initdata, initdata_len); - delete[] tmp_initdata; - tmp_initdata = NULL; - - MidiPlayEvent ev(0, 0, ME_SYSEX, event_data, totlen); + ///int totlen = initdata_len + 1; + + ///event_data = new byte[initdata_len + 1]; + ///event_data[0] = SS_SYSEX_SEND_INIT_DATA; + *((byte*)(tmp_initdata) + 1) = SS_SYSEX_SEND_INIT_DATA; // Re-use the synth ID byte as the command byte. + + ///memcpy(event_data + 1, tmp_initdata, initdata_len); + ///delete[] tmp_initdata; + ///tmp_initdata = NULL; + + ///MidiPlayEvent ev(0, 0, ME_SYSEX, event_data, totlen); + MidiPlayEvent ev(0, 0, ME_SYSEX, tmp_initdata + 1, initdata_len - 1); // Strip MFG ID. gui->writeEvent(ev); - delete[] event_data; + ///delete[] event_data; break; } @@ -639,7 +672,7 @@ const MidiPatch* SimpleSynth::getPatchInfo(int index, const MidiPatch* patch) co \return 0 when done, otherwise return next desired controller index */ //--------------------------------------------------------- -int SimpleSynth::getControllerInfo(int index, const char** name, int* controller, int* min, int* max) +int SimpleSynth::getControllerInfo(int index, const char** name, int* controller, int* min, int* max, int* initval) const { SS_TRACE_IN if (index >= SS_NR_OF_CONTROLLERS) { @@ -652,7 +685,9 @@ int SimpleSynth::getControllerInfo(int index, const char** name, int* controller *min = controllers[index].min; *max = controllers[index].max; - if (SS_DEBUG_MIDI) { + *initval = 0; // p4.0.27 FIXME NOTE TODO + + if (SS_DEBUG_MIDI) { printf("setting controller info: index %d name %s controller %d min %d max %d\n", index, *name, *controller, *min, *max); } SS_TRACE_OUT @@ -660,6 +695,31 @@ int SimpleSynth::getControllerInfo(int index, const char** name, int* controller } //--------------------------------------------------------- +// processMessages +// Called from host always, even if output path is unconnected. +//--------------------------------------------------------- + +void SimpleSynth::processMessages() +{ + //Process messages from the gui + while (gui->fifoSize()) { + MidiPlayEvent ev = gui->readEvent(); + if (ev.type() == ME_SYSEX) { + sysex(ev.len(), ev.data()); + sendEvent(ev); + } + else if (ev.type() == ME_CONTROLLER) { + setController(ev.channel(), ev.dataA(), ev.dataB(), true); + sendEvent(ev); + } + else { + if (SS_DEBUG) + printf("SimpleSynth::process(): unknown event, type: %d\n", ev.type()); + } + } +} + +//--------------------------------------------------------- // process /*! \fn SimpleSynth::process @@ -671,6 +731,7 @@ int SimpleSynth::getControllerInfo(int index, const char** name, int* controller //--------------------------------------------------------- void SimpleSynth::process(float** out, int offset, int len) { + /* //Process messages from the gui while (gui->fifoSize()) { MidiPlayEvent ev = gui->readEvent(); @@ -687,7 +748,8 @@ void SimpleSynth::process(float** out, int offset, int len) printf("SimpleSynth::process(): unknown event, type: %d\n", ev.type()); } } - + */ + if (synth_state == SS_RUNNING) { //Temporary mix-doubles @@ -843,6 +905,19 @@ bool SimpleSynth::init(const char* name) } //--------------------------------------------------------- +// getInitBuffer +//--------------------------------------------------------- +void SimpleSynth::setupInitBuffer(int len) +{ + if (len > initLen) { + if (initBuffer) + delete [] initBuffer; + initBuffer = new byte[len]; + initLen = len; + } +} + +//--------------------------------------------------------- /*! \fn SimpleSynth::getInitData \brief Data for reinitialization of SimpleSynth when loading project @@ -850,7 +925,8 @@ bool SimpleSynth::init(const char* name) \param data - data that is sent as a sysex to the synth on reload of project */ //--------------------------------------------------------- -void SimpleSynth::getInitData(int* n, const unsigned char** data) +//void SimpleSynth::getInitData(int* n, const unsigned char** data) const +void SimpleSynth::getInitData(int* n, const unsigned char** data) { SS_TRACE_IN // Calculate length of data @@ -877,7 +953,10 @@ void SimpleSynth::getInitData(int* n, const unsigned char** data) int labelnamelen = plugin->label().size() + 2; len+=(namelen + labelnamelen); - len+=3; //1 byte for nr of parameters, 1 byte for return gain, 1 byte for effect on/off + ///len+=3; //1 byte for nr of parameters, 1 byte for return gain, 1 byte for effect on/off + // p4.0.27 Tim. + len+=6; //4 bytes for nr of parameters, 1 byte for return gain, 1 byte for effect on/off + len+=sendEffects[i].nrofparameters; // 1 byte for each parameter value } else { @@ -885,17 +964,29 @@ void SimpleSynth::getInitData(int* n, const unsigned char** data) } } + len += 2; // For header. + // First, SS_SYSEX_INIT_DATA - byte* buffer = new byte[len]; - memset(buffer, 0, len); - buffer[0] = SS_SYSEX_INIT_DATA; - buffer[1] = SS_SYSEX_INIT_DATA_VERSION; + + ///byte* buffer = new byte[len]; + setupInitBuffer(len); + + memset(initBuffer, 0, len); + //initBuffer[0] = SS_SYSEX_INIT_DATA; + //initBuffer[1] = SS_SYSEX_INIT_DATA_VERSION; + initBuffer[0] = MUSE_SYNTH_SYSEX_MFG_ID; + initBuffer[1] = SIMPLEDRUMS_UNIQUE_ID; + initBuffer[2] = SS_SYSEX_INIT_DATA; + initBuffer[3] = SS_SYSEX_INIT_DATA_VERSION; if (SS_DEBUG_INIT) { printf("Length of init data: %d\n", len); - printf("buffer[0] - SS_SYSEX_INIT_DATA: %d\n", SS_SYSEX_INIT_DATA); - printf("buffer[1] - SS_SYSEX_INIT_DATA_VERSION: %d\n", SS_SYSEX_INIT_DATA_VERSION); + //printf("initBuffer[0] - SS_SYSEX_INIT_DATA: %d\n", SS_SYSEX_INIT_DATA); + //printf("initBuffer[1] - SS_SYSEX_INIT_DATA_VERSION: %d\n", SS_SYSEX_INIT_DATA_VERSION); + printf("initBuffer[2] - SS_SYSEX_INIT_DATA: %d\n", SS_SYSEX_INIT_DATA); + printf("initBuffer[3] - SS_SYSEX_INIT_DATA_VERSION: %d\n", SS_SYSEX_INIT_DATA_VERSION); } - int i = 2; + //int i = 2; + int i = 4; // All channels: // 0 - volume ctrlval (0-127) // 1 - pan (0-127) @@ -905,71 +996,75 @@ void SimpleSynth::getInitData(int* n, const unsigned char** data) // 8 - len of filename, n // 9 - 9+n - filename for (int ch=0; ch<SS_NR_OF_CHANNELS; ch++) { - buffer[i] = (byte) channels[ch].volume_ctrlval; - buffer[i+1] = (byte) channels[ch].pan; - buffer[i+2] = (byte) channels[ch].noteoff_ignore; - buffer[i+3] = (byte) channels[ch].channel_on; - buffer[i+4] = (byte) round(channels[ch].sendfxlevel[0] * 127.0); - buffer[i+5] = (byte) round(channels[ch].sendfxlevel[1] * 127.0); - buffer[i+6] = (byte) round(channels[ch].sendfxlevel[2] * 127.0); - buffer[i+7] = (byte) round(channels[ch].sendfxlevel[3] * 127.0); + initBuffer[i] = (byte) channels[ch].volume_ctrlval; + initBuffer[i+1] = (byte) channels[ch].pan; + initBuffer[i+2] = (byte) channels[ch].noteoff_ignore; + initBuffer[i+3] = (byte) channels[ch].channel_on; + initBuffer[i+4] = (byte) round(channels[ch].sendfxlevel[0] * 127.0); + initBuffer[i+5] = (byte) round(channels[ch].sendfxlevel[1] * 127.0); + initBuffer[i+6] = (byte) round(channels[ch].sendfxlevel[2] * 127.0); + initBuffer[i+7] = (byte) round(channels[ch].sendfxlevel[3] * 127.0); if (SS_DEBUG_INIT) { printf("Channel %d:\n", ch); - printf("buffer[%d] - channels[ch].volume_ctrlval = \t%d\n", i, channels[ch].volume_ctrlval); - printf("buffer[%d] - channels[ch].pan = \t\t%d\n", i+1, channels[ch].pan); - printf("buffer[%d] - channels[ch].noteoff_ignore = \t%d\n", i+2, channels[ch].noteoff_ignore ); - printf("buffer[%d] - channels[ch].channel_on = \t%d\n", i+3, channels[ch].channel_on); + printf("initBuffer[%d] - channels[ch].volume_ctrlval = \t%d\n", i, channels[ch].volume_ctrlval); + printf("initBuffer[%d] - channels[ch].pan = \t\t%d\n", i+1, channels[ch].pan); + printf("initBuffer[%d] - channels[ch].noteoff_ignore = \t%d\n", i+2, channels[ch].noteoff_ignore ); + printf("initBuffer[%d] - channels[ch].channel_on = \t%d\n", i+3, channels[ch].channel_on); for (int j= i+4; j < i+8; j++) { - printf("buffer[%d] - channels[ch].sendfxlevel[%d]= \t%d\n", j, j-i-4, (int)round(channels[ch].sendfxlevel[j-i-4] * 127.0)); + printf("initBuffer[%d] - channels[ch].sendfxlevel[%d]= \t%d\n", j, j-i-4, (int)round(channels[ch].sendfxlevel[j-i-4] * 127.0)); } } if (channels[ch].sample) { int filenamelen = strlen(channels[ch].sample->filename.c_str()) + 1; - buffer[i+8] = (byte) filenamelen; - memcpy((buffer+(i+9)), channels[ch].sample->filename.c_str(), filenamelen); + initBuffer[i+8] = (byte) filenamelen; + memcpy((initBuffer+(i+9)), channels[ch].sample->filename.c_str(), filenamelen); if (SS_DEBUG_INIT) { - printf("buffer[%d] - filenamelen: %d\n", i+8, filenamelen); - printf("buffer[%d] - buffer[%d] - filename: ", (i+9), (i+9) + filenamelen - 1); + printf("initBuffer[%d] - filenamelen: %d\n", i+8, filenamelen); + printf("initBuffer[%d] - initBuffer[%d] - filename: ", (i+9), (i+9) + filenamelen - 1); for (int j = i+9; j< i+9+filenamelen; j++) { - printf("%c",buffer[j]); + printf("%c",initBuffer[j]); } printf("\n"); } i+= (SS_NR_OF_CHANNEL_CONTROLLERS + 1 + filenamelen); } else { - buffer[i+8] = SS_NO_SAMPLE; + initBuffer[i+8] = SS_NO_SAMPLE; if (SS_DEBUG_INIT) { - printf("buffer[%d]: SS_NO_SAMPLE: - %d\n", i+8, SS_NO_SAMPLE); + printf("initBuffer[%d]: SS_NO_SAMPLE: - %d\n", i+8, SS_NO_SAMPLE); } i+= (SS_NR_OF_CHANNEL_CONTROLLERS + 1); } } if (SS_DEBUG_INIT) { - printf("buffer[%d]: Master vol: - %d\n", i, master_vol_ctrlval); + printf("initBuffer[%d]: Master vol: - %d\n", i, master_vol_ctrlval); } - buffer[i] = master_vol_ctrlval; - *(data) = buffer; *n = len; + initBuffer[i] = master_vol_ctrlval; + *(data) = initBuffer; *n = len; i++; //Send effects: - buffer[i] = SS_SYSEX_INIT_DATA_VERSION; //Just for check + + ///initBuffer[i] = SS_SYSEX_INIT_DATA_VERSION; //Just for check + // Jun 10 2011. Bumped version up from 1 (with its own ID). p4.0.27 Tim + initBuffer[i] = SS_SYSEX_EFFECT_INIT_DATA_VERSION; //Just for check + if (SS_DEBUG_INIT) { - printf("buffer[%d]: Control value, SS_SYSEX_INIT_DATA_VERSION\n", i); + printf("initBuffer[%d]: Control value, SS_SYSEX_EFFECT_INIT_DATA_VERSION = %d\n", i, SS_SYSEX_EFFECT_INIT_DATA_VERSION); } i++; for (int j=0; j<SS_NR_OF_SENDEFFECTS; j++) { if (sendEffects[j].plugin) { int labelnamelen = sendEffects[j].plugin->label().size() + 1; - buffer[i] = labelnamelen; - memcpy((buffer+i+1), sendEffects[j].plugin->label().toLatin1().constData(), labelnamelen); + initBuffer[i] = labelnamelen; + memcpy((initBuffer+i+1), sendEffects[j].plugin->label().toLatin1().constData(), labelnamelen); if (SS_DEBUG_INIT) { - printf("buffer[%d] - labelnamelen: %d\n", i, labelnamelen); - printf("buffer[%d] - buffer[%d] - filename: ", (i+1), (i+1) + labelnamelen - 1); + printf("initBuffer[%d] - labelnamelen: %d\n", i, labelnamelen); + printf("initBuffer[%d] - initBuffer[%d] - filename: ", (i+1), (i+1) + labelnamelen - 1); for (int k = i+1; k < i+1+labelnamelen; k++) { - printf("%c",buffer[k]); + printf("%c",initBuffer[k]); } printf("\n"); } @@ -977,45 +1072,55 @@ void SimpleSynth::getInitData(int* n, const unsigned char** data) i+=(labelnamelen + 1); int namelen = sendEffects[j].plugin->lib().size() + 1; - buffer[i] = namelen; - memcpy((buffer+i+1), sendEffects[j].plugin->lib().toLatin1().constData(), namelen); + initBuffer[i] = namelen; + memcpy((initBuffer+i+1), sendEffects[j].plugin->lib().toLatin1().constData(), namelen); if (SS_DEBUG_INIT) { - printf("buffer[%d] - libnamelen : %d\n", i, namelen); - printf("buffer[%d] - buffer[%d] - filename: ", (i+1), (i+1) + namelen - 1); + printf("initBuffer[%d] - libnamelen : %d\n", i, namelen); + printf("initBuffer[%d] - initBuffer[%d] - filename: ", (i+1), (i+1) + namelen - 1); for (int k = i+1; k < i+1+namelen; k++) { - printf("%c",buffer[k]); + printf("%c",initBuffer[k]); } printf("\n"); } i+=(namelen + 1); - buffer[i]=sendEffects[j].nrofparameters; + ///initBuffer[i]=sendEffects[j].nrofparameters; + // Jun 10 2011. Changed to 32 bit. p4.0.27 Tim. + *((unsigned*)&initBuffer[i]) = sendEffects[j].nrofparameters; if (SS_DEBUG_INIT) { - printf("buffer[%d]: sendEffects[%d].nrofparameters=%d\n", i, j, buffer[i]); + printf("initBuffer[%d]: sendEffects[%d].nrofparameters=%d\n", i, j, *((unsigned*)&initBuffer[i])); + } + ///i++; + i+=4; + + initBuffer[i]=sendEffects[j].retgain_ctrlval; + if (SS_DEBUG_INIT) { + printf("initBuffer[%d]: sendEffects[%d].retgain_ctrlval=%d\n", i, j, initBuffer[i]); } i++; - buffer[i]=sendEffects[j].retgain_ctrlval; + // Jun 10 2011. This one was missing. p4.0.27 Tim. + initBuffer[i] = sendEffects[j].state; if (SS_DEBUG_INIT) { - printf("buffer[%d]: sendEffects[%d].retgain_ctrlval=%d\n", i, j, buffer[i]); + printf("initBuffer[%d]: sendEffects[%d].state=%d\n", i, j, initBuffer[i]); } i++; for (int k=0; k<sendEffects[j].nrofparameters; k++) { //TODO: Convert to 127-scale - buffer[i] = sendEffects[j].plugin->getGuiControlValue(k); + initBuffer[i] = sendEffects[j].plugin->getGuiControlValue(k); if (SS_DEBUG_INIT) { - printf("buffer[%d]: sendEffects[%d].parameterval[%d]=%d\n", i, j, k, buffer[i]); + printf("initBuffer[%d]: sendEffects[%d].parameterval[%d]=%d\n", i, j, k, initBuffer[i]); } i++; } } // No plugin loaded: else { - buffer[i] = SS_NO_PLUGIN; + initBuffer[i] = SS_NO_PLUGIN; if (SS_DEBUG_INIT) { - printf("buffer[%d]: SS_NO_PLUGIN\n", i); + printf("initBuffer[%d]: SS_NO_PLUGIN\n", i); } i++; } @@ -1118,11 +1223,15 @@ void SimpleSynth::parseInitData(const unsigned char* data) ptr++; // Effects: - if (*(ptr) != SS_SYSEX_INIT_DATA_VERSION) { - fprintf(stderr, "Error loading init data - control byte not found. Skipping...\n"); + ///if (*(ptr) != SS_SYSEX_INIT_DATA_VERSION) { + int effver = *(ptr); + if (effver < 1 || effver > SS_SYSEX_EFFECT_INIT_DATA_VERSION) { + //if (SS_DEBUG_INIT) + fprintf(stderr, "Error loading init data - effect init version is from future or too old. Skipping...\n"); SS_TRACE_OUT return; } + ptr++; for (int i=0; i<SS_NR_OF_SENDEFFECTS; i++) { @@ -1149,9 +1258,14 @@ void SimpleSynth::parseInitData(const unsigned char* data) initSendEffect(i, libnametmp.c_str(), labelnametmp.c_str()); //initSendEffect(0, "cmt", "freeverb3"); - byte params = *(ptr); - byte retgain = *(ptr+1); - ptr+=2; + ///byte params = *(ptr); + unsigned params = (effver < 2) ? *(ptr) : *((unsigned*)ptr); // p4.0.27 + ptr+= (effver < 2) ? 1 : 4; + + ///byte retgain = *(ptr+1); + ///ptr+=2; + byte retgain = *(ptr); // p4.0.27 + ptr++; sendEffects[i].nrofparameters = params; @@ -1161,7 +1275,19 @@ void SimpleSynth::parseInitData(const unsigned char* data) MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_PLUGIN_RETURNLEVEL_CONTROLLER(i), retgain); gui->writeEvent(ev); - for (int j=0; j<params; j++) { + // Jun 10 2011. This one was missing. p4.0.27 Tim. + if(effver >= 2) + { + if (SS_DEBUG_INIT) + printf("buffer[%ld] - sendeffect[%d] state=%d\n", long(ptr-data), i, *(ptr)); + sendEffects[i].state = (SS_SendFXState) *(ptr); + MidiPlayEvent ev(0, 0, 0, ME_CONTROLLER, SS_PLUGIN_ONOFF_CONTROLLER(i), sendEffects[i].state); + gui->writeEvent(ev); + ptr++; + } + + ///for (int j=0; j<params; j++) { + for (unsigned j=0; j<params; j++) { if (SS_DEBUG_INIT){ //wilyfoobar-2011-02-13 // arg2 :pointer diifference might be 64 bit (long long) on 64 bit machine, this requires cast to long @@ -1481,16 +1607,23 @@ void SimpleSynth::guiSendSampleLoaded(bool success, int ch, const char* filename { SS_TRACE_IN int len = strlen(filename) + 3; //2 + filenamelen + 1; + //int len = strlen(filename) + 3 + 2; //2 + filenamelen + 1, + 2 for header; byte out[len]; + //out[0] = MUSE_SYNTH_SYSEX_MFG_ID; + //out[1] = SIMPLEDRUMS_UNIQUE_ID; if (success) { out[0] = SS_SYSEX_LOAD_SAMPLE_OK; + //out[2] = SS_SYSEX_LOAD_SAMPLE_OK; } else { out[0] = SS_SYSEX_LOAD_SAMPLE_ERROR; + //out[2] = SS_SYSEX_LOAD_SAMPLE_ERROR; } out[1] = ch; + //out[3] = ch; memcpy(out+2, filename, strlen(filename)+1); + //memcpy(out+4, filename, strlen(filename)+1); MidiPlayEvent ev(0, 0, ME_SYSEX, out, len); gui->writeEvent(ev); SS_TRACE_OUT @@ -1504,8 +1637,13 @@ void SimpleSynth::guiSendError(const char* errorstring) { SS_TRACE_IN byte out[strlen(errorstring)+2]; + //byte out[strlen(errorstring)+4]; + //out[0] = MUSE_SYNTH_SYSEX_MFG_ID; + //out[1] = SIMPLEDRUMS_UNIQUE_ID; out[0] = SS_SYSEX_ERRORMSG; + //out[2] = SS_SYSEX_ERRORMSG; memcpy(out+1, errorstring, strlen(errorstring) +1); + //memcpy(out+3, errorstring, strlen(errorstring) +1); SS_TRACE_OUT } @@ -1590,15 +1728,24 @@ bool SimpleSynth::initSendEffect(int id, QString lib, QString name) //TODO: cleanup if failed } } + //Notify gui - int len = 3; + ///int len = 3; + int len = 2 + 4; // Char is not enough for many plugins. Was causing crash. Changed to 32 bits. p4.0.27 Tim. + //int len = 5; byte out[len]; out[0] = SS_SYSEX_LOAD_SENDEFFECT_OK; out[1] = id; + //out[0] = MUSE_SYNTH_SYSEX_MFG_ID; + //out[1] = SIMPLEDRUMS_UNIQUE_ID; + //out[2] = SS_SYSEX_LOAD_SENDEFFECT_OK; + //out[3] = id; int j=0; for (iPlugin i = plugins.begin(); i!=plugins.end(); i++, j++) { if ((*i)->lib() == plugin->lib() && (*i)->label() == plugin->label()) { - out[2] = j; + ///out[2] = j; + //out[4] = j; + *((unsigned*)(out + 2)) = j; MidiPlayEvent ev(0, 0, ME_SYSEX, out, len); gui->writeEvent(ev); } @@ -1638,9 +1785,15 @@ void SimpleSynth::cleanupPlugin(int id) sendEffects[id].plugin = 0; byte d[2]; + //byte d[4]; d[0] = SS_SYSEX_CLEAR_SENDEFFECT_OK; d[1] = id; + //d[0] = MUSE_SYNTH_SYSEX_MFG_ID; + //d[1] = SIMPLEDRUMS_UNIQUE_ID; + //d[2] = SS_SYSEX_CLEAR_SENDEFFECT_OK; + //d[3] = id; MidiPlayEvent ev(0, 0, ME_SYSEX, d, 2); + //MidiPlayEvent ev(0, 0, ME_SYSEX, d, 4); gui->writeEvent(ev); SS_TRACE_OUT } @@ -1694,11 +1847,19 @@ void SimpleSynth::guiUpdateFxParameter(int fxid, int param, float val) } byte d[4]; + //byte d[6]; d[0] = SS_SYSEX_SET_PLUGIN_PARAMETER_OK; d[1] = fxid; d[2] = param; d[3] = intval; + //d[0] = MUSE_SYNTH_SYSEX_MFG_ID; + //d[1] = SIMPLEDRUMS_UNIQUE_ID; + //d[2] = SS_SYSEX_SET_PLUGIN_PARAMETER_OK; + //d[3] = fxid; + //d[4] = param; + //d[5] = intval; MidiPlayEvent ev(0, 0, ME_SYSEX, d, 4); + //MidiPlayEvent ev(0, 0, ME_SYSEX, d, 6); gui->writeEvent(ev); SS_TRACE_OUT } @@ -1742,9 +1903,15 @@ void SimpleSynth::guiNotifySampleCleared(int ch) { SS_TRACE_IN byte d[2]; + //byte d[4]; d[0] = SS_SYSEX_CLEAR_SAMPLE_OK; d[1] = (byte) ch; + //d[0] = MUSE_SYNTH_SYSEX_MFG_ID; + //d[1] = SIMPLEDRUMS_UNIQUE_ID; + //d[2] = SS_SYSEX_CLEAR_SAMPLE_OK; + //d[3] = (byte) ch; MidiPlayEvent ev(0, 0, ME_SYSEX, d, 2); + //MidiPlayEvent ev(0, 0, ME_SYSEX, d, 4); gui->writeEvent(ev); SS_TRACE_OUT } diff --git a/muse2/synti/simpledrums2/simpledrums.h b/muse2/synti/simpledrums2/simpledrums.h index 58a5945e..f0339d6a 100644 --- a/muse2/synti/simpledrums2/simpledrums.h +++ b/muse2/synti/simpledrums2/simpledrums.h @@ -5,6 +5,7 @@ // // // Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 +// Contributer: (C) Copyright 2011 Tim E. Real (terminator356 at users.sourceforge.net) // // Copyright: See COPYING file that comes with this distribution // @@ -15,6 +16,7 @@ #include <sndfile.h> #include "libsynti/mess.h" #include "common.h" +#include "common_defs.h" //#include "libsynti/mpevent.h" #include "muse/mpevent.h" #include "simpledrumsgui.h" @@ -124,11 +126,15 @@ class SimpleSynth : public Mess virtual bool sysex(int arg1, const unsigned char* arg2); virtual const char* getPatchName(int arg1, int arg2, int arg3) const; virtual const MidiPatch* getPatchInfo(int arg1, const MidiPatch* arg2) const; - virtual int getControllerInfo(int arg1, const char** arg2, int* arg3, int* arg4, int* arg5); + virtual int getControllerInfo(int arg1, const char** arg2, int* arg3, int* arg4, int* arg5, int* arg6) const; + virtual void processMessages(); virtual void process(float** data, int offset, int len); //virtual void showGui(bool arg1); virtual void showNativeGui(bool arg1); + ///virtual void getInitData(int*, const unsigned char**) const; virtual void getInitData(int*, const unsigned char**); + // This is only a kludge required to support old songs' midistates. Do not use in any new synth. + virtual int oldMidiStateHeader(const unsigned char** data) const; bool init(const char* name); void guiSendSampleLoaded(bool success, int ch, const char* filename); void guiSendError(const char* errorstring); @@ -139,6 +145,10 @@ class SimpleSynth : public Mess private: SimpleSynthGui* gui; + byte* initBuffer; + int initLen; + void setupInitBuffer(int len); + SS_Channel channels[SS_NR_OF_CHANNELS]; SS_Controller controllers[SS_NR_OF_CONTROLLERS]; bool setController(int channel, int id, int val, bool fromGui); diff --git a/muse2/synti/simpledrums2/simpledrumsgui.cpp b/muse2/synti/simpledrums2/simpledrumsgui.cpp index f90c1da8..7d314565 100644 --- a/muse2/synti/simpledrums2/simpledrumsgui.cpp +++ b/muse2/synti/simpledrums2/simpledrumsgui.cpp @@ -5,6 +5,7 @@ // // // Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 +// Contributer: (C) Copyright 2011 Tim E. Real (terminator356 at users.sourceforge.net) // // Copyright: See COPYING file that comes with this distribution // @@ -19,6 +20,7 @@ #include <QLineEdit> #include <QMessageBox> +#include "common_defs.h" #include "simpledrumsgui.h" //#include "libsynti/mpevent.h" #include "muse/mpevent.h" @@ -85,10 +87,16 @@ SimpleSynthGui* simplesynthgui_ptr; */ QChannelSlider::QChannelSlider(Qt::Orientation orientation, int ch, QWidget* parent) : QSlider(orientation, parent) - { - channel = ch; - } +{ + channel = ch; +} +void QChannelSlider::sliderChange(SliderChange change) +{ + QSlider::sliderChange(change); + if(change == QAbstractSlider::SliderValueChange) + emit valueChanged(channel, value()); +} /*! \fn QChannelSlider::getChannel() @@ -110,6 +118,7 @@ void QChannelSlider::setChannel(int ch) /*! \fn QChannelSlider::setValue(int val) */ +/* void QChannelSlider::setValue(int val) { val = (val > 127 ? 127 : val); @@ -117,10 +126,32 @@ void QChannelSlider::setValue(int val) QSlider::setValue(val); emit valueChanged(channel, val); } +*/ + +QInvertedSlider::QInvertedSlider(Qt::Orientation o, QWidget* parent) + : QSlider(o, parent) +{ + setInvertedAppearance(true); // p4.0.27 +} + +void QInvertedSlider::sliderChange(SliderChange change) +{ + QSlider::sliderChange(change); + if(change == QAbstractSlider::SliderValueChange) + emit invertedValueChanged(value()); +} + +QInvertedChannelSlider::QInvertedChannelSlider(Qt::Orientation o, int channel, QWidget* parent) + : QChannelSlider(o, channel, parent) +{ + setInvertedAppearance(true); // p4.0.27 + //setInvertedControls(true); +} /*! \fn QInvertedChannelSlider::setValue(int val) */ +/* void QInvertedChannelSlider::setValue(int val) { int inverted = this->maximum() - val; @@ -129,10 +160,12 @@ void QInvertedChannelSlider::setValue(int val) QSlider::setValue(val); emit valueChanged(channel, inverted); } +*/ /*! \fn QInvertedSlider::setValue(int val) */ +/* void QInvertedSlider::setValue(int val) { int inverted = this->maximum() - val; @@ -141,7 +174,7 @@ void QInvertedSlider::setValue(int val) emit invertedValueChanged(inverted); QSlider::setValue(val); } - +*/ /*! \fn QChannelCheckbox::QChannelCheckbox(QWidget* parent, int ch) @@ -194,11 +227,20 @@ QChannelDial::QChannelDial(QWidget* parent, int ch, int fxid) /*! \fn QChannelSlider::setValue(int val) */ +/* void QChannelDial::setValue(int val) { QDial::setValue(val); emit valueChanged(channel, sendfxid, val); } +*/ + +void QChannelDial::sliderChange(SliderChange change) +{ + QDial::sliderChange(change); + if(change == QAbstractSlider::SliderValueChange) + emit valueChanged(channel, sendfxid, value()); +} /*! \fn SimpleSynthGui::SimpleSynthGui() @@ -236,10 +278,16 @@ SimpleSynthGui::SimpleSynthGui() inchnlLayout->addWidget(onOff[i]); connect(onOff[i], SIGNAL(channelState(int, bool)), SLOT(channelOnOff(int, bool))); - volumeSliders[i] = new QInvertedChannelSlider(Qt::Vertical, i, channelButtonGroups[i]); + ///volumeSliders[i] = new QInvertedChannelSlider(Qt::Vertical, i, channelButtonGroups[i]); + // By Tim. p4.0.27 Inverted was not correct type. Maybe was work in progress, rest of code was not converted yet? + volumeSliders[i] = new QChannelSlider(Qt::Vertical, i, channelButtonGroups[i]); + volumeSliders[i]->setMinimum(SS_VOLUME_MIN_VALUE); volumeSliders[i]->setMaximum(SS_VOLUME_MAX_VALUE); - volumeSliders[i]->setValue(SS_VOLUME_MAX_VALUE - SS_VOLUME_DEFAULT_VALUE); + + ///volumeSliders[i]->setValue(SS_VOLUME_MAX_VALUE - SS_VOLUME_DEFAULT_VALUE); + volumeSliders[i]->setValue(SS_VOLUME_DEFAULT_VALUE); // p4.0.27 + // volumeSliders[i]->setMinimumSize(SS_VOLSLDR_WIDTH, SS_VOLSLDR_LENGTH); volumeSliders[i]->setToolTip("Volume, channel " + QString::number(i + 1)); // setMinimumSize(SS_VOLSLDR_WIDTH, SS_VOLSLDR_LENGTH); @@ -310,13 +358,22 @@ SimpleSynthGui::SimpleSynthGui() QVBoxLayout* mbgLayout = new QVBoxLayout(masterButtonGroup); mbgLayout->setAlignment(Qt::AlignCenter); // masterButtonGroup->setMinimumSize(SS_BTNGRP_WIDTH, SS_BTNGRP_HEIGHT); - masterSlider = new QInvertedSlider(Qt::Vertical, masterButtonGroup); + + ///masterSlider = new QInvertedSlider(Qt::Vertical, masterButtonGroup); + // By Tim. p4.0.27 Inverted was not correct type. Maybe was work in progress, rest of code was not converted yet? + masterSlider = new QSlider(Qt::Vertical, masterButtonGroup); + masterSlider->setToolTip("Master volume"); mbgLayout->addWidget(masterSlider); masterSlider->setRange(0, 127); - masterSlider->setValue(SS_VOLUME_MAX_VALUE - (int)(SS_MASTERVOL_DEFAULT_VALUE*SS_VOLUME_MAX_VALUE)); + + ///masterSlider->setValue(SS_VOLUME_MAX_VALUE - (int)(SS_MASTERVOL_DEFAULT_VALUE*SS_VOLUME_MAX_VALUE)); + masterSlider->setValue((int)(SS_MASTERVOL_DEFAULT_VALUE*SS_VOLUME_MAX_VALUE)); // p4.0.27 + // masterSlider->setMinimumSize(SS_MASTERSLDR_WIDTH, SS_MASTERSLDR_HEIGHT); - connect(masterSlider, SIGNAL(invertedValueChanged(int)), SLOT(masterVolChanged(int))); + + ///connect(masterSlider, SIGNAL(invertedValueChanged(int)), SLOT(masterVolChanged(int))); + connect(masterSlider, SIGNAL(valueChanged(int)), SLOT(masterVolChanged(int))); // p4.0.27 //Main groupbox mainGroupBox = new QGroupBox(this); @@ -435,7 +492,10 @@ void SimpleSynthGui::processEvent(const MidiPlayEvent& ev) switch(id) { case SS_CHANNEL_CTRL_VOLUME: volumeSliders[ch]->blockSignals(true); - volumeSliders[ch]->setValue(SS_VOLUME_MAX_VALUE - val); + + ///volumeSliders[ch]->setValue(SS_VOLUME_MAX_VALUE - val); + volumeSliders[ch]->setValue(val); // p4.0.27 + volumeSliders[ch]->blockSignals(false); break; @@ -479,7 +539,10 @@ void SimpleSynthGui::processEvent(const MidiPlayEvent& ev) else if (id >= SS_FIRST_MASTER_CONTROLLER && id <= SS_LAST_MASTER_CONTROLLER) { if (id == SS_MASTER_CTRL_VOLUME) { masterSlider->blockSignals(true); - masterSlider->setValue(SS_MASTERVOL_MAX_VALUE - val); + + ///masterSlider->setValue(SS_MASTERVOL_MAX_VALUE - val); + masterSlider->setValue(val); // p4.0.27 + masterSlider->blockSignals(false); } } @@ -495,6 +558,13 @@ void SimpleSynthGui::processEvent(const MidiPlayEvent& ev) SS_PluginFront* pf = pluginGui->getPluginFront((unsigned)fxid); pf->setRetGain(val); } + // Plugin on/off: + else if (cmd == SS_PLUGIN_ONOFF) { // p4.0.27 + if (SS_DEBUG_MIDI) + printf("SimpleSynthGui::processEvent - fx onoff received: fxid: %d val: %d\n", fxid, val); + SS_PluginFront* pf = pluginGui->getPluginFront((unsigned)fxid); + pf->setOnOff(val); + } } } // @@ -502,6 +572,7 @@ void SimpleSynthGui::processEvent(const MidiPlayEvent& ev) // else if (ev.type() == ME_SYSEX) { byte* data = ev.data(); + //byte* data = d + 2; int cmd = *data; switch (cmd) { case SS_SYSEX_LOAD_SAMPLE_OK: { @@ -549,7 +620,8 @@ void SimpleSynthGui::processEvent(const MidiPlayEvent& ev) } int fxid = *(data+1); SS_PluginFront* pf = pluginGui->getPluginFront((unsigned)fxid); - pf->updatePluginValue(*(data+2)); + ///pf->updatePluginValue(*(data+2)); + pf->updatePluginValue( *((unsigned*)(data+2)) ); // p4.0.27 break; } @@ -711,13 +783,20 @@ void SimpleSynthGui::loadSampleDialogue(int channel) if (SS_DEBUG) printf("lastDir = %s\n", lastDir.toLatin1().constData()); - int l = filename.length() + 4; + //int l = filename.length() + 4; + int l = filename.length() + 6; byte d[l]; - d[0] = SS_SYSEX_LOAD_SAMPLE; - d[1] = (byte) channel; - d[2] = (byte) filename.length(); - memcpy(d+3, filename.toLatin1().constData(), filename.length()+1); + //d[0] = SS_SYSEX_LOAD_SAMPLE; + //d[1] = (byte) channel; + //d[2] = (byte) filename.length(); + d[0] = MUSE_SYNTH_SYSEX_MFG_ID; + d[1] = SIMPLEDRUMS_UNIQUE_ID; + d[2] = SS_SYSEX_LOAD_SAMPLE; + d[3] = (byte) channel; + d[4] = (byte) filename.length(); + //memcpy(d+3, filename.toLatin1().constData(), filename.length()+1); + memcpy(d+5, filename.toLatin1().constData(), filename.length()+1); sendSysex(d, l); } } @@ -730,10 +809,16 @@ void SimpleSynthGui::loadSampleDialogue(int channel) void SimpleSynthGui::clearSample(int ch) { if (sampleNameLineEdit[ch]->text().length() > 0) { //OK, we've got a live one here - byte d[2]; - d[0] = SS_SYSEX_CLEAR_SAMPLE; - d[1] = (byte) ch; - sendSysex(d, 2); + //byte d[2]; + byte d[4]; + //d[0] = SS_SYSEX_CLEAR_SAMPLE; + //d[1] = (byte) ch; + d[0] = MUSE_SYNTH_SYSEX_MFG_ID; + d[1] = SIMPLEDRUMS_UNIQUE_ID; + d[2] = SS_SYSEX_CLEAR_SAMPLE; + d[3] = (byte) ch; + //sendSysex(d, 2); + sendSysex(d, 4); sampleNameLineEdit[ch]->setText(""); } } @@ -751,12 +836,19 @@ void SimpleSynthGui::displayPluginGui() */ void SimpleSynthGui::loadEffectInvoked(int fxid, QString lib, QString label) { - int l = 4 + lib.length() + label.length(); + //int l = 4 + lib.length() + label.length(); + int l = 6 + lib.length() + label.length(); byte d[l]; - d[0] = SS_SYSEX_LOAD_SENDEFFECT; - d[1] = (byte) fxid; - memcpy (d+2, lib.toLatin1().constData(), lib.length()+1); - memcpy (d+3+lib.length(), label.toLatin1().constData(), label.length()+1); + //d[0] = SS_SYSEX_LOAD_SENDEFFECT; + //d[1] = (byte) fxid; + d[0] = MUSE_SYNTH_SYSEX_MFG_ID; + d[1] = SIMPLEDRUMS_UNIQUE_ID; + d[2] = SS_SYSEX_LOAD_SENDEFFECT; + d[3] = (byte) fxid; + //memcpy (d+2, lib.toLatin1().constData(), lib.length()+1); + //memcpy (d+3+lib.length(), label.toLatin1().constData(), label.length()+1); + memcpy (d+4, lib.toLatin1().constData(), lib.length()+1); + memcpy (d+5+lib.length(), label.toLatin1().constData(), label.length()+1); sendSysex(d, l); } @@ -784,10 +876,16 @@ void SimpleSynthGui::toggleEffectOnOff(int fxid, int state) */ void SimpleSynthGui::clearPlugin(int fxid) { - byte d[2]; - d[0] = SS_SYSEX_CLEAR_SENDEFFECT; - d[1] = fxid; - sendSysex(d, 2); + //byte d[2]; + byte d[4]; + //d[0] = SS_SYSEX_CLEAR_SENDEFFECT; + //d[1] = fxid; + d[0] = MUSE_SYNTH_SYSEX_MFG_ID; + d[1] = SIMPLEDRUMS_UNIQUE_ID; + d[2] = SS_SYSEX_CLEAR_SENDEFFECT; + d[3] = fxid; + //sendSysex(d, 2); + sendSysex(d, 4); } @@ -796,13 +894,19 @@ void SimpleSynthGui::clearPlugin(int fxid) */ void SimpleSynthGui::effectParameterChanged(int fxid, int parameter, int val) { - //printf("Gui: effectParameterChanged: %d %d %d\n", fxid, parameter, val); - int len = 4; + //int len = 4; + int len = 6; byte d[len]; - d[0] = SS_SYSEX_SET_PLUGIN_PARAMETER; - d[1] = (byte) fxid; - d[2] = (byte) parameter; - d[3] = (byte) val; + //d[0] = SS_SYSEX_SET_PLUGIN_PARAMETER; + //d[1] = (byte) fxid; + //d[2] = (byte) parameter; + //d[3] = (byte) val; + d[0] = MUSE_SYNTH_SYSEX_MFG_ID; + d[1] = SIMPLEDRUMS_UNIQUE_ID; + d[2] = SS_SYSEX_SET_PLUGIN_PARAMETER; + d[3] = (byte) fxid; + d[4] = (byte) parameter; + d[5] = (byte) val; sendSysex(d, len); } @@ -826,7 +930,9 @@ void SimpleSynthGui::aboutButtonClicked() { QString caption = "SimpleDrums ver"; caption+= SS_VERSIONSTRING; - QString text = caption + "\n\n(C) Copyright 2000-2004 Mathias Lundgren (lunar_shuttle@users.sf.net), Werner Schweer\nPublished under the GNU Public License"; + ///QString text = caption + "\n\n(C) Copyright 2000-2004 Mathias Lundgren (lunar_shuttle@users.sf.net), Werner Schweer\nPublished under the GNU Public License"; + QString text = caption + "\n\n(C) Copyright 2000-2004 Mathias Lundgren (lunar_shuttle@users.sf.net), Werner Schweer\n" + "Fixes/mods: (C) Copyright 2011 Tim E. Real (terminator356@users.sf.net)\nPublished under the GNU Public License"; QMessageBox* msgBox = new QMessageBox(caption, text, QMessageBox::NoIcon, QMessageBox::Ok, Qt::NoButton, Qt::NoButton, this); msgBox->exec(); @@ -851,8 +957,12 @@ void SimpleSynthGui::loadSetup() if (theFile.read((char*)&initdata_len, sizeof(initdata_len)) == -1) success = false; - byte* init_data = new byte[initdata_len]; - if (theFile.read((char*)(init_data), initdata_len) == -1) + ///byte* init_data = new byte[initdata_len]; + byte* init_data = new byte[initdata_len + 2]; // 2 for MFG ID and synth ID. + init_data[0] = MUSE_SYNTH_SYSEX_MFG_ID; + init_data[1] = SIMPLEDRUMS_UNIQUE_ID; + //if (theFile.read((char*)(init_data), initdata_len) == -1) + if (theFile.read((char*)(init_data + 2), initdata_len) == -1) success = false; if (!success) { @@ -862,7 +972,8 @@ void SimpleSynthGui::loadSetup() delete msgBox; } else { - sendSysex(init_data, initdata_len); + ///sendSysex(init_data, initdata_len); + sendSysex(init_data, initdata_len + 2); } delete[] init_data; @@ -883,9 +994,14 @@ void SimpleSynthGui::saveSetup() if (filename != QString::null) { lastSavedProject = filename; - byte d[1]; - d[0] = SS_SYSEX_GET_INIT_DATA; - sendSysex(d, 1); // Makes synth send gui initdata, where rest of the saving takes place + //byte d[1]; + byte d[3]; + //d[0] = SS_SYSEX_GET_INIT_DATA; + d[0] = MUSE_SYNTH_SYSEX_MFG_ID; + d[1] = SIMPLEDRUMS_UNIQUE_ID; + d[2] = SS_SYSEX_GET_INIT_DATA; + //sendSysex(d, 1); // Makes synth send gui initdata, where rest of the saving takes place + sendSysex(d, 3); // Makes synth send gui initdata, where rest of the saving takes place } } diff --git a/muse2/synti/simpledrums2/simpledrumsgui.h b/muse2/synti/simpledrums2/simpledrumsgui.h index be8c492d..af32e432 100644 --- a/muse2/synti/simpledrums2/simpledrumsgui.h +++ b/muse2/synti/simpledrums2/simpledrumsgui.h @@ -5,6 +5,7 @@ // // // Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 +// Contributer: (C) Copyright 2011 Tim E. Real (terminator356 at users.sourceforge.net) // // Copyright: See COPYING file that comes with this distribution // @@ -37,18 +38,19 @@ class QChannelSlider: public QSlider Q_OBJECT public: - QChannelSlider(Qt::Orientation, int ch, QWidget* paren = 0); + QChannelSlider(Qt::Orientation, int ch, QWidget* parent = 0); int getChannel(); void setChannel(int ch); - public slots: - virtual void setValue(int val); + ///public slots: + /// virtual void setValue(int val); signals: void valueChanged(int channel, int value); - + protected: int channel; + virtual void sliderChange(SliderChange change); }; //-------------------------------------- @@ -58,14 +60,17 @@ class QInvertedSlider : public QSlider { Q_OBJECT public: - QInvertedSlider(Qt::Orientation o, QWidget* parent = 0) - : QSlider(o, parent) {} + QInvertedSlider(Qt::Orientation o, QWidget* parent = 0); + ///: QSlider(o, parent) {} - public slots: - virtual void setValue(int val); + ///public slots: + /// virtual void setValue(int val); signals: void invertedValueChanged(int value); + + protected: + virtual void sliderChange(SliderChange change); }; //-------------------------------------- @@ -75,11 +80,10 @@ class QInvertedChannelSlider : public QChannelSlider { Q_OBJECT public: - QInvertedChannelSlider(Qt::Orientation o, int channel, QWidget* parent = 0) - : QChannelSlider(o, channel, parent) {}; + QInvertedChannelSlider(Qt::Orientation o, int channel, QWidget* parent = 0); - public slots: - virtual void setValue(int val); + ///public slots: + /// virtual void setValue(int val); }; @@ -138,12 +142,13 @@ class QChannelDial : public QDial signals: void valueChanged(int channel, int fxid, int val); - public slots: - virtual void setValue(int val); + ///public slots: + /// virtual void setValue(int val); protected: int channel; int sendfxid; + virtual void sliderChange(SliderChange change); }; //-------------------------------------- @@ -160,7 +165,10 @@ class SimpleSynthGui : public QDialog, public Ui::SimpleDrumsGuiBase, public Mes QGroupBox* channelButtonGroups[SS_NR_OF_CHANNELS]; QGroupBox* masterButtonGroup; QGroupBox* mainGroupBox; - QInvertedChannelSlider* volumeSliders[SS_NR_OF_CHANNELS]; + + ///QInvertedChannelSlider* volumeSliders[SS_NR_OF_CHANNELS]; + QChannelSlider* volumeSliders[SS_NR_OF_CHANNELS]; // p4.0.27 Tim. Inverted not correct. Was WIP? + QChannelSlider* panSliders[SS_NR_OF_CHANNELS]; QChannelCheckbox* onOff[SS_NR_OF_CHANNELS]; QChannelCheckbox* nOffIgnore[SS_NR_OF_CHANNELS]; @@ -168,7 +176,10 @@ class SimpleSynthGui : public QDialog, public Ui::SimpleDrumsGuiBase, public Mes QChannelButton* clearSampleButton[SS_NR_OF_CHANNELS]; QLabel* nOffLabel[SS_NR_OF_CHANNELS]; QLineEdit* sampleNameLineEdit[SS_NR_OF_CHANNELS]; - QInvertedSlider* masterSlider; + + ///QInvertedSlider* masterSlider; + QSlider* masterSlider; // p4.0.27 Tim. Inverted not correct. Was WIP? + QChannelDial* sendFxDial[SS_NR_OF_CHANNELS][SS_NR_OF_SENDEFFECTS]; QPushButton* openPluginsButton; diff --git a/muse2/synti/simpledrums2/ssplugin.cpp b/muse2/synti/simpledrums2/ssplugin.cpp index 9d32b2c3..75559a8f 100644 --- a/muse2/synti/simpledrums2/ssplugin.cpp +++ b/muse2/synti/simpledrums2/ssplugin.cpp @@ -6,6 +6,7 @@ // // (C) Copyright 2000 Werner Schweer (ws@seh.de) // Additions/modifications: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 +// (C) Copyright 2011 Tim E. Real (terminator356 at users.sourceforge.net) // Copyright: See COPYING file that comes with this distribution // // diff --git a/muse2/synti/simpledrums2/ssplugin.h b/muse2/synti/simpledrums2/ssplugin.h index 64e80921..8750753b 100644 --- a/muse2/synti/simpledrums2/ssplugin.h +++ b/muse2/synti/simpledrums2/ssplugin.h @@ -6,6 +6,7 @@ // // (C) Copyright 2000 Werner Schweer (ws@seh.de) // Additions/modifications: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 +// (C) Copyright 2011 Tim E. Real (terminator356 at users.sourceforge.net) // Copyright: See COPYING file that comes with this distribution // // diff --git a/muse2/synti/simpledrums2/ssplugingui.cpp b/muse2/synti/simpledrums2/ssplugingui.cpp index d52d3a8f..31ac3ac4 100644 --- a/muse2/synti/simpledrums2/ssplugingui.cpp +++ b/muse2/synti/simpledrums2/ssplugingui.cpp @@ -5,6 +5,7 @@ // // // Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 +// Contributer: (C) Copyright 2011 Tim E. Real (terminator356 at users.sourceforge.net) // // Copyright: See COPYING file that comes with this distribution // @@ -56,18 +57,24 @@ SS_PluginChooser::SS_PluginChooser(QWidget* parent) } connect(okButton, SIGNAL(pressed()), SLOT(okPressed())); connect(cancelButton, SIGNAL(pressed()), SLOT(cancelPressed())); - connect(effectsListView, SIGNAL(selectionChanged(QTreeWidgetItem*)), SLOT(selectionChanged(QTreeWidgetItem*))); - connect(effectsListView, SIGNAL(doubleClicked(QTreeWidgetItem*)), SLOT(doubleClicked(QTreeWidgetItem*))); + + //connect(effectsListView, SIGNAL(selectionChanged(QTreeWidgetItem*)), SLOT(selectionChanged(QTreeWidgetItem*))); + //connect(effectsListView, SIGNAL(doubleClicked(QTreeWidgetItem*)), SLOT(doubleClicked(QTreeWidgetItem*))); + connect(effectsListView, SIGNAL(itemSelectionChanged()), SLOT(selectionChanged())); // p4.0.27 + connect(effectsListView, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), SLOT(doubleClicked(QTreeWidgetItem*))); // + SS_TRACE_OUT } /*! \fn SS_PluginChooser::selectionChanged(QListViewItem* item) */ -void SS_PluginChooser::selectionChanged(QTreeWidgetItem* item) +//void SS_PluginChooser::selectionChanged(QTreeWidgetItem* item) +void SS_PluginChooser::selectionChanged() { SS_TRACE_IN - selectedItem = item; + //selectedItem = item; + selectedItem = effectsListView->currentItem(); SS_TRACE_OUT } @@ -95,9 +102,10 @@ void SS_PluginChooser::cancelPressed() /*! \fn SS_PluginChooser::doubleClicked(QListViewItem* item) */ -void SS_PluginChooser::doubleClicked(QTreeWidgetItem* /*item*/) +void SS_PluginChooser::doubleClicked(QTreeWidgetItem* item) { SS_TRACE_IN + selectedItem = item; // p4.0.27 Tim selectedPlugin = findSelectedPlugin(); SS_TRACE_OUT done(QDialog::Accepted); @@ -109,6 +117,8 @@ void SS_PluginChooser::doubleClicked(QTreeWidgetItem* /*item*/) LadspaPlugin* SS_PluginChooser::findSelectedPlugin() { SS_TRACE_IN + if(!selectedItem) // p4.0.27 Tim + return 0; LadspaPlugin* selected = 0; for (iPlugin i=plugins.begin(); i != plugins.end(); i++) { if ((*i)->name() == selectedItem->text(SS_PLUGINCHOOSER_NAMECOL)) @@ -299,7 +309,7 @@ void SS_PluginFront::updatePluginValue(unsigned k) } iPlugin i; - for (i = plugins.begin(); j != k; i++, j++); + for (i = plugins.begin(); j != k; i++, j++) ; plugin = (LadspaPlugin*) *(i); setPluginName(plugin->label()); outGainSlider->setEnabled(true); @@ -307,7 +317,7 @@ void SS_PluginFront::updatePluginValue(unsigned k) expandButton->setEnabled(true); pluginName->setEnabled(true); onOff->setEnabled(true); - onOff->setChecked(true); + ///onOff->setChecked(true); SS_TRACE_OUT } @@ -359,6 +369,15 @@ void SS_PluginFront::setRetGain(int val) } /*! + \fn SS_PluginFront::setOnOff(bool val) + */ +void SS_PluginFront::setOnOff(bool val) + { + onOff->blockSignals(true); + onOff->setChecked(val); + onOff->blockSignals(false); + } +/*! \fn SS_PluginFront::expandButtonPressed() */ void SS_PluginFront::expandButtonPressed() diff --git a/muse2/synti/simpledrums2/ssplugingui.h b/muse2/synti/simpledrums2/ssplugingui.h index 3d77ecf0..99951d01 100644 --- a/muse2/synti/simpledrums2/ssplugingui.h +++ b/muse2/synti/simpledrums2/ssplugingui.h @@ -5,6 +5,7 @@ // // // Author: Mathias Lundgren <lunar_shuttle@users.sf.net>, (C) 2004 +// Contributer: (C) Copyright 2011 Tim E. Real (terminator356 at users.sourceforge.net) // // Copyright: See COPYING file that comes with this distribution // @@ -83,11 +84,21 @@ class SS_ParameterSlider : public QSlider, public SS_ParameterWidget virtual void setParamValue(int val) { SS_TRACE_IN setValue(val); SS_TRACE_OUT} - public slots: - virtual void setValue(int val) { SS_TRACE_IN QSlider::setValue(val); emit valueChanged(fxid, parameter, val); SS_TRACE_OUT } + ///public slots: + /// virtual void setValue(int val) { SS_TRACE_IN QSlider::setValue(val); emit valueChanged(fxid, parameter, val); SS_TRACE_OUT } signals: void valueChanged(int id, int param, int val); + + protected: + virtual void sliderChange(SliderChange change) // p4.0.27 Tim + { + SS_TRACE_IN + QSlider::sliderChange(change); + if(change == QAbstractSlider::SliderValueChange) + emit valueChanged(fxid, parameter, value()); + SS_TRACE_OUT + } }; typedef std::list<SS_ParameterWidget*> SS_ParameterWidgetList; @@ -110,7 +121,8 @@ class SS_PluginChooser : public QDialog, Ui::SS_PluginChooserBase private slots: void okPressed(); void cancelPressed(); - void selectionChanged(QTreeWidgetItem* item); + ///void selectionChanged(QTreeWidgetItem* item); + void selectionChanged(); void doubleClicked(QTreeWidgetItem* item); private: @@ -154,6 +166,7 @@ class SS_PluginFront : public QGroupBox void clearPluginDisplay(); void setParameterValue(int param, int val); void setRetGain(int val); + void setOnOff(bool val); protected: virtual QSize sizeHint() const; diff --git a/muse2/synti/vam/common_defs.h b/muse2/synti/vam/common_defs.h new file mode 100644 index 00000000..59821a70 --- /dev/null +++ b/muse2/synti/vam/common_defs.h @@ -0,0 +1,8 @@ +#ifndef __VAM_UNIQUE_ID_H +#define __VAM_UNIQUE_ID_H + +// Make sure this number is unique among all the MESS synths. +#define VAM_UNIQUE_ID 2 + +#endif + diff --git a/muse2/synti/vam/vam.cpp b/muse2/synti/vam/vam.cpp index fd71d9ea..14280651 100644 --- a/muse2/synti/vam/vam.cpp +++ b/muse2/synti/vam/vam.cpp @@ -35,6 +35,7 @@ #include "muse/midi.h" #include "muse/midictrl.h" +#include "common_defs.h" #include "vam.h" #include "vamgui.h" #include "libsynti/mono.h" @@ -165,7 +166,8 @@ class VAM : public MessMono { float velocity; //int idata[NUM_CONTROLLER]; // buffer for init data - int *idata; + //int *idata; + unsigned char* idata; EnvelopeGenerator dco1_env; EnvelopeGenerator dco2_env; @@ -192,7 +194,10 @@ class VAM : public MessMono { public: virtual int getControllerInfo(int, const char**, int*, int*, int*, int*) const; - virtual void getInitData(int* n, const unsigned char**p) const; + //virtual void getInitData(int* n, const unsigned char**p) const; + virtual void getInitData(int* n, const unsigned char**p); + // This is only a kludge required to support old songs' midistates. Do not use in any new synth. + virtual int oldMidiStateHeader(const unsigned char** data) const; //virtual bool guiVisible() const; //virtual void showGui(bool); //virtual bool hasGui() const { return true; } @@ -207,7 +212,7 @@ class VAM : public MessMono { virtual bool setController(int channel, int ctrl, int val); virtual bool sysex(int, const unsigned char*); VAM(int sr); - ~VAM(); + virtual ~VAM(); bool init(const char* name); }; @@ -227,7 +232,7 @@ float VAM::lin2exp[VAM::LIN2EXP_SIZE]; VAM::VAM(int sr) : MessMono() { - idata = new int[NUM_CONTROLLER]; + idata = new unsigned char[3 + NUM_CONTROLLER * sizeof(int)]; setSampleRate(sr); gui = 0; } @@ -238,6 +243,10 @@ VAM::VAM(int sr) VAM::~VAM() { + if (gui) + delete gui; + //delete idata; + delete [] idata; // p4.0.27 --useCount; if (useCount == 0) { delete[] sin_tbl; @@ -247,6 +256,13 @@ VAM::~VAM() } } +int VAM::oldMidiStateHeader(const unsigned char** data) const +{ + unsigned char const d[3] = {MUSE_SYNTH_SYSEX_MFG_ID, VAM_UNIQUE_ID, INIT_DATA_CMD}; + *data = &d[0]; + return 3; +} + //--------------------------------------------------------- // curTime //--------------------------------------------------------- @@ -438,11 +454,16 @@ void VAM::processMessages() if (ev.type() == ME_CONTROLLER) { // process local? - setController(ev.dataA() & 0xfff, ev.dataB()); + //setController(ev.dataA() & 0xfff, ev.dataB()); + setController(ev.dataA(), ev.dataB()); sendEvent(ev); } else + { + #ifdef VAM_DEBUG printf("VAM::process(): unknown event\n"); + #endif + } } } @@ -604,7 +625,17 @@ int VAM::getControllerInfo(int id, const char** name, int* controller, bool VAM::setController(int /*channel*/, int ctrl, int data) { - setController(ctrl & 0xfff, data); + //setController(ctrl & 0xfff, data); + // p4.0.27 + if(ctrl < VAM_FIRST_CTRL || ctrl > VAM_LAST_CTRL) + { + #ifdef VAM_DEBUG + printf("VAM::setController Invalid controller number 0x%x\n", ctrl); + #endif + return false; + } + setController(ctrl, data); + MidiPlayEvent ev(0, 0, channel, ME_CONTROLLER, ctrl, data); gui->writeEvent(ev); return false; @@ -612,6 +643,15 @@ bool VAM::setController(int /*channel*/, int ctrl, int data) void VAM::setController(int ctrl, int data) { + // p4.0.27 + if(ctrl < VAM_FIRST_CTRL || ctrl > VAM_LAST_CTRL) + { + #ifdef VAM_DEBUG + printf("VAM: Invalid controller number 0x%x\n", ctrl); + #endif + return; + } + // fprintf(stderr, "ctrl: %d data: %d\n", ctrl, data); int maxval = 128*128-1; double normval = double(data) / double(maxval); @@ -723,22 +763,34 @@ void VAM::setController(int ctrl, int data) if(dco2.pw == 1.0) dco2.pw = 0.99; break; default: - printf("VAM: set unknown Ctrl 0x%x to 0x%x\n", ctrl, data); - break; + //#ifdef VAM_DEBUG + //printf("VAM: set unknown Ctrl 0x%x to 0x%x\n", ctrl, data); + //#endif + //break; + return; // p4.0.27 } - controller[ctrl] = data; + //controller[ctrl] = data; + controller[ctrl - VAM_FIRST_CTRL] = data; // p4.0.27 } //--------------------------------------------------------- // getInitData //--------------------------------------------------------- -void VAM::getInitData(int* n, const unsigned char**p) const - { +//void VAM::getInitData(int* n, const unsigned char**p) const +void VAM::getInitData(int* n, const unsigned char**p) +{ + // p4.0.27 + *n = 3 + NUM_CONTROLLER * sizeof(int); + idata[0] = MUSE_SYNTH_SYSEX_MFG_ID; // Global MusE Soft Synth Manufacturer ID + idata[1] = VAM_UNIQUE_ID; // VAM + idata[2] = INIT_DATA_CMD; // Initialization command + int* d = (int*)&idata[3]; + //int i;//prevent of compiler warning: unused variable - int* d = idata; + //int* d = idata; //int maxval = 128*128-1; //prevent of compiler warning: unused variable - *n = NUM_CONTROLLER * sizeof(int); + // *n = NUM_CONTROLLER * sizeof(int); // // setController(0, DCO1_PITCHMOD, p++); // *d++ = int(dco1.pitchmod+8191*341.333); @@ -935,51 +987,68 @@ void VAM::getInitData(int* n, const unsigned char**p) const *d++ = gui->getController(DCO2_PW); *p = (unsigned char*)idata; - } +} //--------------------------------------------------------- // sysex //--------------------------------------------------------- bool VAM::sysex(int n, const unsigned char* data) +{ + // p4.0.27 + if(unsigned(n) == (3 + NUM_CONTROLLER * sizeof(int))) { - n=n; // remove warning of unused variable - int *p= (int*)data; - setController(0, DCO1_PITCHMOD, *p++); - setController(0, DCO2_PITCHMOD, *p++); - setController(0, DCO1_WAVEFORM, *p++); - setController(0, DCO2_WAVEFORM, *p++); - setController(0, DCO1_FM, *p++); - setController(0, DCO2_FM, *p++); - setController(0, DCO1_PWM, *p++); - setController(0, DCO2_PWM, *p++); - setController(0, DCO1_ATTACK, *p++); - setController(0, DCO2_ATTACK, *p++); - setController(0, DCO1_DECAY, *p++); - setController(0, DCO2_DECAY, *p++); - setController(0, DCO1_SUSTAIN, *p++ ); - setController(0, DCO2_SUSTAIN, *p++ ); - setController(0, DCO1_RELEASE, *p++); - setController(0, DCO2_RELEASE, *p++); - setController(0, LFO_FREQ, *p++); - setController(0, LFO_WAVEFORM, *p++); - setController(0, FILT_ENV_MOD, *p++); - setController(0, FILT_KEYTRACK, *p++); - setController(0, FILT_RES, *p++); - setController(0, FILT_ATTACK, *p++); - setController(0, FILT_DECAY, *p++); - setController(0, FILT_SUSTAIN, *p++); - setController(0, FILT_RELEASE, *p++); - setController(0, DCO2ON, *p++); - setController(0, FILT_INVERT, *p++); - setController(0, FILT_CUTOFF, *p++); - setController(0, DCO1_DETUNE, *p++); - setController(0, DCO2_DETUNE, *p++); - setController(0, DCO1_PW, *p++); - setController(0, DCO2_PW, *p++); - - return false; + if (data[0] == MUSE_SYNTH_SYSEX_MFG_ID) // Global MusE Soft Synth Manufacturer ID + { + if (data[1] == VAM_UNIQUE_ID) // VAM + { + if (data[2] == INIT_DATA_CMD) // Initialization command + { + int *p= (int*)(data + 3); + setController(0, DCO1_PITCHMOD, *p++); + setController(0, DCO2_PITCHMOD, *p++); + setController(0, DCO1_WAVEFORM, *p++); + setController(0, DCO2_WAVEFORM, *p++); + setController(0, DCO1_FM, *p++); + setController(0, DCO2_FM, *p++); + setController(0, DCO1_PWM, *p++); + setController(0, DCO2_PWM, *p++); + setController(0, DCO1_ATTACK, *p++); + setController(0, DCO2_ATTACK, *p++); + setController(0, DCO1_DECAY, *p++); + setController(0, DCO2_DECAY, *p++); + setController(0, DCO1_SUSTAIN, *p++ ); + setController(0, DCO2_SUSTAIN, *p++ ); + setController(0, DCO1_RELEASE, *p++); + setController(0, DCO2_RELEASE, *p++); + setController(0, LFO_FREQ, *p++); + setController(0, LFO_WAVEFORM, *p++); + setController(0, FILT_ENV_MOD, *p++); + setController(0, FILT_KEYTRACK, *p++); + setController(0, FILT_RES, *p++); + setController(0, FILT_ATTACK, *p++); + setController(0, FILT_DECAY, *p++); + setController(0, FILT_SUSTAIN, *p++); + setController(0, FILT_RELEASE, *p++); + setController(0, DCO2ON, *p++); + setController(0, FILT_INVERT, *p++); + setController(0, FILT_CUTOFF, *p++); + setController(0, DCO1_DETUNE, *p++); + setController(0, DCO2_DETUNE, *p++); + setController(0, DCO1_PW, *p++); + setController(0, DCO2_PW, *p++); + return false; + } + } + } } + + #ifdef VAM_DEBUG + printf("VAM: unknown sysex\n"); + #endif + + return false; +} //--------------------------------------------------------- // nativeGuiVisible diff --git a/muse2/synti/vam/vam.h b/muse2/synti/vam/vam.h index 3da27e79..72edd9f8 100644 --- a/muse2/synti/vam/vam.h +++ b/muse2/synti/vam/vam.h @@ -21,8 +21,12 @@ #ifndef __VAM_H #define __VAM_H +#include "muse/midictrl.h" + enum { - DCO1_PITCHMOD, DCO1_WAVEFORM, DCO1_FM, DCO1_PWM, + //DCO1_PITCHMOD, + DCO1_PITCHMOD = CTRL_RPN14_OFFSET, // p4.0.27 + DCO1_WAVEFORM, DCO1_FM, DCO1_PWM, DCO1_ATTACK, DCO1_DECAY, DCO1_SUSTAIN, DCO1_RELEASE, DCO2_PITCHMOD, DCO2_WAVEFORM, DCO2_FM, DCO2_PWM, DCO2_ATTACK, DCO2_DECAY, DCO2_SUSTAIN, DCO2_RELEASE, @@ -32,7 +36,11 @@ enum { DCO1_DETUNE, DCO2_DETUNE, DCO1_PW, DCO2_PW }; +#define VAM_FIRST_CTRL DCO1_PITCHMOD +#define VAM_LAST_CTRL DCO2_PW +#define NUM_CONTROLLER 32 +#define INIT_DATA_CMD 1 -#define NUM_CONTROLLER 32 +//#define VAM_DEBUG #endif /* __VAM_H */ diff --git a/muse2/synti/vam/vamgui.cpp b/muse2/synti/vam/vamgui.cpp index 50b6552c..34f8636c 100644 --- a/muse2/synti/vam/vamgui.cpp +++ b/muse2/synti/vam/vamgui.cpp @@ -32,6 +32,7 @@ #include <list> +#include "common_defs.h" #include "vamgui.h" #include "vam.h" @@ -187,38 +188,39 @@ VAMGui::VAMGui() savePresetsToFile->setIcon(QIcon(*saveasIcon)); deletePreset->setIcon(QIcon(*deleteIcon)); - dctrl[DCO1_PITCHMOD] = SynthGuiCtrl(PitchModS, LCDNumber1, SynthGuiCtrl::SLIDER); - dctrl[DCO1_WAVEFORM] = SynthGuiCtrl(Waveform, 0, SynthGuiCtrl::COMBOBOX); - dctrl[DCO1_FM] = SynthGuiCtrl(FMS, LCDNumber1_2, SynthGuiCtrl::SLIDER); - dctrl[DCO1_PWM] = SynthGuiCtrl(PWMS, LCDNumber1_3, SynthGuiCtrl::SLIDER); - dctrl[DCO1_ATTACK] = SynthGuiCtrl(AttackS, LCDNumber1_3_2, SynthGuiCtrl::SLIDER); - dctrl[DCO1_DECAY] = SynthGuiCtrl(DecayS, LCDNumber1_3_2_2, SynthGuiCtrl::SLIDER); - dctrl[DCO1_SUSTAIN] = SynthGuiCtrl(SustainS, LCDNumber1_3_2_3, SynthGuiCtrl::SLIDER); - dctrl[DCO1_RELEASE] = SynthGuiCtrl(ReleaseS, LCDNumber1_3_2_4, SynthGuiCtrl::SLIDER); - dctrl[DCO2_PITCHMOD] = SynthGuiCtrl(PitchModS2, LCDNumber1_4, SynthGuiCtrl::SLIDER); - dctrl[DCO2_WAVEFORM] = SynthGuiCtrl(Waveform2, 0, SynthGuiCtrl::COMBOBOX); - dctrl[DCO2_FM] = SynthGuiCtrl(FMS2, LCDNumber1_2_2, SynthGuiCtrl::SLIDER); - dctrl[DCO2_PWM] = SynthGuiCtrl(PWMS2, LCDNumber1_3_3, SynthGuiCtrl::SLIDER); - dctrl[DCO2_ATTACK] = SynthGuiCtrl(AttackS2, LCDNumber1_3_2_5, SynthGuiCtrl::SLIDER); - dctrl[DCO2_DECAY] = SynthGuiCtrl(DecayS2, LCDNumber1_3_2_2_2, SynthGuiCtrl::SLIDER); - dctrl[DCO2_SUSTAIN] = SynthGuiCtrl(SustainS2, LCDNumber1_3_2_3_2, SynthGuiCtrl::SLIDER); - dctrl[DCO2_RELEASE] = SynthGuiCtrl(ReleaseS2, LCDNumber1_3_2_4_2, SynthGuiCtrl::SLIDER); - dctrl[LFO_FREQ] = SynthGuiCtrl(FreqS, LCDNumber1_5, SynthGuiCtrl::SLIDER); - dctrl[LFO_WAVEFORM] = SynthGuiCtrl(Waveform2_2, 0, SynthGuiCtrl::COMBOBOX); - dctrl[FILT_ENV_MOD] = SynthGuiCtrl(EnvModS, LCDNumber1_5_3, SynthGuiCtrl::SLIDER); - dctrl[FILT_KEYTRACK] = SynthGuiCtrl(KeyTrack, 0, SynthGuiCtrl::SWITCH); - dctrl[FILT_RES] = SynthGuiCtrl(ResS, LCDNumber1_5_5, SynthGuiCtrl::SLIDER); - dctrl[FILT_ATTACK] = SynthGuiCtrl(AttackS3, LCDNumber1_3_2_5_2, SynthGuiCtrl::SLIDER); - dctrl[FILT_DECAY] = SynthGuiCtrl(DecayS3, LCDNumber1_3_2_2_2_2, SynthGuiCtrl::SLIDER); - dctrl[FILT_SUSTAIN] = SynthGuiCtrl(SustainS3, LCDNumber1_3_2_3_2_2, SynthGuiCtrl::SLIDER); - dctrl[FILT_RELEASE] = SynthGuiCtrl(ReleaseS3, LCDNumber1_3_2_4_2_2, SynthGuiCtrl::SLIDER); - dctrl[DCO2ON] = SynthGuiCtrl(DCO2On, 0, SynthGuiCtrl::SWITCH); - dctrl[FILT_INVERT] = SynthGuiCtrl(FilterInvert, 0, SynthGuiCtrl::SWITCH); - dctrl[FILT_CUTOFF] = SynthGuiCtrl(CutoffS, LCDNumber1_5_5_2, SynthGuiCtrl::SLIDER); - dctrl[DCO1_DETUNE] = SynthGuiCtrl(DetuneS, LCDNumber1_6, SynthGuiCtrl::SLIDER); - dctrl[DCO2_DETUNE] = SynthGuiCtrl(DetuneS2, LCDNumber1_6_2, SynthGuiCtrl::SLIDER); - dctrl[DCO1_PW] = SynthGuiCtrl(PWS, LCDNumber1_2_3, SynthGuiCtrl::SLIDER); - dctrl[DCO2_PW] = SynthGuiCtrl(PWS2, LCDNumber1_2_4, SynthGuiCtrl::SLIDER); + // p4.0.27 First ctrl offset. + dctrl[DCO1_PITCHMOD - VAM_FIRST_CTRL] = SynthGuiCtrl(PitchModS, LCDNumber1, SynthGuiCtrl::SLIDER); + dctrl[DCO1_WAVEFORM - VAM_FIRST_CTRL] = SynthGuiCtrl(Waveform, 0, SynthGuiCtrl::COMBOBOX); + dctrl[DCO1_FM - VAM_FIRST_CTRL] = SynthGuiCtrl(FMS, LCDNumber1_2, SynthGuiCtrl::SLIDER); + dctrl[DCO1_PWM - VAM_FIRST_CTRL] = SynthGuiCtrl(PWMS, LCDNumber1_3, SynthGuiCtrl::SLIDER); + dctrl[DCO1_ATTACK - VAM_FIRST_CTRL] = SynthGuiCtrl(AttackS, LCDNumber1_3_2, SynthGuiCtrl::SLIDER); + dctrl[DCO1_DECAY - VAM_FIRST_CTRL] = SynthGuiCtrl(DecayS, LCDNumber1_3_2_2, SynthGuiCtrl::SLIDER); + dctrl[DCO1_SUSTAIN - VAM_FIRST_CTRL] = SynthGuiCtrl(SustainS, LCDNumber1_3_2_3, SynthGuiCtrl::SLIDER); + dctrl[DCO1_RELEASE - VAM_FIRST_CTRL] = SynthGuiCtrl(ReleaseS, LCDNumber1_3_2_4, SynthGuiCtrl::SLIDER); + dctrl[DCO2_PITCHMOD - VAM_FIRST_CTRL] = SynthGuiCtrl(PitchModS2, LCDNumber1_4, SynthGuiCtrl::SLIDER); + dctrl[DCO2_WAVEFORM - VAM_FIRST_CTRL] = SynthGuiCtrl(Waveform2, 0, SynthGuiCtrl::COMBOBOX); + dctrl[DCO2_FM - VAM_FIRST_CTRL] = SynthGuiCtrl(FMS2, LCDNumber1_2_2, SynthGuiCtrl::SLIDER); + dctrl[DCO2_PWM - VAM_FIRST_CTRL] = SynthGuiCtrl(PWMS2, LCDNumber1_3_3, SynthGuiCtrl::SLIDER); + dctrl[DCO2_ATTACK - VAM_FIRST_CTRL] = SynthGuiCtrl(AttackS2, LCDNumber1_3_2_5, SynthGuiCtrl::SLIDER); + dctrl[DCO2_DECAY - VAM_FIRST_CTRL] = SynthGuiCtrl(DecayS2, LCDNumber1_3_2_2_2, SynthGuiCtrl::SLIDER); + dctrl[DCO2_SUSTAIN - VAM_FIRST_CTRL] = SynthGuiCtrl(SustainS2, LCDNumber1_3_2_3_2, SynthGuiCtrl::SLIDER); + dctrl[DCO2_RELEASE - VAM_FIRST_CTRL] = SynthGuiCtrl(ReleaseS2, LCDNumber1_3_2_4_2, SynthGuiCtrl::SLIDER); + dctrl[LFO_FREQ - VAM_FIRST_CTRL] = SynthGuiCtrl(FreqS, LCDNumber1_5, SynthGuiCtrl::SLIDER); + dctrl[LFO_WAVEFORM - VAM_FIRST_CTRL] = SynthGuiCtrl(Waveform2_2, 0, SynthGuiCtrl::COMBOBOX); + dctrl[FILT_ENV_MOD - VAM_FIRST_CTRL] = SynthGuiCtrl(EnvModS, LCDNumber1_5_3, SynthGuiCtrl::SLIDER); + dctrl[FILT_KEYTRACK - VAM_FIRST_CTRL] = SynthGuiCtrl(KeyTrack, 0, SynthGuiCtrl::SWITCH); + dctrl[FILT_RES - VAM_FIRST_CTRL] = SynthGuiCtrl(ResS, LCDNumber1_5_5, SynthGuiCtrl::SLIDER); + dctrl[FILT_ATTACK - VAM_FIRST_CTRL] = SynthGuiCtrl(AttackS3, LCDNumber1_3_2_5_2, SynthGuiCtrl::SLIDER); + dctrl[FILT_DECAY - VAM_FIRST_CTRL] = SynthGuiCtrl(DecayS3, LCDNumber1_3_2_2_2_2, SynthGuiCtrl::SLIDER); + dctrl[FILT_SUSTAIN - VAM_FIRST_CTRL] = SynthGuiCtrl(SustainS3, LCDNumber1_3_2_3_2_2, SynthGuiCtrl::SLIDER); + dctrl[FILT_RELEASE - VAM_FIRST_CTRL] = SynthGuiCtrl(ReleaseS3, LCDNumber1_3_2_4_2_2, SynthGuiCtrl::SLIDER); + dctrl[DCO2ON - VAM_FIRST_CTRL] = SynthGuiCtrl(DCO2On, 0, SynthGuiCtrl::SWITCH); + dctrl[FILT_INVERT - VAM_FIRST_CTRL] = SynthGuiCtrl(FilterInvert, 0, SynthGuiCtrl::SWITCH); + dctrl[FILT_CUTOFF - VAM_FIRST_CTRL] = SynthGuiCtrl(CutoffS, LCDNumber1_5_5_2, SynthGuiCtrl::SLIDER); + dctrl[DCO1_DETUNE - VAM_FIRST_CTRL] = SynthGuiCtrl(DetuneS, LCDNumber1_6, SynthGuiCtrl::SLIDER); + dctrl[DCO2_DETUNE - VAM_FIRST_CTRL] = SynthGuiCtrl(DetuneS2, LCDNumber1_6_2, SynthGuiCtrl::SLIDER); + dctrl[DCO1_PW - VAM_FIRST_CTRL] = SynthGuiCtrl(PWS, LCDNumber1_2_3, SynthGuiCtrl::SLIDER); + dctrl[DCO2_PW - VAM_FIRST_CTRL] = SynthGuiCtrl(PWS2, LCDNumber1_2_4, SynthGuiCtrl::SLIDER); map = new QSignalMapper(this); @@ -275,11 +277,22 @@ void VAMGui::ctrlChanged(int idx) else if (ctrl->type == SynthGuiCtrl::SWITCH) { val = ((QCheckBox*)(ctrl->editor))->isChecked(); } - sendController(0, idx + CTRL_RPN14_OFFSET, val); + //sendController(0, idx + CTRL_RPN14_OFFSET, val); + sendController(0, idx + VAM_FIRST_CTRL, val); // p4.0.27 } int VAMGui::getController(int idx) { + // p4.0.27 + if(idx < VAM_FIRST_CTRL || idx > VAM_LAST_CTRL) + { + //#ifdef VAM_DEBUG + printf("VAMGui:: invalid controller number %d\n", idx); + //#endif + return 0; + } + idx -= VAM_FIRST_CTRL; + SynthGuiCtrl* ctrl = &dctrl[idx]; int val = 0; if (ctrl->type == SynthGuiCtrl::SLIDER) { @@ -302,8 +315,9 @@ int VAMGui::getControllerInfo(int id, const char** name, int* controller, if (id >= NUM_CONTROLLER) return 0; + //*controller = id; + *controller = id + VAM_FIRST_CTRL; // p4.0.27 - *controller = id; *name = vam_ctrl_names[id]; const SynthGuiCtrl* ctrl = (const SynthGuiCtrl*)&dctrl[id]; //int val = 0; @@ -357,8 +371,9 @@ void VAMGui::activatePreset(Preset* preset) fprintf(stderr, "internal error 1\n"); exit(-1); } - for (unsigned int i = 0; i < sizeof(dctrl)/sizeof(*dctrl); ++i) { - setParam(i, preset->ctrl[i]); + //for (unsigned int i = 0; i < sizeof(dctrl)/sizeof(*dctrl); ++i) { + for (unsigned int i = 0; i < NUM_CONTROLLER; ++i) { // p4.0.27 + setParam(i, preset->ctrl[i]); ctrlChanged(i); } } @@ -443,9 +458,9 @@ void VAMGui::setPreset(Preset* preset) // #if 0 putchar(0xf0); - putchar(0x7c); // mess - putchar(0x2); // vam - putchar(0x3); // setPreset + putchar(MUSE_SYNTH_SYSEX_MFG_ID); // mess + putchar(VAM_UNIQUE_ID); // vam + putchar(0x3); // setPreset QByteArray ba = preset->name.toLatin1(); const char* name = ba.constData(); while (*name) @@ -467,8 +482,11 @@ void VAMGui::setPreset(Preset* preset) void VAMGui::setParam(int param, int val) { - if (param >= int(sizeof(dctrl)/sizeof(*dctrl))) { + //if (param >= int(sizeof(dctrl)/sizeof(*dctrl))) { + if (param >= NUM_CONTROLLER) { // p4.0.27 + #ifdef VAM_DEBUG fprintf(stderr, "vam: set unknown parameter 0x%x to 0x%x\n", param, val); + #endif return; } SynthGuiCtrl* ctrl = &dctrl[param]; @@ -496,15 +514,17 @@ void VAMGui::setParam(int param, int val) // sysexReceived //--------------------------------------------------------- -void VAMGui::sysexReceived(const unsigned char* data, int len) +void VAMGui::sysexReceived(const unsigned char* /*data*/, int /*len*/) { - if (len >= 4) { + // Removed, this is not used. p4.0.27 + /* + if (len >= 4) { //--------------------------------------------- // MusE Soft Synth //--------------------------------------------- - if (data[0] == 0x7c) { - if (data[1] == 2) { // vam + if (data[0] == MUSE_SYNTH_SYSEX_MFG_ID) { + if (data[1] == VAM_UNIQUE_ID) { // vam if (data[2] == 2) { // parameter response if (len != 6) { fprintf(stderr, "vam gui: bad sysEx len\n"); @@ -531,10 +551,15 @@ void VAMGui::sysexReceived(const unsigned char* data, int len) } } } - fprintf(stderr, "vam gui: unknown sysex received, len %d:\n", len); + + #ifdef VAM_DEBUG + fprintf(stderr, "vam gui: unknown sysex received, len %d:\n", len); for (int i = 0; i < len; ++i) fprintf(stderr, "%02x ", data[i]); fprintf(stderr, "\n"); + #endif + */ + } //--------------------------------------------------------- @@ -544,12 +569,28 @@ void VAMGui::sysexReceived(const unsigned char* data, int len) void VAMGui::processEvent(const MidiPlayEvent& ev) { if (ev.type() == ME_CONTROLLER) - setParam(ev.dataA() & 0xfff, ev.dataB()); + { + //setParam(ev.dataA() & 0xfff, ev.dataB()); + // p4.0.27 + int ctl = ev.dataA(); + if(ctl < VAM_FIRST_CTRL || ctl > VAM_LAST_CTRL) + { + //#ifdef VAM_DEBUG + printf("VAMGui:: invalid controller number %d\n", ctl); + //#endif + return; + } + setParam(ctl - VAM_FIRST_CTRL, ev.dataB()); + + } else if (ev.type() == ME_SYSEX) - sysexReceived(ev.data(), ev.len()) - ; + sysexReceived(ev.data(), ev.len()); else + { + #ifdef VAM_DEBUG printf("VAMGui::illegal event type received\n"); + #endif + } } //--------------------------------------------------------- |