//=========================================================================== // // DeicsOnze an emulator of the YAMAHA DX11 synthesizer // // Version 0.5.5 // // // // // Copyright (c) 2004-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA // 02111-1301, USA or point your web browser to http://www.gnu.org. //=========================================================================== #ifndef __DEICSONZE_H #define __DEICSONZE_H #include #include "common_defs.h" #include "deicsonzepreset.h" #include "deicsonzegui.h" #include "deicsonzeplugin.h" #include "deicsonzefilter.h" #include "libsynti/mess.h" #include "plugin.h" #define DEICSONZESTR "deicsonze" #define MAXPITCHBENDVALUE 8191 #define RESOLUTION 96000 #define MAXFXBUFFERSIZE 48000 #define NBRFXINPUTS 2 #define NBRFXOUTPUTS 2 #define NBRCTRLS 127 #define NBRPRESETS 128 #define LOWERNOTEFREQ 8.176 #define DB0LEVEL 90 #define LENGTHNAME 20 #define LENGTHCATEGORY 20 #define LENGTHSUBCATEGORY 20 #define MAXVELO 127 #define MAXVOLUME 100.0 #define MAXSTRLENGTHINITSETPATH 256 #define MAXSTRLENGTHBACKGROUNDPIXPATH 256 #define MAXSTRLENGTHFXLIB 256 #define MAXSTRLENGTHFXLABEL 256 #define DB_MIN 25.0 //coef determined by ear to sound like the YAMAHA DX11 #define COEFFEEDBACK 0.3 #define COEFPLFO(x) (x==0?0.0:(x==1?0.06:(x==2?0.12:(x==3?0.25:(x==4?0.5:(x==5?0.9:(x==6?3.9:7.9))))))) //return pitch amplitude with respect to sensitivity pitch #define COEFALFO(x) (x==0?0.0:(x==1?0.4:(x==2?0.9:1.0))) #define MAX(x,y) (x2.0, 90->1.0, 80->0.5 ... //--------------------------------------------------------- inline double outLevel2Amp(int ol); //--------------------------------------------------------- // level2amp, // 255->0dB->1.0, 0->-27dB->0 //--------------------------------------------------------- inline double level2amp(int l); //--------------------------------------------------------- // amp2level // 1.0->0dB->255, 0->-27dB->0 //--------------------------------------------------------- inline int amp2level(double amp); //--------------------------------------------------------- // amp2lowlevel // 1.0->0dB->127, 0->-27dB->0 //--------------------------------------------------------- inline int amp2lowlevel(double amp); //--------------------------------------------------------- // lowlevel2amp, // 127->0dB->1.0, 0->-27dB->0 //--------------------------------------------------------- inline double lowlevel2amp(int l); //--------------------------------------------------------- // envAR2s // return the time in second of the ATTACK duration //--------------------------------------------------------- inline double envAR2s(int ar); //--------------------------------------------------------- // coefAttack // convert the attack value to a coef for envInct //--------------------------------------------------------- inline double coefAttack(unsigned char attack); //--------------------------------------------------------- // envRR2coef // return the coefficient for the exponential decrease // with respect to rr and sampleRate, sr //--------------------------------------------------------- inline double envRR2coef(int rr, double sr, unsigned char release); //-------------------------------------------------------- // DeicsOnzeCtrl //-------------------------------------------------------- struct DeicsOnzeCtlr { std::string name; int num; int min, max; }; //--------------------------------------------------------- // EnvState //--------------------------------------------------------- enum EnvState{ ATTACK, DECAY, SUSTAIN, RELEASE, OFF }; //--------------------------------------------------------- // OpVoice //--------------------------------------------------------- struct OpVoice { double index; double inct; double targetInct; //used if portamento double amp; //between 0 and 1 double ampVeloNote; //keeps the ratio amplitude from velo2AmpR and note2Amp //in order to change independently the output level //after pressing the note EnvState envState; double envIndex; double envInct; double envLevel; double coefVLevel; }; //--------------------------------------------------------- // PitchEnvState //--------------------------------------------------------- enum PitchEnvState{ PHASE1, PHASE2, RELEASE_PE, OFF_PE }; //--------------------------------------------------------- // Voice //--------------------------------------------------------- struct Voice { bool hasAttractor;//true iff the voice has an attractor (portamento occuring) double attractor; //contains some coeficent for portamento TODO PitchEnvState pitchEnvState; double pitchEnvCoefInct; double pitchEnvCoefInctPhase1; double pitchEnvCoefInctPhase2; double pitchEnvCoefInctPhase3; double pitchEnvCoefInctRelease; double pitchEnvCoefInctInct; bool isOn; bool keyOn; bool isSustained; int pitch; //number of the note double volume; OpVoice op[NBROP]; float sampleFeedback; }; //--------------------------------------------------------- // Channel //--------------------------------------------------------- struct Channel { bool isEnable; float ampLeft; float ampRight; int volume; //0 to 255 int pan; //TODO -63 +64 or -127 +128 int modulation;//0 to 127 int detune;//-31 to 31 int brightness; //0 to 4095 int attack; //0 to 127 int release; //0 to 127 float feedbackAmp; float lfoFreq; float lfoPitch; float lfoMaxCoefInct; float lfoCoefInct; float lfoCoefInctInct; unsigned int lfoIndex; unsigned int lfoMaxIndex; float lfoMaxAmp; float lfoMaxDAmp; float lfoAmp; float lfoCoefAmp; double lfoDelayIndex; double lfoDelayInct; double lfoDelayMaxIndex; bool delayPassed; bool sustain; double pitchBendCoef;//speed coef to read the sample unsigned char nbrVoices; Voice voices[MAXNBRVOICES]; double lastInc[NBROP]; std::list lastVoiceKeyOn; //stack of the voice number int lastVoiceKeyOff; bool isLastNote; //FX float chorusAmount; //between 0.0 and 1.0 float reverbAmount; //between 0.0 and 1.0 float delayAmount; //between 0.0 and 1.0 }; //--------------------------------------------------------- // Global //--------------------------------------------------------- enum Quality { high, middle, low, ultralow }; struct Global { float masterVolume; Quality quality; //high, middle, low int qualityCounter; //counter to skip some sample depending on quality int qualityCounterTop; //number of sample - 1 to skip double deiSampleRate; //depending on quality deicsOnze sample rate varies bool filter; //low passe filter used when the sampling is low int fontSize; float lastLeftSample; float lastRightSample; float lastInputLeftChorusSample; float lastInputRightChorusSample; float lastInputLeftReverbSample; float lastInputRightReverbSample; float lastInputLeftDelaySample; float lastInputRightDelaySample; Channel channel[NBRCHANNELS]; bool isChorusActivated; float chorusReturn; bool isReverbActivated; float reverbReturn; bool isDelayActivated; float delayReturn; }; //--------------------------------------------------------- // DeicsOnze : DX11 emulator //--------------------------------------------------------- class DeicsOnze : public Mess { DeicsOnzeGui* _gui; unsigned char* initBuffer; int initLen; static int useCount; static float waveTable[NBRWAVES][RESOLUTION]; private: void parseInitData(int length, const unsigned char* data); void loadConfiguration(QString fileName); void setupInitBuffer(int len); public: float** tempInputChorus; float** tempOutputChorus; float** tempInputReverb; float** tempOutputReverb; float** tempInputDelay; float** tempOutputDelay; float* getSinusWaveTable(); int nbrCtrl; QString _initSetPath; bool _isInitSet; QString _backgroundPixPath; bool _isBackgroundPix; bool _saveOnlyUsed; bool _saveConfig; DeicsOnzeCtlr _ctrl[NBRCTRLS]; Global _global; Preset* _preset[NBRCHANNELS]; Preset* _initialPreset; //FX MusECore::PluginI* _pluginIReverb; MusECore::PluginI* _pluginIChorus; MusECore::PluginI* _pluginIDelay; void initPluginReverb(MusECore::Plugin*); void initPluginChorus(MusECore::Plugin*); void initPluginDelay(MusECore::Plugin*); void setReverbParam(int i, float val); float getReverbParam(int i) const; void setChorusParam(int i, float val); float getChorusParam(int i) const; void setDelayParam(int i, float val); float getDelayParam(int i) const; void setDelayBPM(float val); void setDelayBeatRatio(float val); void setDelayFeedback(float val); void setDelayLFOFreq(float val); void setDelayLFODepth(float val); void setDelayDryWet(float val); float getDelayDryWet() const; float getDelayBPM() const; float getDelayBeatRatio() const; float getDelayFeedback() const; float getDelayLFOFreq() const; float getDelayLFODepth() const; //Filter LowFilter* _dryFilter; LowFilter* _chorusFilter; LowFilter* _reverbFilter; LowFilter* _delayFilter; mutable MidiPatch _patch; mutable int _numPatchProg; //used by getPatchInfo //preset tree Set* _set; void setSampleRate(int sr); Preset* findPreset(int hbank, int lbank, int prog) const; Subcategory* findSubcategory(int hbank, int lbank) const; Category* findCategory(int hbank) const; void initCtrls(); void initGlobal(); void initChannels(); void initChannel(int c); void resetVoices(); //when panic is pressed void initVoice(int c, int v); void initVoices(int c); void setPreset(int c); void setFeedback(int c); void setLfo(int c); void setOutLevel(int c, int k); //set the output level of the op k void setOutLevel(int c); //do the same for all operators void setEnvAttack(int c, int v, int k); //set envInct of voice v and op k void setEnvAttack(int c, int k); //do the same for all voices of operator k void setEnvAttack(int c); //do the same for all voices all operators void setEnvRelease(int c, int v, int k); //set coefVLevel of voice v and op k void setEnvRelease(int c, int k); //do the same for all voices of operator k void setEnvRelease(int c); //do the same for all voices all operators void setPitchEnvRelease(int c, int v); void setQuality(Quality q); void setFilter(bool f); double brightness2Amp(int c, int k); //get the brightness of the operator k void loadSutulaPresets(); void loadSet(QString s); int noteOff2Voice(int c); //return the first free voice int minVolu2Voice(int c); int pitchOn2Voice(int c, int pitch); void programSelect(int c, int hbank, int lbank, int prog); bool existsKeyOn(int ch); void setNbrVoices(int c, int nv); void setMasterVol(int v); void setChannelEnable(int c, bool e); void setChannelVol(int c, int v); void setChannelPan(int c, int v); void applyChannelAmp(int c); void setChannelDetune(int c, int d); void setChannelBrightness(int c, int b); void setChannelModulation(int c, int m); void setChannelAttack(int c, int a); void setChannelRelease(int c, int r); void setChannelReverb(int c, int r); void setChannelChorus(int c, int val); void setChannelDelay(int c, int val); void setChorusReturn(int val); void setReverbReturn(int val); void setDelayReturn(int val); bool getChannelEnable(int c) const; int getNbrVoices(int c) const; int getMasterVol(void) const; bool getFilter(void) const; int getChannelVol(int c) const; int getChannelPan(int c) const; int getChannelDetune(int c) const; int getChannelBrightness(int c) const; int getChannelModulation(int c) const; int getChannelAttack(int c) const; int getChannelRelease(int c) const; int getChannelReverb(int c) const; int getChannelChorus(int c) const; int getChannelDelay(int c) const; int getChorusReturn(void) const; int getReverbReturn(void) const; int getDelayReturn(void) const; void setPitchBendCoef(int c, int val); void setModulation(int c, int val); //TODO check between setChannelModulation void setSustain(int c, int val); void readConfiguration(QDomNode qdn); void writeConfiguration(AL::Xml* xml); 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 l, const unsigned char* d); virtual QString getPatchName(int ch, int number, bool) const; virtual const MidiPatch* getPatchInfo(int, const MidiPatch *) const; virtual int getControllerInfo(int arg1, const char** arg2, 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 //virtual bool hasGui() const { return true; } //virtual bool guiVisible() const; //virtual void showGui(bool); virtual bool hasNativeGui() const { return true; } virtual bool nativeGuiVisible() const; virtual void showNativeGui(bool); virtual void getNativeGeometry(int* x, int* y, int* w, int* h) const; virtual void setNativeGeometry(int, int, int, int); DeicsOnze(); virtual ~DeicsOnze(); }; #endif /* __DEICSONZE_H */