//=========================================================================== // // DeicsOnze an emulator of the YAMAHA DX11 synthesizer // // Version 0.2.2 // // // // // Copyright (c) 2004 Nil Geisweiller // // // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // 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., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA or point your web browser to http://www.gnu.org. //=========================================================================== #include #include #include #include "config.h" #include "libsynti/mess.h" #include "muse/midictrl.h" #include "deicsonze.h" #include "deicsonzegui.h" #include "muse/midi.h" #define ABS(x) (x>=0?x:-x) float DeicsOnze::waveTable[NBRWAVES][RESOLUTION]; int DeicsOnze::useCount = 0; //--------------------------------------------------------- // DeicsOnze //--------------------------------------------------------- DeicsOnze::DeicsOnze() : Mess(1) { if (useCount++ == 0) { // create sinus wave table, W1 for(int i = 0; i < RESOLUTION; i++) waveTable[W1][i] = (float)(sin((i * 2.0 * M_PI) / (double)RESOLUTION)); // create sinus*abs(sinus) wave table, W2 for(int i = 0; i < RESOLUTION; i++){ double t = (i * 2.0 * M_PI) / (double)RESOLUTION; waveTable[W2][i] = (float)(ABS(sin(t))*sin(t));} // create halfsinus_ wave table, W3 for(int i = 0; i < RESOLUTION; i++) waveTable[W3][i] = (float) (iinitPreset(); setPreset(); _gui = new DeicsOnzeGui(this); _gui->setCaption(QString("DeicsOnze")); _gui->show(); } //--------------------------------------------------------- // ~DeicsOnze //--------------------------------------------------------- DeicsOnze::~DeicsOnze() { //if (--useCount == 0) //delete[] sine_table; } //--------------------------------------------------------- // guiVisible //--------------------------------------------------------- bool DeicsOnze::guiVisible() const { return _gui->isVisible(); } //--------------------------------------------------------- // showGui //--------------------------------------------------------- void DeicsOnze::showGui(bool val) { _gui->setShown(val); } //--------------------------------------------------------- // getGeometry //--------------------------------------------------------- void DeicsOnze::getGeometry(int* x, int* y, int* w, int* h) const { QPoint pos(_gui->pos()); QSize size(_gui->size()); *x = pos.x(); *y = pos.y(); *w = size.width(); *h = size.height(); } //--------------------------------------------------------- // setGeometry //--------------------------------------------------------- void DeicsOnze::setGeometry(int x, int y, int w, int h) { _gui->resize(QSize(w, h)); _gui->move(QPoint(x, y)); } //--------------------------------------------------------- // initGlobal //--------------------------------------------------------- void DeicsOnze::initGlobal() { _global.amp=1.0/(double)NBRVOICES; _global.sustain=false; _global.pitchBendCoef=1.0; _global.lfoIndex=0; _numPatch=0; } //--------------------------------------------------------- // initVoices //--------------------------------------------------------- void DeicsOnze::initVoices() { for(int i=0; i::iterator pvi; for(pvi=_presetVector.begin(); pvi!=_presetVector.end(); pvi++) if((*pvi)->bank==lbank && (*pvi)->prog==prog) { return(*pvi); } return NULL; } Preset* subcategorySet::findPreset(int lbank, int prog) { Preset* p_preset; std::vector::iterator psvi; for(psvi=_subcategoryVector.begin();psvi!=_subcategoryVector.end(); psvi++) { p_preset=(*psvi)->findPreset(lbank, prog); if(p_preset) return p_preset; } return NULL; } Preset* categorySet::findPreset(int lbank, int prog) { Preset* p_preset; std::vector::iterator ssvi; for(ssvi=_categoryVector.begin(); ssvi!=_categoryVector.end(); ssvi++) { p_preset=(*ssvi)->findPreset(lbank, prog); if(p_preset) return p_preset; } return NULL; } Preset* DeicsOnze::findPreset(int lbank, int prog) { return _categorySet->findPreset(lbank, prog); } //--------------------------------------------------------- // findSubcategorySet // take string of a category and return the subcategorySet //--------------------------------------------------------- subcategorySet* categorySet::findSubcategorySet(std::string s) { std::vector::iterator ssvi=_categoryVector.begin(); while(ssvi!=_categoryVector.end() && s!=(*ssvi)->_categoryName) ssvi++; return(*ssvi); } //--------------------------------------------------------- // findPresetSet // take string of a subcategory and return the presetSet //--------------------------------------------------------- presetSet* subcategorySet::findPresetSet(std::string s) { std::vector::iterator pvi=_subcategoryVector.begin(); while(pvi!=_subcategoryVector.end() && s!=(*pvi)->_subcategoryName) pvi++; //if (pvi==NULL) printf("presetSet %s doesn't exist!", s); return(*pvi); } //--------------------------------------------------------- // note2Amp // return the Amp of a note depending on the level scaling //--------------------------------------------------------- inline double note2Amp(double note, int ls) { if(ls==0) return(1.0); else return((notelfo.speed; // lfoSpeed to Hz, obtained by fitting the actual curve by a polynomial _global.lfoFreq=-1.9389e-08*x*x*x*x*x+2.8826e-06*x*x*x*x-9.0316e-05*x*x*x +4.7453e-03*x*x-1.2295e-02*x+7.0347e-02;//a revoir //Pitch LFO _global.lfoMaxIndex=(_global.lfoFreq==0?0:(int)((1.0/_global.lfoFreq) *(double)sampleRate())); _global.lfoPitch=(((double)_preset->lfo.pModDepth/(double)MAXPMODDEPTH) *(COEFPLFO(_preset->sensitivity.pitch))); //Amplitude LFO _global.lfoMaxAmp=(((double)_preset->lfo.aModDepth/(double)MAXAMODDEPTH) *(COEFALFO(_preset->sensitivity.amplitude))); //index is concidered on the frequency of the delay _global.lfoDelayMaxIndex=delay2Time(_preset->lfo.delay)*_global.lfoFreq; _global.lfoDelayInct=(double)(RESOLUTION/4)/_global.lfoDelayMaxIndex; } //----------------------------------------------------------------- // setFeedback //----------------------------------------------------------------- void DeicsOnze::setFeedback() { _global.feedbackAmp=COEFFEEDBACK*exp(log(2)*(double)(_preset->feedback -MAXFEEDBACK)); } //----------------------------------------------------------------- // setPreset //----------------------------------------------------------------- void DeicsOnze::setPreset() { setFeedback(); setLfo(); } //--------------------------------------------------------- // printPreset //--------------------------------------------------------- inline void printPreset(Preset* p) { printf("\n"); printf("Algorithm : %d, Feedback : %d\n", p->algorithm, p->feedback); printf("LFO : "); switch(p->lfo.wave) { case(SAWUP) : printf("SAWUP ,"); break; case(SQUARE) : printf("SQUARE ,"); break; case(TRIANGL) : printf("TRIANGL ,"); break; case(SHOLD) : printf("SHOLD ,"); break; default : printf("No defined, "); break; } printf("Speed : %d, Delay : %d, PModD : %d, AModD : %d, ", p->lfo.speed, p->lfo.delay, p->lfo.pModDepth, p->lfo.aModDepth); if(p->lfo.sync) printf("Sync\n"); else printf("Not Sync\n"); printf("LFO Pitch Sensitivity : %d, LFO Amplitude Sensitivity : %d\n", p->sensitivity.pitch, p->sensitivity.amplitude); for(int i=0; isensitivity.ampOn) printf("ON "); else printf("OFF "); } printf("\n"); for(int i=0; isensitivity.egBias[i]); printf("\n"); for(int i=0; isensitivity.keyVelocity[i]); printf("\n"); for(int i=0; ifrequency[i].isFix) printf("Freq%d : %f ",i+1, p->frequency[i].ratio); else printf("Ratio%d : %f ",i+1, p->frequency[i].ratio); } printf("\n"); for(int i=0; ioscWave[i]) { case(W1) : printf("W1 "); break; case(W2) : printf("W2 "); break; case(W3) : printf("W3 "); break; case(W4) : printf("W4 "); break; case(W5) : printf("W5 "); break; case(W6) : printf("W6 "); break; case(W7) : printf("W7 "); break; case(W8) : printf("W8 "); break; default : printf("No defined "); break; } } printf("\n"); for(int i=0; idetune[i]); printf("\n"); for(int i=0; ieg[i].ar, i+1, p->eg[i].d1r, i+1, p->eg[i].d1l, i+1, p->eg[i].d2r, i+1, p->eg[i].rr, i+1); switch(p->eg[i].egShift) { case(VOF) : printf("VOF"); case(V48) : printf("48"); case(V24) : printf("24"); case(V12) : printf("12"); } printf("\n"); } printf("PitchEg pr1 : %d, pr2 : %d, pr3 : %d, pl1 : %d, pl2 : %d, pl3 : %d" , p->pitchEg.pr1, p->pitchEg.pr2, p->pitchEg.pr3, p->pitchEg.pl1, p->pitchEg.pl2, p->pitchEg.pl3); printf("\n"); for(int i=0; ioutLevel[i]); printf("\n"); printf("Name : %s\n", p->name.c_str()); } void presetSet::printSubcategory() { std::cout << " " << _subcategoryName << "\n"; for(unsigned int i=0; i<_presetVector.size(); i++) printPreset(_presetVector[i]); } void subcategorySet::printCategory() { std::cout << " " << _categoryName << "\n"; for(unsigned int i=0; i<_subcategoryVector.size(); i++) _subcategoryVector[i]->printSubcategory(); } void categorySet::printBank() { std::cout << _bankName << "\n"; for(unsigned int i=0; i<_categoryVector.size(); i++) _categoryVector[i]->printCategory(); } inline double coarseFine2Ratio(int c,int f) { double tab[64][16]= { {0.50,0.56,0.62,0.68,0.75,0.81,0.87,0.93,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}, {0.71,0.79,0.88,0.96,1.05,1.14,1.23,1.32,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}, {0.78,0.88,0.98,1.07,1.17,1.27,1.37,1.47,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}, {0.87,0.97,1.08,1.18,1.29,1.40,1.51,1.62,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}, {1.00,1.06,1.12,1.18,1.25,1.31,1.37,1.43,1.50,1.56,1.62,1.68,1.75,1.81,1.87,1.93}, {1.41,1.49,1.58,1.67,1.76,1.85,1.93,2.02,2.11,2.20,2.29,2.37,2.46,2.55,2.64,2.73}, {1.57,1.66,1.76,1.86,1.96,2.06,2.15,2.25,2.35,2.45,2.55,2.64,2.74,2.84,2.94,3.04}, {1.73,1.83,1.94,2.05,2.16,2.27,2.37,2.48,2.59,2.70,2.81,2.91,3.02,3.13,3.24,3.35}, {2.00,2.06,2.12,2.18,2.25,2.31,2.37,2.43,2.50,2.56,2.62,2.68,2.75,2.81,2.87,2.93}, {2.82,2.90,2.99,3.08,3.17,3.26,3.34,3.43,3.52,3.61,3.70,3.78,3.87,3.96,4.05,3.14}, {3.00,3.06,3.12,3.18,3.25,3.31,3.37,3.43,3.50,3.56,3.62,3.68,3.75,3.81,3.87,3.93} , {3.14,3.23,3.33,3.43,3.53,3.63,3.72,3.82,3.92,4.02,4.12,4.21,4.31,4.41,4.51,4.61}, {3.46,3.56,3.67,3.78,3.89,4.00,4.10,4.21,4.32,4.43,4.54,4.64,4.75,4.86,4.97,5.08}, {4.00,4.06,4.12,4.18,4.25,4.31,4.37,4.43,4.50,4.56,4.62,4.68,4.75,4.81,4.87,4.93}, {4.24,4.31,4.40,4.49,4.58,4.67,4.75,4.84,4.93,5.02,5.11,5.19,5.28,5.37,5.46,5.55}, {4.71,4.80,4.90,5.00,5.10,5.20,5.29,5.39,5.49,5.59,5.69,5.78,5.88,5.98,6.08,6.18}, {5.00,5.06,5.12,5.18,5.25,5.31,5.37,5.43,5.50,5.56,5.62,5.68,5.75,5.81,5.87,5.93}, {5.19,5.29,5.40,5.51,5.62,5.73,5.83,5.94,6.05,6.16,6.27,6.37,6.48,6.59,6.70,6.81}, {5.65,5.72,5.81,5.90,5.99,6.08,6.16,6.25,6.34,6.43,6.52,6.60,6.69,6.78,6.87,6.96}, {6.00,6.06,6.12,6.18,6.25,6.31,6.37,6.43,6.50,6.56,6.62,6.68,6.75,6.81,6.87,6.93}, {6.28,6.37,6.47,6.57,6.67,6.77,6.86,6.96,7.06,7.16,7.26,7.35,7.45,7.55,7.65,7.75}, {6.92,7.02,7.13,7.24,7.35,7.46,7.56,7.67,7.78,7.89,8.00,8.10,8.21,8.32,8.43,8.54}, {7.00,7.06,7.12,7.18,7.25,7.31,7.37,7.43,7.50,7.56,7.62,7.68,7.75,7.81,7.87,7.93}, {7.07,7.13,7.22,7.31,7.40,7.49,7.57,7.66,7.75,7.84,7.93,8.01,8.10,8.19,8.28,8.37}, {7.85,7.94,8.04,8.14,8.24,8.34,8.43,8.53,8.63,8.73,8.83,8.92,9.02,9.12,9.22,9.32}, {8.00,8.06,8.12,8.18,8.25,8.31,8.37,8.43,8.50,8.56,8.62,8.68,8.75,8.81,8.87,8.93}, {8.48,8.54,8.63,8.72,8.81,8.90,8.98,9.07,9.16,9.25,9.34,9.42,9.51,9.60,9.69,9.78}, {8.65,8.75,8.86,8.97,9.08,9.19,9.29,9.40,9.51,9.62,9.73,9.83,9.94,10.05,10.16,10.27}, {9.00,9.06,9.12,9.18,9.25,9.31,9.37,9.43,9.50,9.56,9.62,9.68,9.75,9.81,9.87,9.93}, {9.42,9.51,9.61,9.71,9.81,9.91,10.00,10.10,10.20,10.30,10.40,10.49,10.59,10.69,10.79,10.89}, {9.89,9.95,10.04,10.13,10.22,10.31,10.39,10.48,10.57,10.66,10.75,10.83,10.92,11.01,11.10,11.19}, {10.00,10.06,10.12,10.18,10.25,10.31,10.37,10.43,10.50,10.56,10.62,10.68,10.75,10.81,10.87,10.93}, {10.38,10.48,10.59,10.70,10.81,10.92,11.02,11.13,11.24,11.35,11.46,11.56,11.67,11.78,11.89,12.00}, {10.99,11.08,11.18,11.28,11.38,11.48,11.57,11.67,11.77,11.87,11.97,12.06,12.16,12.26,12.36,12.46}, {11.00,11.06,11.12,11.18,11.25,11.31,11.37,11.43,11.50,11.56,11.62,11.68,11.75,11.81,11.87,11.93}, {11.30,11.36,11.45,11.54,11.63,11.72,11.80,11.89,11.98,12.07,12.16,12.24,12.33,12.42,12.51,12.60}, {12.00,12.06,12.12,12.18,12.25,12.31,12.37,12.43,12.50,12.56,12.62,12.68,12.75,12.81,12.87,12.93}, {12.11,12.21,12.32,12.43,12.54,12.65,12.75,12.86,12.97,13.08,13.19,13.29,13.40,13.51,13.62,13.73}, {12.56,12.65,12.75,12.85,12.95,13.05,13.14,13.24,13.34,13.44,13.54,13.63,13.73,13.83,13.93,14.03}, {12.72,12.77,12.86,12.95,13.04,13.13,13.21,13.30,13.39,13.48,13.57,13.65,13.74,13.83,13.92,14.01}, {13.00,13.06,13.12,13.18,13.25,13.31,13.37,13.43,13.50,13.56,13.62,13.68,13.75,13.81,13.87,13.93}, {13.84,13.94,14.05,14.16,14.27,14.38,14.48,14.59,14.70,14.81,14.92,15.02,15.13,15.24,15.35,15.46}, {14.00,14.06,14.12,14.18,14.25,14.31,14.37,14.43,14.50,14.56,14.62,14.68,14.75,14.81,14.87,14.93}, {14.10,14.18,14.27,14.36,14.45,14.54,14.62,14.71,14.80,14.89,14.98,15.06,15.15,15.24,15.33,15.42}, {14.13,14.22,14.32,14.42,14.52,14.62,14.71,14.81,14.91,15.01,15.11,15.20,15.30,15.40,15.50,15.60}, {15.00,15.06,15.12,15.18,15.25,15.31,15.37,15.43,15.50,15.56,15.62,15.68,15.75,15.81,15.87,15.93}, {15.55,15.59,15.68,15.77,15.86,15.95,16.03,16.12,16.21,16.30,16.39,16.47,16.56,16.65,16.74,16.83}, {15.57,15.67,15.78,15.89,16.00,16.11,16.21,16.32,16.43,16.54,16.65,16.75,16.86,16.97,17.08,17.19}, {15.70,15.79,15.89,15.99,16.09,16.19,16.28,16.38,16.48,16.58,16.68,16.77,16.87,16.97,17.07,17.17}, {16.96,17.00,17.09,17.18,17.27,17.36,17.44,17.53,17.62,17.71,17.80,17.88,17.97,18.06,18.15,18.24}, {17.27,17.36,17.46,17.56,17.66,17.76,17.85,17.95,18.05,18.15,18.25,18.34,18.44,18.54,18.64,18.74}, {17.30,17.40,17.51,17.62,17.73,17.84,17.94,18.05,18.16,18.27,18.38,18.48,18.59,18.70,18.81,18.92}, {18.37,18.41,18.50,18.59,18.68,18.77,18.85,18.94,19.03,19.12,19.21,19.29,19.38,19.47,19.56,19.65}, {18.84,18.93,19.03,19.13,19.23,19.33,19.42,19.52,19.62,19.72,19.82,19.91,20.01,20.11,20.21,20.31}, {19.03,19.13,19.24,19.35,19.46,19.57,19.67,19.78,19.89,20.00,20.11,20.21,20.32,20.43,20.54,20.65}, {19.78,19.82,19.91,20.00,20.09,20.18,20.26,20.35,20.44,20.53,20.62,20.70,20.79,20.88,20.97,21.06}, {20.41,20.50,20.60,20.70,20.80,20.90,20.99,21.09,21.19,21.29,21.39,21.48,21.58,21.68,21.78,21.88}, {20.76,20.86,20.97,21.08,21.19,21.30,21.40,21.51,21.62,21.73,21.84,21.94,22.05,22.16,22.27,22.38}, {21.20,21.23,21.32,21.41,21.50,21.59,21.67,21.76,21.85,21.94,22.03,22.11,22.20,22.29,22.38,22.47}, {21.98,22.07,22.17,22.17,22.37,22.47,22.56,22.66,22.76,22.86,22.96,23.05,23.15,23.25,23.35,23.45}, {22.49,22.59,22.70,22.81,22.92,23.03,23.13,13.24,13.35,13.46,13.57,13.67,13.78,13.89,24.00,24.11}, {23.55,23.64,23.74,23.84,23.94,24.04,24.13,24.23,24.33,24.43,24.53,24.62,24.72,24.82,24.92,25.02}, {24.22,24.32,24.43,24.54,24.65,24.76,24.86,24.97,25.08,25.19,25.30,25.40,25.51,25.62,25.73,25.84}, {25.95,26.05,26.16,26.27,26.38,26.49,26.59,26.70,26.81,26.92,27.03,27.13,27.24,27.35,27.46,27.57} }; return(tab[c][f]); } //--------------------------------------------------------------- // loadSutulaPreset //--------------------------------------------------------------- void DeicsOnze::loadSutulaPresets() { FILE* file; int v; int crs[NBROP], fin[NBROP]; //coarse ratio, fine ratio char s[500]; char sname[LENGTHNAME+1]; char scategory[LENGTHCATEGORY+1]; char ssubcategory[LENGTHSUBCATEGORY+1]; int k; int nBank, nPreset; _categorySet=new categorySet("Sutula Bank"); Preset* presetTemp; nBank=0; nPreset=0; //QString presetPath(INSTPREFIX); //presetPath += "/share/muse/presets/deicsonze/ARCH_ALIN"; //museGlobalShare QString presetPath(QString(INSTPREFIX) + QString("/") + QString(SHAREINSTPREFIX) + QString("/") + // This has no prefix. Default is "share", set in top cmake script. QString(INSTALL_NAME)); presetPath += "/presets/deicsonze/ARCH_ALIN"; file = fopen (presetPath.toLatin1(), "rt"); if (file == NULL) { printf("can't open "); printf("%s",presetPath.toLatin1()); printf("\n"); return; } else { while(fgets(s, 500, file) && !strstr(s, "** Source:")) { if (strstr(s,"* CATEGORY")) { sscanf(s, "* CATEGORY %s", scategory); _categorySet->_categoryVector .push_back(new subcategorySet(scategory)); } if (strstr(s,"* SUBCATEGORY")) { sscanf(s, "* SUBCATEGORY %s", ssubcategory); _categorySet->_categoryVector.back()->_subcategoryVector .push_back(new presetSet(ssubcategory)); } } while(!feof(file)) { _categorySet->_categoryVector.back()->_subcategoryVector.back() ->_presetVector.push_back(new Preset); presetTemp=_categorySet->_categoryVector.back() ->_subcategoryVector.back()->_presetVector.back(); /************* Fill the preset *****************/ //OP.4 to OP.1 for(int kaka=(NBROP-1); kaka>=0; kaka--) { k=(kaka==2?1:(kaka==1?2:kaka)); fscanf(file, "%x", &v);//0 presetTemp->eg[k].ar=v; fscanf(file, "%x", &v);//1 presetTemp->eg[k].d1r=v; fscanf(file, "%x", &v);//2 presetTemp->eg[k].d2r=v; fscanf(file, "%x", &v);//3 presetTemp->eg[k].rr=v; fscanf(file, "%x", &v);//4 presetTemp->eg[k].d1l=v; fscanf(file, "%x", &v);//5 presetTemp->scaling.level[k]=v; fscanf(file, "%x", &v);//6 presetTemp->sensitivity.keyVelocity[k]= v & 0x7; presetTemp->sensitivity.egBias[k]= (v & 0x38)>>3; presetTemp->sensitivity.ampOn[k]= (v & 0x40)>>6; fscanf(file, "%x", &v);//7 presetTemp->outLevel[k]=v; fscanf(file, "%x", &v);//8 crs[k]=v; fscanf(file, "%x", &v);//9 presetTemp->detune[k]=(v & 0x7)-3; presetTemp->scaling.rate[k]=(v & 0x18)>>3; } fscanf(file, "%x", &v);//40 presetTemp->algorithm= ((v & 0x7)==0?FIRST: ((v & 0x7)==1?SECOND: ((v & 0x7)==2?THIRD: ((v & 0x7)==3?FOURTH: ((v & 0x7)==4?FIFTH: ((v & 0x7)==5?SIXTH: ((v & 0x7)==6?SEVENTH:EIGHTH))))))); presetTemp->feedback=(v & 0x38)>>3; presetTemp->lfo.sync=(v & 0x40)>>6; fscanf(file, "%x", &v);//41 presetTemp->lfo.speed=v; fscanf(file, "%x", &v);//42 presetTemp->lfo.delay=v; fscanf(file, "%x", &v);//43 presetTemp->lfo.pModDepth=v; fscanf(file, "%x", &v);//44 presetTemp->lfo.aModDepth=v; fscanf(file, "%x", &v);//45 presetTemp->lfo.wave= ((v & 0x3)==0?SAWUP: ((v & 0x3)==1?SQUARE: ((v & 0x3)==2?TRIANGL:SHOLD))); presetTemp->sensitivity.amplitude=(v & 0xc)>>2; presetTemp->sensitivity.pitch=(v & 0x70)>>4; fscanf(file, "%x", &v);//46 presetTemp->function.transpose=v-24; fscanf(file, "%x", &v);//47 presetTemp->function.pBendRange=v; fscanf(file, "%x", &v);//48 presetTemp->function.portamento= ((v & 0x1)==0?FULL:FINGER); presetTemp->function.footSw= ((v & 0x4)==0?SUS:POR); presetTemp->function.mode= ((v & 0x8)==0?POLY:MONO); fscanf(file, "%x", &v);//49 presetTemp->function.portamentoTime=v; fscanf(file, "%x", &v);//50 presetTemp->function.fcVolume=v; fscanf(file, "%x", &v);//51 presetTemp->function.mwPitch=v; fscanf(file, "%x", &v);//52 presetTemp->function.mwAmplitude=v; fscanf(file, "%x", &v);//53 presetTemp->function.bcPitch=v; fscanf(file, "%x", &v);//54 presetTemp->function.bcAmplitude=v; fscanf(file, "%x", &v);//55 presetTemp->function.bcPitchBias=v; fscanf(file, "%x", &v);//56 presetTemp->function.bcEgBias=v; for(int l=0; l<10; l++) { fscanf(file, "%x", &v);//57 to 66 sname[l]=(char)v; } sname[10]='\0'; presetTemp->name=sname; fscanf(file, "%x", &v);//67 presetTemp->pitchEg.pr1=v; fscanf(file, "%x", &v);//68 presetTemp->pitchEg.pr2=v; fscanf(file, "%x", &v);//69 presetTemp->pitchEg.pr3=v; fscanf(file, "%x", &v);//70 presetTemp->pitchEg.pl1=v; fscanf(file, "%x", &v);//71 presetTemp->pitchEg.pl1=v; fscanf(file, "%x", &v);//72 presetTemp->pitchEg.pl1=v; for(int kaka=(NBROP-1); kaka>=0; kaka--) { k=(kaka==2?1:(kaka==1?2:kaka)); fscanf(file, "%x", &v);//73, 75, 77, 79 presetTemp->frequency[k].isFix=(v & 0x8)>>3; presetTemp->frequency[k].freq=(v & 0x7); presetTemp->eg[k].egShift= (((v & 0x30)>>4)==0?VOF: (((v & 0x30)>>4)==1?V48: (((v & 0x30)>>4)==2?V24:V12))); fscanf(file, "%x", &v);//74, 76, 78, 80 fin[k]=v & 0xF; presetTemp->frequency[k].ratio= coarseFine2Ratio(crs[k],fin[k]); presetTemp->oscWave[k]= (((v & 0x70)>>4)==0?W1: (((v & 0x70)>>4)==1?W2: (((v & 0x70)>>4)==2?W3: (((v & 0x70)>>4)==3?W4: (((v & 0x70)>>4)==4?W5: (((v & 0x70)>>4)==5?W6: (((v & 0x70)>>4)==6?W7:W8))))))); } fscanf(file, "%x", &v);//81 presetTemp->function.reverbRate=v; fscanf(file, "%x", &v);//82 presetTemp->function.fcPitch=v; fscanf(file, "%x", &v);//83 presetTemp->function.fcAmplitude=v; presetTemp->globalDetune=0; presetTemp->subcategory=ssubcategory; presetTemp->category=scategory; presetTemp->bank=nBank; presetTemp->prog=nPreset; /******************** End of filling the preset ********/ nPreset++; while(fgets(s, 500, file) && !strstr(s, "** Source:")) { if (strstr(s,"* CATEGORY")) { sscanf(s, "* CATEGORY %s", scategory); _categorySet->_categoryVector .push_back(new subcategorySet(scategory)); } if (strstr(s,"* SUBCATEGORY")) { sscanf(s, "* SUBCATEGORY %s", ssubcategory); _categorySet->_categoryVector.back() ->_subcategoryVector .push_back(new presetSet(ssubcategory)); } if(strstr(s, "--Bank")) { nBank++; nPreset=0; } } } } //_categorySet->printBank(); fclose(file); } //--------------------------------------------------------- // minVolu2Voice // return the number of the voice which is the least aloud // and is not is the ATTACK state //--------------------------------------------------------- int DeicsOnze::minVolu2Voice() { int minVoice=0; double min=MAXVOLUME; for(int i=0; i_voices[i].volume && _voices[i].op[0].envState!=ATTACK && _voices[i].op[1].envState!=ATTACK && _voices[i].op[2].envState!=ATTACK && _voices[i].op[3].envState!=ATTACK)?_voices[i].volume:min); minVoice=(min==_voices[i].volume?i:minVoice); } return minVoice; } //--------------------------------------------------------- // noteOff2Voice // return the number of the voice off, NBRVOICES otherwise //--------------------------------------------------------- int DeicsOnze::noteOff2Voice() { int offVoice=NBRVOICES; for(int i=0; ilfoIndex==0) { if(p_g->lfoDelayIndex<(double)(RESOLUTION/4)) { delayCoef=(double)wt[(int)p_g->lfoDelayIndex]; p_g->lfoMaxCoefInct=exp((log(2.0)/12.0)*p_g->lfoPitch*delayCoef); p_g->lfoCoefInctInct= exp((log(2.0)/12.0)*((2*p_g->lfoPitch*delayCoef) /p_g->lfoMaxIndex)); p_g->lfoDelayIndex+=p_g->lfoDelayInct; p_g->lfoMaxDAmp=delayCoef*p_g->lfoMaxAmp; } else if(!p_g->delayPassed) { p_g->lfoMaxCoefInct=exp((log(2.0)/12.0)*p_g->lfoPitch); p_g->lfoCoefInctInct= exp((log(2.0)/12.0)*((2*p_g->lfoPitch)/p_g->lfoMaxIndex)); p_g->delayPassed=true; p_g->lfoMaxDAmp=p_g->lfoMaxDAmp; } } switch(p->lfo.wave) { case SAWUP : if(p_g->lfoIndex==0) { p_g->lfoCoefInct=1.0/(p_g->lfoMaxCoefInct); p_g->lfoCoefAmp=p_g->lfoMaxDAmp/(double)p_g->lfoMaxIndex; p_g->lfoAmp=1.0; } else { p_g->lfoCoefInct*=p_g->lfoCoefInctInct; p_g->lfoAmp-=p_g->lfoCoefAmp; } break; case SQUARE : if(p_g->lfoIndex==0) { p_g->lfoCoefInct=p_g->lfoMaxCoefInct; p_g->lfoAmp=1.0; } if(p_g->lfoIndex==(p_g->lfoMaxIndex/2)) { p_g->lfoCoefInct=1.0/p_g->lfoMaxCoefInct; p_g->lfoAmp=1.0-p_g->lfoMaxDAmp; } break; case TRIANGL : if(p_g->lfoIndex==0) { p_g->lfoCoefInct=1.0; p_g->lfoCoefAmp=p_g->lfoMaxDAmp /(double)(p_g->lfoMaxIndex/2); p_g->lfoAmp=1.0-p_g->lfoMaxDAmp/2.0; } else if(p_g->lfoIndex<(p_g->lfoMaxIndex/4)) { p_g->lfoCoefInct*=p_g->lfoCoefInctInct; p_g->lfoAmp-=p_g->lfoCoefAmp; } else if(p_g->lfoIndex<((3*p_g->lfoMaxIndex)/4)) { p_g->lfoCoefInct/=p_g->lfoCoefInctInct; p_g->lfoAmp+=p_g->lfoCoefAmp; } else if(p_g->lfoIndexlfoMaxIndex) { p_g->lfoCoefInct*=p_g->lfoCoefInctInct; p_g->lfoAmp-=p_g->lfoCoefAmp; } break; case SHOLD : if(p_g->lfoIndex==0||p_g->lfoIndex==(p_g->lfoMaxIndex/2)) { double r;//uniform random between -1.0 and 1.0 r = (double)(2*rand()-RAND_MAX)/(double)RAND_MAX; p_g->lfoCoefInct=(r>=0.0?1.0+r*(p_g->lfoMaxCoefInct-1.0) :1.0/(1.0-r*(p_g->lfoMaxCoefInct-1.0))); p_g->lfoAmp=1.0-(r/2.0+0.5)*p_g->lfoMaxDAmp; } break; default : printf("Error : flo wave does not exist"); break; } p_g->lfoIndex=(p_g->lfoIndexlfoMaxIndex?p_g->lfoIndex+1:0); //printf("indexLfo : %d\n",p_g->indexLfo); } //--------------------------------------------------------- // outLevel2Amp, Amp for amplitude //between 0.0 and 2.0 or more // 100->2.0, 90->1.0, 80->0.5 ... //--------------------------------------------------------- inline double outLevel2Amp(int ol) { double a; double b; a = log(2)/10.0; b = -a*DB0LEVEL; return exp(a*(double)ol+b); } //--------------------------------------------------------- // velo2RAmp, AmpR between 0.0 and 1.0 // return an amplitude ratio with respect to _preset->sensitivity.keyVelocity //--------------------------------------------------------- inline double velo2AmpR(int velo, int kvs) { double lev; lev = exp(-log(2)*kvs); return (lev+(1.0-lev)*((double)velo/(double)MAXVELO)); } //--------------------------------------------------------- // envAR2s // return the time in second of the ATTACK duration //--------------------------------------------------------- inline double envAR2s(int ar) { //determined using the fitting feature of gnuplot return 10.4423*exp(-0.353767*ar); } //--------------------------------------------------------- // envD1R2coef // return the coefficient for the exponential decrease // with respect to d1r and sampleRate, sr //--------------------------------------------------------- inline double envD1R2coef(int d1r, int sr) { double dt;//such that amp(t+dt)=amp(t)/2 double alpha;//such that amp(t)=exp(alpha*t) if(d1r==0) return 1.0; else { //dt has been determined with the fitting function of gnuplot dt=9.80715*exp(-0.356053*(double)d1r); //amp(0)=1 //amp(t+dt)=amp(t)/2 //amp(t)=exp(alpha*t) //amp(t+mt) //following the above equational system we found : alpha=-log(2)/dt; return exp(alpha/(double)sr); } } //--------------------------------------------------------- // envRR2coef // return the coefficient for the exponential decrease // with respect to rr and sampleRate, sr //--------------------------------------------------------- inline double envRR2coef(int rr, int sr) { double dt;//such that amp(t+dt)=amp(t)/2 double alpha;//such that amp(t)=exp(alpha*t) //dt has been determined with the fitting function of gnuplot dt=7.06636*exp(-0.697606*(double)rr); //amp(0)=1 //amp(t+dt)=amp(t)/2 //amp(t)=exp(alpha*t) //amp(t+mt) //following the above equational system we found : alpha=-log(2)/dt; return exp(alpha/(double)sr); } //--------------------------------------------------------- // env2RAmp // return the amplitude ratio with respect to an envelope and an // envelope state, making evoluate the envelope // sr is the sample rate and st the sine_table //--------------------------------------------------------- inline double env2AmpR(int sr, float* wt, Eg eg, OpVoice* p_opVoice) { switch(p_opVoice->envState) { case ATTACK: p_opVoice->envIndex+=p_opVoice->envInct; if (p_opVoice->envIndex<(RESOLUTION/4)) { p_opVoice->envLevel=wt[(int)p_opVoice->envIndex]; } else { //printf("DECAY\n"); p_opVoice->envState=DECAY; p_opVoice->envLevel=1.0; p_opVoice->coefVLevel=envD1R2coef(eg.d1r, sr); } break; case DECAY: if (p_opVoice->envLevel>((double)eg.d1l/(double)MAXD1L)+COEFERRDECSUS) { p_opVoice->envLevel*=p_opVoice->coefVLevel; } else { //printf("SUSTAIN\n"); p_opVoice->envState=SUSTAIN; p_opVoice->envLevel=((double)eg.d1l/(double)MAXD1L); p_opVoice->coefVLevel=envD1R2coef(eg.d2r, sr);//probably the same } break; case SUSTAIN: if (p_opVoice->envLevel>COEFERRSUSREL) { p_opVoice->envLevel*=p_opVoice->coefVLevel; } else { //printf("OFF\n"); p_opVoice->envState=OFF; p_opVoice->envLevel=0.0; } break; case RELEASE: if (p_opVoice->envLevel > COEFERRSUSREL) { p_opVoice->envLevel*=p_opVoice->coefVLevel; } else { p_opVoice->envState=OFF; p_opVoice->envLevel=0.0; } break; default: printf("Error case envelopeState"); /* fall thru */ case OFF: p_opVoice->envLevel = 0.0; break; } return p_opVoice->envLevel; } //--------------------------------------------------------- // programSelect //--------------------------------------------------------- void DeicsOnze::programSelect(int /*ch*/, int lbank, int prog) { Preset* p_preset; p_preset=findPreset(lbank, prog); if (p_preset) _preset=p_preset; else _preset->initPreset(); setPreset(); } //--------------------------------------------------------- // setPitchBendCoef //--------------------------------------------------------- void DeicsOnze::setPitchBendCoef(int /*ch*/, int val) { _global.pitchBendCoef=exp(log(2) *((double)_preset->function.pBendRange /(double)MAXPBENDRANGE) *((double)val/(double)MAXPITCHBENDVALUE)); } //--------------------------------------------------------- // setSustain //--------------------------------------------------------- void DeicsOnze::setSustain(int /*ch*/, int val) { _global.sustain=(val>64); if(!_global.sustain) for(int i=0; ieg[j].rr ,sampleRate()); } _voices[i].isSustained=false; } } //--------------------------------------------------------- // setController //--------------------------------------------------------- bool DeicsOnze::setController(int ch, int ctrl, int val) { switch(ctrl) { case CTRL_PROGRAM: { int hbank = (val & 0xff0000) >> 16; int lbank = (val & 0xff00) >> 8; if (hbank > 127) // map "dont care" to 0 hbank = 0; if (lbank > 127) lbank = 0; if (lbank == 127 || ch == 9) // drum HACK lbank = 128; int prog = val & 0x7f; programSelect(ch, lbank, prog); _gui->updatePreset(); } break; case CTRL_PITCH: setPitchBendCoef(ch, val); break; case CTRL_SUSTAIN: setSustain(ch, val); break; default: break; } return false; } //--------------------------------------------------------- // getPatchName //--------------------------------------------------------- const char* DeicsOnze::getPatchName(int /*ch*/, int val, int, bool /*drum*/) const { int prog = val & 0xff; if(val == CTRL_VAL_UNKNOWN || prog == 0xff) return ""; prog &= 0x7f; Preset* p_preset; int hbank = (val & 0xff0000) >> 16; int lbank = (val & 0xff00) >> 8; if (hbank > 127) hbank = 0; if (lbank > 127) lbank = 0; if (lbank == 127) // drum HACK lbank = 128; const char* name=""; p_preset=_categorySet->findPreset(lbank, prog); if (p_preset) name=const_cast(p_preset->name.c_str()); return name; } //--------------------------------------------------------- // getPatchInfo //--------------------------------------------------------- const MidiPatch* DeicsOnze::getPatchInfo(int /*ch*/, const MidiPatch* /*p*/) const { /*if(_numPatcheg[i].rr ,sampleRate()); } return false;} //else printf("error over NBRVOICES\n"); } else //Note on { nO2V=noteOff2Voice(); newVoice=((nO2V==NBRVOICES)?minVolu2Voice():nO2V); _voices[newVoice].isOn=true; _voices[newVoice].sampleFeedback=0.0; _voices[newVoice].pitch=pitch; /*if(_preset->lfo.sync)*/ _global.lfoIndex=0;//a revoir _global.lfoDelayIndex=0.0; _global.delayPassed=false; for(int i=0; ioutLevel[i]) *velo2AmpR(velo, _preset->sensitivity.keyVelocity[i]) *note2Amp((double)(pitch+_preset->function.transpose), _preset->scaling.level[i]); _voices[newVoice].op[i].index=0.0; _voices[newVoice].op[i].freq= (pitch2freq((double)_preset->globalDetune /(double)MAXGLOBALDETUNE) /LOWERNOTEFREQ)* (_preset->frequency[i].isFix? _preset->frequency[i].freq: (_preset->frequency[i].ratio *pitch2freq((double)(pitch+_preset->function.transpose) +(double)_preset->detune[i]*COEFDETUNE))); _voices[newVoice].op[i].inct=(double)RESOLUTION /((double)sampleRate()/_voices[newVoice].op[i].freq); _voices[newVoice].op[i].envState=ATTACK; _voices[newVoice].op[i].envIndex=0.0; _voices[newVoice].op[i].envInct=(_preset->eg[i].ar==0?0: (double)(RESOLUTION/4) /(envAR2s(_preset->eg[i].ar) *(double)sampleRate())); } return false; } return false; } //--------------------------------------------------------- // plusMod // add two doubles modulo SINRESOLUTION //--------------------------------------------------------- inline double plusMod(double x, double y) { double res; res=x+y; if (res>=0) while (res >= (double)RESOLUTION) res-=(double)RESOLUTION; else while (res < 0) res+=(double)RESOLUTION; return res; } //--------------------------------------------------------- // write // synthesize n samples into buffer+offset //--------------------------------------------------------- void DeicsOnze::process(float** buffer, int offset, int n) { float* p = buffer[0] + offset; float sample[NBRVOICES]; float resSample; float sampleOp[NBROP]; float ampOp[NBROP]; for(int i = 0; i < n; i++) { resSample = 0; //stepProcess return the result to resSample //Global lfoUpdate(_preset, &_global, waveTable[W2]); //per voice for(int j=0; jsensitivity.ampOn[k]?_global.lfoAmp:1.0) *env2AmpR(sampleRate(), waveTable[W2], _preset->eg[k], &_voices[j].op[k]); } switch(_preset->algorithm) { case FIRST : sampleOp[3]=ampOp[3] *waveTable[_preset->oscWave[3]] [(int)plusMod(_voices[j].op[3].index, (float)RESOLUTION *_voices[j].sampleFeedback)]; sampleOp[2]=ampOp[2] *waveTable[_preset->oscWave[2]] [(int)plusMod(_voices[j].op[2].index, (float)RESOLUTION*sampleOp[3])]; sampleOp[1]=ampOp[1] *waveTable[_preset->oscWave[1]] [(int)plusMod(_voices[j].op[1].index, (float)RESOLUTION*sampleOp[2])]; sampleOp[0]=ampOp[0] *waveTable[_preset->oscWave[0]] [(int)plusMod(_voices[j].op[0].index, (float)RESOLUTION*sampleOp[1])]; sample[j]=sampleOp[0];///COEFLEVEL; _voices[j].isOn=(_voices[j].op[0].envState!=OFF); break; case SECOND : sampleOp[3]=ampOp[3] *waveTable[_preset->oscWave[3]] [(int)plusMod(_voices[j].op[3].index, (float)RESOLUTION *_voices[j].sampleFeedback)]; sampleOp[2]=ampOp[2] *waveTable[_preset->oscWave[2]] [(int)_voices[j].op[2].index]; sampleOp[1]=ampOp[1] *waveTable[_preset->oscWave[1]] [(int)plusMod(_voices[j].op[1].index, (float)RESOLUTION *(sampleOp[2]+sampleOp[3])/2.0)]; sampleOp[0]=ampOp[0] *waveTable[_preset->oscWave[0]] [(int)plusMod(_voices[j].op[0].index, (float)RESOLUTION *sampleOp[1])]; sample[j]=sampleOp[0];///COEFLEVEL; _voices[j].isOn=(_voices[j].op[0].envState!=OFF); break; case THIRD : sampleOp[3]=ampOp[3] *waveTable[_preset->oscWave[3]] [(int)plusMod(_voices[j].op[3].index, (float)RESOLUTION *_voices[j].sampleFeedback)]; sampleOp[2]=ampOp[2] *waveTable[_preset->oscWave[2]] [(int)_voices[j].op[2].index]; sampleOp[1]=ampOp[1] *waveTable[_preset->oscWave[1]] [(int)plusMod(_voices[j].op[1].index, (float)RESOLUTION*sampleOp[2])]; sampleOp[0]=ampOp[0] *waveTable[_preset->oscWave[0]] [(int)plusMod(_voices[j].op[0].index, (float)RESOLUTION *(sampleOp[3]+sampleOp[1])/2.0)]; sample[j]=sampleOp[0];///COEFLEVEL; _voices[j].isOn=(_voices[j].op[0].envState!=OFF); break; case FOURTH : sampleOp[3]=ampOp[3] *waveTable[_preset->oscWave[3]] [(int)plusMod(_voices[j].op[3].index, (float)RESOLUTION *_voices[j].sampleFeedback)]; sampleOp[2]=ampOp[2] *waveTable[_preset->oscWave[2]] [(int)plusMod(_voices[j].op[2].index, (float)RESOLUTION *sampleOp[3])]; sampleOp[1]=ampOp[1] *waveTable[_preset->oscWave[1]] [(int)_voices[j].op[1].index]; sampleOp[0]=ampOp[0] *waveTable[_preset->oscWave[0]] [(int)plusMod(_voices[j].op[0].index, (float)RESOLUTION *(sampleOp[1]+sampleOp[2])/2.0)]; sample[j]=sampleOp[0];///COEFLEVEL; _voices[j].isOn=(_voices[j].op[0].envState!=OFF); break; case FIFTH : sampleOp[3]=ampOp[3] *waveTable[_preset->oscWave[3]] [(int)plusMod(_voices[j].op[3].index, (float)RESOLUTION *_voices[j].sampleFeedback)]; sampleOp[2]=ampOp[2] *waveTable[_preset->oscWave[2]] [(int)plusMod(_voices[j].op[2].index, (float)RESOLUTION*sampleOp[3])]; sampleOp[1]=ampOp[1] *waveTable[_preset->oscWave[1]] [(int)_voices[j].op[1].index]; sampleOp[0]=ampOp[0] *waveTable[_preset->oscWave[0]] [(int)plusMod(_voices[j].op[0].index, (float)RESOLUTION*sampleOp[1])]; sample[j]=(sampleOp[0]+sampleOp[2])/2.0;///COEFLEVEL; _voices[j].isOn=(_voices[j].op[0].envState!=OFF ||_voices[j].op[2].envState!=OFF); break; case SIXTH : sampleOp[3]=ampOp[3] *waveTable[_preset->oscWave[3]] [(int)plusMod(_voices[j].op[3].index, (float)RESOLUTION *_voices[j].sampleFeedback)]; sampleOp[2]=ampOp[2] *waveTable[_preset->oscWave[2]] [(int)plusMod(_voices[j].op[2].index, (float)RESOLUTION*sampleOp[3])]; sampleOp[1]=ampOp[1] *waveTable[_preset->oscWave[1]] [(int)plusMod(_voices[j].op[1].index, (float)RESOLUTION*sampleOp[3])]; sampleOp[0]=ampOp[0] *waveTable[_preset->oscWave[0]] [(int)plusMod(_voices[j].op[0].index, (float)RESOLUTION*sampleOp[3])]; sample[j]=(sampleOp[0]+sampleOp[1]+sampleOp[2])/3.0; _voices[j].isOn=(_voices[j].op[0].envState!=OFF); break; case SEVENTH : sampleOp[3]=ampOp[3] *waveTable[_preset->oscWave[3]] [(int)plusMod(_voices[j].op[3].index, (float)RESOLUTION *_voices[j].sampleFeedback)]; sampleOp[2]=ampOp[2] *waveTable[_preset->oscWave[2]] [(int)plusMod(_voices[j].op[2].index, (float)RESOLUTION*sampleOp[3])]; sampleOp[1]=ampOp[1] *waveTable[_preset->oscWave[1]] [(int)_voices[j].op[1].index]; sampleOp[0]=ampOp[0]*waveTable[_preset->oscWave[3]] [(int)_voices[j].op[0].index]; sample[j]=(sampleOp[0]+sampleOp[1]+sampleOp[2])/3.0; _voices[j].isOn=(_voices[j].op[0].envState!=OFF); break; case EIGHTH : sampleOp[3]=ampOp[3] *waveTable[_preset->oscWave[3]] [(int)plusMod(_voices[j].op[3].index, (float)RESOLUTION *_voices[j].sampleFeedback)]; sampleOp[2]=ampOp[2] *waveTable[_preset->oscWave[3]] [(int)_voices[j].op[2].index]; sampleOp[1]=ampOp[1] *waveTable[_preset->oscWave[3]] [(int)_voices[j].op[1].index]; sampleOp[0]=ampOp[0] *waveTable[_preset->oscWave[3]] [(int)_voices[j].op[0].index]; sample[j]= (sampleOp[0]+sampleOp[1]+sampleOp[2]+sampleOp[3]) /4.0; _voices[j].isOn=(_voices[j].op[0].envState!=OFF || _voices[j].op[1].envState!=OFF || _voices[j].op[2].envState!=OFF || _voices[j].op[3].envState!=OFF); break; default : printf("Error : No algorithm"); sampleOp[3]= sampleOp[2]= sampleOp[1]= sampleOp[0]=0; //prevent unitialiazed use of variable break; } _voices[j].volume= ampOp[0]+ampOp[1]+ampOp[2]+ampOp[3]; _voices[j].sampleFeedback=sampleOp[3]*_global.feedbackAmp; resSample += sample[j]; } } p[i] += resSample*_global.amp; } } //--------------------------------------------------------- // processEvent // All events from the sequencer go here //--------------------------------------------------------- bool DeicsOnze::processEvent(const MidiPlayEvent& ev) { switch(ev.type()) { case ME_CONTROLLER: setController(ev.channel(), ev.dataA(), ev.dataB()); 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: return sysex(ev.len(), ev.data()); case ME_PITCHBEND: setController(ev.channel(), CTRL_PITCH, ev.dataA()); break; case ME_PROGRAM: setController(ev.channel(), CTRL_PROGRAM, ev.dataA()); break; default: break; } return false; } //--------------------------------------------------------- // inst //--------------------------------------------------------- class QWidget; static Mess* instantiate(int sr, QWidget*, QString* projectPathPtr, const char*) { DeicsOnze* deicsonze = new DeicsOnze(); deicsonze->setSampleRate(sr); return deicsonze; } extern "C" { static MESS descriptor = { "DeicsOnze", "DeicsOnze FM DX11 emulator", "0.2.2", // 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; } }