diff --git a/plugins/zynaddsubfx/src/AUTHORS.txt b/plugins/zynaddsubfx/AUTHORS.txt similarity index 71% rename from plugins/zynaddsubfx/src/AUTHORS.txt rename to plugins/zynaddsubfx/AUTHORS.txt index 83014b3d1..3018c29a0 100644 --- a/plugins/zynaddsubfx/src/AUTHORS.txt +++ b/plugins/zynaddsubfx/AUTHORS.txt @@ -11,6 +11,8 @@ Contributors: Daniel Clemente (with a workaround of X11 repeated key bug) Emmanuel Saracco (fix for JACK output) Achim Settelmeier (QUERTZ keyboard layout for virtual keyboard) - Jérémie Andréi (AZERTY keyboard layout, Array index fix) + Jérémie Andréi (AZERTY keyboard layout, Array index fix, OSS failsafe) Alexis Ballier (const char* <-> string mismatch, NULLMidi prototype fix) + Tobias Doerffel (static vs instance variables alteration) + James Morris (Memory leaks in FLTK GUI) diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index 763112f58..4b835adc0 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -53,7 +53,7 @@ IF(LMMS_HOST_X86 OR LMMS_HOST_X86_64) ENDIF(LMMS_HOST_X86 OR LMMS_HOST_X86_64) # build ZynAddSubFX with full optimizations -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wno-write-strings -Wno-deprecated-declarations") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wno-write-strings -Wno-deprecated-declarations") # link system-libraries when on win32 IF(LMMS_BUILD_WIN32) @@ -106,7 +106,8 @@ SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${PLUGIN_DIR}") SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) ADD_EXECUTABLE(RemoteZynAddSubFx RemoteZynAddSubFx.cpp ${ZYN_SRC_GUI}) INSTALL(TARGETS RemoteZynAddSubFx RUNTIME DESTINATION ${PLUGIN_DIR}) -TARGET_LINK_LIBRARIES(RemoteZynAddSubFx ZynAddSubFxCore ${CMAKE_CURRENT_BINARY_DIR}/fltk/bin/libfltk.a) +TARGET_LINK_LIBRARIES(RemoteZynAddSubFx -L${CMAKE_CURRENT_BINARY_DIR} -lZynAddSubFxCore ${CMAKE_CURRENT_BINARY_DIR}/fltk/bin/libfltk.a) +ADD_DEPENDENCIES(RemoteZynAddSubFx ZynAddSubFxCore) # link system libraries when on win32 IF(LMMS_BUILD_WIN32) diff --git a/plugins/zynaddsubfx/src/COPYING b/plugins/zynaddsubfx/COPYING similarity index 100% rename from plugins/zynaddsubfx/src/COPYING rename to plugins/zynaddsubfx/COPYING diff --git a/plugins/zynaddsubfx/src/ChangeLog b/plugins/zynaddsubfx/ChangeLog similarity index 96% rename from plugins/zynaddsubfx/src/ChangeLog rename to plugins/zynaddsubfx/ChangeLog index f1922e210..fc73cf1c4 100644 --- a/plugins/zynaddsubfx/src/ChangeLog +++ b/plugins/zynaddsubfx/ChangeLog @@ -1,4 +1,4 @@ -6 Mar 2002 -(dupamasa - in jur de ora 4) Mi-a venit ideea exact cum sa fac cand ma plimbam pe strada Rolirudnap +6 Mar 2002 -(dupamasa - in jur de ora 4) Mi-a venit ideea exact cum sa fac cand ma plimbam pe strada Pandurilor 7/8 Mar 2002 - Started to do diagrams 10 Mar 2002 - Started to write "voice" 11 Mar 2002 - Heard first sound @@ -892,3 +892,68 @@ 07 Sep 2009 (Mark McCurry) - Fixed glitch in XMLwrapper, which would prevent file loading + +11 Sep 2009 (Mark McCurry) + - Moved PADsynth_used from public struct to has/set methods in + XMLwrapper + - Created wrapper functions, so that XMLwrapper can be somewhat + usable when const + - Removed multiple addparam methods and replaced it with one + variable argument function + - Replaced int2str, real2str, str2int, and str2real from XMLwrapper + with stringTo and stringFrom function templates in Util. + - Moved newFFTFREQS and deleteFFTFREQS from Util to FFTwrapper + - Removed unneeded stack from XMLwrapper + +18 Sep 2009 (Mark McCurry) + - Started to use versioning information in XMLwrapper + - Remove last of stack helper functions in XMLwrapper + - Added std::string retreval to XMLwrapper + +20 Sep 2009 (Paul Nasca) + - Started to implement the Unison effect for ADsynth + +22 Sep 2009 (Paul Nasca) + - Added vibratto and other features to Unison effect + +22 Sep 2009 (Mark McCurry) + - Changed temporary data for Oscilgen from static to instance + recommended by Tobias Doerffel + - Fixed Memory leaks in UI based upon James Morris' patch + +23 Sep 2009 (Paul Nasca) + - Added unison invert phase + - Made unison frequency spread to depend on Bandwidth controllers and parameters + - Added unison vibratto speed control and other improvements + - bugfixes: Voice Amplitude Envelope and FM + +24 Sep 2009 (Paul Nasca) + - Small enhancements and bugfixes to Unison + - Started to implement Bandwidth to the Reverb effect + +25 Sep 2009 (Mark McCurry) + - Allowed for XMLwrapper to retrieve strings stored in mxml TEXT + fields +29 Sep 2009 (Paul Nasca) + - Remove the old (FFT based) Bandwidth effect to Reverb and started rewrite it (based on multivoice chorus/unison effect) + +01 Oct 2009 (Paul Nasca) + - Corrected the ADsynth unison LFO rounding function + - Made Unison based on Bandwidth (in cents) parameter + +02 Oct 2009 (Mark McCurry) + - Added OSS failsafe by Jérémie Andréi + +04 Oct 2009 (Mark McCurry) + - fixed Ctest issues + +06 Oct 2009 (Mark McCurry) + - Added first simple profiling test + +08 Oct 2009 (Mark McCurry) + - Started to see if memset/memcpy offer performance benifits when + widely used + - Added basic SUBnote test + +09 Oct 2009 (Mark McCurry) + - Restylized codebase with uncrustify diff --git a/plugins/zynaddsubfx/src/FAQ.txt b/plugins/zynaddsubfx/FAQ.txt similarity index 100% rename from plugins/zynaddsubfx/src/FAQ.txt rename to plugins/zynaddsubfx/FAQ.txt diff --git a/plugins/zynaddsubfx/src/HISTORY.txt b/plugins/zynaddsubfx/HISTORY.txt similarity index 100% rename from plugins/zynaddsubfx/src/HISTORY.txt rename to plugins/zynaddsubfx/HISTORY.txt diff --git a/plugins/zynaddsubfx/src/README.txt b/plugins/zynaddsubfx/README.txt similarity index 100% rename from plugins/zynaddsubfx/src/README.txt rename to plugins/zynaddsubfx/README.txt diff --git a/plugins/zynaddsubfx/src/bugs.txt b/plugins/zynaddsubfx/bugs.txt similarity index 100% rename from plugins/zynaddsubfx/src/bugs.txt rename to plugins/zynaddsubfx/bugs.txt diff --git a/plugins/zynaddsubfx/src/Controls/Control.cpp b/plugins/zynaddsubfx/src/Controls/Control.cpp index 36792fc63..d7cf5cb9d 100644 --- a/plugins/zynaddsubfx/src/Controls/Control.cpp +++ b/plugins/zynaddsubfx/src/Controls/Control.cpp @@ -22,19 +22,19 @@ #include "Control.h" Control::Control(char ndefaultval) - :defaultval(ndefaultval),lockqueue(-1),locked(false) + :defaultval(ndefaultval), lockqueue(-1), locked(false) {} void Control::lock() { - locked=true; - lockqueue=-1; + locked = true; + lockqueue = -1; } void Control::ulock() { - if (locked&&lockqueue>=0) + if(locked && (lockqueue >= 0)) setmVal(lockqueue); - locked=false; + locked = false; } diff --git a/plugins/zynaddsubfx/src/Controls/Control.h b/plugins/zynaddsubfx/src/Controls/Control.h index 2b6eaea77..931a4745c 100644 --- a/plugins/zynaddsubfx/src/Controls/Control.h +++ b/plugins/zynaddsubfx/src/Controls/Control.h @@ -25,33 +25,33 @@ /**A control for a parameter within the program*/ class Control { -public: - Control(char ndefaultval);/**\todo create proper initialization list*/ - ~Control() {}; - /**Return the string, which represents the internal value - * @return a string representation of the current value*/ - virtual std::string getString()const=0; - /**Set the Control to the given value - * @param nval A number 0-127*/ - virtual void setmVal(char nval)=0; - /**Return the midi value (aka the char) - * @return the current value*/ - virtual char getmVal()const=0; - /** Will lock the Control until it is ulocked - * - * Locking a Control will Stop it from having - * its internal data altered*/ - void lock(); - /** Will unlock the Control - * - * This will also update the Control - * if something attempted to update it while it was locked*/ - void ulock(); -private: - char defaultval;/** DelayCtl::DelayCtl() - :Control(64),value(64/127.0*1.5) {} /**\todo finishme*/ + :Control(64), value(64 / 127.0 * 1.5) {} /**\todo finishme*/ std::string DelayCtl::getString() const { std::ostringstream buf; - buf< #include "AnalogFilter.h" -AnalogFilter::AnalogFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages) +AnalogFilter::AnalogFilter(unsigned char Ftype, + REALTYPE Ffreq, + REALTYPE Fq, + unsigned char Fstages) { - stages=Fstages; - for (int i=0;i<3;i++) { - oldc[i]=0.0; - oldd[i]=0.0; - c[i]=0.0; - d[i]=0.0; - }; - type=Ftype; - freq=Ffreq; - q=Fq; - gain=1.0; - if (stages>=MAX_FILTER_STAGES) stages=MAX_FILTER_STAGES; + stages = Fstages; + for(int i = 0; i < 3; i++) { + oldc[i] = 0.0; + oldd[i] = 0.0; + c[i] = 0.0; + d[i] = 0.0; + } + type = Ftype; + freq = Ffreq; + q = Fq; + gain = 1.0; + if(stages >= MAX_FILTER_STAGES) + stages = MAX_FILTER_STAGES; cleanup(); - firsttime=0; - abovenq=0; - oldabovenq=0; - setfreq_and_q(Ffreq,Fq); - firsttime=1; - d[0]=0;//this is not used - outgain=1.0; -}; + firsttime = 0; + abovenq = 0; + oldabovenq = 0; + setfreq_and_q(Ffreq, Fq); + firsttime = 1; + d[0] = 0; //this is not used + outgain = 1.0; +} AnalogFilter::~AnalogFilter() -{ -}; +{} void AnalogFilter::cleanup() { - for (int i=0;ifreq; - if (freq>(SAMPLE_RATE/2-500.0)) { - freq=SAMPLE_RATE/2-500.0; - zerocoefs=1; - }; - if (freq<0.1) freq=0.1; + REALTYPE freq = this->freq; + if(freq > (SAMPLE_RATE / 2 - 500.0)) { + freq = SAMPLE_RATE / 2 - 500.0; + zerocoefs = 1; + } + if(freq < 0.1) + freq = 0.1; //do not allow bogus Q - if (q<0.0) q=0.0; - REALTYPE tmpq,tmpgain; - if (stages==0) { - tmpq=q; - tmpgain=gain; - } else { - tmpq=(q>1.0 ? pow(q,1.0/(stages+1)) : q); - tmpgain=pow(gain,1.0/(stages+1)); - }; + if(q < 0.0) + q = 0.0; + REALTYPE tmpq, tmpgain; + if(stages == 0) { + tmpq = q; + tmpgain = gain; + } + else { + tmpq = (q > 1.0 ? pow(q, 1.0 / (stages + 1)) : q); + tmpgain = pow(gain, 1.0 / (stages + 1)); + } //most of theese are implementations of //the "Cookbook formulae for audio EQ" by Robert Bristow-Johnson //The original location of the Cookbook is: //http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt - switch (type) { - case 0://LPF 1 pole - if (zerocoefs==0) tmp=exp(-2.0*PI*freq/SAMPLE_RATE); - else tmp=0.0; - c[0]=1.0-tmp; - c[1]=0.0; - c[2]=0.0; - d[1]=tmp; - d[2]=0.0; - order=1; + switch(type) { + case 0: //LPF 1 pole + if(zerocoefs == 0) + tmp = exp(-2.0 * PI * freq / SAMPLE_RATE); + else + tmp = 0.0; + c[0] = 1.0 - tmp; + c[1] = 0.0; + c[2] = 0.0; + d[1] = tmp; + d[2] = 0.0; + order = 1; break; - case 1://HPF 1 pole - if (zerocoefs==0) tmp=exp(-2.0*PI*freq/SAMPLE_RATE); - else tmp=0.0; - c[0]=(1.0+tmp)/2.0; - c[1]=-(1.0+tmp)/2.0; - c[2]=0.0; - d[1]=tmp; - d[2]=0.0; - order=1; + case 1: //HPF 1 pole + if(zerocoefs == 0) + tmp = exp(-2.0 * PI * freq / SAMPLE_RATE); + else + tmp = 0.0; + c[0] = (1.0 + tmp) / 2.0; + c[1] = -(1.0 + tmp) / 2.0; + c[2] = 0.0; + d[1] = tmp; + d[2] = 0.0; + order = 1; break; - case 2://LPF 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*tmpq); - tmp=1+alpha; - c[0]=(1.0-cs)/2.0/tmp; - c[1]=(1.0-cs)/tmp; - c[2]=(1.0-cs)/2.0/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 2: //LPF 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * tmpq); + tmp = 1 + alpha; + c[0] = (1.0 - cs) / 2.0 / tmp; + c[1] = (1.0 - cs) / tmp; + c[2] = (1.0 - cs) / 2.0 / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 3://HPF 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*tmpq); - tmp=1+alpha; - c[0]=(1.0+cs)/2.0/tmp; - c[1]=-(1.0+cs)/tmp; - c[2]=(1.0+cs)/2.0/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=0.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 3: //HPF 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * tmpq); + tmp = 1 + alpha; + c[0] = (1.0 + cs) / 2.0 / tmp; + c[1] = -(1.0 + cs) / tmp; + c[2] = (1.0 + cs) / 2.0 / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 0.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 4://BPF 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*tmpq); - tmp=1+alpha; - c[0]=alpha/tmp*sqrt(tmpq+1); - c[1]=0; - c[2]=-alpha/tmp*sqrt(tmpq+1); - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=0.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 4: //BPF 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * tmpq); + tmp = 1 + alpha; + c[0] = alpha / tmp *sqrt(tmpq + 1); + c[1] = 0; + c[2] = -alpha / tmp *sqrt(tmpq + 1); + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 0.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 5://NOTCH 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*sqrt(tmpq)); - tmp=1+alpha; - c[0]=1/tmp; - c[1]=-2*cs/tmp; - c[2]=1/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 5: //NOTCH 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * sqrt(tmpq)); + tmp = 1 + alpha; + c[0] = 1 / tmp; + c[1] = -2 * cs / tmp; + c[2] = 1 / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 6://PEAK (2 poles) - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - tmpq*=3.0; - alpha=sn/(2*tmpq); - tmp=1+alpha/tmpgain; - c[0]=(1.0+alpha*tmpgain)/tmp; - c[1]=(-2.0*cs)/tmp; - c[2]=(1.0-alpha*tmpgain)/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha/tmpgain)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 6: //PEAK (2 poles) + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + tmpq *= 3.0; + alpha = sn / (2 * tmpq); + tmp = 1 + alpha / tmpgain; + c[0] = (1.0 + alpha * tmpgain) / tmp; + c[1] = (-2.0 * cs) / tmp; + c[2] = (1.0 - alpha * tmpgain) / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha / tmpgain) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 7://Low Shelf - 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - tmpq=sqrt(tmpq); - alpha=sn/(2*tmpq); - beta=sqrt(tmpgain)/tmpq; - tmp=(tmpgain+1.0)+(tmpgain-1.0)*cs+beta*sn; + case 7: //Low Shelf - 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + tmpq = sqrt(tmpq); + alpha = sn / (2 * tmpq); + beta = sqrt(tmpgain) / tmpq; + tmp = (tmpgain + 1.0) + (tmpgain - 1.0) * cs + beta * sn; - c[0]=tmpgain*((tmpgain+1.0)-(tmpgain-1.0)*cs+beta*sn)/tmp; - c[1]=2.0*tmpgain*((tmpgain-1.0)-(tmpgain+1.0)*cs)/tmp; - c[2]=tmpgain*((tmpgain+1.0)-(tmpgain-1.0)*cs-beta*sn)/tmp; - d[1]=-2.0*((tmpgain-1.0)+(tmpgain+1.0)*cs)/tmp*(-1); - d[2]=((tmpgain+1.0)+(tmpgain-1.0)*cs-beta*sn)/tmp*(-1); - } else { - c[0]=tmpgain; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + c[0] = tmpgain + * ((tmpgain + + 1.0) - (tmpgain - 1.0) * cs + beta * sn) / tmp; + c[1] = 2.0 * tmpgain + * ((tmpgain - 1.0) - (tmpgain + 1.0) * cs) / tmp; + c[2] = tmpgain + * ((tmpgain + + 1.0) - (tmpgain - 1.0) * cs - beta * sn) / tmp; + d[1] = -2.0 * ((tmpgain - 1.0) + (tmpgain + 1.0) * cs) / tmp * (-1); + d[2] = + ((tmpgain + + 1.0) + (tmpgain - 1.0) * cs - beta * sn) / tmp * (-1); + } + else { + c[0] = tmpgain; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 8://High Shelf - 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - tmpq=sqrt(tmpq); - alpha=sn/(2*tmpq); - beta=sqrt(tmpgain)/tmpq; - tmp=(tmpgain+1.0)-(tmpgain-1.0)*cs+beta*sn; + case 8: //High Shelf - 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + tmpq = sqrt(tmpq); + alpha = sn / (2 * tmpq); + beta = sqrt(tmpgain) / tmpq; + tmp = (tmpgain + 1.0) - (tmpgain - 1.0) * cs + beta * sn; - c[0]=tmpgain*((tmpgain+1.0)+(tmpgain-1.0)*cs+beta*sn)/tmp; - c[1]=-2.0*tmpgain*((tmpgain-1.0)+(tmpgain+1.0)*cs)/tmp; - c[2]=tmpgain*((tmpgain+1.0)+(tmpgain-1.0)*cs-beta*sn)/tmp; - d[1]=2.0*((tmpgain-1.0)-(tmpgain+1.0)*cs)/tmp*(-1); - d[2]=((tmpgain+1.0)-(tmpgain-1.0)*cs-beta*sn)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + c[0] = tmpgain + * ((tmpgain + + 1.0) + (tmpgain - 1.0) * cs + beta * sn) / tmp; + c[1] = -2.0 * tmpgain + * ((tmpgain - 1.0) + (tmpgain + 1.0) * cs) / tmp; + c[2] = tmpgain + * ((tmpgain + + 1.0) + (tmpgain - 1.0) * cs - beta * sn) / tmp; + d[1] = 2.0 * ((tmpgain - 1.0) - (tmpgain + 1.0) * cs) / tmp * (-1); + d[2] = + ((tmpgain + + 1.0) - (tmpgain - 1.0) * cs - beta * sn) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - default://wrong type - type=0; + default: //wrong type + type = 0; computefiltercoefs(); break; - }; -}; + } +} void AnalogFilter::setfreq(REALTYPE frequency) { - if (frequency<0.1) frequency=0.1; - REALTYPE rap=freq/frequency; - if (rap<1.0) rap=1.0/rap; + if(frequency < 0.1) + frequency = 0.1; + REALTYPE rap = freq / frequency; + if(rap < 1.0) + rap = 1.0 / rap; - oldabovenq=abovenq; - abovenq=frequency>(SAMPLE_RATE/2-500.0); + oldabovenq = abovenq; + abovenq = frequency > (SAMPLE_RATE / 2 - 500.0); - int nyquistthresh=(abovenq^oldabovenq); + int nyquistthresh = (abovenq ^ oldabovenq); - if ((rap>3.0)||(nyquistthresh!=0)) {//if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) - for (int i=0;i<3;i++) { - oldc[i]=c[i]; - oldd[i]=d[i]; - }; - for (int i=0;i 3.0) || (nyquistthresh != 0)) { //if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) + for(int i = 0; i < 3; i++) { + oldc[i] = c[i]; + oldd[i] = d[i]; + } + for(int i = 0; i < MAX_FILTER_STAGES + 1; i++) { + oldx[i] = x[i]; + oldy[i] = y[i]; + } + if(firsttime == 0) + needsinterpolation = 1; + } + freq = frequency; computefiltercoefs(); - firsttime=0; + firsttime = 0; +} -}; - -void AnalogFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void AnalogFilter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - q=q_; + q = q_; setfreq(frequency); -}; +} void AnalogFilter::setq(REALTYPE q_) { - q=q_; + q = q_; computefiltercoefs(); -}; +} void AnalogFilter::settype(int type_) { - type=type_; + type = type_; computefiltercoefs(); -}; +} void AnalogFilter::setgain(REALTYPE dBgain) { - gain=dB2rap(dBgain); + gain = dB2rap(dBgain); computefiltercoefs(); -}; +} void AnalogFilter::setstages(int stages_) { - if (stages_>=MAX_FILTER_STAGES) stages_=MAX_FILTER_STAGES-1; - stages=stages_; + if(stages_ >= MAX_FILTER_STAGES) + stages_ = MAX_FILTER_STAGES - 1; + stages = stages_; cleanup(); computefiltercoefs(); -}; +} -void AnalogFilter::singlefilterout(REALTYPE *smp,fstage &x,fstage &y,REALTYPE *c,REALTYPE *d) +void AnalogFilter::singlefilterout(REALTYPE *smp, + fstage &x, + fstage &y, + REALTYPE *c, + REALTYPE *d) { - int i; + int i; REALTYPE y0; - if (order==1) {//First order filter - for (i=0;i1,1->2,etc.) - REALTYPE freq;//Frequency given in Hz - REALTYPE q; //Q factor (resonance or Q factor) - REALTYPE gain;//the gain of the filter (if are shelf/peak) filters + void singlefilterout(REALTYPE *smp, + fstage &x, + fstage &y, + REALTYPE *c, + REALTYPE *d); + void computefiltercoefs(); + int type; //The type of the filter (LPF1,HPF1,LPF2,HPF2...) + int stages; //how many times the filter is applied (0->1,1->2,etc.) + REALTYPE freq; //Frequency given in Hz + REALTYPE q; //Q factor (resonance or Q factor) + REALTYPE gain; //the gain of the filter (if are shelf/peak) filters - int order;//the order of the filter (number of poles) + int order; //the order of the filter (number of poles) - REALTYPE c[3],d[3];//coefficients + REALTYPE c[3], d[3]; //coefficients - REALTYPE oldc[3],oldd[3];//old coefficients(used only if some filter paremeters changes very fast, and it needs interpolation) + REALTYPE oldc[3], oldd[3]; //old coefficients(used only if some filter paremeters changes very fast, and it needs interpolation) - REALTYPE xd[3],yd[3];//used if the filter is applied more times - int needsinterpolation,firsttime;/**\todo see if bool works for these*/ - int abovenq;//this is 1 if the frequency is above the nyquist - int oldabovenq;//if the last time was above nyquist (used to see if it needs interpolation) + REALTYPE xd[3], yd[3]; //used if the filter is applied more times + int needsinterpolation, firsttime; /**\todo see if bool works for these*/ + int abovenq; //this is 1 if the frequency is above the nyquist + int oldabovenq; //if the last time was above nyquist (used to see if it needs interpolation) }; diff --git a/plugins/zynaddsubfx/src/DSP/CMakeLists.txt b/plugins/zynaddsubfx/src/DSP/CMakeLists.txt index 8169235e0..c13cd316c 100644 --- a/plugins/zynaddsubfx/src/DSP/CMakeLists.txt +++ b/plugins/zynaddsubfx/src/DSP/CMakeLists.txt @@ -4,6 +4,7 @@ set(zynaddsubfx_dsp_SRCS Filter.cpp FormantFilter.cpp SVFilter.cpp + Unison.cpp ) add_library(zynaddsubfx_dsp STATIC diff --git a/plugins/zynaddsubfx/src/DSP/FFTwrapper.cpp b/plugins/zynaddsubfx/src/DSP/FFTwrapper.cpp index 7e18ae534..d93c0c40c 100644 --- a/plugins/zynaddsubfx/src/DSP/FFTwrapper.cpp +++ b/plugins/zynaddsubfx/src/DSP/FFTwrapper.cpp @@ -25,17 +25,29 @@ FFTwrapper::FFTwrapper(int fftsize_) { - fftsize=fftsize_; - tmpfftdata1=new fftw_real[fftsize]; - tmpfftdata2=new fftw_real[fftsize]; + fftsize = fftsize_; + tmpfftdata1 = new fftw_real[fftsize]; + tmpfftdata2 = new fftw_real[fftsize]; #ifdef FFTW_VERSION_2 - planfftw=rfftw_create_plan(fftsize,FFTW_REAL_TO_COMPLEX,FFTW_ESTIMATE|FFTW_IN_PLACE); - planfftw_inv=rfftw_create_plan(fftsize,FFTW_COMPLEX_TO_REAL,FFTW_ESTIMATE|FFTW_IN_PLACE); + planfftw = rfftw_create_plan(fftsize, + FFTW_REAL_TO_COMPLEX, + FFTW_ESTIMATE | FFTW_IN_PLACE); + planfftw_inv = rfftw_create_plan(fftsize, + FFTW_COMPLEX_TO_REAL, + FFTW_ESTIMATE | FFTW_IN_PLACE); #else - planfftw=fftwf_plan_r2r_1d(fftsize,tmpfftdata1,tmpfftdata1,FFTW_R2HC,FFTW_ESTIMATE); - planfftw_inv=fftwf_plan_r2r_1d(fftsize,tmpfftdata2,tmpfftdata2,FFTW_HC2R,FFTW_ESTIMATE); + planfftw = fftwf_plan_r2r_1d(fftsize, + tmpfftdata1, + tmpfftdata1, + FFTW_R2HC, + FFTW_ESTIMATE); + planfftw_inv = fftwf_plan_r2r_1d(fftsize, + tmpfftdata2, + tmpfftdata2, + FFTW_HC2R, + FFTW_ESTIMATE); #endif -}; +} FFTwrapper::~FFTwrapper() { @@ -49,52 +61,76 @@ FFTwrapper::~FFTwrapper() delete [] tmpfftdata1; delete [] tmpfftdata2; -}; +} /* * do the Fast Fourier Transform */ -void FFTwrapper::smps2freqs(REALTYPE *smps,FFTFREQS freqs) +void FFTwrapper::smps2freqs(REALTYPE *smps, FFTFREQS freqs) { #ifdef FFTW_VERSION_2 - for (int i=0;ic = new REALTYPE[size]; + f->s = new REALTYPE[size]; + for(int i = 0; i < size; i++) { + f->c[i] = 0.0; + f->s[i] = 0.0; + } +} + +void deleteFFTFREQS(FFTFREQS *f) +{ + delete[] f->c; + delete[] f->s; + f->c = f->s = NULL; +} diff --git a/plugins/zynaddsubfx/src/DSP/FFTwrapper.h b/plugins/zynaddsubfx/src/DSP/FFTwrapper.h index f2915f490..17d40805a 100644 --- a/plugins/zynaddsubfx/src/DSP/FFTwrapper.h +++ b/plugins/zynaddsubfx/src/DSP/FFTwrapper.h @@ -47,21 +47,24 @@ Hope all goes right." */ /**A wrapper for the FFTW library (Fast Fourier Transforms)*/ class FFTwrapper { -public: - /**Constructor - * @param fftsize The size of samples to be fed to fftw*/ - FFTwrapper(int fftsize_); - /**Destructor*/ - ~FFTwrapper(); - /**Convert Samples to Frequencies using Fourier Transform - * @param smps Pointer to Samples to be converted; has length fftsize_ - * @param freqs Structure FFTFREQS which stores the frequencies*/ - void smps2freqs(REALTYPE *smps,FFTFREQS freqs); - void freqs2smps(FFTFREQS freqs,REALTYPE *smps); -private: - int fftsize; - fftw_real *tmpfftdata1,*tmpfftdata2; - rfftw_plan planfftw,planfftw_inv; + public: + /**Constructor + * @param fftsize The size of samples to be fed to fftw*/ + FFTwrapper(int fftsize_); + /**Destructor*/ + ~FFTwrapper(); + /**Convert Samples to Frequencies using Fourier Transform + * @param smps Pointer to Samples to be converted; has length fftsize_ + * @param freqs Structure FFTFREQS which stores the frequencies*/ + void smps2freqs(REALTYPE *smps, FFTFREQS freqs); + void freqs2smps(FFTFREQS freqs, REALTYPE *smps); + private: + int fftsize; + fftw_real *tmpfftdata1, *tmpfftdata2; + rfftw_plan planfftw, planfftw_inv; }; + +void newFFTFREQS(FFTFREQS *f, int size); +void deleteFFTFREQS(FFTFREQS *f); #endif diff --git a/plugins/zynaddsubfx/src/DSP/Filter.cpp b/plugins/zynaddsubfx/src/DSP/Filter.cpp index f94a34214..d95abe448 100644 --- a/plugins/zynaddsubfx/src/DSP/Filter.cpp +++ b/plugins/zynaddsubfx/src/DSP/Filter.cpp @@ -27,56 +27,61 @@ Filter::Filter(FilterParams *pars) { - unsigned char Ftype=pars->Ptype; - unsigned char Fstages=pars->Pstages; + unsigned char Ftype = pars->Ptype; + unsigned char Fstages = pars->Pstages; - category=pars->Pcategory; + category = pars->Pcategory; - switch (category) { + switch(category) { case 1: - filter=new FormantFilter(pars); + filter = new FormantFilter(pars); break; case 2: - filter=new SVFilter(Ftype,1000.0,pars->getq(),Fstages); - filter->outgain=dB2rap(pars->getgain()); - if (filter->outgain>1.0) filter->outgain=sqrt(filter->outgain); + filter = new SVFilter(Ftype, 1000.0, pars->getq(), Fstages); + filter->outgain = dB2rap(pars->getgain()); + if(filter->outgain > 1.0) + filter->outgain = sqrt(filter->outgain); break; default: - filter=new AnalogFilter(Ftype,1000.0,pars->getq(),Fstages); - if ((Ftype>=6)&&(Ftype<=8)) filter->setgain(pars->getgain()); - else filter->outgain=dB2rap(pars->getgain()); + filter = new AnalogFilter(Ftype, 1000.0, pars->getq(), Fstages); + if((Ftype >= 6) && (Ftype <= 8)) + filter->setgain(pars->getgain()); + else + filter->outgain = dB2rap(pars->getgain()); break; - }; -}; + } +} Filter::~Filter() { delete (filter); -}; +} void Filter::filterout(REALTYPE *smp) { filter->filterout(smp); -}; +} void Filter::setfreq(REALTYPE frequency) { filter->setfreq(frequency); -}; +} -void Filter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void Filter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - filter->setfreq_and_q(frequency,q_); -}; + filter->setfreq_and_q(frequency, q_); +} void Filter::setq(REALTYPE q_) { filter->setq(q_); -}; +} REALTYPE Filter::getrealfreq(REALTYPE freqpitch) { - if ((category==0)||(category==2)) return(pow(2.0,freqpitch+9.96578428));//log2(1000)=9.95748 - else return(freqpitch); -}; + if((category == 0) || (category == 2)) + return pow(2.0, freqpitch + 9.96578428); //log2(1000)=9.95748 + else + return freqpitch; +} diff --git a/plugins/zynaddsubfx/src/DSP/Filter.h b/plugins/zynaddsubfx/src/DSP/Filter.h index 42bef55ce..b8f568b21 100644 --- a/plugins/zynaddsubfx/src/DSP/Filter.h +++ b/plugins/zynaddsubfx/src/DSP/Filter.h @@ -33,18 +33,18 @@ class Filter { -public: - Filter(FilterParams *pars); - ~Filter(); - void filterout(REALTYPE *smp); - void setfreq(REALTYPE frequency); - void setfreq_and_q(REALTYPE frequency,REALTYPE q_); - void setq(REALTYPE q_); + public: + Filter(FilterParams *pars); + ~Filter(); + void filterout(REALTYPE *smp); + void setfreq(REALTYPE frequency); + void setfreq_and_q(REALTYPE frequency, REALTYPE q_); + void setq(REALTYPE q_); - REALTYPE getrealfreq(REALTYPE freqpitch); -private: - Filter_ *filter; - unsigned char category; + REALTYPE getrealfreq(REALTYPE freqpitch); + private: + Filter_ *filter; + unsigned char category; }; diff --git a/plugins/zynaddsubfx/src/DSP/Filter_.h b/plugins/zynaddsubfx/src/DSP/Filter_.h index b3f2badc1..b577193f3 100644 --- a/plugins/zynaddsubfx/src/DSP/Filter_.h +++ b/plugins/zynaddsubfx/src/DSP/Filter_.h @@ -27,15 +27,15 @@ class Filter_ { -public: - virtual ~Filter_() {}; - virtual void filterout(REALTYPE *smp)=0; - virtual void setfreq(REALTYPE frequency)=0; - virtual void setfreq_and_q(REALTYPE frequency,REALTYPE q_)=0; - virtual void setq(REALTYPE q_)=0; - virtual void setgain(REALTYPE dBgain) {}; - REALTYPE outgain; -private: + public: + virtual ~Filter_() {} + virtual void filterout(REALTYPE *smp) = 0; + virtual void setfreq(REALTYPE frequency) = 0; + virtual void setfreq_and_q(REALTYPE frequency, REALTYPE q_) = 0; + virtual void setq(REALTYPE q_) = 0; + virtual void setgain(REALTYPE dBgain) {} + REALTYPE outgain; + private: }; diff --git a/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp b/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp index 297285648..39c1002d9 100644 --- a/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp +++ b/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp @@ -26,151 +26,202 @@ FormantFilter::FormantFilter(FilterParams *pars) { - numformants=pars->Pnumformants; - for (int i=0;iPstages); + numformants = pars->Pnumformants; + for(int i = 0; i < numformants; i++) + formant[i] = new AnalogFilter(4 /*BPF*/, 1000.0, 10.0, pars->Pstages); cleanup(); - inbuffer=new REALTYPE [SOUND_BUFFER_SIZE]; - tmpbuf=new REALTYPE [SOUND_BUFFER_SIZE]; + inbuffer = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpbuf = new REALTYPE [SOUND_BUFFER_SIZE]; - for (int j=0;jgetformantfreq(pars->Pvowels[j].formants[i].freq); - formantpar[j][i].amp=pars->getformantamp(pars->Pvowels[j].formants[i].amp); - formantpar[j][i].q=pars->getformantq(pars->Pvowels[j].formants[i].q); - }; - for (int i=0;igetformantfreq( + pars->Pvowels[j].formants[i].freq); + formantpar[j][i].amp = pars->getformantamp( + pars->Pvowels[j].formants[i].amp); + formantpar[j][i].q = pars->getformantq( + pars->Pvowels[j].formants[i].q); + } + ; + for(int i = 0; i < FF_MAX_FORMANTS; i++) + oldformantamp[i] = 1.0; + for(int i = 0; i < numformants; i++) { + currentformants[i].freq = 1000.0; + currentformants[i].amp = 1.0; + currentformants[i].q = 2.0; + } - formantslowness=pow(1.0-(pars->Pformantslowness/128.0),3.0); + formantslowness = pow(1.0 - (pars->Pformantslowness / 128.0), 3.0); - sequencesize=pars->Psequencesize; - if (sequencesize==0) sequencesize=1; - for (int k=0;kPsequence[k].nvowel; + sequencesize = pars->Psequencesize; + if(sequencesize == 0) + sequencesize = 1; + for(int k = 0; k < sequencesize; k++) + sequence[k].nvowel = pars->Psequence[k].nvowel; - vowelclearness=pow(10.0,(pars->Pvowelclearness-32.0)/48.0); + vowelclearness = pow(10.0, (pars->Pvowelclearness - 32.0) / 48.0); - sequencestretch=pow(0.1,(pars->Psequencestretch-32.0)/48.0); - if (pars->Psequencereversed) sequencestretch*= -1.0; + sequencestretch = pow(0.1, (pars->Psequencestretch - 32.0) / 48.0); + if(pars->Psequencereversed) + sequencestretch *= -1.0; - outgain=dB2rap(pars->getgain()); + outgain = dB2rap(pars->getgain()); - oldinput=-1.0; - Qfactor=1.0; - oldQfactor=Qfactor; - firsttime=1; -}; + oldinput = -1.0; + Qfactor = 1.0; + oldQfactor = Qfactor; + firsttime = 1; +} FormantFilter::~FormantFilter() { - for (int i=0;icleanup(); -}; + for(int i = 0; i < numformants; i++) + formant[i]->cleanup(); +} void FormantFilter::setpos(REALTYPE input) { - int p1,p2; + int p1, p2; - if (firsttime!=0) slowinput=input; - else slowinput=slowinput*(1.0-formantslowness)+input*formantslowness; + if(firsttime != 0) + slowinput = input; + else + slowinput = slowinput + * (1.0 - formantslowness) + input * formantslowness; - if ((fabs(oldinput-input)<0.001)&&(fabs(slowinput-input)<0.001)&& - (fabs(Qfactor-oldQfactor)<0.001)) { + if((fabs(oldinput - input) < 0.001) && (fabs(slowinput - input) < 0.001) + && (fabs(Qfactor - oldQfactor) < 0.001)) { // oldinput=input; daca setez asta, o sa faca probleme la schimbari foarte lente - firsttime=0; + firsttime = 0; return; - } else oldinput=input; + } + else + oldinput = input; - REALTYPE pos=fmod(input*sequencestretch,1.0); - if (pos<0.0) pos+=1.0; + REALTYPE pos = fmod(input * sequencestretch, 1.0); + if(pos < 0.0) + pos += 1.0; - F2I(pos*sequencesize,p2); - p1=p2-1; - if (p1<0) p1+=sequencesize; + F2I(pos * sequencesize, p2); + p1 = p2 - 1; + if(p1 < 0) + p1 += sequencesize; - pos=fmod(pos*sequencesize,1.0); - if (pos<0.0) pos=0.0; - else if (pos>1.0) pos=1.0; - pos=(atan((pos*2.0-1.0)*vowelclearness)/atan(vowelclearness)+1.0)*0.5; + pos = fmod(pos * sequencesize, 1.0); + if(pos < 0.0) + pos = 0.0; + else + if(pos > 1.0) + pos = 1.0; + pos = + (atan((pos * 2.0 + - 1.0) * vowelclearness) / atan(vowelclearness) + 1.0) * 0.5; - p1=sequence[p1].nvowel; - p2=sequence[p2].nvowel; + p1 = sequence[p1].nvowel; + p2 = sequence[p2].nvowel; - if (firsttime!=0) { - for (int i=0;isetfreq_and_q(currentformants[i].freq,currentformants[i].q*Qfactor); - oldformantamp[i]=currentformants[i].amp; - }; - firsttime=0; - } else { - for (int i=0;isetfreq_and_q(currentformants[i].freq, + currentformants[i].q * Qfactor); + oldformantamp[i] = currentformants[i].amp; + } + firsttime = 0; + } + else { + for(int i = 0; i < numformants; i++) { + currentformants[i].freq = currentformants[i].freq + * (1.0 - formantslowness) + + (formantpar[p1][i].freq + * (1.0 + - pos) + formantpar[p2][i].freq + * pos) * formantslowness; - currentformants[i].amp=currentformants[i].amp*(1.0-formantslowness) - +(formantpar[p1][i].amp*(1.0-pos)+formantpar[p2][i].amp*pos)*formantslowness; + currentformants[i].amp = currentformants[i].amp + * (1.0 - formantslowness) + + (formantpar[p1][i].amp + * (1.0 + - pos) + formantpar[p2][i].amp + * pos) * formantslowness; - currentformants[i].q=currentformants[i].q*(1.0-formantslowness) - +(formantpar[p1][i].q*(1.0-pos)+formantpar[p2][i].q*pos)*formantslowness; + currentformants[i].q = currentformants[i].q + * (1.0 - formantslowness) + + (formantpar[p1][i].q + * (1.0 + - pos) + formantpar[p2][i].q + * pos) * formantslowness; - formant[i]->setfreq_and_q(currentformants[i].freq,currentformants[i].q*Qfactor); - }; - }; + formant[i]->setfreq_and_q(currentformants[i].freq, + currentformants[i].q * Qfactor); + } + } - oldQfactor=Qfactor; -}; + oldQfactor = Qfactor; +} void FormantFilter::setfreq(REALTYPE frequency) { setpos(frequency); -}; +} void FormantFilter::setq(REALTYPE q_) { - Qfactor=q_; - for (int i=0;isetq(Qfactor*currentformants[i].q); -}; + Qfactor = q_; + for(int i = 0; i < numformants; i++) + formant[i]->setq(Qfactor * currentformants[i].q); +} -void FormantFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void FormantFilter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - Qfactor=q_; + Qfactor = q_; setpos(frequency); -}; +} void FormantFilter::filterout(REALTYPE *smp) { - int i,j; - for (i=0;ifilterout(tmpbuf); - if (ABOVE_AMPLITUDE_THRESHOLD(oldformantamp[j],currentformants[j].amp)) - for (i=0;i #include "SVFilter.h" -SVFilter::SVFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages) +SVFilter::SVFilter(unsigned char Ftype, + REALTYPE Ffreq, + REALTYPE Fq, + unsigned char Fstages) { - stages=Fstages; - type=Ftype; - freq=Ffreq; - q=Fq; - gain=1.0; - outgain=1.0; - needsinterpolation=0; - firsttime=1; - if (stages>=MAX_FILTER_STAGES) stages=MAX_FILTER_STAGES; + stages = Fstages; + type = Ftype; + freq = Ffreq; + q = Fq; + gain = 1.0; + outgain = 1.0; + needsinterpolation = 0; + firsttime = 1; + if(stages >= MAX_FILTER_STAGES) + stages = MAX_FILTER_STAGES; cleanup(); - setfreq_and_q(Ffreq,Fq); -}; + setfreq_and_q(Ffreq, Fq); +} SVFilter::~SVFilter() -{ -}; +{} void SVFilter::cleanup() { - for (int i=0;i0.99999) par.f=0.99999; - par.q=1.0-atan(sqrt(q))*2.0/PI; - par.q=pow(par.q,1.0/(stages+1)); - par.q_sqrt=sqrt(par.q); -}; + par.f = freq / SAMPLE_RATE * 4.0; + if(par.f > 0.99999) + par.f = 0.99999; + par.q = 1.0 - atan(sqrt(q)) * 2.0 / PI; + par.q = pow(par.q, 1.0 / (stages + 1)); + par.q_sqrt = sqrt(par.q); +} void SVFilter::setfreq(REALTYPE frequency) { - if (frequency<0.1) frequency=0.1; - REALTYPE rap=freq/frequency; - if (rap<1.0) rap=1.0/rap; + if(frequency < 0.1) + frequency = 0.1; + REALTYPE rap = freq / frequency; + if(rap < 1.0) + rap = 1.0 / rap; - oldabovenq=abovenq; - abovenq=frequency>(SAMPLE_RATE/2-500.0); + oldabovenq = abovenq; + abovenq = frequency > (SAMPLE_RATE / 2 - 500.0); - int nyquistthresh=(abovenq^oldabovenq); + int nyquistthresh = (abovenq ^ oldabovenq); - if ((rap>3.0)||(nyquistthresh!=0)) {//if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) - if (firsttime==0) needsinterpolation=1; - ipar=par; - }; - freq=frequency; + if((rap > 3.0) || (nyquistthresh != 0)) { //if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) + if(firsttime == 0) + needsinterpolation = 1; + ipar = par; + } + freq = frequency; computefiltercoefs(); - firsttime=0; + firsttime = 0; +} -}; - -void SVFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void SVFilter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - q=q_; + q = q_; setfreq(frequency); -}; +} void SVFilter::setq(REALTYPE q_) { - q=q_; + q = q_; computefiltercoefs(); -}; +} void SVFilter::settype(int type_) { - type=type_; + type = type_; computefiltercoefs(); -}; +} void SVFilter::setgain(REALTYPE dBgain) { - gain=dB2rap(dBgain); + gain = dB2rap(dBgain); computefiltercoefs(); -}; +} void SVFilter::setstages(int stages_) { - if (stages_>=MAX_FILTER_STAGES) stages_=MAX_FILTER_STAGES-1; - stages=stages_; + if(stages_ >= MAX_FILTER_STAGES) + stages_ = MAX_FILTER_STAGES - 1; + stages = stages_; cleanup(); computefiltercoefs(); -}; +} -void SVFilter::singlefilterout(REALTYPE *smp,fstage &x,parameters &par) +void SVFilter::singlefilterout(REALTYPE *smp, fstage &x, parameters &par) { int i; - REALTYPE *out=NULL; - switch (type) { + REALTYPE *out = NULL; + switch(type) { case 0: - out=&x.low; + out = &x.low; break; case 1: - out=&x.high; + out = &x.high; break; case 2: - out=&x.band; + out = &x.band; break; case 3: - out=&x.notch; + out = &x.notch; break; - }; + } - for (i=0;i1,1->2,etc.) - REALTYPE freq;//Frequency given in Hz - REALTYPE q; //Q factor (resonance or Q factor) - REALTYPE gain;//the gain of the filter (if are shelf/peak) filters + void singlefilterout(REALTYPE *smp, fstage &x, parameters &par); + void computefiltercoefs(); + int type; //The type of the filter (LPF1,HPF1,LPF2,HPF2...) + int stages; //how many times the filter is applied (0->1,1->2,etc.) + REALTYPE freq; //Frequency given in Hz + REALTYPE q; //Q factor (resonance or Q factor) + REALTYPE gain; //the gain of the filter (if are shelf/peak) filters - int abovenq;//this is 1 if the frequency is above the nyquist - int oldabovenq; - int needsinterpolation,firsttime; + int abovenq; //this is 1 if the frequency is above the nyquist + int oldabovenq; + int needsinterpolation, firsttime; }; diff --git a/plugins/zynaddsubfx/src/DSP/Unison.cpp b/plugins/zynaddsubfx/src/DSP/Unison.cpp new file mode 100644 index 000000000..031a868c3 --- /dev/null +++ b/plugins/zynaddsubfx/src/DSP/Unison.cpp @@ -0,0 +1,192 @@ +/* + ZynAddSubFX - a software synthesizer + + Unison.cpp - Unison effect (multivoice chorus) + Copyright (C) 2002-2009 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include "Unison.h" + +Unison::Unison(int update_period_samples_, REALTYPE max_delay_sec_) { + update_period_samples = update_period_samples_; + max_delay = (int)(max_delay_sec_ * (REALTYPE)SAMPLE_RATE + 1); + if(max_delay < 10) + max_delay = 10; + delay_buffer = new REALTYPE[max_delay]; + delay_k = 0; + base_freq = 1.0; + unison_bandwidth_cents = 10.0; + + ZERO_REALTYPE(delay_buffer, max_delay); + + uv = NULL; + update_period_sample_k = 0; + first_time = 0; + + set_size(1); +} + +Unison::~Unison() { + delete [] delay_buffer; + if(uv) + delete [] uv; +} + +void Unison::set_size(int new_size) { + if(new_size < 1) + new_size = 1; + unison_size = new_size; + if(uv) + delete [] uv; + uv = new UnisonVoice[unison_size]; + first_time = true; + update_parameters(); +} + +void Unison::set_base_frequency(REALTYPE freq) { + base_freq = freq; + update_parameters(); +} + +void Unison::set_bandwidth(REALTYPE bandwidth) { + if(bandwidth < 0) + bandwidth = 0.0; + if(bandwidth > 1200.0) + bandwidth = 1200.0; + + printf("bandwidth %g\n", bandwidth); +#warning \ + : todo: if bandwidth is too small the audio will be self canceled (because of the sign change of the outputs) + unison_bandwidth_cents = bandwidth; + update_parameters(); +} + +void Unison::update_parameters() { + if(!uv) + return; + REALTYPE increments_per_second = SAMPLE_RATE + / (REALTYPE) update_period_samples; +// printf("#%g, %g\n",increments_per_second,base_freq); + for(int i = 0; i < unison_size; i++) { + REALTYPE base = pow(UNISON_FREQ_SPAN, RND * 2.0 - 1.0); + uv[i].relative_amplitude = base; + REALTYPE period = base / base_freq; + REALTYPE m = 4.0 / (period * increments_per_second); + if(RND < 0.5) + m = -m; + uv[i].step = m; +// printf("%g %g\n",uv[i].relative_amplitude,period); + } + + REALTYPE max_speed = pow(2.0, unison_bandwidth_cents / 1200.0); + unison_amplitude_samples = 0.125 + * (max_speed - 1.0) * SAMPLE_RATE / base_freq; + printf("unison_amplitude_samples %g\n", unison_amplitude_samples); + +#warning \ + todo: test if unison_amplitude_samples is to big and reallocate bigger memory + if(unison_amplitude_samples >= max_delay - 1) + unison_amplitude_samples = max_delay - 2; + + update_unison_data(); +} + +void Unison::process(int bufsize, REALTYPE *inbuf, REALTYPE *outbuf) { + if(!uv) + return; + if(!outbuf) + outbuf = inbuf; + + REALTYPE volume = 1.0 / sqrt(unison_size); + REALTYPE xpos_step = 1.0 / (REALTYPE) update_period_samples; + REALTYPE xpos = (REALTYPE) update_period_sample_k * xpos_step; + for(int i = 0; i < bufsize; i++) { + if((update_period_sample_k++) >= update_period_samples) { + update_unison_data(); + update_period_sample_k = 0; + xpos = 0.0; + } + xpos += xpos_step; + REALTYPE in = inbuf[i], out = 0.0; + + REALTYPE sign = 1.0; + for(int k = 0; k < unison_size; k++) { + REALTYPE vpos = uv[k].realpos1 + * (1.0 - xpos) + uv[k].realpos2 * xpos; //optimize + REALTYPE pos = delay_k + max_delay - vpos - 1.0; //optimize + int posi; + REALTYPE posf; + F2I(pos, posi); //optimize! + if(posi >= max_delay) + posi -= max_delay; + posf = pos - floor(pos); + out += + ((1.0 + - posf) * delay_buffer[posi] + posf + * delay_buffer[posi + 1]) * sign; + sign = -sign; + } + outbuf[i] = out * volume; +// printf("%d %g\n",i,outbuf[i]); + delay_buffer[delay_k] = in; + if((++delay_k) >= max_delay) + delay_k = 0; + } +} + +void Unison::update_unison_data() { + if(!uv) + return; + + for(int k = 0; k < unison_size; k++) { + REALTYPE pos = uv[k].position; + REALTYPE step = uv[k].step; + pos += step; + if(pos <= -1.0) { + pos = -1.0; + step = -step; + } + if(pos >= 1.0) { + pos = 1.0; + step = -step; + } + REALTYPE vibratto_val = (pos - 0.333333333 * pos * pos * pos) * 1.5; //make the vibratto lfo smoother +#warning \ + I will use relative amplitude, so the delay might be bigger than the whole buffer +#warning \ + I have to enlarge (reallocate) the buffer to make place for the whole delay + REALTYPE newval = 1.0 + 0.5 + * (vibratto_val + + 1.0) * unison_amplitude_samples + * uv[k].relative_amplitude; + + if(first_time) + uv[k].realpos1 = uv[k].realpos2 = newval; + else{ + uv[k].realpos1 = uv[k].realpos2; + uv[k].realpos2 = newval; + } + + uv[k].position = pos; + uv[k].step = step; + } + if(first_time) + first_time = false; +} + diff --git a/plugins/zynaddsubfx/src/DSP/Unison.h b/plugins/zynaddsubfx/src/DSP/Unison.h new file mode 100644 index 000000000..d4254a114 --- /dev/null +++ b/plugins/zynaddsubfx/src/DSP/Unison.h @@ -0,0 +1,69 @@ +/* + ZynAddSubFX - a software synthesizer + + Unison.h - Unison effect (multivoice chorus) + Copyright (C) 2002-2009 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef UNISON_H +#define UNISON_H +#include +#include "../globals.h" + +#define UNISON_FREQ_SPAN 2.0 +//how much the unison frequencies varies (always >= 1.0) + +class Unison +{ + public: + Unison(int update_period_samples_, REALTYPE max_delay_sec_); + ~Unison(); + + void set_size(int new_size); + void set_base_frequency(REALTYPE freq); + void set_bandwidth(REALTYPE bandwidth_cents); + + void process(int bufsize, REALTYPE *inbuf, REALTYPE *outbuf = NULL); + + private: + void update_parameters(); + void update_unison_data(); + + int unison_size; + REALTYPE base_freq; + struct UnisonVoice { + REALTYPE step, position; //base LFO + REALTYPE realpos1, realpos2; //the position regarding samples + REALTYPE relative_amplitude; + REALTYPE lin_fpos, lin_ffreq; + UnisonVoice() { + position = RND * 1.8 - 0.9; + realpos1 = 0.0; + realpos2 = 0.0; + step = 0.0; + relative_amplitude = 1.0; + } + } *uv; + int update_period_samples, update_period_sample_k; + int max_delay, delay_k; + bool first_time; + REALTYPE *delay_buffer; + REALTYPE unison_amplitude_samples; + REALTYPE unison_bandwidth_cents; +}; +#endif + diff --git a/plugins/zynaddsubfx/src/Effects/Alienwah.cpp b/plugins/zynaddsubfx/src/Effects/Alienwah.cpp index a4bf58e54..fb07d4f11 100644 --- a/plugins/zynaddsubfx/src/Effects/Alienwah.cpp +++ b/plugins/zynaddsubfx/src/Effects/Alienwah.cpp @@ -23,83 +23,87 @@ #include #include "Alienwah.h" -Alienwah::Alienwah(const int &insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0),oldl(NULL),oldr(NULL) +Alienwah::Alienwah(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), oldl(NULL), oldr(NULL) { setpreset(Ppreset); cleanup(); - oldclfol=complex(fb,0.0); - oldclfor=complex(fb,0.0); -}; + oldclfol = complex(fb, 0.0); + oldclfor = complex(fb, 0.0); +} Alienwah::~Alienwah() { - if (oldl!=NULL) delete [] oldl; - if (oldr!=NULL) delete [] oldr ; -}; + if(oldl != NULL) + delete [] oldl; + if(oldr != NULL) + delete [] oldr; +} /* * Apply the effect */ -void Alienwah::out(REALTYPE *smpsl,REALTYPE *smpsr) +void Alienwah::out(REALTYPE *smpsl, REALTYPE *smpsr) { - REALTYPE lfol,lfor; //Left/Right LFOs - complex clfol,clfor,out,tmp; + REALTYPE lfol, lfor; //Left/Right LFOs + complex clfol, clfor, out, tmp; /**\todo Rework, as optimization can be used when the new complex type is * utilized. * Before all calculations needed to be done with individual REALTYPE, * but now they can be done together*/ - lfo.effectlfoout(&lfol,&lfor); - lfol*=depth*PI*2.0; - lfor*=depth*PI*2.0; - clfol=complex(cos(lfol+phase)*fb,sin(lfol+phase)*fb); //rework - clfor=complex(cos(lfor+phase)*fb,sin(lfor+phase)*fb); //rework + lfo.effectlfoout(&lfol, &lfor); + lfol *= depth * PI * 2.0; + lfor *= depth * PI * 2.0; + clfol = complex(cos(lfol + phase) * fb, sin(lfol + phase) * fb); //rework + clfor = complex(cos(lfor + phase) * fb, sin(lfor + phase) * fb); //rework - for (int i=0;i=Pdelay) oldk=0; + if(++oldk >= Pdelay) + oldk = 0; //LRcross - efxoutl[i]=l*(1.0-lrcross)+r*lrcross; - efxoutr[i]=r*(1.0-lrcross)+l*lrcross; - }; + efxoutl[i] = l * (1.0 - lrcross) + r * lrcross; + efxoutr[i] = r * (1.0 - lrcross) + l * lrcross; + } - oldclfol=clfol; - oldclfor=clfor; - -}; + oldclfol = clfol; + oldclfor = clfor; +} /* * Cleanup the effect */ void Alienwah::cleanup() { - for (int i=0;i(0.0,0.0); - oldr[i]=complex(0.0,0.0); - }; - oldk=0; -}; + for(int i = 0; i < Pdelay; i++) { + oldl[i] = complex(0.0, 0.0); + oldr[i] = complex(0.0, 0.0); + } + oldk = 0; +} /* @@ -108,81 +112,92 @@ void Alienwah::cleanup() void Alienwah::setdepth(const unsigned char &Pdepth) { - this->Pdepth=Pdepth; - depth=(Pdepth/127.0); -}; + this->Pdepth = Pdepth; + depth = (Pdepth / 127.0); +} void Alienwah::setfb(const unsigned char &Pfb) { - this->Pfb=Pfb; - fb=fabs((Pfb-64.0)/64.1); - fb=sqrt(fb); - if (fb<0.4) fb=0.4; - if (Pfb<64) fb=-fb; -}; + this->Pfb = Pfb; + fb = fabs((Pfb - 64.0) / 64.1); + fb = sqrt(fb); + if(fb < 0.4) + fb = 0.4; + if(Pfb < 64) + fb = -fb; +} void Alienwah::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} void Alienwah::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} void Alienwah::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0; -}; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0; +} void Alienwah::setphase(const unsigned char &Pphase) { - this->Pphase=Pphase; - phase=(Pphase-64.0)/64.0*PI; -}; + this->Pphase = Pphase; + phase = (Pphase - 64.0) / 64.0 * PI; +} void Alienwah::setdelay(const unsigned char &Pdelay) { - if (oldl!=NULL) delete [] oldl; - if (oldr!=NULL) delete [] oldr; - if (Pdelay>=MAX_ALIENWAH_DELAY) this->Pdelay=MAX_ALIENWAH_DELAY; - else this->Pdelay=Pdelay; - oldl=new complex[Pdelay]; - oldr=new complex[Pdelay]; + if(oldl != NULL) + delete [] oldl; + if(oldr != NULL) + delete [] oldr; + if(Pdelay >= MAX_ALIENWAH_DELAY) + this->Pdelay = MAX_ALIENWAH_DELAY; + else + this->Pdelay = Pdelay; + oldl = new complex[Pdelay]; + oldr = new complex[Pdelay]; cleanup(); -}; +} void Alienwah::setpreset(unsigned char npreset) { - const int PRESET_SIZE=11; - const int NUM_PRESETS=4; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 11; + const int NUM_PRESETS = 4; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //AlienWah1 - {127,64,70,0,0,62,60,105,25,0,64}, + {127, 64, 70, 0, 0, 62, 60, 105, 25, 0, 64}, //AlienWah2 - {127,64,73,106,0,101,60,105,17,0,64}, + {127, 64, 73, 106, 0, 101, 60, 105, 17, 0, 64}, //AlienWah3 - {127,64,63,0,1,100,112,105,31,0,42}, + {127, 64, 63, 0, 1, 100, 112, 105, 31, 0, 42}, //AlienWah4 - {93,64,25,0,1,66,101,11,47,0,86} + {93, 64, 25, 0, 1, 66, 101, 11, 47, 0, 86} }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion == 0) + changepar(0, presets[npreset][0] / 2); //lower the volume if this is system effect + Ppreset = npreset; +} -void Alienwah::changepar(const int &npar,const unsigned char &value) +void Alienwah::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -190,19 +205,19 @@ void Alienwah::changepar(const int &npar,const unsigned char &value) setpanning(value); break; case 2: - lfo.Pfreq=value; + lfo.Pfreq = value; lfo.updateparams(); break; case 3: - lfo.Prandomness=value; + lfo.Prandomness = value; lfo.updateparams(); break; case 4: - lfo.PLFOtype=value; + lfo.PLFOtype = value; lfo.updateparams(); break; case 5: - lfo.Pstereo=value; + lfo.Pstereo = value; lfo.updateparams(); break; case 6: @@ -220,48 +235,47 @@ void Alienwah::changepar(const int &npar,const unsigned char &value) case 10: setphase(value); break; - }; -}; + } +} -unsigned char Alienwah::getpar(const int &npar)const +unsigned char Alienwah::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(lfo.Pfreq); + return lfo.Pfreq; break; case 3: - return(lfo.Prandomness); + return lfo.Prandomness; break; case 4: - return(lfo.PLFOtype); + return lfo.PLFOtype; break; case 5: - return(lfo.Pstereo); + return lfo.Pstereo; break; case 6: - return(Pdepth); + return Pdepth; break; case 7: - return(Pfb); + return Pfb; break; case 8: - return(Pdelay); + return Pdelay; break; case 9: - return(Plrcross); + return Plrcross; break; case 10: - return(Pphase); + return Pphase; break; default: - return (0); - }; - -}; + return 0; + } +} diff --git a/plugins/zynaddsubfx/src/Effects/Alienwah.h b/plugins/zynaddsubfx/src/Effects/Alienwah.h index e813737bf..175c41f24 100644 --- a/plugins/zynaddsubfx/src/Effects/Alienwah.h +++ b/plugins/zynaddsubfx/src/Effects/Alienwah.h @@ -34,49 +34,51 @@ using namespace std; /**"AlienWah" Effect*/ class Alienwah:public Effect { -public: - /** - * Constructor - * @param insetion_ 1 for insertion Effect, 0 for others - * @param efxoutl_ Pointer to Alienwah's left channel output buffer - * @param efxoutr_ Pointer to Alienwah's left channel output buffer - * @return Initialized Alienwah - */ - Alienwah(const int &insetion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_); - ~Alienwah(); - void out(REALTYPE *const smpsl,REALTYPE *const smpsr); + public: + /** + * Constructor + * @param insetion_ 1 for insertion Effect, 0 for others + * @param efxoutl_ Pointer to Alienwah's left channel output buffer + * @param efxoutr_ Pointer to Alienwah's left channel output buffer + * @return Initialized Alienwah + */ + Alienwah(const int &insetion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_); + ~Alienwah(); + void out(REALTYPE *const smpsl, REALTYPE *const smpsr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); -private: - //Alienwah Parameters - EffectLFO lfo;//lfo-ul Alienwah - unsigned char Pvolume; - unsigned char Ppanning; - unsigned char Pdepth;//the depth of the Alienwah - unsigned char Pfb;//feedback - unsigned char Plrcross;//feedback - unsigned char Pdelay; - unsigned char Pphase; + private: + //Alienwah Parameters + EffectLFO lfo; //lfo-ul Alienwah + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth; //the depth of the Alienwah + unsigned char Pfb; //feedback + unsigned char Plrcross; //feedback + unsigned char Pdelay; + unsigned char Pphase; - //Control Parameters - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdepth(const unsigned char &Pdepth); - void setfb(const unsigned char &Pfb); - void setlrcross(const unsigned char &Plrcross); - void setdelay(const unsigned char &Pdelay); - void setphase(const unsigned char &Pphase); + //Control Parameters + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdepth(const unsigned char &Pdepth); + void setfb(const unsigned char &Pfb); + void setlrcross(const unsigned char &Plrcross); + void setdelay(const unsigned char &Pdelay); + void setphase(const unsigned char &Pphase); - //Internal Values - REALTYPE panning,fb,depth,lrcross,phase; - complex *oldl,*oldr; - complex oldclfol,oldclfor; - int oldk; + //Internal Values + REALTYPE panning, fb, depth, lrcross, phase; + complex *oldl, *oldr; + complex oldclfol, oldclfor; + int oldk; }; #endif diff --git a/plugins/zynaddsubfx/src/Effects/Chorus.cpp b/plugins/zynaddsubfx/src/Effects/Chorus.cpp index 844e87f50..708c0cd75 100644 --- a/plugins/zynaddsubfx/src/Effects/Chorus.cpp +++ b/plugins/zynaddsubfx/src/Effects/Chorus.cpp @@ -26,26 +26,28 @@ using namespace std; -Chorus::Chorus(const int &insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0), - maxdelay((int)(MAX_CHORUS_DELAY/1000.0*SAMPLE_RATE)), - delaySample(maxdelay) +Chorus::Chorus(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), + maxdelay((int)(MAX_CHORUS_DELAY / 1000.0 * SAMPLE_RATE)), + delaySample(maxdelay) { - dlk=0; - drk=0; + dlk = 0; + drk = 0; //maxdelay=(int)(MAX_CHORUS_DELAY/1000.0*SAMPLE_RATE); //delayl=new REALTYPE[maxdelay]; //delayr=new REALTYPE[maxdelay]; setpreset(Ppreset); - lfo.effectlfoout(&lfol,&lfor); - dl2=getdelay(lfol); - dr2=getdelay(lfor); + lfo.effectlfoout(&lfol, &lfor); + dl2 = getdelay(lfol); + dr2 = getdelay(lfor); cleanup(); -}; +} -Chorus::~Chorus() {}; +Chorus::~Chorus() {} /* * get the delay value in samples; xlfo is the current lfo value @@ -53,91 +55,100 @@ Chorus::~Chorus() {}; REALTYPE Chorus::getdelay(REALTYPE xlfo) { REALTYPE result; - if (Pflangemode==0) { - result=(delay+xlfo*depth)*SAMPLE_RATE; - } else result=0; + if(Pflangemode == 0) + result = (delay + xlfo * depth) * SAMPLE_RATE; + else + result = 0; //check if it is too big delay(caused bu errornous setdelay() and setdepth() /**\todo fix setdelay() and setdepth(), so this error cannot occur*/ - if ((result+0.5)>=maxdelay) { - cerr << "WARNING: Chorus.C::getdelay(..) too big delay (see setdelay and setdepth funcs.)\n"; - result=maxdelay-1.0; - }; - return(result); -}; + if((result + 0.5) >= maxdelay) { + cerr + << + "WARNING: Chorus.C::getdelay(..) too big delay (see setdelay and setdepth funcs.)\n"; + result = maxdelay - 1.0; + } + return result; +} /* * Apply the effect */ -void Chorus::out(REALTYPE *smpsl,REALTYPE *smpsr) +void Chorus::out(REALTYPE *smpsl, REALTYPE *smpsr) { - const Stereo input(AuSample(SOUND_BUFFER_SIZE,smpsl),AuSample(SOUND_BUFFER_SIZE,smpsr)); + const Stereo input(AuSample(SOUND_BUFFER_SIZE, smpsl), AuSample( + SOUND_BUFFER_SIZE, + smpsr)); out(input); } void Chorus::out(const Stereo &input) { - const REALTYPE one=1.0; - dl1=dl2; - dr1=dr2; - lfo.effectlfoout(&lfol,&lfor); + const REALTYPE one = 1.0; + dl1 = dl2; + dr1 = dr2; + lfo.effectlfoout(&lfol, &lfor); - dl2=getdelay(lfol); - dr2=getdelay(lfor); + dl2 = getdelay(lfol); + dr2 = getdelay(lfor); - for (int i=0;i tmpc(inl,inr); + Stereo tmpc(inl, inr); //REALTYPE r=inr; - inl=tmpc.l()*(1.0-lrcross)+tmpc.r()*lrcross; - inr=tmpc.r()*(1.0-lrcross)+tmpc.l()*lrcross; + inl = tmpc.l() * (1.0 - lrcross) + tmpc.r() * lrcross; + inr = tmpc.r() * (1.0 - lrcross) + tmpc.l() * lrcross; //Left channel //compute the delay in samples using linear interpolation between the lfo delays - mdel=(dl1*(SOUND_BUFFER_SIZE-i)+dl2*i)/SOUND_BUFFER_SIZE; - if (++dlk>=maxdelay) dlk=0; - REALTYPE tmp=dlk-mdel+maxdelay*2.0;//where should I get the sample from + mdel = (dl1 * (SOUND_BUFFER_SIZE - i) + dl2 * i) / SOUND_BUFFER_SIZE; + if(++dlk >= maxdelay) + dlk = 0; + REALTYPE tmp = dlk - mdel + maxdelay * 2.0; //where should I get the sample from - F2I(tmp,dlhi); - dlhi%=maxdelay; + F2I(tmp, dlhi); + dlhi %= maxdelay; - dlhi2=(dlhi-1+maxdelay)%maxdelay; - dllo=1.0-fmod(tmp,one); - efxoutl[i]=delaySample.l()[dlhi2]*dllo+delaySample.l()[dlhi]*(1.0-dllo); - delaySample.l()[dlk]=inl+efxoutl[i]*fb; + dlhi2 = (dlhi - 1 + maxdelay) % maxdelay; + dllo = 1.0 - fmod(tmp, one); + efxoutl[i] = delaySample.l()[dlhi2] * dllo + delaySample.l()[dlhi] + * (1.0 - dllo); + delaySample.l()[dlk] = inl + efxoutl[i] * fb; //Right channel //compute the delay in samples using linear interpolation between the lfo delays - mdel=(dr1*(SOUND_BUFFER_SIZE-i)+dr2*i)/SOUND_BUFFER_SIZE; - if (++drk>=maxdelay) drk=0; - tmp=drk*1.0-mdel+maxdelay*2.0;//where should I get the sample from + mdel = (dr1 * (SOUND_BUFFER_SIZE - i) + dr2 * i) / SOUND_BUFFER_SIZE; + if(++drk >= maxdelay) + drk = 0; + tmp = drk * 1.0 - mdel + maxdelay * 2.0; //where should I get the sample from - F2I(tmp,dlhi); - dlhi%=maxdelay; + F2I(tmp, dlhi); + dlhi %= maxdelay; - dlhi2=(dlhi-1+maxdelay)%maxdelay; - dllo=1.0-fmod(tmp,one); - efxoutr[i]=delaySample.r()[dlhi2]*dllo+delaySample.r()[dlhi]*(1.0-dllo); - delaySample.r()[dlk]=inr+efxoutr[i]*fb; + dlhi2 = (dlhi - 1 + maxdelay) % maxdelay; + dllo = 1.0 - fmod(tmp, one); + efxoutr[i] = delaySample.r()[dlhi2] * dllo + delaySample.r()[dlhi] + * (1.0 - dllo); + delaySample.r()[dlk] = inr + efxoutr[i] * fb; + } - }; - - if (Poutsub!=0) - for (int i=0;iPdepth=Pdepth; - depth=(pow(8.0,(Pdepth/127.0)*2.0)-1.0)/1000.0;//seconds -}; + this->Pdepth = Pdepth; + depth = (pow(8.0, (Pdepth / 127.0) * 2.0) - 1.0) / 1000.0; //seconds +} void Chorus::setdelay(const unsigned char &Pdelay) { - this->Pdelay=Pdelay; - delay=(pow(10.0,(Pdelay/127.0)*2.0)-1.0)/1000.0;//seconds -}; + this->Pdelay = Pdelay; + delay = (pow(10.0, (Pdelay / 127.0) * 2.0) - 1.0) / 1000.0; //seconds +} void Chorus::setfb(const unsigned char &Pfb) { - this->Pfb=Pfb; - fb=(Pfb-64.0)/64.1; -}; + this->Pfb = Pfb; + fb = (Pfb - 64.0) / 64.1; +} void Chorus::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} void Chorus::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} void Chorus::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0; -}; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0; +} void Chorus::setpreset(unsigned char npreset) { - const int PRESET_SIZE=12; - const int NUM_PRESETS=10; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 12; + const int NUM_PRESETS = 10; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //Chorus1 - {64,64,50,0,0,90,40,85,64,119,0,0}, + {64, 64, 50, 0, 0, 90, 40, 85, 64, 119, 0, 0 }, //Chorus2 - {64,64,45,0,0,98,56,90,64,19,0,0}, + {64, 64, 45, 0, 0, 98, 56, 90, 64, 19, 0, 0 }, //Chorus3 - {64,64,29,0,1,42,97,95,90,127,0,0}, + {64, 64, 29, 0, 1, 42, 97, 95, 90, 127, 0, 0 }, //Celeste1 - {64,64,26,0,0,42,115,18,90,127,0,0}, + {64, 64, 26, 0, 0, 42, 115, 18, 90, 127, 0, 0 }, //Celeste2 - {64,64,29,117,0,50,115,9,31,127,0,1}, + {64, 64, 29, 117, 0, 50, 115, 9, 31, 127, 0, 1 }, //Flange1 - {64,64,57,0,0,60,23,3,62,0,0,0}, + {64, 64, 57, 0, 0, 60, 23, 3, 62, 0, 0, 0 }, //Flange2 - {64,64,33,34,1,40,35,3,109,0,0,0}, + {64, 64, 33, 34, 1, 40, 35, 3, 109, 0, 0, 0 }, //Flange3 - {64,64,53,34,1,94,35,3,54,0,0,1}, + {64, 64, 53, 34, 1, 94, 35, 3, 54, 0, 0, 1 }, //Flange4 - {64,64,40,0,1,62,12,19,97,0,0,0}, + {64, 64, 40, 0, 1, 62, 12, 19, 97, 0, 0, 0 }, //Flange5 - {64,64,55,105,0,24,39,19,17,0,0,1} + {64, 64, 55, 105, 0, 24, 39, 19, 17, 0, 0, 1 } }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + Ppreset = npreset; +} -void Chorus::changepar(const int &npar,const unsigned char &value) +void Chorus::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -231,19 +246,19 @@ void Chorus::changepar(const int &npar,const unsigned char &value) setpanning(value); break; case 2: - lfo.Pfreq=value; + lfo.Pfreq = value; lfo.updateparams(); break; case 3: - lfo.Prandomness=value; + lfo.Prandomness = value; lfo.updateparams(); break; case 4: - lfo.PLFOtype=value; + lfo.PLFOtype = value; lfo.updateparams(); break; case 5: - lfo.Pstereo=value; + lfo.Pstereo = value; lfo.updateparams(); break; case 6: @@ -259,58 +274,61 @@ void Chorus::changepar(const int &npar,const unsigned char &value) setlrcross(value); break; case 10: - if (value>1) Pflangemode=1; - else Pflangemode=value; + if(value > 1) + Pflangemode = 1; + else + Pflangemode = value; break; case 11: - if (value>1) Poutsub=1; - else Poutsub=value; + if(value > 1) + Poutsub = 1; + else + Poutsub = value; break; - }; -}; + } +} -unsigned char Chorus::getpar(const int &npar)const +unsigned char Chorus::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(lfo.Pfreq); + return lfo.Pfreq; break; case 3: - return(lfo.Prandomness); + return lfo.Prandomness; break; case 4: - return(lfo.PLFOtype); + return lfo.PLFOtype; break; case 5: - return(lfo.Pstereo); + return lfo.Pstereo; break; case 6: - return(Pdepth); + return Pdepth; break; case 7: - return(Pdelay); + return Pdelay; break; case 8: - return(Pfb); + return Pfb; break; case 9: - return(Plrcross); + return Plrcross; break; case 10: - return(Pflangemode); + return Pflangemode; break; case 11: - return(Poutsub); + return Poutsub; break; default: - return (0); - }; - -}; + return 0; + } +} diff --git a/plugins/zynaddsubfx/src/Effects/Chorus.h b/plugins/zynaddsubfx/src/Effects/Chorus.h index 488e4d85d..748ce5eaf 100644 --- a/plugins/zynaddsubfx/src/Effects/Chorus.h +++ b/plugins/zynaddsubfx/src/Effects/Chorus.h @@ -33,83 +33,83 @@ /**Chorus and Flange effects*/ class Chorus:public Effect { -public: - Chorus(const int &insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - /**Destructor*/ - ~Chorus(); - void out(REALTYPE *smpsl,REALTYPE *smpsr); - void out(const Stereo &input); - void setpreset(unsigned char npreset); - /** - * Sets the value of the chosen variable - * - * The possible parameters are: - * -# Volume - * -# Panning - * -# LFO Frequency - * -# LFO Randomness - * -# LFO Type - * -# LFO stereo - * -# Depth - * -# Delay - * -# Feedback - * -# Flange Mode - * -# Subtractive - * @param npar number of chosen parameter - * @param value the new value - */ - void changepar(const int &npar,const unsigned char &value); - /** - * Gets the value of the chosen variable - * - * The possible parameters are: - * -# Volume - * -# Panning - * -# LFO Frequency - * -# LFO Randomness - * -# LFO Type - * -# LFO stereo - * -# Depth - * -# Delay - * -# Feedback - * -# Flange Mode - * -# Subtractive - * @param npar number of chosen parameter - * @return the value of the parameter - */ - unsigned char getpar(const int &npar)const; - void cleanup(); + public: + Chorus(const int &insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + /**Destructor*/ + ~Chorus(); + void out(REALTYPE *smpsl, REALTYPE *smpsr); + void out(const Stereo &input); + void setpreset(unsigned char npreset); + /** + * Sets the value of the chosen variable + * + * The possible parameters are: + * -# Volume + * -# Panning + * -# LFO Frequency + * -# LFO Randomness + * -# LFO Type + * -# LFO stereo + * -# Depth + * -# Delay + * -# Feedback + * -# Flange Mode + * -# Subtractive + * @param npar number of chosen parameter + * @param value the new value + */ + void changepar(const int &npar, const unsigned char &value); + /** + * Gets the value of the chosen variable + * + * The possible parameters are: + * -# Volume + * -# Panning + * -# LFO Frequency + * -# LFO Randomness + * -# LFO Type + * -# LFO stereo + * -# Depth + * -# Delay + * -# Feedback + * -# Flange Mode + * -# Subtractive + * @param npar number of chosen parameter + * @return the value of the parameter + */ + unsigned char getpar(const int &npar) const; + void cleanup(); -private: - //Chorus Parameters - EffectLFO lfo;//lfo-ul chorus - unsigned char Pvolume; - unsigned char Ppanning; - unsigned char Pdepth;//the depth of the Chorus(ms) - unsigned char Pdelay;//the delay (ms) - unsigned char Pfb;//feedback - unsigned char Plrcross;//feedback - unsigned char Pflangemode;//how the LFO is scaled, to result chorus or flange - unsigned char Poutsub;//if I wish to substract the output instead of the adding it + private: + //Chorus Parameters + EffectLFO lfo; //lfo-ul chorus + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth; //the depth of the Chorus(ms) + unsigned char Pdelay; //the delay (ms) + unsigned char Pfb; //feedback + unsigned char Plrcross; //feedback + unsigned char Pflangemode; //how the LFO is scaled, to result chorus or flange + unsigned char Poutsub; //if I wish to substract the output instead of the adding it - //Parameter Controls - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdepth(const unsigned char &Pdepth); - void setdelay(const unsigned char &Pdelay); - void setfb(const unsigned char &Pfb); - void setlrcross(const unsigned char &Plrcross); + //Parameter Controls + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdepth(const unsigned char &Pdepth); + void setdelay(const unsigned char &Pdelay); + void setfb(const unsigned char &Pfb); + void setlrcross(const unsigned char &Plrcross); - //Internal Values - REALTYPE depth,delay,fb,lrcross,panning; - REALTYPE dl1,dl2,dr1,dr2,lfol,lfor; - int maxdelay; - Stereo delaySample; - //REALTYPE *delayl,*delayr; - int dlk,drk,dlhi,dlhi2; - REALTYPE getdelay(REALTYPE xlfo); - REALTYPE dllo,mdel; + //Internal Values + REALTYPE depth, delay, fb, lrcross, panning; + REALTYPE dl1, dl2, dr1, dr2, lfol, lfor; + int maxdelay; + Stereo delaySample; + //REALTYPE *delayl,*delayr; + int dlk, drk, dlhi, dlhi2; + REALTYPE getdelay(REALTYPE xlfo); + REALTYPE dllo, mdel; }; #endif diff --git a/plugins/zynaddsubfx/src/Effects/Distorsion.cpp b/plugins/zynaddsubfx/src/Effects/Distorsion.cpp index 6aeaab4fb..61fe9966b 100644 --- a/plugins/zynaddsubfx/src/Effects/Distorsion.cpp +++ b/plugins/zynaddsubfx/src/Effects/Distorsion.cpp @@ -28,159 +28,199 @@ * Waveshape (this is called by OscilGen::waveshape and Distorsion::process) */ -void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive) +void waveshapesmps(int n, + REALTYPE *smps, + unsigned char type, + unsigned char drive) { - int i; - REALTYPE ws=drive/127.0; + int i; + REALTYPE ws = drive / 127.0; REALTYPE tmpv; - switch (type) { + switch(type) { case 1: - ws=pow(10,ws*ws*3.0)-1.0+0.001;//Arctangent - for (i=0;iws) { - if (tmp>=0.0) smps[i]=1.0; - else smps[i]=-1.0; - } else smps[i]/=ws; - }; + ws = pow(2.0, -ws * ws * 8.0); //Limiter + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i]; + if(fabs(tmp) > ws) { + if(tmp >= 0.0) + smps[i] = 1.0; + else + smps[i] = -1.0; + } + else + smps[i] /= ws; + } break; case 8: - ws=pow(2.0,-ws*ws*8.0); //Upper Limiter - for (i=0;iws) smps[i]=ws; - smps[i]*=2.0; - }; + ws = pow(2.0, -ws * ws * 8.0); //Upper Limiter + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i]; + if(tmp > ws) + smps[i] = ws; + smps[i] *= 2.0; + } break; case 9: - ws=pow(2.0,-ws*ws*8.0); //Lower Limiter - for (i=0;iws) { - if (tmp>=0.0) smps[i]=tmp-ws; - else smps[i]=tmp+ws; - } else smps[i]=0; - }; + ws = (pow(2.0, ws * 6.0) - 1.0) / pow(2.0, 6.0); //Inverse Limiter + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i]; + if(fabs(tmp) > ws) { + if(tmp >= 0.0) + smps[i] = tmp - ws; + else + smps[i] = tmp + ws; + } + else + smps[i] = 0; + } break; case 11: - ws=pow(5,ws*ws*1.0)-1.0;//Clip - for (i=0;i-2.0) && (tmp<1.0)) smps[i]=tmp*(1.0-tmp)*(tmp+2.0)/tmpv; - else smps[i]=0.0; - }; + ws = ws * ws * ws * 30 + 0.001; //Asym2 + if(ws < 0.3) + tmpv = ws; + else + tmpv = 1.0; + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i] * ws; + if((tmp > -2.0) && (tmp < 1.0)) + smps[i] = tmp * (1.0 - tmp) * (tmp + 2.0) / tmpv; + else + smps[i] = 0.0; + } break; case 13: - ws=ws*ws*ws*32.0+0.0001;//Pow2 - if (ws<1.0) tmpv=ws*(1+ws)/2.0; - else tmpv=1.0; - for (i=0;i-1.0)&&(tmp<1.618034)) smps[i]=tmp*(1.0-tmp)/tmpv; - else if (tmp>0.0) smps[i]=-1.0; - else smps[i]=-2.0; - }; + ws = ws * ws * ws * 32.0 + 0.0001; //Pow2 + if(ws < 1.0) + tmpv = ws * (1 + ws) / 2.0; + else + tmpv = 1.0; + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i] * ws; + if((tmp > -1.0) && (tmp < 1.618034)) + smps[i] = tmp * (1.0 - tmp) / tmpv; + else + if(tmp > 0.0) + smps[i] = -1.0; + else + smps[i] = -2.0; + } break; case 14: - ws=pow(ws,5.0)*80.0+0.0001;//sigmoid - if (ws>10.0) tmpv=0.5; - else tmpv=0.5-1.0/(exp(ws)+1.0); - for (i=0;i10.0) tmp=10.0; - tmp=0.5-1.0/(exp(tmp)+1.0); - smps[i]=tmp/tmpv; - }; + ws = pow(ws, 5.0) * 80.0 + 0.0001; //sigmoid + if(ws > 10.0) + tmpv = 0.5; + else + tmpv = 0.5 - 1.0 / (exp(ws) + 1.0); + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i] * ws; + if(tmp < -10.0) + tmp = -10.0; + else + if(tmp > 10.0) + tmp = 10.0; + tmp = 0.5 - 1.0 / (exp(tmp) + 1.0); + smps[i] = tmp / tmpv; + } break; /**\todo update to Distorsion::changepar (Ptype max) if there is added more waveshapings functions*/ - }; - -}; + } +} -Distorsion::Distorsion(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) +Distorsion::Distorsion(const int &insertion_, + REALTYPE *efxoutl_, + REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0) { - - lpfl=new AnalogFilter(2,22000,1,0); - lpfr=new AnalogFilter(2,22000,1,0); - hpfl=new AnalogFilter(3,20,1,0); - hpfr=new AnalogFilter(3,20,1,0); + lpfl = new AnalogFilter(2, 22000, 1, 0); + lpfr = new AnalogFilter(2, 22000, 1, 0); + hpfl = new AnalogFilter(3, 20, 1, 0); + hpfr = new AnalogFilter(3, 20, 1, 0); //default values - Pvolume=50; - Plrcross=40; - Pdrive=90; - Plevel=64; - Ptype=0; - Pnegate=0; - Plpf=127; - Phpf=0; - Pstereo=0; - Pprefiltering=0; + Pvolume = 50; + Plrcross = 40; + Pdrive = 90; + Plevel = 64; + Ptype = 0; + Pnegate = 0; + Plpf = 127; + Phpf = 0; + Pstereo = 0; + Pprefiltering = 0; setpreset(Ppreset); cleanup(); -}; +} Distorsion::~Distorsion() { @@ -188,8 +228,7 @@ Distorsion::~Distorsion() delete lpfr; delete hpfl; delete hpfr; - -}; +} /* * Cleanup the effect @@ -200,72 +239,77 @@ void Distorsion::cleanup() hpfl->cleanup(); lpfr->cleanup(); hpfr->cleanup(); -}; +} /* * Apply the filters */ -void Distorsion::applyfilters(REALTYPE *efxoutl,REALTYPE *efxoutr) +void Distorsion::applyfilters(REALTYPE *efxoutl, REALTYPE *efxoutr) { lpfl->filterout(efxoutl); hpfl->filterout(efxoutl); - if (Pstereo!=0) {//stereo + if(Pstereo != 0) { //stereo lpfr->filterout(efxoutr); hpfr->filterout(efxoutr); - }; - -}; + } +} /* * Effect output */ -void Distorsion::out(REALTYPE *smpsl,REALTYPE *smpsr) +void Distorsion::out(REALTYPE *smpsl, REALTYPE *smpsr) { - int i; - REALTYPE l,r,lout,rout; + int i; + REALTYPE l, r, lout, rout; - REALTYPE inputvol=pow(5.0,(Pdrive-32.0)/127.0); - if (Pnegate!=0) inputvol*=-1.0; + REALTYPE inputvol = pow(5.0, (Pdrive - 32.0) / 127.0); + if(Pnegate != 0) + inputvol *= -1.0; - if (Pstereo!=0) {//Stereo - for (i=0;iPvolume=Pvolume; + this->Pvolume = Pvolume; - if (insertion==0) { - outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; - volume=1.0; - } else { - volume=outvolume=Pvolume/127.0; - }; - if (Pvolume==0) cleanup(); - -}; + if(insertion == 0) { + outvolume = pow(0.01, (1.0 - Pvolume / 127.0)) * 4.0; + volume = 1.0; + } + else + volume = outvolume = Pvolume / 127.0; + ; + if(Pvolume == 0) + cleanup(); +} void Distorsion::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=(Ppanning+0.5)/127.0; -}; + this->Ppanning = Ppanning; + panning = (Ppanning + 0.5) / 127.0; +} void Distorsion::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0*1.0; -}; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0 * 1.0; +} void Distorsion::setlpf(const unsigned char &Plpf) { - this->Plpf=Plpf; - REALTYPE fr=exp(pow(Plpf/127.0,0.5)*log(25000.0))+40; + this->Plpf = Plpf; + REALTYPE fr = exp(pow(Plpf / 127.0, 0.5) * log(25000.0)) + 40; lpfl->setfreq(fr); lpfr->setfreq(fr); -}; +} void Distorsion::sethpf(const unsigned char &Phpf) { - this->Phpf=Phpf; - REALTYPE fr=exp(pow(Phpf/127.0,0.5)*log(25000.0))+20.0; + this->Phpf = Phpf; + REALTYPE fr = exp(pow(Phpf / 127.0, 0.5) * log(25000.0)) + 20.0; hpfl->setfreq(fr); hpfr->setfreq(fr); -}; +} void Distorsion::setpreset(unsigned char npreset) { - const int PRESET_SIZE=11; - const int NUM_PRESETS=6; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 11; + const int NUM_PRESETS = 6; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //Overdrive 1 - {127,64,35,56,70,0,0,96,0,0,0}, + {127, 64, 35, 56, 70, 0, 0, 96, 0, 0, 0 }, //Overdrive 2 - {127,64,35,29,75,1,0,127,0,0,0}, + {127, 64, 35, 29, 75, 1, 0, 127, 0, 0, 0 }, //A. Exciter 1 - {64,64,35,75,80,5,0,127,105,1,0}, + {64, 64, 35, 75, 80, 5, 0, 127, 105, 1, 0 }, //A. Exciter 2 - {64,64,35,85,62,1,0,127,118,1,0}, + {64, 64, 35, 85, 62, 1, 0, 127, 118, 1, 0 }, //Guitar Amp - {127,64,35,63,75,2,0,55,0,0,0}, + {127, 64, 35, 63, 75, 2, 0, 55, 0, 0, 0 }, //Quantisize - {127,64,35,88,75,4,0,127,0,1,0} + {127, 64, 35, 88, 75, 4, 0, 127, 0, 1, 0 } }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion == 0) + changepar(0, (int) (presets[npreset][0] / 1.5)); //lower the volume if this is system effect + Ppreset = npreset; cleanup(); -}; +} -void Distorsion::changepar(const int &npar,const unsigned char &value) +void Distorsion::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -356,18 +404,22 @@ void Distorsion::changepar(const int &npar,const unsigned char &value) setlrcross(value); break; case 3: - Pdrive=value; + Pdrive = value; break; case 4: - Plevel=value; + Plevel = value; break; case 5: - if (value>13) Ptype=13;//this must be increased if more distorsion types are added - else Ptype=value; + if(value > 13) + Ptype = 13; //this must be increased if more distorsion types are added + else + Ptype = value; break; case 6: - if (value>1) Pnegate=1; - else Pnegate=value; + if(value > 1) + Pnegate = 1; + else + Pnegate = value; break; case 7: setlpf(value); @@ -376,52 +428,54 @@ void Distorsion::changepar(const int &npar,const unsigned char &value) sethpf(value); break; case 9: - if (value>1) Pstereo=1; - else Pstereo=value; + if(value > 1) + Pstereo = 1; + else + Pstereo = value; break; case 10: - Pprefiltering=value; + Pprefiltering = value; break; - }; -}; + } +} -unsigned char Distorsion::getpar(const int &npar)const +unsigned char Distorsion::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(Plrcross); + return Plrcross; break; case 3: - return(Pdrive); + return Pdrive; break; case 4: - return(Plevel); + return Plevel; break; case 5: - return(Ptype); + return Ptype; break; case 6: - return(Pnegate); + return Pnegate; break; case 7: - return(Plpf); + return Plpf; break; case 8: - return(Phpf); + return Phpf; break; case 9: - return(Pstereo); + return Pstereo; break; case 10: - return(Pprefiltering); + return Pprefiltering; break; - }; - return(0);//in case of bogus parameter number -}; + } + return 0; //in case of bogus parameter number +} diff --git a/plugins/zynaddsubfx/src/Effects/Distorsion.h b/plugins/zynaddsubfx/src/Effects/Distorsion.h index efe3b8287..8c082f13f 100644 --- a/plugins/zynaddsubfx/src/Effects/Distorsion.h +++ b/plugins/zynaddsubfx/src/Effects/Distorsion.h @@ -28,44 +28,46 @@ #include "Effect.h" //Waveshaping(called by Distorsion effect and waveshape from OscilGen) -void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive); +void waveshapesmps(int n, + REALTYPE *smps, + unsigned char type, + unsigned char drive); /**Distortion Effect*/ class Distorsion:public Effect { -public: - Distorsion(const int &insertion,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~Distorsion(); - void out(REALTYPE *smpsl,REALTYPE *smpr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); - void applyfilters(REALTYPE *efxoutl,REALTYPE *efxoutr); + public: + Distorsion(const int &insertion, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~Distorsion(); + void out(REALTYPE *smpsl, REALTYPE *smpr); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); + void applyfilters(REALTYPE *efxoutl, REALTYPE *efxoutr); -private: - //Parametrii - unsigned char Pvolume; //Volumul or E/R - unsigned char Ppanning;//Panning - unsigned char Plrcross;// L/R Mixing - unsigned char Pdrive; //the input amplification - unsigned char Plevel; //the output amplification - unsigned char Ptype; //Distorsion type - unsigned char Pnegate; //if the input is negated - unsigned char Plpf; //lowpass filter - unsigned char Phpf; //highpass filter - unsigned char Pstereo; //0=mono,1=stereo - unsigned char Pprefiltering;//if you want to do the filtering before the distorsion + private: + //Parametrii + unsigned char Pvolume; //Volumul or E/R + unsigned char Ppanning; //Panning + unsigned char Plrcross; // L/R Mixing + unsigned char Pdrive; //the input amplification + unsigned char Plevel; //the output amplification + unsigned char Ptype; //Distorsion type + unsigned char Pnegate; //if the input is negated + unsigned char Plpf; //lowpass filter + unsigned char Phpf; //highpass filter + unsigned char Pstereo; //0=mono,1=stereo + unsigned char Pprefiltering; //if you want to do the filtering before the distorsion - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setlrcross(const unsigned char &Plrcross); - void setlpf(const unsigned char &Plpf); - void sethpf(const unsigned char &Phpf); - - //Real Parameters - REALTYPE panning,lrcross; - AnalogFilter *lpfl,*lpfr,*hpfl,*hpfr; + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setlrcross(const unsigned char &Plrcross); + void setlpf(const unsigned char &Plpf); + void sethpf(const unsigned char &Phpf); + //Real Parameters + REALTYPE panning, lrcross; + AnalogFilter *lpfl, *lpfr, *hpfl, *hpfr; }; diff --git a/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp b/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp index b7b367ea3..1b2bb1eb0 100644 --- a/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp +++ b/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp @@ -23,74 +23,75 @@ #include #include "DynamicFilter.h" -DynamicFilter::DynamicFilter(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,new FilterParams(0,64,64),0), - Pvolume(110),Ppanning(64),Pdepth(0),Pampsns(90), - Pampsnsinv(0),Pampsmooth(60), - filterl(NULL),filterr(NULL) +DynamicFilter::DynamicFilter(int insertion_, + REALTYPE *efxoutl_, + REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, new FilterParams(0, 64, 64), 0), + Pvolume(110), Ppanning(64), Pdepth(0), Pampsns(90), + Pampsnsinv(0), Pampsmooth(60), + filterl(NULL), filterr(NULL) { setpreset(Ppreset); cleanup(); -}; +} DynamicFilter::~DynamicFilter() { delete filterpars; delete filterl; delete filterr; -}; +} /* * Apply the effect */ -void DynamicFilter::out(REALTYPE *smpsl,REALTYPE *smpsr) +void DynamicFilter::out(REALTYPE *smpsl, REALTYPE *smpsr) { int i; - if (filterpars->changed) { - filterpars->changed=false; + if(filterpars->changed) { + filterpars->changed = false; cleanup(); - }; + } - REALTYPE lfol,lfor; - lfo.effectlfoout(&lfol,&lfor); - lfol*=depth*5.0; - lfor*=depth*5.0; - REALTYPE freq=filterpars->getfreq(); - REALTYPE q=filterpars->getq(); + REALTYPE lfol, lfor; + lfo.effectlfoout(&lfol, &lfor); + lfol *= depth * 5.0; + lfor *= depth * 5.0; + REALTYPE freq = filterpars->getfreq(); + REALTYPE q = filterpars->getq(); - for (i=0;igetrealfreq(freq+lfol+rms); - REALTYPE frr=filterr->getrealfreq(freq+lfor+rms); + REALTYPE frl = filterl->getrealfreq(freq + lfol + rms); + REALTYPE frr = filterr->getrealfreq(freq + lfor + rms); - filterl->setfreq_and_q(frl,q); - filterr->setfreq_and_q(frr,q); + filterl->setfreq_and_q(frl, q); + filterr->setfreq_and_q(frr, q); filterl->filterout(efxoutl); filterr->filterout(efxoutr); //panning - for (i=0;iPdepth=Pdepth; - depth=pow((Pdepth/127.0),2.0); -}; + this->Pdepth = Pdepth; + depth = pow((Pdepth / 127.0), 2.0); +} void DynamicFilter::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} void DynamicFilter::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} void DynamicFilter::setampsns(const unsigned char &Pampsns) { - ampsns=pow(Pampsns/127.0,2.5)*10.0; - if (Pampsnsinv!=0) ampsns=-ampsns; - ampsmooth=exp(-Pampsmooth/127.0*10.0)*0.99; - this->Pampsns=Pampsns; -}; + ampsns = pow(Pampsns / 127.0, 2.5) * 10.0; + if(Pampsnsinv != 0) + ampsns = -ampsns; + ampsmooth = exp(-Pampsmooth / 127.0 * 10.0) * 0.99; + this->Pampsns = Pampsns; +} void DynamicFilter::reinitfilter() { - if (filterl!=NULL) delete(filterl); - if (filterr!=NULL) delete(filterr); - filterl=new Filter(filterpars); - filterr=new Filter(filterpars); -}; + if(filterl != NULL) + delete (filterl); + if(filterr != NULL) + delete (filterr); + filterl = new Filter(filterpars); + filterr = new Filter(filterpars); +} void DynamicFilter::setpreset(unsigned char npreset) { - const int PRESET_SIZE=10; - const int NUM_PRESETS=5; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 10; + const int NUM_PRESETS = 5; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //WahWah - {110,64,80,0,0,64,0,90,0,60}, + {110, 64, 80, 0, 0, 64, 0, 90, 0, 60}, //AutoWah - {110,64,70,0,0,80,70,0,0,60}, + {110, 64, 70, 0, 0, 80, 70, 0, 0, 60}, //Sweep - {100,64,30,0,0,50,80,0,0,60}, + {100, 64, 30, 0, 0, 50, 80, 0, 0, 60}, //VocalMorph1 - {110,64,80,0,0,64,0,64,0,60}, + {110, 64, 80, 0, 0, 64, 0, 64, 0, 60}, //VocalMorph1 - {127,64,50,0,0,96,64,0,0,60} + {127, 64, 50, 0, 0, 96, 64, 0, 0, 60} }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); filterpars->defaults(); - switch (npreset) { + switch(npreset) { case 0: - filterpars->Pcategory=0; - filterpars->Ptype=2; - filterpars->Pfreq=45; - filterpars->Pq=64; - filterpars->Pstages=1; - filterpars->Pgain=64; + filterpars->Pcategory = 0; + filterpars->Ptype = 2; + filterpars->Pfreq = 45; + filterpars->Pq = 64; + filterpars->Pstages = 1; + filterpars->Pgain = 64; break; case 1: - filterpars->Pcategory=2; - filterpars->Ptype=0; - filterpars->Pfreq=72; - filterpars->Pq=64; - filterpars->Pstages=0; - filterpars->Pgain=64; + filterpars->Pcategory = 2; + filterpars->Ptype = 0; + filterpars->Pfreq = 72; + filterpars->Pq = 64; + filterpars->Pstages = 0; + filterpars->Pgain = 64; break; case 2: - filterpars->Pcategory=0; - filterpars->Ptype=4; - filterpars->Pfreq=64; - filterpars->Pq=64; - filterpars->Pstages=2; - filterpars->Pgain=64; + filterpars->Pcategory = 0; + filterpars->Ptype = 4; + filterpars->Pfreq = 64; + filterpars->Pq = 64; + filterpars->Pstages = 2; + filterpars->Pgain = 64; break; case 3: - filterpars->Pcategory=1; - filterpars->Ptype=0; - filterpars->Pfreq=50; - filterpars->Pq=70; - filterpars->Pstages=1; - filterpars->Pgain=64; + filterpars->Pcategory = 1; + filterpars->Ptype = 0; + filterpars->Pfreq = 50; + filterpars->Pq = 70; + filterpars->Pstages = 1; + filterpars->Pgain = 64; - filterpars->Psequencesize=2; + filterpars->Psequencesize = 2; // "I" - filterpars->Pvowels[0].formants[0].freq=34; - filterpars->Pvowels[0].formants[0].amp=127; - filterpars->Pvowels[0].formants[0].q=64; - filterpars->Pvowels[0].formants[1].freq=99; - filterpars->Pvowels[0].formants[1].amp=122; - filterpars->Pvowels[0].formants[1].q=64; - filterpars->Pvowels[0].formants[2].freq=108; - filterpars->Pvowels[0].formants[2].amp=112; - filterpars->Pvowels[0].formants[2].q=64; + filterpars->Pvowels[0].formants[0].freq = 34; + filterpars->Pvowels[0].formants[0].amp = 127; + filterpars->Pvowels[0].formants[0].q = 64; + filterpars->Pvowels[0].formants[1].freq = 99; + filterpars->Pvowels[0].formants[1].amp = 122; + filterpars->Pvowels[0].formants[1].q = 64; + filterpars->Pvowels[0].formants[2].freq = 108; + filterpars->Pvowels[0].formants[2].amp = 112; + filterpars->Pvowels[0].formants[2].q = 64; // "A" - filterpars->Pvowels[1].formants[0].freq=61; - filterpars->Pvowels[1].formants[0].amp=127; - filterpars->Pvowels[1].formants[0].q=64; - filterpars->Pvowels[1].formants[1].freq=71; - filterpars->Pvowels[1].formants[1].amp=121; - filterpars->Pvowels[1].formants[1].q=64; - filterpars->Pvowels[1].formants[2].freq=99; - filterpars->Pvowels[1].formants[2].amp=117; - filterpars->Pvowels[1].formants[2].q=64; + filterpars->Pvowels[1].formants[0].freq = 61; + filterpars->Pvowels[1].formants[0].amp = 127; + filterpars->Pvowels[1].formants[0].q = 64; + filterpars->Pvowels[1].formants[1].freq = 71; + filterpars->Pvowels[1].formants[1].amp = 121; + filterpars->Pvowels[1].formants[1].q = 64; + filterpars->Pvowels[1].formants[2].freq = 99; + filterpars->Pvowels[1].formants[2].amp = 117; + filterpars->Pvowels[1].formants[2].q = 64; break; case 4: - filterpars->Pcategory=1; - filterpars->Ptype=0; - filterpars->Pfreq=64; - filterpars->Pq=70; - filterpars->Pstages=1; - filterpars->Pgain=64; + filterpars->Pcategory = 1; + filterpars->Ptype = 0; + filterpars->Pfreq = 64; + filterpars->Pq = 70; + filterpars->Pstages = 1; + filterpars->Pgain = 64; - filterpars->Psequencesize=2; - filterpars->Pnumformants=2; - filterpars->Pvowelclearness=0; + filterpars->Psequencesize = 2; + filterpars->Pnumformants = 2; + filterpars->Pvowelclearness = 0; - filterpars->Pvowels[0].formants[0].freq=70; - filterpars->Pvowels[0].formants[0].amp=127; - filterpars->Pvowels[0].formants[0].q=64; - filterpars->Pvowels[0].formants[1].freq=80; - filterpars->Pvowels[0].formants[1].amp=122; - filterpars->Pvowels[0].formants[1].q=64; + filterpars->Pvowels[0].formants[0].freq = 70; + filterpars->Pvowels[0].formants[0].amp = 127; + filterpars->Pvowels[0].formants[0].q = 64; + filterpars->Pvowels[0].formants[1].freq = 80; + filterpars->Pvowels[0].formants[1].amp = 122; + filterpars->Pvowels[0].formants[1].q = 64; - filterpars->Pvowels[1].formants[0].freq=20; - filterpars->Pvowels[1].formants[0].amp=127; - filterpars->Pvowels[1].formants[0].q=64; - filterpars->Pvowels[1].formants[1].freq=100; - filterpars->Pvowels[1].formants[1].amp=121; - filterpars->Pvowels[1].formants[1].q=64; + filterpars->Pvowels[1].formants[0].freq = 20; + filterpars->Pvowels[1].formants[0].amp = 127; + filterpars->Pvowels[1].formants[0].q = 64; + filterpars->Pvowels[1].formants[1].freq = 100; + filterpars->Pvowels[1].formants[1].amp = 121; + filterpars->Pvowels[1].formants[1].q = 64; break; - }; + } // for (int i=0;i<5;i++){ // printf("freq=%d amp=%d q=%d\n",filterpars->Pvowels[0].formants[i].freq,filterpars->Pvowels[0].formants[i].amp,filterpars->Pvowels[0].formants[i].q); // }; - if (insertion==0) changepar(0,presets[npreset][0]/2);//lower the volume if this is system effect - Ppreset=npreset; + if(insertion == 0) + changepar(0, presets[npreset][0] / 2); //lower the volume if this is system effect + Ppreset = npreset; reinitfilter(); -}; +} -void DynamicFilter::changepar(const int &npar,const unsigned char &value) +void DynamicFilter::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -271,19 +280,19 @@ void DynamicFilter::changepar(const int &npar,const unsigned char &value) setpanning(value); break; case 2: - lfo.Pfreq=value; + lfo.Pfreq = value; lfo.updateparams(); break; case 3: - lfo.Prandomness=value; + lfo.Prandomness = value; lfo.updateparams(); break; case 4: - lfo.PLFOtype=value; + lfo.PLFOtype = value; lfo.updateparams(); break; case 5: - lfo.Pstereo=value; + lfo.Pstereo = value; lfo.updateparams(); break; case 6: @@ -293,52 +302,51 @@ void DynamicFilter::changepar(const int &npar,const unsigned char &value) setampsns(value); break; case 8: - Pampsnsinv=value; + Pampsnsinv = value; setampsns(Pampsns); break; case 9: - Pampsmooth=value; + Pampsmooth = value; setampsns(Pampsns); break; - }; -}; + } +} -unsigned char DynamicFilter::getpar(const int &npar)const +unsigned char DynamicFilter::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(lfo.Pfreq); + return lfo.Pfreq; break; case 3: - return(lfo.Prandomness); + return lfo.Prandomness; break; case 4: - return(lfo.PLFOtype); + return lfo.PLFOtype; break; case 5: - return(lfo.Pstereo); + return lfo.Pstereo; break; case 6: - return(Pdepth); + return Pdepth; break; case 7: - return(Pampsns); + return Pampsns; break; case 8: - return(Pampsnsinv); + return Pampsnsinv; break; case 9: - return(Pampsmooth); + return Pampsmooth; break; default: - return (0); - }; - -}; + return 0; + } +} diff --git a/plugins/zynaddsubfx/src/Effects/DynamicFilter.h b/plugins/zynaddsubfx/src/Effects/DynamicFilter.h index 9c547c332..2bb5fcd9b 100644 --- a/plugins/zynaddsubfx/src/Effects/DynamicFilter.h +++ b/plugins/zynaddsubfx/src/Effects/DynamicFilter.h @@ -30,42 +30,42 @@ /**DynamicFilter Effect*/ class DynamicFilter:public Effect { -public: - DynamicFilter(int insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~DynamicFilter(); - void out(REALTYPE *smpsl,REALTYPE *smpsr); + public: + DynamicFilter(int insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~DynamicFilter(); + void out(REALTYPE *smpsl, REALTYPE *smpsr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); // void setdryonly(); -private: - //Parametrii DynamicFilter - EffectLFO lfo;//lfo-ul DynamicFilter - unsigned char Pvolume; - unsigned char Ppanning; - unsigned char Pdepth;/** #include "EQ.h" -EQ::EQ(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) +EQ::EQ(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0) { - - for (int i=0;icleanup(); filter[i].r->cleanup(); - }; -}; + } +} /* * Effect output */ -void EQ::out(REALTYPE *smpsl,REALTYPE *smpsr) +void EQ::out(REALTYPE *smpsl, REALTYPE *smpsr) { int i; - for (i=0;ifilterout(efxoutl); filter[i].r->filterout(efxoutr); - }; -}; + } +} /* @@ -84,131 +83,138 @@ void EQ::out(REALTYPE *smpsl,REALTYPE *smpsr) */ void EQ::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; + this->Pvolume = Pvolume; - outvolume=pow(0.005,(1.0-Pvolume/127.0))*10.0; - if (insertion==0) { - volume=1.0; - } else { - volume=outvolume; - }; - -}; + outvolume = pow(0.005, (1.0 - Pvolume / 127.0)) * 10.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; + ; +} void EQ::setpreset(unsigned char npreset) { - const int PRESET_SIZE=1; - const int NUM_PRESETS=2; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 1; + const int NUM_PRESETS = 2; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //EQ 1 {67}, //EQ 2 {67} }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + Ppreset = npreset; +} -void EQ::changepar(const int &npar,const unsigned char &value) +void EQ::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; - }; - if (npar<10) return; + } + if(npar < 10) + return; - int nb=(npar-10)/5;//number of the band (filter) - if (nb>=MAX_EQ_BANDS) return; - int bp=npar%5;//band paramenter + int nb = (npar - 10) / 5; //number of the band (filter) + if(nb >= MAX_EQ_BANDS) + return; + int bp = npar % 5; //band paramenter REALTYPE tmp; - switch (bp) { + switch(bp) { case 0: - filter[nb].Ptype=value; - if (value>9) filter[nb].Ptype=0;//has to be changed if more filters will be added - if (filter[nb].Ptype!=0) { - filter[nb].l->settype(value-1); - filter[nb].r->settype(value-1); - }; + filter[nb].Ptype = value; + if(value > 9) + filter[nb].Ptype = 0; //has to be changed if more filters will be added + if(filter[nb].Ptype != 0) { + filter[nb].l->settype(value - 1); + filter[nb].r->settype(value - 1); + } break; case 1: - filter[nb].Pfreq=value; - tmp=600.0*pow(30.0,(value-64.0)/64.0); + filter[nb].Pfreq = value; + tmp = 600.0 * pow(30.0, (value - 64.0) / 64.0); filter[nb].l->setfreq(tmp); filter[nb].r->setfreq(tmp); break; case 2: - filter[nb].Pgain=value; - tmp=30.0*(value-64.0)/64.0; + filter[nb].Pgain = value; + tmp = 30.0 * (value - 64.0) / 64.0; filter[nb].l->setgain(tmp); filter[nb].r->setgain(tmp); break; case 3: - filter[nb].Pq=value; - tmp=pow(30.0,(value-64.0)/64.0); + filter[nb].Pq = value; + tmp = pow(30.0, (value - 64.0) / 64.0); filter[nb].l->setq(tmp); filter[nb].r->setq(tmp); break; case 4: - filter[nb].Pstages=value; - if (value>=MAX_FILTER_STAGES) filter[nb].Pstages=MAX_FILTER_STAGES-1; + filter[nb].Pstages = value; + if(value >= MAX_FILTER_STAGES) + filter[nb].Pstages = MAX_FILTER_STAGES - 1; filter[nb].l->setstages(value); filter[nb].r->setstages(value); break; - }; -}; + } +} -unsigned char EQ::getpar(const int &npar)const +unsigned char EQ::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; - }; + } - if (npar<10) return(0); + if(npar < 10) + return 0; - int nb=(npar-10)/5;//number of the band (filter) - if (nb>=MAX_EQ_BANDS) return(0); - int bp=npar%5;//band paramenter - switch (bp) { + int nb = (npar - 10) / 5; //number of the band (filter) + if(nb >= MAX_EQ_BANDS) + return 0; + int bp = npar % 5; //band paramenter + switch(bp) { case 0: - return(filter[nb].Ptype); + return filter[nb].Ptype; break; case 1: - return(filter[nb].Pfreq); + return filter[nb].Pfreq; break; case 2: - return(filter[nb].Pgain); + return filter[nb].Pgain; break; case 3: - return(filter[nb].Pq); + return filter[nb].Pq; break; case 4: - return(filter[nb].Pstages); + return filter[nb].Pstages; break; - }; + } - return(0);//in case of bogus parameter number -}; + return 0; //in case of bogus parameter number +} REALTYPE EQ::getfreqresponse(REALTYPE freq) { - REALTYPE resp=1.0; - - for (int i=0;iH(freq); - }; - return(rap2dB(resp*outvolume)); -}; + REALTYPE resp = 1.0; + for(int i = 0; i < MAX_EQ_BANDS; i++) { + if(filter[i].Ptype == 0) + continue; + resp *= filter[i].l->H(freq); + } + return rap2dB(resp * outvolume); +} diff --git a/plugins/zynaddsubfx/src/Effects/EQ.h b/plugins/zynaddsubfx/src/Effects/EQ.h index 810dd6ee6..6f4130cd1 100644 --- a/plugins/zynaddsubfx/src/Effects/EQ.h +++ b/plugins/zynaddsubfx/src/Effects/EQ.h @@ -30,31 +30,29 @@ /**EQ Effect*/ class EQ:public Effect { -public: - EQ(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~EQ(); - void out(REALTYPE *smpsl,REALTYPE *smpr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); - REALTYPE getfreqresponse(REALTYPE freq); -private: - //Parameters - unsigned char Pvolume;/** #include "Echo.h" -Echo::Echo(const int & insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) - : Effect(insertion_,efxoutl_,efxoutr_,NULL,0), - Pvolume(50),Ppanning(64),//Pdelay(60), - Plrdelay(100),Plrcross(100),Pfb(40),Phidamp(60), - lrdelay(0),delaySample(1),old(0.0) +Echo::Echo(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), + Pvolume(50), Ppanning(64), //Pdelay(60), + Plrdelay(100), Plrcross(100), Pfb(40), Phidamp(60), + lrdelay(0), delaySample(1), old(0.0) { setpreset(Ppreset); } @@ -42,7 +44,7 @@ void Echo::cleanup() { delaySample.l().clear(); delaySample.r().clear(); - old=Stereo(0.0); + old = Stereo(0.0); } @@ -52,85 +54,91 @@ void Echo::cleanup() void Echo::initdelays() { /**\todo make this adjust insted of destroy old delays*/ - kl=0; - kr=0; - dl=(int)(1+delay.getiVal()*SAMPLE_RATE-lrdelay); - if (dl<1) dl=1; - dr=(int)(1+delay.getiVal()*SAMPLE_RATE+lrdelay); - if (dr<1) dr=1; + kl = 0; + kr = 0; + dl = (int)(1 + delay.getiVal() * SAMPLE_RATE - lrdelay); + if(dl < 1) + dl = 1; + dr = (int)(1 + delay.getiVal() * SAMPLE_RATE + lrdelay); + if(dr < 1) + dr = 1; - delaySample.l()=AuSample(dl); - delaySample.r()=AuSample(dr); + delaySample.l() = AuSample(dl); + delaySample.r() = AuSample(dr); - old=Stereo(0.0); + old = Stereo(0.0); } /* * Effect output */ -void Echo::out(REALTYPE *const smpsl,REALTYPE *const smpsr) +void Echo::out(REALTYPE *const smpsl, REALTYPE *const smpsr) { - Stereo input(AuSample(SOUND_BUFFER_SIZE,smpsl),AuSample(SOUND_BUFFER_SIZE,smpsr)); + Stereo input(AuSample(SOUND_BUFFER_SIZE, smpsl), AuSample( + SOUND_BUFFER_SIZE, + smpsr)); out(input); } void Echo::out(const Stereo &input) { //void Echo::out(const Stereo & input){ //ideal - REALTYPE l,r,ldl,rdl;/**\todo move l+r->? ldl+rdl->?*/ + REALTYPE l, r, ldl, rdl; /**\todo move l+r->? ldl+rdl->?*/ - for (int i=0;i=dl) kl=0; - if (++kr>=dr) kr=0; - }; + delaySample.l()[kl] = ldl = ldl * hidamp + old.l() * (1.0 - hidamp); + delaySample.r()[kr] = rdl = rdl * hidamp + old.r() * (1.0 - hidamp); + old.l() = ldl; + old.r() = rdl; + if(++kl >= dl) + kl = 0; + if(++kr >= dr) + kr = 0; + } } /* * Parameter control */ -void Echo::setvolume(const unsigned char & Pvolume) +void Echo::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - - if (insertion==0) { - outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; - volume=1.0; - } else { - volume=outvolume=Pvolume/127.0; - }; - if (Pvolume==0) cleanup(); + this->Pvolume = Pvolume; + if(insertion == 0) { + outvolume = pow(0.01, (1.0 - Pvolume / 127.0)) * 4.0; + volume = 1.0; + } + else + volume = outvolume = Pvolume / 127.0; + ; + if(Pvolume == 0) + cleanup(); } -void Echo::setpanning(const unsigned char & Ppanning) +void Echo::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=(Ppanning+0.5)/127.0; + this->Ppanning = Ppanning; + panning = (Ppanning + 0.5) / 127.0; } -void Echo::setdelay(const unsigned char & Pdelay) +void Echo::setdelay(const unsigned char &Pdelay) { delay.setmVal(Pdelay); //this->Pdelay=Pdelay; @@ -138,71 +146,76 @@ void Echo::setdelay(const unsigned char & Pdelay) initdelays(); } -void Echo::setlrdelay(const unsigned char & Plrdelay) +void Echo::setlrdelay(const unsigned char &Plrdelay) { REALTYPE tmp; - this->Plrdelay=Plrdelay; - tmp=(pow(2,fabs(Plrdelay-64.0)/64.0*9)-1.0)/1000.0*SAMPLE_RATE; - if (Plrdelay<64.0) tmp=-tmp; - lrdelay=(int) tmp; + this->Plrdelay = Plrdelay; + tmp = + (pow(2, fabs(Plrdelay - 64.0) / 64.0 * 9) - 1.0) / 1000.0 * SAMPLE_RATE; + if(Plrdelay < 64.0) + tmp = -tmp; + lrdelay = (int) tmp; initdelays(); } -void Echo::setlrcross(const unsigned char & Plrcross) +void Echo::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0*1.0; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0 * 1.0; } -void Echo::setfb(const unsigned char & Pfb) +void Echo::setfb(const unsigned char &Pfb) { - this->Pfb=Pfb; - fb=Pfb/128.0; + this->Pfb = Pfb; + fb = Pfb / 128.0; } -void Echo::sethidamp(const unsigned char & Phidamp) +void Echo::sethidamp(const unsigned char &Phidamp) { - this->Phidamp=Phidamp; - hidamp=1.0-Phidamp/127.0; + this->Phidamp = Phidamp; + hidamp = 1.0 - Phidamp / 127.0; } void Echo::setpreset(unsigned char npreset) { /**\todo see if the preset array can be replaced with a struct or a class*/ - const int PRESET_SIZE=7; - const int NUM_PRESETS=9; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 7; + const int NUM_PRESETS = 9; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //Echo 1 - {67,64,35,64,30,59,0}, + {67, 64, 35, 64, 30, 59, 0 }, //Echo 2 - {67,64,21,64,30,59,0}, + {67, 64, 21, 64, 30, 59, 0 }, //Echo 3 - {67,75,60,64,30,59,10}, + {67, 75, 60, 64, 30, 59, 10 }, //Simple Echo - {67,60,44,64,30,0,0}, + {67, 60, 44, 64, 30, 0, 0 }, //Canyon - {67,60,102,50,30,82,48}, + {67, 60, 102, 50, 30, 82, 48 }, //Panning Echo 1 - {67,64,44,17,0,82,24}, + {67, 64, 44, 17, 0, 82, 24 }, //Panning Echo 2 - {81,60,46,118,100,68,18}, + {81, 60, 46, 118, 100, 68, 18 }, //Panning Echo 3 - {81,60,26,100,127,67,36}, + {81, 60, 26, 100, 127, 67, 36 }, //Feedback Echo - {62,64,28,64,100,90,55} + {62, 64, 28, 64, 100, 90, 55 } }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion) + setvolume(presets[npreset][0] / 2); //lower the volume if this is insertion effect + Ppreset = npreset; } -void Echo::changepar(const int & npar,const unsigned char & value) +void Echo::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -224,34 +237,34 @@ void Echo::changepar(const int & npar,const unsigned char & value) case 6: sethidamp(value); break; - }; + } } -unsigned char Echo::getpar(const int & npar)const +unsigned char Echo::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(delay.getmVal()); + return delay.getmVal(); break; case 3: - return(Plrdelay); + return Plrdelay; break; case 4: - return(Plrcross); + return Plrcross; break; case 5: - return(Pfb); + return Pfb; break; case 6: - return(Phidamp); + return Phidamp; break; - }; - return(0);// in case of bogus parameter number + } + return 0; // in case of bogus parameter number } diff --git a/plugins/zynaddsubfx/src/Effects/Echo.h b/plugins/zynaddsubfx/src/Effects/Echo.h index 5ed429609..4dbe40925 100644 --- a/plugins/zynaddsubfx/src/Effects/Echo.h +++ b/plugins/zynaddsubfx/src/Effects/Echo.h @@ -32,105 +32,107 @@ /**Echo Effect*/ class Echo:public Effect { -public: + public: - /** - * The Constructor For Echo - * @param insertion_ integer to determine if Echo is an insertion effect - * or not - * @param efxoutl_ Effect out Left Channel - * @param efxoutr_ Effect out Right Channel - * @return An initialized Echo Object - */ - Echo(const int & insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_); + /** + * The Constructor For Echo + * @param insertion_ integer to determine if Echo is an insertion effect + * or not + * @param efxoutl_ Effect out Left Channel + * @param efxoutr_ Effect out Right Channel + * @return An initialized Echo Object + */ + Echo(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_); - /** - * The destructor - */ - ~Echo(); + /** + * The destructor + */ + ~Echo(); - /** - * Outputs the echo to efxoutl and efxoutr - * @param smpsl Sample from Left channel - * @param smpsr Sample from Right channel - * \todo try to figure out if smpsl should be const *const - * or not (It should be) - */ - void out(REALTYPE *const smpsl,REALTYPE *const smpr); - void out(const Stereo &input); + /** + * Outputs the echo to efxoutl and efxoutr + * @param smpsl Sample from Left channel + * @param smpsr Sample from Right channel + * \todo try to figure out if smpsl should be const *const + * or not (It should be) + */ + void out(REALTYPE *const smpsl, REALTYPE *const smpr); + void out(const Stereo &input); - /** - * Sets the state of Echo to the specified preset - * @param npreset number of chosen preset - */ - void setpreset(unsigned char npreset); + /** + * Sets the state of Echo to the specified preset + * @param npreset number of chosen preset + */ + void setpreset(unsigned char npreset); - /** - * Sets the value of the chosen variable - * - * The possible parameters are: - * -# Volume - * -# Panning - * -# Delay - * -# L/R Delay - * -# L/R Crossover - * -# Feedback - * -# Dampening - * @param npar number of chosen parameter - * @param value the new value - */ - void changepar(const int & npar,const unsigned char & value); + /** + * Sets the value of the chosen variable + * + * The possible parameters are: + * -# Volume + * -# Panning + * -# Delay + * -# L/R Delay + * -# L/R Crossover + * -# Feedback + * -# Dampening + * @param npar number of chosen parameter + * @param value the new value + */ + void changepar(const int &npar, const unsigned char &value); - /** - * Gets the specified parameter - * - * The possible parameters are - * -# Volume - * -# Panning - * -# Delay - * -# L/R Delay - * -# L/R Crossover - * -# Feedback - * -# Dampening - * @param npar number of chosen parameter - * @return value of parameter - */ - unsigned char getpar(const int & npar)const; + /** + * Gets the specified parameter + * + * The possible parameters are + * -# Volume + * -# Panning + * -# Delay + * -# L/R Delay + * -# L/R Crossover + * -# Feedback + * -# Dampening + * @param npar number of chosen parameter + * @return value of parameter + */ + unsigned char getpar(const int &npar) const; - int getnumparams(); + int getnumparams(); - /**Zeros out the state of the Echo*/ - void cleanup(); + /**Zeros out the state of the Echo*/ + void cleanup(); - /**\todo This function needs to be implemented or the prototype should be removed*/ - void setdryonly(); -private: - //Parameters - char Pvolume;/**<#1 Volume or Dry/Wetness*/ - char Ppanning;/**<#2 Panning*/ - DelayCtl delay;/**<#3 Delay of the Echo*/ - char Plrdelay;/**<#4 L/R delay difference*/ - char Plrcross;/**<#5 L/R Mixing*/ - char Pfb;/**<#6Feedback*/ - char Phidamp;/**<#7Dampening of the Echo*/ + /**\todo This function needs to be implemented or the prototype should be removed*/ + void setdryonly(); + private: + //Parameters + char Pvolume; /**<#1 Volume or Dry/Wetness*/ + char Ppanning; /**<#2 Panning*/ + DelayCtl delay; /**<#3 Delay of the Echo*/ + char Plrdelay; /**<#4 L/R delay difference*/ + char Plrcross; /**<#5 L/R Mixing*/ + char Pfb; /**<#6Feedback*/ + char Phidamp; /**<#7Dampening of the Echo*/ - void setvolume(const unsigned char & Pvolume); - void setpanning(const unsigned char & Ppanning); - void setdelay(const unsigned char & Pdelay); - void setlrdelay(const unsigned char & Plrdelay); - void setlrcross(const unsigned char & Plrcross); - void setfb(const unsigned char & Pfb); - void sethidamp(const unsigned char & Phidamp); + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdelay(const unsigned char &Pdelay); + void setlrdelay(const unsigned char &Plrdelay); + void setlrcross(const unsigned char &Plrcross); + void setfb(const unsigned char &Pfb); + void sethidamp(const unsigned char &Phidamp); - //Real Parameters - REALTYPE panning,lrcross,fb,hidamp; //needs better names - int dl,dr,lrdelay; //needs better names + //Real Parameters + REALTYPE panning, lrcross, fb, hidamp; //needs better names + int dl, dr, lrdelay; //needs better names - void initdelays(); - Stereo delaySample; - Stereo old; + void initdelays(); + Stereo delaySample; + Stereo old; - int kl,kr; + int kl, kr; }; #endif diff --git a/plugins/zynaddsubfx/src/Effects/Effect.cpp b/plugins/zynaddsubfx/src/Effects/Effect.cpp index b0b4dac30..0a17ebdc4 100644 --- a/plugins/zynaddsubfx/src/Effects/Effect.cpp +++ b/plugins/zynaddsubfx/src/Effects/Effect.cpp @@ -23,8 +23,9 @@ #include "Effect.h" -Effect::Effect(bool insertion_,REALTYPE *const efxoutl_, - REALTYPE *const efxoutr_,FilterParams *filterpars_, - const unsigned char & Ppreset_) - :Ppreset(Ppreset_),efxoutl(efxoutl_),efxoutr(efxoutr_), - filterpars(filterpars_),insertion(insertion_) {} +Effect::Effect(bool insertion_, REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_, FilterParams *filterpars_, + const unsigned char &Ppreset_) + :Ppreset(Ppreset_), efxoutl(efxoutl_), efxoutr(efxoutr_), + filterpars(filterpars_), insertion(insertion_) {} + diff --git a/plugins/zynaddsubfx/src/Effects/Effect.h b/plugins/zynaddsubfx/src/Effects/Effect.h index 0da3d8317..7f769ead8 100644 --- a/plugins/zynaddsubfx/src/Effects/Effect.h +++ b/plugins/zynaddsubfx/src/Effects/Effect.h @@ -31,71 +31,71 @@ /**this class is inherited by the all effects(Reverb, Echo, ..)*/ class Effect { -public: - /** - * Effect Constructor - * @param insertion_ 1 when it is an insertion Effect and 0 when it - * is not an insertion Effect - * @param efxoutl_ Effect output buffer Left channel - * @param efxoutr_ Effect output buffer Right channel - * @param filterpars_ pointer to FilterParams array - * @param Ppreset_ chosen preset - * @return Initialized Effect object*/ - Effect(bool insertion_,REALTYPE *const efxoutl_, - REALTYPE *const efxoutr_,FilterParams *filterpars_, - const unsigned char & Ppreset_); - /**Deconstructor - * - * Deconstructs the Effect and releases any resouces that it has - * allocated for itself*/ - virtual ~Effect() {}; - /** - * Choose a preset - * @param npreset number of chosen preset*/ - virtual void setpreset(unsigned char npreset)=0; - /**Change parameter npar to value - * @param npar chosen parameter - * @param value chosen new value*/ - virtual void changepar(const int &npar,const unsigned char &value)=0; - /**Get the value of parameter npar - * @param npar chosen parameter - * @return the value of the parameter in an unsigned char or 0 if it - * does not exist*/ - virtual unsigned char getpar(const int &npar)const=0; - /**Output result of effect based on the given buffers - * - * This method should result in the effect generating its results - * and placing them into the efxoutl and efxoutr buffers. - * Every Effect should overide this method. - * - * @param smpsl Input buffer for the Left channel - * @param smpsr Input buffer for the Right channel - */ - virtual void out(REALTYPE *const smpsl,REALTYPE *const smpsr)=0; - /**Reset the state of the effect*/ - virtual void cleanup() {}; - /**This is only used for EQ (for user interface)*/ - virtual REALTYPE getfreqresponse(REALTYPE freq) { - return (0); - }; + public: + /** + * Effect Constructor + * @param insertion_ 1 when it is an insertion Effect and 0 when it + * is not an insertion Effect + * @param efxoutl_ Effect output buffer Left channel + * @param efxoutr_ Effect output buffer Right channel + * @param filterpars_ pointer to FilterParams array + * @param Ppreset_ chosen preset + * @return Initialized Effect object*/ + Effect(bool insertion_, REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_, FilterParams *filterpars_, + const unsigned char &Ppreset_); + /**Deconstructor + * + * Deconstructs the Effect and releases any resouces that it has + * allocated for itself*/ + virtual ~Effect() {} + /** + * Choose a preset + * @param npreset number of chosen preset*/ + virtual void setpreset(unsigned char npreset) = 0; + /**Change parameter npar to value + * @param npar chosen parameter + * @param value chosen new value*/ + virtual void changepar(const int &npar, const unsigned char &value) = 0; + /**Get the value of parameter npar + * @param npar chosen parameter + * @return the value of the parameter in an unsigned char or 0 if it + * does not exist*/ + virtual unsigned char getpar(const int &npar) const = 0; + /**Output result of effect based on the given buffers + * + * This method should result in the effect generating its results + * and placing them into the efxoutl and efxoutr buffers. + * Every Effect should overide this method. + * + * @param smpsl Input buffer for the Left channel + * @param smpsr Input buffer for the Right channel + */ + virtual void out(REALTYPE *const smpsl, REALTYPE *const smpsr) = 0; + /**Reset the state of the effect*/ + virtual void cleanup() {} + /**This is only used for EQ (for user interface)*/ + virtual REALTYPE getfreqresponse(REALTYPE freq) { + return 0; + } - unsigned char Ppreset;/**0.49999999) incx=0.499999999; //Limit the Frequency + REALTYPE lfofreq = (pow(2, Pfreq / 127.0 * 10.0) - 1.0) * 0.03; + incx = fabs(lfofreq) * (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; + if(incx > 0.49999999) + incx = 0.499999999; //Limit the Frequency - lfornd=Prandomness/127.0; - if (lfornd<0.0) lfornd=0.0; - else if (lfornd>1.0) lfornd=1.0; + lfornd = Prandomness / 127.0; + if(lfornd < 0.0) + lfornd = 0.0; + else + if(lfornd > 1.0) + lfornd = 1.0; - if (PLFOtype>1) PLFOtype=1;//this has to be updated if more lfo's are added - lfotype=PLFOtype; + if(PLFOtype > 1) + PLFOtype = 1; //this has to be updated if more lfo's are added + lfotype = PLFOtype; - xr=fmod(xl+(Pstereo-64.0)/127.0+1.0,1.0); -}; + xr = fmod(xl + (Pstereo - 64.0) / 127.0 + 1.0, 1.0); +} /* @@ -74,44 +78,50 @@ void EffectLFO::updateparams() REALTYPE EffectLFO::getlfoshape(REALTYPE x) { REALTYPE out; - switch (lfotype) { + switch(lfotype) { case 1: //EffectLFO_TRIANGLE - if ((x>0.0)&&(x<0.25)) out=4.0*x; - else if ((x>0.25)&&(x<0.75)) out=2-4*x; - else out=4.0*x-4.0; + if((x > 0.0) && (x < 0.25)) + out = 4.0 * x; + else + if((x > 0.25) && (x < 0.75)) + out = 2 - 4 * x; + else + out = 4.0 * x - 4.0; break; - /**\todo more to be added here; also ::updateparams() need to be updated (to allow more lfotypes)*/ + /**\todo more to be added here; also ::updateparams() need to be updated (to allow more lfotypes)*/ default: - out=cos(x*2*PI);//EffectLFO_SINE - }; - return(out); -}; + out = cos(x * 2 * PI); //EffectLFO_SINE + } + return out; +} /* * LFO output */ -void EffectLFO::effectlfoout(REALTYPE *outl,REALTYPE *outr) +void EffectLFO::effectlfoout(REALTYPE *outl, REALTYPE *outr) { REALTYPE out; - out=getlfoshape(xl); - if ((lfotype==0)||(lfotype==1)) out*=(ampl1+xl*(ampl2-ampl1)); - xl+=incx; - if (xl>1.0) { - xl-=1.0; - ampl1=ampl2; - ampl2=(1.0-lfornd)+lfornd*RND; - }; - *outl=(out+1.0)*0.5; + out = getlfoshape(xl); + if((lfotype == 0) || (lfotype == 1)) + out *= (ampl1 + xl * (ampl2 - ampl1)); + xl += incx; + if(xl > 1.0) { + xl -= 1.0; + ampl1 = ampl2; + ampl2 = (1.0 - lfornd) + lfornd * RND; + } + *outl = (out + 1.0) * 0.5; - out=getlfoshape(xr); - if ((lfotype==0)||(lfotype==1)) out*=(ampr1+xr*(ampr2-ampr1)); - xr+=incx; - if (xr>1.0) { - xr-=1.0; - ampr1=ampr2; - ampr2=(1.0-lfornd)+lfornd*RND; - }; - *outr=(out+1.0)*0.5; -}; + out = getlfoshape(xr); + if((lfotype == 0) || (lfotype == 1)) + out *= (ampr1 + xr * (ampr2 - ampr1)); + xr += incx; + if(xr > 1.0) { + xr -= 1.0; + ampr1 = ampr2; + ampr2 = (1.0 - lfornd) + lfornd * RND; + } + *outr = (out + 1.0) * 0.5; +} diff --git a/plugins/zynaddsubfx/src/Effects/EffectLFO.h b/plugins/zynaddsubfx/src/Effects/EffectLFO.h index 54a595110..cc14d6652 100644 --- a/plugins/zynaddsubfx/src/Effects/EffectLFO.h +++ b/plugins/zynaddsubfx/src/Effects/EffectLFO.h @@ -28,24 +28,24 @@ * \todo see if this should inherit LFO*/ class EffectLFO { -public: - EffectLFO(); - ~EffectLFO(); - void effectlfoout(REALTYPE *outl,REALTYPE *outr); - void updateparams(); - unsigned char Pfreq; - unsigned char Prandomness; - unsigned char PLFOtype; - unsigned char Pstereo;//"64"=0 -private: - REALTYPE getlfoshape(REALTYPE x); + public: + EffectLFO(); + ~EffectLFO(); + void effectlfoout(REALTYPE *outl, REALTYPE *outr); + void updateparams(); + unsigned char Pfreq; + unsigned char Prandomness; + unsigned char PLFOtype; + unsigned char Pstereo; //"64"=0 + private: + REALTYPE getlfoshape(REALTYPE x); - REALTYPE xl,xr; - REALTYPE incx; - REALTYPE ampl1,ampl2,ampr1,ampr2;//necessary for "randomness" - REALTYPE lfointensity; - REALTYPE lfornd; - char lfotype; /**\todo GET RID OF CHAR (replace with short or enum)*/ + REALTYPE xl, xr; + REALTYPE incx; + REALTYPE ampl1, ampl2, ampr1, ampr2; //necessary for "randomness" + REALTYPE lfointensity; + REALTYPE lfornd; + char lfotype; /**\todo GET RID OF CHAR (replace with short or enum)*/ }; diff --git a/plugins/zynaddsubfx/src/Effects/EffectMgr.cpp b/plugins/zynaddsubfx/src/Effects/EffectMgr.cpp index 081101184..cbb44c02f 100644 --- a/plugins/zynaddsubfx/src/Effects/EffectMgr.cpp +++ b/plugins/zynaddsubfx/src/Effects/EffectMgr.cpp @@ -22,11 +22,11 @@ #include "EffectMgr.h" -EffectMgr::EffectMgr(int insertion_,pthread_mutex_t *mutex_) - :insertion(insertion_), - efxoutl(new REALTYPE[SOUND_BUFFER_SIZE]), - efxoutr(new REALTYPE[SOUND_BUFFER_SIZE]), - filterpars(NULL),nefx(0),efx(NULL),mutex(mutex_),dryonly(false) +EffectMgr::EffectMgr(int insertion_, pthread_mutex_t *mutex_) + :insertion(insertion_), + efxoutl(new REALTYPE[SOUND_BUFFER_SIZE]), + efxoutr(new REALTYPE[SOUND_BUFFER_SIZE]), + filterpars(NULL), nefx(0), efx(NULL), mutex(mutex_), dryonly(false) { setpresettype("Peffect"); /**\todo Figure out what this is doing * , as it might be another leaky abstraction.*/ @@ -36,10 +36,10 @@ EffectMgr::EffectMgr(int insertion_,pthread_mutex_t *mutex_) // mutex=mutex_; // efxoutl=new REALTYPE[SOUND_BUFFER_SIZE]; // efxoutr=new REALTYPE[SOUND_BUFFER_SIZE]; - for (int i=0;ifilterpars; + if(efx != NULL) + filterpars = efx->filterpars; } /* @@ -112,7 +116,7 @@ void EffectMgr::changeeffect(int nefx_) */ int EffectMgr::geteffect() { - return (nefx); + return nefx; } /* @@ -120,7 +124,8 @@ int EffectMgr::geteffect() */ void EffectMgr::cleanup() { - if (efx!=NULL) efx->cleanup(); + if(efx != NULL) + efx->cleanup(); } @@ -130,8 +135,10 @@ void EffectMgr::cleanup() unsigned char EffectMgr::getpreset() { - if (efx!=NULL) return(efx->Ppreset); - else return(0); + if(efx != NULL) + return efx->Ppreset; + else + return 0; } /* @@ -139,7 +146,8 @@ unsigned char EffectMgr::getpreset() */ void EffectMgr::changepreset_nolock(unsigned char npreset) { - if (efx!=NULL) efx->setpreset(npreset); + if(efx != NULL) + efx->setpreset(npreset); } /* @@ -156,19 +164,20 @@ void EffectMgr::changepreset(unsigned char npreset) /* * Change a parameter of the current effect */ -void EffectMgr::seteffectpar_nolock(int npar,unsigned char value) +void EffectMgr::seteffectpar_nolock(int npar, unsigned char value) { - if (efx==NULL) return; - efx->changepar(npar,value); + if(efx == NULL) + return; + efx->changepar(npar, value); } /* * Change a parameter of the current effect (with thread locking) */ -void EffectMgr::seteffectpar(int npar,unsigned char value) +void EffectMgr::seteffectpar(int npar, unsigned char value) { pthread_mutex_lock(mutex); - seteffectpar_nolock(npar,value); + seteffectpar_nolock(npar, value); pthread_mutex_unlock(mutex); } @@ -177,80 +186,85 @@ void EffectMgr::seteffectpar(int npar,unsigned char value) */ unsigned char EffectMgr::geteffectpar(int npar) { - if (efx==NULL) return(0); - return(efx->getpar(npar)); + if(efx == NULL) + return 0; + return efx->getpar(npar); } /* * Apply the effect */ -void EffectMgr::out(REALTYPE *smpsl,REALTYPE *smpsr) +void EffectMgr::out(REALTYPE *smpsl, REALTYPE *smpsr) { int i; - if (efx==NULL) { - if (insertion==0) - for (i=0;iout(smpsl,smpsr); + } + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + smpsl[i] += denormalkillbuf[i]; + smpsr[i] += denormalkillbuf[i]; + efxoutl[i] = 0.0; + efxoutr[i] = 0.0; + } + efx->out(smpsl, smpsr); - REALTYPE volume=efx->volume; + REALTYPE volume = efx->volume; - if (nefx==7) {//this is need only for the EQ effect + if(nefx == 7) { //this is need only for the EQ effect /**\todo figure out why*/ - for (i=0;ioutvolume); + if(efx == NULL) + return 1.0; + else + return efx->outvolume; } @@ -268,65 +284,72 @@ REALTYPE EffectMgr::sysefxgetvolume() */ REALTYPE EffectMgr::getEQfreqresponse(REALTYPE freq) { - if (nefx==7) return(efx->getfreqresponse(freq)); - else return(0.0); + if(nefx == 7) + return efx->getfreqresponse(freq); + else + return 0.0; } void EffectMgr::setdryonly(bool value) { - dryonly=value; + dryonly = value; } void EffectMgr::add2XML(XMLwrapper *xml) { - xml->addpar("type",geteffect()); + xml->addpar("type", geteffect()); - if ((efx==NULL)||(geteffect()==0)) return; - xml->addpar("preset",efx->Ppreset); + if((efx == NULL) || (geteffect() == 0)) + return; + xml->addpar("preset", efx->Ppreset); xml->beginbranch("EFFECT_PARAMETERS"); - for (int n=0;n<128;n++) { /**\todo evaluate who should oversee saving - * and loading of parameters*/ - int par=geteffectpar(n); - if (par==0) continue; - xml->beginbranch("par_no",n); - xml->addpar("par",par); + for(int n = 0; n < 128; n++) { + /**\todo evaluate who should oversee saving + * and loading of parameters*/ + int par = geteffectpar(n); + if(par == 0) + continue; + xml->beginbranch("par_no", n); + xml->addpar("par", par); xml->endbranch(); - }; - if (filterpars!=NULL) { + } + if(filterpars != NULL) { xml->beginbranch("FILTER"); filterpars->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); } void EffectMgr::getfromXML(XMLwrapper *xml) { - changeeffect(xml->getpar127("type",geteffect())); + changeeffect(xml->getpar127("type", geteffect())); - if ((efx==NULL)||(geteffect()==0)) return; + if((efx == NULL) || (geteffect() == 0)) + return; - efx->Ppreset=xml->getpar127("preset",efx->Ppreset); + efx->Ppreset = xml->getpar127("preset", efx->Ppreset); - if (xml->enterbranch("EFFECT_PARAMETERS")) { - for (int n=0;n<128;n++) { - seteffectpar_nolock(n,0);//erase effect parameter - if (xml->enterbranch("par_no",n)==0) continue; + if(xml->enterbranch("EFFECT_PARAMETERS")) { + for(int n = 0; n < 128; n++) { + seteffectpar_nolock(n, 0); //erase effect parameter + if(xml->enterbranch("par_no", n) == 0) + continue; - int par=geteffectpar(n); - seteffectpar_nolock(n,xml->getpar127("par",par)); + int par = geteffectpar(n); + seteffectpar_nolock(n, xml->getpar127("par", par)); xml->exitbranch(); - }; - if (filterpars!=NULL) { - if (xml->enterbranch("FILTER")) { + } + if(filterpars != NULL) { + if(xml->enterbranch("FILTER")) { filterpars->getfromXML(xml); xml->exitbranch(); - }; - }; + } + } xml->exitbranch(); - }; + } cleanup(); } diff --git a/plugins/zynaddsubfx/src/Effects/EffectMgr.h b/plugins/zynaddsubfx/src/Effects/EffectMgr.h index dd5d52ce6..2a1257707 100644 --- a/plugins/zynaddsubfx/src/Effects/EffectMgr.h +++ b/plugins/zynaddsubfx/src/Effects/EffectMgr.h @@ -41,62 +41,62 @@ /**Effect manager, an interface betwen the program and effects*/ class EffectMgr:public Presets { -public: - EffectMgr(int insertion_,pthread_mutex_t *mutex_); - ~EffectMgr(); + public: + EffectMgr(int insertion_, pthread_mutex_t *mutex_); + ~EffectMgr(); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - void out(REALTYPE *smpsl,REALTYPE *smpsr); + void out(REALTYPE *smpsl, REALTYPE *smpsr); - void setdryonly(bool value); + void setdryonly(bool value); - /**get the output(to speakers) volume of the systemeffect*/ - REALTYPE sysefxgetvolume(); + /**get the output(to speakers) volume of the systemeffect*/ + REALTYPE sysefxgetvolume(); - void cleanup();/** -#include "Phaser.h" -#define PHASER_LFO_SHAPE 2 - -Phaser::Phaser(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0),old(1),oldgain(0.0) -{ - setpreset(Ppreset); - cleanup(); -}; - -Phaser::~Phaser() -{ -}; - - -/* - * Effect output - */ -void Phaser::out(REALTYPE *smpsl,REALTYPE *smpsr) -{ - int i,j; - REALTYPE lfol,lfor,lgain,rgain,tmp; - - lfo.effectlfoout(&lfol,&lfor); - lgain=lfol; - rgain=lfor; - lgain=(exp(lgain*PHASER_LFO_SHAPE)-1)/(exp(PHASER_LFO_SHAPE)-1.0); - rgain=(exp(rgain*PHASER_LFO_SHAPE)-1)/(exp(PHASER_LFO_SHAPE)-1.0); - - - lgain=1.0-phase*(1.0-depth)-(1.0-phase)*lgain*depth; - rgain=1.0-phase*(1.0-depth)-(1.0-phase)*rgain*depth; - - if (lgain>1.0) lgain=1.0; - else if (lgain<0.0) lgain=0.0; - if (rgain>1.0) rgain=1.0; - else if (rgain<0.0) rgain=0.0; - - for (i=0;i(lgain,rgain); - - if (Poutsub!=0) - for (i=0;i(0.0); - old.l().clear(); - old.r().clear(); -}; - -/* - * Parameter control - */ -void Phaser::setdepth(const unsigned char &Pdepth) -{ - this->Pdepth=Pdepth; - depth=(Pdepth/127.0); -}; - - -void Phaser::setfb(const unsigned char &Pfb) -{ - this->Pfb=Pfb; - fb=(Pfb-64.0)/64.1; -}; - -void Phaser::setvolume(const unsigned char &Pvolume) -{ - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; - -void Phaser::setpanning(const unsigned char &Ppanning) -{ - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; - -void Phaser::setlrcross(const unsigned char &Plrcross) -{ - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0; -}; - -void Phaser::setstages(const unsigned char &Pstages) -{ - if (Pstages>=MAX_PHASER_STAGES) this->Pstages=MAX_PHASER_STAGES-1; - else this->Pstages=Pstages; - old=Stereo(Pstages*2); - cleanup(); -}; - -void Phaser::setphase(const unsigned char &Pphase) -{ - this->Pphase=Pphase; - phase=(Pphase/127.0); -}; - - -void Phaser::setpreset(unsigned char npreset) -{ - const int PRESET_SIZE=12; - const int NUM_PRESETS=6; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ - //Phaser1 - {64,64,36,0,0,64,110,64,1,0,0,20}, - //Phaser2 - {64,64,35,0,0,88,40,64,3,0,0,20}, - //Phaser3 - {64,64,31,0,0,66,68,107,2,0,0,20}, - //Phaser4 - {39,64,22,0,0,66,67,10,5,0,1,20}, - //Phaser5 - {64,64,20,0,1,110,67,78,10,0,0,20}, - //Phaser6 - {64,64,53,100,0,58,37,78,3,0,0,20} - }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n1) Poutsub=1; - else Poutsub=value; - break; - case 11: - setphase(value); - break; - }; -}; - -unsigned char Phaser::getpar(const int &npar)const -{ - switch (npar) { - case 0: - return(Pvolume); - break; - case 1: - return(Ppanning); - break; - case 2: - return(lfo.Pfreq); - break; - case 3: - return(lfo.Prandomness); - break; - case 4: - return(lfo.PLFOtype); - break; - case 5: - return(lfo.Pstereo); - break; - case 6: - return(Pdepth); - break; - case 7: - return(Pfb); - break; - case 8: - return(Pstages); - break; - case 9: - return(Plrcross); - break; - case 10: - return(Poutsub); - break; - case 11: - return(Pphase); - break; - default: - return (0); - }; - -}; - +/* + ZynAddSubFX - a software synthesizer + + Phaser.C - Phaser effect + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include "Phaser.h" +#define PHASER_LFO_SHAPE 2 + +Phaser::Phaser(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), old(1), oldgain(0.0) +{ + setpreset(Ppreset); + cleanup(); +} + +Phaser::~Phaser() +{} + + +/* + * Effect output + */ +void Phaser::out(REALTYPE *smpsl, REALTYPE *smpsr) +{ + int i, j; + REALTYPE lfol, lfor, lgain, rgain, tmp; + + lfo.effectlfoout(&lfol, &lfor); + lgain = lfol; + rgain = lfor; + lgain = (exp(lgain * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); + rgain = (exp(rgain * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); + + + lgain = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * lgain * depth; + rgain = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * rgain * depth; + + if(lgain > 1.0) + lgain = 1.0; + else + if(lgain < 0.0) + lgain = 0.0; + if(rgain > 1.0) + rgain = 1.0; + else + if(rgain < 0.0) + rgain = 0.0; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE x = (REALTYPE) i / SOUND_BUFFER_SIZE; + REALTYPE x1 = 1.0 - x; + REALTYPE gl = lgain * x + oldgain.left() * x1; + REALTYPE gr = rgain * x + oldgain.right() * x1; + REALTYPE inl = smpsl[i] * panning + fbl; + REALTYPE inr = smpsr[i] * (1.0 - panning) + fbr; + + //Left channel + for(j = 0; j < Pstages * 2; j++) { //Phasing routine + tmp = old.left()[j]; + old.left()[j] = gl * tmp + inl; + inl = tmp - gl *old.left()[j]; + } + //Right channel + for(j = 0; j < Pstages * 2; j++) { //Phasing routine + tmp = old.right()[j]; + old.right()[j] = gr * tmp + inr; + inr = tmp - gr *old.right()[j]; + } + //Left/Right crossing + REALTYPE l = inl; + REALTYPE r = inr; + inl = l * (1.0 - lrcross) + r * lrcross; + inr = r * (1.0 - lrcross) + l * lrcross; + + fbl = inl * fb; + fbr = inr * fb; + efxoutl[i] = inl; + efxoutr[i] = inr; + } + + oldgain = Stereo(lgain, rgain); + + if(Poutsub != 0) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] *= -1.0; + efxoutr[i] *= -1.0; + } + ; +} + +/* + * Cleanup the effect + */ +void Phaser::cleanup() +{ + fbl = 0.0; + fbr = 0.0; + oldgain = Stereo(0.0); + old.l().clear(); + old.r().clear(); +} + +/* + * Parameter control + */ +void Phaser::setdepth(const unsigned char &Pdepth) +{ + this->Pdepth = Pdepth; + depth = (Pdepth / 127.0); +} + + +void Phaser::setfb(const unsigned char &Pfb) +{ + this->Pfb = Pfb; + fb = (Pfb - 64.0) / 64.1; +} + +void Phaser::setvolume(const unsigned char &Pvolume) +{ + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} + +void Phaser::setpanning(const unsigned char &Ppanning) +{ + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} + +void Phaser::setlrcross(const unsigned char &Plrcross) +{ + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0; +} + +void Phaser::setstages(const unsigned char &Pstages) +{ + if(Pstages >= MAX_PHASER_STAGES) + this->Pstages = MAX_PHASER_STAGES - 1; + else + this->Pstages = Pstages; + old = Stereo(Pstages * 2); + cleanup(); +} + +void Phaser::setphase(const unsigned char &Pphase) +{ + this->Pphase = Pphase; + phase = (Pphase / 127.0); +} + + +void Phaser::setpreset(unsigned char npreset) +{ + const int PRESET_SIZE = 12; + const int NUM_PRESETS = 6; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { + //Phaser1 + {64, 64, 36, 0, 0, 64, 110, 64, 1, 0, 0, 20}, + //Phaser2 + {64, 64, 35, 0, 0, 88, 40, 64, 3, 0, 0, 20}, + //Phaser3 + {64, 64, 31, 0, 0, 66, 68, 107, 2, 0, 0, 20}, + //Phaser4 + {39, 64, 22, 0, 0, 66, 67, 10, 5, 0, 1, 20}, + //Phaser5 + {64, 64, 20, 0, 1, 110, 67, 78, 10, 0, 0, 20}, + //Phaser6 + {64, 64, 53, 100, 0, 58, 37, 78, 3, 0, 0, 20} + }; + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + Ppreset = npreset; +} + + +void Phaser::changepar(const int &npar, const unsigned char &value) +{ + switch(npar) { + case 0: + setvolume(value); + break; + case 1: + setpanning(value); + break; + case 2: + lfo.Pfreq = value; + lfo.updateparams(); + break; + case 3: + lfo.Prandomness = value; + lfo.updateparams(); + break; + case 4: + lfo.PLFOtype = value; + lfo.updateparams(); + break; + case 5: + lfo.Pstereo = value; + lfo.updateparams(); + break; + case 6: + setdepth(value); + break; + case 7: + setfb(value); + break; + case 8: + setstages(value); + break; + case 9: + setlrcross(value); + break; + case 10: + if(value > 1) + Poutsub = 1; + else + Poutsub = value; + break; + case 11: + setphase(value); + break; + } +} + +unsigned char Phaser::getpar(const int &npar) const +{ + switch(npar) { + case 0: + return Pvolume; + break; + case 1: + return Ppanning; + break; + case 2: + return lfo.Pfreq; + break; + case 3: + return lfo.Prandomness; + break; + case 4: + return lfo.PLFOtype; + break; + case 5: + return lfo.Pstereo; + break; + case 6: + return Pdepth; + break; + case 7: + return Pfb; + break; + case 8: + return Pstages; + break; + case 9: + return Plrcross; + break; + case 10: + return Poutsub; + break; + case 11: + return Pphase; + break; + default: + return 0; + } +} + diff --git a/plugins/zynaddsubfx/src/Effects/Phaser.h b/plugins/zynaddsubfx/src/Effects/Phaser.h index 700af3dfc..30370a8c6 100644 --- a/plugins/zynaddsubfx/src/Effects/Phaser.h +++ b/plugins/zynaddsubfx/src/Effects/Phaser.h @@ -1,76 +1,76 @@ -/* - ZynAddSubFX - a software synthesizer - - Phaser.h - Phaser effect - Copyright (C) 2002-2005 Nasca Octavian Paul - Author: Nasca Octavian Paul - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - 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 (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#ifndef PHASER_H -#define PHASER_H -#include "../globals.h" -#include "../Misc/Stereo.h" -#include "../Samples/AuSample.h" -#include "Effect.h" -#include "EffectLFO.h" - -#define MAX_PHASER_STAGES 12 -/**Phaser Effect*/ -class Phaser:public Effect -{ -public: - Phaser(const int &insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~Phaser(); - void out(REALTYPE *smpsl,REALTYPE *smpsr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); - void setdryonly(); - -private: - //Parametrii Phaser - EffectLFO lfo;/** old; - //REALTYPE oldlgain,oldrgain; - Stereo oldgain; -}; - -#endif - +/* + ZynAddSubFX - a software synthesizer + + Phaser.h - Phaser effect + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef PHASER_H +#define PHASER_H +#include "../globals.h" +#include "../Misc/Stereo.h" +#include "../Samples/AuSample.h" +#include "Effect.h" +#include "EffectLFO.h" + +#define MAX_PHASER_STAGES 12 +/**Phaser Effect*/ +class Phaser:public Effect +{ + public: + Phaser(const int &insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~Phaser(); + void out(REALTYPE *smpsl, REALTYPE *smpsr); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); + void setdryonly(); + + private: + //Parametrii Phaser + EffectLFO lfo; /** old; + //REALTYPE oldlgain,oldrgain; + Stereo oldgain; +}; + +#endif + diff --git a/plugins/zynaddsubfx/src/Effects/Reverb.cpp b/plugins/zynaddsubfx/src/Effects/Reverb.cpp index 943439716..27b0a554b 100644 --- a/plugins/zynaddsubfx/src/Effects/Reverb.cpp +++ b/plugins/zynaddsubfx/src/Effects/Reverb.cpp @@ -1,471 +1,557 @@ -/* - ZynAddSubFX - a software synthesizer - - Reverb.C - Reverberation effect - Copyright (C) 2002-2005 Nasca Octavian Paul - Author: Nasca Octavian Paul - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - 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 (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#include -#include "Reverb.h" - -/**\todo: EarlyReflections,Prdelay,Perbalance */ - -Reverb::Reverb(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) -{ - inputbuf=new REALTYPE[SOUND_BUFFER_SIZE]; - - //defaults - Pvolume=48; - Ppan=64; - Ptime=64; - Pidelay=40; - Pidelayfb=0; - Prdelay=0; - Plpf=127; - Phpf=0; - Perbalance=64; - Plohidamp=80; - Ptype=1; - Proomsize=64; - roomsize=1.0; - rs=1.0; - - for (int i=0;icleanup(); - if (lpf!=NULL) lpf->cleanup(); - -}; - -/* - * Process one channel; 0=left,1=right - */ -void Reverb::processmono(int ch,REALTYPE *output) -{ - int i,j; - REALTYPE fbout,tmp; - /**\todo: implement the high part from lohidamp*/ - - for (j=REV_COMBS*ch;j=comblength) ck=0; - }; - - combk[j]=ck; - lpcomb[j]=lpcombj; - }; - - for (j=REV_APS*ch;j=aplength) ak=0; - }; - apk[j]=ak; - }; -}; - -/* - * Effect output - */ -void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r) -{ - int i; - if ((Pvolume==0)&&(insertion!=0)) return; - - for (i=0;i=idelaylen) idelayk=0; - }; - }; - - if (lpf!=NULL) lpf->filterout(inputbuf); - if (hpf!=NULL) hpf->filterout(inputbuf); - - processmono(0,efxoutl);//left - processmono(1,efxoutr);//right - - REALTYPE lvol=rs/REV_COMBS*pan; - REALTYPE rvol=rs/REV_COMBS*(1.0-pan); - if (insertion!=0) { - lvol*=2; - rvol*=2; - }; - for (int i=0;iPvolume=Pvolume; - if (insertion==0) { - outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; - volume=1.0; - } else { - volume=outvolume=Pvolume/127.0; - if (Pvolume==0) cleanup(); - }; -}; - -void Reverb::setpan(const unsigned char &Ppan) -{ - this->Ppan=Ppan; - pan=(REALTYPE)Ppan/127.0; -}; - -void Reverb::settime(const unsigned char &Ptime) -{ - int i; - REALTYPE t; - this->Ptime=Ptime; - t=pow(60.0,(REALTYPE)Ptime/127.0)-0.97; - - for (i=0;iPlohidamp=Plohidamp; - if (Plohidamp==64) { - lohidamptype=0; - lohifb=0.0; - } else { - if (Plohidamp<64) lohidamptype=1; - if (Plohidamp>64) lohidamptype=2; - x=fabs((REALTYPE)(Plohidamp-64)/64.1); - lohifb=x*x; - }; -}; - -void Reverb::setidelay(const unsigned char &Pidelay) -{ - REALTYPE delay; - this->Pidelay=Pidelay; - delay=pow(50*Pidelay/127.0,2)-1.0; - - if (idelay!=NULL) delete []idelay; - idelay=NULL; - - idelaylen=(int) (SAMPLE_RATE*delay/1000); - if (idelaylen>1) { - idelayk=0; - idelay=new REALTYPE[idelaylen]; - for (int i=0;iPidelayfb=Pidelayfb; - idelayfb=Pidelayfb/128.0; -}; - -void Reverb::sethpf(const unsigned char &Phpf) -{ - this->Phpf=Phpf; - if (Phpf==0) {//No HighPass - if (hpf!=NULL) delete hpf; - hpf=NULL; - } else { - REALTYPE fr=exp(pow(Phpf/127.0,0.5)*log(10000.0))+20.0; - if (hpf==NULL) hpf=new AnalogFilter(3,fr,1,0); - else hpf->setfreq(fr); - }; -}; - -void Reverb::setlpf(const unsigned char &Plpf) -{ - this->Plpf=Plpf; - if (Plpf==127) {//No LowPass - if (lpf!=NULL) delete lpf; - lpf=NULL; - } else { - REALTYPE fr=exp(pow(Plpf/127.0,0.5)*log(25000.0))+40; - if (lpf==NULL) lpf=new AnalogFilter(2,fr,1,0); - else lpf->setfreq(fr); - }; -}; - -void Reverb::settype(unsigned char Ptype) -{ - const int NUM_TYPES=2; - int combtunings[NUM_TYPES][REV_COMBS]={ - //this is unused (for random) - {0,0,0,0,0,0,0,0}, - //Freeverb by Jezar at Dreampoint - {1116,1188,1277,1356,1422,1491,1557,1617} - }; - int aptunings[NUM_TYPES][REV_APS]={ - //this is unused (for random) - {0,0,0,0}, - //Freeverb by Jezar at Dreampoint - {225,341,441,556} - }; - - if (Ptype>=NUM_TYPES) Ptype=NUM_TYPES-1; - this->Ptype=Ptype; - - REALTYPE tmp; - for (int i=0;iREV_COMBS) tmp+=23.0; - tmp*=SAMPLE_RATE/44100.0;//adjust the combs according to the samplerate - if (tmp<10) tmp=10; - - comblen[i]=(int) tmp; - combk[i]=0; - lpcomb[i]=0; - if (comb[i]!=NULL) delete []comb[i]; - comb[i]=new REALTYPE[comblen[i]]; - }; - - for (int i=0;iREV_APS) tmp+=23.0; - tmp*=SAMPLE_RATE/44100.0;//adjust the combs according to the samplerate - if (tmp<10) tmp=10; - aplen[i]=(int) tmp; - apk[i]=0; - if (ap[i]!=NULL) delete []ap[i]; - ap[i]=new REALTYPE[aplen[i]]; - }; - settime(Ptime); - cleanup(); -}; - -void Reverb::setroomsize(const unsigned char &Proomsize) -{ - this->Proomsize=Proomsize; - if (Proomsize==0) this->Proomsize=64;//this is because the older versions consider roomsize=0 - roomsize=(this->Proomsize-64.0)/64.0; - if (roomsize>0.0) roomsize*=2.0; - roomsize=pow(10.0,roomsize); - rs=sqrt(roomsize); - settype(Ptype); -}; - -void Reverb::setpreset(unsigned char npreset) -{ - const int PRESET_SIZE=12; - const int NUM_PRESETS=13; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ - //Cathedral1 - {80,64,63,24,0,0,0,85,5,83,1,64}, - //Cathedral2 - {80,64,69,35,0,0,0,127,0,71,0,64}, - //Cathedral3 - {80,64,69,24,0,0,0,127,75,78,1,85}, - //Hall1 - {90,64,51,10,0,0,0,127,21,78,1,64}, - //Hall2 - {90,64,53,20,0,0,0,127,75,71,1,64}, - //Room1 - {100,64,33,0,0,0,0,127,0,106,0,30}, - //Room2 - {100,64,21,26,0,0,0,62,0,77,1,45}, - //Basement - {110,64,14,0,0,0,0,127,5,71,0,25}, - //Tunnel - {85,80,84,20,42,0,0,51,0,78,1,105}, - //Echoed1 - {95,64,26,60,71,0,0,114,0,64,1,64}, - //Echoed2 - {90,64,40,88,71,0,0,114,0,88,1,64}, - //VeryLong1 - {90,64,93,15,0,0,0,114,0,77,0,95}, - //VeryLong2 - {90,64,111,30,0,0,0,114,90,74,1,80} - }; - - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n +#include "Reverb.h" + +/**\todo: EarlyReflections,Prdelay,Perbalance */ + +Reverb::Reverb(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0) +{ + inputbuf = new REALTYPE[SOUND_BUFFER_SIZE]; + + bandwidth = NULL; + + //defaults + Pvolume = 48; + Ppan = 64; + Ptime = 64; + Pidelay = 40; + Pidelayfb = 0; + Prdelay = 0; + Plpf = 127; + Phpf = 0; + Perbalance = 64; + Plohidamp = 80; + Ptype = 1; + Proomsize = 64; + Pbandwidth = 30; + roomsize = 1.0; + rs = 1.0; + + for(int i = 0; i < REV_COMBS * 2; i++) { + comblen[i] = 800 + (int)(RND * 1400); + combk[i] = 0; + lpcomb[i] = 0; + combfb[i] = -0.97; + comb[i] = NULL; + } + + for(int i = 0; i < REV_APS * 2; i++) { + aplen[i] = 500 + (int)(RND * 500); + apk[i] = 0; + ap[i] = NULL; + } + + lpf = NULL; + hpf = NULL; //no filter + idelay = NULL; + + setpreset(Ppreset); + cleanup(); //do not call this before the comb initialisation +} + + +Reverb::~Reverb() +{ + int i; + if(idelay != NULL) + delete [] idelay; + if(hpf != NULL) + delete hpf; + if(lpf != NULL) + delete lpf; + + for(i = 0; i < REV_APS * 2; i++) + delete [] ap[i]; + for(i = 0; i < REV_COMBS * 2; i++) + delete [] comb[i]; + + delete [] inputbuf; + if(bandwidth) + delete bandwidth; +} + +/* + * Cleanup the effect + */ +void Reverb::cleanup() +{ + int i, j; + for(i = 0; i < REV_COMBS * 2; i++) { + lpcomb[i] = 0.0; + for(j = 0; j < comblen[i]; j++) + comb[i][j] = 0.0; + } + + for(i = 0; i < REV_APS * 2; i++) + for(j = 0; j < aplen[i]; j++) + ap[i][j] = 0.0; + + if(idelay != NULL) + for(i = 0; i < idelaylen; i++) + idelay[i] = 0.0; + + if(hpf != NULL) + hpf->cleanup(); + if(lpf != NULL) + lpf->cleanup(); +} + +/* + * Process one channel; 0=left,1=right + */ +void Reverb::processmono(int ch, REALTYPE *output) +{ + int i, j; + REALTYPE fbout, tmp; + /**\todo: implement the high part from lohidamp*/ + + for(j = REV_COMBS * ch; j < REV_COMBS * (ch + 1); j++) { + int ck = combk[j]; + int comblength = comblen[j]; + REALTYPE lpcombj = lpcomb[j]; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + fbout = comb[j][ck] * combfb[j]; + fbout = fbout * (1.0 - lohifb) + lpcombj * lohifb; + lpcombj = fbout; + + comb[j][ck] = inputbuf[i] + fbout; + output[i] += fbout; + + if((++ck) >= comblength) + ck = 0; + } + + combk[j] = ck; + lpcomb[j] = lpcombj; + } + + for(j = REV_APS * ch; j < REV_APS * (1 + ch); j++) { + int ak = apk[j]; + int aplength = aplen[j]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmp = ap[j][ak]; + ap[j][ak] = 0.7 * tmp + output[i]; + output[i] = tmp - 0.7 * ap[j][ak]; + if((++ak) >= aplength) + ak = 0; + } + apk[j] = ak; + } +} + +/* + * Effect output + */ +void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r) +{ + int i; + if((Pvolume == 0) && (insertion != 0)) + return; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + inputbuf[i] = (smps_l[i] + smps_r[i]) / 2.0; + ; + + if(idelay != NULL) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + //Initial delay r + REALTYPE tmp = inputbuf[i] + idelay[idelayk] * idelayfb; + inputbuf[i] = idelay[idelayk]; + idelay[idelayk] = tmp; + idelayk++; + if(idelayk >= idelaylen) + idelayk = 0; + ; + } + } + + if(bandwidth) + bandwidth->process(SOUND_BUFFER_SIZE, inputbuf); + + if(lpf != NULL) + lpf->filterout(inputbuf); + if(hpf != NULL) + hpf->filterout(inputbuf); + + processmono(0, efxoutl); //left + processmono(1, efxoutr); //right + + REALTYPE lvol = rs / REV_COMBS * pan; + REALTYPE rvol = rs / REV_COMBS * (1.0 - pan); + if(insertion != 0) { + lvol *= 2; + rvol *= 2; + } + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] *= lvol; + efxoutr[i] *= rvol; + } +} + + +/* + * Parameter control + */ +void Reverb::setvolume(const unsigned char &Pvolume) +{ + this->Pvolume = Pvolume; + if(insertion == 0) { + outvolume = pow(0.01, (1.0 - Pvolume / 127.0)) * 4.0; + volume = 1.0; + } + else { + volume = outvolume = Pvolume / 127.0; + if(Pvolume == 0) + cleanup(); + } +} + +void Reverb::setpan(const unsigned char &Ppan) +{ + this->Ppan = Ppan; + pan = (REALTYPE)Ppan / 127.0; +} + +void Reverb::settime(const unsigned char &Ptime) +{ + int i; + REALTYPE t; + this->Ptime = Ptime; + t = pow(60.0, (REALTYPE)Ptime / 127.0) - 0.97; + + for(i = 0; i < REV_COMBS * 2; i++) + combfb[i] = + -exp((REALTYPE)comblen[i] / (REALTYPE)SAMPLE_RATE * log(0.001) / t); + //the feedback is negative because it removes the DC + ; +} + +void Reverb::setlohidamp(unsigned char Plohidamp) +{ + REALTYPE x; + + if(Plohidamp < 64) + Plohidamp = 64; //remove this when the high part from lohidamp will be added + + this->Plohidamp = Plohidamp; + if(Plohidamp == 64) { + lohidamptype = 0; + lohifb = 0.0; + } + else { + if(Plohidamp < 64) + lohidamptype = 1; + if(Plohidamp > 64) + lohidamptype = 2; + x = fabs((REALTYPE)(Plohidamp - 64) / 64.1); + lohifb = x * x; + } +} + +void Reverb::setidelay(const unsigned char &Pidelay) +{ + REALTYPE delay; + this->Pidelay = Pidelay; + delay = pow(50 * Pidelay / 127.0, 2) - 1.0; + + if(idelay != NULL) + delete [] idelay; + idelay = NULL; + + idelaylen = (int) (SAMPLE_RATE * delay / 1000); + if(idelaylen > 1) { + idelayk = 0; + idelay = new REALTYPE[idelaylen]; + for(int i = 0; i < idelaylen; i++) + idelay[i] = 0.0; + } +} + +void Reverb::setidelayfb(const unsigned char &Pidelayfb) +{ + this->Pidelayfb = Pidelayfb; + idelayfb = Pidelayfb / 128.0; +} + +void Reverb::sethpf(const unsigned char &Phpf) +{ + this->Phpf = Phpf; + if(Phpf == 0) { //No HighPass + if(hpf != NULL) + delete hpf; + hpf = NULL; + } + else { + REALTYPE fr = exp(pow(Phpf / 127.0, 0.5) * log(10000.0)) + 20.0; + if(hpf == NULL) + hpf = new AnalogFilter(3, fr, 1, 0); + else + hpf->setfreq(fr); + } +} + +void Reverb::setlpf(const unsigned char &Plpf) +{ + this->Plpf = Plpf; + if(Plpf == 127) { //No LowPass + if(lpf != NULL) + delete lpf; + lpf = NULL; + } + else { + REALTYPE fr = exp(pow(Plpf / 127.0, 0.5) * log(25000.0)) + 40; + if(lpf == NULL) + lpf = new AnalogFilter(2, fr, 1, 0); + else + lpf->setfreq(fr); + } +} + +void Reverb::settype(unsigned char Ptype) +{ + const int NUM_TYPES = 3; + int combtunings[NUM_TYPES][REV_COMBS] = { + //this is unused (for random) + {0, 0, 0, 0, 0, 0, 0, 0 }, + //Freeverb by Jezar at Dreampoint + {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 }, + //Freeverb by Jezar at Dreampoint //duplicate + {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 } + }; + int aptunings[NUM_TYPES][REV_APS] = { + //this is unused (for random) + {0, 0, 0, 0 }, + //Freeverb by Jezar at Dreampoint + {225, 341, 441, 556 }, + //Freeverb by Jezar at Dreampoint (duplicate) + {225, 341, 441, 556 } + }; + + if(Ptype >= NUM_TYPES) + Ptype = NUM_TYPES - 1; + this->Ptype = Ptype; + + REALTYPE tmp; + for(int i = 0; i < REV_COMBS * 2; i++) { + if(Ptype == 0) + tmp = 800.0 + (int)(RND * 1400.0); + else + tmp = combtunings[Ptype][i % REV_COMBS]; + tmp *= roomsize; + if(i > REV_COMBS) + tmp += 23.0; + tmp *= SAMPLE_RATE / 44100.0; //adjust the combs according to the samplerate + if(tmp < 10) + tmp = 10; + + comblen[i] = (int) tmp; + combk[i] = 0; + lpcomb[i] = 0; + if(comb[i] != NULL) + delete [] comb[i]; + comb[i] = new REALTYPE[comblen[i]]; + } + + for(int i = 0; i < REV_APS * 2; i++) { + if(Ptype == 0) + tmp = 500 + (int)(RND * 500); + else + tmp = aptunings[Ptype][i % REV_APS]; + tmp *= roomsize; + if(i > REV_APS) + tmp += 23.0; + tmp *= SAMPLE_RATE / 44100.0; //adjust the combs according to the samplerate + if(tmp < 10) + tmp = 10; + aplen[i] = (int) tmp; + apk[i] = 0; + if(ap[i] != NULL) + delete [] ap[i]; + ap[i] = new REALTYPE[aplen[i]]; + } + settime(Ptime); + cleanup(); + if(bandwidth) + delete bandwidth; + bandwidth = NULL; + if(Ptype == 2) { //bandwidth + bandwidth = new Unison(SOUND_BUFFER_SIZE / 4 + 1, 2.0); + bandwidth->set_size(50); + bandwidth->set_base_frequency(1.0); +#warning sa schimb size-ul + } +} + +void Reverb::setroomsize(const unsigned char &Proomsize) +{ + this->Proomsize = Proomsize; + if(Proomsize == 0) + this->Proomsize = 64; //this is because the older versions consider roomsize=0 + roomsize = (this->Proomsize - 64.0) / 64.0; + if(roomsize > 0.0) + roomsize *= 2.0; + roomsize = pow(10.0, roomsize); + rs = sqrt(roomsize); + settype(Ptype); +} + +void Reverb::setbandwidth(const unsigned char &Pbandwidth) { + this->Pbandwidth = Pbandwidth; + REALTYPE v = Pbandwidth / 127.0; + if(bandwidth) + bandwidth->set_bandwidth(pow(v, 2.0) * 200.0); +} + +void Reverb::setpreset(unsigned char npreset) +{ + const int PRESET_SIZE = 13; + const int NUM_PRESETS = 13; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { + //Cathedral1 + {80, 64, 63, 24, 0, 0, 0, 85, 5, 83, 1, 64, 20 }, + //Cathedral2 + {80, 64, 69, 35, 0, 0, 0, 127, 0, 71, 0, 64, 20 }, + //Cathedral3 + {80, 64, 69, 24, 0, 0, 0, 127, 75, 78, 1, 85, 20 }, + //Hall1 + {90, 64, 51, 10, 0, 0, 0, 127, 21, 78, 1, 64, 20 }, + //Hall2 + {90, 64, 53, 20, 0, 0, 0, 127, 75, 71, 1, 64, 20 }, + //Room1 + {100, 64, 33, 0, 0, 0, 0, 127, 0, 106, 0, 30, 20 }, + //Room2 + {100, 64, 21, 26, 0, 0, 0, 62, 0, 77, 1, 45, 20 }, + //Basement + {110, 64, 14, 0, 0, 0, 0, 127, 5, 71, 0, 25, 20 }, + //Tunnel + {85, 80, 84, 20, 42, 0, 0, 51, 0, 78, 1, 105, 20 }, + //Echoed1 + {95, 64, 26, 60, 71, 0, 0, 114, 0, 64, 1, 64, 20 }, + //Echoed2 + {90, 64, 40, 88, 71, 0, 0, 114, 0, 88, 1, 64, 20 }, + //VeryLong1 + {90, 64, 93, 15, 0, 0, 0, 114, 0, 77, 0, 95, 20 }, + //VeryLong2 + {90, 64, 111, 30, 0, 0, 0, 114, 90, 74, 1, 80, 20 } + }; + + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion != 0) + changepar(0, presets[npreset][0] / 2); //lower the volume if reverb is insertion effect + Ppreset = npreset; +} + + +void Reverb::changepar(const int &npar, const unsigned char &value) +{ + switch(npar) { + case 0: + setvolume(value); + break; + case 1: + setpan(value); + break; + case 2: + settime(value); + break; + case 3: + setidelay(value); + break; + case 4: + setidelayfb(value); + break; +// case 5: setrdelay(value); +// break; +// case 6: seterbalance(value); +// break; + case 7: + setlpf(value); + break; + case 8: + sethpf(value); + break; + case 9: + setlohidamp(value); + break; + case 10: + settype(value); + break; + case 11: + setroomsize(value); + break; + case 12: + setbandwidth(value); + break; + } +} + +unsigned char Reverb::getpar(const int &npar) const +{ + switch(npar) { + case 0: + return Pvolume; + break; + case 1: + return Ppan; + break; + case 2: + return Ptime; + break; + case 3: + return Pidelay; + break; + case 4: + return Pidelayfb; + break; +// case 5: return(Prdelay); +// break; +// case 6: return(Perbalance); +// break; + case 7: + return Plpf; + break; + case 8: + return Phpf; + break; + case 9: + return Plohidamp; + break; + case 10: + return Ptype; + break; + case 11: + return Proomsize; + break; + case 12: + return Pbandwidth; + break; + } + return 0; //in case of bogus "parameter" +} + diff --git a/plugins/zynaddsubfx/src/Effects/Reverb.h b/plugins/zynaddsubfx/src/Effects/Reverb.h index ddf5900f6..d94f0bcef 100644 --- a/plugins/zynaddsubfx/src/Effects/Reverb.h +++ b/plugins/zynaddsubfx/src/Effects/Reverb.h @@ -1,127 +1,135 @@ -/* - ZynAddSubFX - a software synthesizer - - Reverb.h - Reverberation effect - Copyright (C) 2002-2005 Nasca Octavian Paul - Author: Nasca Octavian Paul - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - 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 (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#ifndef REVERB_H -#define REVERB_H - - -#include "../globals.h" -#include "../DSP/AnalogFilter.h" -#include "Effect.h" - -#define REV_COMBS 8 -#define REV_APS 4 - -/**Creates Reverberation Effects*/ -class Reverb:public Effect -{ -public: - Reverb(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~Reverb(); - void out(REALTYPE *smps_l,REALTYPE *smps_r); - void cleanup(); - - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - -private: - //Parametrii - /**Amount of the reverb*/ - unsigned char Pvolume; - - /**Left/Right Panning*/ - unsigned char Ppan; - - /**duration of reverb*/ - unsigned char Ptime; - - /**Initial delay*/ - unsigned char Pidelay; - - /**Initial delay feedback*/ - unsigned char Pidelayfb; - - /**delay between ER/Reverbs*/ - unsigned char Prdelay; - - /**EarlyReflections/Reverb Balance*/ - unsigned char Perbalance; - - /**HighPassFilter*/ - unsigned char Plpf; - - /**LowPassFilter*/ - unsigned char Phpf; - - /**Low/HighFrequency Damping - * \todo 0..63 lpf,64=off,65..127=hpf(TODO)*/ - unsigned char Plohidamp; - - /**Reverb type*/ - unsigned char Ptype; - - /**Room Size*/ - unsigned char Proomsize; - - //parameter control - void setvolume(const unsigned char &Pvolume); - void setpan(const unsigned char &Ppan); - void settime(const unsigned char &Ptime); - void setlohidamp(unsigned char Plohidamp); - void setidelay(const unsigned char &Pidelay); - void setidelayfb(const unsigned char &Pidelayfb); - void sethpf(const unsigned char &Phpf); - void setlpf(const unsigned char &Plpf); - void settype( unsigned char Ptype); - void setroomsize(const unsigned char &Proomsize); - - REALTYPE pan,erbalance; - //Parametrii 2 - int lohidamptype;/**<0=disable,1=highdamp(lowpass),2=lowdamp(highpass)*/ - int idelaylen,rdelaylen; - int idelayk; - REALTYPE lohifb,idelayfb,roomsize,rs;//rs is used to "normalise" the volume according to the roomsize - int comblen[REV_COMBS*2]; - int aplen[REV_APS*2]; - - //Internal Variables - - REALTYPE *comb[REV_COMBS*2]; - - int combk[REV_COMBS*2]; - REALTYPE combfb[REV_COMBS*2];/** +#include "../globals.h" +#include "../DSP/AnalogFilter.h" +#include "../DSP/FFTwrapper.h" +#include "../DSP/Unison.h" +#include "Effect.h" + +#define REV_COMBS 8 +#define REV_APS 4 + +/**Creates Reverberation Effects*/ + +class Reverb:public Effect +{ + public: + Reverb(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~Reverb(); + void out(REALTYPE *smps_l, REALTYPE *smps_r); + void cleanup(); + + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + + private: + //Parametrii + /**Amount of the reverb*/ + unsigned char Pvolume; + + /**Left/Right Panning*/ + unsigned char Ppan; + + /**duration of reverb*/ + unsigned char Ptime; + + /**Initial delay*/ + unsigned char Pidelay; + + /**Initial delay feedback*/ + unsigned char Pidelayfb; + + /**delay between ER/Reverbs*/ + unsigned char Prdelay; + + /**EarlyReflections/Reverb Balance*/ + unsigned char Perbalance; + + /**HighPassFilter*/ + unsigned char Plpf; + + /**LowPassFilter*/ + unsigned char Phpf; + + /**Low/HighFrequency Damping + * \todo 0..63 lpf,64=off,65..127=hpf(TODO)*/ + unsigned char Plohidamp; + + /**Reverb type*/ + unsigned char Ptype; + + /**Room Size*/ + unsigned char Proomsize; + + /**Bandwidth */ + unsigned char Pbandwidth; + + //parameter control + void setvolume(const unsigned char &Pvolume); + void setpan(const unsigned char &Ppan); + void settime(const unsigned char &Ptime); + void setlohidamp(unsigned char Plohidamp); + void setidelay(const unsigned char &Pidelay); + void setidelayfb(const unsigned char &Pidelayfb); + void sethpf(const unsigned char &Phpf); + void setlpf(const unsigned char &Plpf); + void settype(unsigned char Ptype); + void setroomsize(const unsigned char &Proomsize); + void setbandwidth(const unsigned char &Pbandwidth); + + REALTYPE pan, erbalance; + //Parameters + int lohidamptype; /**<0=disable,1=highdamp(lowpass),2=lowdamp(highpass)*/ + int idelaylen, rdelaylen; + int idelayk; + REALTYPE lohifb, idelayfb, roomsize, rs; //rs is used to "normalise" the volume according to the roomsize + int comblen[REV_COMBS * 2]; + int aplen[REV_APS * 2]; + Unison *bandwidth; + + //Internal Variables + + REALTYPE *comb[REV_COMBS * 2]; + + int combk[REV_COMBS * 2]; + REALTYPE combfb[REV_COMBS * 2]; /**type) { + if(midievent == NULL) + return; + switch(midievent->type) { case SND_SEQ_EVENT_NOTEON: - cmdtype=MidiNoteON; - cmdchan=midievent->data.note.channel; - cmdparams[0]=midievent->data.note.note; - cmdparams[1]=midievent->data.note.velocity; + cmdtype = MidiNoteON; + cmdchan = midievent->data.note.channel; + cmdparams[0] = midievent->data.note.note; + cmdparams[1] = midievent->data.note.velocity; break; case SND_SEQ_EVENT_NOTEOFF: - cmdtype=MidiNoteOFF; - cmdchan=midievent->data.note.channel; - cmdparams[0]=midievent->data.note.note; + cmdtype = MidiNoteOFF; + cmdchan = midievent->data.note.channel; + cmdparams[0] = midievent->data.note.note; break; case SND_SEQ_EVENT_PITCHBEND: - cmdtype=MidiController; - cmdchan=midievent->data.control.channel; - cmdparams[0]=C_pitchwheel;//Pitch Bend - cmdparams[1]=midievent->data.control.value; + cmdtype = MidiController; + cmdchan = midievent->data.control.channel; + cmdparams[0] = C_pitchwheel; //Pitch Bend + cmdparams[1] = midievent->data.control.value; break; case SND_SEQ_EVENT_CONTROLLER: - cmdtype=MidiController; - cmdchan=midievent->data.control.channel; - cmdparams[0]=getcontroller(midievent->data.control.param); - cmdparams[1]=midievent->data.control.value; + cmdtype = MidiController; + cmdchan = midievent->data.control.channel; + cmdparams[0] = getcontroller(midievent->data.control.param); + cmdparams[1] = midievent->data.control.value; //fprintf(stderr,"t=%d val=%d\n",midievent->data.control.param,midievent->data.control.value); break; - - }; -}; + } +} int ALSAMidiIn::getalsaid() { - if (midi_handle) { - snd_seq_client_info_t* seq_info; + if(midi_handle) { + snd_seq_client_info_t *seq_info; snd_seq_client_info_malloc(&seq_info); snd_seq_get_client_info(midi_handle, seq_info); int id = snd_seq_client_info_get_client(seq_info); diff --git a/plugins/zynaddsubfx/src/Input/ALSAMidiIn.h b/plugins/zynaddsubfx/src/Input/ALSAMidiIn.h index e4671014f..cea61fb36 100644 --- a/plugins/zynaddsubfx/src/Input/ALSAMidiIn.h +++ b/plugins/zynaddsubfx/src/Input/ALSAMidiIn.h @@ -30,19 +30,21 @@ /**Midi input for ALSA (this creates an ALSA virtual port)*/ class ALSAMidiIn:public MidiIn { -public: - /**Constructor*/ - ALSAMidiIn(); - /**Destructor*/ - ~ALSAMidiIn(); + public: + /**Constructor*/ + ALSAMidiIn(); + /**Destructor*/ + ~ALSAMidiIn(); - void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); - /**Get the ALSA id - * @return ALSA id*/ - int getalsaid(); + void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams); + /**Get the ALSA id + * @return ALSA id*/ + int getalsaid(); -private: - snd_seq_t *midi_handle; + private: + snd_seq_t *midi_handle; }; #endif diff --git a/plugins/zynaddsubfx/src/Input/MidiIn.cpp b/plugins/zynaddsubfx/src/Input/MidiIn.cpp index 2355b3a64..90df75d95 100644 --- a/plugins/zynaddsubfx/src/Input/MidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/MidiIn.cpp @@ -26,70 +26,71 @@ int MidiIn::getcontroller(unsigned char b) { /**\todo there might be a better way to do this*/ - int ctl=C_NULL; - switch (b) { + int ctl = C_NULL; + switch(b) { case 1: - ctl=C_modwheel;//Modulation Wheel + ctl = C_modwheel; //Modulation Wheel break; case 7: - ctl=C_volume;//Volume + ctl = C_volume; //Volume break; case 10: - ctl=C_panning;//Panning + ctl = C_panning; //Panning break; case 11: - ctl=C_expression;//Expression + ctl = C_expression; //Expression break; case 64: - ctl=C_sustain;//Sustain pedal + ctl = C_sustain; //Sustain pedal break; case 65: - ctl=C_portamento;//Portamento + ctl = C_portamento; //Portamento break; case 71: - ctl=C_filterq;//Filter Q (Sound Timbre) + ctl = C_filterq; //Filter Q (Sound Timbre) break; case 74: - ctl=C_filtercutoff;//Filter Cutoff (Brightness) + ctl = C_filtercutoff; //Filter Cutoff (Brightness) break; case 75: - ctl=C_bandwidth;//BandWidth + ctl = C_bandwidth; //BandWidth break; case 76: - ctl=C_fmamp;//FM amplitude + ctl = C_fmamp; //FM amplitude break; case 77: - ctl=C_resonance_center;//Resonance Center Frequency + ctl = C_resonance_center; //Resonance Center Frequency break; case 78: - ctl=C_resonance_bandwidth;//Resonance Bandwith + ctl = C_resonance_bandwidth; //Resonance Bandwith break; case 120: - ctl=C_allsoundsoff;//All Sounds OFF + ctl = C_allsoundsoff; //All Sounds OFF break; case 121: - ctl=C_resetallcontrollers;//Reset All Controllers + ctl = C_resetallcontrollers; //Reset All Controllers break; case 123: - ctl=C_allnotesoff;//All Notes OFF + ctl = C_allnotesoff; //All Notes OFF break; - //RPN and NRPN + //RPN and NRPN case 0x06: - ctl=C_dataentryhi;//Data Entry (Coarse) + ctl = C_dataentryhi; //Data Entry (Coarse) break; case 0x26: - ctl=C_dataentrylo;//Data Entry (Fine) + ctl = C_dataentrylo; //Data Entry (Fine) break; case 99: - ctl=C_nrpnhi;//NRPN (Coarse) + ctl = C_nrpnhi; //NRPN (Coarse) break; case 98: - ctl=C_nrpnlo;//NRPN (Fine) + ctl = C_nrpnlo; //NRPN (Fine) break; default: - ctl=C_NULL;//unknown controller + ctl = C_NULL; //unknown controller //fprintf(stderr,"Controller=%d , par=%d\n",midievent->data.control.param,cmdparams[1]); break; - }; - return(ctl); -}; + } + return ctl; +} + diff --git a/plugins/zynaddsubfx/src/Input/MidiIn.h b/plugins/zynaddsubfx/src/Input/MidiIn.h index f02d10e76..5d978eaeb 100644 --- a/plugins/zynaddsubfx/src/Input/MidiIn.h +++ b/plugins/zynaddsubfx/src/Input/MidiIn.h @@ -25,23 +25,27 @@ #include "../globals.h" -enum MidiCmdType {MidiNull,MidiNoteOFF,MidiNoteON,MidiController}; +enum MidiCmdType { + MidiNull, MidiNoteOFF, MidiNoteON, MidiController +}; #define MP_MAX_BYTES 4000 //in case of loooong SYS_EXes /**This class is inherited by all the Midi input classes*/ class MidiIn { -public: - /**Get the command,channel and parameters of the MIDI - * - * \todo make pure virtual - * @param cmdtype the referece to the variable that will store the type - * @param cmdchan the channel for the event - * @param parameters for the event*/ - virtual void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams)=0; - int getcontroller(unsigned char b); -protected: - bool inputok;/**<1 if I can read midi bytes from input ports*/ + public: + /**Get the command,channel and parameters of the MIDI + * + * \todo make pure virtual + * @param cmdtype the referece to the variable that will store the type + * @param cmdchan the channel for the event + * @param parameters for the event*/ + virtual void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams) = 0; + int getcontroller(unsigned char b); + protected: + bool inputok; /**<1 if I can read midi bytes from input ports*/ }; #endif diff --git a/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp b/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp index 2a727ac7e..22ee76d75 100644 --- a/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp @@ -23,19 +23,19 @@ #include "NULLMidiIn.h" NULLMidiIn::NULLMidiIn() -{ -}; +{} NULLMidiIn::~NULLMidiIn() -{ -}; +{} /* * Get the midi command,channel and parameters * It returns MidiNull because it is a dummy driver */ -void NULLMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams) +void NULLMidiIn::getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams) { - cmdtype=MidiNull; -}; + cmdtype = MidiNull; +} diff --git a/plugins/zynaddsubfx/src/Input/NULLMidiIn.h b/plugins/zynaddsubfx/src/Input/NULLMidiIn.h index 636302c57..72cef4ad0 100644 --- a/plugins/zynaddsubfx/src/Input/NULLMidiIn.h +++ b/plugins/zynaddsubfx/src/Input/NULLMidiIn.h @@ -29,19 +29,21 @@ /**a dummy Midi port*/ class NULLMidiIn:public MidiIn { -public: - /**Dummy Constructor - * \todo see if the default constructor would work here*/ - NULLMidiIn(); - /**Dummy Destructor - * \todo see if the default destructor would work here*/ - ~NULLMidiIn(); - /**Get the midi command,channel and parameters - * It returns MidiNull because it is a dummy driver - */ - void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); + public: + /**Dummy Constructor + * \todo see if the default constructor would work here*/ + NULLMidiIn(); + /**Dummy Destructor + * \todo see if the default destructor would work here*/ + ~NULLMidiIn(); + /**Get the midi command,channel and parameters + * It returns MidiNull because it is a dummy driver + */ + void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams); -private: + private: }; #endif diff --git a/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp b/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp index 440775abd..b278ae6bf 100644 --- a/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp @@ -33,88 +33,91 @@ OSSMidiIn::OSSMidiIn() { - inputok=false; - midi_handle=open(config.cfg.LinuxOSSSeqInDev,O_RDONLY,0); - if (midi_handle!=-1) inputok=true; + inputok = false; + midi_handle = open(config.cfg.LinuxOSSSeqInDev, O_RDONLY, 0); + if(midi_handle != -1) + inputok = true; - lastmidicmd=0; - cmdtype=0; - cmdchan=0; - -}; + lastmidicmd = 0; + cmdtype = 0; + cmdchan = 0; +} OSSMidiIn::~OSSMidiIn() { close(midi_handle); -}; +} unsigned char OSSMidiIn::readbyte() { unsigned char tmp[4]; - read(midi_handle,&tmp[0],1); - while (tmp[0]!=SEQ_MIDIPUTC) { - read(midi_handle,&tmp[0],4); + read(midi_handle, &tmp[0], 1); + while(tmp[0] != SEQ_MIDIPUTC) { + read(midi_handle, &tmp[0], 4); } - return(tmp[1]); -}; + return tmp[1]; +} unsigned char OSSMidiIn::getmidibyte() { unsigned char b; do { - b=readbyte(); - } while (b==0xfe);//drops the Active Sense Messages - return(b); -}; + b = readbyte(); + } while(b == 0xfe); //drops the Active Sense Messages + return b; +} /* * Get the midi command,channel and parameters */ -void OSSMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams) +void OSSMidiIn::getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams) { - unsigned char tmp,i; - if (inputok==false) { - cmdtype=MidiNull; + unsigned char tmp, i; + if(inputok == false) { + cmdtype = MidiNull; return; } - i=0; - if (lastmidicmd==0) {//asteapta prima data pana cand vine prima comanda midi - while (tmp<0x80) tmp=getmidibyte(); - lastmidicmd=tmp; + i = 0; + if(lastmidicmd == 0) { //asteapta prima data pana cand vine prima comanda midi + while(tmp < 0x80) + tmp = getmidibyte(); + lastmidicmd = tmp; } - tmp=getmidibyte(); + tmp = getmidibyte(); - if (tmp>=0x80) { - lastmidicmd=tmp; - tmp=getmidibyte(); + if(tmp >= 0x80) { + lastmidicmd = tmp; + tmp = getmidibyte(); } - if ((lastmidicmd>=0x80)&&(lastmidicmd<=0x8f)) {//Note OFF - cmdtype=MidiNoteOFF; - cmdchan=lastmidicmd%16; - cmdparams[0]=tmp;//note number + if((lastmidicmd >= 0x80) && (lastmidicmd <= 0x8f)) { //Note OFF + cmdtype = MidiNoteOFF; + cmdchan = lastmidicmd % 16; + cmdparams[0] = tmp; //note number } - if ((lastmidicmd>=0x90)&&(lastmidicmd<=0x9f)) {//Note ON - cmdtype=MidiNoteON; - cmdchan=lastmidicmd%16; - cmdparams[0]=tmp;//note number - cmdparams[1]=getmidibyte();//velocity - if (cmdparams[1]==0) cmdtype=MidiNoteOFF;//if velocity==0 then is note off + if((lastmidicmd >= 0x90) && (lastmidicmd <= 0x9f)) { //Note ON + cmdtype = MidiNoteON; + cmdchan = lastmidicmd % 16; + cmdparams[0] = tmp; //note number + cmdparams[1] = getmidibyte(); //velocity + if(cmdparams[1] == 0) + cmdtype = MidiNoteOFF; //if velocity==0 then is note off } - if ((lastmidicmd>=0xB0)&&(lastmidicmd<=0xBF)) {//Controllers - cmdtype=MidiController; - cmdchan=lastmidicmd%16; - cmdparams[0]=getcontroller(tmp); - cmdparams[1]=getmidibyte(); + if((lastmidicmd >= 0xB0) && (lastmidicmd <= 0xBF)) { //Controllers + cmdtype = MidiController; + cmdchan = lastmidicmd % 16; + cmdparams[0] = getcontroller(tmp); + cmdparams[1] = getmidibyte(); } - if ((lastmidicmd>=0xE0)&&(lastmidicmd<=0xEF)) {//Pitch Wheel - cmdtype=MidiController; - cmdchan=lastmidicmd%16; - cmdparams[0]=C_pitchwheel; - cmdparams[1]=(tmp+getmidibyte()*(int) 128)-8192;//hope this is correct + if((lastmidicmd >= 0xE0) && (lastmidicmd <= 0xEF)) { //Pitch Wheel + cmdtype = MidiController; + cmdchan = lastmidicmd % 16; + cmdparams[0] = C_pitchwheel; + cmdparams[1] = (tmp + getmidibyte() * (int) 128) - 8192; //hope this is correct } -}; - +} diff --git a/plugins/zynaddsubfx/src/Input/OSSMidiIn.h b/plugins/zynaddsubfx/src/Input/OSSMidiIn.h index 7626950ed..a3b56f51b 100644 --- a/plugins/zynaddsubfx/src/Input/OSSMidiIn.h +++ b/plugins/zynaddsubfx/src/Input/OSSMidiIn.h @@ -27,21 +27,22 @@ class OSSMidiIn:public MidiIn { -public: - OSSMidiIn(); - ~OSSMidiIn(); - unsigned char getmidibyte(); - unsigned char readbyte(); + public: + OSSMidiIn(); + ~OSSMidiIn(); + unsigned char getmidibyte(); + unsigned char readbyte(); - //Midi parser - void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); - unsigned char cmdtype;//the Message Type (noteon,noteof,sysex..) - unsigned char cmdchan;//the channel number - -private: - int midi_handle; - unsigned char lastmidicmd;//last byte (>=80) received from the Midi + //Midi parser + void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams); + unsigned char cmdtype; //the Message Type (noteon,noteof,sysex..) + unsigned char cmdchan; //the channel number + private: + int midi_handle; + unsigned char lastmidicmd; //last byte (>=80) received from the Midi }; diff --git a/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp b/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp index 155aa7375..e8462457d 100644 --- a/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp @@ -32,56 +32,63 @@ Master *winmaster; HMIDIIN winmidiinhandle; -MidiIn midictl;//used to convert the controllers to ZynAddSubFX controllers +MidiIn midictl; //used to convert the controllers to ZynAddSubFX controllers -void CALLBACK WinMidiInProc(HMIDIIN hMidiIn,UINT wMsg,DWORD dwInstance, - DWORD dwParam1,DWORD dwParam2) +void CALLBACK WinMidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, + DWORD dwParam1, DWORD dwParam2) { - int midicommand=MidiNull; - if (wMsg==MIM_DATA) { - int cmd,par1,par2; - cmd=dwParam1&0xff; - if (cmd==0xfe) return; - par1=(dwParam1>>8)&0xff; - par2=dwParam1>>16; + int midicommand = MidiNull; + if(wMsg == MIM_DATA) { + int cmd, par1, par2; + cmd = dwParam1 & 0xff; + if(cmd == 0xfe) + return; + par1 = (dwParam1 >> 8) & 0xff; + par2 = dwParam1 >> 16; //printf("%x %x %x\n",cmd,par1,par2);fflush(stdout); - int cmdchan=cmd&0x0f; - int cmdtype=(cmd>>4)&0x0f; + int cmdchan = cmd & 0x0f; + int cmdtype = (cmd >> 4) & 0x0f; - int tmp=0; + int tmp = 0; pthread_mutex_lock(&winmaster->mutex); - switch (cmdtype) { - case(0x8)://noteon - winmaster->NoteOff(cmdchan,par1); + switch(cmdtype) { + case (0x8): //noteon + winmaster->NoteOff(cmdchan, par1); break; - case(0x9)://noteoff - winmaster->NoteOn(cmdchan,par1,par2&0xff); + case (0x9): //noteoff + winmaster->NoteOn(cmdchan, par1, par2 & 0xff); break; - case(0xb)://controller - winmaster->SetController(cmdchan,midictl.getcontroller(par1),par2&0xff); + case (0xb): //controller + winmaster->SetController(cmdchan, midictl.getcontroller( + par1), par2 & 0xff); break; - case(0xe)://pitch wheel - tmp=(par1+par2*(long int) 128)-8192; - winmaster->SetController(cmdchan,C_pitchwheel,tmp); + case (0xe): //pitch wheel + tmp = (par1 + par2 * (long int) 128) - 8192; + winmaster->SetController(cmdchan, C_pitchwheel, tmp); break; default: break; - }; + } pthread_mutex_unlock(&winmaster->mutex); - - }; -}; + } +} void InitWinMidi(Master *master_) { - winmaster=master_; + winmaster = master_; - long int result=midiInOpen(&winmidiinhandle,config.cfg.WindowsMidiInId,(DWORD)WinMidiInProc,0,CALLBACK_FUNCTION); - result=midiInStart(winmidiinhandle); -}; + long int result = + midiInOpen(&winmidiinhandle, + config.cfg.WindowsMidiInId, + (DWORD)WinMidiInProc, + 0, + CALLBACK_FUNCTION); + result = midiInStart(winmidiinhandle); +} void StopWinMidi() { midiInStop(winmidiinhandle); midiInClose(winmidiinhandle); -}; +} + diff --git a/plugins/zynaddsubfx/src/Misc/Bank.cpp b/plugins/zynaddsubfx/src/Misc/Bank.cpp index 4c1b27a96..256184736 100644 --- a/plugins/zynaddsubfx/src/Misc/Bank.cpp +++ b/plugins/zynaddsubfx/src/Misc/Bank.cpp @@ -41,183 +41,213 @@ Bank::Bank() { + ZERO(defaultinsname, PART_MAX_NAME_LEN); + snprintf(defaultinsname, PART_MAX_NAME_LEN, "%s", " "); - - ZERO(defaultinsname,PART_MAX_NAME_LEN); - snprintf(defaultinsname,PART_MAX_NAME_LEN,"%s"," "); - - for (int i=0;i=0) snprintf(tmpfilename,100,"%4d-%s",newslot+1,newname); - else snprintf(tmpfilename,100,"%4d-%s",ninstrument+1,newname); + ZERO(newfilename, 1001); + ZERO(tmpfilename, 101); + if(newslot >= 0) + snprintf(tmpfilename, 100, "%4d-%s", newslot + 1, newname); + else + snprintf(tmpfilename, 100, "%4d-%s", ninstrument + 1, newname); //add the zeroes at the start of filename - for (int i=0;i<4;i++) if (tmpfilename[i]==' ') tmpfilename[i]='0'; + for(int i = 0; i < 4; i++) + if(tmpfilename[i] == ' ') + tmpfilename[i] = '0'; //make the filenames legal - for (int i=0;i<(int) strlen(tmpfilename);i++) { - char c=tmpfilename[i]; - if ((c>='0')&&(c<='9')) continue; - if ((c>='A')&&(c<='Z')) continue; - if ((c>='a')&&(c<='z')) continue; - if ((c=='-')||(c==' ')) continue; + for(int i = 0; i < (int) strlen(tmpfilename); i++) { + char c = tmpfilename[i]; + if((c >= '0') && (c <= '9')) + continue; + if((c >= 'A') && (c <= 'Z')) + continue; + if((c >= 'a') && (c <= 'z')) + continue; + if((c == '-') || (c == ' ')) + continue; - tmpfilename[i]='_'; - }; + tmpfilename[i] = '_'; + } - snprintf(newfilename,1000,"%s/%s.xiz",dirname,tmpfilename); + snprintf(newfilename, 1000, "%s/%s.xiz", dirname, tmpfilename); // printf("rename %s -> %s\n",ins[ninstrument].filename,newfilename);////////////// - rename(ins[ninstrument].filename,newfilename); - if (ins[ninstrument].filename) delete []ins[ninstrument].filename; - ins[ninstrument].filename=new char[strlen(newfilename)+5]; - snprintf(ins[ninstrument].filename,strlen(newfilename)+1,"%s",newfilename); - snprintf(ins[ninstrument].name,PART_MAX_NAME_LEN,"%s",&tmpfilename[5]); - -}; + rename(ins[ninstrument].filename, newfilename); + if(ins[ninstrument].filename) + delete [] ins[ninstrument].filename; + ins[ninstrument].filename = new char[strlen(newfilename) + 5]; + snprintf(ins[ninstrument].filename, strlen( + newfilename) + 1, "%s", newfilename); + snprintf(ins[ninstrument].name, PART_MAX_NAME_LEN, "%s", &tmpfilename[5]); +} /* * Check if there is no instrument on a slot from the bank */ int Bank::emptyslot(unsigned int ninstrument) { - if (ninstrument>=BANK_SIZE) return (1); - if (ins[ninstrument].filename==NULL) return(1); + if(ninstrument >= BANK_SIZE) + return 1; + if(ins[ninstrument].filename == NULL) + return 1; - if (ins[ninstrument].used) return (0); - else return(1); -}; + if(ins[ninstrument].used) + return 0; + else + return 1; +} /* * Removes the instrument from the bank */ void Bank::clearslot(unsigned int ninstrument) { - if (emptyslot(ninstrument)) return; + if(emptyslot(ninstrument)) + return; // printf("remove %s \n",ins[ninstrument].filename);//////////////////////// remove(ins[ninstrument].filename); deletefrombank(ninstrument); -}; +} /* * Save the instrument to a slot */ -void Bank::savetoslot(unsigned int ninstrument,Part *part) +void Bank::savetoslot(unsigned int ninstrument, Part *part) { clearslot(ninstrument); - const int maxfilename=200; - char tmpfilename[maxfilename+20]; - ZERO(tmpfilename,maxfilename+20); + const int maxfilename = 200; + char tmpfilename[maxfilename + 20]; + ZERO(tmpfilename, maxfilename + 20); - snprintf(tmpfilename,maxfilename,"%4d-%s",ninstrument+1,(char *)part->Pname); + snprintf(tmpfilename, + maxfilename, + "%4d-%s", + ninstrument + 1, + (char *)part->Pname); //add the zeroes at the start of filename - for (int i=0;i<4;i++) if (tmpfilename[i]==' ') tmpfilename[i]='0'; + for(int i = 0; i < 4; i++) + if(tmpfilename[i] == ' ') + tmpfilename[i] = '0'; //make the filenames legal - for (int i=0;i<(int)strlen(tmpfilename);i++) { - char c=tmpfilename[i]; - if ((c>='0')&&(c<='9')) continue; - if ((c>='A')&&(c<='Z')) continue; - if ((c>='a')&&(c<='z')) continue; - if ((c=='-')||(c==' ')) continue; + for(int i = 0; i < (int)strlen(tmpfilename); i++) { + char c = tmpfilename[i]; + if((c >= '0') && (c <= '9')) + continue; + if((c >= 'A') && (c <= 'Z')) + continue; + if((c >= 'a') && (c <= 'z')) + continue; + if((c == '-') || (c == ' ')) + continue; - tmpfilename[i]='_'; - }; + tmpfilename[i] = '_'; + } - strncat(tmpfilename,".xiz",maxfilename+10); + strncat(tmpfilename, ".xiz", maxfilename + 10); - int fnsize=strlen(dirname)+strlen(tmpfilename)+10; - char *filename=new char[fnsize+4]; - ZERO(filename,fnsize+2); + int fnsize = strlen(dirname) + strlen(tmpfilename) + 10; + char *filename = new char[fnsize + 4]; + ZERO(filename, fnsize + 2); - snprintf(filename,fnsize,"%s/%s",dirname,tmpfilename); + snprintf(filename, fnsize, "%s/%s", dirname, tmpfilename); remove(filename); part->saveXML(filename); - addtobank(ninstrument,tmpfilename,(char *) part->Pname); + addtobank(ninstrument, tmpfilename, (char *) part->Pname); - delete[]filename; -}; + delete[] filename; +} /* * Loads the instrument from the bank */ -void Bank::loadfromslot(unsigned int ninstrument,Part *part) +void Bank::loadfromslot(unsigned int ninstrument, Part *part) { - if (emptyslot(ninstrument)) return; + if(emptyslot(ninstrument)) + return; part->defaultsinstrument(); // printf("load: %s\n",ins[ninstrument].filename); part->loadXMLinstrument(ins[ninstrument].filename); - -}; +} /* @@ -225,160 +255,173 @@ void Bank::loadfromslot(unsigned int ninstrument,Part *part) */ int Bank::loadbank(const char *bankdirname) { - DIR *dir=opendir(bankdirname); + DIR *dir = opendir(bankdirname); clearbank(); - if (dir==NULL) return(-1); + if(dir == NULL) + return -1; - if (dirname!=NULL) delete[]dirname; - dirname=new char[strlen(bankdirname)+1]; - snprintf(dirname,strlen(bankdirname)+1,"%s",bankdirname); + if(dirname != NULL) + delete[] dirname; + dirname = new char[strlen(bankdirname) + 1]; + snprintf(dirname, strlen(bankdirname) + 1, "%s", bankdirname); - bankfiletitle=dirname; + bankfiletitle = dirname; // printf("loadbank %s/\n",bankdirname); struct dirent *fn; - while ((fn=readdir(dir))) { - const char *filename= fn->d_name; + while((fn = readdir(dir))) { + const char *filename = fn->d_name; //sa verific daca e si extensia dorita - if (strstr(filename,INSTRUMENT_EXTENSION)==NULL) continue; + if(strstr(filename, INSTRUMENT_EXTENSION) == NULL) + continue; //verify if the name is like this NNNN-name (where N is a digit) - int no=0; - unsigned int startname=0; + int no = 0; + unsigned int startname = 0; - for (unsigned int i=0;i<4;i++) { - if (strlen(filename)<=i) break; + for(unsigned int i = 0; i < 4; i++) { + if(strlen(filename) <= i) + break; - if ((filename[i]>='0')&&(filename[i]<='9')) { - no=no*10+(filename[i]-'0'); + if((filename[i] >= '0') && (filename[i] <= '9')) { + no = no * 10 + (filename[i] - '0'); startname++; - }; - }; + } + } - if ((startname+1)=2;i--) { - if (name[i]=='.') { - name[i]='\0'; + for(int i = strlen(name) - 1; i >= 2; i--) { + if(name[i] == '.') { + name[i] = '\0'; break; - }; - }; + } + } - if (no!=0) {//the instrument position in the bank is found - addtobank(no-1,filename,&name[startname]); - } else { - addtobank(-1,filename,name); - }; - - }; + if(no != 0) //the instrument position in the bank is found + addtobank(no - 1, filename, &name[startname]); + else + addtobank(-1, filename, name); + ; + } closedir(dir); - if (dirname!=NULL) { - sprintf(config.cfg.currentBankDir,"%s",dirname); - }; + if(dirname != NULL) + sprintf(config.cfg.currentBankDir, "%s", dirname); + ; - return(0); -}; + return 0; +} /* * Makes a new bank, put it on a file and makes it current bank */ int Bank::newbank(const char *newbankdirname) { - int result; + int result; char tmpfilename[MAX_STRING_SIZE]; char bankdir[MAX_STRING_SIZE]; - snprintf(bankdir,MAX_STRING_SIZE,"%s",config.cfg.bankRootDirList[0]); + snprintf(bankdir, MAX_STRING_SIZE, "%s", config.cfg.bankRootDirList[0]); - if (((bankdir[strlen(bankdir)-1])!='/')&&((bankdir[strlen(bankdir)-1])!='\\')) { - strncat(bankdir,"/",MAX_STRING_SIZE); - }; - strncat(bankdir,newbankdirname,MAX_STRING_SIZE); + if(((bankdir[strlen(bankdir) - 1]) != '/') + && ((bankdir[strlen(bankdir) - 1]) != '\\')) + strncat(bankdir, "/", MAX_STRING_SIZE); + ; + strncat(bankdir, newbankdirname, MAX_STRING_SIZE); #ifdef OS_WINDOWS - result=mkdir(bankdir); + result = mkdir(bankdir); #else - result=mkdir(bankdir,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + result = mkdir(bankdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); #endif - if (result<0) return(-1); + if(result < 0) + return -1; - snprintf(tmpfilename,MAX_STRING_SIZE,"%s/%s",bankdir,FORCE_BANK_DIR_FILE); + snprintf(tmpfilename, + MAX_STRING_SIZE, + "%s/%s", + bankdir, + FORCE_BANK_DIR_FILE); // printf("%s\n",tmpfilename); - FILE *tmpfile=fopen(tmpfilename,"w+"); + FILE *tmpfile = fopen(tmpfilename, "w+"); fclose(tmpfile); - return(loadbank(bankdir)); -}; + return loadbank(bankdir); +} /* * Check if the bank is locked (i.e. the file opened was readonly) */ int Bank::locked() { - return(dirname==NULL); -}; + return dirname == NULL; +} /* * Swaps a slot with another */ void Bank::swapslot(unsigned int n1, unsigned int n2) { - if ((n1==n2)||(locked())) return; - if (emptyslot(n1)&&(emptyslot(n2))) return; - if (emptyslot(n1)) {//change n1 to n2 in order to make - int tmp=n2; - n2=n1; - n1=tmp; - }; + if((n1 == n2) || (locked())) + return; + if(emptyslot(n1) && (emptyslot(n2))) + return; + if(emptyslot(n1)) { //change n1 to n2 in order to make + int tmp = n2; + n2 = n1; + n1 = tmp; + } - if (emptyslot(n2)) {//this is just a movement from slot1 to slot2 - setname(n1,getname(n1),n2); - ins[n2]=ins[n1]; - ins[n1].used=false; - ins[n1].name[0]='\0'; - ins[n1].filename=NULL; - ins[n1].info.PADsynth_used=0; - } else {//if both slots are used - if (strcmp(ins[n1].name,ins[n2].name)==0) {//change the name of the second instrument if the name are equal - strncat(ins[n2].name,"2",PART_MAX_NAME_LEN); - }; - setname(n1,getname(n1),n2); - setname(n2,getname(n2),n1); + if(emptyslot(n2)) { //this is just a movement from slot1 to slot2 + setname(n1, getname(n1), n2); + ins[n2] = ins[n1]; + ins[n1].used = false; + ins[n1].name[0] = '\0'; + ins[n1].filename = NULL; + ins[n1].info.PADsynth_used = 0; + } + else { //if both slots are used + if(strcmp(ins[n1].name, ins[n2].name) == 0) //change the name of the second instrument if the name are equal + strncat(ins[n2].name, "2", PART_MAX_NAME_LEN); + ; + setname(n1, getname(n1), n2); + setname(n2, getname(n2), n1); ins_t tmp; - tmp.used=true; - strcpy(tmp.name,ins[n2].name); - char *tmpfilename=ins[n2].filename; - bool padsynth_used=ins[n2].info.PADsynth_used; + tmp.used = true; + strcpy(tmp.name, ins[n2].name); + char *tmpfilename = ins[n2].filename; + bool padsynth_used = ins[n2].info.PADsynth_used; - ins[n2]=ins[n1]; - strcpy(ins[n1].name,tmp.name); - ins[n1].filename=tmpfilename; - ins[n1].info.PADsynth_used=padsynth_used; - }; - -}; + ins[n2] = ins[n1]; + strcpy(ins[n1].name, tmp.name); + ins[n1].filename = tmpfilename; + ins[n1].info.PADsynth_used = padsynth_used; + } +} //a helper function that compares 2 banks[] arrays -int Bank_compar(const void *a,const void *b) +int Bank_compar(const void *a, const void *b) { - struct Bank::bankstruct *bank1= (Bank::bankstruct *)a; - struct Bank::bankstruct *bank2= (Bank::bankstruct *)b; - if (((bank1->name)==NULL)||((bank2->name)==NULL)) return(0); + struct Bank::bankstruct *bank1 = (Bank::bankstruct *)a; + struct Bank::bankstruct *bank2 = (Bank::bankstruct *)b; + if(((bank1->name) == NULL) || ((bank2->name) == NULL)) + return 0; - int result=strcasecmp(bank1->name,bank2->name); - return(result<0); -}; + int result = strcasecmp(bank1->name, bank2->name); + return result < 0; +} /* @@ -387,56 +430,61 @@ int Bank_compar(const void *a,const void *b) void Bank::rescanforbanks() { - for (int i=0;id_name; - if (dirname[0]=='.') continue; + while((fn = readdir(dir))) { + const char *dirname = fn->d_name; + if(dirname[0] == '.') + continue; - snprintf(bank.dir,maxdirsize,"%s%s%s/",rootdir,separator,dirname); - snprintf(bank.name,maxdirsize,"%s",dirname); + snprintf(bank.dir, maxdirsize, "%s%s%s/", rootdir, separator, dirname); + snprintf(bank.name, maxdirsize, "%s", dirname); //find out if the directory contains at least 1 instrument - bool isbank=false; + bool isbank = false; - DIR *d=opendir(bank.dir); - if (d==NULL) continue; + DIR *d = opendir(bank.dir); + if(d == NULL) + continue; struct dirent *fname; - while ((fname=readdir(d))) { - if ((strstr(fname->d_name,INSTRUMENT_EXTENSION)!=NULL)|| - (strstr(fname->d_name,FORCE_BANK_DIR_FILE)!=NULL)) { - isbank=true; - break;//aici as putea pune in loc de break un update la un counter care imi arata nr. de instrumente din bank - }; - }; + while((fname = readdir(d))) { + if((strstr(fname->d_name, INSTRUMENT_EXTENSION) != NULL) + || (strstr(fname->d_name, FORCE_BANK_DIR_FILE) != NULL)) { + isbank = true; + break; //aici as putea pune in loc de break un update la un counter care imi arata nr. de instrumente din bank + } + } closedir(d); - if (isbank) { - int pos=-1; - for (int i=1;i=0) { - banks[pos].name=new char[maxdirsize]; - banks[pos].dir=new char[maxdirsize]; - snprintf(banks[pos].name,maxdirsize,"%s",bank.name); - snprintf(banks[pos].dir,maxdirsize,"%s",bank.dir); - }; - - }; - - }; + if(pos >= 0) { + banks[pos].name = new char[maxdirsize]; + banks[pos].dir = new char[maxdirsize]; + snprintf(banks[pos].name, maxdirsize, "%s", bank.name); + snprintf(banks[pos].dir, maxdirsize, "%s", bank.dir); + } + } + } closedir(dir); - -}; +} void Bank::clearbank() { - for (int i=0;i=0)&&(pos=BANK_SIZE) pos=-1; + if((pos >= 0) && (pos < BANK_SIZE)) { + if(ins[pos].used) + pos = -1; //force it to find a new free position + } + else + if(pos >= BANK_SIZE) + pos = -1; - if (pos<0) {//find a free position - for (int i=BANK_SIZE-1;i>=0;i--) - if (!ins[i].used) { - pos=i; + if(pos < 0) { //find a free position + for(int i = BANK_SIZE - 1; i >= 0; i--) + if(!ins[i].used) { + pos = i; break; - }; + } + ; + } - }; - - if (pos<0) return (-1);//the bank is full + if(pos < 0) + return -1; //the bank is full // printf("%s %d\n",filename,pos); deletefrombank(pos); - ins[pos].used=true; - snprintf(ins[pos].name,PART_MAX_NAME_LEN,"%s",name); + ins[pos].used = true; + snprintf(ins[pos].name, PART_MAX_NAME_LEN, "%s", name); - snprintf(tmpinsname[pos],PART_MAX_NAME_LEN+10," "); + snprintf(tmpinsname[pos], PART_MAX_NAME_LEN + 10, " "); - int len=strlen(filename)+1+strlen(dirname); - ins[pos].filename=new char[len+2]; - ins[pos].filename[len+1]=0; - snprintf(ins[pos].filename,len+1,"%s/%s",dirname,filename); + int len = strlen(filename) + 1 + strlen(dirname); + ins[pos].filename = new char[len + 2]; + ins[pos].filename[len + 1] = 0; + snprintf(ins[pos].filename, len + 1, "%s/%s", dirname, filename); //see if PADsynth is used - if (config.cfg.CheckPADsynth) { - XMLwrapper *xml=new XMLwrapper(); - xml->checkfileinformation(ins[pos].filename); + if(config.cfg.CheckPADsynth) { + XMLwrapper *xml = new XMLwrapper(); + xml->loadXMLfile(ins[pos].filename); - ins[pos].info.PADsynth_used=xml->information.PADsynth_used; + ins[pos].info.PADsynth_used = xml->hasPadSynth(); delete xml; - } else ins[pos].info.PADsynth_used=false; + } + else + ins[pos].info.PADsynth_used = false; - return(0); -}; + return 0; +} bool Bank::isPADsynth_used(unsigned int ninstrument) { - if (config.cfg.CheckPADsynth==0) return(0); - else return(ins[ninstrument].info.PADsynth_used); -}; + if(config.cfg.CheckPADsynth == 0) + return 0; + else + return ins[ninstrument].info.PADsynth_used; +} void Bank::deletefrombank(int pos) { - if ((pos<0)||(pos>=BANK_SIZE)) return; - ins[pos].used=false; - ZERO(ins[pos].name,PART_MAX_NAME_LEN+1); - if (ins[pos].filename!=NULL) { - delete []ins[pos].filename; - ins[pos].filename=NULL; - }; + if((pos < 0) || (pos >= BANK_SIZE)) + return; + ins[pos].used = false; + ZERO(ins[pos].name, PART_MAX_NAME_LEN + 1); + if(ins[pos].filename != NULL) { + delete [] ins[pos].filename; + ins[pos].filename = NULL; + } - ZERO(tmpinsname[pos],PART_MAX_NAME_LEN+20); - -}; + ZERO(tmpinsname[pos], PART_MAX_NAME_LEN + 20); +} diff --git a/plugins/zynaddsubfx/src/Misc/Bank.h b/plugins/zynaddsubfx/src/Misc/Bank.h index 8359b541b..81acc3dec 100644 --- a/plugins/zynaddsubfx/src/Misc/Bank.h +++ b/plugins/zynaddsubfx/src/Misc/Bank.h @@ -38,70 +38,70 @@ * \todo add in strings to replace char* */ class Bank { -public: - /**Constructor*/ - Bank(); - ~Bank(); - char *getname(unsigned int ninstrument); - char *getnamenumbered(unsigned int ninstrument); - void setname(unsigned int ninstrument,const char *newname,int newslot);//if newslot==-1 then this is ignored, else it will be put on that slot - bool isPADsynth_used(unsigned int ninstrument); + public: + /**Constructor*/ + Bank(); + ~Bank(); + char *getname(unsigned int ninstrument); + char *getnamenumbered(unsigned int ninstrument); + void setname(unsigned int ninstrument, const char *newname, int newslot); //if newslot==-1 then this is ignored, else it will be put on that slot + bool isPADsynth_used(unsigned int ninstrument); - /**returns 0 if the slot is not empty or 1 if the slot is empty - * \todo start using bool before facepalm*/ - int emptyslot(unsigned int ninstrument); + /**returns 0 if the slot is not empty or 1 if the slot is empty + * \todo start using bool before facepalm*/ + int emptyslot(unsigned int ninstrument); - /**Empties out the selected slot*/ - void clearslot(unsigned int ninstrument); - /**Saves the given Part to slot*/ - void savetoslot(unsigned int ninstrument,Part *part); - /**Loads the given slot into a Part*/ - void loadfromslot(unsigned int ninstrument,Part *part); + /**Empties out the selected slot*/ + void clearslot(unsigned int ninstrument); + /**Saves the given Part to slot*/ + void savetoslot(unsigned int ninstrument, Part *part); + /**Loads the given slot into a Part*/ + void loadfromslot(unsigned int ninstrument, Part *part); - /**Swaps Slots*/ - void swapslot(unsigned int n1,unsigned int n2); + /**Swaps Slots*/ + void swapslot(unsigned int n1, unsigned int n2); - int loadbank(const char *bankdirname); - int newbank(const char *newbankdirname); + int loadbank(const char *bankdirname); + int newbank(const char *newbankdirname); - char *bankfiletitle; //this is shown on the UI of the bank (the title of the window) - int locked(); + char *bankfiletitle; //this is shown on the UI of the bank (the title of the window) + int locked(); - void rescanforbanks(); + void rescanforbanks(); - struct bankstruct { - char *dir; - char *name; - }; + struct bankstruct { + char *dir; + char *name; + }; - bankstruct banks[MAX_NUM_BANKS]; + bankstruct banks[MAX_NUM_BANKS]; -private: + private: - //it adds a filename to the bank - //if pos is -1 it try to find a position - //returns -1 if the bank is full, or 0 if the instrument was added - int addtobank(int pos,const char* filename,const char* name); + //it adds a filename to the bank + //if pos is -1 it try to find a position + //returns -1 if the bank is full, or 0 if the instrument was added + int addtobank(int pos, const char *filename, const char *name); - void deletefrombank(int pos); + void deletefrombank(int pos); - void clearbank(); + void clearbank(); - char defaultinsname[PART_MAX_NAME_LEN]; - char tmpinsname[BANK_SIZE][PART_MAX_NAME_LEN+20];//this keeps the numbered names + char defaultinsname[PART_MAX_NAME_LEN]; + char tmpinsname[BANK_SIZE][PART_MAX_NAME_LEN + 20]; //this keeps the numbered names - struct ins_t { - bool used; - char name[PART_MAX_NAME_LEN+1]; - char *filename; - struct { - bool PADsynth_used; - } info; - }ins[BANK_SIZE]; + struct ins_t { + bool used; + char name[PART_MAX_NAME_LEN + 1]; + char *filename; + struct { + bool PADsynth_used; + } info; + } ins[BANK_SIZE]; - char *dirname; + char *dirname; - void scanrootdir(char *rootdir);//scans a root dir for banks + void scanrootdir(char *rootdir); //scans a root dir for banks }; #endif diff --git a/plugins/zynaddsubfx/src/Misc/Config.cpp b/plugins/zynaddsubfx/src/Misc/Config.cpp index 9a290158c..94966e4af 100644 --- a/plugins/zynaddsubfx/src/Misc/Config.cpp +++ b/plugins/zynaddsubfx/src/Misc/Config.cpp @@ -33,309 +33,369 @@ #include "XMLwrapper.h" Config::Config() -{ -}; +{} void Config::init() { - maxstringsize=MAX_STRING_SIZE;//for ui + maxstringsize = MAX_STRING_SIZE; //for ui //defaults - cfg.SampleRate=44100; - cfg.SoundBufferSize=256; - cfg.OscilSize=1024; - cfg.SwapStereo=0; + cfg.SampleRate = 44100; + cfg.SoundBufferSize = 256; + cfg.OscilSize = 1024; + cfg.SwapStereo = 0; - cfg.LinuxOSSWaveOutDev=new char[MAX_STRING_SIZE]; - snprintf(cfg.LinuxOSSWaveOutDev,MAX_STRING_SIZE,"/dev/dsp"); - cfg.LinuxOSSSeqInDev=new char[MAX_STRING_SIZE]; - snprintf(cfg.LinuxOSSSeqInDev,MAX_STRING_SIZE,"/dev/sequencer"); + cfg.LinuxOSSWaveOutDev = new char[MAX_STRING_SIZE]; + snprintf(cfg.LinuxOSSWaveOutDev, MAX_STRING_SIZE, "/dev/dsp"); + cfg.LinuxOSSSeqInDev = new char[MAX_STRING_SIZE]; + snprintf(cfg.LinuxOSSSeqInDev, MAX_STRING_SIZE, "/dev/sequencer"); - cfg.DumpFile=new char[MAX_STRING_SIZE]; - snprintf(cfg.DumpFile,MAX_STRING_SIZE,"zynaddsubfx_dump.txt"); + cfg.DumpFile = new char[MAX_STRING_SIZE]; + snprintf(cfg.DumpFile, MAX_STRING_SIZE, "zynaddsubfx_dump.txt"); - cfg.WindowsWaveOutId=0; - cfg.WindowsMidiInId=0; + cfg.WindowsWaveOutId = 0; + cfg.WindowsMidiInId = 0; - cfg.BankUIAutoClose=0; - cfg.DumpNotesToFile=0; - cfg.DumpAppend=1; + cfg.BankUIAutoClose = 0; + cfg.DumpNotesToFile = 0; + cfg.DumpAppend = 1; - cfg.GzipCompression=3; + cfg.GzipCompression = 3; - cfg.Interpolation=0; - cfg.CheckPADsynth=1; + cfg.Interpolation = 0; + cfg.CheckPADsynth = 1; - cfg.UserInterfaceMode=0; - cfg.VirKeybLayout=1; - winwavemax=1; - winmidimax=1; + cfg.UserInterfaceMode = 0; + cfg.VirKeybLayout = 1; + winwavemax = 1; + winmidimax = 1; //try to find out how many input midi devices are there #ifdef WINMIDIIN - winmidimax=midiInGetNumDevs(); - if (winmidimax==0) winmidimax=1; + winmidimax = midiInGetNumDevs(); + if(winmidimax == 0) + winmidimax = 1; #endif - winmididevices=new winmidionedevice[winmidimax]; - for (int i=0;iloadXMLfile(filename)<0) return; - if (xmlcfg->enterbranch("CONFIGURATION")) { - cfg.SampleRate=xmlcfg->getpar("sample_rate",cfg.SampleRate,4000,1024000); - cfg.SoundBufferSize=xmlcfg->getpar("sound_buffer_size",cfg.SoundBufferSize,16,8192); - cfg.OscilSize=xmlcfg->getpar("oscil_size",cfg.OscilSize,MAX_AD_HARMONICS*2,131072); - cfg.SwapStereo=xmlcfg->getpar("swap_stereo",cfg.SwapStereo,0,1); - cfg.BankUIAutoClose=xmlcfg->getpar("bank_window_auto_close",cfg.BankUIAutoClose,0,1); + XMLwrapper *xmlcfg = new XMLwrapper(); + if(xmlcfg->loadXMLfile(filename) < 0) + return; + if(xmlcfg->enterbranch("CONFIGURATION")) { + cfg.SampleRate = xmlcfg->getpar("sample_rate", + cfg.SampleRate, + 4000, + 1024000); + cfg.SoundBufferSize = xmlcfg->getpar("sound_buffer_size", + cfg.SoundBufferSize, + 16, + 8192); + cfg.OscilSize = xmlcfg->getpar("oscil_size", + cfg.OscilSize, + MAX_AD_HARMONICS * 2, + 131072); + cfg.SwapStereo = xmlcfg->getpar("swap_stereo", + cfg.SwapStereo, + 0, + 1); + cfg.BankUIAutoClose = xmlcfg->getpar("bank_window_auto_close", + cfg.BankUIAutoClose, + 0, + 1); - cfg.DumpNotesToFile=xmlcfg->getpar("dump_notes_to_file",cfg.DumpNotesToFile,0,1); - cfg.DumpAppend=xmlcfg->getpar("dump_append",cfg.DumpAppend,0,1); - xmlcfg->getparstr("dump_file",cfg.DumpFile,MAX_STRING_SIZE); + cfg.DumpNotesToFile = xmlcfg->getpar("dump_notes_to_file", + cfg.DumpNotesToFile, + 0, + 1); + cfg.DumpAppend = xmlcfg->getpar("dump_append", + cfg.DumpAppend, + 0, + 1); + xmlcfg->getparstr("dump_file", cfg.DumpFile, MAX_STRING_SIZE); - cfg.GzipCompression=xmlcfg->getpar("gzip_compression",cfg.GzipCompression,0,9); + cfg.GzipCompression = xmlcfg->getpar("gzip_compression", + cfg.GzipCompression, + 0, + 9); - xmlcfg->getparstr("bank_current",cfg.currentBankDir,MAX_STRING_SIZE); - cfg.Interpolation=xmlcfg->getpar("interpolation",cfg.Interpolation,0,1); + xmlcfg->getparstr("bank_current", cfg.currentBankDir, MAX_STRING_SIZE); + cfg.Interpolation = xmlcfg->getpar("interpolation", + cfg.Interpolation, + 0, + 1); - cfg.CheckPADsynth=xmlcfg->getpar("check_pad_synth",cfg.CheckPADsynth,0,1); + cfg.CheckPADsynth = xmlcfg->getpar("check_pad_synth", + cfg.CheckPADsynth, + 0, + 1); - cfg.UserInterfaceMode=xmlcfg->getpar("user_interface_mode",cfg.UserInterfaceMode,0,2); - cfg.VirKeybLayout=xmlcfg->getpar("virtual_keyboard_layout",cfg.VirKeybLayout,0,10); + cfg.UserInterfaceMode = xmlcfg->getpar("user_interface_mode", + cfg.UserInterfaceMode, + 0, + 2); + cfg.VirKeybLayout = xmlcfg->getpar("virtual_keyboard_layout", + cfg.VirKeybLayout, + 0, + 10); //get bankroot dirs - for (int i=0;ienterbranch("BANKROOT",i)) { - cfg.bankRootDirList[i]=new char[MAX_STRING_SIZE]; - xmlcfg->getparstr("bank_root",cfg.bankRootDirList[i],MAX_STRING_SIZE); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) { + if(xmlcfg->enterbranch("BANKROOT", i)) { + cfg.bankRootDirList[i] = new char[MAX_STRING_SIZE]; + xmlcfg->getparstr("bank_root", + cfg.bankRootDirList[i], + MAX_STRING_SIZE); xmlcfg->exitbranch(); - }; - }; + } + } //get preset root dirs - for (int i=0;ienterbranch("PRESETSROOT",i)) { - cfg.presetsDirList[i]=new char[MAX_STRING_SIZE]; - xmlcfg->getparstr("presets_root",cfg.presetsDirList[i],MAX_STRING_SIZE); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) { + if(xmlcfg->enterbranch("PRESETSROOT", i)) { + cfg.presetsDirList[i] = new char[MAX_STRING_SIZE]; + xmlcfg->getparstr("presets_root", + cfg.presetsDirList[i], + MAX_STRING_SIZE); xmlcfg->exitbranch(); - }; - }; + } + } //linux stuff - xmlcfg->getparstr("linux_oss_wave_out_dev",cfg.LinuxOSSWaveOutDev,MAX_STRING_SIZE); - xmlcfg->getparstr("linux_oss_seq_in_dev",cfg.LinuxOSSSeqInDev,MAX_STRING_SIZE); + xmlcfg->getparstr("linux_oss_wave_out_dev", + cfg.LinuxOSSWaveOutDev, + MAX_STRING_SIZE); + xmlcfg->getparstr("linux_oss_seq_in_dev", + cfg.LinuxOSSSeqInDev, + MAX_STRING_SIZE); //windows stuff - cfg.WindowsWaveOutId=xmlcfg->getpar("windows_wave_out_id",cfg.WindowsWaveOutId,0,winwavemax); - cfg.WindowsMidiInId=xmlcfg->getpar("windows_midi_in_id",cfg.WindowsMidiInId,0,winmidimax); + cfg.WindowsWaveOutId = xmlcfg->getpar("windows_wave_out_id", + cfg.WindowsWaveOutId, + 0, + winwavemax); + cfg.WindowsMidiInId = xmlcfg->getpar("windows_midi_in_id", + cfg.WindowsMidiInId, + 0, + winmidimax); xmlcfg->exitbranch(); - }; - delete(xmlcfg); + } + delete (xmlcfg); - cfg.OscilSize=(int) pow(2,ceil(log (cfg.OscilSize-1.0)/log(2.0))); - -}; + cfg.OscilSize = (int) pow(2, ceil(log(cfg.OscilSize - 1.0) / log(2.0))); +} void Config::saveConfig(const char *filename) { - XMLwrapper *xmlcfg=new XMLwrapper(); + XMLwrapper *xmlcfg = new XMLwrapper(); xmlcfg->beginbranch("CONFIGURATION"); - xmlcfg->addpar("sample_rate",cfg.SampleRate); - xmlcfg->addpar("sound_buffer_size",cfg.SoundBufferSize); - xmlcfg->addpar("oscil_size",cfg.OscilSize); - xmlcfg->addpar("swap_stereo",cfg.SwapStereo); - xmlcfg->addpar("bank_window_auto_close",cfg.BankUIAutoClose); + xmlcfg->addpar("sample_rate", cfg.SampleRate); + xmlcfg->addpar("sound_buffer_size", cfg.SoundBufferSize); + xmlcfg->addpar("oscil_size", cfg.OscilSize); + xmlcfg->addpar("swap_stereo", cfg.SwapStereo); + xmlcfg->addpar("bank_window_auto_close", cfg.BankUIAutoClose); - xmlcfg->addpar("dump_notes_to_file",cfg.DumpNotesToFile); - xmlcfg->addpar("dump_append",cfg.DumpAppend); - xmlcfg->addparstr("dump_file",cfg.DumpFile); + xmlcfg->addpar("dump_notes_to_file", cfg.DumpNotesToFile); + xmlcfg->addpar("dump_append", cfg.DumpAppend); + xmlcfg->addparstr("dump_file", cfg.DumpFile); - xmlcfg->addpar("gzip_compression",cfg.GzipCompression); + xmlcfg->addpar("gzip_compression", cfg.GzipCompression); - xmlcfg->addpar("check_pad_synth",cfg.CheckPADsynth); + xmlcfg->addpar("check_pad_synth", cfg.CheckPADsynth); - xmlcfg->addparstr("bank_current",cfg.currentBankDir); + xmlcfg->addparstr("bank_current", cfg.currentBankDir); - xmlcfg->addpar("user_interface_mode",cfg.UserInterfaceMode); - xmlcfg->addpar("virtual_keyboard_layout",cfg.VirKeybLayout); + xmlcfg->addpar("user_interface_mode", cfg.UserInterfaceMode); + xmlcfg->addpar("virtual_keyboard_layout", cfg.VirKeybLayout); - for (int i=0;ibeginbranch("BANKROOT",i); - xmlcfg->addparstr("bank_root",cfg.bankRootDirList[i]); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) + if(cfg.bankRootDirList[i] != NULL) { + xmlcfg->beginbranch("BANKROOT", i); + xmlcfg->addparstr("bank_root", cfg.bankRootDirList[i]); xmlcfg->endbranch(); - }; + } + ; - for (int i=0;ibeginbranch("PRESETSROOT",i); - xmlcfg->addparstr("presets_root",cfg.presetsDirList[i]); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) + if(cfg.presetsDirList[i] != NULL) { + xmlcfg->beginbranch("PRESETSROOT", i); + xmlcfg->addparstr("presets_root", cfg.presetsDirList[i]); xmlcfg->endbranch(); - }; + } + ; - xmlcfg->addpar("interpolation",cfg.Interpolation); + xmlcfg->addpar("interpolation", cfg.Interpolation); //linux stuff - xmlcfg->addparstr("linux_oss_wave_out_dev",cfg.LinuxOSSWaveOutDev); - xmlcfg->addparstr("linux_oss_seq_in_dev",cfg.LinuxOSSSeqInDev); + xmlcfg->addparstr("linux_oss_wave_out_dev", cfg.LinuxOSSWaveOutDev); + xmlcfg->addparstr("linux_oss_seq_in_dev", cfg.LinuxOSSSeqInDev); //windows stuff - xmlcfg->addpar("windows_wave_out_id",cfg.WindowsWaveOutId); - xmlcfg->addpar("windows_midi_in_id",cfg.WindowsMidiInId); + xmlcfg->addpar("windows_wave_out_id", cfg.WindowsWaveOutId); + xmlcfg->addpar("windows_midi_in_id", cfg.WindowsMidiInId); xmlcfg->endbranch(); - int tmp=cfg.GzipCompression; - cfg.GzipCompression=0; + int tmp = cfg.GzipCompression; + cfg.GzipCompression = 0; xmlcfg->saveXMLfile(filename); - cfg.GzipCompression=tmp; + cfg.GzipCompression = tmp; - delete(xmlcfg); -}; + delete (xmlcfg); +} void Config::getConfigFileName(char *name, int namesize) { - name[0]=0; + name[0] = 0; #ifdef OS_LINUX - snprintf(name,namesize,"%s%s",getenv("HOME"),"/.zynaddsubfxXML.cfg"); + snprintf(name, namesize, "%s%s", getenv("HOME"), "/.zynaddsubfxXML.cfg"); #else - snprintf(name,namesize,"%s","zynaddsubfxXML.cfg"); + snprintf(name, namesize, "%s", "zynaddsubfxXML.cfg"); #endif - -}; +} diff --git a/plugins/zynaddsubfx/src/Misc/Config.h b/plugins/zynaddsubfx/src/Misc/Config.h index 9d4fef615..f08505d80 100644 --- a/plugins/zynaddsubfx/src/Misc/Config.h +++ b/plugins/zynaddsubfx/src/Misc/Config.h @@ -29,43 +29,43 @@ /**Configuration file functions*/ class Config { -public: - /** Constructor*/ - Config(); - /** Destructor*/ - ~Config(); - struct { - char *LinuxOSSWaveOutDev,*LinuxOSSSeqInDev; - int SampleRate,SoundBufferSize,OscilSize,SwapStereo; - int WindowsWaveOutId,WindowsMidiInId; - int BankUIAutoClose; - int DumpNotesToFile,DumpAppend; - int GzipCompression; - int Interpolation; - char *DumpFile; - char *bankRootDirList[MAX_BANK_ROOT_DIRS],*currentBankDir; - char *presetsDirList[MAX_BANK_ROOT_DIRS]; - int CheckPADsynth; - int UserInterfaceMode; - int VirKeybLayout; - } cfg; - int winwavemax,winmidimax;//number of wave/midi devices on Windows - int maxstringsize; + public: + /** Constructor*/ + Config(); + /** Destructor*/ + ~Config(); + struct { + char *LinuxOSSWaveOutDev, *LinuxOSSSeqInDev; + int SampleRate, SoundBufferSize, OscilSize, SwapStereo; + int WindowsWaveOutId, WindowsMidiInId; + int BankUIAutoClose; + int DumpNotesToFile, DumpAppend; + int GzipCompression; + int Interpolation; + char *DumpFile; + char *bankRootDirList[MAX_BANK_ROOT_DIRS], *currentBankDir; + char *presetsDirList[MAX_BANK_ROOT_DIRS]; + int CheckPADsynth; + int UserInterfaceMode; + int VirKeybLayout; + } cfg; + int winwavemax, winmidimax; //number of wave/midi devices on Windows + int maxstringsize; - struct winmidionedevice { - char *name; - }; - winmidionedevice *winmididevices; + struct winmidionedevice { + char *name; + }; + winmidionedevice *winmididevices; - void clearbankrootdirlist(); - void clearpresetsdirlist(); - void init(); - void save(); + void clearbankrootdirlist(); + void clearpresetsdirlist(); + void init(); + void save(); -private: - void readConfig(const char *filename); - void saveConfig(const char *filename); - void getConfigFileName(char *name,int namesize); + private: + void readConfig(const char *filename); + void saveConfig(const char *filename); + void getConfigFileName(char *name, int namesize); }; #endif diff --git a/plugins/zynaddsubfx/src/Misc/Control.h b/plugins/zynaddsubfx/src/Misc/Control.h index 780d4b9e6..297e6f0da 100644 --- a/plugins/zynaddsubfx/src/Misc/Control.h +++ b/plugins/zynaddsubfx/src/Misc/Control.h @@ -27,74 +27,74 @@ class Control { -public: - /** - * The parent is the logical owner of this control. Parent should only - * be null for the root node. - * The id is a string uniquely identifying this control within the - * context of the parent control. No spaces or dots are allowed in this - * id. - * Children id's are denoted by ., so that one - * can refer to any control in the hierarchy by separating them with - * dots. Example: Main.AddSynth.FrequencyLFO.Amplitude - */ - Control(Control *parent, string id); + public: + /** + * The parent is the logical owner of this control. Parent should only + * be null for the root node. + * The id is a string uniquely identifying this control within the + * context of the parent control. No spaces or dots are allowed in this + * id. + * Children id's are denoted by ., so that one + * can refer to any control in the hierarchy by separating them with + * dots. Example: Main.AddSynth.FrequencyLFO.Amplitude + */ + Control(Control *parent, string id); - /** - * Will recursively get the XML representation for all the subcontrols. - * Used for saving to file and copy-pasting settings - */ - string getXMLRepresentation(); + /** + * Will recursively get the XML representation for all the subcontrols. + * Used for saving to file and copy-pasting settings + */ + string getXMLRepresentation(); - /** - * Set the value of this (and possibly subcomponents as well) based on - * a xml description. - */ - void restoreFromXML(string xml); + /** + * Set the value of this (and possibly subcomponents as well) based on + * a xml description. + */ + void restoreFromXML(string xml); - /** - * Register a controluser. This will cause this user to be notified - * whenever the contents of the control changes. - */ - void registerControlUser(ControlUser *user); - - /** - * This should return a string representation of the controls internal - * value - */ - virtual string getStringRepresentation() = 0; + /** + * Register a controluser. This will cause this user to be notified + * whenever the contents of the control changes. + */ + void registerControlUser(ControlUser *user); + /** + * This should return a string representation of the controls internal + * value + */ + virtual string getStringRepresentation() = 0; }; -class FloatControl : public Control +class FloatControl:public Control { -public: - /** - * Set the value of this control. If the ControlUser variable is set, - * then this user will not be updated with the new value. This is to - * avoid setting a value being set back to the source that set it - * (which would be redundant, or possibly causing infinite setValue - * loops). - * NOTE: this function is thread-safe (using a mutex internally) - */ - void setValue(float value, ControlUser *user = NULL); + public: + /** + * Set the value of this control. If the ControlUser variable is set, + * then this user will not be updated with the new value. This is to + * avoid setting a value being set back to the source that set it + * (which would be redundant, or possibly causing infinite setValue + * loops). + * NOTE: this function is thread-safe (using a mutex internally) + */ + void setValue(float value, ControlUser *user = NULL); - /** - * Reimplemented from Control - */ - virtual string getStringRepresentation(); + /** + * Reimplemented from Control + */ + virtual string getStringRepresentation(); - float value(); + float value(); }; class ControlUser { -public: - /** - * Pure virtual method, to notify the controluser that the value has - * been changed internally, and needs to be read again. - */ - virtual void controlUpdated(Control *control) = 0; + public: + /** + * Pure virtual method, to notify the controluser that the value has + * been changed internally, and needs to be read again. + */ + virtual void controlUpdated(Control *control) = 0; }; #endif /* _CONTROL_H_ */ + diff --git a/plugins/zynaddsubfx/src/Misc/Dump.cpp b/plugins/zynaddsubfx/src/Misc/Dump.cpp index cb1728ec6..4c13c9464 100644 --- a/plugins/zynaddsubfx/src/Misc/Dump.cpp +++ b/plugins/zynaddsubfx/src/Misc/Dump.cpp @@ -28,80 +28,97 @@ Dump dump; Dump::Dump() { - file=NULL; - tick=0; - k=0; - keyspressed=0; -}; + file = NULL; + tick = 0; + k = 0; + keyspressed = 0; +} Dump::~Dump() { - if (file!=NULL) { - double duration=(double)tick*(double) SOUND_BUFFER_SIZE/(double) SAMPLE_RATE; - fprintf(file,"\n# statistics: duration = %d seconds; keyspressed = %d\n\n\n\n",(int) duration,keyspressed); + if(file != NULL) { + double duration = (double)tick * (double) SOUND_BUFFER_SIZE + / (double) SAMPLE_RATE; + fprintf( + file, + "\n# statistics: duration = %d seconds; keyspressed = %d\n\n\n\n", + (int) duration, + keyspressed); fclose(file); - }; -}; + } +} void Dump::startnow() { - if (file!=NULL) return;//the file is already open + if(file != NULL) + return; //the file is already open - if (config.cfg.DumpNotesToFile!=0) { - if (config.cfg.DumpAppend!=0) file=fopen(config.cfg.DumpFile,"a"); - else file=fopen(config.cfg.DumpFile,"w"); - if (file==NULL) return; - if (config.cfg.DumpAppend!=0) fprintf(file,"%s","#************************************\n"); + if(config.cfg.DumpNotesToFile != 0) { + if(config.cfg.DumpAppend != 0) + file = fopen(config.cfg.DumpFile, "a"); + else + file = fopen(config.cfg.DumpFile, "w"); + if(file == NULL) + return; + if(config.cfg.DumpAppend != 0) + fprintf(file, "%s", "#************************************\n"); - time_t tm=time(NULL); + time_t tm = time(NULL); - fprintf(file,"#date/time = %s\n",ctime(&tm)); - fprintf(file,"#1 tick = %g milliseconds\n",SOUND_BUFFER_SIZE*1000.0/SAMPLE_RATE); - fprintf(file,"SAMPLERATE = %d\n",SAMPLE_RATE); - fprintf(file,"TICKSIZE = %d #samples\n",SOUND_BUFFER_SIZE); - fprintf(file,"\n\nSTART\n"); - }; -}; + fprintf(file, "#date/time = %s\n", ctime(&tm)); + fprintf(file, + "#1 tick = %g milliseconds\n", + SOUND_BUFFER_SIZE * 1000.0 / SAMPLE_RATE); + fprintf(file, "SAMPLERATE = %d\n", SAMPLE_RATE); + fprintf(file, "TICKSIZE = %d #samples\n", SOUND_BUFFER_SIZE); + fprintf(file, "\n\nSTART\n"); + } +} void Dump::inctick() { tick++; -}; +} -void Dump::dumpnote(char chan,char note, char vel) +void Dump::dumpnote(char chan, char note, char vel) { - if (file==NULL) return; - if (note==0) return; - if (vel==0) fprintf(file,"n %d -> %d %d \n",tick,chan,note);//note off - else fprintf(file,"N %d -> %d %d %d \n",tick,chan,note,vel);//note on + if(file == NULL) + return; + if(note == 0) + return; + if(vel == 0) + fprintf(file, "n %d -> %d %d \n", tick, chan, note); //note off + else + fprintf(file, "N %d -> %d %d %d \n", tick, chan, note, vel); //note on - if (vel!=0) keyspressed++; + if(vel != 0) + keyspressed++; #ifndef JACKAUDIOOUT - if (k++>25) { + if(k++ > 25) { fflush(file); - k=0; - }; + k = 0; + } #endif -}; +} -void Dump::dumpcontroller(char chan,unsigned int type,int par) +void Dump::dumpcontroller(char chan, unsigned int type, int par) { - if (file==NULL) return; - switch (type) { + if(file == NULL) + return; + switch(type) { case C_pitchwheel: - fprintf(file,"P %d -> %d %d\n",tick,chan,par); + fprintf(file, "P %d -> %d %d\n", tick, chan, par); break; default: - fprintf(file,"C %d -> %d %d %d\n",tick,chan,type,par); + fprintf(file, "C %d -> %d %d %d\n", tick, chan, type, par); break; - }; + } #ifndef JACKAUDIOOUT - if (k++>25) { + if(k++ > 25) { fflush(file); - k=0; - }; + k = 0; + } #endif -}; - +} diff --git a/plugins/zynaddsubfx/src/Misc/Dump.h b/plugins/zynaddsubfx/src/Misc/Dump.h index d285eb936..392fd407b 100644 --- a/plugins/zynaddsubfx/src/Misc/Dump.h +++ b/plugins/zynaddsubfx/src/Misc/Dump.h @@ -30,34 +30,35 @@ * \todo upgrade from stdio to iostream*/ class Dump { -public: - /**Constructor*/ - Dump(); - /**Destructor - * Closes the dumpfile*/ - ~Dump(); - /**Open dumpfile and prepare it for dumps - * \todo see if this fits better in the constructor*/ - void startnow(); - /**Tick the timestamp*/ - void inctick(); - /**Dump Note to dumpfile - * @param chan The channel of the note - * @param note The note - * @param vel The velocity of the note*/ - void dumpnote(char chan,char note, char vel); - /** Dump the Controller - * @param chan The channel of the Controller - * @param type The type - * @param par The value of the controller - * \todo figure out what type is exactly meaning*/ - void dumpcontroller(char chan,unsigned int type,int par); + public: + /**Constructor*/ + Dump(); + /**Destructor + * Closes the dumpfile*/ + ~Dump(); + /**Open dumpfile and prepare it for dumps + * \todo see if this fits better in the constructor*/ + void startnow(); + /**Tick the timestamp*/ + void inctick(); + /**Dump Note to dumpfile + * @param chan The channel of the note + * @param note The note + * @param vel The velocity of the note*/ + void dumpnote(char chan, char note, char vel); + /** Dump the Controller + * @param chan The channel of the Controller + * @param type The type + * @param par The value of the controller + * \todo figure out what type is exactly meaning*/ + void dumpcontroller(char chan, unsigned int type, int par); -private: - FILE *file; - int tick; - int k;//This appears to be a constant used to flush the file - //periodically when JACK is used - int keyspressed; + private: + FILE *file; + int tick; + int k; //This appears to be a constant used to flush the file + //periodically when JACK is used + int keyspressed; }; #endif + diff --git a/plugins/zynaddsubfx/src/Misc/LASHClient.cpp b/plugins/zynaddsubfx/src/Misc/LASHClient.cpp index 3434a05fb..a21461f29 100644 --- a/plugins/zynaddsubfx/src/Misc/LASHClient.cpp +++ b/plugins/zynaddsubfx/src/Misc/LASHClient.cpp @@ -26,7 +26,7 @@ #include "LASHClient.h" -LASHClient::LASHClient(int* argc, char*** argv) +LASHClient::LASHClient(int *argc, char ***argv) { client = lash_init(lash_extract_args(argc, argv), "ZynAddSubFX", LASH_Config_File, LASH_PROTOCOL(2, 0)); @@ -35,56 +35,54 @@ LASHClient::LASHClient(int* argc, char*** argv) void LASHClient::setalsaid(int id) { - if (lash_enabled(client)) { - if (id != -1) + if(lash_enabled(client)) + if(id != -1) lash_alsa_client_id(client, id); - } } -void LASHClient::setjackname(const char* name) +void LASHClient::setjackname(const char *name) { - if (lash_enabled(client)) { - if (name != NULL) { + if(lash_enabled(client)) + if(name != NULL) { lash_jack_client_name(client, name); lash_event_t *event = lash_event_new_with_type(LASH_Client_Name); lash_event_set_string(event, name); lash_send_event(client, event); } - } } -LASHClient::Event LASHClient::checkevents(std::string& filename) +LASHClient::Event LASHClient::checkevents(std::string &filename) { - - if (!lash_enabled(client)) + if(!lash_enabled(client)) return NoEvent; Event received = NoEvent; - lash_event_t* event; - while (event = lash_get_event(client)) { - + lash_event_t *event; + while(event = lash_get_event(client)) { // save - if (lash_event_get_type(event) == LASH_Save_File) { - std::cerr<<"LASH event: LASH_Save_File"<defaults(); - part[npart]->Prcvchn=npart%NUM_MIDI_CHANNELS; - }; + part[npart]->Prcvchn = npart % NUM_MIDI_CHANNELS; + } - partonoff(0,1);//enable the first part + partonoff(0, 1); //enable the first part - for (int nefx=0;nefxdefaults(); - Pinsparts[nefx]=-1; - }; + Pinsparts[nefx] = -1; + } //System Effects init - for (int nefx=0;nefxdefaults(); - for (int npart=0;npartchangeeffect(1); microtonal.defaults(); ShutUp(); -}; +} /* * Note On Messages (velocity=0 for NoteOff) */ -void Master::NoteOn(unsigned char chan,unsigned char note,unsigned char velocity) +void Master::NoteOn(unsigned char chan, + unsigned char note, + unsigned char velocity) { - dump.dumpnote(chan,note,velocity); + dump.dumpnote(chan, note, velocity); - noteon(chan,note,velocity); -}; + noteon(chan, note, velocity); +} /* * Internal Note On (velocity=0 for NoteOff) */ -void Master::noteon(unsigned char chan,unsigned char note,unsigned char velocity) +void Master::noteon(unsigned char chan, + unsigned char note, + unsigned char velocity) { int npart; - if (velocity!=0) { - for (npart=0;npartPrcvchn) { - fakepeakpart[npart]=velocity*2; - if (part[npart]->Penabled!=0) part[npart]->NoteOn(note,velocity,keyshift); - }; - }; - } else { - this->NoteOff(chan,note); - }; + if(velocity != 0) { + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + if(chan == part[npart]->Prcvchn) { + fakepeakpart[npart] = velocity * 2; + if(part[npart]->Penabled != 0) + part[npart]->NoteOn(note, velocity, keyshift); + } + } + } + else + this->NoteOff(chan, note); + ; HDDRecorder.triggernow(); -}; +} /* * Note Off Messages */ -void Master::NoteOff(unsigned char chan,unsigned char note) +void Master::NoteOff(unsigned char chan, unsigned char note) { - dump.dumpnote(chan,note,0); + dump.dumpnote(chan, note, 0); - noteoff(chan,note); -}; + noteoff(chan, note); +} /* * Internal Note Off */ -void Master::noteoff(unsigned char chan,unsigned char note) +void Master::noteoff(unsigned char chan, unsigned char note) { int npart; - for (npart=0;npartPrcvchn) && (part[npart]->Penabled!=0)) + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) + if((chan == part[npart]->Prcvchn) && (part[npart]->Penabled != 0)) part[npart]->NoteOff(note); - }; -}; + ; +} /* * Controllers */ -void Master::SetController(unsigned char chan,unsigned int type,int par) +void Master::SetController(unsigned char chan, unsigned int type, int par) { - dump.dumpcontroller(chan,type,par); + dump.dumpcontroller(chan, type, par); - setcontroller(chan,type,par); -}; + setcontroller(chan, type, par); +} /* * Internal Controllers */ -void Master::setcontroller(unsigned char chan,unsigned int type,int par) +void Master::setcontroller(unsigned char chan, unsigned int type, int par) { - if ((type==C_dataentryhi)||(type==C_dataentrylo)|| - (type==C_nrpnhi)||(type==C_nrpnlo)) {//Process RPN and NRPN by the Master (ignore the chan) - ctl.setparameternumber(type,par); + if((type == C_dataentryhi) || (type == C_dataentrylo) + || (type == C_nrpnhi) || (type == C_nrpnlo)) { //Process RPN and NRPN by the Master (ignore the chan) + ctl.setparameternumber(type, par); - int parhi=-1,parlo=-1,valhi=-1,vallo=-1; - if (ctl.getnrpn(&parhi,&parlo,&valhi,&vallo)==0) {//this is NRPN + int parhi = -1, parlo = -1, valhi = -1, vallo = -1; + if(ctl.getnrpn(&parhi, &parlo, &valhi, &vallo) == 0) //this is NRPN //fprintf(stderr,"rcv. NRPN: %d %d %d %d\n",parhi,parlo,valhi,vallo); - switch (parhi) { - case 0x04://System Effects - if (parloseteffectpar_nolock(valhi,vallo); - }; + switch(parhi) { + case 0x04: //System Effects + if(parlo < NUM_SYS_EFX) + sysefx[parlo]->seteffectpar_nolock(valhi, vallo); + ; break; - case 0x08://Insertion Effects - if (parloseteffectpar_nolock(valhi,vallo); - }; + case 0x08: //Insertion Effects + if(parlo < NUM_INS_EFX) + insefx[parlo]->seteffectpar_nolock(valhi, vallo); + ; break; + } + ; + } + else { //other controllers + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) //Send the controller to all part assigned to the channel + if((chan == part[npart]->Prcvchn) && (part[npart]->Penabled != 0)) + part[npart]->SetController(type, par); + ; - }; - }; - } else {//other controllers - for (int npart=0;npartPrcvchn) && (part[npart]->Penabled!=0)) - part[npart]->SetController(type,par); - }; - - if (type==C_allsoundsoff) { //cleanup insertion/system FX - for (int nefx=0;nefxcleanup(); - } - for (int nefx=0;nefxcleanup(); - } } - }; -}; + } +} /* * Enable/Disable a part */ -void Master::partonoff(int npart,int what) +void Master::partonoff(int npart, int what) { - if (npart>=NUM_MIDI_PARTS) return; - if (what==0) {//disable part - fakepeakpart[npart]=0; - part[npart]->Penabled=0; + if(npart >= NUM_MIDI_PARTS) + return; + if(what == 0) { //disable part + fakepeakpart[npart] = 0; + part[npart]->Penabled = 0; part[npart]->cleanup(); - for (int nefx=0;nefxcleanup(); - }; - }; - } else {//enabled - part[npart]->Penabled=1; - fakepeakpart[npart]=0; - }; -}; + ; + } + } + else { //enabled + part[npart]->Penabled = 1; + fakepeakpart[npart] = 0; + } +} /* * Master audio out (the final sound) */ -void Master::AudioOut(REALTYPE *outl,REALTYPE *outr) +void Master::AudioOut(REALTYPE *outl, REALTYPE *outr) { - int i,npart,nefx; + int i, npart, nefx; /* //test!!!!!!!!!!!!! se poate bloca aici (mutex) if (seq.play){ - int type,par1,par2,again,midichan; - int ntrack=1; + int type,par1,par2,again,midichan; + int ntrack=1; // do{ - again=seq.getevent(ntrack,&midichan,&type,&par1,&par2); - if (type>0) { + again=seq.getevent(ntrack,&midichan,&type,&par1,&par2); + if (type>0) { // printf("aaa\n"); - if (type==1){//note_on or note_off - if (par2!=0) NoteOn(midichan,par1,par2); - else NoteOff(midichan,par1); - }; - }; + if (type==1){//note_on or note_off + if (par2!=0) NoteOn(midichan,par1,par2); + else NoteOff(midichan,par1); + }; + }; // } while (again); }; */ @@ -265,250 +271,287 @@ void Master::AudioOut(REALTYPE *outl,REALTYPE *outr) //Swaps the Left channel with Right Channel (if it is asked for) - if (swaplr!=0) { - REALTYPE *tmp=outl; - outl=outr; - outr=tmp; - }; + if(swaplr != 0) { + REALTYPE *tmp = outl; + outl = outr; + outr = tmp; + } //clean up the output samples - for (i=0;ipartoutl,partoutr - for (npart=0;npartPenabled!=0) part[npart]->ComputePartSmps(); + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) + if(part[npart]->Penabled != 0) + part[npart]->ComputePartSmps(); //Insertion effects - for (nefx=0;nefx=0) { - int efxpart=Pinsparts[nefx]; - if (part[efxpart]->Penabled!=0) - insefx[nefx]->out(part[efxpart]->partoutl,part[efxpart]->partoutr); - }; - }; + for(nefx = 0; nefx < NUM_INS_EFX; nefx++) { + if(Pinsparts[nefx] >= 0) { + int efxpart = Pinsparts[nefx]; + if(part[efxpart]->Penabled != 0) + insefx[nefx]->out(part[efxpart]->partoutl, + part[efxpart]->partoutr); + } + } //Apply the part volumes and pannings (after insertion effects) - for (npart=0;npartPenabled==0) continue; + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + if(part[npart]->Penabled == 0) + continue; - REALTYPE newvol_l=part[npart]->volume; - REALTYPE newvol_r=part[npart]->volume; - REALTYPE oldvol_l=part[npart]->oldvolumel; - REALTYPE oldvol_r=part[npart]->oldvolumer; - REALTYPE pan=part[npart]->panning; - if (pan<0.5) newvol_l*=pan*2.0; - else newvol_r*=(1.0-pan)*2.0; + REALTYPE newvol_l = part[npart]->volume; + REALTYPE newvol_r = part[npart]->volume; + REALTYPE oldvol_l = part[npart]->oldvolumel; + REALTYPE oldvol_r = part[npart]->oldvolumer; + REALTYPE pan = part[npart]->panning; + if(pan < 0.5) + newvol_l *= pan * 2.0; + else + newvol_r *= (1.0 - pan) * 2.0; - if (ABOVE_AMPLITUDE_THRESHOLD(oldvol_l,newvol_l)|| - ABOVE_AMPLITUDE_THRESHOLD(oldvol_r,newvol_r)) {//the volume or the panning has changed and needs interpolation - - for (i=0;ipartoutl[i]*=vol_l; - part[npart]->partoutr[i]*=vol_r; - }; - part[npart]->oldvolumel=newvol_l; - part[npart]->oldvolumer=newvol_r; - - } else { - for (i=0;ipartoutl[i]*=newvol_l; - part[npart]->partoutr[i]*=newvol_r; - }; - }; - }; + if(ABOVE_AMPLITUDE_THRESHOLD(oldvol_l, newvol_l) + || ABOVE_AMPLITUDE_THRESHOLD(oldvol_r, newvol_r)) { //the volume or the panning has changed and needs interpolation + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE vol_l = INTERPOLATE_AMPLITUDE(oldvol_l, + newvol_l, + i, + SOUND_BUFFER_SIZE); + REALTYPE vol_r = INTERPOLATE_AMPLITUDE(oldvol_r, + newvol_r, + i, + SOUND_BUFFER_SIZE); + part[npart]->partoutl[i] *= vol_l; + part[npart]->partoutr[i] *= vol_r; + } + part[npart]->oldvolumel = newvol_l; + part[npart]->oldvolumer = newvol_r; + } + else { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //the volume did not changed + part[npart]->partoutl[i] *= newvol_l; + part[npart]->partoutr[i] *= newvol_r; + } + } + } //System effects - for (nefx=0;nefxgeteffect()==0) continue;//the effect is disabled + for(nefx = 0; nefx < NUM_SYS_EFX; nefx++) { + if(sysefx[nefx]->geteffect() == 0) + continue; //the effect is disabled //Clean up the samples used by the system effects - for (i=0;iPenabled==0) continue; + if(part[npart]->Penabled == 0) + continue; //the output volume of each part to system effect - REALTYPE vol=sysefxvol[nefx][npart]; - for (i=0;ipartoutl[i]*vol; - tmpmixr[i]+=part[npart]->partoutr[i]*vol; - }; - }; + REALTYPE vol = sysefxvol[nefx][npart]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpmixl[i] += part[npart]->partoutl[i] * vol; + tmpmixr[i] += part[npart]->partoutr[i] * vol; + } + } // system effect send to next ones - for (int nefxfrom=0;nefxfromefxoutl[i]*v; - tmpmixr[i]+=sysefx[nefxfrom]->efxoutr[i]*v; - }; - }; - }; + for(int nefxfrom = 0; nefxfrom < nefx; nefxfrom++) { + if(Psysefxsend[nefxfrom][nefx] != 0) { + REALTYPE v = sysefxsend[nefxfrom][nefx]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpmixl[i] += sysefx[nefxfrom]->efxoutl[i] * v; + tmpmixr[i] += sysefx[nefxfrom]->efxoutr[i] * v; + } + } + } - sysefx[nefx]->out(tmpmixl,tmpmixr); + sysefx[nefx]->out(tmpmixl, tmpmixr); //Add the System Effect to sound output - REALTYPE outvol=sysefx[nefx]->sysefxgetvolume(); - for (i=0;isysefxgetvolume(); + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] += tmpmixl[i] * outvol; + outr[i] += tmpmixr[i] * outvol; + } + } //Mix all parts - for (npart=0;npartpartoutl[i]; - outr[i]+=part[npart]->partoutr[i]; - }; - }; + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //the volume did not changed + outl[i] += part[npart]->partoutl[i]; + outr[i] += part[npart]->partoutr[i]; + } + } //Insertion effects for Master Out - for (nefx=0;nefxout(outl,outr); - }; + for(nefx = 0; nefx < NUM_INS_EFX; nefx++) + if(Pinsparts[nefx] == -2) + insefx[nefx]->out(outl, outr); + ; //Master Volume - for (i=0;ivuoutpeakl) vuoutpeakl=fabs(outl[i]); - if (fabs(outr[i])>vuoutpeakr) vuoutpeakr=fabs(outr[i]); - }; - if ((vuoutpeakl>1.0)||(vuoutpeakr>1.0)) vuclipped=1; - if (vumaxoutpeakl vuoutpeakl) + vuoutpeakl = fabs(outl[i]); + if(fabs(outr[i]) > vuoutpeakr) + vuoutpeakr = fabs(outr[i]); + } + if((vuoutpeakl > 1.0) || (vuoutpeakr > 1.0)) + vuclipped = 1; + if(vumaxoutpeakl < vuoutpeakl) + vumaxoutpeakl = vuoutpeakl; + if(vumaxoutpeakr < vuoutpeakr) + vumaxoutpeakr = vuoutpeakr; //RMS Peak computation (for vumeters) - vurmspeakl=1e-12; - vurmspeakr=1e-12; - for (i=0;iPenabled!=0) { - REALTYPE *outl=part[npart]->partoutl, - *outr=part[npart]->partoutr; - for (i=0;ivuoutpeakpart[npart]) vuoutpeakpart[npart]=tmp; - }; - vuoutpeakpart[npart]*=volume; - } else { - if (fakepeakpart[npart]>1) fakepeakpart[npart]--; - }; - }; + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + vuoutpeakpart[npart] = 1.0e-12; + if(part[npart]->Penabled != 0) { + REALTYPE *outl = part[npart]->partoutl, + *outr = part[npart]->partoutr; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE tmp = fabs(outl[i] + outr[i]); + if(tmp > vuoutpeakpart[npart]) + vuoutpeakpart[npart] = tmp; + } + vuoutpeakpart[npart] *= volume; + } + else + if(fakepeakpart[npart] > 1) + fakepeakpart[npart]--; + ; + } //Shutup if it is asked (with fade-out) - if (shutup!=0) { - for (i=0;i=SOUND_BUFFER_SIZE) { - AudioOut(&audiooutl[0],&audiooutr[0]); - ksoundbuffersample=0; - }; - }; - } else {//Resample - int ksample=0; - REALTYPE srinc=SAMPLE_RATE/(REALTYPE)samplerate; + if(ksoundbuffersample >= SOUND_BUFFER_SIZE) { + AudioOut(&audiooutl[0], &audiooutr[0]); + ksoundbuffersample = 0; + } + } + } + else { //Resample + int ksample = 0; + REALTYPE srinc = SAMPLE_RATE / (REALTYPE)samplerate; - while (ksample=1.0) { - ksoundbuffersample+=(int) floor(ksoundbuffersamplelow); - ksoundbuffersamplelow=ksoundbuffersamplelow-floor(ksoundbuffersamplelow); - }; + ksoundbuffersamplelow += srinc; + if(ksoundbuffersamplelow >= 1.0) { + ksoundbuffersample += (int) floor(ksoundbuffersamplelow); + ksoundbuffersamplelow = ksoundbuffersamplelow - floor( + ksoundbuffersamplelow); + } - if (ksoundbuffersample>=SOUND_BUFFER_SIZE) { - oldsamplel=audiooutl[SOUND_BUFFER_SIZE-1]; - oldsampler=audiooutr[SOUND_BUFFER_SIZE-1]; - AudioOut(&audiooutl[0],&audiooutr[0]); - ksoundbuffersample=0; - }; - }; - }; -}; + if(ksoundbuffersample >= SOUND_BUFFER_SIZE) { + oldsamplel = audiooutl[SOUND_BUFFER_SIZE - 1]; + oldsampler = audiooutr[SOUND_BUFFER_SIZE - 1]; + AudioOut(&audiooutl[0], &audiooutr[0]); + ksoundbuffersample = 0; + } + } + } +} Master::~Master() { - for (int npart=0;npartcleanup(); - fakepeakpart[npart]=0; - }; - for (int nefx=0;nefxcleanup(); - for (int nefx=0;nefxcleanup(); + fakepeakpart[npart] = 0; + } + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) + insefx[nefx]->cleanup(); + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) + sysefx[nefx]->cleanup(); vuresetpeaks(); - shutup=0; -}; + shutup = 0; +} /* @@ -570,81 +615,80 @@ void Master::ShutUp() */ void Master::vuresetpeaks() { - vuoutpeakl=1e-9; - vuoutpeakr=1e-9; - vumaxoutpeakl=1e-9; - vumaxoutpeakr=1e-9; - vuclipped=0; -}; + vuoutpeakl = 1e-9; + vuoutpeakr = 1e-9; + vumaxoutpeakl = 1e-9; + vumaxoutpeakr = 1e-9; + vuclipped = 0; +} void Master::applyparameters() { - for (int npart=0;npartapplyparameters(); - }; -}; + ; +} void Master::add2XML(XMLwrapper *xml) { - xml->addpar("volume",Pvolume); - xml->addpar("key_shift",Pkeyshift); - xml->addparbool("nrpn_receive",ctl.NRPN.receive); + xml->addpar("volume", Pvolume); + xml->addpar("key_shift", Pkeyshift); + xml->addparbool("nrpn_receive", ctl.NRPN.receive); xml->beginbranch("MICROTONAL"); microtonal.add2XML(xml); xml->endbranch(); - for (int npart=0;npartbeginbranch("PART",npart); + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) { + xml->beginbranch("PART", npart); part[npart]->add2XML(xml); xml->endbranch(); - }; + } xml->beginbranch("SYSTEM_EFFECTS"); - for (int nefx=0;nefxbeginbranch("SYSTEM_EFFECT",nefx); + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) { + xml->beginbranch("SYSTEM_EFFECT", nefx); xml->beginbranch("EFFECT"); sysefx[nefx]->add2XML(xml); xml->endbranch(); - for (int pefx=0;pefxbeginbranch("VOLUME",pefx); - xml->addpar("vol",Psysefxvol[nefx][pefx]); + for(int pefx = 0; pefx < NUM_MIDI_PARTS; pefx++) { + xml->beginbranch("VOLUME", pefx); + xml->addpar("vol", Psysefxvol[nefx][pefx]); xml->endbranch(); - }; + } - for (int tonefx=nefx+1;tonefxbeginbranch("SENDTO",tonefx); - xml->addpar("send_vol",Psysefxsend[nefx][tonefx]); + for(int tonefx = nefx + 1; tonefx < NUM_SYS_EFX; tonefx++) { + xml->beginbranch("SENDTO", tonefx); + xml->addpar("send_vol", Psysefxsend[nefx][tonefx]); xml->endbranch(); - }; + } xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("INSERTION_EFFECTS"); - for (int nefx=0;nefxbeginbranch("INSERTION_EFFECT",nefx); - xml->addpar("part",Pinsparts[nefx]); + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) { + xml->beginbranch("INSERTION_EFFECT", nefx); + xml->addpar("part", Pinsparts[nefx]); xml->beginbranch("EFFECT"); insefx[nefx]->add2XML(xml); xml->endbranch(); xml->endbranch(); - }; + } xml->endbranch(); - -}; +} int Master::getalldata(char **data) { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); xml->beginbranch("MASTER"); @@ -654,20 +698,21 @@ int Master::getalldata(char **data) xml->endbranch(); - *data=xml->getXMLdata(); + *data = xml->getXMLdata(); delete (xml); - return(strlen(*data)+1); -}; + return strlen(*data) + 1; +} -void Master::putalldata(char *data,int size) +void Master::putalldata(char *data, int size) { - XMLwrapper *xml=new XMLwrapper(); - if (!xml->putXMLdata(data)) { - delete(xml); + XMLwrapper *xml = new XMLwrapper(); + if(!xml->putXMLdata(data)) { + delete (xml); return; - }; + } - if (xml->enterbranch("MASTER")==0) return; + if(xml->enterbranch("MASTER") == 0) + return; pthread_mutex_lock(&mutex); getfromXML(xml); @@ -675,104 +720,109 @@ void Master::putalldata(char *data,int size) xml->exitbranch(); - delete(xml); -}; + delete (xml); +} int Master::saveXML(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); xml->beginbranch("MASTER"); add2XML(xml); xml->endbranch(); - int result=xml->saveXMLfile(filename); + int result = xml->saveXMLfile(filename); delete (xml); - return(result); -}; + return result; +} int Master::loadXML(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); - if (xml->loadXMLfile(filename)<0) { - delete(xml); - return(-1); - }; + XMLwrapper *xml = new XMLwrapper(); + if(xml->loadXMLfile(filename) < 0) { + delete (xml); + return -1; + } - if (xml->enterbranch("MASTER")==0) return(-10); + if(xml->enterbranch("MASTER") == 0) + return -10; getfromXML(xml); xml->exitbranch(); - delete(xml); - return(0); -}; + delete (xml); + return 0; +} void Master::getfromXML(XMLwrapper *xml) { - setPvolume(xml->getpar127("volume",Pvolume)); - setPkeyshift(xml->getpar127("key_shift",Pkeyshift)); - ctl.NRPN.receive=xml->getparbool("nrpn_receive",ctl.NRPN.receive); + setPvolume(xml->getpar127("volume", Pvolume)); + setPkeyshift(xml->getpar127("key_shift", Pkeyshift)); + ctl.NRPN.receive = xml->getparbool("nrpn_receive", ctl.NRPN.receive); - part[0]->Penabled=0; - for (int npart=0;npartenterbranch("PART",npart)==0) continue; + part[0]->Penabled = 0; + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) { + if(xml->enterbranch("PART", npart) == 0) + continue; part[npart]->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("MICROTONAL")) { + if(xml->enterbranch("MICROTONAL")) { microtonal.getfromXML(xml); xml->exitbranch(); - }; + } sysefx[0]->changeeffect(0); - if (xml->enterbranch("SYSTEM_EFFECTS")) { - for (int nefx=0;nefxenterbranch("SYSTEM_EFFECT",nefx)==0) continue; - if (xml->enterbranch("EFFECT")) { + if(xml->enterbranch("SYSTEM_EFFECTS")) { + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) { + if(xml->enterbranch("SYSTEM_EFFECT", nefx) == 0) + continue; + if(xml->enterbranch("EFFECT")) { sysefx[nefx]->getfromXML(xml); xml->exitbranch(); - }; + } - for (int partefx=0;partefxenterbranch("VOLUME",partefx)==0) continue; - setPsysefxvol(partefx,nefx,xml->getpar127("vol",Psysefxvol[partefx][nefx])); + for(int partefx = 0; partefx < NUM_MIDI_PARTS; partefx++) { + if(xml->enterbranch("VOLUME", partefx) == 0) + continue; + setPsysefxvol(partefx, nefx, + xml->getpar127("vol", Psysefxvol[partefx][nefx])); xml->exitbranch(); - }; + } - for (int tonefx=nefx+1;tonefxenterbranch("SENDTO",tonefx)==0) continue; - setPsysefxsend(nefx,tonefx,xml->getpar127("send_vol",Psysefxsend[nefx][tonefx])); + for(int tonefx = nefx + 1; tonefx < NUM_SYS_EFX; tonefx++) { + if(xml->enterbranch("SENDTO", tonefx) == 0) + continue; + setPsysefxsend(nefx, tonefx, + xml->getpar127("send_vol", + Psysefxsend[nefx][tonefx])); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("INSERTION_EFFECTS")) { - for (int nefx=0;nefxenterbranch("INSERTION_EFFECT",nefx)==0) continue; - Pinsparts[nefx]=xml->getpar("part",Pinsparts[nefx],-2,NUM_MIDI_PARTS); - if (xml->enterbranch("EFFECT")) { + if(xml->enterbranch("INSERTION_EFFECTS")) { + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) { + if(xml->enterbranch("INSERTION_EFFECT", nefx) == 0) + continue; + Pinsparts[nefx] = xml->getpar("part", + Pinsparts[nefx], + -2, + NUM_MIDI_PARTS); + if(xml->enterbranch("EFFECT")) { insefx[nefx]->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - - }; + } xml->exitbranch(); - }; - - -}; - - - + } +} diff --git a/plugins/zynaddsubfx/src/Misc/Master.h b/plugins/zynaddsubfx/src/Misc/Master.h index 69f1a1ec2..eb4752245 100644 --- a/plugins/zynaddsubfx/src/Misc/Master.h +++ b/plugins/zynaddsubfx/src/Misc/Master.h @@ -40,129 +40,136 @@ extern Dump dump; * process them with system/insertion effects and mix them */ class Master { -public: - /** Constructor*/ - Master(); - /** Destructor*/ - ~Master(); + public: + /** Constructor*/ + Master(); + /** Destructor*/ + ~Master(); - /**Saves all settings to a XML file - * @return 0 for ok or <0 if there is an error*/ - int saveXML(const char *filename); + /**Saves all settings to a XML file + * @return 0 for ok or <0 if there is an error*/ + int saveXML(const char *filename); - /**This adds the parameters to the XML data*/ - void add2XML(XMLwrapper *xml); + /**This adds the parameters to the XML data*/ + void add2XML(XMLwrapper *xml); - void defaults(); + void defaults(); - /**loads all settings from a XML file - * @return 0 for ok or -1 if there is an error*/ - int loadXML(const char *filename); - void applyparameters(); + /**loads all settings from a XML file + * @return 0 for ok or -1 if there is an error*/ + int loadXML(const char *filename); + void applyparameters(); - void getfromXML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); - /**get all data to a newly allocated array (used for VST) - * @return the datasize*/ - int getalldata(char **data); - /**put all data from the *data array to zynaddsubfx parameters (used for VST)*/ - void putalldata(char *data,int size); + /**get all data to a newly allocated array (used for VST) + * @return the datasize*/ + int getalldata(char **data); + /**put all data from the *data array to zynaddsubfx parameters (used for VST)*/ + void putalldata(char *data, int size); - //Midi IN - void NoteOn(unsigned char chan,unsigned char note,unsigned char velocity); - void NoteOff(unsigned char chan,unsigned char note); - void SetController(unsigned char chan,unsigned int type,int par); - //void NRPN... + //Midi IN + void NoteOn(unsigned char chan, + unsigned char note, + unsigned char velocity); + void NoteOff(unsigned char chan, unsigned char note); + void SetController(unsigned char chan, unsigned int type, int par); + //void NRPN... - void ShutUp(); - int shutup; + void ShutUp(); + int shutup; - /**Audio Output*/ - void AudioOut(REALTYPE *outl,REALTYPE *outr); - /**Audio Output (for callback mode). This allows the program to be controled by an external program*/ - void GetAudioOutSamples(int nsamples,int samplerate,REALTYPE *outl,REALTYPE *outr); + /**Audio Output*/ + void AudioOut(REALTYPE *outl, REALTYPE *outr); + /**Audio Output (for callback mode). This allows the program to be controled by an external program*/ + void GetAudioOutSamples(int nsamples, + int samplerate, + REALTYPE *outl, + REALTYPE *outr); - void partonoff(int npart,int what); + void partonoff(int npart, int what); - /**parts \todo see if this can be made to be dynamic*/ - Part *part[NUM_MIDI_PARTS]; + /**parts \todo see if this can be made to be dynamic*/ + Part *part[NUM_MIDI_PARTS]; - //parameters - unsigned char Pvolume; - unsigned char Pkeyshift; - unsigned char Psysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; - unsigned char Psysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; + //parameters + unsigned char Pvolume; + unsigned char Pkeyshift; + unsigned char Psysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; + unsigned char Psysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; - //parameters control - void setPvolume(char Pvolume_); - void setPkeyshift(char Pkeyshift_); - void setPsysefxvol(int Ppart,int Pefx,char Pvol); - void setPsysefxsend(int Pefxfrom,int Pefxto,char Pvol); + //parameters control + void setPvolume(char Pvolume_); + void setPkeyshift(char Pkeyshift_); + void setPsysefxvol(int Ppart, int Pefx, char Pvol); + void setPsysefxsend(int Pefxfrom, int Pefxto, char Pvol); - //effects - EffectMgr *sysefx[NUM_SYS_EFX];//system - EffectMgr *insefx[NUM_INS_EFX];//insertion + //effects + EffectMgr *sysefx[NUM_SYS_EFX]; //system + EffectMgr *insefx[NUM_INS_EFX]; //insertion // void swapcopyeffects(int what,int type,int neff1,int neff2); - //HDD recorder - Recorder HDDRecorder; + //HDD recorder + Recorder HDDRecorder; - //part that's apply the insertion effect; -1 to disable - short int Pinsparts[NUM_INS_EFX]; + //part that's apply the insertion effect; -1 to disable + short int Pinsparts[NUM_INS_EFX]; - //peaks for VU-meter - void vuresetpeaks(); - REALTYPE vuoutpeakl,vuoutpeakr,vumaxoutpeakl,vumaxoutpeakr,vurmspeakl,vurmspeakr; - int vuclipped; + //peaks for VU-meter + void vuresetpeaks(); + REALTYPE vuoutpeakl, vuoutpeakr, vumaxoutpeakl, vumaxoutpeakr, + vurmspeakl, vurmspeakr; + int vuclipped; - //peaks for part VU-meters - REALTYPE vuoutpeakpart[NUM_MIDI_PARTS]; - unsigned char fakepeakpart[NUM_MIDI_PARTS];//this is used to compute the "peak" when the part is disabled + //peaks for part VU-meters + REALTYPE vuoutpeakpart[NUM_MIDI_PARTS]; + unsigned char fakepeakpart[NUM_MIDI_PARTS]; //this is used to compute the "peak" when the part is disabled - Controller ctl; - int swaplr;//1 if L and R are swapped + Controller ctl; + int swaplr; //1 if L and R are swapped - //Sequencer - Sequencer seq; + //Sequencer + Sequencer seq; - //other objects - Microtonal microtonal; - Bank bank; + //other objects + Microtonal microtonal; + Bank bank; - FFTwrapper *fft; - pthread_mutex_t mutex; + FFTwrapper *fft; + pthread_mutex_t mutex; -private: - REALTYPE volume; - REALTYPE sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; - REALTYPE sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; + private: + REALTYPE volume; + REALTYPE sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; + REALTYPE sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; - //Temporary mixing samples for part samples which is sent to system effect - REALTYPE *tmpmixl; - REALTYPE *tmpmixr; + //Temporary mixing samples for part samples which is sent to system effect + REALTYPE *tmpmixl; + REALTYPE *tmpmixr; - int keyshift; + int keyshift; - //Audio Output samples (if it used GetAudioOutSamples - eg. for Jack output; elsewhere is unused) - REALTYPE *audiooutl; - REALTYPE *audiooutr; + //Audio Output samples (if it used GetAudioOutSamples - eg. for Jack output; elsewhere is unused) + REALTYPE *audiooutl; + REALTYPE *audiooutr; - int ksoundbuffersample;//this is used to know if there is need to call AudioOut by GetAudioOutSamples method - REALTYPE ksoundbuffersamplelow;//this is used for resampling (eg. if Jack samplerate!= SAMPLE_RATE) - REALTYPE oldsamplel,oldsampler;//this is used for resampling - - //These are called by the NoteOn, NoteOff,SetController (which are from external sources like MIDI, Virtual Keyboard) - //and are called by internal parts of the program (like sequencer) - void noteon(unsigned char chan,unsigned char note,unsigned char velocity); - void noteoff(unsigned char chan,unsigned char note); - void setcontroller(unsigned char chan,unsigned int type,int par); + int ksoundbuffersample; //this is used to know if there is need to call AudioOut by GetAudioOutSamples method + REALTYPE ksoundbuffersamplelow; //this is used for resampling (eg. if Jack samplerate!= SAMPLE_RATE) + REALTYPE oldsamplel, oldsampler; //this is used for resampling + //These are called by the NoteOn, NoteOff,SetController (which are from external sources like MIDI, Virtual Keyboard) + //and are called by internal parts of the program (like sequencer) + void noteon(unsigned char chan, + unsigned char note, + unsigned char velocity); + void noteoff(unsigned char chan, unsigned char note); + void setcontroller(unsigned char chan, unsigned int type, int par); }; diff --git a/plugins/zynaddsubfx/src/Misc/Microtonal.cpp b/plugins/zynaddsubfx/src/Misc/Microtonal.cpp index b389059c8..e84ee8e64 100644 --- a/plugins/zynaddsubfx/src/Misc/Microtonal.cpp +++ b/plugins/zynaddsubfx/src/Misc/Microtonal.cpp @@ -28,158 +28,190 @@ Microtonal::Microtonal() { - Pname=new unsigned char[MICROTONAL_MAX_NAME_LEN]; - Pcomment=new unsigned char[MICROTONAL_MAX_NAME_LEN]; + Pname = new unsigned char[MICROTONAL_MAX_NAME_LEN]; + Pcomment = new unsigned char[MICROTONAL_MAX_NAME_LEN]; defaults(); -}; +} void Microtonal::defaults() { - Pinvertupdown=0; - Pinvertupdowncenter=60; - octavesize=12; - Penabled=0; - PAnote=69; - PAfreq=440.0; - Pscaleshift=64; + Pinvertupdown = 0; + Pinvertupdowncenter = 60; + octavesize = 12; + Penabled = 0; + PAnote = 69; + PAfreq = 440.0; + Pscaleshift = 64; - Pfirstkey=0; - Plastkey=127; - Pmiddlenote=60; - Pmapsize=12; - Pmappingenabled=0; + Pfirstkey = 0; + Plastkey = 127; + Pmiddlenote = 60; + Pmapsize = 12; + Pmappingenabled = 0; - for (int i=0;i<128;i++) Pmapping[i]=i; + for(int i = 0; i < 128; i++) + Pmapping[i] = i; - for (int i=0;iPlastkey)) return (-1.0); + if(Pmappingenabled != 0) { + if((note < Pfirstkey) || (note > Plastkey)) + return -1.0; //Compute how many mapped keys are from middle note to reference note //and find out the proportion between the freq. of middle note and "A" note - int tmp=PAnote-Pmiddlenote,minus=0; - if (tmp<0) { - tmp=-tmp; - minus=1; - }; - int deltanote=0; - for (int i=0;i=0) deltanote++; - REALTYPE rap_anote_middlenote=(deltanote==0) ? (1.0) : (octave[(deltanote-1)%octavesize].tuning); - if (deltanote!=0) rap_anote_middlenote*=pow(octave[octavesize-1].tuning,(deltanote-1)/octavesize); - if (minus!=0) rap_anote_middlenote=1.0/rap_anote_middlenote; + int tmp = PAnote - Pmiddlenote, minus = 0; + if(tmp < 0) { + tmp = -tmp; + minus = 1; + } + int deltanote = 0; + for(int i = 0; i < tmp; i++) + if(Pmapping[i % Pmapsize] >= 0) + deltanote++; + REALTYPE rap_anote_middlenote = + (deltanote == + 0) ? (1.0) : (octave[(deltanote - 1) % octavesize].tuning); + if(deltanote != 0) + rap_anote_middlenote *= + pow(octave[octavesize - 1].tuning, (deltanote - 1) / octavesize); + if(minus != 0) + rap_anote_middlenote = 1.0 / rap_anote_middlenote; //Convert from note (midi) to degree (note from the tunning) - int degoct=(note-(int)Pmiddlenote+(int) Pmapsize*200)/(int)Pmapsize-200; - int degkey=(note-Pmiddlenote+(int)Pmapsize*100)%Pmapsize; - degkey=Pmapping[degkey]; - if (degkey<0) return(-1.0);//this key is not mapped + int degoct = + (note - (int)Pmiddlenote + (int) Pmapsize + * 200) / (int)Pmapsize - 200; + int degkey = (note - Pmiddlenote + (int)Pmapsize * 100) % Pmapsize; + degkey = Pmapping[degkey]; + if(degkey < 0) + return -1.0; //this key is not mapped //invert the keyboard upside-down if it is asked for //TODO: do the right way by using Pinvertupdowncenter - if (Pinvertupdown!=0) { - degkey=octavesize-degkey-1; - degoct=-degoct; - }; + if(Pinvertupdown != 0) { + degkey = octavesize - degkey - 1; + degoct = -degoct; + } //compute the frequency of the note - degkey=degkey+scaleshift; - degoct+=degkey/octavesize; - degkey%=octavesize; + degkey = degkey + scaleshift; + degoct += degkey / octavesize; + degkey %= octavesize; - REALTYPE freq=(degkey==0) ? (1.0):octave[degkey-1].tuning; - freq*=pow(octave[octavesize-1].tuning,degoct); - freq*=PAfreq/rap_anote_middlenote; - freq*=globalfinedetunerap; - if (scaleshift!=0) freq/=octave[scaleshift-1].tuning; - return(freq*rap_keyshift); - } else {//if the mapping is disabled - int nt=note-PAnote+scaleshift; - int ntkey=(nt+(int)octavesize*100)%octavesize; - int ntoct=(nt-ntkey)/octavesize; + REALTYPE freq = (degkey == 0) ? (1.0) : octave[degkey - 1].tuning; + freq *= pow(octave[octavesize - 1].tuning, degoct); + freq *= PAfreq / rap_anote_middlenote; + freq *= globalfinedetunerap; + if(scaleshift != 0) + freq /= octave[scaleshift - 1].tuning; + return freq * rap_keyshift; + } + else { //if the mapping is disabled + int nt = note - PAnote + scaleshift; + int ntkey = (nt + (int)octavesize * 100) % octavesize; + int ntoct = (nt - ntkey) / octavesize; - REALTYPE oct=octave[octavesize-1].tuning; - REALTYPE freq=octave[(ntkey+octavesize-1)%octavesize].tuning*pow(oct,ntoct)*PAfreq; - if (ntkey==0) freq/=oct; - if (scaleshift!=0) freq/=octave[scaleshift-1].tuning; + REALTYPE oct = octave[octavesize - 1].tuning; + REALTYPE freq = + octave[(ntkey + octavesize - 1) % octavesize].tuning *pow(oct, + ntoct) + * PAfreq; + if(ntkey == 0) + freq /= oct; + if(scaleshift != 0) + freq /= octave[scaleshift - 1].tuning; // fprintf(stderr,"note=%d freq=%.3f cents=%d\n",note,freq,(int)floor(log(freq/PAfreq)/log(2.0)*1200.0+0.5)); - freq*=globalfinedetunerap; - return(freq*rap_keyshift); - }; -}; + freq *= globalfinedetunerap; + return freq * rap_keyshift; + } +} bool Microtonal::operator==(const Microtonal µ) const { - return(!(*this!=micro)); + return !(*this != micro); } bool Microtonal::operator!=(const Microtonal µ) const { - //A simple macro to test equality MiCRotonal EQuals (not the perfect //approach, but good enough) -#define MCREQ( x ) if(x!=micro.x)return true; +#define MCREQ(x) if(x != micro.x) \ + return true; //for floats -#define FMCREQ( x ) if(!((xmicro.x-0.0001)))return true; +#define FMCREQ(x) if(!((x < micro.x + 0.0001) && (x > micro.x - 0.0001))) \ + return true; MCREQ(Pinvertupdown); MCREQ(Pinvertupdowncenter); @@ -195,18 +227,18 @@ bool Microtonal::operator!=(const Microtonal µ) const MCREQ(Pmapsize); MCREQ(Pmappingenabled); - for (int i=0;i<128;i++) + for(int i = 0; i < 128; i++) MCREQ(Pmapping[i]); - for (int i=0;iPname,(const char *)micro.Pname)) + if(strcmp((const char *)this->Pname, (const char *)micro.Pname)) return true; - if(strcmp((const char *)this->Pcomment,(const char *)micro.Pcomment)) + if(strcmp((const char *)this->Pcomment, (const char *)micro.Pcomment)) return true; MCREQ(Pglobalfinedetune); return false; @@ -214,384 +246,442 @@ bool Microtonal::operator!=(const Microtonal µ) const //undefine macros, as they are no longer needed #undef MCREQ #undef FMCREQ - } /* * Convert a line to tunings; returns -1 if it ok */ -int Microtonal::linetotunings(unsigned int nline,const char *line) +int Microtonal::linetotunings(unsigned int nline, const char *line) { - int x1=-1,x2=-1,type=-1; - REALTYPE x=-1.0,tmp,tuning=1.0; - if (strstr(line,"/")==NULL) { - if (strstr(line,".")==NULL) {// M case (M=M/1) - sscanf(line,"%d",&x1); - x2=1; - type=2;//division - } else {// float number case - sscanf(line,"%f",&x); - if (x<0.000001) return(1); - type=1;//float type(cents) - }; - } else {// M/N case - sscanf(line,"%d/%d",&x1,&x2); - if ((x1<0)||(x2<0)) return(1); - if (x2==0) x2=1; - type=2;//division - }; + int x1 = -1, x2 = -1, type = -1; + REALTYPE x = -1.0, tmp, tuning = 1.0; + if(strstr(line, "/") == NULL) { + if(strstr(line, ".") == NULL) { // M case (M=M/1) + sscanf(line, "%d", &x1); + x2 = 1; + type = 2; //division + } + else { // float number case + sscanf(line, "%f", &x); + if(x < 0.000001) + return 1; + type = 1; //float type(cents) + } + } + else { // M/N case + sscanf(line, "%d/%d", &x1, &x2); + if((x1 < 0) || (x2 < 0)) + return 1; + if(x2 == 0) + x2 = 1; + type = 2; //division + } - if (x1<=0) x1=1;//not allow zero frequency sounds (consider 0 as 1) + if(x1 <= 0) + x1 = 1; //not allow zero frequency sounds (consider 0 as 1) //convert to float if the number are too big - if ((type==2)&&((x1>(128*128*128-1))||(x2>(128*128*128-1)))) { - type=1; - x=((REALTYPE) x1)/x2; - }; - switch (type) { + if((type == 2) + && ((x1 > (128 * 128 * 128 - 1)) || (x2 > (128 * 128 * 128 - 1)))) { + type = 1; + x = ((REALTYPE) x1) / x2; + } + switch(type) { case 1: - x1=(int) floor(x); - tmp=fmod(x,1.0); - x2=(int) (floor (tmp*1e6)); - tuning=pow(2.0,x/1200.0); + x1 = (int) floor(x); + tmp = fmod(x, 1.0); + x2 = (int) (floor(tmp * 1e6)); + tuning = pow(2.0, x / 1200.0); break; case 2: - x=((REALTYPE)x1)/x2; - tuning=x; + x = ((REALTYPE)x1) / x2; + tuning = x; break; - }; + } - tmpoctave[nline].tuning=tuning; - tmpoctave[nline].type=type; - tmpoctave[nline].x1=x1; - tmpoctave[nline].x2=x2; + tmpoctave[nline].tuning = tuning; + tmpoctave[nline].type = type; + tmpoctave[nline].x1 = x1; + tmpoctave[nline].x2 = x2; - return(-1);//ok -}; + return -1; //ok +} /* * Convert the text to tunnings */ int Microtonal::texttotunings(const char *text) { - unsigned int i,k=0,nl=0; + unsigned int i, k = 0, nl = 0; char *lin; - lin=new char[MAX_LINE_SIZE+1]; - while (kMAX_OCTAVE_SIZE) nl=MAX_OCTAVE_SIZE; - if (nl==0) return(-2);//the input is empty - octavesize=nl; - for (i=0;i MAX_OCTAVE_SIZE) + nl = MAX_OCTAVE_SIZE; + if(nl == 0) + return -2; //the input is empty + octavesize = nl; + for(i = 0; i < octavesize; i++) { + octave[i].tuning = tmpoctave[i].tuning; + octave[i].type = tmpoctave[i].type; + octave[i].x1 = tmpoctave[i].x1; + octave[i].x2 = tmpoctave[i].x2; + } + return -1; //ok +} /* * Convert the text to mapping */ void Microtonal::texttomapping(const char *text) { - unsigned int i,k=0; + unsigned int i, k = 0; char *lin; - lin=new char[MAX_LINE_SIZE+1]; - for (i=0;i<128;i++) Pmapping[i]=-1; - int tx=0; - while (k127) break; - }; + if((tx++) > 127) + break; + } delete [] lin; - if (tx==0) tx=1; - Pmapsize=tx; -}; + if(tx == 0) + tx = 1; + Pmapsize = tx; +} /* * Convert tunning to text line */ -void Microtonal::tuningtoline(int n,char *line,int maxn) +void Microtonal::tuningtoline(int n, char *line, int maxn) { - if ((n>octavesize) || (n>MAX_OCTAVE_SIZE)) { - line[0]='\0'; + if((n > octavesize) || (n > MAX_OCTAVE_SIZE)) { + line[0] = '\0'; return; - }; - if (octave[n].type==1) snprintf(line,maxn,"%d.%d",octave[n].x1,octave[n].x2); - if (octave[n].type==2) snprintf(line,maxn,"%d/%d",octave[n].x1,octave[n].x2); -}; + } + if(octave[n].type == 1) + snprintf(line, maxn, "%d.%d", octave[n].x1, octave[n].x2); + if(octave[n].type == 2) + snprintf(line, maxn, "%d/%d", octave[n].x1, octave[n].x2); +} -int Microtonal::loadline(FILE *file,char *line) +int Microtonal::loadline(FILE *file, char *line) { do { - if (fgets(line,500,file)==0) return(1); - } while (line[0]=='!'); - return(0); -}; + if(fgets(line, 500, file) == 0) + return 1; + } while(line[0] == '!'); + return 0; +} /* * Loads the tunnings from a scl file */ int Microtonal::loadscl(const char *filename) { - FILE *file=fopen(filename, "r"); - char tmp[500]; - fseek(file,0,SEEK_SET); + FILE *file = fopen(filename, "r"); + char tmp[500]; + fseek(file, 0, SEEK_SET); //loads the short description - if (loadline(file,&tmp[0])!=0) return(2); - for (int i=0;i<500;i++) if (tmp[i]<32) tmp[i]=0; - snprintf((char *) Pname,MICROTONAL_MAX_NAME_LEN,"%s",tmp); - snprintf((char *) Pcomment,MICROTONAL_MAX_NAME_LEN,"%s",tmp); + if(loadline(file, &tmp[0]) != 0) + return 2; + for(int i = 0; i < 500; i++) + if(tmp[i] < 32) + tmp[i] = 0; + snprintf((char *) Pname, MICROTONAL_MAX_NAME_LEN, "%s", tmp); + snprintf((char *) Pcomment, MICROTONAL_MAX_NAME_LEN, "%s", tmp); //loads the number of the notes - if (loadline(file,&tmp[0])!=0) return(2); - int nnotes=MAX_OCTAVE_SIZE; - sscanf(&tmp[0],"%d",&nnotes); - if (nnotes>MAX_OCTAVE_SIZE) return (2); + if(loadline(file, &tmp[0]) != 0) + return 2; + int nnotes = MAX_OCTAVE_SIZE; + sscanf(&tmp[0], "%d", &nnotes); + if(nnotes > MAX_OCTAVE_SIZE) + return 2; //load the tunnings - for (int nline=0;nline127) x=127;//just in case... - Pmapsize=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Pmapsize = x; //loads first MIDI note to retune - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - Pfirstkey=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Pfirstkey = x; //loads last MIDI note to retune - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - Plastkey=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Plastkey = x; //loads last the middle note where scale fro scale degree=0 - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - Pmiddlenote=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Pmiddlenote = x; //loads the reference note - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - PAnote=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + PAnote = x; //loads the reference freq. - if (loadline(file,&tmp[0])!=0) return(2); - REALTYPE tmpPAfreq=440.0; - if (sscanf(&tmp[0],"%f",&tmpPAfreq)==0) return(2); - PAfreq=tmpPAfreq; + if(loadline(file, &tmp[0]) != 0) + return 2; + REALTYPE tmpPAfreq = 440.0; + if(sscanf(&tmp[0], "%f", &tmpPAfreq) == 0) + return 2; + PAfreq = tmpPAfreq; //the scale degree(which is the octave) is not loaded, it is obtained by the tunnings with getoctavesize() method - if (loadline(file,&tmp[0])!=0) return(2); + if(loadline(file, &tmp[0]) != 0) + return 2; //load the mappings - if (Pmapsize!=0) { - for (int nline=0;nlineaddparstr("name",(char *) Pname); - xml->addparstr("comment",(char *) Pcomment); + xml->addparstr("name", (char *) Pname); + xml->addparstr("comment", (char *) Pcomment); - xml->addparbool("invert_up_down",Pinvertupdown); - xml->addpar("invert_up_down_center",Pinvertupdowncenter); + xml->addparbool("invert_up_down", Pinvertupdown); + xml->addpar("invert_up_down_center", Pinvertupdowncenter); - xml->addparbool("enabled",Penabled); - xml->addpar("global_fine_detune",Pglobalfinedetune); + xml->addparbool("enabled", Penabled); + xml->addpar("global_fine_detune", Pglobalfinedetune); - xml->addpar("a_note",PAnote); - xml->addparreal("a_freq",PAfreq); + xml->addpar("a_note", PAnote); + xml->addparreal("a_freq", PAfreq); - if ((Penabled==0)&&(xml->minimal)) return; + if((Penabled == 0) && (xml->minimal)) + return; xml->beginbranch("SCALE"); - xml->addpar("scale_shift",Pscaleshift); - xml->addpar("first_key",Pfirstkey); - xml->addpar("last_key",Plastkey); - xml->addpar("middle_note",Pmiddlenote); + xml->addpar("scale_shift", Pscaleshift); + xml->addpar("first_key", Pfirstkey); + xml->addpar("last_key", Plastkey); + xml->addpar("middle_note", Pmiddlenote); xml->beginbranch("OCTAVE"); - xml->addpar("octave_size",octavesize); - for (int i=0;ibeginbranch("DEGREE",i); - if (octave[i].type==1) { - xml->addparreal("cents",octave[i].tuning); - }; - if (octave[i].type==2) { - xml->addpar("numerator",octave[i].x1); - xml->addpar("denominator",octave[i].x2); - }; + xml->addpar("octave_size", octavesize); + for(int i = 0; i < octavesize; i++) { + xml->beginbranch("DEGREE", i); + if(octave[i].type == 1) + xml->addparreal("cents", octave[i].tuning); + ; + if(octave[i].type == 2) { + xml->addpar("numerator", octave[i].x1); + xml->addpar("denominator", octave[i].x2); + } xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("KEYBOARD_MAPPING"); - xml->addpar("map_size",Pmapsize); - xml->addpar("mapping_enabled",Pmappingenabled); - for (int i=0;ibeginbranch("KEYMAP",i); - xml->addpar("degree",Pmapping[i]); + xml->addpar("map_size", Pmapsize); + xml->addpar("mapping_enabled", Pmappingenabled); + for(int i = 0; i < Pmapsize; i++) { + xml->beginbranch("KEYMAP", i); + xml->addpar("degree", Pmapping[i]); xml->endbranch(); - }; + } xml->endbranch(); xml->endbranch(); -}; +} void Microtonal::getfromXML(XMLwrapper *xml) { - xml->getparstr("name",(char *) Pname,MICROTONAL_MAX_NAME_LEN); - xml->getparstr("comment",(char *) Pcomment,MICROTONAL_MAX_NAME_LEN); + xml->getparstr("name", (char *) Pname, MICROTONAL_MAX_NAME_LEN); + xml->getparstr("comment", (char *) Pcomment, MICROTONAL_MAX_NAME_LEN); - Pinvertupdown=xml->getparbool("invert_up_down",Pinvertupdown); - Pinvertupdowncenter=xml->getpar127("invert_up_down_center",Pinvertupdowncenter); + Pinvertupdown = xml->getparbool("invert_up_down", Pinvertupdown); + Pinvertupdowncenter = xml->getpar127("invert_up_down_center", + Pinvertupdowncenter); - Penabled=xml->getparbool("enabled",Penabled); - Pglobalfinedetune=xml->getpar127("global_fine_detune",Pglobalfinedetune); + Penabled = xml->getparbool("enabled", Penabled); + Pglobalfinedetune = xml->getpar127("global_fine_detune", Pglobalfinedetune); - PAnote=xml->getpar127("a_note",PAnote); - PAfreq=xml->getparreal("a_freq",PAfreq,1.0,10000.0); + PAnote = xml->getpar127("a_note", PAnote); + PAfreq = xml->getparreal("a_freq", PAfreq, 1.0, 10000.0); - if (xml->enterbranch("SCALE")) { - Pscaleshift=xml->getpar127("scale_shift",Pscaleshift); - Pfirstkey=xml->getpar127("first_key",Pfirstkey); - Plastkey=xml->getpar127("last_key",Plastkey); - Pmiddlenote=xml->getpar127("middle_note",Pmiddlenote); + if(xml->enterbranch("SCALE")) { + Pscaleshift = xml->getpar127("scale_shift", Pscaleshift); + Pfirstkey = xml->getpar127("first_key", Pfirstkey); + Plastkey = xml->getpar127("last_key", Plastkey); + Pmiddlenote = xml->getpar127("middle_note", Pmiddlenote); - if (xml->enterbranch("OCTAVE")) { - octavesize=xml->getpar127("octave_size",octavesize); - for (int i=0;ienterbranch("DEGREE",i)==0) continue; - octave[i].x2=0; - octave[i].tuning=xml->getparreal("cents",octave[i].tuning); - octave[i].x1=xml->getpar127("numerator",octave[i].x1); - octave[i].x2=xml->getpar127("denominator",octave[i].x2); + if(xml->enterbranch("OCTAVE")) { + octavesize = xml->getpar127("octave_size", octavesize); + for(int i = 0; i < octavesize; i++) { + if(xml->enterbranch("DEGREE", i) == 0) + continue; + octave[i].x2 = 0; + octave[i].tuning = xml->getparreal("cents", octave[i].tuning); + octave[i].x1 = xml->getpar127("numerator", octave[i].x1); + octave[i].x2 = xml->getpar127("denominator", octave[i].x2); - if (octave[i].x2!=0) octave[i].type=2; - else octave[i].type=1; + if(octave[i].x2 != 0) + octave[i].type = 2; + else + octave[i].type = 1; xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("KEYBOARD_MAPPING")) { - Pmapsize=xml->getpar127("map_size",Pmapsize); - Pmappingenabled=xml->getpar127("mapping_enabled",Pmappingenabled); - for (int i=0;ienterbranch("KEYMAP",i)==0) continue; - Pmapping[i]=xml->getpar127("degree",Pmapping[i]); + if(xml->enterbranch("KEYBOARD_MAPPING")) { + Pmapsize = xml->getpar127("map_size", Pmapsize); + Pmappingenabled = xml->getpar127("mapping_enabled", Pmappingenabled); + for(int i = 0; i < Pmapsize; i++) { + if(xml->enterbranch("KEYMAP", i) == 0) + continue; + Pmapping[i] = xml->getpar127("degree", Pmapping[i]); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; -}; + } +} -int Microtonal::saveXML(const char *filename)const +int Microtonal::saveXML(const char *filename) const { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); xml->beginbranch("MICROTONAL"); add2XML(xml); xml->endbranch(); - int result=xml->saveXMLfile(filename); + int result = xml->saveXMLfile(filename); delete (xml); - return(result); -}; + return result; +} int Microtonal::loadXML(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); - if (xml->loadXMLfile(filename)<0) { - delete(xml); - return(-1); - }; + XMLwrapper *xml = new XMLwrapper(); + if(xml->loadXMLfile(filename) < 0) { + delete (xml); + return -1; + } - if (xml->enterbranch("MICROTONAL")==0) return(-10); + if(xml->enterbranch("MICROTONAL") == 0) + return -10; getfromXML(xml); xml->exitbranch(); - delete(xml); - return(0); -}; - + delete (xml); + return 0; +} diff --git a/plugins/zynaddsubfx/src/Misc/Microtonal.h b/plugins/zynaddsubfx/src/Misc/Microtonal.h index 99d73a24d..c7fd7c200 100644 --- a/plugins/zynaddsubfx/src/Misc/Microtonal.h +++ b/plugins/zynaddsubfx/src/Misc/Microtonal.h @@ -35,102 +35,100 @@ /**Tuning settings and microtonal capabilities*/ class Microtonal { -public: - /**Constructor*/ - Microtonal(); - /**Destructor*/ - ~Microtonal(); - void defaults(); - /**Calculates the frequency for a given note - */ - REALTYPE getnotefreq(int note,int keyshift) const; + public: + /**Constructor*/ + Microtonal(); + /**Destructor*/ + ~Microtonal(); + void defaults(); + /**Calculates the frequency for a given note + */ + REALTYPE getnotefreq(int note, int keyshift) const; - //Parameters - /**if the keys are inversed (the pitch is lower to keys from the right direction)*/ - unsigned char Pinvertupdown; + //Parameters + /**if the keys are inversed (the pitch is lower to keys from the right direction)*/ + unsigned char Pinvertupdown; - /**the central key of the inversion*/ - unsigned char Pinvertupdowncenter; + /**the central key of the inversion*/ + unsigned char Pinvertupdowncenter; - /**0 for 12 key temperate scale, 1 for microtonal*/ - unsigned char Penabled; + /**0 for 12 key temperate scale, 1 for microtonal*/ + unsigned char Penabled; - /**the note of "A" key*/ - unsigned char PAnote; + /**the note of "A" key*/ + unsigned char PAnote; - /**the frequency of the "A" note*/ - REALTYPE PAfreq; + /**the frequency of the "A" note*/ + REALTYPE PAfreq; - /**if the scale is "tuned" to a note, you can tune to other note*/ - unsigned char Pscaleshift; + /**if the scale is "tuned" to a note, you can tune to other note*/ + unsigned char Pscaleshift; - //first and last key (to retune) - unsigned char Pfirstkey; - unsigned char Plastkey; + //first and last key (to retune) + unsigned char Pfirstkey; + unsigned char Plastkey; - /**The middle note where scale degree 0 is mapped to*/ - unsigned char Pmiddlenote; + /**The middle note where scale degree 0 is mapped to*/ + unsigned char Pmiddlenote; - /**Map size*/ - unsigned char Pmapsize; + /**Map size*/ + unsigned char Pmapsize; - /**Mapping ON/OFF*/ - unsigned char Pmappingenabled; - /**Mapping (keys)*/ - short int Pmapping[128]; + /**Mapping ON/OFF*/ + unsigned char Pmappingenabled; + /**Mapping (keys)*/ + short int Pmapping[128]; - /**Fine detune to be applied to all notes*/ - unsigned char Pglobalfinedetune; + /**Fine detune to be applied to all notes*/ + unsigned char Pglobalfinedetune; - // Functions - /** Return the current octave size*/ - unsigned char getoctavesize() const; - /**Convert tunning to string*/ - void tuningtoline(int n,char *line,int maxn); - /**load the tunnings from a .scl file*/ - int loadscl(const char *filename); - /**load the mapping from .kbm file*/ - int loadkbm(const char *filename); - /**Load text into the internal tunings - * - *\todo better description*/ - int texttotunings(const char *text); - /**Load text into the internal mappings - * - *\todo better description*/ - void texttomapping(const char *text); + // Functions + /** Return the current octave size*/ + unsigned char getoctavesize() const; + /**Convert tunning to string*/ + void tuningtoline(int n, char *line, int maxn); + /**load the tunnings from a .scl file*/ + int loadscl(const char *filename); + /**load the mapping from .kbm file*/ + int loadkbm(const char *filename); + /**Load text into the internal tunings + * + *\todo better description*/ + int texttotunings(const char *text); + /**Load text into the internal mappings + * + *\todo better description*/ + void texttomapping(const char *text); - /**Name of Microtonal tuning*/ - unsigned char *Pname; - /**Comment about the tuning*/ - unsigned char *Pcomment; + /**Name of Microtonal tuning*/ + unsigned char *Pname; + /**Comment about the tuning*/ + unsigned char *Pcomment; - void add2XML(XMLwrapper *xml)const; - void getfromXML(XMLwrapper *xml); - int saveXML(const char *filename)const; - int loadXML(const char *filename); + void add2XML(XMLwrapper *xml) const; + void getfromXML(XMLwrapper *xml); + int saveXML(const char *filename) const; + int loadXML(const char *filename); - //simple operators primarily for debug - bool operator==(const Microtonal µ) const; - bool operator!=(const Microtonal µ) const; + //simple operators primarily for debug + bool operator==(const Microtonal µ) const; + bool operator!=(const Microtonal µ) const; -private: - int linetotunings(unsigned int nline,const char *line); - int loadline(FILE *file,char *line);//loads a line from the text file, while ignoring the lines beggining with "!" - unsigned char octavesize; - struct { - unsigned char type;//1 for cents or 2 for division + private: + int linetotunings(unsigned int nline, const char *line); + int loadline(FILE *file, char *line); //loads a line from the text file, while ignoring the lines beggining with "!" + unsigned char octavesize; + struct { + unsigned char type; //1 for cents or 2 for division - // the real tuning (eg. +1.05946 for one halftone) - // or 2.0 for one octave - REALTYPE tuning; - - //the real tunning is x1/x2 - unsigned int x1,x2; - - } octave[MAX_OCTAVE_SIZE],tmpoctave[MAX_OCTAVE_SIZE]; + // the real tuning (eg. +1.05946 for one halftone) + // or 2.0 for one octave + REALTYPE tuning; + //the real tunning is x1/x2 + unsigned int x1, x2; + } octave[MAX_OCTAVE_SIZE], tmpoctave[MAX_OCTAVE_SIZE]; }; #endif diff --git a/plugins/zynaddsubfx/src/Misc/Part.cpp b/plugins/zynaddsubfx/src/Misc/Part.cpp index 2adf152d7..2f8dfe7ba 100644 --- a/plugins/zynaddsubfx/src/Misc/Part.cpp +++ b/plugins/zynaddsubfx/src/Misc/Part.cpp @@ -26,122 +26,122 @@ #include #include -Part::Part(Microtonal *microtonal_,FFTwrapper *fft_, pthread_mutex_t *mutex_) +Part::Part(Microtonal *microtonal_, FFTwrapper *fft_, pthread_mutex_t *mutex_) { - microtonal=microtonal_; - fft=fft_; - mutex=mutex_; - partoutl=new REALTYPE [SOUND_BUFFER_SIZE]; - partoutr=new REALTYPE [SOUND_BUFFER_SIZE]; - tmpoutl=new REALTYPE [SOUND_BUFFER_SIZE]; - tmpoutr=new REALTYPE [SOUND_BUFFER_SIZE]; + microtonal = microtonal_; + fft = fft_; + mutex = mutex_; + partoutl = new REALTYPE [SOUND_BUFFER_SIZE]; + partoutr = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpoutl = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpoutr = new REALTYPE [SOUND_BUFFER_SIZE]; - for (int n=0;ndefaults(); kit[0].subpars->defaults(); kit[0].padpars->defaults(); - for (int nefx=0;nefxdefaults(); - Pefxroute[nefx]=0;//route to next effect - }; - -}; + Pefxroute[nefx] = 0; //route to next effect + } +} @@ -150,321 +150,515 @@ void Part::defaultsinstrument() */ void Part::cleanup() { - for (int k=0;kcleanup(); - for (int n=0;ncleanup(); + for(int n = 0; n < NUM_PART_EFX + 1; n++) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + partfxinputl[n][i] = denormalkillbuf[i]; + partfxinputr[n][i] = denormalkillbuf[i]; + } + } +} Part::~Part() { cleanup(); - for (int n=0;nPmaxkey)) return; + if(Pnoteon == 0) + return; + if((note < Pminkey) || (note > Pmaxkey)) + return; // MonoMem stuff: - if (Ppolymode==0) { // If Poly is off + if(Ppolymode == 0) { // If Poly is off monomemnotes.push_back(note); // Add note to the list. - monomem[note].velocity=velocity; // Store this note's velocity. - monomem[note].mkeyshift=masterkeyshift; /* Store masterkeyshift too, - I'm not sure why though... */ - if ((partnote[lastpos].status!=KEY_PLAYING) - && (partnote[lastpos].status!=KEY_RELASED_AND_SUSTAINED)) { - ismonofirstnote=true; // No other keys are held or sustained. + monomem[note].velocity = velocity; // Store this note's velocity. + monomem[note].mkeyshift = masterkeyshift; /* Store masterkeyshift too, + I'm not sure why though... */ + if((partnote[lastpos].status != KEY_PLAYING) + && (partnote[lastpos].status != KEY_RELASED_AND_SUSTAINED)) + ismonofirstnote = true; // No other keys are held or sustained. + } + else + // Poly mode is On so just make sure the list is empty. + if(not monomemnotes.empty()) + monomemnotes.clear(); + + lastnote = note; + + pos = -1; + for(i = 0; i < POLIPHONY; i++) { + if(partnote[i].status == KEY_OFF) { + pos = i; + break; } - } else { - // Poly mode is On so just make sure the list is empty. - if (not monomemnotes.empty()) monomemnotes.clear(); } - lastnote=note; - - pos=-1; - for (i=0;i POLIPHONY) - (Part.C::NoteOn(..))\n"); - } else { - + fprintf(stderr, + "%s", + "NOTES TOO MANY (> POLIPHONY) - (Part.C::NoteOn(..))\n"); + else { //start the note - partnote[pos].status=KEY_PLAYING; - partnote[pos].note=note; - if (legatomodevalid) { - partnote[posb].status=KEY_PLAYING; - partnote[posb].note=note; + partnote[pos].status = KEY_PLAYING; + partnote[pos].note = note; + if(legatomodevalid) { + partnote[posb].status = KEY_PLAYING; + partnote[posb].note = note; } //this computes the velocity sensing of the part - REALTYPE vel=VelF(velocity/127.0,Pvelsns); + REALTYPE vel = VelF(velocity / 127.0, Pvelsns); //compute the velocity offset - vel+=(Pveloffs-64.0)/64.0; - if (vel<0.0) vel=0.0; - else if (vel>1.0) vel=1.0; + vel += (Pveloffs - 64.0) / 64.0; + if(vel < 0.0) + vel = 0.0; + else + if(vel > 1.0) + vel = 1.0; //compute the keyshift - int partkeyshift=(int)Pkeyshift-64; - int keyshift=masterkeyshift+partkeyshift; + int partkeyshift = (int)Pkeyshift - 64; + int keyshift = masterkeyshift + partkeyshift; //initialise note frequency REALTYPE notebasefreq; - if (Pdrummode==0) { - notebasefreq=microtonal->getnotefreq(note,keyshift); - if (notebasefreq<0.0) return;//the key is no mapped - } else { - notebasefreq=440.0*pow(2.0,(note-69.0)/12.0); - }; + if(Pdrummode == 0) { + notebasefreq = microtonal->getnotefreq(note, keyshift); + if(notebasefreq < 0.0) + return; //the key is no mapped + } + else + notebasefreq = 440.0 * pow(2.0, (note - 69.0) / 12.0); + ; //Portamento - if (oldfreq<1.0) oldfreq=notebasefreq;//this is only the first note is played + if(oldfreq < 1.0) + oldfreq = notebasefreq; //this is only the first note is played // For Mono/Legato: Force Portamento Off on first // notes. That means it is required that the previous note is // still held down or sustained for the Portamento to activate // (that's like Legato). - int portamento=0; - if ((Ppolymode!=0) || (not ismonofirstnote)) { + int portamento = 0; + if((Ppolymode != 0) || (not ismonofirstnote)) // I added a third argument to the // ctl.initportamento(...) function to be able // to tell it if we're doing a legato note. - portamento=ctl.initportamento(oldfreq,notebasefreq,doinglegato); - } + portamento = ctl.initportamento(oldfreq, notebasefreq, doinglegato); - if (portamento!=0) ctl.portamento.noteusing=pos; - oldfreq=notebasefreq; + if(portamento != 0) + ctl.portamento.noteusing = pos; + oldfreq = notebasefreq; - lastpos=pos; // Keep a trace of used pos. + lastpos = pos; // Keep a trace of used pos. - if (doinglegato) { + if(doinglegato) { // Do Legato note - if (Pkitmode==0) { // "normal mode" legato note - if ((kit[0].Padenabled!=0) - && (partnote[pos].kititem[0].adnote!=NULL) - && (partnote[posb].kititem[0].adnote!=NULL)) { - partnote[pos].kititem[0].adnote->ADlegatonote(notebasefreq, vel, portamento, note, true);//'true' is to tell it it's being called from here. - partnote[posb].kititem[0].adnote->ADlegatonote(notebasefreq, vel, portamento, note, true); + if(Pkitmode == 0) { // "normal mode" legato note + if((kit[0].Padenabled != 0) + && (partnote[pos].kititem[0].adnote != NULL) + && (partnote[posb].kititem[0].adnote != NULL)) { + partnote[pos].kititem[0].adnote->ADlegatonote(notebasefreq, + vel, + portamento, + note, + true); //'true' is to tell it it's being called from here. + partnote[posb].kititem[0].adnote->ADlegatonote(notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[0].Psubenabled!=0) - && (partnote[pos].kititem[0].subnote!=NULL) - && (partnote[posb].kititem[0].subnote!=NULL)) { - partnote[pos].kititem[0].subnote->SUBlegatonote(notebasefreq, vel, portamento, note, true); - partnote[posb].kititem[0].subnote->SUBlegatonote(notebasefreq, vel, portamento, note, true); + if((kit[0].Psubenabled != 0) + && (partnote[pos].kititem[0].subnote != NULL) + && (partnote[posb].kititem[0].subnote != NULL)) { + partnote[pos].kititem[0].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[0].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[0].Ppadenabled!=0) - && (partnote[pos].kititem[0].padnote!=NULL) - && (partnote[posb].kititem[0].padnote!=NULL)) { - partnote[pos].kititem[0].padnote->PADlegatonote(notebasefreq, vel, portamento, note, true); - partnote[posb].kititem[0].padnote->PADlegatonote(notebasefreq, vel, portamento, note, true); + if((kit[0].Ppadenabled != 0) + && (partnote[pos].kititem[0].padnote != NULL) + && (partnote[posb].kititem[0].padnote != NULL)) { + partnote[pos].kititem[0].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[0].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } + } + else { // "kit mode" legato note + int ci = 0; + for(int item = 0; item < NUM_KIT_ITEMS; item++) { + if(kit[item].Pmuted != 0) + continue; + if((note < kit[item].Pminkey) || (note > kit[item].Pmaxkey)) + continue; - } else { // "kit mode" legato note - int ci=0; - for (int item=0;itemkit[item].Pmaxkey)) continue; - - if ((lastnotecopykit[item].Pmaxkey)) + if((lastnotecopy < kit[item].Pminkey) + || (lastnotecopy > kit[item].Pmaxkey)) continue; // We will not perform legato across 2 key regions. - partnote[pos].kititem[ci].sendtoparteffect=( kit[item].PsendtoparteffectADlegatonote(notebasefreq,vel,portamento,note,true); - partnote[posb].kititem[ci].adnote->ADlegatonote(notebasefreq,vel,portamento,note,true); + if((kit[item].Padenabled != 0) && (kit[item].adpars != NULL) + && (partnote[pos].kititem[ci].adnote != NULL) + && (partnote[posb].kititem[ci].adnote != NULL)) { + partnote[pos].kititem[ci].adnote->ADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[ci].adnote->ADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[item].Psubenabled!=0) && (kit[item].subpars!=NULL) - && (partnote[pos].kititem[ci].subnote!=NULL) - && (partnote[posb].kititem[ci].subnote!=NULL)) { - partnote[pos].kititem[ci].subnote->SUBlegatonote(notebasefreq,vel,portamento,note,true); - partnote[posb].kititem[ci].subnote->SUBlegatonote(notebasefreq,vel,portamento,note,true); + if((kit[item].Psubenabled != 0) + && (kit[item].subpars != NULL) + && (partnote[pos].kititem[ci].subnote != NULL) + && (partnote[posb].kititem[ci].subnote != NULL)) { + partnote[pos].kititem[ci].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[ci].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[item].Ppadenabled!=0) && (kit[item].padpars!=NULL) - && (partnote[pos].kititem[ci].padnote!=NULL) - && (partnote[posb].kititem[ci].padnote!=NULL)) { - partnote[pos].kititem[ci].padnote->PADlegatonote(notebasefreq,vel,portamento,note,true); - partnote[posb].kititem[ci].padnote->PADlegatonote(notebasefreq,vel,portamento,note,true); + if((kit[item].Ppadenabled != 0) + && (kit[item].padpars != NULL) + && (partnote[pos].kititem[ci].padnote != NULL) + && (partnote[posb].kititem[ci].padnote != NULL)) { + partnote[pos].kititem[ci].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[ci].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[item].adpars!=NULL)||(kit[item].subpars!=NULL)||(kit[item].padpars!=NULL)) { + if((kit[item].adpars != NULL) + || (kit[item].subpars != NULL) + || (kit[item].padpars != NULL)) { ci++; - if ( ((kit[item].Padenabled!=0)||(kit[item].Psubenabled!=0)||(kit[item].Ppadenabled!=0)) && (Pkitmode==2) ) break; + if(((kit[item].Padenabled != 0) + || (kit[item].Psubenabled != 0) + || (kit[item].Ppadenabled != 0)) && (Pkitmode == 2)) + break; } } - if (ci==0) { + if(ci == 0) { // No legato were performed at all, so pretend nothing happened: monomemnotes.pop_back(); // Remove last note from the list. - lastnote=lastnotecopy; // Set lastnote back to previous value. + lastnote = lastnotecopy; // Set lastnote back to previous value. } } return; // Ok, Legato note done, return. } - partnote[pos].itemsplaying=0; - if (legatomodevalid) partnote[posb].itemsplaying=0; + partnote[pos].itemsplaying = 0; + if(legatomodevalid) + partnote[posb].itemsplaying = 0; - if (Pkitmode==0) {//init the notes for the "normal mode" - partnote[pos].kititem[0].sendtoparteffect=0; - if (kit[0].Padenabled!=0) partnote[pos].kititem[0].adnote=new ADnote(kit[0].adpars,&ctl,notebasefreq,vel,portamento,note,false); - if (kit[0].Psubenabled!=0) partnote[pos].kititem[0].subnote=new SUBnote(kit[0].subpars,&ctl,notebasefreq,vel,portamento,note,false); - if (kit[0].Ppadenabled!=0) partnote[pos].kititem[0].padnote=new PADnote(kit[0].padpars,&ctl,notebasefreq,vel,portamento,note,false); - if ((kit[0].Padenabled!=0)||(kit[0].Psubenabled!=0)||(kit[0].Ppadenabled!=0)) partnote[pos].itemsplaying++; + if(Pkitmode == 0) { //init the notes for the "normal mode" + partnote[pos].kititem[0].sendtoparteffect = 0; + if(kit[0].Padenabled != 0) + partnote[pos].kititem[0].adnote = new ADnote(kit[0].adpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); + if(kit[0].Psubenabled != 0) + partnote[pos].kititem[0].subnote = new SUBnote(kit[0].subpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); + if(kit[0].Ppadenabled != 0) + partnote[pos].kititem[0].padnote = new PADnote(kit[0].padpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); + if((kit[0].Padenabled != 0) || (kit[0].Psubenabled != 0) + || (kit[0].Ppadenabled != 0)) + partnote[pos].itemsplaying++; // Spawn another note (but silent) if legatomodevalid==true - if (legatomodevalid) { - partnote[posb].kititem[0].sendtoparteffect=0; - if (kit[0].Padenabled!=0) partnote[posb].kititem[0].adnote=new ADnote(kit[0].adpars,&ctl,notebasefreq,vel,portamento,note,true);//true for silent. - if (kit[0].Psubenabled!=0) partnote[posb].kititem[0].subnote=new SUBnote(kit[0].subpars,&ctl,notebasefreq,vel,portamento,note,true); - if (kit[0].Ppadenabled!=0) partnote[posb].kititem[0].padnote=new PADnote(kit[0].padpars,&ctl,notebasefreq,vel,portamento,note,true); - if ((kit[0].Padenabled!=0)||(kit[0].Psubenabled!=0)||(kit[0].Ppadenabled!=0)) partnote[posb].itemsplaying++; + if(legatomodevalid) { + partnote[posb].kititem[0].sendtoparteffect = 0; + if(kit[0].Padenabled != 0) + partnote[posb].kititem[0].adnote = new ADnote(kit[0].adpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); //true for silent. + if(kit[0].Psubenabled != 0) + partnote[posb].kititem[0].subnote = new SUBnote( + kit[0].subpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); + if(kit[0].Ppadenabled != 0) + partnote[posb].kititem[0].padnote = new PADnote( + kit[0].padpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); + if((kit[0].Padenabled != 0) || (kit[0].Psubenabled != 0) + || (kit[0].Ppadenabled != 0)) + partnote[posb].itemsplaying++; } + } + else { //init the notes for the "kit mode" + for(int item = 0; item < NUM_KIT_ITEMS; item++) { + if(kit[item].Pmuted != 0) + continue; + if((note < kit[item].Pminkey) || (note > kit[item].Pmaxkey)) + continue; - } else {//init the notes for the "kit mode" - for (int item=0;itemkit[item].Pmaxkey)) continue; + int ci = partnote[pos].itemsplaying; //ci=current item - int ci=partnote[pos].itemsplaying;//ci=current item + partnote[pos].kititem[ci].sendtoparteffect = + (kit[item].Psendtoparteffect < NUM_PART_EFX ? + kit[item]. + Psendtoparteffect : NUM_PART_EFX); //if this parameter is 127 for "unprocessed" - partnote[pos].kititem[ci].sendtoparteffect=( kit[item].Psendtoparteffect=0;i--) { //first note in, is first out if there are same note multiple times - if ((partnote[i].status==KEY_PLAYING)&&(partnote[i].note==note)) { - if (ctl.sustain.sustain==0) { //the sustain pedal is not pushed - if ((Ppolymode==0) && (not monomemnotes.empty())) { + for(i = POLIPHONY - 1; i >= 0; i--) //first note in, is first out if there are same note multiple times + if((partnote[i].status == KEY_PLAYING) && (partnote[i].note == note)) { + if(ctl.sustain.sustain == 0) { //the sustain pedal is not pushed + if((Ppolymode == 0) && (not monomemnotes.empty())) MonoMemRenote(); // To play most recent still held note. - } else { + else RelaseNotePos(i); /// break; - } - } else {//the sustain pedal is pushed - partnote[i].status=KEY_RELASED_AND_SUSTAINED; } + else //the sustain pedal is pushed + partnote[i].status = KEY_RELASED_AND_SUSTAINED; } - } -}; +} /* * Controllers */ -void Part::SetController(unsigned int type,int par) +void Part::SetController(unsigned int type, int par) { - switch (type) { + switch(type) { case C_pitchwheel: ctl.setpitchwheel(par); break; case C_expression: ctl.setexpression(par); - setPvolume(Pvolume);//update the volume + setPvolume(Pvolume); //update the volume break; case C_portamento: ctl.setportamento(par); break; case C_panning: ctl.setpanning(par); - setPpanning(Ppanning);//update the panning + setPpanning(Ppanning); //update the panning break; case C_filtercutoff: ctl.setfiltercutoff(par); @@ -529,32 +722,38 @@ void Part::SetController(unsigned int type,int par) break; case C_volume: ctl.setvolume(par); - if (ctl.volume.receive!=0) volume=ctl.volume.volume; - else setPvolume(Pvolume); + if(ctl.volume.receive != 0) + volume = ctl.volume.volume; + else + setPvolume(Pvolume); break; case C_sustain: ctl.setsustain(par); - if (ctl.sustain.sustain==0) RelaseSustainedKeys(); + if(ctl.sustain.sustain == 0) + RelaseSustainedKeys(); break; case C_allsoundsoff: - AllNotesOff();//Panic + AllNotesOff(); //Panic break; case C_resetallcontrollers: ctl.resetall(); RelaseSustainedKeys(); - if (ctl.volume.receive!=0) volume=ctl.volume.volume; - else setPvolume(Pvolume); - setPvolume(Pvolume);//update the volume - setPpanning(Ppanning);//update the panning + if(ctl.volume.receive != 0) + volume = ctl.volume.volume; + else + setPvolume(Pvolume); + setPvolume(Pvolume); //update the volume + setPpanning(Ppanning); //update the panning - for (int item=0;itemGlobalPar.Reson-> - sendcontroller(C_resonance_center,1.0); + sendcontroller(C_resonance_center, 1.0); kit[item].adpars->GlobalPar.Reson-> - sendcontroller(C_resonance_bandwidth,1.0); - }; + sendcontroller(C_resonance_bandwidth, 1.0); + } //more update to add here if I add controllers break; case C_allnotesoff: @@ -562,19 +761,20 @@ void Part::SetController(unsigned int type,int par) break; case C_resonance_center: ctl.setresonancecenter(par); - for (int item=0;itemGlobalPar.Reson-> - sendcontroller(C_resonance_center,ctl.resonancecenter.relcenter); - }; + sendcontroller(C_resonance_center, ctl.resonancecenter.relcenter); + } break; case C_resonance_bandwidth: ctl.setresonancebw(par); kit[0].adpars->GlobalPar.Reson-> - sendcontroller(C_resonance_bandwidth,ctl.resonancebandwidth.relbw); + sendcontroller(C_resonance_bandwidth, ctl.resonancebandwidth.relbw); break; - }; -}; + } +} /* * Relase the sustained keys */ @@ -582,13 +782,14 @@ void Part::SetController(unsigned int type,int par) void Part::RelaseSustainedKeys() { // Let's call MonoMemRenote() on some conditions: - if ((Ppolymode==0) && (not monomemnotes.empty())) - if (monomemnotes.back()!=lastnote) // Sustain controller manipulation would cause repeated same note respawn without this check. + if((Ppolymode == 0) && (not monomemnotes.empty())) + if(monomemnotes.back() != lastnote) // Sustain controller manipulation would cause repeated same note respawn without this check. MonoMemRenote(); // To play most recent still held note. - for (int i=0;irelasekey(); - if (partnote[pos].kititem[j].subnote!=NULL) - if (partnote[pos].kititem[j].subnote!=NULL) + if(partnote[pos].kititem[j].subnote != NULL) + if(partnote[pos].kititem[j].subnote != NULL) partnote[pos].kititem[j].subnote->relasekey(); - if (partnote[pos].kititem[j].padnote!=NULL) - if (partnote[pos].kititem[j].padnote) + if(partnote[pos].kititem[j].padnote != NULL) + if(partnote[pos].kititem[j].padnote) partnote[pos].kititem[j].padnote->relasekey(); - }; - partnote[pos].status=KEY_RELASED; -}; + } + partnote[pos].status = KEY_RELASED; +} /* @@ -646,30 +844,30 @@ void Part::RelaseNotePos(int pos) */ void Part::KillNotePos(int pos) { - partnote[pos].status=KEY_OFF; - partnote[pos].note=-1; - partnote[pos].time=0; - partnote[pos].itemsplaying=0; + partnote[pos].status = KEY_OFF; + partnote[pos].note = -1; + partnote[pos].time = 0; + partnote[pos].itemsplaying = 0; - for (int j=0;jPkeylimit=Pkeylimit; - int keylimit=Pkeylimit; - if (keylimit==0) keylimit=POLIPHONY-5; + this->Pkeylimit = Pkeylimit; + int keylimit = Pkeylimit; + if(keylimit == 0) + keylimit = POLIPHONY - 5; //release old keys if the number of notes>keylimit - if (Ppolymode!=0) { - int notecount=0; - for (int i=0;ikeylimit) {//find out the oldest note - for (int i=0;imaxtime)) { - maxtime=partnote[i].time; - oldestnotepos=i; - }; - }; - }; - if (oldestnotepos!=-1) RelaseNotePos(oldestnotepos); - }; -}; + ; + int oldestnotepos = -1, maxtime = 0; + if(notecount > keylimit) { //find out the oldest note + for(int i = 0; i < POLIPHONY; i++) { + if(((partnote[i].status == KEY_PLAYING) + || (partnote[i].status == KEY_RELASED_AND_SUSTAINED)) + && (partnote[i].time > maxtime)) { + maxtime = partnote[i].time; + oldestnotepos = i; + } + } + } + if(oldestnotepos != -1) + RelaseNotePos(oldestnotepos); + } +} /* @@ -708,8 +910,8 @@ void Part::setkeylimit(unsigned char Pkeylimit) */ void Part::AllNotesOff() { - killallnotes=1; -}; + killallnotes = 1; +} /* @@ -717,266 +919,287 @@ void Part::AllNotesOff() */ void Part::ComputePartSmps() { - int i,k; - int noteplay;//0 if there is nothing activated - for (int nefx=0;nefxready!=0) adnote->noteout(&tmpoutl[0],&tmpoutr[0]); - else for (i=0;ifinished()!=0) { + if(adnote->ready != 0) + adnote->noteout(&tmpoutl[0], &tmpoutr[0]); + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpoutl[i] = 0.0; + tmpoutr[i] = 0.0; + } + ; + if(adnote->finished() != 0) { delete (adnote); - partnote[k].kititem[item].adnote=NULL; - }; - for (i=0;iready!=0) subnote->noteout(&tmpoutl[0],&tmpoutr[0]); - else for (i=0;iready != 0) + subnote->noteout(&tmpoutl[0], &tmpoutr[0]); + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpoutl[i] = 0.0; + tmpoutr[i] = 0.0; + } + ; - for (i=0;ifinished()!=0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //add the SUBnote to part(mix) + partfxinputl[sendcurrenttofx][i] += tmpoutl[i]; + partfxinputr[sendcurrenttofx][i] += tmpoutr[i]; + } + if(subnote->finished() != 0) { delete (subnote); - partnote[k].kititem[item].subnote=NULL; - }; - }; + partnote[k].kititem[item].subnote = NULL; + } + } //get from the PADnote - if (padnote!=NULL) { + if(padnote != NULL) { noteplay++; - if (padnote->ready!=0) padnote->noteout(&tmpoutl[0],&tmpoutr[0]); - else for (i=0;ifinished()!=0) { + if(padnote->ready != 0) + padnote->noteout(&tmpoutl[0], &tmpoutr[0]); + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpoutl[i] = 0.0; + tmpoutr[i] = 0.0; + } + ; + if(padnote->finished() != 0) { delete (padnote); - partnote[k].kititem[item].padnote=NULL; - }; - for (i=0;iout(partfxinputl[nefx],partfxinputr[nefx]); - if (Pefxroute[nefx]==2) { - for (i=0;iefxoutl[i]; - partfxinputr[nefx+1][i]+=partefx[nefx]->efxoutr[i]; - }; - }; - }; - int routeto=((Pefxroute[nefx]==0) ? nefx+1 : NUM_PART_EFX); - for (i=0;iout(partfxinputl[nefx], partfxinputr[nefx]); + if(Pefxroute[nefx] == 2) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + partfxinputl[nefx + 1][i] += partefx[nefx]->efxoutl[i]; + partfxinputr[nefx + 1][i] += partefx[nefx]->efxoutr[i]; + } + } + } + int routeto = ((Pefxroute[nefx] == 0) ? nefx + 1 : NUM_PART_EFX); + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + partfxinputl[routeto][i] += partfxinputl[nefx][i]; + partfxinputr[routeto][i] += partfxinputr[nefx][i]; + } + } + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + partoutl[i] = partfxinputl[NUM_PART_EFX][i]; + partoutr[i] = partfxinputr[NUM_PART_EFX][i]; + } //Kill All Notes if killallnotes!=0 - if (killallnotes!=0) { - for (i=0;icleanup(); - }; - }; + ; + } ctl.updateportamento(); -}; +} /* * Parameter control */ void Part::setPvolume(char Pvolume_) { - Pvolume=Pvolume_; - volume=dB2rap((Pvolume-96.0)/96.0*40.0)*ctl.expression.relvolume; -}; + Pvolume = Pvolume_; + volume = dB2rap((Pvolume - 96.0) / 96.0 * 40.0) * ctl.expression.relvolume; +} void Part::setPpanning(char Ppanning_) { - Ppanning=Ppanning_; - panning=Ppanning/127.0+ctl.panning.pan; - if (panning<0.0) panning=0.0; - else if (panning>1.0) panning=1.0; - -}; + Ppanning = Ppanning_; + panning = Ppanning / 127.0 + ctl.panning.pan; + if(panning < 0.0) + panning = 0.0; + else + if(panning > 1.0) + panning = 1.0; +} /* * Enable or disable a kit item */ -void Part::setkititemstatus(int kititem,int Penabled_) +void Part::setkititemstatus(int kititem, int Penabled_) { - if ((kititem==0)&&(kititem>=NUM_KIT_ITEMS)) return;//nonexistent kit item and the first kit item is always enabled - kit[kititem].Penabled=Penabled_; + if((kititem == 0) && (kititem >= NUM_KIT_ITEMS)) + return; //nonexistent kit item and the first kit item is always enabled + kit[kititem].Penabled = Penabled_; - bool resetallnotes=false; - if (Penabled_==0) { - if (kit[kititem].adpars!=NULL) delete (kit[kititem].adpars); - if (kit[kititem].subpars!=NULL) delete (kit[kititem].subpars); - if (kit[kititem].padpars!=NULL) { + bool resetallnotes = false; + if(Penabled_ == 0) { + if(kit[kititem].adpars != NULL) + delete (kit[kititem].adpars); + if(kit[kititem].subpars != NULL) + delete (kit[kititem].subpars); + if(kit[kititem].padpars != NULL) { delete (kit[kititem].padpars); - resetallnotes=true; - }; - kit[kititem].adpars=NULL; - kit[kititem].subpars=NULL; - kit[kititem].padpars=NULL; - kit[kititem].Pname[0]='\0'; - } else { - if (kit[kititem].adpars==NULL) kit[kititem].adpars=new ADnoteParameters(fft); - if (kit[kititem].subpars==NULL) kit[kititem].subpars=new SUBnoteParameters(); - if (kit[kititem].padpars==NULL) kit[kititem].padpars=new PADnoteParameters(fft,mutex); - }; + resetallnotes = true; + } + kit[kititem].adpars = NULL; + kit[kititem].subpars = NULL; + kit[kititem].padpars = NULL; + kit[kititem].Pname[0] = '\0'; + } + else { + if(kit[kititem].adpars == NULL) + kit[kititem].adpars = new ADnoteParameters(fft); + if(kit[kititem].subpars == NULL) + kit[kititem].subpars = new SUBnoteParameters(); + if(kit[kititem].padpars == NULL) + kit[kititem].padpars = new PADnoteParameters(fft, mutex); + } - if (resetallnotes) for (int k=0;kbeginbranch("INFO"); - xml->addparstr("name",(char *)Pname); - xml->addparstr("author",(char *)info.Pauthor); - xml->addparstr("comments",(char *)info.Pcomments); - xml->addpar("type",info.Ptype); + xml->addparstr("name", (char *)Pname); + xml->addparstr("author", (char *)info.Pauthor); + xml->addparstr("comments", (char *)info.Pcomments); + xml->addpar("type", info.Ptype); xml->endbranch(); xml->beginbranch("INSTRUMENT_KIT"); - xml->addpar("kit_mode",Pkitmode); - xml->addparbool("drum_mode",Pdrummode); + xml->addpar("kit_mode", Pkitmode); + xml->addparbool("drum_mode", Pdrummode); - for (int i=0;ibeginbranch("INSTRUMENT_KIT_ITEM",i); - xml->addparbool("enabled",kit[i].Penabled); - if (kit[i].Penabled!=0) { - xml->addparstr("name",(char *)kit[i].Pname); + for(int i = 0; i < NUM_KIT_ITEMS; i++) { + xml->beginbranch("INSTRUMENT_KIT_ITEM", i); + xml->addparbool("enabled", kit[i].Penabled); + if(kit[i].Penabled != 0) { + xml->addparstr("name", (char *)kit[i].Pname); - xml->addparbool("muted",kit[i].Pmuted); - xml->addpar("min_key",kit[i].Pminkey); - xml->addpar("max_key",kit[i].Pmaxkey); + xml->addparbool("muted", kit[i].Pmuted); + xml->addpar("min_key", kit[i].Pminkey); + xml->addpar("max_key", kit[i].Pmaxkey); - xml->addpar("send_to_instrument_effect",kit[i].Psendtoparteffect); + xml->addpar("send_to_instrument_effect", kit[i].Psendtoparteffect); - xml->addparbool("add_enabled",kit[i].Padenabled); - if ((kit[i].Padenabled!=0)&&(kit[i].adpars!=NULL)) { + xml->addparbool("add_enabled", kit[i].Padenabled); + if((kit[i].Padenabled != 0) && (kit[i].adpars != NULL)) { xml->beginbranch("ADD_SYNTH_PARAMETERS"); kit[i].adpars->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("sub_enabled",kit[i].Psubenabled); - if ((kit[i].Psubenabled!=0)&&(kit[i].subpars!=NULL)) { + xml->addparbool("sub_enabled", kit[i].Psubenabled); + if((kit[i].Psubenabled != 0) && (kit[i].subpars != NULL)) { xml->beginbranch("SUB_SYNTH_PARAMETERS"); kit[i].subpars->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("pad_enabled",kit[i].Ppadenabled); - if ((kit[i].Ppadenabled!=0)&&(kit[i].padpars!=NULL)) { + xml->addparbool("pad_enabled", kit[i].Ppadenabled); + if((kit[i].Ppadenabled != 0) && (kit[i].padpars != NULL)) { xml->beginbranch("PAD_SYNTH_PARAMETERS"); kit[i].padpars->add2XML(xml); xml->endbranch(); - }; - - }; + } + } xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("INSTRUMENT_EFFECTS"); - for (int nefx=0;nefxbeginbranch("INSTRUMENT_EFFECT",nefx); + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) { + xml->beginbranch("INSTRUMENT_EFFECT", nefx); xml->beginbranch("EFFECT"); partefx[nefx]->add2XML(xml); xml->endbranch(); - xml->addpar("route",Pefxroute[nefx]); - partefx[nefx]->setdryonly(Pefxroute[nefx]==2); - xml->addparbool("bypass",Pefxbypass[nefx]); + xml->addpar("route", Pefxroute[nefx]); + partefx[nefx]->setdryonly(Pefxroute[nefx] == 2); + xml->addparbool("bypass", Pefxbypass[nefx]); xml->endbranch(); - }; + } xml->endbranch(); -}; +} void Part::add2XML(XMLwrapper *xml) { //parameters - xml->addparbool("enabled",Penabled); - if ((Penabled==0)&&(xml->minimal)) return; + xml->addparbool("enabled", Penabled); + if((Penabled == 0) && (xml->minimal)) + return; - xml->addpar("volume",Pvolume); - xml->addpar("panning",Ppanning); + xml->addpar("volume", Pvolume); + xml->addpar("panning", Ppanning); - xml->addpar("min_key",Pminkey); - xml->addpar("max_key",Pmaxkey); - xml->addpar("key_shift",Pkeyshift); - xml->addpar("rcv_chn",Prcvchn); + xml->addpar("min_key", Pminkey); + xml->addpar("max_key", Pmaxkey); + xml->addpar("key_shift", Pkeyshift); + xml->addpar("rcv_chn", Prcvchn); - xml->addpar("velocity_sensing",Pvelsns); - xml->addpar("velocity_offset",Pveloffs); + xml->addpar("velocity_sensing", Pvelsns); + xml->addpar("velocity_offset", Pveloffs); - xml->addparbool("note_on",Pnoteon); - xml->addparbool("poly_mode",Ppolymode); - xml->addpar("legato_mode",Plegatomode); - xml->addpar("key_limit",Pkeylimit); + xml->addparbool("note_on", Pnoteon); + xml->addparbool("poly_mode", Ppolymode); + xml->addpar("legato_mode", Plegatomode); + xml->addpar("key_limit", Pkeylimit); xml->beginbranch("INSTRUMENT"); add2XMLinstrument(xml); @@ -985,154 +1208,163 @@ void Part::add2XML(XMLwrapper *xml) xml->beginbranch("CONTROLLER"); ctl.add2XML(xml); xml->endbranch(); -}; +} int Part::saveXML(char *filename) { XMLwrapper *xml; - xml=new XMLwrapper(); + xml = new XMLwrapper(); xml->beginbranch("INSTRUMENT"); add2XMLinstrument(xml); xml->endbranch(); - int result=xml->saveXMLfile(filename); + int result = xml->saveXMLfile(filename); delete (xml); - return(result); -}; + return result; +} int Part::loadXMLinstrument(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); - if (xml->loadXMLfile(filename)<0) { - delete(xml); - return(-1); - }; + XMLwrapper *xml = new XMLwrapper(); + if(xml->loadXMLfile(filename) < 0) { + delete (xml); + return -1; + } - if (xml->enterbranch("INSTRUMENT")==0) return(-10); + if(xml->enterbranch("INSTRUMENT") == 0) + return -10; getfromXMLinstrument(xml); xml->exitbranch(); - delete(xml); - return(0); -}; + delete (xml); + return 0; +} void Part::applyparameters() { - for (int n=0;napplyparameters(true); - }; -}; + for(int n = 0; n < NUM_KIT_ITEMS; n++) + if((kit[n].padpars != NULL) && (kit[n].Ppadenabled != 0)) + kit[n].padpars->applyparameters(true); + ; +} void Part::getfromXMLinstrument(XMLwrapper *xml) { - if (xml->enterbranch("INFO")) { - xml->getparstr("name",(char *)Pname,PART_MAX_NAME_LEN); - xml->getparstr("author",(char *)info.Pauthor,MAX_INFO_TEXT_SIZE); - xml->getparstr("comments",(char *)info.Pcomments,MAX_INFO_TEXT_SIZE); - info.Ptype=xml->getpar("type",info.Ptype,0,16); + if(xml->enterbranch("INFO")) { + xml->getparstr("name", (char *)Pname, PART_MAX_NAME_LEN); + xml->getparstr("author", (char *)info.Pauthor, MAX_INFO_TEXT_SIZE); + xml->getparstr("comments", (char *)info.Pcomments, MAX_INFO_TEXT_SIZE); + info.Ptype = xml->getpar("type", info.Ptype, 0, 16); xml->exitbranch(); - }; + } - if (xml->enterbranch("INSTRUMENT_KIT")) { - Pkitmode=xml->getpar127("kit_mode",Pkitmode); - Pdrummode=xml->getparbool("drum_mode",Pdrummode); + if(xml->enterbranch("INSTRUMENT_KIT")) { + Pkitmode = xml->getpar127("kit_mode", Pkitmode); + Pdrummode = xml->getparbool("drum_mode", Pdrummode); - setkititemstatus(0,0); - for (int i=0;ienterbranch("INSTRUMENT_KIT_ITEM",i)==0) continue; - setkititemstatus(i,xml->getparbool("enabled",kit[i].Penabled)); - if (kit[i].Penabled==0) { + setkititemstatus(0, 0); + for(int i = 0; i < NUM_KIT_ITEMS; i++) { + if(xml->enterbranch("INSTRUMENT_KIT_ITEM", i) == 0) + continue; + setkititemstatus(i, xml->getparbool("enabled", kit[i].Penabled)); + if(kit[i].Penabled == 0) { xml->exitbranch(); continue; - }; + } - xml->getparstr("name",(char *)kit[i].Pname,PART_MAX_NAME_LEN); + xml->getparstr("name", (char *)kit[i].Pname, PART_MAX_NAME_LEN); - kit[i].Pmuted=xml->getparbool("muted",kit[i].Pmuted); - kit[i].Pminkey=xml->getpar127("min_key",kit[i].Pminkey); - kit[i].Pmaxkey=xml->getpar127("max_key",kit[i].Pmaxkey); + kit[i].Pmuted = xml->getparbool("muted", kit[i].Pmuted); + kit[i].Pminkey = xml->getpar127("min_key", kit[i].Pminkey); + kit[i].Pmaxkey = xml->getpar127("max_key", kit[i].Pmaxkey); - kit[i].Psendtoparteffect=xml->getpar127("send_to_instrument_effect",kit[i].Psendtoparteffect); + kit[i].Psendtoparteffect = xml->getpar127( + "send_to_instrument_effect", + kit[i].Psendtoparteffect); - kit[i].Padenabled=xml->getparbool("add_enabled",kit[i].Padenabled); - if (xml->enterbranch("ADD_SYNTH_PARAMETERS")) { + kit[i].Padenabled = xml->getparbool("add_enabled", + kit[i].Padenabled); + if(xml->enterbranch("ADD_SYNTH_PARAMETERS")) { kit[i].adpars->getfromXML(xml); xml->exitbranch(); - }; + } - kit[i].Psubenabled=xml->getparbool("sub_enabled",kit[i].Psubenabled); - if (xml->enterbranch("SUB_SYNTH_PARAMETERS")) { + kit[i].Psubenabled = xml->getparbool("sub_enabled", + kit[i].Psubenabled); + if(xml->enterbranch("SUB_SYNTH_PARAMETERS")) { kit[i].subpars->getfromXML(xml); xml->exitbranch(); - }; + } - kit[i].Ppadenabled=xml->getparbool("pad_enabled",kit[i].Ppadenabled); - if (xml->enterbranch("PAD_SYNTH_PARAMETERS")) { + kit[i].Ppadenabled = xml->getparbool("pad_enabled", + kit[i].Ppadenabled); + if(xml->enterbranch("PAD_SYNTH_PARAMETERS")) { kit[i].padpars->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("INSTRUMENT_EFFECTS")) { - for (int nefx=0;nefxenterbranch("INSTRUMENT_EFFECT",nefx)==0) continue; - if (xml->enterbranch("EFFECT")) { + if(xml->enterbranch("INSTRUMENT_EFFECTS")) { + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) { + if(xml->enterbranch("INSTRUMENT_EFFECT", nefx) == 0) + continue; + if(xml->enterbranch("EFFECT")) { partefx[nefx]->getfromXML(xml); xml->exitbranch(); - }; + } - Pefxroute[nefx]=xml->getpar("route",Pefxroute[nefx],0,NUM_PART_EFX); - partefx[nefx]->setdryonly(Pefxroute[nefx]==2); - Pefxbypass[nefx]=xml->getparbool("bypass",Pefxbypass[nefx]); + Pefxroute[nefx] = xml->getpar("route", + Pefxroute[nefx], + 0, + NUM_PART_EFX); + partefx[nefx]->setdryonly(Pefxroute[nefx] == 2); + Pefxbypass[nefx] = xml->getparbool("bypass", Pefxbypass[nefx]); xml->exitbranch(); - }; + } xml->exitbranch(); - }; - -}; + } +} void Part::getfromXML(XMLwrapper *xml) { - Penabled=xml->getparbool("enabled",Penabled); + Penabled = xml->getparbool("enabled", Penabled); - setPvolume(xml->getpar127("volume",Pvolume)); - setPpanning(xml->getpar127("panning",Ppanning)); + setPvolume(xml->getpar127("volume", Pvolume)); + setPpanning(xml->getpar127("panning", Ppanning)); - Pminkey=xml->getpar127("min_key",Pminkey); - Pmaxkey=xml->getpar127("max_key",Pmaxkey); - Pkeyshift=xml->getpar127("key_shift",Pkeyshift); - Prcvchn=xml->getpar127("rcv_chn",Prcvchn); + Pminkey = xml->getpar127("min_key", Pminkey); + Pmaxkey = xml->getpar127("max_key", Pmaxkey); + Pkeyshift = xml->getpar127("key_shift", Pkeyshift); + Prcvchn = xml->getpar127("rcv_chn", Prcvchn); - Pvelsns=xml->getpar127("velocity_sensing",Pvelsns); - Pveloffs=xml->getpar127("velocity_offset",Pveloffs); + Pvelsns = xml->getpar127("velocity_sensing", Pvelsns); + Pveloffs = xml->getpar127("velocity_offset", Pveloffs); - Pnoteon=xml->getparbool("note_on",Pnoteon); - Ppolymode=xml->getparbool("poly_mode",Ppolymode); - Plegatomode=xml->getparbool("legato_mode",Plegatomode);//older versions - if (!Plegatomode) Plegatomode=xml->getpar127("legato_mode",Plegatomode); - Pkeylimit=xml->getpar127("key_limit",Pkeylimit); + Pnoteon = xml->getparbool("note_on", Pnoteon); + Ppolymode = xml->getparbool("poly_mode", Ppolymode); + Plegatomode = xml->getparbool("legato_mode", Plegatomode); //older versions + if(!Plegatomode) + Plegatomode = xml->getpar127("legato_mode", Plegatomode); + Pkeylimit = xml->getpar127("key_limit", Pkeylimit); - if (xml->enterbranch("INSTRUMENT")) { + if(xml->enterbranch("INSTRUMENT")) { getfromXMLinstrument(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("CONTROLLER")) { + if(xml->enterbranch("CONTROLLER")) { ctl.getfromXML(xml); xml->exitbranch(); - }; - -}; - - + } +} diff --git a/plugins/zynaddsubfx/src/Misc/Part.h b/plugins/zynaddsubfx/src/Misc/Part.h index 1ac12a50b..66169e3e3 100644 --- a/plugins/zynaddsubfx/src/Misc/Part.h +++ b/plugins/zynaddsubfx/src/Misc/Part.h @@ -43,159 +43,163 @@ /** Part implementation*/ class Part { + public: + /**Constructor + * @param microtonal_ Pointer to the microtonal object + * @param fft_ Pointer to the FFTwrapper + * @param mutex_ Pointer to the master pthread_mutex_t*/ + Part(Microtonal *microtonal_, FFTwrapper *fft_, pthread_mutex_t *mutex_); + /**Destructor*/ + ~Part(); -public: - /**Constructor - * @param microtonal_ Pointer to the microtonal object - * @param fft_ Pointer to the FFTwrapper - * @param mutex_ Pointer to the master pthread_mutex_t*/ - Part(Microtonal *microtonal_,FFTwrapper *fft_,pthread_mutex_t *mutex_); - /**Destructor*/ - ~Part(); + // Midi commands implemented + void NoteOn(unsigned char note, + unsigned char velocity, + int masterkeyshift); + void NoteOff(unsigned char note); + void AllNotesOff(); //panic + void SetController(unsigned int type, int par); + void RelaseSustainedKeys(); //this is called when the sustain pedal is relased + void RelaseAllKeys(); //this is called on AllNotesOff controller - // Midi commands implemented - void NoteOn(unsigned char note,unsigned char velocity,int masterkeyshift); - void NoteOff(unsigned char note); - void AllNotesOff();//panic - void SetController(unsigned int type,int par); - void RelaseSustainedKeys();//this is called when the sustain pedal is relased - void RelaseAllKeys();//this is called on AllNotesOff controller + /* The synthesizer part output */ + void ComputePartSmps(); //Part output - /* The synthesizer part output */ - void ComputePartSmps();//Part output - - //instrumentonly: 0 - save all, 1 - save only instrumnet, 2 - save only instrument without the name(used in bank) + //instrumentonly: 0 - save all, 1 - save only instrumnet, 2 - save only instrument without the name(used in bank) - //saves the instrument settings to a XML file - //returns 0 for ok or <0 if there is an error - int saveXML(char *filename); - int loadXMLinstrument(const char *filename); + //saves the instrument settings to a XML file + //returns 0 for ok or <0 if there is an error + int saveXML(char *filename); + int loadXMLinstrument(const char *filename); - void add2XML(XMLwrapper *xml); - void add2XMLinstrument(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void add2XMLinstrument(XMLwrapper *xml); - void defaults(); - void defaultsinstrument(); + void defaults(); + void defaultsinstrument(); - void applyparameters(); + void applyparameters(); - void getfromXML(XMLwrapper *xml); - void getfromXMLinstrument(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); + void getfromXMLinstrument(XMLwrapper *xml); - void cleanup(); + void cleanup(); // ADnoteParameters *ADPartParameters; // SUBnoteParameters *SUBPartParameters; - //the part's kit - struct { - unsigned char Penabled,Pmuted,Pminkey,Pmaxkey; - unsigned char *Pname; - unsigned char Padenabled,Psubenabled,Ppadenabled; - unsigned char Psendtoparteffect; - ADnoteParameters *adpars; - SUBnoteParameters *subpars; - PADnoteParameters *padpars; - } kit[NUM_KIT_ITEMS]; - - - //Part parameters - void setkeylimit(unsigned char Pkeylimit); - void setkititemstatus(int kititem,int Penabled_); - - unsigned char Penabled;/** monomemnotes; // A list to remember held notes. - struct { - unsigned char velocity; - int mkeyshift;// I'm not sure masterkeyshift should be remembered. - } monomem[256]; /* 256 is to cover all possible note values. - monomem[] is used in conjunction with the list to - store the velocity and masterkeyshift values of a - given note (the list only store note values). - For example 'monomem[note].velocity' would be the - velocity value of the note 'note'. - */ + //Part parameters + void setkeylimit(unsigned char Pkeylimit); + void setkititemstatus(int kititem, int Penabled_); - PartNotes partnote[POLIPHONY]; + unsigned char Penabled; /** monomemnotes; // A list to remember held notes. + struct { + unsigned char velocity; + int mkeyshift; // I'm not sure masterkeyshift should be remembered. + } monomem[256]; /* 256 is to cover all possible note values. + monomem[] is used in conjunction with the list to + store the velocity and masterkeyshift values of a + given note (the list only store note values). + For example 'monomem[note].velocity' would be the + velocity value of the note 'note'. + */ + + PartNotes partnote[POLIPHONY]; + + REALTYPE *tmpoutl; //used to get the note + REALTYPE *tmpoutr; + + REALTYPE oldfreq; //this is used for portamento + Microtonal *microtonal; + FFTwrapper *fft; }; #endif diff --git a/plugins/zynaddsubfx/src/Misc/Stereo.cpp b/plugins/zynaddsubfx/src/Misc/Stereo.cpp index fde296043..928be6e29 100644 --- a/plugins/zynaddsubfx/src/Misc/Stereo.cpp +++ b/plugins/zynaddsubfx/src/Misc/Stereo.cpp @@ -19,19 +19,20 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -template +template Stereo::Stereo(const T &left, const T &right) - :leftChannel(left),rightChannel(right) + :leftChannel(left), rightChannel(right) {} -template +template Stereo::Stereo(const T &val) - :leftChannel(val),rightChannel(val) + :leftChannel(val), rightChannel(val) {} -template -void Stereo::operator=(const Stereo & nstr) +template +void Stereo::operator=(const Stereo &nstr) { - leftChannel=nstr.leftChannel; - rightChannel=nstr.rightChannel; + leftChannel = nstr.leftChannel; + rightChannel = nstr.rightChannel; } + diff --git a/plugins/zynaddsubfx/src/Misc/Stereo.h b/plugins/zynaddsubfx/src/Misc/Stereo.h index b9c71b359..8bdf43017 100644 --- a/plugins/zynaddsubfx/src/Misc/Stereo.h +++ b/plugins/zynaddsubfx/src/Misc/Stereo.h @@ -21,46 +21,45 @@ #ifndef STEREO_H #define STEREO_H -template +template class Stereo { -public: - Stereo(const T &left,const T &right); + public: + Stereo(const T &left, const T &right); - /**Initializes Stereo with left and right set to val - * @param val the value for both channels*/ - Stereo(const T &val); - ~Stereo() {}; - - void operator=(const Stereo &smp); - T &left() { - return leftChannel; - }; - T &right() { - return rightChannel; - }; - T &l() { - return leftChannel; - }; - T &r() { - return rightChannel; - }; - const T &left()const { - return leftChannel; - }; - const T &right()const { - return rightChannel; - }; - const T &l()const { - return leftChannel; - }; - const T &r()const { - return rightChannel; - }; -private: - T leftChannel; - T rightChannel; + /**Initializes Stereo with left and right set to val + * @param val the value for both channels*/ + Stereo(const T &val); + ~Stereo() {} + void operator=(const Stereo &smp); + T &left() { + return leftChannel; + } + T &right() { + return rightChannel; + } + T &l() { + return leftChannel; + } + T &r() { + return rightChannel; + } + const T &left() const { + return leftChannel; + } + const T &right() const { + return rightChannel; + } + const T &l() const { + return leftChannel; + } + const T &r() const { + return rightChannel; + } + private: + T leftChannel; + T rightChannel; }; #include "Stereo.cpp" #endif diff --git a/plugins/zynaddsubfx/src/Misc/Util.cpp b/plugins/zynaddsubfx/src/Misc/Util.cpp index 5069a9ea6..0f862c602 100644 --- a/plugins/zynaddsubfx/src/Misc/Util.cpp +++ b/plugins/zynaddsubfx/src/Misc/Util.cpp @@ -31,92 +31,85 @@ #include #include -int SAMPLE_RATE=44100; -int SOUND_BUFFER_SIZE=256; -int OSCIL_SIZE=1024; +int SAMPLE_RATE = 44100; +int SOUND_BUFFER_SIZE = 256; +int OSCIL_SIZE = 1024; -Config config; +Config config; REALTYPE *denormalkillbuf; /* * Transform the velocity according the scaling parameter (velocity sensing) */ -REALTYPE VelF(REALTYPE velocity,unsigned char scaling) +REALTYPE VelF(REALTYPE velocity, unsigned char scaling) { REALTYPE x; - x=pow(VELOCITY_MAX_SCALE,(64.0-scaling)/64.0); - if ((scaling==127)||(velocity>0.99)) return(1.0); - else return(pow(velocity,x)); -}; + x = pow(VELOCITY_MAX_SCALE, (64.0 - scaling) / 64.0); + if((scaling == 127) || (velocity > 0.99)) + return 1.0; + else + return pow(velocity, x); +} /* * Get the detune in cents */ -REALTYPE getdetune(unsigned char type,unsigned short int coarsedetune,unsigned short int finedetune) +REALTYPE getdetune(unsigned char type, + unsigned short int coarsedetune, + unsigned short int finedetune) { - REALTYPE det=0.0,octdet=0.0,cdet=0.0,findet=0.0; + REALTYPE det = 0.0, octdet = 0.0, cdet = 0.0, findet = 0.0; //Get Octave - int octave=coarsedetune/1024; - if (octave>=8) octave-=16; - octdet=octave*1200.0; + int octave = coarsedetune / 1024; + if(octave >= 8) + octave -= 16; + octdet = octave * 1200.0; //Coarse and fine detune - int cdetune=coarsedetune%1024; - if (cdetune>512) cdetune-=1024; + int cdetune = coarsedetune % 1024; + if(cdetune > 512) + cdetune -= 1024; - int fdetune=finedetune-8192; + int fdetune = finedetune - 8192; - switch (type) { + switch(type) { // case 1: is used for the default (see below) case 2: - cdet=fabs(cdetune*10.0); - findet=fabs(fdetune/8192.0)*10.0; + cdet = fabs(cdetune * 10.0); + findet = fabs(fdetune / 8192.0) * 10.0; break; case 3: - cdet=fabs(cdetune*100); - findet=pow(10,fabs(fdetune/8192.0)*3.0)/10.0-0.1; + cdet = fabs(cdetune * 100); + findet = pow(10, fabs(fdetune / 8192.0) * 3.0) / 10.0 - 0.1; break; case 4: - cdet=fabs(cdetune*701.95500087);//perfect fifth - findet=(pow(2,fabs(fdetune/8192.0)*12.0)-1.0)/4095*1200; + cdet = fabs(cdetune * 701.95500087); //perfect fifth + findet = (pow(2, fabs(fdetune / 8192.0) * 12.0) - 1.0) / 4095 * 1200; break; - //case ...: need to update N_DETUNE_TYPES, if you'll add more + //case ...: need to update N_DETUNE_TYPES, if you'll add more default: - cdet=fabs(cdetune*50.0); - findet=fabs(fdetune/8192.0)*35.0;//almost like "Paul's Sound Designer 2" + cdet = fabs(cdetune * 50.0); + findet = fabs(fdetune / 8192.0) * 35.0; //almost like "Paul's Sound Designer 2" break; - }; - if (finedetune<8192) findet=-findet; - if (cdetune<0) cdet=-cdet; + } + if(finedetune < 8192) + findet = -findet; + if(cdetune < 0) + cdet = -cdet; - det=octdet+cdet+findet; - return(det); -}; + det = octdet + cdet + findet; + return det; +} bool fileexists(const char *filename) { struct stat tmp; - int result=stat(filename,&tmp); - if (result>=0) return(true); + int result = stat(filename, &tmp); + if(result >= 0) + return true; - return(false); -}; - -void newFFTFREQS(FFTFREQS *f,int size) -{ - f->c=new REALTYPE[size]; - f->s=new REALTYPE[size]; - for (int i=0;ic[i]=0.0; - f->s[i]=0.0; - }; -}; -void deleteFFTFREQS(FFTFREQS *f) -{ - delete[] f->c; - delete[] f->s; - f->c=f->s=NULL; -}; + return false; +} diff --git a/plugins/zynaddsubfx/src/Misc/Util.h b/plugins/zynaddsubfx/src/Misc/Util.h index 66c313b13..ccdac4dea 100644 --- a/plugins/zynaddsubfx/src/Misc/Util.h +++ b/plugins/zynaddsubfx/src/Misc/Util.h @@ -23,23 +23,42 @@ #ifndef UTIL_H #define UTIL_H -#include +#include +#include #include "../globals.h" -#include "Microtonal.h" -#include "../DSP/FFTwrapper.h" #include "Config.h" //Velocity Sensing function -extern REALTYPE VelF(REALTYPE velocity,unsigned char scaling); +extern REALTYPE VelF(REALTYPE velocity, unsigned char scaling); bool fileexists(const char *filename); #define N_DETUNE_TYPES 4 //the number of detune types -extern REALTYPE getdetune(unsigned char type,unsigned short int coarsedetune,unsigned short int finedetune); +extern REALTYPE getdetune(unsigned char type, + unsigned short int coarsedetune, + unsigned short int finedetune); -extern REALTYPE *denormalkillbuf;/** +std::string stringFrom(T x) +{ + std::stringstream ss; + ss << x; + return ss.str(); +} + +template +T stringTo(const char *x) +{ + std::string str = x != NULL ? x : "0"; //should work for the basic float/int + std::stringstream ss(str); + T ans; + ss >> ans; + return ans; +} + #endif diff --git a/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp b/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp index 078cbb86f..b9ee3d6e6 100644 --- a/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp +++ b/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp @@ -3,7 +3,9 @@ XMLwrapper.C - XML wrapper Copyright (C) 2003-2005 Nasca Octavian Paul + Copyright (C) 2009-2009 Mark McCurry Author: Nasca Octavian Paul + Mark McCurry This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License @@ -34,241 +36,263 @@ using namespace std; -int xml_k=0; -char tabs[STACKSIZE+2]; +int xml_k = 0; +bool verbose = false; -const char *XMLwrapper_whitespace_callback(mxml_node_t *node,int where) +const char *XMLwrapper_whitespace_callback(mxml_node_t *node, int where) { - const char *name=node->value.element.name; + const char *name = node->value.element.name; - if ((where==MXML_WS_BEFORE_OPEN)&&(!strcmp(name,"?xml"))) return(NULL); - if ((where==MXML_WS_BEFORE_CLOSE)&&(!strcmp(name,"string"))) return(NULL); + if((where == MXML_WS_BEFORE_OPEN) && (!strcmp(name, "?xml"))) + return NULL; + if((where == MXML_WS_BEFORE_CLOSE) && (!strcmp(name, "string"))) + return NULL; - if ((where==MXML_WS_BEFORE_OPEN)||(where==MXML_WS_BEFORE_CLOSE)) { + if((where == MXML_WS_BEFORE_OPEN) || (where == MXML_WS_BEFORE_CLOSE)) /* const char *tmp=node->value.element.name; - if (tmp!=NULL) { - if ((strstr(tmp,"par")!=tmp)&&(strstr(tmp,"string")!=tmp)) { - printf("%s ",tmp); - if (where==MXML_WS_BEFORE_OPEN) xml_k++; - if (where==MXML_WS_BEFORE_CLOSE) xml_k--; - if (xml_k>=STACKSIZE) xml_k=STACKSIZE-1; - if (xml_k<0) xml_k=0; - printf("%d\n",xml_k); - printf("\n"); - }; + if (tmp!=NULL) { + if ((strstr(tmp,"par")!=tmp)&&(strstr(tmp,"string")!=tmp)) { + printf("%s ",tmp); + if (where==MXML_WS_BEFORE_OPEN) xml_k++; + if (where==MXML_WS_BEFORE_CLOSE) xml_k--; + if (xml_k>=STACKSIZE) xml_k=STACKSIZE-1; + if (xml_k<0) xml_k=0; + printf("%d\n",xml_k); + printf("\n"); + }; - }; - int i=0; - for (i=1;i(mxmlFindElement( + const_cast(node), + const_cast(top), + name, attr, value, descend)); +} + +//temporary const overload of mxmlElementGetAttr +const char *mxmlElementGetAttr(const mxml_node_t *node, const char *name) +{ + return mxmlElementGetAttr(const_cast(node), name); +} XMLwrapper::XMLwrapper() { - ZERO(&parentstack,(int)sizeof(parentstack)); - ZERO(&values,(int)sizeof(values)); + version.Major = 2; + version.Minor = 4; + version.Revision = 1; - minimal=true; - stackpos=0; + minimal = true; - information.PADsynth_used=false; - - tree=mxmlNewElement(MXML_NO_PARENT,"?xml version=\"1.0\" encoding=\"UTF-8\"?"); + node = tree = mxmlNewElement(MXML_NO_PARENT, + "?xml version=\"1.0\" encoding=\"UTF-8\"?"); /* for mxml 2.1 (and older) tree=mxmlNewElement(MXML_NO_PARENT,"?xml"); mxmlElementSetAttr(tree,"version","1.0"); mxmlElementSetAttr(tree,"encoding","UTF-8"); */ - mxml_node_t *doctype=mxmlNewElement(tree,"!DOCTYPE"); - mxmlElementSetAttr(doctype,"ZynAddSubFX-data",NULL); + mxml_node_t *doctype = mxmlNewElement(tree, "!DOCTYPE"); + mxmlElementSetAttr(doctype, "ZynAddSubFX-data", NULL); - node=root=mxmlNewElement(tree,"ZynAddSubFX-data"); - - mxmlElementSetAttr(root,"version-major","1"); - mxmlElementSetAttr(root,"version-minor","1"); - mxmlElementSetAttr(root,"ZynAddSubFX-author","Nasca Octavian Paul"); + node = root = addparams("ZynAddSubFX-data", 4, + "version-major", stringFrom( + version.Major).c_str(), + "version-minor", stringFrom( + version.Minor).c_str(), + "version-revision", + stringFrom(version.Revision).c_str(), + "ZynAddSubFX-author", "Nasca Octavian Paul"); //make the empty branch that will contain the information parameters - info=addparams0("INFORMATION"); + info = addparams("INFORMATION", 0); //save zynaddsubfx specifications beginbranch("BASE_PARAMETERS"); - addpar("max_midi_parts",NUM_MIDI_PARTS); - addpar("max_kit_items_per_instrument",NUM_KIT_ITEMS); + addpar("max_midi_parts", NUM_MIDI_PARTS); + addpar("max_kit_items_per_instrument", NUM_KIT_ITEMS); - addpar("max_system_effects",NUM_SYS_EFX); - addpar("max_insertion_effects",NUM_INS_EFX); - addpar("max_instrument_effects",NUM_PART_EFX); + addpar("max_system_effects", NUM_SYS_EFX); + addpar("max_insertion_effects", NUM_INS_EFX); + addpar("max_instrument_effects", NUM_PART_EFX); - addpar("max_addsynth_voices",NUM_VOICES); + addpar("max_addsynth_voices", NUM_VOICES); endbranch(); - -}; +} XMLwrapper::~XMLwrapper() { - if (tree!=NULL) mxmlDelete(tree); -}; + if(tree != NULL) + mxmlDelete(tree); +} -bool XMLwrapper::checkfileinformation(const char *filename) +void XMLwrapper::setPadSynth(bool enabled) { - stackpos=0; - ZERO(&parentstack,(int)sizeof(parentstack)); - information.PADsynth_used=false; + /**@bug this might create multiple nodes when only one is needed*/ + mxml_node_t *oldnode = node; + node = info; + //Info storing + addparbool("PADsynth_used", enabled); + node = oldnode; +} - if (tree!=NULL) mxmlDelete(tree); - tree=NULL; - char *xmldata=doloadfile(filename); - if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed +bool XMLwrapper::hasPadSynth() const +{ + /**Right now this has a copied implementation of setparbool, so this should + * be reworked as XMLwrapper evolves*/ + mxml_node_t *tmp = mxmlFindElement(tree, + tree, + "INFORMATION", + NULL, + NULL, + MXML_DESCEND); + mxml_node_t *parameter = mxmlFindElement(tmp, + tmp, + "par_bool", + "name", + "PADsynth_used", + MXML_DESCEND_FIRST); + if(parameter == NULL) //no information availiable + return false; - char *start=strstr(xmldata,""); - char *end=strstr(xmldata,""); + const char *strval = mxmlElementGetAttr(parameter, "value"); + if(strval == NULL) //no information available + return false; - if ((start==NULL)||(end==NULL)||(start>end)) { - delete []xmldata; - return(false); - }; - end+=strlen(""); - end[0]='\0'; - - tree=mxmlNewElement(MXML_NO_PARENT,"?xml"); - node=root=mxmlLoadString(tree,xmldata,MXML_OPAQUE_CALLBACK); - if (root==NULL) { - delete []xmldata; - mxmlDelete(tree); - node=root=tree=NULL; - return(false); - }; - - root=mxmlFindElement(tree,tree,"INFORMATION",NULL,NULL,MXML_DESCEND); - push(root); - - if (root==NULL) { - delete []xmldata; - mxmlDelete(tree); - node=root=tree=NULL; - return(false); - }; - - information.PADsynth_used=getparbool("PADsynth_used",false); - - exitbranch(); - if (tree!=NULL) mxmlDelete(tree); - delete []xmldata; - node=root=tree=NULL; - - return(true); -}; + if((strval[0] == 'Y') || (strval[0] == 'y')) + return true; + else + return false; +} /* SAVE XML members */ -int XMLwrapper::saveXMLfile(const string &filename) +int XMLwrapper::saveXMLfile(const string &filename) const { - char *xmldata=getXMLdata(); - if (xmldata==NULL) return(-2); + char *xmldata = getXMLdata(); + if(xmldata == NULL) + return -2; - int compression=config.cfg.GzipCompression; - int result=dosavefile(filename.c_str(),compression,xmldata); + int compression = config.cfg.GzipCompression; + int result = dosavefile(filename.c_str(), compression, xmldata); free(xmldata); - return(result); -}; + return result; +} -char *XMLwrapper::getXMLdata() +char *XMLwrapper::getXMLdata() const { - xml_k=0; - ZERO(tabs,STACKSIZE+2); + xml_k = 0; - mxml_node_t *oldnode=node; + char *xmldata = mxmlSaveAllocString(tree, XMLwrapper_whitespace_callback); - node=info; - //Info storing - addparbool("PADsynth_used",information.PADsynth_used); - - node=oldnode; - char *xmldata=mxmlSaveAllocString(tree,XMLwrapper_whitespace_callback); - - return(xmldata); -}; + return xmldata; +} -int XMLwrapper::dosavefile(const char *filename,int compression,const char *xmldata) +int XMLwrapper::dosavefile(const char *filename, + int compression, + const char *xmldata) const { - if (compression==0) { + if(compression == 0) { FILE *file; - file=fopen(filename,"w"); - if (file==NULL) return(-1); - fputs(xmldata,file); + file = fopen(filename, "w"); + if(file == NULL) + return -1; + fputs(xmldata, file); fclose(file); - } else { - if (compression>9) compression=9; - if (compression<1) compression=1; + } + else { + if(compression > 9) + compression = 9; + if(compression < 1) + compression = 1; char options[10]; - snprintf(options,10,"wb%d",compression); + snprintf(options, 10, "wb%d", compression); gzFile gzfile; - gzfile=gzopen(filename,options); - if (gzfile==NULL) return(-1); - gzputs(gzfile,xmldata); + gzfile = gzopen(filename, options); + if(gzfile == NULL) + return -1; + gzputs(gzfile, xmldata); gzclose(gzfile); - }; + } - return(0); -}; + return 0; +} -void XMLwrapper::addpar(const string &name,int val) +void XMLwrapper::addpar(const string &name, int val) { - addparams2("par","name",name.c_str(),"value",int2str(val)); -}; + addparams("par", 2, "name", name.c_str(), "value", stringFrom( + val).c_str()); +} -void XMLwrapper::addparreal(const string &name,REALTYPE val) +void XMLwrapper::addparreal(const string &name, REALTYPE val) { - addparams2("par_real","name",name.c_str(),"value",real2str(val)); -}; + addparams("par_real", 2, "name", name.c_str(), "value", + stringFrom(val).c_str()); +} -void XMLwrapper::addparbool(const string &name,int val) +void XMLwrapper::addparbool(const string &name, int val) { - if (val!=0) addparams2("par_bool","name",name.c_str(),"value","yes"); - else addparams2("par_bool","name",name.c_str(),"value","no"); -}; + if(val != 0) + addparams("par_bool", 2, "name", name.c_str(), "value", "yes"); + else + addparams("par_bool", 2, "name", name.c_str(), "value", "no"); +} -void XMLwrapper::addparstr(const string &name,const string &val) +void XMLwrapper::addparstr(const string &name, const string &val) { - mxml_node_t *element=mxmlNewElement(node,"string"); - mxmlElementSetAttr(element,"name",name.c_str()); - mxmlNewText(element,0,val.c_str()); -}; + mxml_node_t *element = mxmlNewElement(node, "string"); + mxmlElementSetAttr(element, "name", name.c_str()); + mxmlNewText(element, 0, val.c_str()); +} void XMLwrapper::beginbranch(const string &name) { - push(node); - node=addparams0(name.c_str()); -}; + if(verbose) + cout << "beginbranch()" << name << endl; + node = addparams(name.c_str(), 0); +} -void XMLwrapper::beginbranch(const string &name,int id) +void XMLwrapper::beginbranch(const string &name, int id) { - push(node); - node=addparams1(name.c_str(),"id",int2str(id)); -}; + if(verbose) + cout << "beginbranch(" << id << ")" << name << endl; + node = addparams(name.c_str(), 1, "id", stringFrom(id).c_str()); +} void XMLwrapper::endbranch() { - node=pop(); -}; + if(verbose) + cout << "endbranch()" << node << "-" << node->value.element.name + << " To " + << node->parent << "-" << node->parent->value.element.name << endl; + node = node->parent; +} @@ -276,61 +300,71 @@ void XMLwrapper::endbranch() int XMLwrapper::loadXMLfile(const string &filename) { - if (tree!=NULL) mxmlDelete(tree); - tree=NULL; + if(tree != NULL) + mxmlDelete(tree); + tree = NULL; - ZERO(&parentstack,(int)sizeof(parentstack)); - ZERO(&values,(int)sizeof(values)); + const char *xmldata = doloadfile(filename.c_str()); + if(xmldata == NULL) + return -1; //the file could not be loaded or uncompressed - stackpos=0; + root = tree = mxmlLoadString(NULL, xmldata, MXML_OPAQUE_CALLBACK); - const char *xmldata=doloadfile(filename.c_str()); - if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed + delete [] xmldata; - root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK); - - delete []xmldata; - - if (tree==NULL) return(-2);//this is not XML + if(tree == NULL) + return -2; //this is not XML - node=root=mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND); - if (root==NULL) return(-3);//the XML doesnt embbed zynaddsubfx data - push(root); + node = root = mxmlFindElement(tree, + tree, + "ZynAddSubFX-data", + NULL, + NULL, + MXML_DESCEND); + if(root == NULL) + return -3; //the XML doesnt embbed zynaddsubfx data - values.xml_version.major=str2int(mxmlElementGetAttr(root,"version-major")); - values.xml_version.minor=str2int(mxmlElementGetAttr(root,"version-minor")); + //fetch version information + version.Major = stringTo(mxmlElementGetAttr(root, "version-major")); + version.Minor = stringTo(mxmlElementGetAttr(root, "version-minor")); + version.Revision = + stringTo(mxmlElementGetAttr(root, "version-revision")); - return(0); -}; + if(verbose) + cout << "loadXMLfile() version: " << version.Major << '.' + << version.Minor << '.' << version.Revision << endl; -char *XMLwrapper::doloadfile(const string &filename) + return 0; +} + + +char *XMLwrapper::doloadfile(const string &filename) const { - char * xmldata = NULL; - gzFile gzfile = gzopen(filename.c_str(),"rb"); - - if (gzfile != NULL) {//The possibly compressed file opened + char *xmldata = NULL; + gzFile gzfile = gzopen(filename.c_str(), "rb"); + if(gzfile != NULL) { //The possibly compressed file opened stringstream strBuf; //reading stream const int bufSize = 500; //fetch size - char fetchBuf[bufSize+1];//fetch buffer - int read = 0; //chars read in last fetch + char fetchBuf[bufSize + 1]; //fetch buffer + int read = 0; //chars read in last fetch - fetchBuf[bufSize] = 0;//force null termination + fetchBuf[bufSize] = 0; //force null termination while(bufSize == (read = gzread(gzfile, fetchBuf, bufSize))) strBuf << fetchBuf; - fetchBuf[read] = 0;//Truncate last partial read + fetchBuf[read] = 0; //Truncate last partial read strBuf << fetchBuf; gzclose(gzfile); //Place data in output format string tmp = strBuf.str(); - xmldata = new char[tmp.size()+1]; - strncpy(xmldata, tmp.c_str(), tmp.size()+1); + xmldata = new char[tmp.size() + 1]; + strncpy(xmldata, tmp.c_str(), tmp.size() + 1); } return xmldata; @@ -338,218 +372,246 @@ char *XMLwrapper::doloadfile(const string &filename) bool XMLwrapper::putXMLdata(const char *xmldata) { - if (tree!=NULL) mxmlDelete(tree); - tree=NULL; + if(tree != NULL) + mxmlDelete(tree); - ZERO(&parentstack,(int)sizeof(parentstack)); - ZERO(&values,(int)sizeof(values)); + tree = NULL; + if(xmldata == NULL) + return false; - stackpos=0; + root = tree = mxmlLoadString(NULL, xmldata, MXML_OPAQUE_CALLBACK); + if(tree == NULL) + return false; - if (xmldata==NULL) return (false); + node = root = mxmlFindElement(tree, + tree, + "ZynAddSubFX-data", + NULL, + NULL, + MXML_DESCEND); + if(root == NULL) + return false; - root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK); - - if (tree==NULL) return(false); - - node=root=mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND); - if (root==NULL) return (false);; - push(root); - - return(true); -}; + return true; +} int XMLwrapper::enterbranch(const string &name) { - node=mxmlFindElement(peek(),peek(),name.c_str(),NULL,NULL,MXML_DESCEND_FIRST); - if (node==NULL) return(0); + if(verbose) + cout << "enterbranch() " << name << endl; + mxml_node_t *tmp = mxmlFindElement(node, node, + name.c_str(), NULL, NULL, + MXML_DESCEND_FIRST); + if(tmp == NULL) + return 0; - push(node); - return(1); -}; + node = tmp; + return 1; +} -int XMLwrapper::enterbranch(const string &name,int id) +int XMLwrapper::enterbranch(const string &name, int id) { - snprintf(tmpstr,TMPSTR_SIZE,"%d",id); - node=mxmlFindElement(peek(),peek(),name.c_str(),"id",tmpstr,MXML_DESCEND_FIRST); - if (node==NULL) return(0); + if(verbose) + cout << "enterbranch(" << id << ") " << name << endl; + mxml_node_t *tmp = mxmlFindElement(node, node, + name.c_str(), "id", stringFrom( + id).c_str(), MXML_DESCEND_FIRST); + if(tmp == NULL) + return 0; - push(node); - return(1); -}; + node = tmp; + return 1; +} void XMLwrapper::exitbranch() { - /**@bug Does not set the current node correctly*/ - pop(); -}; + if(verbose) + cout << "exitbranch()" << node << "-" << node->value.element.name + << " To " + << node->parent << "-" << node->parent->value.element.name << endl; + node = node->parent; +} -int XMLwrapper::getbranchid(int min, int max) +int XMLwrapper::getbranchid(int min, int max) const { - int id=str2int(mxmlElementGetAttr(node,"id")); - if ((min==0)&&(max==0)) return(id); + int id = stringTo(mxmlElementGetAttr(node, "id")); + if((min == 0) && (max == 0)) + return id; - if (idmax) id=max; + if(id < min) + id = min; + else + if(id > max) + id = max; - return(id); -}; + return id; +} -int XMLwrapper::getpar(const string &name,int defaultpar,int min,int max) +int XMLwrapper::getpar(const string &name, int defaultpar, int min, + int max) const { - node=mxmlFindElement(peek(),peek(),"par","name",name.c_str(),MXML_DESCEND_FIRST); - if (node==NULL) return(defaultpar); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "par", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - const char *strval=mxmlElementGetAttr(node,"value"); - if (strval==NULL) return(defaultpar); + if(tmp == NULL) + return defaultpar; - int val=str2int(strval); - if (valmax) val=max; + const char *strval = mxmlElementGetAttr(tmp, "value"); + if(strval == NULL) + return defaultpar; - return(val); -}; + int val = stringTo(strval); + if(val < min) + val = min; + else + if(val > max) + val = max; -int XMLwrapper::getpar127(const string &name,int defaultpar) + return val; +} + +int XMLwrapper::getpar127(const string &name, int defaultpar) const { - return(getpar(name,defaultpar,0,127)); -}; + return getpar(name, defaultpar, 0, 127); +} -int XMLwrapper::getparbool(const string &name,int defaultpar) +int XMLwrapper::getparbool(const string &name, int defaultpar) const { - node=mxmlFindElement(peek(),peek(),"par_bool","name",name.c_str(),MXML_DESCEND_FIRST); - if (node==NULL) return(defaultpar); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "par_bool", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - const char *strval=mxmlElementGetAttr(node,"value"); - if (strval==NULL) return(defaultpar); + if(tmp == NULL) + return defaultpar; - if ((strval[0]=='Y')||(strval[0]=='y')) return(1); - else return(0); -}; + const char *strval = mxmlElementGetAttr(tmp, "value"); + if(strval == NULL) + return defaultpar; -void XMLwrapper::getparstr(const string &name,char *par,int maxstrlen) + if((strval[0] == 'Y') || (strval[0] == 'y')) + return 1; + else + return 0; +} + +void XMLwrapper::getparstr(const string &name, char *par, int maxstrlen) const { - ZERO(par,maxstrlen); - node=mxmlFindElement(peek(),peek(),"string","name",name.c_str(),MXML_DESCEND_FIRST); + ZERO(par, maxstrlen); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "string", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - if (node==NULL) return; - if (node->child==NULL) return; - if (node->child->type!=MXML_OPAQUE) return; + if(tmp == NULL) + return; + if(tmp->child == NULL) + return; + if(tmp->child->type == MXML_OPAQUE) { + snprintf(par, maxstrlen, "%s", tmp->child->value.element.name); + return; + } + if((tmp->child->type == MXML_TEXT) + && (tmp->child->value.text.string != NULL)) { + snprintf(par, maxstrlen, "%s", tmp->child->value.text.string); + return; + } +} - snprintf(par,maxstrlen,"%s",node->child->value.element.name); - -}; - -REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar) +string XMLwrapper::getparstr(const string &name, + const std::string &defaultpar) const { - node=mxmlFindElement(peek(),peek(),"par_real","name",name,MXML_DESCEND_FIRST); - if (node==NULL) return(defaultpar); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "string", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - const char *strval=mxmlElementGetAttr(node,"value"); - if (strval==NULL) return(defaultpar); + if((tmp == NULL) || (tmp->child == NULL)) + return defaultpar; - return(str2real(strval)); -}; + if((tmp->child->type == MXML_OPAQUE) + && (tmp->child->value.element.name != NULL)) + return tmp->child->value.element.name; -REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max) + if((tmp->child->type == MXML_TEXT) + && (tmp->child->value.text.string != NULL)) + return tmp->child->value.text.string; + + return defaultpar; +} + +REALTYPE XMLwrapper::getparreal(const char *name, REALTYPE defaultpar) const { - REALTYPE result=getparreal(name,defaultpar); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "par_real", + "name", + name, + MXML_DESCEND_FIRST); + if(tmp == NULL) + return defaultpar; - if (resultmax) result=max; - return(result); -}; + const char *strval = mxmlElementGetAttr(tmp, "value"); + if(strval == NULL) + return defaultpar; + + return stringTo(strval); +} + +REALTYPE XMLwrapper::getparreal(const char *name, + REALTYPE defaultpar, + REALTYPE min, + REALTYPE max) const +{ + REALTYPE result = getparreal(name, defaultpar); + + if(result < min) + result = min; + else + if(result > max) + result = max; + return result; +} /** Private members **/ -char *XMLwrapper::int2str(int x) +mxml_node_t *XMLwrapper::addparams(const char *name, unsigned int params, + ...) const { - snprintf(tmpstr,TMPSTR_SIZE,"%d",x); - return(tmpstr); -}; - -char *XMLwrapper::real2str(REALTYPE x) -{ - snprintf(tmpstr,TMPSTR_SIZE,"%g",x); - return(tmpstr); -}; - -int XMLwrapper::str2int(const char *str) -{ - if (str==NULL) return(0); - int result=strtol(str,NULL,10); - return(result); -}; - -REALTYPE XMLwrapper::str2real(const char *str) -{ - if (str==NULL) return(0.0); - REALTYPE result=strtod(str,NULL); - return(result); -}; - - -mxml_node_t *XMLwrapper::addparams0(const char *name) -{ - mxml_node_t *element=mxmlNewElement(node,name); - return(element); -}; - -mxml_node_t *XMLwrapper::addparams1(const char *name,const char *par1,const char *val1) -{ - mxml_node_t *element=mxmlNewElement(node,name); - mxmlElementSetAttr(element,par1,val1); - return(element); -}; - -mxml_node_t *XMLwrapper::addparams2(const char *name,const char *par1,const char *val1,const char *par2, const char *val2) -{ - mxml_node_t *element=mxmlNewElement(node,name); - mxmlElementSetAttr(element,par1,val1); - mxmlElementSetAttr(element,par2,val2); - return(element); -}; - -void XMLwrapper::push(mxml_node_t *node) -{ - if (stackpos>=STACKSIZE-1) { - cerr << "BUG!: XMLwrapper::push() - full parentstack" << endl; - return; - }; - stackpos++; - parentstack[stackpos]=node; - -// printf("push %d - %s\n",stackpos,node->value.element.name); - -}; -mxml_node_t *XMLwrapper::pop() -{ - if (stackpos<=0) { - cerr << "BUG!: XMLwrapper::pop() - empty parentstack" << endl; - return (root); - }; - mxml_node_t *node=parentstack[stackpos]; - parentstack[stackpos]=NULL; - -// printf("pop %d - %s\n",stackpos,node->value.element.name); - - stackpos--; - return(node); -}; - -mxml_node_t *XMLwrapper::peek() -{ - if (stackpos<=0) { - cerr << "BUG!: XMLwrapper::peek() - empty parentstack" << endl; - return (root); - }; - return(parentstack[stackpos]); -}; + /**@todo make this function send out a good error message if something goes + * wrong**/ + mxml_node_t *element = mxmlNewElement(node, name); + if(params) { + va_list variableList; + va_start(variableList, params); + const char *ParamName; + const char *ParamValue; + while(params--) { + ParamName = va_arg(variableList, const char *); + ParamValue = va_arg(variableList, const char *); + if(verbose) + cout << "addparams()[" << params << "]=" << name << " " + << ParamName << "=\"" << ParamValue << "\"" << endl; + mxmlElementSetAttr(element, ParamName, ParamValue); + } + } + return element; +} diff --git a/plugins/zynaddsubfx/src/Misc/XMLwrapper.h b/plugins/zynaddsubfx/src/Misc/XMLwrapper.h index ccf875de6..5860f0764 100644 --- a/plugins/zynaddsubfx/src/Misc/XMLwrapper.h +++ b/plugins/zynaddsubfx/src/Misc/XMLwrapper.h @@ -31,287 +31,242 @@ #ifndef XML_WRAPPER_H #define XML_WRAPPER_H -#define TMPSTR_SIZE 50 - -//the maxim tree depth -#define STACKSIZE 100 - /**Mxml wrapper*/ class XMLwrapper { -public: - /** - * Constructor. - * Will Construct the object and fill in top level branch - * */ - XMLwrapper(); + public: + /** + * Constructor. + * Will Construct the object and fill in top level branch + * */ + XMLwrapper(); - /**Destructor*/ - ~XMLwrapper(); + /**Destructor*/ + ~XMLwrapper(); - /** - * Saves the XML to a file. - * @param filename the name of the destination file. - * @returns 0 if ok or -1 if the file cannot be saved. - */ - int saveXMLfile(const std::string &filename); + /** + * Saves the XML to a file. + * @param filename the name of the destination file. + * @returns 0 if ok or -1 if the file cannot be saved. + */ + int saveXMLfile(const std::string &filename) const; - /** - * Return XML tree as a string. - * Note: The string must be freed with free() to deallocate - * @returns a newly allocated NULL terminated string of the XML data. - */ - char *getXMLdata(); + /** + * Return XML tree as a string. + * Note: The string must be freed with free() to deallocate + * @returns a newly allocated NULL terminated string of the XML data. + */ + char *getXMLdata() const; - /** - * Add simple parameter. - * @param name The name of the mXML node. - * @param val The string value of the mXml node - */ - void addpar(const std::string &name,int val); + /** + * Add simple parameter. + * @param name The name of the mXML node. + * @param val The string value of the mXml node + */ + void addpar(const std::string &name, int val); - /** - * Adds a realtype parameter. - * @param name The name of the mXML node. - * @param val The REALTYPE value of the node. - */ - void addparreal(const std::string &name,REALTYPE val); + /** + * Adds a realtype parameter. + * @param name The name of the mXML node. + * @param val The REALTYPE value of the node. + */ + void addparreal(const std::string &name, REALTYPE val); - /** - * Add boolean parameter. - * \todo Fix this reverse boolean logic. - * @param name The name of the mXML node. - * @param val The boolean value of the node (0->"yes";else->"no"). - */ - void addparbool(const std::string &name,int val); + /** + * Add boolean parameter. + * \todo Fix this reverse boolean logic. + * @param name The name of the mXML node. + * @param val The boolean value of the node (0->"yes";else->"no"). + */ + void addparbool(const std::string &name, int val); - /** - * Add string parameter. - * @param name The name of the mXML node. - * @param val The string value of the node. - */ - void addparstr(const std::string &name,const std::string &val); + /** + * Add string parameter. + * @param name The name of the mXML node. + * @param val The string value of the node. + */ + void addparstr(const std::string &name, const std::string &val); - /** - * Create a new branch. - * @param name Name of new branch - * @see void endbranch() - */ - void beginbranch(const std::string &name); - /** - * Create a new branch. - * @param name Name of new branch - * @param id "id" value of branch - * @see void endbranch() - */ - void beginbranch(const std::string &name, int id); + /** + * Create a new branch. + * @param name Name of new branch + * @see void endbranch() + */ + void beginbranch(const std::string &name); + /** + * Create a new branch. + * @param name Name of new branch + * @param id "id" value of branch + * @see void endbranch() + */ + void beginbranch(const std::string &name, int id); - /**Closes new branches. - * This must be called to exit each branch created by beginbranch( ). - * @see void beginbranch(const std::string &name) - * @see void beginbranch(const std::string &name, int id) - */ - void endbranch(); + /**Closes new branches. + * This must be called to exit each branch created by beginbranch( ). + * @see void beginbranch(const std::string &name) + * @see void beginbranch(const std::string &name, int id) + */ + void endbranch(); - /** - * Loads file into XMLwrapper. - * @param filename file to be loaded - * @returns 0 if ok or -1 if the file cannot be loaded - */ - int loadXMLfile(const std::string &filename); + /** + * Loads file into XMLwrapper. + * @param filename file to be loaded + * @returns 0 if ok or -1 if the file cannot be loaded + */ + int loadXMLfile(const std::string &filename); - /** - * Loads string into XMLwrapper. - * @param xmldata NULL terminated string of XML data. - * @returns true if successful. - */ - bool putXMLdata(const char *xmldata); + /** + * Loads string into XMLwrapper. + * @param xmldata NULL terminated string of XML data. + * @returns true if successful. + */ + bool putXMLdata(const char *xmldata); - /** - * Enters the branch. - * @param name Name of branch. - * @returns 1 if is ok, or 0 otherwise. - */ - int enterbranch(const std::string &name); + /** + * Enters the branch. + * @param name Name of branch. + * @returns 1 if is ok, or 0 otherwise. + */ + int enterbranch(const std::string &name); - /** - * Enter into the branch \c name with id \c id. - * @param name Name of branch. - * @param id Value of branch's "id". - * @returns 1 if is ok, or 0 otherwise. - */ - int enterbranch(const std::string &name, int id); + /** + * Enter into the branch \c name with id \c id. + * @param name Name of branch. + * @param id Value of branch's "id". + * @returns 1 if is ok, or 0 otherwise. + */ + int enterbranch(const std::string &name, int id); - /**Exits from a branch*/ - void exitbranch(); + /**Exits from a branch*/ + void exitbranch(); - /**Get the the branch_id and limits it between the min and max. - * if min==max==0, it will not limit it - * if there isn't any id, will return min - * this must be called only imediately after enterbranch() - */ - int getbranchid(int min, int max); + /**Get the the branch_id and limits it between the min and max. + * if min==max==0, it will not limit it + * if there isn't any id, will return min + * this must be called only imediately after enterbranch() + */ + int getbranchid(int min, int max) const; - /** - * Returns the integer value stored in node name. - * It returns the integer value between the limits min and max. - * If min==max==0, then the value will not be limited. - * If there is no location named name, then defaultpar will be returned. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - * @param min The minimum return value. - * @param max The maximum return value. - */ - int getpar(const std::string &name,int defaultpar,int min,int max); + /** + * Returns the integer value stored in node name. + * It returns the integer value between the limits min and max. + * If min==max==0, then the value will not be limited. + * If there is no location named name, then defaultpar will be returned. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + * @param min The minimum return value. + * @param max The maximum return value. + */ + int getpar(const std::string &name, int defaultpar, int min, + int max) const; - /** - * Returns the integer value stored in the node with range [0,127]. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - */ - int getpar127(const std::string &name,int defaultpar); + /** + * Returns the integer value stored in the node with range [0,127]. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + int getpar127(const std::string &name, int defaultpar) const; - /** - * Returns the boolean value stored in the node. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - */ - int getparbool(const std::string &name,int defaultpar); + /** + * Returns the boolean value stored in the node. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + int getparbool(const std::string &name, int defaultpar) const; - /** - * Get the string value stored in the node. - * @param name The parameter name. - * @param par Pointer to destination string - * @param maxstrlen Max string length for destination - */ - void getparstr(const std::string &name,char *par,int maxstrlen); + /** + * Get the string value stored in the node. + * @param name The parameter name. + * @param par Pointer to destination string + * @param maxstrlen Max string length for destination + */ + void getparstr(const std::string &name, char *par, int maxstrlen) const; - /** - * Returns the real value stored in the node. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - */ - REALTYPE getparreal(const char *name,REALTYPE defaultpar); + /** + * Get the string value stored in the node. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + std::string getparstr(const std::string &name, + const std::string &defaultpar) const; - /** - * Returns the real value stored in the node. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - * @param min The minimum value - * @param max The maximum value - */ - REALTYPE getparreal(const char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max); + /** + * Returns the real value stored in the node. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + REALTYPE getparreal(const char *name, REALTYPE defaultpar) const; - bool minimal;/** + * + * @param name The name of the xml node + * @param params The number of the attributes + * @param ... const char * pairs that are in the format attribute_name, + * attribute_value + */ + mxml_node_t *addparams(const char *name, unsigned int params, + ...) const; - /** - * Adds params like this: - * . - * @returns The node - */ - mxml_node_t *addparams0(const char *name); - - /** - * Adds params like this: - * . - * @returns The node - */ - mxml_node_t *addparams1(const char *name,const char *par1,const char *val1); - - /** - * Adds params like this: - * . - * @returns the node - */ - mxml_node_t *addparams2(const char *name,const char *par1,const char *val1,const char *par2, const char *val2); - - /** - * Convert integer to string - * @param x integer input - * @returns string output - */ - char *int2str(int x); - - /** - * Convert integer to string - * @param x integer input - * @returns string output - */ - char *real2str(REALTYPE x); - - /** - * Convert string to int - * @param str string input - * @returns integer output - */ - int str2int(const char *str); - - /** - * Convert string to realtype - * @param x integer input - * @returns string output - */ - REALTYPE str2real(const char *str); - - /**Temporary string for various uses*/ - char tmpstr[TMPSTR_SIZE]; - - - /**this is used to store the parents. - * @todo Use the stack class provided by C++*/ - mxml_node_t *parentstack[STACKSIZE]; - int stackpos;/**outl = data; break; @@ -58,7 +58,7 @@ static void connectPortTS(LADSPA_Handle instance, unsigned long port, const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { - switch (index) { + switch(index) { case 0: return tsLDescriptor; default: @@ -71,7 +71,7 @@ const DSSI_Descriptor *dssi_descriptor(unsigned long index) // FILE *a=fopen("/tmp/zzzzz11z","w"); // fprintf(a,"aaaaaaaaaaa TEST\n"); // fclose(a); - switch (index) { + switch(index) { case 0: return tsDDescriptor; default: @@ -79,14 +79,13 @@ const DSSI_Descriptor *dssi_descriptor(unsigned long index) } } -static LADSPA_Handle instantiateTS(const LADSPA_Descriptor * descriptor, +static LADSPA_Handle instantiateTS(const LADSPA_Descriptor *descriptor, unsigned long s_rate) { - TS *plugin_data = (TS *) malloc(sizeof(TS)); /* for (i=0; iomega[i] = M_PI * 2.0 / (double)s_rate * - pow(2.0, (i-69.0) / 12.0); + plugin_data->omega[i] = M_PI * 2.0 / (double)s_rate * + pow(2.0, (i-69.0) / 12.0); } */ return (LADSPA_Handle) plugin_data; @@ -115,47 +114,47 @@ static void runTS(LADSPA_Handle instance, unsigned long sample_count, unsigned long note; /* if (freq < 1.0) { - freq = 440.0f; + freq = 440.0f; } if (vol < 0.000001) { - vol = 1.0f; + vol = 1.0f; } if (event_count > 0) { - printf("trivial_synth: have %ld events\n", event_count); + printf("trivial_synth: have %ld events\n", event_count); } for (pos = 0, event_pos = 0; pos < sample_count; pos++) { - while (event_pos < event_count - && pos == events[event_pos].time.tick) { + while (event_pos < event_count + && pos == events[event_pos].time.tick) { - printf("trivial_synth: event type %d\n", events[event_pos].type); + printf("trivial_synth: event type %d\n", events[event_pos].type); - if (events[event_pos].type == SND_SEQ_EVENT_NOTEON) { - data[events[event_pos].data.note.note].amp = - events[event_pos].data.note.velocity / 512.0f; - data[events[event_pos].data.note.note]. - active = events[event_pos].data.note.velocity > 0; - data[events[event_pos].data.note.note]. - phase = 0.0; - } else if (events[event_pos].type == SND_SEQ_EVENT_NOTEOFF) { - data[events[event_pos].data.note.note]. - active = 0; - } - event_pos++; - } + if (events[event_pos].type == SND_SEQ_EVENT_NOTEON) { + data[events[event_pos].data.note.note].amp = + events[event_pos].data.note.velocity / 512.0f; + data[events[event_pos].data.note.note]. + active = events[event_pos].data.note.velocity > 0; + data[events[event_pos].data.note.note]. + phase = 0.0; + } else if (events[event_pos].type == SND_SEQ_EVENT_NOTEOFF) { + data[events[event_pos].data.note.note]. + active = 0; + } + event_pos++; + } - output[pos] = 0.0f; - for (note = 0; note < MIDI_NOTES; note++) { - if (data[note].active) { - output[pos] += sin(data[note].phase) * data[note].amp * vol; - data[note].phase += plugin_data->omega[note] * freq; - if (data[note].phase > M_PI * 2.0) { - data[note].phase -= M_PI * 2.0; - } - } - } + output[pos] = 0.0f; + for (note = 0; note < MIDI_NOTES; note++) { + if (data[note].active) { + output[pos] += sin(data[note].phase) * data[note].amp * vol; + data[note].phase += plugin_data->omega[note] * freq; + if (data[note].phase > M_PI * 2.0) { + data[note].phase -= M_PI * 2.0; + } + } + } } */ } @@ -176,22 +175,23 @@ void _init() { char **port_names; LADSPA_PortDescriptor *port_descriptors; - LADSPA_PortRangeHint *port_range_hints; + LADSPA_PortRangeHint *port_range_hints; - FILE *a=fopen("/tmp/zzzzzz","w"); - fprintf(a,"aaaaaaaaaaa TEST\n"); + FILE *a = fopen("/tmp/zzzzzz", "w"); + fprintf(a, "aaaaaaaaaaa TEST\n"); fclose(a); tsLDescriptor = (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor)); - if (tsLDescriptor) { - tsLDescriptor->UniqueID = 100; - tsLDescriptor->Label = "ZASF"; + if(tsLDescriptor) { + tsLDescriptor->UniqueID = 100; + tsLDescriptor->Label = "ZASF"; tsLDescriptor->Properties = 0; tsLDescriptor->Name = "ZynAddSubFX"; - tsLDescriptor->Maker = "Nasca Octavian Paul "; - tsLDescriptor->Copyright = "GNU General Public License v.2"; - tsLDescriptor->PortCount = 2; + tsLDescriptor->Maker = + "Nasca Octavian Paul "; + tsLDescriptor->Copyright = "GNU General Public License v.2"; + tsLDescriptor->PortCount = 2; port_descriptors = (LADSPA_PortDescriptor *) calloc(tsLDescriptor->PortCount, sizeof @@ -208,42 +208,40 @@ void _init() port_names = (char **) calloc(tsLDescriptor->PortCount, sizeof(char *)); tsLDescriptor->PortNames = (const char **) port_names; - port_descriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_descriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; port_names[0] = "Output L"; port_range_hints[0].HintDescriptor = 0; port_descriptors[1] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; port_names[1] = "Output R"; port_range_hints[1].HintDescriptor = 0; - tsLDescriptor->activate = activateTS; - tsLDescriptor->cleanup = cleanupTS; + tsLDescriptor->activate = activateTS; + tsLDescriptor->cleanup = cleanupTS; tsLDescriptor->connect_port = connectPortTS; - tsLDescriptor->deactivate = NULL; - tsLDescriptor->instantiate = instantiateTS; + tsLDescriptor->deactivate = NULL; + tsLDescriptor->instantiate = instantiateTS; tsLDescriptor->run = runTSWrapper; - tsLDescriptor->run_adding = NULL; + tsLDescriptor->run_adding = NULL; tsLDescriptor->set_run_adding_gain = NULL; } tsDDescriptor = (DSSI_Descriptor *) malloc(sizeof(DSSI_Descriptor)); - if (tsDDescriptor) { - tsDDescriptor->DSSI_API_Version = 1; - tsDDescriptor->LADSPA_Plugin = tsLDescriptor; + if(tsDDescriptor) { + tsDDescriptor->DSSI_API_Version = 1; + tsDDescriptor->LADSPA_Plugin = tsLDescriptor; tsDDescriptor->configure = NULL; - tsDDescriptor->get_program = NULL; + tsDDescriptor->get_program = NULL; tsDDescriptor->get_midi_controller_for_port = getControllerTS; - tsDDescriptor->select_program = NULL; + tsDDescriptor->select_program = NULL; tsDDescriptor->run_synth = runTS; - tsDDescriptor->run_synth_adding = NULL; + tsDDescriptor->run_synth_adding = NULL; tsDDescriptor->run_multiple_synths = NULL; tsDDescriptor->run_multiple_synths_adding = NULL; } - -}; +} void _fini() -{ -}; +{} @@ -272,17 +270,18 @@ long int VSTSynth::canDo(char *txt){ }; bool VSTSynth::getVendorString(char *txt){ - strcpy(txt,"Nasca O. Paul"); - return(true); + strcpy(txt,"Nasca O. Paul"); + return(true); }; bool VSTSynth::getProductString(char *txt){ - strcpy(txt,"ZynAddSubFX"); - return(true); + strcpy(txt,"ZynAddSubFX"); + return(true); }; void VSTSynth::resume(){ - wantEvents(); + wantEvents(); }; */ + diff --git a/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h index 6ca808fbf..a2ecf3c55 100644 --- a/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h +++ b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h @@ -34,25 +34,25 @@ /* class VSTSynth:public AudioEffectX{ public: - VSTSynth (audioMasterCallback audioMaster); - ~VSTSynth(); + VSTSynth (audioMasterCallback audioMaster); + ~VSTSynth(); - virtual void process (float **inputs, float **outputs, long sampleframes); - virtual void processReplacing (float **inputs, float **outputs, long sampleframes); - virtual long processEvents(VstEvents *events);//this is used for Midi input - virtual long int canDo(char *txt); - virtual bool getVendorString(char *txt); - virtual bool getProductString(char *txt); - virtual void resume(); + virtual void process (float **inputs, float **outputs, long sampleframes); + virtual void processReplacing (float **inputs, float **outputs, long sampleframes); + virtual long processEvents(VstEvents *events);//this is used for Midi input + virtual long int canDo(char *txt); + virtual bool getVendorString(char *txt); + virtual bool getProductString(char *txt); + virtual void resume(); - virtual long getChunk(void** data,bool isPreset=false); - virtual void setChunk(void *data,long size,bool isPreset=false); + virtual long getChunk(void** data,bool isPreset=false); + virtual void setChunk(void *data,long size,bool isPreset=false); - MasterUI *ui; - int Pexitprogram; + MasterUI *ui; + int Pexitprogram; Master *vmaster; - pthread_t thr; + pthread_t thr; }; */ #endif diff --git a/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp index ca568e08b..2ee019d1c 100644 --- a/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp @@ -33,174 +33,197 @@ extern "C" #include "JACKaudiooutput.h" Master *jackmaster; -jack_client_t *jackclient; -jack_port_t *outport_left,*outport_right; -jack_ringbuffer_t *rb=NULL; +jack_client_t *jackclient; +jack_port_t *outport_left, *outport_right; +jack_ringbuffer_t *rb = NULL; -REALTYPE *jackoutl,*jackoutr; -int jackfinish=0; +REALTYPE *jackoutl, *jackoutr; +int jackfinish = 0; void *thread_blocked(void *arg); -int jackprocess(jack_nframes_t nframes,void *arg); -int jacksrate(jack_nframes_t nframes,void *arg); +int jackprocess(jack_nframes_t nframes, void *arg); +int jacksrate(jack_nframes_t nframes, void *arg); void jackshutdown(void *arg); -pthread_cond_t more_data=PTHREAD_COND_INITIALIZER; -pthread_mutex_t zyn_thread_lock=PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t more_data = PTHREAD_COND_INITIALIZER; +pthread_mutex_t zyn_thread_lock = PTHREAD_MUTEX_INITIALIZER; pthread_t bthr; bool JACKaudiooutputinit(Master *master_) { - jackmaster=master_; - jackclient=0; + jackmaster = master_; + jackclient = 0; char tmpstr[100]; - jackoutl=new REALTYPE [SOUND_BUFFER_SIZE]; - jackoutr=new REALTYPE [SOUND_BUFFER_SIZE]; + jackoutl = new REALTYPE [SOUND_BUFFER_SIZE]; + jackoutr = new REALTYPE [SOUND_BUFFER_SIZE]; - int rbbufsize=SOUND_BUFFER_SIZE*sizeof (REALTYPE)*2*2; - printf("%d\n",rbbufsize); - rb=jack_ringbuffer_create(rbbufsize); - for (int i=0;ibuf[i]=0.0; + int rbbufsize = SOUND_BUFFER_SIZE * sizeof(REALTYPE) * 2 * 2; + printf("%d\n", rbbufsize); + rb = jack_ringbuffer_create(rbbufsize); + for(int i = 0; i < rbbufsize; i++) + rb->buf[i] = 0.0; - for (int i=0;i<15;i++) { - if (i!=0) snprintf(tmpstr,100,"ZynAddSubFX_%d",i); - else snprintf(tmpstr,100,"ZynAddSubFX"); - jackclient=jack_client_new(tmpstr); - if (jackclient!=0) break; - }; + for(int i = 0; i < 15; i++) { + if(i != 0) + snprintf(tmpstr, 100, "ZynAddSubFX_%d", i); + else + snprintf(tmpstr, 100, "ZynAddSubFX"); + jackclient = jack_client_new(tmpstr); + if(jackclient != 0) + break; + } - if (jackclient==0) { - fprintf(stderr,"\nERROR: Cannot make a jack client (possible reasons: JACK server is not running or jackd is launched by root and zynaddsubfx by another user.).\n\n\n"); - return(false); - }; + if(jackclient == 0) { + fprintf( + stderr, + "\nERROR: Cannot make a jack client (possible reasons: JACK server is not running or jackd is launched by root and zynaddsubfx by another user.).\n\n\n"); + return false; + } - fprintf(stderr,"Internal SampleRate = %d\nJack Output SampleRate= %d\n",SAMPLE_RATE,jack_get_sample_rate(jackclient)); - if ((unsigned int)jack_get_sample_rate(jackclient)!=(unsigned int) SAMPLE_RATE) - fprintf(stderr,"It is recomanded that the both samplerates to be equal.\n"); + fprintf(stderr, + "Internal SampleRate = %d\nJack Output SampleRate= %d\n", + SAMPLE_RATE, + jack_get_sample_rate(jackclient)); + if((unsigned int)jack_get_sample_rate(jackclient) != + (unsigned int) SAMPLE_RATE) + fprintf(stderr, + "It is recomanded that the both samplerates to be equal.\n"); - jack_set_process_callback(jackclient,jackprocess,0); - jack_set_sample_rate_callback(jackclient,jacksrate,0); - jack_on_shutdown(jackclient,jackshutdown,0); + jack_set_process_callback(jackclient, jackprocess, 0); + jack_set_sample_rate_callback(jackclient, jacksrate, 0); + jack_on_shutdown(jackclient, jackshutdown, 0); - outport_left=jack_port_register(jackclient,"out_1", - JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); - outport_right=jack_port_register(jackclient,"out_2", - JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); + outport_left = jack_port_register(jackclient, + "out_1", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsOutput | JackPortIsTerminal, + 0); + outport_right = jack_port_register(jackclient, + "out_2", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsOutput | JackPortIsTerminal, + 0); - if (jack_activate(jackclient)) { - fprintf(stderr,"Cannot activate jack client\n"); - return(false); - }; + if(jack_activate(jackclient)) { + fprintf(stderr, "Cannot activate jack client\n"); + return false; + } - pthread_create(&bthr,NULL,thread_blocked,NULL); + pthread_create(&bthr, NULL, thread_blocked, NULL); /* jack_connect(jackclient,jack_port_name(outport_left),"alsa_pcm:out_1"); jack_connect(jackclient,jack_port_name(outport_right),"alsa_pcm:out_2"); */ - return(true); -}; + return true; +} void *thread_blocked(void *arg) { - int datasize=SOUND_BUFFER_SIZE*sizeof (REALTYPE); + int datasize = SOUND_BUFFER_SIZE * sizeof(REALTYPE); //try to get realtime sched_param sc; - sc.sched_priority=50; - int err=sched_setscheduler(0,SCHED_FIFO,&sc); + sc.sched_priority = 50; + int err = sched_setscheduler(0, SCHED_FIFO, &sc); - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_mutex_lock(&zyn_thread_lock); - while (jackfinish==0) { - while (jack_ringbuffer_write_space(rb)>=datasize) { + while(jackfinish == 0) { + while(jack_ringbuffer_write_space(rb) >= datasize) { pthread_mutex_lock(&jackmaster->mutex); - jackmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE,jack_get_sample_rate(jackclient),jackoutl,jackoutr); + jackmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE, + jack_get_sample_rate(jackclient), + jackoutl, + jackoutr); pthread_mutex_unlock(&jackmaster->mutex); - jack_ringbuffer_write(rb, (char *) jackoutl,datasize); - jack_ringbuffer_write(rb, (char *) jackoutr,datasize); - }; - pthread_cond_wait(&more_data,&zyn_thread_lock); - }; + jack_ringbuffer_write(rb, (char *) jackoutl, datasize); + jack_ringbuffer_write(rb, (char *) jackoutr, datasize); + } + pthread_cond_wait(&more_data, &zyn_thread_lock); + } pthread_mutex_unlock(&zyn_thread_lock); - return(0); -}; + return 0; +} -int jackprocess(jack_nframes_t nframes,void *arg) +int jackprocess(jack_nframes_t nframes, void *arg) { - jack_default_audio_sample_t *outl=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_left, nframes); - jack_default_audio_sample_t *outr=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_right, nframes); + jack_default_audio_sample_t *outl = + (jack_default_audio_sample_t *) jack_port_get_buffer(outport_left, + nframes); + jack_default_audio_sample_t *outr = + (jack_default_audio_sample_t *) jack_port_get_buffer(outport_right, + nframes); - int datasize=nframes*sizeof (REALTYPE); - int incoming_datasize=SOUND_BUFFER_SIZE*sizeof (REALTYPE); - int data_read=0; + int datasize = nframes * sizeof(REALTYPE); + int incoming_datasize = SOUND_BUFFER_SIZE * sizeof(REALTYPE); + int data_read = 0; - if (jack_ringbuffer_read_space(rb)>=(2*incoming_datasize)) { - if (datasize>incoming_datasize) { - data_read=0; - while (data_read < datasize) { - jack_ringbuffer_read(rb, (char *) outl+data_read,datasize); - jack_ringbuffer_read(rb, (char *) outr+data_read,datasize); - data_read+=incoming_datasize; - }; - } else if (datasize==incoming_datasize) { - jack_ringbuffer_read(rb, (char *) outl,datasize); - jack_ringbuffer_read(rb, (char *) outr,datasize); - } else { - }; - } else {//the ringbuffer is empty or there are too small amount of samples in it - for (int i=0;i= (2 * incoming_datasize)) { + if(datasize > incoming_datasize) { + data_read = 0; + while(data_read < datasize) { + jack_ringbuffer_read(rb, (char *) outl + data_read, datasize); + jack_ringbuffer_read(rb, (char *) outr + data_read, datasize); + data_read += incoming_datasize; + } + } + else + if(datasize == incoming_datasize) { + jack_ringbuffer_read(rb, (char *) outl, datasize); + jack_ringbuffer_read(rb, (char *) outr, datasize); + } + else {} + } + else { //the ringbuffer is empty or there are too small amount of samples in it + for(int i = 0; i < nframes; i++) { + outl[i] = 0.0; + outr[i] = 0.0; + } + } /* if (jack_ringbuffer_read_space(rb)>=datasize){ - jack_ringbuffer_read(rb, (char *) outl,datasize); - jack_ringbuffer_read(rb, (char *) outr,datasize); + jack_ringbuffer_read(rb, (char *) outl,datasize); + jack_ringbuffer_read(rb, (char *) outr,datasize); } else {//the ringbuffer is empty or there are too small amount of samples in it - for (int i=0;imutex)) { + if(!pthread_mutex_trylock(&jackmaster->mutex)) { JACKhandlemidi(nframes); - jackmaster->GetAudioOutSamples(nframes,jack_get_sample_rate(jackclient),outl,outr); + jackmaster->GetAudioOutSamples(nframes, jack_get_sample_rate( + jackclient), outl, outr); pthread_mutex_unlock(&jackmaster->mutex); - } else { + } + else { memset(outl, 0, sizeof(jack_default_audio_sample_t) * nframes); memset(outr, 0, sizeof(jack_default_audio_sample_t) * nframes); } - return(0); -}; + return 0; +} void JACKfinish() { jack_client_close(jackclient); -}; +} -int jacksrate(jack_nframes_t nframes,void *arg) +int jacksrate(jack_nframes_t nframes, void *arg) { - - return(0); -}; + return 0; +} void jackshutdown(void *arg) -{ -}; +{} void JACKhandlemidi(unsigned long frames) { - // We must have the master mutex before we run this function // XXX This is really nasty, not only do we lose the sample accuracy of // JACK MIDI, but any accuracy at all below the buffer size - void* midi_buf = jack_port_get_buffer(midi_inport, frames); + void *midi_buf = jack_port_get_buffer(midi_inport, frames); jack_midi_event_t jack_midi_event; - jack_nframes_t event_index = 0; - unsigned char* midi_data; - unsigned char type, chan; + jack_nframes_t event_index = 0; + unsigned char *midi_data; + unsigned char type, chan; - while (jack_midi_event_get(&jack_midi_event,midi_buf, event_index++) == 0) { + while(jack_midi_event_get(&jack_midi_event, midi_buf, + event_index++) == 0) { midi_data = jack_midi_event.buffer; - type = midi_data[0] & 0xF0; - chan = midi_data[0] & 0x0F; - - switch (type) { + type = midi_data[0] & 0xF0; + chan = midi_data[0] & 0x0F; + switch(type) { case 0x80: /* note-off */ jackmaster->NoteOff(chan, midi_data[1]); break; @@ -151,13 +173,13 @@ void JACKhandlemidi(unsigned long frames) /* XXX TODO: handle MSB/LSB controllers and RPNs and NRPNs */ } } - } -const char* JACKgetname() +const char *JACKgetname() { - if (jackclient != NULL) + if(jackclient != NULL) return jackname; return NULL; } + diff --git a/plugins/zynaddsubfx/src/Output/JACKaudiooutput.h b/plugins/zynaddsubfx/src/Output/JACKaudiooutput.h index 7061f8c16..afc5e5b7f 100644 --- a/plugins/zynaddsubfx/src/Output/JACKaudiooutput.h +++ b/plugins/zynaddsubfx/src/Output/JACKaudiooutput.h @@ -28,11 +28,12 @@ #include "../Misc/Master.h" -#if (REALTYPE!=jack_default_audio_sample_t) -#error "The internal sample datatype of ZynAddSubFX and the datatype of jack differs.\ - In order to compile ZynAddSubFX the 'REALTYPE' and 'jack_default_audio_sample_t' must be equal.\ - Set the 'REALTYPE' data type (which is defined in 'globals.h') to what is defined \ - in the file types.h from jack include directory as 'jack_default_audio_sample_t' (as float or double)." +#if (REALTYPE != jack_default_audio_sample_t) +#error \ + "The internal sample datatype of ZynAddSubFX and the datatype of jack differs. \ + In order to compile ZynAddSubFX the 'REALTYPE' and 'jack_default_audio_sample_t' must be equal. \ + Set the 'REALTYPE' data type (which is defined in 'globals.h') to what is defined \ + in the file types.h from jack include directory as 'jack_default_audio_sample_t' (as float or double)." #endif @@ -41,7 +42,7 @@ bool JACKaudiooutputinit(Master *master_); void JACKfinish(); void JACKhandlemidi(unsigned long frames); -const char* JACKgetname(); +const char *JACKgetname(); #endif diff --git a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp index d10d32c96..ad77573af 100644 --- a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp @@ -37,60 +37,92 @@ using namespace std; OSSaudiooutput::OSSaudiooutput() { int i; - int snd_bitsize=16; - snd_fragment=0x00080009;//fragment size (?) - snd_stereo=1;//stereo - snd_format=AFMT_S16_LE; - snd_samplerate=SAMPLE_RATE; + int snd_bitsize = 16; + snd_fragment = 0x00080009; //fragment size (?) + snd_stereo = 1; //stereo + snd_format = AFMT_S16_LE; + snd_samplerate = SAMPLE_RATE; + playing_until.tv_sec = 0; + playing_until.tv_usec = 0; - smps=new short int[SOUND_BUFFER_SIZE*2]; - for (i=0;i 10000) //Don't sleep() less than 10ms. + //This will add latency... + usleep(remaining - 10000); + if(remaining < 0) + cerr << "WARNING - too late" << endl; + } + playing_until.tv_usec += SOUND_BUFFER_SIZE * 1000000 / SAMPLE_RATE; + if(remaining < 0) + playing_until.tv_usec -= remaining; + playing_until.tv_sec += playing_until.tv_usec / 1000000; + playing_until.tv_usec %= 1000000; + return; + } - if (l<-1.0) l=-1.0; - else if (l>1.0) l=1.0; - if (r<-1.0) r=-1.0; - else if (r>1.0) r=1.0; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + l = smp_left[i]; + r = smp_right[i]; - smps[i*2]=(short int) (l*32767.0); - smps[i*2+1]=(short int) (r*32767.0); - }; - write(snd_handle,smps,SOUND_BUFFER_SIZE*4);// *2 because is 16 bit, again * 2 because is stereo -}; + if(l < -1.0) + l = -1.0; + else + if(l > 1.0) + l = 1.0; + if(r < -1.0) + r = -1.0; + else + if(r > 1.0) + r = 1.0; + + smps[i * 2] = (short int) (l * 32767.0); + smps[i * 2 + 1] = (short int) (r * 32767.0); + } + write(snd_handle, smps, SOUND_BUFFER_SIZE * 4); // *2 because is 16 bit, again * 2 because is stereo +} OSSaudiooutput::~OSSaudiooutput() { close(snd_handle); delete [] smps; -}; +} diff --git a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.h b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.h index 3f130e084..28da1cfaf 100644 --- a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.h +++ b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.h @@ -23,25 +23,27 @@ #ifndef OSS_AUDIO_OUTPUT_H #define OSS_AUDIO_OUTPUT_H +#include #include "../globals.h" class OSSaudiooutput { -public: - OSSaudiooutput(); - ~OSSaudiooutput(); + public: + OSSaudiooutput(); + ~OSSaudiooutput(); - //the out is [-1.0 .. 1.0] - /* smp_left[] and smp_right[] has the size of SOUND_BUFFER_SIZE */ - void OSSout(REALTYPE *smp_left,REALTYPE *smp_right); -private: - int snd_handle; - int snd_fragment; - int snd_stereo; - int snd_format; - int snd_samplerate; + //the out is [-1.0 .. 1.0] + /* smp_left[] and smp_right[] has the size of SOUND_BUFFER_SIZE */ + void OSSout(REALTYPE *smp_left, REALTYPE *smp_right); + private: + int snd_handle; + int snd_fragment; + int snd_stereo; + int snd_format; + int snd_samplerate; + struct timeval playing_until; - short int *smps;//Samples to be sent to soundcard + short int *smps; //Samples to be sent to soundcard }; #endif diff --git a/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp index 161153ffd..73b346827 100644 --- a/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp @@ -22,52 +22,59 @@ #include "PAaudiooutput.h" -Master *PAmaster; +Master *PAmaster; PaStream *stream; -REALTYPE *outl,*outr; +REALTYPE *outl, *outr; -int PAprocess(void *inputBuffer,void *outputBuffer, +int PAprocess(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, - PaTimestamp outTime,void *userData) + PaTimestamp outTime, void *userData) { - - if (framesPerBuffer!=SOUND_BUFFER_SIZE) { - fprintf(stderr,"Bug: PAudioOutput::PAprocess SOUND_BUFFER_SIZE!=framesPerBuffer"); - fprintf(stderr,"%d %d\n",framesPerBuffer,SOUND_BUFFER_SIZE); - }; + if(framesPerBuffer != SOUND_BUFFER_SIZE) { + fprintf( + stderr, + "Bug: PAudioOutput::PAprocess SOUND_BUFFER_SIZE!=framesPerBuffer"); + fprintf(stderr, "%d %d\n", framesPerBuffer, SOUND_BUFFER_SIZE); + } pthread_mutex_lock(&PAmaster->mutex); - PAmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE,SAMPLE_RATE,outl,outr); + PAmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE, SAMPLE_RATE, outl, outr); pthread_mutex_unlock(&PAmaster->mutex); - float *out=(float *)outputBuffer; + float *out = (float *)outputBuffer; - for (int i=0;i=SOUND_BUFFER_SIZE) break;//this should never happens, except only when framesPerBuffer!>SOUND_BUFFER_SIZE - out[i*2]=outl[i]; - out[i*2+1]=outr[i]; - }; + for(int i = 0; i < framesPerBuffer; i++) { + if(i >= SOUND_BUFFER_SIZE) + break; //this should never happens, except only when framesPerBuffer!>SOUND_BUFFER_SIZE + out[i * 2] = outl[i]; + out[i * 2 + 1] = outr[i]; + } - return(0); -}; + return 0; +} void PAaudiooutputinit(Master *master_) { - PAmaster=master_; - outl=new REALTYPE [SOUND_BUFFER_SIZE]; - outr=new REALTYPE [SOUND_BUFFER_SIZE]; + PAmaster = master_; + outl = new REALTYPE [SOUND_BUFFER_SIZE]; + outr = new REALTYPE [SOUND_BUFFER_SIZE]; Pa_Initialize(); - Pa_OpenDefaultStream(&stream,0,2,paFloat32,SAMPLE_RATE,SOUND_BUFFER_SIZE,0,PAprocess,NULL); + Pa_OpenDefaultStream(&stream, + 0, + 2, + paFloat32, + SAMPLE_RATE, + SOUND_BUFFER_SIZE, + 0, + PAprocess, + NULL); Pa_StartStream(stream); -}; +} void PAfinish() { Pa_StopStream(stream); delete (outl); delete (outr); -}; - - - +} diff --git a/plugins/zynaddsubfx/src/Output/Recorder.cpp b/plugins/zynaddsubfx/src/Output/Recorder.cpp index 388ab7f74..43a44630e 100644 --- a/plugins/zynaddsubfx/src/Output/Recorder.cpp +++ b/plugins/zynaddsubfx/src/Output/Recorder.cpp @@ -25,80 +25,89 @@ Recorder::Recorder() { - recordbuf_16bit=new short int [SOUND_BUFFER_SIZE*2]; - status=0; - notetrigger=0; - for (int i=0;i32767) tmp=32767; - recordbuf_16bit[i*2]=tmp; + if(status != 2) + return; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmp = (int)(outl[i] * 32767.0); + if(tmp < -32768) + tmp = -32768; + if(tmp > 32767) + tmp = 32767; + recordbuf_16bit[i * 2] = tmp; - tmp=(int)(outr[i]*32767.0); - if (tmp<-32768) tmp=-32768; - if (tmp>32767) tmp=32767; - recordbuf_16bit[i*2+1]=tmp; - }; - wav.write_stereo_samples(SOUND_BUFFER_SIZE,recordbuf_16bit); -}; + tmp = (int)(outr[i] * 32767.0); + if(tmp < -32768) + tmp = -32768; + if(tmp > 32767) + tmp = 32767; + recordbuf_16bit[i * 2 + 1] = tmp; + } + wav.write_stereo_samples(SOUND_BUFFER_SIZE, recordbuf_16bit); +} void Recorder::triggernow() { - if (status==2) notetrigger=1; -}; + if(status == 2) + notetrigger = 1; +} + diff --git a/plugins/zynaddsubfx/src/Output/Recorder.h b/plugins/zynaddsubfx/src/Output/Recorder.h index 059f7108f..997ed3783 100644 --- a/plugins/zynaddsubfx/src/Output/Recorder.h +++ b/plugins/zynaddsubfx/src/Output/Recorder.h @@ -29,28 +29,29 @@ /**Records sound to a file*/ class Recorder { -public: + public: - Recorder(); - ~Recorder(); - int preparefile(std::string filename_,int overwrite);//returns 1 if the file exists - void start(); - void stop(); - void pause(); - int recording(); - void triggernow(); - void recordbuffer(REALTYPE *outl,REALTYPE *outr); + Recorder(); + ~Recorder(); + int preparefile(std::string filename_, int overwrite); //returns 1 if the file exists + void start(); + void stop(); + void pause(); + int recording(); + void triggernow(); + void recordbuffer(REALTYPE *outl, REALTYPE *outr); - /** Status: - * 0 - not ready(no file selected), - * 1 - ready - * 2 - recording */ - int status; + /** Status: + * 0 - not ready(no file selected), + * 1 - ready + * 2 - recording */ + int status; -private: - WAVaudiooutput wav; - short int *recordbuf_16bit; - int notetrigger; + private: + WAVaudiooutput wav; + short int *recordbuf_16bit; + int notetrigger; }; #endif + diff --git a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp index 6441ab092..183a3bb55 100644 --- a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp @@ -24,42 +24,45 @@ //the constructor and the destructor are defined in main.C -void VSTSynth::process (float **inputs, float **outputs, long sampleframes) +void VSTSynth::process(float **inputs, float **outputs, long sampleframes) { - float *outl=outputs[0]; - float *outr=outputs[1]; + float *outl = outputs[0]; + float *outr = outputs[1]; pthread_mutex_lock(&vmaster->mutex); - vmaster->GetAudioOutSamples(sampleframes,(int) getSampleRate(),outl,outr); + vmaster->GetAudioOutSamples(sampleframes, (int) getSampleRate(), outl, outr); pthread_mutex_unlock(&vmaster->mutex); -}; +} -void VSTSynth::processReplacing (float **inputs, float **outputs, long sampleframes) +void VSTSynth::processReplacing(float **inputs, + float **outputs, + long sampleframes) { - process(inputs,outputs,sampleframes); -}; + process(inputs, outputs, sampleframes); +} long int VSTSynth::canDo(char *txt) { - if (strcmp(txt,"receiveVstEvents")==0) return (1); - if (strcmp(txt,"receiveVstMidiEvent")==0) return (1); - return(-1); -}; + if(strcmp(txt, "receiveVstEvents") == 0) + return 1; + if(strcmp(txt, "receiveVstMidiEvent") == 0) + return 1; + return -1; +} bool VSTSynth::getVendorString(char *txt) { - strcpy(txt,"Nasca O. Paul"); - return(true); -}; + strcpy(txt, "Nasca O. Paul"); + return true; +} bool VSTSynth::getProductString(char *txt) { - strcpy(txt,"ZynAddSubFX"); - return(true); -}; + strcpy(txt, "ZynAddSubFX"); + return true; +} void VSTSynth::resume() { wantEvents(); -}; - +} diff --git a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.h b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.h index 116f33004..1fe0afd13 100644 --- a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.h +++ b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.h @@ -32,26 +32,28 @@ class VSTSynth:public AudioEffectX { -public: - VSTSynth (audioMasterCallback audioMaster); - ~VSTSynth(); + public: + VSTSynth(audioMasterCallback audioMaster); + ~VSTSynth(); - virtual void process (float **inputs, float **outputs, long sampleframes); - virtual void processReplacing (float **inputs, float **outputs, long sampleframes); - virtual long processEvents(VstEvents *events);//this is used for Midi input - virtual long int canDo(char *txt); - virtual bool getVendorString(char *txt); - virtual bool getProductString(char *txt); - virtual void resume(); + virtual void process(float **inputs, float **outputs, long sampleframes); + virtual void processReplacing(float **inputs, + float **outputs, + long sampleframes); + virtual long processEvents(VstEvents *events); //this is used for Midi input + virtual long int canDo(char *txt); + virtual bool getVendorString(char *txt); + virtual bool getProductString(char *txt); + virtual void resume(); - virtual long getChunk(void** data,bool isPreset=false); - virtual long setChunk(void *data,long size,bool isPreset=false); + virtual long getChunk(void **data, bool isPreset = false); + virtual long setChunk(void *data, long size, bool isPreset = false); - MasterUI *ui; - int Pexitprogram; + MasterUI *ui; + int Pexitprogram; - Master *vmaster; - pthread_t thr; + Master *vmaster; + pthread_t thr; }; #endif diff --git a/plugins/zynaddsubfx/src/Output/WAVaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.cpp index fc03243c4..cc1f87c0e 100644 --- a/plugins/zynaddsubfx/src/Output/WAVaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.cpp @@ -23,77 +23,79 @@ using namespace std; WAVaudiooutput::WAVaudiooutput() { - file=NULL; - sampleswritten=0; - samplerate=44100; -}; + file = NULL; + sampleswritten = 0; + samplerate = 44100; +} WAVaudiooutput::~WAVaudiooutput() { close(); -}; +} -bool WAVaudiooutput::newfile(string filename,int samplerate,int channels) +bool WAVaudiooutput::newfile(string filename, int samplerate, int channels) { /**\todo Move this into the Constructor*/ - close();//inchide un posibil fisier existent - file=fopen(filename.c_str(),"w"); - if (!file) return false; - this->samplerate=samplerate; - this->channels=channels; - sampleswritten=0; + close(); //inchide un posibil fisier existent + file = fopen(filename.c_str(), "w"); + if(!file) + return false; + this->samplerate = samplerate; + this->channels = channels; + sampleswritten = 0; char tmp[44]; - fwrite(tmp,1,44,file); - return(true); -}; + fwrite(tmp, 1, 44, file); + return true; +} void WAVaudiooutput::close() { - if (file) { + if(file) { unsigned int chunksize; rewind(file); - fwrite("RIFF",4,1,file); - chunksize=sampleswritten*4+36; - fwrite(&chunksize,4,1,file); + fwrite("RIFF", 4, 1, file); + chunksize = sampleswritten * 4 + 36; + fwrite(&chunksize, 4, 1, file); - fwrite("WAVEfmt ",8,1,file); - chunksize=16; - fwrite(&chunksize,4,1,file); - unsigned short int formattag=1;//uncompresed wave - fwrite(&formattag,2,1,file); - unsigned short int nchannels=channels;//stereo - fwrite(&nchannels,2,1,file); - unsigned int samplerate_=samplerate;//samplerate - fwrite(&samplerate_,4,1,file); - unsigned int bytespersec=samplerate*2*channels;//bytes/sec - fwrite(&bytespersec,4,1,file); - unsigned short int blockalign=2*channels;//2 channels * 16 bits/8 - fwrite(&blockalign,2,1,file); - unsigned short int bitspersample=16; - fwrite(&bitspersample,2,1,file); + fwrite("WAVEfmt ", 8, 1, file); + chunksize = 16; + fwrite(&chunksize, 4, 1, file); + unsigned short int formattag = 1; //uncompresed wave + fwrite(&formattag, 2, 1, file); + unsigned short int nchannels = channels; //stereo + fwrite(&nchannels, 2, 1, file); + unsigned int samplerate_ = samplerate; //samplerate + fwrite(&samplerate_, 4, 1, file); + unsigned int bytespersec = samplerate * 2 * channels; //bytes/sec + fwrite(&bytespersec, 4, 1, file); + unsigned short int blockalign = 2 * channels; //2 channels * 16 bits/8 + fwrite(&blockalign, 2, 1, file); + unsigned short int bitspersample = 16; + fwrite(&bitspersample, 2, 1, file); - fwrite("data",4,1,file); - chunksize=sampleswritten*blockalign; - fwrite(&chunksize,4,1,file); + fwrite("data", 4, 1, file); + chunksize = sampleswritten * blockalign; + fwrite(&chunksize, 4, 1, file); fclose(file); - file=NULL; + file = NULL; } -}; +} -void WAVaudiooutput::write_stereo_samples(int nsmps,short int *smps) +void WAVaudiooutput::write_stereo_samples(int nsmps, short int *smps) { - if (!file) return; - fwrite(smps,nsmps,4,file); - sampleswritten+=nsmps; -}; + if(!file) + return; + fwrite(smps, nsmps, 4, file); + sampleswritten += nsmps; +} -void WAVaudiooutput::write_mono_samples(int nsmps,short int *smps) +void WAVaudiooutput::write_mono_samples(int nsmps, short int *smps) { - if (!file) return; - fwrite(smps,nsmps,2,file); - sampleswritten+=nsmps; -}; - + if(!file) + return; + fwrite(smps, nsmps, 2, file); + sampleswritten += nsmps; +} diff --git a/plugins/zynaddsubfx/src/Output/WAVaudiooutput.h b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.h index 54abae8fd..193fb19f3 100644 --- a/plugins/zynaddsubfx/src/Output/WAVaudiooutput.h +++ b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.h @@ -23,20 +23,21 @@ class WAVaudiooutput { -public: - WAVaudiooutput(); - ~WAVaudiooutput(); + public: + WAVaudiooutput(); + ~WAVaudiooutput(); - bool newfile(std::string filename,int samplerate,int channels); - void close(); + bool newfile(std::string filename, int samplerate, int channels); + void close(); - void write_mono_samples(int nsmps, short int *smps); - void write_stereo_samples(int nsmps, short int *smps); + void write_mono_samples(int nsmps, short int *smps); + void write_stereo_samples(int nsmps, short int *smps); -private: - int sampleswritten; - int samplerate; - int channels; - FILE *file; + private: + int sampleswritten; + int samplerate; + int channels; + FILE *file; }; #endif + diff --git a/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp b/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp index 5fb6ce797..80c23391d 100644 --- a/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp +++ b/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp @@ -25,114 +25,125 @@ #include #include "ADnoteParameters.h" +int ADnote_unison_sizes[] = +{1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 25, 30, 40, 50, 0}; ADnoteParameters::ADnoteParameters(FFTwrapper *fft_):Presets() { setpresettype("Padsyth"); - fft=fft_; + fft = fft_; - GlobalPar.FreqEnvelope=new EnvelopeParams(0,0); - GlobalPar.FreqEnvelope->ASRinit(64,50,64,60); - GlobalPar.FreqLfo=new LFOParams(70,0,64,0,0,0,0,0); + GlobalPar.FreqEnvelope = new EnvelopeParams(0, 0); + GlobalPar.FreqEnvelope->ASRinit(64, 50, 64, 60); + GlobalPar.FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0); - GlobalPar.AmpEnvelope=new EnvelopeParams(64,1); - GlobalPar.AmpEnvelope->ADSRinit_dB(0,40,127,25); - GlobalPar.AmpLfo=new LFOParams(80,0,64,0,0,0,0,1); + GlobalPar.AmpEnvelope = new EnvelopeParams(64, 1); + GlobalPar.AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); + GlobalPar.AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1); - GlobalPar.GlobalFilter=new FilterParams(2,94,40); - GlobalPar.FilterEnvelope=new EnvelopeParams(0,1); - GlobalPar.FilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); - GlobalPar.FilterLfo=new LFOParams(80,0,64,0,0,0,0,2); - GlobalPar.Reson=new Resonance(); + GlobalPar.GlobalFilter = new FilterParams(2, 94, 40); + GlobalPar.FilterEnvelope = new EnvelopeParams(0, 1); + GlobalPar.FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); + GlobalPar.FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2); + GlobalPar.Reson = new Resonance(); - for (int nvoice=0;nvoicedefaults(); GlobalPar.FreqLfo->defaults(); - GlobalPar.PBandwidth=64; + GlobalPar.PBandwidth = 64; /* Amplitude Global Parameters */ - GlobalPar.PVolume=90; - GlobalPar.PPanning=64;//center - GlobalPar.PAmpVelocityScaleFunction=64; + GlobalPar.PVolume = 90; + GlobalPar.PPanning = 64; //center + GlobalPar.PAmpVelocityScaleFunction = 64; GlobalPar.AmpEnvelope->defaults(); GlobalPar.AmpLfo->defaults(); - GlobalPar.PPunchStrength=0; - GlobalPar.PPunchTime=60; - GlobalPar.PPunchStretch=64; - GlobalPar.PPunchVelocitySensing=72; - GlobalPar.Hrandgrouping=0; + GlobalPar.PPunchStrength = 0; + GlobalPar.PPunchTime = 60; + GlobalPar.PPunchStretch = 64; + GlobalPar.PPunchVelocitySensing = 72; + GlobalPar.Hrandgrouping = 0; /* Filter Global Parameters*/ - GlobalPar.PFilterVelocityScale=64; - GlobalPar.PFilterVelocityScaleFunction=64; + GlobalPar.PFilterVelocityScale = 64; + GlobalPar.PFilterVelocityScaleFunction = 64; GlobalPar.GlobalFilter->defaults(); GlobalPar.FilterEnvelope->defaults(); GlobalPar.FilterLfo->defaults(); GlobalPar.Reson->defaults(); - for (int nvoice=0;nvoicedefaults(); VoicePar[nvoice].FMSmp->defaults(); @@ -149,7 +160,7 @@ void ADnoteParameters::defaults(int n) VoicePar[nvoice].FMFreqEnvelope->defaults(); VoicePar[nvoice].FMAmpEnvelope->defaults(); -}; +} @@ -158,39 +169,48 @@ void ADnoteParameters::defaults(int n) */ void ADnoteParameters::EnableVoice(int nvoice) { - VoicePar[nvoice].OscilSmp=new OscilGen(fft,GlobalPar.Reson); - VoicePar[nvoice].FMSmp=new OscilGen(fft,NULL); + VoicePar[nvoice].OscilSmp = new OscilGen(fft, GlobalPar.Reson); + VoicePar[nvoice].FMSmp = new OscilGen(fft, NULL); - VoicePar[nvoice].AmpEnvelope=new EnvelopeParams(64,1); - VoicePar[nvoice].AmpEnvelope->ADSRinit_dB(0,100,127,100); - VoicePar[nvoice].AmpLfo=new LFOParams(90,32,64,0,0,30,0,1); + VoicePar[nvoice].AmpEnvelope = new EnvelopeParams(64, 1); + VoicePar[nvoice].AmpEnvelope->ADSRinit_dB(0, 100, 127, 100); + VoicePar[nvoice].AmpLfo = new LFOParams(90, 32, 64, 0, 0, 30, 0, 1); - VoicePar[nvoice].FreqEnvelope=new EnvelopeParams(0,0); - VoicePar[nvoice].FreqEnvelope->ASRinit(30,40,64,60); - VoicePar[nvoice].FreqLfo=new LFOParams(50,40,0,0,0,0,0,0); + VoicePar[nvoice].FreqEnvelope = new EnvelopeParams(0, 0); + VoicePar[nvoice].FreqEnvelope->ASRinit(30, 40, 64, 60); + VoicePar[nvoice].FreqLfo = new LFOParams(50, 40, 0, 0, 0, 0, 0, 0); - VoicePar[nvoice].VoiceFilter=new FilterParams(2,50,60); - VoicePar[nvoice].FilterEnvelope=new EnvelopeParams(0,0); - VoicePar[nvoice].FilterEnvelope->ADSRinit_filter(90,70,40,70,10,40); - VoicePar[nvoice].FilterLfo=new LFOParams(50,20,64,0,0,0,0,2); + VoicePar[nvoice].VoiceFilter = new FilterParams(2, 50, 60); + VoicePar[nvoice].FilterEnvelope = new EnvelopeParams(0, 0); + VoicePar[nvoice].FilterEnvelope->ADSRinit_filter(90, 70, 40, 70, 10, 40); + VoicePar[nvoice].FilterLfo = new LFOParams(50, 20, 64, 0, 0, 0, 0, 2); - VoicePar[nvoice].FMFreqEnvelope=new EnvelopeParams(0,0); - VoicePar[nvoice].FMFreqEnvelope->ASRinit(20,90,40,80); - VoicePar[nvoice].FMAmpEnvelope=new EnvelopeParams(64,1); - VoicePar[nvoice].FMAmpEnvelope->ADSRinit(80,90,127,100); -}; + VoicePar[nvoice].FMFreqEnvelope = new EnvelopeParams(0, 0); + VoicePar[nvoice].FMFreqEnvelope->ASRinit(20, 90, 40, 80); + VoicePar[nvoice].FMAmpEnvelope = new EnvelopeParams(64, 1); + VoicePar[nvoice].FMAmpEnvelope->ADSRinit(80, 90, 127, 100); +} /* * Get the Multiplier of the fine detunes of the voices */ REALTYPE ADnoteParameters::getBandwidthDetuneMultiplier() { - REALTYPE bw=(GlobalPar.PBandwidth-64.0)/64.0; - bw=pow(2.0,bw*pow(fabs(bw),0.2)*5.0); + REALTYPE bw = (GlobalPar.PBandwidth - 64.0) / 64.0; + bw = pow(2.0, bw * pow(fabs(bw), 0.2) * 5.0); - return(bw); -}; + return bw; +} +/* + * Get the unison spread in cents for a voice + */ + +REALTYPE ADnoteParameters::getUnisonFrequencySpreadCents(int nvoice) { + REALTYPE unison_spread = VoicePar[nvoice].Unison_frequency_spread / 127.0; + unison_spread = pow(unison_spread * 2.0, 2.0) * 50.0; //cents + return unison_spread; +} /* * Kill the voice @@ -212,56 +232,101 @@ void ADnoteParameters::KillVoice(int nvoice) delete (VoicePar[nvoice].FMFreqEnvelope); delete (VoicePar[nvoice].FMAmpEnvelope); -}; +} ADnoteParameters::~ADnoteParameters() { - delete(GlobalPar.FreqEnvelope); - delete(GlobalPar.FreqLfo); - delete(GlobalPar.AmpEnvelope); - delete(GlobalPar.AmpLfo); - delete(GlobalPar.GlobalFilter); - delete(GlobalPar.FilterEnvelope); - delete(GlobalPar.FilterLfo); - delete(GlobalPar.Reson); + delete (GlobalPar.FreqEnvelope); + delete (GlobalPar.FreqLfo); + delete (GlobalPar.AmpEnvelope); + delete (GlobalPar.AmpLfo); + delete (GlobalPar.GlobalFilter); + delete (GlobalPar.FilterEnvelope); + delete (GlobalPar.FilterLfo); + delete (GlobalPar.Reson); - for (int nvoice=0;nvoice= NUM_VOICES) + return 0; + int unison = VoicePar[nvoice].Unison_size; + + while(1) { + if(ADnote_unison_sizes[index] >= unison) + return index; + ; + if(ADnote_unison_sizes[index] == 0) + return index - 1; + ; + index++; + } + return 0; +} + +void ADnoteParameters::set_unison_size_index(int nvoice, int index) { + int unison = 1; + for(int i = 0; i <= index; i++) { + unison = ADnote_unison_sizes[i]; + if(unison == 0) { + unison = ADnote_unison_sizes[i - 1]; + break; + } + } + + VoicePar[nvoice].Unison_size = unison; +} - -void ADnoteParameters::add2XMLsection(XMLwrapper *xml,int n) +void ADnoteParameters::add2XMLsection(XMLwrapper *xml, int n) { - int nvoice=n; - if (nvoice>=NUM_VOICES) return; + int nvoice = n; + if(nvoice >= NUM_VOICES) + return; - int oscilused=0,fmoscilused=0;//if the oscil or fmoscil are used by another voice + int oscilused = 0, fmoscilused = 0; //if the oscil or fmoscil are used by another voice - for (int i=0;iaddparbool("enabled",VoicePar[nvoice].Enabled); - if (((VoicePar[nvoice].Enabled==0)&&(oscilused==0)&&(fmoscilused==0))&&(xml->minimal)) return; + xml->addparbool("enabled", VoicePar[nvoice].Enabled); + if(((VoicePar[nvoice].Enabled == 0) && (oscilused == 0) + && (fmoscilused == 0)) && (xml->minimal)) + return; - xml->addpar("type",VoicePar[nvoice].Type); - xml->addpar("delay",VoicePar[nvoice].PDelay); - xml->addparbool("resonance",VoicePar[nvoice].Presonance); - xml->addpar("ext_oscil",VoicePar[nvoice].Pextoscil); - xml->addpar("ext_fm_oscil",VoicePar[nvoice].PextFMoscil); + xml->addpar("type", VoicePar[nvoice].Type); - xml->addpar("oscil_phase",VoicePar[nvoice].Poscilphase); - xml->addpar("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase); + xml->addpar("unison_size", VoicePar[nvoice].Unison_size); + xml->addpar("unison_frequency_spread", + VoicePar[nvoice].Unison_frequency_spread); + xml->addpar("unison_stereo_spread", VoicePar[nvoice].Unison_stereo_spread); + xml->addpar("unison_vibratto", VoicePar[nvoice].Unison_vibratto); + xml->addpar("unison_vibratto_speed", VoicePar[nvoice].Unison_vibratto_speed); + xml->addpar("unison_invert_phase", VoicePar[nvoice].Unison_invert_phase); - xml->addparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled); - xml->addparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass); + xml->addpar("delay", VoicePar[nvoice].PDelay); + xml->addparbool("resonance", VoicePar[nvoice].Presonance); - xml->addpar("fm_enabled",VoicePar[nvoice].PFMEnabled); + xml->addpar("ext_oscil", VoicePar[nvoice].Pextoscil); + xml->addpar("ext_fm_oscil", VoicePar[nvoice].PextFMoscil); + + xml->addpar("oscil_phase", VoicePar[nvoice].Poscilphase); + xml->addpar("oscil_fm_phase", VoicePar[nvoice].PFMoscilphase); + + xml->addparbool("filter_enabled", VoicePar[nvoice].PFilterEnabled); + xml->addparbool("filter_bypass", VoicePar[nvoice].Pfilterbypass); + + xml->addpar("fm_enabled", VoicePar[nvoice].PFMEnabled); xml->beginbranch("OSCIL"); VoicePar[nvoice].OscilSmp->add2XML(xml); @@ -269,94 +334,102 @@ void ADnoteParameters::add2XMLsection(XMLwrapper *xml,int n) xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addpar("panning",VoicePar[nvoice].PPanning); - xml->addpar("volume",VoicePar[nvoice].PVolume); - xml->addparbool("volume_minus",VoicePar[nvoice].PVolumeminus); - xml->addpar("velocity_sensing",VoicePar[nvoice].PAmpVelocityScaleFunction); + xml->addpar("panning", VoicePar[nvoice].PPanning); + xml->addpar("volume", VoicePar[nvoice].PVolume); + xml->addparbool("volume_minus", VoicePar[nvoice].PVolumeminus); + xml->addpar("velocity_sensing", VoicePar[nvoice].PAmpVelocityScaleFunction); - xml->addparbool("amp_envelope_enabled",VoicePar[nvoice].PAmpEnvelopeEnabled); - if ((VoicePar[nvoice].PAmpEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("amp_envelope_enabled", + VoicePar[nvoice].PAmpEnvelopeEnabled); + if((VoicePar[nvoice].PAmpEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("AMPLITUDE_ENVELOPE"); VoicePar[nvoice].AmpEnvelope->add2XML(xml); xml->endbranch(); - }; - xml->addparbool("amp_lfo_enabled",VoicePar[nvoice].PAmpLfoEnabled); - if ((VoicePar[nvoice].PAmpLfoEnabled!=0)||(!xml->minimal)) { + } + xml->addparbool("amp_lfo_enabled", VoicePar[nvoice].PAmpLfoEnabled); + if((VoicePar[nvoice].PAmpLfoEnabled != 0) || (!xml->minimal)) { xml->beginbranch("AMPLITUDE_LFO"); VoicePar[nvoice].AmpLfo->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addparbool("fixed_freq",VoicePar[nvoice].Pfixedfreq); - xml->addpar("fixed_freq_et",VoicePar[nvoice].PfixedfreqET); - xml->addpar("detune",VoicePar[nvoice].PDetune); - xml->addpar("coarse_detune",VoicePar[nvoice].PCoarseDetune); - xml->addpar("detune_type",VoicePar[nvoice].PDetuneType); + xml->addparbool("fixed_freq", VoicePar[nvoice].Pfixedfreq); + xml->addpar("fixed_freq_et", VoicePar[nvoice].PfixedfreqET); + xml->addpar("detune", VoicePar[nvoice].PDetune); + xml->addpar("coarse_detune", VoicePar[nvoice].PCoarseDetune); + xml->addpar("detune_type", VoicePar[nvoice].PDetuneType); - xml->addparbool("freq_envelope_enabled",VoicePar[nvoice].PFreqEnvelopeEnabled); - if ((VoicePar[nvoice].PFreqEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("freq_envelope_enabled", + VoicePar[nvoice].PFreqEnvelopeEnabled); + if((VoicePar[nvoice].PFreqEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_ENVELOPE"); VoicePar[nvoice].FreqEnvelope->add2XML(xml); xml->endbranch(); - }; - xml->addparbool("freq_lfo_enabled",VoicePar[nvoice].PFreqLfoEnabled); - if ((VoicePar[nvoice].PFreqLfoEnabled!=0)||(!xml->minimal)) { + } + xml->addparbool("freq_lfo_enabled", VoicePar[nvoice].PFreqLfoEnabled); + if((VoicePar[nvoice].PFreqLfoEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_LFO"); VoicePar[nvoice].FreqLfo->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); - if ((VoicePar[nvoice].PFilterEnabled!=0)||(!xml->minimal)) { + if((VoicePar[nvoice].PFilterEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER_PARAMETERS"); xml->beginbranch("FILTER"); VoicePar[nvoice].VoiceFilter->add2XML(xml); xml->endbranch(); - xml->addparbool("filter_envelope_enabled",VoicePar[nvoice].PFilterEnvelopeEnabled); - if ((VoicePar[nvoice].PFilterEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("filter_envelope_enabled", + VoicePar[nvoice].PFilterEnvelopeEnabled); + if((VoicePar[nvoice].PFilterEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER_ENVELOPE"); VoicePar[nvoice].FilterEnvelope->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("filter_lfo_enabled",VoicePar[nvoice].PFilterLfoEnabled); - if ((VoicePar[nvoice].PFilterLfoEnabled!=0)||(!xml->minimal)) { + xml->addparbool("filter_lfo_enabled", + VoicePar[nvoice].PFilterLfoEnabled); + if((VoicePar[nvoice].PFilterLfoEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER_LFO"); VoicePar[nvoice].FilterLfo->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); - }; + } - if ((VoicePar[nvoice].PFMEnabled!=0)||(fmoscilused!=0)||(!xml->minimal)) { + if((VoicePar[nvoice].PFMEnabled != 0) || (fmoscilused != 0) + || (!xml->minimal)) { xml->beginbranch("FM_PARAMETERS"); - xml->addpar("input_voice",VoicePar[nvoice].PFMVoice); + xml->addpar("input_voice", VoicePar[nvoice].PFMVoice); - xml->addpar("volume",VoicePar[nvoice].PFMVolume); - xml->addpar("volume_damp",VoicePar[nvoice].PFMVolumeDamp); - xml->addpar("velocity_sensing",VoicePar[nvoice].PFMVelocityScaleFunction); + xml->addpar("volume", VoicePar[nvoice].PFMVolume); + xml->addpar("volume_damp", VoicePar[nvoice].PFMVolumeDamp); + xml->addpar("velocity_sensing", + VoicePar[nvoice].PFMVelocityScaleFunction); - xml->addparbool("amp_envelope_enabled",VoicePar[nvoice].PFMAmpEnvelopeEnabled); - if ((VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("amp_envelope_enabled", + VoicePar[nvoice].PFMAmpEnvelopeEnabled); + if((VoicePar[nvoice].PFMAmpEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("AMPLITUDE_ENVELOPE"); VoicePar[nvoice].FMAmpEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->beginbranch("MODULATOR"); - xml->addpar("detune",VoicePar[nvoice].PFMDetune); - xml->addpar("coarse_detune",VoicePar[nvoice].PFMCoarseDetune); - xml->addpar("detune_type",VoicePar[nvoice].PFMDetuneType); + xml->addpar("detune", VoicePar[nvoice].PFMDetune); + xml->addpar("coarse_detune", VoicePar[nvoice].PFMCoarseDetune); + xml->addpar("detune_type", VoicePar[nvoice].PFMDetuneType); - xml->addparbool("freq_envelope_enabled",VoicePar[nvoice].PFMFreqEnvelopeEnabled); - if ((VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("freq_envelope_enabled", + VoicePar[nvoice].PFMFreqEnvelopeEnabled); + if((VoicePar[nvoice].PFMFreqEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_ENVELOPE"); VoicePar[nvoice].FMFreqEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->beginbranch("OSCIL"); VoicePar[nvoice].FMSmp->add2XML(xml); @@ -364,23 +437,23 @@ void ADnoteParameters::add2XMLsection(XMLwrapper *xml,int n) xml->endbranch(); xml->endbranch(); - }; -}; + } +} void ADnoteParameters::add2XML(XMLwrapper *xml) { - xml->addparbool("stereo",GlobalPar.PStereo); + xml->addparbool("stereo", GlobalPar.PStereo); xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addpar("volume",GlobalPar.PVolume); - xml->addpar("panning",GlobalPar.PPanning); - xml->addpar("velocity_sensing",GlobalPar.PAmpVelocityScaleFunction); - xml->addpar("punch_strength",GlobalPar.PPunchStrength); - xml->addpar("punch_time",GlobalPar.PPunchTime); - xml->addpar("punch_stretch",GlobalPar.PPunchStretch); - xml->addpar("punch_velocity_sensing",GlobalPar.PPunchVelocitySensing); - xml->addpar("harmonic_randomness_grouping",GlobalPar.Hrandgrouping); + xml->addpar("volume", GlobalPar.PVolume); + xml->addpar("panning", GlobalPar.PPanning); + xml->addpar("velocity_sensing", GlobalPar.PAmpVelocityScaleFunction); + xml->addpar("punch_strength", GlobalPar.PPunchStrength); + xml->addpar("punch_time", GlobalPar.PPunchTime); + xml->addpar("punch_stretch", GlobalPar.PPunchStretch); + xml->addpar("punch_velocity_sensing", GlobalPar.PPunchVelocitySensing); + xml->addpar("harmonic_randomness_grouping", GlobalPar.Hrandgrouping); xml->beginbranch("AMPLITUDE_ENVELOPE"); GlobalPar.AmpEnvelope->add2XML(xml); @@ -392,12 +465,12 @@ void ADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addpar("detune",GlobalPar.PDetune); + xml->addpar("detune", GlobalPar.PDetune); - xml->addpar("coarse_detune",GlobalPar.PCoarseDetune); - xml->addpar("detune_type",GlobalPar.PDetuneType); + xml->addpar("coarse_detune", GlobalPar.PCoarseDetune); + xml->addpar("detune_type", GlobalPar.PDetuneType); - xml->addpar("bandwidth",GlobalPar.PBandwidth); + xml->addpar("bandwidth", GlobalPar.PBandwidth); xml->beginbranch("FREQUENCY_ENVELOPE"); GlobalPar.FreqEnvelope->add2XML(xml); @@ -410,8 +483,8 @@ void ADnoteParameters::add2XML(XMLwrapper *xml) xml->beginbranch("FILTER_PARAMETERS"); - xml->addpar("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale); - xml->addpar("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction); + xml->addpar("velocity_sensing_amplitude", GlobalPar.PFilterVelocityScale); + xml->addpar("velocity_sensing", GlobalPar.PFilterVelocityScaleFunction); xml->beginbranch("FILTER"); GlobalPar.GlobalFilter->add2XML(xml); @@ -430,48 +503,66 @@ void ADnoteParameters::add2XML(XMLwrapper *xml) GlobalPar.Reson->add2XML(xml); xml->endbranch(); - for (int nvoice=0;nvoicebeginbranch("VOICE",nvoice); - add2XMLsection(xml,nvoice); + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + xml->beginbranch("VOICE", nvoice); + add2XMLsection(xml, nvoice); xml->endbranch(); - }; -}; + } +} void ADnoteParameters::getfromXML(XMLwrapper *xml) { - GlobalPar.PStereo=xml->getparbool("stereo",GlobalPar.PStereo); + GlobalPar.PStereo = xml->getparbool("stereo", GlobalPar.PStereo); - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - GlobalPar.PVolume=xml->getpar127("volume",GlobalPar.PVolume); - GlobalPar.PPanning=xml->getpar127("panning",GlobalPar.PPanning); - GlobalPar.PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",GlobalPar.PAmpVelocityScaleFunction); + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + GlobalPar.PVolume = xml->getpar127("volume", GlobalPar.PVolume); + GlobalPar.PPanning = xml->getpar127("panning", GlobalPar.PPanning); + GlobalPar.PAmpVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + GlobalPar. + PAmpVelocityScaleFunction); - GlobalPar.PPunchStrength=xml->getpar127("punch_strength",GlobalPar.PPunchStrength); - GlobalPar.PPunchTime=xml->getpar127("punch_time",GlobalPar.PPunchTime); - GlobalPar.PPunchStretch=xml->getpar127("punch_stretch",GlobalPar.PPunchStretch); - GlobalPar.PPunchVelocitySensing=xml->getpar127("punch_velocity_sensing",GlobalPar.PPunchVelocitySensing); - GlobalPar.Hrandgrouping=xml->getpar127("harmonic_randomness_grouping",GlobalPar.Hrandgrouping); + GlobalPar.PPunchStrength = xml->getpar127("punch_strength", + GlobalPar.PPunchStrength); + GlobalPar.PPunchTime = xml->getpar127("punch_time", + GlobalPar.PPunchTime); + GlobalPar.PPunchStretch = xml->getpar127("punch_stretch", + GlobalPar.PPunchStretch); + GlobalPar.PPunchVelocitySensing = xml->getpar127( + "punch_velocity_sensing", + GlobalPar.PPunchVelocitySensing); + GlobalPar.Hrandgrouping = xml->getpar127( + "harmonic_randomness_grouping", + GlobalPar.Hrandgrouping); - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { GlobalPar.AmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("AMPLITUDE_LFO")) { + if(xml->enterbranch("AMPLITUDE_LFO")) { GlobalPar.AmpLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - GlobalPar.PDetune=xml->getpar("detune",GlobalPar.PDetune,0,16383); - GlobalPar.PCoarseDetune=xml->getpar("coarse_detune",GlobalPar.PCoarseDetune,0,16383); - GlobalPar.PDetuneType=xml->getpar127("detune_type",GlobalPar.PDetuneType); + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + GlobalPar.PDetune = xml->getpar("detune", + GlobalPar.PDetune, + 0, + 16383); + GlobalPar.PCoarseDetune = xml->getpar("coarse_detune", + GlobalPar.PCoarseDetune, + 0, + 16383); + GlobalPar.PDetuneType = xml->getpar127("detune_type", + GlobalPar.PDetuneType); - GlobalPar.PBandwidth=xml->getpar127("bandwidth",GlobalPar.PBandwidth); + GlobalPar.PBandwidth = xml->getpar127("bandwidth", + GlobalPar.PBandwidth); xml->enterbranch("FREQUENCY_ENVELOPE"); GlobalPar.FreqEnvelope->getfromXML(xml); @@ -482,12 +573,16 @@ void ADnoteParameters::getfromXML(XMLwrapper *xml) xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - GlobalPar.PFilterVelocityScale=xml->getpar127("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale); - GlobalPar.PFilterVelocityScaleFunction=xml->getpar127("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction); + if(xml->enterbranch("FILTER_PARAMETERS")) { + GlobalPar.PFilterVelocityScale = xml->getpar127( + "velocity_sensing_amplitude", + GlobalPar.PFilterVelocityScale); + GlobalPar.PFilterVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + GlobalPar.PFilterVelocityScaleFunction); xml->enterbranch("FILTER"); GlobalPar.GlobalFilter->getfromXML(xml); @@ -501,148 +596,244 @@ void ADnoteParameters::getfromXML(XMLwrapper *xml) GlobalPar.FilterLfo->getfromXML(xml); xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("RESONANCE")) { + if(xml->enterbranch("RESONANCE")) { GlobalPar.Reson->getfromXML(xml); xml->exitbranch(); - }; + } - for (int nvoice=0;nvoiceenterbranch("VOICE",nvoice)==0) continue; - getfromXMLsection(xml,nvoice); + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + VoicePar[nvoice].Enabled = 0; + if(xml->enterbranch("VOICE", nvoice) == 0) + continue; + getfromXMLsection(xml, nvoice); xml->exitbranch(); - }; + } +} - -}; - -void ADnoteParameters::getfromXMLsection(XMLwrapper *xml,int n) +void ADnoteParameters::getfromXMLsection(XMLwrapper *xml, int n) { - int nvoice=n; - if (nvoice>=NUM_VOICES) return; + int nvoice = n; + if(nvoice >= NUM_VOICES) + return; - VoicePar[nvoice].Enabled=xml->getparbool("enabled",0); + VoicePar[nvoice].Enabled = xml->getparbool("enabled", 0); - VoicePar[nvoice].Type=xml->getpar127("type",VoicePar[nvoice].Type); - VoicePar[nvoice].PDelay=xml->getpar127("delay",VoicePar[nvoice].PDelay); - VoicePar[nvoice].Presonance=xml->getparbool("resonance",VoicePar[nvoice].Presonance); + VoicePar[nvoice].Unison_size = + xml->getpar127("unison_size", VoicePar[nvoice].Unison_size); + VoicePar[nvoice].Unison_frequency_spread = xml->getpar127( + "unison_frequency_spread", + VoicePar[nvoice].Unison_frequency_spread); + VoicePar[nvoice].Unison_stereo_spread = xml->getpar127( + "unison_stereo_spread", + VoicePar[nvoice].Unison_stereo_spread); + VoicePar[nvoice].Unison_vibratto = xml->getpar127( + "unison_vibratto", + VoicePar[nvoice]. + Unison_vibratto); + VoicePar[nvoice].Unison_vibratto_speed = xml->getpar127( + "unison_vibratto_speed", + VoicePar[nvoice].Unison_vibratto_speed); + VoicePar[nvoice].Unison_invert_phase = xml->getpar127( + "unison_invert_phase", + VoicePar[nvoice].Unison_invert_phase); - VoicePar[nvoice].Pextoscil=xml->getpar("ext_oscil",-1,-1,nvoice-1); - VoicePar[nvoice].PextFMoscil=xml->getpar("ext_fm_oscil",-1,-1,nvoice-1); + VoicePar[nvoice].Type = xml->getpar127("type", + VoicePar[nvoice].Type); + VoicePar[nvoice].PDelay = xml->getpar127("delay", + VoicePar[nvoice].PDelay); + VoicePar[nvoice].Presonance = + xml->getparbool("resonance", VoicePar[nvoice].Presonance); - VoicePar[nvoice].Poscilphase=xml->getpar127("oscil_phase",VoicePar[nvoice].Poscilphase); - VoicePar[nvoice].PFMoscilphase=xml->getpar127("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase); + VoicePar[nvoice].Pextoscil = xml->getpar("ext_oscil", + -1, + -1, + nvoice - 1); + VoicePar[nvoice].PextFMoscil = xml->getpar("ext_fm_oscil", + -1, + -1, + nvoice - 1); - VoicePar[nvoice].PFilterEnabled=xml->getparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled); - VoicePar[nvoice].Pfilterbypass=xml->getparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass); + VoicePar[nvoice].Poscilphase = + xml->getpar127("oscil_phase", VoicePar[nvoice].Poscilphase); + VoicePar[nvoice].PFMoscilphase = xml->getpar127( + "oscil_fm_phase", + VoicePar[nvoice]. + PFMoscilphase); - VoicePar[nvoice].PFMEnabled=xml->getpar127("fm_enabled",VoicePar[nvoice].PFMEnabled); + VoicePar[nvoice].PFilterEnabled = xml->getparbool( + "filter_enabled", + VoicePar[nvoice]. + PFilterEnabled); + VoicePar[nvoice].Pfilterbypass = xml->getparbool( + "filter_bypass", + VoicePar[nvoice]. + Pfilterbypass); - if (xml->enterbranch("OSCIL")) { + VoicePar[nvoice].PFMEnabled = + xml->getpar127("fm_enabled", VoicePar[nvoice].PFMEnabled); + + if(xml->enterbranch("OSCIL")) { VoicePar[nvoice].OscilSmp->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - VoicePar[nvoice].PPanning=xml->getpar127("panning",VoicePar[nvoice].PPanning); - VoicePar[nvoice].PVolume=xml->getpar127("volume",VoicePar[nvoice].PVolume); - VoicePar[nvoice].PVolumeminus=xml->getparbool("volume_minus",VoicePar[nvoice].PVolumeminus); - VoicePar[nvoice].PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",VoicePar[nvoice].PAmpVelocityScaleFunction); + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + VoicePar[nvoice].PPanning = + xml->getpar127("panning", VoicePar[nvoice].PPanning); + VoicePar[nvoice].PVolume = + xml->getpar127("volume", VoicePar[nvoice].PVolume); + VoicePar[nvoice].PVolumeminus = xml->getparbool( + "volume_minus", + VoicePar[nvoice]. + PVolumeminus); + VoicePar[nvoice].PAmpVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + VoicePar[nvoice].PAmpVelocityScaleFunction); - VoicePar[nvoice].PAmpEnvelopeEnabled=xml->getparbool("amp_envelope_enabled",VoicePar[nvoice].PAmpEnvelopeEnabled); - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + VoicePar[nvoice].PAmpEnvelopeEnabled = xml->getparbool( + "amp_envelope_enabled", + VoicePar[nvoice].PAmpEnvelopeEnabled); + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { VoicePar[nvoice].AmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PAmpLfoEnabled=xml->getparbool("amp_lfo_enabled",VoicePar[nvoice].PAmpLfoEnabled); - if (xml->enterbranch("AMPLITUDE_LFO")) { + VoicePar[nvoice].PAmpLfoEnabled = xml->getparbool( + "amp_lfo_enabled", + VoicePar[nvoice]. + PAmpLfoEnabled); + if(xml->enterbranch("AMPLITUDE_LFO")) { VoicePar[nvoice].AmpLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - VoicePar[nvoice].Pfixedfreq=xml->getparbool("fixed_freq",VoicePar[nvoice].Pfixedfreq); - VoicePar[nvoice].PfixedfreqET=xml->getpar127("fixed_freq_et",VoicePar[nvoice].PfixedfreqET); + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + VoicePar[nvoice].Pfixedfreq = + xml->getparbool("fixed_freq", VoicePar[nvoice].Pfixedfreq); + VoicePar[nvoice].PfixedfreqET = xml->getpar127( + "fixed_freq_et", + VoicePar[nvoice]. + PfixedfreqET); - VoicePar[nvoice].PDetune=xml->getpar("detune",VoicePar[nvoice].PDetune,0,16383); + VoicePar[nvoice].PDetune = xml->getpar("detune", + VoicePar[nvoice].PDetune, + 0, + 16383); - VoicePar[nvoice].PCoarseDetune=xml->getpar("coarse_detune",VoicePar[nvoice].PCoarseDetune,0,16383); - VoicePar[nvoice].PDetuneType=xml->getpar127("detune_type",VoicePar[nvoice].PDetuneType); + VoicePar[nvoice].PCoarseDetune = + xml->getpar("coarse_detune", + VoicePar[nvoice].PCoarseDetune, + 0, + 16383); + VoicePar[nvoice].PDetuneType = xml->getpar127( + "detune_type", + VoicePar[nvoice]. + PDetuneType); - VoicePar[nvoice].PFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",VoicePar[nvoice].PFreqEnvelopeEnabled); - if (xml->enterbranch("FREQUENCY_ENVELOPE")) { + VoicePar[nvoice].PFreqEnvelopeEnabled = xml->getparbool( + "freq_envelope_enabled", + VoicePar[nvoice].PFreqEnvelopeEnabled); + if(xml->enterbranch("FREQUENCY_ENVELOPE")) { VoicePar[nvoice].FreqEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PFreqLfoEnabled=xml->getparbool("freq_lfo_enabled",VoicePar[nvoice].PFreqLfoEnabled); - if (xml->enterbranch("FREQUENCY_LFO")) { + VoicePar[nvoice].PFreqLfoEnabled = xml->getparbool( + "freq_lfo_enabled", + VoicePar[nvoice]. + PFreqLfoEnabled); + if(xml->enterbranch("FREQUENCY_LFO")) { VoicePar[nvoice].FreqLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - if (xml->enterbranch("FILTER")) { + if(xml->enterbranch("FILTER_PARAMETERS")) { + if(xml->enterbranch("FILTER")) { VoicePar[nvoice].VoiceFilter->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PFilterEnvelopeEnabled=xml->getparbool("filter_envelope_enabled",VoicePar[nvoice].PFilterEnvelopeEnabled); - if (xml->enterbranch("FILTER_ENVELOPE")) { + VoicePar[nvoice].PFilterEnvelopeEnabled = xml->getparbool( + "filter_envelope_enabled", + VoicePar[nvoice].PFilterEnvelopeEnabled); + if(xml->enterbranch("FILTER_ENVELOPE")) { VoicePar[nvoice].FilterEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PFilterLfoEnabled=xml->getparbool("filter_lfo_enabled",VoicePar[nvoice].PFilterLfoEnabled); - if (xml->enterbranch("FILTER_LFO")) { + VoicePar[nvoice].PFilterLfoEnabled = xml->getparbool( + "filter_lfo_enabled", + VoicePar[nvoice].PFilterLfoEnabled); + if(xml->enterbranch("FILTER_LFO")) { VoicePar[nvoice].FilterLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FM_PARAMETERS")) { - VoicePar[nvoice].PFMVoice=xml->getpar("input_voice",VoicePar[nvoice].PFMVoice,-1,nvoice-1); + if(xml->enterbranch("FM_PARAMETERS")) { + VoicePar[nvoice].PFMVoice = + xml->getpar("input_voice", + VoicePar[nvoice].PFMVoice, + -1, + nvoice - 1); - VoicePar[nvoice].PFMVolume=xml->getpar127("volume",VoicePar[nvoice].PFMVolume); - VoicePar[nvoice].PFMVolumeDamp=xml->getpar127("volume_damp",VoicePar[nvoice].PFMVolumeDamp); - VoicePar[nvoice].PFMVelocityScaleFunction=xml->getpar127("velocity_sensing",VoicePar[nvoice].PFMVelocityScaleFunction); + VoicePar[nvoice].PFMVolume = + xml->getpar127("volume", VoicePar[nvoice].PFMVolume); + VoicePar[nvoice].PFMVolumeDamp = xml->getpar127( + "volume_damp", + VoicePar[nvoice]. + PFMVolumeDamp); + VoicePar[nvoice].PFMVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + VoicePar[nvoice].PFMVelocityScaleFunction); - VoicePar[nvoice].PFMAmpEnvelopeEnabled=xml->getparbool("amp_envelope_enabled",VoicePar[nvoice].PFMAmpEnvelopeEnabled); - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + VoicePar[nvoice].PFMAmpEnvelopeEnabled = xml->getparbool( + "amp_envelope_enabled", + VoicePar[nvoice].PFMAmpEnvelopeEnabled); + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { VoicePar[nvoice].FMAmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("MODULATOR")) { - VoicePar[nvoice].PFMDetune=xml->getpar("detune",VoicePar[nvoice].PFMDetune,0,16383); - VoicePar[nvoice].PFMCoarseDetune=xml->getpar("coarse_detune",VoicePar[nvoice].PFMCoarseDetune,0,16383); - VoicePar[nvoice].PFMDetuneType=xml->getpar127("detune_type",VoicePar[nvoice].PFMDetuneType); + if(xml->enterbranch("MODULATOR")) { + VoicePar[nvoice].PFMDetune = + xml->getpar("detune", VoicePar[nvoice].PFMDetune, 0, 16383); + VoicePar[nvoice].PFMCoarseDetune = xml->getpar( + "coarse_detune", + VoicePar[nvoice]. + PFMCoarseDetune, + 0, + 16383); + VoicePar[nvoice].PFMDetuneType = xml->getpar127( + "detune_type", + VoicePar[nvoice]. + PFMDetuneType); - VoicePar[nvoice].PFMFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",VoicePar[nvoice].PFMFreqEnvelopeEnabled); - if (xml->enterbranch("FREQUENCY_ENVELOPE")) { + VoicePar[nvoice].PFMFreqEnvelopeEnabled = xml->getparbool( + "freq_envelope_enabled", + VoicePar[nvoice].PFMFreqEnvelopeEnabled); + if(xml->enterbranch("FREQUENCY_ENVELOPE")) { VoicePar[nvoice].FMFreqEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("OSCIL")) { + if(xml->enterbranch("OSCIL")) { VoicePar[nvoice].FMSmp->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; -}; - + } +} diff --git a/plugins/zynaddsubfx/src/Params/ADnoteParameters.h b/plugins/zynaddsubfx/src/Params/ADnoteParameters.h index 8b35f92c4..ee5a632bd 100644 --- a/plugins/zynaddsubfx/src/Params/ADnoteParameters.h +++ b/plugins/zynaddsubfx/src/Params/ADnoteParameters.h @@ -35,14 +35,16 @@ #include "../DSP/FFTwrapper.h" #include "Presets.h" -enum FMTYPE {NONE,MORPH,RING_MOD,PHASE_MOD,FREQ_MOD,PITCH_MOD}; +enum FMTYPE { + NONE, MORPH, RING_MOD, PHASE_MOD, FREQ_MOD, PITCH_MOD +}; +extern int ADnote_unison_sizes[]; /*****************************************************************/ /* GLOBAL PARAMETERS */ /*****************************************************************/ struct ADnoteGlobalParam { - /* The instrument type - MONO/STEREO If the mode is MONO, the panning of voices are not used Stereo=1, Mono=0. */ @@ -53,35 +55,36 @@ struct ADnoteGlobalParam { /****************************************** * FREQUENCY GLOBAL PARAMETERS * ******************************************/ - unsigned short int PDetune;//fine detune - unsigned short int PCoarseDetune;//coarse detune+octave - unsigned char PDetuneType;//detune type + unsigned short int PDetune; //fine detune + unsigned short int PCoarseDetune; //coarse detune+octave + unsigned char PDetuneType; //detune type - unsigned char PBandwidth;//how much the relative fine detunes of the voices are changed + unsigned char PBandwidth; //how much the relative fine detunes of the voices are changed - EnvelopeParams *FreqEnvelope; //Frequency Envelope + EnvelopeParams *FreqEnvelope; //Frequency Envelope - LFOParams *FreqLfo;//Frequency LFO + LFOParams *FreqLfo; //Frequency LFO /******************************************** * AMPLITUDE GLOBAL PARAMETERS * ********************************************/ /* Panning - 0 - random - 1 - left - 64 - center - 127 - right */ - unsigned char PPanning; + 1 - left + 64 - center + 127 - right */ + unsigned char PPanning; - unsigned char PVolume; + unsigned char PVolume; - unsigned char PAmpVelocityScaleFunction; + unsigned char PAmpVelocityScaleFunction; EnvelopeParams *AmpEnvelope; - LFOParams *AmpLfo; + LFOParams *AmpLfo; - unsigned char PPunchStrength,PPunchTime,PPunchStretch,PPunchVelocitySensing; + unsigned char PPunchStrength, PPunchTime, PPunchStretch, + PPunchVelocitySensing; /****************************************** * FILTER GLOBAL PARAMETERS * @@ -92,11 +95,11 @@ struct ADnoteGlobalParam { unsigned char PFilterVelocityScale; // filter velocity sensing - unsigned char PFilterVelocityScaleFunction; + unsigned char PFilterVelocityScaleFunction; EnvelopeParams *FilterEnvelope; - LFOParams *FilterLfo; + LFOParams *FilterLfo; // RESONANCE Resonance *Reson; @@ -111,10 +114,27 @@ struct ADnoteGlobalParam { /* VOICE PARAMETERS */ /***********************************************************/ struct ADnoteVoiceParam { - /** If the voice is enabled */ unsigned char Enabled; + /** How many subvoices are used in this voice */ + unsigned char Unison_size; + + /** How subvoices are spread */ + unsigned char Unison_frequency_spread; + + /** Stereo spread of the subvoices*/ + unsigned char Unison_stereo_spread; + + /** Vibratto of the subvoices (which makes the unison more "natural")*/ + unsigned char Unison_vibratto; + + /** Medium speed of the vibratto of the subvoices*/ + unsigned char Unison_vibratto_speed; + + /** Unison invert phase */ + unsigned char Unison_invert_phase; //0=none,1=random,2=50%,3=33%,4=25% + /** Type of the voice (0=Sound,1=Noise)*/ unsigned char Type; @@ -125,11 +145,11 @@ struct ADnoteVoiceParam { unsigned char Presonance; // What external oscil should I use, -1 for internal OscilSmp&FMSmp - short int Pextoscil,PextFMoscil; + short int Pextoscil, PextFMoscil; // it is not allowed that the externoscil,externFMoscil => current voice // oscillator phases - unsigned char Poscilphase,PFMoscilphase; + unsigned char Poscilphase, PFMoscilphase; // filter bypass unsigned char Pfilterbypass; @@ -159,12 +179,12 @@ struct ADnoteVoiceParam { unsigned char PDetuneType; /* Frequency Envelope */ - unsigned char PFreqEnvelopeEnabled; + unsigned char PFreqEnvelopeEnabled; EnvelopeParams *FreqEnvelope; /* Frequency LFO */ unsigned char PFreqLfoEnabled; - LFOParams *FreqLfo; + LFOParams *FreqLfo; /*************************** @@ -172,9 +192,9 @@ struct ADnoteVoiceParam { ***************************/ /* Panning 0 - random - 1 - left - 64 - center - 127 - right + 1 - left + 64 - center + 127 - right The Panning is ignored if the instrument is mono */ unsigned char PPanning; @@ -188,12 +208,12 @@ struct ADnoteVoiceParam { unsigned char PAmpVelocityScaleFunction; /* Amplitude Envelope */ - unsigned char PAmpEnvelopeEnabled; + unsigned char PAmpEnvelopeEnabled; EnvelopeParams *AmpEnvelope; /* Amplitude LFO */ unsigned char PAmpLfoEnabled; - LFOParams *AmpLfo; + LFOParams *AmpLfo; @@ -206,12 +226,12 @@ struct ADnoteVoiceParam { FilterParams *VoiceFilter; /* Filter Envelope */ - unsigned char PFilterEnvelopeEnabled; + unsigned char PFilterEnvelopeEnabled; EnvelopeParams *FilterEnvelope; /* LFO Envelope */ unsigned char PFilterLfoEnabled; - LFOParams *FilterLfo; + LFOParams *FilterLfo; /**************************** * MODULLATOR PARAMETERS * @@ -247,37 +267,41 @@ struct ADnoteVoiceParam { unsigned char PFMDetuneType; /* Frequency Envelope of the Modullator */ - unsigned char PFMFreqEnvelopeEnabled; + unsigned char PFMFreqEnvelopeEnabled; EnvelopeParams *FMFreqEnvelope; /* Frequency Envelope of the Modullator */ - unsigned char PFMAmpEnvelopeEnabled; + unsigned char PFMAmpEnvelopeEnabled; EnvelopeParams *FMAmpEnvelope; }; class ADnoteParameters:public Presets { -public: - ADnoteParameters(FFTwrapper *fft_); - ~ADnoteParameters(); + public: + ADnoteParameters(FFTwrapper *fft_); + ~ADnoteParameters(); - ADnoteGlobalParam GlobalPar; - ADnoteVoiceParam VoicePar[NUM_VOICES]; + ADnoteGlobalParam GlobalPar; + ADnoteVoiceParam VoicePar[NUM_VOICES]; - void defaults(); - void add2XML(XMLwrapper *xml); - void getfromXML(XMLwrapper *xml); + void defaults(); + void add2XML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); - REALTYPE getBandwidthDetuneMultiplier(); -private: - void defaults(int n);//n is the nvoice + REALTYPE getBandwidthDetuneMultiplier(); + REALTYPE getUnisonFrequencySpreadCents(int nvoice); + int get_unison_size_index(int nvoice); + void set_unison_size_index(int nvoice, int index); + private: + void defaults(int n); //n is the nvoice - void EnableVoice(int nvoice); - void KillVoice(int nvoice); - FFTwrapper *fft; + void EnableVoice(int nvoice); + void KillVoice(int nvoice); + FFTwrapper *fft; - void add2XMLsection(XMLwrapper *xml,int n); - void getfromXMLsection(XMLwrapper *xml,int n); + void add2XMLsection(XMLwrapper *xml, int n); + void getfromXMLsection(XMLwrapper *xml, int n); }; #endif + diff --git a/plugins/zynaddsubfx/src/Params/Controller.cpp b/plugins/zynaddsubfx/src/Params/Controller.cpp index 2388dd4b6..61a0793e0 100644 --- a/plugins/zynaddsubfx/src/Params/Controller.cpp +++ b/plugins/zynaddsubfx/src/Params/Controller.cpp @@ -28,50 +28,48 @@ Controller::Controller() { defaults(); resetall(); -}; +} Controller::~Controller() -{ -}; +{} void Controller::defaults() { - setpitchwheelbendrange(200);//2 halftones - expression.receive=1; - panning.depth=64; - filtercutoff.depth=64; - filterq.depth=64; - bandwidth.depth=64; - bandwidth.exponential=0; - modwheel.depth=80; - modwheel.exponential=0; - fmamp.receive=1; - volume.receive=1; - sustain.receive=1; - NRPN.receive=1; + setpitchwheelbendrange(200); //2 halftones + expression.receive = 1; + panning.depth = 64; + filtercutoff.depth = 64; + filterq.depth = 64; + bandwidth.depth = 64; + bandwidth.exponential = 0; + modwheel.depth = 80; + modwheel.exponential = 0; + fmamp.receive = 1; + volume.receive = 1; + sustain.receive = 1; + NRPN.receive = 1; - portamento.portamento=0; - portamento.used=0; - portamento.proportional=0; - portamento.propRate=80; - portamento.propDepth=90; - portamento.receive=1; - portamento.time=64; - portamento.updowntimestretch=64; - portamento.pitchthresh=3; - portamento.pitchthreshtype=1; - portamento.noteusing=-1; - resonancecenter.depth=64; - resonancebandwidth.depth=64; + portamento.portamento = 0; + portamento.used = 0; + portamento.proportional = 0; + portamento.propRate = 80; + portamento.propDepth = 90; + portamento.receive = 1; + portamento.time = 64; + portamento.updowntimestretch = 64; + portamento.pitchthresh = 3; + portamento.pitchthreshtype = 1; + portamento.noteusing = -1; + resonancecenter.depth = 64; + resonancebandwidth.depth = 64; - initportamento(440.0,440.0,false); // Now has a third argument + initportamento(440.0, 440.0, false); // Now has a third argument setportamento(0); - -}; +} void Controller::resetall() { - setpitchwheel(0);//center + setpitchwheel(0); //center setexpression(127); setpanning(64); setfiltercutoff(64); @@ -85,276 +83,333 @@ void Controller::resetall() setresonancebw(64); //reset the NRPN - NRPN.parhi=-1; - NRPN.parlo=-1; - NRPN.valhi=-1; - NRPN.vallo=-1; -}; + NRPN.parhi = -1; + NRPN.parlo = -1; + NRPN.valhi = -1; + NRPN.vallo = -1; +} void Controller::setpitchwheel(int value) { - pitchwheel.data=value; - REALTYPE cents=value/8192.0; - cents*=pitchwheel.bendrange; - pitchwheel.relfreq=pow(2,cents/1200.0); + pitchwheel.data = value; + REALTYPE cents = value / 8192.0; + cents *= pitchwheel.bendrange; + pitchwheel.relfreq = pow(2, cents / 1200.0); //fprintf(stderr,"%ld %ld -> %.3f\n",pitchwheel.bendrange,pitchwheel.data,pitchwheel.relfreq);fflush(stderr); -}; +} void Controller::setpitchwheelbendrange(unsigned short int value) { - pitchwheel.bendrange=value; -}; + pitchwheel.bendrange = value; +} void Controller::setexpression(int value) { - expression.data=value; - if (expression.receive!=0) expression.relvolume=value/127.0; - else expression.relvolume=1.0; -}; + expression.data = value; + if(expression.receive != 0) + expression.relvolume = value / 127.0; + else + expression.relvolume = 1.0; +} void Controller::setpanning(int value) { - panning.data=value; - panning.pan=(value/128.0-0.5)*(panning.depth/64.0); -}; + panning.data = value; + panning.pan = (value / 128.0 - 0.5) * (panning.depth / 64.0); +} void Controller::setfiltercutoff(int value) { - filtercutoff.data=value; - filtercutoff.relfreq=(value-64.0)*filtercutoff.depth/4096.0*3.321928;//3.3219..=ln2(10) -}; + filtercutoff.data = value; + filtercutoff.relfreq = + (value - 64.0) * filtercutoff.depth / 4096.0 * 3.321928; //3.3219..=ln2(10) +} void Controller::setfilterq(int value) { - filterq.data=value; - filterq.relq=pow(30.0,(value-64.0)/64.0*(filterq.depth/64.0)); -}; + filterq.data = value; + filterq.relq = pow(30.0, (value - 64.0) / 64.0 * (filterq.depth / 64.0)); +} void Controller::setbandwidth(int value) { - bandwidth.data=value; - if (bandwidth.exponential==0) { - REALTYPE tmp=pow(25.0,pow(bandwidth.depth/127.0,1.5))-1.0; - if ((value<64)&&(bandwidth.depth>=64)) tmp=1.0; - bandwidth.relbw=(value/64.0-1.0)*tmp+1.0; - if (bandwidth.relbw<0.01) bandwidth.relbw=0.01; - } else { - bandwidth.relbw=pow(25.0,(value-64.0)/64.0*(bandwidth.depth/64.0)); - }; -}; + bandwidth.data = value; + if(bandwidth.exponential == 0) { + REALTYPE tmp = pow(25.0, pow(bandwidth.depth / 127.0, 1.5)) - 1.0; + if((value < 64) && (bandwidth.depth >= 64)) + tmp = 1.0; + bandwidth.relbw = (value / 64.0 - 1.0) * tmp + 1.0; + if(bandwidth.relbw < 0.01) + bandwidth.relbw = 0.01; + } + else + bandwidth.relbw = + pow(25.0, (value - 64.0) / 64.0 * (bandwidth.depth / 64.0)); + ; +} void Controller::setmodwheel(int value) { - modwheel.data=value; - if (modwheel.exponential==0) { - REALTYPE tmp=pow(25.0,pow(modwheel.depth/127.0,1.5)*2.0)/25.0; - if ((value<64)&&(modwheel.depth>=64)) tmp=1.0; - modwheel.relmod=(value/64.0-1.0)*tmp+1.0; - if (modwheel.relmod<0.0) modwheel.relmod=0.0; - } else modwheel.relmod=pow(25.0,(value-64.0)/64.0*(modwheel.depth/80.0)); -}; + modwheel.data = value; + if(modwheel.exponential == 0) { + REALTYPE tmp = pow(25.0, pow(modwheel.depth / 127.0, 1.5) * 2.0) / 25.0; + if((value < 64) && (modwheel.depth >= 64)) + tmp = 1.0; + modwheel.relmod = (value / 64.0 - 1.0) * tmp + 1.0; + if(modwheel.relmod < 0.0) + modwheel.relmod = 0.0; + } + else + modwheel.relmod = + pow(25.0, (value - 64.0) / 64.0 * (modwheel.depth / 80.0)); +} void Controller::setfmamp(int value) { - fmamp.data=value; - fmamp.relamp=value/127.0; - if (fmamp.receive!=0) fmamp.relamp=value/127.0; - else fmamp.relamp=1.0; -}; + fmamp.data = value; + fmamp.relamp = value / 127.0; + if(fmamp.receive != 0) + fmamp.relamp = value / 127.0; + else + fmamp.relamp = 1.0; +} void Controller::setvolume(int value) { - volume.data=value; - if (volume.receive!=0) volume.volume=pow(0.1,(127-value)/127.0*2.0); - else volume.volume=1.0; -}; + volume.data = value; + if(volume.receive != 0) + volume.volume = pow(0.1, (127 - value) / 127.0 * 2.0); + else + volume.volume = 1.0; +} void Controller::setsustain(int value) { - sustain.data=value; - if (sustain.receive!=0) sustain.sustain=((value<64) ? 0 : 1 ); - else sustain.sustain=0; -}; + sustain.data = value; + if(sustain.receive != 0) + sustain.sustain = ((value < 64) ? 0 : 1); + else + sustain.sustain = 0; +} void Controller::setportamento(int value) { - portamento.data=value; - if (portamento.receive!=0) portamento.portamento=((value<64) ? 0 : 1 ); -}; + portamento.data = value; + if(portamento.receive != 0) + portamento.portamento = ((value < 64) ? 0 : 1); +} -int Controller::initportamento(REALTYPE oldfreq,REALTYPE newfreq,bool legatoflag) +int Controller::initportamento(REALTYPE oldfreq, + REALTYPE newfreq, + bool legatoflag) { - portamento.x=0.0; + portamento.x = 0.0; - if (legatoflag) { // Legato in progress - if (portamento.portamento==0) return(0); - } else { // No legato, do the original if...return - if ((portamento.used!=0) || (portamento.portamento==0)) return(0); - }; + if(legatoflag) { // Legato in progress + if(portamento.portamento == 0) + return 0; + } + else // No legato, do the original if...return + if((portamento.used != 0) || (portamento.portamento == 0)) + return 0; + ; - REALTYPE portamentotime=pow(100.0,portamento.time/127.0)/50.0;//portamento time in seconds - - if (portamento.proportional) { + REALTYPE portamentotime = pow(100.0, portamento.time / 127.0) / 50.0; //portamento time in seconds + + if(portamento.proportional) { //If there is a min(float,float) and a max(float,float) then they //could be used here //Linear functors could also make this nicer if(oldfreq > newfreq) //2 is the center of propRate - portamentotime *= pow(oldfreq/newfreq/(portamento.propRate/127.0*3+.05), - (portamento.propDepth/127.0*1.6+.2)); + portamentotime *= + pow(oldfreq / newfreq / (portamento.propRate / 127.0 * 3 + .05), + (portamento.propDepth / 127.0 * 1.6 + .2)); else //1 is the center of propDepth - portamentotime *= pow(newfreq/oldfreq/(portamento.propRate/127.0*3+.05), - (portamento.propDepth/127.0*1.6+.2)); + portamentotime *= + pow(newfreq / oldfreq / (portamento.propRate / 127.0 * 3 + .05), + (portamento.propDepth / 127.0 * 1.6 + .2)); } - if ((portamento.updowntimestretch>=64)&&(newfreq= 64) && (newfreq < oldfreq)) { + if(portamento.updowntimestretch == 127) + return 0; + portamentotime *= pow(0.1, (portamento.updowntimestretch - 64) / 63.0); + } + if((portamento.updowntimestretch < 64) && (newfreq > oldfreq)) { + if(portamento.updowntimestretch == 0) + return 0; + portamentotime *= pow(0.1, (64.0 - portamento.updowntimestretch) / 64.0); } - if ((portamento.updowntimestretch<64)&&(newfreq>oldfreq)) { - if (portamento.updowntimestretch==0) return(0); - portamentotime*=pow(0.1,(64.0-portamento.updowntimestretch)/64.0); - }; //printf("%f->%f : Time %f\n",oldfreq,newfreq,portamentotime); - portamento.dx=SOUND_BUFFER_SIZE/(portamentotime*SAMPLE_RATE); - portamento.origfreqrap=oldfreq/newfreq; + portamento.dx = SOUND_BUFFER_SIZE / (portamentotime * SAMPLE_RATE); + portamento.origfreqrap = oldfreq / newfreq; - REALTYPE tmprap=( (portamento.origfreqrap>1.0) ? - (portamento.origfreqrap) : - (1.0/portamento.origfreqrap) ); + REALTYPE tmprap = ((portamento.origfreqrap > 1.0) ? + (portamento.origfreqrap) : + (1.0 / portamento.origfreqrap)); - REALTYPE thresholdrap=pow(2.0,portamento.pitchthresh/12.0); - if ((portamento.pitchthreshtype==0) && (tmprap-0.00001>thresholdrap) ) return(0); - if ((portamento.pitchthreshtype==1) && (tmprap+0.00001 thresholdrap)) + return 0; + if((portamento.pitchthreshtype == 1) && (tmprap + 0.00001 < thresholdrap)) + return 0; - portamento.used=1; - portamento.freqrap=portamento.origfreqrap; - return (1); -}; + portamento.used = 1; + portamento.freqrap = portamento.origfreqrap; + return 1; +} void Controller::updateportamento() { - if (portamento.used==0) return; + if(portamento.used == 0) + return; - portamento.x+=portamento.dx; - if (portamento.x>1.0) { - portamento.x=1.0; - portamento.used=0; - }; - portamento.freqrap=(1.0-portamento.x)*portamento.origfreqrap+portamento.x; -}; + portamento.x += portamento.dx; + if(portamento.x > 1.0) { + portamento.x = 1.0; + portamento.used = 0; + } + portamento.freqrap = + (1.0 - portamento.x) * portamento.origfreqrap + portamento.x; +} void Controller::setresonancecenter(int value) { - resonancecenter.data=value; - resonancecenter.relcenter=pow(3.0,(value-64.0)/64.0*(resonancecenter.depth/64.0)); -}; + resonancecenter.data = value; + resonancecenter.relcenter = + pow(3.0, (value - 64.0) / 64.0 * (resonancecenter.depth / 64.0)); +} void Controller::setresonancebw(int value) { - resonancebandwidth.data=value; - resonancebandwidth.relbw=pow(1.5,(value-64.0)/64.0*(resonancebandwidth.depth/127.0)); -}; + resonancebandwidth.data = value; + resonancebandwidth.relbw = + pow(1.5, (value - 64.0) / 64.0 * (resonancebandwidth.depth / 127.0)); +} //Returns 0 if there is NRPN or 1 if there is not int Controller::getnrpn(int *parhi, int *parlo, int *valhi, int *vallo) { - if (NRPN.receive==0) return(1); - if ((NRPN.parhi<0)||(NRPN.parlo<0)||(NRPN.valhi<0)||(NRPN.vallo<0)) - return(1); + if(NRPN.receive == 0) + return 1; + if((NRPN.parhi < 0) || (NRPN.parlo < 0) || (NRPN.valhi < 0) + || (NRPN.vallo < 0)) + return 1; - *parhi=NRPN.parhi; - *parlo=NRPN.parlo; - *valhi=NRPN.valhi; - *vallo=NRPN.vallo; - return(0); -}; + *parhi = NRPN.parhi; + *parlo = NRPN.parlo; + *valhi = NRPN.valhi; + *vallo = NRPN.vallo; + return 0; +} -void Controller::setparameternumber(unsigned int type,int value) +void Controller::setparameternumber(unsigned int type, int value) { - switch (type) { + switch(type) { case C_nrpnhi: - NRPN.parhi=value; - NRPN.valhi=-1; - NRPN.vallo=-1;//clear the values + NRPN.parhi = value; + NRPN.valhi = -1; + NRPN.vallo = -1; //clear the values break; case C_nrpnlo: - NRPN.parlo=value; - NRPN.valhi=-1; - NRPN.vallo=-1;//clear the values + NRPN.parlo = value; + NRPN.valhi = -1; + NRPN.vallo = -1; //clear the values break; case C_dataentryhi: - if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.valhi=value; + if((NRPN.parhi >= 0) && (NRPN.parlo >= 0)) + NRPN.valhi = value; break; case C_dataentrylo: - if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.vallo=value; + if((NRPN.parhi >= 0) && (NRPN.parlo >= 0)) + NRPN.vallo = value; break; - }; -}; + } +} void Controller::add2XML(XMLwrapper *xml) { - xml->addpar("pitchwheel_bendrange",pitchwheel.bendrange); + xml->addpar("pitchwheel_bendrange", pitchwheel.bendrange); - xml->addparbool("expression_receive",expression.receive); - xml->addpar("panning_depth",panning.depth); - xml->addpar("filter_cutoff_depth",filtercutoff.depth); - xml->addpar("filter_q_depth",filterq.depth); - xml->addpar("bandwidth_depth",bandwidth.depth); - xml->addpar("mod_wheel_depth",modwheel.depth); - xml->addparbool("mod_wheel_exponential",modwheel.exponential); - xml->addparbool("fm_amp_receive",fmamp.receive); - xml->addparbool("volume_receive",volume.receive); - xml->addparbool("sustain_receive",sustain.receive); + xml->addparbool("expression_receive", expression.receive); + xml->addpar("panning_depth", panning.depth); + xml->addpar("filter_cutoff_depth", filtercutoff.depth); + xml->addpar("filter_q_depth", filterq.depth); + xml->addpar("bandwidth_depth", bandwidth.depth); + xml->addpar("mod_wheel_depth", modwheel.depth); + xml->addparbool("mod_wheel_exponential", modwheel.exponential); + xml->addparbool("fm_amp_receive", fmamp.receive); + xml->addparbool("volume_receive", volume.receive); + xml->addparbool("sustain_receive", sustain.receive); - xml->addparbool("portamento_receive",portamento.receive); - xml->addpar("portamento_time",portamento.time); - xml->addpar("portamento_pitchthresh",portamento.pitchthresh); - xml->addpar("portamento_pitchthreshtype",portamento.pitchthreshtype); - xml->addpar("portamento_portamento",portamento.portamento); - xml->addpar("portamento_updowntimestretch",portamento.updowntimestretch); - xml->addpar("portamento_proportional",portamento.proportional); - xml->addpar("portamento_proprate",portamento.propRate); - xml->addpar("portamento_propdepth",portamento.propDepth); + xml->addparbool("portamento_receive", portamento.receive); + xml->addpar("portamento_time", portamento.time); + xml->addpar("portamento_pitchthresh", portamento.pitchthresh); + xml->addpar("portamento_pitchthreshtype", portamento.pitchthreshtype); + xml->addpar("portamento_portamento", portamento.portamento); + xml->addpar("portamento_updowntimestretch", portamento.updowntimestretch); + xml->addpar("portamento_proportional", portamento.proportional); + xml->addpar("portamento_proprate", portamento.propRate); + xml->addpar("portamento_propdepth", portamento.propDepth); - xml->addpar("resonance_center_depth",resonancecenter.depth); - xml->addpar("resonance_bandwidth_depth",resonancebandwidth.depth); -}; + xml->addpar("resonance_center_depth", resonancecenter.depth); + xml->addpar("resonance_bandwidth_depth", resonancebandwidth.depth); +} void Controller::getfromXML(XMLwrapper *xml) { - pitchwheel.bendrange=xml->getpar("pitchwheel_bendrange",pitchwheel.bendrange,-6400,6400); + pitchwheel.bendrange = xml->getpar("pitchwheel_bendrange", + pitchwheel.bendrange, + -6400, + 6400); - expression.receive=xml->getparbool("expression_receive",expression.receive); - panning.depth=xml->getpar127("panning_depth",panning.depth); - filtercutoff.depth=xml->getpar127("filter_cutoff_depth",filtercutoff.depth); - filterq.depth=xml->getpar127("filter_q_depth",filterq.depth); - bandwidth.depth=xml->getpar127("bandwidth_depth",bandwidth.depth); - modwheel.depth=xml->getpar127("mod_wheel_depth",modwheel.depth); - modwheel.exponential=xml->getparbool("mod_wheel_exponential",modwheel.exponential); - fmamp.receive=xml->getparbool("fm_amp_receive",fmamp.receive); - volume.receive=xml->getparbool("volume_receive",volume.receive); - sustain.receive=xml->getparbool("sustain_receive",sustain.receive); + expression.receive = xml->getparbool("expression_receive", + expression.receive); + panning.depth = xml->getpar127("panning_depth", panning.depth); + filtercutoff.depth = xml->getpar127("filter_cutoff_depth", + filtercutoff.depth); + filterq.depth = xml->getpar127("filter_q_depth", filterq.depth); + bandwidth.depth = xml->getpar127("bandwidth_depth", bandwidth.depth); + modwheel.depth = xml->getpar127("mod_wheel_depth", modwheel.depth); + modwheel.exponential = xml->getparbool("mod_wheel_exponential", + modwheel.exponential); + fmamp.receive = xml->getparbool("fm_amp_receive", + fmamp.receive); + volume.receive = xml->getparbool("volume_receive", + volume.receive); + sustain.receive = xml->getparbool("sustain_receive", + sustain.receive); - portamento.receive=xml->getparbool("portamento_receive",portamento.receive); - portamento.time=xml->getpar127("portamento_time",portamento.time); - portamento.pitchthresh=xml->getpar127("portamento_pitchthresh",portamento.pitchthresh); - portamento.pitchthreshtype=xml->getpar127("portamento_pitchthreshtype",portamento.pitchthreshtype); - portamento.portamento=xml->getpar127("portamento_portamento",portamento.portamento); - portamento.updowntimestretch=xml->getpar127("portamento_updowntimestretch",portamento.updowntimestretch); - portamento.proportional=xml->getpar127("portamento_proportional",portamento.proportional); - portamento.propRate=xml->getpar127("portamento_proprate",portamento.propRate); - portamento.propDepth=xml->getpar127("portamento_propdepth",portamento.propDepth); - - - resonancecenter.depth=xml->getpar127("resonance_center_depth",resonancecenter.depth); - resonancebandwidth.depth=xml->getpar127("resonance_bandwidth_depth",resonancebandwidth.depth); -}; + portamento.receive = xml->getparbool("portamento_receive", + portamento.receive); + portamento.time = xml->getpar127("portamento_time", + portamento.time); + portamento.pitchthresh = xml->getpar127("portamento_pitchthresh", + portamento.pitchthresh); + portamento.pitchthreshtype = xml->getpar127("portamento_pitchthreshtype", + portamento.pitchthreshtype); + portamento.portamento = xml->getpar127("portamento_portamento", + portamento.portamento); + portamento.updowntimestretch = xml->getpar127( + "portamento_updowntimestretch", + portamento.updowntimestretch); + portamento.proportional = xml->getpar127("portamento_proportional", + portamento.proportional); + portamento.propRate = xml->getpar127("portamento_proprate", + portamento.propRate); + portamento.propDepth = xml->getpar127("portamento_propdepth", + portamento.propDepth); + resonancecenter.depth = xml->getpar127("resonance_center_depth", + resonancecenter.depth); + resonancebandwidth.depth = xml->getpar127("resonance_bandwidth_depth", + resonancebandwidth.depth); +} diff --git a/plugins/zynaddsubfx/src/Params/Controller.h b/plugins/zynaddsubfx/src/Params/Controller.h index 3e5ededac..86a4badbb 100644 --- a/plugins/zynaddsubfx/src/Params/Controller.h +++ b/plugins/zynaddsubfx/src/Params/Controller.h @@ -30,191 +30,191 @@ /**(Midi) Controllers implementation*/ class Controller { -public: - Controller(); - ~Controller(); - void resetall(); + public: + Controller(); + ~Controller(); + void resetall(); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - //Controllers functions - void setpitchwheel(int value); - void setpitchwheelbendrange(unsigned short int value); - void setexpression(int value); - void setpanning(int value); - void setfiltercutoff(int value); - void setfilterq(int value); - void setbandwidth(int value); - void setmodwheel(int value); - void setfmamp(int value); - void setvolume(int value); - void setsustain(int value); - /**Enable or disable portamento - * @param value 0-127 MIDI value (greater than 64 enables)*/ - void setportamento(int value); - void setresonancecenter(int value); - void setresonancebw(int value); + //Controllers functions + void setpitchwheel(int value); + void setpitchwheelbendrange(unsigned short int value); + void setexpression(int value); + void setpanning(int value); + void setfiltercutoff(int value); + void setfilterq(int value); + void setbandwidth(int value); + void setmodwheel(int value); + void setfmamp(int value); + void setvolume(int value); + void setsustain(int value); + /**Enable or disable portamento + * @param value 0-127 MIDI value (greater than 64 enables)*/ + void setportamento(int value); + void setresonancecenter(int value); + void setresonancebw(int value); - void setparameternumber(unsigned int type,int value);//used for RPN and NRPN's - int getnrpn(int *parhi, int *parlo, int *valhi, int *vallo); + void setparameternumber(unsigned int type, int value); //used for RPN and NRPN's + int getnrpn(int *parhi, int *parlo, int *valhi, int *vallo); - /** - * Initialize a portamento - * - * @param oldfreq Starting frequency of the portamento (Hz) - * @param newfreq Ending frequency of the portamento (Hz) - * @param legatoflag true when legato is in progress, false otherwise - * @returns 1 if properly initialized, 0 otherwise*/ - int initportamento(REALTYPE oldfreq,REALTYPE newfreq,bool legatoflag); - /**Update portamento's freqrap to next value based upon dx*/ - void updateportamento(); - - // Controllers values - struct {//Pitch Wheel - int data; - short int bendrange;//bendrange is in cents - REALTYPE relfreq;//the relative frequency (default is 1.0) - } pitchwheel; - - struct {//Expression - int data; - REALTYPE relvolume; - unsigned char receive; - } expression; - - struct {//Panning - int data; - REALTYPE pan; - unsigned char depth; - } panning; - - - struct {//Filter cutoff - int data; - REALTYPE relfreq; - unsigned char depth; - } filtercutoff; - - struct {//Filter Q - int data; - REALTYPE relq; - unsigned char depth; - } filterq; - - struct {//Bandwidth - int data; - REALTYPE relbw; - unsigned char depth; - unsigned char exponential; - } bandwidth; - - struct {//Modulation Wheel - int data; - REALTYPE relmod; - unsigned char depth; - unsigned char exponential; - } modwheel; - - struct {//FM amplitude - int data; - REALTYPE relamp; - unsigned char receive; - } fmamp; - - struct {//Volume - int data; - REALTYPE volume; - unsigned char receive; - } volume; - - struct {//Sustain - int data,sustain; - unsigned char receive; - } sustain; - - struct {/** #include "EnvelopeParams.h" -EnvelopeParams::EnvelopeParams(unsigned char Penvstretch_,unsigned char Pforcedrelease_):Presets() +EnvelopeParams::EnvelopeParams(unsigned char Penvstretch_, + unsigned char Pforcedrelease_):Presets() { int i; - PA_dt=10; - PD_dt=10; - PR_dt=10; - PA_val=64; - PD_val=64; - PS_val=64; - PR_val=64; + PA_dt = 10; + PD_dt = 10; + PR_dt = 10; + PA_val = 64; + PD_val = 64; + PS_val = 64; + PR_val = 64; - for (i=0;iaddparbool("free_mode",Pfreemode); - xml->addpar("env_points",Penvpoints); - xml->addpar("env_sustain",Penvsustain); - xml->addpar("env_stretch",Penvstretch); - xml->addparbool("forced_release",Pforcedrelease); - xml->addparbool("linear_envelope",Plinearenvelope); - xml->addpar("A_dt",PA_dt); - xml->addpar("D_dt",PD_dt); - xml->addpar("R_dt",PR_dt); - xml->addpar("A_val",PA_val); - xml->addpar("D_val",PD_val); - xml->addpar("S_val",PS_val); - xml->addpar("R_val",PR_val); + xml->addparbool("free_mode", Pfreemode); + xml->addpar("env_points", Penvpoints); + xml->addpar("env_sustain", Penvsustain); + xml->addpar("env_stretch", Penvstretch); + xml->addparbool("forced_release", Pforcedrelease); + xml->addparbool("linear_envelope", Plinearenvelope); + xml->addpar("A_dt", PA_dt); + xml->addpar("D_dt", PD_dt); + xml->addpar("R_dt", PR_dt); + xml->addpar("A_val", PA_val); + xml->addpar("D_val", PD_val); + xml->addpar("S_val", PS_val); + xml->addpar("R_val", PR_val); - if ((Pfreemode!=0)||(!xml->minimal)) { - for (int i=0;ibeginbranch("POINT",i); - if (i!=0) xml->addpar("dt",Penvdt[i]); - xml->addpar("val",Penvval[i]); + if((Pfreemode != 0) || (!xml->minimal)) { + for(int i = 0; i < Penvpoints; i++) { + xml->beginbranch("POINT", i); + if(i != 0) + xml->addpar("dt", Penvdt[i]); + xml->addpar("val", Penvval[i]); xml->endbranch(); - }; - }; -}; + } + } +} void EnvelopeParams::getfromXML(XMLwrapper *xml) { - Pfreemode=xml->getparbool("free_mode",Pfreemode); - Penvpoints=xml->getpar127("env_points",Penvpoints); - Penvsustain=xml->getpar127("env_sustain",Penvsustain); - Penvstretch=xml->getpar127("env_stretch",Penvstretch); - Pforcedrelease=xml->getparbool("forced_release",Pforcedrelease); - Plinearenvelope=xml->getparbool("linear_envelope",Plinearenvelope); + Pfreemode = xml->getparbool("free_mode", Pfreemode); + Penvpoints = xml->getpar127("env_points", Penvpoints); + Penvsustain = xml->getpar127("env_sustain", Penvsustain); + Penvstretch = xml->getpar127("env_stretch", Penvstretch); + Pforcedrelease = xml->getparbool("forced_release", Pforcedrelease); + Plinearenvelope = xml->getparbool("linear_envelope", Plinearenvelope); - PA_dt=xml->getpar127("A_dt",PA_dt); - PD_dt=xml->getpar127("D_dt",PD_dt); - PR_dt=xml->getpar127("R_dt",PR_dt); - PA_val=xml->getpar127("A_val",PA_val); - PD_val=xml->getpar127("D_val",PD_val); - PS_val=xml->getpar127("S_val",PS_val); - PR_val=xml->getpar127("R_val",PR_val); + PA_dt = xml->getpar127("A_dt", PA_dt); + PD_dt = xml->getpar127("D_dt", PD_dt); + PR_dt = xml->getpar127("R_dt", PR_dt); + PA_val = xml->getpar127("A_val", PA_val); + PD_val = xml->getpar127("D_val", PD_val); + PS_val = xml->getpar127("S_val", PS_val); + PR_val = xml->getpar127("R_val", PR_val); - for (int i=0;ienterbranch("POINT",i)==0) continue; - if (i!=0) Penvdt[i]=xml->getpar127("dt",Penvdt[i]); - Penvval[i]=xml->getpar127("val",Penvval[i]); + for(int i = 0; i < Penvpoints; i++) { + if(xml->enterbranch("POINT", i) == 0) + continue; + if(i != 0) + Penvdt[i] = xml->getpar127("dt", Penvdt[i]); + Penvval[i] = xml->getpar127("val", Penvval[i]); xml->exitbranch(); - }; + } - if (!Pfreemode) converttofree(); -}; + if(!Pfreemode) + converttofree(); +} void EnvelopeParams::defaults() { - Penvstretch=Denvstretch; - Pforcedrelease=Dforcedrelease; - Plinearenvelope=Dlinearenvelope; - PA_dt=DA_dt; - PD_dt=DD_dt; - PR_dt=DR_dt; - PA_val=DA_val; - PD_val=DD_val; - PS_val=DS_val; - PR_val=DR_val; - Pfreemode=0; + Penvstretch = Denvstretch; + Pforcedrelease = Dforcedrelease; + Plinearenvelope = Dlinearenvelope; + PA_dt = DA_dt; + PD_dt = DD_dt; + PR_dt = DR_dt; + PA_val = DA_val; + PD_val = DD_val; + PS_val = DS_val; + PR_val = DR_val; + Pfreemode = 0; converttofree(); -}; +} void EnvelopeParams::store2defaults() { - Denvstretch=Penvstretch; - Dforcedrelease=Pforcedrelease; - Dlinearenvelope=Plinearenvelope; - DA_dt=PA_dt; - DD_dt=PD_dt; - DR_dt=PR_dt; - DA_val=PA_val; - DD_val=PD_val; - DS_val=PS_val; - DR_val=PR_val; -}; + Denvstretch = Penvstretch; + Dforcedrelease = Pforcedrelease; + Dlinearenvelope = Plinearenvelope; + DA_dt = PA_dt; + DD_dt = PD_dt; + DR_dt = PR_dt; + DA_val = PA_val; + DD_val = PD_val; + DS_val = PS_val; + DR_val = PR_val; +} diff --git a/plugins/zynaddsubfx/src/Params/EnvelopeParams.h b/plugins/zynaddsubfx/src/Params/EnvelopeParams.h index d7d44c859..e2fcf3ec8 100644 --- a/plugins/zynaddsubfx/src/Params/EnvelopeParams.h +++ b/plugins/zynaddsubfx/src/Params/EnvelopeParams.h @@ -32,54 +32,58 @@ class EnvelopeParams:public Presets { -public: - EnvelopeParams(unsigned char Penvstretch_,unsigned char Pforcedrelease_); - ~EnvelopeParams(); - void ADSRinit(char A_dt,char D_dt,char S_val,char R_dt); - void ADSRinit_dB(char A_dt,char D_dt,char S_val,char R_dt); - void ASRinit(char A_val,char A_dt,char R_val,char R_dt); - void ADSRinit_filter(char A_val,char A_dt,char D_val,char D_dt,char R_dt,char R_val); - void ASRinit_bw(char A_val,char A_dt,char R_val,char R_dt); - void converttofree(); + public: + EnvelopeParams(unsigned char Penvstretch_, + unsigned char Pforcedrelease_); + ~EnvelopeParams(); + void ADSRinit(char A_dt, char D_dt, char S_val, char R_dt); + void ADSRinit_dB(char A_dt, char D_dt, char S_val, char R_dt); + void ASRinit(char A_val, char A_dt, char R_val, char R_dt); + void ADSRinit_filter(char A_val, + char A_dt, + char D_val, + char D_dt, + char R_dt, + char R_val); + void ASRinit_bw(char A_val, char A_dt, char R_val, char R_dt); + void converttofree(); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - REALTYPE getdt(char i); + REALTYPE getdt(char i); - /* MIDI Parameters */ - unsigned char Pfreemode;//1 daca este in modul free sau 0 daca este in mod ADSR,ASR,... - unsigned char Penvpoints; - unsigned char Penvsustain;//127 pentru dezactivat - unsigned char Penvdt[MAX_ENVELOPE_POINTS]; - unsigned char Penvval[MAX_ENVELOPE_POINTS]; - unsigned char Penvstretch;//64=normal stretch (piano-like), 0=no stretch - unsigned char Pforcedrelease;//0 - OFF, 1 - ON - unsigned char Plinearenvelope;//if the amplitude envelope is linear + /* MIDI Parameters */ + unsigned char Pfreemode; //1 daca este in modul free sau 0 daca este in mod ADSR,ASR,... + unsigned char Penvpoints; + unsigned char Penvsustain; //127 pentru dezactivat + unsigned char Penvdt[MAX_ENVELOPE_POINTS]; + unsigned char Penvval[MAX_ENVELOPE_POINTS]; + unsigned char Penvstretch; //64=normal stretch (piano-like), 0=no stretch + unsigned char Pforcedrelease; //0 - OFF, 1 - ON + unsigned char Plinearenvelope; //if the amplitude envelope is linear - unsigned char PA_dt,PD_dt,PR_dt, - PA_val,PD_val,PS_val,PR_val; + unsigned char PA_dt, PD_dt, PR_dt, + PA_val, PD_val, PS_val, PR_val; - int Envmode;// 1 for ADSR parameters (linear amplitude) - // 2 for ADSR_dB parameters (dB amplitude) - // 3 for ASR parameters (frequency LFO) - // 4 for ADSR_filter parameters (filter parameters) - // 5 for ASR_bw parameters (bandwidth parameters) - -private: - void store2defaults(); - - /* Default parameters */ - unsigned char Denvstretch; - unsigned char Dforcedrelease; - unsigned char Dlinearenvelope; - unsigned char DA_dt,DD_dt,DR_dt, - DA_val,DD_val,DS_val,DR_val; + int Envmode; // 1 for ADSR parameters (linear amplitude) + // 2 for ADSR_dB parameters (dB amplitude) + // 3 for ASR parameters (frequency LFO) + // 4 for ADSR_filter parameters (filter parameters) + // 5 for ASR_bw parameters (bandwidth parameters) + private: + void store2defaults(); + /* Default parameters */ + unsigned char Denvstretch; + unsigned char Dforcedrelease; + unsigned char Dlinearenvelope; + unsigned char DA_dt, DD_dt, DR_dt, + DA_val, DD_val, DS_val, DR_val; }; #endif diff --git a/plugins/zynaddsubfx/src/Params/FilterParams.cpp b/plugins/zynaddsubfx/src/Params/FilterParams.cpp index 861b6d313..a74bf5a99 100644 --- a/plugins/zynaddsubfx/src/Params/FilterParams.cpp +++ b/plugins/zynaddsubfx/src/Params/FilterParams.cpp @@ -25,58 +25,60 @@ #include #include "FilterParams.h" -FilterParams::FilterParams(unsigned char Ptype_,unsigned char Pfreq_,unsigned char Pq_):Presets() +FilterParams::FilterParams(unsigned char Ptype_, + unsigned char Pfreq_, + unsigned char Pq_):Presets() { setpresettype("Pfilter"); - Dtype=Ptype_; - Dfreq=Pfreq_; - Dq=Pq_; + Dtype = Ptype_; + Dfreq = Pfreq_; + Dq = Pq_; - changed=false; + changed = false; defaults(); -}; +} FilterParams::~FilterParams() -{ -}; +{} void FilterParams::defaults() { - Ptype=Dtype; - Pfreq=Dfreq; - Pq=Dq; + Ptype = Dtype; + Pfreq = Dfreq; + Pq = Dq; - Pstages=0; - Pfreqtrack=64; - Pgain=64; - Pcategory=0; + Pstages = 0; + Pfreqtrack = 64; + Pgain = 64; + Pcategory = 0; - Pnumformants=3; - Pformantslowness=64; - for (int j=0;jPtype; - Pfreq=pars->Pfreq; - Pq=pars->Pq; + Ptype = pars->Ptype; + Pfreq = pars->Pfreq; + Pq = pars->Pq; - Pstages=pars->Pstages; - Pfreqtrack=pars->Pfreqtrack; - Pgain=pars->Pgain; - Pcategory=pars->Pcategory; + Pstages = pars->Pstages; + Pfreqtrack = pars->Pfreqtrack; + Pgain = pars->Pgain; + Pcategory = pars->Pcategory; - Pnumformants=pars->Pnumformants; - Pformantslowness=pars->Pformantslowness; - for (int j=0;jPvowels[j].formants[i].freq; - Pvowels[j].formants[i].q=pars->Pvowels[j].formants[i].q; - Pvowels[j].formants[i].amp=pars->Pvowels[j].formants[i].amp; - }; - }; + Pnumformants = pars->Pnumformants; + Pformantslowness = pars->Pformantslowness; + for(int j = 0; j < FF_MAX_VOWELS; j++) { + for(int i = 0; i < FF_MAX_FORMANTS; i++) { + Pvowels[j].formants[i].freq = pars->Pvowels[j].formants[i].freq; + Pvowels[j].formants[i].q = pars->Pvowels[j].formants[i].q; + Pvowels[j].formants[i].amp = pars->Pvowels[j].formants[i].amp; + } + } - Psequencesize=pars->Psequencesize; - for (int i=0;iPsequence[i].nvowel; + Psequencesize = pars->Psequencesize; + for(int i = 0; i < FF_MAX_SEQUENCE; i++) + Psequence[i].nvowel = pars->Psequence[i].nvowel; - Psequencestretch=pars->Psequencestretch; - Psequencereversed=pars->Psequencereversed; - Pcenterfreq=pars->Pcenterfreq; - Poctavesfreq=pars->Poctavesfreq; - Pvowelclearness=pars->Pvowelclearness; -}; + Psequencestretch = pars->Psequencestretch; + Psequencereversed = pars->Psequencereversed; + Pcenterfreq = pars->Pcenterfreq; + Poctavesfreq = pars->Poctavesfreq; + Pvowelclearness = pars->Pvowelclearness; +} /* @@ -124,243 +128,264 @@ void FilterParams::getfromFilterParams(FilterParams *pars) */ REALTYPE FilterParams::getfreq() { - return((Pfreq/64.0-1.0)*5.0); -}; + return (Pfreq / 64.0 - 1.0) * 5.0; +} REALTYPE FilterParams::getq() { - return(exp(pow((REALTYPE) Pq/127.0,2)*log(1000.0))-0.9); -}; + return exp(pow((REALTYPE) Pq / 127.0, 2) * log(1000.0)) - 0.9; +} REALTYPE FilterParams::getfreqtracking(REALTYPE notefreq) { - return(log(notefreq/440.0)*(Pfreqtrack-64.0)/(64.0*LOG_2)); -}; + return log(notefreq / 440.0) * (Pfreqtrack - 64.0) / (64.0 * LOG_2); +} REALTYPE FilterParams::getgain() { - return((Pgain/64.0-1.0)*30.0);//-30..30dB -}; + return (Pgain / 64.0 - 1.0) * 30.0; //-30..30dB +} /* * Get the center frequency of the formant's graph */ REALTYPE FilterParams::getcenterfreq() { - return(10000.0*pow(10,-(1.0-Pcenterfreq/127.0)*2.0)); -}; + return 10000.0 * pow(10, -(1.0 - Pcenterfreq / 127.0) * 2.0); +} /* * Get the number of octave that the formant functions applies to */ REALTYPE FilterParams::getoctavesfreq() { - return(0.25+10.0*Poctavesfreq/127.0); -}; + return 0.25 + 10.0 * Poctavesfreq / 127.0; +} /* * Get the frequency from x, where x is [0..1] */ REALTYPE FilterParams::getfreqx(REALTYPE x) { - if (x>1.0) x=1.0; - REALTYPE octf=pow(2.0,getoctavesfreq()); - return(getcenterfreq()/sqrt(octf)*pow(octf,x)); -}; + if(x > 1.0) + x = 1.0; + REALTYPE octf = pow(2.0, getoctavesfreq()); + return getcenterfreq() / sqrt(octf) * pow(octf, x); +} /* * Get the x coordinate from frequency (used by the UI) */ REALTYPE FilterParams::getfreqpos(REALTYPE freq) { - return((log(freq)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq()); -}; + return (log(freq) - log(getfreqx(0.0))) / log(2.0) / getoctavesfreq(); +} /* * Get the freq. response of the formant filter */ -void FilterParams::formantfilterH(int nvowel,int nfreqs,REALTYPE *freqs) +void FilterParams::formantfilterH(int nvowel, int nfreqs, REALTYPE *freqs) { - REALTYPE c[3],d[3]; - REALTYPE filter_freq,filter_q,filter_amp; - REALTYPE omega,sn,cs,alpha; + REALTYPE c[3], d[3]; + REALTYPE filter_freq, filter_q, filter_amp; + REALTYPE omega, sn, cs, alpha; - for (int i=0;i0) filter_q=(filter_q>1.0 ? pow(filter_q,1.0/(Pstages+1)) : filter_q); + filter_freq = getformantfreq(Pvowels[nvowel].formants[nformant].freq); + filter_q = getformantq(Pvowels[nvowel].formants[nformant].q) * getq(); + if(Pstages > 0) + filter_q = + (filter_q > 1.0 ? pow(filter_q, 1.0 / (Pstages + 1)) : filter_q); - filter_amp=getformantamp(Pvowels[nvowel].formants[nformant].amp); + filter_amp = getformantamp(Pvowels[nvowel].formants[nformant].amp); - if (filter_freq<=(SAMPLE_RATE/2-100.0)) { - omega=2*PI*filter_freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*filter_q); - REALTYPE tmp=1+alpha; - c[0]=alpha/tmp*sqrt(filter_q+1); - c[1]=0; - c[2]=-alpha/tmp*sqrt(filter_q+1); - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else continue; + if(filter_freq <= (SAMPLE_RATE / 2 - 100.0)) { + omega = 2 * PI * filter_freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * filter_q); + REALTYPE tmp = 1 + alpha; + c[0] = alpha / tmp *sqrt(filter_q + 1); + c[1] = 0; + c[2] = -alpha / tmp *sqrt(filter_q + 1); + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else + continue; - for (int i=0;iSAMPLE_RATE/2) { - for (int tmp=i;tmp SAMPLE_RATE / 2) { + for(int tmp = i; tmp < nfreqs; tmp++) + freqs[tmp] = 0.0; break; - }; - REALTYPE fr=freq/SAMPLE_RATE*PI*2.0; - REALTYPE x=c[0],y=0.0; - for (int n=1;n<3;n++) { - x+=cos(n*fr)*c[n]; - y-=sin(n*fr)*c[n]; - }; - REALTYPE h=x*x+y*y; - x=1.0; - y=0.0; - for (int n=1;n<3;n++) { - x-=cos(n*fr)*d[n]; - y+=sin(n*fr)*d[n]; - }; - h=h/(x*x+y*y); + } + REALTYPE fr = freq / SAMPLE_RATE * PI * 2.0; + REALTYPE x = c[0], y = 0.0; + for(int n = 1; n < 3; n++) { + x += cos(n * fr) * c[n]; + y -= sin(n * fr) * c[n]; + } + REALTYPE h = x * x + y * y; + x = 1.0; + y = 0.0; + for(int n = 1; n < 3; n++) { + x -= cos(n * fr) * d[n]; + y += sin(n * fr) * d[n]; + } + h = h / (x * x + y * y); - freqs[i]+=pow(h,(Pstages+1.0)/2.0)*filter_amp; - }; - }; - for (int i=0;i0.000000001) freqs[i]=rap2dB(freqs[i])+getgain(); - else freqs[i]=-90.0; - }; - -}; + freqs[i] += pow(h, (Pstages + 1.0) / 2.0) * filter_amp; + } + } + for(int i = 0; i < nfreqs; i++) { + if(freqs[i] > 0.000000001) + freqs[i] = rap2dB(freqs[i]) + getgain(); + else + freqs[i] = -90.0; + } +} /* * Transforms a parameter to the real value */ REALTYPE FilterParams::getformantfreq(unsigned char freq) { - REALTYPE result=getfreqx(freq/127.0); - return(result); -}; + REALTYPE result = getfreqx(freq / 127.0); + return result; +} REALTYPE FilterParams::getformantamp(unsigned char amp) { - REALTYPE result=pow(0.1,(1.0-amp/127.0)*4.0); - return(result); -}; + REALTYPE result = pow(0.1, (1.0 - amp / 127.0) * 4.0); + return result; +} REALTYPE FilterParams::getformantq(unsigned char q) { //temp - REALTYPE result=pow(25.0,(q-32.0)/64.0); - return(result); -}; + REALTYPE result = pow(25.0, (q - 32.0) / 64.0); + return result; +} -void FilterParams::add2XMLsection(XMLwrapper *xml,int n) +void FilterParams::add2XMLsection(XMLwrapper *xml, int n) { - int nvowel=n; - for (int nformant=0;nformantbeginbranch("FORMANT",nformant); - xml->addpar("freq",Pvowels[nvowel].formants[nformant].freq); - xml->addpar("amp",Pvowels[nvowel].formants[nformant].amp); - xml->addpar("q",Pvowels[nvowel].formants[nformant].q); + int nvowel = n; + for(int nformant = 0; nformant < FF_MAX_FORMANTS; nformant++) { + xml->beginbranch("FORMANT", nformant); + xml->addpar("freq", Pvowels[nvowel].formants[nformant].freq); + xml->addpar("amp", Pvowels[nvowel].formants[nformant].amp); + xml->addpar("q", Pvowels[nvowel].formants[nformant].q); xml->endbranch(); - }; -}; + } +} void FilterParams::add2XML(XMLwrapper *xml) { //filter parameters - xml->addpar("category",Pcategory); - xml->addpar("type",Ptype); - xml->addpar("freq",Pfreq); - xml->addpar("q",Pq); - xml->addpar("stages",Pstages); - xml->addpar("freq_track",Pfreqtrack); - xml->addpar("gain",Pgain); + xml->addpar("category", Pcategory); + xml->addpar("type", Ptype); + xml->addpar("freq", Pfreq); + xml->addpar("q", Pq); + xml->addpar("stages", Pstages); + xml->addpar("freq_track", Pfreqtrack); + xml->addpar("gain", Pgain); //formant filter parameters - if ((Pcategory==1)||(!xml->minimal)) { + if((Pcategory == 1) || (!xml->minimal)) { xml->beginbranch("FORMANT_FILTER"); - xml->addpar("num_formants",Pnumformants); - xml->addpar("formant_slowness",Pformantslowness); - xml->addpar("vowel_clearness",Pvowelclearness); - xml->addpar("center_freq",Pcenterfreq); - xml->addpar("octaves_freq",Poctavesfreq); - for (int nvowel=0;nvowelbeginbranch("VOWEL",nvowel); - add2XMLsection(xml,nvowel); + xml->addpar("num_formants", Pnumformants); + xml->addpar("formant_slowness", Pformantslowness); + xml->addpar("vowel_clearness", Pvowelclearness); + xml->addpar("center_freq", Pcenterfreq); + xml->addpar("octaves_freq", Poctavesfreq); + for(int nvowel = 0; nvowel < FF_MAX_VOWELS; nvowel++) { + xml->beginbranch("VOWEL", nvowel); + add2XMLsection(xml, nvowel); xml->endbranch(); - }; - xml->addpar("sequence_size",Psequencesize); - xml->addpar("sequence_stretch",Psequencestretch); - xml->addparbool("sequence_reversed",Psequencereversed); - for (int nseq=0;nseqbeginbranch("SEQUENCE_POS",nseq); - xml->addpar("vowel_id",Psequence[nseq].nvowel); + } + xml->addpar("sequence_size", Psequencesize); + xml->addpar("sequence_stretch", Psequencestretch); + xml->addparbool("sequence_reversed", Psequencereversed); + for(int nseq = 0; nseq < FF_MAX_SEQUENCE; nseq++) { + xml->beginbranch("SEQUENCE_POS", nseq); + xml->addpar("vowel_id", Psequence[nseq].nvowel); xml->endbranch(); - }; + } xml->endbranch(); - }; -}; + } +} -void FilterParams::getfromXMLsection(XMLwrapper *xml,int n) +void FilterParams::getfromXMLsection(XMLwrapper *xml, int n) { - int nvowel=n; - for (int nformant=0;nformantenterbranch("FORMANT",nformant)==0) continue; - Pvowels[nvowel].formants[nformant].freq=xml->getpar127("freq",Pvowels[nvowel].formants[nformant].freq); - Pvowels[nvowel].formants[nformant].amp=xml->getpar127("amp",Pvowels[nvowel].formants[nformant].amp); - Pvowels[nvowel].formants[nformant].q=xml->getpar127("q",Pvowels[nvowel].formants[nformant].q); + int nvowel = n; + for(int nformant = 0; nformant < FF_MAX_FORMANTS; nformant++) { + if(xml->enterbranch("FORMANT", nformant) == 0) + continue; + Pvowels[nvowel].formants[nformant].freq = xml->getpar127( + "freq", + Pvowels[nvowel + ].formants[nformant].freq); + Pvowels[nvowel].formants[nformant].amp = xml->getpar127( + "amp", + Pvowels[nvowel + ].formants[nformant].amp); + Pvowels[nvowel].formants[nformant].q = + xml->getpar127("q", Pvowels[nvowel].formants[nformant].q); xml->exitbranch(); - }; -}; + } +} void FilterParams::getfromXML(XMLwrapper *xml) { //filter parameters - Pcategory=xml->getpar127("category",Pcategory); - Ptype=xml->getpar127("type",Ptype); - Pfreq=xml->getpar127("freq",Pfreq); - Pq=xml->getpar127("q",Pq); - Pstages=xml->getpar127("stages",Pstages); - Pfreqtrack=xml->getpar127("freq_track",Pfreqtrack); - Pgain=xml->getpar127("gain",Pgain); + Pcategory = xml->getpar127("category", Pcategory); + Ptype = xml->getpar127("type", Ptype); + Pfreq = xml->getpar127("freq", Pfreq); + Pq = xml->getpar127("q", Pq); + Pstages = xml->getpar127("stages", Pstages); + Pfreqtrack = xml->getpar127("freq_track", Pfreqtrack); + Pgain = xml->getpar127("gain", Pgain); //formant filter parameters - if (xml->enterbranch("FORMANT_FILTER")) { - Pnumformants=xml->getpar127("num_formants",Pnumformants); - Pformantslowness=xml->getpar127("formant_slowness",Pformantslowness); - Pvowelclearness=xml->getpar127("vowel_clearness",Pvowelclearness); - Pcenterfreq=xml->getpar127("center_freq",Pcenterfreq); - Poctavesfreq=xml->getpar127("octaves_freq",Poctavesfreq); + if(xml->enterbranch("FORMANT_FILTER")) { + Pnumformants = xml->getpar127("num_formants", Pnumformants); + Pformantslowness = xml->getpar127("formant_slowness", Pformantslowness); + Pvowelclearness = xml->getpar127("vowel_clearness", Pvowelclearness); + Pcenterfreq = xml->getpar127("center_freq", Pcenterfreq); + Poctavesfreq = xml->getpar127("octaves_freq", Poctavesfreq); - for (int nvowel=0;nvowelenterbranch("VOWEL",nvowel)==0) continue; - getfromXMLsection(xml,nvowel); + for(int nvowel = 0; nvowel < FF_MAX_VOWELS; nvowel++) { + if(xml->enterbranch("VOWEL", nvowel) == 0) + continue; + getfromXMLsection(xml, nvowel); xml->exitbranch(); - }; - Psequencesize=xml->getpar127("sequence_size",Psequencesize); - Psequencestretch=xml->getpar127("sequence_stretch",Psequencestretch); - Psequencereversed=xml->getparbool("sequence_reversed",Psequencereversed); - for (int nseq=0;nseqenterbranch("SEQUENCE_POS",nseq)==0) continue; - Psequence[nseq].nvowel=xml->getpar("vowel_id",Psequence[nseq].nvowel,0,FF_MAX_VOWELS-1); + } + Psequencesize = xml->getpar127("sequence_size", Psequencesize); + Psequencestretch = xml->getpar127("sequence_stretch", Psequencestretch); + Psequencereversed = xml->getparbool("sequence_reversed", + Psequencereversed); + for(int nseq = 0; nseq < FF_MAX_SEQUENCE; nseq++) { + if(xml->enterbranch("SEQUENCE_POS", nseq) == 0) + continue; + Psequence[nseq].nvowel = xml->getpar("vowel_id", + Psequence[nseq].nvowel, + 0, + FF_MAX_VOWELS - 1); xml->exitbranch(); - }; + } xml->exitbranch(); - }; - -}; + } +} diff --git a/plugins/zynaddsubfx/src/Params/FilterParams.h b/plugins/zynaddsubfx/src/Params/FilterParams.h index 89c8b46ad..2a1df6b28 100644 --- a/plugins/zynaddsubfx/src/Params/FilterParams.h +++ b/plugins/zynaddsubfx/src/Params/FilterParams.h @@ -29,72 +29,74 @@ class FilterParams:public Presets { -public: - FilterParams(unsigned char Ptype_,unsigned char Pfreq,unsigned char Pq_); - ~FilterParams(); + public: + FilterParams(unsigned char Ptype_, + unsigned char Pfreq, + unsigned char Pq_); + ~FilterParams(); - void add2XML(XMLwrapper *xml); - void add2XMLsection(XMLwrapper *xml,int n); - void defaults(); - void getfromXML(XMLwrapper *xml); - void getfromXMLsection(XMLwrapper *xml,int n); + void add2XML(XMLwrapper *xml); + void add2XMLsection(XMLwrapper *xml, int n); + void defaults(); + void getfromXML(XMLwrapper *xml); + void getfromXMLsection(XMLwrapper *xml, int n); - void getfromFilterParams(FilterParams *pars); + void getfromFilterParams(FilterParams *pars); - REALTYPE getfreq(); - REALTYPE getq(); - REALTYPE getfreqtracking(REALTYPE notefreq); - REALTYPE getgain(); + REALTYPE getfreq(); + REALTYPE getq(); + REALTYPE getfreqtracking(REALTYPE notefreq); + REALTYPE getgain(); - unsigned char Pcategory;//Filter category (Analog/Formant/StVar) - unsigned char Ptype;// Filter type (for analog lpf,hpf,bpf..) - unsigned char Pfreq;// Frequency (64-central frequency) - unsigned char Pq; // Q parameters (resonance or bandwidth) - unsigned char Pstages; //filter stages+1 - unsigned char Pfreqtrack;//how the filter frequency is changing according the note frequency - unsigned char Pgain;//filter's output gain + unsigned char Pcategory; //Filter category (Analog/Formant/StVar) + unsigned char Ptype; // Filter type (for analog lpf,hpf,bpf..) + unsigned char Pfreq; // Frequency (64-central frequency) + unsigned char Pq; // Q parameters (resonance or bandwidth) + unsigned char Pstages; //filter stages+1 + unsigned char Pfreqtrack; //how the filter frequency is changing according the note frequency + unsigned char Pgain; //filter's output gain - //Formant filter parameters - unsigned char Pnumformants;//how many formants are used - unsigned char Pformantslowness;//how slow varies the formants - unsigned char Pvowelclearness;//how vowels are kept clean (how much try to avoid "mixed" vowels) - unsigned char Pcenterfreq,Poctavesfreq;//the center frequency of the res. func., and the number of octaves + //Formant filter parameters + unsigned char Pnumformants; //how many formants are used + unsigned char Pformantslowness; //how slow varies the formants + unsigned char Pvowelclearness; //how vowels are kept clean (how much try to avoid "mixed" vowels) + unsigned char Pcenterfreq, Poctavesfreq; //the center frequency of the res. func., and the number of octaves - struct { struct { - unsigned char freq,amp,q;//frequency,amplitude,Q - }formants[FF_MAX_FORMANTS]; - }Pvowels[FF_MAX_VOWELS]; + struct { + unsigned char freq, amp, q; //frequency,amplitude,Q + } formants[FF_MAX_FORMANTS]; + } Pvowels[FF_MAX_VOWELS]; - unsigned char Psequencesize;//how many vowels are in the sequence - unsigned char Psequencestretch;//how the sequence is stretched (how the input from filter envelopes/LFOs/etc. is "stretched") - unsigned char Psequencereversed;//if the input from filter envelopes/LFOs/etc. is reversed(negated) - struct { - unsigned char nvowel;//the vowel from the position - } Psequence[FF_MAX_SEQUENCE]; + unsigned char Psequencesize; //how many vowels are in the sequence + unsigned char Psequencestretch; //how the sequence is stretched (how the input from filter envelopes/LFOs/etc. is "stretched") + unsigned char Psequencereversed; //if the input from filter envelopes/LFOs/etc. is reversed(negated) + struct { + unsigned char nvowel; //the vowel from the position + } Psequence[FF_MAX_SEQUENCE]; - REALTYPE getcenterfreq(); - REALTYPE getoctavesfreq(); - REALTYPE getfreqpos(REALTYPE freq); - REALTYPE getfreqx(REALTYPE x); + REALTYPE getcenterfreq(); + REALTYPE getoctavesfreq(); + REALTYPE getfreqpos(REALTYPE freq); + REALTYPE getfreqx(REALTYPE x); - void formantfilterH(int nvowel,int nfreqs,REALTYPE *freqs);//used by UI + void formantfilterH(int nvowel, int nfreqs, REALTYPE *freqs); //used by UI - REALTYPE getformantfreq(unsigned char freq); - REALTYPE getformantamp(unsigned char amp); - REALTYPE getformantq(unsigned char q); + REALTYPE getformantfreq(unsigned char freq); + REALTYPE getformantamp(unsigned char amp); + REALTYPE getformantq(unsigned char q); - bool changed; + bool changed; -private: - void defaults(int n); + private: + void defaults(int n); - //stored default parameters - unsigned char Dtype; - unsigned char Dfreq; - unsigned char Dq; + //stored default parameters + unsigned char Dtype; + unsigned char Dfreq; + unsigned char Dq; }; #endif diff --git a/plugins/zynaddsubfx/src/Params/LFOParams.cpp b/plugins/zynaddsubfx/src/Params/LFOParams.cpp index a124c5937..3cfc37fc8 100644 --- a/plugins/zynaddsubfx/src/Params/LFOParams.cpp +++ b/plugins/zynaddsubfx/src/Params/LFOParams.cpp @@ -27,9 +27,16 @@ int LFOParams::time; -LFOParams::LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOtype_,char Prandomness_, char Pdelay_,char Pcontinous_,char fel_):Presets() +LFOParams::LFOParams(char Pfreq_, + char Pintensity_, + char Pstartphase_, + char PLFOtype_, + char Prandomness_, + char Pdelay_, + char Pcontinous_, + char fel_):Presets() { - switch (fel_) { + switch(fel_) { case 0: setpresettype("Plfofrequency"); break; @@ -39,61 +46,60 @@ LFOParams::LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOty case 2: setpresettype("Plfofilter"); break; - }; - Dfreq=Pfreq_; - Dintensity=Pintensity_; - Dstartphase=Pstartphase_; - DLFOtype=PLFOtype_; - Drandomness=Prandomness_; - Ddelay=Pdelay_; - Dcontinous=Pcontinous_; - fel=fel_; - time=0; + } + Dfreq = Pfreq_; + Dintensity = Pintensity_; + Dstartphase = Pstartphase_; + DLFOtype = PLFOtype_; + Drandomness = Prandomness_; + Ddelay = Pdelay_; + Dcontinous = Pcontinous_; + fel = fel_; + time = 0; defaults(); -}; +} LFOParams::~LFOParams() -{ -}; +{} void LFOParams::defaults() { - Pfreq=Dfreq/127.0; - Pintensity=Dintensity; - Pstartphase=Dstartphase; - PLFOtype=DLFOtype; - Prandomness=Drandomness; - Pdelay=Ddelay; - Pcontinous=Dcontinous; - Pfreqrand=0; - Pstretch=64; -}; + Pfreq = Dfreq / 127.0; + Pintensity = Dintensity; + Pstartphase = Dstartphase; + PLFOtype = DLFOtype; + Prandomness = Drandomness; + Pdelay = Ddelay; + Pcontinous = Dcontinous; + Pfreqrand = 0; + Pstretch = 64; +} void LFOParams::add2XML(XMLwrapper *xml) { - xml->addparreal("freq",Pfreq); - xml->addpar("intensity",Pintensity); - xml->addpar("start_phase",Pstartphase); - xml->addpar("lfo_type",PLFOtype); - xml->addpar("randomness_amplitude",Prandomness); - xml->addpar("randomness_frequency",Pfreqrand); - xml->addpar("delay",Pdelay); - xml->addpar("stretch",Pstretch); - xml->addparbool("continous",Pcontinous); -}; + xml->addparreal("freq", Pfreq); + xml->addpar("intensity", Pintensity); + xml->addpar("start_phase", Pstartphase); + xml->addpar("lfo_type", PLFOtype); + xml->addpar("randomness_amplitude", Prandomness); + xml->addpar("randomness_frequency", Pfreqrand); + xml->addpar("delay", Pdelay); + xml->addpar("stretch", Pstretch); + xml->addparbool("continous", Pcontinous); +} void LFOParams::getfromXML(XMLwrapper *xml) { - Pfreq=xml->getparreal("freq",Pfreq,0.0,1.0); - Pintensity=xml->getpar127("intensity",Pintensity); - Pstartphase=xml->getpar127("start_phase",Pstartphase); - PLFOtype=xml->getpar127("lfo_type",PLFOtype); - Prandomness=xml->getpar127("randomness_amplitude",Prandomness); - Pfreqrand=xml->getpar127("randomness_frequency",Pfreqrand); - Pdelay=xml->getpar127("delay",Pdelay); - Pstretch=xml->getpar127("stretch",Pstretch); - Pcontinous=xml->getparbool("continous",Pcontinous); -}; + Pfreq = xml->getparreal("freq", Pfreq, 0.0, 1.0); + Pintensity = xml->getpar127("intensity", Pintensity); + Pstartphase = xml->getpar127("start_phase", Pstartphase); + PLFOtype = xml->getpar127("lfo_type", PLFOtype); + Prandomness = xml->getpar127("randomness_amplitude", Prandomness); + Pfreqrand = xml->getpar127("randomness_frequency", Pfreqrand); + Pdelay = xml->getpar127("delay", Pdelay); + Pstretch = xml->getpar127("stretch", Pstretch); + Pcontinous = xml->getparbool("continous", Pcontinous); +} diff --git a/plugins/zynaddsubfx/src/Params/LFOParams.h b/plugins/zynaddsubfx/src/Params/LFOParams.h index a650d27f3..6a7dcd915 100644 --- a/plugins/zynaddsubfx/src/Params/LFOParams.h +++ b/plugins/zynaddsubfx/src/Params/LFOParams.h @@ -28,38 +28,45 @@ class LFOParams:public Presets { -public: - LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOtype_,char Prandomness_, char Pdelay_,char Pcontinous,char fel_); - ~LFOParams(); + public: + LFOParams(char Pfreq_, + char Pintensity_, + char Pstartphase_, + char PLFOtype_, + char Prandomness_, + char Pdelay_, + char Pcontinous, + char fel_); + ~LFOParams(); - void add2XML(XMLwrapper *xml); - void defaults(); - /**Loads the LFO from the xml*/ - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + /**Loads the LFO from the xml*/ + void getfromXML(XMLwrapper *xml); - /* MIDI Parameters*/ - REALTYPE Pfreq; /**ADvsPAD=true; + resonance = new Resonance(); + oscilgen = new OscilGen(fft_, resonance); + oscilgen->ADvsPAD = true; - FreqEnvelope=new EnvelopeParams(0,0); - FreqEnvelope->ASRinit(64,50,64,60); - FreqLfo=new LFOParams(70,0,64,0,0,0,0,0); + FreqEnvelope = new EnvelopeParams(0, 0); + FreqEnvelope->ASRinit(64, 50, 64, 60); + FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0); - AmpEnvelope=new EnvelopeParams(64,1); - AmpEnvelope->ADSRinit_dB(0,40,127,25); - AmpLfo=new LFOParams(80,0,64,0,0,0,0,1); + AmpEnvelope = new EnvelopeParams(64, 1); + AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); + AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1); - GlobalFilter=new FilterParams(2,94,40); - FilterEnvelope=new EnvelopeParams(0,1); - FilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); - FilterLfo=new LFOParams(80,0,64,0,0,0,0,2); + GlobalFilter = new FilterParams(2, 94, 40); + FilterEnvelope = new EnvelopeParams(0, 1); + FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); + FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2); - for (int i=0;idefaults(); oscilgen->defaults(); - Phrpos.type=0; - Phrpos.par1=64; - Phrpos.par2=64; - Phrpos.par3=0; + Phrpos.type = 0; + Phrpos.par1 = 64; + Phrpos.par2 = 64; + Phrpos.par3 = 0; - Pquality.samplesize=3; - Pquality.basenote=4; - Pquality.oct=3; - Pquality.smpoct=2; + Pquality.samplesize = 3; + Pquality.basenote = 4; + Pquality.oct = 3; + Pquality.smpoct = 2; - PStereo=1;//stereo + PStereo = 1; //stereo /* Frequency Global Parameters */ - Pfixedfreq=0; - PfixedfreqET=0; - PDetune=8192;//zero - PCoarseDetune=0; - PDetuneType=1; + Pfixedfreq = 0; + PfixedfreqET = 0; + PDetune = 8192; //zero + PCoarseDetune = 0; + PDetuneType = 1; FreqEnvelope->defaults(); FreqLfo->defaults(); /* Amplitude Global Parameters */ - PVolume=90; - PPanning=64;//center - PAmpVelocityScaleFunction=64; + PVolume = 90; + PPanning = 64; //center + PAmpVelocityScaleFunction = 64; AmpEnvelope->defaults(); AmpLfo->defaults(); - PPunchStrength=0; - PPunchTime=60; - PPunchStretch=64; - PPunchVelocitySensing=72; + PPunchStrength = 0; + PPunchTime = 60; + PPunchStretch = 64; + PPunchVelocitySensing = 72; /* Filter Global Parameters*/ - PFilterVelocityScale=64; - PFilterVelocityScaleFunction=64; + PFilterVelocityScale = 64; + PFilterVelocityScaleFunction = 64; GlobalFilter->defaults(); FilterEnvelope->defaults(); FilterLfo->defaults(); deletesamples(); -}; +} void PADnoteParameters::deletesample(int n) { - if ((n<0)||(n>=PAD_MAX_SAMPLES)) return; - if (sample[n].smp!=NULL) { - delete[]sample[n].smp; - sample[n].smp=NULL; - }; - sample[n].size=0; - sample[n].basefreq=440.0; -}; + if((n < 0) || (n >= PAD_MAX_SAMPLES)) + return; + if(sample[n].smp != NULL) { + delete[] sample[n].smp; + sample[n].smp = NULL; + } + sample[n].size = 0; + sample[n].basefreq = 440.0; +} void PADnoteParameters::deletesamples() { - for (int i=0;i1.0) { - x=1.0; - makezero=true; - }; - }; + x = (x - 0.5) * width + 0.5; + if(x < 0.0) { + x = 0.0; + makezero = true; + } + else { + if(x > 1.0) { + x = 1.0; + makezero = true; + } + } //compute the full profile or one half - switch (Php.onehalf) { + switch(Php.onehalf) { case 1: - x=x*0.5+0.5; + x = x * 0.5 + 0.5; break; case 2: - x=x*0.5; + x = x * 0.5; break; - }; + } - REALTYPE x_before_freq_mult=x; + REALTYPE x_before_freq_mult = x; //do the frequency multiplier - x*=freqmult; + x *= freqmult; //do the modulation of the profile - x+=sin(x_before_freq_mult*3.1415926*modfreq)*modpar1; - x=fmod(x+1000.0,1.0)*2.0-1.0; + x += sin(x_before_freq_mult * 3.1415926 * modfreq) * modpar1; + x = fmod(x + 1000.0, 1.0) * 2.0 - 1.0; //this is the base function of the profile REALTYPE f; - switch (Php.base.type) { + switch(Php.base.type) { case 1: - f=exp(-(x*x)*basepar); - if (f<0.4) f=0.0; - else f=1.0; + f = exp(-(x * x) * basepar); + if(f < 0.4) + f = 0.0; + else + f = 1.0; break; case 2: - f=exp(-(fabs(x))*sqrt(basepar)); + f = exp(-(fabs(x)) * sqrt(basepar)); break; default: - f=exp(-(x*x)*basepar); + f = exp(-(x * x) * basepar); break; - }; - if (makezero) f=0.0; + } + if(makezero) + f = 0.0; - REALTYPE amp=1.0; - origx=origx*2.0-1.0; + REALTYPE amp = 1.0; + origx = origx * 2.0 - 1.0; //compute the amplitude multiplier - switch (Php.amp.type) { + switch(Php.amp.type) { case 1: - amp=exp(-(origx*origx)*10.0*amppar1); + amp = exp(-(origx * origx) * 10.0 * amppar1); break; case 2: - amp=0.5*(1.0+cos(3.1415926*origx*sqrt(amppar1*4.0+1.0))); + amp = 0.5 * (1.0 + cos(3.1415926 * origx * sqrt(amppar1 * 4.0 + 1.0))); break; case 3: - amp=1.0/(pow(origx*(amppar1*2.0+0.8),14.0)+1.0); + amp = 1.0 / (pow(origx * (amppar1 * 2.0 + 0.8), 14.0) + 1.0); break; - }; + } //apply the amplitude multiplier - REALTYPE finalsmp=f; - if (Php.amp.type!=0) { - switch (Php.amp.mode) { + REALTYPE finalsmp = f; + if(Php.amp.type != 0) + switch(Php.amp.mode) { case 0: - finalsmp=amp*(1.0-amppar2)+finalsmp*amppar2; + finalsmp = amp * (1.0 - amppar2) + finalsmp * amppar2; break; case 1: - finalsmp*=amp*(1.0-amppar2)+amppar2; + finalsmp *= amp * (1.0 - amppar2) + amppar2; break; case 2: - finalsmp=finalsmp/(amp+pow(amppar2,4.0)*20.0+0.0001); + finalsmp = finalsmp / (amp + pow(amppar2, 4.0) * 20.0 + 0.0001); break; case 3: - finalsmp=amp/(finalsmp+pow(amppar2,4.0)*20.0+0.0001); + finalsmp = amp / (finalsmp + pow(amppar2, 4.0) * 20.0 + 0.0001); break; - }; - }; + } + ; - smp[i/supersample]+=finalsmp/supersample; - }; + smp[i / supersample] += finalsmp / supersample; + } //normalize the profile (make the max. to be equal to 1.0) - REALTYPE max=0.0; - for (int i=0;imax) max=smp[i]; - }; - if (max<0.00001) max=1.0; - for (int i=0;i max) + max = smp[i]; + } + if(max < 0.00001) + max = 1.0; + for(int i = 0; i < size; i++) + smp[i] /= max; - if (!Php.autoscale) return(0.5); + if(!Php.autoscale) + return 0.5; //compute the estimated perceived bandwidth - REALTYPE sum=0.0; - int i; - for (i=0;i=4.0) break; - }; + REALTYPE sum = 0.0; + int i; + for(i = 0; i < size / 2 - 2; i++) { + sum += smp[i] * smp[i] + smp[size - i - 1] * smp[size - i - 1]; + if(sum >= 4.0) + break; + } - REALTYPE result=1.0-2.0*i/(REALTYPE) size; - return(result); -}; + REALTYPE result = 1.0 - 2.0 * i / (REALTYPE) size; + return result; +} /* * Compute the real bandwidth in cents and returns it @@ -287,340 +306,412 @@ REALTYPE PADnoteParameters::getprofile(REALTYPE *smp,int size) */ REALTYPE PADnoteParameters::setPbandwidth(int Pbandwidth) { - this->Pbandwidth=Pbandwidth; - REALTYPE result=pow(Pbandwidth/1000.0,1.1); - result=pow(10.0,result*4.0)*0.25; - return(result); -}; + this->Pbandwidth = Pbandwidth; + REALTYPE result = pow(Pbandwidth / 1000.0, 1.1); + result = pow(10.0, result * 4.0) * 0.25; + return result; +} /* * Get the harmonic(overtone) position */ REALTYPE PADnoteParameters::getNhr(int n) { - REALTYPE result=1.0; - REALTYPE par1=pow(10.0,-(1.0-Phrpos.par1/255.0)*3.0); - REALTYPE par2=Phrpos.par2/255.0; + REALTYPE result = 1.0; + REALTYPE par1 = pow(10.0, -(1.0 - Phrpos.par1 / 255.0) * 3.0); + REALTYPE par2 = Phrpos.par2 / 255.0; - REALTYPE n0=n-1.0; - REALTYPE tmp=0.0; - int thresh=0; - switch (Phrpos.type) { + REALTYPE n0 = n - 1.0; + REALTYPE tmp = 0.0; + int thresh = 0; + switch(Phrpos.type) { case 1: - thresh=(int)(par2*par2*100.0)+1; - if (nget(harmonics,basefreq,false); + oscilgen->get(harmonics, basefreq, false); //normalize - REALTYPE max=0.0; - for (int i=0;imax) max=harmonics[i]; - if (max<0.000001) max=1; - for (int i=0;i max) + max = harmonics[i]; + if(max < 0.000001) + max = 1; + for(int i = 0; i < OSCIL_SIZE / 2; i++) + harmonics[i] /= max; - for (int nh=1;nhSAMPLE_RATE*0.49999) break; - if (realfreq<20.0) break; - if (harmonics[nh-1]<1e-4) continue; + for(int nh = 1; nh < OSCIL_SIZE / 2; nh++) { //for each harmonic + REALTYPE realfreq = getNhr(nh) * basefreq; + if(realfreq > SAMPLE_RATE * 0.49999) + break; + if(realfreq < 20.0) + break; + if(harmonics[nh - 1] < 1e-4) + continue; //compute the bandwidth of each harmonic - REALTYPE bandwidthcents=setPbandwidth(Pbandwidth); - REALTYPE bw=(pow(2.0,bandwidthcents/1200.0)-1.0)*basefreq/bwadjust; - REALTYPE power=1.0; - switch (Pbwscale) { + REALTYPE bandwidthcents = setPbandwidth(Pbandwidth); + REALTYPE bw = + (pow(2.0, bandwidthcents / 1200.0) - 1.0) * basefreq / bwadjust; + REALTYPE power = 1.0; + switch(Pbwscale) { case 0: - power=1.0; + power = 1.0; break; case 1: - power=0.0; + power = 0.0; break; case 2: - power=0.25; + power = 0.25; break; case 3: - power=0.5; + power = 0.5; break; case 4: - power=0.75; + power = 0.75; break; case 5: - power=1.5; + power = 1.5; break; case 6: - power=2.0; + power = 2.0; break; case 7: - power=-0.5; + power = -0.5; break; - }; - bw=bw*pow(realfreq/basefreq,power); - int ibw=(int)((bw/(SAMPLE_RATE*0.5)*size))+1; + } + bw = bw * pow(realfreq / basefreq, power); + int ibw = (int)((bw / (SAMPLE_RATE * 0.5) * size)) + 1; - REALTYPE amp=harmonics[nh-1]; - if (resonance->Penabled) amp*=resonance->getfreqresponse(realfreq); + REALTYPE amp = harmonics[nh - 1]; + if(resonance->Penabled) + amp *= resonance->getfreqresponse(realfreq); - if (ibw>profilesize) {//if the bandwidth is larger than the profilesize - REALTYPE rap=sqrt((REALTYPE)profilesize/(REALTYPE)ibw); - int cfreq=(int) (realfreq/(SAMPLE_RATE*0.5)*size)-ibw/2; - for (int i=0;i=size) break; - spectrum[spfreq]+=amp*profile[src]*rap; - }; - } else {//if the bandwidth is smaller than the profilesize - REALTYPE rap=sqrt((REALTYPE)ibw/(REALTYPE)profilesize); - REALTYPE ibasefreq=realfreq/(SAMPLE_RATE*0.5)*size; - for (int i=0;i=size-1) break; - spectrum[spfreq]+=amp*profile[i]*rap*(1.0-fspfreq); - spectrum[spfreq+1]+=amp*profile[i]*rap*fspfreq; - }; - }; - }; -}; + if(ibw > profilesize) { //if the bandwidth is larger than the profilesize + REALTYPE rap = sqrt((REALTYPE)profilesize / (REALTYPE)ibw); + int cfreq = + (int) (realfreq / (SAMPLE_RATE * 0.5) * size) - ibw / 2; + for(int i = 0; i < ibw; i++) { + int src = (int)(i * rap * rap); + int spfreq = i + cfreq; + if(spfreq < 0) + continue; + if(spfreq >= size) + break; + spectrum[spfreq] += amp * profile[src] * rap; + } + } + else { //if the bandwidth is smaller than the profilesize + REALTYPE rap = sqrt((REALTYPE)ibw / (REALTYPE)profilesize); + REALTYPE ibasefreq = realfreq / (SAMPLE_RATE * 0.5) * size; + for(int i = 0; i < profilesize; i++) { + REALTYPE idfreq = i / (REALTYPE)profilesize - 0.5; + idfreq *= ibw; + int spfreq = (int) (idfreq + ibasefreq); + REALTYPE fspfreq = fmod(idfreq + ibasefreq, 1.0); + if(spfreq <= 0) + continue; + if(spfreq >= size - 1) + break; + spectrum[spfreq] += amp * profile[i] * rap * (1.0 - fspfreq); + spectrum[spfreq + 1] += amp * profile[i] * rap * fspfreq; + } + } + } +} /* * Generates the long spectrum for non-Bandwidth modes (only amplitudes are generated; phases will be random) */ -void PADnoteParameters::generatespectrum_otherModes(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust) +void PADnoteParameters::generatespectrum_otherModes(REALTYPE *spectrum, + int size, + REALTYPE basefreq, + REALTYPE *profile, + int profilesize, + REALTYPE bwadjust) { - for (int i=0;iget(harmonics,basefreq,false); + oscilgen->get(harmonics, basefreq, false); //normalize - REALTYPE max=0.0; - for (int i=0;imax) max=harmonics[i]; - if (max<0.000001) max=1; - for (int i=0;i max) + max = harmonics[i]; + if(max < 0.000001) + max = 1; + for(int i = 0; i < OSCIL_SIZE / 2; i++) + harmonics[i] /= max; - for (int nh=1;nhSAMPLE_RATE*0.49999) break; - if (realfreq<20.0) break; + if(realfreq > SAMPLE_RATE * 0.49999) + break; + if(realfreq < 20.0) + break; // if (harmonics[nh-1]<1e-4) continue; - REALTYPE amp=harmonics[nh-1]; - if (resonance->Penabled) amp*=resonance->getfreqresponse(realfreq); - int cfreq=(int) (realfreq/(SAMPLE_RATE*0.5)*size); + REALTYPE amp = harmonics[nh - 1]; + if(resonance->Penabled) + amp *= resonance->getfreqresponse(realfreq); + int cfreq = (int) (realfreq / (SAMPLE_RATE * 0.5) * size); - spectrum[cfreq]=amp+1e-9; - }; + spectrum[cfreq] = amp + 1e-9; + } - if (Pmode!=1) { - int old=0; - for (int k=1;k1e-10) || (k==(size-1)) ) { - int delta=k-old; - REALTYPE val1=spectrum[old]; - REALTYPE val2=spectrum[k]; - REALTYPE idelta=1.0/delta; - for (int i=0;i 1e-10) || (k == (size - 1))) { + int delta = k - old; + REALTYPE val1 = spectrum[old]; + REALTYPE val2 = spectrum[k]; + REALTYPE idelta = 1.0 / delta; + for(int i = 0; i < delta; i++) { + REALTYPE x = idelta * i; + spectrum[old + i] = val1 * (1.0 - x) + val2 * x; + } + old = k; + } + } + } +} /* * Applies the parameters (i.e. computes all the samples, based on parameters); */ void PADnoteParameters::applyparameters(bool lockmutex) { - const int samplesize=(((int) 1)<<(Pquality.samplesize+14)); - int spectrumsize=samplesize/2; + const int samplesize = (((int) 1) << (Pquality.samplesize + 14)); + int spectrumsize = samplesize / 2; REALTYPE spectrum[spectrumsize]; - int profilesize=512; + int profilesize = 512; REALTYPE profile[profilesize]; - REALTYPE bwadjust=getprofile(profile,profilesize); + REALTYPE bwadjust = getprofile(profile, profilesize); // for (int i=0;ifreqs2smps(fftfreqs,newsample.smp);//that's all; here is the only ifft for the whole sample; no windows are used ;-) + newsample.smp[0] = 0.0; + for(int i = 1; i < spectrumsize; i++) { //randomize the phases + REALTYPE phase = RND * 6.29; + fftfreqs.c[i] = spectrum[i] * cos(phase); + fftfreqs.s[i] = spectrum[i] * sin(phase); + } + fft->freqs2smps(fftfreqs, newsample.smp); //that's all; here is the only ifft for the whole sample; no windows are used ;-) //normalize(rms) - REALTYPE rms=0.0; - for (int i=0;iinformation.PADsynth_used=true; + xml->setPadSynth(true); - xml->addparbool("stereo",PStereo); - xml->addpar("mode",Pmode); - xml->addpar("bandwidth",Pbandwidth); - xml->addpar("bandwidth_scale",Pbwscale); + xml->addparbool("stereo", PStereo); + xml->addpar("mode", Pmode); + xml->addpar("bandwidth", Pbandwidth); + xml->addpar("bandwidth_scale", Pbwscale); xml->beginbranch("HARMONIC_PROFILE"); - xml->addpar("base_type",Php.base.type); - xml->addpar("base_par1",Php.base.par1); - xml->addpar("frequency_multiplier",Php.freqmult); - xml->addpar("modulator_par1",Php.modulator.par1); - xml->addpar("modulator_frequency",Php.modulator.freq); - xml->addpar("width",Php.width); - xml->addpar("amplitude_multiplier_type",Php.amp.type); - xml->addpar("amplitude_multiplier_mode",Php.amp.mode); - xml->addpar("amplitude_multiplier_par1",Php.amp.par1); - xml->addpar("amplitude_multiplier_par2",Php.amp.par2); - xml->addparbool("autoscale",Php.autoscale); - xml->addpar("one_half",Php.onehalf); + xml->addpar("base_type", Php.base.type); + xml->addpar("base_par1", Php.base.par1); + xml->addpar("frequency_multiplier", Php.freqmult); + xml->addpar("modulator_par1", Php.modulator.par1); + xml->addpar("modulator_frequency", Php.modulator.freq); + xml->addpar("width", Php.width); + xml->addpar("amplitude_multiplier_type", Php.amp.type); + xml->addpar("amplitude_multiplier_mode", Php.amp.mode); + xml->addpar("amplitude_multiplier_par1", Php.amp.par1); + xml->addpar("amplitude_multiplier_par2", Php.amp.par2); + xml->addparbool("autoscale", Php.autoscale); + xml->addpar("one_half", Php.onehalf); xml->endbranch(); xml->beginbranch("OSCIL"); @@ -632,27 +723,27 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("HARMONIC_POSITION"); - xml->addpar("type",Phrpos.type); - xml->addpar("parameter1",Phrpos.par1); - xml->addpar("parameter2",Phrpos.par2); - xml->addpar("parameter3",Phrpos.par3); + xml->addpar("type", Phrpos.type); + xml->addpar("parameter1", Phrpos.par1); + xml->addpar("parameter2", Phrpos.par2); + xml->addpar("parameter3", Phrpos.par3); xml->endbranch(); xml->beginbranch("SAMPLE_QUALITY"); - xml->addpar("samplesize",Pquality.samplesize); - xml->addpar("basenote",Pquality.basenote); - xml->addpar("octaves",Pquality.oct); - xml->addpar("samples_per_octave",Pquality.smpoct); + xml->addpar("samplesize", Pquality.samplesize); + xml->addpar("basenote", Pquality.basenote); + xml->addpar("octaves", Pquality.oct); + xml->addpar("samples_per_octave", Pquality.smpoct); xml->endbranch(); xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addpar("volume",PVolume); - xml->addpar("panning",PPanning); - xml->addpar("velocity_sensing",PAmpVelocityScaleFunction); - xml->addpar("punch_strength",PPunchStrength); - xml->addpar("punch_time",PPunchTime); - xml->addpar("punch_stretch",PPunchStretch); - xml->addpar("punch_velocity_sensing",PPunchVelocitySensing); + xml->addpar("volume", PVolume); + xml->addpar("panning", PPanning); + xml->addpar("velocity_sensing", PAmpVelocityScaleFunction); + xml->addpar("punch_strength", PPunchStrength); + xml->addpar("punch_time", PPunchTime); + xml->addpar("punch_stretch", PPunchStretch); + xml->addpar("punch_velocity_sensing", PPunchVelocitySensing); xml->beginbranch("AMPLITUDE_ENVELOPE"); AmpEnvelope->add2XML(xml); @@ -665,11 +756,11 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addpar("fixed_freq",Pfixedfreq); - xml->addpar("fixed_freq_et",PfixedfreqET); - xml->addpar("detune",PDetune); - xml->addpar("coarse_detune",PCoarseDetune); - xml->addpar("detune_type",PDetuneType); + xml->addpar("fixed_freq", Pfixedfreq); + xml->addpar("fixed_freq_et", PfixedfreqET); + xml->addpar("detune", PDetune); + xml->addpar("coarse_detune", PCoarseDetune); + xml->addpar("detune_type", PDetuneType); xml->beginbranch("FREQUENCY_ENVELOPE"); FreqEnvelope->add2XML(xml); @@ -681,8 +772,8 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("FILTER_PARAMETERS"); - xml->addpar("velocity_sensing_amplitude",PFilterVelocityScale); - xml->addpar("velocity_sensing",PFilterVelocityScaleFunction); + xml->addpar("velocity_sensing_amplitude", PFilterVelocityScale); + xml->addpar("velocity_sensing", PFilterVelocityScaleFunction); xml->beginbranch("FILTER"); GlobalFilter->add2XML(xml); @@ -696,65 +787,75 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) FilterLfo->add2XML(xml); xml->endbranch(); xml->endbranch(); -}; +} void PADnoteParameters::getfromXML(XMLwrapper *xml) { - PStereo=xml->getparbool("stereo",PStereo); - Pmode=xml->getpar127("mode",0); - Pbandwidth=xml->getpar("bandwidth",Pbandwidth,0,1000); - Pbwscale=xml->getpar127("bandwidth_scale",Pbwscale); + PStereo = xml->getparbool("stereo", PStereo); + Pmode = xml->getpar127("mode", 0); + Pbandwidth = xml->getpar("bandwidth", Pbandwidth, 0, 1000); + Pbwscale = xml->getpar127("bandwidth_scale", Pbwscale); - if (xml->enterbranch("HARMONIC_PROFILE")) { - Php.base.type=xml->getpar127("base_type",Php.base.type); - Php.base.par1=xml->getpar127("base_par1",Php.base.par1); - Php.freqmult=xml->getpar127("frequency_multiplier",Php.freqmult); - Php.modulator.par1=xml->getpar127("modulator_par1",Php.modulator.par1); - Php.modulator.freq=xml->getpar127("modulator_frequency",Php.modulator.freq); - Php.width=xml->getpar127("width",Php.width); - Php.amp.type=xml->getpar127("amplitude_multiplier_type",Php.amp.type); - Php.amp.mode=xml->getpar127("amplitude_multiplier_mode",Php.amp.mode); - Php.amp.par1=xml->getpar127("amplitude_multiplier_par1",Php.amp.par1); - Php.amp.par2=xml->getpar127("amplitude_multiplier_par2",Php.amp.par2); - Php.autoscale=xml->getparbool("autoscale",Php.autoscale); - Php.onehalf=xml->getpar127("one_half",Php.onehalf); + if(xml->enterbranch("HARMONIC_PROFILE")) { + Php.base.type = xml->getpar127("base_type", Php.base.type); + Php.base.par1 = xml->getpar127("base_par1", Php.base.par1); + Php.freqmult = xml->getpar127("frequency_multiplier", + Php.freqmult); + Php.modulator.par1 = xml->getpar127("modulator_par1", + Php.modulator.par1); + Php.modulator.freq = xml->getpar127("modulator_frequency", + Php.modulator.freq); + Php.width = xml->getpar127("width", Php.width); + Php.amp.type = xml->getpar127("amplitude_multiplier_type", + Php.amp.type); + Php.amp.mode = xml->getpar127("amplitude_multiplier_mode", + Php.amp.mode); + Php.amp.par1 = xml->getpar127("amplitude_multiplier_par1", + Php.amp.par1); + Php.amp.par2 = xml->getpar127("amplitude_multiplier_par2", + Php.amp.par2); + Php.autoscale = xml->getparbool("autoscale", Php.autoscale); + Php.onehalf = xml->getpar127("one_half", Php.onehalf); xml->exitbranch(); - }; + } - if (xml->enterbranch("OSCIL")) { + if(xml->enterbranch("OSCIL")) { oscilgen->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("RESONANCE")) { + if(xml->enterbranch("RESONANCE")) { resonance->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("HARMONIC_POSITION")) { - Phrpos.type=xml->getpar127("type",Phrpos.type); - Phrpos.par1=xml->getpar("parameter1",Phrpos.par1,0,255); - Phrpos.par2=xml->getpar("parameter2",Phrpos.par2,0,255); - Phrpos.par3=xml->getpar("parameter3",Phrpos.par3,0,255); + if(xml->enterbranch("HARMONIC_POSITION")) { + Phrpos.type = xml->getpar127("type", Phrpos.type); + Phrpos.par1 = xml->getpar("parameter1", Phrpos.par1, 0, 255); + Phrpos.par2 = xml->getpar("parameter2", Phrpos.par2, 0, 255); + Phrpos.par3 = xml->getpar("parameter3", Phrpos.par3, 0, 255); xml->exitbranch(); - }; + } - if (xml->enterbranch("SAMPLE_QUALITY")) { - Pquality.samplesize=xml->getpar127("samplesize",Pquality.samplesize); - Pquality.basenote=xml->getpar127("basenote",Pquality.basenote); - Pquality.oct=xml->getpar127("octaves",Pquality.oct); - Pquality.smpoct=xml->getpar127("samples_per_octave",Pquality.smpoct); + if(xml->enterbranch("SAMPLE_QUALITY")) { + Pquality.samplesize = xml->getpar127("samplesize", Pquality.samplesize); + Pquality.basenote = xml->getpar127("basenote", Pquality.basenote); + Pquality.oct = xml->getpar127("octaves", Pquality.oct); + Pquality.smpoct = xml->getpar127("samples_per_octave", + Pquality.smpoct); xml->exitbranch(); - }; + } - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - PVolume=xml->getpar127("volume",PVolume); - PPanning=xml->getpar127("panning",PPanning); - PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",PAmpVelocityScaleFunction); - PPunchStrength=xml->getpar127("punch_strength",PPunchStrength); - PPunchTime=xml->getpar127("punch_time",PPunchTime); - PPunchStretch=xml->getpar127("punch_stretch",PPunchStretch); - PPunchVelocitySensing=xml->getpar127("punch_velocity_sensing",PPunchVelocitySensing); + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + PVolume = xml->getpar127("volume", PVolume); + PPanning = xml->getpar127("panning", PPanning); + PAmpVelocityScaleFunction = xml->getpar127("velocity_sensing", + PAmpVelocityScaleFunction); + PPunchStrength = xml->getpar127("punch_strength", PPunchStrength); + PPunchTime = xml->getpar127("punch_time", PPunchTime); + PPunchStretch = xml->getpar127("punch_stretch", PPunchStretch); + PPunchVelocitySensing = xml->getpar127("punch_velocity_sensing", + PPunchVelocitySensing); xml->enterbranch("AMPLITUDE_ENVELOPE"); AmpEnvelope->getfromXML(xml); @@ -765,14 +866,14 @@ void PADnoteParameters::getfromXML(XMLwrapper *xml) xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - Pfixedfreq=xml->getpar127("fixed_freq",Pfixedfreq); - PfixedfreqET=xml->getpar127("fixed_freq_et",PfixedfreqET); - PDetune=xml->getpar("detune",PDetune,0,16383); - PCoarseDetune=xml->getpar("coarse_detune",PCoarseDetune,0,16383); - PDetuneType=xml->getpar127("detune_type",PDetuneType); + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + Pfixedfreq = xml->getpar127("fixed_freq", Pfixedfreq); + PfixedfreqET = xml->getpar127("fixed_freq_et", PfixedfreqET); + PDetune = xml->getpar("detune", PDetune, 0, 16383); + PCoarseDetune = xml->getpar("coarse_detune", PCoarseDetune, 0, 16383); + PDetuneType = xml->getpar127("detune_type", PDetuneType); xml->enterbranch("FREQUENCY_ENVELOPE"); FreqEnvelope->getfromXML(xml); @@ -782,11 +883,14 @@ void PADnoteParameters::getfromXML(XMLwrapper *xml) FreqLfo->getfromXML(xml); xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - PFilterVelocityScale=xml->getpar127("velocity_sensing_amplitude",PFilterVelocityScale); - PFilterVelocityScaleFunction=xml->getpar127("velocity_sensing",PFilterVelocityScaleFunction); + if(xml->enterbranch("FILTER_PARAMETERS")) { + PFilterVelocityScale = xml->getpar127("velocity_sensing_amplitude", + PFilterVelocityScale); + PFilterVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + PFilterVelocityScaleFunction); xml->enterbranch("FILTER"); GlobalFilter->getfromXML(xml); @@ -800,7 +904,6 @@ void PADnoteParameters::getfromXML(XMLwrapper *xml) FilterLfo->getfromXML(xml); xml->exitbranch(); xml->exitbranch(); - }; -}; - + } +} diff --git a/plugins/zynaddsubfx/src/Params/PADnoteParameters.h b/plugins/zynaddsubfx/src/Params/PADnoteParameters.h index eacd676c8..dde2c6499 100644 --- a/plugins/zynaddsubfx/src/Params/PADnoteParameters.h +++ b/plugins/zynaddsubfx/src/Params/PADnoteParameters.h @@ -38,133 +38,145 @@ class PADnoteParameters:public Presets { -public: - PADnoteParameters(FFTwrapper *fft_,pthread_mutex_t *mutex_); - ~PADnoteParameters(); + public: + PADnoteParameters(FFTwrapper *fft_, pthread_mutex_t *mutex_); + ~PADnoteParameters(); - void defaults(); - void add2XML(XMLwrapper *xml); - void getfromXML(XMLwrapper *xml); + void defaults(); + void add2XML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); - //returns a value between 0.0-1.0 that represents the estimation perceived bandwidth - REALTYPE getprofile(REALTYPE *smp,int size); + //returns a value between 0.0-1.0 that represents the estimation perceived bandwidth + REALTYPE getprofile(REALTYPE *smp, int size); - //parameters + //parameters - //the mode: 0 - bandwidth, 1 - discrete (bandwidth=0), 2 - continous - //the harmonic profile is used only on mode 0 - unsigned char Pmode; + //the mode: 0 - bandwidth, 1 - discrete (bandwidth=0), 2 - continous + //the harmonic profile is used only on mode 0 + unsigned char Pmode; - //Harmonic profile (the frequency distribution of a single harmonic) - struct { - struct {//base function + //Harmonic profile (the frequency distribution of a single harmonic) + struct { + struct { //base function + unsigned char type; + unsigned char par1; + } base; + unsigned char freqmult; //frequency multiplier of the distribution + struct { //the modulator of the distribution + unsigned char par1; + unsigned char freq; + } modulator; + + unsigned char width; //the width of the resulting function after the modulation + struct { //the amplitude multiplier of the harmonic profile + unsigned char mode; + unsigned char type; + unsigned char par1; + unsigned char par2; + } amp; + bool autoscale; //if the scale of the harmonic profile is computed automaticaly + unsigned char onehalf; //what part of the base function is used to make the distribution + } Php; + + + unsigned int Pbandwidth; //the values are from 0 to 1000 + unsigned char Pbwscale; //how the bandwidth is increased according to the harmonic's frequency + + struct { //where are positioned the harmonics (on integer multimplier or different places) unsigned char type; - unsigned char par1; - }base; - unsigned char freqmult;//frequency multiplier of the distribution - struct {//the modulator of the distribution - unsigned char par1; - unsigned char freq; - }modulator; + unsigned char par1, par2, par3; //0..255 + } Phrpos; - unsigned char width;//the width of the resulting function after the modulation - struct {//the amplitude multiplier of the harmonic profile - unsigned char mode; - unsigned char type; - unsigned char par1; - unsigned char par2; - }amp; - bool autoscale;//if the scale of the harmonic profile is computed automaticaly - unsigned char onehalf;//what part of the base function is used to make the distribution - }Php; + struct { //quality of the samples (how many samples, the length of them,etc.) + unsigned char samplesize; + unsigned char basenote, oct, smpoct; + } Pquality; + //frequency parameters + //If the base frequency is fixed to 440 Hz + unsigned char Pfixedfreq; - unsigned int Pbandwidth;//the values are from 0 to 1000 - unsigned char Pbwscale;//how the bandwidth is increased according to the harmonic's frequency + /* Equal temperate (this is used only if the Pfixedfreq is enabled) + If this parameter is 0, the frequency is fixed (to 440 Hz); + if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ + unsigned char PfixedfreqET; + unsigned short int PDetune; //fine detune + unsigned short int PCoarseDetune; //coarse detune+octave + unsigned char PDetuneType; //detune type - struct {//where are positioned the harmonics (on integer multimplier or different places) - unsigned char type; - unsigned char par1,par2,par3;//0..255 - }Phrpos; + EnvelopeParams *FreqEnvelope; //Frequency Envelope + LFOParams *FreqLfo; //Frequency LFO - struct {//quality of the samples (how many samples, the length of them,etc.) - unsigned char samplesize; - unsigned char basenote,oct,smpoct; - } Pquality; + //Amplitude parameters + unsigned char PStereo; + /* Panning - 0 - random + 1 - left + 64 - center + 127 - right */ + unsigned char PPanning; - //frequency parameters - //If the base frequency is fixed to 440 Hz - unsigned char Pfixedfreq; + unsigned char PVolume; - /* Equal temperate (this is used only if the Pfixedfreq is enabled) - If this parameter is 0, the frequency is fixed (to 440 Hz); - if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ - unsigned char PfixedfreqET; - unsigned short int PDetune;//fine detune - unsigned short int PCoarseDetune;//coarse detune+octave - unsigned char PDetuneType;//detune type + unsigned char PAmpVelocityScaleFunction; - EnvelopeParams *FreqEnvelope; //Frequency Envelope - LFOParams *FreqLfo;//Frequency LFO + EnvelopeParams *AmpEnvelope; - //Amplitude parameters - unsigned char PStereo; - /* Panning - 0 - random - 1 - left - 64 - center - 127 - right */ - unsigned char PPanning; + LFOParams *AmpLfo; - unsigned char PVolume; + unsigned char PPunchStrength, PPunchTime, PPunchStretch, + PPunchVelocitySensing; - unsigned char PAmpVelocityScaleFunction; + //Filter Parameters + FilterParams *GlobalFilter; - EnvelopeParams *AmpEnvelope; + // filter velocity sensing + unsigned char PFilterVelocityScale; - LFOParams *AmpLfo; + // filter velocity sensing + unsigned char PFilterVelocityScaleFunction; - unsigned char PPunchStrength,PPunchTime,PPunchStretch,PPunchVelocitySensing; - - //Filter Parameters - FilterParams *GlobalFilter; - - // filter velocity sensing - unsigned char PFilterVelocityScale; - - // filter velocity sensing - unsigned char PFilterVelocityScaleFunction; - - EnvelopeParams *FilterEnvelope; - LFOParams *FilterLfo; + EnvelopeParams *FilterEnvelope; + LFOParams *FilterLfo; - REALTYPE setPbandwidth(int Pbandwidth);//returns the BandWidth in cents - REALTYPE getNhr(int n);//gets the n-th overtone position relatively to N harmonic + REALTYPE setPbandwidth(int Pbandwidth); //returns the BandWidth in cents + REALTYPE getNhr(int n); //gets the n-th overtone position relatively to N harmonic - void applyparameters(bool lockmutex); - void export2wav(std::string basefilename); + void applyparameters(bool lockmutex); + void export2wav(std::string basefilename); - OscilGen *oscilgen; - Resonance *resonance; + OscilGen *oscilgen; + Resonance *resonance; - struct { - int size; - REALTYPE basefreq; - REALTYPE *smp; - }sample[PAD_MAX_SAMPLES],newsample; + struct { + int size; + REALTYPE basefreq; + REALTYPE *smp; + } sample[PAD_MAX_SAMPLES], newsample; -private: - void generatespectrum_bandwidthMode(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust); - void generatespectrum_otherModes(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust); - void deletesamples(); - void deletesample(int n); + private: + void generatespectrum_bandwidthMode(REALTYPE *spectrum, + int size, + REALTYPE basefreq, + REALTYPE *profile, + int profilesize, + REALTYPE bwadjust); + void generatespectrum_otherModes(REALTYPE *spectrum, + int size, + REALTYPE basefreq, + REALTYPE *profile, + int profilesize, + REALTYPE bwadjust); + void deletesamples(); + void deletesample(int n); - FFTwrapper *fft; - pthread_mutex_t *mutex; + FFTwrapper *fft; + pthread_mutex_t *mutex; }; #endif + diff --git a/plugins/zynaddsubfx/src/Params/Presets.cpp b/plugins/zynaddsubfx/src/Params/Presets.cpp index 40c78c24d..b3cfd1610 100644 --- a/plugins/zynaddsubfx/src/Params/Presets.cpp +++ b/plugins/zynaddsubfx/src/Params/Presets.cpp @@ -26,113 +26,124 @@ Presets::Presets() { - type[0]=0; - nelement=-1; -}; + type[0] = 0; + nelement = -1; +} Presets::~Presets() -{ -}; +{} void Presets::setpresettype(const char *type) { - strcpy(this->type,type); -}; + strcpy(this->type, type); +} void Presets::copy(const char *name) { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); //used only for the clipboard - if (name==NULL) xml->minimal=false; + if(name == NULL) + xml->minimal = false; char type[MAX_PRESETTYPE_SIZE]; - strcpy(type,this->type); - if (nelement!=-1) strcat(type,"n"); - if (name==NULL) { - if (strstr(type,"Plfo")!=NULL) strcpy(type,"Plfo"); - }; + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); + if(name == NULL) + if(strstr(type, "Plfo") != NULL) + strcpy(type, "Plfo"); + ; xml->beginbranch(type); - if (nelement==-1) add2XML(xml); - else add2XMLsection(xml,nelement); + if(nelement == -1) + add2XML(xml); + else + add2XMLsection(xml, nelement); xml->endbranch(); - if (name==NULL) presetsstore.copyclipboard(xml,type); - else presetsstore.copypreset(xml,type,name); + if(name == NULL) + presetsstore.copyclipboard(xml, type); + else + presetsstore.copypreset(xml, type, name); - delete(xml); - nelement=-1; -}; + delete (xml); + nelement = -1; +} void Presets::paste(int npreset) { char type[MAX_PRESETTYPE_SIZE]; - strcpy(type,this->type); - if (nelement!=-1) strcat(type,"n"); - if (npreset==0) { - if (strstr(type,"Plfo")!=NULL) strcpy(type,"Plfo"); - }; + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); + if(npreset == 0) + if(strstr(type, "Plfo") != NULL) + strcpy(type, "Plfo"); + ; - XMLwrapper *xml=new XMLwrapper(); - if (npreset==0) { - if (!checkclipboardtype()) { - nelement=-1; - delete(xml); + XMLwrapper *xml = new XMLwrapper(); + if(npreset == 0) { + if(!checkclipboardtype()) { + nelement = -1; + delete (xml); return; - }; - if (!presetsstore.pasteclipboard(xml)) { - delete(xml); - nelement=-1; + } + if(!presetsstore.pasteclipboard(xml)) { + delete (xml); + nelement = -1; return; - }; - } else { - if (!presetsstore.pastepreset(xml,npreset)) { - delete(xml); - nelement=-1; + } + } + else { + if(!presetsstore.pastepreset(xml, npreset)) { + delete (xml); + nelement = -1; return; - }; - }; + } + } - if (xml->enterbranch(type)==0) { - nelement=-1; + if(xml->enterbranch(type) == 0) { + nelement = -1; return; - }; - if (nelement==-1) { + } + if(nelement == -1) { defaults(); getfromXML(xml); - } else { + } + else { defaults(nelement); - getfromXMLsection(xml,nelement); - }; + getfromXMLsection(xml, nelement); + } xml->exitbranch(); - delete(xml); - nelement=-1; -}; + delete (xml); + nelement = -1; +} bool Presets::checkclipboardtype() { char type[MAX_PRESETTYPE_SIZE]; - strcpy(type,this->type); - if (nelement!=-1) strcat(type,"n"); + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); - return(presetsstore.checkclipboardtype(type)); -}; + return presetsstore.checkclipboardtype(type); +} void Presets::setelement(int n) { - nelement=n; -}; + nelement = n; +} void Presets::rescanforpresets() { presetsstore.rescanforpresets(type); -}; +} void Presets::deletepreset(int npreset) { presetsstore.deletepreset(npreset); -}; +} diff --git a/plugins/zynaddsubfx/src/Params/Presets.h b/plugins/zynaddsubfx/src/Params/Presets.h index 4f4bf78a4..8e143aed6 100644 --- a/plugins/zynaddsubfx/src/Params/Presets.h +++ b/plugins/zynaddsubfx/src/Params/Presets.h @@ -30,30 +30,30 @@ /**Presets and Clipboard management*/ class Presets { -public: - Presets(); - virtual ~Presets(); + public: + Presets(); + virtual ~Presets(); - void copy(const char *name);/**getXMLdata(); -}; + strcpy(clipboard.type, type); + if(clipboard.data != NULL) + free(clipboard.data); + clipboard.data = xml->getXMLdata(); +} bool PresetsStore::pasteclipboard(XMLwrapper *xml) { - if (clipboard.data!=NULL) xml->putXMLdata(clipboard.data); - else return(false); - return(true); -}; + if(clipboard.data != NULL) + xml->putXMLdata(clipboard.data); + else + return false; + return true; +} bool PresetsStore::checkclipboardtype(char *type) { //makes LFO's compatible - if ((strstr(type,"Plfo")!=NULL)&&(strstr(clipboard.type,"Plfo")!=NULL)) return(true); - return(strcmp(type,clipboard.type)==0); -}; + if((strstr(type, + "Plfo") != NULL) && (strstr(clipboard.type, "Plfo") != NULL)) + return true; + return strcmp(type, clipboard.type) == 0; +} //Presets management void PresetsStore::clearpresets() { - for (int i=0;iname)==NULL)||((p2->name)==NULL)) return(0); + struct PresetsStore::presetstruct *p1 = (PresetsStore::presetstruct *)a; + struct PresetsStore::presetstruct *p2 = (PresetsStore::presetstruct *)b; + if(((p1->name) == NULL) || ((p2->name) == NULL)) + return 0; - return(strcasecmp(p1->name,p2->name)<0); -}; + return strcasecmp(p1->name, p2->name) < 0; +} void PresetsStore::rescanforpresets(char *type) { clearpresets(); - int presetk=0; + int presetk = 0; char ftype[MAX_STRING_SIZE]; - snprintf(ftype,MAX_STRING_SIZE,".%s.xpz",type); + snprintf(ftype, MAX_STRING_SIZE, ".%s.xpz", type); - for (int i=0;id_name; - if (strstr(filename,ftype)==NULL) continue; + while((fn = readdir(dir))) { + const char *filename = fn->d_name; + if(strstr(filename, ftype) == NULL) + continue; - presets[presetk].file=new char [MAX_STRING_SIZE]; - presets[presetk].name=new char [MAX_STRING_SIZE]; - char tmpc=dirname[strlen(dirname)-1]; + presets[presetk].file = new char [MAX_STRING_SIZE]; + presets[presetk].name = new char [MAX_STRING_SIZE]; + char tmpc = dirname[strlen(dirname) - 1]; const char *tmps; - if ((tmpc=='/')||(tmpc=='\\')) tmps=""; - else tmps="/"; - snprintf(presets[presetk].file,MAX_STRING_SIZE,"%s%s%s",dirname,tmps,filename); - snprintf(presets[presetk].name,MAX_STRING_SIZE,"%s",filename); + if((tmpc == '/') || (tmpc == '\\')) + tmps = ""; + else + tmps = "/"; + snprintf(presets[presetk].file, + MAX_STRING_SIZE, + "%s%s%s", + dirname, + tmps, + filename); + snprintf(presets[presetk].name, MAX_STRING_SIZE, "%s", filename); - char *tmp=strstr(presets[presetk].name,ftype); - if (tmp!=NULL) tmp[0]='\0'; + char *tmp = strstr(presets[presetk].name, ftype); + if(tmp != NULL) + tmp[0] = '\0'; presetk++; - if (presetk>=MAX_PRESETS) return; - }; + if(presetk >= MAX_PRESETS) + return; + } closedir(dir); - }; + } //sort the presets - for (int j=0;j='0')&&(c<='9')) continue; - if ((c>='A')&&(c<='Z')) continue; - if ((c>='a')&&(c<='z')) continue; - if ((c=='-')||(c==' ')) continue; - tmpfilename[i]='_'; - }; + for(int i = 0; i < (int) strlen(tmpfilename); i++) { + char c = tmpfilename[i]; + if((c >= '0') && (c <= '9')) + continue; + if((c >= 'A') && (c <= 'Z')) + continue; + if((c >= 'a') && (c <= 'z')) + continue; + if((c == '-') || (c == ' ')) + continue; + tmpfilename[i] = '_'; + } - const char *dirname=config.cfg.presetsDirList[0]; - char tmpc=dirname[strlen(dirname)-1]; + const char *dirname = config.cfg.presetsDirList[0]; + char tmpc = dirname[strlen(dirname) - 1]; const char *tmps; - if ((tmpc=='/')||(tmpc=='\\')) tmps=""; - else tmps="/"; + if((tmpc == '/') || (tmpc == '\\')) + tmps = ""; + else + tmps = "/"; - snprintf(filename,MAX_STRING_SIZE,"%s%s%s.%s.xpz",dirname,tmps,name,type); + snprintf(filename, + MAX_STRING_SIZE, + "%s%s%s.%s.xpz", + dirname, + tmps, + name, + type); xml->saveXMLfile(filename); -}; +} bool PresetsStore::pastepreset(XMLwrapper *xml, int npreset) { npreset--; - if (npreset>=MAX_PRESETS) return(false); - char *filename=presets[npreset].file; - if (filename==NULL) return(false); - bool result=(xml->loadXMLfile(filename)>=0); - return(result); -}; + if(npreset >= MAX_PRESETS) + return false; + char *filename = presets[npreset].file; + if(filename == NULL) + return false; + bool result = (xml->loadXMLfile(filename) >= 0); + return result; +} void PresetsStore::deletepreset(int npreset) { npreset--; - if (npreset>=MAX_PRESETS) return; - char *filename=presets[npreset].file; - if (filename==NULL) return; + if(npreset >= MAX_PRESETS) + return; + char *filename = presets[npreset].file; + if(filename == NULL) + return; remove(filename); -}; +} diff --git a/plugins/zynaddsubfx/src/Params/PresetsStore.h b/plugins/zynaddsubfx/src/Params/PresetsStore.h index 8ff602beb..c81498231 100644 --- a/plugins/zynaddsubfx/src/Params/PresetsStore.h +++ b/plugins/zynaddsubfx/src/Params/PresetsStore.h @@ -28,36 +28,35 @@ class PresetsStore { -public: - PresetsStore(); - ~PresetsStore(); + public: + PresetsStore(); + ~PresetsStore(); - //Clipboard stuff - void copyclipboard(XMLwrapper *xml,char *type); - bool pasteclipboard(XMLwrapper *xml); - bool checkclipboardtype(char *type); + //Clipboard stuff + void copyclipboard(XMLwrapper *xml, char *type); + bool pasteclipboard(XMLwrapper *xml); + bool checkclipboardtype(char *type); - //presets stuff - void copypreset(XMLwrapper *xml,char *type, const char *name); - bool pastepreset(XMLwrapper *xml, int npreset); - void deletepreset(int npreset); + //presets stuff + void copypreset(XMLwrapper *xml, char *type, const char *name); + bool pastepreset(XMLwrapper *xml, int npreset); + void deletepreset(int npreset); - struct presetstruct { - char *file; - char *name; - }; - presetstruct presets[MAX_PRESETS]; + struct presetstruct { + char *file; + char *name; + }; + presetstruct presets[MAX_PRESETS]; - void rescanforpresets(char *type); + void rescanforpresets(char *type); -private: - struct { - char *data; - char type[MAX_PRESETTYPE_SIZE]; - } clipboard; - - void clearpresets(); + private: + struct { + char *data; + char type[MAX_PRESETTYPE_SIZE]; + } clipboard; + void clearpresets(); }; extern PresetsStore presetsstore; diff --git a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp index 963af0911..27fdb46d0 100644 --- a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp +++ b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp @@ -27,59 +27,58 @@ SUBnoteParameters::SUBnoteParameters():Presets() { setpresettype("Psubsyth"); - AmpEnvelope=new EnvelopeParams(64,1); - AmpEnvelope->ADSRinit_dB(0,40,127,25); - FreqEnvelope=new EnvelopeParams(64,0); - FreqEnvelope->ASRinit(30,50,64,60); - BandWidthEnvelope=new EnvelopeParams(64,0); - BandWidthEnvelope->ASRinit_bw(100,70,64,60); + AmpEnvelope = new EnvelopeParams(64, 1); + AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); + FreqEnvelope = new EnvelopeParams(64, 0); + FreqEnvelope->ASRinit(30, 50, 64, 60); + BandWidthEnvelope = new EnvelopeParams(64, 0); + BandWidthEnvelope->ASRinit_bw(100, 70, 64, 60); - GlobalFilter=new FilterParams(2,80,40); - GlobalFilterEnvelope=new EnvelopeParams(0,1); - GlobalFilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); + GlobalFilter = new FilterParams(2, 80, 40); + GlobalFilterEnvelope = new EnvelopeParams(0, 1); + GlobalFilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); defaults(); -}; +} void SUBnoteParameters::defaults() { - PVolume=96; - PPanning=64; - PAmpVelocityScaleFunction=90; + PVolume = 96; + PPanning = 64; + PAmpVelocityScaleFunction = 90; - Pfixedfreq=0; - PfixedfreqET=0; - Pnumstages=2; - Pbandwidth=40; - Phmagtype=0; - Pbwscale=64; - Pstereo=1; - Pstart=1; + Pfixedfreq = 0; + PfixedfreqET = 0; + Pnumstages = 2; + Pbandwidth = 40; + Phmagtype = 0; + Pbwscale = 64; + Pstereo = 1; + Pstart = 1; - PDetune=8192; - PCoarseDetune=0; - PDetuneType=1; - PFreqEnvelopeEnabled=0; - PBandWidthEnvelopeEnabled=0; + PDetune = 8192; + PCoarseDetune = 0; + PDetuneType = 1; + PFreqEnvelopeEnabled = 0; + PBandWidthEnvelopeEnabled = 0; - for (int n=0;ndefaults(); FreqEnvelope->defaults(); BandWidthEnvelope->defaults(); GlobalFilter->defaults(); GlobalFilterEnvelope->defaults(); - -}; +} @@ -90,154 +89,163 @@ SUBnoteParameters::~SUBnoteParameters() delete (BandWidthEnvelope); delete (GlobalFilter); delete (GlobalFilterEnvelope); -}; +} void SUBnoteParameters::add2XML(XMLwrapper *xml) { - xml->addpar("num_stages",Pnumstages); - xml->addpar("harmonic_mag_type",Phmagtype); - xml->addpar("start",Pstart); + xml->addpar("num_stages", Pnumstages); + xml->addpar("harmonic_mag_type", Phmagtype); + xml->addpar("start", Pstart); xml->beginbranch("HARMONICS"); - for (int i=0;iminimal)) continue; - xml->beginbranch("HARMONIC",i); - xml->addpar("mag",Phmag[i]); - xml->addpar("relbw",Phrelbw[i]); + for(int i = 0; i < MAX_SUB_HARMONICS; i++) { + if((Phmag[i] == 0) && (xml->minimal)) + continue; + xml->beginbranch("HARMONIC", i); + xml->addpar("mag", Phmag[i]); + xml->addpar("relbw", Phrelbw[i]); xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addparbool("stereo",Pstereo); - xml->addpar("volume",PVolume); - xml->addpar("panning",PPanning); - xml->addpar("velocity_sensing",PAmpVelocityScaleFunction); + xml->addparbool("stereo", Pstereo); + xml->addpar("volume", PVolume); + xml->addpar("panning", PPanning); + xml->addpar("velocity_sensing", PAmpVelocityScaleFunction); xml->beginbranch("AMPLITUDE_ENVELOPE"); AmpEnvelope->add2XML(xml); xml->endbranch(); xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addparbool("fixed_freq",Pfixedfreq); - xml->addpar("fixed_freq_et",PfixedfreqET); + xml->addparbool("fixed_freq", Pfixedfreq); + xml->addpar("fixed_freq_et", PfixedfreqET); - xml->addpar("detune",PDetune); - xml->addpar("coarse_detune",PCoarseDetune); - xml->addpar("detune_type",PDetuneType); + xml->addpar("detune", PDetune); + xml->addpar("coarse_detune", PCoarseDetune); + xml->addpar("detune_type", PDetuneType); - xml->addpar("bandwidth",Pbandwidth); - xml->addpar("bandwidth_scale",Pbwscale); + xml->addpar("bandwidth", Pbandwidth); + xml->addpar("bandwidth_scale", Pbwscale); - xml->addparbool("freq_envelope_enabled",PFreqEnvelopeEnabled); - if ((PFreqEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("freq_envelope_enabled", PFreqEnvelopeEnabled); + if((PFreqEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_ENVELOPE"); FreqEnvelope->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("band_width_envelope_enabled",PBandWidthEnvelopeEnabled); - if ((PBandWidthEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("band_width_envelope_enabled", PBandWidthEnvelopeEnabled); + if((PBandWidthEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("BANDWIDTH_ENVELOPE"); BandWidthEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("FILTER_PARAMETERS"); - xml->addparbool("enabled",PGlobalFilterEnabled); - if ((PGlobalFilterEnabled!=0)||(!xml->minimal)) { + xml->addparbool("enabled", PGlobalFilterEnabled); + if((PGlobalFilterEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER"); GlobalFilter->add2XML(xml); xml->endbranch(); - xml->addpar("filter_velocity_sensing",PGlobalFilterVelocityScaleFunction); - xml->addpar("filter_velocity_sensing_amplitude",PGlobalFilterVelocityScale); + xml->addpar("filter_velocity_sensing", + PGlobalFilterVelocityScaleFunction); + xml->addpar("filter_velocity_sensing_amplitude", + PGlobalFilterVelocityScale); xml->beginbranch("FILTER_ENVELOPE"); GlobalFilterEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); -}; +} void SUBnoteParameters::getfromXML(XMLwrapper *xml) { - Pnumstages=xml->getpar127("num_stages",Pnumstages); - Phmagtype=xml->getpar127("harmonic_mag_type",Phmagtype); - Pstart=xml->getpar127("start",Pstart); + Pnumstages = xml->getpar127("num_stages", Pnumstages); + Phmagtype = xml->getpar127("harmonic_mag_type", Phmagtype); + Pstart = xml->getpar127("start", Pstart); - if (xml->enterbranch("HARMONICS")) { - Phmag[0]=0; - for (int i=0;ienterbranch("HARMONIC",i)==0) continue; - Phmag[i]=xml->getpar127("mag",Phmag[i]); - Phrelbw[i]=xml->getpar127("relbw",Phrelbw[i]); + if(xml->enterbranch("HARMONICS")) { + Phmag[0] = 0; + for(int i = 0; i < MAX_SUB_HARMONICS; i++) { + if(xml->enterbranch("HARMONIC", i) == 0) + continue; + Phmag[i] = xml->getpar127("mag", Phmag[i]); + Phrelbw[i] = xml->getpar127("relbw", Phrelbw[i]); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - Pstereo=xml->getparbool("stereo",Pstereo); - PVolume=xml->getpar127("volume",PVolume); - PPanning=xml->getpar127("panning",PPanning); - PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",PAmpVelocityScaleFunction); - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + Pstereo = xml->getparbool("stereo", Pstereo); + PVolume = xml->getpar127("volume", PVolume); + PPanning = xml->getpar127("panning", PPanning); + PAmpVelocityScaleFunction = xml->getpar127("velocity_sensing", + PAmpVelocityScaleFunction); + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { AmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - Pfixedfreq=xml->getparbool("fixed_freq",Pfixedfreq); - PfixedfreqET=xml->getpar127("fixed_freq_et",PfixedfreqET); + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + Pfixedfreq = xml->getparbool("fixed_freq", Pfixedfreq); + PfixedfreqET = xml->getpar127("fixed_freq_et", PfixedfreqET); - PDetune=xml->getpar("detune",PDetune,0,16383); - PCoarseDetune=xml->getpar("coarse_detune",PCoarseDetune,0,16383); - PDetuneType=xml->getpar127("detune_type",PDetuneType); + PDetune = xml->getpar("detune", PDetune, 0, 16383); + PCoarseDetune = xml->getpar("coarse_detune", PCoarseDetune, 0, 16383); + PDetuneType = xml->getpar127("detune_type", PDetuneType); - Pbandwidth=xml->getpar127("bandwidth",Pbandwidth); - Pbwscale=xml->getpar127("bandwidth_scale",Pbwscale); + Pbandwidth = xml->getpar127("bandwidth", Pbandwidth); + Pbwscale = xml->getpar127("bandwidth_scale", Pbwscale); - PFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",PFreqEnvelopeEnabled); - if (xml->enterbranch("FREQUENCY_ENVELOPE")) { + PFreqEnvelopeEnabled = xml->getparbool("freq_envelope_enabled", + PFreqEnvelopeEnabled); + if(xml->enterbranch("FREQUENCY_ENVELOPE")) { FreqEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - PBandWidthEnvelopeEnabled=xml->getparbool("band_width_envelope_enabled",PBandWidthEnvelopeEnabled); - if (xml->enterbranch("BANDWIDTH_ENVELOPE")) { + PBandWidthEnvelopeEnabled = xml->getparbool( + "band_width_envelope_enabled", + PBandWidthEnvelopeEnabled); + if(xml->enterbranch("BANDWIDTH_ENVELOPE")) { BandWidthEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - PGlobalFilterEnabled=xml->getparbool("enabled",PGlobalFilterEnabled); - if (xml->enterbranch("FILTER")) { + if(xml->enterbranch("FILTER_PARAMETERS")) { + PGlobalFilterEnabled = xml->getparbool("enabled", PGlobalFilterEnabled); + if(xml->enterbranch("FILTER")) { GlobalFilter->getfromXML(xml); xml->exitbranch(); - }; + } - PGlobalFilterVelocityScaleFunction=xml->getpar127("filter_velocity_sensing",PGlobalFilterVelocityScaleFunction); - PGlobalFilterVelocityScale=xml->getpar127("filter_velocity_sensing_amplitude",PGlobalFilterVelocityScale); + PGlobalFilterVelocityScaleFunction = xml->getpar127( + "filter_velocity_sensing", + PGlobalFilterVelocityScaleFunction); + PGlobalFilterVelocityScale = xml->getpar127( + "filter_velocity_sensing_amplitude", + PGlobalFilterVelocityScale); - if (xml->enterbranch("FILTER_ENVELOPE")) { + if(xml->enterbranch("FILTER_ENVELOPE")) { GlobalFilterEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; -}; - - - + } +} diff --git a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.h b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.h index a0ebd8fde..57bc08004 100644 --- a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.h +++ b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.h @@ -31,76 +31,74 @@ class SUBnoteParameters:public Presets { -public: - SUBnoteParameters(); - ~SUBnoteParameters(); + public: + SUBnoteParameters(); + ~SUBnoteParameters(); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - //Parameters - //AMPLITUDE PARAMETRERS - unsigned char Pstereo;//0 for mono,1 for stereo - unsigned char PVolume; - unsigned char PPanning; - unsigned char PAmpVelocityScaleFunction; - EnvelopeParams *AmpEnvelope; + //Parameters + //AMPLITUDE PARAMETRERS + unsigned char Pstereo; //0 for mono,1 for stereo + unsigned char PVolume; + unsigned char PPanning; + unsigned char PAmpVelocityScaleFunction; + EnvelopeParams *AmpEnvelope; - //Frequency Parameters - unsigned short int PDetune; - unsigned short int PCoarseDetune; - unsigned char PDetuneType; - unsigned char PFreqEnvelopeEnabled; - EnvelopeParams *FreqEnvelope; - unsigned char PBandWidthEnvelopeEnabled; - EnvelopeParams *BandWidthEnvelope; + //Frequency Parameters + unsigned short int PDetune; + unsigned short int PCoarseDetune; + unsigned char PDetuneType; + unsigned char PFreqEnvelopeEnabled; + EnvelopeParams *FreqEnvelope; + unsigned char PBandWidthEnvelopeEnabled; + EnvelopeParams *BandWidthEnvelope; - //Filter Parameters (Global) - unsigned char PGlobalFilterEnabled; - FilterParams *GlobalFilter; - unsigned char PGlobalFilterVelocityScale; - unsigned char PGlobalFilterVelocityScaleFunction; - EnvelopeParams *GlobalFilterEnvelope; + //Filter Parameters (Global) + unsigned char PGlobalFilterEnabled; + FilterParams *GlobalFilter; + unsigned char PGlobalFilterVelocityScale; + unsigned char PGlobalFilterVelocityScaleFunction; + EnvelopeParams *GlobalFilterEnvelope; - //Other Parameters + //Other Parameters - //If the base frequency is fixed to 440 Hz - unsigned char Pfixedfreq; + //If the base frequency is fixed to 440 Hz + unsigned char Pfixedfreq; - /* Equal temperate (this is used only if the Pfixedfreq is enabled) - If this parameter is 0, the frequency is fixed (to 440 Hz); - if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ - unsigned char PfixedfreqET; + /* Equal temperate (this is used only if the Pfixedfreq is enabled) + If this parameter is 0, the frequency is fixed (to 440 Hz); + if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ + unsigned char PfixedfreqET; - //how many times the filters are applied - unsigned char Pnumstages; + //how many times the filters are applied + unsigned char Pnumstages; - //bandwidth - unsigned char Pbandwidth; + //bandwidth + unsigned char Pbandwidth; - //How the magnitudes are computed (0=linear,1=-60dB,2=-60dB) - unsigned char Phmagtype; + //How the magnitudes are computed (0=linear,1=-60dB,2=-60dB) + unsigned char Phmagtype; - //Magnitudes - unsigned char Phmag[MAX_SUB_HARMONICS]; + //Magnitudes + unsigned char Phmag[MAX_SUB_HARMONICS]; - //Relative BandWidth ("64"=1.0) - unsigned char Phrelbw[MAX_SUB_HARMONICS]; + //Relative BandWidth ("64"=1.0) + unsigned char Phrelbw[MAX_SUB_HARMONICS]; - //how much the bandwidth is increased according to lower/higher frequency; 64-default - unsigned char Pbwscale; + //how much the bandwidth is increased according to lower/higher frequency; 64-default + unsigned char Pbwscale; - //how the harmonics start("0"=0,"1"=random,"2"=1) - unsigned char Pstart; + //how the harmonics start("0"=0,"1"=random,"2"=1) + unsigned char Pstart; -private: + private: }; #endif - - diff --git a/plugins/zynaddsubfx/src/Samples/AuSample.cpp b/plugins/zynaddsubfx/src/Samples/AuSample.cpp index 5d95390cf..49f3a2887 100644 --- a/plugins/zynaddsubfx/src/Samples/AuSample.cpp +++ b/plugins/zynaddsubfx/src/Samples/AuSample.cpp @@ -20,9 +20,9 @@ */ #include "AuSample.h" -AuSample::AuSample(int length,REALTYPE fill) - : Sample(length,fill) {} +AuSample::AuSample(int length, REALTYPE fill) + :Sample(length, fill) {} -AuSample::AuSample(int length,const REALTYPE *input) - : Sample(length,input) {} +AuSample::AuSample(int length, const REALTYPE *input) + :Sample(length, input) {} diff --git a/plugins/zynaddsubfx/src/Samples/AuSample.h b/plugins/zynaddsubfx/src/Samples/AuSample.h index f82166482..cad4a786c 100644 --- a/plugins/zynaddsubfx/src/Samples/AuSample.h +++ b/plugins/zynaddsubfx/src/Samples/AuSample.h @@ -24,13 +24,12 @@ #include "Sample.h" #include "FqSample.h" -class AuSample : public Sample +class AuSample:public Sample { -public: - AuSample(int length,REALTYPE fill=0); - AuSample(int length,const REALTYPE *input); - FqSample getFqSample();/**\todo implement this*/ - + public: + AuSample(int length, REALTYPE fill = 0); + AuSample(int length, const REALTYPE *input); + FqSample getFqSample(); /**\todo implement this*/ }; #endif diff --git a/plugins/zynaddsubfx/src/Samples/FqSample.cpp b/plugins/zynaddsubfx/src/Samples/FqSample.cpp index 888dd0c45..94774047a 100644 --- a/plugins/zynaddsubfx/src/Samples/FqSample.cpp +++ b/plugins/zynaddsubfx/src/Samples/FqSample.cpp @@ -20,12 +20,12 @@ */ #include "FqSample.h" -FqSample::FqSample(int length,REALTYPE fill) - :Sample(length,fill) +FqSample::FqSample(int length, REALTYPE fill) + :Sample(length, fill) {} -FqSample::FqSample(int length,const REALTYPE *input) - : Sample(length,input) +FqSample::FqSample(int length, const REALTYPE *input) + :Sample(length, input) {} FqSample::~FqSample() diff --git a/plugins/zynaddsubfx/src/Samples/FqSample.h b/plugins/zynaddsubfx/src/Samples/FqSample.h index f81abe20f..fd31535cb 100644 --- a/plugins/zynaddsubfx/src/Samples/FqSample.h +++ b/plugins/zynaddsubfx/src/Samples/FqSample.h @@ -24,14 +24,14 @@ #include "FqSample.h" #include "Sample.h" -class FqSample : public Sample +class FqSample:public Sample { -public: - FqSample(int length,REALTYPE fill=0); - FqSample(int length,const REALTYPE *input); - ~FqSample(); - //FqSample &operator=(const FqSample &smp); - //float *dontuse(){return buffer;}; + public: + FqSample(int length, REALTYPE fill = 0); + FqSample(int length, const REALTYPE *input); + ~FqSample(); + //FqSample &operator=(const FqSample &smp); + //float *dontuse(){return buffer;}; }; #endif diff --git a/plugins/zynaddsubfx/src/Samples/Sample.cpp b/plugins/zynaddsubfx/src/Samples/Sample.cpp index c11bc6d56..ca5bdc128 100644 --- a/plugins/zynaddsubfx/src/Samples/Sample.cpp +++ b/plugins/zynaddsubfx/src/Samples/Sample.cpp @@ -24,34 +24,35 @@ /**\TODO start using pointer math here as these will be Frequency called * functions throughout the code*/ Sample::Sample(const Sample &smp) - : bufferSize(smp.bufferSize) + :bufferSize(smp.bufferSize) { - buffer=new REALTYPE[bufferSize]; - for (int i=0;i0) { - buffer=new REALTYPE[length]; - for (int i=0;i 0) { + buffer = new REALTYPE[length]; + for(int i = 0; i < length; ++i) + *(buffer + i) = *(input + i); + } + else { + buffer = new REALTYPE[1]; + bufferSize = 1; + *buffer = 0; } } @@ -62,58 +63,59 @@ Sample::~Sample() void Sample::clear() { - for (int i=0;ibufferSize!=smp.bufferSize) + if(this->bufferSize != smp.bufferSize) return false; - for(int i=0;ibuffer[i]!=smp.buffer[i]) + for(int i = 0; i < bufferSize; ++i) + if(this->buffer[i] != smp.buffer[i]) return false; return true; } -REALTYPE Sample::max()const +REALTYPE Sample::max() const { - REALTYPE max=-1500;//a good low considering that samples should store values -1.0 to 1.0 - for(int i=0;imax) - max=buffer[i]; + REALTYPE max = -1500; //a good low considering that samples should store values -1.0 to 1.0 + for(int i = 0; i < bufferSize; ++i) + if(buffer[i] > max) + max = buffer[i]; return max; } -REALTYPE Sample::min()const +REALTYPE Sample::min() const { - REALTYPE min=1500;//a good high considering that samples should store values -1.0 to 1.0 - for(int i=0;imax) - max=fabs(buffer[i]); + REALTYPE max = 0; + for(int i = 0; i < bufferSize; ++i) + if(fabs(buffer[i]) > max) + max = fabs(buffer[i]); return max; } + diff --git a/plugins/zynaddsubfx/src/Samples/Sample.h b/plugins/zynaddsubfx/src/Samples/Sample.h index c46786d8b..ebdae66e5 100644 --- a/plugins/zynaddsubfx/src/Samples/Sample.h +++ b/plugins/zynaddsubfx/src/Samples/Sample.h @@ -26,45 +26,43 @@ */ class Sample { -public: - Sample(const Sample &smp); - Sample(int length,REALTYPE fill=0); - Sample(int length,const REALTYPE *fill); - ~Sample(); - /**Fills the buffer with zeros*/ - void clear(); - /**States the size of the buffer - * @return the size of the buffer*/ - int size() const { - return bufferSize; - }; - /**Provides the indexing operator for non const Samples*/ - REALTYPE &operator[](int index) { - return *(buffer+index%bufferSize); - }; - /**Provides the indexing operator for const Samples*/ - const REALTYPE &operator[](int index)const { - return *(buffer+index%bufferSize); - }; - /**Provides the assignment operator*/ - void operator=(const Sample &smp); - /**Provides the == operator*/ - bool operator==(const Sample &smp)const; - /**Provides direct access to the buffer to allow for transition - * - * This method is like c_str() from the string class and should be used - * sparingly*/ - const REALTYPE *c_buf() { - return buffer; - }; - REALTYPE max()const; - REALTYPE min()const; - REALTYPE absMax()const; -private: - int bufferSize; - float *buffer; - - + public: + Sample(const Sample &smp); + Sample(int length, REALTYPE fill = 0); + Sample(int length, const REALTYPE *fill); + ~Sample(); + /**Fills the buffer with zeros*/ + void clear(); + /**States the size of the buffer + * @return the size of the buffer*/ + int size() const { + return bufferSize; + } + /**Provides the indexing operator for non const Samples*/ + REALTYPE &operator[](int index) { + return *(buffer + index % bufferSize); + } + /**Provides the indexing operator for const Samples*/ + const REALTYPE &operator[](int index) const { + return *(buffer + index % bufferSize); + } + /**Provides the assignment operator*/ + void operator=(const Sample &smp); + /**Provides the == operator*/ + bool operator==(const Sample &smp) const; + /**Provides direct access to the buffer to allow for transition + * + * This method is like c_str() from the string class and should be used + * sparingly*/ + const REALTYPE *c_buf() { + return buffer; + } + REALTYPE max() const; + REALTYPE min() const; + REALTYPE absMax() const; + private: + int bufferSize; + float *buffer; }; #endif diff --git a/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp b/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp index 42618c1ce..3bbab6c48 100644 --- a/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp +++ b/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp @@ -25,68 +25,69 @@ #include MIDIEvents::MIDIEvents() -{ -}; +{} MIDIEvents::~MIDIEvents() -{ -}; +{} /************** Track stuff ***************/ -void MIDIEvents::writeevent(list *l,event *ev) +void MIDIEvents::writeevent(list *l, event *ev) { - listpos *tmp=new listpos; - tmp->next=NULL; - tmp->ev=*ev; - if (l->current!=NULL) l->current->next=tmp; - else l->first=tmp; - l->current=tmp; + listpos *tmp = new listpos; + tmp->next = NULL; + tmp->ev = *ev; + if(l->current != NULL) + l->current->next = tmp; + else + l->first = tmp; + l->current = tmp; // printf("Wx%x ",(int) l->current); // printf("-> %d \n",l->current->ev.deltatime); l->size++; -}; +} -void MIDIEvents::readevent(list *l,event *ev) +void MIDIEvents::readevent(list *l, event *ev) { - if (l->current==NULL) { - ev->type=-1; + if(l->current == NULL) { + ev->type = -1; return; - }; - *ev=l->current->ev; - l->current=l->current->next; + } + *ev = l->current->ev; + l->current = l->current->next; //test - if (l->current!=NULL) { + if(l->current != NULL) { // ev->deltatime=10000; // printf("Rx%d\n",l->current->ev.deltatime); // printf("Rx%x ",(int) l->current); // printf("-> %d (next=%x) \n",(int)l->current->ev.deltatime,(int)l->current->next); - }; - -}; + } +} void MIDIEvents::rewindlist(list *l) { - l->current=l->first; -}; + l->current = l->first; +} void MIDIEvents::deletelist(list *l) { - l->current=l->first; - if (l->current==NULL) return; - while (l->current->next!=NULL) { - listpos *tmp=l->current; - l->current=l->current->next; - delete(tmp); - }; + l->current = l->first; + if(l->current == NULL) + return; + while(l->current->next != NULL) { + listpos *tmp = l->current; + l->current = l->current->next; + delete (tmp); + } deletelistreference(l); -}; +} void MIDIEvents::deletelistreference(list *l) { - l->current=l->first=NULL; - l->size=0; - l->length=0.0; -}; + l->current = l->first = NULL; + l->size = 0; + l->length = 0.0; +} + diff --git a/plugins/zynaddsubfx/src/Seq/MIDIEvents.h b/plugins/zynaddsubfx/src/Seq/MIDIEvents.h index 5b3b6f1e1..222404876 100644 --- a/plugins/zynaddsubfx/src/Seq/MIDIEvents.h +++ b/plugins/zynaddsubfx/src/Seq/MIDIEvents.h @@ -31,39 +31,38 @@ class MIDIEvents { friend class MIDIFile; -public: - MIDIEvents(); - ~MIDIEvents(); + public: + MIDIEvents(); + ~MIDIEvents(); -protected: + protected: - /* Events */ - struct event { - int deltatime; - int channel;//on what midi channel is - int type,par1,par2;//type=1 for note, type=2 for controller, type=255 for time messages - } tmpevent; - struct listpos { - event ev; - struct listpos *next; - }; - struct list { - listpos *first,*current; - int size;//how many events are - double length;//in seconds - }; - struct { - list track;//the stored track - list record;//the track being "recorded" from midi - } miditrack[NUM_MIDI_TRACKS]; + /* Events */ + struct event { + int deltatime; + int channel; //on what midi channel is + int type, par1, par2; //type=1 for note, type=2 for controller, type=255 for time messages + } tmpevent; + struct listpos { + event ev; + struct listpos *next; + }; + struct list { + listpos *first, *current; + int size; //how many events are + double length; //in seconds + }; + struct { + list track; //the stored track + list record; //the track being "recorded" from midi + } miditrack[NUM_MIDI_TRACKS]; - void writeevent(list *l,event *ev); - void readevent(list *l,event *ev); - - void rewindlist(list *l); - void deletelist(list *l); - void deletelistreference(list *l); + void writeevent(list *l, event *ev); + void readevent(list *l, event *ev); + void rewindlist(list *l); + void deletelist(list *l); + void deletelistreference(list *l); }; #endif diff --git a/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp b/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp index 61e748d3a..882d96e02 100644 --- a/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp +++ b/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp @@ -27,382 +27,395 @@ MIDIFile::MIDIFile() { - midifile=NULL; - midifilesize=0; - midifilek=0; - midieof=false; - me=NULL; -}; + midifile = NULL; + midifilesize = 0; + midifilek = 0; + midieof = false; + me = NULL; +} MIDIFile::~MIDIFile() { clearmidifile(); -}; +} int MIDIFile::loadfile(const char *filename) { clearmidifile(); - FILE *file=fopen(filename,"r"); - if (file==NULL) return(-1); + FILE *file = fopen(filename, "r"); + if(file == NULL) + return -1; char header[4]; - ZERO(header,4); - fread(header,4,1,file); + ZERO(header, 4); + fread(header, 4, 1, file); //test to see if this a midi file - if ((header[0]!='M')||(header[1]!='T')||(header[2]!='h')||(header[3]!='d')) { + if((header[0] != 'M') || (header[1] != 'T') || (header[2] != 'h') + || (header[3] != 'd')) { fclose(file); - return(-1); - }; + return -1; + } //get the filesize - fseek(file,0,SEEK_END); - midifilesize=ftell(file); + fseek(file, 0, SEEK_END); + midifilesize = ftell(file); rewind(file); - midifile=new unsigned char[midifilesize]; - ZERO(midifile,midifilesize); - fread(midifile,midifilesize,1,file); + midifile = new unsigned char[midifilesize]; + ZERO(midifile, midifilesize); + fread(midifile, midifilesize, 1, file); fclose(file); // for (int i=0;ime=me_; + this->me = me_; //read the header - int chunk=getint32();//MThd - if (chunk!=0x4d546864) return(-1); - int size=getint32(); - if (size!=6) return(-1);//header is always 6 bytes long + int chunk = getint32(); //MThd + if(chunk != 0x4d546864) + return -1; + int size = getint32(); + if(size != 6) + return -1; //header is always 6 bytes long - int format=getint16(); - printf("format %d\n",format); + int format = getint16(); + printf("format %d\n", format); - int ntracks=getint16();//this is always 1 if the format is "0" - printf("ntracks %d\n",ntracks); + int ntracks = getint16(); //this is always 1 if the format is "0" + printf("ntracks %d\n", ntracks); - int division=getint16(); - printf("division %d\n",division); - if (division>=0) {//delta time units in each a quater note + int division = getint16(); + printf("division %d\n", division); + if(division >= 0) { //delta time units in each a quater note // tick=???; - } else {//SMPTE (frames/second and ticks/frame) - printf("ERROR:in MIDIFile.C::parsemidifile() - SMPTE not implemented yet."); - }; + } + else //SMPTE (frames/second and ticks/frame) + printf( + "ERROR:in MIDIFile.C::parsemidifile() - SMPTE not implemented yet."); + ; - if (ntracks>=NUM_MIDI_TRACKS) ntracks=NUM_MIDI_TRACKS-1; + if(ntracks >= NUM_MIDI_TRACKS) + ntracks = NUM_MIDI_TRACKS - 1; - for (int n=0;nme=NULL; - return(0); -}; + this->me = NULL; + return 0; +} //private members int MIDIFile::parsetrack(int ntrack) { - printf("\n--==*Reading track %d **==--\n",ntrack); + printf("\n--==*Reading track %d **==--\n", ntrack); - int chunk=getint32();//MTrk - if (chunk!=0x4d54726b) return(-1); + int chunk = getint32(); //MTrk + if(chunk != 0x4d54726b) + return -1; - int size=getint32(); - printf("size = %d\n",size); + int size = getint32(); + printf("size = %d\n", size); - int oldmidifilek=midifilek; + int oldmidifilek = midifilek; - unsigned char lastmsg=0; - unsigned int dt=0; + unsigned char lastmsg = 0; + unsigned int dt = 0; - while (!midieof) { - unsigned int msgdeltatime=getvarint32(); + while(!midieof) { + unsigned int msgdeltatime = getvarint32(); /// printf("MSGDELTATIME = %d\n",msgdeltatime); // dt+=msgdeltatime; - int msg=peekbyte(); + int msg = peekbyte(); /// printf("raw msg=0x%x ",msg); - if (msg<0x80) { - msg=lastmsg; - } else { - lastmsg=msg; + if(msg < 0x80) + msg = lastmsg; + else { + lastmsg = msg; getbyte(); - }; + } /// printf("msg=0x%x\n",msg); // dt+=msgdeltatime; add_dt(ntrack, msgdeltatime); - unsigned int mtype,mlength; + unsigned int mtype, mlength; - switch (msg) { - case 0x80 ... 0x8f://note on off - parsenoteoff(ntrack,msg & 0x0f,dt); - dt=0; + switch(msg) { + case 0x80 ... 0x8f: //note on off + parsenoteoff(ntrack, msg & 0x0f, dt); + dt = 0; break; - case 0x90 ... 0x9f://note on (or note off) - parsenoteon(ntrack,msg & 0x0f,dt); - dt=0; + case 0x90 ... 0x9f: //note on (or note off) + parsenoteon(ntrack, msg & 0x0f, dt); + dt = 0; break; - case 0xa0 ... 0xaf://aftertouch - ignored + case 0xa0 ... 0xaf: //aftertouch - ignored skipnbytes(2); break; - case 0xb0 ... 0xbf://control change - parsecontrolchange(ntrack,msg & 0x0f,dt); - dt=0; + case 0xb0 ... 0xbf: //control change + parsecontrolchange(ntrack, msg & 0x0f, dt); + dt = 0; break; - case 0xc0 ... 0xcf://program change - ignored + case 0xc0 ... 0xcf: //program change - ignored skipnbytes(1); break; - case 0xd0 ... 0xdf://channel pressure - ignored + case 0xd0 ... 0xdf: //channel pressure - ignored skipnbytes(1); break; - case 0xe0 ... 0xef://channel mode messages + case 0xe0 ... 0xef: //channel mode messages skipnbytes(2); break; - case 0xf0://sysex - ignored - while (getbyte()!=0xf7) { - if (midieof) break; - }; + case 0xf0: //sysex - ignored + while(getbyte() != 0xf7) { + if(midieof) + break; + } break; - case 0xf7://sysex (another type) - ignored + case 0xf7: //sysex (another type) - ignored skipnbytes(getvarint32()); break; - case 0xff://meta-event - mtype=getbyte(); - mlength=getbyte(); - parsemetaevent(mtype,mlength); + case 0xff: //meta-event + mtype = getbyte(); + mlength = getbyte(); + parsemetaevent(mtype, mlength); break; default: getbyte(); - printf("UNKNOWN message! 0x%x\n",msg); - return(-1); + printf("UNKNOWN message! 0x%x\n", msg); + return -1; break; - }; + } - if (midieof) return(-1); + if(midieof) + return -1; - if ((midifilek-oldmidifilek)==size) break; - else if ((midifilek-oldmidifilek)>size) return(-1); + if((midifilek - oldmidifilek) == size) + break; + else + if((midifilek - oldmidifilek) > size) + return -1; // if (size!=6) return(-1);//header is always 6 bytes long - }; + } printf("End Track\n\n"); - return(0); -}; + return 0; +} -void MIDIFile::parsenoteoff(char ntrack,char chan,unsigned int dt) +void MIDIFile::parsenoteoff(char ntrack, char chan, unsigned int dt) { unsigned char note; - note=getbyte(); + note = getbyte(); - unsigned char noteoff_velocity=getbyte();//unused by zynaddsubfx - noteoff_velocity=0; - if (chan>=NUM_MIDI_CHANNELS) return; + unsigned char noteoff_velocity = getbyte(); //unused by zynaddsubfx + noteoff_velocity = 0; + if(chan >= NUM_MIDI_CHANNELS) + return; - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=1; - me->tmpevent.par1=note; - me->tmpevent.par2=0; - me->tmpevent.channel=chan; + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 1; + me->tmpevent.par1 = note; + me->tmpevent.par2 = 0; + me->tmpevent.channel = chan; - printf("Note off:%d \n",note); + printf("Note off:%d \n", note); ///test // ntrack=0; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); - -}; + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} -void MIDIFile::parsenoteon(char ntrack,char chan,unsigned int dt) +void MIDIFile::parsenoteon(char ntrack, char chan, unsigned int dt) { - unsigned char note,vel; - note=getbyte(); - vel=getbyte(); + unsigned char note, vel; + note = getbyte(); + vel = getbyte(); // printf("ntrack=%d\n",ntrack); - printf("[dt %d ] Note on:%d %d\n",dt,note,vel); + printf("[dt %d ] Note on:%d %d\n", dt, note, vel); - if (chan>=NUM_MIDI_CHANNELS) return; + if(chan >= NUM_MIDI_CHANNELS) + return; - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=1; - me->tmpevent.par1=note; - me->tmpevent.par2=vel; - me->tmpevent.channel=chan; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 1; + me->tmpevent.par1 = note; + me->tmpevent.par2 = vel; + me->tmpevent.channel = chan; + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} - - -}; - -void MIDIFile::parsecontrolchange(char ntrack,char chan,unsigned int dt) +void MIDIFile::parsecontrolchange(char ntrack, char chan, unsigned int dt) { - unsigned char control,value; - control=getbyte(); - value=getbyte(); + unsigned char control, value; + control = getbyte(); + value = getbyte(); - if (chan>=NUM_MIDI_CHANNELS) return; + if(chan >= NUM_MIDI_CHANNELS) + return; - printf("[dt %d] Control change:%d %d\n",dt,control,value); + printf("[dt %d] Control change:%d %d\n", dt, control, value); - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=2; - me->tmpevent.par1=control;//???????????? ma uit la Sequencer::recordnote() din varianele vechi de zyn - me->tmpevent.par2=value; - me->tmpevent.channel=chan; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 2; + me->tmpevent.par1 = control; //???????????? ma uit la Sequencer::recordnote() din varianele vechi de zyn + me->tmpevent.par2 = value; + me->tmpevent.channel = chan; + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} -}; - -void MIDIFile::parsepitchwheel(char ntrack,char chan, unsigned int dt) +void MIDIFile::parsepitchwheel(char ntrack, char chan, unsigned int dt) { - unsigned char valhi,vallo; - vallo=getbyte(); - valhi=getbyte(); + unsigned char valhi, vallo; + vallo = getbyte(); + valhi = getbyte(); - if (chan>=NUM_MIDI_CHANNELS) return; + if(chan >= NUM_MIDI_CHANNELS) + return; - int value=(int)valhi*128+vallo; + int value = (int)valhi * 128 + vallo; - printf("[dt %d] Pitch wheel:%d\n",dt,value); + printf("[dt %d] Pitch wheel:%d\n", dt, value); +} -}; - -void MIDIFile::parsemetaevent(unsigned char mtype,unsigned char mlength) +void MIDIFile::parsemetaevent(unsigned char mtype, unsigned char mlength) { - int oldmidifilek=midifilek; - printf("meta-event type=0x%x length=%d\n",mtype,mlength); + int oldmidifilek = midifilek; + printf("meta-event type=0x%x length=%d\n", mtype, mlength); - midifilek=oldmidifilek+mlength; - -}; + midifilek = oldmidifilek + mlength; +} void MIDIFile::add_dt(char ntrack, unsigned int dt) { - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=255; - me->tmpevent.par1=0; - me->tmpevent.par2=0; - me->tmpevent.channel=0; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); -}; + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 255; + me->tmpevent.par1 = 0; + me->tmpevent.par2 = 0; + me->tmpevent.channel = 0; + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} unsigned int MIDIFile::convertdt(unsigned int dt) { - double result=dt; - printf("DT=%d\n",dt); + double result = dt; + printf("DT=%d\n", dt); - return((int) (result*15.0)); -}; + return (int) (result * 15.0); +} void MIDIFile::clearmidifile() { - if (midifile!=NULL) delete(midifile); - midifile=NULL; - midifilesize=0; - midifilek=0; - midieof=false; - data.tick=0.05; -}; + if(midifile != NULL) + delete (midifile); + midifile = NULL; + midifilesize = 0; + midifilek = 0; + midieof = false; + data.tick = 0.05; +} unsigned char MIDIFile::getbyte() { - if (midifilek>=midifilesize) { - midieof=true; - return(0); - }; + if(midifilek >= midifilesize) { + midieof = true; + return 0; + } /// printf("(%d) ",midifile[midifilek]); - return(midifile[midifilek++]); -}; + return midifile[midifilek++]; +} unsigned char MIDIFile::peekbyte() { - if (midifilek>=midifilesize) { - midieof=true; - return(0); - }; - return(midifile[midifilek]); -}; + if(midifilek >= midifilesize) { + midieof = true; + return 0; + } + return midifile[midifilek]; +} unsigned int MIDIFile::getint32() { - unsigned int result=0; - for (int i=0;i<4;i++) { - result=result*256+getbyte(); - }; - if (midieof) result=0; - return(result); -}; + unsigned int result = 0; + for(int i = 0; i < 4; i++) + result = result * 256 + getbyte(); + ; + if(midieof) + result = 0; + return result; +} unsigned short int MIDIFile::getint16() { - unsigned short int result=0; - for (int i=0;i<2;i++) { - result=result*256+getbyte(); - }; - if (midieof) result=0; - return(result); -}; + unsigned short int result = 0; + for(int i = 0; i < 2; i++) + result = result * 256 + getbyte(); + ; + if(midieof) + result = 0; + return result; +} unsigned int MIDIFile::getvarint32() { - unsigned long result=0; + unsigned long result = 0; unsigned char b; /// printf("\n[start]"); - if ((result = getbyte()) & 0x80) { + if((result = getbyte()) & 0x80) { result &= 0x7f; - do { - b=getbyte(); + do { + b = getbyte(); result = (result << 7) + (b & 0x7f); - } while (b & 0x80); + } while(b & 0x80); } /// printf("[end - result= %d]\n",result); return result; -}; +} void MIDIFile::skipnbytes(int n) { - midifilek+=n; - if (midifilek>=midifilesize) { - midifilek=midifilesize-1; - midieof=true; - }; -}; + midifilek += n; + if(midifilek >= midifilesize) { + midifilek = midifilesize - 1; + midieof = true; + } +} diff --git a/plugins/zynaddsubfx/src/Seq/MIDIFile.h b/plugins/zynaddsubfx/src/Seq/MIDIFile.h index 7f831589f..374d98c1c 100644 --- a/plugins/zynaddsubfx/src/Seq/MIDIFile.h +++ b/plugins/zynaddsubfx/src/Seq/MIDIFile.h @@ -29,66 +29,64 @@ /**MIDI file loader*/ class MIDIFile { -public: - MIDIFile(); - ~MIDIFile(); + public: + MIDIFile(); + ~MIDIFile(); - /**Loads the given file - * @param filename The name of the file to load - * @return -1 if there is an error, otherwise 0*/ - int loadfile(const char *filename); + /**Loads the given file + * @param filename The name of the file to load + * @return -1 if there is an error, otherwise 0*/ + int loadfile(const char *filename); - //returns -1 if there is an error, otherwise 0 - int parsemidifile(MIDIEvents *me_); + //returns -1 if there is an error, otherwise 0 + int parsemidifile(MIDIEvents *me_); -private: - MIDIEvents *me; + private: + MIDIEvents *me; - unsigned char *midifile; - int midifilesize,midifilek; - bool midieof; + unsigned char *midifile; + int midifilesize, midifilek; + bool midieof; - //returns -1 if there is an error, otherwise 0 - int parsetrack(int ntrack); + //returns -1 if there is an error, otherwise 0 + int parsetrack(int ntrack); - void parsenoteoff(char ntrack,char chan,unsigned int dt); - void parsenoteon(char ntrack,char chan,unsigned int dt); - void parsecontrolchange(char ntrack,char chan,unsigned int dt); - void parsepitchwheel(char ntrack,char chan, unsigned int dt); - void parsemetaevent(unsigned char mtype,unsigned char mlength); + void parsenoteoff(char ntrack, char chan, unsigned int dt); + void parsenoteon(char ntrack, char chan, unsigned int dt); + void parsecontrolchange(char ntrack, char chan, unsigned int dt); + void parsepitchwheel(char ntrack, char chan, unsigned int dt); + void parsemetaevent(unsigned char mtype, unsigned char mlength); - void add_dt(char ntrack, unsigned int dt); + void add_dt(char ntrack, unsigned int dt); - void clearmidifile(); + void clearmidifile(); - //convert the delta-time to internal format - unsigned int convertdt(unsigned int dt); + //convert the delta-time to internal format + unsigned int convertdt(unsigned int dt); - /* Low Level MIDIfile functions */ + /* Low Level MIDIfile functions */ - //get a byte from the midifile - unsigned char getbyte(); + //get a byte from the midifile + unsigned char getbyte(); - //peek the current byte from the midifile - unsigned char peekbyte(); + //peek the current byte from the midifile + unsigned char peekbyte(); - //get a set of 4 bytes from the midifile - unsigned int getint32(); + //get a set of 4 bytes from the midifile + unsigned int getint32(); - //get a word of 2 bytes from the midifile - unsigned short int getint16(); + //get a word of 2 bytes from the midifile + unsigned short int getint16(); - //read a variable length quantity - unsigned int getvarint32(); + //read a variable length quantity + unsigned int getvarint32(); - //skip some bytes - void skipnbytes(int n); - - struct { - double tick;//how many seconds one tick has - - }data; + //skip some bytes + void skipnbytes(int n); + struct { + double tick; //how many seconds one tick has + } data; }; #endif diff --git a/plugins/zynaddsubfx/src/Seq/Sequencer.cpp b/plugins/zynaddsubfx/src/Seq/Sequencer.cpp index d0a32f1c4..cedc9249e 100644 --- a/plugins/zynaddsubfx/src/Seq/Sequencer.cpp +++ b/plugins/zynaddsubfx/src/Seq/Sequencer.cpp @@ -33,76 +33,85 @@ Sequencer::Sequencer() { - play=0; - for (int i=0;i1sec) sa elimin nota - if (ntrack==1) printf("_ %f %.2f (%d)\n",nextevent[(int)ntrack].time,playtime[(int)ntrack].abs,nextevent[(int)ntrack].ev.par2); + if(ntrack == 1) + printf("_ %f %.2f (%d)\n", nextevent[(int)ntrack].time, + playtime[(int)ntrack].abs, nextevent[(int)ntrack].ev.par2); - *type=nextevent[(int)ntrack].ev.type; - *par1=nextevent[(int)ntrack].ev.par1; - *par2=nextevent[(int)ntrack].ev.par2; - *midich=nextevent[(int)ntrack].ev.channel; + *type = nextevent[(int)ntrack].ev.type; + *par1 = nextevent[(int)ntrack].ev.par1; + *par2 = nextevent[(int)ntrack].ev.par2; + *midich = nextevent[(int)ntrack].ev.channel; - double dt=nextevent[(int)ntrack].ev.deltatime*0.0001*realplayspeed; - printf("zzzzzzzzzzzzzz[%d] %d\n",ntrack,nextevent[(int)ntrack].ev.deltatime); - nextevent[(int)ntrack].time+=dt; + double dt = nextevent[(int)ntrack].ev.deltatime * 0.0001 * realplayspeed; + printf("zzzzzzzzzzzzzz[%d] %d\n", + ntrack, + nextevent[(int)ntrack].ev.deltatime); + nextevent[(int)ntrack].time += dt; // printf("%f - %d %d \n",nextevent[ntrack].time,par1,par2); - return(0);//?? sau 1 -}; + return 0; //?? sau 1 +} /************** Timer stuff ***************/ void Sequencer::resettime(timestruct *t) { - t->abs=0.0; - t->rel=0.0; + t->abs = 0.0; + t->rel = 0.0; timeval tval; - t->last=0.0; + t->last = 0.0; #ifndef OS_WINDOWS - if (gettimeofday(&tval,NULL)==0) - t->last=tval.tv_sec+tval.tv_usec*0.000001; + if(gettimeofday(&tval, NULL) == 0) + t->last = tval.tv_sec + tval.tv_usec * 0.000001; #endif - -}; +} void Sequencer::updatecounter(timestruct *t) { timeval tval; - double current=0.0; + double current = 0.0; #ifndef OS_WINDOWS - if (gettimeofday(&tval,NULL)==0) - current=tval.tv_sec+tval.tv_usec*0.000001; + if(gettimeofday(&tval, NULL) == 0) + current = tval.tv_sec + tval.tv_usec * 0.000001; #endif - t->rel=current - t->last; - t->abs+=t->rel; - t->last=current; + t->rel = current - t->last; + t->abs += t->rel; + t->last = current; // printf("%f %f %f\n",t->last,t->abs,t->rel); -}; +} void Sequencer::setplayspeed(int speed) { - playspeed=speed; - realplayspeed=pow(10.0,speed/128.0); -}; + playspeed = speed; + realplayspeed = pow(10.0, speed / 128.0); +} diff --git a/plugins/zynaddsubfx/src/Seq/Sequencer.h b/plugins/zynaddsubfx/src/Seq/Sequencer.h index 7798c9943..dd2d75613 100644 --- a/plugins/zynaddsubfx/src/Seq/Sequencer.h +++ b/plugins/zynaddsubfx/src/Seq/Sequencer.h @@ -30,61 +30,60 @@ * \todo restructure some of this code*/ class Sequencer:public MIDIEvents { -public: - /**Constructor*/ - Sequencer(); - /**Destructor*/ - ~Sequencer(); + public: + /**Constructor*/ + Sequencer(); + /**Destructor*/ + ~Sequencer(); - //these functions are called by the master and are ignored if the recorder/player are stopped - void recordnote(char chan, char note, char vel); - void recordcontroller(char chan,unsigned int type,int par); + //these functions are called by the master and are ignored if the recorder/player are stopped + void recordnote(char chan, char note, char vel); + void recordcontroller(char chan, unsigned int type, int par); - /**Gets an event \todo better description - * - * this is only for player - * @return 1 if this must be called at least once more - * 0 if there are no more notes for the current time - * -1 if there are no notes*/ - int getevent(char ntrack, int *midich,int *type,int *par1, int *par2); + /**Gets an event \todo better description + * + * this is only for player + * @return 1 if this must be called at least once more + * 0 if there are no more notes for the current time + * -1 if there are no notes*/ + int getevent(char ntrack, int *midich, int *type, int *par1, int *par2); - /**Imports a given midifile - * @return 0 if ok or -1 if there is a error loading file*/ - int importmidifile(const char *filename); + /**Imports a given midifile + * @return 0 if ok or -1 if there is a error loading file*/ + int importmidifile(const char *filename); - void startplay(); - void stopplay(); + void startplay(); + void stopplay(); - int play; - int playspeed;//viteza de rulare (0.1x-10x), 0=1.0x, 128=10x - void setplayspeed(int speed); + int play; + int playspeed; //viteza de rulare (0.1x-10x), 0=1.0x, 128=10x + void setplayspeed(int speed); -private: + private: - MIDIFile midifile; + MIDIFile midifile; - /* Timer */ - struct timestruct { - double abs;//the time from the begining of the track - double rel;//the time difference between the last and the current event - double last;//the time of the last event (absolute, since 1 Jan 1970) - //these must be double, because the float's precision is too low - //and all these represent the time in seconds - } playtime[NUM_MIDI_TRACKS]; + /* Timer */ + struct timestruct { + double abs; //the time from the begining of the track + double rel; //the time difference between the last and the current event + double last; //the time of the last event (absolute, since 1 Jan 1970) + //these must be double, because the float's precision is too low + //and all these represent the time in seconds + } playtime[NUM_MIDI_TRACKS]; - void resettime(timestruct *t); - void updatecounter(timestruct *t);//this updates the timer values + void resettime(timestruct *t); + void updatecounter(timestruct *t); //this updates the timer values - /* Player only*/ + /* Player only*/ - struct { - event ev; - double time; - } nextevent[NUM_MIDI_TRACKS]; - - double realplayspeed; + struct { + event ev; + double time; + } nextevent[NUM_MIDI_TRACKS]; + double realplayspeed; }; #endif diff --git a/plugins/zynaddsubfx/src/Synth/ADnote.cpp b/plugins/zynaddsubfx/src/Synth/ADnote.cpp index d6a0b7bdf..a70f3feef 100644 --- a/plugins/zynaddsubfx/src/Synth/ADnote.cpp +++ b/plugins/zynaddsubfx/src/Synth/ADnote.cpp @@ -22,402 +22,689 @@ #include #include #include - +#include #include "../globals.h" #include "../Misc/Util.h" #include "ADnote.h" -ADnote::ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_,bool besilent) +ADnote::ADnote(ADnoteParameters *pars, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote_, + bool besilent) { - ready=0; + ready = 0; - tmpwave=new REALTYPE [SOUND_BUFFER_SIZE]; - bypassl=new REALTYPE [SOUND_BUFFER_SIZE]; - bypassr=new REALTYPE [SOUND_BUFFER_SIZE]; + tmpwavel = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpwaver = new REALTYPE [SOUND_BUFFER_SIZE]; + bypassl = new REALTYPE [SOUND_BUFFER_SIZE]; + bypassr = new REALTYPE [SOUND_BUFFER_SIZE]; // Initialise some legato-specific vars - Legato.msg=LM_Norm; - Legato.fade.length=(int)(SAMPLE_RATE*0.005);// 0.005 seems ok. - if (Legato.fade.length<1) Legato.fade.length=1;// (if something's fishy) - Legato.fade.step=(1.0/Legato.fade.length); - Legato.decounter=-10; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote_; - Legato.silent=besilent; + Legato.msg = LM_Norm; + Legato.fade.length = (int)(SAMPLE_RATE * 0.005); // 0.005 seems ok. + if(Legato.fade.length < 1) + Legato.fade.length = 1; // (if something's fishy) + Legato.fade.step = (1.0 / Legato.fade.length); + Legato.decounter = -10; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote_; + Legato.silent = besilent; - partparams=pars; - ctl=ctl_; - portamento=portamento_; - midinote=midinote_; - NoteEnabled=ON; - basefreq=freq; - if (velocity>1.0) velocity=1.0; - this->velocity=velocity; - time=0.0; - stereo=pars->GlobalPar.PStereo; + partparams = pars; + ctl = ctl_; + portamento = portamento_; + midinote = midinote_; + NoteEnabled = ON; + basefreq = freq; + if(velocity > 1.0) + velocity = 1.0; + this->velocity = velocity; + time = 0.0; + stereo = pars->GlobalPar.PStereo; - NoteGlobalPar.Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->GlobalPar.PCoarseDetune,pars->GlobalPar.PDetune); - bandwidthDetuneMultiplier=pars->getBandwidthDetuneMultiplier(); + NoteGlobalPar.Detune = getdetune(pars->GlobalPar.PDetuneType, + pars->GlobalPar.PCoarseDetune, + pars->GlobalPar.PDetune); + bandwidthDetuneMultiplier = pars->getBandwidthDetuneMultiplier(); - if (pars->GlobalPar.PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->GlobalPar.PPanning/128.0; + if(pars->GlobalPar.PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->GlobalPar.PPanning / 128.0; - NoteGlobalPar.FilterCenterPitch=pars->GlobalPar.GlobalFilter->getfreq()+//center freq - pars->GlobalPar.PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->GlobalPar.PFilterVelocityScaleFunction)-1); + NoteGlobalPar.FilterCenterPitch = pars->GlobalPar.GlobalFilter->getfreq() //center freq + + pars->GlobalPar.PFilterVelocityScale + / 127.0 * 6.0 //velocity sensing + * (VelF(velocity, + pars->GlobalPar. + PFilterVelocityScaleFunction) - 1); - if (pars->GlobalPar.PPunchStrength!=0) { - NoteGlobalPar.Punch.Enabled=1; - NoteGlobalPar.Punch.t=1.0;//start from 1.0 and to 0.0 - NoteGlobalPar.Punch.initialvalue=( (pow(10,1.5*pars->GlobalPar.PPunchStrength/127.0)-1.0) - *VelF(velocity,pars->GlobalPar.PPunchVelocitySensing) ); - REALTYPE time=pow(10,3.0*pars->GlobalPar.PPunchTime/127.0)/10000.0;//0.1 .. 100 ms - REALTYPE stretch=pow(440.0/freq,pars->GlobalPar.PPunchStretch/64.0); - NoteGlobalPar.Punch.dt=1.0/(time*SAMPLE_RATE*stretch); - } else NoteGlobalPar.Punch.Enabled=0; + if(pars->GlobalPar.PPunchStrength != 0) { + NoteGlobalPar.Punch.Enabled = 1; + NoteGlobalPar.Punch.t = 1.0; //start from 1.0 and to 0.0 + NoteGlobalPar.Punch.initialvalue = + ((pow(10, 1.5 * pars->GlobalPar.PPunchStrength / 127.0) - 1.0) + * VelF(velocity, + pars->GlobalPar.PPunchVelocitySensing)); + REALTYPE time = + pow(10, 3.0 * pars->GlobalPar.PPunchTime / 127.0) / 10000.0; //0.1 .. 100 ms + REALTYPE stretch = pow(440.0 / freq, + pars->GlobalPar.PPunchStretch / 64.0); + NoteGlobalPar.Punch.dt = 1.0 / (time * SAMPLE_RATE * stretch); + } + else + NoteGlobalPar.Punch.Enabled = 0; - for (int nvoice=0;nvoiceVoicePar[nvoice].OscilSmp->newrandseed(rand()); - NoteVoicePar[nvoice].OscilSmp=NULL; - NoteVoicePar[nvoice].FMSmp=NULL; - NoteVoicePar[nvoice].VoiceOut=NULL; + NoteVoicePar[nvoice].OscilSmp = NULL; + NoteVoicePar[nvoice].FMSmp = NULL; + NoteVoicePar[nvoice].VoiceOut = NULL; - NoteVoicePar[nvoice].FMVoice=-1; + NoteVoicePar[nvoice].FMVoice = -1; + unison_size[nvoice] = 1; - if (pars->VoicePar[nvoice].Enabled==0) { - NoteVoicePar[nvoice].Enabled=OFF; + if(pars->VoicePar[nvoice].Enabled == 0) { + NoteVoicePar[nvoice].Enabled = OFF; continue; //the voice is disabled - }; + } - NoteVoicePar[nvoice].Enabled=ON; - NoteVoicePar[nvoice].fixedfreq=pars->VoicePar[nvoice].Pfixedfreq; - NoteVoicePar[nvoice].fixedfreqET=pars->VoicePar[nvoice].PfixedfreqET; + unison_stereo_spread[nvoice] = + pars->VoicePar[nvoice].Unison_stereo_spread / 127.0; + int unison = pars->VoicePar[nvoice].Unison_size; + if(unison < 1) + unison = 1; + + //compute unison + unison_size[nvoice] = unison; + + unison_base_freq_rap[nvoice] = new REALTYPE[unison]; + unison_freq_rap[nvoice] = new REALTYPE[unison]; + unison_invert_phase[nvoice] = new bool[unison]; + REALTYPE unison_spread = pars->getUnisonFrequencySpreadCents( + nvoice); + REALTYPE unison_real_spread = pow(2.0, (unison_spread * 0.5) / 1200.0); + REALTYPE unison_vibratto_a = pars->VoicePar[nvoice].Unison_vibratto + / 127.0; //0.0 .. 1.0 + + + switch(unison) { + case 1: + unison_base_freq_rap[nvoice][0] = 1.0; //if the unison is not used, always make the only subvoice to have the default note + break; + case 2: { //unison for 2 subvoices + unison_base_freq_rap[nvoice][0] = 1.0 / unison_real_spread; + unison_base_freq_rap[nvoice][1] = unison_real_spread; + }; + break; + default: { //unison for more than 2 subvoices + REALTYPE unison_values[unison]; + REALTYPE min = -1e-6, max = 1e-6; + for(int k = 0; k < unison; k++) { + REALTYPE step = (k / (REALTYPE) (unison - 1)) * 2.0 - 1.0; //this makes the unison spread more uniform + REALTYPE val = step + (RND * 2.0 - 1.0) / (unison - 1); + unison_values[k] = val; + if(val > max) + max = val; + if(val < min) + min = val; + } + REALTYPE diff = max - min; + for(int k = 0; k < unison; k++) { + unison_values[k] = + (unison_values[k] - (max + min) * 0.5) / diff; //the lowest value will be -1 and the highest will be 1 + unison_base_freq_rap[nvoice][k] = + pow(2.0, (unison_spread * unison_values[k]) / 1200); + } + }; + } + + //unison vibrattos + if(unison > 1) { + for(int k = 0; k < unison; k++) //reduce the frequency difference for larger vibrattos + unison_base_freq_rap[nvoice][k] = 1.0 + + (unison_base_freq_rap[ + nvoice][k] + - 1.0) + * (1.0 - unison_vibratto_a); + ; + } + unison_vibratto[nvoice].step = new REALTYPE[unison]; + unison_vibratto[nvoice].position = new REALTYPE[unison]; + unison_vibratto[nvoice].amplitude = + (unison_real_spread - 1.0) * unison_vibratto_a; + + REALTYPE increments_per_second = SAMPLE_RATE + / (REALTYPE)SOUND_BUFFER_SIZE; + REALTYPE vibratto_base_period = 0.25 + * pow(2.0, + (1.0 + - pars->VoicePar[nvoice]. + Unison_vibratto_speed / 127.0) * 4.0); + for(int k = 0; k < unison; k++) { + unison_vibratto[nvoice].position[k] = RND * 1.8 - 0.9; + REALTYPE vibratto_period = vibratto_base_period * pow( + 2.0, + RND * 2.0 + - 1.0); //make period to vary randomly from 50% to 200% vibratto base period + + REALTYPE m = 4.0 / (vibratto_period * increments_per_second); + if(RND < 0.5) + m = -m; + unison_vibratto[nvoice].step[k] = m; + } + + if(unison == 1) { //no vibratto for a single voice + unison_vibratto[nvoice].step[0] = 0.0; + unison_vibratto[nvoice].position[0] = 0.0; + unison_vibratto[nvoice].amplitude = 0.0; + } + + //phase invert for unison + unison_invert_phase[nvoice][0] = false; + if(unison != 1) { + int inv = pars->VoicePar[nvoice].Unison_invert_phase; + switch(inv) { + case 0: for(int k = 0; k < unison; k++) + unison_invert_phase[nvoice][k] = false; + break; + case 1: for(int k = 0; k < unison; k++) + unison_invert_phase[nvoice][k] = (RND > 0.5); + break; + default: for(int k = 0; k < unison; k++) + unison_invert_phase[nvoice][k] = + (k % inv == 0) ? true : false; + break; + } + } + + + oscfreqhi[nvoice] = new int[unison]; + oscfreqlo[nvoice] = new REALTYPE[unison]; + oscfreqhiFM[nvoice] = new unsigned int[unison]; + oscfreqloFM[nvoice] = new REALTYPE[unison]; + oscposhi[nvoice] = new int[unison]; + oscposlo[nvoice] = new REALTYPE[unison]; + oscposhiFM[nvoice] = new unsigned int[unison]; + oscposloFM[nvoice] = new REALTYPE[unison]; + + NoteVoicePar[nvoice].Enabled = ON; + NoteVoicePar[nvoice].fixedfreq = pars->VoicePar[nvoice].Pfixedfreq; + NoteVoicePar[nvoice].fixedfreqET = pars->VoicePar[nvoice].PfixedfreqET; //use the Globalpars.detunetype if the detunetype is 0 - if (pars->VoicePar[nvoice].PDetuneType!=0) { - NoteVoicePar[nvoice].Detune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune - } else { - NoteVoicePar[nvoice].Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->GlobalPar.PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune - }; - if (pars->VoicePar[nvoice].PFMDetuneType!=0) { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->VoicePar[nvoice].PFMDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); - } else { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); - }; + if(pars->VoicePar[nvoice].PDetuneType != 0) { + NoteVoicePar[nvoice].Detune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + else { + NoteVoicePar[nvoice].Detune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->GlobalPar.PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + if(pars->VoicePar[nvoice].PFMDetuneType != 0) + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->VoicePar[nvoice].PFMDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + else + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + ; - oscposhi[nvoice]=0; - oscposlo[nvoice]=0.0; - oscposhiFM[nvoice]=0; - oscposloFM[nvoice]=0.0; - NoteVoicePar[nvoice].OscilSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES];//the extra points contains the first point + for(int k = 0; k < unison; k++) { + oscposhi[nvoice][k] = 0; + oscposlo[nvoice][k] = 0.0; + oscposhiFM[nvoice][k] = 0; + oscposloFM[nvoice][k] = 0.0; + } + + NoteVoicePar[nvoice].OscilSmp = + new REALTYPE[OSCIL_SIZE + OSCIL_SMP_EXTRA_SAMPLES]; //the extra points contains the first point //Get the voice's oscil or external's voice oscil - int vc=nvoice; - if (pars->VoicePar[nvoice].Pextoscil!=-1) vc=pars->VoicePar[nvoice].Pextoscil; - if (!pars->GlobalPar.Hrandgrouping) pars->VoicePar[vc].OscilSmp->newrandseed(rand()); - oscposhi[nvoice]=pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice), - pars->VoicePar[nvoice].Presonance); + int vc = nvoice; + if(pars->VoicePar[nvoice].Pextoscil != -1) + vc = pars->VoicePar[nvoice].Pextoscil; + if(!pars->GlobalPar.Hrandgrouping) + pars->VoicePar[vc].OscilSmp->newrandseed(rand()); + int oscposhi_start = + pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp, + getvoicebasefreq(nvoice), + pars->VoicePar[nvoice].Presonance); //I store the first elments to the last position for speedups - for (int i=0;iVoicePar[nvoice].Poscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); - oscposhi[nvoice]%=OSCIL_SIZE; + oscposhi_start += + (int)((pars->VoicePar[nvoice].Poscilphase + - 64.0) / 128.0 * OSCIL_SIZE + OSCIL_SIZE * 4); + oscposhi_start %= OSCIL_SIZE; + for(int k = 0; k < unison; k++) { + oscposhi[nvoice][k] = oscposhi_start; + oscposhi_start = (int)(RND * (OSCIL_SIZE - 1)); //put random starting point for other subvoices + } - NoteVoicePar[nvoice].FreqLfo=NULL; - NoteVoicePar[nvoice].FreqEnvelope=NULL; + NoteVoicePar[nvoice].FreqLfo = NULL; + NoteVoicePar[nvoice].FreqEnvelope = NULL; - NoteVoicePar[nvoice].AmpLfo=NULL; - NoteVoicePar[nvoice].AmpEnvelope=NULL; + NoteVoicePar[nvoice].AmpLfo = NULL; + NoteVoicePar[nvoice].AmpEnvelope = NULL; - NoteVoicePar[nvoice].VoiceFilter=NULL; - NoteVoicePar[nvoice].FilterEnvelope=NULL; - NoteVoicePar[nvoice].FilterLfo=NULL; + NoteVoicePar[nvoice].VoiceFilterL = NULL; + NoteVoicePar[nvoice].VoiceFilterR = NULL; + NoteVoicePar[nvoice].FilterEnvelope = NULL; + NoteVoicePar[nvoice].FilterLfo = NULL; - NoteVoicePar[nvoice].FilterCenterPitch=pars->VoicePar[nvoice].VoiceFilter->getfreq(); - NoteVoicePar[nvoice].filterbypass=pars->VoicePar[nvoice].Pfilterbypass; + NoteVoicePar[nvoice].FilterCenterPitch = + pars->VoicePar[nvoice].VoiceFilter->getfreq(); + NoteVoicePar[nvoice].filterbypass = + pars->VoicePar[nvoice].Pfilterbypass; - switch (pars->VoicePar[nvoice].PFMEnabled) { + switch(pars->VoicePar[nvoice].PFMEnabled) { case 1: - NoteVoicePar[nvoice].FMEnabled=MORPH; + NoteVoicePar[nvoice].FMEnabled = MORPH; break; case 2: - NoteVoicePar[nvoice].FMEnabled=RING_MOD; + NoteVoicePar[nvoice].FMEnabled = RING_MOD; break; case 3: - NoteVoicePar[nvoice].FMEnabled=PHASE_MOD; + NoteVoicePar[nvoice].FMEnabled = PHASE_MOD; break; case 4: - NoteVoicePar[nvoice].FMEnabled=FREQ_MOD; + NoteVoicePar[nvoice].FMEnabled = FREQ_MOD; break; case 5: - NoteVoicePar[nvoice].FMEnabled=PITCH_MOD; + NoteVoicePar[nvoice].FMEnabled = PITCH_MOD; break; default: - NoteVoicePar[nvoice].FMEnabled=NONE; - }; + NoteVoicePar[nvoice].FMEnabled = NONE; + } - NoteVoicePar[nvoice].FMVoice=pars->VoicePar[nvoice].PFMVoice; - NoteVoicePar[nvoice].FMFreqEnvelope=NULL; - NoteVoicePar[nvoice].FMAmpEnvelope=NULL; + NoteVoicePar[nvoice].FMVoice = pars->VoicePar[nvoice].PFMVoice; + NoteVoicePar[nvoice].FMFreqEnvelope = NULL; + NoteVoicePar[nvoice].FMAmpEnvelope = NULL; //Compute the Voice's modulator volume (incl. damping) - REALTYPE fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0-1.0); - switch (NoteVoicePar[nvoice].FMEnabled) { + REALTYPE fmvoldamp = pow(440.0 / getvoicebasefreq( + nvoice), + pars->VoicePar[nvoice].PFMVolumeDamp / 64.0 + - 1.0); + switch(NoteVoicePar[nvoice].FMEnabled) { case PHASE_MOD: - fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0); - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + fmvoldamp = + pow(440.0 / getvoicebasefreq( + nvoice), pars->VoicePar[nvoice].PFMVolumeDamp / 64.0); + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; case FREQ_MOD: - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; - // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? - // break; + // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? + // break; default: - if (fmvoldamp>1.0) fmvoldamp=1.0; - NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp; - }; + if(fmvoldamp > 1.0) + fmvoldamp = 1.0; + NoteVoicePar[nvoice].FMVolume = pars->VoicePar[nvoice].PFMVolume + / 127.0 * fmvoldamp; + } //Voice's modulator velocity sensing - NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction); + NoteVoicePar[nvoice].FMVolume *= + VelF(velocity, + partparams->VoicePar[nvoice].PFMVelocityScaleFunction); - FMoldsmp[nvoice]=0.0;//this is for FM (integration) + FMoldsmp[nvoice] = new REALTYPE [unison]; + for(int k = 0; k < unison; k++) + FMoldsmp[nvoice][k] = 0.0; //this is for FM (integration) - firsttick[nvoice]=1; - NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE); - }; + firsttick[nvoice] = 1; + NoteVoicePar[nvoice].DelayTicks = + (int)((exp(pars->VoicePar[nvoice].PDelay / 127.0 + * log(50.0)) + - 1.0) / SOUND_BUFFER_SIZE / 10.0 * SAMPLE_RATE); + } + + max_unison = 1; + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) + if(unison_size[nvoice] > max_unison) + max_unison = unison_size[nvoice]; + ; + + tmpwave_unison = new REALTYPE *[max_unison]; + for(int k = 0; k < max_unison; k++) { + tmpwave_unison[k] = new REALTYPE[SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwave_unison[k][i] = 0.0; + } initparameters(); - ready=1; -}; - + ready = 1; +} // ADlegatonote: This function is (mostly) a copy of ADnote(...) and // initparameters() stuck together with some lines removed so that it // only alter the already playing note (to perform legato). It is // possible I left stuff that is not required for this. -void ADnote::ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote_, bool externcall) +void ADnote::ADlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote_, + bool externcall) { - ADnoteParameters *pars=partparams; + ADnoteParameters *pars = partparams; //Controller *ctl_=ctl; // Manage legato stuff - if (externcall) Legato.msg=LM_Norm; - if (Legato.msg!=LM_CatchUp) { - Legato.lastfreq=Legato.param.freq; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote_; - if (Legato.msg==LM_Norm) { - if (Legato.silent) { - Legato.fade.m=0.0; - Legato.msg=LM_FadeIn; - } else { - Legato.fade.m=1.0; - Legato.msg=LM_FadeOut; + if(externcall) + Legato.msg = LM_Norm; + if(Legato.msg != LM_CatchUp) { + Legato.lastfreq = Legato.param.freq; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote_; + if(Legato.msg == LM_Norm) { + if(Legato.silent) { + Legato.fade.m = 0.0; + Legato.msg = LM_FadeIn; + } + else { + Legato.fade.m = 1.0; + Legato.msg = LM_FadeOut; return; } } - if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + if(Legato.msg == LM_ToNorm) + Legato.msg = LM_Norm; } - portamento=portamento_; - midinote=midinote_; - basefreq=freq; + portamento = portamento_; + midinote = midinote_; + basefreq = freq; - if (velocity>1.0) velocity=1.0; - this->velocity=velocity; + if(velocity > 1.0) + velocity = 1.0; + this->velocity = velocity; - NoteGlobalPar.Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->GlobalPar.PCoarseDetune,pars->GlobalPar.PDetune); - bandwidthDetuneMultiplier=pars->getBandwidthDetuneMultiplier(); + NoteGlobalPar.Detune = getdetune(pars->GlobalPar.PDetuneType, + pars->GlobalPar.PCoarseDetune, + pars->GlobalPar.PDetune); + bandwidthDetuneMultiplier = pars->getBandwidthDetuneMultiplier(); - if (pars->GlobalPar.PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->GlobalPar.PPanning/128.0; + if(pars->GlobalPar.PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->GlobalPar.PPanning / 128.0; - NoteGlobalPar.FilterCenterPitch=pars->GlobalPar.GlobalFilter->getfreq()+//center freq - pars->GlobalPar.PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->GlobalPar.PFilterVelocityScaleFunction)-1); + NoteGlobalPar.FilterCenterPitch = pars->GlobalPar.GlobalFilter->getfreq() //center freq + + pars->GlobalPar.PFilterVelocityScale + / 127.0 * 6.0 //velocity sensing + * (VelF(velocity, + pars->GlobalPar. + PFilterVelocityScaleFunction) - 1); - for (int nvoice=0;nvoiceVoicePar[nvoice].Pfixedfreq; - NoteVoicePar[nvoice].fixedfreqET=pars->VoicePar[nvoice].PfixedfreqET; + NoteVoicePar[nvoice].fixedfreq = pars->VoicePar[nvoice].Pfixedfreq; + NoteVoicePar[nvoice].fixedfreqET = pars->VoicePar[nvoice].PfixedfreqET; //use the Globalpars.detunetype if the detunetype is 0 - if (pars->VoicePar[nvoice].PDetuneType!=0) { - NoteVoicePar[nvoice].Detune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune - } else { - NoteVoicePar[nvoice].Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->GlobalPar.PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune - }; - if (pars->VoicePar[nvoice].PFMDetuneType!=0) { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->VoicePar[nvoice].PFMDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); - } else { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); - }; + if(pars->VoicePar[nvoice].PDetuneType != 0) { + NoteVoicePar[nvoice].Detune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + else { + NoteVoicePar[nvoice].Detune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->GlobalPar.PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + if(pars->VoicePar[nvoice].PFMDetuneType != 0) + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->VoicePar[nvoice].PFMDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + else + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + ; //Get the voice's oscil or external's voice oscil - int vc=nvoice; - if (pars->VoicePar[nvoice].Pextoscil!=-1) vc=pars->VoicePar[nvoice].Pextoscil; - if (!pars->GlobalPar.Hrandgrouping) pars->VoicePar[vc].OscilSmp->newrandseed(rand()); + int vc = nvoice; + if(pars->VoicePar[nvoice].Pextoscil != -1) + vc = pars->VoicePar[nvoice].Pextoscil; + if(!pars->GlobalPar.Hrandgrouping) + pars->VoicePar[vc].OscilSmp->newrandseed(rand()); - ///oscposhi[nvoice]=pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice),pars->VoicePar[nvoice].Presonance); - pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice),pars->VoicePar[nvoice].Presonance);//(gf)Modif of the above line. + pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp, + getvoicebasefreq(nvoice), + pars->VoicePar[nvoice].Presonance); //(gf)Modif of the above line. //I store the first elments to the last position for speedups - for (int i=0;iVoicePar[nvoice].VoiceFilter->getfreq(); - NoteVoicePar[nvoice].filterbypass=pars->VoicePar[nvoice].Pfilterbypass; + NoteVoicePar[nvoice].FilterCenterPitch = + pars->VoicePar[nvoice].VoiceFilter->getfreq(); + NoteVoicePar[nvoice].filterbypass = + pars->VoicePar[nvoice].Pfilterbypass; - NoteVoicePar[nvoice].FMVoice=pars->VoicePar[nvoice].PFMVoice; + NoteVoicePar[nvoice].FMVoice = pars->VoicePar[nvoice].PFMVoice; //Compute the Voice's modulator volume (incl. damping) - REALTYPE fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0-1.0); + REALTYPE fmvoldamp = pow(440.0 / getvoicebasefreq( + nvoice), + pars->VoicePar[nvoice].PFMVolumeDamp / 64.0 + - 1.0); - switch (NoteVoicePar[nvoice].FMEnabled) { + switch(NoteVoicePar[nvoice].FMEnabled) { case PHASE_MOD: - fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0); - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + fmvoldamp = + pow(440.0 / getvoicebasefreq( + nvoice), pars->VoicePar[nvoice].PFMVolumeDamp / 64.0); + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; case FREQ_MOD: - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; - // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? - // break; + // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? + // break; default: - if (fmvoldamp>1.0) fmvoldamp=1.0; - NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp; - }; + if(fmvoldamp > 1.0) + fmvoldamp = 1.0; + NoteVoicePar[nvoice].FMVolume = pars->VoicePar[nvoice].PFMVolume + / 127.0 * fmvoldamp; + } //Voice's modulator velocity sensing - NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction); + NoteVoicePar[nvoice].FMVolume *= + VelF(velocity, + partparams->VoicePar[nvoice].PFMVelocityScaleFunction); - NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE); - }; + NoteVoicePar[nvoice].DelayTicks = + (int)((exp(pars->VoicePar[nvoice].PDelay / 127.0 + * log(50.0)) + - 1.0) / SOUND_BUFFER_SIZE / 10.0 * SAMPLE_RATE); + } /// initparameters(); /////////////// // Altered content of initparameters(): - int nvoice,i,tmp[NUM_VOICES]; + int nvoice, i, tmp[NUM_VOICES]; - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-partparams->GlobalPar.PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,partparams->GlobalPar.PAmpVelocityScaleFunction);//velocity sensing + NoteGlobalPar.Volume = 4.0 + * pow(0.1, 3.0 + * (1.0 - partparams->GlobalPar.PVolume / 96.0)) //-60 dB .. 0 dB + * VelF( + velocity, + partparams->GlobalPar. + PAmpVelocityScaleFunction); //velocity sensing - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.FilterQ=partparams->GlobalPar.GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FilterQ = partparams->GlobalPar.GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = + partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); // Forbids the Modulation Voice to be greater or equal than voice - for (i=0;i=i) NoteVoicePar[i].FMVoice=-1; + for(i = 0; i < NUM_VOICES; i++) + if(NoteVoicePar[i].FMVoice >= i) + NoteVoicePar[i].FMVoice = -1; // Voice Parameter init - for (nvoice=0;nvoiceVoicePar[nvoice].Type; + NoteVoicePar[nvoice].noisetype = partparams->VoicePar[nvoice].Type; /* Voice Amplitude Parameters Init */ - NoteVoicePar[nvoice].Volume=pow(0.1,3.0*(1.0-partparams->VoicePar[nvoice].PVolume/127.0)) // -60 dB .. 0 dB - *VelF(velocity,partparams->VoicePar[nvoice].PAmpVelocityScaleFunction);//velocity + NoteVoicePar[nvoice].Volume = + pow(0.1, 3.0 * (1.0 - partparams->VoicePar[nvoice].PVolume / 127.0)) // -60 dB .. 0 dB + * VelF(velocity, + partparams->VoicePar[nvoice].PAmpVelocityScaleFunction); //velocity - if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume; + if(partparams->VoicePar[nvoice].PVolumeminus != 0) + NoteVoicePar[nvoice].Volume = -NoteVoicePar[nvoice].Volume; - if (partparams->VoicePar[nvoice].PPanning==0) - NoteVoicePar[nvoice].Panning=RND;// random panning - else NoteVoicePar[nvoice].Panning=partparams->VoicePar[nvoice].PPanning/128.0; + if(partparams->VoicePar[nvoice].PPanning == 0) + NoteVoicePar[nvoice].Panning = RND; // random panning + else + NoteVoicePar[nvoice].Panning = + partparams->VoicePar[nvoice].PPanning / 128.0; - newamplitude[nvoice]=1.0; - if ((partparams->VoicePar[nvoice].PAmpEnvelopeEnabled!=0) - && (NoteVoicePar[nvoice].AmpEnvelope!=NULL)) { - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); - }; + newamplitude[nvoice] = 1.0; + if((partparams->VoicePar[nvoice].PAmpEnvelopeEnabled != 0) + && (NoteVoicePar[nvoice].AmpEnvelope != NULL)) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + ; - if ((partparams->VoicePar[nvoice].PAmpLfoEnabled!=0) - && (NoteVoicePar[nvoice].AmpLfo!=NULL)) { - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); - }; + if((partparams->VoicePar[nvoice].PAmpLfoEnabled != 0) + && (NoteVoicePar[nvoice].AmpLfo != NULL)) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout(); + ; - NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); + NoteVoicePar[nvoice].FilterFreqTracking = + partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); /* Voice Modulation Parameters Init */ - if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)) { + if((NoteVoicePar[nvoice].FMEnabled != NONE) + && (NoteVoicePar[nvoice].FMVoice < 0)) { partparams->VoicePar[nvoice].FMSmp->newrandseed(rand()); //Perform Anti-aliasing only on MORPH or RING MODULATION - int vc=nvoice; - if (partparams->VoicePar[nvoice].PextFMoscil!=-1) vc=partparams->VoicePar[nvoice].PextFMoscil; + int vc = nvoice; + if(partparams->VoicePar[nvoice].PextFMoscil != -1) + vc = partparams->VoicePar[nvoice].PextFMoscil; - REALTYPE tmp=1.0; - if ((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics!=0)|| - (NoteVoicePar[nvoice].FMEnabled==MORPH)|| - (NoteVoicePar[nvoice].FMEnabled==RING_MOD)) { - tmp=getFMvoicebasefreq(nvoice); - }; - if (!partparams->GlobalPar.Hrandgrouping) partparams->VoicePar[vc].FMSmp->newrandseed(rand()); + REALTYPE tmp = 1.0; + if((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics != 0) + || (NoteVoicePar[nvoice].FMEnabled == MORPH) + || (NoteVoicePar[nvoice].FMEnabled == RING_MOD)) + tmp = getFMvoicebasefreq(nvoice); + ; + if(!partparams->GlobalPar.Hrandgrouping) + partparams->VoicePar[vc].FMSmp->newrandseed(rand()); ///oscposhiFM[nvoice]=(oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp)) % OSCIL_SIZE; // / oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp); //(gf) Modif of the above line. - for (int i=0;iVoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); ///oscposhiFM[nvoice]%=OSCIL_SIZE; - }; + } - FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; + FMnewamplitude[nvoice] = NoteVoicePar[nvoice].FMVolume + * ctl->fmamp.relamp; - if ((partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0) - && (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL)) { - FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); - }; - }; + if((partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled != 0) + && (NoteVoicePar[nvoice].FMAmpEnvelope != NULL)) + FMnewamplitude[nvoice] *= + NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + ; + } - for (nvoice=0;nvoiceGlobalPar.FreqEnvelope,basefreq); - NoteGlobalPar.FreqLfo=new LFO(partparams->GlobalPar.FreqLfo,basefreq); + NoteGlobalPar.FreqEnvelope = new Envelope( + partparams->GlobalPar.FreqEnvelope, + basefreq); + NoteGlobalPar.FreqLfo = new LFO(partparams->GlobalPar.FreqLfo, + basefreq); - NoteGlobalPar.AmpEnvelope=new Envelope(partparams->GlobalPar.AmpEnvelope,basefreq); - NoteGlobalPar.AmpLfo=new LFO(partparams->GlobalPar.AmpLfo,basefreq); + NoteGlobalPar.AmpEnvelope = new Envelope(partparams->GlobalPar.AmpEnvelope, + basefreq); + NoteGlobalPar.AmpLfo = new LFO(partparams->GlobalPar.AmpLfo, basefreq); - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-partparams->GlobalPar.PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,partparams->GlobalPar.PAmpVelocityScaleFunction);//velocity sensing + NoteGlobalPar.Volume = 4.0 + * pow(0.1, 3.0 + * (1.0 - partparams->GlobalPar.PVolume / 96.0)) //-60 dB .. 0 dB + * VelF( + velocity, + partparams->GlobalPar. + PAmpVelocityScaleFunction); //velocity sensing - NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.GlobalFilterL=new Filter(partparams->GlobalPar.GlobalFilter); - if (stereo!=0) NoteGlobalPar.GlobalFilterR=new Filter(partparams->GlobalPar.GlobalFilter); + NoteGlobalPar.GlobalFilterL = new Filter(partparams->GlobalPar.GlobalFilter); + if(stereo != 0) + NoteGlobalPar.GlobalFilterR = new Filter( + partparams->GlobalPar.GlobalFilter); - NoteGlobalPar.FilterEnvelope=new Envelope(partparams->GlobalPar.FilterEnvelope,basefreq); - NoteGlobalPar.FilterLfo=new LFO(partparams->GlobalPar.FilterLfo,basefreq); - NoteGlobalPar.FilterQ=partparams->GlobalPar.GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FilterEnvelope = new Envelope( + partparams->GlobalPar.FilterEnvelope, + basefreq); + NoteGlobalPar.FilterLfo = new LFO(partparams->GlobalPar.FilterLfo, + basefreq); + NoteGlobalPar.FilterQ = partparams->GlobalPar.GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = + partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); // Forbids the Modulation Voice to be greater or equal than voice - for (i=0;i=i) NoteVoicePar[i].FMVoice=-1; + for(i = 0; i < NUM_VOICES; i++) + if(NoteVoicePar[i].FMVoice >= i) + NoteVoicePar[i].FMVoice = -1; // Voice Parameter init - for (nvoice=0;nvoiceVoicePar[nvoice].Type; + NoteVoicePar[nvoice].noisetype = partparams->VoicePar[nvoice].Type; /* Voice Amplitude Parameters Init */ - NoteVoicePar[nvoice].Volume=pow(0.1,3.0*(1.0-partparams->VoicePar[nvoice].PVolume/127.0)) // -60 dB .. 0 dB - *VelF(velocity,partparams->VoicePar[nvoice].PAmpVelocityScaleFunction);//velocity + NoteVoicePar[nvoice].Volume = + pow(0.1, 3.0 * (1.0 - partparams->VoicePar[nvoice].PVolume / 127.0)) // -60 dB .. 0 dB + * VelF(velocity, + partparams->VoicePar[nvoice].PAmpVelocityScaleFunction); //velocity - if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume; + if(partparams->VoicePar[nvoice].PVolumeminus != 0) + NoteVoicePar[nvoice].Volume = -NoteVoicePar[nvoice].Volume; - if (partparams->VoicePar[nvoice].PPanning==0) - NoteVoicePar[nvoice].Panning=RND;// random panning - else NoteVoicePar[nvoice].Panning=partparams->VoicePar[nvoice].PPanning/128.0; + if(partparams->VoicePar[nvoice].PPanning == 0) + NoteVoicePar[nvoice].Panning = RND; // random panning + else + NoteVoicePar[nvoice].Panning = + partparams->VoicePar[nvoice].PPanning / 128.0; - newamplitude[nvoice]=1.0; - if (partparams->VoicePar[nvoice].PAmpEnvelopeEnabled!=0) { - NoteVoicePar[nvoice].AmpEnvelope=new Envelope(partparams->VoicePar[nvoice].AmpEnvelope,basefreq); - NoteVoicePar[nvoice].AmpEnvelope->envout_dB();//discard the first envelope sample - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); - }; + newamplitude[nvoice] = 1.0; + if(partparams->VoicePar[nvoice].PAmpEnvelopeEnabled != 0) { + NoteVoicePar[nvoice].AmpEnvelope = new Envelope( + partparams->VoicePar[nvoice].AmpEnvelope, + basefreq); + NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); //discard the first envelope sample + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + } - if (partparams->VoicePar[nvoice].PAmpLfoEnabled!=0) { - NoteVoicePar[nvoice].AmpLfo=new LFO(partparams->VoicePar[nvoice].AmpLfo,basefreq); - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); - }; + if(partparams->VoicePar[nvoice].PAmpLfoEnabled != 0) { + NoteVoicePar[nvoice].AmpLfo = new LFO( + partparams->VoicePar[nvoice].AmpLfo, + basefreq); + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout(); + } /* Voice Frequency Parameters Init */ - if (partparams->VoicePar[nvoice].PFreqEnvelopeEnabled!=0) - NoteVoicePar[nvoice].FreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FreqEnvelope,basefreq); + if(partparams->VoicePar[nvoice].PFreqEnvelopeEnabled != 0) + NoteVoicePar[nvoice].FreqEnvelope = new Envelope( + partparams->VoicePar[nvoice].FreqEnvelope, + basefreq); - if (partparams->VoicePar[nvoice].PFreqLfoEnabled!=0) NoteVoicePar[nvoice].FreqLfo=new LFO(partparams->VoicePar[nvoice].FreqLfo,basefreq); + if(partparams->VoicePar[nvoice].PFreqLfoEnabled != 0) + NoteVoicePar[nvoice].FreqLfo = new LFO( + partparams->VoicePar[nvoice].FreqLfo, + basefreq); /* Voice Filter Parameters Init */ - if (partparams->VoicePar[nvoice].PFilterEnabled!=0) { - NoteVoicePar[nvoice].VoiceFilter=new Filter(partparams->VoicePar[nvoice].VoiceFilter); - }; + if(partparams->VoicePar[nvoice].PFilterEnabled != 0) { + NoteVoicePar[nvoice].VoiceFilterL = new Filter( + partparams->VoicePar[nvoice].VoiceFilter); + NoteVoicePar[nvoice].VoiceFilterR = new Filter( + partparams->VoicePar[nvoice].VoiceFilter); + } - if (partparams->VoicePar[nvoice].PFilterEnvelopeEnabled!=0) - NoteVoicePar[nvoice].FilterEnvelope=new Envelope(partparams->VoicePar[nvoice].FilterEnvelope,basefreq); + if(partparams->VoicePar[nvoice].PFilterEnvelopeEnabled != 0) + NoteVoicePar[nvoice].FilterEnvelope = new Envelope( + partparams->VoicePar[nvoice].FilterEnvelope, + basefreq); - if (partparams->VoicePar[nvoice].PFilterLfoEnabled!=0) - NoteVoicePar[nvoice].FilterLfo=new LFO(partparams->VoicePar[nvoice].FilterLfo,basefreq); + if(partparams->VoicePar[nvoice].PFilterLfoEnabled != 0) + NoteVoicePar[nvoice].FilterLfo = + new LFO(partparams->VoicePar[nvoice].FilterLfo, basefreq); - NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); + NoteVoicePar[nvoice].FilterFreqTracking = + partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); /* Voice Modulation Parameters Init */ - if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)) { + if((NoteVoicePar[nvoice].FMEnabled != NONE) + && (NoteVoicePar[nvoice].FMVoice < 0)) { partparams->VoicePar[nvoice].FMSmp->newrandseed(rand()); - NoteVoicePar[nvoice].FMSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES]; + NoteVoicePar[nvoice].FMSmp = + new REALTYPE[OSCIL_SIZE + OSCIL_SMP_EXTRA_SAMPLES]; //Perform Anti-aliasing only on MORPH or RING MODULATION - int vc=nvoice; - if (partparams->VoicePar[nvoice].PextFMoscil!=-1) vc=partparams->VoicePar[nvoice].PextFMoscil; + int vc = nvoice; + if(partparams->VoicePar[nvoice].PextFMoscil != -1) + vc = partparams->VoicePar[nvoice].PextFMoscil; - REALTYPE tmp=1.0; - if ((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics!=0)|| - (NoteVoicePar[nvoice].FMEnabled==MORPH)|| - (NoteVoicePar[nvoice].FMEnabled==RING_MOD)) { - tmp=getFMvoicebasefreq(nvoice); - }; - if (!partparams->GlobalPar.Hrandgrouping) partparams->VoicePar[vc].FMSmp->newrandseed(rand()); + REALTYPE tmp = 1.0; + if((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics != 0) + || (NoteVoicePar[nvoice].FMEnabled == MORPH) + || (NoteVoicePar[nvoice].FMEnabled == RING_MOD)) + tmp = getFMvoicebasefreq(nvoice); + ; + if(!partparams->GlobalPar.Hrandgrouping) + partparams->VoicePar[vc].FMSmp->newrandseed(rand()); - oscposhiFM[nvoice]=(oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp)) % OSCIL_SIZE; - for (int i=0;iVoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); - oscposhiFM[nvoice]%=OSCIL_SIZE; - }; + for(int k = 0; k < unison_size[nvoice]; k++) + oscposhiFM[nvoice][k] = + (oscposhi[nvoice][k] + + partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice] + . + FMSmp, + tmp)) % OSCIL_SIZE; + ; + for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; i++) + NoteVoicePar[nvoice].FMSmp[OSCIL_SIZE + + i] = NoteVoicePar[nvoice].FMSmp[i]; + int oscposhiFM_add = + (int)((partparams->VoicePar[nvoice].PFMoscilphase + - 64.0) / 128.0 * OSCIL_SIZE + OSCIL_SIZE * 4); + for(int k = 0; k < unison_size[nvoice]; k++) { + oscposhiFM[nvoice][k] += oscposhiFM_add; + oscposhiFM[nvoice][k] %= OSCIL_SIZE; + } + } - if (partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0) - NoteVoicePar[nvoice].FMFreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FMFreqEnvelope,basefreq); + if(partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled != 0) + NoteVoicePar[nvoice].FMFreqEnvelope = new Envelope( + partparams->VoicePar[nvoice].FMFreqEnvelope, + basefreq); - FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; + FMnewamplitude[nvoice] = NoteVoicePar[nvoice].FMVolume + * ctl->fmamp.relamp; - if (partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0) { - NoteVoicePar[nvoice].FMAmpEnvelope=new Envelope(partparams->VoicePar[nvoice].FMAmpEnvelope,basefreq); - FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); - }; - }; + if(partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled != 0) { + NoteVoicePar[nvoice].FMAmpEnvelope = new Envelope( + partparams->VoicePar[nvoice].FMAmpEnvelope, + basefreq); + FMnewamplitude[nvoice] *= + NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + } + } - for (nvoice=0;nvoicebandwidth.relbw * bandwidthDetuneMultiplier; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE pos = unison_vibratto[nvoice].position[k]; + REALTYPE step = unison_vibratto[nvoice].step[k]; + pos += step; + if(pos <= -1.0) { + pos = -1.0; + step = -step; + } + if(pos >= 1.0) { + pos = 1.0; + step = -step; + } + REALTYPE vibratto_val = (pos - 0.333333333 * pos * pos * pos) * 1.5; //make the vibratto lfo smoother + unison_freq_rap[nvoice][k] = 1.0 + + ((unison_base_freq_rap[nvoice][k] + - 1.0) + vibratto_val + * unison_vibratto[nvoice].amplitude) + * relbw; + + unison_vibratto[nvoice].position[k] = pos; + step = unison_vibratto[nvoice].step[k] = step; + } +} + /* * Computes the frequency of an oscillator */ -void ADnote::setfreq(int nvoice,REALTYPE freq) +void ADnote::setfreq(int nvoice, REALTYPE in_freq) { - REALTYPE speed; - freq=fabs(freq); - speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE; - if (speed>OSCIL_SIZE) speed=OSCIL_SIZE; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE freq = fabs(in_freq) * unison_freq_rap[nvoice][k]; + REALTYPE speed = freq * REALTYPE(OSCIL_SIZE) / (REALTYPE) SAMPLE_RATE; + if(speed > OSCIL_SIZE) + speed = OSCIL_SIZE; - F2I(speed,oscfreqhi[nvoice]); - oscfreqlo[nvoice]=speed-floor(speed); -}; + F2I(speed, oscfreqhi[nvoice][k]); + oscfreqlo[nvoice][k] = speed - floor(speed); + } +} /* * Computes the frequency of an modullator oscillator */ -void ADnote::setfreqFM(int nvoice,REALTYPE freq) +void ADnote::setfreqFM(int nvoice, REALTYPE in_freq) { - REALTYPE speed; - freq=fabs(freq); - speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE; - if (speed>OSCIL_SIZE) speed=OSCIL_SIZE; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE freq = fabs(in_freq) * unison_freq_rap[nvoice][k]; + REALTYPE speed = freq * REALTYPE(OSCIL_SIZE) / (REALTYPE) SAMPLE_RATE; + if(speed > OSCIL_SIZE) + speed = OSCIL_SIZE; - F2I(speed,oscfreqhiFM[nvoice]); - oscfreqloFM[nvoice]=speed-floor(speed); -}; + F2I(speed, oscfreqhiFM[nvoice][k]); + oscfreqloFM[nvoice][k] = speed - floor(speed); + } +} /* * Get Voice base frequency */ -REALTYPE ADnote::getvoicebasefreq(int nvoice) +REALTYPE ADnote::getvoicebasefreq(int nvoice) const { - REALTYPE detune=NoteVoicePar[nvoice].Detune/100.0+ - NoteVoicePar[nvoice].FineDetune/100.0*ctl->bandwidth.relbw*bandwidthDetuneMultiplier+ - NoteGlobalPar.Detune/100.0; + REALTYPE detune = NoteVoicePar[nvoice].Detune / 100.0 + + NoteVoicePar[nvoice].FineDetune / 100.0 + * ctl->bandwidth.relbw * bandwidthDetuneMultiplier + + NoteGlobalPar.Detune / 100.0; - if (NoteVoicePar[nvoice].fixedfreq==0) return(this->basefreq*pow(2,detune/12.0)); - else {//the fixed freq is enabled - REALTYPE fixedfreq=440.0; - int fixedfreqET=NoteVoicePar[nvoice].fixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) fixedfreq*=pow(2.0,tmp); - else fixedfreq*=pow(3.0,tmp); - }; - return(fixedfreq*pow(2.0,detune/12.0)); - }; -}; + if(NoteVoicePar[nvoice].fixedfreq == 0) + return this->basefreq * pow(2, detune / 12.0); + else { //the fixed freq is enabled + REALTYPE fixedfreq = 440.0; + int fixedfreqET = NoteVoicePar[nvoice].fixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + fixedfreq *= pow(2.0, tmp); + else + fixedfreq *= pow(3.0, tmp); + } + return fixedfreq * pow(2.0, detune / 12.0); + } +} /* * Get Voice's Modullator base frequency */ -REALTYPE ADnote::getFMvoicebasefreq(int nvoice) +REALTYPE ADnote::getFMvoicebasefreq(int nvoice) const { - REALTYPE detune=NoteVoicePar[nvoice].FMDetune/100.0; - return(getvoicebasefreq(nvoice)*pow(2,detune/12.0)); -}; + REALTYPE detune = NoteVoicePar[nvoice].FMDetune / 100.0; + return getvoicebasefreq(nvoice) * pow(2, detune / 12.0); +} /* * Computes all the parameters for each tick */ void ADnote::computecurrentparameters() { - int nvoice; - REALTYPE voicefreq,voicepitch,filterpitch,filterfreq,FMfreq,FMrelativepitch,globalpitch,globalfilterpitch; - globalpitch=0.01*(NoteGlobalPar.FreqEnvelope->envout()+ - NoteGlobalPar.FreqLfo->lfoout()*ctl->modwheel.relmod); - globaloldamplitude=globalnewamplitude; - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + int nvoice; + REALTYPE voicefreq, voicepitch, filterpitch, filterfreq, FMfreq, + FMrelativepitch, globalpitch, globalfilterpitch; + globalpitch = 0.01 * (NoteGlobalPar.FreqEnvelope->envout() + + NoteGlobalPar.FreqLfo->lfoout() + * ctl->modwheel.relmod); + globaloldamplitude = globalnewamplitude; + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout() - +NoteGlobalPar.FilterCenterPitch; + globalfilterpitch = NoteGlobalPar.FilterEnvelope->envout() + + NoteGlobalPar.FilterLfo->lfoout() + + NoteGlobalPar.FilterCenterPitch; - REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq - +NoteGlobalPar.FilterFreqTracking; + REALTYPE tmpfilterfreq = globalfilterpitch + ctl->filtercutoff.relfreq + + NoteGlobalPar.FilterFreqTracking; - tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); + tmpfilterfreq = NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); - REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq; - NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq); - if (stereo!=0) NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq); + REALTYPE globalfilterq = NoteGlobalPar.FilterQ * ctl->filterq.relq; + NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq, globalfilterq); + if(stereo != 0) + NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq, globalfilterq); //compute the portamento, if it is used by this note - REALTYPE portamentofreqrap=1.0; - if (portamento!=0) {//this voice use portamento - portamentofreqrap=ctl->portamento.freqrap; - if (ctl->portamento.used==0) {//the portamento has finished - portamento=0;//this note is no longer "portamented" - }; - }; + REALTYPE portamentofreqrap = 1.0; + if(portamento != 0) { //this voice use portamento + portamentofreqrap = ctl->portamento.freqrap; + if(ctl->portamento.used == 0) //the portamento has finished + portamento = 0; //this note is no longer "portamented" + ; + } //compute parameters for all voices - for (nvoice=0;nvoice0) continue; + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if(NoteVoicePar[nvoice].Enabled != ON) + continue; + NoteVoicePar[nvoice].DelayTicks -= 1; + if(NoteVoicePar[nvoice].DelayTicks > 0) + continue; + + compute_unison_freq_rap(nvoice); /*******************/ /* Voice Amplitude */ /*******************/ - oldamplitude[nvoice]=newamplitude[nvoice]; - newamplitude[nvoice]=1.0; + oldamplitude[nvoice] = newamplitude[nvoice]; + newamplitude[nvoice] = 1.0; - if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + if(NoteVoicePar[nvoice].AmpEnvelope != NULL) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); - if (NoteVoicePar[nvoice].AmpLfo!=NULL) - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); + if(NoteVoicePar[nvoice].AmpLfo != NULL) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout(); /****************/ /* Voice Filter */ /****************/ - if (NoteVoicePar[nvoice].VoiceFilter!=NULL) { - filterpitch=NoteVoicePar[nvoice].FilterCenterPitch; + if(NoteVoicePar[nvoice].VoiceFilterL != NULL) { + filterpitch = NoteVoicePar[nvoice].FilterCenterPitch; - if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) - filterpitch+=NoteVoicePar[nvoice].FilterEnvelope->envout(); + if(NoteVoicePar[nvoice].FilterEnvelope != NULL) + filterpitch += NoteVoicePar[nvoice].FilterEnvelope->envout(); - if (NoteVoicePar[nvoice].FilterLfo!=NULL) - filterpitch+=NoteVoicePar[nvoice].FilterLfo->lfoout(); + if(NoteVoicePar[nvoice].FilterLfo != NULL) + filterpitch += NoteVoicePar[nvoice].FilterLfo->lfoout(); - filterfreq=filterpitch+NoteVoicePar[nvoice].FilterFreqTracking; - filterfreq=NoteVoicePar[nvoice].VoiceFilter->getrealfreq(filterfreq); + filterfreq = filterpitch + NoteVoicePar[nvoice].FilterFreqTracking; + filterfreq = NoteVoicePar[nvoice].VoiceFilterL->getrealfreq( + filterfreq); - NoteVoicePar[nvoice].VoiceFilter->setfreq(filterfreq); - }; - - if (NoteVoicePar[nvoice].noisetype==0) {//compute only if the voice isn't noise + NoteVoicePar[nvoice].VoiceFilterL->setfreq(filterfreq); + if(stereo && NoteVoicePar[nvoice].VoiceFilterR) + NoteVoicePar[nvoice].VoiceFilterR->setfreq(filterfreq); + } + if(NoteVoicePar[nvoice].noisetype == 0) { //compute only if the voice isn't noise /*******************/ /* Voice Frequency */ /*******************/ - voicepitch=0.0; - if (NoteVoicePar[nvoice].FreqLfo!=NULL) - voicepitch+=NoteVoicePar[nvoice].FreqLfo->lfoout()/100.0 - *ctl->bandwidth.relbw; + voicepitch = 0.0; + if(NoteVoicePar[nvoice].FreqLfo != NULL) + voicepitch += NoteVoicePar[nvoice].FreqLfo->lfoout() / 100.0 + * ctl->bandwidth.relbw; - if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) voicepitch+=NoteVoicePar[nvoice].FreqEnvelope->envout()/100.0; - voicefreq=getvoicebasefreq(nvoice)*pow(2,(voicepitch+globalpitch)/12.0);//Hz frequency - voicefreq*=ctl->pitchwheel.relfreq;//change the frequency by the controller - setfreq(nvoice,voicefreq*portamentofreqrap); + if(NoteVoicePar[nvoice].FreqEnvelope != NULL) + voicepitch += NoteVoicePar[nvoice].FreqEnvelope->envout() + / 100.0; + voicefreq = getvoicebasefreq(nvoice) + * pow(2, (voicepitch + globalpitch) / 12.0); //Hz frequency + voicefreq *= ctl->pitchwheel.relfreq; //change the frequency by the controller + setfreq(nvoice, voicefreq * portamentofreqrap); /***************/ /* Modulator */ /***************/ - if (NoteVoicePar[nvoice].FMEnabled!=NONE) { - FMrelativepitch=NoteVoicePar[nvoice].FMDetune/100.0; - if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) FMrelativepitch+=NoteVoicePar[nvoice].FMFreqEnvelope->envout()/100; - FMfreq=pow(2.0,FMrelativepitch/12.0)*voicefreq*portamentofreqrap; - setfreqFM(nvoice,FMfreq); + if(NoteVoicePar[nvoice].FMEnabled != NONE) { + FMrelativepitch = NoteVoicePar[nvoice].FMDetune / 100.0; + if(NoteVoicePar[nvoice].FMFreqEnvelope != NULL) + FMrelativepitch += + NoteVoicePar[nvoice].FMFreqEnvelope->envout() / 100; + FMfreq = + pow(2.0, FMrelativepitch + / 12.0) * voicefreq * portamentofreqrap; + setfreqFM(nvoice, FMfreq); - FMoldamplitude[nvoice]=FMnewamplitude[nvoice]; - FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; - if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) - FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); - }; - }; - - }; - time+=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; -}; + FMoldamplitude[nvoice] = FMnewamplitude[nvoice]; + FMnewamplitude[nvoice] = NoteVoicePar[nvoice].FMVolume + * ctl->fmamp.relamp; + if(NoteVoicePar[nvoice].FMAmpEnvelope != NULL) + FMnewamplitude[nvoice] *= + NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + } + } + } + time += (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; +} /* * Fadein in a way that removes clicks but keep sound "punchy" */ -inline void ADnote::fadein(REALTYPE *smps) +inline void ADnote::fadein(REALTYPE *smps) const { - int zerocrossings=0; - for (int i=1;i0.0)) zerocrossings++;//this is only the possitive crossings + int zerocrossings = 0; + for(int i = 1; i < SOUND_BUFFER_SIZE; i++) + if((smps[i - 1] < 0.0) && (smps[i] > 0.0)) + zerocrossings++; //this is only the possitive crossings - REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0; - if (tmp<8.0) tmp=8.0; + REALTYPE tmp = (SOUND_BUFFER_SIZE - 1.0) / (zerocrossings + 1) / 3.0; + if(tmp < 8.0) + tmp = 8.0; int n; - F2I(tmp,n);//how many samples is the fade-in - if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; - for (int i=0;i SOUND_BUFFER_SIZE) + n = SOUND_BUFFER_SIZE; + for(int i = 0; i < n; i++) { //fade-in + REALTYPE tmp = 0.5 - cos((REALTYPE)i / (REALTYPE) n * PI) * 0.5; + smps[i] *= tmp; + } +} /* * Computes the Oscillator (Without Modulation) - LinearInterpolation */ inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int nvoice) { - int i,poshi; + int i, poshi; REALTYPE poslo; - poshi=oscposhi[nvoice]; - poslo=oscposlo[nvoice]; - REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp; - for (i=0;i=1.0) { - poslo-=1.0; - poshi++; - }; - poshi+=oscfreqhi[nvoice]; - poshi&=OSCIL_SIZE-1; - }; - oscposhi[nvoice]=poshi; - oscposlo[nvoice]=poslo; -}; + for(int k = 0; k < unison_size[nvoice]; k++) { + poshi = oscposhi[nvoice][k]; + poslo = oscposlo[nvoice][k]; + int freqhi = oscfreqhi[nvoice][k]; + REALTYPE freqlo = oscfreqlo[nvoice][k]; + REALTYPE *smps = NoteVoicePar[nvoice].OscilSmp; + REALTYPE *tw = tmpwave_unison[k]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tw[i] = smps[poshi] * (1.0 - poslo) + smps[poshi + 1] * poslo; + poslo += freqlo; + if(poslo >= 1.0) { + poslo -= 1.0; + poshi++; + } + poshi += freqhi; + poshi &= OSCIL_SIZE - 1; + } + oscposhi[nvoice][k] = poshi; + oscposlo[nvoice][k] = poslo; + } +} @@ -848,22 +1314,22 @@ inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){ REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp; REALTYPE xm1,x0,x1,x2,a,b,c; for (i=0;i=1.0) { - poslo-=1.0; - poshi++; - }; - poshi+=oscfreqhi[nvoice]; + xm1=smps[poshi]; + x0=smps[poshi+1]; + x1=smps[poshi+2]; + x2=smps[poshi+3]; + a=(3.0 * (x0-x1) - xm1 + x2) / 2.0; + b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0; + c = (x1 - xm1) / 2.0; + tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0; + printf("a\n"); + //tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo; + poslo+=oscfreqlo[nvoice]; + if (poslo>=1.0) { + poslo-=1.0; + poshi++; + }; + poshi+=oscfreqhi[nvoice]; poshi&=OSCIL_SIZE-1; }; oscposhi[nvoice]=poshi; @@ -875,182 +1341,269 @@ inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){ */ inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice) { - int i; + int i; REALTYPE amp; ComputeVoiceOscillator_LinearInterpolation(nvoice); - if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0; - if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0; + if(FMnewamplitude[nvoice] > 1.0) + FMnewamplitude[nvoice] = 1.0; + if(FMoldamplitude[nvoice] > 1.0) + FMoldamplitude[nvoice] = 1.0; - if (NoteVoicePar[nvoice].FMVoice>=0) { + if(NoteVoicePar[nvoice].FMVoice >= 0) { //if I use VoiceOut[] as modullator - int FMVoice=NoteVoicePar[nvoice].FMVoice; - for (i=0;i=1.0) { - posloFM-=1.0; - poshiFM++; - }; - poshiFM+=oscfreqhiFM[nvoice]; - poshiFM&=OSCIL_SIZE-1; - }; - oscposhiFM[nvoice]=poshiFM; - oscposloFM[nvoice]=posloFM; - }; -}; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice], + FMnewamplitude[nvoice], + i, + SOUND_BUFFER_SIZE); + tw[i] = tw[i] * (1.0 - amp) + amp + * (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1 - posloFM) + + NoteVoicePar[nvoice].FMSmp[poshiFM + 1] * posloFM); + posloFM += freqloFM; + if(posloFM >= 1.0) { + posloFM -= 1.0; + poshiFM++; + } + poshiFM += freqhiFM; + poshiFM &= OSCIL_SIZE - 1; + } + oscposhiFM[nvoice][k] = poshiFM; + oscposloFM[nvoice][k] = posloFM; + } + } +} /* * Computes the Oscillator (Ring Modulation) */ inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice) { - int i; + int i; REALTYPE amp; ComputeVoiceOscillator_LinearInterpolation(nvoice); - if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0; - if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0; - if (NoteVoicePar[nvoice].FMVoice>=0) { + if(FMnewamplitude[nvoice] > 1.0) + FMnewamplitude[nvoice] = 1.0; + if(FMoldamplitude[nvoice] > 1.0) + FMoldamplitude[nvoice] = 1.0; + if(NoteVoicePar[nvoice].FMVoice >= 0) { // if I use VoiceOut[] as modullator - for (i=0;i=1.0) { - posloFM-=1.0; - poshiFM++; - }; - poshiFM+=oscfreqhiFM[nvoice]; - poshiFM&=OSCIL_SIZE-1; - }; - oscposhiFM[nvoice]=poshiFM; - oscposloFM[nvoice]=posloFM; - }; -}; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice], + FMnewamplitude[nvoice], + i, + SOUND_BUFFER_SIZE); + tw[i] *= (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1.0 - posloFM) + + NoteVoicePar[nvoice].FMSmp[poshiFM + + 1] * posloFM) * amp + + (1.0 - amp); + posloFM += freqloFM; + if(posloFM >= 1.0) { + posloFM -= 1.0; + poshiFM++; + } + poshiFM += freqhiFM; + poshiFM &= OSCIL_SIZE - 1; + } + oscposhiFM[nvoice][k] = poshiFM; + oscposloFM[nvoice][k] = posloFM; + } + } +} /* * Computes the Oscillator (Phase Modulation or Frequency Modulation) */ -inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode) +inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice, + int FMmode) { - int carposhi; - int i,FMmodfreqhi; - REALTYPE FMmodfreqlo,carposlo; + int carposhi = 0; + int i, FMmodfreqhi = 0; + REALTYPE FMmodfreqlo = 0, carposlo = 0; - if (NoteVoicePar[nvoice].FMVoice>=0) { + if(NoteVoicePar[nvoice].FMVoice >= 0) { //if I use VoiceOut[] as modulator - for (i=0;i=1.0) { - posloFM=fmod(posloFM,1.0); - poshiFM++; - }; - poshiFM+=oscfreqhiFM[nvoice]; - poshiFM&=OSCIL_SIZE-1; - }; - oscposhiFM[nvoice]=poshiFM; - oscposloFM[nvoice]=posloFM; - }; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tw[i] = + (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1.0 - posloFM) + + NoteVoicePar[nvoice].FMSmp[poshiFM + 1] * posloFM); + posloFM += freqloFM; + if(posloFM >= 1.0) { + posloFM = fmod(posloFM, 1.0); + poshiFM++; + } + poshiFM += freqhiFM; + poshiFM &= OSCIL_SIZE - 1; + } + oscposhiFM[nvoice][k] = poshiFM; + oscposloFM[nvoice][k] = posloFM; + } + } // Amplitude interpolation - if (ABOVE_AMPLITUDE_THRESHOLD(FMoldamplitude[nvoice],FMnewamplitude[nvoice])) { - for (i=0;i=1.0) { - carposhi++; - carposlo=fmod(carposlo,1.0); - }; - carposhi&=(OSCIL_SIZE-1); + //carrier + carposhi = poshi + FMmodfreqhi; + carposlo = poslo + FMmodfreqlo; - tmpwave[i]=NoteVoicePar[nvoice].OscilSmp[carposhi]*(1.0-carposlo) - +NoteVoicePar[nvoice].OscilSmp[carposhi+1]*carposlo; + if(carposlo >= 1.0) { + carposhi++; + carposlo = fmod(carposlo, 1.0); + } + carposhi &= (OSCIL_SIZE - 1); - oscposlo[nvoice]+=oscfreqlo[nvoice]; - if (oscposlo[nvoice]>=1.0) { - oscposlo[nvoice]=fmod(oscposlo[nvoice],1.0); - oscposhi[nvoice]++; - }; + tw[i] = NoteVoicePar[nvoice].OscilSmp[carposhi] + * (1.0 - carposlo) + + NoteVoicePar[nvoice].OscilSmp[carposhi + + 1] * carposlo; - oscposhi[nvoice]+=oscfreqhi[nvoice]; - oscposhi[nvoice]&=OSCIL_SIZE-1; - }; -}; + poslo += freqlo; + if(poslo >= 1.0) { + poslo = fmod(poslo, 1.0); + poshi++; + } + + poshi += freqhi; + poshi &= OSCIL_SIZE - 1; + } + oscposhi[nvoice][k] = poshi; + oscposlo[nvoice][k] = poslo; + } +} /*Calculeaza Oscilatorul cu PITCH MODULATION*/ inline void ADnote::ComputeVoiceOscillatorPitchModulation(int nvoice) { //TODO -}; +} /* * Computes the Noise */ inline void ADnote::ComputeVoiceNoise(int nvoice) { - for (int i=0;i0)) continue; - if (NoteVoicePar[nvoice].noisetype==0) {//voice mode=sound - switch (NoteVoicePar[nvoice].FMEnabled) { + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if((NoteVoicePar[nvoice].Enabled != ON) + || (NoteVoicePar[nvoice].DelayTicks > 0)) + continue; + if(NoteVoicePar[nvoice].noisetype == 0) //voice mode=sound + switch(NoteVoicePar[nvoice].FMEnabled) { case MORPH: ComputeVoiceOscillatorMorph(nvoice); break; @@ -1087,205 +1638,328 @@ int ADnote::noteout(REALTYPE *outl,REALTYPE *outr) ComputeVoiceOscillatorRingModulation(nvoice); break; case PHASE_MOD: - ComputeVoiceOscillatorFrequencyModulation(nvoice,0); + ComputeVoiceOscillatorFrequencyModulation(nvoice, 0); break; case FREQ_MOD: - ComputeVoiceOscillatorFrequencyModulation(nvoice,1); + ComputeVoiceOscillatorFrequencyModulation(nvoice, 1); break; - //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break; + //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break; default: ComputeVoiceOscillator_LinearInterpolation(nvoice); //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(nvoice); - - }; - } else ComputeVoiceNoise(nvoice); + } + else + ComputeVoiceNoise(nvoice); // Voice Processing + + //mix subvoices into voice + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] = 0.0; + if(stereo) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwaver[i] = 0.0; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + if(stereo) { + REALTYPE stereo_pos = 0; + if(unison_size[nvoice] > 1) + stereo_pos = k + / (REALTYPE)(unison_size[nvoice] + - 1) * 2.0 - 1.0; + REALTYPE stereo_spread = unison_stereo_spread[nvoice] * 2.0; //between 0 and 2.0 + if(stereo_spread > 1.0) { + REALTYPE stereo_pos_1 = (stereo_pos >= 0.0) ? 1.0 : -1.0; + stereo_pos = + (2.0 + - stereo_spread) * stereo_pos + + (stereo_spread - 1.0) * stereo_pos_1; + } + else + stereo_pos *= stereo_spread; + ; + if(unison_size[nvoice] == 1) + stereo_pos = 0.0; + REALTYPE panning = (stereo_pos + 1.0) * 0.5; + + + REALTYPE lvol = (1.0 - panning) * 2.0; + if(lvol > 1.0) + lvol = 1.0; + + REALTYPE rvol = panning * 2.0; + if(rvol > 1.0) + rvol = 1.0; + + if(unison_invert_phase[nvoice][k]) { + lvol = -lvol; + rvol = -rvol; + } + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] += tw[i] * lvol; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwaver[i] += tw[i] * rvol; + } + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] += tw[i]; + ; + } + + + REALTYPE unison_amplitude = 1.0 / sqrt(unison_size[nvoice]); //reduce the amplitude for large unison sizes // Amplitude - if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude[nvoice],newamplitude[nvoice])) { - int rest=SOUND_BUFFER_SIZE; + REALTYPE oldam = oldamplitude[nvoice] * unison_amplitude; + REALTYPE newam = newamplitude[nvoice] * unison_amplitude; + + if(ABOVE_AMPLITUDE_THRESHOLD(oldam, newam)) { + int rest = SOUND_BUFFER_SIZE; //test if the amplitude if raising and the difference is high - if ((newamplitude[nvoice]>oldamplitude[nvoice])&&((newamplitude[nvoice]-oldamplitude[nvoice])>0.25)) { - rest=10; - if (rest>SOUND_BUFFER_SIZE) rest=SOUND_BUFFER_SIZE; - for (int i=0;i oldam) && ((newam - oldam) > 0.25)) { + rest = 10; + if(rest > SOUND_BUFFER_SIZE) + rest = SOUND_BUFFER_SIZE; + for(int i = 0; i < SOUND_BUFFER_SIZE - rest; i++) + tmpwavel[i] *= oldam; + if(stereo) + for(int i = 0; i < SOUND_BUFFER_SIZE - rest; i++) + tmpwaver[i] *= oldam; + } // Amplitude interpolation - for (i=0;ifilterout(&tmpwave[0]); + if(NoteVoicePar[nvoice].VoiceFilterL != NULL) + NoteVoicePar[nvoice].VoiceFilterL->filterout(&tmpwavel[0]); + if((stereo) && (NoteVoicePar[nvoice].VoiceFilterR != NULL)) + NoteVoicePar[nvoice].VoiceFilterR->filterout(&tmpwaver[0]); //check if the amplitude envelope is finished, if yes, the voice will be fadeout - if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) { - if (NoteVoicePar[nvoice].AmpEnvelope->finished()!=0) - for (i=0;ifinished() != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] *= 1.0 - (REALTYPE)i + / (REALTYPE)SOUND_BUFFER_SIZE; + if(stereo) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwaver[i] *= 1.0 - (REALTYPE)i + / (REALTYPE)SOUND_BUFFER_SIZE; + } //the voice is killed later - }; + } // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator) - if (NoteVoicePar[nvoice].VoiceOut!=NULL) - for (i=0;ifinished()!=0) KillVoice(nvoice); - }; - }; + if(NoteVoicePar[nvoice].AmpEnvelope != NULL) + if(NoteVoicePar[nvoice].AmpEnvelope->finished() != 0) + KillVoice(nvoice); + ; + } //Processing Global parameters NoteGlobalPar.GlobalFilterL->filterout(&outl[0]); - if (stereo==0) { - for (i=0;ifilterout(&outr[0]); + else + NoteGlobalPar.GlobalFilterR->filterout(&outr[0]); - for (i=0;ifinished()!=0) { - for (i=0;ifinished() != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //fade-out + REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE; + outl[i] *= tmp; + outr[i] *= tmp; + } KillNote(); - }; - return(1); -}; + } + return 1; +} /* @@ -1294,28 +1968,33 @@ int ADnote::noteout(REALTYPE *outl,REALTYPE *outr) void ADnote::relasekey() { int nvoice; - for (nvoice=0;nvoicerelasekey(); - if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) NoteVoicePar[nvoice].FreqEnvelope->relasekey(); - if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) NoteVoicePar[nvoice].FilterEnvelope->relasekey(); - if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) NoteVoicePar[nvoice].FMFreqEnvelope->relasekey(); - if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) NoteVoicePar[nvoice].FMAmpEnvelope->relasekey(); - }; + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if(NoteVoicePar[nvoice].Enabled == 0) + continue; + if(NoteVoicePar[nvoice].AmpEnvelope != NULL) + NoteVoicePar[nvoice].AmpEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FreqEnvelope != NULL) + NoteVoicePar[nvoice].FreqEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FilterEnvelope != NULL) + NoteVoicePar[nvoice].FilterEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FMFreqEnvelope != NULL) + NoteVoicePar[nvoice].FMFreqEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FMAmpEnvelope != NULL) + NoteVoicePar[nvoice].FMAmpEnvelope->relasekey(); + } NoteGlobalPar.FreqEnvelope->relasekey(); NoteGlobalPar.FilterEnvelope->relasekey(); NoteGlobalPar.AmpEnvelope->relasekey(); - -}; +} /* * Check if the note is finished */ -int ADnote::finished() +int ADnote::finished() const { - if (NoteEnabled==ON) return(0); - else return(1); -}; - - + if(NoteEnabled == ON) + return 0; + else + return 1; +} diff --git a/plugins/zynaddsubfx/src/Synth/ADnote.h b/plugins/zynaddsubfx/src/Synth/ADnote.h index 1ec25832e..9f494a906 100644 --- a/plugins/zynaddsubfx/src/Synth/ADnote.h +++ b/plugins/zynaddsubfx/src/Synth/ADnote.h @@ -40,240 +40,310 @@ /**The "additive" synthesizer*/ class ADnote //ADDitive note { -public: - ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_,bool besilent);//(gf)Added the besilent parameter to tell it to start silent (if true). - ~ADnote(); + public: + /**Constructor. + * @param pars Note Parameters + * @param ctl_ Pointer to system Controller + * @param freq Base frequency for note + * @param velocity Velocity of note + * @param portamento_ 1 if the note has portamento + * @param midinote_ The midi number of the note + * @param besilent Start silent note if true*/ + ADnote(ADnoteParameters *pars, Controller *ctl_, REALTYPE freq, + REALTYPE velocity, int portamento_, int midinote_, + bool besilent); + /**Destructor*/ + ~ADnote(); - void ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote_, bool externcall); + /**Alters the playing note for legato effect*/ + void ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, + int midinote_, bool externcall); - int noteout(REALTYPE *outl,REALTYPE *outr); - void relasekey(); - int finished(); + /**Compute ADnote Samples. + * @return 0 if note is finished*/ + int noteout(REALTYPE *outl, REALTYPE *outr); + + /**Release the key for the note and start release portion of envelopes.*/ + void relasekey(); + /**Return if note is finished. + * @return finished=1 unfinished=0*/ + int finished() const; - /*ready - this is 0 if it is not ready (the parameters has to be computed) - or other value if the parameters has been computed and if it is ready to output*/ - char ready; + /**Nonzero when ready for output(the parameters has been computed) + * zero when parameters need to be computed.*/ + char ready; -private: + private: - void setfreq(int nvoice,REALTYPE freq); - void setfreqFM(int nvoice,REALTYPE freq); - void computecurrentparameters(); - void initparameters(); - void KillVoice(int nvoice); - void KillNote(); - inline REALTYPE getvoicebasefreq(int nvoice); - inline REALTYPE getFMvoicebasefreq(int nvoice); - inline void ComputeVoiceOscillator_LinearInterpolation(int nvoice); - inline void ComputeVoiceOscillator_CubicInterpolation(int nvoice); - inline void ComputeVoiceOscillatorMorph(int nvoice); - inline void ComputeVoiceOscillatorRingModulation(int nvoice); - inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode);//FMmode=0 for phase modulation, 1 for Frequency modulation - // inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice); - inline void ComputeVoiceOscillatorPitchModulation(int nvoice); + /**Changes the frequency of an oscillator. + * @param nvoice voice to run computations on + * @param in_freq new frequency*/ + void setfreq(int nvoice, REALTYPE in_freq); + /**Set the frequency of the modulator oscillator*/ + void setfreqFM(int nvoice, REALTYPE in_freq); + /**Computes relative frequency for unison and unison's vibratto. + * Note: Must be called before setfreq* functions.*/ + void compute_unison_freq_rap(int nvoice); + /**Compute parameters for next tick*/ + void computecurrentparameters(); + /**Initializes All Parameters*/ + void initparameters(); + /**Deallocate/Cleanup given voice*/ + void KillVoice(int nvoice); + /**Deallocate Note resources and voice resources*/ + void KillNote(); + /**Get the Voice's base frequency*/ + inline REALTYPE getvoicebasefreq(int nvoice) const; + /**Get modulator's base frequency*/ + inline REALTYPE getFMvoicebasefreq(int nvoice) const; + /**Compute the Oscillator's samples. + * Affects tmpwave_unison and updates oscposhi/oscposlo*/ + inline void ComputeVoiceOscillator_LinearInterpolation(int nvoice); + /**Compute the Oscillator's samples. + * Affects tmpwave_unison and updates oscposhi/oscposlo + * @todo remove this declaration if it is commented out*/ + inline void ComputeVoiceOscillator_CubicInterpolation(int nvoice); + /**Computes the Oscillator samples with morphing. + * updates tmpwave_unison*/ + inline void ComputeVoiceOscillatorMorph(int nvoice); + /**Computes the Ring Modulated Oscillator.*/ + inline void ComputeVoiceOscillatorRingModulation(int nvoice); + /**Computes the Frequency Modulated Oscillator. + * @param FMmode modulation type 0=Phase 1=Frequency*/ + inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice, + int FMmode); //FMmode=0 for phase modulation, 1 for Frequency modulation + // inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice); + /**TODO*/ + inline void ComputeVoiceOscillatorPitchModulation(int nvoice); - inline void ComputeVoiceNoise(int nvoice); + /**Generate Noise Samples for Voice*/ + inline void ComputeVoiceNoise(int nvoice); - inline void fadein(REALTYPE *smps); + /**Fadein in a way that removes clicks but keep sound "punchy"*/ + inline void fadein(REALTYPE *smps) const; - //GLOBALS - ADnoteParameters *partparams; - unsigned char stereo;//if the note is stereo (allows note Panning) - int midinote; - REALTYPE velocity,basefreq; + //GLOBALS + ADnoteParameters *partparams; + unsigned char stereo; //if the note is stereo (allows note Panning) + int midinote; + REALTYPE velocity, basefreq; - ONOFFTYPE NoteEnabled; - Controller *ctl; + ONOFFTYPE NoteEnabled; + Controller *ctl; - /*****************************************************************/ - /* GLOBAL PARAMETERS */ - /*****************************************************************/ + /*****************************************************************/ + /* GLOBAL PARAMETERS */ + /*****************************************************************/ - struct ADnoteGlobal { - /****************************************** - * FREQUENCY GLOBAL PARAMETERS * - ******************************************/ - REALTYPE Detune;//cents + struct ADnoteGlobal { + /****************************************** + * FREQUENCY GLOBAL PARAMETERS * + ******************************************/ + REALTYPE Detune; //cents - Envelope *FreqEnvelope; - LFO *FreqLfo; + Envelope *FreqEnvelope; + LFO *FreqLfo; - /******************************************** - * AMPLITUDE GLOBAL PARAMETERS * - ********************************************/ - REALTYPE Volume;// [ 0 .. 1 ] + /******************************************** + * AMPLITUDE GLOBAL PARAMETERS * + ********************************************/ + REALTYPE Volume; // [ 0 .. 1 ] - REALTYPE Panning;// [ 0 .. 1 ] + REALTYPE Panning; // [ 0 .. 1 ] - Envelope *AmpEnvelope; - LFO *AmpLfo; + Envelope *AmpEnvelope; + LFO *AmpLfo; + struct { + int Enabled; + REALTYPE initialvalue, dt, t; + } Punch; + + /****************************************** + * FILTER GLOBAL PARAMETERS * + ******************************************/ + Filter *GlobalFilterL, *GlobalFilterR; + + REALTYPE FilterCenterPitch; //octaves + REALTYPE FilterQ; + REALTYPE FilterFreqTracking; + + Envelope *FilterEnvelope; + + LFO *FilterLfo; + } NoteGlobalPar; + + + + /***********************************************************/ + /* VOICE PARAMETERS */ + /***********************************************************/ + struct ADnoteVoice { + /* If the voice is enabled */ + ONOFFTYPE Enabled; + + /* Voice Type (sound/noise)*/ + int noisetype; + + /* Filter Bypass */ + int filterbypass; + + /* Delay (ticks) */ + int DelayTicks; + + /* Waveform of the Voice */ + REALTYPE *OscilSmp; + + /************************************ + * FREQUENCY PARAMETERS * + ************************************/ + int fixedfreq; //if the frequency is fixed to 440 Hz + int fixedfreqET; //if the "fixed" frequency varies according to the note (ET) + + // cents = basefreq*VoiceDetune + REALTYPE Detune, FineDetune; + + Envelope *FreqEnvelope; + LFO *FreqLfo; + + + /*************************** + * AMPLITUDE PARAMETERS * + ***************************/ + + /* Panning 0.0=left, 0.5 - center, 1.0 = right */ + REALTYPE Panning; + REALTYPE Volume; // [-1.0 .. 1.0] + + Envelope *AmpEnvelope; + LFO *AmpLfo; + + /************************* + * FILTER PARAMETERS * + *************************/ + + Filter *VoiceFilterL; + Filter *VoiceFilterR; + + REALTYPE FilterCenterPitch; /* Filter center Pitch*/ + REALTYPE FilterFreqTracking; + + Envelope *FilterEnvelope; + LFO *FilterLfo; + + + /**************************** + * MODULLATOR PARAMETERS * + ****************************/ + + FMTYPE FMEnabled; + + int FMVoice; + + // Voice Output used by other voices if use this as modullator + REALTYPE *VoiceOut; + + /* Wave of the Voice */ + REALTYPE *FMSmp; + + REALTYPE FMVolume; + REALTYPE FMDetune; //in cents + + Envelope *FMFreqEnvelope; + Envelope *FMAmpEnvelope; + } NoteVoicePar[NUM_VOICES]; + + + /********************************************************/ + /* INTERNAL VALUES OF THE NOTE AND OF THE VOICES */ + /********************************************************/ + + //time from the start of the note + REALTYPE time; + + //the size of unison for a single voice + int unison_size[NUM_VOICES]; + + //the stereo spread of the unison subvoices (0.0=mono,1.0=max) + REALTYPE unison_stereo_spread[NUM_VOICES]; + + //fractional part (skip) + REALTYPE *oscposlo[NUM_VOICES], *oscfreqlo[NUM_VOICES]; + + //integer part (skip) + int *oscposhi[NUM_VOICES], *oscfreqhi[NUM_VOICES]; + + //fractional part (skip) of the Modullator + REALTYPE *oscposloFM[NUM_VOICES], *oscfreqloFM[NUM_VOICES]; + + //the unison base_value + REALTYPE *unison_base_freq_rap[NUM_VOICES]; + + //how the unison subvoice's frequency is changed (1.0 for no change) + REALTYPE *unison_freq_rap[NUM_VOICES]; + + //which subvoice has phase inverted + bool *unison_invert_phase[NUM_VOICES]; + + //unison vibratto struct { - int Enabled; - REALTYPE initialvalue,dt,t; - } Punch; - - /****************************************** - * FILTER GLOBAL PARAMETERS * - ******************************************/ - Filter *GlobalFilterL,*GlobalFilterR; - - REALTYPE FilterCenterPitch;//octaves - REALTYPE FilterQ; - REALTYPE FilterFreqTracking; - - Envelope *FilterEnvelope; - - LFO *FilterLfo; - } NoteGlobalPar; + REALTYPE amplitude; //amplitude which be added to unison_freq_rap + REALTYPE *step; //value which increments the position + REALTYPE *position; //between -1.0 and 1.0 + } unison_vibratto[NUM_VOICES]; + //integer part (skip) of the Modullator + unsigned int *oscposhiFM[NUM_VOICES], *oscfreqhiFM[NUM_VOICES]; - /***********************************************************/ - /* VOICE PARAMETERS */ - /***********************************************************/ - struct ADnoteVoice { - /* If the voice is enabled */ - ONOFFTYPE Enabled; + //used to compute and interpolate the amplitudes of voices and modullators + REALTYPE oldamplitude[NUM_VOICES], + newamplitude[NUM_VOICES], + FMoldamplitude[NUM_VOICES], + FMnewamplitude[NUM_VOICES]; - /* Voice Type (sound/noise)*/ - int noisetype; + //used by Frequency Modulation (for integration) + REALTYPE *FMoldsmp[NUM_VOICES]; - /* Filter Bypass */ - int filterbypass; + //temporary buffer + REALTYPE *tmpwavel; + REALTYPE *tmpwaver; + int max_unison; + REALTYPE **tmpwave_unison; - /* Delay (ticks) */ - int DelayTicks; + //Filter bypass samples + REALTYPE *bypassl, *bypassr; - /* Waveform of the Voice */ - REALTYPE *OscilSmp; + //interpolate the amplitudes + REALTYPE globaloldamplitude, globalnewamplitude; - /************************************ - * FREQUENCY PARAMETERS * - ************************************/ - int fixedfreq;//if the frequency is fixed to 440 Hz - int fixedfreqET;//if the "fixed" frequency varies according to the note (ET) + //1 - if it is the fitst tick (used to fade in the sound) + char firsttick[NUM_VOICES]; - // cents = basefreq*VoiceDetune - REALTYPE Detune,FineDetune; + //1 if the note has portamento + int portamento; - Envelope *FreqEnvelope; - LFO *FreqLfo; + //how the fine detunes are made bigger or smaller + REALTYPE bandwidthDetuneMultiplier; - - /*************************** - * AMPLITUDE PARAMETERS * - ***************************/ - - /* Panning 0.0=left, 0.5 - center, 1.0 = right */ - REALTYPE Panning; - REALTYPE Volume;// [-1.0 .. 1.0] - - Envelope *AmpEnvelope; - LFO *AmpLfo; - - /************************* - * FILTER PARAMETERS * - *************************/ - - Filter *VoiceFilter; - - REALTYPE FilterCenterPitch;/* Filter center Pitch*/ - REALTYPE FilterFreqTracking; - - Envelope *FilterEnvelope; - LFO *FilterLfo; - - - /**************************** - * MODULLATOR PARAMETERS * - ****************************/ - - FMTYPE FMEnabled; - - int FMVoice; - - // Voice Output used by other voices if use this as modullator - REALTYPE *VoiceOut; - - /* Wave of the Voice */ - REALTYPE *FMSmp; - - REALTYPE FMVolume; - REALTYPE FMDetune; //in cents - - Envelope *FMFreqEnvelope; - Envelope *FMAmpEnvelope; - } NoteVoicePar[NUM_VOICES]; - - - /********************************************************/ - /* INTERNAL VALUES OF THE NOTE AND OF THE VOICES */ - /********************************************************/ - - //time from the start of the note - REALTYPE time; - - //fractional part (skip) - REALTYPE oscposlo[NUM_VOICES],oscfreqlo[NUM_VOICES]; - - //integer part (skip) - int oscposhi[NUM_VOICES],oscfreqhi[NUM_VOICES]; - - //fractional part (skip) of the Modullator - REALTYPE oscposloFM[NUM_VOICES],oscfreqloFM[NUM_VOICES]; - - //integer part (skip) of the Modullator - unsigned short int oscposhiFM[NUM_VOICES],oscfreqhiFM[NUM_VOICES]; - - //used to compute and interpolate the amplitudes of voices and modullators - REALTYPE oldamplitude[NUM_VOICES], - newamplitude[NUM_VOICES], - FMoldamplitude[NUM_VOICES], - FMnewamplitude[NUM_VOICES]; - - //used by Frequency Modulation (for integration) - REALTYPE FMoldsmp[NUM_VOICES]; - - //temporary buffer - REALTYPE *tmpwave; - - //Filter bypass samples - REALTYPE *bypassl,*bypassr; - - //interpolate the amplitudes - REALTYPE globaloldamplitude,globalnewamplitude; - - //1 - if it is the fitst tick (used to fade in the sound) - char firsttick[NUM_VOICES]; - - //1 if the note has portamento - int portamento; - - //how the fine detunes are made bigger or smaller - REALTYPE bandwidthDetuneMultiplier; - - // Legato vars - struct { - bool silent; - REALTYPE lastfreq; - LegatoMsg msg; - int decounter; - struct { // Fade In/Out vars - int length; - REALTYPE m, step; - } fade; - struct { // Note parameters - REALTYPE freq, vel; - int portamento, midinote; - } param; - } Legato; + // Legato vars + struct { + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; }; #endif - - - diff --git a/plugins/zynaddsubfx/src/Synth/Envelope.cpp b/plugins/zynaddsubfx/src/Synth/Envelope.cpp index 83450e31a..ce8456481 100644 --- a/plugins/zynaddsubfx/src/Synth/Envelope.cpp +++ b/plugins/zynaddsubfx/src/Synth/Envelope.cpp @@ -23,64 +23,71 @@ #include #include "Envelope.h" -Envelope::Envelope(EnvelopeParams *envpars,REALTYPE basefreq) +Envelope::Envelope(EnvelopeParams *envpars, REALTYPE basefreq) { int i; - envpoints=envpars->Penvpoints; - if (envpoints>MAX_ENVELOPE_POINTS) envpoints=MAX_ENVELOPE_POINTS; - envsustain=(envpars->Penvsustain==0)?-1:envpars->Penvsustain; - forcedrelase=envpars->Pforcedrelease; - envstretch=pow(440.0/basefreq,envpars->Penvstretch/64.0); - linearenvelope=envpars->Plinearenvelope; + envpoints = envpars->Penvpoints; + if(envpoints > MAX_ENVELOPE_POINTS) + envpoints = MAX_ENVELOPE_POINTS; + envsustain = (envpars->Penvsustain == 0) ? -1 : envpars->Penvsustain; + forcedrelase = envpars->Pforcedrelease; + envstretch = pow(440.0 / basefreq, envpars->Penvstretch / 64.0); + linearenvelope = envpars->Plinearenvelope; - if (envpars->Pfreemode==0) envpars->converttofree(); + if(envpars->Pfreemode == 0) + envpars->converttofree(); - REALTYPE bufferdt=SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; + REALTYPE bufferdt = SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; - int mode=envpars->Envmode; + int mode = envpars->Envmode; //for amplitude envelopes - if ((mode==1)&&(linearenvelope==0)) mode=2;//change to log envelope - if ((mode==2)&&(linearenvelope!=0)) mode=1;//change to linear + if((mode == 1) && (linearenvelope == 0)) + mode = 2; //change to log envelope + if((mode == 2) && (linearenvelope != 0)) + mode = 1; //change to linear - for (i=0;igetdt(i)/1000.0*envstretch; - if (tmp>bufferdt) envdt[i]=bufferdt/tmp; - else envdt[i]=2.0;//any value larger than 1 + for(i = 0; i < MAX_ENVELOPE_POINTS; i++) { + REALTYPE tmp = envpars->getdt(i) / 1000.0 * envstretch; + if(tmp > bufferdt) + envdt[i] = bufferdt / tmp; + else + envdt[i] = 2.0; //any value larger than 1 - switch (mode) { + switch(mode) { case 2: - envval[i]=(1.0-envpars->Penvval[i]/127.0)*MIN_ENVELOPE_DB; + envval[i] = (1.0 - envpars->Penvval[i] / 127.0) * MIN_ENVELOPE_DB; break; case 3: - envval[i]=(pow(2,6.0*fabs(envpars->Penvval[i]-64.0)/64.0)-1.0)*100.0; - if (envpars->Penvval[i]<64) envval[i]=-envval[i]; + envval[i] = + (pow(2, 6.0 + * fabs(envpars->Penvval[i] - 64.0) / 64.0) - 1.0) * 100.0; + if(envpars->Penvval[i] < 64) + envval[i] = -envval[i]; break; case 4: - envval[i]=(envpars->Penvval[i]-64.0)/64.0*6.0;//6 octaves (filtru) + envval[i] = (envpars->Penvval[i] - 64.0) / 64.0 * 6.0; //6 octaves (filtru) break; case 5: - envval[i]=(envpars->Penvval[i]-64.0)/64.0*10; + envval[i] = (envpars->Penvval[i] - 64.0) / 64.0 * 10; break; default: - envval[i]=envpars->Penvval[i]/127.0; - }; + envval[i] = envpars->Penvval[i] / 127.0; + } + } - }; + envdt[0] = 1.0; - envdt[0]=1.0; - - currentpoint=1;//the envelope starts from 1 - keyreleased=0; - t=0.0; - envfinish=0; - inct=envdt[1]; - envoutval=0.0; -}; + currentpoint = 1; //the envelope starts from 1 + keyreleased = 0; + t = 0.0; + envfinish = 0; + inct = envdt[1]; + envoutval = 0.0; +} Envelope::~Envelope() -{ -}; +{} /* @@ -88,10 +95,12 @@ Envelope::~Envelope() */ void Envelope::relasekey() { - if (keyreleased==1) return; - keyreleased=1; - if (forcedrelase!=0) t=0.0; -}; + if(keyreleased == 1) + return; + keyreleased = 1; + if(forcedrelase != 0) + t = 0.0; +} /* * Envelope Output @@ -100,46 +109,54 @@ REALTYPE Envelope::envout() { REALTYPE out; - if (envfinish!=0) {//if the envelope is finished - envoutval=envval[envpoints-1]; - return(envoutval); - }; - if ((currentpoint==envsustain+1)&&(keyreleased==0)) {//if it is sustaining now - envoutval=envval[envsustain]; - return(envoutval); - }; + if(envfinish != 0) { //if the envelope is finished + envoutval = envval[envpoints - 1]; + return envoutval; + } + if((currentpoint == envsustain + 1) && (keyreleased == 0)) { //if it is sustaining now + envoutval = envval[envsustain]; + return envoutval; + } - if ((keyreleased!=0) && (forcedrelase!=0)) {//do the forced release + if((keyreleased != 0) && (forcedrelase != 0)) { //do the forced release + int tmp = (envsustain < 0) ? (envpoints - 1) : (envsustain + 1); //if there is no sustain point, use the last point for release - int tmp=(envsustain<0) ? (envpoints-1):(envsustain+1);//if there is no sustain point, use the last point for release + if(envdt[tmp] < 0.00000001) + out = envval[tmp]; + else + out = envoutval + (envval[tmp] - envoutval) * t; + t += envdt[tmp] * envstretch; - if (envdt[tmp]<0.00000001) out=envval[tmp]; - else out=envoutval+(envval[tmp]-envoutval)*t; - t+=envdt[tmp]*envstretch; + if(t >= 1.0) { + currentpoint = envsustain + 2; + forcedrelase = 0; + t = 0.0; + inct = envdt[currentpoint]; + if((currentpoint >= envpoints) || (envsustain < 0)) + envfinish = 1; + } + return out; + } + if(inct >= 1.0) + out = envval[currentpoint]; + else + out = + envval[currentpoint + - 1] + (envval[currentpoint] - envval[currentpoint - 1]) * t; - if (t>=1.0) { - currentpoint=envsustain+2; - forcedrelase=0; - t=0.0; - inct=envdt[currentpoint]; - if ((currentpoint>=envpoints)||(envsustain<0)) envfinish=1; - }; - return(out); - }; - if (inct>=1.0) out=envval[currentpoint]; - else out=envval[currentpoint-1]+(envval[currentpoint]-envval[currentpoint-1])*t; + t += inct; + if(t >= 1.0) { + if(currentpoint >= envpoints - 1) + envfinish = 1; + else + currentpoint++; + t = 0.0; + inct = envdt[currentpoint]; + } - t+=inct; - if (t>=1.0) { - if (currentpoint>=envpoints-1) envfinish=1; - else currentpoint++; - t=0.0; - inct=envdt[currentpoint]; - }; - - envoutval=out; - return (out); -}; + envoutval = out; + return out; +} /* * Envelope Output (dB) @@ -147,30 +164,35 @@ REALTYPE Envelope::envout() REALTYPE Envelope::envout_dB() { REALTYPE out; - if (linearenvelope!=0) return (envout()); + if(linearenvelope != 0) + return envout(); - if ((currentpoint==1)&&((keyreleased==0)||(forcedrelase==0))) {//first point is always lineary interpolated - REALTYPE v1=dB2rap(envval[0]); - REALTYPE v2=dB2rap(envval[1]); - out=v1+(v2-v1)*t; + if((currentpoint == 1) && ((keyreleased == 0) || (forcedrelase == 0))) { //first point is always lineary interpolated + REALTYPE v1 = dB2rap(envval[0]); + REALTYPE v2 = dB2rap(envval[1]); + out = v1 + (v2 - v1) * t; - t+=inct; - if (t>=1.0) { - t=0.0; - inct=envdt[2]; + t += inct; + if(t >= 1.0) { + t = 0.0; + inct = envdt[2]; currentpoint++; - out=v2; - }; + out = v2; + } - if (out>0.001) envoutval=rap2dB(out); - else envoutval=-40.0; - } else out=dB2rap(envout()); + if(out > 0.001) + envoutval = rap2dB(out); + else + envoutval = -40.0; + } + else + out = dB2rap(envout()); - return(out); -}; + return out; +} int Envelope::finished() { - return(envfinish); -}; + return envfinish; +} diff --git a/plugins/zynaddsubfx/src/Synth/Envelope.h b/plugins/zynaddsubfx/src/Synth/Envelope.h index 60a17ed49..1a15813a7 100644 --- a/plugins/zynaddsubfx/src/Synth/Envelope.h +++ b/plugins/zynaddsubfx/src/Synth/Envelope.h @@ -30,35 +30,35 @@ /**Implementation of a general Envelope*/ class Envelope { -public: + public: - /**Constructor*/ - Envelope(EnvelopeParams *envpars,REALTYPE basefreq); - /**Destructor*/ - ~Envelope(); - void relasekey(); - REALTYPE envout(); - REALTYPE envout_dB(); - /**Determines the status of the Envelope - * - *\todo see if this can be changed to use a boolean - * @return returns 1 if the envelope is finished*/ - int finished(); -private: - int envpoints; - int envsustain;//"-1" means disabled - REALTYPE envdt[MAX_ENVELOPE_POINTS];//millisecons - REALTYPE envval[MAX_ENVELOPE_POINTS];// [0.0 .. 1.0] - REALTYPE envstretch; - int linearenvelope; + /**Constructor*/ + Envelope(EnvelopeParams *envpars, REALTYPE basefreq); + /**Destructor*/ + ~Envelope(); + void relasekey(); + REALTYPE envout(); + REALTYPE envout_dB(); + /**Determines the status of the Envelope + * + *\todo see if this can be changed to use a boolean + * @return returns 1 if the envelope is finished*/ + int finished(); + private: + int envpoints; + int envsustain; //"-1" means disabled + REALTYPE envdt[MAX_ENVELOPE_POINTS]; //millisecons + REALTYPE envval[MAX_ENVELOPE_POINTS]; // [0.0 .. 1.0] + REALTYPE envstretch; + int linearenvelope; - int currentpoint; //current envelope point (starts from 1) - int forcedrelase; - char keyreleased; //if the key was released /** \todo figure out WHY IS THIS A CHAR*/ - char envfinish; /** \todo figure out WHY IS THIS A CHAR*/ - REALTYPE t; // the time from the last point - REALTYPE inct;// the time increment - REALTYPE envoutval;//used to do the forced release + int currentpoint; //current envelope point (starts from 1) + int forcedrelase; + char keyreleased; //if the key was released /** \todo figure out WHY IS THIS A CHAR*/ + char envfinish; /** \todo figure out WHY IS THIS A CHAR*/ + REALTYPE t; // the time from the last point + REALTYPE inct; // the time increment + REALTYPE envoutval; //used to do the forced release }; diff --git a/plugins/zynaddsubfx/src/Synth/LFO.cpp b/plugins/zynaddsubfx/src/Synth/LFO.cpp index 3c1d9962a..a7d00232b 100644 --- a/plugins/zynaddsubfx/src/Synth/LFO.cpp +++ b/plugins/zynaddsubfx/src/Synth/LFO.cpp @@ -27,59 +27,68 @@ #include "LFO.h" -LFO::LFO(LFOParams *lfopars,REALTYPE basefreq) +LFO::LFO(LFOParams *lfopars, REALTYPE basefreq) { - if (lfopars->Pstretch==0) lfopars->Pstretch=1; - REALTYPE lfostretch=pow(basefreq/440.0,(lfopars->Pstretch-64.0)/63.0);//max 2x/octave + if(lfopars->Pstretch == 0) + lfopars->Pstretch = 1; + REALTYPE lfostretch = pow(basefreq / 440.0, + (lfopars->Pstretch - 64.0) / 63.0); //max 2x/octave - REALTYPE lfofreq=(pow(2,lfopars->Pfreq*10.0)-1.0)/12.0*lfostretch; - incx=fabs(lfofreq)*(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; + REALTYPE lfofreq = + (pow(2, lfopars->Pfreq * 10.0) - 1.0) / 12.0 * lfostretch; + incx = fabs(lfofreq) * (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; - if (lfopars->Pcontinous==0) { - if (lfopars->Pstartphase==0) x=RND; - else x=fmod((lfopars->Pstartphase-64.0)/127.0+1.0,1.0); - } else { - REALTYPE tmp=fmod(lfopars->time*incx,1.0); - x=fmod((lfopars->Pstartphase-64.0)/127.0+1.0+tmp,1.0); - }; + if(lfopars->Pcontinous == 0) { + if(lfopars->Pstartphase == 0) + x = RND; + else + x = fmod((lfopars->Pstartphase - 64.0) / 127.0 + 1.0, 1.0); + } + else { + REALTYPE tmp = fmod(lfopars->time * incx, 1.0); + x = fmod((lfopars->Pstartphase - 64.0) / 127.0 + 1.0 + tmp, 1.0); + } //Limit the Frequency(or else...) - if (incx>0.49999999) incx=0.499999999; + if(incx > 0.49999999) + incx = 0.499999999; - lfornd=lfopars->Prandomness/127.0; - if (lfornd<0.0) lfornd=0.0; - else if (lfornd>1.0) lfornd=1.0; + lfornd = lfopars->Prandomness / 127.0; + if(lfornd < 0.0) + lfornd = 0.0; + else + if(lfornd > 1.0) + lfornd = 1.0; // lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*2.0*4.0; - lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*4.0; + lfofreqrnd = pow(lfopars->Pfreqrand / 127.0, 2.0) * 4.0; - switch (lfopars->fel) { + switch(lfopars->fel) { case 1: - lfointensity=lfopars->Pintensity/127.0; + lfointensity = lfopars->Pintensity / 127.0; break; case 2: - lfointensity=lfopars->Pintensity/127.0*4.0; - break;//in octave + lfointensity = lfopars->Pintensity / 127.0 * 4.0; + break; //in octave default: - lfointensity=pow(2,lfopars->Pintensity/127.0*11.0)-1.0;//in centi - x-=0.25;//chance the starting phase + lfointensity = pow(2, lfopars->Pintensity / 127.0 * 11.0) - 1.0; //in centi + x -= 0.25; //chance the starting phase break; - }; + } - amp1=(1-lfornd)+lfornd*RND; - amp2=(1-lfornd)+lfornd*RND; - lfotype=lfopars->PLFOtype; - lfodelay=lfopars->Pdelay/127.0*4.0;//0..4 sec - incrnd=nextincrnd=1.0; - freqrndenabled=(lfopars->Pfreqrand!=0); + amp1 = (1 - lfornd) + lfornd * RND; + amp2 = (1 - lfornd) + lfornd * RND; + lfotype = lfopars->PLFOtype; + lfodelay = lfopars->Pdelay / 127.0 * 4.0; //0..4 sec + incrnd = nextincrnd = 1.0; + freqrndenabled = (lfopars->Pfreqrand != 0); computenextincrnd(); - computenextincrnd();//twice because I want incrnd & nextincrnd to be random -}; + computenextincrnd(); //twice because I want incrnd & nextincrnd to be random +} LFO::~LFO() -{ -}; +{} /* * LFO out @@ -87,53 +96,67 @@ LFO::~LFO() REALTYPE LFO::lfoout() { REALTYPE out; - switch (lfotype) { + switch(lfotype) { case 1: //LFO_TRIANGLE - if ((x>=0.0)&&(x<0.25)) out=4.0*x; - else if ((x>0.25)&&(x<0.75)) out=2-4*x; - else out=4.0*x-4.0; + if((x >= 0.0) && (x < 0.25)) + out = 4.0 * x; + else + if((x > 0.25) && (x < 0.75)) + out = 2 - 4 * x; + else + out = 4.0 * x - 4.0; break; case 2: //LFO_SQUARE - if (x<0.5) out=-1; - else out=1; + if(x < 0.5) + out = -1; + else + out = 1; break; case 3: //LFO_RAMPUP - out=(x-0.5)*2.0; + out = (x - 0.5) * 2.0; break; case 4: //LFO_RAMPDOWN - out=(0.5-x)*2.0; + out = (0.5 - x) * 2.0; break; case 5: //LFO_EXP_DOWN 1 - out=pow(0.05,x)*2.0-1.0; + out = pow(0.05, x) * 2.0 - 1.0; break; case 6: //LFO_EXP_DOWN 2 - out=pow(0.001,x)*2.0-1.0; + out = pow(0.001, x) * 2.0 - 1.0; break; default: - out=cos(x*2.0*PI);//LFO_SINE - }; + out = cos(x * 2.0 * PI); //LFO_SINE + } - if ((lfotype==0)||(lfotype==1)) out*=lfointensity*(amp1+x*(amp2-amp1)); - else out*=lfointensity*amp2; - if (lfodelay<0.00001) { - if (freqrndenabled==0) x+=incx; + if((lfotype == 0) || (lfotype == 1)) + out *= lfointensity * (amp1 + x * (amp2 - amp1)); + else + out *= lfointensity * amp2; + if(lfodelay < 0.00001) { + if(freqrndenabled == 0) + x += incx; else { - float tmp=(incrnd*(1.0-x)+nextincrnd*x); - if (tmp>1.0) tmp=1.0; - else if (tmp<0.0) tmp=0.0; - x+=incx*tmp; - }; - if (x>=1) { - x=fmod(x,1.0); - amp1=amp2; - amp2=(1-lfornd)+lfornd*RND; + float tmp = (incrnd * (1.0 - x) + nextincrnd * x); + if(tmp > 1.0) + tmp = 1.0; + else + if(tmp < 0.0) + tmp = 0.0; + x += incx * tmp; + } + if(x >= 1) { + x = fmod(x, 1.0); + amp1 = amp2; + amp2 = (1 - lfornd) + lfornd * RND; computenextincrnd(); - }; - } else lfodelay-=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; - return(out); -}; + } + } + else + lfodelay -= (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; + return out; +} /* * LFO out (for amplitude) @@ -141,17 +164,21 @@ REALTYPE LFO::lfoout() REALTYPE LFO::amplfoout() { REALTYPE out; - out=1.0-lfointensity+lfoout(); - if (out<-1.0) out=-1.0; - else if (out>1.0) out=1.0; - return(out); -}; + out = 1.0 - lfointensity + lfoout(); + if(out < -1.0) + out = -1.0; + else + if(out > 1.0) + out = 1.0; + return out; +} void LFO::computenextincrnd() { - if (freqrndenabled==0) return; - incrnd=nextincrnd; - nextincrnd=pow(0.5,lfofreqrnd)+RND*(pow(2.0,lfofreqrnd)-1.0); -}; + if(freqrndenabled == 0) + return; + incrnd = nextincrnd; + nextincrnd = pow(0.5, lfofreqrnd) + RND * (pow(2.0, lfofreqrnd) - 1.0); +} diff --git a/plugins/zynaddsubfx/src/Synth/LFO.h b/plugins/zynaddsubfx/src/Synth/LFO.h index 12d01325d..9dd984bcf 100644 --- a/plugins/zynaddsubfx/src/Synth/LFO.h +++ b/plugins/zynaddsubfx/src/Synth/LFO.h @@ -29,31 +29,30 @@ /**Class for creating Low Frequency Ocillators*/ class LFO { -public: - /**Constructor - * - * @param lfopars pointer to a LFOParams object - * @param basefreq base frequency of LFO - */ - LFO(LFOParams *lfopars, REALTYPE basefreq); - /**Deconstructor*/ - ~LFO(); - REALTYPE lfoout(); - REALTYPE amplfoout(); -private: - REALTYPE x; - REALTYPE incx,incrnd,nextincrnd; - REALTYPE amp1,amp2;// used for randomness - REALTYPE lfointensity; - REALTYPE lfornd,lfofreqrnd; - REALTYPE lfodelay; - /**\todo see if an enum would be better here*/ - char lfotype; - int freqrndenabled; + public: + /**Constructor + * + * @param lfopars pointer to a LFOParams object + * @param basefreq base frequency of LFO + */ + LFO(LFOParams *lfopars, REALTYPE basefreq); + /**Deconstructor*/ + ~LFO(); + REALTYPE lfoout(); + REALTYPE amplfoout(); + private: + REALTYPE x; + REALTYPE incx, incrnd, nextincrnd; + REALTYPE amp1, amp2; // used for randomness + REALTYPE lfointensity; + REALTYPE lfornd, lfofreqrnd; + REALTYPE lfodelay; + /**\todo see if an enum would be better here*/ + char lfotype; + int freqrndenabled; - void computenextincrnd(); - + void computenextincrnd(); }; #endif diff --git a/plugins/zynaddsubfx/src/Synth/OscilGen.cpp b/plugins/zynaddsubfx/src/Synth/OscilGen.cpp index 2e67d51dc..bbd62f3bb 100644 --- a/plugins/zynaddsubfx/src/Synth/OscilGen.cpp +++ b/plugins/zynaddsubfx/src/Synth/OscilGen.cpp @@ -27,21 +27,22 @@ #include "OscilGen.h" #include "../Effects/Distorsion.h" -OscilGen::OscilGen(FFTwrapper *fft_,Resonance *res_):Presets() +OscilGen::OscilGen(FFTwrapper *fft_, Resonance *res_):Presets() { setpresettype("Poscilgen"); - fft=fft_; - res=res_; - tmpsmps = new REALTYPE[OSCIL_SIZE]; - newFFTFREQS(&outoscilFFTfreqs, OSCIL_SIZE/2); - newFFTFREQS(&oscilFFTfreqs,OSCIL_SIZE/2); - newFFTFREQS(&basefuncFFTfreqs,OSCIL_SIZE/2); + fft = fft_; + res = res_; - randseed=1; - ADvsPAD=false; + tmpsmps = new REALTYPE[OSCIL_SIZE]; + newFFTFREQS(&outoscilFFTfreqs, OSCIL_SIZE / 2); + newFFTFREQS(&oscilFFTfreqs, OSCIL_SIZE / 2); + newFFTFREQS(&basefuncFFTfreqs, OSCIL_SIZE / 2); + + randseed = 1; + ADvsPAD = false; defaults(); -}; +} OscilGen::~OscilGen() { @@ -49,237 +50,271 @@ OscilGen::~OscilGen() deleteFFTFREQS(&outoscilFFTfreqs); deleteFFTFREQS(&basefuncFFTfreqs); deleteFFTFREQS(&oscilFFTfreqs); -}; +} void OscilGen::defaults() { + oldbasefunc = 0; + oldbasepar = 64; + oldhmagtype = 0; + oldwaveshapingfunction = 0; + oldwaveshaping = 64; + oldbasefuncmodulation = 0; + oldharmonicshift = 0; + oldbasefuncmodulationpar1 = 0; + oldbasefuncmodulationpar2 = 0; + oldbasefuncmodulationpar3 = 0; + oldmodulation = 0; + oldmodulationpar1 = 0; + oldmodulationpar2 = 0; + oldmodulationpar3 = 0; - oldbasefunc=0; - oldbasepar=64; - oldhmagtype=0; - oldwaveshapingfunction=0; - oldwaveshaping=64; - oldbasefuncmodulation=0; - oldharmonicshift=0; - oldbasefuncmodulationpar1=0; - oldbasefuncmodulationpar2=0; - oldbasefuncmodulationpar3=0; - oldmodulation=0; - oldmodulationpar1=0; - oldmodulationpar2=0; - oldmodulationpar3=0; + for(int i = 0; i < MAX_AD_HARMONICS; i++) { + hmag[i] = 0.0; + hphase[i] = 0.0; + Phmag[i] = 64; + Phphase[i] = 64; + } + Phmag[0] = 127; + Phmagtype = 0; + if(ADvsPAD) + Prand = 127; //max phase randomness (usefull if the oscil will be imported to a ADsynth from a PADsynth + else + Prand = 64; //no randomness - for (int i=0;ismps2freqs(oscil,freqs); - delete(fft); + get(oscil, -1.0); + FFTwrapper *fft = new FFTwrapper(OSCIL_SIZE); + fft->smps2freqs(oscil, freqs); + delete (fft); - REALTYPE max=0.0; + REALTYPE max = 0.0; - mag[0]=0; - phase[0]=0; - for (int i=0;i127) Phphase[i]=127; + Phphase[i] = 64 - (int) (64.0 * newphase / PI); + if(Phphase[i] > 127) + Phphase[i] = 127; - if (Phmag[i]==64) Phphase[i]=64; - }; + if(Phmag[i] == 64) + Phphase[i] = 64; + } deleteFFTFREQS(&freqs); prepare(); -}; +} /* * Base Functions - START */ -REALTYPE OscilGen::basefunc_pulse(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_pulse(REALTYPE x, REALTYPE a) { - return((fmod(x,1.0)0.99999) a=0.99999; - x=fmod(x,1); - if (x 0.99999) + a = 0.99999; + x = fmod(x, 1); + if(x < a) + return x / a * 2.0 - 1.0; + else + return (1.0 - x) / (1.0 - a) * 2.0 - 1.0; +} -REALTYPE OscilGen::basefunc_triangle(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_triangle(REALTYPE x, REALTYPE a) { - x=fmod(x+0.25,1); - a=1-a; - if (a<0.00001) a=0.00001; - if (x<0.5) x=x*4-1.0; - else x=(1.0-x)*4-1.0; - x/=-a; - if (x<-1.0) x=-1.0; - if (x>1.0) x=1.0; - return(x); -}; + x = fmod(x + 0.25, 1); + a = 1 - a; + if(a < 0.00001) + a = 0.00001; + if(x < 0.5) + x = x * 4 - 1.0; + else + x = (1.0 - x) * 4 - 1.0; + x /= -a; + if(x < -1.0) + x = -1.0; + if(x > 1.0) + x = 1.0; + return x; +} -REALTYPE OscilGen::basefunc_power(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_power(REALTYPE x, REALTYPE a) { - x=fmod(x,1); - if (a<0.00001) a=0.00001; - else if (a>0.99999) a=0.99999; - return(pow(x,exp((a-0.5)*10.0))*2.0-1.0); -}; + x = fmod(x, 1); + if(a < 0.00001) + a = 0.00001; + else + if(a > 0.99999) + a = 0.99999; + return pow(x, exp((a - 0.5) * 10.0)) * 2.0 - 1.0; +} -REALTYPE OscilGen::basefunc_gauss(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_gauss(REALTYPE x, REALTYPE a) { - x=fmod(x,1)*2.0-1.0; - if (a<0.00001) a=0.00001; - return(exp(-x*x*(exp(a*8)+5.0))*2.0-1.0); -}; + x = fmod(x, 1) * 2.0 - 1.0; + if(a < 0.00001) + a = 0.00001; + return exp(-x * x * (exp(a * 8) + 5.0)) * 2.0 - 1.0; +} -REALTYPE OscilGen::basefunc_diode(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_diode(REALTYPE x, REALTYPE a) { - if (a<0.00001) a=0.00001; - else if (a>0.99999) a=0.99999; - a=a*2.0-1.0; - x=cos((x+0.5)*2.0*PI)-a; - if (x<0.0) x=0.0; - return(x/(1.0-a)*2-1.0); -}; + if(a < 0.00001) + a = 0.00001; + else + if(a > 0.99999) + a = 0.99999; + a = a * 2.0 - 1.0; + x = cos((x + 0.5) * 2.0 * PI) - a; + if(x < 0.0) + x = 0.0; + return x / (1.0 - a) * 2 - 1.0; +} -REALTYPE OscilGen::basefunc_abssine(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_abssine(REALTYPE x, REALTYPE a) { - x=fmod(x,1); - if (a<0.00001) a=0.00001; - else if (a>0.99999) a=0.99999; - return(sin(pow(x,exp((a-0.5)*5.0))*PI)*2.0-1.0); -}; + x = fmod(x, 1); + if(a < 0.00001) + a = 0.00001; + else + if(a > 0.99999) + a = 0.99999; + return sin(pow(x, exp((a - 0.5) * 5.0)) * PI) * 2.0 - 1.0; +} -REALTYPE OscilGen::basefunc_pulsesine(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_pulsesine(REALTYPE x, REALTYPE a) { - if (a<0.00001) a=0.00001; - x=(fmod(x,1)-0.5)*exp((a-0.5)*log(128)); - if (x<-0.5) x=-0.5; - else if (x>0.5) x=0.5; - x=sin(x*PI*2.0); - return(x); -}; + if(a < 0.00001) + a = 0.00001; + x = (fmod(x, 1) - 0.5) * exp((a - 0.5) * log(128)); + if(x < -0.5) + x = -0.5; + else + if(x > 0.5) + x = 0.5; + x = sin(x * PI * 2.0); + return x; +} -REALTYPE OscilGen::basefunc_stretchsine(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_stretchsine(REALTYPE x, REALTYPE a) { - x=fmod(x+0.5,1)*2.0-1.0; - a=(a-0.5)*4; - if (a>0.0) a*=2; - a=pow(3.0,a); - REALTYPE b=pow(fabs(x),a); - if (x<0) b=-b; - return(-sin(b*PI)); -}; + x = fmod(x + 0.5, 1) * 2.0 - 1.0; + a = (a - 0.5) * 4; + if(a > 0.0) + a *= 2; + a = pow(3.0, a); + REALTYPE b = pow(fabs(x), a); + if(x < 0) + b = -b; + return -sin(b * PI); +} -REALTYPE OscilGen::basefunc_chirp(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_chirp(REALTYPE x, REALTYPE a) { - x=fmod(x,1.0)*2.0*PI; - a=(a-0.5)*4; - if (a<0.0) a*=2.0; - a=pow(3.0,a); - return(sin(x/2.0)*sin(a*x*x)); -}; + x = fmod(x, 1.0) * 2.0 * PI; + a = (a - 0.5) * 4; + if(a < 0.0) + a *= 2.0; + a = pow(3.0, a); + return sin(x / 2.0) * sin(a * x * x); +} -REALTYPE OscilGen::basefunc_absstretchsine(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_absstretchsine(REALTYPE x, REALTYPE a) { - x=fmod(x+0.5,1)*2.0-1.0; - a=(a-0.5)*9; - a=pow(3.0,a); - REALTYPE b=pow(fabs(x),a); - if (x<0) b=-b; - return(-pow(sin(b*PI),2)); -}; + x = fmod(x + 0.5, 1) * 2.0 - 1.0; + a = (a - 0.5) * 9; + a = pow(3.0, a); + REALTYPE b = pow(fabs(x), a); + if(x < 0) + b = -b; + return -pow(sin(b * PI), 2); +} -REALTYPE OscilGen::basefunc_chebyshev(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_chebyshev(REALTYPE x, REALTYPE a) { - a=a*a*a*30.0+1.0; - return(cos(acos(x*2.0-1.0)*a)); -}; + a = a * a * a * 30.0 + 1.0; + return cos(acos(x * 2.0 - 1.0) * a); +} -REALTYPE OscilGen::basefunc_sqr(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_sqr(REALTYPE x, REALTYPE a) { - a=a*a*a*a*160.0+0.001; - return(-atan(sin(x*2.0*PI)*a)); -}; + a = a * a * a * a * 160.0 + 0.001; + return -atan(sin(x * 2.0 * PI) * a); +} /* * Base Functions - END */ @@ -290,223 +325,266 @@ REALTYPE OscilGen::basefunc_sqr(REALTYPE x,REALTYPE a) */ void OscilGen::getbasefunction(REALTYPE *smps) { - int i; - REALTYPE par=(Pbasefuncpar+0.5)/128.0; - if (Pbasefuncpar==64) par=0.5; + int i; + REALTYPE par = (Pbasefuncpar + 0.5) / 128.0; + if(Pbasefuncpar == 64) + par = 0.5; - REALTYPE basefuncmodulationpar1=Pbasefuncmodulationpar1/127.0, - basefuncmodulationpar2=Pbasefuncmodulationpar2/127.0, - basefuncmodulationpar3=Pbasefuncmodulationpar3/127.0; + REALTYPE basefuncmodulationpar1 = Pbasefuncmodulationpar1 / 127.0, + basefuncmodulationpar2 = Pbasefuncmodulationpar2 / 127.0, + basefuncmodulationpar3 = Pbasefuncmodulationpar3 / 127.0; - switch (Pbasefuncmodulation) { + switch(Pbasefuncmodulation) { case 1: - basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*5.0)-1.0)/10.0; - basefuncmodulationpar3=floor((pow(2,basefuncmodulationpar3*5.0)-1.0)); - if (basefuncmodulationpar3<0.9999) basefuncmodulationpar3=-1.0; + basefuncmodulationpar1 = + (pow(2, basefuncmodulationpar1 * 5.0) - 1.0) / 10.0; + basefuncmodulationpar3 = + floor((pow(2, basefuncmodulationpar3 * 5.0) - 1.0)); + if(basefuncmodulationpar3 < 0.9999) + basefuncmodulationpar3 = -1.0; break; case 2: - basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*5.0)-1.0)/10.0; - basefuncmodulationpar3=1.0+floor((pow(2,basefuncmodulationpar3*5.0)-1.0)); + basefuncmodulationpar1 = + (pow(2, basefuncmodulationpar1 * 5.0) - 1.0) / 10.0; + basefuncmodulationpar3 = 1.0 + + floor((pow(2, basefuncmodulationpar3 + * 5.0) - 1.0)); break; case 3: - basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*7.0)-1.0)/10.0; - basefuncmodulationpar3=0.01+(pow(2,basefuncmodulationpar3*16.0)-1.0)/10.0; + basefuncmodulationpar1 = + (pow(2, basefuncmodulationpar1 * 7.0) - 1.0) / 10.0; + basefuncmodulationpar3 = 0.01 + + (pow(2, basefuncmodulationpar3 + * 16.0) - 1.0) / 10.0; break; - }; + } // printf("%.5f %.5f\n",basefuncmodulationpar1,basefuncmodulationpar3); - for (i=0;ipow(2,(1.0-par)*10)?0.0:1.0)*par2+(1.0-par2);//lp2 + tmp = pow(par2, 0.33); + gain = + (i + 1 > + pow(2, (1.0 - par) * 10) ? 0.0 : 1.0) * par2 + (1.0 - par2); //lp2 break; case 7: - tmp=pow(par2,0.33); + tmp = pow(par2, 0.33); //tmp=1.0-(1.0-par2)*(1.0-par2); - gain=(i+1>pow(2,(1.0-par)*7)?1.0:0.0)*par2+(1.0-par2);//hp2 - if (Pfilterpar1==0) gain=1.0; + gain = + (i + 1 > + pow(2, (1.0 - par) * 7) ? 1.0 : 0.0) * par2 + (1.0 - par2); //hp2 + if(Pfilterpar1 == 0) + gain = 1.0; break; case 8: - tmp=pow(par2,0.33); + tmp = pow(par2, 0.33); //tmp=1.0-(1.0-par2)*(1.0-par2); - gain=(fabs(pow(2,(1.0-par)*7)-i)>i/2+1?0.0:1.0)*par2+(1.0-par2);//bp2 + gain = + (fabs(pow(2, + (1.0 + - par) + * 7) - i) > i / 2 + 1 ? 0.0 : 1.0) * par2 + (1.0 - par2); //bp2 break; case 9: - tmp=pow(par2,0.33); - gain=(fabs(pow(2,(1.0-par)*7)-i)1.0) x=1.0; - tmp=pow(1.0-par2,2.0); - gain=cos(x*PI)*(1.0-tmp)+1.01+tmp;//low shelf + p2 = 1.0 - par + 0.2; + x = i / (64.0 * p2 * p2); + if(x < 0.0) + x = 0.0; + else + if(x > 1.0) + x = 1.0; + tmp = pow(1.0 - par2, 2.0); + gain = cos(x * PI) * (1.0 - tmp) + 1.01 + tmp; //low shelf break; case 13: - tmp=(int) (pow(2.0,(1.0-par)*7.2)); - gain=1.0; - if (i==(int) (tmp)) gain=pow(2.0,par2*par2*8.0); + tmp = (int) (pow(2.0, (1.0 - par) * 7.2)); + gain = 1.0; + if(i == (int) (tmp)) + gain = pow(2.0, par2 * par2 * 8.0); break; - }; + } - oscilFFTfreqs.s[i]*=gain; - oscilFFTfreqs.c[i]*=gain; - REALTYPE tmp=oscilFFTfreqs.s[i]*oscilFFTfreqs.s[i]+ - oscilFFTfreqs.c[i]*oscilFFTfreqs.c[i]; - if (maxsmps2freqs(tmpsmps,basefuncFFTfreqs); - basefuncFFTfreqs.c[0]=0.0; - } else { - for (int i=0;ismps2freqs(tmpsmps, basefuncFFTfreqs); + basefuncFFTfreqs.c[0] = 0.0; + } + else { + for(int i = 0; i < OSCIL_SIZE / 2; i++) { + basefuncFFTfreqs.s[i] = 0.0; + basefuncFFTfreqs.c[i] = 0.0; + } //in this case basefuncFFTfreqs_ are not used } - oscilprepared=0; - oldbasefunc=Pcurrentbasefunc; - oldbasepar=Pbasefuncpar; - oldbasefuncmodulation=Pbasefuncmodulation; - oldbasefuncmodulationpar1=Pbasefuncmodulationpar1; - oldbasefuncmodulationpar2=Pbasefuncmodulationpar2; - oldbasefuncmodulationpar3=Pbasefuncmodulationpar3; -}; + oscilprepared = 0; + oldbasefunc = Pcurrentbasefunc; + oldbasepar = Pbasefuncpar; + oldbasefuncmodulation = Pbasefuncmodulation; + oldbasefuncmodulationpar1 = Pbasefuncmodulationpar1; + oldbasefuncmodulationpar2 = Pbasefuncmodulationpar2; + oldbasefuncmodulationpar3 = Pbasefuncmodulationpar3; +} /* * Waveshape @@ -515,32 +593,36 @@ void OscilGen::waveshape() { int i; - oldwaveshapingfunction=Pwaveshapingfunction; - oldwaveshaping=Pwaveshaping; - if (Pwaveshapingfunction==0) return; + oldwaveshapingfunction = Pwaveshapingfunction; + oldwaveshaping = Pwaveshaping; + if(Pwaveshapingfunction == 0) + return; - oscilFFTfreqs.c[0]=0.0;//remove the DC + oscilFFTfreqs.c[0] = 0.0; //remove the DC //reduce the amplitude of the freqs near the nyquist - for (i=1;ifreqs2smps(oscilFFTfreqs,tmpsmps); + for(i = 1; i < OSCIL_SIZE / 8; i++) { + REALTYPE tmp = i / (OSCIL_SIZE / 8.0); + oscilFFTfreqs.s[OSCIL_SIZE / 2 - i] *= tmp; + oscilFFTfreqs.c[OSCIL_SIZE / 2 - i] *= tmp; + } + fft->freqs2smps(oscilFFTfreqs, tmpsmps); //Normalize - REALTYPE max=0.0; - for (i=0;ismps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT -}; + fft->smps2freqs(tmpsmps, oscilFFTfreqs); //perform FFT +} /* @@ -550,79 +632,91 @@ void OscilGen::modulation() { int i; - oldmodulation=Pmodulation; - oldmodulationpar1=Pmodulationpar1; - oldmodulationpar2=Pmodulationpar2; - oldmodulationpar3=Pmodulationpar3; - if (Pmodulation==0) return; + oldmodulation = Pmodulation; + oldmodulationpar1 = Pmodulationpar1; + oldmodulationpar2 = Pmodulationpar2; + oldmodulationpar3 = Pmodulationpar3; + if(Pmodulation == 0) + return; - REALTYPE modulationpar1=Pmodulationpar1/127.0, - modulationpar2=0.5-Pmodulationpar2/127.0, - modulationpar3=Pmodulationpar3/127.0; + REALTYPE modulationpar1 = Pmodulationpar1 / 127.0, + modulationpar2 = 0.5 - Pmodulationpar2 / 127.0, + modulationpar3 = Pmodulationpar3 / 127.0; - switch (Pmodulation) { + switch(Pmodulation) { case 1: - modulationpar1=(pow(2,modulationpar1*7.0)-1.0)/100.0; - modulationpar3=floor((pow(2,modulationpar3*5.0)-1.0)); - if (modulationpar3<0.9999) modulationpar3=-1.0; + modulationpar1 = (pow(2, modulationpar1 * 7.0) - 1.0) / 100.0; + modulationpar3 = floor((pow(2, modulationpar3 * 5.0) - 1.0)); + if(modulationpar3 < 0.9999) + modulationpar3 = -1.0; break; case 2: - modulationpar1=(pow(2,modulationpar1*7.0)-1.0)/100.0; - modulationpar3=1.0+floor((pow(2,modulationpar3*5.0)-1.0)); + modulationpar1 = (pow(2, modulationpar1 * 7.0) - 1.0) / 100.0; + modulationpar3 = 1.0 + floor((pow(2, modulationpar3 * 5.0) - 1.0)); break; case 3: - modulationpar1=(pow(2,modulationpar1*9.0)-1.0)/100.0; - modulationpar3=0.01+(pow(2,modulationpar3*16.0)-1.0)/10.0; + modulationpar1 = (pow(2, modulationpar1 * 9.0) - 1.0) / 100.0; + modulationpar3 = 0.01 + (pow(2, modulationpar3 * 16.0) - 1.0) / 10.0; break; - }; + } - oscilFFTfreqs.c[0]=0.0;//remove the DC + oscilFFTfreqs.c[0] = 0.0; //remove the DC //reduce the amplitude of the freqs near the nyquist - for (i=1;ifreqs2smps(oscilFFTfreqs,tmpsmps); - int extra_points=2; - REALTYPE *in=new REALTYPE[OSCIL_SIZE+extra_points]; + for(i = 1; i < OSCIL_SIZE / 8; i++) { + REALTYPE tmp = i / (OSCIL_SIZE / 8.0); + oscilFFTfreqs.s[OSCIL_SIZE / 2 - i] *= tmp; + oscilFFTfreqs.c[OSCIL_SIZE / 2 - i] *= tmp; + } + fft->freqs2smps(oscilFFTfreqs, tmpsmps); + int extra_points = 2; + REALTYPE *in = new REALTYPE[OSCIL_SIZE + extra_points]; //Normalize - REALTYPE max=0.0; - for (i=0;ismps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT -}; + fft->smps2freqs(tmpsmps, oscilFFTfreqs); //perform FFT +} @@ -631,477 +725,534 @@ void OscilGen::modulation() */ void OscilGen::spectrumadjust() { - if (Psatype==0) return; - REALTYPE par=Psapar/127.0; - switch (Psatype) { + if(Psatype == 0) + return; + REALTYPE par = Psapar / 127.0; + switch(Psatype) { case 1: - par=1.0-par*2.0; - if (par>=0.0) par=pow(5.0,par); - else par=pow(8.0,par); + par = 1.0 - par * 2.0; + if(par >= 0.0) + par = pow(5.0, par); + else + par = pow(8.0, par); break; case 2: - par=pow(10.0,(1.0-par)*3.0)*0.25; + par = pow(10.0, (1.0 - par) * 3.0) * 0.25; break; case 3: - par=pow(10.0,(1.0-par)*3.0)*0.25; + par = pow(10.0, (1.0 - par) * 3.0) * 0.25; break; - }; + } - REALTYPE max=0.0; - for (int i=0;i1.0) mag=1.0; + mag /= par; + if(mag > 1.0) + mag = 1.0; break; - }; - oscilFFTfreqs.c[i]=mag*cos(phase); - oscilFFTfreqs.s[i]=mag*sin(phase); - }; - -}; + } + oscilFFTfreqs.c[i] = mag * cos(phase); + oscilFFTfreqs.s[i] = mag * sin(phase); + } +} void OscilGen::shiftharmonics() { - if (Pharmonicshift==0) return; + if(Pharmonicshift == 0) + return; - REALTYPE hc,hs; - int harmonicshift=-Pharmonicshift; + REALTYPE hc, hs; + int harmonicshift = -Pharmonicshift; - if (harmonicshift>0) { - for (int i=OSCIL_SIZE/2-2;i>=0;i--) { - int oldh=i-harmonicshift; - if (oldh<0) { - hc=0.0; - hs=0.0; - } else { - hc=oscilFFTfreqs.c[oldh+1]; - hs=oscilFFTfreqs.s[oldh+1]; - }; - oscilFFTfreqs.c[i+1]=hc; - oscilFFTfreqs.s[i+1]=hs; - }; - } else { - for (int i=0;i=(OSCIL_SIZE/2-1)) { - hc=0.0; - hs=0.0; - } else { - hc=oscilFFTfreqs.c[oldh+1]; - hs=oscilFFTfreqs.s[oldh+1]; - if (fabs(hc)<0.000001) hc=0.0; - if (fabs(hs)<0.000001) hs=0.0; - }; + if(harmonicshift > 0) { + for(int i = OSCIL_SIZE / 2 - 2; i >= 0; i--) { + int oldh = i - harmonicshift; + if(oldh < 0) { + hc = 0.0; + hs = 0.0; + } + else { + hc = oscilFFTfreqs.c[oldh + 1]; + hs = oscilFFTfreqs.s[oldh + 1]; + } + oscilFFTfreqs.c[i + 1] = hc; + oscilFFTfreqs.s[i + 1] = hs; + } + } + else { + for(int i = 0; i < OSCIL_SIZE / 2 - 1; i++) { + int oldh = i + abs(harmonicshift); + if(oldh >= (OSCIL_SIZE / 2 - 1)) { + hc = 0.0; + hs = 0.0; + } + else { + hc = oscilFFTfreqs.c[oldh + 1]; + hs = oscilFFTfreqs.s[oldh + 1]; + if(fabs(hc) < 0.000001) + hc = 0.0; + if(fabs(hs) < 0.000001) + hs = 0.0; + } - oscilFFTfreqs.c[i+1]=hc; - oscilFFTfreqs.s[i+1]=hs; - }; - }; + oscilFFTfreqs.c[i + 1] = hc; + oscilFFTfreqs.s[i + 1] = hs; + } + } - oscilFFTfreqs.c[0]=0.0; -}; + oscilFFTfreqs.c[0] = 0.0; +} /* * Prepare the Oscillator */ void OscilGen::prepare() { - int i,j,k; - REALTYPE a,b,c,d,hmagnew; + int i, j, k; + REALTYPE a, b, c, d, hmagnew; - if ((oldbasepar!=Pbasefuncpar)||(oldbasefunc!=Pcurrentbasefunc)|| - (oldbasefuncmodulation!=Pbasefuncmodulation)|| - (oldbasefuncmodulationpar1!=Pbasefuncmodulationpar1)|| - (oldbasefuncmodulationpar2!=Pbasefuncmodulationpar2)|| - (oldbasefuncmodulationpar3!=Pbasefuncmodulationpar3)) + if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc) + || (oldbasefuncmodulation != Pbasefuncmodulation) + || (oldbasefuncmodulationpar1 != Pbasefuncmodulationpar1) + || (oldbasefuncmodulationpar2 != Pbasefuncmodulationpar2) + || (oldbasefuncmodulationpar3 != Pbasefuncmodulationpar3)) changebasefunction(); - for (i=0;i=OSCIL_SIZE/2) break; - a=basefuncFFTfreqs.c[i]; - b=basefuncFFTfreqs.s[i]; - c=hmag[j]*cos(hphase[j]*k); - d=hmag[j]*sin(hphase[j]*k); - oscilFFTfreqs.c[k]+=a*c-b*d; - oscilFFTfreqs.s[k]+=a*d+b*c; - }; - }; + for(i = 0; i < OSCIL_SIZE / 2; i++) { + oscilFFTfreqs.c[i] = 0.0; + oscilFFTfreqs.s[i] = 0.0; + } + if(Pcurrentbasefunc == 0) { //the sine case + for(i = 0; i < MAX_AD_HARMONICS; i++) { + oscilFFTfreqs.c[i + 1] = -hmag[i] * sin(hphase[i] * (i + 1)) / 2.0; + oscilFFTfreqs.s[i + 1] = hmag[i] * cos(hphase[i] * (i + 1)) / 2.0; + } + } + else { + for(j = 0; j < MAX_AD_HARMONICS; j++) { + if(Phmag[j] == 64) + continue; + for(i = 1; i < OSCIL_SIZE / 2; i++) { + k = i * (j + 1); + if(k >= OSCIL_SIZE / 2) + break; + a = basefuncFFTfreqs.c[i]; + b = basefuncFFTfreqs.s[i]; + c = hmag[j] * cos(hphase[j] * k); + d = hmag[j] * sin(hphase[j] * k); + oscilFFTfreqs.c[k] += a * c - b * d; + oscilFFTfreqs.s[k] += a * d + b * c; + } + } + } - }; - - if (Pharmonicshiftfirst!=0) shiftharmonics(); + if(Pharmonicshiftfirst != 0) + shiftharmonics(); - if (Pfilterbeforews==0) { + if(Pfilterbeforews == 0) { waveshape(); oscilfilter(); - } else { + } + else { oscilfilter(); waveshape(); - }; + } modulation(); spectrumadjust(); - if (Pharmonicshiftfirst==0) shiftharmonics(); + if(Pharmonicshiftfirst == 0) + shiftharmonics(); - oscilFFTfreqs.c[0]=0.0; + oscilFFTfreqs.c[0] = 0.0; - oldhmagtype=Phmagtype; - oldharmonicshift=Pharmonicshift+Pharmonicshiftfirst*256; + oldhmagtype = Phmagtype; + oldharmonicshift = Pharmonicshift + Pharmonicshiftfirst * 256; - oscilprepared=1; -}; + oscilprepared = 1; +} -void OscilGen::adaptiveharmonic(FFTFREQS f,REALTYPE freq) +void OscilGen::adaptiveharmonic(FFTFREQS f, REALTYPE freq) { - if ((Padaptiveharmonics==0)/*||(freq<1.0)*/) return; - if (freq<1.0) freq=440.0; + if((Padaptiveharmonics == 0) /*||(freq<1.0)*/) + return; + if(freq < 1.0) + freq = 440.0; FFTFREQS inf; - newFFTFREQS(&inf,OSCIL_SIZE/2); - for (int i=0;i1.0) { - rap=1.0/rap; - down=true; - }; + bool down = false; + if(rap > 1.0) { + rap = 1.0 / rap; + down = true; + } - for (int i=0;i=(OSCIL_SIZE/2-2)) { + if(high >= (OSCIL_SIZE / 2 - 2)) break; - } else { - if (down) { - f.c[high]+=inf.c[i]*(1.0-low); - f.s[high]+=inf.s[i]*(1.0-low); - f.c[high+1]+=inf.c[i]*low; - f.s[high+1]+=inf.s[i]*low; - } else { - hc=inf.c[high]*(1.0-low)+inf.c[high+1]*low; - hs=inf.s[high]*(1.0-low)+inf.s[high+1]*low; - }; - if (fabs(hc)<0.000001) hc=0.0; - if (fabs(hs)<0.000001) hs=0.0; - }; + else { + if(down) { + f.c[high] += inf.c[i] * (1.0 - low); + f.s[high] += inf.s[i] * (1.0 - low); + f.c[high + 1] += inf.c[i] * low; + f.s[high + 1] += inf.s[i] * low; + } + else { + hc = inf.c[high] * (1.0 - low) + inf.c[high + 1] * low; + hs = inf.s[high] * (1.0 - low) + inf.s[high + 1] * low; + } + if(fabs(hc) < 0.000001) + hc = 0.0; + if(fabs(hs) < 0.000001) + hs = 0.0; + } - if (!down) { - if (i==0) {//corect the aplitude of the first harmonic - hc*=rap; - hs*=rap; - }; - f.c[i]=hc; - f.s[i]=hs; - }; - }; + if(!down) { + if(i == 0) { //corect the aplitude of the first harmonic + hc *= rap; + hs *= rap; + } + f.c[i] = hc; + f.s[i] = hs; + } + } - f.c[1]+=f.c[0]; - f.s[1]+=f.s[0]; - f.c[0]=0.0; - f.s[0]=0.0; + f.c[1] += f.c[0]; + f.s[1] += f.s[0]; + f.c[0] = 0.0; + f.s[0] = 0.0; deleteFFTFREQS(&inf); -}; +} -void OscilGen::adaptiveharmonicpostprocess(REALTYPE *f,int size) +void OscilGen::adaptiveharmonicpostprocess(REALTYPE *f, int size) { - if (Padaptiveharmonics<=1) return; - REALTYPE *inf=new REALTYPE[size]; - REALTYPE par=Padaptiveharmonicspar*0.01; - par=1.0-pow((1.0-par),1.5); + if(Padaptiveharmonics <= 1) + return; + REALTYPE *inf = new REALTYPE[size]; + REALTYPE par = Padaptiveharmonicspar * 0.01; + par = 1.0 - pow((1.0 - par), 1.5); - for (int i=0;iget(smps,freqHz,0)); -}; + return this->get(smps, freqHz, 0); +} void OscilGen::newrandseed(unsigned int randseed) { - this->randseed=randseed; -}; + this->randseed = randseed; +} /* * Get the oscillator function */ -short int OscilGen::get(REALTYPE *smps,REALTYPE freqHz,int resonance) +short int OscilGen::get(REALTYPE *smps, REALTYPE freqHz, int resonance) { int i; - int nyquist,outpos; + int nyquist, outpos; - if ((oldbasepar!=Pbasefuncpar)||(oldbasefunc!=Pcurrentbasefunc)||(oldhmagtype!=Phmagtype) - ||(oldwaveshaping!=Pwaveshaping)||(oldwaveshapingfunction!=Pwaveshapingfunction)) oscilprepared=0; - if (oldfilterpars!=Pfiltertype*256+Pfilterpar1+Pfilterpar2*65536+Pfilterbeforews*16777216) { - oscilprepared=0; - oldfilterpars=Pfiltertype*256+Pfilterpar1+Pfilterpar2*65536+Pfilterbeforews*16777216; - }; - if (oldsapars!=Psatype*256+Psapar) { - oscilprepared=0; - oldsapars=Psatype*256+Psapar; - }; + if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc) + || (oldhmagtype != Phmagtype) + || (oldwaveshaping != Pwaveshaping) + || (oldwaveshapingfunction != Pwaveshapingfunction)) + oscilprepared = 0; + if(oldfilterpars != Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536 + + Pfilterbeforews * 16777216) { + oscilprepared = 0; + oldfilterpars = Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536 + + Pfilterbeforews * 16777216; + } + if(oldsapars != Psatype * 256 + Psapar) { + oscilprepared = 0; + oldsapars = Psatype * 256 + Psapar; + } - if ((oldbasefuncmodulation!=Pbasefuncmodulation)|| - (oldbasefuncmodulationpar1!=Pbasefuncmodulationpar1)|| - (oldbasefuncmodulationpar2!=Pbasefuncmodulationpar2)|| - (oldbasefuncmodulationpar3!=Pbasefuncmodulationpar3)) - oscilprepared=0; + if((oldbasefuncmodulation != Pbasefuncmodulation) + || (oldbasefuncmodulationpar1 != Pbasefuncmodulationpar1) + || (oldbasefuncmodulationpar2 != Pbasefuncmodulationpar2) + || (oldbasefuncmodulationpar3 != Pbasefuncmodulationpar3)) + oscilprepared = 0; - if ((oldmodulation!=Pmodulation)|| - (oldmodulationpar1!=Pmodulationpar1)|| - (oldmodulationpar2!=Pmodulationpar2)|| - (oldmodulationpar3!=Pmodulationpar3)) - oscilprepared=0; + if((oldmodulation != Pmodulation) + || (oldmodulationpar1 != Pmodulationpar1) + || (oldmodulationpar2 != Pmodulationpar2) + || (oldmodulationpar3 != Pmodulationpar3)) + oscilprepared = 0; - if (oldharmonicshift!=Pharmonicshift+Pharmonicshiftfirst*256) oscilprepared=0; + if(oldharmonicshift != Pharmonicshift + Pharmonicshiftfirst * 256) + oscilprepared = 0; - if (oscilprepared!=1) prepare(); + if(oscilprepared != 1) + prepare(); - outpos=(int)((RND*2.0-1.0)*(REALTYPE) OSCIL_SIZE*(Prand-64.0)/64.0); - outpos=(outpos+2*OSCIL_SIZE) % OSCIL_SIZE; + outpos = + (int)((RND * 2.0 - 1.0) * (REALTYPE) OSCIL_SIZE * (Prand - 64.0) / 64.0); + outpos = (outpos + 2 * OSCIL_SIZE) % OSCIL_SIZE; - for (i=0;iOSCIL_SIZE/2) nyquist=OSCIL_SIZE/2; + nyquist = (int)(0.5 * SAMPLE_RATE / fabs(freqHz)) + 2; + if(ADvsPAD) + nyquist = (int)(OSCIL_SIZE / 2); + if(nyquist > OSCIL_SIZE / 2) + nyquist = OSCIL_SIZE / 2; - int realnyquist=nyquist; + int realnyquist = nyquist; - if (Padaptiveharmonics!=0) nyquist=OSCIL_SIZE/2; - for (i=1;i64)&&(freqHz>=0.0)&&(!ADvsPAD)) { - REALTYPE rnd,angle,a,b,c,d; - rnd=PI*pow((Prand-64.0)/64.0,2.0); - for (i=1;i 64) && (freqHz >= 0.0) && (!ADvsPAD)) { + REALTYPE rnd, angle, a, b, c, d; + rnd = PI * pow((Prand - 64.0) / 64.0, 2.0); + for(i = 1; i < nyquist - 1; i++) { //to Nyquist only for AntiAliasing + angle = rnd * i * RND; + a = outoscilFFTfreqs.c[i]; + b = outoscilFFTfreqs.s[i]; + c = cos(angle); + d = sin(angle); + outoscilFFTfreqs.c[i] = a * c - b * d; + outoscilFFTfreqs.s[i] = a * d + b * c; + } + } //Harmonic Amplitude Randomness - if ((freqHz>0.1)&&(!ADvsPAD)) { - unsigned int realrnd=rand(); + if((freqHz > 0.1) && (!ADvsPAD)) { + unsigned int realrnd = rand(); srand(randseed); - REALTYPE power=Pamprandpower/127.0; - REALTYPE normalize=1.0/(1.2-power); - switch (Pamprandtype) { + REALTYPE power = Pamprandpower / 127.0; + REALTYPE normalize = 1.0 / (1.2 - power); + switch(Pamprandtype) { case 1: - power=power*2.0-0.5; - power=pow(15.0,power); - for (i=1;i0.1)&&(resonance!=0)) res->applyres(nyquist-1,outoscilFFTfreqs,freqHz); + if((freqHz > 0.1) && (resonance != 0)) + res->applyres(nyquist - 1, outoscilFFTfreqs, freqHz); //Full RMS normalize - REALTYPE sum=0; - for (int j=1;j0.1)) {//in this case the smps will contain the freqs - for (i=1;ifreqs2smps(outoscilFFTfreqs,smps); - for (i=0;i 0.1)) //in this case the smps will contain the freqs + for(i = 1; i < OSCIL_SIZE / 2; i++) + smps[i - 1] = sqrt(outoscilFFTfreqs.c[i] * outoscilFFTfreqs.c[i] + + outoscilFFTfreqs.s[i] * outoscilFFTfreqs.s[i]); + else { + fft->freqs2smps(outoscilFFTfreqs, smps); + for(i = 0; i < OSCIL_SIZE; i++) + smps[i] *= 0.25; //correct the amplitude + } - if (Prand<64) return(outpos); - else return(0); -}; + if(Prand < 64) + return outpos; + else + return 0; +} /* * Get the spectrum of the oscillator for the UI */ -void OscilGen::getspectrum(int n, REALTYPE *spc,int what) +void OscilGen::getspectrum(int n, REALTYPE *spc, int what) { - if (n>OSCIL_SIZE/2) n=OSCIL_SIZE/2; + if(n > OSCIL_SIZE / 2) + n = OSCIL_SIZE / 2; - for (int i=1;ifreqs2smps(basefuncFFTfreqs,smps); - } else getbasefunction(smps);//the sine case -}; + if(Pcurrentbasefunc != 0) + fft->freqs2smps(basefuncFFTfreqs, smps); + else + getbasefunction(smps); //the sine case +} void OscilGen::add2XML(XMLwrapper *xml) { - xml->addpar("harmonic_mag_type",Phmagtype); + xml->addpar("harmonic_mag_type", Phmagtype); - xml->addpar("base_function",Pcurrentbasefunc); - xml->addpar("base_function_par",Pbasefuncpar); - xml->addpar("base_function_modulation",Pbasefuncmodulation); - xml->addpar("base_function_modulation_par1",Pbasefuncmodulationpar1); - xml->addpar("base_function_modulation_par2",Pbasefuncmodulationpar2); - xml->addpar("base_function_modulation_par3",Pbasefuncmodulationpar3); + xml->addpar("base_function", Pcurrentbasefunc); + xml->addpar("base_function_par", Pbasefuncpar); + xml->addpar("base_function_modulation", Pbasefuncmodulation); + xml->addpar("base_function_modulation_par1", Pbasefuncmodulationpar1); + xml->addpar("base_function_modulation_par2", Pbasefuncmodulationpar2); + xml->addpar("base_function_modulation_par3", Pbasefuncmodulationpar3); - xml->addpar("modulation",Pmodulation); - xml->addpar("modulation_par1",Pmodulationpar1); - xml->addpar("modulation_par2",Pmodulationpar2); - xml->addpar("modulation_par3",Pmodulationpar3); + xml->addpar("modulation", Pmodulation); + xml->addpar("modulation_par1", Pmodulationpar1); + xml->addpar("modulation_par2", Pmodulationpar2); + xml->addpar("modulation_par3", Pmodulationpar3); - xml->addpar("wave_shaping",Pwaveshaping); - xml->addpar("wave_shaping_function",Pwaveshapingfunction); + xml->addpar("wave_shaping", Pwaveshaping); + xml->addpar("wave_shaping_function", Pwaveshapingfunction); - xml->addpar("filter_type",Pfiltertype); - xml->addpar("filter_par1",Pfilterpar1); - xml->addpar("filter_par2",Pfilterpar2); - xml->addpar("filter_before_wave_shaping",Pfilterbeforews); + xml->addpar("filter_type", Pfiltertype); + xml->addpar("filter_par1", Pfilterpar1); + xml->addpar("filter_par2", Pfilterpar2); + xml->addpar("filter_before_wave_shaping", Pfilterbeforews); - xml->addpar("spectrum_adjust_type",Psatype); - xml->addpar("spectrum_adjust_par",Psapar); + xml->addpar("spectrum_adjust_type", Psatype); + xml->addpar("spectrum_adjust_par", Psapar); - xml->addpar("rand",Prand); - xml->addpar("amp_rand_type",Pamprandtype); - xml->addpar("amp_rand_power",Pamprandpower); + xml->addpar("rand", Prand); + xml->addpar("amp_rand_type", Pamprandtype); + xml->addpar("amp_rand_power", Pamprandpower); - xml->addpar("harmonic_shift",Pharmonicshift); - xml->addparbool("harmonic_shift_first",Pharmonicshiftfirst); + xml->addpar("harmonic_shift", Pharmonicshift); + xml->addparbool("harmonic_shift_first", Pharmonicshiftfirst); - xml->addpar("adaptive_harmonics",Padaptiveharmonics); - xml->addpar("adaptive_harmonics_base_frequency",Padaptiveharmonicsbasefreq); - xml->addpar("adaptive_harmonics_power",Padaptiveharmonicspower); + xml->addpar("adaptive_harmonics", Padaptiveharmonics); + xml->addpar("adaptive_harmonics_base_frequency", Padaptiveharmonicsbasefreq); + xml->addpar("adaptive_harmonics_power", Padaptiveharmonicspower); xml->beginbranch("HARMONICS"); - for (int n=0;nbeginbranch("HARMONIC",n+1); - xml->addpar("mag",Phmag[n]); - xml->addpar("phase",Phphase[n]); + for(int n = 0; n < MAX_AD_HARMONICS; n++) { + if((Phmag[n] == 64) && (Phphase[n] == 64)) + continue; + xml->beginbranch("HARMONIC", n + 1); + xml->addpar("mag", Phmag[n]); + xml->addpar("phase", Phphase[n]); xml->endbranch(); - }; + } xml->endbranch(); - if (Pcurrentbasefunc==127) { - REALTYPE max=0.0; + if(Pcurrentbasefunc == 127) { + REALTYPE max = 0.0; - for (int i=0;ibeginbranch("BASE_FUNCTION"); - for (int i=1;i0.00001)&&(fabs(xs)>0.00001)) { - xml->beginbranch("BF_HARMONIC",i); - xml->addparreal("cos",xc); - xml->addparreal("sin",xs); + for(int i = 1; i < OSCIL_SIZE / 2; i++) { + REALTYPE xc = basefuncFFTfreqs.c[i] / max; + REALTYPE xs = basefuncFFTfreqs.s[i] / max; + if((fabs(xs) > 0.00001) && (fabs(xs) > 0.00001)) { + xml->beginbranch("BF_HARMONIC", i); + xml->addparreal("cos", xc); + xml->addparreal("sin", xs); xml->endbranch(); - }; - }; + } + } xml->endbranch(); - }; -}; + } +} void OscilGen::getfromXML(XMLwrapper *xml) { + Phmagtype = xml->getpar127("harmonic_mag_type", Phmagtype); - Phmagtype=xml->getpar127("harmonic_mag_type",Phmagtype); + Pcurrentbasefunc = xml->getpar127("base_function", Pcurrentbasefunc); + Pbasefuncpar = xml->getpar127("base_function_par", Pbasefuncpar); - Pcurrentbasefunc=xml->getpar127("base_function",Pcurrentbasefunc); - Pbasefuncpar=xml->getpar127("base_function_par",Pbasefuncpar); + Pbasefuncmodulation = xml->getpar127("base_function_modulation", + Pbasefuncmodulation); + Pbasefuncmodulationpar1 = xml->getpar127("base_function_modulation_par1", + Pbasefuncmodulationpar1); + Pbasefuncmodulationpar2 = xml->getpar127("base_function_modulation_par2", + Pbasefuncmodulationpar2); + Pbasefuncmodulationpar3 = xml->getpar127("base_function_modulation_par3", + Pbasefuncmodulationpar3); - Pbasefuncmodulation=xml->getpar127("base_function_modulation",Pbasefuncmodulation); - Pbasefuncmodulationpar1=xml->getpar127("base_function_modulation_par1",Pbasefuncmodulationpar1); - Pbasefuncmodulationpar2=xml->getpar127("base_function_modulation_par2",Pbasefuncmodulationpar2); - Pbasefuncmodulationpar3=xml->getpar127("base_function_modulation_par3",Pbasefuncmodulationpar3); + Pmodulation = xml->getpar127("modulation", Pmodulation); + Pmodulationpar1 = xml->getpar127("modulation_par1", + Pmodulationpar1); + Pmodulationpar2 = xml->getpar127("modulation_par2", + Pmodulationpar2); + Pmodulationpar3 = xml->getpar127("modulation_par3", + Pmodulationpar3); - Pmodulation=xml->getpar127("modulation",Pmodulation); - Pmodulationpar1=xml->getpar127("modulation_par1",Pmodulationpar1); - Pmodulationpar2=xml->getpar127("modulation_par2",Pmodulationpar2); - Pmodulationpar3=xml->getpar127("modulation_par3",Pmodulationpar3); + Pwaveshaping = xml->getpar127("wave_shaping", Pwaveshaping); + Pwaveshapingfunction = xml->getpar127("wave_shaping_function", + Pwaveshapingfunction); - Pwaveshaping=xml->getpar127("wave_shaping",Pwaveshaping); - Pwaveshapingfunction=xml->getpar127("wave_shaping_function",Pwaveshapingfunction); + Pfiltertype = xml->getpar127("filter_type", Pfiltertype); + Pfilterpar1 = xml->getpar127("filter_par1", Pfilterpar1); + Pfilterpar2 = xml->getpar127("filter_par2", Pfilterpar2); + Pfilterbeforews = xml->getpar127("filter_before_wave_shaping", + Pfilterbeforews); - Pfiltertype=xml->getpar127("filter_type",Pfiltertype); - Pfilterpar1=xml->getpar127("filter_par1",Pfilterpar1); - Pfilterpar2=xml->getpar127("filter_par2",Pfilterpar2); - Pfilterbeforews=xml->getpar127("filter_before_wave_shaping",Pfilterbeforews); + Psatype = xml->getpar127("spectrum_adjust_type", Psatype); + Psapar = xml->getpar127("spectrum_adjust_par", Psapar); - Psatype=xml->getpar127("spectrum_adjust_type",Psatype); - Psapar=xml->getpar127("spectrum_adjust_par",Psapar); + Prand = xml->getpar127("rand", Prand); + Pamprandtype = xml->getpar127("amp_rand_type", Pamprandtype); + Pamprandpower = xml->getpar127("amp_rand_power", Pamprandpower); - Prand=xml->getpar127("rand",Prand); - Pamprandtype=xml->getpar127("amp_rand_type",Pamprandtype); - Pamprandpower=xml->getpar127("amp_rand_power",Pamprandpower); + Pharmonicshift = xml->getpar("harmonic_shift", + Pharmonicshift, + -64, + 64); + Pharmonicshiftfirst = xml->getparbool("harmonic_shift_first", + Pharmonicshiftfirst); - Pharmonicshift=xml->getpar("harmonic_shift",Pharmonicshift,-64,64); - Pharmonicshiftfirst=xml->getparbool("harmonic_shift_first",Pharmonicshiftfirst); - - Padaptiveharmonics=xml->getpar("adaptive_harmonics",Padaptiveharmonics,0,127); - Padaptiveharmonicsbasefreq=xml->getpar("adaptive_harmonics_base_frequency",Padaptiveharmonicsbasefreq,0,255); - Padaptiveharmonicspower=xml->getpar("adaptive_harmonics_power",Padaptiveharmonicspower,0,200); + Padaptiveharmonics = xml->getpar("adaptive_harmonics", + Padaptiveharmonics, + 0, + 127); + Padaptiveharmonicsbasefreq = xml->getpar( + "adaptive_harmonics_base_frequency", + Padaptiveharmonicsbasefreq, + 0, + 255); + Padaptiveharmonicspower = xml->getpar("adaptive_harmonics_power", + Padaptiveharmonicspower, + 0, + 200); - if (xml->enterbranch("HARMONICS")) { - Phmag[0]=64; - Phphase[0]=64; - for (int n=0;nenterbranch("HARMONIC",n+1)==0) continue; - Phmag[n]=xml->getpar127("mag",64); - Phphase[n]=xml->getpar127("phase",64); + if(xml->enterbranch("HARMONICS")) { + Phmag[0] = 64; + Phphase[0] = 64; + for(int n = 0; n < MAX_AD_HARMONICS; n++) { + if(xml->enterbranch("HARMONIC", n + 1) == 0) + continue; + Phmag[n] = xml->getpar127("mag", 64); + Phphase[n] = xml->getpar127("phase", 64); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (Pcurrentbasefunc!=0) changebasefunction(); + if(Pcurrentbasefunc != 0) + changebasefunction(); - if (xml->enterbranch("BASE_FUNCTION")) { - for (int i=1;ienterbranch("BF_HARMONIC",i)) { - basefuncFFTfreqs.c[i]=xml->getparreal("cos",0.0); - basefuncFFTfreqs.s[i]=xml->getparreal("sin",0.0); + if(xml->enterbranch("BASE_FUNCTION")) { + for(int i = 1; i < OSCIL_SIZE / 2; i++) { + if(xml->enterbranch("BF_HARMONIC", i)) { + basefuncFFTfreqs.c[i] = xml->getparreal("cos", 0.0); + basefuncFFTfreqs.s[i] = xml->getparreal("sin", 0.0); xml->exitbranch(); - }; - - - }; + } + } xml->exitbranch(); - REALTYPE max=0.0; + REALTYPE max = 0.0; - basefuncFFTfreqs.c[0]=0.0; - for (int i=0;ivelocity=velocity; - finished_=false; + pars = parameters; + portamento = portamento_; + ctl = ctl_; + this->velocity = velocity; + finished_ = false; - if (pars->Pfixedfreq==0) basefreq=freq; + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } - }; - - firsttime=true; - released=false; - realfreq=basefreq; - NoteGlobalPar.Detune=getdetune(pars->PDetuneType - ,pars->PCoarseDetune,pars->PDetune); + firsttime = true; + released = false; + realfreq = basefreq; + NoteGlobalPar.Detune = getdetune(pars->PDetuneType, + pars->PCoarseDetune, pars->PDetune); //find out the closest note - REALTYPE logfreq=log(basefreq*pow(2.0,NoteGlobalPar.Detune/1200.0)); - REALTYPE mindist=fabs(logfreq-log(pars->sample[0].basefreq+0.0001)); - nsample=0; - for (int i=1;isample[i].smp==NULL) break; - REALTYPE dist=fabs(logfreq-log(pars->sample[i].basefreq+0.0001)); + REALTYPE logfreq = log(basefreq * pow(2.0, NoteGlobalPar.Detune / 1200.0)); + REALTYPE mindist = fabs(logfreq - log(pars->sample[0].basefreq + 0.0001)); + nsample = 0; + for(int i = 1; i < PAD_MAX_SAMPLES; i++) { + if(pars->sample[i].smp == NULL) + break; + REALTYPE dist = fabs(logfreq - log(pars->sample[i].basefreq + 0.0001)); // printf("(mindist=%g) %i %g %g\n",mindist,i,dist,pars->sample[i].basefreq); - if (distsample[nsample].size; - if (size==0) size=1; + int size = pars->sample[nsample].size; + if(size == 0) + size = 1; - poshi_l=(int)(RND*(size-1)); - if (pars->PStereo!=0) poshi_r=(poshi_l+size/2)%size; - else poshi_r=poshi_l; - poslo=0.0; + poshi_l = (int)(RND * (size - 1)); + if(pars->PStereo != 0) + poshi_r = (poshi_l + size / 2) % size; + else + poshi_r = poshi_l; + poslo = 0.0; - tmpwave=new REALTYPE [SOUND_BUFFER_SIZE]; + tmpwave = new REALTYPE [SOUND_BUFFER_SIZE]; - if (pars->PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->PPanning/128.0; + if(pars->PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->PPanning / 128.0; - NoteGlobalPar.FilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - pars->PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->PFilterVelocityScaleFunction)-1); + NoteGlobalPar.FilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + pars->PFilterVelocityScale / 127.0 + * 6.0 //velocity sensing + * (VelF(velocity, + pars-> + PFilterVelocityScaleFunction) - 1); - if (pars->PPunchStrength!=0) { - NoteGlobalPar.Punch.Enabled=1; - NoteGlobalPar.Punch.t=1.0;//start from 1.0 and to 0.0 - NoteGlobalPar.Punch.initialvalue=( (pow(10,1.5*pars->PPunchStrength/127.0)-1.0) - *VelF(velocity,pars->PPunchVelocitySensing) ); - REALTYPE time=pow(10,3.0*pars->PPunchTime/127.0)/10000.0;//0.1 .. 100 ms - REALTYPE stretch=pow(440.0/freq,pars->PPunchStretch/64.0); - NoteGlobalPar.Punch.dt=1.0/(time*SAMPLE_RATE*stretch); - } else NoteGlobalPar.Punch.Enabled=0; + if(pars->PPunchStrength != 0) { + NoteGlobalPar.Punch.Enabled = 1; + NoteGlobalPar.Punch.t = 1.0; //start from 1.0 and to 0.0 + NoteGlobalPar.Punch.initialvalue = + ((pow(10, 1.5 * pars->PPunchStrength / 127.0) - 1.0) + * VelF(velocity, + pars->PPunchVelocitySensing)); + REALTYPE time = pow(10, 3.0 * pars->PPunchTime / 127.0) / 10000.0; //0.1 .. 100 ms + REALTYPE stretch = pow(440.0 / freq, pars->PPunchStretch / 64.0); + NoteGlobalPar.Punch.dt = 1.0 / (time * SAMPLE_RATE * stretch); + } + else + NoteGlobalPar.Punch.Enabled = 0; - NoteGlobalPar.FreqEnvelope=new Envelope(pars->FreqEnvelope,basefreq); - NoteGlobalPar.FreqLfo=new LFO(pars->FreqLfo,basefreq); + NoteGlobalPar.FreqEnvelope = new Envelope(pars->FreqEnvelope, basefreq); + NoteGlobalPar.FreqLfo = new LFO(pars->FreqLfo, basefreq); - NoteGlobalPar.AmpEnvelope=new Envelope(pars->AmpEnvelope,basefreq); - NoteGlobalPar.AmpLfo=new LFO(pars->AmpLfo,basefreq); + NoteGlobalPar.AmpEnvelope = new Envelope(pars->AmpEnvelope, basefreq); + NoteGlobalPar.AmpLfo = new LFO(pars->AmpLfo, basefreq); - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-pars->PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,pars->PAmpVelocityScaleFunction);//velocity sensing + NoteGlobalPar.Volume = 4.0 * pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)) //-60 dB .. 0 dB + * VelF(velocity, pars->PAmpVelocityScaleFunction); //velocity sensing - NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output - globaloldamplitude=globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output + globaloldamplitude = globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope-> + envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.GlobalFilterL=new Filter(pars->GlobalFilter); - NoteGlobalPar.GlobalFilterR=new Filter(pars->GlobalFilter); + NoteGlobalPar.GlobalFilterL = new Filter(pars->GlobalFilter); + NoteGlobalPar.GlobalFilterR = new Filter(pars->GlobalFilter); - NoteGlobalPar.FilterEnvelope=new Envelope(pars->FilterEnvelope,basefreq); - NoteGlobalPar.FilterLfo=new LFO(pars->FilterLfo,basefreq); - NoteGlobalPar.FilterQ=pars->GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FilterEnvelope = new Envelope(pars->FilterEnvelope, + basefreq); + NoteGlobalPar.FilterLfo = new LFO(pars->FilterLfo, basefreq); + NoteGlobalPar.FilterQ = pars->GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = pars->GlobalFilter->getfreqtracking( + basefreq); - ready=1;///sa il pun pe asta doar cand e chiar gata + ready = 1; ///sa il pun pe asta doar cand e chiar gata - if (parameters->sample[nsample].smp==NULL) { - finished_=true; + if(parameters->sample[nsample].smp == NULL) { + finished_ = true; return; - }; -}; + } +} // PADlegatonote: This function is (mostly) a copy of PADnote(...) // with some lines removed so that it only alter the already playing // note (to perform legato). It is possible I left stuff that is not // required for this. -void PADnote::PADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall) +void PADnote::PADlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall) { - PADnoteParameters *parameters=pars; + PADnoteParameters *parameters = pars; //Controller *ctl_=ctl; // Manage legato stuff - if (externcall) Legato.msg=LM_Norm; - if (Legato.msg!=LM_CatchUp) { - Legato.lastfreq=Legato.param.freq; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote; - if (Legato.msg==LM_Norm) { - if (Legato.silent) { - Legato.fade.m=0.0; - Legato.msg=LM_FadeIn; - } else { - Legato.fade.m=1.0; - Legato.msg=LM_FadeOut; + if(externcall) + Legato.msg = LM_Norm; + if(Legato.msg != LM_CatchUp) { + Legato.lastfreq = Legato.param.freq; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote; + if(Legato.msg == LM_Norm) { + if(Legato.silent) { + Legato.fade.m = 0.0; + Legato.msg = LM_FadeIn; + } + else { + Legato.fade.m = 1.0; + Legato.msg = LM_FadeOut; return; } } - if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + if(Legato.msg == LM_ToNorm) + Legato.msg = LM_Norm; } - portamento=portamento_; - this->velocity=velocity; - finished_=false; + portamento = portamento_; + this->velocity = velocity; + finished_ = false; - if (pars->Pfixedfreq==0) basefreq=freq; + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; - }; + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } - released=false; - realfreq=basefreq; + released = false; + realfreq = basefreq; - getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); + getdetune(pars->PDetuneType, pars->PCoarseDetune, pars->PDetune); //find out the closest note - REALTYPE logfreq=log(basefreq*pow(2.0,NoteGlobalPar.Detune/1200.0)); - REALTYPE mindist=fabs(logfreq-log(pars->sample[0].basefreq+0.0001)); - nsample=0; - for (int i=1;isample[i].smp==NULL) break; - REALTYPE dist=fabs(logfreq-log(pars->sample[i].basefreq+0.0001)); + REALTYPE logfreq = log(basefreq * pow(2.0, NoteGlobalPar.Detune / 1200.0)); + REALTYPE mindist = fabs(logfreq - log(pars->sample[0].basefreq + 0.0001)); + nsample = 0; + for(int i = 1; i < PAD_MAX_SAMPLES; i++) { + if(pars->sample[i].smp == NULL) + break; + REALTYPE dist = fabs(logfreq - log(pars->sample[i].basefreq + 0.0001)); - if (distsample[nsample].size; - if (size==0) size=1; + int size = pars->sample[nsample].size; + if(size == 0) + size = 1; - if (pars->PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->PPanning/128.0; + if(pars->PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->PPanning / 128.0; - NoteGlobalPar.FilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - pars->PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->PFilterVelocityScaleFunction)-1); + NoteGlobalPar.FilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + pars->PFilterVelocityScale / 127.0 + * 6.0 //velocity sensing + * (VelF(velocity, + pars-> + PFilterVelocityScaleFunction) - 1); - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-pars->PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,pars->PAmpVelocityScaleFunction);//velocity sensing + NoteGlobalPar.Volume = 4.0 * pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)) //-60 dB .. 0 dB + * VelF(velocity, pars->PAmpVelocityScaleFunction); //velocity sensing - NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output - globaloldamplitude=globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output + globaloldamplitude = globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope-> + envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.FilterQ=pars->GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FilterQ = pars->GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = pars->GlobalFilter->getfreqtracking( + basefreq); - if (parameters->sample[nsample].smp==NULL) { - finished_=true; + if(parameters->sample[nsample].smp == NULL) { + finished_ = true; return; - }; + } // End of the PADlegatonote function. -}; +} PADnote::~PADnote() @@ -246,282 +298,317 @@ PADnote::~PADnote() delete (NoteGlobalPar.FilterEnvelope); delete (NoteGlobalPar.FilterLfo); delete [] tmpwave; -}; +} inline void PADnote::fadein(REALTYPE *smps) { - int zerocrossings=0; - for (int i=1;i0.0)) zerocrossings++;//this is only the possitive crossings + int zerocrossings = 0; + for(int i = 1; i < SOUND_BUFFER_SIZE; i++) + if((smps[i - 1] < 0.0) && (smps[i] > 0.0)) + zerocrossings++; //this is only the possitive crossings - REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0; - if (tmp<8.0) tmp=8.0; + REALTYPE tmp = (SOUND_BUFFER_SIZE - 1.0) / (zerocrossings + 1) / 3.0; + if(tmp < 8.0) + tmp = 8.0; int n; - F2I(tmp,n);//how many samples is the fade-in - if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; - for (int i=0;i SOUND_BUFFER_SIZE) + n = SOUND_BUFFER_SIZE; + for(int i = 0; i < n; i++) { //fade-in + REALTYPE tmp = 0.5 - cos((REALTYPE)i / (REALTYPE) n * PI) * 0.5; + smps[i] *= tmp; + } +} void PADnote::computecurrentparameters() { - REALTYPE globalpitch,globalfilterpitch; - globalpitch=0.01*(NoteGlobalPar.FreqEnvelope->envout()+ - NoteGlobalPar.FreqLfo->lfoout()*ctl->modwheel.relmod+NoteGlobalPar.Detune); - globaloldamplitude=globalnewamplitude; - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + REALTYPE globalpitch, globalfilterpitch; + globalpitch = 0.01 * (NoteGlobalPar.FreqEnvelope->envout() + + NoteGlobalPar.FreqLfo->lfoout() + * ctl->modwheel.relmod + NoteGlobalPar.Detune); + globaloldamplitude = globalnewamplitude; + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout() - +NoteGlobalPar.FilterCenterPitch; + globalfilterpitch = NoteGlobalPar.FilterEnvelope->envout() + + NoteGlobalPar.FilterLfo->lfoout() + + NoteGlobalPar.FilterCenterPitch; - REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq - +NoteGlobalPar.FilterFreqTracking; + REALTYPE tmpfilterfreq = globalfilterpitch + ctl->filtercutoff.relfreq + + NoteGlobalPar.FilterFreqTracking; - tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); + tmpfilterfreq = NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); - REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq; - NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq); - NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq); + REALTYPE globalfilterq = NoteGlobalPar.FilterQ * ctl->filterq.relq; + NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq, globalfilterq); + NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq, globalfilterq); //compute the portamento, if it is used by this note - REALTYPE portamentofreqrap=1.0; - if (portamento!=0) {//this voice use portamento - portamentofreqrap=ctl->portamento.freqrap; - if (ctl->portamento.used==0) {//the portamento has finished - portamento=0;//this note is no longer "portamented" - }; - }; + REALTYPE portamentofreqrap = 1.0; + if(portamento != 0) { //this voice use portamento + portamentofreqrap = ctl->portamento.freqrap; + if(ctl->portamento.used == 0) //the portamento has finished + portamento = 0; //this note is no longer "portamented" + ; + } - realfreq=basefreq*portamentofreqrap*pow(2.0,globalpitch/12.0)*ctl->pitchwheel.relfreq; -}; + realfreq = basefreq * portamentofreqrap + * pow(2.0, globalpitch / 12.0) * ctl->pitchwheel.relfreq; +} -int PADnote::Compute_Linear(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo) +int PADnote::Compute_Linear(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo) { - REALTYPE *smps=pars->sample[nsample].smp; - if (smps==NULL) { - finished_=true; - return(1); - }; - int size=pars->sample[nsample].size; - for (int i=0;i=1.0) { - poshi_l+=1; - poshi_r+=1; - poslo-=1.0; - }; - if (poshi_l>=size) poshi_l%=size; - if (poshi_r>=size) poshi_r%=size; + REALTYPE *smps = pars->sample[nsample].smp; + if(smps == NULL) { + finished_ = true; + return 1; + } + int size = pars->sample[nsample].size; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + poshi_l += freqhi; + poshi_r += freqhi; + poslo += freqlo; + if(poslo >= 1.0) { + poshi_l += 1; + poshi_r += 1; + poslo -= 1.0; + } + if(poshi_l >= size) + poshi_l %= size; + if(poshi_r >= size) + poshi_r %= size; - outl[i]=smps[poshi_l]*(1.0-poslo)+smps[poshi_l+1]*poslo; - outr[i]=smps[poshi_r]*(1.0-poslo)+smps[poshi_r+1]*poslo; - }; - return(1); -}; -int PADnote::Compute_Cubic(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo) + outl[i] = smps[poshi_l] * (1.0 - poslo) + smps[poshi_l + 1] * poslo; + outr[i] = smps[poshi_r] * (1.0 - poslo) + smps[poshi_r + 1] * poslo; + } + return 1; +} +int PADnote::Compute_Cubic(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo) { - REALTYPE *smps=pars->sample[nsample].smp; - if (smps==NULL) { - finished_=true; - return(1); - }; - int size=pars->sample[nsample].size; - REALTYPE xm1,x0,x1,x2,a,b,c; - for (int i=0;i=1.0) { - poshi_l+=1; - poshi_r+=1; - poslo-=1.0; - }; - if (poshi_l>=size) poshi_l%=size; - if (poshi_r>=size) poshi_r%=size; + REALTYPE *smps = pars->sample[nsample].smp; + if(smps == NULL) { + finished_ = true; + return 1; + } + int size = pars->sample[nsample].size; + REALTYPE xm1, x0, x1, x2, a, b, c; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + poshi_l += freqhi; + poshi_r += freqhi; + poslo += freqlo; + if(poslo >= 1.0) { + poshi_l += 1; + poshi_r += 1; + poslo -= 1.0; + } + if(poshi_l >= size) + poshi_l %= size; + if(poshi_r >= size) + poshi_r %= size; //left - xm1=smps[poshi_l]; - x0=smps[poshi_l + 1]; - x1=smps[poshi_l + 2]; - x2=smps[poshi_l + 3]; - a = (3.0 * (x0-x1) - xm1 + x2)*0.5; - b = 2.0*x1 + xm1 - (5.0*x0 + x2)*0.5; - c = (x1 - xm1)*0.5; + xm1 = smps[poshi_l]; + x0 = smps[poshi_l + 1]; + x1 = smps[poshi_l + 2]; + x2 = smps[poshi_l + 3]; + a = (3.0 * (x0 - x1) - xm1 + x2) * 0.5; + b = 2.0 * x1 + xm1 - (5.0 * x0 + x2) * 0.5; + c = (x1 - xm1) * 0.5; outl[i] = (((a * poslo) + b) * poslo + c) * poslo + x0; //right - xm1=smps[poshi_r]; - x0=smps[poshi_r + 1]; - x1=smps[poshi_r + 2]; - x2=smps[poshi_r + 3]; - a = (3.0 * (x0-x1) - xm1 + x2)*0.5; - b = 2.0*x1 + xm1 - (5.0*x0 + x2)*0.5; - c = (x1 - xm1)*0.5; + xm1 = smps[poshi_r]; + x0 = smps[poshi_r + 1]; + x1 = smps[poshi_r + 2]; + x2 = smps[poshi_r + 3]; + a = (3.0 * (x0 - x1) - xm1 + x2) * 0.5; + b = 2.0 * x1 + xm1 - (5.0 * x0 + x2) * 0.5; + c = (x1 - xm1) * 0.5; outr[i] = (((a * poslo) + b) * poslo + c) * poslo + x0; - }; - return(1); -}; + } + return 1; +} -int PADnote::noteout(REALTYPE *outl,REALTYPE *outr) +int PADnote::noteout(REALTYPE *outl, REALTYPE *outr) { computecurrentparameters(); - REALTYPE *smps=pars->sample[nsample].smp; - if (smps==NULL) { - for (int i=0;isample[nsample].basefreq; + REALTYPE *smps = pars->sample[nsample].smp; + if(smps == NULL) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] = 0.0; + outr[i] = 0.0; + } + return 1; + } + REALTYPE smpfreq = pars->sample[nsample].basefreq; - REALTYPE freqrap=realfreq/smpfreq; - int freqhi=(int) (floor(freqrap)); - REALTYPE freqlo=freqrap-floor(freqrap); + REALTYPE freqrap = realfreq / smpfreq; + int freqhi = (int) (floor(freqrap)); + REALTYPE freqlo = freqrap - floor(freqrap); - if (config.cfg.Interpolation) Compute_Cubic(outl,outr,freqhi,freqlo); - else Compute_Linear(outl,outr,freqhi,freqlo); + if(config.cfg.Interpolation) + Compute_Cubic(outl, outr, freqhi, freqlo); + else + Compute_Linear(outl, outr, freqhi, freqlo); - if (firsttime) { + if(firsttime) { fadein(outl); fadein(outr); - firsttime=false; - }; + firsttime = false; + } NoteGlobalPar.GlobalFilterL->filterout(outl); NoteGlobalPar.GlobalFilterR->filterout(outr); //Apply the punch - if (NoteGlobalPar.Punch.Enabled!=0) { - for (int i=0;ifinished()!=0) { - for (int i=0;ifinished() != 0) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { //fade-out + REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE; + outl[i] *= tmp; + outr[i] *= tmp; + } + finished_ = 1; + } - return(1); -}; + return 1; +} int PADnote::finished() { - return(finished_); -}; + return finished_; +} void PADnote::relasekey() { NoteGlobalPar.FreqEnvelope->relasekey(); NoteGlobalPar.FilterEnvelope->relasekey(); NoteGlobalPar.AmpEnvelope->relasekey(); -}; +} diff --git a/plugins/zynaddsubfx/src/Synth/PADnote.h b/plugins/zynaddsubfx/src/Synth/PADnote.h index 4722857f0..956353218 100644 --- a/plugins/zynaddsubfx/src/Synth/PADnote.h +++ b/plugins/zynaddsubfx/src/Synth/PADnote.h @@ -32,95 +32,112 @@ /**The "pad" synthesizer*/ class PADnote { -public: - PADnote(PADnoteParameters *parameters, Controller *ctl_,REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool besilent); - ~PADnote(); + public: + PADnote(PADnoteParameters *parameters, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool besilent); + ~PADnote(); - void PADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall); + void PADlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall); - int noteout(REALTYPE *outl,REALTYPE *outr); - int finished(); - void relasekey(); + int noteout(REALTYPE *outl, REALTYPE *outr); + int finished(); + void relasekey(); - int ready; + int ready; -private: - void fadein(REALTYPE *smps); - void computecurrentparameters(); - bool finished_; - PADnoteParameters *pars; + private: + void fadein(REALTYPE *smps); + void computecurrentparameters(); + bool finished_; + PADnoteParameters *pars; - int poshi_l,poshi_r; - REALTYPE poslo; + int poshi_l, poshi_r; + REALTYPE poslo; - REALTYPE basefreq; - bool firsttime,released; + REALTYPE basefreq; + bool firsttime, released; - int nsample,portamento; + int nsample, portamento; - int Compute_Linear(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo); - int Compute_Cubic(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo); + int Compute_Linear(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo); + int Compute_Cubic(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo); - struct { - /****************************************** - * FREQUENCY GLOBAL PARAMETERS * - ******************************************/ - REALTYPE Detune;//cents - - Envelope *FreqEnvelope; - LFO *FreqLfo; - - /******************************************** - * AMPLITUDE GLOBAL PARAMETERS * - ********************************************/ - REALTYPE Volume;// [ 0 .. 1 ] - - REALTYPE Panning;// [ 0 .. 1 ] - - Envelope *AmpEnvelope; - LFO *AmpLfo; - struct { - int Enabled; - REALTYPE initialvalue,dt,t; - } Punch; + /****************************************** + * FREQUENCY GLOBAL PARAMETERS * + ******************************************/ + REALTYPE Detune; //cents - /****************************************** - * FILTER GLOBAL PARAMETERS * - ******************************************/ - Filter *GlobalFilterL,*GlobalFilterR; + Envelope *FreqEnvelope; + LFO *FreqLfo; - REALTYPE FilterCenterPitch;//octaves - REALTYPE FilterQ; - REALTYPE FilterFreqTracking; + /******************************************** + * AMPLITUDE GLOBAL PARAMETERS * + ********************************************/ + REALTYPE Volume; // [ 0 .. 1 ] - Envelope *FilterEnvelope; + REALTYPE Panning; // [ 0 .. 1 ] - LFO *FilterLfo; - } NoteGlobalPar; + Envelope *AmpEnvelope; + LFO *AmpLfo; + + struct { + int Enabled; + REALTYPE initialvalue, dt, t; + } Punch; + + /****************************************** + * FILTER GLOBAL PARAMETERS * + ******************************************/ + Filter *GlobalFilterL, *GlobalFilterR; + + REALTYPE FilterCenterPitch; //octaves + REALTYPE FilterQ; + REALTYPE FilterFreqTracking; + + Envelope *FilterEnvelope; + + LFO *FilterLfo; + } NoteGlobalPar; - REALTYPE globaloldamplitude,globalnewamplitude,velocity,realfreq; - REALTYPE *tmpwave; - Controller *ctl; + REALTYPE globaloldamplitude, globalnewamplitude, velocity, realfreq; + REALTYPE *tmpwave; + Controller *ctl; - // Legato vars - struct { - bool silent; - REALTYPE lastfreq; - LegatoMsg msg; - int decounter; - struct { // Fade In/Out vars - int length; - REALTYPE m, step; - } fade; - struct { // Note parameters - REALTYPE freq, vel; - int portamento, midinote; - } param; - } Legato; + // Legato vars + struct { + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; }; #endif + diff --git a/plugins/zynaddsubfx/src/Synth/Resonance.cpp b/plugins/zynaddsubfx/src/Synth/Resonance.cpp index fcf043d3a..4e12572a3 100644 --- a/plugins/zynaddsubfx/src/Synth/Resonance.cpp +++ b/plugins/zynaddsubfx/src/Synth/Resonance.cpp @@ -30,68 +30,79 @@ Resonance::Resonance():Presets() { setpresettype("Presonance"); defaults(); -}; +} Resonance::~Resonance() -{ -}; +{} void Resonance::defaults() { - Penabled=0; - PmaxdB=20; - Pcenterfreq=64;//1 kHz - Poctavesfreq=64; - Pprotectthefundamental=0; - ctlcenter=1.0; - ctlbw=1.0; - for (int i=0;i=N_RES_POINTS)) return; - Prespoints[n]=p; -}; + if((n < 0) || (n >= N_RES_POINTS)) + return; + Prespoints[n] = p; +} /* * Apply the resonance to FFT data */ -void Resonance::applyres(int n,FFTFREQS fftdata,REALTYPE freq) +void Resonance::applyres(int n, FFTFREQS fftdata, REALTYPE freq) { - if (Penabled==0) return;//if the resonance is disabled - REALTYPE sum=0.0, - l1=log(getfreqx(0.0)*ctlcenter), - l2=log(2.0)*getoctavesfreq()*ctlbw; + if(Penabled == 0) + return; //if the resonance is disabled + REALTYPE sum = 0.0, + l1 = log(getfreqx(0.0) * ctlcenter), + l2 = log(2.0) * getoctavesfreq() * ctlbw; - for (int i=0;i=N_RES_POINTS) kx1=N_RES_POINTS-1; - int kx2=kx1+1; - if (kx2>=N_RES_POINTS) kx2=N_RES_POINTS-1; - REALTYPE y=(Prespoints[kx1]*(1.0-dx)+Prespoints[kx2]*dx)/127.0-sum/127.0; + x *= N_RES_POINTS; + REALTYPE dx = x - floor(x); + x = floor(x); + int kx1 = (int)x; + if(kx1 >= N_RES_POINTS) + kx1 = N_RES_POINTS - 1; + int kx2 = kx1 + 1; + if(kx2 >= N_RES_POINTS) + kx2 = N_RES_POINTS - 1; + REALTYPE y = + (Prespoints[kx1] + * (1.0 - dx) + Prespoints[kx2] * dx) / 127.0 - sum / 127.0; - y=pow(10.0,y*PmaxdB/20.0); + y = pow(10.0, y * PmaxdB / 20.0); - if ((Pprotectthefundamental!=0)&&(i==1)) y=1.0; + if((Pprotectthefundamental != 0) && (i == 1)) + y = 1.0; - fftdata.c[i]*=y; - fftdata.s[i]*=y; - }; -}; + fftdata.c[i] *= y; + fftdata.s[i] *= y; + } +} /* * Gets the response at the frequency "freq" @@ -99,25 +110,33 @@ void Resonance::applyres(int n,FFTFREQS fftdata,REALTYPE freq) REALTYPE Resonance::getfreqresponse(REALTYPE freq) { - REALTYPE l1=log(getfreqx(0.0)*ctlcenter), - l2=log(2.0)*getoctavesfreq()*ctlbw,sum=0.0; + REALTYPE l1 = log(getfreqx(0.0) * ctlcenter), + l2 = log(2.0) * getoctavesfreq() * ctlbw, sum = 0.0; - for (int i=0;i=N_RES_POINTS) kx1=N_RES_POINTS-1; - int kx2=kx1+1; - if (kx2>=N_RES_POINTS) kx2=N_RES_POINTS-1; - REALTYPE result=(Prespoints[kx1]*(1.0-dx)+Prespoints[kx2]*dx)/127.0-sum/127.0; - result=pow(10.0,result*PmaxdB/20.0); - return(result); -}; + REALTYPE x = (log(freq) - l1) / l2; //compute where the n-th hamonics fits to the graph + if(x < 0.0) + x = 0.0; + x *= N_RES_POINTS; + REALTYPE dx = x - floor(x); + x = floor(x); + int kx1 = (int)x; + if(kx1 >= N_RES_POINTS) + kx1 = N_RES_POINTS - 1; + int kx2 = kx1 + 1; + if(kx2 >= N_RES_POINTS) + kx2 = N_RES_POINTS - 1; + REALTYPE result = + (Prespoints[kx1] + * (1.0 - dx) + Prespoints[kx2] * dx) / 127.0 - sum / 127.0; + result = pow(10.0, result * PmaxdB / 20.0); + return result; +} /* @@ -125,129 +144,139 @@ REALTYPE Resonance::getfreqresponse(REALTYPE freq) */ void Resonance::smooth() { - REALTYPE old=Prespoints[0]; - for (int i=0;i0;i--) { - old=old*0.4+Prespoints[i]*0.6; - Prespoints[i]=(int) old+1; - if (Prespoints[i]>127) Prespoints[i]=127; - }; -}; + REALTYPE old = Prespoints[0]; + for(int i = 0; i < N_RES_POINTS; i++) { + old = old * 0.4 + Prespoints[i] * 0.6; + Prespoints[i] = (int) old; + } + old = Prespoints[N_RES_POINTS - 1]; + for(int i = N_RES_POINTS - 1; i > 0; i--) { + old = old * 0.4 + Prespoints[i] * 0.6; + Prespoints[i] = (int) old + 1; + if(Prespoints[i] > 127) + Prespoints[i] = 127; + } +} /* * Randomize the resonance function */ void Resonance::randomize(int type) { - int r=(int)(RND*127.0); - for (int i=0;i1.0) x=1.0; - REALTYPE octf=pow(2.0,getoctavesfreq()); - return(getcenterfreq()/sqrt(octf)*pow(octf,x)); -}; + if(x > 1.0) + x = 1.0; + REALTYPE octf = pow(2.0, getoctavesfreq()); + return getcenterfreq() / sqrt(octf) * pow(octf, x); +} /* * Get the x coordinate from frequency (used by the UI) */ REALTYPE Resonance::getfreqpos(REALTYPE freq) { - return((log(freq)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq()); -}; + return (log(freq) - log(getfreqx(0.0))) / log(2.0) / getoctavesfreq(); +} /* * Get the center frequency of the resonance graph */ REALTYPE Resonance::getcenterfreq() { - return(10000.0*pow(10,-(1.0-Pcenterfreq/127.0)*2.0)); -}; + return 10000.0 * pow(10, -(1.0 - Pcenterfreq / 127.0) * 2.0); +} /* * Get the number of octave that the resonance functions applies to */ REALTYPE Resonance::getoctavesfreq() { - return(0.25+10.0*Poctavesfreq/127.0); -}; + return 0.25 + 10.0 * Poctavesfreq / 127.0; +} -void Resonance::sendcontroller(MidiControllers ctl,REALTYPE par) +void Resonance::sendcontroller(MidiControllers ctl, REALTYPE par) { - if (ctl==C_resonance_center) ctlcenter=par; - else ctlbw=par; -}; + if(ctl == C_resonance_center) + ctlcenter = par; + else + ctlbw = par; +} void Resonance::add2XML(XMLwrapper *xml) { - xml->addparbool("enabled",Penabled); + xml->addparbool("enabled", Penabled); - if ((Penabled==0)&&(xml->minimal)) return; + if((Penabled == 0) && (xml->minimal)) + return; - xml->addpar("max_db",PmaxdB); - xml->addpar("center_freq",Pcenterfreq); - xml->addpar("octaves_freq",Poctavesfreq); - xml->addparbool("protect_fundamental_frequency",Pprotectthefundamental); - xml->addpar("resonance_points",N_RES_POINTS); - for (int i=0;ibeginbranch("RESPOINT",i); - xml->addpar("val",Prespoints[i]); + xml->addpar("max_db", PmaxdB); + xml->addpar("center_freq", Pcenterfreq); + xml->addpar("octaves_freq", Poctavesfreq); + xml->addparbool("protect_fundamental_frequency", Pprotectthefundamental); + xml->addpar("resonance_points", N_RES_POINTS); + for(int i = 0; i < N_RES_POINTS; i++) { + xml->beginbranch("RESPOINT", i); + xml->addpar("val", Prespoints[i]); xml->endbranch(); - }; -}; + } +} void Resonance::getfromXML(XMLwrapper *xml) { - Penabled=xml->getparbool("enabled",Penabled); + Penabled = xml->getparbool("enabled", Penabled); - PmaxdB=xml->getpar127("max_db",PmaxdB); - Pcenterfreq=xml->getpar127("center_freq",Pcenterfreq); - Poctavesfreq=xml->getpar127("octaves_freq",Poctavesfreq); - Pprotectthefundamental=xml->getparbool("protect_fundamental_frequency",Pprotectthefundamental); - for (int i=0;ienterbranch("RESPOINT",i)==0) continue; - Prespoints[i]=xml->getpar127("val",Prespoints[i]); + PmaxdB = xml->getpar127("max_db", PmaxdB); + Pcenterfreq = xml->getpar127("center_freq", Pcenterfreq); + Poctavesfreq = xml->getpar127("octaves_freq", Poctavesfreq); + Pprotectthefundamental = xml->getparbool("protect_fundamental_frequency", + Pprotectthefundamental); + for(int i = 0; i < N_RES_POINTS; i++) { + if(xml->enterbranch("RESPOINT", i) == 0) + continue; + Prespoints[i] = xml->getpar127("val", Prespoints[i]); xml->exitbranch(); - }; -}; - + } +} diff --git a/plugins/zynaddsubfx/src/Synth/Resonance.h b/plugins/zynaddsubfx/src/Synth/Resonance.h index 458ace0c4..6df43093d 100644 --- a/plugins/zynaddsubfx/src/Synth/Resonance.h +++ b/plugins/zynaddsubfx/src/Synth/Resonance.h @@ -31,39 +31,40 @@ class Resonance:public Presets { -public: - Resonance(); - ~Resonance(); - void setpoint(int n,unsigned char p); - void applyres(int n,FFTFREQS fftdata,REALTYPE freq); - void smooth(); - void interpolatepeaks(int type); - void randomize(int type); + public: + Resonance(); + ~Resonance(); + void setpoint(int n, unsigned char p); + void applyres(int n, FFTFREQS fftdata, REALTYPE freq); + void smooth(); + void interpolatepeaks(int type); + void randomize(int type); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - REALTYPE getfreqpos(REALTYPE freq); - REALTYPE getfreqx(REALTYPE x); - REALTYPE getfreqresponse(REALTYPE freq); - REALTYPE getcenterfreq(); - REALTYPE getoctavesfreq(); - void sendcontroller(MidiControllers ctl,REALTYPE par); + REALTYPE getfreqpos(REALTYPE freq); + REALTYPE getfreqx(REALTYPE x); + REALTYPE getfreqresponse(REALTYPE freq); + REALTYPE getcenterfreq(); + REALTYPE getoctavesfreq(); + void sendcontroller(MidiControllers ctl, REALTYPE par); - //parameters - unsigned char Penabled; //if the ressonance is enabled - unsigned char Prespoints[N_RES_POINTS]; //how many points define the resonance function - unsigned char PmaxdB; //how many dB the signal may be amplified - unsigned char Pcenterfreq,Poctavesfreq; //the center frequency of the res. func., and the number of octaves - unsigned char Pprotectthefundamental; //the fundamental (1-st harmonic) is not damped, even it resonance function is low + //parameters + unsigned char Penabled; //if the ressonance is enabled + unsigned char Prespoints[N_RES_POINTS]; //how many points define the resonance function + unsigned char PmaxdB; //how many dB the signal may be amplified + unsigned char Pcenterfreq, Poctavesfreq; //the center frequency of the res. func., and the number of octaves + unsigned char Pprotectthefundamental; //the fundamental (1-st harmonic) is not damped, even it resonance function is low - //controllers - REALTYPE ctlcenter;//center frequency(relative) - REALTYPE ctlbw;//bandwidth(relative) + //controllers + REALTYPE ctlcenter; //center frequency(relative) + REALTYPE ctlbw; //bandwidth(relative) -private: + private: }; #endif + diff --git a/plugins/zynaddsubfx/src/Synth/SUBnote.cpp b/plugins/zynaddsubfx/src/Synth/SUBnote.cpp index b3666229d..0a3affba5 100644 --- a/plugins/zynaddsubfx/src/Synth/SUBnote.cpp +++ b/plugins/zynaddsubfx/src/Synth/SUBnote.cpp @@ -27,420 +27,491 @@ #include "SUBnote.h" #include "../Misc/Util.h" -SUBnote::SUBnote(SUBnoteParameters *parameters,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote,bool besilent) +SUBnote::SUBnote(SUBnoteParameters *parameters, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool besilent) { - ready=0; + ready = 0; - tmpsmp=new REALTYPE[SOUND_BUFFER_SIZE]; - tmprnd=new REALTYPE[SOUND_BUFFER_SIZE]; + tmpsmp = new REALTYPE[SOUND_BUFFER_SIZE]; + tmprnd = new REALTYPE[SOUND_BUFFER_SIZE]; // Initialise some legato-specific vars - Legato.msg=LM_Norm; - Legato.fade.length=(int)(SAMPLE_RATE*0.005);// 0.005 seems ok. - if (Legato.fade.length<1) Legato.fade.length=1;// (if something's fishy) - Legato.fade.step=(1.0/Legato.fade.length); - Legato.decounter=-10; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote; - Legato.silent=besilent; + Legato.msg = LM_Norm; + Legato.fade.length = (int)(SAMPLE_RATE * 0.005); // 0.005 seems ok. + if(Legato.fade.length < 1) + Legato.fade.length = 1; // (if something's fishy) + Legato.fade.step = (1.0 / Legato.fade.length); + Legato.decounter = -10; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote; + Legato.silent = besilent; - pars=parameters; - ctl=ctl_; - portamento=portamento_; - NoteEnabled=ON; - volume=pow(0.1,3.0*(1.0-pars->PVolume/96.0));//-60 dB .. 0 dB - volume*=VelF(velocity,pars->PAmpVelocityScaleFunction); - if (pars->PPanning!=0) panning=pars->PPanning/127.0; - else panning=RND; - numstages=pars->Pnumstages; - stereo=pars->Pstereo; - start=pars->Pstart; - firsttick=1; + pars = parameters; + ctl = ctl_; + portamento = portamento_; + NoteEnabled = ON; + volume = pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)); //-60 dB .. 0 dB + volume *= VelF(velocity, pars->PAmpVelocityScaleFunction); + if(pars->PPanning != 0) + panning = pars->PPanning / 127.0; + else + panning = RND; + numstages = pars->Pnumstages; + stereo = pars->Pstereo; + start = pars->Pstart; + firsttick = 1; int pos[MAX_SUB_HARMONICS]; - if (pars->Pfixedfreq==0) basefreq=freq; + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; - - }; - REALTYPE detune=getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); - basefreq*=pow(2.0,detune/1200.0);//detune + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } + REALTYPE detune = getdetune(pars->PDetuneType, + pars->PCoarseDetune, + pars->PDetune); + basefreq *= pow(2.0, detune / 1200.0); //detune // basefreq*=ctl->pitchwheel.relfreq;//pitch wheel //global filter - GlobalFilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - (pars->PGlobalFilterVelocityScale/127.0*6.0)* //velocity sensing - (VelF(velocity,pars->PGlobalFilterVelocityScaleFunction)-1); + GlobalFilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + (pars->PGlobalFilterVelocityScale / 127.0 * 6.0) //velocity sensing + * (VelF(velocity, + pars->PGlobalFilterVelocityScaleFunction) + - 1); - GlobalFilterL=NULL; - GlobalFilterR=NULL; - GlobalFilterEnvelope=NULL; + GlobalFilterL = NULL; + GlobalFilterR = NULL; + GlobalFilterEnvelope = NULL; //select only harmonics that desire to compute - numharmonics=0; - for (int n=0;nPhmag[n]==0)continue; - if (n*basefreq>SAMPLE_RATE/2.0) break;//remove the freqs above the Nyquist freq - pos[numharmonics++]=n; - }; - firstnumharmonics=numharmonics;//(gf)Useful in legato mode. + numharmonics = 0; + for(int n = 0; n < MAX_SUB_HARMONICS; n++) { + if(pars->Phmag[n] == 0) + continue; + if(n * basefreq > SAMPLE_RATE / 2.0) + break; //remove the freqs above the Nyquist freq + pos[numharmonics++] = n; + } + firstnumharmonics = numharmonics; //(gf)Useful in legato mode. - if (numharmonics==0) { - NoteEnabled=OFF; + if(numharmonics == 0) { + NoteEnabled = OFF; return; - }; + } - lfilter=new bpfilter[numstages*numharmonics]; - if (stereo!=0) rfilter=new bpfilter[numstages*numharmonics]; + lfilter = new bpfilter[numstages * numharmonics]; + if(stereo != 0) + rfilter = new bpfilter[numstages * numharmonics]; //how much the amplitude is normalised (because the harmonics) - REALTYPE reduceamp=0.0; + REALTYPE reduceamp = 0.0; - for (int n=0;nPbandwidth-127.0)/127.0*4)*numstages; + REALTYPE bw = + pow(10, (pars->Pbandwidth - 127.0) / 127.0 * 4) * numstages; //Bandwidth Scale - bw*=pow(1000/freq,(pars->Pbwscale-64.0)/64.0*3.0); + bw *= pow(1000 / freq, (pars->Pbwscale - 64.0) / 64.0 * 3.0); //Relative BandWidth - bw*=pow(100,(pars->Phrelbw[pos[n]]-64.0)/64.0); + bw *= pow(100, (pars->Phrelbw[pos[n]] - 64.0) / 64.0); - if (bw>25.0) bw=25.0; + if(bw > 25.0) + bw = 25.0; //try to keep same amplitude on all freqs and bw. (empirically) - REALTYPE gain=sqrt(1500.0/(bw*freq)); + REALTYPE gain = sqrt(1500.0 / (bw * freq)); - REALTYPE hmagnew=1.0-pars->Phmag[pos[n]]/127.0; + REALTYPE hmagnew = 1.0 - pars->Phmag[pos[n]] / 127.0; REALTYPE hgain; - switch (pars->Phmagtype) { + switch(pars->Phmagtype) { case 1: - hgain=exp(hmagnew*log(0.01)); + hgain = exp(hmagnew * log(0.01)); break; case 2: - hgain=exp(hmagnew*log(0.001)); + hgain = exp(hmagnew * log(0.001)); break; case 3: - hgain=exp(hmagnew*log(0.0001)); + hgain = exp(hmagnew * log(0.0001)); break; case 4: - hgain=exp(hmagnew*log(0.00001)); + hgain = exp(hmagnew * log(0.00001)); break; default: - hgain=1.0-hmagnew; - }; - gain*=hgain; - reduceamp+=hgain; + hgain = 1.0 - hmagnew; + } + gain *= hgain; + reduceamp += hgain; - for (int nph=0;nphPfixedfreq==0) initparameters(basefreq); - else initparameters(basefreq/440.0*freq); + oldpitchwheel = 0; + oldbandwidth = 64; + if(pars->Pfixedfreq == 0) + initparameters(basefreq); + else + initparameters(basefreq / 440.0 * freq); - oldamplitude=newamplitude; - ready=1; -}; + oldamplitude = newamplitude; + ready = 1; +} // SUBlegatonote: This function is (mostly) a copy of SUBnote(...) and // initparameters(...) stuck together with some lines removed so that // it only alter the already playing note (to perform legato). It is // possible I left stuff that is not required for this. -void SUBnote::SUBlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall) +void SUBnote::SUBlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall) { //SUBnoteParameters *parameters=pars; //Controller *ctl_=ctl; // Manage legato stuff - if (externcall) Legato.msg=LM_Norm; - if (Legato.msg!=LM_CatchUp) { - Legato.lastfreq=Legato.param.freq; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote; - if (Legato.msg==LM_Norm) { - if (Legato.silent) { - Legato.fade.m=0.0; - Legato.msg=LM_FadeIn; - } else { - Legato.fade.m=1.0; - Legato.msg=LM_FadeOut; + if(externcall) + Legato.msg = LM_Norm; + if(Legato.msg != LM_CatchUp) { + Legato.lastfreq = Legato.param.freq; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote; + if(Legato.msg == LM_Norm) { + if(Legato.silent) { + Legato.fade.m = 0.0; + Legato.msg = LM_FadeIn; + } + else { + Legato.fade.m = 1.0; + Legato.msg = LM_FadeOut; return; } } - if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + if(Legato.msg == LM_ToNorm) + Legato.msg = LM_Norm; } - portamento=portamento_; + portamento = portamento_; - volume=pow(0.1,3.0*(1.0-pars->PVolume/96.0));//-60 dB .. 0 dB - volume*=VelF(velocity,pars->PAmpVelocityScaleFunction); - if (pars->PPanning!=0) panning=pars->PPanning/127.0; - else panning=RND; + volume = pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)); //-60 dB .. 0 dB + volume *= VelF(velocity, pars->PAmpVelocityScaleFunction); + if(pars->PPanning != 0) + panning = pars->PPanning / 127.0; + else + panning = RND; ///start=pars->Pstart; int pos[MAX_SUB_HARMONICS]; - if (pars->Pfixedfreq==0) basefreq=freq; + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; - }; - REALTYPE detune=getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); - basefreq*=pow(2.0,detune/1200.0);//detune + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } + REALTYPE detune = getdetune(pars->PDetuneType, + pars->PCoarseDetune, + pars->PDetune); + basefreq *= pow(2.0, detune / 1200.0); //detune //global filter - GlobalFilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - (pars->PGlobalFilterVelocityScale/127.0*6.0)* //velocity sensing - (VelF(velocity,pars->PGlobalFilterVelocityScaleFunction)-1); + GlobalFilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + (pars->PGlobalFilterVelocityScale / 127.0 * 6.0) //velocity sensing + * (VelF(velocity, + pars->PGlobalFilterVelocityScaleFunction) + - 1); - int legatonumharmonics=0; - for (int n=0;nPhmag[n]==0)continue; - if (n*basefreq>SAMPLE_RATE/2.0) break;//remove the freqs above the Nyquist freq - pos[legatonumharmonics++]=n; - }; - if (legatonumharmonics>firstnumharmonics) numharmonics=firstnumharmonics; - else numharmonics=legatonumharmonics; + int legatonumharmonics = 0; + for(int n = 0; n < MAX_SUB_HARMONICS; n++) { + if(pars->Phmag[n] == 0) + continue; + if(n * basefreq > SAMPLE_RATE / 2.0) + break; //remove the freqs above the Nyquist freq + pos[legatonumharmonics++] = n; + } + if(legatonumharmonics > firstnumharmonics) + numharmonics = firstnumharmonics; + else + numharmonics = legatonumharmonics; - if (numharmonics==0) { - NoteEnabled=OFF; + if(numharmonics == 0) { + NoteEnabled = OFF; return; - }; + } //how much the amplitude is normalised (because the harmonics) - REALTYPE reduceamp=0.0; + REALTYPE reduceamp = 0.0; - for (int n=0;nPbandwidth-127.0)/127.0*4)*numstages; + REALTYPE bw = + pow(10, (pars->Pbandwidth - 127.0) / 127.0 * 4) * numstages; //Bandwidth Scale - bw*=pow(1000/freq,(pars->Pbwscale-64.0)/64.0*3.0); + bw *= pow(1000 / freq, (pars->Pbwscale - 64.0) / 64.0 * 3.0); //Relative BandWidth - bw*=pow(100,(pars->Phrelbw[pos[n]]-64.0)/64.0); + bw *= pow(100, (pars->Phrelbw[pos[n]] - 64.0) / 64.0); - if (bw>25.0) bw=25.0; + if(bw > 25.0) + bw = 25.0; //try to keep same amplitude on all freqs and bw. (empirically) - REALTYPE gain=sqrt(1500.0/(bw*freq)); + REALTYPE gain = sqrt(1500.0 / (bw * freq)); - REALTYPE hmagnew=1.0-pars->Phmag[pos[n]]/127.0; + REALTYPE hmagnew = 1.0 - pars->Phmag[pos[n]] / 127.0; REALTYPE hgain; - switch (pars->Phmagtype) { + switch(pars->Phmagtype) { case 1: - hgain=exp(hmagnew*log(0.01)); + hgain = exp(hmagnew * log(0.01)); break; case 2: - hgain=exp(hmagnew*log(0.001)); + hgain = exp(hmagnew * log(0.001)); break; case 3: - hgain=exp(hmagnew*log(0.0001)); + hgain = exp(hmagnew * log(0.0001)); break; case 4: - hgain=exp(hmagnew*log(0.00001)); + hgain = exp(hmagnew * log(0.00001)); break; default: - hgain=1.0-hmagnew; - }; - gain*=hgain; - reduceamp+=hgain; + hgain = 1.0 - hmagnew; + } + gain *= hgain; + reduceamp += hgain; - for (int nph=0;nphPfixedfreq==0) freq=basefreq; - else freq*=basefreq/440.0; + if(pars->Pfixedfreq == 0) + freq = basefreq; + else + freq *= basefreq / 440.0; /////////////// // Altered initparameters(...) content: - if (pars->PGlobalFilterEnabled!=0) { - globalfiltercenterq=pars->GlobalFilter->getq(); - GlobalFilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); - }; + if(pars->PGlobalFilterEnabled != 0) { + globalfiltercenterq = pars->GlobalFilter->getq(); + GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(basefreq); + } // end of the altered initparameters function content. /////////////// - oldamplitude=newamplitude; + oldamplitude = newamplitude; // End of the SUBlegatonote function. -}; +} SUBnote::~SUBnote() { - if (NoteEnabled!=OFF) KillNote(); + if(NoteEnabled != OFF) + KillNote(); delete [] tmpsmp; delete [] tmprnd; -}; +} /* * Kill the note */ void SUBnote::KillNote() { - if (NoteEnabled!=OFF) { + if(NoteEnabled != OFF) { delete [] lfilter; - lfilter=NULL; - if (stereo!=0) delete [] rfilter; - rfilter=NULL; - delete(AmpEnvelope); - if (FreqEnvelope!=NULL) delete(FreqEnvelope); - if (BandWidthEnvelope!=NULL) delete(BandWidthEnvelope); - NoteEnabled=OFF; - }; - -}; + lfilter = NULL; + if(stereo != 0) + delete [] rfilter; + rfilter = NULL; + delete (AmpEnvelope); + if(FreqEnvelope != NULL) + delete (FreqEnvelope); + if(BandWidthEnvelope != NULL) + delete (BandWidthEnvelope); + NoteEnabled = OFF; + } +} /* * Compute the filters coefficients */ -void SUBnote::computefiltercoefs(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE gain) +void SUBnote::computefiltercoefs(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE gain) { - if (freq>SAMPLE_RATE/2.0-200.0) { - freq=SAMPLE_RATE/2.0-200.0; - }; + if(freq > SAMPLE_RATE / 2.0 - 200.0) + freq = SAMPLE_RATE / 2.0 - 200.0; + ; - REALTYPE omega=2.0*PI*freq/SAMPLE_RATE; - REALTYPE sn=sin(omega); - REALTYPE cs=cos(omega); - REALTYPE alpha=sn*sinh(LOG_2/2.0*bw*omega/sn); + REALTYPE omega = 2.0 * PI * freq / SAMPLE_RATE; + REALTYPE sn = sin(omega); + REALTYPE cs = cos(omega); + REALTYPE alpha = sn * sinh(LOG_2 / 2.0 * bw * omega / sn); - if (alpha>1) alpha=1; - if (alpha>bw) alpha=bw; + if(alpha > 1) + alpha = 1; + if(alpha > bw) + alpha = bw; - filter.b0=alpha/(1.0+alpha)*filter.amp*gain; - filter.b2=-alpha/(1.0+alpha)*filter.amp*gain; - filter.a1=-2.0*cs/(1.0+alpha); - filter.a2=(1.0-alpha)/(1.0+alpha); - -}; + filter.b0 = alpha / (1.0 + alpha) * filter.amp * gain; + filter.b2 = -alpha / (1.0 + alpha) * filter.amp * gain; + filter.a1 = -2.0 * cs / (1.0 + alpha); + filter.a2 = (1.0 - alpha) / (1.0 + alpha); +} /* * Initialise the filters */ -void SUBnote::initfilter(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE amp,REALTYPE mag) +void SUBnote::initfilter(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE amp, + REALTYPE mag) { - filter.xn1=0.0; - filter.xn2=0.0; + filter.xn1 = 0.0; + filter.xn2 = 0.0; - if (start==0) { - filter.yn1=0.0; - filter.yn2=0.0; - } else { - REALTYPE a=0.1*mag;//empirically - REALTYPE p=RND*2.0*PI; - if (start==1) a*=RND; - filter.yn1=a*cos(p); - filter.yn2=a*cos(p+freq*2.0*PI/SAMPLE_RATE); + if(start == 0) { + filter.yn1 = 0.0; + filter.yn2 = 0.0; + } + else { + REALTYPE a = 0.1 * mag; //empirically + REALTYPE p = RND * 2.0 * PI; + if(start == 1) + a *= RND; + filter.yn1 = a * cos(p); + filter.yn2 = a * cos(p + freq * 2.0 * PI / SAMPLE_RATE); //correct the error of computation the start amplitude //at very high frequencies - if (freq>SAMPLE_RATE*0.96) { - filter.yn1=0.0; - filter.yn2=0.0; + if(freq > SAMPLE_RATE * 0.96) { + filter.yn1 = 0.0; + filter.yn2 = 0.0; + } + } - }; - }; - - filter.amp=amp; - filter.freq=freq; - filter.bw=bw; - computefiltercoefs(filter,freq,bw,1.0); -}; + filter.amp = amp; + filter.freq = freq; + filter.bw = bw; + computefiltercoefs(filter, freq, bw, 1.0); +} /* * Do the filtering */ -void SUBnote::filter(bpfilter &filter,REALTYPE *smps) +void SUBnote::filter(bpfilter &filter, REALTYPE *smps) { - int i; + int i; REALTYPE out; - for (i=0;iAmpEnvelope,freq); - if (pars->PFreqEnvelopeEnabled!=0) FreqEnvelope=new Envelope(pars->FreqEnvelope,freq); - else FreqEnvelope=NULL; - if (pars->PBandWidthEnvelopeEnabled!=0) BandWidthEnvelope=new Envelope(pars->BandWidthEnvelope,freq); - else BandWidthEnvelope=NULL; - if (pars->PGlobalFilterEnabled!=0) { - globalfiltercenterq=pars->GlobalFilter->getq(); - GlobalFilterL=new Filter(pars->GlobalFilter); - if (stereo!=0) GlobalFilterR=new Filter(pars->GlobalFilter); - GlobalFilterEnvelope=new Envelope(pars->GlobalFilterEnvelope,freq); - GlobalFilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); - }; + AmpEnvelope = new Envelope(pars->AmpEnvelope, freq); + if(pars->PFreqEnvelopeEnabled != 0) + FreqEnvelope = new Envelope(pars->FreqEnvelope, freq); + else + FreqEnvelope = NULL; + if(pars->PBandWidthEnvelopeEnabled != 0) + BandWidthEnvelope = new Envelope(pars->BandWidthEnvelope, freq); + else + BandWidthEnvelope = NULL; + if(pars->PGlobalFilterEnabled != 0) { + globalfiltercenterq = pars->GlobalFilter->getq(); + GlobalFilterL = new Filter(pars->GlobalFilter); + if(stereo != 0) + GlobalFilterR = new Filter(pars->GlobalFilter); + GlobalFilterEnvelope = new Envelope(pars->GlobalFilterEnvelope, + freq); + GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(basefreq); + } computecurrentparameters(); -}; +} /* @@ -448,213 +519,249 @@ void SUBnote::initparameters(REALTYPE freq) */ void SUBnote::computecurrentparameters() { - if ((FreqEnvelope!=NULL)||(BandWidthEnvelope!=NULL)|| - (oldpitchwheel!=ctl->pitchwheel.data)|| - (oldbandwidth!=ctl->bandwidth.data)|| - (portamento!=0)) { - REALTYPE envfreq=1.0; - REALTYPE envbw=1.0; - REALTYPE gain=1.0; + if((FreqEnvelope != NULL) || (BandWidthEnvelope != NULL) + || (oldpitchwheel != ctl->pitchwheel.data) + || (oldbandwidth != ctl->bandwidth.data) + || (portamento != 0)) { + REALTYPE envfreq = 1.0; + REALTYPE envbw = 1.0; + REALTYPE gain = 1.0; - if (FreqEnvelope!=NULL) { - envfreq=FreqEnvelope->envout()/1200; - envfreq=pow(2.0,envfreq); - }; - envfreq*=ctl->pitchwheel.relfreq;//pitch wheel - if (portamento!=0) {//portamento is used - envfreq*=ctl->portamento.freqrap; - if (ctl->portamento.used==0) {//the portamento has finished - portamento=0;//this note is no longer "portamented" - }; - }; + if(FreqEnvelope != NULL) { + envfreq = FreqEnvelope->envout() / 1200; + envfreq = pow(2.0, envfreq); + } + envfreq *= ctl->pitchwheel.relfreq; //pitch wheel + if(portamento != 0) { //portamento is used + envfreq *= ctl->portamento.freqrap; + if(ctl->portamento.used == 0) //the portamento has finished + portamento = 0; //this note is no longer "portamented" + ; + } - if (BandWidthEnvelope!=NULL) { - envbw=BandWidthEnvelope->envout(); - envbw=pow(2,envbw); - }; - envbw*=ctl->bandwidth.relbw;//bandwidth controller + if(BandWidthEnvelope != NULL) { + envbw = BandWidthEnvelope->envout(); + envbw = pow(2, envbw); + } + envbw *= ctl->bandwidth.relbw; //bandwidth controller - REALTYPE tmpgain=1.0/sqrt(envbw*envfreq); + REALTYPE tmpgain = 1.0 / sqrt(envbw * envfreq); - for (int n=0;nbandwidth.data; - oldpitchwheel=ctl->pitchwheel.data; - }; - newamplitude=volume*AmpEnvelope->envout_dB()*2.0; + for(int n = 0; n < numharmonics; n++) { + for(int nph = 0; nph < numstages; nph++) { + if(nph == 0) + gain = tmpgain; + else + gain = 1.0; + computefiltercoefs(lfilter[nph + n * numstages], + lfilter[nph + n * numstages].freq * envfreq, + lfilter[nph + n * numstages].bw * envbw, + gain); + } + } + if(stereo != 0) + for(int n = 0; n < numharmonics; n++) { + for(int nph = 0; nph < numstages; nph++) { + if(nph == 0) + gain = tmpgain; + else + gain = 1.0; + computefiltercoefs( + rfilter[nph + n * numstages], + rfilter[nph + n + * numstages].freq * envfreq, + rfilter[nph + n * numstages].bw * envbw, + gain); + } + } + ; + oldbandwidth = ctl->bandwidth.data; + oldpitchwheel = ctl->pitchwheel.data; + } + newamplitude = volume * AmpEnvelope->envout_dB() * 2.0; //Filter - if (GlobalFilterL!=NULL) { - REALTYPE globalfilterpitch=GlobalFilterCenterPitch+GlobalFilterEnvelope->envout(); - REALTYPE filterfreq=globalfilterpitch+ctl->filtercutoff.relfreq+GlobalFilterFreqTracking; - filterfreq=GlobalFilterL->getrealfreq(filterfreq); + if(GlobalFilterL != NULL) { + REALTYPE globalfilterpitch = GlobalFilterCenterPitch + + GlobalFilterEnvelope->envout(); + REALTYPE filterfreq = globalfilterpitch + ctl->filtercutoff.relfreq + + GlobalFilterFreqTracking; + filterfreq = GlobalFilterL->getrealfreq(filterfreq); - GlobalFilterL->setfreq_and_q(filterfreq,globalfiltercenterq*ctl->filterq.relq); - if (GlobalFilterR!=NULL) GlobalFilterR->setfreq_and_q(filterfreq,globalfiltercenterq*ctl->filterq.relq); - }; - -}; + GlobalFilterL->setfreq_and_q(filterfreq, + globalfiltercenterq * ctl->filterq.relq); + if(GlobalFilterR != NULL) + GlobalFilterR->setfreq_and_q( + filterfreq, + globalfiltercenterq + * ctl->filterq.relq); + } +} /* * Note Output */ -int SUBnote::noteout(REALTYPE *outl,REALTYPE *outr) +int SUBnote::noteout(REALTYPE *outl, REALTYPE *outr) { int i; - for (i=0;ifilterout(&outl[0]); + if(GlobalFilterL != NULL) + GlobalFilterL->filterout(&outl[0]); //right channel - if (stereo!=0) { - for (i=0;ifilterout(&outr[0]); - } else for (i=0;ifilterout(&outr[0]); + } + else + memcpy(outr, outl, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); - if (firsttick!=0) { - int n=10; - if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; - for (i=0;i SOUND_BUFFER_SIZE) + n = SOUND_BUFFER_SIZE; + for(i = 0; i < n; i++) { + REALTYPE ampfadein = 0.5 - 0.5 * cos( + (REALTYPE) i / (REALTYPE) n * PI); + outl[i] *= ampfadein; + outr[i] *= ampfadein; + } + firsttick = 0; + } - if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude,newamplitude)) { + if(ABOVE_AMPLITUDE_THRESHOLD(oldamplitude, newamplitude)) { // Amplitude interpolation - for (i=0;ifinished()!=0) { - for (i=0;ifinished() != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //fade-out + REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE; + outl[i] *= tmp; + outr[i] *= tmp; + } KillNote(); - }; - return(1); -}; + } + return 1; +} /* * Relase Key (Note Off) @@ -662,17 +769,22 @@ int SUBnote::noteout(REALTYPE *outl,REALTYPE *outr) void SUBnote::relasekey() { AmpEnvelope->relasekey(); - if (FreqEnvelope!=NULL) FreqEnvelope->relasekey(); - if (BandWidthEnvelope!=NULL) BandWidthEnvelope->relasekey(); - if (GlobalFilterEnvelope!=NULL) GlobalFilterEnvelope->relasekey(); -}; + if(FreqEnvelope != NULL) + FreqEnvelope->relasekey(); + if(BandWidthEnvelope != NULL) + BandWidthEnvelope->relasekey(); + if(GlobalFilterEnvelope != NULL) + GlobalFilterEnvelope->relasekey(); +} /* * Check if the note is finished */ int SUBnote::finished() { - if (NoteEnabled==OFF) return(1); - else return(0); -}; + if(NoteEnabled == OFF) + return 1; + else + return 0; +} diff --git a/plugins/zynaddsubfx/src/Synth/SUBnote.h b/plugins/zynaddsubfx/src/Synth/SUBnote.h index 48b55f1ca..e6b875e48 100644 --- a/plugins/zynaddsubfx/src/Synth/SUBnote.h +++ b/plugins/zynaddsubfx/src/Synth/SUBnote.h @@ -31,84 +31,101 @@ class SUBnote { -public: - SUBnote(SUBnoteParameters *parameters,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote,bool besilent); - ~SUBnote(); + public: + SUBnote(SUBnoteParameters *parameters, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool besilent); + ~SUBnote(); - void SUBlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall); + void SUBlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall); - int noteout(REALTYPE *outl,REALTYPE *outr);//note output,return 0 if the note is finished - void relasekey(); - int finished(); + int noteout(REALTYPE *outl, REALTYPE *outr); //note output,return 0 if the note is finished + void relasekey(); + int finished(); - int ready; //if I can get the sampledata + int ready; //if I can get the sampledata -private: + private: - void computecurrentparameters(); - void initparameters(REALTYPE freq); - void KillNote(); + void computecurrentparameters(); + void initparameters(REALTYPE freq); + void KillNote(); - SUBnoteParameters *pars; + SUBnoteParameters *pars; - //parameters - int stereo; - int numstages;//number of stages of filters - int numharmonics;//number of harmonics (after the too higher hamonics are removed) - int firstnumharmonics;//To keep track of the first note's numharmonics value, useful in legato mode. - int start;//how the harmonics start - REALTYPE basefreq; - REALTYPE panning; - Envelope *AmpEnvelope; - Envelope *FreqEnvelope; - Envelope *BandWidthEnvelope; + //parameters + int stereo; + int numstages; //number of stages of filters + int numharmonics; //number of harmonics (after the too higher hamonics are removed) + int firstnumharmonics; //To keep track of the first note's numharmonics value, useful in legato mode. + int start; //how the harmonics start + REALTYPE basefreq; + REALTYPE panning; + Envelope *AmpEnvelope; + Envelope *FreqEnvelope; + Envelope *BandWidthEnvelope; - Filter *GlobalFilterL,*GlobalFilterR; + Filter *GlobalFilterL, *GlobalFilterR; - Envelope *GlobalFilterEnvelope; + Envelope *GlobalFilterEnvelope; - //internal values - ONOFFTYPE NoteEnabled; - int firsttick,portamento; - REALTYPE volume,oldamplitude,newamplitude; + //internal values + ONOFFTYPE NoteEnabled; + int firsttick, portamento; + REALTYPE volume, oldamplitude, newamplitude; - REALTYPE GlobalFilterCenterPitch;//octaves - REALTYPE GlobalFilterFreqTracking; + REALTYPE GlobalFilterCenterPitch; //octaves + REALTYPE GlobalFilterFreqTracking; - struct bpfilter { - REALTYPE freq,bw,amp; //filter parameters - REALTYPE a1,a2,b0,b2;//filter coefs. b1=0 - REALTYPE xn1,xn2,yn1,yn2; //filter internal values - }; + struct bpfilter { + REALTYPE freq, bw, amp; //filter parameters + REALTYPE a1, a2, b0, b2; //filter coefs. b1=0 + REALTYPE xn1, xn2, yn1, yn2; //filter internal values + }; - void initfilter(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE amp,REALTYPE mag); - void computefiltercoefs(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE gain); - void filter(bpfilter &filter,REALTYPE *smps); + void initfilter(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE amp, + REALTYPE mag); + void computefiltercoefs(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE gain); + inline void filter(bpfilter &filter, REALTYPE *smps); - bpfilter *lfilter,*rfilter; + bpfilter *lfilter, *rfilter; - REALTYPE *tmpsmp; - REALTYPE *tmprnd;//this is filled with random numbers + REALTYPE *tmpsmp; + REALTYPE *tmprnd; //this is filled with random numbers - Controller *ctl; - int oldpitchwheel,oldbandwidth; - REALTYPE globalfiltercenterq; + Controller *ctl; + int oldpitchwheel, oldbandwidth; + REALTYPE globalfiltercenterq; - // Legato vars - struct { - bool silent; - REALTYPE lastfreq; - LegatoMsg msg; - int decounter; - struct { // Fade In/Out vars - int length; - REALTYPE m, step; - } fade; - struct { // Note parameters - REALTYPE freq, vel; - int portamento, midinote; - } param; - } Legato; + // Legato vars + struct { + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; }; diff --git a/plugins/zynaddsubfx/src/UI/ADnoteUI.cc b/plugins/zynaddsubfx/src/UI/ADnoteUI.cc index 831a8a533..9d3ca6caf 100644 --- a/plugins/zynaddsubfx/src/UI/ADnoteUI.cc +++ b/plugins/zynaddsubfx/src/UI/ADnoteUI.cc @@ -517,6 +517,56 @@ void ADvoiceUI::cb_Use1(Fl_Choice* o, void* v) { ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Use1_i(o,v); } +void ADvoiceUI::cb_Stereo_i(WidgetPDial* o, void*) { + pars->VoicePar[nvoice].Unison_stereo_spread=(int)o->value(); +} +void ADvoiceUI::cb_Stereo(WidgetPDial* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Stereo_i(o,v); +} + +void ADvoiceUI::cb_Unison_i(Fl_Choice* o, void*) { + pars->set_unison_size_index(nvoice,(int) o->value()); +} +void ADvoiceUI::cb_Unison(Fl_Choice* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Unison_i(o,v); +} + +void ADvoiceUI::cb_Vibratto_i(WidgetPDial* o, void*) { + pars->VoicePar[nvoice].Unison_vibratto=(int)o->value(); +} +void ADvoiceUI::cb_Vibratto(WidgetPDial* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Vibratto_i(o,v); +} + +void ADvoiceUI::cb_Invert_i(Fl_Choice* o, void*) { + pars->VoicePar[nvoice].Unison_invert_phase=(int) o->value(); +} +void ADvoiceUI::cb_Invert(Fl_Choice* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Invert_i(o,v); +} + +void ADvoiceUI::cb_Frequency_i(Fl_Slider* o, void*) { + pars->VoicePar[nvoice].Unison_frequency_spread=(int)o->value(); +unisonspreadoutput->do_callback(); +} +void ADvoiceUI::cb_Frequency(Fl_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Frequency_i(o,v); +} + +void ADvoiceUI::cb_unisonspreadoutput_i(Fl_Value_Output* o, void*) { + o->value(pars->getUnisonFrequencySpreadCents(nvoice)); +} +void ADvoiceUI::cb_unisonspreadoutput(Fl_Value_Output* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_unisonspreadoutput_i(o,v); +} + +void ADvoiceUI::cb_Vib_i(WidgetPDial* o, void*) { + pars->VoicePar[nvoice].Unison_vibratto_speed=(int)o->value(); +} +void ADvoiceUI::cb_Vib(WidgetPDial* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Vib_i(o,v); +} + void ADvoiceUI::cb_Vol1_i(Fl_Value_Slider* o, void*) { pars->VoicePar[nvoice].PVolume=(int)o->value(); } @@ -645,7 +695,7 @@ void ADvoiceUI::cb_voiceonbutton(Fl_Check_Button* o, void* v) { } Fl_Group* ADvoiceUI::make_window() { - { ADnoteVoiceParameters = new Fl_Group(0, 0, 765, 525, "Voice"); + { ADnoteVoiceParameters = new Fl_Group(0, 0, 765, 575, "Voice"); ADnoteVoiceParameters->box(FL_FLAT_BOX); ADnoteVoiceParameters->color(FL_BACKGROUND_COLOR); ADnoteVoiceParameters->selection_color(FL_BACKGROUND_COLOR); @@ -656,11 +706,11 @@ Fl_Group* ADvoiceUI::make_window() { ADnoteVoiceParameters->user_data((void*)(this)); ADnoteVoiceParameters->align(Fl_Align(FL_ALIGN_TOP)); ADnoteVoiceParameters->when(FL_WHEN_RELEASE); - { Fl_Group* o = voiceparametersgroup = new Fl_Group(0, 0, 765, 525); + { Fl_Group* o = voiceparametersgroup = new Fl_Group(0, 0, 765, 580); voiceparametersgroup->box(FL_THIN_UP_BOX); voiceparametersgroup->color((Fl_Color)48); - { voicemodegroup = new Fl_Group(0, 5, 760, 515); - { Fl_Group* o = voiceFMparametersgroup = new Fl_Group(530, 5, 230, 515, "MODULATOR"); + { voicemodegroup = new Fl_Group(0, 5, 760, 575); + { Fl_Group* o = voiceFMparametersgroup = new Fl_Group(530, 5, 230, 565, "MODULATOR"); voiceFMparametersgroup->box(FL_THIN_UP_FRAME); voiceFMparametersgroup->color((Fl_Color)48); voiceFMparametersgroup->labeltype(FL_EMBOSSED_LABEL); @@ -823,8 +873,8 @@ Fl_Group* ADvoiceUI::make_window() { } // Fl_Value_Slider* o o->end(); } // Fl_Group* o - { modoscil = new Fl_Group(535, 365, 220, 150); - { Fl_Group* o = fmoscil = new Fl_Group(535, 405, 220, 110); + { modoscil = new Fl_Group(535, 365, 220, 200); + { Fl_Group* o = fmoscil = new Fl_Group(535, 425, 220, 140); fmoscil->box(FL_THIN_DOWN_BOX); fmoscil->color(FL_GRAY0); fmoscil->selection_color((Fl_Color)71); @@ -845,7 +895,7 @@ Fl_Group* ADvoiceUI::make_window() { changeFMoscilbutton->callback((Fl_Callback*)cb_changeFMoscilbutton); if (pars->VoicePar[nvoice].PextFMoscil>=0) o->labelcolor(FL_BLUE); } // Fl_Button* changeFMoscilbutton - { Fl_Slider* o = new Fl_Slider(665, 395, 65, 10, "Phase"); + { Fl_Slider* o = new Fl_Slider(665, 400, 65, 10, "Phase"); o->type(5); o->box(FL_FLAT_BOX); o->labelsize(10); @@ -856,7 +906,7 @@ Fl_Group* ADvoiceUI::make_window() { o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); o->value(64-pars->VoicePar[nvoice].PFMoscilphase); } // Fl_Slider* o - { Fl_Choice* o = new Fl_Choice(560, 390, 75, 15, "Use"); + { Fl_Choice* o = new Fl_Choice(560, 395, 75, 15, "Use"); o->down_box(FL_BORDER_BOX); o->labelsize(10); o->textfont(1); @@ -1082,6 +1132,102 @@ cy)"); char tmp[50]; for (int i=0;iadd(tmp);}; o->value(pars->VoicePar[nvoice].Pextoscil+1); } // Fl_Choice* o + { Fl_Group* o = new Fl_Group(5, 525, 515, 45); + o->box(FL_ENGRAVED_BOX); + { WidgetPDial* o = new WidgetPDial(285, 540, 25, 25, "Stereo"); + o->tooltip("Stereo Spread"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Stereo); + o->align(Fl_Align(FL_ALIGN_TOP)); + o->when(FL_WHEN_CHANGED); + o->value(pars->VoicePar[nvoice].Unison_stereo_spread); + } // WidgetPDial* o + { Fl_Choice* o = new Fl_Choice(10, 545, 75, 20, "Unison"); + o->tooltip("Unison size"); + o->down_box(FL_BORDER_BOX); + o->labelfont(1); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_Unison); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + o->add("OFF");char tmp[100];for (int i=1;ADnote_unison_sizes[i];i++){snprintf(tmp,100,"size %d",ADnote_unison_sizes[i]);o->add(tmp);}; + o->value(pars->get_unison_size_index(nvoice)); + } // Fl_Choice* o + { WidgetPDial* o = new WidgetPDial(340, 540, 25, 25, "Vibratto"); + o->tooltip("Vibratto"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Vibratto); + o->align(Fl_Align(FL_ALIGN_TOP)); + o->when(FL_WHEN_CHANGED); + o->value(pars->VoicePar[nvoice].Unison_vibratto); + } // WidgetPDial* o + { Fl_Choice* o = new Fl_Choice(445, 545, 65, 15, "Invert"); + o->tooltip("Phase Invert"); + o->down_box(FL_BORDER_BOX); + o->labelsize(11); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_Invert); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + o->add("None");o->add("Random");char tmp[100];for (int i=2;i<=5;i++){snprintf(tmp,100,"%d %%",100/i);o->add(tmp);}; + o->value(pars->VoicePar[nvoice].Unison_invert_phase); + } // Fl_Choice* o + { Fl_Slider* o = new Fl_Slider(95, 547, 125, 13, "Frequency Spread"); + o->tooltip("Frequency Spread of the Unison"); + o->type(5); + o->box(FL_FLAT_BOX); + o->labelsize(12); + o->maximum(127); + o->step(1); + o->value(64); + o->callback((Fl_Callback*)cb_Frequency); + o->align(Fl_Align(FL_ALIGN_TOP)); + o->value(pars->VoicePar[nvoice].Unison_frequency_spread); + } // Fl_Slider* o + { Fl_Value_Output* o = unisonspreadoutput = new Fl_Value_Output(225, 545, 40, 15, "(cents)"); + unisonspreadoutput->labelsize(10); + unisonspreadoutput->maximum(1000); + unisonspreadoutput->step(0.1); + unisonspreadoutput->textfont(1); + unisonspreadoutput->textsize(10); + unisonspreadoutput->callback((Fl_Callback*)cb_unisonspreadoutput); + unisonspreadoutput->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + o->value(pars->getUnisonFrequencySpreadCents(nvoice)); + } // Fl_Value_Output* unisonspreadoutput + { WidgetPDial* o = new WidgetPDial(390, 540, 25, 25, "Vib.speed"); + o->tooltip("Vibratto Average Speed"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Vib); + o->align(Fl_Align(FL_ALIGN_TOP)); + o->when(FL_WHEN_CHANGED); + o->value(pars->VoicePar[nvoice].Unison_vibratto_speed); + } // WidgetPDial* o + o->end(); + } // Fl_Group* o voicemodegroup->end(); } // Fl_Group* voicemodegroup { Fl_Group* o = new Fl_Group(5, 40, 240, 210, "AMPLITUDE"); @@ -1522,7 +1668,7 @@ void ADnoteUI::cb_currentvoicecounter_i(Fl_Counter* o, void*) { advoice->hide(); ADnoteVoice->remove(advoice); delete advoice; -advoice=new ADvoiceUI(0,0,765,525); +advoice=new ADvoiceUI(0,0,765,585); ADnoteVoice->add(advoice); advoice->init(pars,nvoice,master); advoice->show(); @@ -1899,9 +2045,9 @@ Fl_Double_Window* ADnoteUI::make_window() { } // Fl_Button* o ADnoteGlobalParameters->end(); } // Fl_Double_Window* ADnoteGlobalParameters - { ADnoteVoice = new Fl_Double_Window(765, 560, "ADsynth Voice Parameters"); + { ADnoteVoice = new Fl_Double_Window(765, 620, "ADsynth Voice Parameters"); ADnoteVoice->user_data((void*)(this)); - { ADvoiceUI* o = advoice = new ADvoiceUI(0, 0, 760, 525); + { ADvoiceUI* o = advoice = new ADvoiceUI(0, 0, 760, 575); advoice->box(FL_BORDER_BOX); advoice->color(FL_BACKGROUND_COLOR); advoice->selection_color(FL_BACKGROUND_COLOR); @@ -1915,12 +2061,12 @@ Fl_Double_Window* ADnoteUI::make_window() { o->show(); advoice->end(); } // ADvoiceUI* advoice - { Fl_Button* o = new Fl_Button(300, 530, 195, 25, "Close Window"); + { Fl_Button* o = new Fl_Button(300, 585, 195, 25, "Close Window"); o->box(FL_THIN_UP_BOX); o->labelfont(1); o->callback((Fl_Callback*)cb_Close1); } // Fl_Button* o - { Fl_Counter* o = currentvoicecounter = new Fl_Counter(5, 530, 130, 25, "Current Voice"); + { Fl_Counter* o = currentvoicecounter = new Fl_Counter(5, 585, 130, 25, "Current Voice"); currentvoicecounter->type(1); currentvoicecounter->labelfont(1); currentvoicecounter->minimum(0); @@ -1933,7 +2079,7 @@ Fl_Double_Window* ADnoteUI::make_window() { currentvoicecounter->align(Fl_Align(FL_ALIGN_RIGHT)); o->bounds(1,NUM_VOICES); } // Fl_Counter* currentvoicecounter - { Fl_Button* o = new Fl_Button(700, 535, 25, 15, "C"); + { Fl_Button* o = new Fl_Button(700, 590, 25, 15, "C"); o->box(FL_THIN_UP_BOX); o->color((Fl_Color)179); o->labelfont(1); @@ -1941,7 +2087,7 @@ Fl_Double_Window* ADnoteUI::make_window() { o->labelcolor(FL_BACKGROUND2_COLOR); o->callback((Fl_Callback*)cb_C1); } // Fl_Button* o - { Fl_Button* o = new Fl_Button(730, 535, 25, 15, "P"); + { Fl_Button* o = new Fl_Button(730, 590, 25, 15, "P"); o->box(FL_THIN_UP_BOX); o->color((Fl_Color)179); o->labelfont(1); diff --git a/plugins/zynaddsubfx/src/UI/ADnoteUI.fl b/plugins/zynaddsubfx/src/UI/ADnoteUI.fl index 4888eaea4..748156c74 100644 --- a/plugins/zynaddsubfx/src/UI/ADnoteUI.fl +++ b/plugins/zynaddsubfx/src/UI/ADnoteUI.fl @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0107 +version 1.0109 header_name {.h} code_name {.cc} decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} @@ -178,19 +178,19 @@ class ADvoiceUI {open : {public Fl_Group} } { Fl_Window ADnoteVoiceParameters { label Voice - xywh {225 174 765 525} type Double hide - class Fl_Group + xywh {69 185 765 575} type Double + class Fl_Group visible } { - Fl_Group voiceparametersgroup { - xywh {0 0 765 525} box THIN_UP_BOX color 48 + Fl_Group voiceparametersgroup {open + xywh {0 0 765 580} box THIN_UP_BOX color 48 code0 {if (pars->VoicePar[nvoice].Enabled==0) o->deactivate();} } { - Fl_Group voicemodegroup { - xywh {0 5 760 515} + Fl_Group voicemodegroup {open + xywh {0 5 760 575} } { Fl_Group voiceFMparametersgroup { label MODULATOR - xywh {530 5 230 515} box THIN_UP_FRAME color 48 labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + xywh {530 5 230 565} box THIN_UP_FRAME color 48 labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 code0 {if (pars->VoicePar[nvoice].PFMEnabled==0) o->deactivate();} } { Fl_Group modfrequency { @@ -209,7 +209,7 @@ class ADvoiceUI {open : {public Fl_Group} callback {pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled=(int)o->value(); if (o->value()==0) voiceFMfreqenvgroup->deactivate(); else voiceFMfreqenvgroup->activate(); -o->redraw();} selected +o->redraw();} tooltip {Forced Relase} xywh {545 295 50 10} down_box DOWN_BOX labelfont 1 labelsize 10 code0 {o->value(pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled);} } @@ -298,10 +298,10 @@ o->redraw();} } } Fl_Group modoscil { - xywh {535 365 220 150} + xywh {535 365 220 200} } { Fl_Group fmoscil {open - xywh {535 405 220 110} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 + xywh {535 425 220 140} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 code0 {oscFM=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} code1 {int nv=nvoice; if (pars->VoicePar[nvoice].PextFMoscil>=0) nv=pars->VoicePar[nvoice].PextFMoscil;} code2 {oscFM->init(pars->VoicePar[nv].FMSmp,0,pars->VoicePar[nvoice].PFMoscilphase,master);} @@ -326,7 +326,7 @@ oscedit=new OscilEditor(pars->VoicePar[nv].FMSmp,fmoscil,NULL,NULL,master);} callback {pars->VoicePar[nvoice].PFMoscilphase=64-(int)o->value(); oscFM->phase=64-(int) o->value(); fmoscil->redraw();} - xywh {665 395 65 10} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum -64 maximum 63 step 1 + xywh {665 400 65 10} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum -64 maximum 63 step 1 code0 {o->value(64-pars->VoicePar[nvoice].PFMoscilphase);} } Fl_Choice {} { @@ -340,7 +340,7 @@ if ((int) o->value() != 0) { changeFMoscilbutton->labelcolor(FL_BLACK); }; voiceFMparametersgroup->redraw();} open - xywh {560 390 75 15} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10 + xywh {560 395 75 15} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10 code0 {o->add("Internal");} code1 {char tmp[50]; for (int i=0;iadd(tmp);};} code3 {o->value(pars->VoicePar[nvoice].PextFMoscil+1);} @@ -548,6 +548,58 @@ voiceonbutton->redraw();} open code1 {char tmp[50]; for (int i=0;iadd(tmp);};} code3 {o->value(pars->VoicePar[nvoice].Pextoscil+1);} } {} + Fl_Group {} {open + xywh {5 525 515 45} box ENGRAVED_BOX + } { + Fl_Dial {} { + label Stereo + callback {pars->VoicePar[nvoice].Unison_stereo_spread=(int)o->value();} + tooltip {Stereo Spread} xywh {285 540 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].Unison_stereo_spread);} + class WidgetPDial + } + Fl_Choice {} { + label Unison + callback {pars->set_unison_size_index(nvoice,(int) o->value());} open selected + tooltip {Unison size} xywh {10 545 75 20} down_box BORDER_BOX labelfont 1 align 5 textfont 1 textsize 10 + code0 {o->add("OFF");char tmp[100];for (int i=1;ADnote_unison_sizes[i];i++){snprintf(tmp,100,"size %d",ADnote_unison_sizes[i]);o->add(tmp);};} + code1 {o->value(pars->get_unison_size_index(nvoice));} + } {} + Fl_Dial {} { + label Vibratto + callback {pars->VoicePar[nvoice].Unison_vibratto=(int)o->value();} + tooltip Vibratto xywh {340 540 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].Unison_vibratto);} + class WidgetPDial + } + Fl_Choice {} { + label Invert + callback {pars->VoicePar[nvoice].Unison_invert_phase=(int) o->value();} open + tooltip {Phase Invert} xywh {445 545 65 15} down_box BORDER_BOX labelsize 11 align 5 textfont 1 textsize 10 + code0 {o->add("None");o->add("Random");char tmp[100];for (int i=2;i<=5;i++){snprintf(tmp,100,"%d %%",100/i);o->add(tmp);};} + code1 {o->value(pars->VoicePar[nvoice].Unison_invert_phase);} + } {} + Fl_Slider {} { + label {Frequency Spread} + callback {pars->VoicePar[nvoice].Unison_frequency_spread=(int)o->value(); +unisonspreadoutput->do_callback();} + tooltip {Frequency Spread of the Unison} xywh {95 547 125 13} type {Horz Knob} box FLAT_BOX labelsize 12 align 1 maximum 127 step 1 value 64 + code0 {o->value(pars->VoicePar[nvoice].Unison_frequency_spread);} + } + Fl_Value_Output unisonspreadoutput { + label {(cents)} + callback {o->value(pars->getUnisonFrequencySpreadCents(nvoice));} + xywh {225 545 40 15} labelsize 10 align 5 maximum 1000 step 0.1 textfont 1 textsize 10 + code0 {o->value(pars->getUnisonFrequencySpreadCents(nvoice));} + } + Fl_Dial {} { + label {Vib.speed} + callback {pars->VoicePar[nvoice].Unison_vibratto_speed=(int)o->value();} + tooltip {Vibratto Average Speed} xywh {390 540 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].Unison_vibratto_speed);} + class WidgetPDial + } + } } Fl_Group {} { label AMPLITUDE @@ -728,7 +780,8 @@ o->redraw();} pars=NULL; oscedit=NULL;} {} } - Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {} { + Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {open + } { code {pars=parameters; nvoice=nvoice_; master=master_; @@ -752,7 +805,7 @@ if (oscedit!=NULL) { decl {Master *master;} {} } -class ADnoteUI {: {public PresetsUI_} +class ADnoteUI {open : {public PresetsUI_} } { Function {make_window()} {open private } { @@ -967,10 +1020,10 @@ resui->resonancewindow->show();} } Fl_Window ADnoteVoice { label {ADsynth Voice Parameters} - xywh {53 58 765 560} type Double hide + xywh {152 271 765 620} type Double visible } { Fl_Group advoice { - xywh {0 0 760 525} box BORDER_BOX + xywh {0 0 760 575} box BORDER_BOX code0 {o->init(pars,nvoice,master);} code1 {o->show();} class ADvoiceUI @@ -978,7 +1031,7 @@ resui->resonancewindow->show();} Fl_Button {} { label {Close Window} callback {ADnoteVoice->hide();} - xywh {300 530 195 25} box THIN_UP_BOX labelfont 1 + xywh {300 585 195 25} box THIN_UP_BOX labelfont 1 } Fl_Counter currentvoicecounter { label {Current Voice} @@ -986,23 +1039,23 @@ resui->resonancewindow->show();} advoice->hide(); ADnoteVoice->remove(advoice); delete advoice; -advoice=new ADvoiceUI(0,0,765,525); +advoice=new ADvoiceUI(0,0,765,585); ADnoteVoice->add(advoice); advoice->init(pars,nvoice,master); advoice->show(); ADnoteVoice->redraw();} - xywh {5 530 130 25} type Simple labelfont 1 align 8 minimum 0 maximum 2 step 1 value 1 textfont 1 textsize 13 + xywh {5 585 130 25} type Simple labelfont 1 align 8 minimum 0 maximum 2 step 1 value 1 textfont 1 textsize 13 code0 {o->bounds(1,NUM_VOICES);} } Fl_Button {} { label C callback {presetsui->copy(pars,nvoice);} - xywh {700 535 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + xywh {700 590 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 } Fl_Button {} { label P callback {presetsui->paste(pars,this,nvoice);} - xywh {730 535 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + xywh {730 590 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 } } Fl_Window ADnoteVoiceList { diff --git a/plugins/zynaddsubfx/src/UI/ADnoteUI.h b/plugins/zynaddsubfx/src/UI/ADnoteUI.h index 01817c196..a9a573d60 100644 --- a/plugins/zynaddsubfx/src/UI/ADnoteUI.h +++ b/plugins/zynaddsubfx/src/UI/ADnoteUI.h @@ -174,6 +174,23 @@ private: static void cb_R(Fl_Check_Button*, void*); void cb_Use1_i(Fl_Choice*, void*); static void cb_Use1(Fl_Choice*, void*); + void cb_Stereo_i(WidgetPDial*, void*); + static void cb_Stereo(WidgetPDial*, void*); + void cb_Unison_i(Fl_Choice*, void*); + static void cb_Unison(Fl_Choice*, void*); + void cb_Vibratto_i(WidgetPDial*, void*); + static void cb_Vibratto(WidgetPDial*, void*); + void cb_Invert_i(Fl_Choice*, void*); + static void cb_Invert(Fl_Choice*, void*); + void cb_Frequency_i(Fl_Slider*, void*); + static void cb_Frequency(Fl_Slider*, void*); +public: + Fl_Value_Output *unisonspreadoutput; +private: + void cb_unisonspreadoutput_i(Fl_Value_Output*, void*); + static void cb_unisonspreadoutput(Fl_Value_Output*, void*); + void cb_Vib_i(WidgetPDial*, void*); + static void cb_Vib(WidgetPDial*, void*); void cb_Vol1_i(Fl_Value_Slider*, void*); static void cb_Vol1(Fl_Value_Slider*, void*); void cb_V1_i(Fl_Value_Slider*, void*); diff --git a/plugins/zynaddsubfx/src/UI/EffUI.cc b/plugins/zynaddsubfx/src/UI/EffUI.cc index 9da1534d9..9c1b141c7 100644 --- a/plugins/zynaddsubfx/src/UI/EffUI.cc +++ b/plugins/zynaddsubfx/src/UI/EffUI.cc @@ -154,6 +154,7 @@ void EffUI::cb_revp10(Fl_Choice* o, void* v) { Fl_Menu_Item EffUI::menu_revp10[] = { {"Random", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, {"Freeverb", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Bandwidth", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, {0,0,0,0,0,0,0,0,0} }; @@ -192,11 +193,11 @@ void EffUI::cb_revp4(WidgetPDial* o, void* v) { ((EffUI*)(o->parent()->user_data()))->cb_revp4_i(o,v); } -void EffUI::cb_revp5_i(WidgetPDial* o, void*) { - eff->seteffectpar(5,(int) o->value()); +void EffUI::cb_revp12_i(WidgetPDial* o, void*) { + eff->seteffectpar(12,(int) o->value()); } -void EffUI::cb_revp5(WidgetPDial* o, void* v) { - ((EffUI*)(o->parent()->user_data()))->cb_revp5_i(o,v); +void EffUI::cb_revp12(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp12_i(o,v); } void EffUI::cb_revp6_i(WidgetPDial* o, void*) { @@ -1022,7 +1023,7 @@ Fl_Group* EffUI::make_reverb_window() { revp->align(Fl_Align(FL_ALIGN_TOP_LEFT)); revp->menu(menu_revp); } // Fl_Choice* revp - { revp10 = new Fl_Choice(110, 15, 75, 15, "Type"); + { revp10 = new Fl_Choice(110, 15, 85, 15, "Type"); revp10->down_box(FL_BORDER_BOX); revp10->color((Fl_Color)14); revp10->labelfont(1); @@ -1103,20 +1104,19 @@ Fl_Group* EffUI::make_reverb_window() { revp4->align(Fl_Align(FL_ALIGN_BOTTOM)); revp4->when(FL_WHEN_CHANGED); } // WidgetPDial* revp4 - { revp5 = new WidgetPDial(200, 40, 30, 30, "R.delay"); - revp5->box(FL_ROUND_UP_BOX); - revp5->color(FL_BACKGROUND_COLOR); - revp5->selection_color(FL_INACTIVE_COLOR); - revp5->labeltype(FL_NORMAL_LABEL); - revp5->labelfont(1); - revp5->labelsize(11); - revp5->labelcolor(FL_FOREGROUND_COLOR); - revp5->maximum(127); - revp5->callback((Fl_Callback*)cb_revp5); - revp5->align(Fl_Align(FL_ALIGN_BOTTOM)); - revp5->when(FL_WHEN_RELEASE); - revp5->deactivate(); - } // WidgetPDial* revp5 + { revp12 = new WidgetPDial(200, 40, 30, 30, "bw"); + revp12->box(FL_ROUND_UP_BOX); + revp12->color(FL_BACKGROUND_COLOR); + revp12->selection_color(FL_INACTIVE_COLOR); + revp12->labeltype(FL_NORMAL_LABEL); + revp12->labelfont(1); + revp12->labelsize(11); + revp12->labelcolor(FL_FOREGROUND_COLOR); + revp12->maximum(127); + revp12->callback((Fl_Callback*)cb_revp12); + revp12->align(Fl_Align(FL_ALIGN_BOTTOM)); + revp12->when(FL_WHEN_RELEASE); + } // WidgetPDial* revp12 { revp6 = new WidgetPDial(235, 40, 30, 30, "E/R"); revp6->box(FL_ROUND_UP_BOX); revp6->color(FL_BACKGROUND_COLOR); @@ -1175,7 +1175,7 @@ Fl_Group* EffUI::make_reverb_window() { revp9->align(Fl_Align(FL_ALIGN_BOTTOM)); revp9->when(FL_WHEN_CHANGED); } // WidgetPDial* revp9 - { revp11 = new WidgetPDial(190, 10, 25, 25, "R.S."); + { revp11 = new WidgetPDial(200, 10, 25, 25, "R.S."); revp11->tooltip("RoomSize"); revp11->box(FL_ROUND_UP_BOX); revp11->color(FL_BACKGROUND_COLOR); @@ -2449,13 +2449,14 @@ switch(eff->geteffect()){ revp2->value(eff->geteffectpar(2)); revp3->value(eff->geteffectpar(3)); revp4->value(eff->geteffectpar(4)); - revp5->value(eff->geteffectpar(5)); + //revp5->value(eff->geteffectpar(5)); revp6->value(eff->geteffectpar(6)); revp7->value(eff->geteffectpar(7)); revp8->value(eff->geteffectpar(8)); revp9->value(eff->geteffectpar(9)); revp10->value(eff->geteffectpar(10)); revp11->value(eff->geteffectpar(11)); + revp12->value(eff->geteffectpar(12)); effreverbwindow->show(); break; @@ -2573,13 +2574,13 @@ void EffUI::refresh() { refresh(eff); } -void SimpleEffUI::cb_revpa_i(Fl_Choice* o, void*) { +void SimpleEffUI::cb_revp5_i(Fl_Choice* o, void*) { eff->changepreset((int)o->value()); refresh(eff); } -void SimpleEffUI::cb_revpa(Fl_Choice* o, void* v) { - ((SimpleEffUI*)(o->parent()->user_data()))->cb_revpa_i(o,v); +void SimpleEffUI::cb_revp5(Fl_Choice* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_revp5_i(o,v); } Fl_Menu_Item SimpleEffUI::menu_revp1[] = { @@ -3118,7 +3119,7 @@ Fl_Group* SimpleEffUI::make_reverb_window() { revp->textfont(1); revp->textsize(10); revp->textcolor(FL_BACKGROUND2_COLOR); - revp->callback((Fl_Callback*)cb_revpa); + revp->callback((Fl_Callback*)cb_revp5); revp->align(Fl_Align(FL_ALIGN_TOP_LEFT)); revp->menu(menu_revp1); } // Fl_Choice* revp diff --git a/plugins/zynaddsubfx/src/UI/EffUI.fl b/plugins/zynaddsubfx/src/UI/EffUI.fl index e2712f107..178f3ad04 100644 --- a/plugins/zynaddsubfx/src/UI/EffUI.fl +++ b/plugins/zynaddsubfx/src/UI/EffUI.fl @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0107 +version 1.0109 header_name {.h} code_name {.cc} decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} @@ -36,7 +36,7 @@ decl {\#include "../Effects/EffectMgr.h"} {public decl {\#include "PresetsUI.h"} {public } -class EQGraph {selected : {public Fl_Box} +class EQGraph {: {public Fl_Box} } { Function {EQGraph(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { code {eff=NULL; @@ -155,7 +155,7 @@ return(log(freq/20.0)/log(1000.0));} {} decl {int maxdB;} {} } -class EffUI {: {public Fl_Group,public PresetsUI_} +class EffUI {open : {public Fl_Group,public PresetsUI_} } { Function {EffUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { code {eff=NULL; @@ -188,10 +188,11 @@ if (filterwindow!=NULL){ } } } - Function {make_reverb_window()} {} { - Fl_Window effreverbwindow { - xywh {343 337 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide - class Fl_Group + Function {make_reverb_window()} {open + } { + Fl_Window effreverbwindow {open + xywh {343 337 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 + class Fl_Group visible } { Fl_Text_Display {} { label {Reverb } @@ -259,8 +260,8 @@ refresh(eff);} } Fl_Choice revp10 { label Type - callback {eff->seteffectpar(10,(int) o->value());} - xywh {110 15 75 15} down_box BORDER_BOX color 14 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + callback {eff->seteffectpar(10,(int) o->value());} open + xywh {110 15 85 15} down_box BORDER_BOX color 14 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 } { MenuItem {} { label Random @@ -270,6 +271,10 @@ refresh(eff);} label Freeverb xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 } + MenuItem {} { + label Bandwidth + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } } Fl_Dial revp0 { label Vol @@ -301,10 +306,10 @@ refresh(eff);} tooltip {Initial Delay Feedback} xywh {155 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 class WidgetPDial } - Fl_Dial revp5 { - label {R.delay} - callback {eff->seteffectpar(5,(int) o->value());} - xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 deactivate + Fl_Dial revp12 { + label bw + callback {eff->seteffectpar(12,(int) o->value());} + xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 class WidgetPDial } Fl_Dial revp6 { @@ -337,7 +342,7 @@ refresh(eff);} if (Fl::event_button1()) x=(int)o->value(); else o->value(x); eff->seteffectpar(11,x);} - tooltip RoomSize xywh {190 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 8 align 8 minimum 1 maximum 127 step 1 + tooltip RoomSize xywh {200 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 8 align 8 minimum 1 maximum 127 step 1 class WidgetPDial } } @@ -1263,7 +1268,8 @@ effdynamicfilterwindow->position(px,py); refresh(eff);} {} } - Function {refresh(EffectMgr *eff_)} {} { + Function {refresh(EffectMgr *eff_)} {open + } { code {eff=eff_; this->hide(); @@ -1293,13 +1299,14 @@ switch(eff->geteffect()){ revp2->value(eff->geteffectpar(2)); revp3->value(eff->geteffectpar(3)); revp4->value(eff->geteffectpar(4)); - revp5->value(eff->geteffectpar(5)); + //revp5->value(eff->geteffectpar(5)); revp6->value(eff->geteffectpar(6)); revp7->value(eff->geteffectpar(7)); revp8->value(eff->geteffectpar(8)); revp9->value(eff->geteffectpar(9)); revp10->value(eff->geteffectpar(10)); revp11->value(eff->geteffectpar(11)); + revp12->value(eff->geteffectpar(12)); effreverbwindow->show(); break; @@ -1410,7 +1417,8 @@ switch(eff->geteffect()){ break; }; -this->show();} {} +this->show();} {selected + } } Function {refresh()} {} { code {refresh(eff);} {} diff --git a/plugins/zynaddsubfx/src/UI/EffUI.h b/plugins/zynaddsubfx/src/UI/EffUI.h index 3fddc2920..9f8721b51 100644 --- a/plugins/zynaddsubfx/src/UI/EffUI.h +++ b/plugins/zynaddsubfx/src/UI/EffUI.h @@ -84,10 +84,10 @@ private: void cb_revp4_i(WidgetPDial*, void*); static void cb_revp4(WidgetPDial*, void*); public: - WidgetPDial *revp5; + WidgetPDial *revp12; private: - void cb_revp5_i(WidgetPDial*, void*); - static void cb_revp5(WidgetPDial*, void*); + void cb_revp12_i(WidgetPDial*, void*); + static void cb_revp12(WidgetPDial*, void*); public: WidgetPDial *revp6; private: @@ -545,8 +545,8 @@ public: Fl_Group *effreverbwindow; Fl_Choice *revp; private: - void cb_revpa_i(Fl_Choice*, void*); - static void cb_revpa(Fl_Choice*, void*); + void cb_revp5_i(Fl_Choice*, void*); + static void cb_revp5(Fl_Choice*, void*); static Fl_Menu_Item menu_revp1[]; public: WidgetPDial *revp0; diff --git a/plugins/zynaddsubfx/src/UI/MasterUI.cc b/plugins/zynaddsubfx/src/UI/MasterUI.cc index 2b91bd54e..bd8545239 100644 --- a/plugins/zynaddsubfx/src/UI/MasterUI.cc +++ b/plugins/zynaddsubfx/src/UI/MasterUI.cc @@ -214,7 +214,8 @@ labelsize(10); align(FL_ALIGN_TOP); value(master->Psysefxsend[neff1][neff2]); -char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1);this->label(strdup(tmp)); +char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1); +this->copy_label(tmp); } SysEffSend::~SysEffSend() { @@ -380,7 +381,7 @@ Fl_Group* Panellistitem::make_window() { partenabled->labelsize(13); partenabled->callback((Fl_Callback*)cb_partenabled); partenabled->align(Fl_Align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE)); - char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp)); + char tmp[10];snprintf(tmp,10,"%d",npart+1);o->copy_label(tmp); o->value(master->part[npart]->Penabled); } // Fl_Check_Button* partenabled panellistitem->end(); @@ -1986,7 +1987,7 @@ General Public License for details."); partenabled->labelsize(13); partenabled->callback((Fl_Callback*)cb_partenabled1); partenabled->align(Fl_Align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE)); - //char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp)); + //char tmp[10];snprintf(tmp,10,"%d",npart+1);o->copy_label(tmp); o->value(master->part[npart]->Penabled); } // Fl_Check_Button* partenabled { VirKeys* o = virkeys = new VirKeys(5, 215, 590, 80, "Keyboard"); @@ -2338,19 +2339,23 @@ simplerefresh(); MasterUI::~MasterUI() { masterwindow->hide(); -delete (masterwindow); +delete masterwindow; +simplemasterwindow->hide(); +delete simplemasterwindow; aboutwindow->hide(); -delete (aboutwindow); +delete aboutwindow; syseffsendwindow->hide(); -delete(syseffsendwindow); +delete syseffsendwindow; -delete (virkeyboard); -delete (microtonalui); -delete (bankui); -delete (configui); -delete (sequi); +delete virkeyboard; +delete microtonalui; +delete bankui; +delete configui; +delete sequi; -delete(presetsui); +delete presetsui; +delete panelwindow; +delete selectuiwindow; } void MasterUI::showUI() { diff --git a/plugins/zynaddsubfx/src/UI/MasterUI.fl b/plugins/zynaddsubfx/src/UI/MasterUI.fl index b0c77d790..a844def6c 100644 --- a/plugins/zynaddsubfx/src/UI/MasterUI.fl +++ b/plugins/zynaddsubfx/src/UI/MasterUI.fl @@ -1,9 +1,8 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0109 +version 1.0107 header_name {.h} code_name {.cc} -decl {//Copyright (c) 2002-2009 Nasca Octavian Paul} {selected -} +decl {//Copyright (c) 2002-2009 Nasca Octavian Paul} {} decl {//License: GNU GPL version 2 or later} {} @@ -275,7 +274,8 @@ labelsize(10); align(FL_ALIGN_TOP); value(master->Psysefxsend[neff1][neff2]); -char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1);this->label(strdup(tmp));} {} +char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1); +this->copy_label(tmp);} {} } Function {~SysEffSend()} {} { code {hide();} {} @@ -344,7 +344,7 @@ bankui->show();} xywh {15 235 40 20} box PLASTIC_UP_BOX labelsize 10 } Fl_Choice partrcv { - callback {master->part[npart]->Prcvchn=(int) o->value();} open + callback {master->part[npart]->Prcvchn=(int) o->value();} tooltip {receive from Midi channel} xywh {10 213 50 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 code0 {char nrstr[10]; for(int i=0;iadd(nrstr); else o->add("Dr10");};} code1 {o->value(master->part[npart]->Prcvchn);} @@ -367,7 +367,7 @@ if ((int) o->value()==0) panellistitemgroup->deactivate(); o->redraw();} private xywh {5 0 45 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 24 - code0 {char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp));} + code0 {char tmp[10];snprintf(tmp,10,"%d",npart+1);o->copy_label(tmp);} code1 {o->value(master->part[npart]->Penabled);} } } @@ -386,8 +386,7 @@ make_window(); panellistitem->show(); end();} {} } - Function {refresh()} {open - } { + Function {refresh()} {} { code {partenabled->value(master->part[npart]->Penabled); if (master->part[npart]->Penabled!=0) panellistitemgroup->activate(); else panellistitemgroup->deactivate(); @@ -415,7 +414,8 @@ panellistitemgroup->redraw();} {} } class MasterUI {} { - Function {make_window()} {} { + Function {make_window()} {selected + } { Fl_Window masterwindow { label zynaddsubfx callback {\#ifdef VSTAUDIOOUT @@ -426,7 +426,7 @@ if (fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) { *exitprogram=1; }; \#endif} - xywh {31 206 390 465} type Double xclass zynaddsubfx visible + xywh {31 206 390 465} type Double hide xclass zynaddsubfx } { Fl_Menu_Bar mastermenu { xywh {-5 0 690 25} @@ -1043,18 +1043,18 @@ GNU General Public License for details.} label {ZynAddSubFX Panel} xywh {89 59 630 635} type Double hide } { - Fl_Scroll {} {open + Fl_Scroll {} { xywh {0 5 570 310} type HORIZONTAL box THIN_UP_BOX } { - Fl_Pack {} {open + Fl_Pack {} { xywh {5 10 560 285} type HORIZONTAL code0 {for (int i=0;iinit(master,i,bankui);}} } {} } - Fl_Scroll {} {open + Fl_Scroll {} { xywh {0 320 570 310} type HORIZONTAL box THIN_UP_BOX } { - Fl_Pack {} {open + Fl_Pack {} { xywh {5 325 560 285} type HORIZONTAL code0 {for (int i=NUM_MIDI_PARTS/2;iinit(master,i,bankui);}} } {} @@ -1288,7 +1288,7 @@ if ((int) o->value()==0) simplelistitemgroup->deactivate(); o->redraw();} private xywh {250 40 85 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 24 - code0 {//char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp));} + code0 {//char tmp[10];snprintf(tmp,10,"%d",npart+1);o->copy_label(tmp);} code1 {o->value(master->part[npart]->Penabled);} } Fl_Box virkeys { @@ -1643,19 +1643,23 @@ simplerefresh();} {} } Function {~MasterUI()} {} { code {masterwindow->hide(); -delete (masterwindow); +delete masterwindow; +simplemasterwindow->hide(); +delete simplemasterwindow; aboutwindow->hide(); -delete (aboutwindow); +delete aboutwindow; syseffsendwindow->hide(); -delete(syseffsendwindow); +delete syseffsendwindow; -delete (virkeyboard); -delete (microtonalui); -delete (bankui); -delete (configui); -delete (sequi); +delete virkeyboard; +delete microtonalui; +delete bankui; +delete configui; +delete sequi; -delete(presetsui);} {} +delete presetsui; +delete panelwindow; +delete selectuiwindow;} {} } Function {showUI()} {} { code {switch (config.cfg.UserInterfaceMode){ diff --git a/plugins/zynaddsubfx/src/UI/PartUI.cc b/plugins/zynaddsubfx/src/UI/PartUI.cc index 986b11995..f25571165 100644 --- a/plugins/zynaddsubfx/src/UI/PartUI.cc +++ b/plugins/zynaddsubfx/src/UI/PartUI.cc @@ -38,7 +38,7 @@ Fl_Group* PartSysEffSend::make_window() { o->when(FL_WHEN_CHANGED); o->size(25,25); o->value(master->Psysefxvol[neff][npart]); - char tmp[10];snprintf(tmp,10,"%d",neff+1);o->label(strdup(tmp)); + char tmp[10];snprintf(tmp,10,"%d",neff+1);o->copy_label(tmp); } // WidgetPDial* o syseffsend->end(); } // Fl_Group* syseffsend @@ -333,7 +333,7 @@ Fl_Group* PartKitItem::make_window() { enabledcheck->labelsize(13); enabledcheck->callback((Fl_Callback*)cb_enabledcheck); enabledcheck->align(Fl_Align(FL_ALIGN_LEFT)); - snprintf(label,10,"%d",n+1);o->label(strdup(label)); + snprintf(label,10,"%d",n+1);o->label(label); o->value(part->kit[n].Penabled); if (n==0) o->deactivate(); } // Fl_Check_Button* enabledcheck diff --git a/plugins/zynaddsubfx/src/UI/PartUI.fl b/plugins/zynaddsubfx/src/UI/PartUI.fl index 05fe5151a..fcf15f0e4 100644 --- a/plugins/zynaddsubfx/src/UI/PartUI.fl +++ b/plugins/zynaddsubfx/src/UI/PartUI.fl @@ -56,7 +56,7 @@ class PartSysEffSend {: {public Fl_Group} xywh {0 0 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 align 130 maximum 127 step 1 code0 {o->size(25,25);} code1 {o->value(master->Psysefxvol[neff][npart]);} - code2 {char tmp[10];snprintf(tmp,10,"%d",neff+1);o->label(strdup(tmp));} + code2 {char tmp[10];snprintf(tmp,10,"%d",neff+1);o->copy_label(tmp);} class WidgetPDial } } @@ -212,7 +212,7 @@ o->redraw(); partui->showparameters(n,-1);//use to delete the ui, if it is not to item 0 } else o->value(1);} private xywh {30 0 20 15} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 4 - code0 {snprintf(label,10,"%d",n+1);o->label(strdup(label));} + code0 {snprintf(label,10,"%d",n+1);o->label(label);} code1 {o->value(part->kit[n].Penabled);} code2 {if (n==0) o->deactivate();} } @@ -590,7 +590,7 @@ part->ctl.portamento.updowntimestretch=x;} } Fl_Dial proptb { label {Prp.Dpth} - callback {part->ctl.portamento.propDepth=(int) o->value();} selected + callback {part->ctl.portamento.propDepth=(int) o->value();} tooltip {The difference from nonproportinal portamento} xywh {405 60 25 25} labelsize 9 maximum 127 step 1 code0 {o->value(part->ctl.portamento.propDepth);} class WidgetPDial @@ -841,7 +841,7 @@ if (part->Pkitmode==0) { } } Fl_Window instrumenteditwindow { - label {Instrument Edit} + label {Instrument Edit} selected xywh {182 214 395 360} type Double hide } { Fl_Group {} { diff --git a/plugins/zynaddsubfx/src/UI/VirKeyboard.cc b/plugins/zynaddsubfx/src/UI/VirKeyboard.cc index 49491ff62..25df926ad 100644 --- a/plugins/zynaddsubfx/src/UI/VirKeyboard.cc +++ b/plugins/zynaddsubfx/src/UI/VirKeyboard.cc @@ -486,6 +486,10 @@ midictl=75; make_window(); } +VirKeyboard::~VirKeyboard() { + delete virkeyboardwindow; +} + void VirKeyboard::show() { virkeyboardwindow->show(); } diff --git a/plugins/zynaddsubfx/src/UI/VirKeyboard.fl b/plugins/zynaddsubfx/src/UI/VirKeyboard.fl index 0b83b5b56..37fe43e5c 100644 --- a/plugins/zynaddsubfx/src/UI/VirKeyboard.fl +++ b/plugins/zynaddsubfx/src/UI/VirKeyboard.fl @@ -41,9 +41,9 @@ decl {const int keysoct1qwertz[]={'q','2','w','3','e','r','5','t','6','z','7','u decl {const int keysoct2qwertz[]={'y','s','x','d','c','v','g','b','h','n','j','m',',','l','.',246,'-',0};} {} -decl {const int keysoct1az[]={'a',233,'z','\\"','e','r','(','t','-','y',232,'u','i',231,'o',224,'p',65106,'=','$',0};} {} +decl {const int keysoct1az[]={'a',233,'z','\\"','e','r','(','t','-','y',232,'u','i',231,'o',224,'p',65106,'=','$',0};} {} -decl {const int keysoct2az[]={'w','s','x','d','c','v','g','b','h','n','j',',',';','l',':','m','!',0};} {} +decl {const int keysoct2az[]={'w','s','x','d','c','v','g','b','h','n','j',',',';','l',':','m','!',0};} {} class VirKeys {: {public Fl_Box} } { @@ -184,8 +184,7 @@ if ((event==FL_KEYDOWN)||(event==FL_KEYUP)){ return(1);} {} } - Function {presskey(int nk,int exclusive,int type)} {selected - } { + Function {presskey(int nk,int exclusive,int type)} {} { code {//Exclusive means that multiple keys can be pressed at once //when the user uses the shift key if (nk>=N_OCT*12) return; @@ -410,6 +409,10 @@ virkeys->take_focus();} open midictl=75; make_window();} {} } + Function {~VirKeyboard()} {} { + code {delete virkeyboardwindow;} {selected + } + } Function {show()} {} { code {virkeyboardwindow->show();} {} } diff --git a/plugins/zynaddsubfx/src/UI/VirKeyboard.h b/plugins/zynaddsubfx/src/UI/VirKeyboard.h index bfcec5b53..7d7e7b95e 100644 --- a/plugins/zynaddsubfx/src/UI/VirKeyboard.h +++ b/plugins/zynaddsubfx/src/UI/VirKeyboard.h @@ -80,6 +80,7 @@ private: static void cb_partrcv(Fl_Choice*, void*); public: VirKeyboard(Master *master_); + ~VirKeyboard(); void show(); void relaseallkeys(); private: diff --git a/plugins/zynaddsubfx/src/UI/WidgetPDial.cc b/plugins/zynaddsubfx/src/UI/WidgetPDial.cc index bd1d43653..dde9e8854 100644 --- a/plugins/zynaddsubfx/src/UI/WidgetPDial.cc +++ b/plugins/zynaddsubfx/src/UI/WidgetPDial.cc @@ -33,7 +33,8 @@ textmode=false; } void TipWin::setText(const char * c) { - strcpy(text,c); + strncpy(text, c, max_tooltip_len-1); +text[max_tooltip_len-1] = 0; textmode=true; // Recalc size of window fl_font(labelfont(), labelsize()); diff --git a/plugins/zynaddsubfx/src/UI/WidgetPDial.fl b/plugins/zynaddsubfx/src/UI/WidgetPDial.fl index 0fed5b571..f68a96ec3 100644 --- a/plugins/zynaddsubfx/src/UI/WidgetPDial.fl +++ b/plugins/zynaddsubfx/src/UI/WidgetPDial.fl @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0109 +version 1.0107 header_name {.h} code_name {.cc} decl {//Copyright (c) 2003-2005 Nasca Octavian Paul} {} @@ -61,7 +61,8 @@ textmode=false; } Function {setText(const char * c)} {return_type void } { - code {strcpy(text,c); + code {strncpy(text, c, max_tooltip_len-1); +text[max_tooltip_len-1] = 0; textmode=true; // Recalc size of window fl_font(labelfont(), labelsize()); @@ -84,7 +85,9 @@ textmode=true; } decl {char tip[40];} {} decl {bool textmode;} {} - decl {char text[400];//bad stuff will happen if too much is put in this (perhaps dynamically allocate?)} {} + decl {enum { max_tooltip_len = 400 };} {selected + } + decl {char text[max_tooltip_len];} {} } class WidgetPDial {: {public Fl_Dial} @@ -153,8 +156,7 @@ case FL_RELEASE: return(1); break; }; -return(0);} {selected - } +return(0);} {} } Function {drawgradient(int cx,int cy,int sx,double m1,double m2)} {return_type void } { diff --git a/plugins/zynaddsubfx/src/UI/WidgetPDial.h b/plugins/zynaddsubfx/src/UI/WidgetPDial.h index 7f9759c1e..e81f17e18 100644 --- a/plugins/zynaddsubfx/src/UI/WidgetPDial.h +++ b/plugins/zynaddsubfx/src/UI/WidgetPDial.h @@ -22,7 +22,8 @@ public: private: char tip[40]; bool textmode; - char text[400]; //bad stuff will happen if too much is put in this (perhaps dynamically allocate?) + enum { max_tooltip_len = 400 }; + char text[max_tooltip_len]; }; class WidgetPDial : public Fl_Dial { diff --git a/plugins/zynaddsubfx/src/globals.h b/plugins/zynaddsubfx/src/globals.h index f13da7d95..7c0717168 100644 --- a/plugins/zynaddsubfx/src/globals.h +++ b/plugins/zynaddsubfx/src/globals.h @@ -29,10 +29,10 @@ #define REALTYPE float struct FFTFREQS { - REALTYPE *s,*c;//sine and cosine components + REALTYPE *s, *c; //sine and cosine components }; -extern void newFFTFREQS(FFTFREQS *f,int size); +extern void newFFTFREQS(FFTFREQS *f, int size); extern void deleteFFTFREQS(FFTFREQS *f); /**Sampling rate*/ @@ -131,7 +131,7 @@ extern int OSCIL_SIZE; * The maximum number of bands of the equaliser */ #define MAX_EQ_BANDS 8 -#if (MAX_EQ_BANDS>=20) +#if (MAX_EQ_BANDS >= 20) #error "Too many EQ bands in globals.h" #endif @@ -162,46 +162,67 @@ extern int OSCIL_SIZE; /* * How the amplitude threshold is computed */ -#define ABOVE_AMPLITUDE_THRESHOLD(a,b) ( ( 2.0*fabs( (b) - (a) ) / \ - ( fabs( (b) + (a) + 0.0000000001) ) ) > AMPLITUDE_INTERPOLATION_THRESHOLD ) +#define ABOVE_AMPLITUDE_THRESHOLD(a, b) ((2.0 * fabs((b) - (a)) \ + / (fabs((b) + (a) + 0.0000000001))) > \ + AMPLITUDE_INTERPOLATION_THRESHOLD) /* * Interpolate Amplitude */ -#define INTERPOLATE_AMPLITUDE(a,b,x,size) ( (a) + \ - ( (b) - (a) ) * (REALTYPE)(x) / (REALTYPE) (size) ) +#define INTERPOLATE_AMPLITUDE(a, b, x, size) ((a) \ + + ((b) \ + - (a)) * (REALTYPE)(x) \ + / (REALTYPE) (size)) /* * dB */ -#define dB2rap(dB) ((exp((dB)*LOG_10/20.0))) -#define rap2dB(rap) ((20*log(rap)/LOG_10)) +#define dB2rap(dB) ((exp((dB) * LOG_10 / 20.0))) +#define rap2dB(rap) ((20 * log(rap) / LOG_10)) /* * The random generator (0.0..1.0) */ -#define RND (rand()/(RAND_MAX+1.0)) +#define RND (rand() / (RAND_MAX + 1.0)) -#define ZERO(data,size) {char *data_=(char *) data;for (int i=0;i0) ? ( (int)(f) ) :( (int)(f-1.0) )); +#define F2I(f, i) (i) = ((f > 0) ? ((int)(f)) : ((int)(f - 1.0))); #endif