diff options
author | Werner Schweer <ws.seh.de> | 2006-10-27 13:58:10 +0000 |
---|---|---|
committer | Werner Schweer <ws.seh.de> | 2006-10-27 13:58:10 +0000 |
commit | 60121112a52f6f3ef8a907b529af40291798e927 (patch) | |
tree | 60508d2690feafce8e75e0d687df2a44b42403cd | |
parent | 607987b47389a0ad2b0cb5871d5efe22a0f41590 (diff) |
added zyaddsubfx
125 files changed, 32997 insertions, 3 deletions
diff --git a/muse/CMakeLists.txt b/muse/CMakeLists.txt index 60473bf0..a0394030 100644 --- a/muse/CMakeLists.txt +++ b/muse/CMakeLists.txt @@ -30,7 +30,7 @@ set(CMAKE_BUILD_TYPE debug) # set(CMAKE_BUILD_TYPE release) # for debugging the make system uncomment next line: -#set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_CXX_FLAGS "-Wall -Wextra -Winvalid-pch -fno-exceptions") set(CMAKE_CXX_FLAGS_RELEASE "-O2") @@ -50,9 +50,10 @@ SET(MusE_INSTALL_NAME "muse-1.0pre1") include ( ${PROJECT_SOURCE_DIR}/cmake/UsePkgConfig1.cmake ) -option ( ENABLE_DSSI "enable Disposable Soft Synth Interface" ON) +option ( ENABLE_DSSI "enable Disposable Soft Synth Interface" ON) option ( ENABLE_VST "enable VST/win support" OFF) -option ( ENABLE_FLUID "enable fluidsynth softsynth plugins" ON) +option ( ENABLE_FLUID "enable fluidsynth softsynth plugins" ON) +option ( ENABLE_ZYNADDSUBFX "enable zyaddsubfx softsynth plugin" ON) set(QT_MIN_VERSION "4.2.0") set(QT_USE_QTXML TRUE) @@ -116,6 +117,27 @@ endif (NOT ALSA_INCDIR) endif (APPLE) ## +## find packages for zyaddsubfx +## +## PKGCONFIG (fftw3 + +if (ENABLE_ZYNADDSUBFX) + find_path( FLTK_FLUID_EXECUTABLE fluid ) + find_path( FLTK_CONFIG_PATH fltk-config ) +# set (FLTK_LIBRARIES $FLTK_CONFIG_PATH) +# FLTK_INCLUDE_DIR +# FLTK_FOUND +# +# if (NOT FLTK_FOUND) +# message(FATAL_ERROR "fltk toolkit not found, zynaddsubfx not build") +# set(ENABLE_ZYNADDSUBFX OFF) +# else (NOT FLTK_FOUND) +# message("fltk toolkit found") +# endif (NOT FLTK_FOUND) +endif (ENABLE_ZYNADDSUBFX) + + +## ## find sndfile >= 1.0.0 ## diff --git a/muse/ChangeLog b/muse/ChangeLog index 133527ea..b3f2b6e5 100644 --- a/muse/ChangeLog +++ b/muse/ChangeLog @@ -1,3 +1,5 @@ +27.10 (ws) + - added a MESS port of the Zynaddsubfx software synthesizer 25.10 (ws) - make default path for midi- and wave import configurable 23.10 (ws) diff --git a/muse/synti/CMakeLists.txt b/muse/synti/CMakeLists.txt index 09d2f1b3..30a27361 100644 --- a/muse/synti/CMakeLists.txt +++ b/muse/synti/CMakeLists.txt @@ -29,6 +29,10 @@ include_directories( set (SubDirs libsynti s1 organ deicsonze simpledrums vam mus) +if (ENABLE_ZYNADDSUBFX) + set (SubDirs ${SubDirs} zynaddsubfx) +endif (ENABLE_ZYNADDSUBFX) + if (ENABLE_FLUID) set (SubDirs ${SubDirs} fluid fluidsynth ) endif (ENABLE_FLUID) diff --git a/muse/synti/zynaddsubfx/.files, b/muse/synti/zynaddsubfx/.files, new file mode 100644 index 00000000..88761921 --- /dev/null +++ b/muse/synti/zynaddsubfx/.files, @@ -0,0 +1,152 @@ +. +./UI +./UI/WidgetPDial.fl +./UI/.qped +./UI/MicrotonalUI.fl +./UI/LFOUI.fl +./UI/MasterUI.fl +./UI/EnvelopeUI.fl +./UI/ResonanceUI.fl +./UI/OscilGenUI.fl +./UI/PADnoteUI.fl +./UI/ConfigUI.fl +./UI/SeqUI.fl +./UI/PresetsUI.fl +./UI/SUBnoteUI.fl +./UI/PartUI.fl +./UI/VirKeyboard.fl +./UI/FilterUI.fl +./UI/ADnoteUI.fl +./UI/EffUI.fl +./UI/BankUI.fl +./DSP +./DSP/.qped +./DSP/Filter.C +./DSP/Filter.h +./DSP/.Filter_.h, +./DSP/FormantFilter.C +./DSP/FormantFilter.h +./DSP/SVFilter.C +./DSP/SVFilter.h +./DSP/Filter_.h +./DSP/FFTwrapper.C +./DSP/FFTwrapper.h +./DSP/AnalogFilter.C +./DSP/AnalogFilter.h +./Seq +./Seq/MIDIFile.C +./Seq/MIDIFile.h +./Seq/.qped +./Seq/MIDIEvents.C +./Seq/MIDIEvents.h +./Seq/Sequencer.C +./Seq/Sequencer.h +./Misc +./Misc/Bank.C +./Misc/Bank.h +./Misc/Dump.C +./Misc/Dump.h +./Misc/.qped +./Misc/Microtonal.C +./Misc/Microtonal.h +./Misc/Config.C +./Misc/Config.h +./Misc/Master.C +./Misc/Master.h +./Misc/Part.C +./Misc/Part.h +./Misc/Util.C +./Misc/Util.h +./Misc/XMLwrapper.C +./Misc/XMLwrapper.h +./Misc/.Master.C, +./Misc/.Master.h, +./.qped +./Input +./Input/.qped +./Input/.MidiIn.h, +./Input/MidiIn.C +./Input/MidiIn.h +./Input/ALSAMidiIn.C +./Input/ALSAMidiIn.h +./Input/OSSMidiIn.C +./Input/OSSMidiIn.h +./Input/NULLMidiIn.C +./Input/NULLMidiIn.h +./Input/WINMidiIn.C +./Input/WINMidiIn.h +./Synth +./Synth/Envelope.C +./Synth/Envelope.h +./Synth/.qped +./Synth/LFO.C +./Synth/LFO.h +./Synth/SUBnote.C +./Synth/SUBnote.h +./Synth/OscilGen.C +./Synth/OscilGen.h +./Synth/PADnote.C +./Synth/PADnote.h +./Synth/ADnote.C +./Synth/ADnote.h +./Synth/Resonance.C +./Synth/Resonance.h +./files +./Params +./Params/.qped +./Params/Presets.C +./Params/Presets.h +./Params/FilterParams.C +./Params/FilterParams.h +./Params/PresetsStore.C +./Params/PresetsStore.h +./Params/Controller.C +./Params/Controller.h +./Params/SUBnoteParameters.C +./Params/SUBnoteParameters.h +./Params/LFOParams.C +./Params/LFOParams.h +./Params/.Presets.h, +./Params/EnvelopeParams.C +./Params/EnvelopeParams.h +./Params/ADnoteParameters.C +./Params/ADnoteParameters.h +./Params/PADnoteParameters.C +./Params/PADnoteParameters.h +./Output +./Output/Recorder.C +./Output/Recorder.h +./.zynaddsubfx.cpp, +./.launch_zynaddsubfx.bat, +./CMakeLists.txt +./main.cpp +./.main.cpp, +./Effects +./Effects/Distorsion.C +./Effects/Distorsion.h +./Effects/EQ.C +./Effects/EQ.h +./Effects/.Effect.h, +./Effects/Echo.C +./Effects/Echo.h +./Effects/Alienwah.C +./Effects/Alienwah.h +./Effects/.qped +./Effects/Chorus.C +./Effects/Chorus.h +./Effects/EffectLFO.C +./Effects/EffectLFO.h +./Effects/EffectMgr.C +./Effects/EffectMgr.h +./Effects/DynamicFilter.C +./Effects/DynamicFilter.h +./Effects/Phaser.C +./Effects/Phaser.h +./Effects/Reverb.C +./Effects/Reverb.h +./Effects/Effect.C +./Effects/Effect.h +./globals.h +./.Makefile.inc, +./.CMakeLists.txt, +./zynaddsubfx_icon.svg diff --git a/muse/synti/zynaddsubfx/CMakeLists.txt b/muse/synti/zynaddsubfx/CMakeLists.txt new file mode 100644 index 00000000..a0f095a2 --- /dev/null +++ b/muse/synti/zynaddsubfx/CMakeLists.txt @@ -0,0 +1,126 @@ +#============================================================================= +# MusE +# Linux Music Editor +# $Id:$ +# +# Copyright (C) 2006 by Werner Schweer and others +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#============================================================================= + +SET(FLTK_FLUID_EXECUTABLE "/usr/bin/fluid") + +include_directories( + BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/UI + BEFORE ${CMAKE_CURRENT_BINARY_DIR} + ) + +FLTK_WRAP_UI ( fltk_ui + UI/ADnoteUI.fl + UI/BankUI.fl + UI/ConfigUI.fl + UI/EffUI.fl + UI/EnvelopeUI.fl + UI/FilterUI.fl + UI/LFOUI.fl + UI/MasterUI.fl + UI/MicrotonalUI.fl + UI/OscilGenUI.fl + UI/PADnoteUI.fl + UI/PartUI.fl + UI/PresetsUI.fl + UI/ResonanceUI.fl + UI/SUBnoteUI.fl + UI/SeqUI.fl + UI/VirKeyboard.fl + UI/WidgetPDial.fl + ) + +# ${fltk_ui_FLTK_UI_SRCS} +# Output/JACKaudiooutput.C +# Input/MidiIn.C + +add_library ( zynaddsubfx SHARED + ${fltk_ui_FLTK_UI_SRCS} + DSP/AnalogFilter.C + DSP/FFTwrapper.C + DSP/Filter.C + DSP/FormantFilter.C + DSP/SVFilter.C + Effects/Alienwah.C + Effects/Chorus.C + Effects/Distorsion.C + Effects/DynamicFilter.C + Effects/EQ.C + Effects/Echo.C + Effects/Effect.C + Effects/EffectLFO.C + Effects/EffectMgr.C + Effects/Phaser.C + Effects/Reverb.C + Input/ALSAMidiIn.C + Input/NULLMidiIn.C + Output/Recorder.C + Misc/Bank.C + Misc/Config.C + Misc/Dump.C + Misc/Master.C + Misc/Microtonal.C + Misc/Part.C + Misc/Util.C + Misc/XMLwrapper.C + Seq/MIDIEvents.C + Seq/MIDIFile.C + Seq/Sequencer.C + Params/ADnoteParameters.C + Params/Controller.C + Params/EnvelopeParams.C + Params/FilterParams.C + Params/LFOParams.C + Params/PADnoteParameters.C + Params/Presets.C + Params/PresetsStore.C + Params/SUBnoteParameters.C + Synth/ADnote.C + Synth/Envelope.C + Synth/LFO.C + Synth/OscilGen.C + Synth/PADnote.C + Synth/Resonance.C + Synth/SUBnote.C + main.cpp + ) + +# - tell cmake to name target zynaddsubfx.so instead of +# libzynaddsubfx.so +# + +set_target_properties ( zynaddsubfx + PROPERTIES PREFIX "" + COMPILE_FLAGS "-fvisibility=hidden -DOS_LINUX -DNONEMIDIIN -DFFTW_VERSION_3 -DASM_F2I_YES -DNONEAUDIOOUT" + ) + +target_link_libraries( zynaddsubfx + synti + jack + asound + pthread + fftw3 + mxml + m + z + fltk + ) + +install_targets ( /${CMAKE_INSTALL_LIBDIR}/${MusE_INSTALL_NAME}/synthi/ zynaddsubfx ) + diff --git a/muse/synti/zynaddsubfx/DSP/AnalogFilter.C b/muse/synti/zynaddsubfx/DSP/AnalogFilter.C new file mode 100644 index 00000000..5e461a0b --- /dev/null +++ b/muse/synti/zynaddsubfx/DSP/AnalogFilter.C @@ -0,0 +1,358 @@ +/* + ZynAddSubFX - a software synthesizer + + AnalogFilter.C - Several analog filters (lowpass, highpass...) + 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) 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 <math.h> +#include <stdio.h> +#include "AnalogFilter.h" + +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; + cleanup(); + 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;i<MAX_FILTER_STAGES+1;i++){ + x[i].c1=0.0;x[i].c2=0.0; + y[i].c1=0.0;y[i].c2=0.0; + oldx[i]=x[i]; + oldy[i]=y[i]; + }; + needsinterpolation=0; +}; + +void AnalogFilter::computefiltercoefs(){ + REALTYPE tmp; + REALTYPE omega,sn,cs,alpha,beta; + int zerocoefs=0;//this is used if the freq is too high + + //do not allow frequencies bigger than samplerate/2 + 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)); + }; + + //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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + + 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; + + 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; + 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; + + oldabovenq=abovenq;abovenq=frequency>(SAMPLE_RATE/2-500.0); + + 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<MAX_FILTER_STAGES+1;i++){ + oldx[i]=x[i]; + oldy[i]=y[i]; + }; + if (firsttime==0) needsinterpolation=1; + }; + freq=frequency; + computefiltercoefs(); + firsttime=0; + +}; + +void AnalogFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_){ + q=q_; + setfreq(frequency); +}; + +void AnalogFilter::setq(REALTYPE q_){ + q=q_; + computefiltercoefs(); +}; + +void AnalogFilter::settype(int type_){ + type=type_; + computefiltercoefs(); +}; + +void AnalogFilter::setgain(REALTYPE dBgain){ + gain=dB2rap(dBgain); + computefiltercoefs(); +}; + +void AnalogFilter::setstages(int 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){ + int i; + REALTYPE y0; + if (order==1) {//First order filter + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + y0=smp[i]*c[0]+x.c1*c[1]+y.c1*d[1]; + y.c1=y0; + x.c1=smp[i]; + //output + smp[i]=y0; + }; + }; + if (order==2) {//Second order filter + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + y0=smp[i]*c[0]+x.c1*c[1]+x.c2*c[2]+y.c1*d[1]+y.c2*d[2]; + y.c2=y.c1; + y.c1=y0; + x.c2=x.c1; + x.c1=smp[i]; + //output + smp[i]=y0; + }; + }; +}; +void AnalogFilter::filterout(REALTYPE *smp){ + REALTYPE *ismp=NULL;//used if it needs interpolation + int i; + if (needsinterpolation!=0){ + ismp=new REALTYPE[SOUND_BUFFER_SIZE]; + for (i=0;i<SOUND_BUFFER_SIZE;i++) ismp[i]=smp[i]; + for (i=0;i<stages+1;i++) singlefilterout(ismp,oldx[i],oldy[i],oldc,oldd); + }; + + for (i=0;i<stages+1;i++) singlefilterout(smp,x[i],y[i],c,d); + + if (needsinterpolation!=0){ + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + REALTYPE x=i/(REALTYPE) SOUND_BUFFER_SIZE; + smp[i]=ismp[i]*(1.0-x)+smp[i]*x; + }; + delete (ismp); + needsinterpolation=0; + }; + + for (i=0;i<SOUND_BUFFER_SIZE;i++) smp[i]*=outgain; +}; + +REALTYPE AnalogFilter::H(REALTYPE freq){ + 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); + return(pow(h,(stages+1.0)/2.0)); +}; + diff --git a/muse/synti/zynaddsubfx/DSP/AnalogFilter.h b/muse/synti/zynaddsubfx/DSP/AnalogFilter.h new file mode 100644 index 00000000..2e9fe68b --- /dev/null +++ b/muse/synti/zynaddsubfx/DSP/AnalogFilter.h @@ -0,0 +1,72 @@ +/* + ZynAddSubFX - a software synthesizer + + Analog Filter.h - Several analog filters (lowpass, highpass...) + 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) 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 ANALOG_FILTER_H +#define ANALOG_FILTER_H + +#include "../globals.h" +#include "Filter_.h" +class AnalogFilter:public Filter_{ + public: + AnalogFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages); + ~AnalogFilter(); + void filterout(REALTYPE *smp); + void setfreq(REALTYPE frequency); + void setfreq_and_q(REALTYPE frequency,REALTYPE q_); + void setq(REALTYPE q_); + + void settype(int type_); + void setgain(REALTYPE dBgain); + void setstages(int stages_); + void cleanup(); + + REALTYPE H(REALTYPE freq);//Obtains the response for a given frequency + + private: + struct fstage{ + REALTYPE c1,c2; + } x[MAX_FILTER_STAGES+1],y[MAX_FILTER_STAGES+1], + oldx[MAX_FILTER_STAGES+1],oldy[MAX_FILTER_STAGES+1]; + + 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) + + 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 xd[3],yd[3];//used if the filter is applied more times + int needsinterpolation,firsttime; + 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) +}; + + +#endif + diff --git a/muse/synti/zynaddsubfx/DSP/FFTwrapper.C b/muse/synti/zynaddsubfx/DSP/FFTwrapper.C new file mode 100644 index 00000000..7c67e631 --- /dev/null +++ b/muse/synti/zynaddsubfx/DSP/FFTwrapper.C @@ -0,0 +1,99 @@ +/* + ZynAddSubFX - a software synthesizer + + FFTwrapper.c - A wrapper for Fast Fourier Transforms + 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) 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 <math.h> +#include "FFTwrapper.h" + +FFTwrapper::FFTwrapper(int 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); +#else + planfftw=fftw_plan_r2r_1d(fftsize,tmpfftdata1,tmpfftdata1,FFTW_R2HC,FFTW_ESTIMATE); + planfftw_inv=fftw_plan_r2r_1d(fftsize,tmpfftdata2,tmpfftdata2,FFTW_HC2R,FFTW_ESTIMATE); +#endif +}; + +FFTwrapper::~FFTwrapper(){ +#ifdef FFTW_VERSION_2 + rfftw_destroy_plan(planfftw); + rfftw_destroy_plan(planfftw_inv); +#else + fftw_destroy_plan(planfftw); + fftw_destroy_plan(planfftw_inv); +#endif + + delete [] tmpfftdata1; + delete [] tmpfftdata2; +}; + +/* + * do the Fast Fourier Transform + */ +void FFTwrapper::smps2freqs(REALTYPE *smps,FFTFREQS freqs){ +#ifdef FFTW_VERSION_2 + for (int i=0;i<fftsize;i++) tmpfftdata1[i]=smps[i]; + rfftw_one(planfftw,tmpfftdata1,tmpfftdata2); + for (int i=0;i<fftsize/2;i++) { + freqs.c[i]=tmpfftdata2[i]; + if (i!=0) freqs.s[i]=tmpfftdata2[fftsize-i]; + }; +#else + for (int i=0;i<fftsize;i++) tmpfftdata1[i]=smps[i]; + fftw_execute(planfftw); + for (int i=0;i<fftsize/2;i++) { + freqs.c[i]=tmpfftdata1[i]; + if (i!=0) freqs.s[i]=tmpfftdata1[fftsize-i]; + }; +#endif + tmpfftdata2[fftsize/2]=0.0; +}; + +/* + * do the Inverse Fast Fourier Transform + */ +void FFTwrapper::freqs2smps(FFTFREQS freqs,REALTYPE *smps){ + tmpfftdata2[fftsize/2]=0.0; +#ifdef FFTW_VERSION_2 + for (int i=0;i<fftsize/2;i++) { + tmpfftdata1[i]=freqs.c[i]; + if (i!=0) tmpfftdata1[fftsize-i]=freqs.s[i]; + }; + rfftw_one(planfftw_inv,tmpfftdata1,tmpfftdata2); + for (int i=0;i<fftsize;i++) smps[i]=tmpfftdata2[i]; +#else + for (int i=0;i<fftsize/2;i++) { + tmpfftdata2[i]=freqs.c[i]; + if (i!=0) tmpfftdata2[fftsize-i]=freqs.s[i]; + }; + fftw_execute(planfftw_inv); + for (int i=0;i<fftsize;i++) smps[i]=tmpfftdata2[i]; +#endif + +}; + + + + diff --git a/muse/synti/zynaddsubfx/DSP/FFTwrapper.h b/muse/synti/zynaddsubfx/DSP/FFTwrapper.h new file mode 100644 index 00000000..df8cad7a --- /dev/null +++ b/muse/synti/zynaddsubfx/DSP/FFTwrapper.h @@ -0,0 +1,59 @@ +/* + ZynAddSubFX - a software synthesizer + + FFTwrapper.h - A wrapper for Fast Fourier Transforms + 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) 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 FFT_WRAPPER_H +#define FFT_WRAPPER_H + +#include "../globals.h" + +#ifdef FFTW_VERSION_2 + +#include <fftw.h> + +/* If you got error messages about rfftw.h, replace the next include line with "#include <srfftw.h>" +or with "#include <drfftw.h> (if one doesn't work try the other). It may be necessary to replace +the <fftw.h> with <dfftw.h> or <sfftw.h>. If the neither one doesn't work, +please install latest version of fftw(recomanded from the sources) from www.fftw.org. +If you'll install fftw3 you need to change the Makefile.inc +Hope all goes right." */ +#include <rfftw.h> + +#else + +#include <fftw3.h> +#define fftw_real double +#define rfftw_plan fftw_plan +#endif + +class FFTwrapper{ + public: + FFTwrapper(int fftsize_); + ~FFTwrapper(); + void smps2freqs(REALTYPE *smps,FFTFREQS freqs); + void freqs2smps(FFTFREQS freqs,REALTYPE *smps); + private: + int fftsize; + fftw_real *tmpfftdata1,*tmpfftdata2; + rfftw_plan planfftw,planfftw_inv; +}; +#endif + diff --git a/muse/synti/zynaddsubfx/DSP/Filter.C b/muse/synti/zynaddsubfx/DSP/Filter.C new file mode 100644 index 00000000..fccb0265 --- /dev/null +++ b/muse/synti/zynaddsubfx/DSP/Filter.C @@ -0,0 +1,72 @@ +/* + ZynAddSubFX - a software synthesizer + + Filter.C - Filters, uses analog,formant,etc. filters + 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) 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 <math.h> +#include <stdio.h> + +#include "Filter.h" + +Filter::Filter(FilterParams *pars){ + unsigned char Ftype=pars->Ptype; + unsigned char Fstages=pars->Pstages; + + category=pars->Pcategory; + + switch (category) { + case 1: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); + 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()); + 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_){ + 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); +}; + diff --git a/muse/synti/zynaddsubfx/DSP/Filter.h b/muse/synti/zynaddsubfx/DSP/Filter.h new file mode 100644 index 00000000..dab948c1 --- /dev/null +++ b/muse/synti/zynaddsubfx/DSP/Filter.h @@ -0,0 +1,51 @@ +/* + ZynAddSubFX - a software synthesizer + + Filter.h - Filters, uses analog,formant,etc. filters + 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) 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 FILTER_H +#define FILTER_H + +#include "../globals.h" + +#include "Filter_.h" +#include "AnalogFilter.h" +#include "FormantFilter.h" +#include "SVFilter.h" +#include "../Params/FilterParams.h" + +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_); + + REALTYPE getrealfreq(REALTYPE freqpitch); + private: + Filter_ *filter; + unsigned char category; +}; + + +#endif + diff --git a/muse/synti/zynaddsubfx/DSP/Filter_.h b/muse/synti/zynaddsubfx/DSP/Filter_.h new file mode 100644 index 00000000..66fff867 --- /dev/null +++ b/muse/synti/zynaddsubfx/DSP/Filter_.h @@ -0,0 +1,42 @@ +/* + ZynAddSubFX - a software synthesizer + + Filter_.h - This class is inherited by filter classes + 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) 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 FILTER__H +#define FILTER__H + +#include "../globals.h" + +class Filter_{ + public: + virtual ~Filter_(){}; + virtual void filterout(REALTYPE */*smp*/){}; + virtual void setfreq(REALTYPE /*frequency*/){}; + virtual void setfreq_and_q(REALTYPE /*frequency*/,REALTYPE /*q_*/){}; + virtual void setq(REALTYPE /*q_*/){}; + virtual void setgain(REALTYPE /*dBgain*/){}; + REALTYPE outgain; + private: +}; + + +#endif + diff --git a/muse/synti/zynaddsubfx/DSP/FormantFilter.C b/muse/synti/zynaddsubfx/DSP/FormantFilter.C new file mode 100644 index 00000000..482cef91 --- /dev/null +++ b/muse/synti/zynaddsubfx/DSP/FormantFilter.C @@ -0,0 +1,163 @@ +/* + ZynAddSubFX - a software synthesizer + + FormantFilter.C - formant filters + 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) 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 <math.h> +#include <stdio.h> +#include "FormantFilter.h" + +FormantFilter::FormantFilter(FilterParams *pars){ + 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]; + + for (int j=0;j<FF_MAX_VOWELS;j++) + for (int i=0;i<numformants;i++){ + formantpar[j][i].freq=pars->getformantfreq(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); + + 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); + + sequencestretch=pow(0.1,(pars->Psequencestretch-32.0)/48.0); + if (pars->Psequencereversed) sequencestretch*= -1.0; + + outgain=dB2rap(pars->getgain()); + + oldinput=-1.0; + Qfactor=1.0;oldQfactor=Qfactor; + firsttime=1; +}; + +FormantFilter::~FormantFilter(){ + for (int i=0;i<numformants;i++) delete(formant[i]); + delete (inbuffer); + delete (tmpbuf); +}; + + + + +void FormantFilter::cleanup(){ + for (int i=0;i<numformants;i++) formant[i]->cleanup(); +}; + +void FormantFilter::setpos(REALTYPE input){ + int p1,p2; + + 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)) { +// oldinput=input; daca setez asta, o sa faca probleme la schimbari foarte lente + firsttime=0; + return; + } else oldinput=input; + + + 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; + + 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; + + if (firsttime!=0) { + for (int i=0;i<numformants;i++){ + currentformants[i].freq=formantpar[p1][i].freq*(1.0-pos)+formantpar[p2][i].freq*pos; + currentformants[i].amp=formantpar[p1][i].amp*(1.0-pos)+formantpar[p2][i].amp*pos; + currentformants[i].q=formantpar[p1][i].q*(1.0-pos)+formantpar[p2][i].q*pos; + formant[i]->setfreq_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].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); + }; + }; + + oldQfactor=Qfactor; +}; + +void FormantFilter::setfreq(REALTYPE frequency){ + setpos(frequency); +}; + +void FormantFilter::setq(REALTYPE 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_){ + Qfactor=q_; + setpos(frequency); +}; + + +void FormantFilter::filterout(REALTYPE *smp){ + int i,j; + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + inbuffer[i]=smp[i]; + smp[i]=0.0; + }; + + for (j=0;j<numformants;j++) { + for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpbuf[i]=inbuffer[i]*outgain; + formant[j]->filterout(tmpbuf); + + if (ABOVE_AMPLITUDE_THRESHOLD(oldformantamp[j],currentformants[j].amp)) + for (i=0;i<SOUND_BUFFER_SIZE;i++) smp[i]+=tmpbuf[i]* + INTERPOLATE_AMPLITUDE(oldformantamp[j],currentformants[j].amp,i,SOUND_BUFFER_SIZE); + else for (i=0;i<SOUND_BUFFER_SIZE;i++) smp[i]+=tmpbuf[i]*currentformants[j].amp; + oldformantamp[j]=currentformants[j].amp; + }; +}; + diff --git a/muse/synti/zynaddsubfx/DSP/FormantFilter.h b/muse/synti/zynaddsubfx/DSP/FormantFilter.h new file mode 100644 index 00000000..7cb52499 --- /dev/null +++ b/muse/synti/zynaddsubfx/DSP/FormantFilter.h @@ -0,0 +1,67 @@ +/* + ZynAddSubFX - a software synthesizer + + FormantFilter.h - formant filter + 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) 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 FORMANT_FILTER_H +#define FORMANT_FILTER_H + +#include "../globals.h" +#include "Filter_.h" +#include "AnalogFilter.h" +#include "../Params/FilterParams.h" + + +class FormantFilter:public Filter_{ + public: + FormantFilter(FilterParams *pars); + ~FormantFilter(); + void filterout(REALTYPE *smp); + void setfreq(REALTYPE frequency); + void setfreq_and_q(REALTYPE frequency,REALTYPE q_); + void setq(REALTYPE q_); + + void cleanup(); + private: + AnalogFilter *formant[FF_MAX_FORMANTS]; + REALTYPE *inbuffer,*tmpbuf; + + struct { + REALTYPE freq,amp,q;//frequency,amplitude,Q + } formantpar[FF_MAX_VOWELS][FF_MAX_FORMANTS],currentformants[FF_MAX_FORMANTS]; + + struct { + unsigned char nvowel; + } sequence [FF_MAX_SEQUENCE]; + + REALTYPE oldformantamp[FF_MAX_FORMANTS]; + + int sequencesize,numformants,firsttime; + REALTYPE oldinput,slowinput; + REALTYPE Qfactor,formantslowness,oldQfactor; + REALTYPE vowelclearness,sequencestretch; + + void setpos(REALTYPE input); + +}; + + +#endif + diff --git a/muse/synti/zynaddsubfx/DSP/SVFilter.C b/muse/synti/zynaddsubfx/DSP/SVFilter.C new file mode 100644 index 00000000..8c0e16b2 --- /dev/null +++ b/muse/synti/zynaddsubfx/DSP/SVFilter.C @@ -0,0 +1,152 @@ +/* + ZynAddSubFX - a software synthesizer + + SVFilter.C - Several state-variable filters + 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) 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 <math.h> +#include <stdio.h> +#include "SVFilter.h" + +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; + cleanup(); + setfreq_and_q(Ffreq,Fq); +}; + +SVFilter::~SVFilter(){ +}; + +void SVFilter::cleanup(){ + for (int i=0;i<MAX_FILTER_STAGES+1;i++){ + st[i].low=0.0;st[i].high=0.0; + st[i].band=0.0;st[i].notch=0.0; + }; + oldabovenq=0; + abovenq=0; +}; + +void SVFilter::computefiltercoefs(){ + 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; + + oldabovenq=abovenq;abovenq=frequency>(SAMPLE_RATE/2-500.0); + + 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; + computefiltercoefs(); + firsttime=0; + +}; + +void SVFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_){ + q=q_; + setfreq(frequency); +}; + +void SVFilter::setq(REALTYPE q_){ + q=q_; + computefiltercoefs(); +}; + +void SVFilter::settype(int type_){ + type=type_; + computefiltercoefs(); +}; + +void SVFilter::setgain(REALTYPE dBgain){ + gain=dB2rap(dBgain); + computefiltercoefs(); +}; + +void SVFilter::setstages(int stages_){ + if (stages_>=MAX_FILTER_STAGES) stages_=MAX_FILTER_STAGES-1; + stages=stages_; + cleanup(); + computefiltercoefs(); +}; + +void SVFilter::singlefilterout(REALTYPE *smp,fstage &x,parameters &par){ + int i; + REALTYPE *out=NULL; + switch(type){ + case 0: out=&x.low;break; + case 1: out=&x.high;break; + case 2: out=&x.band;break; + case 3: out=&x.notch;break; + }; + + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + x.low = x.low + par.f * x.band; + x.high = par.q_sqrt * smp[i] - x.low - par.q*x.band; + x.band = par.f * x.high + x.band; + x.notch = x.high + x.low; + + smp[i]= *out; + }; +}; + +void SVFilter::filterout(REALTYPE *smp){ + int i; + REALTYPE *ismp=NULL; + + if (needsinterpolation!=0){ + ismp=new REALTYPE[SOUND_BUFFER_SIZE]; + for (i=0;i<SOUND_BUFFER_SIZE;i++) ismp[i]=smp[i]; + for (i=0;i<stages+1;i++) singlefilterout(ismp,st[i],ipar); + }; + + for (i=0;i<stages+1;i++) singlefilterout(smp,st[i],par); + + if (needsinterpolation!=0){ + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + REALTYPE x=i/(REALTYPE) SOUND_BUFFER_SIZE; + smp[i]=ismp[i]*(1.0-x)+smp[i]*x; + }; + delete (ismp); + needsinterpolation=0; + }; + + for (i=0;i<SOUND_BUFFER_SIZE;i++) smp[i]*=outgain; + +}; + diff --git a/muse/synti/zynaddsubfx/DSP/SVFilter.h b/muse/synti/zynaddsubfx/DSP/SVFilter.h new file mode 100644 index 00000000..3117e2c9 --- /dev/null +++ b/muse/synti/zynaddsubfx/DSP/SVFilter.h @@ -0,0 +1,67 @@ +/* + ZynAddSubFX - a software synthesizer + + SV Filter.h - Several state-variable filters + 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) 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 SV_FILTER_H +#define SV_FILTER_H + +#include "../globals.h" +#include "Filter_.h" +class SVFilter:public Filter_{ + public: + SVFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages); + ~SVFilter(); + void filterout(REALTYPE *smp); + void setfreq(REALTYPE frequency); + void setfreq_and_q(REALTYPE frequency,REALTYPE q_); + void setq(REALTYPE q_); + + void settype(int type_); + void setgain(REALTYPE dBgain); + void setstages(int stages_); + void cleanup(); + + private: + struct fstage{ + REALTYPE low,high,band,notch; + } st[MAX_FILTER_STAGES+1]; + + struct parameters{ + REALTYPE f,q,q_sqrt; + }par,ipar; + + + 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; +}; + + +#endif + diff --git a/muse/synti/zynaddsubfx/Effects/Alienwah.C b/muse/synti/zynaddsubfx/Effects/Alienwah.C new file mode 100644 index 00000000..8d2475d2 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Alienwah.C @@ -0,0 +1,244 @@ +/* + ZynAddSubFX - a software synthesizer + + Alienwah.C - "AlienWah" 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) 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 <math.h> +#include "Alienwah.h" +#include <stdio.h> + +Alienwah::Alienwah(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){ + efxoutl=efxoutl_; + efxoutr=efxoutr_; + + oldl=NULL; + oldr=NULL; + filterpars=NULL; + insertion=insertion_; + + Ppreset=0; + setpreset(Ppreset); + cleanup(); + oldclfol.a=fb;oldclfol.b=0.0; + oldclfor.a=fb;oldclfor.b=0.0; +}; + +Alienwah::~Alienwah(){ + if (oldl!=NULL) delete [] oldl; + if (oldr!=NULL) delete [] oldr ; +}; + + +/* + * Apply the effect + */ +void Alienwah::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i; + REALTYPE lfol,lfor; + COMPLEXTYPE clfol,clfor,out,tmp; + + lfo.effectlfoout(&lfol,&lfor); + lfol*=depth*PI*2.0;lfor*=depth*PI*2.0; + clfol.a=cos(lfol+phase)*fb;clfol.b=sin(lfol+phase)*fb; + clfor.a=cos(lfor+phase)*fb;clfor.b=sin(lfor+phase)*fb; + + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + REALTYPE x=((REALTYPE) i)/SOUND_BUFFER_SIZE; + REALTYPE x1=1.0-x; + //left + tmp.a=clfol.a*x+oldclfol.a*x1; + tmp.b=clfol.b*x+oldclfol.b*x1; + + out.a=tmp.a*oldl[oldk].a-tmp.b*oldl[oldk].b + +(1-fabs(fb))*smpsl[i]*panning; + out.b=tmp.a*oldl[oldk].b+tmp.b*oldl[oldk].a; + oldl[oldk].a=out.a; + oldl[oldk].b=out.b; + REALTYPE l=out.a*10.0*(fb+0.1); + + //right + tmp.a=clfor.a*x+oldclfor.a*x1; + tmp.b=clfor.b*x+oldclfor.b*x1; + + out.a=tmp.a*oldr[oldk].a-tmp.b*oldr[oldk].b + +(1-fabs(fb))*smpsr[i]*(1.0-panning); + out.b=tmp.a*oldr[oldk].b+tmp.b*oldr[oldk].a; + oldr[oldk].a=out.a; + oldr[oldk].b=out.b; + REALTYPE r=out.a*10.0*(fb+0.1); + + + if (++oldk>=Pdelay) oldk=0; + //LRcross + efxoutl[i]=l*(1.0-lrcross)+r*lrcross; + efxoutr[i]=r*(1.0-lrcross)+l*lrcross; + }; + + oldclfol.a=clfol.a;oldclfol.b=clfol.b; + oldclfor.a=clfor.a;oldclfor.b=clfor.b; + +}; + +/* + * Cleanup the effect + */ +void Alienwah::cleanup(){ + for (int i=0;i<Pdelay;i++) { + oldl[i].a=0.0; + oldl[i].b=0.0; + oldr[i].a=0.0; + oldr[i].b=0.0; + }; + oldk=0; +}; + + +/* + * Parameter control + */ + +void Alienwah::setdepth(unsigned char Pdepth){ + this->Pdepth=Pdepth; + depth=(Pdepth/127.0); +}; + +void Alienwah::setfb(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; +}; + +void Alienwah::setvolume(unsigned char Pvolume){ + this->Pvolume=Pvolume; + outvolume=Pvolume/127.0; + if (insertion==0) volume=1.0; + else volume=outvolume; +}; + +void Alienwah::setpanning(unsigned char Ppanning){ + this->Ppanning=Ppanning; + panning=Ppanning/127.0; +}; + +void Alienwah::setlrcross(unsigned char Plrcross){ + this->Plrcross=Plrcross; + lrcross=Plrcross/127.0; +}; + +void Alienwah::setphase(unsigned char Pphase){ + this->Pphase=Pphase; + phase=(Pphase-64.0)/64.0*PI; +}; + +void Alienwah::setdelay(unsigned char Pdelay){ + if (oldl!=NULL) delete [] oldl; + if (oldr!=NULL) delete [] oldr; + if (Pdelay>=MAX_ALIENWAH_DELAY) Pdelay=MAX_ALIENWAH_DELAY; + this->Pdelay=Pdelay; + oldl=new COMPLEXTYPE[Pdelay]; + oldr=new COMPLEXTYPE[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]={ + //AlienWah1 + {127,64,70,0,0,62,60,105,25,0,64}, + //AlienWah2 + {127,64,73,106,0,101,60,105,17,0,64}, + //AlienWah3 + {127,64,63,0,1,100,112,105,31,0,42}, + //AlienWah4 + {93,64,25,0,1,66,101,11,47,0,86}}; + + 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 this is system effect + Ppreset=npreset; +}; + + +void Alienwah::changepar(int npar,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: setdelay(value); + break; + case 9: setlrcross(value); + break; + case 10:setphase(value); + break; + }; +}; + +unsigned char Alienwah::getpar(int npar){ + 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(Pdelay); + break; + case 9: return(Plrcross); + break; + case 10:return(Pphase); + break; + default:return (0); + }; + +}; + + + + diff --git a/muse/synti/zynaddsubfx/Effects/Alienwah.h b/muse/synti/zynaddsubfx/Effects/Alienwah.h new file mode 100644 index 00000000..b1bfaedc --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Alienwah.h @@ -0,0 +1,77 @@ +/* + ZynAddSubFX - a software synthesizer + + Alienwah.h - "AlienWah" 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) 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 ALIENWAH_H +#define ALIENWAH_H +#include "../globals.h" +#include "Effect.h" +#include "EffectLFO.h" + + +#define MAX_ALIENWAH_DELAY 100 + +struct COMPLEXTYPE { + REALTYPE a,b; +}; + +class Alienwah:public Effect { + public: + Alienwah(int insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~Alienwah(); + void out(REALTYPE *smpsl,REALTYPE *smpsr); + + void setpreset(unsigned char npreset); + void changepar(int npar,unsigned char value); + unsigned char getpar(int npar); + void cleanup(); + + private: + //Parametrii Alienwah + 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 Parametrii + void setvolume(unsigned char Pvolume); + void setpanning(unsigned char Ppanning); + void setdepth(unsigned char Pdepth); + void setfb(unsigned char Pfb); + void setlrcross(unsigned char Plrcross); + void setdelay(unsigned char Pdelay); + void setphase(unsigned char Pphase); + + //Valorile interne + int insertion; + REALTYPE panning,fb,depth,lrcross,phase; + COMPLEXTYPE *oldl,*oldr; + COMPLEXTYPE oldclfol,oldclfor; + int oldk; +}; + +#endif + diff --git a/muse/synti/zynaddsubfx/Effects/Chorus.C b/muse/synti/zynaddsubfx/Effects/Chorus.C new file mode 100644 index 00000000..fb40c93b --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Chorus.C @@ -0,0 +1,277 @@ +/* + ZynAddSubFX - a software synthesizer + + Chorus.C - Chorus and Flange effects + 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) 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 <math.h> +#include "Chorus.h" +#include <stdio.h> + +Chorus::Chorus(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){ + efxoutl=efxoutl_; + efxoutr=efxoutr_; + dlk=0;drk=0; + maxdelay=(int)(MAX_CHORUS_DELAY/1000.0*SAMPLE_RATE); + delayl=new REALTYPE[maxdelay]; + delayr=new REALTYPE[maxdelay]; + insertion=insertion_; + + filterpars=NULL; + Ppreset=0; + setpreset(Ppreset); + + lfo.effectlfoout(&lfol,&lfor); + dl2=getdelay(lfol); + dr2=getdelay(lfor); + cleanup(); +}; + +Chorus::~Chorus(){ + delete [] delayl; + delete [] delayr; +}; + +/* + * get the delay value in samples; xlfo is the current lfo value + */ +REALTYPE Chorus::getdelay(REALTYPE xlfo){ + REALTYPE result; + 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() + if ((result+0.5)>=maxdelay) { + fprintf(stderr,"%s","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){ + int i; + dl1=dl2;dr1=dr2; + lfo.effectlfoout(&lfol,&lfor); + + dl2=getdelay(lfol); + dr2=getdelay(lfor); + + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + REALTYPE inl=smpsl[i]; + REALTYPE inr=smpsr[i]; + //LRcross + REALTYPE l=inl; + REALTYPE r=inr; + inl=l*(1.0-lrcross)+r*lrcross; + inr=r*(1.0-lrcross)+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 + + F2I(tmp,dlhi); + dlhi%=maxdelay; + + dlhi2=(dlhi-1+maxdelay)%maxdelay; + dllo=1.0-fmod(tmp,1.0); + efxoutl[i]=delayl[dlhi2]*dllo+delayl[dlhi]*(1.0-dllo); + delayl[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-mdel+maxdelay*2.0;//where should I get the sample from + + F2I(tmp,dlhi); + dlhi%=maxdelay; + + dlhi2=(dlhi-1+maxdelay)%maxdelay; + dllo=1.0-fmod(tmp,1.0); + efxoutr[i]=delayr[dlhi2]*dllo+delayr[dlhi]*(1.0-dllo); + delayr[dlk]=inr+efxoutr[i]*fb; + + }; + + if (Poutsub!=0) + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + efxoutl[i] *= -1.0; + efxoutr[i] *= -1.0; + }; + + + for (int i=0;i<SOUND_BUFFER_SIZE;i++){ + efxoutl[i]*=panning; + efxoutr[i]*=(1.0-panning); + }; +}; + +/* + * Cleanup the effect + */ +void Chorus::cleanup(){ + for (int i=0;i<maxdelay;i++){ + delayl[i]=0.0; + delayr[i]=0.0; + }; + +}; + +/* + * Parameter control + */ +void Chorus::setdepth(unsigned char Pdepth){ + this->Pdepth=Pdepth; + depth=(pow(8.0,(Pdepth/127.0)*2.0)-1.0)/1000.0;//seconds +}; + +void Chorus::setdelay(unsigned char Pdelay){ + this->Pdelay=Pdelay; + delay=(pow(10.0,(Pdelay/127.0)*2.0)-1.0)/1000.0;//seconds +}; + +void Chorus::setfb(unsigned char Pfb){ + this->Pfb=Pfb; + fb=(Pfb-64.0)/64.1; +}; +void Chorus::setvolume(unsigned char Pvolume){ + this->Pvolume=Pvolume; + outvolume=Pvolume/127.0; + if (insertion==0) volume=1.0; + else volume=outvolume; +}; + +void Chorus::setpanning(unsigned char Ppanning){ + this->Ppanning=Ppanning; + panning=Ppanning/127.0; +}; + +void Chorus::setlrcross(unsigned char Plrcross){ + 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]={ + //Chorus1 + {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}, + //Chorus3 + {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}, + //Celeste2 + {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}, + //Flange2 + {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}, + //Flange4 + {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}}; + + if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; + for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]); + Ppreset=npreset; +}; + + +void Chorus::changepar(int npar,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: setdelay(value); + break; + case 8: setfb(value); + break; + case 9: setlrcross(value); + break; + case 10:if (value>1) value=1; + Pflangemode=value; + break; + case 11:if (value>1) value=1; + Poutsub=value; + break; + }; +}; + +unsigned char Chorus::getpar(int npar){ + 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(Pdelay); + break; + case 8: return(Pfb); + break; + case 9: return(Plrcross); + break; + case 10:return(Pflangemode); + break; + case 11:return(Poutsub); + break; + default:return (0); + }; + +}; + + + + diff --git a/muse/synti/zynaddsubfx/Effects/Chorus.h b/muse/synti/zynaddsubfx/Effects/Chorus.h new file mode 100644 index 00000000..25e2ec34 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Chorus.h @@ -0,0 +1,73 @@ +/* + ZynAddSubFX - a software synthesizer + + Chorus.h - Chorus and Flange effects + 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) 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 CHORUS_H +#define CHORUS_H +#include "../globals.h" +#include "Effect.h" +#include "EffectLFO.h" + +#define MAX_CHORUS_DELAY 250.0 //ms + +class Chorus:public Effect { + public: + Chorus(int insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~Chorus(); + void out(REALTYPE *smpsl,REALTYPE *smpsr); + void setpreset(unsigned char npreset); + void changepar(int npar,unsigned char value); + unsigned char getpar(int npar); + void cleanup(); + + private: + //Parametrii Chorus + 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 + + + //Control Parametrii + void setvolume(unsigned char Pvolume); + void setpanning(unsigned char Ppanning); + void setdepth(unsigned char Pdepth); + void setdelay(unsigned char Pdelay); + void setfb(unsigned char Pfb); + void setlrcross(unsigned char Plrcross); + + //Valorile interne + REALTYPE depth,delay,fb,lrcross,panning; + REALTYPE dl1,dl2,dr1,dr2,lfol,lfor; + int insertion,maxdelay; + REALTYPE *delayl,*delayr; + int dlk,drk,dlhi,dlhi2; + REALTYPE getdelay(REALTYPE xlfo); + REALTYPE dllo,mdel; +}; + +#endif + diff --git a/muse/synti/zynaddsubfx/Effects/Distorsion.C b/muse/synti/zynaddsubfx/Effects/Distorsion.C new file mode 100644 index 00000000..fa1b1163 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Distorsion.C @@ -0,0 +1,384 @@ +/* + ZynAddSubFX - a software synthesizer + + Distorsion.C - Distorsion 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) 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 <stdio.h> +#include <stdlib.h> +#include <math.h> +#include "Distorsion.h" + + +/* + * Waveshape (this is called by OscilGen::waveshape and Distorsion::process) + */ + +void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive){ + int i; + REALTYPE ws=drive/127.0; + REALTYPE tmpv; + + switch(type){ + case 1: ws=pow(10,ws*ws*3.0)-1.0+0.001;//Arctangent + for (i=0;i<n;i++) + smps[i]=atan(smps[i]*ws)/atan(ws); + break; + case 2: ws=ws*ws*32.0+0.0001;//Asymmetric + if (ws<1.0) tmpv=sin(ws)+0.1; + else tmpv=1.1; + for (i=0;i<n;i++) { + smps[i]=sin(smps[i]*(0.1+ws-ws*smps[i]))/tmpv; + }; + break; + case 3: ws=ws*ws*ws*20.0+0.0001;//Pow + for (i=0;i<n;i++) { + smps[i]*=ws; + if (fabs(smps[i])<1.0) { + smps[i]=(smps[i]-pow(smps[i],3.0))*3.0; + if (ws<1.0) smps[i]/=ws; + } else smps[i]=0.0; + }; + break; + case 4: ws=ws*ws*ws*32.0+0.0001;//Sine + if (ws<1.57) tmpv=sin(ws); + else tmpv=1.0; + for (i=0;i<n;i++) smps[i]=sin(smps[i]*ws)/tmpv; + break; + case 5: ws=ws*ws+0.000001;//Quantisize + for (i=0;i<n;i++) + smps[i]=floor(smps[i]/ws+0.5)*ws; + break; + case 6: ws=ws*ws*ws*32+0.0001;//Zigzag + if (ws<1.0) tmpv=sin(ws); + else tmpv=1.0; + for (i=0;i<n;i++) + smps[i]=asin(sin(smps[i]*ws))/tmpv; + break; + case 7: 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;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;i<n;i++) { + REALTYPE tmp=smps[i]; + if (tmp<-ws) smps[i]=-ws; + smps[i]*=2.0; + }; + break; + case 10: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<n;i++) + smps[i]=smps[i]*(ws+0.5)*0.9999-floor(0.5+smps[i]*(ws+0.5)*0.9999); + break; + case 12: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<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;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; + //update to Distorsion::changepar (Ptype max) if there is added more waveshapings functions + }; + +}; + + +Distorsion::Distorsion(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){ + efxoutl=efxoutl_; + efxoutr=efxoutr_; + + 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); + + filterpars=NULL; + + insertion=insertion_; + //default values + Ppreset=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(){ + delete (lpfl); + delete (lpfr); + delete (hpfl); + delete (hpfr); + +}; + +/* + * Cleanup the effect + */ +void Distorsion::cleanup(){ + lpfl->cleanup(); + hpfl->cleanup(); + lpfr->cleanup(); + hpfr->cleanup(); +}; + + +/* + * Apply the filters + */ + +void Distorsion::applyfilters(REALTYPE *efxoutl,REALTYPE *efxoutr){ + lpfl->filterout(efxoutl); + hpfl->filterout(efxoutl); + if (Pstereo!=0){//stereo + lpfr->filterout(efxoutr); + hpfr->filterout(efxoutr); + }; + +}; + + +/* + * Effect output + */ +void Distorsion::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i; + REALTYPE l,r,lout,rout; + + REALTYPE inputvol=pow(5.0,(Pdrive-32.0)/127.0); + if (Pnegate!=0) inputvol*=-1.0; + + if (Pstereo!=0){//Stereo + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + efxoutl[i]=smpsl[i]*inputvol*panning; + efxoutr[i]=smpsr[i]*inputvol*(1.0-panning); + }; + } else { + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + efxoutl[i]=( smpsl[i]*panning + smpsr[i]*(1.0-panning) ) * inputvol; + }; + }; + + if (Pprefiltering!=0) applyfilters(efxoutl,efxoutr); + + //no optimised, yet (no look table) + waveshapesmps(SOUND_BUFFER_SIZE,efxoutl,Ptype+1,Pdrive); + if (Pstereo!=0) waveshapesmps(SOUND_BUFFER_SIZE,efxoutr,Ptype+1,Pdrive); + + if (Pprefiltering==0) applyfilters(efxoutl,efxoutr); + + if (Pstereo==0) for (i=0;i<SOUND_BUFFER_SIZE;i++) efxoutr[i]=efxoutl[i]; + + REALTYPE level=dB2rap(60.0*Plevel/127.0-40.0); + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + lout=efxoutl[i]; + rout=efxoutr[i]; + l=lout*(1.0-lrcross)+rout*lrcross; + r=rout*(1.0-lrcross)+lout*lrcross; + lout=l;rout=r; + + efxoutl[i]=lout*2.0*level; + efxoutr[i]=rout*2.0*level; + + }; + +}; + + +/* + * Parameter control + */ +void Distorsion::setvolume(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 Distorsion::setpanning(unsigned char Ppanning){ + this->Ppanning=Ppanning; + panning=(Ppanning+0.5)/127.0; +}; + + +void Distorsion::setlrcross(unsigned char Plrcross){ + this->Plrcross=Plrcross; + lrcross=Plrcross/127.0*1.0; +}; + +void Distorsion::setlpf(unsigned char Plpf){ + 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(unsigned char Phpf){ + 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]={ + //Overdrive 1 + {127,64,35,56,70,0,0,96,0,0,0}, + //Overdrive 2 + {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}, + //A. Exciter 2 + {64,64,35,85,62,1,0,127,118,1,0}, + //Guitar Amp + {127,64,35,63,75,2,0,55,0,0,0}, + //Quantisize + {127,64,35,88,75,4,0,127,0,1,0}}; + + + 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,(int) (presets[npreset][0]/1.5));//lower the volume if this is system effect + Ppreset=npreset; + cleanup(); +}; + + +void Distorsion::changepar(int npar,unsigned char value){ + switch (npar){ + case 0: setvolume(value); + break; + case 1: setpanning(value); + break; + case 2: setlrcross(value); + break; + case 3: Pdrive=value; + break; + case 4: Plevel=value; + break; + case 5: if (value>13) value=13;//this must be increased if more distorsion types are added + Ptype=value; + break; + case 6: if (value>1) value=1; + Pnegate=value; + break; + case 7: setlpf(value); + break; + case 8: sethpf(value); + break; + case 9: if (value>1) value=1; + Pstereo=value; + break; + case 10:Pprefiltering=value; + break; + }; +}; + +unsigned char Distorsion::getpar(int npar){ + switch (npar){ + case 0: return(Pvolume); + break; + case 1: return(Ppanning); + break; + case 2: return(Plrcross); + break; + case 3: return(Pdrive); + break; + case 4: return(Plevel); + break; + case 5: return(Ptype); + break; + case 6: return(Pnegate); + break; + case 7: return(Plpf); + break; + case 8: return(Phpf); + break; + case 9: return(Pstereo); + break; + case 10:return(Pprefiltering); + break; + }; + return(0);//in case of bogus parameter number +}; + + + + diff --git a/muse/synti/zynaddsubfx/Effects/Distorsion.h b/muse/synti/zynaddsubfx/Effects/Distorsion.h new file mode 100644 index 00000000..5e0aba93 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Distorsion.h @@ -0,0 +1,73 @@ +/* + ZynAddSubFX - a software synthesizer + + Distorsion.h - Distorsion 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) 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 DISTORSION_H +#define DISTORSION_H + +#include "../globals.h" +#include "../DSP/AnalogFilter.h" +#include "Effect.h" + +//Waveshaping(called by Distorsion effect and waveshape from OscilGen) +void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive); + +class Distorsion:public Effect{ + public: + Distorsion(int insertion,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~Distorsion(); + void out(REALTYPE *smpsl,REALTYPE *smpr); + void setpreset(unsigned char npreset); + void changepar(int npar,unsigned char value); + unsigned char getpar(int npar); + 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 ouput 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(unsigned char Pvolume); + void setpanning(unsigned char Ppanning); + void setlrcross(unsigned char Plrcross); + void setlpf(unsigned char Plpf); + void sethpf(unsigned char Phpf); + + //Parametrii reali + REALTYPE panning,lrcross; + AnalogFilter *lpfl,*lpfr,*hpfl,*hpfr; + +}; + + +#endif + + diff --git a/muse/synti/zynaddsubfx/Effects/DynamicFilter.C b/muse/synti/zynaddsubfx/Effects/DynamicFilter.C new file mode 100644 index 00000000..a86794f0 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/DynamicFilter.C @@ -0,0 +1,318 @@ +/* + ZynAddSubFX - a software synthesizer + + DynamicFilter.C - "WahWah" effect and others + 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) 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 <math.h> +#include "DynamicFilter.h" +#include <stdio.h> + +DynamicFilter::DynamicFilter(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){ + efxoutl=efxoutl_; + efxoutr=efxoutr_; + + insertion=insertion_; + + Ppreset=0; + filterl=NULL; + filterr=NULL; + filterpars=new FilterParams(0,64,64); + setpreset(Ppreset); + cleanup(); +}; + +DynamicFilter::~DynamicFilter(){ + delete(filterpars); + delete(filterl); + delete(filterr); +}; + + +/* + * Apply the effect + */ +void DynamicFilter::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i; + 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(); + + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + efxoutl[i]=smpsl[i]; + efxoutr[i]=smpsr[i]; + + REALTYPE x=(fabs(smpsl[i])+fabs(smpsr[i]))*0.5; + ms1=ms1*(1.0-ampsmooth)+x*ampsmooth+1e-10; + }; + + + REALTYPE ampsmooth2=pow(ampsmooth,0.2)*0.3; + ms2=ms2*(1.0-ampsmooth2)+ms1*ampsmooth2; + ms3=ms3*(1.0-ampsmooth2)+ms2*ampsmooth2; + ms4=ms4*(1.0-ampsmooth2)+ms3*ampsmooth2; + REALTYPE rms=(sqrt(ms4))*ampsns; + + 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->filterout(efxoutl); + filterr->filterout(efxoutr); + + //panning + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + efxoutl[i]*=panning; + efxoutr[i]*=(1.0-panning); + }; + +}; + +/* + * Cleanup the effect + */ +void DynamicFilter::cleanup(){ + reinitfilter(); + ms1=0.0; + ms2=0.0; + ms3=0.0; + ms4=0.0; +}; + + +/* + * Parameter control + */ + +void DynamicFilter::setdepth(unsigned char Pdepth){ + this->Pdepth=Pdepth; + depth=pow((Pdepth/127.0),2.0); +}; + + +void DynamicFilter::setvolume(unsigned char Pvolume){ + this->Pvolume=Pvolume; + outvolume=Pvolume/127.0; + if (insertion==0) volume=1.0; + else volume=outvolume; +}; + +void DynamicFilter::setpanning(unsigned char Ppanning){ + this->Ppanning=Ppanning; + panning=Ppanning/127.0; +}; + + +void DynamicFilter::setampsns(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; +}; + +void DynamicFilter::reinitfilter(){ + 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]={ + //WahWah + {110,64,80,0,0,64,0,90,0,60}, + //AutoWah + {110,64,70,0,0,80,70,0,0,60}, + //Sweep + {100,64,30,0,0,50,80,0,0,60}, + //VocalMorph1 + {110,64,80,0,0,64,0,64,0,60}, + //VocalMorph1 + {127,64,50,0,0,96,64,0,0,60}}; + + if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; + for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]); + + filterpars->defaults(); + switch(npreset){ + case 0: + 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; + break; + case 2: + 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->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; + // "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; + break; + case 4: + 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->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; + 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; + + reinitfilter(); +}; + + +void DynamicFilter::changepar(int npar,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: setampsns(value); + break; + case 8: Pampsnsinv=value; + setampsns(Pampsns); + break; + case 9: Pampsmooth=value; + setampsns(Pampsns); + break; + }; +}; + +unsigned char DynamicFilter::getpar(int npar){ + 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(Pampsns); + break; + case 8: return(Pampsnsinv); + break; + case 9: return(Pampsmooth); + break; + default:return (0); + }; + +}; + + + + diff --git a/muse/synti/zynaddsubfx/Effects/DynamicFilter.h b/muse/synti/zynaddsubfx/Effects/DynamicFilter.h new file mode 100644 index 00000000..42ab5981 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/DynamicFilter.h @@ -0,0 +1,72 @@ +/* + ZynAddSubFX - a software synthesizer + + DynamicFilter.h - "WahWah" effect and others + 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) 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 DYNAMICFILTER_H +#define DYNAMICFILTER_H +#include "../globals.h" +#include "Effect.h" +#include "EffectLFO.h" + +#include "../DSP/Filter.h" + +class DynamicFilter:public Effect { + public: + DynamicFilter(int insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~DynamicFilter(); + void out(REALTYPE *smpsl,REALTYPE *smpsr); + + void setpreset(unsigned char npreset); + void changepar(int npar,unsigned char value); + unsigned char getpar(int npar); + void cleanup(); + +// void setdryonly(); + + private: + //Parametrii DynamicFilter + EffectLFO lfo;//lfo-ul DynamicFilter + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth;//the depth of the lfo of the DynamicFilter + unsigned char Pampsns;//how the filter varies according to the input amplitude + unsigned char Pampsnsinv;//if the filter freq is lowered if the input amplitude rises + unsigned char Pampsmooth;//how smooth the input amplitude changes the filter + + //Control Parametrii + void setvolume(unsigned char Pvolume); + void setpanning(unsigned char Ppanning); + void setdepth(unsigned char Pdepth); + void setampsns(unsigned char Pampsns); + + void reinitfilter(); + + //Valorile interne + int insertion; + REALTYPE panning,depth,ampsns,ampsmooth; + + Filter *filterl,*filterr; + + REALTYPE ms1,ms2,ms3,ms4;//mean squares +}; + +#endif + diff --git a/muse/synti/zynaddsubfx/Effects/EQ.C b/muse/synti/zynaddsubfx/Effects/EQ.C new file mode 100644 index 00000000..8180a655 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/EQ.C @@ -0,0 +1,198 @@ +/* + ZynAddSubFX - a software synthesizer + + EQ.C - EQ 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) 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 <stdio.h> +#include <stdlib.h> +#include <math.h> +#include "EQ.h" + +EQ::EQ(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){ + efxoutl=efxoutl_; + efxoutr=efxoutr_; + insertion=insertion_; + filterpars=NULL; + + for (int i=0;i<MAX_EQ_BANDS;i++){ + filter[i].Ptype=0; + filter[i].Pfreq=64; + filter[i].Pgain=64; + filter[i].Pq=64; + filter[i].Pstages=0; + filter[i].l=new AnalogFilter(6,1000.0,1.0,0); + filter[i].r=new AnalogFilter(6,1000.0,1.0,0); + }; + //default values + Ppreset=0; + Pvolume=50; + + setpreset(Ppreset); + cleanup(); +}; + +EQ::~EQ(){ +}; + +/* + * Cleanup the effect + */ +void EQ::cleanup(){ + for (int i=0;i<MAX_EQ_BANDS;i++){ + filter[i].l->cleanup(); + filter[i].r->cleanup(); + }; +}; + + + +/* + * Effect output + */ +void EQ::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i; + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + efxoutl[i]=smpsl[i]*volume; + efxoutr[i]=smpsr[i]*volume; + }; + + for (i=0;i<MAX_EQ_BANDS;i++){ + if (filter[i].Ptype==0) continue; + filter[i].l->filterout(efxoutl); + filter[i].r->filterout(efxoutr); + }; +}; + + +/* + * Parameter control + */ +void EQ::setvolume(unsigned char Pvolume){ + this->Pvolume=Pvolume; + + 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]={ + //EQ 1 + {67}, + //EQ 2 + {67}}; + + if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; + for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]); + Ppreset=npreset; +}; + + +void EQ::changepar(int npar,unsigned char value){ + switch (npar){ + case 0: setvolume(value); + break; + }; + 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 + + REALTYPE tmp; + switch(bp){ + case 0: if (value>9) value=0;//has to be changed if more filters will be added + filter[nb].Ptype=value; + if (value!=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].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].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].l->setq(tmp); + filter[nb].r->setq(tmp); + break; + case 4: if (value>=MAX_FILTER_STAGES) value=MAX_FILTER_STAGES-1; + filter[nb].Pstages=value; + filter[nb].l->setstages(value); + filter[nb].r->setstages(value); + break; + }; +}; + +unsigned char EQ::getpar(int npar){ + switch (npar){ + case 0: return(Pvolume); + break; + }; + + 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){ + case 0: return(filter[nb].Ptype); + break; + case 1: return(filter[nb].Pfreq); + break; + case 2: return(filter[nb].Pgain); + break; + case 3: return(filter[nb].Pq); + break; + case 4: return(filter[nb].Pstages); + break; + }; + + return(0);//in case of bogus parameter number +}; + + + + +REALTYPE EQ::getfreqresponse(REALTYPE freq){ + 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/muse/synti/zynaddsubfx/Effects/EQ.h b/muse/synti/zynaddsubfx/Effects/EQ.h new file mode 100644 index 00000000..843b957b --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/EQ.h @@ -0,0 +1,58 @@ +/* + ZynAddSubFX - a software synthesizer + + EQ.h - EQ 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) 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 EQ_H +#define EQ_H + +#include "../globals.h" +#include "../DSP/AnalogFilter.h" +#include "Effect.h" + +class EQ:public Effect{ + public: + EQ(int insertion,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~EQ(); + void out(REALTYPE *smpsl,REALTYPE *smpr); + void setpreset(unsigned char npreset); + void changepar(int npar,unsigned char value); + unsigned char getpar(int npar); + void cleanup(); + REALTYPE getfreqresponse(REALTYPE freq); + private: + //Parametrii + unsigned char Pvolume;//Volumul + + void setvolume(unsigned char Pvolume); + + struct { + //parameters + unsigned char Ptype,Pfreq,Pgain,Pq,Pstages; + //internal values + AnalogFilter *l,*r; + }filter[MAX_EQ_BANDS]; + +}; + + +#endif + + diff --git a/muse/synti/zynaddsubfx/Effects/Echo.C b/muse/synti/zynaddsubfx/Effects/Echo.C new file mode 100644 index 00000000..a35ee1ba --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Echo.C @@ -0,0 +1,240 @@ +/* + ZynAddSubFX - a software synthesizer + + Echo.C - Echo 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) 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 <stdio.h> +#include <stdlib.h> +#include <math.h> +#include "Echo.h" + +Echo::Echo(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){ + efxoutl=efxoutl_; + efxoutr=efxoutr_; + filterpars=NULL; + + insertion=insertion_; + //default values + Ppreset=0; + Pvolume=50; + Ppanning=64; + Pdelay=60; + Plrdelay=100; + Plrcross=100; + Pfb=40; + Phidamp=60; + + ldelay=NULL; + rdelay=NULL; + lrdelay=0; + + setpreset(Ppreset); + cleanup(); +}; + +Echo::~Echo(){ + delete[] ldelay; + delete[] rdelay; +}; + +/* + * Cleanup the effect + */ +void Echo::cleanup(){ + int i; + for (i=0;i<dl;i++) ldelay[i]=0.0; + for (i=0;i<dr;i++) rdelay[i]=0.0; + oldl=0.0; + oldr=0.0; +}; + + +/* + * Initialize the delays + */ +void Echo::initdelays(){ + kl=0;kr=0; + dl=delay-lrdelay;if (dl<1) dl=1; + dr=delay+lrdelay;if (dr<1) dr=1; + + if (ldelay!=NULL) delete [] ldelay; + if (rdelay!=NULL) delete [] rdelay; + ldelay=new REALTYPE[dl]; + rdelay=new REALTYPE[dr]; + + cleanup(); +}; + +/* + * Effect output + */ +void Echo::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i; + REALTYPE l,r,ldl,rdl; + + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + ldl=ldelay[kl]; + rdl=rdelay[kr]; + l=ldl*(1.0-lrcross)+rdl*lrcross; + r=rdl*(1.0-lrcross)+ldl*lrcross; + ldl=l;rdl=r; + + efxoutl[i]=ldl*2.0; + efxoutr[i]=rdl*2.0; + ldl=smpsl[i]*panning-ldl*fb; + rdl=smpsr[i]*(1.0-panning)-rdl*fb; + + //LowPass Filter + ldelay[kl]=ldl=ldl*hidamp+oldl*(1.0-hidamp); + rdelay[kr]=rdl=rdl*hidamp+oldr*(1.0-hidamp); + oldl=ldl; + oldr=rdl; + + if (++kl>=dl) kl=0; + if (++kr>=dr) kr=0; + }; + +}; + + +/* + * Parameter control + */ +void Echo::setvolume(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 Echo::setpanning(unsigned char Ppanning){ + this->Ppanning=Ppanning; + panning=(Ppanning+0.5)/127.0; +}; + +void Echo::setdelay(unsigned char Pdelay){ + this->Pdelay=Pdelay; + delay=1+(int)(Pdelay/127.0*SAMPLE_RATE*1.5);//0 .. 1.5 sec + initdelays(); +}; + +void Echo::setlrdelay(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; + initdelays(); +}; + +void Echo::setlrcross(unsigned char Plrcross){ + this->Plrcross=Plrcross; + lrcross=Plrcross/127.0*1.0; +}; + +void Echo::setfb(unsigned char Pfb){ + this->Pfb=Pfb; + fb=Pfb/128.0; +}; + +void Echo::sethidamp(unsigned char Phidamp){ + this->Phidamp=Phidamp; + hidamp=1.0-Phidamp/127.0; +}; + +void Echo::setpreset(unsigned char npreset){ + 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}, + //Echo 2 + {67,64,21,64,30,59,0}, + //Echo 3 + {67,75,60,64,30,59,10}, + //Simple Echo + {67,60,44,64,30,0,0}, + //Canyon + {67,60,102,50,30,82,48}, + //Panning Echo 1 + {67,64,44,17,0,82,24}, + //Panning Echo 2 + {81,60,46,118,100,68,18}, + //Panning Echo 3 + {81,60,26,100,127,67,36}, + //Feedback Echo + {62,64,28,64,100,90,55}}; + + + 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 this is insertion effect + Ppreset=npreset; +}; + + +void Echo::changepar(int npar,unsigned char value){ + switch (npar){ + case 0: setvolume(value); + break; + case 1: setpanning(value); + break; + case 2: setdelay(value); + break; + case 3: setlrdelay(value); + break; + case 4: setlrcross(value); + break; + case 5: setfb(value); + break; + case 6: sethidamp(value); + break; + }; +}; + +unsigned char Echo::getpar(int npar){ + switch (npar){ + case 0: return(Pvolume); + break; + case 1: return(Ppanning); + break; + case 2: return(Pdelay); + break; + case 3: return(Plrdelay); + break; + case 4: return(Plrcross); + break; + case 5: return(Pfb); + break; + case 6: return(Phidamp); + break; + }; + return(0);//in case of bogus parameter number +}; + + + + diff --git a/muse/synti/zynaddsubfx/Effects/Echo.h b/muse/synti/zynaddsubfx/Effects/Echo.h new file mode 100644 index 00000000..8d6e6288 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Echo.h @@ -0,0 +1,71 @@ +/* + ZynAddSubFX - a software synthesizer + + Echo.h - Echo 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) 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 ECHO_H +#define ECHO_H + +#include "../globals.h" +#include "Effect.h" + +class Echo:public Effect{ + public: + Echo(int insertion,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~Echo(); + void out(REALTYPE *smpsl,REALTYPE *smpr); + void setpreset(unsigned char npreset); + void changepar(int npar,unsigned char value); + unsigned char getpar(int npar); + void cleanup(); + + void setdryonly(); + private: + //Parametrii + unsigned char Pvolume;//Volumul or E/R + unsigned char Ppanning;//Panning + unsigned char Pdelay; + unsigned char Plrdelay;// L/R delay difference + unsigned char Plrcross;// L/R Mixing + unsigned char Pfb;//Feed-back-ul + unsigned char Phidamp; + + void setvolume(unsigned char Pvolume); + void setpanning(unsigned char Ppanning); + void setdelay(unsigned char Pdelay); + void setlrdelay(unsigned char Plrdelay); + void setlrcross(unsigned char Plrcross); + void setfb(unsigned char Pfb); + void sethidamp(unsigned char Phidamp); + + //Parametrii reali + REALTYPE panning,lrcross,fb,hidamp; + int dl,dr,delay,lrdelay; + + void initdelays(); + REALTYPE *ldelay,*rdelay; + REALTYPE oldl,oldr;//pt. lpf + int kl,kr; +}; + + +#endif + + diff --git a/muse/synti/zynaddsubfx/Effects/Effect.C b/muse/synti/zynaddsubfx/Effects/Effect.C new file mode 100644 index 00000000..d9ec124c --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Effect.C @@ -0,0 +1,24 @@ +/* + ZynAddSubFX - a software synthesizer + + Effect.C - this class is inherited by the all effects(Reverb, Echo, ..) + 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) 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 "Effect.h" + diff --git a/muse/synti/zynaddsubfx/Effects/Effect.h b/muse/synti/zynaddsubfx/Effects/Effect.h new file mode 100644 index 00000000..14df43ba --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Effect.h @@ -0,0 +1,61 @@ +/* + ZynAddSubFX - a software synthesizer + + Effect.h - this class is inherited by the all effects(Reverb, Echo, ..) + 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) 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 EFFECT_H +#define EFFECT_H + +#include <pthread.h> +#include "../Misc/Util.h" +#include "../globals.h" +#include "../Params/FilterParams.h" + + +class Effect{ + public: + + virtual ~Effect(){}; + virtual void setpreset(unsigned char /*npreset*/){}; + virtual void changepar(int /*npar*/,unsigned char /*value*/){}; + virtual unsigned char getpar(int /*npar*/){return(0);}; + virtual void out(REALTYPE */*smpsl*/,REALTYPE */*smpsr*/){}; + virtual void cleanup(){}; + virtual REALTYPE getfreqresponse(REALTYPE /*freq*/){return (0);};//this is only used for EQ (for user interface) + + unsigned char Ppreset; + REALTYPE *efxoutl; + REALTYPE *efxoutr; + + REALTYPE outvolume;//this is the volume of effect and is public because need it in system effect. The out volume of such effects are always 1.0, so this setting tells me how is the volume to the Master Output only. + + REALTYPE volume; + + FilterParams *filterpars; + protected: + + int insertion;//1 for insertion effect +}; + +#endif + + + + diff --git a/muse/synti/zynaddsubfx/Effects/EffectLFO.C b/muse/synti/zynaddsubfx/Effects/EffectLFO.C new file mode 100644 index 00000000..1e800710 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/EffectLFO.C @@ -0,0 +1,110 @@ +/* + ZynAddSubFX - a software synthesizer + + EffectLFO.C - Stereo LFO used by some effects + 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) 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 <stdlib.h> +#include <stdio.h> +#include <math.h> + +#include "EffectLFO.h" + + +EffectLFO::EffectLFO(){ + xl=0.0;xr=0.0; + Pfreq=40; + Prandomness=0; + PLFOtype=0; + Pstereo=96; + + updateparams(); + + ampl1=(1-lfornd)+lfornd*RND; + ampl2=(1-lfornd)+lfornd*RND; + ampr1=(1-lfornd)+lfornd*RND; + ampr2=(1-lfornd)+lfornd*RND; +}; + +EffectLFO::~EffectLFO(){ +}; + + +/* + * Update the changed parameters + */ +void EffectLFO::updateparams(){ + 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; + + 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); +}; + + +/* + * Compute the shape of the LFO + */ +REALTYPE EffectLFO::getlfoshape(REALTYPE x){ + REALTYPE out; + 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; + break; + //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); +}; + +/* + * LFO output + */ +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(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/muse/synti/zynaddsubfx/Effects/EffectLFO.h b/muse/synti/zynaddsubfx/Effects/EffectLFO.h new file mode 100644 index 00000000..c1bb8cce --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/EffectLFO.h @@ -0,0 +1,50 @@ +/* + ZynAddSubFX - a software synthesizer + + EffectLFO.h - Stereo LFO used by some effects + 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) 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 EFFECT_LFO_H +#define EFFECT_LFO_H + +#include "../globals.h" + +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); + + REALTYPE xl,xr; + REALTYPE incx; + REALTYPE ampl1,ampl2,ampr1,ampr2;//necesar pentru "randomness" + REALTYPE lfointensity; + REALTYPE lfornd; + char lfotype; +}; + + +#endif diff --git a/muse/synti/zynaddsubfx/Effects/EffectMgr.C b/muse/synti/zynaddsubfx/Effects/EffectMgr.C new file mode 100644 index 00000000..354bc684 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/EffectMgr.C @@ -0,0 +1,291 @@ +/* + ZynAddSubFX - a software synthesizer + + EffectMgr.C - Effect manager, an interface betwen the program and effects + 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) 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 <stdlib.h> +#include <stdio.h> +#include "EffectMgr.h" + +EffectMgr::EffectMgr(int insertion_,pthread_mutex_t *mutex_){ + setpresettype("Peffect"); + efx=NULL; + nefx=0; + insertion=insertion_; + mutex=mutex_; + efxoutl=new REALTYPE[SOUND_BUFFER_SIZE]; + efxoutr=new REALTYPE[SOUND_BUFFER_SIZE];; + for (int i=0;i<SOUND_BUFFER_SIZE;i++){ + efxoutl[i]=0.0; + efxoutr[i]=0.0; + }; + filterpars=NULL; + dryonly=false; + defaults(); +}; + + +EffectMgr::~EffectMgr(){ + if (efx!=NULL) delete (efx); + delete (efxoutl); + delete (efxoutr); +}; + +void EffectMgr::defaults(){ + changeeffect(0); + setdryonly(false); +}; + +/* + * Change the effect + */ +void EffectMgr::changeeffect(int nefx_){ + cleanup(); + if (nefx==nefx_) return; + nefx=nefx_; + for (int i=0;i<SOUND_BUFFER_SIZE;i++){ + efxoutl[i]=0.0; + efxoutr[i]=0.0; + }; + + if (efx!=NULL) delete (efx); + switch (nefx){ + case 1:efx=new Reverb(insertion,efxoutl,efxoutr);break; + case 2:efx=new Echo(insertion,efxoutl,efxoutr);break; + case 3:efx=new Chorus(insertion,efxoutl,efxoutr);break; + case 4:efx=new Phaser(insertion,efxoutl,efxoutr);break; + case 5:efx=new Alienwah(insertion,efxoutl,efxoutr);break; + case 6:efx=new Distorsion(insertion,efxoutl,efxoutr);break; + case 7:efx=new EQ(insertion,efxoutl,efxoutr);break; + case 8:efx=new DynamicFilter(insertion,efxoutl,efxoutr);break; + //put more effect here + default:efx=NULL;break;//no effect (thru) + }; + + if (efx!=NULL) filterpars=efx->filterpars; +}; + +/* + * Obtain the effect number + */ +int EffectMgr::geteffect(){ + return (nefx); +}; + +/* + * Cleanup the current effect + */ +void EffectMgr::cleanup(){ + if (efx!=NULL) efx->cleanup(); +}; + + +/* + * Get the preset of the current effect + */ + +unsigned char EffectMgr::getpreset(){ + if (efx!=NULL) return(efx->Ppreset); + else return(0); +}; + +/* + * Change the preset of the current effect + */ +void EffectMgr::changepreset_nolock(unsigned char npreset){ + if (efx!=NULL) efx->setpreset(npreset); +}; + +/* + * Change the preset of the current effect(with thread locking) + */ +void EffectMgr::changepreset(unsigned char npreset){ + pthread_mutex_lock(mutex); + changepreset_nolock(npreset); + pthread_mutex_unlock(mutex); +}; + + +/* + * Change a parameter of the current effect + */ +void EffectMgr::seteffectpar_nolock(int npar,unsigned char 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){ + pthread_mutex_lock(mutex); + seteffectpar_nolock(npar,value); + pthread_mutex_unlock(mutex); +}; + +/* + * Get a parameter of the current effect + */ +unsigned char EffectMgr::geteffectpar(int npar){ + if (efx==NULL) return(0); + return(efx->getpar(npar)); +}; + + +/* + * Apply the effect + */ +void EffectMgr::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i; + if (efx==NULL){ + if (insertion==0) + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + smpsl[i]=0.0;smpsr[i]=0.0; + efxoutl[i]=0.0;efxoutr[i]=0.0; + }; + return; + }; + 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; + + if (nefx==7){//this is need only for the EQ effect + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + smpsl[i]=efxoutl[i]; + smpsr[i]=efxoutr[i]; + }; + return; + }; + + //Insertion effect + if (insertion!=0) { + REALTYPE v1,v2; + if (volume<0.5) { + v1=1.0; + v2=volume*2.0; + } else { + v1=(1.0-volume)*2.0; + v2=1.0; + }; + if ((nefx==1)||(nefx==2)) v2*=v2;//for Reverb and Echo, the wet function is not liniar + + if (dryonly){//this is used for instrument effect only + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + smpsl[i]*=v1; + smpsr[i]*=v1; + efxoutl[i]*=v2; + efxoutr[i]*=v2; + }; + }else{//normal instrument/insertion effect + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + smpsl[i]=smpsl[i]*v1+efxoutl[i]*v2; + smpsr[i]=smpsr[i]*v1+efxoutr[i]*v2; + }; + }; + } else {//System effect + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + efxoutl[i]*=2.0*volume; + efxoutr[i]*=2.0*volume; + smpsl[i]=efxoutl[i]; + smpsr[i]=efxoutr[i]; + }; + }; + +}; + +/* + * Get the effect volume for the system effect + */ +REALTYPE EffectMgr::sysefxgetvolume(){ + if (efx==NULL) return (1.0); + else return(efx->outvolume); +}; + + +/* + * Get the EQ response + */ +REALTYPE EffectMgr::getEQfreqresponse(REALTYPE freq){ + if (nefx==7) return(efx->getfreqresponse(freq)); + else return(0.0); +}; + + +void EffectMgr::setdryonly(bool value){ + dryonly=value; +}; + +void EffectMgr::add2XML(XMLwrapper *xml){ + xml->addpar("type",geteffect()); + + if ((efx==NULL)||(geteffect()==0)) return; + xml->addpar("preset",efx->Ppreset); + + xml->beginbranch("EFFECT_PARAMETERS"); + for (int n=0;n<128;n++){ + int par=geteffectpar(n); + if (par==0) continue; + xml->beginbranch("par_no",n); + xml->addpar("par",par); + xml->endbranch(); + }; + if (filterpars!=NULL){ + xml->beginbranch("FILTER"); + filterpars->add2XML(xml); + xml->endbranch(); + }; + xml->endbranch(); +}; + +void EffectMgr::getfromXML(XMLwrapper *xml){ + changeeffect(xml->getpar127("type",geteffect())); + + if ((efx==NULL)||(geteffect()==0)) return; + + 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; + + int par=geteffectpar(n); + seteffectpar_nolock(n,xml->getpar127("par",par)); + xml->exitbranch(); + }; + if (filterpars!=NULL){ + if (xml->enterbranch("FILTER")){ + filterpars->getfromXML(xml); + xml->exitbranch(); + }; + }; + xml->exitbranch(); + }; + cleanup(); +}; + + + diff --git a/muse/synti/zynaddsubfx/Effects/EffectMgr.h b/muse/synti/zynaddsubfx/Effects/EffectMgr.h new file mode 100644 index 00000000..42e9379d --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/EffectMgr.h @@ -0,0 +1,86 @@ +/* + ZynAddSubFX - a software synthesizer + + EffectMgr.h - Effect manager, an interface betwen the program and effects + 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) 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 EFFECTMGR_H +#define EFFECTMGR_H + +#include <pthread.h> + +#include "Effect.h" +#include "Reverb.h" +#include "Echo.h" +#include "Chorus.h" +#include "Phaser.h" +#include "Alienwah.h" +#include "Distorsion.h" +#include "EQ.h" +#include "DynamicFilter.h" +#include "../Misc/XMLwrapper.h" +#include "../Params/FilterParams.h" +#include "../Params/Presets.h" + + +class EffectMgr:public Presets{ + public: + EffectMgr(int insertion_,pthread_mutex_t *mutex_); + ~EffectMgr(); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + void out(REALTYPE *smpsl,REALTYPE *smpsr); + + void setdryonly(bool value); + + //get the output(to speakers) volume of the systemeffect + REALTYPE sysefxgetvolume(); + + void cleanup();//cleanup the effect + + void changeeffect(int nefx_); + int geteffect(); + void changepreset(unsigned char npreset); + void changepreset_nolock(unsigned char npreset); + unsigned char getpreset(); + void seteffectpar(int npar,unsigned char value); + void seteffectpar_nolock(int npar,unsigned char value);//sets the effect par without thread lock + unsigned char geteffectpar(int npar); + int insertion;//1 if the effect is connected as insertion effect + REALTYPE *efxoutl,*efxoutr; + + //used by UI + REALTYPE getEQfreqresponse(REALTYPE freq); + + FilterParams *filterpars; + + private: + int nefx; + Effect *efx; + pthread_mutex_t *mutex; + bool dryonly; +}; + +#endif + + + diff --git a/muse/synti/zynaddsubfx/Effects/Phaser.C b/muse/synti/zynaddsubfx/Effects/Phaser.C new file mode 100644 index 00000000..6f21f39e --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Phaser.C @@ -0,0 +1,260 @@ +/* + 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) 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 <math.h> +#include "Phaser.h" +#include <stdio.h> +#define PHASER_LFO_SHAPE 2 + +Phaser::Phaser(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){ + efxoutl=efxoutl_; + efxoutr=efxoutr_; + filterpars=NULL; + + oldl=NULL; + oldr=NULL; + insertion=insertion_; + + Ppreset=0; + setpreset(Ppreset); + cleanup(); +}; + +Phaser::~Phaser(){ + if (oldl!=NULL) delete [] oldl; + if (oldr!=NULL) delete [] oldr; +}; + + +/* + * 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+oldlgain*x1; + REALTYPE gr=rgain*x+oldrgain*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=oldl[j]; + oldl[j]=gl*tmp+inl; + inl=tmp-gl*oldl[j]; + }; + //Right channel + for (j=0;j<Pstages*2;j++){//Phasing routine + tmp=oldr[j]; + oldr[j]=gr*tmp+inr; + inr=tmp-gr*oldr[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; + + }; + + oldlgain=lgain; oldrgain=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; + oldlgain=0.0; + oldrgain=0.0; + for (int i=0;i<Pstages*2;i++) { + oldl[i]=0.0; + oldr[i]=0.0; + }; +}; + +/* + * Parameter control + */ +void Phaser::setdepth(unsigned char Pdepth){ + this->Pdepth=Pdepth; + depth=(Pdepth/127.0); +}; + + +void Phaser::setfb(unsigned char Pfb){ + this->Pfb=Pfb; + fb=(Pfb-64.0)/64.1; +}; + +void Phaser::setvolume(unsigned char Pvolume){ + this->Pvolume=Pvolume; + outvolume=Pvolume/127.0; + if (insertion==0) volume=1.0; + else volume=outvolume; +}; + +void Phaser::setpanning(unsigned char Ppanning){ + this->Ppanning=Ppanning; + panning=Ppanning/127.0; +}; + +void Phaser::setlrcross(unsigned char Plrcross){ + this->Plrcross=Plrcross; + lrcross=Plrcross/127.0; +}; + +void Phaser::setstages(unsigned char Pstages){ + if (oldl!=NULL) delete [] oldl; + if (oldr!=NULL) delete [] oldr; + if (Pstages>=MAX_PHASER_STAGES) Pstages=MAX_PHASER_STAGES-1; + this->Pstages=Pstages; + oldl=new REALTYPE[Pstages*2]; + oldr=new REALTYPE[Pstages*2]; + cleanup(); +}; + +void Phaser::setphase(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(int npar,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) value=1; + Poutsub=value; + break; + case 11:setphase(value); + break; + }; +}; + +unsigned char Phaser::getpar(int npar){ + 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/muse/synti/zynaddsubfx/Effects/Phaser.h b/muse/synti/zynaddsubfx/Effects/Phaser.h new file mode 100644 index 00000000..b4382668 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Phaser.h @@ -0,0 +1,70 @@ +/* + 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) 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 "Effect.h" +#include "EffectLFO.h" + +#define MAX_PHASER_STAGES 12 +class Phaser:public Effect { + public: + Phaser(int insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~Phaser(); + void out(REALTYPE *smpsl,REALTYPE *smpsr); + void setpreset(unsigned char npreset); + void changepar(int npar,unsigned char value); + unsigned char getpar(int npar); + void cleanup(); + void setdryonly(); + + private: + //Parametrii Phaser + EffectLFO lfo;//lfo-ul Phaser + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth;//the depth of the Phaser + unsigned char Pfb;//feedback + unsigned char Plrcross;//feedback + unsigned char Pstages; + unsigned char Poutsub;//if I wish to substract the output instead of the adding it + unsigned char Pphase; + + //Control Parametrii + void setvolume(unsigned char Pvolume); + void setpanning(unsigned char Ppanning); + void setdepth(unsigned char Pdepth); + void setfb(unsigned char Pfb); + void setlrcross(unsigned char Plrcross); + void setstages(unsigned char Pstages); + void setphase(unsigned char Pphase); + + //Valorile interne + int insertion; + REALTYPE panning,fb,depth,lrcross,fbl,fbr,phase; + REALTYPE *oldl,*oldr; + REALTYPE oldlgain,oldrgain; +}; + +#endif + diff --git a/muse/synti/zynaddsubfx/Effects/Reverb.C b/muse/synti/zynaddsubfx/Effects/Reverb.C new file mode 100644 index 00000000..b39e41c9 --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Reverb.C @@ -0,0 +1,438 @@ +/* + 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) 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 <stdio.h> + +#include <math.h> +#include <stdlib.h> +#include "Reverb.h" + +/*TODO: EarlyReflections,Prdelay,Perbalance */ + +Reverb::Reverb(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){ + efxoutl=efxoutl_; + efxoutr=efxoutr_; + inputbuf=new REALTYPE[SOUND_BUFFER_SIZE]; + filterpars=NULL; + + insertion=insertion_; + //defaults + Ppreset=0; + 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;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; +}; + +/* + * 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; + //Initial delay r + if (idelay!=NULL){ + REALTYPE tmp=inputbuf[i]+idelay[idelayk]*idelayfb; + inputbuf[i]=idelay[idelayk]; + idelay[idelayk]=tmp; + idelayk++;if (idelayk>=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;i<SOUND_BUFFER_SIZE;i++){ + efxoutl[i]*=lvol; + efxoutr[i]*=rvol; + }; +}; + + +/* + * Parameter control + */ +void Reverb::setvolume(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(unsigned char Ppan){ + this->Ppan=Ppan; + pan=(REALTYPE)Ppan/127.0; +}; + +void Reverb::settime(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(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(unsigned char Pidelayfb){ + this->Pidelayfb=Pidelayfb; + idelayfb=Pidelayfb/128.0; +}; + +void Reverb::sethpf(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(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;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(); +}; + +void Reverb::setroomsize(unsigned char Proomsize){ + if (Proomsize==0) Proomsize=64;//this is because the older versions consider roomsize=0 + this->Proomsize=Proomsize; + roomsize=(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<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(int npar,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; + }; +}; + +unsigned char Reverb::getpar(int npar){ + 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; + }; + return(0);//in case of bogus "parameter" +}; + + + diff --git a/muse/synti/zynaddsubfx/Effects/Reverb.h b/muse/synti/zynaddsubfx/Effects/Reverb.h new file mode 100644 index 00000000..99c9890c --- /dev/null +++ b/muse/synti/zynaddsubfx/Effects/Reverb.h @@ -0,0 +1,127 @@ +/* + 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) 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 + +class Reverb:public Effect { + public: + Reverb(int insertion,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~Reverb(); + void out(REALTYPE *smps_l,REALTYPE *smps_r); + void cleanup(); + + void setpreset(unsigned char npreset); + void changepar(int npar,unsigned char value); + unsigned char getpar(int npar); + + 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 + unsigned char Plohidamp;// 0..63 lpf,64=off,65..127=hpf(TODO) + + //Reverb type + unsigned char Ptype; + + //Room Size + unsigned char Proomsize; + + //parameter control + void setvolume(unsigned char Pvolume); + void setpan(unsigned char Ppan); + void settime(unsigned char Ptime); + void setlohidamp(unsigned char Plohidamp); + void setidelay(unsigned char Pidelay); + void setidelayfb(unsigned char Pidelayfb); + void sethpf(unsigned char Phpf); + void setlpf(unsigned char Plpf); + void settype(unsigned char Ptype); + void setroomsize(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]; + + //Valorile interne + + REALTYPE *comb[REV_COMBS*2]; + + int combk[REV_COMBS*2]; + REALTYPE combfb[REV_COMBS*2];//feedback-ul fiecarui filtru "comb" + REALTYPE lpcomb[REV_COMBS*2];//pentru Filtrul LowPass + + REALTYPE *ap[REV_APS*2]; + + int apk[REV_APS*2]; + + REALTYPE *idelay; + AnalogFilter *lpf,*hpf;//filters + REALTYPE *inputbuf; + + void processmono(int ch,REALTYPE *output); +}; + + + + +#endif + diff --git a/muse/synti/zynaddsubfx/Input/ALSAMidiIn.C b/muse/synti/zynaddsubfx/Input/ALSAMidiIn.C new file mode 100644 index 00000000..13aa14d1 --- /dev/null +++ b/muse/synti/zynaddsubfx/Input/ALSAMidiIn.C @@ -0,0 +1,96 @@ +/* + ZynAddSubFX - a software synthesizer + + ALSAMidiIn.C - Midi input for ALSA (this creates an ALSA virtual port) + 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) 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 "ALSAMidiIn.h" +#include <stdlib.h> +#include <stdio.h> + + +ALSAMidiIn::ALSAMidiIn(){ + int alsaport; + inputok=0; + char portname[50]; + sprintf(portname,"ZynAddSubFX"); + + midi_handle=NULL; + + if (snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_INPUT,0)!=0) return; + + snd_seq_set_client_name(midi_handle,"ZynAddSubFX");//thanks to Frank Neumann + + alsaport = snd_seq_create_simple_port(midi_handle,portname + ,SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE + ,SND_SEQ_PORT_TYPE_SYNTH); + if (alsaport<0) return; + + inputok=1; +}; + +ALSAMidiIn::~ALSAMidiIn(){ + snd_seq_close(midi_handle); +}; + + +/* + * Get the midi command,channel and parameters + */ +void ALSAMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams){ + snd_seq_event_t *midievent=NULL; + cmdtype=MidiNull; + + if (inputok==0){ + return; + }; + + snd_seq_event_input(midi_handle,&midievent); + + 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; + break; + case SND_SEQ_EVENT_NOTEOFF: + 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; + 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; + //fprintf(stderr,"t=%d val=%d\n",midievent->data.control.param,midievent->data.control.value); + break; + + }; +}; + + diff --git a/muse/synti/zynaddsubfx/Input/ALSAMidiIn.h b/muse/synti/zynaddsubfx/Input/ALSAMidiIn.h new file mode 100644 index 00000000..dc4a0b0c --- /dev/null +++ b/muse/synti/zynaddsubfx/Input/ALSAMidiIn.h @@ -0,0 +1,42 @@ +/* + ZynAddSubFX - a software synthesizer + + ALSAMidiIn.h - Midi input for ALSA (this creates an ALSA virtual port) + 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) 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 ALSA_MIDI_IN_H +#define ALSA_MIDI_IN_H + +#include <alsa/asoundlib.h> +#include "MidiIn.h" + + +class ALSAMidiIn:public MidiIn{ + public: + ALSAMidiIn(); + ~ALSAMidiIn(); + void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); + + private: + snd_seq_t *midi_handle; +}; + + +#endif + diff --git a/muse/synti/zynaddsubfx/Input/MidiIn.C b/muse/synti/zynaddsubfx/Input/MidiIn.C new file mode 100644 index 00000000..3063b793 --- /dev/null +++ b/muse/synti/zynaddsubfx/Input/MidiIn.C @@ -0,0 +1,73 @@ +/* + ZynAddSubFX - a software synthesizer + + MidiIn.C - This class is inherited by all the Midi input classes + 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) 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 "../globals.h" +#include "MidiIn.h" + +int MidiIn::getcontroller(unsigned char b){ + int ctl=C_NULL; + switch (b){ + case 1:ctl=C_modwheel;//Modulation Wheel + break; + case 7:ctl=C_volume;//Volume + break; + case 10:ctl=C_panning;//Panning + break; + case 11:ctl=C_expression;//Expression + break; + case 64:ctl=C_sustain;//Sustain pedal + break; + case 65:ctl=C_portamento;//Portamento + break; + case 71:ctl=C_filterq;//Filter Q (Sound Timbre) + break; + case 74:ctl=C_filtercutoff;//Filter Cutoff (Brightness) + break; + case 75:ctl=C_bandwidth;//BandWidth + break; + case 76:ctl=C_fmamp;//FM amplitude + break; + case 77:ctl=C_resonance_center;//Resonance Center Frequency + break; + case 78:ctl=C_resonance_bandwidth;//Resonance Bandwith + break; + case 120:ctl=C_allsoundsoff;//All Sounds OFF + break; + case 121:ctl=C_resetallcontrollers;//Reset All Controllers + break; + case 123:ctl=C_allnotesoff;//All Notes OFF + break; + //RPN and NRPN + case 0x06:ctl=C_dataentryhi;//Data Entry (Coarse) + break; + case 0x26:ctl=C_dataentrylo;//Data Entry (Fine) + break; + case 99:ctl=C_nrpnhi;//NRPN (Coarse) + break; + case 98:ctl=C_nrpnlo;//NRPN (Fine) + break; + default:ctl=C_NULL;//unknown controller + //fprintf(stderr,"Controller=%d , par=%d\n",midievent->data.control.param,cmdparams[1]); + break; + }; + return(ctl); +}; diff --git a/muse/synti/zynaddsubfx/Input/MidiIn.h b/muse/synti/zynaddsubfx/Input/MidiIn.h new file mode 100644 index 00000000..8a8277d0 --- /dev/null +++ b/muse/synti/zynaddsubfx/Input/MidiIn.h @@ -0,0 +1,42 @@ +/* + ZynAddSubFX - a software synthesizer + + MidiIn.h - This class is inherited by all the Midi input classes + 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) 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 MIDI_IN_H +#define MIDI_IN_H + +#include "../globals.h" + +enum MidiCmdType{MidiNull,MidiNoteOFF,MidiNoteON,MidiController}; +#define MP_MAX_BYTES 4000 //in case of loooong SYS_EXes + +class MidiIn{ + public: + virtual void getmidicmd(MidiCmdType &/*cmdtype*/,unsigned char &/*cmdchan*/,int */*cmdparams*/){}; + virtual ~MidiIn(){}; + int getcontroller(unsigned char b); + protected: + int inputok;//1 if I can read midi bytes from input ports +}; + + +#endif + diff --git a/muse/synti/zynaddsubfx/Input/NULLMidiIn.C b/muse/synti/zynaddsubfx/Input/NULLMidiIn.C new file mode 100644 index 00000000..5c2b56d2 --- /dev/null +++ b/muse/synti/zynaddsubfx/Input/NULLMidiIn.C @@ -0,0 +1,43 @@ +/* + ZynAddSubFX - a software synthesizer + + NULLMidiIn.C - a dummy Midi port + 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) 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 "NULLMidiIn.h" +#include <stdlib.h> +#include <stdio.h> +#include <unistd.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,unsigned char *cmdparams){ + cmdtype=MidiNull; +}; + + diff --git a/muse/synti/zynaddsubfx/Input/NULLMidiIn.h b/muse/synti/zynaddsubfx/Input/NULLMidiIn.h new file mode 100644 index 00000000..6f7b845e --- /dev/null +++ b/muse/synti/zynaddsubfx/Input/NULLMidiIn.h @@ -0,0 +1,40 @@ +/* + ZynAddSubFX - a software synthesizer + + NULLMidiIn.h - a dummy Midi port + 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) 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 NULL_MIDI_IN_H +#define NULL_MIDI_IN_H + +#include "MidiIn.h" + + +class NULLMidiIn:public MidiIn{ + public: + NULLMidiIn(); + ~NULLMidiIn(); + void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,unsigned char *cmdparams); + + private: +}; + + +#endif + diff --git a/muse/synti/zynaddsubfx/Input/OSSMidiIn.C b/muse/synti/zynaddsubfx/Input/OSSMidiIn.C new file mode 100644 index 00000000..5a6ae509 --- /dev/null +++ b/muse/synti/zynaddsubfx/Input/OSSMidiIn.C @@ -0,0 +1,115 @@ +/* + ZynAddSubFX - a software synthesizer + + OSSMidiIn.C - Midi input for Open Sound System + 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) 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 <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/soundcard.h> + +#include "OSSMidiIn.h" +#include "../Misc/Util.h" + +OSSMidiIn::OSSMidiIn(){ + inputok=0; + midi_handle=open(config.cfg.LinuxOSSSeqInDev,O_RDONLY,0); + if (midi_handle!=-1) inputok=1; + + 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); + }; + return(tmp[1]); +}; + +unsigned char OSSMidiIn::getmidibyte(){ + unsigned char b; + do { + 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){ + unsigned char tmp,i; + if (inputok==0) { + cmdtype=MidiNull; + return; + }; + i=0; + if (lastmidicmd==0){//asteapta prima data pana cand vine prima comanda midi + while (tmp<0x80) tmp=getmidibyte(); + 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>=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>=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/muse/synti/zynaddsubfx/Input/OSSMidiIn.h b/muse/synti/zynaddsubfx/Input/OSSMidiIn.h new file mode 100644 index 00000000..302a812e --- /dev/null +++ b/muse/synti/zynaddsubfx/Input/OSSMidiIn.h @@ -0,0 +1,48 @@ +/* + ZynAddSubFX - a software synthesizer + + OSSMidiIn.h - Midi input for Open Sound System + 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) 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 OSS_MIDI_IN_H +#define OSS_MIDI_IN_H + +#include "MidiIn.h" + +class OSSMidiIn:public MidiIn{ + 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 + +}; + + +#endif + diff --git a/muse/synti/zynaddsubfx/Input/WINMidiIn.C b/muse/synti/zynaddsubfx/Input/WINMidiIn.C new file mode 100644 index 00000000..c20841bb --- /dev/null +++ b/muse/synti/zynaddsubfx/Input/WINMidiIn.C @@ -0,0 +1,83 @@ +/* + ZynAddSubFX - a software synthesizer + + WINMidiIn.C - Midi input for Windows + 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) 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 <stdlib.h> +#include <stdio.h> +#include <windows.h> +#include <mmsystem.h> +#include <pthread.h> + +#include "WINMidiIn.h" +#include "MidiIn.h" +#include "../Misc/Util.h" + +Master *winmaster; +HMIDIIN winmidiinhandle; +MidiIn midictl;//used to convert the controllers to ZynAddSubFX controllers + +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; + //printf("%x %x %x\n",cmd,par1,par2);fflush(stdout); + int cmdchan=cmd&0x0f; + int cmdtype=(cmd>>4)&0x0f; + + int tmp=0; + pthread_mutex_lock(&winmaster->mutex); + switch(cmdtype){ + case(0x8)://noteon + winmaster->NoteOff(cmdchan,par1); + break; + case(0x9)://noteoff + winmaster->NoteOn(cmdchan,par1,par2&0xff); + break; + 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); + break; + default:break; + }; + pthread_mutex_unlock(&winmaster->mutex); + + }; +}; + +void InitWinMidi(Master *master_){ + winmaster=master_; + + 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/muse/synti/zynaddsubfx/Input/WINMidiIn.h b/muse/synti/zynaddsubfx/Input/WINMidiIn.h new file mode 100644 index 00000000..95c3791d --- /dev/null +++ b/muse/synti/zynaddsubfx/Input/WINMidiIn.h @@ -0,0 +1,34 @@ +/* + ZynAddSubFX - a software synthesizer + + WINMidiIn.h - Midi input for Windows + 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) 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 WIN_MIDI_IN_H +#define WIN_MIDI_IN_H + + +#include "../Misc/Master.h" + +void InitWinMidi(Master *master_); +void StopWinMidi(); + + +#endif + diff --git a/muse/synti/zynaddsubfx/Misc/Bank.C b/muse/synti/zynaddsubfx/Misc/Bank.C new file mode 100644 index 00000000..7d8c6f00 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Bank.C @@ -0,0 +1,562 @@ +/* + ZynAddSubFX - a software synthesizer + + Bank.h - Instrument Bank + 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) 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 "Bank.h" +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <dirent.h> +#include <sys/stat.h> + +#include <sys/types.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> + +#include "Config.h" + +#define INSTRUMENT_EXTENSION ".xiz" + +//if this file exists into a directory, this make the directory to be considered as a bank, even if it not contains a instrument file +#define FORCE_BANK_DIR_FILE ".bankdir" + +Bank::Bank(){ + + + ZERO(defaultinsname,PART_MAX_NAME_LEN); + snprintf(defaultinsname,PART_MAX_NAME_LEN,"%s"," "); + + for (int i=0;i<BANK_SIZE;i++){ + ins[i].used=false; + ins[i].filename=NULL; + ins[i].info.PADsynth_used=false; + }; + dirname=NULL; + clearbank(); + + + + for (int i=0;i<MAX_NUM_BANKS;i++){ + banks[i].dir=NULL; + banks[i].name=NULL; + }; + + bankfiletitle=dirname; + + loadbank(config.cfg.currentBankDir); + +}; + +Bank::~Bank(){ + for (int i=0;i<MAX_NUM_BANKS;i++){ + if (banks[i].dir!=NULL) delete (banks[i].dir); + if (banks[i].name!=NULL) delete (banks[i].name); + }; + + clearbank(); +}; + +/* + * Get the name of an instrument from the bank + */ +char *Bank::getname (unsigned int ninstrument){ + if (emptyslot(ninstrument)) return (defaultinsname); + return (ins[ninstrument].name); +}; + +/* + * Get the numbered name of an instrument from the bank + */ +char *Bank::getnamenumbered (unsigned int ninstrument){ + if (emptyslot(ninstrument)) return (defaultinsname); + snprintf(tmpinsname[ninstrument],PART_MAX_NAME_LEN+15,"%d. %s",ninstrument+1,getname(ninstrument)); + return(tmpinsname[ninstrument]); +}; + +/* + * Changes the name of an instrument (and the filename) + */ +void Bank::setname(unsigned int ninstrument,const char *newname,int newslot){ + if (emptyslot(ninstrument)) return; + + char newfilename[1000+1],tmpfilename[100+1]; + + 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'; + + //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; + + tmpfilename[i]='_'; + }; + + 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]); + +}; + +/* + * 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 (ins[ninstrument].used) return (0); + else return(1); +}; + +/* + * Removes the instrument from the bank + */ +void Bank::clearslot(unsigned int ninstrument){ + 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){ + clearslot(ninstrument); + + const int maxfilename=200; + char tmpfilename[maxfilename+20]; + ZERO(tmpfilename,maxfilename+20); + + 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'; + + //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; + + tmpfilename[i]='_'; + }; + + strncat(tmpfilename,".xiz",maxfilename+10); + + int fnsize=strlen(dirname)+strlen(tmpfilename)+10; + char *filename=new char[fnsize+4]; + ZERO(filename,fnsize+2); + + snprintf(filename,fnsize,"%s/%s",dirname,tmpfilename); + + remove(filename); + part->saveXML(filename); + addtobank(ninstrument,tmpfilename,(char *) part->Pname); + + delete(filename); +}; + +/* + * Loads the instrument from the bank + */ +void Bank::loadfromslot(unsigned int ninstrument,Part *part){ + if (emptyslot(ninstrument)) return; + + part->defaultsinstrument(); + +// printf("load: %s\n",ins[ninstrument].filename); + + part->loadXMLinstrument(ins[ninstrument].filename); + +}; + + +/* + * Makes current a bank directory + */ +int Bank::loadbank(const char *bankdirname){ + DIR *dir=opendir(bankdirname); + clearbank(); + + if (dir==NULL) return(-1); + + if (dirname!=NULL) delete(dirname); + dirname=new char[strlen(bankdirname)+1]; + snprintf(dirname,strlen(bankdirname)+1,"%s",bankdirname); + + bankfiletitle=dirname; + + // printf("loadbank %s/\n",bankdirname); + struct dirent *fn; + + while ((fn=readdir(dir))){ + const char *filename= fn->d_name; + + //sa verific daca e si extensia dorita + 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; + + 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'); + startname++; + }; + }; + + + if ((startname+1)<strlen(filename)) startname++;//to take out the "-" + + char name[PART_MAX_NAME_LEN+1]; + ZERO(name,PART_MAX_NAME_LEN+1); + snprintf(name,PART_MAX_NAME_LEN,"%s",filename); + + //remove the file extension + 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); + }; + + }; + + + closedir(dir); + + if (dirname!=NULL) { + sprintf(config.cfg.currentBankDir,"%s",dirname); + }; + + return(0); +}; + +/* + * Makes a new bank, put it on a file and makes it current bank + */ +int Bank::newbank(const char *newbankdirname){ + int result; + char tmpfilename[MAX_STRING_SIZE]; + char bankdir[MAX_STRING_SIZE]; + 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); +#ifdef OS_WINDOWS + result=mkdir(bankdir); +#else + result=mkdir(bankdir,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif + if (result<0) return(-1); + + snprintf(tmpfilename,MAX_STRING_SIZE,"%s/%s",bankdir,FORCE_BANK_DIR_FILE); +// printf("%s\n",tmpfilename); + FILE *tmpfile=fopen(tmpfilename,"w+"); + fclose(tmpfile); + + return(loadbank(bankdir)); +}; + +/* + * Check if the bank is locked (i.e. the file opened was readonly) + */ +int Bank::locked(){ + 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 (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; + + 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){ + 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); +}; + + +/* + * Re-scan for directories containing instrument banks + */ + +void Bank::rescanforbanks(){ + for (int i=0;i<MAX_NUM_BANKS;i++){ + if (banks[i].dir!=NULL) delete (banks[i].dir); + if (banks[i].name!=NULL) delete (banks[i].name); + banks[i].dir=NULL; + banks[i].name=NULL; + }; + + for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) if (config.cfg.bankRootDirList[i]!=NULL) scanrootdir(config.cfg.bankRootDirList[i]); + + //sort the banks + for (int j=0;j<MAX_NUM_BANKS-1;j++){ + for (int i=j+1;i<MAX_NUM_BANKS;i++){ + if (Bank_compar(&banks[i],&banks[j])) { + char *tmpname=banks[i].name; + char *tmpdir=banks[i].dir; + + banks[i].name=banks[j].name; + banks[i].dir=banks[j].dir; + + banks[j].name=tmpname; + banks[j].dir=tmpdir; + + }; + }; + }; + + //remove duplicate bank names + int dupl=0; + for (int j=0;j<MAX_NUM_BANKS-1;j++){ + for (int i=j+1;i<MAX_NUM_BANKS;i++){ + if ((banks[i].name==NULL)||(banks[j].name==NULL)) continue; + if (strcmp(banks[i].name,banks[j].name)==0) {//add a [1] to the first bankname and [n] to others + char *tmpname=banks[i].name; + banks[i].name=new char[strlen(tmpname)+100]; + sprintf(banks[i].name,"%s[%d]",tmpname,dupl+2); + delete(tmpname); + + if (dupl==0){ + char *tmpname=banks[j].name; + banks[j].name=new char[strlen(tmpname)+100]; + sprintf(banks[j].name,"%s[1]",tmpname); + delete(tmpname); + }; + + dupl++; + } else dupl=0; + }; + }; + +}; + + + +// private stuff + +void Bank::scanrootdir(char *rootdir){ +// printf("Scanning root dir:%s\n",rootdir); + DIR *dir=opendir(rootdir); + if (dir==NULL) return; + + const int maxdirsize=1000; + struct { + char dir[maxdirsize]; + char name[maxdirsize]; + }bank; + + char *separator="/"; + if (strlen(rootdir)) { + char tmp=rootdir[strlen(rootdir)-1]; + if ((tmp=='/') || (tmp=='\\')) separator=""; + }; + + struct dirent *fn; + 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); + //find out if the directory contains at least 1 instrument + bool isbank=false; + + 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 + }; + }; + + closedir(d); + + if (isbank) { + int pos=-1; + for (int i=1;i<MAX_NUM_BANKS;i++){ //banks[0] e liber intotdeauna + if (banks[i].name==NULL) { + pos=i; + break; + }; + }; + + 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<BANK_SIZE;i++) deletefrombank(i); + if (dirname!=NULL) delete(dirname); + bankfiletitle=NULL; + dirname=NULL; +}; + +int Bank::addtobank(int pos, const char *filename, const char* name){ + 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; + break; + }; + + }; + + 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); + + 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); + + //see if PADsynth is used + if (config.cfg.CheckPADsynth){ + XMLwrapper *xml=new XMLwrapper(); + xml->checkfileinformation(ins[pos].filename); + + ins[pos].info.PADsynth_used=xml->information.PADsynth_used; + delete(xml); + } else ins[pos].info.PADsynth_used=false; + + return(0); +}; + +bool Bank::isPADsynth_used(unsigned int ninstrument){ + 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; + }; + + ZERO(tmpinsname[pos],PART_MAX_NAME_LEN+20); + +}; + diff --git a/muse/synti/zynaddsubfx/Misc/Bank.h b/muse/synti/zynaddsubfx/Misc/Bank.h new file mode 100644 index 00000000..1a2f4382 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Bank.h @@ -0,0 +1,100 @@ +/* + ZynAddSubFX - a software synthesizer + + Bank.C - Instrument Bank + 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) 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 BANK_H +#define BANK_H + +#include "../globals.h" +#include "XMLwrapper.h" +#include "Part.h" + +#define BANK_SIZE 160 + +/* + * The max. number of banks that are used + */ +#define MAX_NUM_BANKS 400 + + +class Bank{ + public: + 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 + int emptyslot(unsigned int ninstrument); + + void clearslot(unsigned int ninstrument); + void savetoslot(unsigned int ninstrument,Part *part); + void loadfromslot(unsigned int ninstrument,Part *part); + + void swapslot(unsigned int n1,unsigned int n2); + + 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(); + + void rescanforbanks(); + + struct bankstruct{ + char *dir; + char *name; + }; + + bankstruct banks[MAX_NUM_BANKS]; + + 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); + + void deletefrombank(int pos); + + void clearbank(); + + 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]; + + char *dirname; + + void scanrootdir(char *rootdir);//scans a root dir for banks +}; + +#endif + diff --git a/muse/synti/zynaddsubfx/Misc/Config.C b/muse/synti/zynaddsubfx/Misc/Config.C new file mode 100644 index 00000000..5014708a --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Config.C @@ -0,0 +1,331 @@ +/* + ZynAddSubFX - a software synthesizer + + Config.C - Configuration file functions + Copyright (C) 2003-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) 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 <stdio.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> + +#ifdef OS_WINDOWS +#include <windows.h> +#include <mmsystem.h> +#endif + +#include "Config.h" +#include "XMLwrapper.h" + +Config::Config(){ +}; +void Config::init(){ + maxstringsize=MAX_STRING_SIZE;//for ui + //defaults + cfg.SampleRate=44100; + cfg.SoundBufferSize=256; + cfg.OscilSize=512; + 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.DumpFile=new char[MAX_STRING_SIZE]; + snprintf(cfg.DumpFile,MAX_STRING_SIZE,"zynaddsubfx_dump.txt"); + + cfg.WindowsWaveOutId=0; + cfg.WindowsMidiInId=0; + + cfg.BankUIAutoClose=0; + cfg.DumpNotesToFile=0; + cfg.DumpAppend=1; + + cfg.GzipCompression=3; + + cfg.Interpolation=0; + cfg.CheckPADsynth=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; +#endif + winmididevices=new winmidionedevice[winmidimax]; + for (int i=0;i<winmidimax;i++) { + winmididevices[i].name=new char[MAX_STRING_SIZE]; + for (int j=0;j<MAX_STRING_SIZE;j++) winmididevices[i].name[j]='\0'; + }; + + +//get the midi input devices name +#ifdef WINMIDIIN + MIDIINCAPS midiincaps; + for (int i=0;i<winmidimax;i++){ + if (! midiInGetDevCaps(i,&midiincaps,sizeof(MIDIINCAPS))) + snprintf(winmididevices[i].name,MAX_STRING_SIZE,"%s",midiincaps.szPname); + }; +#endif + for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) cfg.bankRootDirList[i]=NULL; + cfg.currentBankDir=new char[MAX_STRING_SIZE]; + sprintf(cfg.currentBankDir,"./testbnk"); + + for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) cfg.presetsDirList[i]=NULL; + + char filename[MAX_STRING_SIZE]; + getConfigFileName(filename,MAX_STRING_SIZE); + readConfig(filename); + + if (cfg.bankRootDirList[0]==NULL){ +#if defined(OS_LINUX) + //banks + cfg.bankRootDirList[0]=new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[0],"~/banks"); + + cfg.bankRootDirList[1]=new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[1],"./"); + + cfg.bankRootDirList[2]=new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[2],"/usr/share/zynaddsubfx/banks"); + + cfg.bankRootDirList[3]=new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[3],"/usr/local/share/zynaddsubfx/banks"); + + cfg.bankRootDirList[4]=new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[4],"../banks"); + + cfg.bankRootDirList[5]=new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[5],"banks"); + +#else + //banks + cfg.bankRootDirList[0]=new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[0],"./"); + +#ifdef VSTAUDIOOUT + cfg.bankRootDirList[1]=new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[1],"c:/Program Files/ZynAddSubFX/banks"); +#else + cfg.bankRootDirList[1]=new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[1],"../banks"); +#endif + cfg.bankRootDirList[2]=new char[MAX_STRING_SIZE]; + sprintf(cfg.bankRootDirList[2],"banks"); + +#endif + }; + + if (cfg.presetsDirList[0]==NULL){ +#if defined(OS_LINUX) + //presets + cfg.presetsDirList[0]=new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[0],"./"); + + cfg.presetsDirList[1]=new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[1],"../presets"); + + cfg.presetsDirList[2]=new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[2],"presets"); + + cfg.presetsDirList[3]=new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[3],"/usr/share/zynaddsubfx/presets"); + + cfg.presetsDirList[4]=new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[4],"/usr/local/share/zynaddsubfx/presets"); + +#else + //presets + cfg.presetsDirList[0]=new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[0],"./"); + +#ifdef VSTAUDIOOUT + cfg.presetsDirList[1]=new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[1],"c:/Program Files/ZynAddSubFX/presets"); +#else + cfg.presetsDirList[1]=new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[1],"../presets"); +#endif + + cfg.presetsDirList[2]=new char[MAX_STRING_SIZE]; + sprintf(cfg.presetsDirList[2],"presets"); +#endif + }; + +}; + +Config::~Config(){ + + delete(cfg.LinuxOSSWaveOutDev); + delete(cfg.LinuxOSSSeqInDev); + delete(cfg.DumpFile); + + for (int i=0;i<winmidimax;i++) delete (winmididevices[i].name); + delete(winmididevices); +}; + + +void Config::save(){ + char filename[MAX_STRING_SIZE]; + getConfigFileName(filename,MAX_STRING_SIZE); + saveConfig(filename); +}; + +void Config::clearbankrootdirlist(){ + for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) { + if (cfg.bankRootDirList[i]==NULL) delete(cfg.bankRootDirList[i]); + cfg.bankRootDirList[i]=NULL; + }; +}; + +void Config::clearpresetsdirlist(){ + for (int i=0;i<MAX_BANK_ROOT_DIRS;i++) { + if (cfg.presetsDirList[i]==NULL) delete(cfg.presetsDirList[i]); + cfg.presetsDirList[i]=NULL; + }; +}; + +void Config::readConfig(char *filename){ + 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.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); + + 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); + + //get bankroot dirs + 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;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); + + //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); + + xmlcfg->exitbranch(); + }; + delete(xmlcfg); + + cfg.OscilSize=(int) pow(2,ceil(log (cfg.OscilSize-1.0)/log(2.0))); + +}; + +void Config::saveConfig(char *filename){ + 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("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("check_pad_synth",cfg.CheckPADsynth); + + xmlcfg->addparstr("bank_current",cfg.currentBankDir); + + xmlcfg->addpar("user_interface_mode",cfg.UserInterfaceMode); + xmlcfg->addpar("virtual_keyboard_layout",cfg.VirKeybLayout); + + + 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;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); + + //linux stuff + 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->endbranch(); + + int tmp=cfg.GzipCompression; + cfg.GzipCompression=0; + xmlcfg->saveXMLfile(filename); + cfg.GzipCompression=tmp; + + delete(xmlcfg); +}; + +void Config::getConfigFileName(char *name, int namesize){ + name[0]=0; +#ifdef OS_LINUX + snprintf(name,namesize,"%s%s",getenv("HOME"),"/.zynaddsubfxXML.cfg"); +#else + snprintf(name,namesize,"%s","zynaddsubfxXML.cfg"); +#endif + +}; + diff --git a/muse/synti/zynaddsubfx/Misc/Config.h b/muse/synti/zynaddsubfx/Misc/Config.h new file mode 100644 index 00000000..800a1823 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Config.h @@ -0,0 +1,67 @@ +/* + ZynAddSubFX - a software synthesizer + + Config.h - Configuration file functions + Copyright (C) 2003-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) 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 CONFIG_H +#define CONFIG_H +#include "../globals.h" +#define MAX_STRING_SIZE 4000 +#define MAX_BANK_ROOT_DIRS 100 + +class Config{ + public: + Config(); + ~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; + + void clearbankrootdirlist(); + void clearpresetsdirlist(); + void init(); + void save(); + + private: + void readConfig(char *filename); + void saveConfig(char *filename); + void getConfigFileName(char *name,int namesize); +}; +#endif + diff --git a/muse/synti/zynaddsubfx/Misc/Dump.C b/muse/synti/zynaddsubfx/Misc/Dump.C new file mode 100644 index 00000000..2b5bd810 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Dump.C @@ -0,0 +1,99 @@ +/* + ZynAddSubFX - a software synthesizer + + Dump.C - It dumps the notes to a text file + + 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) 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 <stdlib.h> +#include <time.h> +#include "Util.h" +#include "Dump.h" + +Dump dump; + +Dump::Dump(){ + 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); + fclose(file); + }; +}; + +void Dump::startnow(){ + 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"); + + 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"); + }; +}; + +void Dump::inctick(){ + tick++; +}; + + +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 (vel!=0) keyspressed++; +#ifndef JACKAUDIOOUT + if (k++>25) { + fflush(file); + k=0; + }; +#endif +}; + +void Dump::dumpcontroller(char chan,unsigned int type,int par){ + if (file==NULL) return; + switch(type){ + case C_pitchwheel:fprintf(file,"P %d -> %d %d\n",tick,chan,par); + break; + default:fprintf(file,"C %d -> %d %d %d\n",tick,chan,type,par); + break; + }; +#ifndef JACKAUDIOOUT + if (k++>25) { + fflush(file); + k=0; + }; +#endif +}; + + diff --git a/muse/synti/zynaddsubfx/Misc/Dump.h b/muse/synti/zynaddsubfx/Misc/Dump.h new file mode 100644 index 00000000..e5a49570 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Dump.h @@ -0,0 +1,43 @@ +/* + ZynAddSubFX - a software synthesizer + + Dump.h - It dumps the notes to a text file + + 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) 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 DUMP_H +#define DUMP_H + +#include <stdio.h> + +class Dump{ + public: + Dump(); + ~Dump(); + void startnow(); + void inctick(); + + void dumpnote(char chan,char note, char vel); + void dumpcontroller(char chan,unsigned int type,int par); + + private: + FILE *file; + int tick; + int k; + int keyspressed; +}; +#endif diff --git a/muse/synti/zynaddsubfx/Misc/Master.C b/muse/synti/zynaddsubfx/Misc/Master.C new file mode 100644 index 00000000..7d697418 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Master.C @@ -0,0 +1,685 @@ +/* + ZynAddSubFX - a software synthesizer + + Master.C - It sends Midi Messages to Parts, receives samples from parts, + process them with system/insertion effects and mix them + 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) 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 "Master.h" + +#include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <unistd.h> + +Master::Master(){ + swaplr=0; + + pthread_mutex_init(&mutex,NULL); + fft=new FFTwrapper(OSCIL_SIZE); + + tmpmixl=new REALTYPE[SOUND_BUFFER_SIZE]; + tmpmixr=new REALTYPE[SOUND_BUFFER_SIZE]; + audiooutl=new REALTYPE[SOUND_BUFFER_SIZE]; + audiooutr=new REALTYPE[SOUND_BUFFER_SIZE]; + + ksoundbuffersamples=0; + ksoundbuffersamplelow=0.0; + oldsamplel=0.0;oldsampler=0.0; + shutup=0; + for (int npart=0;npart<NUM_MIDI_PARTS;npart++) { + vuoutpeakpart[npart]=1e-9; + fakepeakpart[npart]=0; + }; + + for (int i=0;i<SOUND_BUFFER_SIZE;i++) { + audiooutl[i]=0.0; + audiooutr[i]=0.0; + }; + + for (int npart=0;npart<NUM_MIDI_PARTS;npart++) + part[npart]=new Part(µtonal,fft,&mutex); + + + + //Insertion Effects init + for (int nefx=0;nefx<NUM_INS_EFX;nefx++) + insefx[nefx]=new EffectMgr(1,&mutex); + + //System Effects init + for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) { + sysefx[nefx]=new EffectMgr(0,&mutex); + }; + + + defaults(); +}; + +void Master::defaults(){ + volume=1.0; + setPvolume(80); + setPkeyshift(64); + + for (int npart=0;npart<NUM_MIDI_PARTS;npart++){ + part[npart]->defaults(); + part[npart]->Prcvchn=npart%NUM_MIDI_CHANNELS; + }; + + partonoff(0,1);//enable the first part + + for (int nefx=0;nefx<NUM_INS_EFX;nefx++) { + insefx[nefx]->defaults(); + Pinsparts[nefx]=-1; + }; + + //System Effects init + for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) { + sysefx[nefx]->defaults(); + for (int npart=0;npart<NUM_MIDI_PARTS;npart++){ + if (nefx==0) setPsysefxvol(npart,nefx,64); + else setPsysefxvol(npart,nefx,0); + }; + for (int nefxto=0;nefxto<NUM_SYS_EFX;nefxto++) + setPsysefxsend(nefx,nefxto,0); + }; + + sysefx[0]->changeeffect(1); + microtonal.defaults(); + ShutUp(); +}; + +/* + * Note On Messages (velocity=0 for NoteOff) + */ +void Master::NoteOn(unsigned char chan,unsigned char note,unsigned char velocity){ + dump.dumpnote(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){ + int npart; + 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){ + dump.dumpnote(chan,note,0); + + noteoff(chan,note); +}; + +/* + * Internal Note Off + */ +void Master::noteoff(unsigned char chan,unsigned char note){ + int npart; + 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){ + dump.dumpcontroller(chan,type,par); + + setcontroller(chan,type,par); +}; + +/* + * Internal Controllers + */ +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); + + 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 (parlo<NUM_SYS_EFX) { + sysefx[parlo]->seteffectpar_nolock(valhi,vallo); + }; + break; + 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); + }; + }; +}; + + +/* + * Enable/Disable a part + */ +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; + part[npart]->cleanup(); + for (int nefx=0;nefx<NUM_INS_EFX;nefx++){ + if (Pinsparts[nefx]==npart) { + insefx[nefx]->cleanup(); + }; + }; + } else {//enabled + part[npart]->Penabled=1; + fakepeakpart[npart]=0; + }; +}; + +/* + * Master audio out (the final sound) + */ + +void Master::AudioOut(REALTYPE* outl, REALTYPE* outr) + { + int i,npart,nefx; + + //Swaps the Left channel with Right Channel (if it is asked for) + if (swaplr != 0) { + REALTYPE *tmp=outl; + outl = outr; + outr = tmp; + } + + //clean up the output samples + memset(outl, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + memset(outr, 0, sizeof(REALTYPE) * SOUND_BUFFER_SIZE); + + //Compute part samples and store them part[npart]->partoutl,partoutr + for (npart=0; npart<NUM_MIDI_PARTS; npart++) + if (part[npart]->Penabled != 0) + part[npart]->ComputePartSmps(); + + //Insertion effects + 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; 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; + + 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;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;i<SOUND_BUFFER_SIZE;i++) { + tmpmixl[i]=0.0; + tmpmixr[i]=0.0; + }; + + //Mix the channels according to the part settings about System Effect + for (npart=0;npart<NUM_MIDI_PARTS;npart++){ + //skip if the part has no output to effect + if (Psysefxvol[nefx][npart]==0) continue; + + //skip if the part is disabled + if (part[npart]->Penabled==0) continue; + + //the output volume of each part to system effect + 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;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); + + //Add the System Effect to sound output + REALTYPE outvol=sysefx[nefx]->sysefxgetvolume(); + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + outl[i]+=tmpmixl[i]*outvol; + outr[i]+=tmpmixr[i]*outvol; + }; + + }; + + //Mix all parts + 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;nefx<NUM_INS_EFX;nefx++) { + if (Pinsparts[nefx] == -2) + insefx[nefx]->out(outl, outr); + } + + //Master Volume + for (i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] *= volume; + outr[i] *= volume; + } + + //Peak computation (for vumeters) + vuoutpeakl=1e-12;vuoutpeakr=1e-12; + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + if (fabs(outl[i])>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;i<SOUND_BUFFER_SIZE;i++) { + vurmspeakl+=outl[i]*outl[i]; + vurmspeakr+=outr[i]*outr[i]; + }; + vurmspeakl=sqrt(vurmspeakl/SOUND_BUFFER_SIZE); + vurmspeakr=sqrt(vurmspeakr/SOUND_BUFFER_SIZE); + + //Part Peak computation (for Part vumeters or fake part vumeters) + 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; i++) { + REALTYPE tmp=(SOUND_BUFFER_SIZE-i)/(REALTYPE) SOUND_BUFFER_SIZE; + outl[i] *= tmp; + outr[i] *= tmp; + } + ShutUp(); + } + + //update the LFO's time + LFOParams::time++; + + if (HDDRecorder.recording()) + HDDRecorder.recordbuffer(outl,outr); + dump.inctick(); + }; + +//--------------------------------------------------------- +// GetAudioOutSamples +//--------------------------------------------------------- + +void Master::GetAudioOutSamples(int nsamples, REALTYPE* outl, REALTYPE* outr) + { + while (nsamples) { + if (ksoundbuffersamples == 0) { + AudioOut(audiooutl, audiooutr); + ksoundbuffersamples = SOUND_BUFFER_SIZE; + } + int n = nsamples > ksoundbuffersamples ? ksoundbuffersamples : nsamples; + memcpy(outl, audiooutl + SOUND_BUFFER_SIZE - ksoundbuffersamples, + n * sizeof(REALTYPE)); + memcpy(outr, audiooutr + SOUND_BUFFER_SIZE - ksoundbuffersamples, + n * sizeof(REALTYPE)); + nsamples -= n; + ksoundbuffersamples -= n; + } + } + +Master::~Master(){ + for (int npart=0;npart<NUM_MIDI_PARTS;npart++) delete (part[npart]); + for (int nefx=0;nefx<NUM_INS_EFX;nefx++) delete (insefx[nefx]); + for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) delete (sysefx[nefx]); + + delete [] audiooutl; + delete [] audiooutr; + delete [] tmpmixl; + delete [] tmpmixr; + delete (fft); + + pthread_mutex_destroy(&mutex); +}; + + +/* + * Parameter control + */ +void Master::setPvolume(char Pvolume_){ + Pvolume=Pvolume_; + volume=dB2rap((Pvolume-96.0)/96.0*40.0); +}; + +void Master::setPkeyshift(char Pkeyshift_){ + Pkeyshift=Pkeyshift_; + keyshift=(int)Pkeyshift-64; +}; + + +void Master::setPsysefxvol(int Ppart,int Pefx,char Pvol){ + Psysefxvol[Pefx][Ppart]=Pvol; + sysefxvol[Pefx][Ppart]=pow(0.1,(1.0-Pvol/96.0)*2.0); +}; + +void Master::setPsysefxsend(int Pefxfrom,int Pefxto,char Pvol){ + Psysefxsend[Pefxfrom][Pefxto]=Pvol; + sysefxsend[Pefxfrom][Pefxto]=pow(0.1,(1.0-Pvol/96.0)*2.0); +}; + + +/* + * Panic! (Clean up all parts and effects) + */ +void Master::ShutUp(){ + for (int npart=0;npart<NUM_MIDI_PARTS;npart++) { + part[npart]->cleanup(); + 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; +}; + + +/* + * Reset peaks and clear the "cliped" flag (for VU-meter) + */ +void Master::vuresetpeaks(){ + vuoutpeakl=1e-9;vuoutpeakr=1e-9;vumaxoutpeakl=1e-9;vumaxoutpeakr=1e-9; + vuclipped=0; +}; + + + +void Master::applyparameters(){ + for (int npart=0;npart<NUM_MIDI_PARTS;npart++){ + part[npart]->applyparameters(); + }; +}; + +void Master::add2XML(XMLwrapper *xml){ + 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;npart<NUM_MIDI_PARTS;npart++){ + xml->beginbranch("PART",npart); + part[npart]->add2XML(xml); + xml->endbranch(); + }; + + xml->beginbranch("SYSTEM_EFFECTS"); + 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;pefx<NUM_MIDI_PARTS;pefx++){ + xml->beginbranch("VOLUME",pefx); + xml->addpar("vol",Psysefxvol[nefx][pefx]); + xml->endbranch(); + }; + + 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;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(); + + xml->beginbranch("MASTER"); + + pthread_mutex_lock(&mutex); + add2XML(xml); + pthread_mutex_unlock(&mutex); + + xml->endbranch(); + + *data=xml->getXMLdata(); + delete (xml); + return(strlen(*data)+1); +}; + +void Master::putalldata(char *data,int size){ + XMLwrapper *xml=new XMLwrapper(); + if (!xml->putXMLdata(data)) { + delete(xml); + return; + }; + + if (xml->enterbranch("MASTER")==0) return; + + pthread_mutex_lock(&mutex); + getfromXML(xml); + pthread_mutex_unlock(&mutex); + + xml->exitbranch(); + + delete(xml); +}; + +int Master::saveXML(char *filename){ + XMLwrapper *xml=new XMLwrapper(); + + xml->beginbranch("MASTER"); + add2XML(xml); + xml->endbranch(); + + int result=xml->saveXMLfile(filename); + delete (xml); + return(result); +}; + + + +int Master::loadXML(char *filename){ + XMLwrapper *xml=new XMLwrapper(); + if (xml->loadXMLfile(filename)<0) { + delete(xml); + return(-1); + }; + + if (xml->enterbranch("MASTER")==0) return(-10); + getfromXML(xml); + xml->exitbranch(); + + 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); + + + 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")){ + microtonal.getfromXML(xml); + xml->exitbranch(); + }; + + sysefx[0]->changeeffect(0); + 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;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;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;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/muse/synti/zynaddsubfx/Misc/Master.h b/muse/synti/zynaddsubfx/Misc/Master.h new file mode 100644 index 00000000..10a183f3 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Master.h @@ -0,0 +1,164 @@ +/* + ZynAddSubFX - a software synthesizer + + Master.h - It sends Midi Messages to Parts, receives samples from parts, + process them with system/insertion effects and mix them + 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) 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 MASTER_H +#define MASTER_H + +#include "../globals.h" +#include "../Effects/EffectMgr.h" +#include "Part.h" +#include "../Output/Recorder.h" +#include "Microtonal.h" + +#include "Bank.h" +#include "Dump.h" +#include "../Seq/Sequencer.h" +#include "XMLwrapper.h" + +extern Dump dump; +class Master{ + public: + Master(); + ~Master(); + + //saves all settings to a XML file + //returns 0 for ok or <0 if there is an error + int saveXML(char *filename); + + //this adds the parameters to the XML data + void add2XML(XMLwrapper *xml); + + void defaults(); + + + //loads all settings from a XML file + //returns 0 for ok or -1 if there is an error + int loadXML(char *filename); + void applyparameters(); + + void getfromXML(XMLwrapper *xml); + + //get all data to a newly allocated array (used for VST) + //returns 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... + + + 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, REALTYPE *outl,REALTYPE *outr); + + + void partonoff(int npart,int what); + + //parts + 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 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 +// void swapcopyeffects(int what,int type,int neff1,int neff2); + + //HDD recorder + Recorder HDDRecorder; + + //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 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 + + //Sequencer + Sequencer seq; + + //other objects + Microtonal microtonal; + Bank bank; + + 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]; + + //Temporary mixing samples for part samples which is sent to system effect + REALTYPE *tmpmixl; + REALTYPE *tmpmixr; + + + int keyshift; + + //Audio Output samples (if it used GetAudioOutSamples - eg. for Jack output; elsewhere is unused) + REALTYPE *audiooutl; + REALTYPE *audiooutr; + + int ksoundbuffersamples; // number of valid samples in audiooutr/l + REALTYPE ksoundbuffersamplelow;//this is used for resampling (eg. if Jack samplerate!= SAMPLE_RATE) + REALTYPE oldsamplel,oldsampler;//this is used for resampling + + //Theese 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); +}; + + +#endif + diff --git a/muse/synti/zynaddsubfx/Misc/Microtonal.C b/muse/synti/zynaddsubfx/Misc/Microtonal.C new file mode 100644 index 00000000..30a3a71e --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Microtonal.C @@ -0,0 +1,514 @@ +/* + ZynAddSubFX - a software synthesizer + + Microtonal.C - Tuning settings and microtonal capabilities + 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) 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 <math.h> +#include <string.h> +#include "Microtonal.h" + +#define MAX_LINE_SIZE 80 + +Microtonal::Microtonal(){ + 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; + + 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<MAX_OCTAVE_SIZE;i++){ + octave[i].tuning=tmpoctave[i].tuning=pow(2,(i%octavesize+1)/12.0); + octave[i].type=tmpoctave[i].type=1; + octave[i].x1=tmpoctave[i].x1=(i%octavesize+1)*100; + octave[i].x2=tmpoctave[i].x2=0; + }; + octave[11].type=2;octave[11].x1=2;octave[11].x2=1; + for (int i=0;i<MICROTONAL_MAX_NAME_LEN;i++){ + Pname[i]='\0'; + Pcomment[i]='\0'; + }; + snprintf((char *) Pname,MICROTONAL_MAX_NAME_LEN,"12tET"); + snprintf((char *) Pcomment,MICROTONAL_MAX_NAME_LEN,"Equal Temperament 12 notes per octave"); + Pglobalfinedetune=64; +}; + +Microtonal::~Microtonal(){ + delete (Pname); + delete (Pcomment); +}; + +/* + * Get the size of the octave + */ +unsigned char Microtonal::getoctavesize(){ + if (Penabled!=0) return(octavesize); + else return(12); +}; + +/* + * Get the frequency according the note number + */ +REALTYPE Microtonal::getnotefreq(int note,int keyshift){ + // in this function will appears many times things like this: + // var=(a+b*100)%b + // I had written this way because if I use var=a%b gives unwanted results when a<0 + // This is the same with divisions. + + if ((Pinvertupdown!=0)&&((Pmappingenabled==0)||(Penabled==0))) note=(int) Pinvertupdowncenter*2-note; + + //compute global fine detune + REALTYPE globalfinedetunerap=pow(2.0,(Pglobalfinedetune-64.0)/1200.0);//-64.0 .. 63.0 cents + + if (Penabled==0) return(pow(2.0,(note-PAnote+keyshift)/12.0)*PAfreq*globalfinedetunerap);//12tET + + int scaleshift=((int)Pscaleshift-64+(int) octavesize*100)%octavesize; + + //compute the keyshift + REALTYPE rap_keyshift=1.0; + if (keyshift!=0){ + int kskey=(keyshift+(int)octavesize*100)%octavesize; + int ksoct=(keyshift+(int)octavesize*100)/octavesize-100; + rap_keyshift=(kskey==0) ? (1.0):(octave[kskey-1].tuning); + rap_keyshift*=pow(octave[octavesize-1].tuning,ksoct); + }; + + //if the mapping is enabled + 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<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 + + //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; + }; + //compute the frequency of the note + 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 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); + }; +}; + + +/* + * Convert a line to tunings; returns -1 if it ok + */ +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 + }; + + 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){ + case 1: 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; + break; + }; + + tmpoctave[nline].tuning=tuning; + tmpoctave[nline].type=type; + tmpoctave[nline].x1=x1; + tmpoctave[nline].x2=x2; + + return(-1);//ok +}; + +/* + * Convert the text to tunnings + */ +int Microtonal::texttotunings(const char *text){ + unsigned int i,k=0,nl=0; + char *lin; + lin=new char[MAX_LINE_SIZE+1]; + while (k<strlen(text)){ + for (i=0;i<MAX_LINE_SIZE;i++){ + lin[i]=text[k++]; + if (lin[i]<0x20) break; + }; + lin[i]='\0'; + if (strlen(lin)==0) continue; + int err=linetotunings(nl,lin); + if (err!=-1) { + delete [] lin; + return(nl);//Parse error + }; + nl++; + }; + delete [] lin; + if (nl>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; + char *lin; + lin=new char[MAX_LINE_SIZE+1]; + for (i=0;i<128;i++) Pmapping[i]=-1; + int tx=0; + while (k<strlen(text)){ + for (i=0;i<MAX_LINE_SIZE;i++){ + lin[i]=text[k++]; + if (lin[i]<0x20) break; + }; + lin[i]='\0'; + if (strlen(lin)==0) continue; + + int tmp=0; + if (sscanf(lin,"%d",&tmp)==0) tmp=-1; + if (tmp<-1) tmp=-1; + Pmapping[tx]=tmp; + + if ((tx++)>127) break; + }; + delete [] lin; + + if (tx==0) tx=1; + Pmapsize=tx; +}; + +/* + * Convert tunning to text line + */ +void Microtonal::tuningtoline(int n,char *line,int maxn){ + 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); +}; + + +int Microtonal::loadline(FILE *file,char *line){ + do { + 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); + //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); + //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); + //load the tunnings + for (int nline=0;nline<nnotes;nline++){ + if (loadline(file,&tmp[0])!=0) return(2); + linetotunings(nline,&tmp[0]); + }; + fclose(file); + + octavesize=nnotes; + for (int 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(0); +}; + +/* + * Loads the mapping from a kbm file + */ +int Microtonal::loadkbm(const char *filename){ + FILE *file=fopen(filename, "r"); + int x; + char tmp[500]; + + fseek(file,0,SEEK_SET); + //loads the mapsize + 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; + //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; + //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; + //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; + //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; + + //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); + + //load the mappings + if (Pmapsize!=0){ + for (int nline=0;nline<Pmapsize;nline++){ + if (loadline(file,&tmp[0])!=0) return(2); + if (sscanf(&tmp[0],"%d",&x)==0) x=-1; + Pmapping[nline]=x; + }; + Pmappingenabled=1; + } else { + Pmappingenabled=0; + Pmapping[0]=0; + Pmapsize=1; + }; + fclose(file); + + return(0); +}; + + + +void Microtonal::add2XML(XMLwrapper *xml){ + xml->addparstr("name",(char *) Pname); + xml->addparstr("comment",(char *) Pcomment); + + xml->addparbool("invert_up_down",Pinvertupdown); + xml->addparbool("invert_up_down_center",Pinvertupdowncenter); + + xml->addparbool("enabled",Penabled); + xml->addpar("global_fine_detune",Pglobalfinedetune); + + xml->addpar("a_note",PAnote); + xml->addparreal("a_freq",PAfreq); + + 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->beginbranch("OCTAVE"); + 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;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); + + Pinvertupdown=xml->getparbool("invert_up_down",Pinvertupdown); + Pinvertupdowncenter=xml->getparbool("invert_up_down_center",Pinvertupdowncenter); + + 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); + + 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;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; + + 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;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(char *filename){ + XMLwrapper *xml=new XMLwrapper(); + + xml->beginbranch("MICROTONAL"); + add2XML(xml); + xml->endbranch(); + + int result=xml->saveXMLfile(filename); + delete (xml); + return(result); +}; + +int Microtonal::loadXML(char *filename){ + XMLwrapper *xml=new XMLwrapper(); + if (xml->loadXMLfile(filename)<0) { + delete(xml); + return(-1); + }; + + if (xml->enterbranch("MICROTONAL")==0) return(-10); + getfromXML(xml); + xml->exitbranch(); + + delete(xml); + return(0); +}; + + diff --git a/muse/synti/zynaddsubfx/Misc/Microtonal.h b/muse/synti/zynaddsubfx/Misc/Microtonal.h new file mode 100644 index 00000000..60ffc4cf --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Microtonal.h @@ -0,0 +1,111 @@ +/* + ZynAddSubFX - a software synthesizer + + Microtonal.h - Tuning settings and microtonal capabilities + 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) 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 MICROTONAL_H +#define MICROTONAL_H + +#include "../globals.h" +#include "XMLwrapper.h" + +#define MAX_OCTAVE_SIZE 128 +#define MICROTONAL_MAX_NAME_LEN 120 + +#include <stdio.h> + +class Microtonal{ + public: + Microtonal(); + ~Microtonal(); + void defaults(); + REALTYPE getnotefreq(int note,int keyshift); + + + //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; + + //0 for 12 key temperate scale, 1 for microtonal + unsigned char Penabled; + + //the note of "A" key + unsigned char PAnote; + + //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; + + //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; + + //Map size + unsigned char Pmapsize; + + //Mapping ON/OFF + unsigned char Pmappingenabled; + //Mapping (keys) + short int Pmapping[128]; + + unsigned char Pglobalfinedetune; + + // Functions + unsigned char getoctavesize(); + void tuningtoline(int n,char *line,int maxn); + int loadscl(const char *filename);//load the tunnings from a .scl file + int loadkbm(const char *filename);//load the mapping from .kbm file + int texttotunings(const char *text); + void texttomapping(const char *text); + unsigned char *Pname; + unsigned char *Pcomment; + + void add2XML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); + int saveXML(char *filename); + int loadXML(char *filename); + + 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]; + +}; + +#endif diff --git a/muse/synti/zynaddsubfx/Misc/Part.C b/muse/synti/zynaddsubfx/Misc/Part.C new file mode 100644 index 00000000..54d542c7 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Part.C @@ -0,0 +1,875 @@ +/* + ZynAddSubFX - a software synthesizer + + Part.C - Part implementation + 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) 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 "Part.h" +#include "Microtonal.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +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]; + + for (int n=0;n<NUM_KIT_ITEMS;n++){ + kit[n].Pname=new unsigned char [PART_MAX_NAME_LEN]; + kit[n].adpars=NULL;kit[n].subpars=NULL;kit[n].padpars=NULL; + }; + + kit[0].adpars=new ADnoteParameters(fft); + kit[0].subpars=new SUBnoteParameters(); + kit[0].padpars=new PADnoteParameters(fft,mutex); +// ADPartParameters=kit[0].adpars; +// SUBPartParameters=kit[0].subpars; + + //Part's Insertion Effects init + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) + partefx[nefx]=new EffectMgr(1,mutex); + + for (int n=0;n<NUM_PART_EFX+1;n++) { + partfxinputl[n]=new REALTYPE [SOUND_BUFFER_SIZE]; + partfxinputr[n]=new REALTYPE [SOUND_BUFFER_SIZE]; + Pefxbypass[n]=false; + }; + + killallnotes=0; + oldfreq=-1.0; + + int i,j; + for (i=0;i<POLIPHONY;i++){ + partnote[i].status=KEY_OFF; + partnote[i].note=-1; + partnote[i].itemsplaying=0; + for (j=0;j<NUM_KIT_ITEMS;j++){ + partnote[i].kititem[j].adnote=NULL; + partnote[i].kititem[j].subnote=NULL; + partnote[i].kititem[j].padnote=NULL; + }; + partnote[i].time=0; + }; + cleanup(); + + Pname=new unsigned char [PART_MAX_NAME_LEN]; + + oldvolumel=oldvolumer=0.5; + lastnote=-1; + + + defaults(); +}; + +void Part::defaults(){ + Penabled=0; + Pminkey=0; + Pmaxkey=127; + Pnoteon=1; + Ppolymode=1; + setPvolume(96); + Pkeyshift=64; + Prcvchn=0; + setPpanning(64); + Pvelsns=64; + Pveloffs=64; + Pkeylimit=15; + defaultsinstrument(); + ctl.defaults(); +}; + +void Part::defaultsinstrument(){ + ZERO(Pname,PART_MAX_NAME_LEN); + + info.Ptype=0; + ZERO(info.Pauthor,MAX_INFO_TEXT_SIZE+1); + ZERO(info.Pcomments,MAX_INFO_TEXT_SIZE+1); + + Pkitmode=0; + Pdrummode=0; + + for (int n=0;n<NUM_KIT_ITEMS;n++){ + kit[n].Penabled=0;kit[n].Pmuted=0; + kit[n].Pminkey=0;kit[n].Pmaxkey=127; + kit[n].Padenabled=0;kit[n].Psubenabled=0;kit[n].Ppadenabled=0; + ZERO(kit[n].Pname,PART_MAX_NAME_LEN); + kit[n].Psendtoparteffect=0; + if (n!=0) setkititemstatus(n,0); + }; + kit[0].Penabled=1; + kit[0].Padenabled=1; + kit[0].adpars->defaults(); + kit[0].subpars->defaults(); + kit[0].padpars->defaults(); + + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { + partefx[nefx]->defaults(); + Pefxroute[nefx]=0;//route to next effect + }; + +}; + + + +/* + * Cleanup the part + */ +void Part::cleanup(){ + for (int k=0;k<POLIPHONY;k++) KillNotePos(k); + for (int i=0;i<SOUND_BUFFER_SIZE;i++){ + partoutl[i]=denormalkillbuf[i]; + partoutr[i]=denormalkillbuf[i]; + tmpoutl[i]=0.0; + tmpoutr[i]=0.0; + }; + ctl.resetall(); + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) partefx[nefx]->cleanup(); + 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;n<NUM_KIT_ITEMS;n++){ + if (kit[n].adpars!=NULL) delete (kit[n].adpars); + if (kit[n].subpars!=NULL) delete (kit[n].subpars); + if (kit[n].padpars!=NULL) delete (kit[n].padpars); + kit[n].adpars=NULL;kit[n].subpars=NULL;kit[n].padpars=NULL; + delete(kit[n].Pname); + }; + + delete (Pname); + delete (partoutl); + delete (partoutr); + delete (tmpoutl); + delete (tmpoutr); + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) + delete (partefx[nefx]); + for (int n=0;n<NUM_PART_EFX+1;n++) { + delete (partfxinputl[n]); + delete (partfxinputr[n]); + }; +}; + +/* + * Note On Messages + */ +void Part::NoteOn(unsigned char note,unsigned char velocity,int masterkeyshift){ + int i,pos; + + lastnote=note; + if ((note<Pminkey)||(note>Pmaxkey)) return; + + pos=-1; + for (i=0;i<POLIPHONY;i++){ + if (partnote[i].status==KEY_OFF){ + pos=i; + break; + }; + }; + + if (Ppolymode==0){//if the mode is 'mono' turn off all other notes + for (i=0;i<POLIPHONY;i++) + if (partnote[i].status==KEY_PLAYING) NoteOff(partnote[i].note); + RelaseSustainedKeys(); + }; + + if (pos==-1){ + //test + fprintf(stderr,"%s","NOTES TOO MANY (> POLIPHONY) - (Part.C::NoteOn(..))\n"); + } else { + if (Pnoteon!=0){ + //start the note + partnote[pos].status=KEY_PLAYING; + partnote[pos].note=note; + + //this computes the velocity sensing of the part + 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; + + //compute the keyshift + 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); + }; + + //Portamento + if (oldfreq<1.0) oldfreq=notebasefreq;//this is only the first note is played + + int portamento=ctl.initportamento(oldfreq,notebasefreq); + + if (portamento!=0) ctl.portamento.noteusing=pos; + oldfreq=notebasefreq; + + partnote[pos].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); + if (kit[0].Psubenabled!=0) partnote[pos].kititem[0].subnote=new SUBnote(kit[0].subpars,&ctl,notebasefreq,vel,portamento,note); + if (kit[0].Ppadenabled!=0) partnote[pos].kititem[0].padnote=new PADnote(kit[0].padpars,&ctl,notebasefreq,vel,portamento,note); + if ((kit[0].Padenabled!=0)||(kit[0].Psubenabled!=0)||(kit[0].Ppadenabled!=0)) partnote[pos].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; + + 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" + + if ((kit[item].adpars!=NULL)&&(kit[item].Padenabled)!=0) + partnote[pos].kititem[ci].adnote=new ADnote(kit[item].adpars,&ctl,notebasefreq,vel,portamento,note); + + if ((kit[item].subpars!=NULL)&&(kit[item].Psubenabled)!=0) + partnote[pos].kititem[ci].subnote=new SUBnote(kit[item].subpars,&ctl,notebasefreq,vel,portamento,note); + + if ((kit[item].padpars!=NULL)&&(kit[item].Ppadenabled)!=0) + partnote[pos].kititem[ci].padnote=new PADnote(kit[item].padpars,&ctl,notebasefreq,vel,portamento,note); + + if ((kit[item].adpars!=NULL)|| (kit[item].subpars!=NULL)) { + partnote[pos].itemsplaying++; + if ( ((kit[item].Padenabled!=0)||(kit[item].Psubenabled!=0)||(kit[item].Ppadenabled!=0)) + && (Pkitmode==2) ) break; + }; + }; + }; + }; + }; + + //this only relase the keys if there is maximum number of keys allowed + setkeylimit(Pkeylimit); +}; + +/* + * Note Off Messages + */ +void Part::NoteOff(unsigned char note){//relase the key + int i; + 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 + RelaseNotePos(i); + break; + } else {//the sustain pedal is pushed + partnote[i].status=KEY_RELASED_AND_SUSTAINED; + }; + }; + }; +}; + +/* + * Controllers + */ +void Part::SetController(unsigned int type,int par){ + switch (type){ + case C_pitchwheel:ctl.setpitchwheel(par); + break; + case C_expression:ctl.setexpression(par); + setPvolume(Pvolume);//update the volume + break; + case C_portamento:ctl.setportamento(par); + break; + case C_panning:ctl.setpanning(par); + setPpanning(Ppanning);//update the panning + break; + case C_filtercutoff:ctl.setfiltercutoff(par); + break; + case C_filterq:ctl.setfilterq(par); + break; + case C_bandwidth:ctl.setbandwidth(par); + break; + case C_modwheel:ctl.setmodwheel(par); + break; + case C_fmamp:ctl.setfmamp(par); + break; + case C_volume:ctl.setvolume(par); + 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(); + break; + case C_allsoundsoff: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 + + for (int item=0;item<NUM_KIT_ITEMS;item++){ + if (kit[item].adpars==NULL) continue; + kit[item].adpars->GlobalPar.Reson-> + sendcontroller(C_resonance_center,1.0); + + kit[item].adpars->GlobalPar.Reson-> + sendcontroller(C_resonance_bandwidth,1.0); + }; + //more update to add here if I add controllers + break; + case C_allnotesoff:RelaseAllKeys(); + break; + case C_resonance_center: + ctl.setresonancecenter(par); + for (int item=0;item<NUM_KIT_ITEMS;item++){ + if (kit[item].adpars==NULL) continue; + kit[item].adpars->GlobalPar.Reson-> + 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); + break; + }; +}; +/* + * Relase the sustained keys + */ + +void Part::RelaseSustainedKeys(){ + for (int i=0;i<POLIPHONY;i++) + if (partnote[i].status==KEY_RELASED_AND_SUSTAINED) RelaseNotePos(i); +}; + +/* + * Relase all keys + */ + +void Part::RelaseAllKeys(){ + for (int i=0;i<POLIPHONY;i++){ + if ((partnote[i].status!=KEY_RELASED)&& + (partnote[i].status!=KEY_OFF)) //thanks to Frank Neumann + RelaseNotePos(i); + }; +}; + +/* + * Release note at position + */ +void Part::RelaseNotePos(int pos){ + + for (int j=0;j<NUM_KIT_ITEMS;j++){ + + if (partnote[pos].kititem[j].adnote!=NULL) + if (partnote[pos].kititem[j].adnote) + partnote[pos].kititem[j].adnote->relasekey(); + + 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) + partnote[pos].kititem[j].padnote->relasekey(); + }; + partnote[pos].status=KEY_RELASED; +}; + + +/* + * Kill note at position + */ +void Part::KillNotePos(int pos){ + partnote[pos].status=KEY_OFF; + partnote[pos].note=-1; + partnote[pos].time=0; + partnote[pos].itemsplaying=0; + + for (int j=0;j<NUM_KIT_ITEMS;j++){ + if (partnote[pos].kititem[j].adnote!=NULL) { + delete(partnote[pos].kititem[j].adnote); + partnote[pos].kititem[j].adnote=NULL; + }; + if (partnote[pos].kititem[j].subnote!=NULL) { + delete(partnote[pos].kititem[j].subnote); + partnote[pos].kititem[j].subnote=NULL; + }; + if (partnote[pos].kititem[j].padnote!=NULL) { + delete(partnote[pos].kititem[j].padnote); + partnote[pos].kititem[j].padnote=NULL; + }; + }; + if (pos==ctl.portamento.noteusing) { + ctl.portamento.noteusing=-1; + ctl.portamento.used=0; + }; +}; + + +/* + * Set Part's key limit + */ +void Part::setkeylimit(unsigned char Pkeylimit){ + 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;i<POLIPHONY;i++){ + if ((partnote[i].status==KEY_PLAYING)||(partnote[i].status==KEY_RELASED_AND_SUSTAINED)) + notecount++; + }; + 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); + }; +}; + + +/* + * Prepare all notes to be turned off + */ +void Part::AllNotesOff(){ + killallnotes=1; +}; + + +/* + * Compute Part samples and store them in the partoutl[] and partoutr[] + */ +void Part::ComputePartSmps(){ + int i,k; + int noteplay;//0 if there is nothing activated + for (int nefx=0;nefx<NUM_PART_EFX+1;nefx++){ + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + partfxinputl[nefx][i]=0.0; + partfxinputr[nefx][i]=0.0; + }; + }; + + for (k=0;k<POLIPHONY;k++){ + if (partnote[k].status==KEY_OFF) continue; + noteplay=0; + partnote[k].time++; + //get the sampledata of the note and kill it if it's finished + + for (int item=0;item<partnote[k].itemsplaying;item++){ + + int sendcurrenttofx=partnote[k].kititem[item].sendtoparteffect; + + ADnote *adnote=partnote[k].kititem[item].adnote; + SUBnote *subnote=partnote[k].kititem[item].subnote; + PADnote *padnote=partnote[k].kititem[item].padnote; + //get from the ADnote + if (adnote!=NULL) { + noteplay++; + 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;i<SOUND_BUFFER_SIZE;i++){//add the ADnote to part(mix) + partfxinputl[sendcurrenttofx][i]+=tmpoutl[i]; + partfxinputr[sendcurrenttofx][i]+=tmpoutr[i]; + }; + }; + //get from the SUBnote + if (subnote!=NULL) { + noteplay++; + if (subnote->ready!=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;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; + }; + }; + //get from the PADnote + if (padnote!=NULL) { + noteplay++; + 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;i<SOUND_BUFFER_SIZE;i++){//add the PADnote to part(mix) + partfxinputl[sendcurrenttofx][i]+=tmpoutl[i]; + partfxinputr[sendcurrenttofx][i]+=tmpoutr[i]; + }; + }; + + }; + //Kill note if there is no synth on that note + if (noteplay==0) KillNotePos(k); + }; + + + //Apply part's effects and mix them + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { + if (!Pefxbypass[nefx]) { + partefx[nefx]->out(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;i<SOUND_BUFFER_SIZE;i++) { + REALTYPE tmp=(SOUND_BUFFER_SIZE-i)/(REALTYPE) SOUND_BUFFER_SIZE; + partoutl[i]*=tmp; + partoutr[i]*=tmp; + tmpoutl[i]=0.0; + tmpoutr[i]=0.0; + }; + for (int k=0;k<POLIPHONY;k++) KillNotePos(k); + killallnotes=0; + for (int nefx=0;nefx<NUM_PART_EFX;nefx++) { + partefx[nefx]->cleanup(); + }; + }; + ctl.updateportamento(); +}; + +/* + * Parameter control + */ +void Part::setPvolume(char Pvolume_){ + 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; + +}; + +/* + * Enable or disable a kit item + */ +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_; + + 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); + }; + + if (resetallnotes) for (int k=0;k<POLIPHONY;k++) KillNotePos(k); +}; + + + +void Part::add2XMLinstrument(XMLwrapper *xml){ + xml->beginbranch("INFO"); + 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); + + 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->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->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->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->beginbranch("PAD_SYNTH_PARAMETERS"); + kit[i].padpars->add2XML(xml); + xml->endbranch(); + }; + + }; + xml->endbranch(); + }; + xml->endbranch(); + + xml->beginbranch("INSTRUMENT_EFFECTS"); + 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->endbranch(); + }; + xml->endbranch(); +}; + + +void Part::add2XML(XMLwrapper *xml){ + //parameters + xml->addparbool("enabled",Penabled); + if ((Penabled==0)&&(xml->minimal)) return; + + 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("velocity_sensing",Pvelsns); + xml->addpar("velocity_offset",Pveloffs); + + xml->addparbool("note_on",Pnoteon); + xml->addparbool("poly_mode",Ppolymode); + xml->addpar("key_limit",Pkeylimit); + + xml->beginbranch("INSTRUMENT"); + add2XMLinstrument(xml); + xml->endbranch(); + + xml->beginbranch("CONTROLLER"); + ctl.add2XML(xml); + xml->endbranch(); +}; + +int Part::saveXML(char *filename){ + XMLwrapper *xml; + xml=new XMLwrapper(); + + xml->beginbranch("INSTRUMENT"); + add2XMLinstrument(xml); + xml->endbranch(); + + int result=xml->saveXMLfile(filename); + delete (xml); + return(result); +}; + +int Part::loadXMLinstrument(const char *filename){ + XMLwrapper *xml=new XMLwrapper(); + if (xml->loadXMLfile(filename)<0) { + delete(xml); + return(-1); + }; + + if (xml->enterbranch("INSTRUMENT")==0) return(-10); + getfromXMLinstrument(xml); + xml->exitbranch(); + + delete(xml); + return(0); +}; + + +void Part::applyparameters(){ + 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); + + xml->exitbranch(); + }; + + if (xml->enterbranch("INSTRUMENT_KIT")){ + Pkitmode=xml->getpar127("kit_mode",Pkitmode); + Pdrummode=xml->getparbool("drum_mode",Pdrummode); + + 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); + + 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].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].subpars->getfromXML(xml); + xml->exitbranch(); + }; + + 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;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]); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + +}; + +void Part::getfromXML(XMLwrapper *xml){ + Penabled=xml->getparbool("enabled",Penabled); + + 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); + + Pvelsns=xml->getpar127("velocity_sensing",Pvelsns); + Pveloffs=xml->getpar127("velocity_offset",Pveloffs); + + Pnoteon=xml->getparbool("note_on",Pnoteon); + Ppolymode=xml->getparbool("poly_mode",Ppolymode); + Pkeylimit=xml->getpar127("key_limit",Pkeylimit); + + + if (xml->enterbranch("INSTRUMENT")){ + getfromXMLinstrument(xml); + xml->exitbranch(); + }; + + if (xml->enterbranch("CONTROLLER")){ + ctl.getfromXML(xml); + xml->exitbranch(); + }; + +}; + + + diff --git a/muse/synti/zynaddsubfx/Misc/Part.h b/muse/synti/zynaddsubfx/Misc/Part.h new file mode 100644 index 00000000..2c569750 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Part.h @@ -0,0 +1,174 @@ +/* + ZynAddSubFX - a software synthesizer + + Part.h - Part implementation + 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) 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 PART_H +#define PART_H + +#define MAX_INFO_TEXT_SIZE 1000 + +#include "../globals.h" +#include "../Params/ADnoteParameters.h" +#include "../Params/SUBnoteParameters.h" +#include "../Params/PADnoteParameters.h" +#include "../Synth/ADnote.h" +#include "../Synth/SUBnote.h" +#include "../Synth/PADnote.h" +#include "../Params/Controller.h" +#include "../Misc/Microtonal.h" +#include "../DSP/FFTwrapper.h" +#include "../Effects/EffectMgr.h" +#include "XMLwrapper.h" + +class Part{ + + public: + Part(Microtonal *microtonal_,FFTwrapper *fft_,pthread_mutex_t *mutex_); + ~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 + + /* 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) + + + //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 defaults(); + void defaultsinstrument(); + + void applyparameters(); + + void getfromXML(XMLwrapper *xml); + void getfromXMLinstrument(XMLwrapper *xml); + + 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;//if the part is enabled + unsigned char Pvolume;//part volume + unsigned char Pminkey;//the minimum key that the part receives noteon messages + unsigned char Pmaxkey;//the maximum key that the part receives noteon messages + void setPvolume(char Pvolume); + unsigned char Pkeyshift;//Part keyshift + unsigned char Prcvchn;//from what midi channel it receive commnads + unsigned char Ppanning;//part panning + void setPpanning(char Ppanning); + unsigned char Pvelsns;//velocity sensing (amplitude velocity scale) + unsigned char Pveloffs;//velocity offset + unsigned char Pnoteon;//if the part receives NoteOn messages + unsigned char Pkitmode;//if the kitmode is enabled + unsigned char Pdrummode;//if all keys are mapped and the system is 12tET (used for drums) + + unsigned char Ppolymode;//Part mode - 0=monophonic , 1=polyphonic + unsigned char Pkeylimit;//how many keys are alowed to be played same time (0=off), the older will be relased + + unsigned char *Pname; //name of the instrument + struct{//instrument additional information + unsigned char Ptype; + unsigned char Pauthor[MAX_INFO_TEXT_SIZE+1]; + unsigned char Pcomments[MAX_INFO_TEXT_SIZE+1]; + } info; + + + REALTYPE *partoutl;//Left channel output of the part + REALTYPE *partoutr;//Right channel output of the part + + REALTYPE *partfxinputl[NUM_PART_EFX+1],*partfxinputr[NUM_PART_EFX+1];//Left and right signal that pass thru part effects; partfxinput l/r [NUM_PART_EFX] is for "no effect" buffer + + enum NoteStatus{KEY_OFF,KEY_PLAYING,KEY_RELASED_AND_SUSTAINED,KEY_RELASED}; + + REALTYPE volume,oldvolumel,oldvolumer;//this is applied by Master + REALTYPE panning;//this is applied by Master, too + + Controller ctl;//Part controllers + + EffectMgr *partefx[NUM_PART_EFX];//insertion part effects (they are part of the instrument) + unsigned char Pefxroute[NUM_PART_EFX];//how the effect's output is routed(to next effect/to out) + bool Pefxbypass[NUM_PART_EFX];//if the effects are bypassed + + + pthread_mutex_t *mutex; + + int lastnote; + + private: + void KillNotePos(int pos); + void RelaseNotePos(int pos); + int killallnotes;//is set to 1 if I want to kill all notes + + struct PartNotes{ + NoteStatus status; + int note;//if there is no note playing, the "note"=-1 + int itemsplaying; + struct { + ADnote *adnote; + SUBnote *subnote; + PADnote *padnote; + int sendtoparteffect; + } kititem[NUM_KIT_ITEMS]; + int time; + }; + + 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/muse/synti/zynaddsubfx/Misc/Util.C b/muse/synti/zynaddsubfx/Misc/Util.C new file mode 100644 index 00000000..74619731 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Util.C @@ -0,0 +1,112 @@ +/* + ZynAddSubFX - a software synthesizer + + Util.C - Miscellaneous functions + 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) 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 "Util.h" +#include <math.h> +#include <stdio.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +int SAMPLE_RATE=44100; +int SOUND_BUFFER_SIZE=256; +int OSCIL_SIZE=512; + +Config config; +REALTYPE *denormalkillbuf; + + +/* + * Transform the velocity according the scaling parameter (velocity sensing) + */ +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)); +}; + +/* + * Get the detune in cents + */ +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; + //Get Octave + 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 fdetune=finedetune-8192; + + 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; + break; + case 3: 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; + break; + //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" + break; + }; + if (finedetune<8192) findet=-findet; + if (cdetune<0) cdet=-cdet; + + det=octdet+cdet+findet; + return(det); +}; + + +bool fileexists(char *filename){ + struct stat tmp; + 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;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/muse/synti/zynaddsubfx/Misc/Util.h b/muse/synti/zynaddsubfx/Misc/Util.h new file mode 100644 index 00000000..c5b39476 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/Util.h @@ -0,0 +1,45 @@ +/* + ZynAddSubFX - a software synthesizer + + Util.h - Miscellaneous functions + 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) 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 UTIL_H +#define UTIL_H + +#include <pthread.h> +#include "../globals.h" +#include "Microtonal.h" +#include "../DSP/FFTwrapper.h" +#include "Config.h" + +//Velocity Sensing function +extern REALTYPE VelF(REALTYPE velocity,unsigned char scaling); + +bool fileexists(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 *denormalkillbuf;//the buffer to add noise in order to avoid denormalisation + +extern Config config; + +#endif + diff --git a/muse/synti/zynaddsubfx/Misc/XMLwrapper.C b/muse/synti/zynaddsubfx/Misc/XMLwrapper.C new file mode 100644 index 00000000..0f35faf2 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/XMLwrapper.C @@ -0,0 +1,533 @@ +/* + ZynAddSubFX - a software synthesizer + + XMLwrapper.C - XML wrapper + Copyright (C) 2003-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) 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 "XMLwrapper.h" +#include <stdio.h> +#include <stdlib.h> +#include <zlib.h> + +#include "../globals.h" +#include "Util.h" + +int xml_k=0; +char tabs[STACKSIZE+2]; + +const char *XMLwrapper_whitespace_callback(mxml_node_t *node,int where){ + 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)||(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"); + }; + + }; + int i=0; + for (i=1;i<xml_k;i++) tabs[i]='\t'; + tabs[0]='\n';tabs[i+1]='\0'; + if (where==MXML_WS_BEFORE_OPEN) return(tabs); + else return("\n"); +*/ + return("\n"); + }; + + return(0); +}; + + +XMLwrapper::XMLwrapper(){ + ZERO(&parentstack,(int)sizeof(parentstack)); + ZERO(&values,(int)sizeof(values)); + + minimal=true; + stackpos=0; + + information.PADsynth_used=false; + + 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); + + node=root=mxmlNewElement(tree,"ZynAddSubFX-data"); + + mxmlElementSetAttr(root,"version-major","1"); + mxmlElementSetAttr(root,"version-minor","1"); + mxmlElementSetAttr(root,"ZynAddSubFX-author","Nasca Octavian Paul"); + + //make the empty branch that will contain the information parameters + info=addparams0("INFORMATION"); + + //save zynaddsubfx specifications + beginbranch("BASE_PARAMETERS"); + 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_addsynth_voices",NUM_VOICES); + endbranch(); + +}; + +XMLwrapper::~XMLwrapper(){ + if (tree!=NULL) mxmlDelete(tree); +}; + +bool XMLwrapper::checkfileinformation(char *filename){ + stackpos=0; + ZERO(&parentstack,(int)sizeof(parentstack)); + information.PADsynth_used=false; + + if (tree!=NULL) mxmlDelete(tree);tree=NULL; + char *xmldata=doloadfile(filename); + if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed + + + char *start=strstr(xmldata,"<INFORMATION>"); + char *end=strstr(xmldata,"</INFORMATION>"); + + if ((start==NULL)||(end==NULL)||(start>end)) { + delete(xmldata); + return(false); + }; + end+=strlen("</INFORMATION>"); + 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); +}; + + +/* SAVE XML members */ + +int XMLwrapper::saveXMLfile(char *filename){ + char *xmldata=getXMLdata(); + if (xmldata==NULL) return(-2); + + int compression=config.cfg.GzipCompression; + + int fnsize=strlen(filename)+100; + char *filenamenew=new char [fnsize]; + snprintf(filenamenew,fnsize,"%s",filename); + + int result=dosavefile(filenamenew,compression,xmldata); + + delete(filenamenew); + delete(xmldata); + return(result); +}; + +char *XMLwrapper::getXMLdata(){ + xml_k=0; + ZERO(tabs,STACKSIZE+2); + + mxml_node_t *oldnode=node; + + node=info; + //Info storing + addparbool("PADsynth_used",information.PADsynth_used); + + node=oldnode; + char *xmldata=mxmlSaveAllocString(tree,XMLwrapper_whitespace_callback); + + return(xmldata); +}; + + +int XMLwrapper::dosavefile(char *filename,int compression,char *xmldata){ + if (compression==0){ + FILE *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; + char options[10]; + snprintf(options,10,"wb%d",compression); + + gzFile gzfile; + gzfile=gzopen(filename,options); + if (gzfile==NULL) return(-1); + gzputs(gzfile,xmldata); + gzclose(gzfile); + }; + + return(0); +}; + + + +void XMLwrapper::addpar(char *name,int val){ + addparams2("par","name",name,"value",int2str(val)); +}; + +void XMLwrapper::addparreal(char *name,REALTYPE val){ + addparams2("par_real","name",name,"value",real2str(val)); +}; + +void XMLwrapper::addparbool(char *name,int val){ + if (val!=0) addparams2("par_bool","name",name,"value","yes"); + else addparams2("par_bool","name",name,"value","no"); +}; + +void XMLwrapper::addparstr(char *name,char *val){ + mxml_node_t *element=mxmlNewElement(node,"string"); + mxmlElementSetAttr(element,"name",name); + mxmlNewText(element,0,val); +}; + + +void XMLwrapper::beginbranch(char *name){ + push(node); + node=addparams0(name); +}; + +void XMLwrapper::beginbranch(char *name,int id){ + push(node); + node=addparams1(name,"id",int2str(id)); +}; + +void XMLwrapper::endbranch(){ + node=pop(); +}; + + + +/* LOAD XML members */ + +int XMLwrapper::loadXMLfile(const char *filename){ + if (tree!=NULL) mxmlDelete(tree); + tree=NULL; + + ZERO(&parentstack,(int)sizeof(parentstack)); + ZERO(&values,(int)sizeof(values)); + + stackpos=0; + + char *xmldata=doloadfile(filename); + if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed + + root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK); + + delete(xmldata); + + 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); + + values.xml_version.major=str2int(mxmlElementGetAttr(root,"version-major")); + values.xml_version.minor=str2int(mxmlElementGetAttr(root,"version-minor")); + + return(0); +}; + + +char *XMLwrapper::doloadfile(const char *filename){ + char *xmldata=NULL; + int filesize=-1; + + //try get filesize as gzip data (first) + gzFile gzfile=gzopen(filename,"rb"); + if (gzfile!=NULL){//this is a gzip file + // first check it's size + while(!gzeof(gzfile)) { + gzseek (gzfile,1024*1024,SEEK_CUR); + if (gztell(gzfile)>10000000) { + gzclose(gzfile); + goto notgzip;//the file is too big + }; + }; + filesize=gztell(gzfile); + + //rewind the file and load the data + xmldata=new char[filesize+1]; + ZERO(xmldata,filesize+1); + + gzrewind(gzfile); + gzread(gzfile,xmldata,filesize); + + gzclose(gzfile); + return (xmldata); + } else {//this is not a gzip file + notgzip: + FILE *file=fopen(filename,"rb"); + if (file==NULL) return(NULL); + fseek(file,0,SEEK_END); + filesize=ftell(file); + + xmldata=new char [filesize+1]; + ZERO(xmldata,filesize+1); + + rewind(file); + fread(xmldata,filesize,1,file); + + fclose(file); + return(xmldata); + }; +}; + +bool XMLwrapper::putXMLdata(char *xmldata){ + if (tree!=NULL) mxmlDelete(tree); + tree=NULL; + + ZERO(&parentstack,(int)sizeof(parentstack)); + ZERO(&values,(int)sizeof(values)); + + stackpos=0; + + if (xmldata==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); +}; + + + +int XMLwrapper::enterbranch(char *name){ + node=mxmlFindElement(peek(),peek(),name,NULL,NULL,MXML_DESCEND_FIRST); + if (node==NULL) return(0); + + push(node); + return(1); +}; + +int XMLwrapper::enterbranch(char *name,int id){ + snprintf(tmpstr,TMPSTR_SIZE,"%d",id); + node=mxmlFindElement(peek(),peek(),name,"id",tmpstr,MXML_DESCEND_FIRST); + if (node==NULL) return(0); + + push(node); + return(1); +}; + + +void XMLwrapper::exitbranch(){ + pop(); +}; + + +int XMLwrapper::getbranchid(int min, int max){ + int id=str2int(mxmlElementGetAttr(node,"id")); + if ((min==0)&&(max==0)) return(id); + + if (id<min) id=min; + else if (id>max) id=max; + + return(id); +}; + +int XMLwrapper::getpar(char *name,int defaultpar,int min,int max){ + node=mxmlFindElement(peek(),peek(),"par","name",name,MXML_DESCEND_FIRST); + if (node==NULL) return(defaultpar); + + const char *strval=mxmlElementGetAttr(node,"value"); + if (strval==NULL) return(defaultpar); + + int val=str2int(strval); + if (val<min) val=min; + else if (val>max) val=max; + + return(val); +}; + +int XMLwrapper::getpar127(char *name,int defaultpar){ + return(getpar(name,defaultpar,0,127)); +}; + +int XMLwrapper::getparbool(char *name,int defaultpar){ + node=mxmlFindElement(peek(),peek(),"par_bool","name",name,MXML_DESCEND_FIRST); + if (node==NULL) return(defaultpar); + + const char *strval=mxmlElementGetAttr(node,"value"); + if (strval==NULL) return(defaultpar); + + if ((strval[0]=='Y')||(strval[0]=='y')) return(1); + else return(0); +}; + +void XMLwrapper::getparstr(char *name,char *par,int maxstrlen){ + ZERO(par,maxstrlen); + node=mxmlFindElement(peek(),peek(),"string","name",name,MXML_DESCEND_FIRST); + + if (node==NULL) return; + if (node->child==NULL) return; + if (node->child->type!=MXML_OPAQUE) return; + + snprintf(par,maxstrlen,"%s",node->child->value.element.name); + +}; + +REALTYPE XMLwrapper::getparreal(char *name,REALTYPE defaultpar){ + node=mxmlFindElement(peek(),peek(),"par_real","name",name,MXML_DESCEND_FIRST); + if (node==NULL) return(defaultpar); + + const char *strval=mxmlElementGetAttr(node,"value"); + if (strval==NULL) return(defaultpar); + + return(str2real(strval)); +}; + +REALTYPE XMLwrapper::getparreal(char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max){ + 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){ + 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(char *name){ + mxml_node_t *element=mxmlNewElement(node,name); + return(element); +}; + +mxml_node_t *XMLwrapper::addparams1(char *name,char *par1,char *val1){ + mxml_node_t *element=mxmlNewElement(node,name); + mxmlElementSetAttr(element,par1,val1); + return(element); +}; + +mxml_node_t *XMLwrapper::addparams2(char *name,char *par1,char *val1,char *par2, 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) { + printf("BUG!: XMLwrapper::push() - full parentstack\n"); + return; + }; + stackpos++; + parentstack[stackpos]=node; + +// printf("push %d - %s\n",stackpos,node->value.element.name); + +}; +mxml_node_t *XMLwrapper::pop(){ + if (stackpos<=0) { + printf("BUG!: XMLwrapper::pop() - empty parentstack\n"); + 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) { + printf("BUG!: XMLwrapper::peek() - empty parentstack\n"); + return (root); + }; + return(parentstack[stackpos]); +}; + + + diff --git a/muse/synti/zynaddsubfx/Misc/XMLwrapper.h b/muse/synti/zynaddsubfx/Misc/XMLwrapper.h new file mode 100644 index 00000000..765622a2 --- /dev/null +++ b/muse/synti/zynaddsubfx/Misc/XMLwrapper.h @@ -0,0 +1,175 @@ +/* + ZynAddSubFX - a software synthesizer + + XML.h - XML wrapper + Copyright (C) 2003-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) 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 <mxml.h> +#ifndef REALTYPE +#define REALTYPE float +#endif + +#ifndef XML_WRAPPER_H +#define XML_WRAPPER_H + +#define TMPSTR_SIZE 50 + +//the maxim tree depth +#define STACKSIZE 100 + +class XMLwrapper{ + public: + XMLwrapper(); + ~XMLwrapper(); + + /********************************/ + /* SAVE to XML */ + /********************************/ + + //returns 0 if ok or -1 if the file cannot be saved + int saveXMLfile(char *filename); + + //returns the new allocated string that contains the XML data (used for clipboard) + //the string is NULL terminated + char *getXMLdata(); + + //add simple parameter (name and value) + void addpar(char *name,int val); + void addparreal(char *name,REALTYPE val); + + //add boolean parameter (name and boolean value) + //if the value is 0 => "yes", else "no" + void addparbool(char *name,int val); + + //add string parameter (name and string) + void addparstr(char *name,char *val); + + //add a branch + void beginbranch(char *name); + void beginbranch(char *name, int id); + + //this must be called after each branch (nodes that contains child nodes) + void endbranch(); + + /********************************/ + /* LOAD from XML */ + /********************************/ + + //returns 0 if ok or -1 if the file cannot be loaded + int loadXMLfile(const char *filename); + + //used by the clipboard + bool putXMLdata(char *xmldata); + + //enter into the branch + //returns 1 if is ok, or 0 otherwise + int enterbranch(char *name); + + + //enter into the branch with id + //returns 1 if is ok, or 0 otherwise + int enterbranch(char *name, int id); + + //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); + + //it returns the parameter and limits it between min and max + //if min==max==0, it will not limit it + //if no parameter will be here, the defaultpar will be returned + int getpar(char *name,int defaultpar,int min,int max); + + //the same as getpar, but the limits are 0 and 127 + int getpar127(char *name,int defaultpar); + + int getparbool(char *name,int defaultpar); + + void getparstr(char *name,char *par,int maxstrlen); + REALTYPE getparreal(char *name,REALTYPE defaultpar); + REALTYPE getparreal(char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max); + + bool minimal;//false if all parameters will be stored (used only for clipboard) + + struct { + bool PADsynth_used; + }information; + + //opens a file and parse only the "information" data on it + //returns "true" if all went ok or "false" on errors + bool checkfileinformation(char *filename); + + private: + + int dosavefile(char *filename,int compression,char *xmldata); + char *doloadfile(const char *filename); + + + mxml_node_t *tree;//all xml data + mxml_node_t *root;//xml data used by zynaddsubfx + mxml_node_t *node;//current node + mxml_node_t *info;//this node is used to store the information about the data + + //adds params like this: + // <name> + //returns the node + mxml_node_t *addparams0(char *name); + + //adds params like this: + // <name par1="val1"> + //returns the node + mxml_node_t *addparams1(char *name,char *par1,char *val1); + + //adds params like this: + // <name par1="val1" par2="val2"> + //returns the node + mxml_node_t *addparams2(char *name,char *par1,char *val1,char *par2, char *val2); + + char *int2str(int x); + char *real2str(REALTYPE x); + + int str2int(const char *str); + REALTYPE str2real(const char *str); + + char tmpstr[TMPSTR_SIZE]; + + + //this is used to store the parents + mxml_node_t *parentstack[STACKSIZE]; + int stackpos; + + + void push(mxml_node_t *node); + mxml_node_t *pop(); + mxml_node_t *peek(); + + //theese are used to store the values + struct{ + struct { + int major,minor; + }xml_version; + }values; + +}; + +#endif diff --git a/muse/synti/zynaddsubfx/Output/Recorder.C b/muse/synti/zynaddsubfx/Output/Recorder.C new file mode 100644 index 00000000..525bedc5 --- /dev/null +++ b/muse/synti/zynaddsubfx/Output/Recorder.C @@ -0,0 +1,138 @@ +/* + ZynAddSubFX - a software synthesizer + + Recorder.C - Records sound to a file + 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) 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 <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> + +#include "Recorder.h" + +Recorder::Recorder(){ + recordbuf_16bit=new short int [SOUND_BUFFER_SIZE*2]; + status=0;file=-1; + sampleswritten=0; + notetrigger=0; + for (int i=0;i<SOUND_BUFFER_SIZE*2;i++){ + recordbuf_16bit[i]=0; + }; +}; + +Recorder::~Recorder(){ + if (recording()==1) stop(); + delete [] recordbuf_16bit; +}; + +int Recorder::preparefile(char *filename_,int overwrite){ + if (overwrite==0) file=open(filename_,O_CREAT|O_EXCL|O_WRONLY|O_BINARY,00444+00222); + else file=open(filename_,O_CREAT|O_WRONLY|O_TRUNC|O_BINARY,00444+00222);//overwrite if the file exists + if (file==-1) { + if (errno==EEXIST) return(1);//file exists already + else return(2);//Access Denied or any other problem + }; + status=1;//ready + + //prepare the space fot the wav header + //the header itself, will be written when the file is closed + unsigned char zerobuf[44]; for (int i=0;i<44;i++) zerobuf[i]=0; + write(file,zerobuf,44); + + return(0); +}; + +void Recorder::start(){ + notetrigger=0; + status=2;//recording +}; + +void Recorder::stop(){ + unsigned int chunksize; + lseek(file,0,SEEK_SET); + + write(file,"RIFF",4); + chunksize=sampleswritten*4+36; + write(file,&chunksize,4); + + write(file,"WAVEfmt ",8); + chunksize=16; + write(file,&chunksize,4); + unsigned short int formattag=1;//uncompresed wave + write(file,&formattag,2); + unsigned short int nchannels=2;//stereo + write(file,&nchannels,2); + unsigned int samplerate=SAMPLE_RATE;//samplerate + write(file,&samplerate,4); + unsigned int bytespersec=SAMPLE_RATE*4;//bytes/sec + write(file,&bytespersec,4); + unsigned short int blockalign=4;//2 channels * 16 bits/8 + write(file,&blockalign,2); + unsigned short int bitspersample=16; + write(file,&bitspersample,2); + + write(file,"data",4); + chunksize=sampleswritten*blockalign; + write(file,&chunksize,4); + + close(file); + file=-1; + status=0; + sampleswritten=0; +}; + +void Recorder::pause(){ + status=0; +}; + +int Recorder::recording(){ + if ((status==2)&&(notetrigger!=0)) return(1); + else return(0); +}; + +void Recorder::recordbuffer(REALTYPE *outl,REALTYPE *outr){ + int 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; + }; + if (write(file,recordbuf_16bit,SOUND_BUFFER_SIZE*4)<SOUND_BUFFER_SIZE*4) { + fprintf(stderr,"Error while recording !\n"); + stop(); + }; + sampleswritten+=SOUND_BUFFER_SIZE; +}; + +void Recorder::triggernow(){ + if (status==2) notetrigger=1; +}; diff --git a/muse/synti/zynaddsubfx/Output/Recorder.h b/muse/synti/zynaddsubfx/Output/Recorder.h new file mode 100644 index 00000000..fea6e409 --- /dev/null +++ b/muse/synti/zynaddsubfx/Output/Recorder.h @@ -0,0 +1,52 @@ +/* + ZynAddSubFX - a software synthesizer + + Recorder.h - Records sound to a file + 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) 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 RECORDER_H +#define RECORDER_H + +#include "../globals.h" + +class Recorder{ + public: + Recorder(); + ~Recorder(); + int preparefile(char *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; + + private: + int file; + short int *recordbuf_16bit; + int sampleswritten,notetrigger; +}; + +#endif diff --git a/muse/synti/zynaddsubfx/Params/ADnoteParameters.C b/muse/synti/zynaddsubfx/Params/ADnoteParameters.C new file mode 100644 index 00000000..fdbbbe83 --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/ADnoteParameters.C @@ -0,0 +1,637 @@ +/* + ZynAddSubFX - a software synthesizer + + ADnoteParameters.C - Parameters for ADnote (ADsynth) + 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) 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 <stdlib.h> +#include <stdio.h> +#include <math.h> + +#include "ADnoteParameters.h" + +ADnoteParameters::ADnoteParameters(FFTwrapper *fft_):Presets(){ + setpresettype("Padsyth"); + 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.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(); + + for (int nvoice=0;nvoice<NUM_VOICES;nvoice++) EnableVoice(nvoice); + + defaults(); +}; + +void ADnoteParameters::defaults(){ + //Default Parameters + /* Frequency Global Parameters */ + GlobalPar.PStereo=1;//stereo + GlobalPar.PDetune=8192;//zero + GlobalPar.PCoarseDetune=0; + GlobalPar.PDetuneType=1; + GlobalPar.FreqEnvelope->defaults(); + GlobalPar.FreqLfo->defaults(); + GlobalPar.PBandwidth=64; + + /* Amplitude Global Parameters */ + 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; + + /* Filter Global Parameters*/ + GlobalPar.PFilterVelocityScale=64; + GlobalPar.PFilterVelocityScaleFunction=64; + GlobalPar.GlobalFilter->defaults(); + GlobalPar.FilterEnvelope->defaults(); + GlobalPar.FilterLfo->defaults(); + GlobalPar.Reson->defaults(); + + + for (int nvoice=0;nvoice<NUM_VOICES;nvoice++){ + defaults(nvoice); + }; + VoicePar[0].Enabled=1; +}; + +/* + * Defaults a voice + */ +void ADnoteParameters::defaults(int n){ + int nvoice=n; + VoicePar[nvoice].Enabled=0; + VoicePar[nvoice].Type=0; + VoicePar[nvoice].Pfixedfreq=0; + VoicePar[nvoice].PfixedfreqET=0; + VoicePar[nvoice].Presonance=1; + VoicePar[nvoice].Pfilterbypass=0; + VoicePar[nvoice].Pextoscil=-1; + VoicePar[nvoice].PextFMoscil=-1; + VoicePar[nvoice].Poscilphase=64; + VoicePar[nvoice].PFMoscilphase=64; + VoicePar[nvoice].PDelay=0; + VoicePar[nvoice].PVolume=100; + VoicePar[nvoice].PVolumeminus=0; + VoicePar[nvoice].PPanning=64;//center + VoicePar[nvoice].PDetune=8192;//8192=0 + VoicePar[nvoice].PCoarseDetune=0; + VoicePar[nvoice].PDetuneType=0; + VoicePar[nvoice].PFreqLfoEnabled=0; + VoicePar[nvoice].PFreqEnvelopeEnabled=0; + VoicePar[nvoice].PAmpEnvelopeEnabled=0; + VoicePar[nvoice].PAmpLfoEnabled=0; + VoicePar[nvoice].PAmpVelocityScaleFunction=127; + VoicePar[nvoice].PFilterEnabled=0; + VoicePar[nvoice].PFilterEnvelopeEnabled=0; + VoicePar[nvoice].PFilterLfoEnabled=0; + VoicePar[nvoice].PFMEnabled=0; + + //I use the internal oscillator (-1) + VoicePar[nvoice].PFMVoice=-1; + + VoicePar[nvoice].PFMVolume=90; + VoicePar[nvoice].PFMVolumeDamp=64; + VoicePar[nvoice].PFMDetune=8192; + VoicePar[nvoice].PFMCoarseDetune=0; + VoicePar[nvoice].PFMDetuneType=0; + VoicePar[nvoice].PFMFreqEnvelopeEnabled=0; + VoicePar[nvoice].PFMAmpEnvelopeEnabled=0; + VoicePar[nvoice].PFMVelocityScaleFunction=64; + + VoicePar[nvoice].OscilSmp->defaults(); + VoicePar[nvoice].FMSmp->defaults(); + + VoicePar[nvoice].AmpEnvelope->defaults(); + VoicePar[nvoice].AmpLfo->defaults(); + + VoicePar[nvoice].FreqEnvelope->defaults(); + VoicePar[nvoice].FreqLfo->defaults(); + + VoicePar[nvoice].VoiceFilter->defaults(); + VoicePar[nvoice].FilterEnvelope->defaults(); + VoicePar[nvoice].FilterLfo->defaults(); + + VoicePar[nvoice].FMFreqEnvelope->defaults(); + VoicePar[nvoice].FMAmpEnvelope->defaults(); +}; + + + +/* + * Init the voice parameters + */ +void ADnoteParameters::EnableVoice(int nvoice){ + 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].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].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); + + return(bw); +}; + + +/* + * Kill the voice + */ +void ADnoteParameters::KillVoice(int nvoice){ + delete (VoicePar[nvoice].OscilSmp); + delete (VoicePar[nvoice].FMSmp); + + delete (VoicePar[nvoice].AmpEnvelope); + delete (VoicePar[nvoice].AmpLfo); + + delete (VoicePar[nvoice].FreqEnvelope); + delete (VoicePar[nvoice].FreqLfo); + + delete (VoicePar[nvoice].VoiceFilter); + delete (VoicePar[nvoice].FilterEnvelope); + delete (VoicePar[nvoice].FilterLfo); + + 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); + + for (int nvoice=0;nvoice<NUM_VOICES;nvoice++){ + KillVoice(nvoice); + }; +}; + + + + +void ADnoteParameters::add2XMLsection(XMLwrapper *xml,int n){ + int nvoice=n; + if (nvoice>=NUM_VOICES) return; + + int oscilused=0,fmoscilused=0;//if the oscil or fmoscil are used by another voice + + for (int i=0;i<NUM_VOICES;i++){ + if (VoicePar[i].Pextoscil==nvoice) oscilused=1; + if (VoicePar[i].PextFMoscil==nvoice) fmoscilused=1; + }; + + 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("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); + xml->endbranch(); + + + 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->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->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("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->beginbranch("FREQUENCY_LFO"); + VoicePar[nvoice].FreqLfo->add2XML(xml); + xml->endbranch(); + }; + xml->endbranch(); + + + 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->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->beginbranch("FILTER_LFO"); + VoicePar[nvoice].FilterLfo->add2XML(xml); + xml->endbranch(); + }; + xml->endbranch(); + }; + + if ((VoicePar[nvoice].PFMEnabled!=0)||(fmoscilused!=0)||(!xml->minimal)){ + xml->beginbranch("FM_PARAMETERS"); + 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->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->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); + xml->endbranch(); + + xml->endbranch(); + xml->endbranch(); + }; +}; + + +void ADnoteParameters::add2XML(XMLwrapper *xml){ + 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->beginbranch("AMPLITUDE_ENVELOPE"); + GlobalPar.AmpEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("AMPLITUDE_LFO"); + GlobalPar.AmpLfo->add2XML(xml); + xml->endbranch(); + xml->endbranch(); + + xml->beginbranch("FREQUENCY_PARAMETERS"); + xml->addpar("detune",GlobalPar.PDetune); + + xml->addpar("coarse_detune",GlobalPar.PCoarseDetune); + xml->addpar("detune_type",GlobalPar.PDetuneType); + + xml->addpar("bandwidth",GlobalPar.PBandwidth); + + xml->beginbranch("FREQUENCY_ENVELOPE"); + GlobalPar.FreqEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FREQUENCY_LFO"); + GlobalPar.FreqLfo->add2XML(xml); + xml->endbranch(); + xml->endbranch(); + + + xml->beginbranch("FILTER_PARAMETERS"); + xml->addpar("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale); + xml->addpar("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction); + + xml->beginbranch("FILTER"); + GlobalPar.GlobalFilter->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FILTER_ENVELOPE"); + GlobalPar.FilterEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FILTER_LFO"); + GlobalPar.FilterLfo->add2XML(xml); + xml->endbranch(); + xml->endbranch(); + + xml->beginbranch("RESONANCE"); + GlobalPar.Reson->add2XML(xml); + xml->endbranch(); + + 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); + + 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); + + if (xml->enterbranch("AMPLITUDE_ENVELOPE")){ + GlobalPar.AmpEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + 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); + + GlobalPar.PBandwidth=xml->getpar127("bandwidth",GlobalPar.PBandwidth); + + xml->enterbranch("FREQUENCY_ENVELOPE"); + GlobalPar.FreqEnvelope->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FREQUENCY_LFO"); + GlobalPar.FreqLfo->getfromXML(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); + + xml->enterbranch("FILTER"); + GlobalPar.GlobalFilter->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FILTER_ENVELOPE"); + GlobalPar.FilterEnvelope->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FILTER_LFO"); + GlobalPar.FilterLfo->getfromXML(xml); + xml->exitbranch(); + xml->exitbranch(); + }; + + if (xml->enterbranch("RESONANCE")){ + GlobalPar.Reson->getfromXML(xml); + xml->exitbranch(); + }; + + 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){ + int nvoice=n; + if (nvoice>=NUM_VOICES) return; + + 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].Pextoscil=xml->getpar("ext_oscil",-1,-1,nvoice-1); + VoicePar[nvoice].PextFMoscil=xml->getpar("ext_fm_oscil",-1,-1,nvoice-1); + + VoicePar[nvoice].Poscilphase=xml->getpar127("oscil_phase",VoicePar[nvoice].Poscilphase); + VoicePar[nvoice].PFMoscilphase=xml->getpar127("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase); + + VoicePar[nvoice].PFilterEnabled=xml->getparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled); + VoicePar[nvoice].Pfilterbypass=xml->getparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass); + + 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); + + 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].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); + + + 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].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].FreqLfo->getfromXML(xml); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + + 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].FilterEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + 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); + + 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].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); + + 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")){ + VoicePar[nvoice].FMSmp->getfromXML(xml); + xml->exitbranch(); + }; + + xml->exitbranch(); + }; + xml->exitbranch(); + }; +}; + + diff --git a/muse/synti/zynaddsubfx/Params/ADnoteParameters.h b/muse/synti/zynaddsubfx/Params/ADnoteParameters.h new file mode 100644 index 00000000..1773f2cd --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/ADnoteParameters.h @@ -0,0 +1,282 @@ +/* + ZynAddSubFX - a software synthesizer + + ADnoteParameters.h - Parameters for ADnote (ADsynth) + 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) 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 AD_NOTE_PARAMETERS_H +#define AD_NOTE_PARAMETERS_H + + +#include "../globals.h" +#include "EnvelopeParams.h" +#include "LFOParams.h" +#include "FilterParams.h" +#include "../Synth/OscilGen.h" +#include "../Synth/Resonance.h" +#include "../Misc/Util.h" +#include "../Misc/XMLwrapper.h" +#include "../DSP/FFTwrapper.h" +#include "Presets.h" + + enum FMTYPE{NONE,MORPH,RING_MOD,PHASE_MOD,FREQ_MOD,PITCH_MOD}; + + /*****************************************************************/ + /* 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. */ + + unsigned char PStereo; + + + /****************************************** + * FREQUENCY GLOBAL PARAMETERS * + ******************************************/ + 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 + + EnvelopeParams *FreqEnvelope; //Frequency Envelope + + LFOParams *FreqLfo;//Frequency LFO + + /******************************************** + * AMPLITUDE GLOBAL PARAMETERS * + ********************************************/ + + /* Panning - 0 - random + 1 - left + 64 - center + 127 - right */ + unsigned char PPanning; + + unsigned char PVolume; + + unsigned char PAmpVelocityScaleFunction; + + EnvelopeParams *AmpEnvelope; + + LFOParams *AmpLfo; + + unsigned char PPunchStrength,PPunchTime,PPunchStretch,PPunchVelocitySensing; + + /****************************************** + * FILTER GLOBAL PARAMETERS * + ******************************************/ + FilterParams *GlobalFilter; + + // filter velocity sensing + unsigned char PFilterVelocityScale; + + // filter velocity sensing + unsigned char PFilterVelocityScaleFunction; + + EnvelopeParams *FilterEnvelope; + + LFOParams *FilterLfo; + + // RESONANCE + Resonance *Reson; + + //how the randomness is applied to the harmonics on more voices using the same oscillator + unsigned char Hrandgrouping; + }; + + + + /***********************************************************/ + /* VOICE PARAMETERS */ + /***********************************************************/ + struct ADnoteVoiceParam{ + + /* If the voice is enabled */ + unsigned char Enabled; + + /* Type of the voice (0=Sound,1=Noise)*/ + unsigned char Type; + + /* Voice Delay */ + unsigned char PDelay; + + /* If the resonance is enabled for this voice */ + unsigned char Presonance; + + // What external oscil should I use, -1 for internal OscilSmp&FMSmp + short int Pextoscil,PextFMoscil; + // it is not allowed that the externoscil,externFMoscil => current voice + + // oscillator phases + unsigned char Poscilphase,PFMoscilphase; + + // filter bypass + unsigned char Pfilterbypass; + + /* Voice oscillator */ + OscilGen *OscilSmp; + + /********************************** + * FREQUENCY PARAMETERS * + **********************************/ + + /* 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; + + /* Fine detune */ + unsigned short int PDetune; + + /* Coarse detune + octave */ + unsigned short int PCoarseDetune; + + /* Detune type */ + unsigned char PDetuneType; + + /* Frequency Envelope */ + unsigned char PFreqEnvelopeEnabled; + EnvelopeParams *FreqEnvelope; + + /* Frequency LFO */ + unsigned char PFreqLfoEnabled; + LFOParams *FreqLfo; + + + /*************************** + * AMPLITUDE PARAMETERS * + ***************************/ + + /* Panning 0 - random + 1 - left + 64 - center + 127 - right + The Panning is ignored if the instrument is mono */ + unsigned char PPanning; + + /* Voice Volume */ + unsigned char PVolume; + + /* If the Volume negative */ + unsigned char PVolumeminus; + + /* Velocity sensing */ + unsigned char PAmpVelocityScaleFunction; + + /* Amplitude Envelope */ + unsigned char PAmpEnvelopeEnabled; + EnvelopeParams *AmpEnvelope; + + /* Amplitude LFO */ + unsigned char PAmpLfoEnabled; + LFOParams *AmpLfo; + + + + /************************* + * FILTER PARAMETERS * + *************************/ + + /* Voice Filter */ + unsigned char PFilterEnabled; + FilterParams *VoiceFilter; + + /* Filter Envelope */ + unsigned char PFilterEnvelopeEnabled; + EnvelopeParams *FilterEnvelope; + + /* LFO Envelope */ + unsigned char PFilterLfoEnabled; + LFOParams *FilterLfo; + + /**************************** + * MODULLATOR PARAMETERS * + ****************************/ + + /* Modullator Parameters (0=off,1=Morph,2=RM,3=PM,4=FM.. */ + unsigned char PFMEnabled; + + /* Voice that I use as modullator instead of FMSmp. + It is -1 if I use FMSmp(default). + It maynot be equal or bigger than current voice */ + short int PFMVoice; + + /* Modullator oscillator */ + OscilGen *FMSmp; + + /* Modullator Volume */ + unsigned char PFMVolume; + + /* Modullator damping at higher frequencies */ + unsigned char PFMVolumeDamp; + + /* Modullator Velocity Sensing */ + unsigned char PFMVelocityScaleFunction; + + /* Fine Detune of the Modullator*/ + unsigned short int PFMDetune; + + /* Coarse Detune of the Modullator */ + unsigned short int PFMCoarseDetune; + + /* The detune type */ + unsigned char PFMDetuneType; + + /* Frequency Envelope of the Modullator */ + unsigned char PFMFreqEnvelopeEnabled; + EnvelopeParams *FMFreqEnvelope; + + /* Frequency Envelope of the Modullator */ + unsigned char PFMAmpEnvelopeEnabled; + EnvelopeParams *FMAmpEnvelope; + }; + +class ADnoteParameters:public Presets{ + public: + ADnoteParameters(FFTwrapper *fft_); + ~ADnoteParameters(); + + ADnoteGlobalParam GlobalPar; + ADnoteVoiceParam VoicePar[NUM_VOICES]; + + void defaults(); + void add2XML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); + + REALTYPE getBandwidthDetuneMultiplier(); + private: + void defaults(int n);//n is the nvoice + + void EnableVoice(int nvoice); + void KillVoice(int nvoice); + FFTwrapper *fft; + + void add2XMLsection(XMLwrapper *xml,int n); + void getfromXMLsection(XMLwrapper *xml,int n); +}; + +#endif diff --git a/muse/synti/zynaddsubfx/Params/Controller.C b/muse/synti/zynaddsubfx/Params/Controller.C new file mode 100644 index 00000000..30f59161 --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/Controller.C @@ -0,0 +1,300 @@ +/* + ZynAddSubFX - a software synthesizer + + Controller.C - (Midi) Controllers implementation + 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) 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 "Controller.h" +#include <math.h> +#include <stdio.h> + +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=0; + sustain.receive=1; + NRPN.receive=1; + + portamento.portamento=0; + portamento.used=0; + 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); + setportamento(0); + +}; + +void Controller::resetall(){ + setpitchwheel(0);//center + setexpression(127); + setpanning(64); + setfiltercutoff(64); + setfilterq(64); + setbandwidth(64); + setmodwheel(64); + setfmamp(127); + setvolume(127); + setsustain(0); + setresonancecenter(64); + setresonancebw(64); + + //reset the NRPN + 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); + //fprintf(stderr,"%ld %ld -> %.3f\n",pitchwheel.bendrange,pitchwheel.data,pitchwheel.relfreq);fflush(stderr); +}; + +void Controller::setpitchwheelbendrange(unsigned short int 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; +}; + +void Controller::setpanning(int value){ + 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) +}; + +void Controller::setfilterq(int value){ + 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)); + }; +}; + +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)); +}; + +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; +}; + +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; +}; + +void Controller::setsustain(int value){ + 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 ); +}; + +int Controller::initportamento(REALTYPE oldfreq,REALTYPE newfreq){ + portamento.x=0.0; + 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.updowntimestretch>=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); + }; + + 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 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); + + portamento.used=1; + portamento.freqrap=portamento.origfreqrap; + return (1); +}; + +void Controller::updateportamento(){ + 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; +}; + + +void Controller::setresonancecenter(int value){ + 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)); +}; + + +//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); + + *parhi=NRPN.parhi; + *parlo=NRPN.parlo; + *valhi=NRPN.valhi; + *vallo=NRPN.vallo; + return(0); +}; + + +void Controller::setparameternumber(unsigned int type,int value){ + switch(type){ + case C_nrpnhi: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 + break; + case C_dataentryhi:if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.valhi=value; + break; + case C_dataentrylo:if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.vallo=value; + break; + }; +}; + + + +void Controller::add2XML(XMLwrapper *xml){ + 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("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("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); + + 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); + + resonancecenter.depth=xml->getpar127("resonance_center_depth",resonancecenter.depth); + resonancebandwidth.depth=xml->getpar127("resonance_bandwidth_depth",resonancebandwidth.depth); +}; + + + diff --git a/muse/synti/zynaddsubfx/Params/Controller.h b/muse/synti/zynaddsubfx/Params/Controller.h new file mode 100644 index 00000000..12257b59 --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/Controller.h @@ -0,0 +1,179 @@ +/* + ZynAddSubFX - a software synthesizer + + Controller.h - (Midi) Controllers implementation + 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) 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 CONTROLLER_H +#define CONTROLLER_H + +#include "../globals.h" +#include "../Misc/XMLwrapper.h" + +class Controller{ + public: + Controller(); + ~Controller(); + void resetall(); + + 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); + 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); + + int initportamento(REALTYPE oldfreq,REALTYPE newfreq);//returns 1 if the portamento's conditions are true, else return 0 + void updateportamento(); //update portamento values + + // 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{//Portamento + //parameters + int data; + unsigned char portamento; + + //pitchthresh is the threshold of enabling protamento + //pitchthreshtype -> enable the portamento only below(0)/above(1) the threshold + unsigned char receive,time,pitchthresh,pitchthreshtype; + + //'up portanemto' means when the frequency is rising (eg: the portamento is from 200Hz to 300 Hz) + //'down portanemto' means when the frequency is lowering (eg: the portamento is from 300Hz to 200 Hz) + unsigned char updowntimestretch;//this value represent how the portamento time is reduced + //0 - for down portamento, 1..63 - the up portamento's time is smaller than the down portamento + //64 - the portamento time is always the same + //64-126 - the down portamento's time is smaller than the up portamento + //127 - for upper portamento + + REALTYPE freqrap;//this value is used to compute the actual portamento + int noteusing;//this is used by the Part:: for knowing which note uses the portamento + int used;//if a the portamento is used by a note + //internal data + REALTYPE x,dx;//x is from 0.0 (start portamento) to 1.0 (finished portamento), dx is x increment + REALTYPE origfreqrap;// this is used for computing oldfreq value from x + } portamento; + + struct{//Resonance Center Frequency + int data; + REALTYPE relcenter; + unsigned char depth; + } resonancecenter; + + struct{//Resonance Bandwidth + int data; + REALTYPE relbw; + unsigned char depth; + } resonancebandwidth; + + + /* RPN and NPRPN */ + struct{//nrpn + int parhi,parlo; + int valhi,vallo; + unsigned char receive;//this is saved to disk by Master + } NRPN; + + private: +}; + + + + + +#endif + diff --git a/muse/synti/zynaddsubfx/Params/EnvelopeParams.C b/muse/synti/zynaddsubfx/Params/EnvelopeParams.C new file mode 100644 index 00000000..074d6aee --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/EnvelopeParams.C @@ -0,0 +1,227 @@ +/* + ZynAddSubFX - a software synthesizer + + EnvelopeParams.C - Parameters for Envelope + 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) 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 <stdio.h> + +#include <math.h> +#include <stdlib.h> +#include "EnvelopeParams.h" + +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; + + for (i=0;i<MAX_ENVELOPE_POINTS;i++){ + Penvdt[i]=32; + Penvval[i]=64; + }; + Penvdt[0]=0;//no used + Penvsustain=1; + Penvpoints=1; + Envmode=1; + Penvstretch=Penvstretch_; + Pforcedrelease=Pforcedrelease_; + Pfreemode=1; + Plinearenvelope=0; + + store2defaults(); +}; + +EnvelopeParams::~EnvelopeParams(){ +}; + +REALTYPE EnvelopeParams::getdt(char i){ + REALTYPE result=(pow(2.0,Penvdt[i]/127.0*12.0)-1.0)*10.0;//miliseconds + return(result); +}; + + +/* + * ADSR/ASR... initialisations + */ +void EnvelopeParams::ADSRinit(char A_dt,char D_dt,char S_val,char R_dt){ + setpresettype("Penvamplitude"); + Envmode=1; + PA_dt=A_dt;PD_dt=D_dt;PS_val=S_val;PR_dt=R_dt; + Pfreemode=0; + converttofree(); + + store2defaults(); +}; + +void EnvelopeParams::ADSRinit_dB(char A_dt,char D_dt,char S_val,char R_dt){ + setpresettype("Penvamplitude"); + Envmode=2; + PA_dt=A_dt;PD_dt=D_dt;PS_val=S_val;PR_dt=R_dt; + Pfreemode=0; + converttofree(); + + store2defaults(); +}; + +void EnvelopeParams::ASRinit(char A_val,char A_dt,char R_val,char R_dt){ + setpresettype("Penvfrequency"); + Envmode=3; + PA_val=A_val;PA_dt=A_dt;PR_val=R_val;PR_dt=R_dt; + Pfreemode=0; + converttofree(); + + store2defaults(); +}; + +void EnvelopeParams::ADSRinit_filter(char A_val,char A_dt,char D_val,char D_dt,char R_dt,char R_val){ + setpresettype("Penvfilter"); + Envmode=4; + PA_val=A_val;PA_dt=A_dt;PD_val=D_val;PD_dt=D_dt;PR_dt=R_dt;PR_val=R_val; + Pfreemode=0; + converttofree(); + store2defaults(); +}; + +void EnvelopeParams::ASRinit_bw(char A_val,char A_dt,char R_val,char R_dt){ + setpresettype("Penvbandwidth"); + Envmode=5; + PA_val=A_val;PA_dt=A_dt;PR_val=R_val;PR_dt=R_dt; + Pfreemode=0; + converttofree(); + store2defaults(); +}; + +/* + * Convert the Envelope to freemode + */ +void EnvelopeParams::converttofree(){ + switch (Envmode){ + case 1: Penvpoints=4;Penvsustain=2; + Penvval[0]=0;Penvdt[1]=PA_dt;Penvval[1]=127; + Penvdt[2]=PD_dt;Penvval[2]=PS_val; + Penvdt[3]=PR_dt;Penvval[3]=0; + break; + case 2: Penvpoints=4;Penvsustain=2; + Penvval[0]=0;Penvdt[1]=PA_dt; + Penvval[1]=127;Penvdt[2]=PD_dt; + Penvval[2]=PS_val;Penvdt[3]=PR_dt;Penvval[3]=0; + break; + case 3: Penvpoints=3;Penvsustain=1; + Penvval[0]=PA_val;Penvdt[1]=PA_dt; + Penvval[1]=64;Penvdt[2]=PR_dt;Penvval[2]=PR_val; + break; + case 4: Penvpoints=4;Penvsustain=2; + Penvval[0]=PA_val;Penvdt[1]=PA_dt; + Penvval[1]=PD_val;Penvdt[2]=PD_dt;Penvval[2]=64; + Penvdt[3]=PR_dt;Penvval[3]=PR_val; + break; + case 5: Penvpoints=3;Penvsustain=1; + Penvval[0]=PA_val;Penvdt[1]=PA_dt; + Penvval[1]=64;Penvdt[2]=PR_dt;Penvval[2]=PR_val; + break; + }; +}; + + + + +void EnvelopeParams::add2XML(XMLwrapper *xml){ + 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;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); + + 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;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(); +}; + + +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; + 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; +}; + + + diff --git a/muse/synti/zynaddsubfx/Params/EnvelopeParams.h b/muse/synti/zynaddsubfx/Params/EnvelopeParams.h new file mode 100644 index 00000000..793291c6 --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/EnvelopeParams.h @@ -0,0 +1,86 @@ +/* + ZynAddSubFX - a software synthesizer + + EnvelopeParams.h - Parameters for Envelope + 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) 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 ENVELOPE_PARAMS_H +#define ENVELOPE_PARAMS_H + +#include "../globals.h" +#include "../Misc/XMLwrapper.h" +#include "Presets.h" + +#define MAX_ENVELOPE_POINTS 40 +#define MIN_ENVELOPE_DB -40 + +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(); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + REALTYPE getdt(char i); + + /* Parametrii MIDI */ + 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; + + + + 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/muse/synti/zynaddsubfx/Params/FilterParams.C b/muse/synti/zynaddsubfx/Params/FilterParams.C new file mode 100644 index 00000000..073f6711 --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/FilterParams.C @@ -0,0 +1,344 @@ +/* + ZynAddSubFX - a software synthesizer + + FilterParams.C - Parameters for filter + 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) 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 <math.h> +#include <stdio.h> +#include <stdlib.h> +#include "FilterParams.h" + +FilterParams::FilterParams(unsigned char Ptype_,unsigned char Pfreq_,unsigned char Pq_):Presets(){ + setpresettype("Pfilter"); + Dtype=Ptype_; + Dfreq=Pfreq_; + Dq=Pq_; + + changed=false; + defaults(); +}; + +FilterParams::~FilterParams(){ +}; + + +void FilterParams::defaults(){ + Ptype=Dtype; + Pfreq=Dfreq; + Pq=Dq; + + Pstages=0; + Pfreqtrack=64; + Pgain=64; + Pcategory=0; + + Pnumformants=3; + Pformantslowness=64; + for (int j=0;j<FF_MAX_VOWELS;j++){ + defaults(j); + }; + + Psequencesize=3; + for (int i=0;i<FF_MAX_SEQUENCE;i++) Psequence[i].nvowel=i%FF_MAX_VOWELS; + + Psequencestretch=40; + Psequencereversed=0; + Pcenterfreq=64;//1 kHz + Poctavesfreq=64; + Pvowelclearness=64; +}; + +void FilterParams::defaults(int n){ + int j=n; + for (int i=0;i<FF_MAX_FORMANTS;i++){ + Pvowels[j].formants[i].freq=(int)(RND*127.0);//some random freqs + Pvowels[j].formants[i].q=64; + Pvowels[j].formants[i].amp=127; + }; +}; + + +/* + * Get the parameters from other FilterParams + */ + +void FilterParams::getfromFilterParams(FilterParams *pars){ + defaults(); + + if (pars==NULL) return; + + Ptype=pars->Ptype; + Pfreq=pars->Pfreq; + Pq=pars->Pq; + + Pstages=pars->Pstages; + Pfreqtrack=pars->Pfreqtrack; + Pgain=pars->Pgain; + Pcategory=pars->Pcategory; + + 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;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; +}; + + +/* + * Parameter control + */ +REALTYPE FilterParams::getfreq(){ + return((Pfreq/64.0-1.0)*5.0); +}; + +REALTYPE FilterParams::getq(){ + 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)); +}; + +REALTYPE FilterParams::getgain(){ + 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)); +}; + +/* + * Get the number of octave that the formant functions applies to + */ +REALTYPE FilterParams::getoctavesfreq(){ + 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)); +}; + +/* + * 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()); +}; + + +/* + * Get the freq. response of the formant filter + */ +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; + + for (int i=0;i<nfreqs;i++) freqs[i]=0.0; + + //for each formant... + for (int nformant=0;nformant<Pnumformants;nformant++){ + //compute formant parameters(frequency,amplitude,etc.) + 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); + + + 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;i<nfreqs;i++) { + REALTYPE freq=getfreqx(i/(REALTYPE) nfreqs); + if (freq>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); + + 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 FilterParams::getformantamp(unsigned char amp){ + 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); +}; + + + +void FilterParams::add2XMLsection(XMLwrapper *xml,int n){ + 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); + + //formant filter parameters + 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;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;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){ + 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); + + //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); + + 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;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/muse/synti/zynaddsubfx/Params/FilterParams.h b/muse/synti/zynaddsubfx/Params/FilterParams.h new file mode 100644 index 00000000..58ebd589 --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/FilterParams.h @@ -0,0 +1,100 @@ +/* + ZynAddSubFX - a software synthesizer + + FilterParams.h - Parameters for filter + 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) 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 FILTER_PARAMS_H +#define FILTER_PARAMS_H + +#include "../globals.h" +#include "../Misc/XMLwrapper.h" +#include "Presets.h" + +class FilterParams:public Presets{ + 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 getfromFilterParams(FilterParams *pars); + + 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 + + //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]; + + + 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); + + 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); + + bool changed; + + private: + void defaults(int n); + + //stored default parameters + unsigned char Dtype; + unsigned char Dfreq; + unsigned char Dq; +}; + +#endif + diff --git a/muse/synti/zynaddsubfx/Params/LFOParams.C b/muse/synti/zynaddsubfx/Params/LFOParams.C new file mode 100644 index 00000000..0f9c816d --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/LFOParams.C @@ -0,0 +1,91 @@ +/* + ZynAddSubFX - a software synthesizer + + LFOParams.C - Parameters for LFO + 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) 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 <math.h> +#include <stdio.h> +#include "../globals.h" +#include "LFOParams.h" + +int LFOParams::time; + +LFOParams::LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOtype_,char Prandomness_, char Pdelay_,char Pcontinous_,char fel_):Presets(){ + switch(fel_) { + case 0:setpresettype("Plfofrequency"); + break; + case 1:setpresettype("Plfoamplitude"); + break; + case 2:setpresettype("Plfofilter"); + break; + }; + 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; +}; + + +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); +}; + +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); +}; + diff --git a/muse/synti/zynaddsubfx/Params/LFOParams.h b/muse/synti/zynaddsubfx/Params/LFOParams.h new file mode 100644 index 00000000..48a0d5d2 --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/LFOParams.h @@ -0,0 +1,64 @@ +/* + ZynAddSubFX - a software synthesizer + + LFOParams.h - Parameters for LFO + 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) 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 LFO_PARAMS_H +#define LFO_PARAMS_H + +#include "../Misc/XMLwrapper.h" +#include "Presets.h" + +class LFOParams:public Presets{ + 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(); + void getfromXML(XMLwrapper *xml); + + /* Parametrii MIDI */ + REALTYPE Pfreq; // frequency + unsigned char Pintensity; // intensity + unsigned char Pstartphase;// start phase (0=random) + unsigned char PLFOtype; // LFO type (sin,triangle,square,ramp,...) + unsigned char Prandomness;// randomness (0=off) + unsigned char Pfreqrand; // frequency randomness (0=off) + unsigned char Pdelay; // delay (0=off) + unsigned char Pcontinous; // 1 if LFO is continous + unsigned char Pstretch; // how the LFO is "stretched" according the note frequency (64=no stretch) + + int fel;//what kind is the LFO (0 - frequency, 1 - amplitude, 2 - filter) + static int time;//is used by Pcontinous parameter + private: + /* Default parameters */ + unsigned char Dfreq; + unsigned char Dintensity; + unsigned char Dstartphase; + unsigned char DLFOtype; + unsigned char Drandomness; + unsigned char Ddelay; + unsigned char Dcontinous; + +}; + + +#endif diff --git a/muse/synti/zynaddsubfx/Params/PADnoteParameters.C b/muse/synti/zynaddsubfx/Params/PADnoteParameters.C new file mode 100644 index 00000000..05fbdf0f --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/PADnoteParameters.C @@ -0,0 +1,740 @@ +/* + ZynAddSubFX - a software synthesizer + + PADnoteParameters.C - Parameters for PADnote (PADsynth) + 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) 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 <math.h> +#include "PADnoteParameters.h" + +PADnoteParameters::PADnoteParameters(FFTwrapper *fft_,pthread_mutex_t *mutex_):Presets(){ + setpresettype("Ppadsyth"); + + fft=fft_; + mutex=mutex_; + + 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); + + 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); + + for (int i=0;i<PAD_MAX_SAMPLES;i++) sample[i].smp=NULL; + newsample.smp=NULL; + + defaults(); +}; + +PADnoteParameters::~PADnoteParameters(){ + deletesamples(); + delete(oscilgen); + delete(resonance); + + delete(FreqEnvelope); + delete(FreqLfo); + delete(AmpEnvelope); + delete(AmpLfo); + delete(GlobalFilter); + delete(FilterEnvelope); + delete(FilterLfo); + +}; + +void PADnoteParameters::defaults(){ + Pmode=0; + Php.base.type=0; + Php.base.par1=80; + Php.freqmult=0; + Php.modulator.par1=0; + Php.modulator.freq=30; + Php.width=127; + Php.amp.type=0; + Php.amp.mode=0; + Php.amp.par1=80; + Php.amp.par2=64; + Php.autoscale=true; + Php.onehalf=0; + + setPbandwidth(500); + Pbwscale=0; + + resonance->defaults(); + oscilgen->defaults(); + + Phrpos.type=0; + Phrpos.par1=64; + Phrpos.par2=64; + Phrpos.par3=0; + + Pquality.samplesize=3; + Pquality.basenote=4; + Pquality.oct=3; + Pquality.smpoct=2; + + PStereo=1;//stereo + /* Frequency Global Parameters */ + 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; + AmpEnvelope->defaults(); + AmpLfo->defaults(); + PPunchStrength=0; + PPunchTime=60; + PPunchStretch=64; + PPunchVelocitySensing=72; + + /* Filter Global Parameters*/ + 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; +}; + +void PADnoteParameters::deletesamples(){ + for (int i=0;i<PAD_MAX_SAMPLES;i++) deletesample(i); +}; + +/* + * Get the harmonic profile (i.e. the frequency distributio of a single harmonic) + */ +REALTYPE PADnoteParameters::getprofile(REALTYPE *smp,int size){ + for (int i=0;i<size;i++) smp[i]=0.0; + const int supersample=16; + REALTYPE basepar=pow(2.0,(1.0-Php.base.par1/127.0)*12.0); + REALTYPE freqmult=floor(pow(2.0,Php.freqmult/127.0*5.0)+0.000001); + + REALTYPE modfreq=floor(pow(2.0,Php.modulator.freq/127.0*5.0)+0.000001); + REALTYPE modpar1=pow(Php.modulator.par1/127.0,4.0)*5.0/sqrt(modfreq); + REALTYPE amppar1=pow(2.0,pow(Php.amp.par1/127.0,2.0)*10.0)-0.999; + REALTYPE amppar2=(1.0-Php.amp.par2/127.0)*0.998+0.001; + REALTYPE width=pow(150.0/(Php.width+22.0),2.0); + + for (int i=0;i<size*supersample;i++){ + bool makezero=false; + REALTYPE x=i*1.0/(size*(REALTYPE) supersample); + + REALTYPE origx=x; + + //do the sizing (width) + 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){ + case 1:x=x*0.5+0.5; + break; + case 2:x=x*0.5; + break; + }; + + REALTYPE x_before_freq_mult=x; + + //do the frequency multiplier + 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; + + + //this is the base function of the profile + REALTYPE f; + switch (Php.base.type){ + case 1: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)); + break; + default:f=exp(-(x*x)*basepar); + break; + }; + if (makezero) f=0.0; + + REALTYPE amp=1.0; + origx=origx*2.0-1.0; + + //compute the amplitude multiplier + switch(Php.amp.type){ + case 1: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))); + break; + case 3: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){ + case 0:finalsmp=amp*(1.0-amppar2)+finalsmp*amppar2; + break; + case 1:finalsmp*=amp*(1.0-amppar2)+amppar2; + break; + case 2: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); + break; + }; + }; + + 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;i<size;i++) { + if (smp[i]<0.0) smp[i]=0.0; + if (smp[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); + + //compute the estimated perceived bandwidth + 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); +}; + +/* + * Compute the real bandwidth in cents and returns it + * Also, sets the bandwidth parameter + */ +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); +}; + +/* + * 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 n0=n-1.0; + REALTYPE tmp=0.0; + int thresh=0; + switch(Phrpos.type){ + case 1: + thresh=(int)(par2*par2*100.0)+1; + if (n<thresh) result=n; + else result=1.0+n0+(n0-thresh+1.0)*par1*8.0; + break; + case 2: + thresh=(int)(par2*par2*100.0)+1; + if (n<thresh) result=n; + else result=1.0+n0-(n0-thresh+1.0)*par1*0.90; + break; + case 3: + tmp=par1*100.0+1.0; + result=pow(n0/tmp,1.0-par2*0.8)*tmp+1.0; + break; + case 4: + result=n0*(1.0-par1)+pow(n0*0.1,par2*3.0+1.0)*par1*10.0+1.0; + break; + case 5: + result=n0+sin(n0*par2*par2*PI*0.999)*sqrt(par1)*2.0+1.0; + break; + case 6: + tmp=pow(par2*2.0,2.0)+0.1; + result=n0*pow(1.0+par1*pow(n0*0.8,tmp),tmp)+1.0; + break; + default: + result=n; + break; + }; + + REALTYPE par3=Phrpos.par3/255.0; + + REALTYPE iresult=floor(result+0.5); + REALTYPE dresult=result-iresult; + + result=iresult+(1.0-par3)*dresult; + + return(result); +}; + +/* + * Generates the long spectrum for Bandwidth mode (only amplitudes are generated; phases will be random) + */ +void PADnoteParameters::generatespectrum_bandwidthMode(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust){ + for (int i=0;i<size;i++) spectrum[i]=0.0; + + REALTYPE harmonics[OSCIL_SIZE/2]; + for (int i=0;i<OSCIL_SIZE/2;i++) harmonics[i]=0.0; + //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only) + oscilgen->get(harmonics,basefreq,false); + + //normalize + REALTYPE max=0.0; + for (int i=0;i<OSCIL_SIZE/2;i++) if (harmonics[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;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){ + case 0: power=1.0;break; + case 1: power=0.0;break; + case 2: power=0.25;break; + case 3: power=0.5;break; + case 4: power=0.75;break; + case 5: power=1.5;break; + case 6: power=2.0;break; + case 7: power=-0.5;break; + }; + 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); + + 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){ + for (int i=0;i<size;i++) spectrum[i]=0.0; + + REALTYPE harmonics[OSCIL_SIZE/2]; + for (int i=0;i<OSCIL_SIZE/2;i++) harmonics[i]=0.0; + //get the harmonic structure from the oscillator (I am using the frequency amplitudes, only) + oscilgen->get(harmonics,basefreq,false); + + //normalize + REALTYPE max=0.0; + for (int i=0;i<OSCIL_SIZE/2;i++) if (harmonics[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;nh<OSCIL_SIZE/2;nh++){//for each harmonic + REALTYPE realfreq=getNhr(nh)*basefreq; + + ///sa fac aici interpolarea si sa am grija daca frecv descresc + + 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); + + spectrum[cfreq]=amp+1e-9; + }; + + if (Pmode!=1){ + int old=0; + for (int k=1;k<size;k++){ + if ( (spectrum[k]>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; + REALTYPE spectrum[spectrumsize]; + int profilesize=512; + REALTYPE profile[profilesize]; + + + REALTYPE bwadjust=getprofile(profile,profilesize); +// for (int i=0;i<profilesize;i++) profile[i]*=profile[i]; + REALTYPE basefreq=65.406*pow(2.0,Pquality.basenote/2); + if (Pquality.basenote%2==1) basefreq*=1.5; + + int samplemax=Pquality.oct+1; + int smpoct=Pquality.smpoct; + if (Pquality.smpoct==5) smpoct=6; + if (Pquality.smpoct==6) smpoct=12; + if (smpoct!=0) samplemax*=smpoct; + else samplemax=samplemax/2+1; + if (samplemax==0) samplemax=1; + + //prepare a BIG FFT stuff + FFTwrapper *fft=new FFTwrapper(samplesize); + FFTFREQS fftfreqs; + newFFTFREQS(&fftfreqs,samplesize/2); + + REALTYPE adj[samplemax];//this is used to compute frequency relation to the base frequency + for (int nsample=0;nsample<samplemax;nsample++) adj[nsample]=(Pquality.oct+1.0)*(REALTYPE)nsample/samplemax; + for (int nsample=0;nsample<samplemax;nsample++){ + REALTYPE tmp=adj[nsample]-adj[samplemax-1]*0.5; + REALTYPE basefreqadjust=pow(2.0,tmp); + + if (Pmode==0) generatespectrum_bandwidthMode(spectrum,spectrumsize,basefreq*basefreqadjust,profile,profilesize,bwadjust); + else generatespectrum_otherModes(spectrum,spectrumsize,basefreq*basefreqadjust,profile,profilesize,bwadjust); + + const int extra_samples=5;//the last samples contains the first samples (used for linear/cubic interpolation) + newsample.smp=new REALTYPE[samplesize+extra_samples]; + + 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;i<samplesize;i++) rms+=newsample.smp[i]*newsample.smp[i]; + rms=sqrt(rms); + if (rms<0.000001) rms=1.0; + rms*=sqrt(262144.0/samplesize); + for (int i=0;i<samplesize;i++) newsample.smp[i]*=1.0/rms*50.0; + + //prepare extra samples used by the linear or cubic interpolation + for (int i=0;i<extra_samples;i++) newsample.smp[i+samplesize]=newsample.smp[i]; + + //replace the current sample with the new computed sample + if (lockmutex){ + pthread_mutex_lock(mutex); + deletesample(nsample); + sample[nsample].smp=newsample.smp; + sample[nsample].size=samplesize; + sample[nsample].basefreq=basefreq*basefreqadjust; + pthread_mutex_unlock(mutex); + } else { + deletesample(nsample); + sample[nsample].smp=newsample.smp; + sample[nsample].size=samplesize; + sample[nsample].basefreq=basefreq*basefreqadjust; + }; + newsample.smp=NULL; + }; + delete(fft); + deleteFFTFREQS(&fftfreqs); + + //delete the additional samples that might exists and are not useful + if (lockmutex){ + pthread_mutex_lock(mutex); + for (int i=samplemax;i<PAD_MAX_SAMPLES;i++) deletesample(i); + pthread_mutex_unlock(mutex); + } else { + for (int i=samplemax;i<PAD_MAX_SAMPLES;i++) deletesample(i); + }; +}; + + +void PADnoteParameters::add2XML(XMLwrapper *xml){ + xml->information.PADsynth_used=true; + + 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->endbranch(); + + xml->beginbranch("OSCIL"); + oscilgen->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("RESONANCE"); + resonance->add2XML(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->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->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->beginbranch("AMPLITUDE_ENVELOPE"); + AmpEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("AMPLITUDE_LFO"); + AmpLfo->add2XML(xml); + xml->endbranch(); + + 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->beginbranch("FREQUENCY_ENVELOPE"); + FreqEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FREQUENCY_LFO"); + FreqLfo->add2XML(xml); + xml->endbranch(); + xml->endbranch(); + + xml->beginbranch("FILTER_PARAMETERS"); + xml->addpar("velocity_sensing_amplitude",PFilterVelocityScale); + xml->addpar("velocity_sensing",PFilterVelocityScaleFunction); + + xml->beginbranch("FILTER"); + GlobalFilter->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FILTER_ENVELOPE"); + FilterEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FILTER_LFO"); + 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); + + 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")){ + oscilgen->getfromXML(xml); + xml->exitbranch(); + }; + + 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); + 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); + 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); + + xml->enterbranch("AMPLITUDE_ENVELOPE"); + AmpEnvelope->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("AMPLITUDE_LFO"); + AmpLfo->getfromXML(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); + + xml->enterbranch("FREQUENCY_ENVELOPE"); + FreqEnvelope->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FREQUENCY_LFO"); + 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); + + xml->enterbranch("FILTER"); + GlobalFilter->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FILTER_ENVELOPE"); + FilterEnvelope->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FILTER_LFO"); + FilterLfo->getfromXML(xml); + xml->exitbranch(); + xml->exitbranch(); + }; +}; + + diff --git a/muse/synti/zynaddsubfx/Params/PADnoteParameters.h b/muse/synti/zynaddsubfx/Params/PADnoteParameters.h new file mode 100644 index 00000000..dcb883e4 --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/PADnoteParameters.h @@ -0,0 +1,168 @@ +/* + ZynAddSubFX - a software synthesizer + + PADnoteParameters.h - Parameters for PADnote (PADsynth) + 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) 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 PAD_NOTE_PARAMETERS_H +#define PAD_NOTE_PARAMETERS_H + +#include "../Misc/XMLwrapper.h" +#include "../DSP/FFTwrapper.h" +#include "../globals.h" +#include "../Synth/OscilGen.h" +#include "../Synth/Resonance.h" +#include "../Misc/Util.h" + +#include "EnvelopeParams.h" +#include "LFOParams.h" +#include "FilterParams.h" +#include "Presets.h" + + +class PADnoteParameters:public Presets{ + public: + PADnoteParameters(FFTwrapper *fft_,pthread_mutex_t *mutex_); + ~PADnoteParameters(); + + 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); + + //parameters + + //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 + 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,par2,par3;//0..255 + }Phrpos; + + 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; + + /* 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 + + EnvelopeParams *FreqEnvelope; //Frequency Envelope + LFOParams *FreqLfo;//Frequency LFO + + //Amplitude parameters + unsigned char PStereo; + /* Panning - 0 - random + 1 - left + 64 - center + 127 - right */ + unsigned char PPanning; + + unsigned char PVolume; + + unsigned char PAmpVelocityScaleFunction; + + EnvelopeParams *AmpEnvelope; + + LFOParams *AmpLfo; + + 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; + + + + + 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); + + OscilGen *oscilgen; + Resonance *resonance; + + 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); + + FFTwrapper *fft; + pthread_mutex_t *mutex; +}; + + + +#endif diff --git a/muse/synti/zynaddsubfx/Params/Presets.C b/muse/synti/zynaddsubfx/Params/Presets.C new file mode 100644 index 00000000..e5f6e10c --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/Presets.C @@ -0,0 +1,129 @@ +/* + ZynAddSubFX - a software synthesizer + + Presets.C - Presets and Clipboard management + 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) 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 "Presets.h" +#include <string.h> + + +Presets::Presets(){ + type[0]=0; + nelement=-1; +}; + +Presets::~Presets(){ +}; + +void Presets::setpresettype(char *type){ + strcpy(this->type,type); +}; + +void Presets::copy(const char *name){ + XMLwrapper *xml=new XMLwrapper(); + + //used only for the clipboard + 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"); + }; + + xml->beginbranch(type); + if (nelement==-1) add2XML(xml); + else add2XMLsection(xml,nelement); + xml->endbranch(); + + if (name==NULL) presetsstore.copyclipboard(xml,type); + else presetsstore.copypreset(xml,type,name); + + 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"); + }; + + XMLwrapper *xml=new XMLwrapper(); + if (npreset==0){ + if (!checkclipboardtype()) { + nelement=-1; + delete(xml); + return; + }; + if (!presetsstore.pasteclipboard(xml)) { + delete(xml); + nelement=-1; + return; + }; + } else { + if (!presetsstore.pastepreset(xml,npreset)) { + delete(xml); + nelement=-1; + return; + }; + }; + + if (xml->enterbranch(type)==0) { + nelement=-1; + return; + }; + if (nelement==-1) { + defaults(); + getfromXML(xml); + } else { + defaults(nelement); + getfromXMLsection(xml,nelement); + }; + xml->exitbranch(); + + delete(xml); + nelement=-1; +}; + +bool Presets::checkclipboardtype(){ + char type[MAX_PRESETTYPE_SIZE]; + strcpy(type,this->type); + if (nelement!=-1) strcat(type,"n"); + + return(presetsstore.checkclipboardtype(type)); +}; + +void Presets::setelement(int n){ + nelement=n; +}; + +void Presets::rescanforpresets(){ + presetsstore.rescanforpresets(type); +}; + + +void Presets::deletepreset(int npreset){ + presetsstore.deletepreset(npreset); +}; + diff --git a/muse/synti/zynaddsubfx/Params/Presets.h b/muse/synti/zynaddsubfx/Params/Presets.h new file mode 100644 index 00000000..d7d938d1 --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/Presets.h @@ -0,0 +1,58 @@ +/* + ZynAddSubFX - a software synthesizer + + Presets.h - Presets and Clipboard management + 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) 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 PRESETS_H +#define PRESETS_H + +#include "../Misc/XMLwrapper.h" + +#include "PresetsStore.h" + +class Presets{ + public: + Presets(); + virtual ~Presets(); + + void copy(const char *name);//if name==NULL, the clipboard is used + void paste(int npreset);//npreset==0 for clipboard + bool checkclipboardtype(); + void deletepreset(int npreset); + + char type[MAX_PRESETTYPE_SIZE]; + void setelement(int n); + + void rescanforpresets(); + + protected: + void setpresettype(char *type); + private: + virtual void add2XML(XMLwrapper *xml)=0; + virtual void getfromXML(XMLwrapper *xml)=0; + virtual void defaults()=0; + virtual void add2XMLsection(XMLwrapper */*xml*/,int /*n*/){}; + virtual void getfromXMLsection(XMLwrapper */*xml*/,int /*n*/){}; + virtual void defaults(int /*n*/){}; + int nelement; +}; + +#endif + diff --git a/muse/synti/zynaddsubfx/Params/PresetsStore.C b/muse/synti/zynaddsubfx/Params/PresetsStore.C new file mode 100644 index 00000000..8bbb2bec --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/PresetsStore.C @@ -0,0 +1,181 @@ +/* + ZynAddSubFX - a software synthesizer + + PresetsStore.C - Presets and Clipboard store + 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) 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 <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <sys/stat.h> + +#include "PresetsStore.h" +#include "../Misc/Util.h" + +PresetsStore presetsstore; + +PresetsStore::PresetsStore(){ + clipboard.data=NULL; + clipboard.type[0]=0; + + for (int i=0;i<MAX_PRESETS;i++){ + presets[i].file=NULL; + presets[i].name=NULL; + }; + +}; + +PresetsStore::~PresetsStore(){ + if (clipboard.data!=NULL) delete (clipboard.data); + clearpresets(); +}; + +//Clipboard management + +void PresetsStore::copyclipboard(XMLwrapper *xml,char *type){ + strcpy(clipboard.type,type); + if (clipboard.data!=NULL) delete (clipboard.data); + clipboard.data=xml->getXMLdata(); +}; + +bool PresetsStore::pasteclipboard(XMLwrapper *xml){ + 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); +}; + +//Presets management +void PresetsStore::clearpresets(){ + for (int i=0;i<MAX_PRESETS;i++){ + if (presets[i].file!=NULL) { + delete(presets[i].file); + presets[i].file=NULL; + }; + if (presets[i].name!=NULL) { + delete(presets[i].name); + presets[i].name=NULL; + }; + }; + +}; + +//a helper function that compares 2 presets[] +int Presets_compar(const void *a,const void *b){ + 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); +}; + + +void PresetsStore::rescanforpresets(char *type){ + clearpresets(); + int presetk=0; + char ftype[MAX_STRING_SIZE]; + snprintf(ftype,MAX_STRING_SIZE,".%s.xpz",type); + + for (int i=0;i<MAX_BANK_ROOT_DIRS;i++){ + if (config.cfg.presetsDirList[i]==NULL) continue; + char *dirname=config.cfg.presetsDirList[i]; + DIR *dir=opendir(dirname); + if (dir==NULL) continue; + struct dirent *fn; + 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]; + char *tmps="/"; + if ((tmpc=='/')||(tmpc=='\\')) 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'; + presetk++; if (presetk>=MAX_PRESETS) return; + }; + + closedir(dir); + }; + + //sort the presets + for (int j=0;j<MAX_PRESETS-1;j++){ + for (int i=j+1;i<MAX_PRESETS;i++){ + if (Presets_compar(&presets[i],&presets[j])) { + presetstruct tmp=presets[i]; + presets[i]=presets[j]; + presets[j]=tmp; + }; + }; + }; +}; + +void PresetsStore::copypreset(XMLwrapper *xml,char *type, const char *name){ + char filename[MAX_STRING_SIZE],tmpfilename[MAX_STRING_SIZE]; + + if (config.cfg.presetsDirList[0]==NULL) return; + + snprintf(tmpfilename,MAX_STRING_SIZE,"%s",name); + + //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; + tmpfilename[i]='_'; + }; + + char *dirname=config.cfg.presetsDirList[0]; + char tmpc=dirname[strlen(dirname)-1]; + char *tmps="/"; + if ((tmpc=='/')||(tmpc=='\\')) tmps=""; + + 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); +}; + +void PresetsStore::deletepreset(int npreset){ + npreset--; + if (npreset>=MAX_PRESETS) return; + char *filename=presets[npreset].file; + if (filename==NULL) return; + remove(filename); +}; + diff --git a/muse/synti/zynaddsubfx/Params/PresetsStore.h b/muse/synti/zynaddsubfx/Params/PresetsStore.h new file mode 100644 index 00000000..555e20cb --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/PresetsStore.h @@ -0,0 +1,63 @@ +/* + ZynAddSubFX - a software synthesizer + + PresetsStore.C - Presets and Clipboard store + 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) 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 "../Misc/XMLwrapper.h" +#include "../Misc/Config.h" + +#define MAX_PRESETTYPE_SIZE 30 +#define MAX_PRESETS 1000 + +class PresetsStore{ + public: + PresetsStore(); + ~PresetsStore(); + + //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); + + struct presetstruct{ + char *file; + char *name; + }; + presetstruct presets[MAX_PRESETS]; + + void rescanforpresets(char *type); + + private: + struct { + char *data; + char type[MAX_PRESETTYPE_SIZE]; + } clipboard; + + void clearpresets(); + +}; + +extern PresetsStore presetsstore; + diff --git a/muse/synti/zynaddsubfx/Params/SUBnoteParameters.C b/muse/synti/zynaddsubfx/Params/SUBnoteParameters.C new file mode 100644 index 00000000..b04b2a9f --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/SUBnoteParameters.C @@ -0,0 +1,238 @@ +/* + ZynAddSubFX - a software synthesizer + + SUBnoteParameters.C - Parameters for SUBnote (SUBsynth) + 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) 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 "../globals.h" +#include "SUBnoteParameters.h" +#include <stdio.h> + +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); + + 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; + + 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; + + for (int n=0;n<MAX_SUB_HARMONICS;n++){ + Phmag[n]=0; + Phrelbw[n]=64; + }; + Phmag[0]=127; + + PGlobalFilterEnabled=0; + PGlobalFilterVelocityScale=64; + PGlobalFilterVelocityScaleFunction=64; + + AmpEnvelope->defaults(); + FreqEnvelope->defaults(); + BandWidthEnvelope->defaults(); + GlobalFilter->defaults(); + GlobalFilterEnvelope->defaults(); + +}; + + + +SUBnoteParameters::~SUBnoteParameters(){ + delete (AmpEnvelope); + delete (FreqEnvelope); + 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->beginbranch("HARMONICS"); + 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->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->addpar("detune",PDetune); + xml->addpar("coarse_detune",PCoarseDetune); + xml->addpar("detune_type",PDetuneType); + + xml->addpar("bandwidth",Pbandwidth); + xml->addpar("bandwidth_scale",Pbwscale); + + 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->beginbranch("BANDWIDTH_ENVELOPE"); + BandWidthEnvelope->add2XML(xml); + xml->endbranch(); + }; + xml->endbranch(); + + xml->beginbranch("FILTER_PARAMETERS"); + 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->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); + + 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")){ + 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); + + 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); + + 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")){ + BandWidthEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + xml->exitbranch(); + }; + + 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); + + if (xml->enterbranch("FILTER_ENVELOPE")){ + GlobalFilterEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + xml->exitbranch(); + }; +}; + + + + diff --git a/muse/synti/zynaddsubfx/Params/SUBnoteParameters.h b/muse/synti/zynaddsubfx/Params/SUBnoteParameters.h new file mode 100644 index 00000000..a506a260 --- /dev/null +++ b/muse/synti/zynaddsubfx/Params/SUBnoteParameters.h @@ -0,0 +1,105 @@ +/* + ZynAddSubFX - a software synthesizer + + SUBnoteParameters.h - Parameters for SUBnote (SUBsynth) + 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) 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 SUB_NOTE_PARAMETERS_H +#define SUB_NOTE_PARAMETERS_H + +#include "../globals.h" +#include "../Misc/XMLwrapper.h" +#include "EnvelopeParams.h" +#include "FilterParams.h" +#include "Presets.h" + +class SUBnoteParameters:public Presets{ + public: + SUBnoteParameters(); + ~SUBnoteParameters(); + + 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; + + //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; + + + //Other Parameters + + //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; + + + //how many times the filters are applied + unsigned char Pnumstages; + + //bandwidth + unsigned char Pbandwidth; + + //How the magnitudes are computed (0=linear,1=-60dB,2=-60dB) + unsigned char Phmagtype; + + //Magnitudes + unsigned char Phmag[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 the harmonics start("0"=0,"1"=random,"2"=1) + unsigned char Pstart; + + + private: +}; + +#endif + + + diff --git a/muse/synti/zynaddsubfx/Seq/MIDIEvents.C b/muse/synti/zynaddsubfx/Seq/MIDIEvents.C new file mode 100644 index 00000000..729089c6 --- /dev/null +++ b/muse/synti/zynaddsubfx/Seq/MIDIEvents.C @@ -0,0 +1,85 @@ +/* + ZynAddSubFX - a software synthesizer + + MIDIEvents.C - It stores the midi events from midi file or sequencer + Copyright (C) 2003-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) 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 "MIDIEvents.h" +#include <stdlib.h> +#include <stdio.h> + +MIDIEvents::MIDIEvents(){ +}; + +MIDIEvents::~MIDIEvents(){ +}; + + +/************** Track stuff ***************/ +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; +// printf("Wx%x ",(int) l->current); +// printf("-> %d \n",l->current->ev.deltatime); + l->size++; +}; + +void MIDIEvents::readevent(list *l,event *ev){ + if (l->current==NULL) { + ev->type=-1; + return; + }; + *ev=l->current->ev; + l->current=l->current->next; + + //test + 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; +}; + +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); + }; + deletelistreference(l); +}; + +void MIDIEvents::deletelistreference(list *l){ + l->current=l->first=NULL; + l->size=0; + l->length=0.0; +}; diff --git a/muse/synti/zynaddsubfx/Seq/MIDIEvents.h b/muse/synti/zynaddsubfx/Seq/MIDIEvents.h new file mode 100644 index 00000000..1bf9befc --- /dev/null +++ b/muse/synti/zynaddsubfx/Seq/MIDIEvents.h @@ -0,0 +1,66 @@ +/* + ZynAddSubFX - a software synthesizer + + MIDIEvents.h - It stores the midi events from midi file or sequencer + Copyright (C) 2003-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) 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 MIDI_EVENTS_H +#define MIDI_EVENTS_H + +#include "../globals.h" +#define NUM_MIDI_TRACKS NUM_MIDI_CHANNELS + +class MIDIEvents{ + friend class MIDIFile; + public: + MIDIEvents(); + ~MIDIEvents(); + + 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]; + + 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/muse/synti/zynaddsubfx/Seq/MIDIFile.C b/muse/synti/zynaddsubfx/Seq/MIDIFile.C new file mode 100644 index 00000000..a5fdaa1c --- /dev/null +++ b/muse/synti/zynaddsubfx/Seq/MIDIFile.C @@ -0,0 +1,389 @@ +/* + ZynAddSubFX - a software synthesizer + + MIDIFile.C - MIDI file loader + Copyright (C) 2003-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) 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 <stdio.h> +#include <string.h> +#include "MIDIFile.h" + + +MIDIFile::MIDIFile(){ + midifile=NULL; + midifilesize=0; + midifilek=0; + midieof=false; + me=NULL; +}; + +MIDIFile::~MIDIFile(){ + clearmidifile(); +}; + +int MIDIFile::loadfile(char *filename){ + clearmidifile(); + + FILE *file=fopen(filename,"r"); + if (file==NULL) return(-1); + + char header[4]; + 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')){ + fclose(file); + return(-1); + }; + + //get the filesize + fseek(file,0,SEEK_END); + midifilesize=ftell(file); + rewind(file); + + midifile=new unsigned char[midifilesize]; + ZERO(midifile,midifilesize); + fread(midifile,midifilesize,1,file); + fclose(file); + +// for (int i=0;i<midifilesize;i++) printf("%2x ",midifile[i]); +// printf("\n"); + + + return(0); +}; + +int MIDIFile::parsemidifile(MIDIEvents *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 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 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."); + }; + + if (ntracks>=NUM_MIDI_TRACKS) ntracks=NUM_MIDI_TRACKS-1; + + for (int n=0;n<ntracks;n++){ + if (parsetrack(n)<0) { + clearmidifile(); + return(-1); + }; + }; + + printf("\n\nCURRENT File position is = 0x%x\n",midifilek); + printf("\nMIDI file succesfully parsed.\n"); +// printf("\n0x%x\n",getbyte()); + + this->me=NULL; + return(0); +}; + +//private members + + +int MIDIFile::parsetrack(int ntrack){ + printf("\n--==*Reading track %d **==--\n",ntrack); + + int chunk=getint32();//MTrk + if (chunk!=0x4d54726b) return(-1); + + int size=getint32(); + printf("size = %d\n",size); + + int oldmidifilek=midifilek; + + unsigned char lastmsg=0; + unsigned int dt=0; + + while(!midieof){ + unsigned int msgdeltatime=getvarint32(); + +/// printf("MSGDELTATIME = %d\n",msgdeltatime); + +// dt+=msgdeltatime; + + int msg=peekbyte(); +/// printf("raw msg=0x%x ",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; + + 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; + break; + case 0xa0 ... 0xaf://aftertouch - ignored + skipnbytes(2); + break; + case 0xb0 ... 0xbf://control change + parsecontrolchange(ntrack,msg & 0x0f,dt); + dt=0; + break; + case 0xc0 ... 0xcf://program change - ignored + skipnbytes(1); + break; + case 0xd0 ... 0xdf://channel pressure - ignored + skipnbytes(1); + break; + case 0xe0 ... 0xef://channel mode messages + skipnbytes(2); + break; + case 0xf0://sysex - ignored + while (getbyte()!=0xf7){ + if (midieof) break; + }; + break; + case 0xf7://sysex (another type) - ignored + skipnbytes(getvarint32()); + break; + + case 0xff://meta-event + mtype=getbyte(); + mlength=getbyte(); + parsemetaevent(mtype,mlength); + break; + + default: + getbyte(); + printf("UNKNOWN message! 0x%x\n",msg); + return(-1); + break; + }; + + + + if (midieof) 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); +}; + + +void MIDIFile::parsenoteoff(char ntrack,char chan,unsigned int dt){ + unsigned char note; + note=getbyte(); + + 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; + + printf("Note off:%d \n",note); + + ///test +// ntrack=0; + + me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); + +}; + + +void MIDIFile::parsenoteon(char ntrack,char chan,unsigned int dt){ + unsigned char note,vel; + note=getbyte(); + vel=getbyte(); + +// printf("ntrack=%d\n",ntrack); + printf("[dt %d ] Note on:%d %d\n",dt,note,vel); + + 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); + + + +}; + +void MIDIFile::parsecontrolchange(char ntrack,char chan,unsigned int dt){ + unsigned char control,value; + control=getbyte(); + value=getbyte(); + + if (chan>=NUM_MIDI_CHANNELS) return; + + 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); + +}; + +void MIDIFile::parsepitchwheel(char ntrack,char chan, unsigned int dt){ + unsigned char valhi,vallo; + vallo=getbyte(); + valhi=getbyte(); + + if (chan>=NUM_MIDI_CHANNELS) return; + + int value=(int)valhi*128+vallo; + + printf("[dt %d] Pitch wheel:%d\n",dt,value); + +}; + +void MIDIFile::parsemetaevent(unsigned char mtype,unsigned char mlength){ + int oldmidifilek=midifilek; + printf("meta-event type=0x%x length=%d\n",mtype,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); +}; + + +unsigned int MIDIFile::convertdt(unsigned int dt){ + double result=dt; + printf("DT=%d\n",dt); + + 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; +}; + +unsigned char MIDIFile::getbyte(){ + if (midifilek>=midifilesize) { + midieof=true; + return(0); + }; + +/// printf("(%d) ",midifile[midifilek]); + return(midifile[midifilek++]); +}; + +unsigned char MIDIFile::peekbyte(){ + 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 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 int MIDIFile::getvarint32(){ + unsigned long result=0; + unsigned char b; + +/// printf("\n[start]"); + + if ((result = getbyte()) & 0x80) { + result &= 0x7f; + do { + b=getbyte(); + result = (result << 7) + (b & 0x7f); + }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; + }; +}; + diff --git a/muse/synti/zynaddsubfx/Seq/MIDIFile.h b/muse/synti/zynaddsubfx/Seq/MIDIFile.h new file mode 100644 index 00000000..c88f679c --- /dev/null +++ b/muse/synti/zynaddsubfx/Seq/MIDIFile.h @@ -0,0 +1,90 @@ +/* + ZynAddSubFX - a software synthesizer + + MIDIFile.h - MIDI file loader + Copyright (C) 2003-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) 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 MIDIFILE_H +#define MIDIFILE_H + +#include "../globals.h" +#include "MIDIEvents.h" + +class MIDIFile{ + public: + MIDIFile(); + ~MIDIFile(); + + //returns -1 if there is an error, otherwise 0 + int loadfile(char *filename); + + //returns -1 if there is an error, otherwise 0 + int parsemidifile(MIDIEvents *me_); + + private: + MIDIEvents *me; + + unsigned char *midifile; + int midifilesize,midifilek; + bool midieof; + + //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 add_dt(char ntrack, unsigned int dt); + + void clearmidifile(); + + //convert the delta-time to internal format + unsigned int convertdt(unsigned int dt); + + /* Low Level MIDIfile functions */ + + //get a byte from the midifile + unsigned char getbyte(); + + //peek the current byte from the midifile + unsigned char peekbyte(); + + //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(); + + //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; + +}; + +#endif diff --git a/muse/synti/zynaddsubfx/Seq/Sequencer.C b/muse/synti/zynaddsubfx/Seq/Sequencer.C new file mode 100644 index 00000000..d81ee611 --- /dev/null +++ b/muse/synti/zynaddsubfx/Seq/Sequencer.C @@ -0,0 +1,165 @@ +/* + ZynAddSubFX - a software synthesizer + + Sequencer.C - The Sequencer + Copyright (C) 2003-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) 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 <math.h> +#include <stdlib.h> +#include <stdio.h> + +#include <sys/time.h> +#include <time.h> + +#include "Sequencer.h" + + + +Sequencer::Sequencer(){ + play=0; + for (int i=0;i<NUM_MIDI_TRACKS;i++){ + miditrack[i].track.first=NULL; + miditrack[i].track.current=NULL; + miditrack[i].track.size=0; + miditrack[i].track.length=0.0; + miditrack[i].record.first=NULL; + miditrack[i].record.current=NULL; + miditrack[i].record.size=0; + miditrack[i].record.length=0.0; + + nextevent[i].time=0.0; + resettime(&playtime[i]); + }; + + setplayspeed(0); +}; + +Sequencer::~Sequencer(){ + for (int i=0;i<NUM_MIDI_TRACKS;i++){ + deletelist(&miditrack[i].track); + deletelist(&miditrack[i].record); + }; +}; + + +int Sequencer::importmidifile(char *filename){ + if (midifile.loadfile(filename)<0) return(-1); + + for (int i=0;i<NUM_MIDI_TRACKS;i++){ + deletelist(&miditrack[i].record); + }; + if (midifile.parsemidifile(this)<0) return(-1); + + //copy the "record" track to the main track + for (int i=0;i<NUM_MIDI_TRACKS;i++){ + deletelist(&miditrack[i].track); + miditrack[i].track=miditrack[i].record; + deletelistreference(&miditrack[i].record); + }; + return(0); +}; + + + +void Sequencer::startplay(){ + if (play!=0) return; + for (int i=0;i<NUM_MIDI_TRACKS;i++) resettime(&playtime[i]); + + for (int i=0;i<NUM_MIDI_TRACKS;i++){ + rewindlist(&miditrack[i].track); + }; + play=1; + +}; +void Sequencer::stopplay(){ + if (play==0) return; + play=0; +}; + +// ************ Player stuff *************** + +int Sequencer::getevent(char ntrack,int *midich, int *type,int *par1, int *par2){ + *type=0; + if (play==0) return(-1); + + //test +// if (ntrack!=0) return(-1); + + updatecounter(&playtime[(int)ntrack]); + +// printf("%g %g\n",nextevent[ntrack].time,playtime[ntrack].abs); + + if (nextevent[(int)ntrack].time<playtime[(int)ntrack].abs) readevent(&miditrack[(int)ntrack].track,&nextevent[(int)ntrack].ev); + else return(-1); + if (nextevent[(int)ntrack].ev.type==-1) return(-1); +// printf("********************************\n"); + + //sa pun aici o protectie. a.i. daca distanta dintre timpul curent si eveliment e prea mare (>1sec) sa elimin nota + + 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; + + + 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 +}; + +/************** Timer stuff ***************/ + +void Sequencer::resettime(timestruct *t){ + t->abs=0.0; + t->rel=0.0; + + timeval tval; + + t->last=0.0; + #ifndef OS_WINDOWS + 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; + #ifndef OS_WINDOWS + 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; + +// 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); +}; diff --git a/muse/synti/zynaddsubfx/Seq/Sequencer.h b/muse/synti/zynaddsubfx/Seq/Sequencer.h new file mode 100644 index 00000000..82ebe495 --- /dev/null +++ b/muse/synti/zynaddsubfx/Seq/Sequencer.h @@ -0,0 +1,84 @@ +/* + ZynAddSubFX - a software synthesizer + + Sequencer.h - The Sequencer + Copyright (C) 2003-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) 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 SEQUENCER_H +#define SEQUENCER_H + +#include "../globals.h" +#include "MIDIEvents.h" +#include "MIDIFile.h" + +class Sequencer:public MIDIEvents{ + public: + Sequencer(); + ~Sequencer(); + + //theese 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); + + //this is only for player + //it returns 1 if this must be called at least once more + //it returns 0 if there are no more notes for the current time + //or -1 if there is no note + int getevent(char ntrack, int *midich,int *type,int *par1, int *par2); + + //returns 0 if ok or -1 if there is a error loading file + int importmidifile(char *filename); + + void startplay(); + void stopplay(); + + + int play; + int playspeed;//viteza de rulare (0.1x-10x), 0=1.0x, 128=10x + void setplayspeed(int speed); + + private: + + 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) + //theese must be double, because the float's precision is too low + //and all theese represents the time in seconds + } playtime[NUM_MIDI_TRACKS]; + + void resettime(timestruct *t); + void updatecounter(timestruct *t);//this updates the timer values + + /* Player only*/ + + struct { + event ev; + double time; + } nextevent[NUM_MIDI_TRACKS]; + + double realplayspeed; + +}; + + +#endif + diff --git a/muse/synti/zynaddsubfx/Synth/ADnote.C b/muse/synti/zynaddsubfx/Synth/ADnote.C new file mode 100644 index 00000000..574e2bea --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/ADnote.C @@ -0,0 +1,984 @@ +/* + ZynAddSubFX - a software synthesizer + + ADnote.C - The "additive" synthesizer + 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) 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 <math.h> +#include <stdlib.h> +#include <stdio.h> + + +#include "../globals.h" +#include "../Misc/Util.h" +#include "ADnote.h" + + +ADnote::ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_){ + ready=0; + + tmpwave=new REALTYPE [SOUND_BUFFER_SIZE]; + bypassl=new REALTYPE [SOUND_BUFFER_SIZE]; + bypassr=new REALTYPE [SOUND_BUFFER_SIZE]; + + 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(); + + 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); + + 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;nvoice<NUM_VOICES;nvoice++){ + pars->VoicePar[nvoice].OscilSmp->newrandseed(rand()); + NoteVoicePar[nvoice].OscilSmp=NULL; + NoteVoicePar[nvoice].FMSmp=NULL; + NoteVoicePar[nvoice].VoiceOut=NULL; + + NoteVoicePar[nvoice].FMVoice=-1; + + 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; + + //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); + }; + + 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 + + //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); + + //I store the first elments to the last position for speedups + for (int i=0;i<OSCIL_SMP_EXTRA_SAMPLES;i++) NoteVoicePar[nvoice].OscilSmp[OSCIL_SIZE+i]=NoteVoicePar[nvoice].OscilSmp[i]; + + oscposhi[nvoice]+=(int)((pars->VoicePar[nvoice].Poscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); + oscposhi[nvoice]%=OSCIL_SIZE; + + + NoteVoicePar[nvoice].FreqLfo=NULL; + NoteVoicePar[nvoice].FreqEnvelope=NULL; + + NoteVoicePar[nvoice].AmpLfo=NULL; + NoteVoicePar[nvoice].AmpEnvelope=NULL; + + NoteVoicePar[nvoice].VoiceFilter=NULL; + NoteVoicePar[nvoice].FilterEnvelope=NULL; + NoteVoicePar[nvoice].FilterLfo=NULL; + + NoteVoicePar[nvoice].FilterCenterPitch=pars->VoicePar[nvoice].VoiceFilter->getfreq(); + NoteVoicePar[nvoice].filterbypass=pars->VoicePar[nvoice].Pfilterbypass; + + switch(pars->VoicePar[nvoice].PFMEnabled){ + case 1:NoteVoicePar[nvoice].FMEnabled=MORPH;break; + case 2:NoteVoicePar[nvoice].FMEnabled=RING_MOD;break; + case 3:NoteVoicePar[nvoice].FMEnabled=PHASE_MOD;break; + case 4:NoteVoicePar[nvoice].FMEnabled=FREQ_MOD;break; + case 5:NoteVoicePar[nvoice].FMEnabled=PITCH_MOD;break; + default:NoteVoicePar[nvoice].FMEnabled=NONE; + }; + + 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){ + 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; + break; + case FREQ_MOD: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; + default: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); + + FMoldsmp[nvoice]=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); + }; + + initparameters(); + ready=1; +}; + + +/* + * Kill a voice of ADnote + */ +void ADnote::KillVoice(int nvoice){ + + delete (NoteVoicePar[nvoice].OscilSmp); + + if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) delete(NoteVoicePar[nvoice].FreqEnvelope); + NoteVoicePar[nvoice].FreqEnvelope=NULL; + + if (NoteVoicePar[nvoice].FreqLfo!=NULL) delete(NoteVoicePar[nvoice].FreqLfo); + NoteVoicePar[nvoice].FreqLfo=NULL; + + if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) delete (NoteVoicePar[nvoice].AmpEnvelope); + NoteVoicePar[nvoice].AmpEnvelope=NULL; + + if (NoteVoicePar[nvoice].AmpLfo!=NULL) delete (NoteVoicePar[nvoice].AmpLfo); + NoteVoicePar[nvoice].AmpLfo=NULL; + + if (NoteVoicePar[nvoice].VoiceFilter!=NULL) delete (NoteVoicePar[nvoice].VoiceFilter); + NoteVoicePar[nvoice].VoiceFilter=NULL; + + if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) delete (NoteVoicePar[nvoice].FilterEnvelope); + NoteVoicePar[nvoice].FilterEnvelope=NULL; + + if (NoteVoicePar[nvoice].FilterLfo!=NULL) delete (NoteVoicePar[nvoice].FilterLfo); + NoteVoicePar[nvoice].FilterLfo=NULL; + + if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) delete (NoteVoicePar[nvoice].FMFreqEnvelope); + NoteVoicePar[nvoice].FMFreqEnvelope=NULL; + + if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) delete (NoteVoicePar[nvoice].FMAmpEnvelope); + NoteVoicePar[nvoice].FMAmpEnvelope=NULL; + + if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)) delete NoteVoicePar[nvoice].FMSmp; + + if (NoteVoicePar[nvoice].VoiceOut!=NULL) + for (int i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=0.0;//do not delete, yet: perhaps is used by another voice + + NoteVoicePar[nvoice].Enabled=OFF; +}; + +/* + * Kill the note + */ +void ADnote::KillNote(){ + int nvoice; + for (nvoice=0;nvoice<NUM_VOICES;nvoice++){ + if (NoteVoicePar[nvoice].Enabled==ON) KillVoice(nvoice); + + //delete VoiceOut + if (NoteVoicePar[nvoice].VoiceOut!=NULL) delete(NoteVoicePar[nvoice].VoiceOut); + NoteVoicePar[nvoice].VoiceOut=NULL; + }; + + delete (NoteGlobalPar.FreqEnvelope); + delete (NoteGlobalPar.FreqLfo); + delete (NoteGlobalPar.AmpEnvelope); + delete (NoteGlobalPar.AmpLfo); + delete (NoteGlobalPar.GlobalFilterL); + if (stereo!=0) delete (NoteGlobalPar.GlobalFilterR); + delete (NoteGlobalPar.FilterEnvelope); + delete (NoteGlobalPar.FilterLfo); + + NoteEnabled=OFF; +}; + +ADnote::~ADnote(){ + if (NoteEnabled==ON) KillNote(); + delete [] tmpwave; + delete [] bypassl; + delete [] bypassr; +}; + + +/* + * Init the parameters + */ +void ADnote::initparameters(){ + int nvoice,i,tmp[NUM_VOICES]; + + // Global Parameters + 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.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.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); + + // Forbids the Modulation Voice to be greater or equal than voice + for (i=0;i<NUM_VOICES;i++) if (NoteVoicePar[i].FMVoice>=i) NoteVoicePar[i].FMVoice=-1; + + // Voice Parameter init + for (nvoice=0;nvoice<NUM_VOICES;nvoice++){ + if (NoteVoicePar[nvoice].Enabled==0) continue; + + 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 + + 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; + + 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(); + }; + + /* Voice Frequency Parameters Init */ + 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); + + /* Voice Filter Parameters Init */ + if (partparams->VoicePar[nvoice].PFilterEnabled!=0){ + NoteVoicePar[nvoice].VoiceFilter=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].PFilterLfoEnabled!=0) + NoteVoicePar[nvoice].FilterLfo=new LFO(partparams->VoicePar[nvoice].FilterLfo,basefreq); + + NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); + + /* Voice Modulation Parameters Init */ + 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]; + + //Perform Anti-aliasing only on MORPH or RING MODULATION + + 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()); + + oscposhiFM[nvoice]=(oscposhi[nvoice]+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]; + oscposhiFM[nvoice]+=(int)((partparams->VoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); + oscposhiFM[nvoice]%=OSCIL_SIZE; + }; + + if (partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0) + NoteVoicePar[nvoice].FMFreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FMFreqEnvelope,basefreq); + + 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(); + }; + }; + + for (nvoice=0;nvoice<NUM_VOICES;nvoice++){ + for (i=nvoice+1;i<NUM_VOICES;i++) tmp[i]=0; + for (i=nvoice+1;i<NUM_VOICES;i++) + if ((NoteVoicePar[i].FMVoice==nvoice)&&(tmp[i]==0)){ + NoteVoicePar[nvoice].VoiceOut=new REALTYPE[SOUND_BUFFER_SIZE]; + tmp[i]=1; + }; + if (NoteVoicePar[nvoice].VoiceOut!=NULL) for (i=0;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=0.0; + }; +}; + + + +/* + * Computes the frequency of an oscillator + */ +void ADnote::setfreq(int nvoice,REALTYPE freq){ + REALTYPE speed; + freq=fabs(freq); + speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE; + if (speed>OSCIL_SIZE) speed=OSCIL_SIZE; + + F2I(speed,oscfreqhi[nvoice]); + oscfreqlo[nvoice]=speed-floor(speed); +}; + +/* + * Computes the frequency of an modullator oscillator + */ +void ADnote::setfreqFM(int nvoice,REALTYPE freq){ + REALTYPE speed; + freq=fabs(freq); + speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE; + if (speed>OSCIL_SIZE) speed=OSCIL_SIZE; + + F2I(speed,oscfreqhiFM[nvoice]); + oscfreqloFM[nvoice]=speed-floor(speed); +}; + +/* + * Get Voice base frequency + */ +REALTYPE ADnote::getvoicebasefreq(int nvoice){ + 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)); + }; +}; + +/* + * Get Voice's Modullator base frequency + */ +REALTYPE ADnote::getFMvoicebasefreq(int nvoice){ + 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(); + + globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout() + +NoteGlobalPar.FilterCenterPitch; + + REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq + +NoteGlobalPar.FilterFreqTracking; + + 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); + + //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" + }; + }; + + //compute parameters for all voices + for (nvoice=0;nvoice<NUM_VOICES;nvoice++){ + if (NoteVoicePar[nvoice].Enabled!=ON) continue; + NoteVoicePar[nvoice].DelayTicks-=1; + if (NoteVoicePar[nvoice].DelayTicks>0) continue; + + /*******************/ + /* Voice Amplitude */ + /*******************/ + oldamplitude[nvoice]=newamplitude[nvoice]; + newamplitude[nvoice]=1.0; + + if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) + newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + + 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].FilterEnvelope!=NULL) + filterpitch+=NoteVoicePar[nvoice].FilterEnvelope->envout(); + + if (NoteVoicePar[nvoice].FilterLfo!=NULL) + filterpitch+=NoteVoicePar[nvoice].FilterLfo->lfoout(); + + filterfreq=filterpitch+NoteVoicePar[nvoice].FilterFreqTracking; + filterfreq=NoteVoicePar[nvoice].VoiceFilter->getrealfreq(filterfreq); + + NoteVoicePar[nvoice].VoiceFilter->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; + + 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); + + 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){ + 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; + + 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<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; + REALTYPE poslo; + + poshi=oscposhi[nvoice]; + poslo=oscposlo[nvoice]; + REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp; + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + 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; + oscposlo[nvoice]=poslo; +}; + + + +/* + * Computes the Oscillator (Without Modulation) - CubicInterpolation + * + The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512) +inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){ + int i,poshi; + REALTYPE poslo; + + poshi=oscposhi[nvoice]; + poslo=oscposlo[nvoice]; + REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp; + REALTYPE xm1,x0,x1,x2,a,b,c; + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + 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; + oscposlo[nvoice]=poslo; +}; +*/ +/* + * Computes the Oscillator (Morphing) + */ +inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice){ + 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 I use VoiceOut[] as modullator + int FMVoice=NoteVoicePar[nvoice].FMVoice; + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice] + ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE); + tmpwave[i]=tmpwave[i]*(1.0-amp)+amp*NoteVoicePar[FMVoice].VoiceOut[i]; + }; + } else { + int poshiFM=oscposhiFM[nvoice]; + REALTYPE posloFM=oscposloFM[nvoice]; + + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice] + ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE); + tmpwave[i]=tmpwave[i]*(1.0-amp)+amp + *(NoteVoicePar[nvoice].FMSmp[poshiFM]*(1-posloFM) + +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM); + posloFM+=oscfreqloFM[nvoice]; + if (posloFM>=1.0) { + posloFM-=1.0; + poshiFM++; + }; + poshiFM+=oscfreqhiFM[nvoice]; + poshiFM&=OSCIL_SIZE-1; + }; + oscposhiFM[nvoice]=poshiFM; + oscposloFM[nvoice]=posloFM; + }; +}; + +/* + * Computes the Oscillator (Ring Modulation) + */ +inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice){ + 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 I use VoiceOut[] as modullator + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice] + ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE); + int FMVoice=NoteVoicePar[nvoice].FMVoice; + for (i=0;i<SOUND_BUFFER_SIZE;i++) + tmpwave[i]*=(1.0-amp)+amp*NoteVoicePar[FMVoice].VoiceOut[i]; + }; + } else { + int poshiFM=oscposhiFM[nvoice]; + REALTYPE posloFM=oscposloFM[nvoice]; + + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + amp=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice] + ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE); + tmpwave[i]*=( NoteVoicePar[nvoice].FMSmp[poshiFM]*(1.0-posloFM) + +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM)*amp + +(1.0-amp); + posloFM+=oscfreqloFM[nvoice]; + if (posloFM>=1.0) { + posloFM-=1.0; + poshiFM++; + }; + poshiFM+=oscfreqhiFM[nvoice]; + poshiFM&=OSCIL_SIZE-1; + }; + oscposhiFM[nvoice]=poshiFM; + oscposloFM[nvoice]=posloFM; + }; +}; + + + +/* + * Computes the Oscillator (Phase Modulation or Frequency Modulation) + */ +inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode){ + int carposhi; + int i,FMmodfreqhi; + REALTYPE FMmodfreqlo,carposlo; + + if (NoteVoicePar[nvoice].FMVoice>=0){ + //if I use VoiceOut[] as modulator + for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]=NoteVoicePar[NoteVoicePar[nvoice].FMVoice].VoiceOut[i]; + } else { + //Compute the modulator and store it in tmpwave[] + int poshiFM=oscposhiFM[nvoice]; + REALTYPE posloFM=oscposloFM[nvoice]; + + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + tmpwave[i]=(NoteVoicePar[nvoice].FMSmp[poshiFM]*(1.0-posloFM) + +NoteVoicePar[nvoice].FMSmp[poshiFM+1]*posloFM); + posloFM+=oscfreqloFM[nvoice]; + if (posloFM>=1.0) { + posloFM=fmod(posloFM,1.0); + poshiFM++; + }; + poshiFM+=oscfreqhiFM[nvoice]; + poshiFM&=OSCIL_SIZE-1; + }; + oscposhiFM[nvoice]=poshiFM; + oscposloFM[nvoice]=posloFM; + }; + // Amplitude interpolation + if (ABOVE_AMPLITUDE_THRESHOLD(FMoldamplitude[nvoice],FMnewamplitude[nvoice])){ + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + tmpwave[i]*=INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice] + ,FMnewamplitude[nvoice],i,SOUND_BUFFER_SIZE); + }; + } else for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=FMnewamplitude[nvoice]; + + + //normalize makes all sample-rates, oscil_sizes toproduce same sound + if (FMmode!=0){//Frequency modulation + REALTYPE normalize=OSCIL_SIZE/262144.0*44100.0/(REALTYPE)SAMPLE_RATE; + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + FMoldsmp[nvoice]=fmod(FMoldsmp[nvoice]+tmpwave[i]*normalize,OSCIL_SIZE); + tmpwave[i]=FMoldsmp[nvoice]; + }; + } else {//Phase modulation + REALTYPE normalize=OSCIL_SIZE/262144.0; + for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=normalize; + }; + + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + F2I(tmpwave[i],FMmodfreqhi); + FMmodfreqlo=fmod(tmpwave[i]+0.0000000001,1.0); + if (FMmodfreqhi<0) FMmodfreqlo++; + + //carrier + carposhi=oscposhi[nvoice]+FMmodfreqhi; + carposlo=oscposlo[nvoice]+FMmodfreqlo; + + if (carposlo>=1.0) { + carposhi++; + carposlo=fmod(carposlo,1.0); + }; + carposhi&=(OSCIL_SIZE-1); + + tmpwave[i]=NoteVoicePar[nvoice].OscilSmp[carposhi]*(1.0-carposlo) + +NoteVoicePar[nvoice].OscilSmp[carposhi+1]*carposlo; + + oscposlo[nvoice]+=oscfreqlo[nvoice]; + if (oscposlo[nvoice]>=1.0) { + oscposlo[nvoice]=fmod(oscposlo[nvoice],1.0); + oscposhi[nvoice]++; + }; + + oscposhi[nvoice]+=oscfreqhi[nvoice]; + oscposhi[nvoice]&=OSCIL_SIZE-1; + }; +}; + + +/*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;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]=RND*2.0-1.0; +}; + + + +/* + * Compute the ADnote samples + * Returns 0 if the note is finished + */ +int ADnote::noteout(REALTYPE *outl,REALTYPE *outr){ + int i,nvoice; + + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + outl[i]=denormalkillbuf[i]; + outr[i]=denormalkillbuf[i]; + }; + + if (NoteEnabled==OFF) return(0); + + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + bypassl[i]=0.0; + bypassr[i]=0.0; + }; + + computecurrentparameters(); + + 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; + case RING_MOD:ComputeVoiceOscillatorRingModulation(nvoice);break; + case PHASE_MOD:ComputeVoiceOscillatorFrequencyModulation(nvoice,0);break; + case FREQ_MOD:ComputeVoiceOscillatorFrequencyModulation(nvoice,1);break; + //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break; + default:ComputeVoiceOscillator_LinearInterpolation(nvoice); + //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(nvoice); + + }; + } else ComputeVoiceNoise(nvoice); + // Voice Processing + + // Amplitude + if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude[nvoice],newamplitude[nvoice])){ + 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<SOUND_BUFFER_SIZE-rest;i++) tmpwave[i]*=oldamplitude[nvoice]; + }; + // Amplitude interpolation + for (i=0;i<rest;i++){ + tmpwave[i+(SOUND_BUFFER_SIZE-rest)]*=INTERPOLATE_AMPLITUDE(oldamplitude[nvoice] + ,newamplitude[nvoice],i,rest); + }; + } else for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpwave[i]*=newamplitude[nvoice]; + + // Fade in + if (firsttick[nvoice]!=0){ + fadein(&tmpwave[0]); + firsttick[nvoice]=0; + }; + + + // Filter + if (NoteVoicePar[nvoice].VoiceFilter!=NULL) NoteVoicePar[nvoice].VoiceFilter->filterout(&tmpwave[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;i<SOUND_BUFFER_SIZE;i++) + tmpwave[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;i<SOUND_BUFFER_SIZE;i++) NoteVoicePar[nvoice].VoiceOut[i]=tmpwave[i]; + + + // Add the voice that do not bypass the filter to out + if (NoteVoicePar[nvoice].filterbypass==0){//no bypass + if (stereo==0) for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume;//mono + else for (i=0;i<SOUND_BUFFER_SIZE;i++) {//stereo + outl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*NoteVoicePar[nvoice].Panning*2.0; + outr[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*(1.0-NoteVoicePar[nvoice].Panning)*2.0; + }; + } else {//bypass the filter + if (stereo==0) for (i=0;i<SOUND_BUFFER_SIZE;i++) bypassl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume;//mono + else for (i=0;i<SOUND_BUFFER_SIZE;i++) {//stereo + bypassl[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*NoteVoicePar[nvoice].Panning*2.0; + bypassr[i]+=tmpwave[i]*NoteVoicePar[nvoice].Volume*(1.0-NoteVoicePar[nvoice].Panning)*2.0; + }; + }; + // chech if there is necesary to proces the voice longer (if the Amplitude envelope isn't finished) + 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;i<SOUND_BUFFER_SIZE;i++) {//set the right channel=left channel + outr[i]=outl[i]; + bypassr[i]=bypassl[i]; + } + } else NoteGlobalPar.GlobalFilterR->filterout(&outr[0]); + + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + outl[i]+=bypassl[i]; + outr[i]+=bypassr[i]; + }; + + if (ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude,globalnewamplitude)){ + // Amplitude Interpolation + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + REALTYPE tmpvol=INTERPOLATE_AMPLITUDE(globaloldamplitude + ,globalnewamplitude,i,SOUND_BUFFER_SIZE); + outl[i]*=tmpvol*NoteGlobalPar.Panning; + outr[i]*=tmpvol*(1.0-NoteGlobalPar.Panning); + }; + } else { + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + outl[i]*=globalnewamplitude*NoteGlobalPar.Panning; + outr[i]*=globalnewamplitude*(1.0-NoteGlobalPar.Panning); + }; + }; + + //Apply the punch + if (NoteGlobalPar.Punch.Enabled!=0){ + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + REALTYPE punchamp=NoteGlobalPar.Punch.initialvalue*NoteGlobalPar.Punch.t+1.0; + outl[i]*=punchamp; + outr[i]*=punchamp; + NoteGlobalPar.Punch.t-=NoteGlobalPar.Punch.dt; + if (NoteGlobalPar.Punch.t<0.0) { + NoteGlobalPar.Punch.Enabled=0; + break; + }; + }; + }; + + // Check if the global amplitude is finished. + // If it does, disable the note + if (NoteGlobalPar.AmpEnvelope->finished()!=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); +}; + + +/* + * Relase the key (NoteOff) + */ +void ADnote::relasekey(){ +int nvoice; + 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(){ + if (NoteEnabled==ON) return(0); + else return(1); +}; + + + diff --git a/muse/synti/zynaddsubfx/Synth/ADnote.h b/muse/synti/zynaddsubfx/Synth/ADnote.h new file mode 100644 index 00000000..28c18975 --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/ADnote.h @@ -0,0 +1,258 @@ +/* + ZynAddSubFX - a software synthesizer + + ADnote.h - The "additive" synthesizer + 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) 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 AD_NOTE_H +#define AD_NOTE_H + +#include "../globals.h" +#include "Envelope.h" +#include "LFO.h" +#include "../DSP/Filter.h" +#include "../Params/ADnoteParameters.h" +#include "../Params/Controller.h" + +//Globals + +//FM amplitude tune +#define FM_AMP_MULTIPLIER 14.71280603 + +#define OSCIL_SMP_EXTRA_SAMPLES 5 + +class ADnote{ //ADDitive note + public: + ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_); + ~ADnote(); + int noteout(REALTYPE *outl,REALTYPE *outr); + void relasekey(); + int finished(); + + + /*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; + + 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); + + inline void ComputeVoiceNoise(int nvoice); + + inline void fadein(REALTYPE *smps); + + + //GLOBALS + ADnoteParameters *partparams; + unsigned char stereo;//if the note is stereo (allows note Panning) + int midinote; + REALTYPE velocity,basefreq; + + ONOFFTYPE NoteEnabled; + Controller *ctl; + + /*****************************************************************/ + /* GLOBAL PARAMETERS */ + /*****************************************************************/ + + struct ADnoteGlobal{ + /****************************************** + * 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; + + /****************************************** + * 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 *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; +}; + +#endif + + + + diff --git a/muse/synti/zynaddsubfx/Synth/Envelope.C b/muse/synti/zynaddsubfx/Synth/Envelope.C new file mode 100644 index 00000000..a0194022 --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/Envelope.C @@ -0,0 +1,165 @@ +/* + ZynAddSubFX - a software synthesizer + + Envelope.C - Envelope implementation + 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) 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 <stdio.h> +#include "Envelope.h" + +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; + + if (envpars->Pfreemode==0) envpars->converttofree(); + + REALTYPE bufferdt=SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; + + 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 + + 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){ + case 2: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]; + break; + case 4: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; + break; + default:envval[i]=envpars->Penvval[i]/127.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; +}; + +Envelope::~Envelope(){ +}; + + +/* + * Relase the key (note envelope) + */ +void Envelope::relasekey(){ + if (keyreleased==1) return; + keyreleased=1; + if (forcedrelase!=0) t=0.0; +}; + +/* + * Envelope Output + */ +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 ((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 + + 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; + + t+=inct; + if (t>=1.0){ + if (currentpoint>=envpoints-1) envfinish=1; + else currentpoint++; + t=0.0; + inct=envdt[currentpoint]; + }; + + envoutval=out; + return (out); +}; + +/* + * Envelope Output (dB) + */ +REALTYPE Envelope::envout_dB(){ + REALTYPE out; + 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; + + t+=inct; + if (t>=1.0) { + t=0.0; + inct=envdt[2]; + currentpoint++; + out=v2; + }; + + if (out>0.001) envoutval=rap2dB(out); + else envoutval=-40.0; + } else out=dB2rap(envout()); + + return(out); +}; + +int Envelope::finished(){ + return(envfinish); +}; + diff --git a/muse/synti/zynaddsubfx/Synth/Envelope.h b/muse/synti/zynaddsubfx/Synth/Envelope.h new file mode 100644 index 00000000..d78eb16d --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/Envelope.h @@ -0,0 +1,58 @@ +/* + ZynAddSubFX - a software synthesizer + + Envelope.h - Envelope implementation + 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) 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 ENVELOPE_H +#define ENVELOPE_H + +#include <math.h> +#include "../globals.h" +#include "../Params/EnvelopeParams.h" + +class Envelope{ +public: + Envelope(EnvelopeParams *envpars,REALTYPE basefreq); + ~Envelope(); + void relasekey(); + REALTYPE envout(); + REALTYPE envout_dB(); + int finished();//returns 1 if the envelope is 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 + char envfinish; + REALTYPE t; // the time from the last point + REALTYPE inct;// the time increment + REALTYPE envoutval;//used to do the forced release +}; + + +#endif + + diff --git a/muse/synti/zynaddsubfx/Synth/LFO.C b/muse/synti/zynaddsubfx/Synth/LFO.C new file mode 100644 index 00000000..4ae548c1 --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/LFO.C @@ -0,0 +1,145 @@ +/* + ZynAddSubFX - a software synthesizer + + LFO.C - LFO implementation + 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) 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 <stdlib.h> +#include <stdio.h> +#include <math.h> + +#include "LFO.h" + + +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 + + 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); + }; + + //Limit the Frequency(or else...) + 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; + +// lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*2.0*4.0; + lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*4.0; + + switch (lfopars->fel){ + case 1:lfointensity=lfopars->Pintensity/127.0;break; + case 2: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 + 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); + computenextincrnd(); + computenextincrnd();//twice because I want incrnd & nextincrnd to be random +}; + +LFO::~LFO(){ +}; + +/* + * LFO out + */ +REALTYPE LFO::lfoout(){ + REALTYPE out; + 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; + break; + case 2: //LFO_SQUARE + if (x<0.5) out=-1; + else out=1; + break; + case 3: //LFO_RAMPUP + out=(x-0.5)*2.0; + break; + case 4: //LFO_RAMPDOWN + out=(0.5-x)*2.0; + break; + case 5: //LFO_EXP_DOWN 1 + 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; + break; + default: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; + 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; + + computenextincrnd(); + }; + } else lfodelay-=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; + return(out); +}; + +/* + * LFO out (for amplitude) + */ +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); +}; + + +void LFO::computenextincrnd(){ + if (freqrndenabled==0) return; + incrnd=nextincrnd; + nextincrnd=pow(0.5,lfofreqrnd)+RND*(pow(2.0,lfofreqrnd)-1.0); +}; + diff --git a/muse/synti/zynaddsubfx/Synth/LFO.h b/muse/synti/zynaddsubfx/Synth/LFO.h new file mode 100644 index 00000000..30d04f10 --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/LFO.h @@ -0,0 +1,52 @@ +/* + ZynAddSubFX - a software synthesizer + + LFO.h - LFO implementation + 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) 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 LFO_H +#define LFO_H + +#include "../globals.h" +#include "../Params/LFOParams.h" + + +class LFO{ + public: + LFO(LFOParams *lfopars, REALTYPE basefreq); + ~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; + char lfotype; + int freqrndenabled; + + + void computenextincrnd(); + +}; + + +#endif diff --git a/muse/synti/zynaddsubfx/Synth/OscilGen.C b/muse/synti/zynaddsubfx/Synth/OscilGen.C new file mode 100644 index 00000000..4e6a4dd3 --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/OscilGen.C @@ -0,0 +1,1182 @@ +/* + ZynAddSubFX - a software synthesizer + + OscilGen.C - Waveform generator for ADnote + 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) 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 <stdlib.h> +#include <math.h> +#include <stdio.h> + +#include "OscilGen.h" +#include "../Effects/Distorsion.h" + +REALTYPE *OscilGen::tmpsmps;//this array stores some termporary data and it has SOUND_BUFFER_SIZE elements +FFTFREQS OscilGen::outoscilFFTfreqs; + + +OscilGen::OscilGen(FFTwrapper *fft_,Resonance *res_):Presets(){ + setpresettype("Poscilgen"); + fft=fft_; + res=res_; + newFFTFREQS(&oscilFFTfreqs,OSCIL_SIZE/2); + newFFTFREQS(&basefuncFFTfreqs,OSCIL_SIZE/2); + + randseed=1; + ADvsPAD=false; + + defaults(); +}; + +OscilGen::~OscilGen(){ + 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; + + 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 + + Pcurrentbasefunc=0; + Pbasefuncpar=64; + + Pbasefuncmodulation=0; + Pbasefuncmodulationpar1=64; + Pbasefuncmodulationpar2=64; + Pbasefuncmodulationpar3=32; + + Pmodulation=0; + Pmodulationpar1=64; + Pmodulationpar2=64; + Pmodulationpar3=32; + + Pwaveshapingfunction=0; + Pwaveshaping=64; + Pfiltertype=0; + Pfilterpar1=64; + Pfilterpar2=64; + Pfilterbeforews=0; + Psatype=0; + Psapar=64; + + Pamprandpower=64; + Pamprandtype=0; + + Pharmonicshift=0; + Pharmonicshiftfirst=0; + + Padaptiveharmonics=0; + Padaptiveharmonicspower=100; + Padaptiveharmonicsbasefreq=128; + Padaptiveharmonicspar=50; + + for (int i=0;i<OSCIL_SIZE/2;i++) { + oscilFFTfreqs.s[i]=0.0; + oscilFFTfreqs.c[i]=0.0; + basefuncFFTfreqs.s[i]=0.0; + basefuncFFTfreqs.c[i]=0.0; + }; + oscilprepared=0; + oldfilterpars=0;oldsapars=0; + prepare(); +}; + +void OscilGen::convert2sine(int magtype){ + REALTYPE mag[MAX_AD_HARMONICS],phase[MAX_AD_HARMONICS]; + REALTYPE oscil[OSCIL_SIZE]; + FFTFREQS freqs; + newFFTFREQS(&freqs,OSCIL_SIZE/2); + + get(oscil,-1.0); + FFTwrapper *fft=new FFTwrapper(OSCIL_SIZE); + fft->smps2freqs(oscil,freqs); + delete(fft); + + REALTYPE max=0.0; + + mag[0]=0; + phase[0]=0; + for (int i=0;i<MAX_AD_HARMONICS;i++){ + mag[i]=sqrt(pow(freqs.s[i+1],2)+pow(freqs.c[i+1],2.0)); + phase[i]=atan2(freqs.c[i+1],freqs.s[i+1]); + if (max<mag[i]) max=mag[i]; + }; + if (max<0.00001) max=1.0; + + defaults(); + + for (int i=0;i<MAX_AD_HARMONICS-1;i++){ + REALTYPE newmag=mag[i]/max; + REALTYPE newphase=phase[i]; + + Phmag[i]=(int) ((newmag)*64.0)+64; + + Phphase[i]=64-(int) (64.0*newphase/PI); + if (Phphase[i]>127) Phphase[i]=127; + + if (Phmag[i]==64) Phphase[i]=64; + }; + deleteFFTFREQS(&freqs); + prepare(); +}; + +/* + * Base Functions - START + */ +REALTYPE OscilGen::basefunc_pulse(REALTYPE x,REALTYPE a){ + return((fmod(x,1.0)<a)?-1.0:1.0); +}; + +REALTYPE OscilGen::basefunc_saw(REALTYPE x,REALTYPE a){ + if (a<0.00001) a=0.00001; + else if (a>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){ + 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){ + 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){ + 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){ + 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){ + 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){ + 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){ + 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){ + 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){ + 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){ + 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){ + a=a*a*a*a*160.0+0.001; + return(-atan(sin(x*2.0*PI)*a)); +}; +/* + * Base Functions - END + */ + + +/* + * Get the base function + */ +void OscilGen::getbasefunction(REALTYPE *smps){ + 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; + + 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; + break; + case 2: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; + break; + }; + +// printf("%.5f %.5f\n",basefuncmodulationpar1,basefuncmodulationpar3); + + for (i=0;i<OSCIL_SIZE;i++) { + REALTYPE t=i*1.0/OSCIL_SIZE; + + switch(Pbasefuncmodulation){ + case 1:t=t*basefuncmodulationpar3+sin((t+basefuncmodulationpar2)*2.0*PI)*basefuncmodulationpar1;//rev + break; + case 2:t=t+sin((t*basefuncmodulationpar3+basefuncmodulationpar2)*2.0*PI)*basefuncmodulationpar1;//sine + break; + case 3:t=t+pow((1.0-cos((t+basefuncmodulationpar2)*2.0*PI))*0.5,basefuncmodulationpar3)*basefuncmodulationpar1;//power + break; + }; + + t=t-floor(t); + + switch (Pcurrentbasefunc){ + case 1:smps[i]=basefunc_triangle(t,par); + break; + case 2:smps[i]=basefunc_pulse(t,par); + break; + case 3:smps[i]=basefunc_saw(t,par); + break; + case 4:smps[i]=basefunc_power(t,par); + break; + case 5:smps[i]=basefunc_gauss(t,par); + break; + case 6:smps[i]=basefunc_diode(t,par); + break; + case 7:smps[i]=basefunc_abssine(t,par); + break; + case 8:smps[i]=basefunc_pulsesine(t,par); + break; + case 9:smps[i]=basefunc_stretchsine(t,par); + break; + case 10:smps[i]=basefunc_chirp(t,par); + break; + case 11:smps[i]=basefunc_absstretchsine(t,par); + break; + case 12:smps[i]=basefunc_chebyshev(t,par); + break; + case 13:smps[i]=basefunc_sqr(t,par); + break; + default:smps[i]=-sin(2.0*PI*i/OSCIL_SIZE); + }; + }; +}; + +/* + * Filter the oscillator + */ +void OscilGen::oscilfilter(){ + if (Pfiltertype==0) return; + REALTYPE par=1.0-Pfilterpar1/128.0; + REALTYPE par2=Pfilterpar2/127.0; + REALTYPE max=0.0,tmp=0.0,p2,x; + for (int i=1;i<OSCIL_SIZE/2;i++){ + REALTYPE gain=1.0; + switch(Pfiltertype){ + case 1: gain=pow(1.0-par*par*par*0.99,i);//lp + tmp=par2*par2*par2*par2*0.5+0.0001; + if (gain<tmp) gain=pow(gain,10.0)/pow(tmp,9.0); + break; + case 2: gain=1.0-pow(1.0-par*par,i+1);//hp1 + gain=pow(gain,par2*2.0+0.1); + break; + case 3: if (par<0.2) par=par*0.25+0.15; + gain=1.0-pow(1.0-par*par*0.999+0.001,i*0.05*i+1.0);//hp1b + tmp=pow(5.0,par2*2.0); + gain=pow(gain,tmp); + break; + case 4: gain=i+1-pow(2,(1.0-par)*7.5);//bp1 + gain=1.0/(1.0+gain*gain/(i+1.0)); + tmp=pow(5.0,par2*2.0); + gain=pow(gain,tmp); + if (gain<1e-5) gain=1e-5; + break; + case 5: gain=i+1-pow(2,(1.0-par)*7.5);//bs1 + gain=pow(atan(gain/(i/10.0+1))/1.57,6); + gain=pow(gain,par2*par2*3.9+0.1); + break; + case 6: 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=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; + break; + case 8: 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 + break; + case 9: tmp=pow(par2,0.33); + gain=(fabs(pow(2,(1.0-par)*7)-i)<i/2+1?0.0:1.0)*par2+(1.0-par2);//bs2 + break; + case 10:tmp=pow(5.0,par2*2.0-1.0); + tmp=pow(i/32.0,tmp)*32.0; + if (Pfilterpar2==64) tmp=i; + gain=cos(par*par*PI/2.0*tmp);//cos + gain*=gain; + break; + case 11:tmp=pow(5.0,par2*2.0-1.0); + tmp=pow(i/32.0,tmp)*32.0; + if (Pfilterpar2==64) tmp=i; + gain=sin(par*par*PI/2.0*tmp);//sin + gain*=gain; + break; + case 12: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); + break; + }; + + + oscilFFTfreqs.s[i]*=gain; + oscilFFTfreqs.c[i]*=gain; + REALTYPE tmp=oscilFFTfreqs.s[i]*oscilFFTfreqs.s[i]+ + oscilFFTfreqs.c[i]*oscilFFTfreqs.c[i]; + if (max<tmp) max=tmp; + }; + + max=sqrt(max); + if (max<1e-10) max=1.0; + REALTYPE imax=1.0/max; + for (int i=1;i<OSCIL_SIZE/2;i++) { + oscilFFTfreqs.s[i]*=imax; + oscilFFTfreqs.c[i]*=imax; + }; +}; + +/* + * Change the base function + */ +void OscilGen::changebasefunction(){ + if (Pcurrentbasefunc!=0) { + getbasefunction(tmpsmps); + fft->smps2freqs(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; +}; + +/* + * Waveshape + */ +void OscilGen::waveshape(){ + int i; + + oldwaveshapingfunction=Pwaveshapingfunction; + oldwaveshaping=Pwaveshaping; + if (Pwaveshapingfunction==0) return; + + oscilFFTfreqs.c[0]=0.0;//remove the DC + //reduce the amplitude of the freqs near the nyquist + 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;i<OSCIL_SIZE;i++) + if (max<fabs(tmpsmps[i])) max=fabs(tmpsmps[i]); + if (max<0.00001) max=1.0; + max=1.0/max;for (i=0;i<OSCIL_SIZE;i++) tmpsmps[i]*=max; + + //Do the waveshaping + waveshapesmps(OSCIL_SIZE,tmpsmps,Pwaveshapingfunction,Pwaveshaping); + + fft->smps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT +}; + + +/* + * Do the Frequency Modulation of the Oscil + */ +void OscilGen::modulation(){ + int i; + + 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; + + 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; + break; + case 2: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; + break; + }; + + oscilFFTfreqs.c[0]=0.0;//remove the DC + //reduce the amplitude of the freqs near the nyquist + 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;i<OSCIL_SIZE;i++) if (max<fabs(tmpsmps[i])) max=fabs(tmpsmps[i]); + if (max<0.00001) max=1.0; + max=1.0/max;for (i=0;i<OSCIL_SIZE;i++) in[i]=tmpsmps[i]*max; + for (i=0;i<extra_points;i++) in[i+OSCIL_SIZE]=tmpsmps[i]*max; + + //Do the modulation + for (i=0;i<OSCIL_SIZE;i++) { + REALTYPE t=i*1.0/OSCIL_SIZE; + + switch(Pmodulation){ + case 1:t=t*modulationpar3+sin((t+modulationpar2)*2.0*PI)*modulationpar1;//rev + break; + case 2:t=t+sin((t*modulationpar3+modulationpar2)*2.0*PI)*modulationpar1;//sine + break; + case 3:t=t+pow((1.0-cos((t+modulationpar2)*2.0*PI))*0.5,modulationpar3)*modulationpar1;//power + break; + }; + + t=(t-floor(t))*OSCIL_SIZE; + + int poshi=(int) t; + REALTYPE poslo=t-floor(t); + + tmpsmps[i]=in[poshi]*(1.0-poslo)+in[poshi+1]*poslo; + }; + + delete(in); + fft->smps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT +}; + + + +/* + * Adjust the spectrum + */ +void OscilGen::spectrumadjust(){ + 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); + break; + case 2: 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; + break; + }; + + + REALTYPE max=0.0; + for (int i=0;i<OSCIL_SIZE/2;i++){ + REALTYPE tmp=pow(oscilFFTfreqs.c[i],2)+pow(oscilFFTfreqs.s[i],2.0); + if (max<tmp) max=tmp; + }; + max=sqrt(max)/OSCIL_SIZE*2.0; + if (max<1e-8) max=1.0; + + + for (int i=0;i<OSCIL_SIZE/2;i++){ + REALTYPE mag=sqrt(pow(oscilFFTfreqs.s[i],2)+pow(oscilFFTfreqs.c[i],2.0))/max; + REALTYPE phase=atan2(oscilFFTfreqs.s[i],oscilFFTfreqs.c[i]); + + switch (Psatype){ + case 1: mag=pow(mag,par); + break; + case 2: if (mag<par) mag=0.0; + break; + case 3: mag/=par; + if (mag>1.0) mag=1.0; + break; + }; + oscilFFTfreqs.c[i]=mag*cos(phase); + oscilFFTfreqs.s[i]=mag*sin(phase); + }; + +}; + +void OscilGen::shiftharmonics(){ + if (Pharmonicshift==0) return; + + 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;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[0]=0.0; +}; + +/* + * Prepare the Oscillator + */ +void OscilGen::prepare(){ + int i,j,k; + REALTYPE a,b,c,d,hmagnew; + + if ((oldbasepar!=Pbasefuncpar)||(oldbasefunc!=Pcurrentbasefunc)|| + (oldbasefuncmodulation!=Pbasefuncmodulation)|| + (oldbasefuncmodulationpar1!=Pbasefuncmodulationpar1)|| + (oldbasefuncmodulationpar2!=Pbasefuncmodulationpar2)|| + (oldbasefuncmodulationpar3!=Pbasefuncmodulationpar3)) + changebasefunction(); + + for (i=0;i<MAX_AD_HARMONICS;i++) hphase[i]=(Phphase[i]-64.0)/64.0*PI/(i+1); + + for (i=0;i<MAX_AD_HARMONICS;i++){ + hmagnew=1.0-fabs(Phmag[i]/64.0-1.0); + switch(Phmagtype){ + case 1:hmag[i]=exp(hmagnew*log(0.01)); break; + case 2:hmag[i]=exp(hmagnew*log(0.001));break; + case 3:hmag[i]=exp(hmagnew*log(0.0001));break; + case 4:hmag[i]=exp(hmagnew*log(0.00001));break; + default:hmag[i]=1.0-hmagnew; + break; + }; + + if (Phmag[i]<64) hmag[i]=-hmag[i]; + }; + + //remove the harmonics where Phmag[i]==64 + for (i=0;i<MAX_AD_HARMONICS;i++) if (Phmag[i]==64) hmag[i]=0.0; + + + 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 (Pfilterbeforews==0){ + waveshape(); + oscilfilter(); + } else { + oscilfilter(); + waveshape(); + }; + + modulation(); + spectrumadjust(); + if (Pharmonicshiftfirst==0) shiftharmonics(); + + oscilFFTfreqs.c[0]=0.0; + + oldhmagtype=Phmagtype; + oldharmonicshift=Pharmonicshift+Pharmonicshiftfirst*256; + + oscilprepared=1; +}; + +void OscilGen::adaptiveharmonic(FFTFREQS f,REALTYPE freq){ + 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;i<OSCIL_SIZE/2;i++) { + inf.s[i]=f.s[i]; + inf.c[i]=f.c[i]; + f.s[i]=0.0; + f.c[i]=0.0; + }; + inf.c[0]=0.0;inf.s[0]=0.0; + + REALTYPE hc=0.0,hs=0.0; + REALTYPE basefreq=30.0*pow(10.0,Padaptiveharmonicsbasefreq/128.0); + REALTYPE power=(Padaptiveharmonicspower+1.0)/101.0; + + REALTYPE rap=freq/basefreq; + + rap=pow(rap,power); + + bool down=false; + if (rap>1.0) { + rap=1.0/rap; + down=true; + }; + + for (int i=0;i<OSCIL_SIZE/2-2;i++){ + REALTYPE h=i*rap; + int high=(int)(i*rap); + REALTYPE low=fmod(h,1.0); + + 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; + }; + + 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; + deleteFFTFREQS(&inf); +}; + +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); + + for (int i=0;i<size;i++) { + inf[i]=f[i]*par; + f[i]=f[i]*(1.0-par); + }; + + + if (Padaptiveharmonics==2){//2n+1 + for (int i=0;i<size;i++) if ((i%2)==0) f[i]+=inf[i];//i=0 pt prima armonica,etc. + } else{//celelalte moduri + int nh=(Padaptiveharmonics-3)/2+2; + int sub_vs_add=(Padaptiveharmonics-3)%2; + if (sub_vs_add==0){ + for (int i=0;i<size;i++) { + if (((i+1)%nh)==0){ + f[i]+=inf[i]; + }; + }; + } else { + for (int i=0;i<size/nh-1;i++) { + f[(i+1)*nh-1]+=inf[i]; + }; + }; + }; + + delete(inf); +}; + + + +/* + * Get the oscillator function + */ +short int OscilGen::get(REALTYPE *smps,REALTYPE freqHz){ + return(this->get(smps,freqHz,0)); +}; + +void OscilGen::newrandseed(unsigned int randseed){ + this->randseed=randseed; +}; + +/* + * Get the oscillator function + */ +short int OscilGen::get(REALTYPE *smps,REALTYPE freqHz,int resonance){ + int i; + 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 ((oldbasefuncmodulation!=Pbasefuncmodulation)|| + (oldbasefuncmodulationpar1!=Pbasefuncmodulationpar1)|| + (oldbasefuncmodulationpar2!=Pbasefuncmodulationpar2)|| + (oldbasefuncmodulationpar3!=Pbasefuncmodulationpar3)) + oscilprepared=0; + + if ((oldmodulation!=Pmodulation)|| + (oldmodulationpar1!=Pmodulationpar1)|| + (oldmodulationpar2!=Pmodulationpar2)|| + (oldmodulationpar3!=Pmodulationpar3)) + oscilprepared=0; + + if (oldharmonicshift!=Pharmonicshift+Pharmonicshiftfirst*256) oscilprepared=0; + + 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; + + + for (i=0;i<OSCIL_SIZE/2;i++){ + outoscilFFTfreqs.c[i]=0.0; + outoscilFFTfreqs.s[i]=0.0; + }; + + 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; + + if (Padaptiveharmonics!=0) nyquist=OSCIL_SIZE/2; + for (i=1;i<nyquist-1;i++) { + outoscilFFTfreqs.c[i]=oscilFFTfreqs.c[i]; + outoscilFFTfreqs.s[i]=oscilFFTfreqs.s[i]; + }; + + adaptiveharmonic(outoscilFFTfreqs,freqHz); + adaptiveharmonicpostprocess(&outoscilFFTfreqs.c[1],OSCIL_SIZE/2-1); + adaptiveharmonicpostprocess(&outoscilFFTfreqs.s[1],OSCIL_SIZE/2-1); + + nyquist=realnyquist; + if (Padaptiveharmonics){//do the antialiasing in the case of adaptive harmonics + for (i=nyquist;i<OSCIL_SIZE/2;i++) { + outoscilFFTfreqs.s[i]=0; + outoscilFFTfreqs.c[i]=0; + }; + }; + + // Randomness (each harmonic), the block type is computed + // in ADnote by setting start position according to this setting + if ((Prand>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(); + srand(randseed); + 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;i<nyquist-1;i++){ + REALTYPE amp=pow(RND,power)*normalize; + outoscilFFTfreqs.c[i]*=amp; + outoscilFFTfreqs.s[i]*=amp; + }; + break; + case 2: power=power*2.0-0.5; + power=pow(15.0,power)*2.0; + REALTYPE rndfreq=2*PI*RND; + for (i=1;i<nyquist-1;i++){ + REALTYPE amp=pow(fabs(sin(i*rndfreq)),power)*normalize; + outoscilFFTfreqs.c[i]*=amp; + outoscilFFTfreqs.s[i]*=amp; + }; + break; + }; + srand(realrnd+1); + }; + + if ((freqHz>0.1)&&(resonance!=0)) res->applyres(nyquist-1,outoscilFFTfreqs,freqHz); + + //Full RMS normalize + REALTYPE sum=0; + for (int j=1;j<OSCIL_SIZE/2;j++) { + REALTYPE term=outoscilFFTfreqs.c[j]*outoscilFFTfreqs.c[j] + +outoscilFFTfreqs.s[j]*outoscilFFTfreqs.s[j]; + sum+=term; + }; + if (sum<0.000001) sum=1.0; + sum=1.0/sqrt(sum); + for (int j=1;j<OSCIL_SIZE/2;j++) { + outoscilFFTfreqs.c[j]*=sum; + outoscilFFTfreqs.s[j]*=sum; + }; + + + if ((ADvsPAD)&&(freqHz>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); +}; + + +/* + * Get the spectrum of the oscillator for the UI + */ +void OscilGen::getspectrum(int n, REALTYPE *spc,int what){ + if (n>OSCIL_SIZE/2) n=OSCIL_SIZE/2; + + for (int i=1;i<n;i++){ + if (what==0){ + spc[i-1]=sqrt(oscilFFTfreqs.c[i]*oscilFFTfreqs.c[i] + +oscilFFTfreqs.s[i]*oscilFFTfreqs.s[i]); + } else { + if (Pcurrentbasefunc==0) spc[i-1]=((i==1)?(1.0):(0.0)); + else spc[i-1]=sqrt(basefuncFFTfreqs.c[i]*basefuncFFTfreqs.c[i]+ + basefuncFFTfreqs.s[i]*basefuncFFTfreqs.s[i]); + }; + }; + + if (what==0) { + for (int i=0;i<n;i++) outoscilFFTfreqs.s[i]=outoscilFFTfreqs.c[i]=spc[i+1]; + for (int i=n;i<OSCIL_SIZE/2;i++) outoscilFFTfreqs.s[i]=outoscilFFTfreqs.c[i]=0.0; + adaptiveharmonic(outoscilFFTfreqs,0.0); + for (int i=1;i<n;i++) spc[i-1]=outoscilFFTfreqs.s[i]; + adaptiveharmonicpostprocess(spc,n-1); + }; +}; + + +/* + * Convert the oscillator as base function + */ +void OscilGen::useasbase(){ + int i; + + for (i=0;i<OSCIL_SIZE/2;i++) { + basefuncFFTfreqs.c[i]=oscilFFTfreqs.c[i]; + basefuncFFTfreqs.s[i]=oscilFFTfreqs.s[i]; + }; + + oldbasefunc=Pcurrentbasefunc=127; + + prepare(); +}; + + +/* + * Get the base function for UI + */ +void OscilGen::getcurrentbasefunction(REALTYPE *smps){ + 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("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("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("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("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->beginbranch("HARMONICS"); + 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; + + for (int i=0;i<OSCIL_SIZE/2;i++){ + if (max<fabs(basefuncFFTfreqs.c[i])) max=fabs(basefuncFFTfreqs.c[i]); + if (max<fabs(basefuncFFTfreqs.s[i])) max=fabs(basefuncFFTfreqs.s[i]); + }; + if (max<0.00000001) max=1.0; + + xml->beginbranch("BASE_FUNCTION"); + 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); + + 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); + + 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); + + 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); + + 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); + + 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;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 (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; + + basefuncFFTfreqs.c[0]=0.0; + for (int i=0;i<OSCIL_SIZE/2;i++) { + if (max<fabs(basefuncFFTfreqs.c[i])) max=fabs(basefuncFFTfreqs.c[i]); + if (max<fabs(basefuncFFTfreqs.s[i])) max=fabs(basefuncFFTfreqs.s[i]); + }; + if (max<0.00000001) max=1.0; + + for (int i=0;i<OSCIL_SIZE/2;i++) { + if (basefuncFFTfreqs.c[i]) basefuncFFTfreqs.c[i]/=max; + if (basefuncFFTfreqs.s[i]) basefuncFFTfreqs.s[i]/=max; + }; + }; +}; + + + diff --git a/muse/synti/zynaddsubfx/Synth/OscilGen.h b/muse/synti/zynaddsubfx/Synth/OscilGen.h new file mode 100644 index 00000000..1d9980a9 --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/OscilGen.h @@ -0,0 +1,176 @@ +/* + ZynAddSubFX - a software synthesizer + + OscilGen.h - Waveform generator for ADnote + 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) 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 OSCIL_GEN_H +#define OSCIL_GEN_H + +#include "../globals.h" +#include "../Misc/XMLwrapper.h" +#include "Resonance.h" +#include "../DSP/FFTwrapper.h" +#include "../Params/Presets.h" + +class OscilGen:public Presets{ + public: + OscilGen(FFTwrapper *fft_,Resonance *res_); + ~OscilGen(); + + //computes the full spectrum of oscil from harmonics,phases and basefunc + void prepare(); + + //do the antialiasing(cut off higher freqs.),apply randomness and do a IFFT + short get(REALTYPE *smps,REALTYPE freqHz);//returns where should I start getting samples, used in block type randomness + short get(REALTYPE *smps,REALTYPE freqHz,int resonance); + //if freqHz is smaller than 0, return the "un-randomized" sample for UI + + void getbasefunction(REALTYPE *smps); + + //called by UI + void getspectrum(int n,REALTYPE *spc,int what);//what=0 pt. oscil,1 pt. basefunc + void getcurrentbasefunction(REALTYPE *smps); + void useasbase();//convert oscil to base function + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + void convert2sine(int magtype); + + //Parameters + + /* + The hmag and hphase starts counting from 0, so the first harmonic(1) has the index 0, + 2-nd harmonic has index 1, ..the 128 harminic has index 127 + */ + unsigned char Phmag[MAX_AD_HARMONICS],Phphase[MAX_AD_HARMONICS];//the MIDI parameters for mag. and phases + + + /*The Type of magnitude: + 0 - Linear + 1 - dB scale (-40) + 2 - dB scale (-60) + 3 - dB scale (-80) + 4 - dB scale (-100)*/ + unsigned char Phmagtype; + + unsigned char Pcurrentbasefunc;//The base function used - 0=sin, 1=... + unsigned char Pbasefuncpar;//the parameter of the base function + + unsigned char Pbasefuncmodulation;//what modulation is applied to the basefunc + unsigned char Pbasefuncmodulationpar1,Pbasefuncmodulationpar2,Pbasefuncmodulationpar3;//the parameter of the base function modulation + + /*the Randomness: + 64=no randomness + 63..0 - block type randomness - 0 is maximum + 65..127 - each harmonic randomness - 127 is maximum*/ + unsigned char Prand; + unsigned char Pwaveshaping,Pwaveshapingfunction; + unsigned char Pfiltertype,Pfilterpar1,Pfilterpar2; + unsigned char Pfilterbeforews; + unsigned char Psatype,Psapar;//spectrum adjust + + unsigned char Pamprandpower, Pamprandtype;//amplitude randomness + int Pharmonicshift;//how the harmonics are shifted + int Pharmonicshiftfirst;//if the harmonic shift is done before waveshaping and filter + + unsigned char Padaptiveharmonics;//the adaptive harmonics status (off=0,on=1,etc..) + unsigned char Padaptiveharmonicsbasefreq;//the base frequency of the adaptive harmonic (30..3000Hz) + unsigned char Padaptiveharmonicspower;//the strength of the effect (0=off,100=full) + unsigned char Padaptiveharmonicspar;//the parameters in 2,3,4.. modes of adaptive harmonics + + unsigned char Pmodulation;//what modulation is applied to the oscil + unsigned char Pmodulationpar1,Pmodulationpar2,Pmodulationpar3;//the parameter of the parameters + + + //makes a new random seed for Amplitude Randomness + //this should be called every note on event + void newrandseed(unsigned int randseed); + + bool ADvsPAD;//if it is used by ADsynth or by PADsynth + + static REALTYPE *tmpsmps;//this array stores some termporary data and it has SOUND_BUFFER_SIZE elements + static FFTFREQS outoscilFFTfreqs; + + private: + + REALTYPE hmag[MAX_AD_HARMONICS],hphase[MAX_AD_HARMONICS];//the magnituides and the phases of the sine/nonsine harmonics +// private: + FFTwrapper *fft; + //computes the basefunction and make the FFT; newbasefunc<0 = same basefunc + void changebasefunction(); + //Waveshaping + void waveshape(); + + //Filter the oscillator accotding to Pfiltertype and Pfilterpar + void oscilfilter(); + + //Adjust the spectrum + void spectrumadjust(); + + //Shift the harmonics + void shiftharmonics(); + + //Do the oscil modulation stuff + void modulation(); + + //Do the adaptive harmonic stuff + void adaptiveharmonic(FFTFREQS f,REALTYPE freq); + + //Do the adaptive harmonic postprocessing (2n+1,2xS,2xA,etc..) + //this function is called even for the user interface + //this can be called for the sine and components, and for the spectrum + //(that's why the sine and cosine components should be processed with a separate call) + void adaptiveharmonicpostprocess(REALTYPE *f, int size); + + //Basic/base functions (Functiile De Baza) + REALTYPE basefunc_pulse(REALTYPE x,REALTYPE a); + REALTYPE basefunc_saw(REALTYPE x,REALTYPE a); + REALTYPE basefunc_triangle(REALTYPE x,REALTYPE a); + REALTYPE basefunc_power(REALTYPE x,REALTYPE a); + REALTYPE basefunc_gauss(REALTYPE x,REALTYPE a); + REALTYPE basefunc_diode(REALTYPE x,REALTYPE a); + REALTYPE basefunc_abssine(REALTYPE x,REALTYPE a); + REALTYPE basefunc_pulsesine(REALTYPE x,REALTYPE a); + REALTYPE basefunc_stretchsine(REALTYPE x,REALTYPE a); + REALTYPE basefunc_chirp(REALTYPE x,REALTYPE a); + REALTYPE basefunc_absstretchsine(REALTYPE x,REALTYPE a); + REALTYPE basefunc_chebyshev(REALTYPE x,REALTYPE a); + REALTYPE basefunc_sqr(REALTYPE x,REALTYPE a); + + //Internal Data + unsigned char oldbasefunc,oldbasepar,oldhmagtype,oldwaveshapingfunction,oldwaveshaping; + int oldfilterpars,oldsapars,oldbasefuncmodulation,oldbasefuncmodulationpar1,oldbasefuncmodulationpar2,oldbasefuncmodulationpar3,oldharmonicshift; + int oldmodulation,oldmodulationpar1,oldmodulationpar2,oldmodulationpar3; + + + FFTFREQS basefuncFFTfreqs;//Base Function Frequencies + FFTFREQS oscilFFTfreqs;//Oscillator Frequencies - this is different than the hamonics set-up by the user, it may contains time-domain data if the antialiasing is turned off + int oscilprepared;//1 if the oscil is prepared, 0 if it is not prepared and is need to call ::prepare() before ::get() + + Resonance *res; + + unsigned int randseed; + +}; + + +#endif diff --git a/muse/synti/zynaddsubfx/Synth/PADnote.C b/muse/synti/zynaddsubfx/Synth/PADnote.C new file mode 100644 index 00000000..9ecc8877 --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/PADnote.C @@ -0,0 +1,342 @@ +/* + ZynAddSubFX - a software synthesizer + + PADnote.C - The "pad" synthesizer + 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) 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 <math.h> +#include "PADnote.h" +#include "../Misc/Config.h" + +PADnote::PADnote(PADnoteParameters *parameters, Controller *ctl_,REALTYPE freq, REALTYPE velocity, int portamento_, int midinote){ + ready=0; + pars=parameters; + portamento=portamento_; + ctl=ctl_; + this->velocity=velocity; + finished_=false; + + + 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); + }; + + }; + + 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;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 (dist<mindist){ + nsample=i; + mindist=dist; + }; + }; + + 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; + + tmpwave=new REALTYPE [SOUND_BUFFER_SIZE]; + + + + 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); + + 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.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.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.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 + + if (parameters->sample[nsample].smp==NULL){ + finished_=true; + return; + }; +}; + +PADnote::~PADnote(){ + delete (NoteGlobalPar.FreqEnvelope); + delete (NoteGlobalPar.FreqLfo); + delete (NoteGlobalPar.AmpEnvelope); + delete (NoteGlobalPar.AmpLfo); + delete (NoteGlobalPar.GlobalFilterL); + delete (NoteGlobalPar.GlobalFilterR); + delete (NoteGlobalPar.FilterEnvelope); + delete (NoteGlobalPar.FilterLfo); + delete (tmpwave); +}; + + +inline void PADnote::fadein(REALTYPE *smps){ + 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; + + 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<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(); + + globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout() + +NoteGlobalPar.FilterCenterPitch; + + REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq + +NoteGlobalPar.FilterFreqTracking; + + 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); + + //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" + }; + }; + + realfreq=basefreq*portamentofreqrap*pow(2.0,globalpitch/12.0)*ctl->pitchwheel.relfreq; +}; + + +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<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){ + 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; + 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; + outr[i] = (((a * poslo) + b) * poslo + c) * poslo + x0; + }; + return(1); +}; + + +int PADnote::noteout(REALTYPE *outl,REALTYPE *outr){ + computecurrentparameters(); + 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); + + + if (config.cfg.Interpolation) Compute_Cubic(outl,outr,freqhi,freqlo); + else Compute_Linear(outl,outr,freqhi,freqlo); + + + if (firsttime){ + fadein(outl); + fadein(outr); + firsttime=false; + }; + + NoteGlobalPar.GlobalFilterL->filterout(outl); + NoteGlobalPar.GlobalFilterR->filterout(outr); + + //Apply the punch + if (NoteGlobalPar.Punch.Enabled!=0){ + for (int i=0;i<SOUND_BUFFER_SIZE;i++){ + REALTYPE punchamp=NoteGlobalPar.Punch.initialvalue*NoteGlobalPar.Punch.t+1.0; + outl[i]*=punchamp; + outr[i]*=punchamp; + NoteGlobalPar.Punch.t-=NoteGlobalPar.Punch.dt; + if (NoteGlobalPar.Punch.t<0.0) { + NoteGlobalPar.Punch.Enabled=0; + break; + }; + }; + }; + + if (ABOVE_AMPLITUDE_THRESHOLD(globaloldamplitude,globalnewamplitude)){ + // Amplitude Interpolation + for (int i=0;i<SOUND_BUFFER_SIZE;i++){ + REALTYPE tmpvol=INTERPOLATE_AMPLITUDE(globaloldamplitude,globalnewamplitude,i,SOUND_BUFFER_SIZE); + outl[i]*=tmpvol*NoteGlobalPar.Panning; + outr[i]*=tmpvol*(1.0-NoteGlobalPar.Panning); + }; + } else { + for (int i=0;i<SOUND_BUFFER_SIZE;i++) { + outl[i]*=globalnewamplitude*NoteGlobalPar.Panning; + outr[i]*=globalnewamplitude*(1.0-NoteGlobalPar.Panning); + }; + }; + + + // Check if the global amplitude is finished. + // If it does, disable the note + if (NoteGlobalPar.AmpEnvelope->finished()!=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); +}; + +int PADnote::finished(){ + return(finished_); +}; + +void PADnote::relasekey(){ + NoteGlobalPar.FreqEnvelope->relasekey(); + NoteGlobalPar.FilterEnvelope->relasekey(); + NoteGlobalPar.AmpEnvelope->relasekey(); +}; + diff --git a/muse/synti/zynaddsubfx/Synth/PADnote.h b/muse/synti/zynaddsubfx/Synth/PADnote.h new file mode 100644 index 00000000..2a99577f --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/PADnote.h @@ -0,0 +1,106 @@ +/* + ZynAddSubFX - a software synthesizer + + PADnote.h - The "pad" synthesizer + 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) 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 PAD_NOTE_H +#define PAD_NOTE_H + +#include "../globals.h" +#include "../Params/PADnoteParameters.h" +#include "../Params/Controller.h" +#include "Envelope.h" +#include "LFO.h" +#include "../DSP/Filter.h" +#include "../Params/Controller.h" + +class PADnote{ + public: + PADnote(PADnoteParameters *parameters, Controller *ctl_,REALTYPE freq, REALTYPE velocity, int portamento_, int midinote); + ~PADnote(); + + int noteout(REALTYPE *outl,REALTYPE *outr); + int finished(); + void relasekey(); + + int ready; + + private: + void fadein(REALTYPE *smps); + void computecurrentparameters(); + bool finished_; + PADnoteParameters *pars; + + int poshi_l,poshi_r; + REALTYPE poslo; + + REALTYPE basefreq; + bool firsttime,released; + + 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); + + + 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; + + /****************************************** + * 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; +}; + + +#endif diff --git a/muse/synti/zynaddsubfx/Synth/Resonance.C b/muse/synti/zynaddsubfx/Synth/Resonance.C new file mode 100644 index 00000000..fb741055 --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/Resonance.C @@ -0,0 +1,231 @@ +/* + ZynAddSubFX - a software synthesizer + + Resonance.C - Resonance + 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) 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 <math.h> +#include <stdlib.h> +#include "Resonance.h" + + +#include <stdio.h> + +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;i++) Prespoints[i]=64; +}; + +/* + * Set a point of resonance function with a value + */ +void Resonance::setpoint(int n,unsigned char 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){ + 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;i++) if (sum<Prespoints[i]) sum=Prespoints[i]; + if (sum<1.0) sum=1.0; + + for (int i=1;i<n;i++){ + REALTYPE x=(log(freq*i)-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 y=(Prespoints[kx1]*(1.0-dx)+Prespoints[kx2]*dx)/127.0-sum/127.0; + + y=pow(10.0,y*PmaxdB/20.0); + + if ((Pprotectthefundamental!=0)&&(i==1)) y=1.0; + + fftdata.c[i]*=y; + fftdata.s[i]*=y; + }; +}; + +/* + * Gets the response at the frequency "freq" + */ + +REALTYPE Resonance::getfreqresponse(REALTYPE freq){ + REALTYPE l1=log(getfreqx(0.0)*ctlcenter), + l2=log(2.0)*getoctavesfreq()*ctlbw,sum=0.0; + + for (int i=0;i<N_RES_POINTS;i++) if (sum<Prespoints[i]) sum=Prespoints[i]; + if (sum<1.0) sum=1.0; + + 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); +}; + + +/* + * Smooth the resonance function + */ +void Resonance::smooth(){ + 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;i<N_RES_POINTS;i++){ + Prespoints[i]=r; + if ((RND<0.1)&&(type==0)) r=(int)(RND*127.0); + if ((RND<0.3)&&(type==1)) r=(int)(RND*127.0); + if (type==2) r=(int)(RND*127.0); + }; + smooth(); +}; + +/* + * Interpolate the peaks + */ +void Resonance::interpolatepeaks(int type){ + int x1=0,y1=Prespoints[0]; + for (int i=1;i<N_RES_POINTS;i++){ + if ((Prespoints[i]!=64)||(i+1==N_RES_POINTS)){ + int y2=Prespoints[i]; + for (int k=0;k<i-x1;k++){ + float x=(float) k/(i-x1); + if (type==0) x=(1-cos(x*PI))*0.5; + Prespoints[x1+k]=(int)(y1*(1.0-x)+y2*x); + }; + x1=i; + y1=y2; + }; + }; +}; + +/* + * Get the frequency from x, where x is [0..1]; x is the x coordinate + */ +REALTYPE Resonance::getfreqx(REALTYPE 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()); +}; + +/* + * Get the center frequency of the resonance graph + */ +REALTYPE Resonance::getcenterfreq(){ + 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); +}; + +void Resonance::sendcontroller(MidiControllers ctl,REALTYPE par){ + if (ctl==C_resonance_center) ctlcenter=par; + else ctlbw=par; +}; + + + + +void Resonance::add2XML(XMLwrapper *xml){ + xml->addparbool("enabled",Penabled); + + 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;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); + + 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/muse/synti/zynaddsubfx/Synth/Resonance.h b/muse/synti/zynaddsubfx/Synth/Resonance.h new file mode 100644 index 00000000..7b09e295 --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/Resonance.h @@ -0,0 +1,68 @@ +/* + ZynAddSubFX - a software synthesizer + + Resonance.h - Resonance + 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) 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 RESONANCE_H +#define RESONANCE_H + +#include "../globals.h" +#include "../Misc/Util.h" +#include "../Misc/XMLwrapper.h" +#include "../Params/Presets.h" + +#define N_RES_POINTS 256 + +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); + + 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); + + //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) + + private: +}; + +#endif diff --git a/muse/synti/zynaddsubfx/Synth/SUBnote.C b/muse/synti/zynaddsubfx/Synth/SUBnote.C new file mode 100644 index 00000000..f198ba04 --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/SUBnote.C @@ -0,0 +1,419 @@ +/* + ZynAddSubFX - a software synthesizer + + SUBnote.C - The "subtractive" synthesizer + 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) 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 <math.h> +#include <stdlib.h> +#include <stdio.h> +#include "../globals.h" +#include "SUBnote.h" +#include "../Misc/Util.h" + +SUBnote::SUBnote(SUBnoteParameters *parameters,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote){ + ready=0; + + tmpsmp=new REALTYPE[SOUND_BUFFER_SIZE]; + tmprnd=new REALTYPE[SOUND_BUFFER_SIZE]; + + 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; + 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*=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); + + GlobalFilterL=NULL;GlobalFilterR=NULL; + GlobalFilterEnvelope=NULL; + + //select only harmonics that desire to compute + 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; + }; + + if (numharmonics==0) { + NoteEnabled=OFF; + return; + }; + + + 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; + + for (int n=0;n<numharmonics;n++){ + + REALTYPE freq=basefreq*(pos[n]+1); + + //the bandwidth is not absolute(Hz); it is relative to frequency + 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); + + //Relative BandWidth + bw*=pow(100,(pars->Phrelbw[pos[n]]-64.0)/64.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 hmagnew=1.0-pars->Phmag[pos[n]]/127.0; + REALTYPE hgain; + + switch(pars->Phmagtype){ + case 1:hgain=exp(hmagnew*log(0.01)); break; + case 2:hgain=exp(hmagnew*log(0.001));break; + case 3:hgain=exp(hmagnew*log(0.0001));break; + case 4:hgain=exp(hmagnew*log(0.00001));break; + default:hgain=1.0-hmagnew; + }; + gain*=hgain; + reduceamp+=hgain; + + for (int nph=0;nph<numstages;nph++){ + REALTYPE amp=1.0; + if (nph==0) amp=gain; + initfilter(lfilter[nph+n*numstages],freq,bw,amp,hgain); + if (stereo!=0) initfilter(rfilter[nph+n*numstages],freq,bw,amp,hgain); + }; + }; + + if (reduceamp<0.001) reduceamp=1.0; + volume/=reduceamp; + + oldpitchwheel=0; + oldbandwidth=64; + if (pars->Pfixedfreq==0) initparameters(basefreq); + else initparameters(basefreq/440.0*freq); + + oldamplitude=newamplitude; + ready=1; +}; + +SUBnote::~SUBnote(){ + if (NoteEnabled!=OFF) KillNote(); + delete [] tmpsmp; + delete [] tmprnd; +}; + +/* + * Kill the note + */ +void SUBnote::KillNote(){ + 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; + }; + +}; + + +/* + * Compute the filters coefficients + */ +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; + }; + + 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; + + 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){ + 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); + + //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; + + }; + }; + + 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){ + int i; + REALTYPE out; + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + out=smps[i] * filter.b0 + filter.b2 * filter.xn2 + -filter.a1 * filter.yn1 - filter.a2 * filter.yn2; + filter.xn2=filter.xn1; + filter.xn1=smps[i]; + filter.yn2=filter.yn1; + filter.yn1=out; + smps[i]=out; + + }; +}; + +/* + * Init Parameters + */ +void SUBnote::initparameters(REALTYPE freq){ + 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(); +}; + + +/* + * Compute Parameters of SUBnote for each tick + */ +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) { + 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 + + REALTYPE tmpgain=1.0/sqrt(envbw*envfreq); + + 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); + + 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 i; + + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + outl[i]=denormalkillbuf[i]; + outr[i]=denormalkillbuf[i]; + }; + + if (NoteEnabled==OFF) return(0); + + //left channel + for (i=0;i<SOUND_BUFFER_SIZE;i++) tmprnd[i]=RND*2.0-1.0; + for (int n=0;n<numharmonics;n++){ + for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpsmp[i]=tmprnd[i]; + for (int nph=0;nph<numstages;nph++) + filter(lfilter[nph+n*numstages],tmpsmp); + for (i=0;i<SOUND_BUFFER_SIZE;i++) outl[i]+=tmpsmp[i]; + }; + + if (GlobalFilterL!=NULL) GlobalFilterL->filterout(&outl[0]); + + //right channel + if (stereo!=0){ + for (i=0;i<SOUND_BUFFER_SIZE;i++) tmprnd[i]=RND*2.0-1.0; + for (int n=0;n<numharmonics;n++){ + for (i=0;i<SOUND_BUFFER_SIZE;i++) tmpsmp[i]=tmprnd[i]; + for (int nph=0;nph<numstages;nph++) + filter(rfilter[nph+n*numstages],tmpsmp); + for (i=0;i<SOUND_BUFFER_SIZE;i++) outr[i]+=tmpsmp[i]; + }; + if (GlobalFilterR!=NULL) GlobalFilterR->filterout(&outr[0]); + } else for (i=0;i<SOUND_BUFFER_SIZE;i++) outr[i]=outl[i]; + + if (firsttick!=0){ + int n=10;if (n>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)){ + // Amplitude interpolation + for (i=0;i<SOUND_BUFFER_SIZE;i++){ + REALTYPE tmpvol=INTERPOLATE_AMPLITUDE(oldamplitude + ,newamplitude,i,SOUND_BUFFER_SIZE); + outl[i]*=tmpvol*panning; + outr[i]*=tmpvol*(1.0-panning); + }; + } else { + for (i=0;i<SOUND_BUFFER_SIZE;i++) { + outl[i]*=newamplitude*panning; + outr[i]*=newamplitude*(1.0-panning); + }; + }; + + oldamplitude=newamplitude; + computecurrentparameters(); + + // Check if the note needs to be computed more + if (AmpEnvelope->finished()!=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); +}; + +/* + * Relase Key (Note Off) + */ +void SUBnote::relasekey(){ + AmpEnvelope->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); +}; + diff --git a/muse/synti/zynaddsubfx/Synth/SUBnote.h b/muse/synti/zynaddsubfx/Synth/SUBnote.h new file mode 100644 index 00000000..6e4e2991 --- /dev/null +++ b/muse/synti/zynaddsubfx/Synth/SUBnote.h @@ -0,0 +1,98 @@ +/* + ZynAddSubFX - a software synthesizer + + SUBnote.h - The subtractive synthesizer + 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) 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 SUB_NOTE_H +#define SUB_NOTE_H + +#include "../globals.h" +#include "../Params/SUBnoteParameters.h" +#include "../Params/Controller.h" +#include "Envelope.h" +#include "../DSP/Filter.h" + +class SUBnote{ + public: + SUBnote(SUBnoteParameters *parameters,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote); + ~SUBnote(); + 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 + + private: + + void computecurrentparameters(); + void initparameters(REALTYPE freq); + void KillNote(); + + 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 start;//how the harmonics start + REALTYPE basefreq; + REALTYPE panning; + Envelope *AmpEnvelope; + Envelope *FreqEnvelope; + Envelope *BandWidthEnvelope; + + Filter *GlobalFilterL,*GlobalFilterR; + + Envelope *GlobalFilterEnvelope; + + //internal values + ONOFFTYPE NoteEnabled; + int firsttick,portamento; + REALTYPE volume,oldamplitude,newamplitude; + + 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 + }; + + 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); + + bpfilter *lfilter,*rfilter; + + REALTYPE *tmpsmp; + REALTYPE *tmprnd;//this is filled with random numbers + + Controller *ctl; + int oldpitchwheel,oldbandwidth; + REALTYPE globalfiltercenterq; + +}; + + + + +#endif + diff --git a/muse/synti/zynaddsubfx/UI/ADnoteUI.fl b/muse/synti/zynaddsubfx/UI/ADnoteUI.fl new file mode 100644 index 00000000..33e25dff --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/ADnoteUI.fl @@ -0,0 +1,1107 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include "../Params/ADnoteParameters.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "ResonanceUI.h"} {public +} + +decl {\#include <FL/Fl_Box.H>} {public +} + +decl {\#include <FL/Fl_Group.H>} {public +} + +decl {\#include <math.h>} {} + +decl {\#include <stdio.h>} {} + +decl {\#include <stdlib.h>} {} + +decl {\#include <string.h>} {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EnvelopeUI.h"} {public +} + +decl {\#include "LFOUI.h"} {public +} + +decl {\#include "FilterUI.h"} {public +} + +decl {\#include "OscilGenUI.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class ADvoicelistitem {: {public Fl_Group} +} { + Function {make_window()} {private + } { + Fl_Window ADnoteVoiceListItem { + private xywh {247 599 615 30} type Double hide + class Fl_Group + } { + Fl_Group voicelistitemgroup { + private xywh {50 0 570 25} box FLAT_BOX + code0 {if (pars->VoicePar[nvoice].Enabled==0) o->deactivate();} + } { + Fl_Value_Slider voicevolume { + callback {pars->VoicePar[nvoice].PVolume=(int)o->value();} + tooltip Volume xywh {90 5 115 20} type {Horz Knob} box FLAT_BOX labelsize 8 align 5 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PVolume);} + } + Fl_Check_Button voiceresonanceenabled { + callback {pars->VoicePar[nvoice].Presonance=(int)o->value();} + tooltip {Resonance On/Off} xywh {245 7 15 17} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 12 align 4 + code0 {o->value(pars->VoicePar[nvoice].Presonance);} + } + Fl_Value_Slider voicelfofreq { + callback {pars->VoicePar[nvoice].FreqLfo->Pintensity=(int)o->value();} + tooltip {Frequency LFO amount} xywh {500 5 115 20} type {Horz Knob} box FLAT_BOX labelsize 8 align 5 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].FreqLfo->Pintensity);} + } + Fl_Dial voicepanning { + callback {pars->VoicePar[nvoice].PPanning=(int) o->value();} + tooltip {Panning (leftmost is Random)} xywh {215 5 20 20} box ROUND_UP_BOX labelsize 11 align 4 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PPanning);} + class WidgetPDial + } + Fl_Group voiceoscil {open + xywh {60 5 30 20} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 + code0 {osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} + code1 {osc->init(pars->VoicePar[nvoice].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master);} + code2 {if (pars->VoicePar[nvoice].Pextoscil != -1) {osc->init(pars->VoicePar[pars->VoicePar[nvoice].Pextoscil].OscilSmp,master);}} + } {} + Fl_Value_Output detunevalueoutput { + callback {o->value(getdetune((pars->VoicePar[nvoice].PDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PDetuneType),0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier());} + xywh {265 5 45 20} labelsize 10 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 10 + code0 {o->value(getdetune(pars->VoicePar[nvoice].PDetuneType,0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier());} + } + Fl_Slider voicedetune { + callback {pars->VoicePar[nvoice].PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {315 5 185 20} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->VoicePar[nvoice].PDetune-8192);} + } + Fl_Box noiselabel { + label N + callback {if (pars->VoicePar[nvoice].Type==0) { + o->hide(); + voiceresonanceenabled->activate(); + detunevalueoutput->activate(); + voicedetune->activate(); + voicelfofreq->activate(); + voiceoscil->activate(); +} else { + o->show(); + voiceresonanceenabled->deactivate(); + detunevalueoutput->deactivate(); + voicedetune->deactivate(); + voicelfofreq->deactivate(); + voiceoscil->deactivate(); +};} + xywh {65 5 20 20} labelfont 1 labelsize 16 labelcolor 7 + code0 {if (pars->VoicePar[nvoice].Type==0) o->hide();} + } + } + Fl_Check_Button voiceenabled { + label 01 + callback {pars->VoicePar[nvoice].Enabled=(int)o->value(); +if (o->value()==0) voicelistitemgroup->deactivate(); +else voicelistitemgroup->activate(); +o->redraw();} + private xywh {30 5 20 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 4 + code0 {char tmp[10];snprintf(tmp,10,"%d",nvoice+1);o->label(strdup(tmp));} + code1 {o->value(pars->VoicePar[nvoice].Enabled);} + } + } + } + Function {ADvoicelistitem(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {nvoice=0; +pars=NULL;} {} + } + Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {} { + code {pars=parameters; +nvoice=nvoice_; +master=master_; +make_window(); +ADnoteVoiceListItem->show(); +end();} {} + } + Function {refreshlist()} {} { + code {voiceenabled->value(pars->VoicePar[nvoice].Enabled); +voiceresonanceenabled->value(pars->VoicePar[nvoice].Presonance); +voicevolume->value(pars->VoicePar[nvoice].PVolume); +voicedetune->value(pars->VoicePar[nvoice].PDetune-8192); +voicepanning->value(pars->VoicePar[nvoice].PPanning); +voicelfofreq->value(pars->VoicePar[nvoice].FreqLfo->Pintensity); +if (pars->VoicePar[nvoice].Pextoscil != -1) { + osc->init(pars->VoicePar[pars->VoicePar[nvoice].Pextoscil].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master); +} else + osc->init(pars->VoicePar[nvoice].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master); +if (pars->VoicePar[nvoice].Enabled==0) voicelistitemgroup->deactivate(); + else voicelistitemgroup->activate(); +detunevalueoutput->do_callback(); +noiselabel->do_callback(); +ADnoteVoiceListItem->redraw();} {} + } + Function {~ADvoicelistitem()} {} { + code {ADnoteVoiceListItem->hide(); +//delete(ADnoteVoiceListItem);} {} + } + decl {ADnoteParameters *pars;} {} + decl {int nvoice;} {} + decl {Oscilloscope *osc;} {} + decl {Master *master;} {} +} + +class ADvoiceUI {: {public Fl_Group} +} { + Function {make_window()} {} { + Fl_Window ADnoteVoiceParameters { + label Voice + xywh {231 132 765 525} type Double hide + class Fl_Group + } { + Fl_Group voiceparametersgroup { + xywh {0 0 765 525} 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 voiceFMparametersgroup { + label MODULATOR + xywh {530 5 230 515} box THIN_UP_FRAME color 48 labeltype EMBOSSED_LABEL labelfont 1 labelsize 18 align 17 + code0 {if (pars->VoicePar[nvoice].PFMEnabled==0) o->deactivate();} + } { + Fl_Group modfrequency { + label {Mod.FREQUENCY} + xywh {535 220 220 145} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + } { + Fl_Group voiceFMfreqenvgroup { + label {ADSynth Modulator - Frequency Envelope} + xywh {540 290 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->VoicePar[nvoice].FMFreqEnvelope);} + code1 {if (pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voiceFMfreqenvgroup->deactivate(); +else voiceFMfreqenvgroup->activate(); +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);} + } + Fl_Counter {} { + label {Coarse Det.} + callback {int k=(int) o->value(); +if (k<0) k+=1024; +pars->VoicePar[nvoice].PFMCoarseDetune = k+ + (pars->VoicePar[nvoice].PFMCoarseDetune/1024)*1024;} + tooltip {Coarse Detune} xywh {685 270 60 15} labelsize 11 align 1 minimum -64 maximum 63 step 1 textfont 1 textsize 12 + code0 {int k=pars->VoicePar[nvoice].PFMCoarseDetune%1024;} + code1 {if (k>=512) k-=1024;} + code2 {o->value(k);} + code3 {o->lstep(10);} + } + Fl_Counter {} { + label Octave + callback {int k=(int) o->value(); +if (k<0) k+=16; +pars->VoicePar[nvoice].PFMCoarseDetune = k*1024+ + pars->VoicePar[nvoice].PFMCoarseDetune%1024;} + tooltip Octave xywh {625 270 45 15} type Simple labelsize 10 align 1 minimum -8 maximum 7 step 1 textfont 1 textsize 12 + code0 {int k=pars->VoicePar[nvoice].PFMCoarseDetune/1024;} + code1 {if (k>=8) k-=16;} + code2 {o->value(k);} + } + Fl_Slider {} { + callback {pars->VoicePar[nvoice].PFMDetune=(int)o->value()+8192; +fmdetunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {590 245 160 10} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->VoicePar[nvoice].PFMDetune-8192);} + } + Fl_Value_Output fmdetunevalueoutput { + label Detune + callback {o->value(getdetune((pars->VoicePar[nvoice].PFMDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PFMDetuneType),0,pars->VoicePar[nvoice].PFMDetune));} + xywh {540 245 45 13} labelsize 8 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 8 + code0 {o->value(getdetune((pars->VoicePar[nvoice].PFMDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PFMDetuneType),0,pars->VoicePar[nvoice].PFMDetune));} + code1 {//o->value(getdetune(pars->VoicePar[nvoice].PFMDetuneType,0,pars->VoicePar[nvoice].PFMDetune));} + } + Fl_Choice {} { + label {Detune Type} + callback {pars->VoicePar[nvoice].PFMDetuneType=(int) o->value(); +fmdetunevalueoutput->do_callback();} open + xywh {540 270 75 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("Default");o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");} + code1 {o->value(pars->VoicePar[nvoice].PFMDetuneType);} + } {} + } + Fl_Group {} { + label {Mod.AMPLITUDE} + xywh {535 60 220 160} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + } { + Fl_Value_Slider {} { + label Vol + callback {pars->VoicePar[nvoice].PFMVolume=(int)o->value();} + tooltip Volume xywh {540 80 160 15} type {Horz Knob} box FLAT_BOX labelsize 12 align 8 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PFMVolume);} + } + Fl_Value_Slider {} { + label {V.Sns} + callback {pars->VoicePar[nvoice].PFMVelocityScaleFunction=(int) o->value();} + tooltip {Velocity Sensing Function (rightmost to disable)} xywh {540 100 160 15} type {Horz Knob} box FLAT_BOX labelsize 12 align 8 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PFMVelocityScaleFunction);} + } + Fl_Group voiceFMampenvgroup { + label {ADSynth Modulator - Amplitude Envelope} open + xywh {540 145 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->VoicePar[nvoice].FMAmpEnvelope);} + code1 {if (pars->VoicePar[nvoice].PFMAmpEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFMAmpEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voiceFMampenvgroup->deactivate(); +else voiceFMampenvgroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {545 150 50 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PFMAmpEnvelopeEnabled);} + } + Fl_Value_Slider {} { + label {F.Damp} + callback {pars->VoicePar[nvoice].PFMVolumeDamp=(int) o->value()+64;} + tooltip {Modulator Damp at Higher frequency} xywh {540 120 160 15} type {Horz Knob} box FLAT_BOX labelsize 12 align 8 minimum -64 maximum 63 step 1 + code0 {o->value(pars->VoicePar[nvoice].PFMVolumeDamp-64);} + } + } + Fl_Group modoscil { + xywh {535 365 220 150} + } { + Fl_Group fmoscil {open + xywh {535 405 220 110} 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);} + } {} + Fl_Box {} { + label {Mod.Oscillator} + xywh {535 365 155 20} labelfont 1 align 20 + } + Fl_Button changeFMoscilbutton { + label Change + callback {if (oscedit!=NULL) delete(oscedit); + +int nv=nvoice; +if (pars->VoicePar[nvoice].PextFMoscil>=0) nv=pars->VoicePar[nvoice].PextFMoscil; + +oscedit=new OscilEditor(pars->VoicePar[nv].FMSmp,fmoscil,NULL,NULL,master);} selected + xywh {700 370 55 15} box THIN_UP_BOX labelfont 1 labelsize 12 + code0 {if (pars->VoicePar[nvoice].PextFMoscil>=0) o->labelcolor(FL_BLUE);} + } + Fl_Slider {} { + label Phase + 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 + code0 {o->value(64-pars->VoicePar[nvoice].PFMoscilphase);} + } + Fl_Choice {} { + label Use + callback {pars->VoicePar[nvoice].PextFMoscil=(int)o->value()-1; +if ((int) o->value() != 0) { + oscFM->init(pars->VoicePar[(int) o->value()-1].FMSmp,master); + changeFMoscilbutton->labelcolor(FL_BLUE); +} else { + oscFM->init(pars->VoicePar[nvoice].FMSmp,master); + changeFMoscilbutton->labelcolor(FL_BLACK); +}; +voiceFMparametersgroup->redraw();} open + xywh {560 390 75 15} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10 + code0 {o->add("Internal");} + code1 {char tmp[50]; for (int i=0;i<nvoice;i++) {sprintf(tmp,"ExtM.%2d",i+1);o->add(tmp);};} + code3 {o->value(pars->VoicePar[nvoice].PextFMoscil+1);} + } {} + } + Fl_Choice {} { + label {External Mod.} + callback {pars->VoicePar[nvoice].PFMVoice=(int)o->value()-1; +if ((int) o->value() != 0) { + modoscil->deactivate(); + modfrequency->deactivate(); +} else { + modoscil->activate(); + modfrequency->activate(); +}; +voiceFMparametersgroup->redraw();} open + xywh {635 40 85 20} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("OFF");} + code1 {char tmp[50]; for (int i=0;i<nvoice;i++) {sprintf(tmp,"ExtMod.%2d",i+1);o->add(tmp);};} + code2 {o->value(pars->VoicePar[nvoice].PFMVoice+1);} + code3 {if ((int) o->value() != 0) {modoscil->deactivate();modfrequency->deactivate();}} + } {} + } + Fl_Choice {} { + label {Type:} + callback {pars->VoicePar[nvoice].PFMEnabled=(int)o->value(); +if (o->value()==0) voiceFMparametersgroup->deactivate(); +else voiceFMparametersgroup->activate(); +o->redraw();} + xywh {535 40 80 20} down_box BORDER_BOX align 5 + code0 {o->value(pars->VoicePar[nvoice].PFMEnabled);} + } { + menuitem {} { + label OFF + xywh {40 40 100 20} labelfont 1 + } + menuitem {} { + label MORPH + xywh {50 50 100 20} labelfont 1 + } + menuitem {} { + label RING + xywh {60 60 100 20} labelfont 1 + } + menuitem {} { + label PM + xywh {70 70 100 20} labelfont 1 + } + menuitem {} { + label FM + xywh {80 80 100 20} labelfont 1 + } + menuitem {} { + label PITCH + xywh {90 90 100 20} labelfont 1 deactivate + } + } + Fl_Group {} { + label FREQUENCY + xywh {5 250 525 120} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + } { + Fl_Group voicefreqenvgroup { + label {ADSynth Voice - Frequency Envelope} open + xywh {10 290 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->VoicePar[nvoice].FreqEnvelope);} + code1 {if (pars->VoicePar[nvoice].PFreqEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFreqEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voicefreqenvgroup->deactivate(); +else voicefreqenvgroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {15 295 50 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PFreqEnvelopeEnabled);} + } + Fl_Group voicefreqlfogroup { + label {Frequency LFO } open + xywh {215 290 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->VoicePar[nvoice].FreqLfo);} + code1 {if (pars->VoicePar[nvoice].PFreqLfoEnabled==0) o->deactivate();} + class LFOUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFreqLfoEnabled=(int)o->value(); +if (o->value()==0) voicefreqlfogroup->deactivate(); +else voicefreqlfogroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {220 295 55 10} down_box DOWN_BOX labelfont 1 labelsize 12 align 24 + code0 {o->value(pars->VoicePar[nvoice].PFreqLfoEnabled);} + } + Fl_Counter {} { + label Octave + callback {int k=(int) o->value(); +if (k<0) k+=16; +pars->VoicePar[nvoice].PCoarseDetune = k*1024+ + pars->VoicePar[nvoice].PCoarseDetune%1024;} + tooltip Octave xywh {470 270 45 15} type Simple labelsize 10 align 1 minimum -8 maximum 7 step 1 textfont 1 textsize 12 + code0 {int k=pars->VoicePar[nvoice].PCoarseDetune/1024;} + code1 {if (k>=8) k-=16;} + code2 {o->value(k);} + } + Fl_Counter {} { + label {Coarse Det.} + callback {int k=(int) o->value(); +if (k<0) k+=1024; +pars->VoicePar[nvoice].PCoarseDetune = k+ + (pars->VoicePar[nvoice].PCoarseDetune/1024)*1024;} + tooltip {Coarse Detune} xywh {455 340 60 20} labelsize 11 align 1 minimum -64 maximum 63 step 1 textfont 1 textsize 12 + code0 {int k=pars->VoicePar[nvoice].PCoarseDetune%1024;} + code1 {if (k>=512) k-=1024;} + code2 {o->value(k);} + code3 {o->lstep(10);} + } + Fl_Slider {} { + callback {pars->VoicePar[nvoice].PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {58 272 392 13} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->VoicePar[nvoice].PDetune-8192);} + } + Fl_Value_Output detunevalueoutput { + label Detune + callback {o->value(getdetune((pars->VoicePar[nvoice].PDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PDetuneType),0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier());} + xywh {10 272 45 15} labelsize 10 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 10 + code0 {o->value(getdetune((pars->VoicePar[nvoice].PDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PDetuneType),0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier());} + } + Fl_Check_Button {} { + label 440Hz + callback {int x=(int) o->value(); +pars->VoicePar[nvoice].Pfixedfreq=x; +if (x==0) fixedfreqetdial->deactivate(); + else fixedfreqetdial->activate();} + tooltip {Set the voice base frequency to 440Hz} xywh {345 253 55 15} down_box DOWN_BOX labelfont 1 labelsize 12 + code0 {o->value(pars->VoicePar[nvoice].Pfixedfreq);} + } + Fl_Dial fixedfreqetdial { + label {Eq.T.} + callback {pars->VoicePar[nvoice].PfixedfreqET=(int) o->value();} + tooltip {How the frequency varies acording to the keyboard (leftmost for fixed frequency)} xywh {405 255 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PfixedfreqET);} + code1 {if (pars->VoicePar[nvoice].Pfixedfreq==0) o->deactivate();} + class WidgetPDial + } + Fl_Choice {} { + label {Detune Type} + callback {pars->VoicePar[nvoice].PDetuneType=(int) o->value(); +detunevalueoutput->do_callback();} open + xywh {450 305 75 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("Default");o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");} + code1 {o->value(pars->VoicePar[nvoice].PDetuneType);} + } {} + } + Fl_Group voiceoscil { + xywh {80 375 445 145} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 + code0 {osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} + code1 {int nv=nvoice; if (pars->VoicePar[nvoice].Pextoscil>=0) nv=pars->VoicePar[nvoice].Pextoscil;} + code2 {osc->init(pars->VoicePar[nv].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master);} + } {} + Fl_Button changevoiceoscilbutton { + label Change + callback {if (oscedit!=NULL) delete(oscedit); + +int nv=nvoice; +if (pars->VoicePar[nvoice].Pextoscil>=0) nv=pars->VoicePar[nvoice].Pextoscil; + +oscedit=new OscilEditor(pars->VoicePar[nv].OscilSmp,voiceoscil,NULL,NULL,master);} + xywh {5 475 65 20} box THIN_UP_BOX labelfont 1 labelsize 12 + code0 {if (pars->VoicePar[nvoice].Pextoscil>=0) o->labelcolor(FL_BLUE);} + } + Fl_Box {} { + label {Voice Oscillator} + xywh {5 375 75 35} labelfont 1 align 128 + } + Fl_Slider {} { + label Phase + callback {pars->VoicePar[nvoice].Poscilphase=64-(int)o->value(); +osc->phase=64-(int) o->value(); +voiceoscil->redraw();} + xywh {10 420 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].Poscilphase);} + } + Fl_Check_Button {} { + label {R.} + callback {pars->VoicePar[nvoice].Presonance=(int) o->value();} + tooltip {Resonance On/Off} xywh {210 5 35 35} box THIN_UP_BOX down_box DOWN_BOX labelfont 1 labelsize 12 + code0 {o->value(pars->VoicePar[nvoice].Presonance);} + } + Fl_Choice {} { + label {Use Oscil.} + callback {pars->VoicePar[nvoice].Pextoscil=(int)o->value()-1; +if ((int) o->value() != 0) { + osc->init(pars->VoicePar[(int) o->value()-1].OscilSmp,master); + changevoiceoscilbutton->labelcolor(FL_BLUE); +} else { + osc->init(pars->VoicePar[nvoice].OscilSmp,master); + changevoiceoscilbutton->labelcolor(FL_BLACK); +}; + +voiceparametersgroup->redraw(); +voiceonbutton->redraw();} open + xywh {5 455 65 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("Internal");} + code1 {char tmp[50]; for (int i=0;i<nvoice;i++) {sprintf(tmp,"Ext.%2d",i+1);o->add(tmp);};} + code3 {o->value(pars->VoicePar[nvoice].Pextoscil+1);} + } {} + } + Fl_Group {} { + label AMPLITUDE + xywh {5 40 240 210} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + } { + Fl_Value_Slider {} { + label Vol + callback {pars->VoicePar[nvoice].PVolume=(int)o->value();} + tooltip Volume xywh {10 60 160 15} type {Horz Knob} box FLAT_BOX labelsize 12 align 8 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PVolume);} + } + Fl_Value_Slider {} { + label {V.Sns} + callback {pars->VoicePar[nvoice].PAmpVelocityScaleFunction=(int) o->value();} + tooltip {Velocity Sensing Function (rightmost to disable)} xywh {10 80 160 15} type {Horz Knob} box FLAT_BOX labelsize 12 align 8 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PAmpVelocityScaleFunction);} + } + Fl_Group voiceampenvgroup { + label {ADSynth Voice - Amplitude Envelope} open + xywh {10 105 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->VoicePar[nvoice].AmpEnvelope);} + code1 {if (pars->VoicePar[nvoice].PAmpEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Dial {} { + label Pan + callback {pars->VoicePar[nvoice].PPanning=(int) o->value();} + tooltip {Panning (leftmost is Random)} xywh {210 60 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PPanning);} + class WidgetPDial + } + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PAmpEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voiceampenvgroup->deactivate(); +else voiceampenvgroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {15 110 50 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PAmpEnvelopeEnabled);} + } + Fl_Group voiceamplfogroup { + label {Amplitude LFO } open + xywh {10 175 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->VoicePar[nvoice].AmpLfo);} + code1 {if (pars->VoicePar[nvoice].PAmpLfoEnabled==0) o->deactivate();} + class LFOUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PAmpLfoEnabled=(int)o->value(); +if (o->value()==0) voiceamplfogroup->deactivate(); +else voiceamplfogroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {15 180 55 10} down_box DOWN_BOX labelfont 1 labelsize 12 align 24 + code0 {o->value(pars->VoicePar[nvoice].PAmpLfoEnabled);} + } + Fl_Check_Button {} { + label Minus + callback {pars->VoicePar[nvoice].PVolumeminus=(int)o->value();} + xywh {10 45 50 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PVolumeminus);} + } + } + Fl_Group voicefiltergroup { + label FILTER + xywh {245 5 285 245} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + code0 {if (pars->VoicePar[nvoice].PFilterEnabled==0) o->deactivate();} + } { + Fl_Group {} { + label {ADsynth Voice - Filter} open + xywh {250 30 275 75} box FLAT_BOX color 50 align 144 + code0 {o->init(pars->VoicePar[nvoice].VoiceFilter,NULL,NULL);} + class FilterUI + } {} + Fl_Group voicefilterenvgroup { + label {ADSynth Voice - Filter Envelope} open + xywh {250 105 275 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->VoicePar[nvoice].FilterEnvelope);} + code1 {if (pars->VoicePar[nvoice].PFilterEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFilterEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voicefilterenvgroup->deactivate(); +else voicefilterenvgroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {255 110 55 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PFilterEnvelopeEnabled);} + } + Fl_Group voicefilterlfogroup { + label {Filter LFO } open + xywh {250 175 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->VoicePar[nvoice].FilterLfo);} + code1 {if (pars->VoicePar[nvoice].PFilterLfoEnabled==0) o->deactivate();} + class LFOUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFilterLfoEnabled=(int)o->value(); +if (o->value()==0) voicefilterlfogroup->deactivate(); +else voicefilterlfogroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {255 180 55 10} down_box DOWN_BOX labelfont 1 labelsize 12 align 24 + code0 {o->value(pars->VoicePar[nvoice].PFilterLfoEnabled);} + } + } + Fl_Group {} { + label 01 + xywh {5 5 55 35} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 30 align 16 + code0 {char tmp[10];snprintf(tmp,10,"%d",nvoice+1);o->label(strdup(tmp));} + } {} + Fl_Choice {} { + callback {int x=(int) o->value(); +pars->VoicePar[nvoice].Type=x; +if (x==0) voicemodegroup->activate(); + else voicemodegroup->deactivate(); +noiselabel->do_callback();} + tooltip {Oscillator Type (sound/noise)} xywh {5 500 65 20} down_box BORDER_BOX labelsize 11 textfont 1 textsize 11 + code0 {o->value(pars->VoicePar[nvoice].Type);} + code1 {if (pars->VoicePar[nvoice].Type!=0) voicemodegroup->deactivate();} + } { + menuitem {} { + label Sound + xywh {5 5 100 20} labelfont 1 labelsize 13 + } + menuitem {} { + label NOISE + xywh {15 15 100 20} labelfont 1 labelsize 13 labelcolor 1 + } + } + Fl_Check_Button bypassfiltercheckbutton { + label {Bypass Global F.} + callback {pars->VoicePar[nvoice].Pfilterbypass=(int)o->value();} + xywh {425 10 100 20} down_box DOWN_BOX labelfont 1 labelsize 10 align 148 + code0 {o->value(pars->VoicePar[nvoice].Pfilterbypass);} + } + Fl_Group {} { + xywh {115 5 95 35} box THIN_UP_BOX + } { + Fl_Value_Slider {} { + label Delay + callback {pars->VoicePar[nvoice].PDelay=(int)o->value();} + tooltip Volume xywh {120 21 84 12} type {Horz Knob} box FLAT_BOX labelsize 12 align 5 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PDelay);} + } + } + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFilterEnabled=(int)o->value(); +if (o->value()==0) voicefiltergroup->deactivate(); +else voicefiltergroup->activate(); +o->redraw(); +bypassfiltercheckbutton->redraw();} + tooltip {Enable Filter} xywh {250 15 60 15} down_box DOWN_BOX labelfont 1 labelsize 12 + code0 {o->value(pars->VoicePar[nvoice].PFilterEnabled);} + } + Fl_Box noiselabel { + label {White Noise} + callback {if (pars->VoicePar[nvoice].Type==0) o->hide(); else o->show();} + xywh {150 415 300 65} labelfont 1 labelsize 50 labelcolor 7 + code0 {if (pars->VoicePar[nvoice].Type==0) o->hide(); else o->show();} + } + } + Fl_Check_Button voiceonbutton { + label On + callback {pars->VoicePar[nvoice].Enabled=(int)o->value(); +if (o->value()==0) voiceparametersgroup->deactivate(); +else voiceparametersgroup->activate(); +o->redraw();} + xywh {60 5 55 35} box THIN_UP_BOX down_box DOWN_BOX labelfont 1 labelsize 16 + code0 {o->value(pars->VoicePar[nvoice].Enabled);} + } + } + } + Function {ADvoiceUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {nvoice=0; +pars=NULL; +oscedit=NULL;} {} + } + Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {} { + code {pars=parameters; +nvoice=nvoice_; +master=master_; +make_window(); +end(); +ADnoteVoiceParameters->show();} {} + } + Function {~ADvoiceUI()} {} { + code {ADnoteVoiceParameters->hide(); +hide(); +if (oscedit!=NULL) { + delete(oscedit); +}; +//delete (ADnoteVoiceParameters);} {} + } + decl {int nvoice;} {} + decl {ADnoteParameters *pars;} {} + decl {OscilEditor *oscedit;} {} + decl {Oscilloscope *osc;} {} + decl {Oscilloscope *oscFM;} {} + decl {Master *master;} {} +} + +class ADnoteUI {: {public PresetsUI_} +} { + Function {make_window()} {private + } { + Fl_Window ADnoteGlobalParameters { + label {ADsynth Global Parameters of the Instrument} + xywh {66 187 535 405} type Double hide + } { + Fl_Group {} { + label FREQUENCY + xywh {5 255 525 115} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + } { + Fl_Group freqenv { + label {ADSynth Global - Frequency Envelope} open + xywh {10 295 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->GlobalPar.FreqEnvelope);} + class EnvelopeUI + } {} + Fl_Counter octave { + label Octave + callback {int k=(int) o->value(); +if (k<0) k+=16; +pars->GlobalPar.PCoarseDetune = k*1024+ + pars->GlobalPar.PCoarseDetune%1024;} + tooltip Octave xywh {450 275 45 15} type Simple labelsize 10 align 1 minimum -8 maximum 7 step 1 textfont 1 textsize 12 + code0 {int k=pars->GlobalPar.PCoarseDetune/1024;if (k>=8) k-=16;} + code2 {o->value(k);} + } + Fl_Counter coarsedet { + label {Coarse det.} + callback {int k=(int) o->value(); +if (k<0) k+=1024; +pars->GlobalPar.PCoarseDetune = k+ + (pars->GlobalPar.PCoarseDetune/1024)*1024;} + tooltip {Coarse Detune} xywh {455 345 60 20} labelsize 10 align 5 minimum -64 maximum 63 step 1 textfont 1 textsize 12 + code0 {int k=pars->GlobalPar.PCoarseDetune%1024;if (k>=512) k-=1024;} + code2 {o->value(k);} + code3 {o->lstep(10);} + } + Fl_Group freqlfo { + label {Frequency LFO } open + xywh {215 295 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->GlobalPar.FreqLfo);} + class LFOUI + } {} + Fl_Slider freq { + callback {pars->GlobalPar.PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {60 275 385 15} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->GlobalPar.PDetune-8192);} + } + Fl_Value_Output detunevalueoutput { + label Detune + callback {o->value(getdetune(pars->GlobalPar.PDetuneType,0,pars->GlobalPar.PDetune));} + xywh {12 275 45 15} labelsize 10 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 10 + code0 {o->value(getdetune(pars->GlobalPar.PDetuneType,0,pars->GlobalPar.PDetune));} + } + Fl_Choice detunetype { + label {Detune Type} + callback {pars->GlobalPar.PDetuneType=(int) o->value()+1; +detunevalueoutput->do_callback();} open + xywh {450 315 75 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");} + code1 {o->value(pars->GlobalPar.PDetuneType-1);} + } {} + Fl_Dial {} { + label relBW + callback {pars->GlobalPar.PBandwidth=(int) o->value(); + +pars->getBandwidthDetuneMultiplier(); + +for (int i=0;i<NUM_VOICES;i++){ + voicelistitem[i]->refreshlist(); +};} + tooltip {Bandwidth - how the relative fine detune of the voice are changed} xywh {500 270 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PBandwidth);} + class WidgetPDial + } + } + Fl_Group {} { + label AMPLITUDE + xywh {5 5 240 250} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + } { + Fl_Value_Slider volume { + label Vol + callback {pars->GlobalPar.PVolume=(int)o->value();} + tooltip Volume xywh {10 30 160 15} type {Horz Knob} box FLAT_BOX labelsize 12 align 8 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PVolume);} + } + Fl_Value_Slider vsns { + label {V.Sns} + callback {pars->GlobalPar.PAmpVelocityScaleFunction=(int) o->value();} + tooltip {Velocity Sensing Function (rightmost to disable)} xywh {10 50 160 15} type {Horz Knob} box FLAT_BOX labelsize 12 align 8 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PAmpVelocityScaleFunction);} + } + Fl_Dial pan { + label Pan + callback {pars->GlobalPar.PPanning=(int) o->value();} + tooltip {Panning (leftmost is Random)} xywh {210 25 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PPanning);} + class WidgetPDial + } + Fl_Dial pstr { + label {P.Str.} + callback {pars->GlobalPar.PPunchStrength=(int) o->value();} + tooltip {Punch Strength} xywh {125 227 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PPunchStrength);} + class WidgetPDial + } + Fl_Dial pt { + label {P.t.} + callback {pars->GlobalPar.PPunchTime=(int) o->value();} + tooltip {Punch Time (duration)} xywh {155 227 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PPunchTime);} + class WidgetPDial + } + Fl_Dial pstc { + label {P.Stc.} + callback {pars->GlobalPar.PPunchStretch=(int) o->value();} + tooltip {Punch Stretch} xywh {185 227 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PPunchStretch);} + class WidgetPDial + } + Fl_Dial pvel { + label {P.Vel.} + callback {pars->GlobalPar.PPunchVelocitySensing=(int) o->value();} + tooltip {Punch Velocity Sensing} xywh {215 227 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PPunchVelocitySensing);} + class WidgetPDial + } + Fl_Group ampenv { + label {ADSynth Global - Amplitude Envelope} open + xywh {10 75 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->GlobalPar.AmpEnvelope);} + class EnvelopeUI + } {} + Fl_Group amplfo { + label {Amplitude LFO } open + xywh {10 145 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->GlobalPar.AmpLfo);} + class LFOUI + } {} + Fl_Check_Button rndgrp { + label {Rnd Grp} + callback {pars->GlobalPar.Hrandgrouping=(int) o->value();} + tooltip {How the Harmonic Amplitude is applied to voices that use the same oscillator} xywh {70 225 40 25} down_box DOWN_BOX labelsize 10 align 148 + code0 {o->value(pars->GlobalPar.Hrandgrouping);} + } + } + Fl_Group {} { + label FILTER + xywh {245 5 285 250} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + } { + Fl_Group filterenv { + label {ADSynth Global - Filter Envelope} open + xywh {250 110 275 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->GlobalPar.FilterEnvelope);} + class EnvelopeUI + } {} + Fl_Group filterlfo { + label {Filter LFO} open + xywh {250 180 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->GlobalPar.FilterLfo);} + class LFOUI + } {} + Fl_Group filterui { + label {ADsynth Global - Filter} open + xywh {250 35 275 75} box FLAT_BOX color 50 align 144 + code0 {o->init(pars->GlobalPar.GlobalFilter,&pars->GlobalPar.PFilterVelocityScale,&pars->GlobalPar.PFilterVelocityScaleFunction);} + class FilterUI + } {} + } + Fl_Check_Button stereo { + label Stereo + callback {pars->GlobalPar.PStereo=(int) o->value();} + xywh {5 220 65 35} box ENGRAVED_BOX down_box DOWN_BOX labelfont 1 labelsize 12 + code0 {o->value(pars->GlobalPar.PStereo);} + } + Fl_Button {} { + label {Show Voice List} + callback {for (int i=0;i<NUM_VOICES;i++){ + voicelistitem[i]->refreshlist(); +} +ADnoteVoiceList->show();} + xywh {180 375 125 25} + } + Fl_Button {} { + label {Show Voice Parameters} + callback {ADnoteVoice->show();} + xywh {5 375 170 25} labelfont 1 + } + Fl_Button {} { + label Close + callback {ADnoteGlobalParameters->hide();} + xywh {470 375 60 25} box THIN_UP_BOX + } + Fl_Button {} { + label Resonance + callback {resui->resonancewindow->redraw(); +resui->resonancewindow->show();} + tooltip Resonance xywh {309 375 86 25} box THIN_UP_BOX + } + Fl_Button {} { + label C + callback {presetsui->copy(pars);} + xywh {405 380 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this);} + xywh {435 380 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + } + Fl_Window ADnoteVoice { + label {ADsynth Voice Parameters} + xywh {53 58 765 560} type Double hide + } { + Fl_Group advoice { + xywh {0 0 760 525} box BORDER_BOX + code0 {o->init(pars,nvoice,master);} + code1 {o->show();} + class ADvoiceUI + } {} + Fl_Button {} { + label {Close Window} + callback {ADnoteVoice->hide();} + xywh {300 530 195 25} box THIN_UP_BOX labelfont 1 + } + Fl_Counter currentvoicecounter { + label {Current Voice} + callback {nvoice=(int)o->value()-1; +advoice->hide(); +ADnoteVoice->remove(advoice); +delete advoice; +advoice=new ADvoiceUI(0,0,765,525); +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 18 + 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 12 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 12 labelcolor 7 + } + } + Fl_Window ADnoteVoiceList { + label {ADsynth Voices list} + xywh {32 266 650 260} type Double hide + } { + Fl_Text_Display {} { + label {No.} + xywh {10 15 30 10} box NO_BOX labelfont 1 labelsize 13 + } + Fl_Text_Display {} { + label Vol + xywh {145 15 30 10} box NO_BOX labelfont 1 labelsize 13 + } + Fl_Text_Display {} { + label Detune + xywh {384 15 25 10} box NO_BOX labelfont 1 labelsize 13 + } + Fl_Text_Display {} { + label Pan + xywh {210 15 30 10} box NO_BOX labelfont 1 labelsize 13 + } + Fl_Text_Display {} { + label {Vib. Depth} + xywh {560 15 30 10} box NO_BOX labelfont 1 labelsize 13 + } + Fl_Text_Display {} { + label {R.} + xywh {245 15 25 10} box NO_BOX labelfont 1 labelsize 13 + } + Fl_Button {} { + label {Hide Voice List} + callback {ADnoteVoiceList->hide();} + xywh {255 237 125 20} + } + Fl_Scroll {} {open + xywh {0 15 640 220} type VERTICAL box THIN_UP_BOX + } { + Fl_Pack {} {open + xywh {0 20 620 210} + code0 {for (int i=0;i<NUM_VOICES;i++){voicelistitem[i]=new ADvoicelistitem(0,0,620,25,"");voicelistitem[i]->init(pars,i,master);}} + } {} + } + } + } + Function {ADnoteUI(ADnoteParameters *parameters,Master *master_)} {} { + code {pars=parameters; +master=master_; +nvoice=0; +resui=new ResonanceUI(pars->GlobalPar.Reson); +make_window();} {} + } + Function {~ADnoteUI()} {} { + code {ADnoteVoiceList->hide(); +ADnoteGlobalParameters->hide(); +ADnoteVoice->hide(); +delete(ADnoteVoiceList); +delete(ADnoteGlobalParameters); +delete(ADnoteVoice); +delete(resui);} {} + } + Function {refresh()} {} { + code {volume->value(pars->GlobalPar.PVolume); +vsns->value(pars->GlobalPar.PAmpVelocityScaleFunction); +pan->value(pars->GlobalPar.PPanning); + +stereo->value(pars->GlobalPar.PStereo); +rndgrp->value(pars->GlobalPar.Hrandgrouping); + +pstr->value(pars->GlobalPar.PPunchStrength); +pt->value(pars->GlobalPar.PPunchTime); +pstc->value(pars->GlobalPar.PPunchStretch); +pvel->value(pars->GlobalPar.PPunchVelocitySensing); + +detunevalueoutput->value(getdetune(pars->GlobalPar.PDetuneType,0,pars->GlobalPar.PDetune)); +freq->value(pars->GlobalPar.PDetune-8192); + +int k=pars->GlobalPar.PCoarseDetune/1024;if (k>=8) k-=16; +octave->value(k); + +detunetype->value(pars->GlobalPar.PDetuneType-1); +k=pars->GlobalPar.PCoarseDetune%1024;if (k>=512) k-=1024; +coarsedet->value(k); +amplfo->refresh(); +freqlfo->refresh(); +filterlfo->refresh(); + +ampenv->refresh(); +freqenv->refresh(); +filterenv->refresh(); +filterui->refresh(); + +for (int i=0;i<NUM_VOICES;i++) voicelistitem[i]->refreshlist(); + +resui->refresh(); +currentvoicecounter->do_callback();} {} + } + decl {ADnoteParameters *pars;} {} + decl {ResonanceUI *resui;} {} + decl {Master *master;} {} + decl {int nvoice;} {} + decl {ADvoicelistitem *voicelistitem[NUM_VOICES];} {} +} diff --git a/muse/synti/zynaddsubfx/UI/BankUI.fl b/muse/synti/zynaddsubfx/UI/BankUI.fl new file mode 100644 index 00000000..90df024d --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/BankUI.fl @@ -0,0 +1,352 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0104 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <string.h>} {public +} + +decl {\#include <FL/Fl_Button.H>} {public +} + +decl {\#include <FL/Fl_File_Chooser.H>} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "../Misc/Bank.h"} {public +} + +decl {\#include "../Misc/Config.h"} {public +} + +class BankProcess_ {} { + Function {process()} {open return_type {virtual void} + } {} + decl {Bank *bank;} {public + } +} + +class BankSlot {: {public Fl_Button,BankProcess_} +} { + Function {BankSlot(int x,int y, int w, int h, const char *label=0):Fl_Button(x,y,w,h,label)} {} { + code {what=NULL; +whatslot=NULL; +nslot=0; +nselected=NULL;} {} + } + Function {handle(int event)} {return_type int + } { + code {if (what==NULL) return(0); +if (Fl::event_inside(this)){ + *what=0;*whatslot=nslot; + if ((event==FL_RELEASE)&&(Fl::event_button()==1))*what=1; + if ((event==FL_RELEASE)&&(Fl::event_button()==3))*what=2; + if (event==FL_PUSH) highlight=1; +}else highlight=0; + +int tmp=Fl_Button::handle(event); +if ((*what!=0) && Fl::event_inside(this)) (bp->*fnc)(); +return(tmp);} {} + } + Function {init(int nslot_, int *what_, int *whatslot_,void (BankProcess_:: *fnc_)(void),BankProcess_ *bp_,Bank *bank_,int *nselected_)} {} { + code {nslot=nslot_; +what=what_; +whatslot=whatslot_; +fnc=fnc_; +bp=bp_; +bank=bank_; +nselected=nselected_; +box(FL_THIN_UP_BOX); +align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP); + +highlight=0; +refresh();} {} + } + Function {refresh()} {} { + code {if (bank->emptyslot(nslot)) { + color(46); +} else { + if (bank->isPADsynth_used(nslot)) color(26); + else color(51); +}; + +if (*nselected==nslot) color(6); + + +label(bank->getnamenumbered(nslot));} {} + } + decl {int *what,*whatslot,nslot,highlight, *nselected;} {} + decl {void (BankProcess_:: *fnc)(void);} {} + decl {BankProcess_ *bp;} {} +} + +class BankUI {: {public BankProcess_} +} { + Function {make_window()} {} { + Fl_Window bankuiwindow { + label Bank + xywh {4 64 785 575} type Double hide + code0 {o->label(bank->bankfiletitle);} + code1 {if (bank->bankfiletitle==NULL) o->label ("Choose a bank from the bank list on the left (or go to settings if to configure the bank location) or choose 'New Bank...' to make a new bank.");} + } { + Fl_Button {} { + label Close + callback {bankuiwindow->hide();} + xywh {705 546 70 24} box THIN_UP_BOX + } + Fl_Group {} { + xywh {5 34 772 491} box ENGRAVED_FRAME + } { + Fl_Pack {} { + xywh {10 39 150 481} box BORDER_BOX + code0 {o->box(FL_NO_BOX);} + code1 {for (int i=0;i<32;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);};} + } {} + Fl_Pack {} { + xywh {163 39 150 481} box BORDER_BOX + code0 {o->box(FL_NO_BOX);} + code1 {for (int i=32;i<64;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);};} + } {} + Fl_Pack {} { + xywh {316 39 150 481} box BORDER_BOX + code0 {o->box(FL_NO_BOX);} + code1 {for (int i=64;i<96;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);};} + } {} + Fl_Pack {} { + xywh {469 39 150 481} box BORDER_BOX + code0 {o->box(FL_NO_BOX);} + code1 {for (int i=96;i<128;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);};} + } {} + Fl_Pack {} { + xywh {622 39 150 481} box BORDER_BOX + code0 {o->box(FL_NO_BOX);} + code1 {for (int i=128;i<160;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);};} + } {} + } + Fl_Group modeselect { + xywh {5 528 425 42} box ENGRAVED_BOX + } { + Fl_Light_Button writebutton { + label WRITE + callback {if (o->value()>0.5) mode=2; +removeselection();} + xywh {116 534 99 30} type Radio box PLASTIC_UP_BOX down_box THIN_DOWN_BOX selection_color 1 labeltype ENGRAVED_LABEL labelfont 1 labelsize 18 + code0 {if (bank->locked()) o->deactivate();} + } + Fl_Light_Button readbutton { + label READ + callback {if (o->value()>0.5) mode=1; +removeselection();} + xywh {11 534 99 30} type Radio box PLASTIC_UP_BOX down_box THIN_DOWN_BOX selection_color 101 labeltype ENGRAVED_LABEL labelfont 1 labelsize 18 + code0 {o->value(1);} + } + Fl_Light_Button clearbutton { + label CLEAR + callback {if (o->value()>0.5) mode=3; +removeselection();} + xywh {221 534 99 30} type Radio box PLASTIC_UP_BOX down_box THIN_DOWN_BOX selection_color 0 labeltype ENGRAVED_LABEL labelfont 1 labelsize 18 + code0 {if (bank->locked()) o->deactivate();} + } + Fl_Light_Button swapbutton { + label SWAP + callback {if (o->value()>0.5) mode=4; +removeselection();} + xywh {325 534 99 30} type Radio box PLASTIC_UP_BOX down_box THIN_DOWN_BOX selection_color 227 labeltype ENGRAVED_LABEL labelfont 1 labelsize 18 + code0 {if (bank->locked()) o->deactivate();} + } + } + Fl_Button {} { + label {New Bank...} + callback {const char *dirname; + +dirname=fl_input("New empty Bank:"); +if (dirname==NULL) return; + + +int result=bank->newbank(dirname); + +if (result!=0) fl_alert("Error: Could not make a new bank (directory).."); + +refreshmainwindow();} + xywh {685 5 93 25} box PLASTIC_UP_BOX labelfont 1 labelsize 12 align 128 + } + Fl_Check_Button {} { + label {auto close} + callback {config.cfg.BankUIAutoClose=(int) o->value();} + tooltip {automatically close the bank window if the instrument is loaded} xywh {705 529 60 15} down_box DOWN_BOX labelsize 10 + code0 {o->value(config.cfg.BankUIAutoClose);} + } + Fl_Choice banklist { + callback {int n=o->value(); +char *dirname=bank->banks[n].dir; +if (dirname==NULL) return; + +if (bank->loadbank(dirname)==2) + fl_alert("Error: Could not load the bank from the directory\\n%s.",dirname); +for (int i=0;i<BANK_SIZE;i++) bs[i]->refresh(); +refreshmainwindow();} open + xywh {5 8 220 20} down_box BORDER_BOX labelfont 1 align 0 textfont 1 textsize 12 + } {} + Fl_Button {} { + label {Refresh bank list} + callback {rescan_for_banks(); +banklist->value(0);} + tooltip {Refresh the bank list (rescan)} xywh {230 8 105 20} box THIN_UP_BOX color 50 labelsize 12 + } + Fl_Check_Button {} { + label {Show PADsynth status} + callback {config.cfg.CheckPADsynth=(int) o->value(); +refreshmainwindow();} + xywh {435 530 150 15} down_box DOWN_BOX labelsize 12 + code0 {o->value(config.cfg.CheckPADsynth);} + } + } + } + Function {BankUI(Master *master_,int *npart_)} {} { + code {fnc=&BankProcess_::process; +master=master_; +npart=npart_; +bank=&master_->bank; +what=0; +nselected=-1; +make_window(); +mode=1;} {} + } + Function {~BankUI()} {return_type virtual + } { + code {bankuiwindow->hide(); +delete(bankuiwindow);} {} + } + Function {show()} {} { + code {bankuiwindow->show(); +simplesetmode(config.cfg.UserInterfaceMode==2);} {} + } + Function {hide()} {} { + code {bankuiwindow->hide();} {} + } + Function {init(Fl_Valuator *cbwig_)} {} { + code {cbwig=cbwig_; +rescan_for_banks();} {} + } + Function {process()} {return_type void + } { + code {int slot=this->slot; + +if ((what==2)&&(bank->emptyslot(slot)==0)&&(mode!=4)) {//Rename slot + const char *tmp=fl_input("Slot (instrument) name:",(const char *)bank->getname(slot)); + if (tmp!=NULL) bank->setname(slot,tmp,-1); + bs[slot]->refresh(); +}; + +if ((what==1)&&(mode==1)&&(!bank->emptyslot(slot))){//Reads from slot + pthread_mutex_lock(&master->mutex); + bank->loadfromslot(slot,master->part[*npart]); + pthread_mutex_unlock(&master->mutex); + master->part[*npart]->applyparameters(); + snprintf((char *)master->part[*npart]->Pname,PART_MAX_NAME_LEN,"%s",bank->getname(slot)); + cbwig->do_callback(); + + if (config.cfg.BankUIAutoClose!=0) + bankuiwindow->hide(); + +}; + +if ((what==1)&&(mode==2)){//save(write) to slot + if (!bank->emptyslot(slot)){ + if (!fl_ask("Overwrite the slot no. %d ?",slot+1)) goto nooverwriteslot; + }; + pthread_mutex_lock(&master->mutex); + bank->savetoslot(slot,master->part[*npart]); + pthread_mutex_unlock(&master->mutex); + + bs[slot]->refresh(); + mode=1;readbutton->value(1);writebutton->value(0); + nooverwriteslot:; +}; + + + +if ((what==1)&&(mode==3)&&(!bank->emptyslot(slot))){//Clears the slot + if (fl_ask("Clear the slot no. %d ?",slot+1)){ + bank->clearslot(slot); + bs[slot]->refresh(); + }; +}; + +if (mode==4){//swap + bool done=false; + if ((what==1)&&(nselected>=0)){ + bank->swapslot(nselected,slot); + int ns=nselected; + nselected=-1; + bs[slot]->refresh(); + bs[ns]->refresh(); + done=true; + }; + if (((nselected<0)||(what==2))&&(!done)){ + int ns=nselected; + nselected=slot; + if (ns>0) bs[ns]->refresh(); + bs[slot]->refresh(); + }; +}; +if (mode!=4) refreshmainwindow();} {selected + } + } + Function {refreshmainwindow()} {} { + code {bankuiwindow->label(bank->bankfiletitle); +mode=1;readbutton->value(1);writebutton->value(0);clearbutton->value(0);swapbutton->value(0); +nselected=-1; +if (bank->locked()){ + writebutton->deactivate(); + clearbutton->deactivate(); + swapbutton->deactivate(); +} else { + writebutton->activate(); + clearbutton->activate(); + swapbutton->activate(); +}; +for (int i=0;i<BANK_SIZE;i++) bs[i]->refresh();} {} + } + Function {removeselection()} {} { + code {if (nselected>=0) { + int ns=nselected; + nselected=-1; + bs[ns]->refresh(); +};} {} + } + Function {rescan_for_banks()} {} { + code {banklist->clear(); +banklist->add(" "); +bank->rescanforbanks(); + +for (int i=1;i<MAX_NUM_BANKS;i++) { + if (bank->banks[i].name!=NULL) banklist->add(bank->banks[i].name); +};} {} + } + Function {simplesetmode(bool beginnerui)} {} { + code {readbutton->value(1); +mode=1; +removeselection(); +if (beginnerui) modeselect->hide(); + else modeselect->show();} {} + } + decl {BankSlot *bs[BANK_SIZE];} {} + decl {int slot,what;//"what"=what button is pressed} {} + decl {int mode,*npart,nselected;} {} + decl {Master *master;} {} + decl {void (BankProcess_::* fnc)(void);} {} + decl {Fl_Valuator *cbwig;} {public + } +} diff --git a/muse/synti/zynaddsubfx/UI/ConfigUI.fl b/muse/synti/zynaddsubfx/UI/ConfigUI.fl new file mode 100644 index 00000000..c130259e --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/ConfigUI.fl @@ -0,0 +1,443 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <math.h>} {public +} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include <FL/Fl_File_Chooser.H>} {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Misc/Dump.h"} {public +} + +decl {extern Dump dump;} {public +} + +class ConfigUI {} { + Function {make_window()} {} { + Fl_Window configwindow { + label {ZynAddSubFX Settings} + callback {writebankcfg(); +o->hide();} + xywh {88 313 510 340} type Double hide + } { + Fl_Tabs {} { + xywh {5 5 500 305} + } { + Fl_Group {} { + label {Main settings} + xywh {5 25 500 285} + } { + Fl_Group {} { + label {Sample Rate} + xywh {15 45 165 30} box ENGRAVED_FRAME + } { + Fl_Choice {} { + callback {if ((int)o->value()==0) samplerateinput->activate(); + else samplerateinput->deactivate(); + +int samplerates[8]={44100,16000,22050,32000,44100,48000,88200,96000}; +config.cfg.SampleRate=samplerates[(int)o->value()]; + +setsamplerateinput();} + xywh {20 50 85 20} down_box BORDER_BOX textsize 10 + code0 {o->value(getsamplerateorder());} + } { + menuitem {} { + label Custom + xywh {10 10 100 20} labelfont 1 + } + menuitem {} { + label 16000Hz + xywh {30 30 100 20} labelfont 1 + } + menuitem {} { + label 22050Hz + xywh {20 20 100 20} labelfont 1 + } + menuitem {} { + label 32000Hz + xywh {30 30 100 20} labelfont 1 + } + menuitem {} { + label 44100Hz + xywh {40 40 100 20} labelfont 1 + } + menuitem {} { + label 48000Hz + xywh {50 50 100 20} labelfont 1 + } + menuitem {} { + label 88200Hz + xywh {60 60 100 20} labelfont 1 + } + menuitem {} { + label 96000Hz + xywh {70 70 100 20} labelfont 1 + } + } + Fl_Input samplerateinput { + callback {char *tmp; +config.cfg.SampleRate=strtoul(o->value(),&tmp,10);} + xywh {115 50 60 20} type Int textfont 1 + code0 {setsamplerateinput();} + code1 {if (getsamplerateorder()!=0) o->deactivate();} + } + } + Fl_Input {} { + label {Buffer Size} + callback {char *tmp; +config.cfg.SoundBufferSize=strtoul(o->value(),&tmp,10);} + tooltip {Internal Sound Buffer Size (samples)} xywh {190 45 60 20} type Int labelsize 12 align 129 textfont 1 + code0 {char *tmpbuf=new char[100];o->cut(0,o->maximum_size());} + code1 {snprintf(tmpbuf,100,"%d",config.cfg.SoundBufferSize);o->insert(tmpbuf);} + code2 {delete(tmpbuf);} + } + Fl_Light_Button {} { + label {Swap Stereo } + callback {config.cfg.SwapStereo=(int) o->value();} + xywh {20 80 85 20} box THIN_UP_BOX labelsize 11 + code0 {o->value(config.cfg.SwapStereo);} + } + Fl_Choice {} { + label OscilSize + callback {config.cfg.OscilSize=128<<o->value();} + tooltip {ADSynth Oscillator Size (samples)} xywh {175 80 75 20} down_box BORDER_BOX labelfont 1 labelsize 12 textsize 10 + code0 {o->value( (int) (log(config.cfg.OscilSize/128.0-1.0)/log(2)) +1);} + } { + menuitem {} { + label 128 + xywh {25 25 100 20} labelfont 1 + } + menuitem {} { + label 256 + xywh {35 35 100 20} labelfont 1 + } + menuitem {} { + label 512 + xywh {45 45 100 20} labelfont 1 + } + menuitem {} { + label 1024 + xywh {45 45 100 20} labelfont 1 + } + menuitem {} { + label 2048 + xywh {55 55 100 20} labelfont 1 + } + menuitem {} { + label 4096 + xywh {55 55 100 20} labelfont 1 + } + menuitem {} { + label 8192 + xywh {65 65 100 20} labelfont 1 + } + menuitem {} { + label 16384 + xywh {75 75 100 20} labelfont 1 + } + } + Fl_Box {} { + label {Most settings has effect only after ZynAddSubFX is restarted.} + xywh {15 275 235 30} labelfont 1 labelsize 12 align 128 + } + Fl_Box {} { + label {Read the Readme.txt for other settings} + xywh {10 255 240 20} labelfont 1 labelsize 12 align 128 + } + Fl_Group {} { + xywh {15 125 230 85} box ENGRAVED_BOX + } { + Fl_File_Input {} { + label {Dump File} + callback {snprintf(config.cfg.DumpFile,config.maxstringsize,"%s",o->value());} + xywh {20 170 220 35} align 5 + code0 {o->insert(config.cfg.DumpFile);} + } + Fl_Check_Button {} { + label {Dump notes} + callback {config.cfg.DumpNotesToFile=(int) o->value(); +dump.startnow();//this has effect only if this option was disabled} + xywh {20 130 100 20} down_box DOWN_BOX + code0 {o->value(config.cfg.DumpNotesToFile);} + } + Fl_Check_Button {} { + label Append + callback {config.cfg.DumpAppend=(int) o->value();} + xywh {160 130 80 20} down_box DOWN_BOX + code0 {o->value(config.cfg.DumpAppend);} + } + } + Fl_Group {} { + xywh {255 45 245 260} box ENGRAVED_FRAME + } { + Fl_Box {} { + label {Note: Not all the following settings are used (this depends on the operating system, etc..)} + xywh {260 50 235 45} labelfont 1 labelsize 12 align 128 + } + Fl_Group {} { + label Linux + xywh {260 110 235 115} box ENGRAVED_BOX labelfont 1 labelsize 16 align 5 + } { + Fl_File_Input {} { + label {OSS Sequencer Device (/dev/...)} + callback {snprintf(config.cfg.LinuxOSSSeqInDev,config.maxstringsize,"%s",o->value());} + xywh {265 180 225 35} align 5 + code0 {o->insert(config.cfg.LinuxOSSSeqInDev);} + } + Fl_File_Input {} { + label {OSS Wave Out Device (/dev/...)} + callback {snprintf(config.cfg.LinuxOSSWaveOutDev,config.maxstringsize,"%s",o->value());} + xywh {265 130 225 35} align 5 + code0 {o->insert(config.cfg.LinuxOSSWaveOutDev);} + } + } + Fl_Group {} { + label Windows + xywh {260 250 235 50} box ENGRAVED_BOX labelfont 1 labelsize 16 align 5 + } { + Fl_Counter {} { + label {Midi In Dev} + callback {config.cfg.WindowsMidiInId=(int) o->value(); +midiinputnamebox->label(config.winmididevices[config.cfg.WindowsMidiInId].name);} + xywh {270 270 65 20} type Simple labelsize 12 align 1 minimum 0 maximum 100 step 1 + code0 {o->maximum(config.winmidimax-1);} + code1 {o->value(config.cfg.WindowsMidiInId);} + } + Fl_Box midiinputnamebox { + label {Midi input device name} + xywh {340 260 150 35} labelfont 1 labelsize 12 align 212 + code0 {o->label(config.winmididevices[config.cfg.WindowsMidiInId].name);} + } + } + } + Fl_Counter {} { + label {XML compression level} + callback {config.cfg.GzipCompression=(int) o->value();} + tooltip {gzip compression level (0 - uncompressed)} xywh {20 215 65 15} type Simple labelsize 12 align 8 minimum 0 maximum 9 step 1 + code0 {o->value(config.cfg.GzipCompression);} + } + Fl_Choice {} { + label {PADsynth Interpolation} + callback {config.cfg.Interpolation=(int) o->value();} + xywh {175 105 75 15} down_box BORDER_BOX labelsize 11 textsize 12 + code0 {o->value(config.cfg.Interpolation);} + } { + menuitem {} { + label {Linear(fast)} + xywh {0 0 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {Cubic(slow)} + xywh {10 10 100 20} labelfont 1 labelsize 10 + } + } + Fl_Choice {} { + label {Virtual Keyboard Layout} + callback {config.cfg.VirKeybLayout=(int) o->value();;} open selected + xywh {155 235 85 20} down_box BORDER_BOX labelsize 13 textfont 1 textsize 12 + code0 {o->value(config.cfg.VirKeybLayout);} + } { + menuitem {} { + label { } + xywh {5 5 100 20} labelfont 1 labelsize 13 deactivate + } + menuitem {} { + label QWERTY + xywh {15 15 100 20} labelfont 1 labelsize 13 + } + menuitem {} { + label Dvorak + xywh {25 25 100 20} labelfont 1 labelsize 13 + } + } + } + Fl_Group {} { + label {Bank root dirs} + xywh {5 25 500 285} hide + } { + Fl_Browser rootsbrowse { + callback {activatebutton_rootdir(o->value()!=0);} + xywh {15 35 485 220} type Hold + } + Fl_Button {} { + label {Add root directory...} + callback {const char *dirname; +dirname=fl_dir_chooser("Add a root directory for banks:",NULL,0); +if (dirname==NULL) return; + +rootsbrowse->add(dirname);} + xywh {15 265 80 35} box THIN_UP_BOX align 128 + } + Fl_Button removerootdirbutton { + label {Remove root dir...} + callback {if (rootsbrowse->value()!=0) { + rootsbrowse->remove(rootsbrowse->value()); +}; +activatebutton_rootdir(false);} + xywh {105 265 80 35} box THIN_UP_BOX align 128 + code0 {o->deactivate();} + } + Fl_Button makedefaultrootdirbutton { + label {Make default} + callback {int n=rootsbrowse->value(); + +if (n!=0) { + rootsbrowse->move(1,n); + rootsbrowse->value(1); + rootsbrowse->redraw(); +}; +activatebutton_rootdir(true);} + xywh {190 265 80 35} box THIN_UP_BOX align 128 + code0 {o->deactivate();} + } + } + Fl_Group {} { + label {Presets dirs} + xywh {5 25 500 285} hide + } { + Fl_Browser presetbrowse { + callback {activatebutton_presetdir(o->value()!=0);} + xywh {15 35 485 220} type Hold + } + Fl_Button {} { + label {Add preset directory...} + callback {const char *dirname; +dirname=fl_dir_chooser("Add a preset directory :",NULL,0); +if (dirname==NULL) return; + +presetbrowse->add(dirname);} + xywh {15 265 80 35} box THIN_UP_BOX align 128 + } + Fl_Button removepresetbutton { + label {Remove preset dir...} + callback {if (presetbrowse->value()!=0) { + presetbrowse->remove(presetbrowse->value()); +}; +activatebutton_presetdir(false);} + xywh {105 265 80 35} box THIN_UP_BOX align 128 + code0 {o->deactivate();} + } + Fl_Button makedefaultpresetbutton { + label {Make default} + callback {int n=presetbrowse->value(); + +if (n!=0) { + presetbrowse->move(1,n); + presetbrowse->value(1); + presetbrowse->redraw(); +}; +activatebutton_presetdir(true);} + xywh {190 265 80 35} box THIN_UP_BOX align 128 + code0 {o->deactivate();} + } + } + } + Fl_Button {} { + label Close + callback {configwindow->hide(); +writebankcfg(); +writepresetcfg();} + xywh {200 315 105 20} box THIN_UP_BOX + } + } + } + Function {ConfigUI()} {} { + code {make_window(); +readbankcfg(); +readpresetcfg();} {} + } + Function {activatebutton_rootdir(bool active)} {} { + code {if (active) { + removerootdirbutton->activate(); + makedefaultrootdirbutton->activate(); +}else{ + removerootdirbutton->deactivate(); + makedefaultrootdirbutton->deactivate(); +};} {} + } + Function {activatebutton_presetdir(bool active)} {} { + code {if (active) { + removepresetbutton->activate(); + makedefaultpresetbutton->activate(); +}else{ + removepresetbutton->deactivate(); + makedefaultpresetbutton->deactivate(); +};} {} + } + Function {readbankcfg()} {} { + code {rootsbrowse->clear(); + +for (int i=0;i<MAX_BANK_ROOT_DIRS;i++){ + if (config.cfg.bankRootDirList[i]!=NULL) rootsbrowse->add(config.cfg.bankRootDirList[i]); +};} {} + } + Function {writebankcfg()} {} { + code {config.clearbankrootdirlist(); + +for (int n=0;n<rootsbrowse->size();n++){ + config.cfg.bankRootDirList[n]=new char [MAX_STRING_SIZE]; + strncpy(config.cfg.bankRootDirList[n],rootsbrowse->text(n+1),MAX_STRING_SIZE); +};} {} + } + Function {readpresetcfg()} {} { + code {presetbrowse->clear(); + +for (int i=0;i<MAX_BANK_ROOT_DIRS;i++){ + if (config.cfg.presetsDirList[i]!=NULL) presetbrowse->add(config.cfg.presetsDirList[i]); +};} {} + } + Function {writepresetcfg()} {} { + code {config.clearpresetsdirlist(); + +for (int n=0;n<presetbrowse->size();n++){ + config.cfg.presetsDirList[n]=new char [MAX_STRING_SIZE]; + strncpy(config.cfg.presetsDirList[n],presetbrowse->text(n+1),MAX_STRING_SIZE); +};} {} + } + Function {getsamplerateorder()} {return_type int + } { + code {int smpr=config.cfg.SampleRate; +int order=0; +switch(smpr){ + case 16000:order=1;break; + case 22050:order=2;break; + case 32000:order=3;break; + case 44100:order=4;break; + case 48000:order=5;break; + case 88200:order=6;break; + case 96000:order=7;break; + default:order=0;break; +}; +return(order);} {} + } + Function {setsamplerateinput()} {return_type void + } { + code {char *tmpbuf=new char[100]; +samplerateinput->cut(0,samplerateinput->maximum_size()); +snprintf(tmpbuf,100,"%d",config.cfg.SampleRate); +samplerateinput->insert(tmpbuf); +delete (tmpbuf);} {} + } + Function {show()} {} { + code {configwindow->show();} {} + } +} diff --git a/muse/synti/zynaddsubfx/UI/EffUI.fl b/muse/synti/zynaddsubfx/UI/EffUI.fl new file mode 100644 index 00000000..e3ad8fc9 --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/EffUI.fl @@ -0,0 +1,2310 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0104 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <string.h>} {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EnvelopeUI.h"} {public +} + +decl {\#include "FilterUI.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Effects/EffectMgr.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +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; +maxdB=30;} {} + } + Function {init(EffectMgr *eff_)} {} { + code {eff=eff_; +oldx=-1; +khzval=-1;} {} + } + Function {draw_freq_line(REALTYPE freq,int type)} {} { + code {fl_color(FL_GRAY); +REALTYPE freqx=getfreqpos(freq); +switch(type){ + case 0:if (active_r()) fl_color(FL_WHITE); + else fl_color(205,205,205); + fl_line_style(FL_SOLID); + break; + case 1:fl_line_style(FL_DOT);break; + case 2:fl_line_style(FL_DASH);break; +}; + + +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(x()+(int) (freqx*w()),y(), + x()+(int) (freqx*w()),y()+h());} {} + } + Function {draw()} {} { + code {int ox=x(),oy=y(),lx=w(),ly=h(),i,iy,oiy; +REALTYPE freqx; + +if (active_r()) fl_color(0,70,150); + else fl_color(80,120,160); +fl_rectf(ox,oy,lx,ly); + + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +freqx=getfreqpos(1000.0); +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(ox+(int) (freqx*lx),oy, + ox+(int) (freqx*lx),oy+ly); + +for (i=1;i<10;i++){ + if(i==1){ + draw_freq_line(i*100.0,0); + draw_freq_line(i*1000.0,0); + }else + if (i==5){ + draw_freq_line(i*10.0,2); + draw_freq_line(i*100.0,2); + draw_freq_line(i*1000.0,2); + }else{ + draw_freq_line(i*10.0,1); + draw_freq_line(i*100.0,1); + draw_freq_line(i*1000.0,1); + }; +}; + +draw_freq_line(10000.0,0); +draw_freq_line(20000.0,1); + + +fl_line_style(FL_DOT); +int GY=6;if (ly<GY*3) GY=-1; +for (i=1;i<GY;i++){ + int tmp=(int)(ly/(REALTYPE)GY*i); + fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp); +}; + + +//draw the frequency response +if (active_r()) fl_color(FL_YELLOW); + else fl_color(200,200,80); +fl_line_style(FL_SOLID); +oiy=getresponse(ly,getfreqx(0.0)); +for (i=1;i<lx;i++){ + REALTYPE frq=getfreqx(i/(REALTYPE) lx); + if (frq>SAMPLE_RATE/2) break; + iy=getresponse(ly,frq); + if ((oiy>=0) && (oiy<ly) && + (iy>=0) && (iy<ly) ) + fl_line(ox+i-1,oy+ly-oiy,ox+i,oy+ly-iy); + oiy=iy; +};} {} + } + Function {getresponse(int maxy,REALTYPE freq)} {return_type int + } { + code {REALTYPE dbresp=eff->getEQfreqresponse(freq); +int idbresp=(int) ((dbresp/maxdB+1.0)*maxy/2.0); + + +//fprintf(stderr,"%.5f\\n",(dbresp/maxdB+1.0)*maxy/2.0); + + +return(idbresp);} {} + } + Function {getfreqx(REALTYPE x)} {return_type REALTYPE + } { + code {if (x>1.0) x=1.0; +return(20.0*pow(1000.0,x));} {} + } + Function {getfreqpos(REALTYPE freq)} {return_type REALTYPE + } { + code {if (freq<0.00001) freq=0.00001; +return(log(freq/20.0)/log(1000.0));} {} + } + decl {int oldx,oldy;} {} + decl {REALTYPE khzval;} {public + } + decl {EffectMgr *eff;} {} + decl {int maxdB;} {} +} + +class EffUI {: {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; +filterwindow=NULL;} {} + } + Function {~EffUI()} {} { + code {effnullwindow->hide();//delete (effnullwindow); +effreverbwindow->hide();//delete (effreverbwindow); +effechowindow->hide();//delete (effechowindow); +effchoruswindow->hide();//delete (effchoruswindow); +effphaserwindow->hide();//delete (effphaserwindow); +effalienwahwindow->hide();//delete (effalienwahwindow); +effdistorsionwindow->hide();//delete (effdistorsionwindow); +effeqwindow->hide();//delete (effeqwindow); +effdynamicfilterwindow->hide();//delete (effdynamicfilterwindow); + +if (filterwindow!=NULL){ + filterwindow->hide(); + delete(filterwindow); +};} {} + } + Function {make_null_window()} {} { + Fl_Window effnullwindow { + xywh {287 379 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label {No Effect} + xywh {120 35 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 labelcolor 43 align 8 + } + } + } + Function {make_reverb_window()} {} { + Fl_Window effreverbwindow { + xywh {262 421 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label {Reverb } + xywh {275 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Choice revp { + label Preset + callback {eff->changepreset((int)o->value()); + +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Cathedral 1} + xywh {10 10 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Cathedral 2} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Cathedral 3} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Hall 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Hall 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Room 1} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Room 2} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label Basement + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label Tunnel + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Echoed 1} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Echoed 2} + xywh {110 110 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Very Long 1} + xywh {120 120 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Very Long 2} + xywh {130 130 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + 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 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label Random + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label Freeverb + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Dial revp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial revp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial revp2 { + label Time + callback {eff->seteffectpar(2,(int) o->value());} + xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial revp3 { + label {I.del} + callback {eff->seteffectpar(3,(int) o->value());} + xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial revp4 { + label {I.delfb} + callback {eff->seteffectpar(4,(int) o->value());} + xywh {155 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 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 12 when 4 maximum 127 deactivate + class WidgetPDial + } + Fl_Dial revp6 { + label {E/R} + callback {eff->seteffectpar(6,(int) o->value());} + xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 deactivate + class WidgetPDial + } + Fl_Dial revp7 { + label LPF + callback {eff->seteffectpar(7,(int) o->value());} + xywh {270 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial revp8 { + label HPF + callback {eff->seteffectpar(8,(int) o->value());} + xywh {305 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial revp9 { + label Damp + callback {eff->seteffectpar(9,(int) o->value());} + xywh {340 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 minimum 64 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial revp11 { + label {R.S.} + callback {int x=64; +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 + class WidgetPDial + } + } + } + Function {make_echo_window()} {} { + Fl_Window effechowindow { + xywh {178 394 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice echop { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {11 15 95 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Echo 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Echo 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Echo 3} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Simple Echo} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label Canyon + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Panning Echo 1} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Panning Echo 2} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Panning Echo 3} + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Feedback Echo} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Echo + xywh {295 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial echop0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial echop1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial echop2 { + label Delay + callback {eff->seteffectpar(2,(int) o->value());} + xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial echop3 { + label {LRdl.} + callback {eff->seteffectpar(3,(int) o->value());} + xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial echop4 { + label {LRc.} + callback {eff->seteffectpar(4,(int) o->value());} + xywh {155 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial echop5 { + label {Fb.} + callback {eff->seteffectpar(5,(int) o->value());} + xywh {195 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial echop6 { + label Damp + callback {eff->seteffectpar(6,(int) o->value());} + xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + } + } + Function {make_chorus_window()} {} { + Fl_Window effchoruswindow { + xywh {210 263 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice chorusp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Chorus 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Chorus 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Chorus 3} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Celeste 1} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Celeste 2} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Flange 1} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Flange 2} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Flange 3} + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Flange 4} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Flange 5} + xywh {110 110 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Chorus + xywh {265 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial chorusp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp3 { + label Rnd + callback {eff->seteffectpar(3,(int) o->value());} + xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp5 { + label {St.df} + callback {eff->seteffectpar(5,(int) o->value());} + xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp7 { + label Delay + callback {eff->seteffectpar(7,(int) o->value());} + xywh {270 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp8 { + label Fb + callback {eff->seteffectpar(8,(int) o->value());} + xywh {305 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp9 { + label {L/R} + callback {eff->seteffectpar(9,(int) o->value());} + xywh {340 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Check_Button {} { + label Flange + callback {eff->seteffectpar(10,(int) o->value());} + xywh {120 10 55 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10 hide deactivate + code0 {o->value(eff->geteffectpar(10));} + } + Fl_Check_Button chorusp11 { + label Substract + callback {eff->seteffectpar(11,(int) o->value());} + xywh {185 10 70 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10 + } + Fl_Choice chorusp4 { + label {LFO type} + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {LFO function} xywh {155 50 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8 + } { + menuitem {} { + label SINE + xywh {15 15 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label TRI + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + } + } + } + Function {make_phaser_window()} {} { + Fl_Window effphaserwindow { + xywh {197 313 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice phaserp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Phaser 1} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Phaser 2} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Phaser 3} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Phaser 4} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Phaser 5} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Phaser 6} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Phaser + xywh {275 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial phaserp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp3 { + label Rnd + callback {eff->seteffectpar(3,(int) o->value());} + xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp5 { + label {St.df} + callback {eff->seteffectpar(5,(int) o->value());} + xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp7 { + label Fb + callback {eff->seteffectpar(7,(int) o->value());} + xywh {270 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp9 { + label {L/R} + callback {eff->seteffectpar(9,(int) o->value());} + xywh {345 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Check_Button phaserp10 { + label Substract + callback {eff->seteffectpar(10,(int) o->value());} + xywh {185 10 70 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10 + } + Fl_Choice phaserp4 { + label {LFO type} + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {LFO function} xywh {155 50 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8 + } { + menuitem {} { + label SINE + xywh {15 15 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label TRI + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + } + Fl_Counter phaserp8 { + label Stages + callback {eff->seteffectpar(8,(int) o->value());} + xywh {305 55 35 15} type Simple labelfont 1 labelsize 12 minimum 0 maximum 127 step 1 + code0 {o->range(1,MAX_PHASER_STAGES);} + } + Fl_Dial phaserp11 { + label Phase + callback {eff->seteffectpar(11,(int) o->value());} + xywh {155 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127 + class WidgetPDial + } + } + } + Function {make_alienwah_window()} {} { + Fl_Window effalienwahwindow { + xywh {230 283 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice awp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Alienwah 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Alienwah 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Alienwah 3} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Alienwah 4} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label AlienWah + xywh {245 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial awp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial awp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial awp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial awp3 { + label Rnd + callback {eff->seteffectpar(3,(int) o->value());} + xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial awp5 { + label {St.df} + callback {eff->seteffectpar(5,(int) o->value());} + xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial awp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial awp7 { + label Fb + callback {eff->seteffectpar(7,(int) o->value());} + xywh {270 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial awp9 { + label {L/R} + callback {eff->seteffectpar(9,(int) o->value());} + xywh {345 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Choice awp4 { + label {LFO type} + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {LFO function} xywh {155 50 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8 + } { + menuitem {} { + label SINE + xywh {15 15 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label TRI + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial awp10 { + label Phase + callback {eff->seteffectpar(10,(int) o->value());} + xywh {160 5 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Counter awp8 { + label Delay + callback {eff->seteffectpar(8,(int) o->value());} + xywh {305 55 35 15} type Simple labelfont 1 labelsize 12 minimum 0 maximum 127 step 1 + code0 {o->range(1,MAX_ALIENWAH_DELAY);} + } + } + } + Function {make_distorsion_window()} {} { + Fl_Window effdistorsionwindow { + xywh {259 186 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice distp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {11 15 95 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Overdrive 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Overdrive 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {A. Exciter 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {A. Exciter 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Guitar Amp} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label Quantisize + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Distortion + xywh {230 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial distp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial distp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial distp2 { + label {LRc.} + callback {eff->seteffectpar(2,(int) o->value());} + xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial distp3 { + label Drive + callback {eff->seteffectpar(3,(int) o->value());} + xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial distp4 { + label Level + callback {eff->seteffectpar(4,(int) o->value());} + xywh {155 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial distp7 { + label LPF + callback {eff->seteffectpar(7,(int) o->value());} + xywh {285 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial distp8 { + label HPF + callback {eff->seteffectpar(8,(int) o->value());} + xywh {320 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Choice distp5 { + label Type + callback {eff->seteffectpar(5,(int) o->value());} + xywh {190 50 60 20} box UP_BOX down_box BORDER_BOX labelfont 1 labelsize 12 align 2 textsize 10 + } { + menuitem {} { + label Atan + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Asym1 + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pow + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sine + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Qnts + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Zigzg + xywh {105 105 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Lmt + xywh {115 115 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LmtU + xywh {125 125 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LmtL + xywh {135 135 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label ILmt + xywh {147 147 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Clip + xywh {157 157 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Asym2 + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pow2 + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sgm + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + } + Fl_Check_Button distp6 { + label {Neg.} + callback {eff->seteffectpar(6,(int) o->value());} + xywh {260 55 15 15} down_box DOWN_BOX labelfont 1 labelsize 12 align 2 + } + Fl_Check_Button distp9 { + label {St.} + callback {eff->seteffectpar(9,(int) o->value());} + tooltip Stereo xywh {355 60 15 15} down_box DOWN_BOX labelfont 1 labelsize 12 align 2 + } + Fl_Check_Button distp10 { + label PF + callback {eff->seteffectpar(10,(int) o->value());} + tooltip {Applies the filters(before or after) the distorsion} xywh {355 44 15 15} down_box DOWN_BOX labelfont 1 labelsize 12 align 1 + } + } + } + Function {make_eq_window()} {} { + Fl_Window effeqwindow { + xywh {258 307 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label EQ + xywh {320 10 15 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial eqp0 { + label Gain + callback {eff->seteffectpar(0,(int) o->value()); +eqgraph->redraw();} + xywh {10 35 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Counter bandcounter { + label {B.} + callback {eqband=(int) o->value(); +int npb=eqband*5+10; + +int type=eff->geteffectpar(npb); +typechoice->value(type); + +if (type>6) gaindial->activate(); + else gaindial->deactivate(); + +if (type==0) bandgroup->deactivate(); +else bandgroup->activate(); + +int freq=eff->geteffectpar(npb+1); +freqdial->value(freq); + +int gain=eff->geteffectpar(npb+2); +gaindial->value(gain); + +int q=eff->geteffectpar(npb+3); +qdial->value(q); + +int dbl=eff->geteffectpar(npb+4); +stagescounter->value(dbl);} + tooltip {Band no.} xywh {240 20 45 15} type Simple labelfont 1 labelsize 12 align 1 minimum 0 maximum 1 step 1 textfont 1 textsize 12 + code0 {o->bounds(0,MAX_EQ_BANDS-1);} + } + Fl_Group bandgroup { + xywh {245 40 130 50} box ENGRAVED_FRAME + code0 {if (eff->geteffectpar(10)==0) o->deactivate();} + } { + Fl_Dial freqdial { + label Freq + callback {int np=eqband*5+11; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + xywh {250 50 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 + class WidgetPDial + } + Fl_Dial gaindial { + label Gain + callback {int np=eqband*5+12; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + xywh {280 50 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial qdial { + label Q + callback {int np=eqband*5+13; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + xywh {310 50 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 + class WidgetPDial + } + Fl_Counter stagescounter { + label {St.} + callback {int np=eqband*5+14; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + tooltip {Additional filter stages} xywh {340 60 30 15} type Simple labelfont 1 labelsize 10 minimum 1 maximum 127 step 1 textfont 1 textsize 12 + code0 {o->bounds(0,MAX_FILTER_STAGES-1);} + } + } + Fl_Choice typechoice { + label {T.} + callback {int np=eqband*5+10; +eff->seteffectpar(np,(int) o->value()); +bandcounter->do_callback(); +eqgraph->redraw();} + tooltip Type xywh {290 20 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 1 when 6 textsize 10 + } { + menuitem {} { + label OFF + xywh {0 0 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Lp1 + xywh {10 10 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Hp1 + xywh {20 20 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Lp2 + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Hp2 + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Bp2 + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label N2 + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pk + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LSh + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label HSh + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + } + Fl_Box eqgraph { + xywh {45 10 190 75} box BORDER_BOX color 178 + code0 {o->init(eff);} + class EQGraph + } + } + } + Function {make_dynamicfilter_window()} {} { + Fl_Window effdynamicfilterwindow { + xywh {104 461 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice dfp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label WahWah + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label AutoWah + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label Sweep + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label VocalMorph1 + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label VocalMorph2 + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label DynFilter + xywh {245 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial dfp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial dfp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial dfp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial dfp3 { + label Rnd + callback {eff->seteffectpar(3,(int) o->value());} + xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial dfp5 { + label {St.df} + callback {eff->seteffectpar(5,(int) o->value());} + xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial dfp6 { + label LfoD + callback {eff->seteffectpar(6,(int) o->value());} + xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Choice dfp4 { + label {LFO type} + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {LFO function} xywh {155 50 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8 + } { + menuitem {} { + label SINE + xywh {15 15 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label TRI + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + } + Fl_Button {} { + label Filter + callback {filterwindow->show();} + xywh {115 10 55 25} box PLASTIC_THIN_UP_BOX + } + Fl_Group {} {open + xywh {270 40 105 45} box BORDER_BOX color 181 + } { + Fl_Dial dfp7 { + label {A.S.} + callback {eff->seteffectpar(7,(int) o->value());} + xywh {275 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial dfp9 { + label {A.M} + callback {eff->seteffectpar(9,(int) o->value());} + xywh {305 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Check_Button dfp8 { + label {A.Inv.} + callback {eff->seteffectpar(8,(int) o->value());} + xywh {345 55 15 15} down_box DOWN_BOX labelfont 1 labelsize 12 align 2 + } + } + } + } + Function {make_filter_window()} {} { + Fl_Window filterwindow { + label {Filter Parameters for DynFilter Eff.} + xywh {212 170 290 110} type Double hide + } { + Fl_Group {} { + label {DynFilter effect - Filter} open + xywh {5 5 275 75} box FLAT_BOX color 50 align 144 + code0 {o->init(eff->filterpars,NULL,NULL);} + code1 {o->use_for_dynamic_filter();} + class FilterUI + } {} + Fl_Button {} { + label Close + callback {filterwindow->hide();} + xywh {105 85 70 20} box THIN_UP_BOX + } + } + } + Function {init(EffectMgr *eff_)} {} { + code {eff=eff_; + +make_null_window(); +make_reverb_window(); +make_echo_window(); +make_chorus_window(); +make_phaser_window(); +make_alienwah_window(); +make_distorsion_window(); +make_eq_window(); +make_dynamicfilter_window(); + +int px=this->parent()->x(); +int py=this->parent()->y(); + +effnullwindow->position(px,py); +effreverbwindow->position(px,py); +effechowindow->position(px,py); +effchoruswindow->position(px,py); +effphaserwindow->position(px,py); +effalienwahwindow->position(px,py); +effdistorsionwindow->position(px,py); +effeqwindow->position(px,py); +effdynamicfilterwindow->position(px,py); + +refresh(eff);} {} + } + Function {refresh(EffectMgr *eff_)} {} { + code {eff=eff_; +this->hide(); + +effnullwindow->hide(); +effreverbwindow->hide(); +effechowindow->hide(); +effchoruswindow->hide(); +effphaserwindow->hide(); +effalienwahwindow->hide(); +effdistorsionwindow->hide(); +effeqwindow->hide(); +effdynamicfilterwindow->hide(); + +eqband=0; + +if (filterwindow!=NULL){ + filterwindow->hide(); + delete(filterwindow); + filterwindow=NULL; +}; + +switch(eff->geteffect()){ + case 1: + revp->value(eff->getpreset()); + revp0->value(eff->geteffectpar(0));if (eff->insertion!=0) revp0->label("D/W"); + revp1->value(eff->geteffectpar(1)); + revp2->value(eff->geteffectpar(2)); + revp3->value(eff->geteffectpar(3)); + revp4->value(eff->geteffectpar(4)); + 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)); + + effreverbwindow->show(); + break; + case 2: + echop->value(eff->getpreset()); + echop0->value(eff->geteffectpar(0));if (eff->insertion!=0) echop0->label("D/W"); + echop1->value(eff->geteffectpar(1)); + echop2->value(eff->geteffectpar(2)); + echop3->value(eff->geteffectpar(3)); + echop4->value(eff->geteffectpar(4)); + echop5->value(eff->geteffectpar(5)); + echop6->value(eff->geteffectpar(6)); + effechowindow->show(); + break; + case 3: + chorusp->value(eff->getpreset()); + chorusp0->value(eff->geteffectpar(0));if (eff->insertion!=0) chorusp0->label("D/W"); + chorusp1->value(eff->geteffectpar(1)); + chorusp2->value(eff->geteffectpar(2)); + chorusp3->value(eff->geteffectpar(3)); + chorusp4->value(eff->geteffectpar(4)); + chorusp5->value(eff->geteffectpar(5)); + chorusp6->value(eff->geteffectpar(6)); + chorusp7->value(eff->geteffectpar(7)); + chorusp8->value(eff->geteffectpar(8)); + chorusp9->value(eff->geteffectpar(9)); + chorusp11->value(eff->geteffectpar(11)); + effchoruswindow->show(); + break; + case 4: + phaserp->value(eff->getpreset()); + phaserp0->value(eff->geteffectpar(0));if (eff->insertion!=0) phaserp0->label("D/W"); + phaserp1->value(eff->geteffectpar(1)); + phaserp2->value(eff->geteffectpar(2)); + phaserp3->value(eff->geteffectpar(3)); + phaserp4->value(eff->geteffectpar(4)); + phaserp5->value(eff->geteffectpar(5)); + phaserp6->value(eff->geteffectpar(6)); + phaserp7->value(eff->geteffectpar(7)); + phaserp8->value(eff->geteffectpar(8)); + phaserp9->value(eff->geteffectpar(9)); + phaserp10->value(eff->geteffectpar(10)); + phaserp11->value(eff->geteffectpar(11)); + effphaserwindow->show(); + break; + case 5: + awp->value(eff->getpreset()); + awp0->value(eff->geteffectpar(0));if (eff->insertion!=0) awp0->label("D/W"); + awp1->value(eff->geteffectpar(1)); + awp2->value(eff->geteffectpar(2)); + awp3->value(eff->geteffectpar(3)); + awp4->value(eff->geteffectpar(4)); + awp5->value(eff->geteffectpar(5)); + awp6->value(eff->geteffectpar(6)); + awp7->value(eff->geteffectpar(7)); + awp8->value(eff->geteffectpar(8)); + awp9->value(eff->geteffectpar(9)); + awp10->value(eff->geteffectpar(10)); + + effalienwahwindow->show(); + break; + case 6: + distp->value(eff->getpreset()); + distp0->value(eff->geteffectpar(0));if (eff->insertion!=0) distp0->label("D/W"); + distp1->value(eff->geteffectpar(1)); + distp2->value(eff->geteffectpar(2)); + distp3->value(eff->geteffectpar(3)); + distp4->value(eff->geteffectpar(4)); + distp5->value(eff->geteffectpar(5)); + distp6->value(eff->geteffectpar(6)); + distp7->value(eff->geteffectpar(7)); + distp8->value(eff->geteffectpar(8)); + distp9->value(eff->geteffectpar(9)); + distp10->value(eff->geteffectpar(10)); + effdistorsionwindow->show(); + break; + case 7:eqband=0; + eqp0->value(eff->geteffectpar(0)); + bandcounter->value(eqband); + bandcounter->do_callback(); + typechoice->value(eff->geteffectpar(10)); + eqgraph->redraw(); + freqdial->value(eff->geteffectpar(11)); + gaindial->value(eff->geteffectpar(12)); + if (eff->geteffectpar(10)<6) gaindial->deactivate(); + qdial->value(eff->geteffectpar(13)); + stagescounter->value(eff->geteffectpar(14)); + eqgraph->init(eff); + effeqwindow->show(); + break; + case 8:make_filter_window(); + dfp->value(eff->getpreset()); + dfp0->value(eff->geteffectpar(0));if (eff->insertion!=0) dfp0->label("D/W"); + dfp1->value(eff->geteffectpar(1)); + dfp2->value(eff->geteffectpar(2)); + dfp3->value(eff->geteffectpar(3)); + dfp4->value(eff->geteffectpar(4)); + dfp5->value(eff->geteffectpar(5)); + dfp6->value(eff->geteffectpar(6)); + dfp7->value(eff->geteffectpar(7)); + dfp8->value(eff->geteffectpar(8)); + dfp9->value(eff->geteffectpar(9)); + + + effdynamicfilterwindow->show(); + break; + default:effnullwindow->show(); + break; +}; + +this->show();} {} + } + Function {refresh()} {} { + code {refresh(eff);} {} + } + decl {EffectMgr *eff;} {} + decl {int eqband;} {} +} + +class SimpleEffUI {: {public Fl_Group,public PresetsUI_} +} { + Function {SimpleEffUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {eff=NULL;} {} + } + Function {~SimpleEffUI()} {} { + code {effnullwindow->hide();//delete (effnullwindow); +effreverbwindow->hide();//delete (effreverbwindow); +effechowindow->hide();//delete (effechowindow); +effchoruswindow->hide();//delete (effchoruswindow); +effphaserwindow->hide();//delete (effphaserwindow); +effalienwahwindow->hide();//delete (effalienwahwindow); +effdistorsionwindow->hide();//delete (effdistorsionwindow); +effeqwindow->hide();//delete (effeqwindow); +effdynamicfilterwindow->hide();//delete (effdynamicfilterwindow);} {} + } + Function {make_null_window()} {} { + Fl_Window effnullwindow { + xywh {539 150 233 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label {No Effect} + xywh {25 35 35 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 labelcolor 43 align 8 + } + } + } + Function {make_reverb_window()} {} { + Fl_Window effreverbwindow { + xywh {151 285 233 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label {Reverb } + xywh {115 10 20 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Choice revp { + label Preset + callback {eff->changepreset((int)o->value()); + +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Cathedral 1} + xywh {10 10 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Cathedral 2} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Cathedral 3} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Hall 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Hall 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Room 1} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Room 2} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label Basement + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label Tunnel + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Echoed 1} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Echoed 2} + xywh {110 110 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Very Long 1} + xywh {120 120 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Very Long 2} + xywh {130 130 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Dial revp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial revp2 { + label Time + callback {eff->seteffectpar(2,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial revp3 { + label {I.del} + callback {eff->seteffectpar(3,(int) o->value());} + xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial revp9 { + label Damp + callback {eff->seteffectpar(9,(int) o->value());} + xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 minimum 64 maximum 127 step 1 + class WidgetPDial + } + } + } + Function {make_echo_window()} {} { + Fl_Window effechowindow { + xywh {243 350 231 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice echop { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {11 15 95 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Echo 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Echo 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Echo 3} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Simple Echo} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label Canyon + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Panning Echo 1} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Panning Echo 2} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Panning Echo 3} + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Feedback Echo} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Echo + xywh {145 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial echop0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial echop2 { + label Delay + callback {eff->seteffectpar(2,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial echop5 { + label {Fb.} + callback {eff->seteffectpar(5,(int) o->value());} + xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + } + } + Function {make_chorus_window()} {} { + Fl_Window effchoruswindow { + xywh {234 353 233 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice chorusp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Chorus 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Chorus 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Chorus 3} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Celeste 1} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Celeste 2} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Flange 1} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Flange 2} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Flange 3} + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Flange 4} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Flange 5} + xywh {110 110 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Chorus + xywh {120 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial chorusp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp7 { + label Delay + callback {eff->seteffectpar(7,(int) o->value());} + xywh {115 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp8 { + label Fb + callback {eff->seteffectpar(8,(int) o->value());} + xywh {150 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Check_Button {} { + label Flange + callback {eff->seteffectpar(10,(int) o->value());} + xywh {120 10 55 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10 hide deactivate + code0 {o->value(eff->geteffectpar(10));} + } + } + } + Function {make_phaser_window()} {} { + Fl_Window effphaserwindow { + xywh {171 303 232 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice phaserp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Phaser 1} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Phaser 2} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Phaser 3} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Phaser 4} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Phaser 5} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Phaser 6} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Phaser + xywh {125 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial phaserp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp5 { + label {St.df} + callback {eff->seteffectpar(5,(int) o->value());} + xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + xywh {115 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp7 { + label Fb + callback {eff->seteffectpar(7,(int) o->value());} + xywh {150 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Counter phaserp8 { + label Stages + callback {eff->seteffectpar(8,(int) o->value());} + xywh {185 55 35 15} type Simple labelfont 1 labelsize 12 minimum 0 maximum 127 step 1 + code0 {o->range(1,MAX_PHASER_STAGES);} + } + } + } + Function {make_alienwah_window()} {} { + Fl_Window effalienwahwindow { + xywh {183 344 234 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice awp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Alienwah 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Alienwah 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Alienwah 3} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Alienwah 4} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label AlienWah + xywh {100 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial awp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial awp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial awp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Counter awp8 { + label Delay + callback {eff->seteffectpar(8,(int) o->value());} + xywh {125 55 35 15} type Simple labelfont 1 labelsize 12 minimum 0 maximum 127 step 1 + code0 {o->range(1,MAX_ALIENWAH_DELAY);} + } + } + } + Function {make_distorsion_window()} {} { + Fl_Window effdistorsionwindow { + xywh {257 432 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice distp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {11 15 95 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label {Overdrive 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Overdrive 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {A. Exciter 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {A. Exciter 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label {Guitar Amp} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label Quantisize + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Distortion + xywh {110 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 20 align 8 + } + Fl_Dial distp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial distp3 { + label Drive + callback {eff->seteffectpar(3,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial distp4 { + label Level + callback {eff->seteffectpar(4,(int) o->value());} + xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial distp7 { + label LPF + callback {eff->seteffectpar(7,(int) o->value());} + xywh {190 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Choice distp5 { + label Type + callback {eff->seteffectpar(5,(int) o->value());} + xywh {120 50 60 20} box UP_BOX down_box BORDER_BOX labelfont 1 labelsize 12 align 2 textsize 10 + } { + menuitem {} { + label Atan + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Asym1 + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pow + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sine + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Qnts + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Zigzg + xywh {105 105 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Lmt + xywh {115 115 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LmtU + xywh {125 125 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LmtL + xywh {135 135 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label ILmt + xywh {147 147 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Clip + xywh {157 157 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Asym2 + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pow2 + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sgm + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + } + } + } + Function {make_eq_window()} {} { + Fl_Window effeqwindow { + xywh {258 307 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label EQ + xywh {170 5 15 25} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Counter bandcounter { + label Band + callback {eqband=(int) o->value(); +int npb=eqband*5+10; + +int type=eff->geteffectpar(npb); +typechoice->value(type); + +if (type>6) gaindial->activate(); + else gaindial->deactivate(); + +if (type==0) bandgroup->deactivate(); +else bandgroup->activate(); + +int freq=eff->geteffectpar(npb+1); +freqdial->value(freq); + +int gain=eff->geteffectpar(npb+2); +gaindial->value(gain); + +int q=eff->geteffectpar(npb+3); +qdial->value(q); + +int dbl=eff->geteffectpar(npb+4); +stagescounter->value(dbl);} + tooltip {Band no.} xywh {85 15 45 15} type Simple labelfont 1 labelsize 12 align 1 minimum 0 maximum 1 step 1 textfont 1 textsize 12 + code0 {o->bounds(0,MAX_EQ_BANDS-1);} + } + Fl_Group bandgroup { + xywh {5 5 75 85} box ENGRAVED_FRAME + code0 {if (eff->geteffectpar(10)==0) o->deactivate();} + } { + Fl_Dial freqdial { + label Freq + callback {int np=eqband*5+11; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + xywh {10 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 + class WidgetPDial + } + Fl_Dial gaindial { + label Gain + callback {int np=eqband*5+12; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + xywh {45 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial qdial { + label Q + callback {int np=eqband*5+13; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + xywh {10 50 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 + class WidgetPDial + } + Fl_Counter stagescounter { + label Stages + callback {int np=eqband*5+14; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + tooltip {Additional filter stages} xywh {40 55 30 15} type Simple labelfont 1 labelsize 10 minimum 1 maximum 127 step 1 textfont 1 textsize 12 + code0 {o->bounds(0,MAX_FILTER_STAGES-1);} + } + } + Fl_Choice typechoice { + label Type + callback {int np=eqband*5+10; +eff->seteffectpar(np,(int) o->value()); +bandcounter->do_callback(); +eqgraph->redraw();} + tooltip Type xywh {135 15 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 1 when 6 textsize 10 + } { + menuitem {} { + label OFF + xywh {10 10 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Lp1 + xywh {20 20 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Hp1 + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Lp2 + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Hp2 + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Bp2 + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label N2 + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pk + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LSh + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label HSh + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + } + Fl_Box eqgraph { + xywh {85 35 140 55} box BORDER_BOX color 178 + code0 {o->init(eff);} + class EQGraph + } + } + } + Function {make_dynamicfilter_window()} {} { + Fl_Window effdynamicfilterwindow { + xywh {271 375 232 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice dfp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 labelcolor 0 align 5 textfont 1 textsize 10 textcolor 7 + } { + menuitem {} { + label WahWah + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label AutoWah + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label Sweep + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label VocalMorph1 + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + menuitem {} { + label VocalMorph2 + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label DynFilter + xywh {100 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 26 align 8 + } + Fl_Dial dfp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial dfp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial dfp6 { + label LfoD + callback {eff->seteffectpar(6,(int) o->value());} + xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Group {} {open + xywh {115 40 65 45} box BORDER_BOX color 181 + } { + Fl_Dial dfp7 { + label {A.S.} + callback {eff->seteffectpar(7,(int) o->value());} + xywh {120 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + Fl_Dial dfp9 { + label {A.M} + callback {eff->seteffectpar(9,(int) o->value());} + xywh {150 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 12 maximum 127 + class WidgetPDial + } + } + } + } + Function {init(EffectMgr *eff_)} {} { + code {eff=eff_; + +make_null_window(); +make_reverb_window(); +make_echo_window(); +make_chorus_window(); +make_phaser_window(); +make_alienwah_window(); +make_distorsion_window(); +make_eq_window(); +make_dynamicfilter_window(); + +int px=this->parent()->x(); +int py=this->parent()->y(); + +effnullwindow->position(px,py); +effreverbwindow->position(px,py); +effechowindow->position(px,py); +effchoruswindow->position(px,py); +effphaserwindow->position(px,py); +effalienwahwindow->position(px,py); +effdistorsionwindow->position(px,py); +effeqwindow->position(px,py); +effdynamicfilterwindow->position(px,py); + +refresh(eff);} {} + } + Function {refresh(EffectMgr *eff_)} {open + } { + code {eff=eff_; +this->hide(); + +effnullwindow->hide(); +effreverbwindow->hide(); +effechowindow->hide(); +effchoruswindow->hide(); +effphaserwindow->hide(); +effalienwahwindow->hide(); +effdistorsionwindow->hide(); +effeqwindow->hide(); +effdynamicfilterwindow->hide(); + +eqband=0; + + +switch(eff->geteffect()){ + case 1: + revp->value(eff->getpreset()); + revp0->value(eff->geteffectpar(0));if (eff->insertion!=0) revp0->label("D/W"); + revp2->value(eff->geteffectpar(2)); + revp3->value(eff->geteffectpar(3)); + revp9->value(eff->geteffectpar(9)); + effreverbwindow->show(); + break; + case 2: + echop->value(eff->getpreset()); + echop0->value(eff->geteffectpar(0));if (eff->insertion!=0) echop0->label("D/W"); + echop2->value(eff->geteffectpar(2)); + echop5->value(eff->geteffectpar(5)); + effechowindow->show(); + break; + case 3: + chorusp->value(eff->getpreset()); + chorusp0->value(eff->geteffectpar(0));if (eff->insertion!=0) chorusp0->label("D/W"); + chorusp2->value(eff->geteffectpar(2)); + chorusp6->value(eff->geteffectpar(6)); + chorusp7->value(eff->geteffectpar(7)); + chorusp8->value(eff->geteffectpar(8)); + effchoruswindow->show(); + break; + case 4: + phaserp->value(eff->getpreset()); + phaserp0->value(eff->geteffectpar(0));if (eff->insertion!=0) phaserp0->label("D/W"); + phaserp2->value(eff->geteffectpar(2)); + phaserp5->value(eff->geteffectpar(5)); + phaserp6->value(eff->geteffectpar(6)); + phaserp7->value(eff->geteffectpar(7)); + phaserp8->value(eff->geteffectpar(8)); + effphaserwindow->show(); + break; + case 5: + awp->value(eff->getpreset()); + awp0->value(eff->geteffectpar(0));if (eff->insertion!=0) awp0->label("D/W"); + awp2->value(eff->geteffectpar(2)); + awp6->value(eff->geteffectpar(6)); + awp8->value(eff->geteffectpar(8)); + effalienwahwindow->show(); + break; + case 6: + distp->value(eff->getpreset()); + distp0->value(eff->geteffectpar(0));if (eff->insertion!=0) distp0->label("D/W"); + distp3->value(eff->geteffectpar(3)); + distp4->value(eff->geteffectpar(4)); + distp5->value(eff->geteffectpar(5)); + distp7->value(eff->geteffectpar(7)); + effdistorsionwindow->show(); + break; + case 7: + bandcounter->value(eqband); + bandcounter->do_callback(); + typechoice->value(eff->geteffectpar(10)); + eqgraph->redraw(); + freqdial->value(eff->geteffectpar(11)); + gaindial->value(eff->geteffectpar(12)); + if (eff->geteffectpar(10)<6) gaindial->deactivate(); + qdial->value(eff->geteffectpar(13)); + stagescounter->value(eff->geteffectpar(14)); + eqgraph->init(eff); + effeqwindow->show(); + break; + case 8: + dfp->value(eff->getpreset()); + dfp0->value(eff->geteffectpar(0));if (eff->insertion!=0) dfp0->label("D/W"); + dfp2->value(eff->geteffectpar(2)); + dfp6->value(eff->geteffectpar(6)); + dfp7->value(eff->geteffectpar(7)); + dfp9->value(eff->geteffectpar(9)); + + + effdynamicfilterwindow->show(); + break; + default:effnullwindow->show(); + break; +}; + +this->show();} {selected + } + } + Function {refresh()} {} { + code {refresh(eff);} {} + } + decl {EffectMgr *eff;} {} + decl {int eqband;} {} +} diff --git a/muse/synti/zynaddsubfx/UI/EnvelopeUI.fl b/muse/synti/zynaddsubfx/UI/EnvelopeUI.fl new file mode 100644 index 00000000..090a77fc --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/EnvelopeUI.fl @@ -0,0 +1,851 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include <FL/Fl_Group.H>} {public +} + +decl {\#include "../Params/EnvelopeParams.h"} {public +} + +decl {\#include <FL/Fl_Box.H>} {public +} + +decl {\#include <FL/fl_draw.H>} {public +} + +decl {\#include <FL/fl_ask.H>} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class EnvelopeFreeEdit {: {public Fl_Box} +} { + Function {EnvelopeFreeEdit(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {env=NULL; +pair=NULL;} {} + } + Function {init(EnvelopeParams *env_)} {} { + code {env=env_; +oldx=-1; +currentpoint=-1; +cpx=0; +lastpoint=-1;} {} + } + Function {setpair(Fl_Box *pair_)} {} { + code {pair=pair_;} {} + } + Function {getpointx(int n)} {return_type int + } { + code {int lx=w()-10; +int npoints=env->Penvpoints; + +float sum=0; +for (int i=1;i<npoints;i++) sum+=env->getdt(i)+1; + +float sumbefore=0;//the sum of all points before the computed point +for (int i=1;i<=n;i++) sumbefore+=env->getdt(i)+1; + +return((int) (sumbefore/(REALTYPE) sum*lx));} {} + } + Function {getpointy(int n)} {return_type int + } { + code {int ly=h()-10; + +return((int) ((1.0-env->Penvval[n]/127.0)*ly));} {} + } + Function {getnearest(int x,int y)} {return_type int + } { + code {x-=5;y-=5; + +int nearestpoint=0; +int nearestval=1000000;//a big value +for (int i=0;i<env->Penvpoints;i++){ + int distance=abs(x-getpointx(i))+abs(y-getpointy(i)); + if (distance<nearestval) { + nearestpoint=i; + nearestval=distance; + }; +}; +return(nearestpoint);} {} + } + Function {draw()} {private + } { + code {int ox=x(),oy=y(),lx=w(),ly=h(); +if (env->Pfreemode==0) env->converttofree(); +int npoints=env->Penvpoints; + +if (active_r()) fl_color(FL_BLACK); + else fl_color(90,90,90); +if (!active_r()) currentpoint=-1; + +fl_rectf(ox,oy,lx,ly); + +ox+=5;oy+=5;lx-=10;ly-=10; + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +//draws the evelope points and lines +Fl_Color alb=FL_WHITE; +if (!active_r()) alb=fl_rgb_color(180,180,180); +fl_color(alb); +int oldxx=0,xx=0,oldyy=0,yy=getpointy(0); +fl_rectf(ox-3,oy+yy-3,6,6); +for (int i=1;i<npoints;i++){ + oldxx=xx;oldyy=yy; + xx=getpointx(i);yy=getpointy(i); + if (i==currentpoint) fl_color(FL_RED); + else fl_color(alb); + fl_line(ox+oldxx,oy+oldyy,ox+xx,oy+yy); + fl_rectf(ox+xx-3,oy+yy-3,6,6); +}; + +//draw the last moved point point (if exists) +if (lastpoint>=0){ + fl_color(FL_CYAN); + fl_rectf(ox+getpointx(lastpoint)-5,oy+getpointy(lastpoint)-5,10,10); +}; + +//draw the sustain position +if (env->Penvsustain>0){ + fl_color(FL_YELLOW); + xx=getpointx(env->Penvsustain); + fl_line(ox+xx,oy+0,ox+xx,oy+ly); +}; + +//Show the envelope duration and the current line duration +fl_font(FL_HELVETICA|FL_BOLD,10); +float time=0.0; +if (currentpoint<=0){ + fl_color(alb); + for (int i=1;i<npoints;i++) time+=env->getdt(i); +} else { + fl_color(255,0,0); + time=env->getdt(currentpoint); +}; +char tmpstr[20]; +if (time<1000.0) snprintf((char *)&tmpstr,20,"%.1fms",time); + else snprintf((char *)&tmpstr,20,"%.2fs",time/1000.0); +fl_draw(tmpstr,ox+lx-20,oy+ly-10,20,10,FL_ALIGN_RIGHT,NULL,0);} {} + } + Function {handle(int event)} {return_type int + } { + code {int x_=Fl::event_x()-x(); +int y_=Fl::event_y()-y(); + +if (event==FL_PUSH) { + currentpoint=getnearest(x_,y_); + cpx=x_; + cpdt=env->Penvdt[currentpoint]; + lastpoint=currentpoint; + redraw(); + if (pair!=NULL) pair->redraw(); +}; + +if (event==FL_RELEASE){ + currentpoint=-1; + redraw(); + if (pair!=NULL) pair->redraw(); +}; + +if ((event==FL_DRAG)&&(currentpoint>=0)){ + int ny=127-(int) (y_*127.0/h()); + if (ny<0) ny=0;if (ny>127) ny=127; + env->Penvval[currentpoint]=ny; + + int dx=(int)((x_-cpx)*0.1); + int newdt=cpdt+dx; + if (newdt<0) newdt=0;if (newdt>127) newdt=127; + if (currentpoint!=0) env->Penvdt[currentpoint]=newdt; + else env->Penvdt[currentpoint]=0; + + redraw(); + if (pair!=NULL) pair->redraw(); +}; + + +return(1);} {} + } + decl {Fl_Box *pair;} {} + decl {EnvelopeParams *env;} {} + decl {int oldx,oldy;} {} + decl {int currentpoint,cpx,cpdt;} {} + decl {int lastpoint;} {public + } +} + +class EnvelopeUI {: {public Fl_Group,PresetsUI_} +} { + Function {EnvelopeUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {env=NULL; +freemodeeditwindow=NULL; +envADSR=NULL; +envASR=NULL; +envADSRfilter=NULL; +envASRbw=NULL; +envfree=NULL;} {} + } + Function {~EnvelopeUI()} {} { + code {envwindow->hide(); +hide(); +freemodeeditwindow->hide(); +delete (freemodeeditwindow);} {} + } + Function {make_freemode_edit_window()} {} { + Fl_Window freemodeeditwindow { + label Envelope + xywh {60 308 575 180} type Double hide + } { + Fl_Box freeedit { + label Envelope + xywh {5 5 565 145} box FLAT_BOX color 0 + code0 {o->init(env);} + class EnvelopeFreeEdit + } + Fl_Button addpoint { + label {Add point} + callback {int curpoint=freeedit->lastpoint; +if (curpoint<0) return; +//if (curpoint>=env->Penvpoints-1) return; +if (env->Penvpoints>=MAX_ENVELOPE_POINTS) return; + +for (int i=env->Penvpoints;i>=curpoint+1;i--){ + env->Penvdt[i]=env->Penvdt[i-1]; + env->Penvval[i]=env->Penvval[i-1]; +}; + +if (curpoint==0) { + env->Penvdt[1]=64; +}; + +env->Penvpoints++; +if (curpoint<=env->Penvsustain) env->Penvsustain++; + +freeedit->lastpoint+=1; +freeedit->redraw(); +envfree->redraw(); + +sustaincounter->value(env->Penvsustain); +sustaincounter->maximum(env->Penvpoints-2);} + xywh {115 155 80 20} box THIN_UP_BOX + code0 {if (env->Pfreemode==0) o->hide();} + } + Fl_Button deletepoint { + label {Delete point} + callback {int curpoint=freeedit->lastpoint; +if (curpoint<1) return; +if (curpoint>=env->Penvpoints-1) return; +if (env->Penvpoints<=3) return; + +for (int i=curpoint+1;i<env->Penvpoints;i++){ + env->Penvdt[i-1]=env->Penvdt[i]; + env->Penvval[i-1]=env->Penvval[i]; +}; + +env->Penvpoints--; + +if (curpoint<=env->Penvsustain) env->Penvsustain--; + + +freeedit->lastpoint-=1; +freeedit->redraw(); +envfree->redraw(); + +sustaincounter->value(env->Penvsustain); +sustaincounter->maximum(env->Penvpoints-2);} + xywh {200 155 80 20} box THIN_UP_BOX + code0 {if (env->Pfreemode==0) o->hide();} + } + Fl_Light_Button freemodebutton { + label FreeMode + callback {reinit(); + +freeedit->lastpoint=-1; +freeedit->redraw();} + tooltip {Enable or disable the freemode} xywh {10 155 95 25} box PLASTIC_UP_BOX + } + Fl_Check_Button forcedreleasecheck { + label frcR + callback {env->Pforcedrelease=(int)o->value();} + tooltip {Forced Relase} xywh {410 165 40 15} down_box DOWN_BOX labelsize 11 + code0 {o->value(env->Pforcedrelease);} + code1 {if (env->Pfreemode==0) o->hide();} + } + Fl_Dial envstretchdial { + label {Str.} + callback {env->Penvstretch=(int)o->value();} + tooltip {Envelope stretch (on lower notes make the envelope longer)} xywh {380 155 25 25} box ROUND_UP_BOX labelsize 11 align 4 maximum 127 step 1 + code0 {o->value(env->Penvstretch);} + code1 {if (env->Pfreemode==0) o->hide();} + class WidgetPDial + } + Fl_Button {} { + label Close + callback {freemodeeditwindow->hide();} + xywh {510 155 60 25} box THIN_UP_BOX + } + Fl_Check_Button linearenvelopecheck { + label L + callback {env->Plinearenvelope=(int)o->value();} + tooltip {Linear Envelope} xywh {410 151 30 15} down_box DOWN_BOX labelsize 11 + code0 {o->value(env->Plinearenvelope);} + code1 {if ((env->Pfreemode==0)||(env->Envmode>2)) o->hide();} + } + Fl_Counter sustaincounter { + label Sust + callback {env->Penvsustain=(int) o->value(); +freeedit->redraw(); +envfree->redraw();} + tooltip {Sustain (0 is disabled)} xywh {315 155 40 15} type Simple labelsize 12 align 4 minimum 0 maximum 127 step 1 + code0 {o->value(env->Penvsustain);} + code1 {if (env->Pfreemode==0) o->hide();} + code2 {o->maximum(env->Penvpoints-2);} + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {465 160 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {482 160 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + Function {make_ADSR_window()} {} { + Fl_Window envADSR { + xywh {108 336 205 70} type Double color 50 labelfont 1 hide + class Fl_Group + } { + Fl_Group {} { + label {Amplitude Envelope} + xywh {0 0 205 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 11 align 17 + } { + Fl_Dial e1adt { + label {A.dt} + callback {env->PA_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Attack time} xywh {5 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PA_dt);} + class WidgetPDial + } + Fl_Dial e1ddt { + label {D.dt} + callback {env->PD_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Decay time} xywh {40 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PD_dt);} + class WidgetPDial + } + Fl_Dial e1rdt { + label {R.dt} + callback {env->PR_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Release time} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PR_dt);} + class WidgetPDial + } + Fl_Dial e1sval { + label {S.val} + callback {env->PS_val=(int)o->value(); +freeedit->redraw();} + tooltip {Sustain value} xywh {75 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PS_val);} + class WidgetPDial + } + Fl_Check_Button e1forcedrelease { + label frcR + callback {env->Pforcedrelease=(int)o->value();} + tooltip {Forced Relase} xywh {180 35 20 15} down_box DOWN_BOX labelsize 11 align 6 + code0 {o->value(env->Pforcedrelease);} + } + Fl_Dial e1envstretch { + label Stretch + callback {env->Penvstretch=(int)o->value();} + tooltip {Envelope stretch (on lower notes makes the envelope longer)} xywh {145 25 25 25} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->Penvstretch);} + class WidgetPDial + } + Fl_Button {} { + label E + callback {freemodeeditwindow->show();} + tooltip {Envelope window} xywh {185 5 15 15} box PLASTIC_UP_BOX labelfont 1 labelsize 10 + } + Fl_Check_Button e1linearenvelope { + label L + callback {env->Plinearenvelope=(int)o->value();} + tooltip {The evelope is linear} xywh {180 20 15 15} down_box DOWN_BOX labelsize 11 align 4 + code0 {o->value(env->Plinearenvelope);} + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {150 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {167 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + } + Function {make_ASR_window()} {} { + Fl_Window envASR { + xywh {71 320 210 70} type Double hide + class Fl_Group + } { + Fl_Group {} { + label {Frequency Envelope} + xywh {0 0 210 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 11 align 17 + } { + Fl_Dial e2aval { + label {A.val} + callback {env->PA_val=(int)o->value(); +freeedit->redraw();} + tooltip {Starting value} xywh {5 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PA_val);} + class WidgetPDial + } + Fl_Dial e2adt { + label {A.dt} + callback {env->PA_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Attack time} xywh {40 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PA_dt);} + class WidgetPDial + } + Fl_Dial e2rval { + label {R.val} + callback {env->PR_val=(int)o->value(); +freeedit->redraw();} + tooltip {Release value} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PR_val);} + class WidgetPDial + } + Fl_Dial e2rdt { + label {R.dt} + callback {env->PR_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Release time} xywh {75 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PR_dt);} + class WidgetPDial + } + Fl_Dial e2envstretch { + label Stretch + callback {env->Penvstretch=(int)o->value();} + tooltip {Envelope stretch (on lower notes makes the envelope longer)} xywh {145 25 25 25} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->Penvstretch);} + class WidgetPDial + } + Fl_Check_Button e2forcedrelease { + label frcR + callback {env->Pforcedrelease=(int)o->value();} + tooltip {Forced release} xywh {180 25 15 25} down_box DOWN_BOX labelsize 11 align 6 + code0 {o->value(env->Pforcedrelease);} + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {155 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {172 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Button {} { + label E + callback {freemodeeditwindow->show();} + tooltip {Envelope window} xywh {190 5 15 15} box PLASTIC_UP_BOX labelfont 1 labelsize 10 + } + } + } + Function {make_ADSRfilter_window()} {} { + Fl_Window envADSRfilter { + xywh {87 143 275 70} type Double color 50 labelfont 1 hide + class Fl_Group + } { + Fl_Group {} { + label {Filter Envelope} + xywh {0 0 275 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 11 align 17 + } { + Fl_Dial e3aval { + label {A.val} + callback {env->PA_val=(int)o->value(); +freeedit->redraw();} + tooltip {Starting value} xywh {5 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PA_val);} + class WidgetPDial + } + Fl_Dial e3adt { + label {A.dt} + callback {env->PA_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Attack time} xywh {40 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PA_dt);} + class WidgetPDial + } + Fl_Dial e3dval { + label {D.val} + callback {env->PD_val=(int)o->value(); +freeedit->redraw();} + tooltip {decay value} xywh {75 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PD_val);} + class WidgetPDial + } + Fl_Dial e3ddt { + label {D.dt} + callback {env->PD_dt=(int)o->value(); +freeedit->redraw();} + tooltip {decay time} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PD_dt);} + class WidgetPDial + } + Fl_Dial e3rdt { + label {R.dt} + callback {env->PR_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Release time} xywh {145 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PR_dt);} + class WidgetPDial + } + Fl_Dial e3rval { + label {R.val} + callback {env->PR_val=(int)o->value(); +freeedit->redraw();} + tooltip {Release value} xywh {180 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PR_val);} + class WidgetPDial + } + Fl_Dial e3envstretch { + label Stretch + callback {env->Penvstretch=(int)o->value();} + tooltip {Envelope stretch (on lower notes makes the envelope longer)} xywh {215 25 25 25} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->Penvstretch);} + class WidgetPDial + } + Fl_Check_Button e3forcedrelease { + label frcR + callback {env->Pforcedrelease=(int)o->value();} + tooltip {Forced Relase} xywh {250 30 15 20} down_box DOWN_BOX labelsize 11 align 6 + code0 {o->value(env->Pforcedrelease);} + } + Fl_Button {} { + label E + callback {freemodeeditwindow->show();} + xywh {255 5 15 15} box PLASTIC_UP_BOX labelfont 1 labelsize 10 + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {220 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {237 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + } + Function {make_ASRbw_window()} {} { + Fl_Window envASRbw { + xywh {224 539 210 70} type Double hide + class Fl_Group + } { + Fl_Group {} { + label {BandWidth Envelope} + xywh {0 0 210 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 11 align 17 + } { + Fl_Dial e4aval { + label {A.val} + callback {env->PA_val=(int)o->value(); +freeedit->redraw();} + tooltip {Starting value} xywh {5 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PA_val);} + class WidgetPDial + } + Fl_Dial e4adt { + label {A.dt} + callback {env->PA_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Attack time} xywh {40 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PA_dt);} + class WidgetPDial + } + Fl_Dial e4rval { + label {R.val} + callback {env->PR_val=(int)o->value(); +freeedit->redraw();} + tooltip {Release value} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PR_val);} + class WidgetPDial + } + Fl_Dial e4rdt { + label {R.dt} + callback {env->PR_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Release time} xywh {75 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->PR_dt);} + class WidgetPDial + } + Fl_Dial e4envstretch { + label Stretch + callback {env->Penvstretch=(int)o->value();} + tooltip {Envelope stretch (on lower notes makes the envelope longer)} xywh {145 25 25 25} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(env->Penvstretch);} + class WidgetPDial + } + Fl_Check_Button e4forcedrelease { + label frcR + callback {env->Pforcedrelease=(int)o->value();} + tooltip {Forced release} xywh {180 25 15 25} down_box DOWN_BOX labelsize 11 align 6 + code0 {o->value(env->Pforcedrelease);} + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {155 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {172 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Button {} { + label E + callback {freemodeeditwindow->show();} + xywh {190 5 15 15} box PLASTIC_UP_BOX labelfont 1 labelsize 10 + } + } + } + Function {make_free_window()} {} { + Fl_Window envfree { + xywh {373 413 205 70} type Double color 50 labelfont 1 hide resizable + class Fl_Group + } { + Fl_Group envfreegroup { + label {Amplitude Envelope} + xywh {0 0 205 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 11 align 17 resizable + } { + Fl_Box freeeditsmall { + label Envelope + callback {envfree->redraw();} + xywh {5 20 195 45} box FLAT_BOX color 0 resizable + code0 {o->init(env);} + class EnvelopeFreeEdit + } + Fl_Button {} { + label E + callback {freemodeeditwindow->show();} + xywh {185 5 15 15} box PLASTIC_UP_BOX labelfont 1 labelsize 10 + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {150 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {167 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + } + Function {init(EnvelopeParams *env_)} {} { + code {env=env_; +make_ADSR_window(); +make_ASR_window(); +make_ADSRfilter_window(); +make_ASRbw_window(); +make_free_window(); + +make_freemode_edit_window(); + +envwindow=NULL; +if (env->Envmode==3) envfreegroup->label("Frequency Envelope"); +if (env->Envmode==4) envfreegroup->label("Filter Envelope"); +if (env->Envmode==5) envfreegroup->label("Bandwidth Envelope"); + +freemodeeditwindow->label(this->label()); + + +freeeditsmall->setpair(freeedit); +freeedit->setpair(freeeditsmall); + + +refresh();} {} + } + Function {reinit()} {} { + code {if (env->Pfreemode!=0){ + int answer=fl_ask("Disable the free mode of the Envelope?"); + if (env->Pfreemode!=0) freemodebutton->value(1); + else freemodebutton->value(0); + if (answer==0) return; +}; + +if (env->Pfreemode==0) env->Pfreemode=1; + else env->Pfreemode=0; + +hide(); +int winx=freemodeeditwindow->x(); +int winy=freemodeeditwindow->y(); + +freemodeeditwindow->hide(); + +envwindow->hide(); +Fl_Group *par=envwindow->parent(); +par->hide(); + + +refresh(); +envwindow->show(); +par->redraw(); + +par->show(); +show(); +freemodeeditwindow->position(winx,winy); +freemodeeditwindow->show(); + +if (env->Pfreemode!=0) { + freemodebutton->value(1); + addpoint->show(); + deletepoint->show(); + forcedreleasecheck->show(); +}else{ + freemodebutton->value(0); + addpoint->hide(); + deletepoint->hide(); + forcedreleasecheck->hide(); +};} {selected + } + } + Function {refresh()} {} { + code {freemodebutton->value(env->Pfreemode); + +sustaincounter->value(env->Penvsustain); +if (env->Pfreemode==0) sustaincounter->hide(); + else sustaincounter->show(); +sustaincounter->maximum(env->Penvpoints-2); + +envstretchdial->value(env->Penvstretch); +if (env->Pfreemode==0) envstretchdial->hide(); + else envstretchdial->show(); + +linearenvelopecheck->value(env->Plinearenvelope); +if ((env->Pfreemode==0)||(env->Envmode>2)) linearenvelopecheck->hide(); + else linearenvelopecheck->show(); + +forcedreleasecheck->value(env->Pforcedrelease); +if (env->Pfreemode==0) forcedreleasecheck->hide(); + +freeedit->redraw(); + + +if (env->Pfreemode==0){ + switch(env->Envmode){ + case(1): + case(2): + e1adt->value(env->PA_dt); + e1ddt->value(env->PD_dt); + e1sval->value(env->PS_val); + e1rdt->value(env->PR_dt); + e1envstretch->value(env->Penvstretch); + e1linearenvelope->value(env->Plinearenvelope); + e1forcedrelease->value(env->Pforcedrelease); + break; + case(3): + e2aval->value(env->PA_val); + e2adt->value(env->PA_dt); + e2rdt->value(env->PR_dt); + e2rval->value(env->PR_val); + e2envstretch->value(env->Penvstretch); + e2forcedrelease->value(env->Pforcedrelease); + break; + case(4): + e3aval->value(env->PA_val); + e3adt->value(env->PA_dt); + e3dval->value(env->PD_val); + e3ddt->value(env->PD_dt); + e3rdt->value(env->PR_dt); + e3rval->value(env->PR_val); + e3envstretch->value(env->Penvstretch); + e3forcedrelease->value(env->Pforcedrelease); + break; + case(5): + e4aval->value(env->PA_val); + e4adt->value(env->PA_dt); + e4rdt->value(env->PR_dt); + e4rval->value(env->PR_val); + e4envstretch->value(env->Penvstretch); + e4forcedrelease->value(env->Pforcedrelease); + break; + default: + break; + }; +}else{ + envfree->redraw(); +}; + + +envADSR->hide(); +envASR->hide(); +envADSRfilter->hide(); +envASRbw->hide(); +envfree->hide(); + +if (env->Pfreemode==0){ + switch(env->Envmode){ + case(1): + case(2): + envwindow=envADSR; + break; + case(3): + envwindow=envASR; + break; + case(4): + envwindow=envADSRfilter; + break; + case(5): + envwindow=envASRbw; + break; + default: + break; + }; +}else{ + envwindow=envfree; +}; + +envwindow->resize(this->x(),this->y(),this->w(),this->h()); + +envwindow->show();} {} + } + decl {EnvelopeParams *env;} {} + decl {Fl_Group *envwindow;} {} +} diff --git a/muse/synti/zynaddsubfx/UI/FilterUI.fl b/muse/synti/zynaddsubfx/UI/FilterUI.fl new file mode 100644 index 00000000..44b50b94 --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/FilterUI.fl @@ -0,0 +1,624 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include <FL/Fl_Group.H>} {public +} + +decl {\#include "../Params/FilterParams.h"} {public +} + +decl {\#include <FL/Fl_Box.H>} {public +} + +decl {\#include <FL/fl_draw.H>} {public +} + +decl {\#include <FL/fl_ask.H>} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class FormantFilterGraph {: {public Fl_Box} +} { + Function {FormantFilterGraph(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {pars=NULL; +nvowel=NULL; +nformant=NULL; +graphpoints=NULL;} {} + } + Function {init(FilterParams *pars_,int *nvowel_,int *nformant_)} {} { + code {pars=pars_; +nvowel=nvowel_; +nformant=nformant_; +oldx=-1; +graphpoints=new REALTYPE [w()];} {} + } + Function {draw_freq_line(REALTYPE freq,int type)} {} { + code {REALTYPE freqx=pars->getfreqpos(freq); +switch(type){ + case 0:fl_line_style(FL_SOLID);break; + case 1:fl_line_style(FL_DOT);break; + case 2:fl_line_style(FL_DASH);break; +}; + + +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(x()+(int) (freqx*w()),y(), + x()+(int) (freqx*w()),y()+h());} {} + } + Function {draw()} {open + } { + code {int maxdB=30; +int ox=x(),oy=y(),lx=w(),ly=h(),i,oiy; +REALTYPE freqx; + +fl_color(FL_BLACK); +fl_rectf(ox,oy,lx,ly); + + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +//fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +freqx=pars->getfreqpos(1000.0); +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(ox+(int) (freqx*lx),oy, + ox+(int) (freqx*lx),oy+ly); + +for (i=1;i<10;i++){ + if(i==1){ + draw_freq_line(i*100.0,0); + draw_freq_line(i*1000.0,0); + }else + if (i==5){ + draw_freq_line(i*100.0,2); + draw_freq_line(i*1000.0,2); + }else{ + draw_freq_line(i*100.0,1); + draw_freq_line(i*1000.0,1); + }; +}; + +draw_freq_line(10000.0,0); +draw_freq_line(20000.0,1); + +fl_line_style(FL_DOT); +int GY=10;if (ly<GY*3) GY=-1; +for (i=1;i<GY;i++){ + int tmp=(int)(ly/(REALTYPE)GY*i); + fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp); +}; + +fl_color(FL_YELLOW); +fl_font(FL_HELVETICA,10); +if (*nformant<pars->Pnumformants){ + draw_freq_line(pars->getformantfreq(pars->Pvowels[*nvowel].formants[*nformant].freq),2); + +//show some information (like current formant frequency,amplitude) + char tmpstr[20]; + + snprintf(tmpstr,20,"%.2f kHz",pars->getformantfreq(pars->Pvowels[*nvowel].formants[*nformant].freq)*0.001); + fl_draw(tmpstr,ox+1,oy+1,40,12,FL_ALIGN_LEFT,NULL,0); + + snprintf(tmpstr,20,"%d dB",(int)( rap2dB(1e-9 + pars->getformantamp(pars->Pvowels[*nvowel].formants[*nformant].amp)) + pars->getgain() )); + fl_draw(tmpstr,ox+1,oy+15,40,12,FL_ALIGN_LEFT,NULL,0); + +}; + +//draw the data + +fl_color(FL_RED); +fl_line_style(FL_SOLID); + +pars->formantfilterH(*nvowel,lx,graphpoints); + +oiy=(int) ((graphpoints[0]/maxdB+1.0)*ly/2.0); +for (i=1;i<lx;i++){ + int iy=(int) ((graphpoints[i]/maxdB+1.0)*ly/2.0); + if ((iy>=0)&&(oiy>=0)&&(iy<ly)&&(oiy<lx)) + fl_line(ox+i-1,oy+ly-oiy,ox+i,oy+ly-iy); + oiy=iy; +};} {} + } + Function {~FormantFilterGraph()} {} { + code {delete(graphpoints);} {} + } + decl {FilterParams *pars;} {} + decl {int oldx,oldy;} {} + decl {int *nvowel,*nformant;} {} + decl {REALTYPE *graphpoints;} {} +} + +class FilterUI {: {public Fl_Group,PresetsUI_} +} { + Function {FilterUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {pars=NULL; +velsnsamp=NULL; +velsns=NULL; +nvowel=0;nformant=0;nseqpos=0;} {} + } + Function {~FilterUI()} {} { + code {filterui->hide(); +formantparswindow->hide(); +hide(); +//delete (filterui); +delete (formantparswindow);} {} + } + Function {make_window()} {} { + Fl_Window filterui { + xywh {211 312 275 75} type Double color 50 labelfont 1 hide + class Fl_Group + } { + Fl_Group filterparamswindow { + label {Filter Parameters} + xywh {0 0 275 75} box PLASTIC_UP_BOX color 183 labeltype ENGRAVED_LABEL labelsize 11 align 17 + } { + Fl_Choice analogfiltertypechoice { + label FilterType + callback {pars->Ptype=(int)o->value(); +pars->changed=true;} + tooltip {The Filter type} xywh {10 50 50 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code1 {o->value(pars->Ptype);} + } { + menuitem {} { + label LPF1 + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label HPF1 + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LPF2 + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label HPF2 + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label BPF2 + xywh {82 82 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label NF2 + xywh {94 94 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label PkF2 + xywh {104 104 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LSh2 + xywh {114 114 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label HSh2 + xywh {124 124 100 20} labelfont 1 labelsize 10 + } + } + Fl_Choice svfiltertypechoice { + label FilterType + callback {pars->Ptype=(int)o->value(); +pars->changed=true;} + tooltip {The Filter type} xywh {10 50 50 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code1 {o->value(pars->Ptype);} + } { + menuitem {} { + label 1LPF + xywh {134 134 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 1HPF + xywh {144 144 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 1BPF + xywh {154 154 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 1NF + xywh {164 164 100 20} labelfont 1 labelsize 10 + } + } + Fl_Choice filtertype { + label Category + callback {switchcategory((int)o->value()); +pars->changed=true;} + tooltip {The Category of the Filter (Analog/Formantic/etc.)} xywh {10 20 60 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code0 {o->value(pars->Pcategory);} + } { + menuitem {} { + label Analog + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Formant + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label StVarF + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial cfreqdial { + label {C.Freq} + callback {pars->Pfreq=(int)o->value();} + tooltip {Center Frequency of the Filter or the base position in the vowel's sequence} xywh {75 25 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(pars->Pfreq);} + class WidgetPDial + } + Fl_Dial qdial { + label Q + callback {pars->Pq=(int)o->value(); +formantfiltergraph->redraw();} + tooltip {Filter resonance or bandwidth} xywh {110 25 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(pars->Pq);} + class WidgetPDial + } + Fl_Dial freqtrdial { + label {freq.tr.} + callback {pars->Pfreqtrack=(int) o->value();} + tooltip {Filter frequency tracking (left is negative, middle is 0, and right is positive)} xywh {215 25 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(pars->Pfreqtrack);} + class WidgetPDial + } + Fl_Dial vsnsadial { + label {V.SnsA.} + callback {if (velsnsamp!=NULL) *velsnsamp=(int)o->value();} + tooltip {Velocity sensing amount of the Filter} xywh {145 25 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial vsnsdial { + label {V.Sns.} + callback {if (velsns!=NULL) *velsns=(int)o->value();} + tooltip {Velocity Sensing Function of the Filter} xywh {180 25 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial gaindial { + label gain + callback {pars->Pgain=(int)o->value(); +formantfiltergraph->redraw(); +pars->changed=true;} + tooltip {Filter output gain/damp} xywh {250 35 20 20} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(pars->Pgain);} + class WidgetPDial + } + Fl_Choice stcounter { + label St + callback {pars->Pstages=(int)o->value(); +formantfiltergraph->redraw(); +pars->changed=true;} open + tooltip {Filter stages (in order to increase dB/oct. value and the order of the filter)} xywh {235 5 35 15} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10 + code1 {for (int i=0;i<MAX_FILTER_STAGES;i++) {char tmp[10];snprintf(tmp,10,"%dx",i+1);o->add(tmp);};} + code2 {o->value(pars->Pstages);} + } {} + } + Fl_Button editbutton { + label Edit + callback {formantparswindow->show();} + xywh {15 40 50 25} box PLASTIC_UP_BOX labelfont 1 labelsize 12 + } + Fl_Button {} { + label C + callback {presetsui->copy(pars);} + xywh {186 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this);} + xywh {203 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + Function {make_formant_window()} {} { + Fl_Window formantparswindow { + label {Formant Filter Parameters} + xywh {47 301 700 205} type Double hide + } { + Fl_Group {} { + xywh {485 47 105 113} box THIN_UP_BOX + } { + Fl_Counter {} { + label {Formant } + callback {nformant=(int) o->value(); +update_formant_window(); +formantfiltergraph->redraw();} + xywh {545 80 40 15} type Simple labelfont 1 labelsize 10 align 4 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->bounds(0,FF_MAX_FORMANTS-1);} + code1 {o->value(nformant);} + } + Fl_Counter {} { + label {Vowel no.} + callback {nvowel=(int) o->value(); +update_formant_window(); +formantfiltergraph->redraw();} + xywh {545 55 40 20} type Simple labelfont 1 labelsize 10 align 4 minimum 0 maximum 127 step 1 textfont 1 textsize 12 + code0 {o->bounds(0,FF_MAX_VOWELS-1);} + code1 {o->value(nvowel);} + } + Fl_Group formantparsgroup { + xywh {490 105 95 50} box ENGRAVED_FRAME + } { + Fl_Dial formant_freq_dial { + label freq + callback {pars->Pvowels[nvowel].formants[nformant].freq=(int) o->value(); +formantfiltergraph->redraw(); +pars->changed=true;} + tooltip {Formant frequency} xywh {495 115 25 25} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial formant_q_dial { + label Q + callback {pars->Pvowels[nvowel].formants[nformant].q=(int) o->value(); +formantfiltergraph->redraw(); +pars->changed=true;} + tooltip {Formant's Q} xywh {525 115 24 25} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial formant_amp_dial { + label amp + callback {pars->Pvowels[nvowel].formants[nformant].amp=(int) o->value(); +formantfiltergraph->redraw(); +pars->changed=true;} + tooltip {Formant amplitude} xywh {555 115 24 25} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + class WidgetPDial + } + } + } + Fl_Group {} { + xywh {590 47 100 113} box THIN_UP_BOX + } { + Fl_Counter {} { + label {Seq.Size} + callback {pars->Psequencesize=(int) o->value(); +update_formant_window(); +pars->changed=true;} + xywh {595 62 55 20} type Simple labelfont 1 labelsize 10 align 5 minimum 0 maximum 127 step 1 textfont 1 textsize 12 + code0 {o->bounds(1,FF_MAX_SEQUENCE-1);} + code1 {o->value(pars->Psequencesize);} + } + Fl_Counter {} { + label {S.Pos.} + callback {nseqpos=(int) o->value(); +update_formant_window(); +pars->changed=true;} + tooltip {Current position from the sequence} xywh {595 97 40 15} type Simple labelfont 1 labelsize 10 align 9 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->bounds(0,FF_MAX_SEQUENCE-2);} + code1 {o->value(nseqpos);} + } + Fl_Counter vowel_counter { + label Vowel + callback {pars->Psequence[nseqpos].nvowel=(int) o->value(); +pars->changed=true;} + xywh {640 97 40 15} type Simple labelsize 10 align 1 minimum 0 maximum 127 step 1 textsize 11 + code0 {o->bounds(0,FF_MAX_VOWELS-1);} + } + Fl_Check_Button {} { + label {Neg.Input} + callback {pars->Psequencereversed=(int) o->value(); +pars->changed=true;} + tooltip {Negate the input from LFO/envelopes/etc.} xywh {625 132 60 20} down_box DOWN_BOX labelsize 10 + code0 {o->value(pars->Psequencereversed);} + } + Fl_Dial strchdial { + label Strch + callback {pars->Psequencestretch=(int) o->value(); +pars->changed=true;} + tooltip {Sequence Stretch} xywh {595 130 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->Psequencestretch);} + class WidgetPDial + } + } + Fl_Counter {} { + label {Num.Formants} + callback {pars->Pnumformants=(int) o->value(); +update_formant_window(); +pars->changed=true; +formantfiltergraph->redraw();} + xywh {485 15 65 20} type Simple labelfont 1 labelsize 11 align 5 minimum 0 maximum 127 step 1 + code0 {o->bounds(1,FF_MAX_FORMANTS);} + code1 {o->value(pars->Pnumformants);} + } + Fl_Dial frsldial { + label {Fr.Sl.} + callback {pars->Pformantslowness=(int) o->value(); +pars->changed=true;} + tooltip {Formant's Slowness (Morphing)} xywh {565 15 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->Pformantslowness);} + class WidgetPDial + } + Fl_Value_Output centerfreqvo { + label {C.f.} + callback {o->value(pars->getcenterfreq()/1000.0);} + tooltip {Center Frequency (kHz)} xywh {515 164 33 18} when 3 minimum 1 maximum 10 step 0.01 value 1 textfont 1 + code0 {o->value(pars->getcenterfreq()/1000.0);} + } + Fl_Value_Output octavesfreqvo { + label {Oct.} + callback {o->value(pars->getoctavesfreq());} + tooltip {No. of octaves} xywh {515 182 33 18} when 3 minimum 1 maximum 127 step 1 value 5 textfont 1 + code0 {o->value(pars->getoctavesfreq());} + } + Fl_Slider cfknob { + callback {pars->Pcenterfreq=(int)o->value(); +centerfreqvo->do_callback(); +formantfiltergraph->redraw(); +pars->changed=true;} + xywh {551 167 84 15} type {Horz Knob} box FLAT_BOX maximum 127 + code0 {o->value(pars->Pcenterfreq);} + } + Fl_Slider octknob { + callback {pars->Poctavesfreq=(int)o->value(); +octavesfreqvo->do_callback(); +formantfiltergraph->redraw();} + xywh {551 185 84 15} type {Horz Knob} box FLAT_BOX maximum 127 + code0 {o->value(pars->Poctavesfreq);} + } + Fl_Box formantfiltergraph { + xywh {5 5 475 195} box BORDER_BOX + code0 {o->init(pars,&nvowel,&nformant);} + class FormantFilterGraph + } + Fl_Dial wvknob { + label {Vw.Cl.} + callback {pars->Pvowelclearness=(int) o->value(); +pars->changed=true;} + tooltip {Vowel "clearness" (how the mixed vowels are avoided)} xywh {600 15 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->Pvowelclearness);} + class WidgetPDial + } + Fl_Button {} { + label Close + callback {formantparswindow->hide();} + xywh {645 180 50 25} box THIN_UP_BOX + } + Fl_Button {} { + label C + callback {presetsui->copy(pars,nvowel);} + xywh {635 25 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this,nvowel);} + xywh {665 25 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Box {} { + label Vowel + xywh {635 10 55 15} + } + } + } + Function {update_formant_window()} {} { + code {formant_freq_dial->value(pars->Pvowels[nvowel].formants[nformant].freq); +formant_q_dial->value(pars->Pvowels[nvowel].formants[nformant].q); +formant_amp_dial->value(pars->Pvowels[nvowel].formants[nformant].amp); +if (nformant<pars->Pnumformants) formantparsgroup->activate(); + else formantparsgroup->deactivate(); + +if (nseqpos<pars->Psequencesize) vowel_counter->activate(); + else vowel_counter->deactivate(); + + +vowel_counter->value(pars->Psequence[nseqpos].nvowel);} {} + } + Function {refresh()} {} { + code {update_formant_window(); +formantfiltergraph->redraw(); + +if (pars->Pcategory==0) svfiltertypechoice->value(pars->Ptype); +if (pars->Pcategory==2) analogfiltertypechoice->value(pars->Ptype); + +filtertype->value(pars->Pcategory); + +cfreqdial->value(pars->Pfreq); +qdial->value(pars->Pq); + +freqtrdial->value(pars->Pfreqtrack); +gaindial->value(pars->Pgain); + +stcounter->value(pars->Pstages); + +int categ=pars->Pcategory; +if ((categ==0)||(categ==2)) { + if (categ==0) { + analogfiltertypechoice->show(); + svfiltertypechoice->hide(); + } else { + svfiltertypechoice->show(); + analogfiltertypechoice->hide(); + }; + editbutton->hide(); + formantparswindow->hide(); + cfreqdial->label("C.freq"); +} else { + analogfiltertypechoice->hide(); + svfiltertypechoice->hide(); + editbutton->show(); + cfreqdial->label("BS.pos"); +}; + +filterparamswindow->redraw();} {selected + } + } + Function {init(FilterParams *filterpars_,unsigned char *velsnsamp_,unsigned char *velsns_)} {} { + code {pars=filterpars_; +velsnsamp=velsnsamp_; +velsns=velsns_; + +make_window(); +end(); +make_formant_window(); + + +filterui->resize(this->x(),this->y(),this->w(),this->h()); + + +if (velsnsamp==NULL){ + vsnsadial->deactivate(); + vsnsadial->value(127); + } else vsnsadial->value(*velsnsamp); + +if (velsns==NULL){ + vsnsdial->deactivate(); + vsnsdial->value(127); + } else vsnsdial->value(*velsns); + +switchcategory(pars->Pcategory); + + +formantparswindow->label(this->label()); + +update_formant_window();} {} + } + Function {switchcategory(int newcat)} {} { + code {if (pars->Pcategory!=newcat){ + pars->Pgain=64; + gaindial->value(64); + analogfiltertypechoice->value(0); + analogfiltertypechoice->do_callback(); + svfiltertypechoice->value(0); + svfiltertypechoice->do_callback(); +}; +pars->Pcategory=newcat; + +refresh();} {} + } + Function {use_for_dynamic_filter()} {} { + code {freqtrdial->deactivate(); +gaindial->when(0); + +cfknob->when(FL_WHEN_RELEASE); +octknob->when(FL_WHEN_RELEASE); + +frsldial->when(0); +wvknob->when(0); +formant_freq_dial->when(0); +formant_q_dial->when(0); +formant_amp_dial->when(0); +strchdial->when(0);} {} + } + decl {FilterParams *pars;} {} + decl {unsigned char *velsnsamp,*velsns;} {} + decl {int nvowel,nformant,nseqpos;} {} +} diff --git a/muse/synti/zynaddsubfx/UI/LFOUI.fl b/muse/synti/zynaddsubfx/UI/LFOUI.fl new file mode 100644 index 00000000..373afc44 --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/LFOUI.fl @@ -0,0 +1,176 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0105 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include <FL/Fl_Group.H>} {public +} + +decl {\#include "../Params/LFOParams.h"} {public +} + +decl {\#include <FL/Fl_Box.H>} {public +} + +decl {\#include <FL/fl_draw.H>} {public +} + +decl {\#include <FL/fl_ask.H>} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class LFOUI {: {public Fl_Group, PresetsUI_} +} { + Function {LFOUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {pars=NULL;} {} + } + Function {~LFOUI()} {} { + code {lfoui->hide(); +hide(); +//delete (lfoui);} {} + } + Function {make_window()} {} { + Fl_Window lfoui { + xywh {66 328 230 70} type Double color 50 labelfont 1 hide + class Fl_Group + } { + Fl_Group lfoparamswindow { + label LFO + xywh {0 0 230 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 11 align 17 + } { + Fl_Dial freq { + label {Freq.} + callback {pars->Pfreq=o->value();} + tooltip {LFO Frequency} xywh {5 20 30 30} box ROUND_UP_BOX labelsize 11 step 1e-05 + class WidgetPDial + } + Fl_Dial intensity { + label Depth + callback {pars->Pintensity=(int)o->value();} + tooltip {LFO Amount} xywh {40 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial delay { + label Delay + callback {pars->Pdelay=(int)o->value();} + tooltip {LFO delay} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial startphase { + label Start + callback {pars->Pstartphase=(int)o->value();} + tooltip {LFO Startphase (leftmost is Random)} xywh {75 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial randomness { + label {A.R.} + callback {pars->Prandomness=(int)o->value();} + tooltip {LFO Amplitude Randomness} xywh {180 7 20 20} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Choice LFOtype { + label Type + callback {pars->PLFOtype=(int)o->value();} + tooltip {LFO function} xywh {180 40 45 15} down_box BORDER_BOX labelsize 10 align 2 textsize 8 + } { + menuitem {} { + label SINE + xywh {20 20 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label TRI + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label SQR + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {R.up} + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {R.dn} + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label E1dn + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label E2dn + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + } + Fl_Check_Button continous { + label {C.} + callback {pars->Pcontinous=(int)o->value();} + tooltip {Continous LFO} xywh {165 35 15 15} down_box DOWN_BOX labelsize 11 align 2 + } + Fl_Dial freqrand { + label {F.R.} + callback {pars->Pfreqrand=(int)o->value();} + tooltip {LFO Frequency Randomness} xywh {205 7 20 20} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial stretch { + label {Str.} + callback {pars->Pstretch=(int)o->value();} + tooltip {LFO stretch} xywh {144 30 20 20} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Button {} { + label C + callback {presetsui->copy(pars);} selected + xywh {145 10 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this);} selected + xywh {162 10 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + } + Function {refresh()} {} { + code {freq->value(pars->Pfreq); +intensity->value(pars->Pintensity); +startphase->value(pars->Pstartphase); +delay->value(pars->Pdelay); +continous->value(pars->Pcontinous); +stretch->value(pars->Pstretch); +randomness->value(pars->Prandomness); +freqrand->value(pars->Pfreqrand); +LFOtype->value(pars->PLFOtype);} {} + } + Function {init(LFOParams *lfopars_)} {} { + code {pars=lfopars_; + +make_window(); +end(); + +refresh(); + +lfoui->resize(this->x(),this->y(),this->w(),this->h()); + +lfoparamswindow->label(this->label());} {} + } + decl {LFOParams *pars;} {} +} diff --git a/muse/synti/zynaddsubfx/UI/MasterUI.fl b/muse/synti/zynaddsubfx/UI/MasterUI.fl new file mode 100644 index 00000000..384154ce --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/MasterUI.fl @@ -0,0 +1,1798 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <string.h>} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "ADnoteUI.h"} {public +} + +decl {\#include "SUBnoteUI.h"} {public +} + +decl {\#include "EffUI.h"} {public +} + +decl {\#include "VirKeyboard.h"} {public +} + +decl {\#include "ConfigUI.h"} {public +} + +decl {\#include "BankUI.h"} {public +} + +decl {\#include "PartUI.h"} {public +} + +decl {\#include "MicrotonalUI.h"} {public +} + +decl {\#include "SeqUI.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "../Misc/Part.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../globals.h"} {public +} + +class VUMeter {: {public Fl_Box} +} { + Function {VUMeter(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {master=NULL; +npart=-1;} {} + } + Function {init(Master *master_,int part_)} {} { + code {//the "part_" parameters sets the part (if it is >=0), else it sets the master +master=master_; +label(NULL); +npart=part_; +olddbl=0.0; +olddbr=0.0; +oldrmsdbl=0.0; +oldrmsdbr=0.0;} {} + } + Function {draw_master()} {} { + code {\#define MIN_DB (-48) + +int ox=x(); int oy=y(); int lx=w(); int ly=h(); + +pthread_mutex_lock(&master->mutex); +REALTYPE dbl=rap2dB(master->vuoutpeakl); +REALTYPE dbr=rap2dB(master->vuoutpeakr); +REALTYPE rmsdbl=rap2dB(master->vurmspeakl); +REALTYPE rmsdbr=rap2dB(master->vurmspeakr); +REALTYPE maxdbl=rap2dB(master->vumaxoutpeakl); +REALTYPE maxdbr=rap2dB(master->vumaxoutpeakr); +int clipped=master->vuclipped; +pthread_mutex_unlock(&master->mutex); + +dbl=(MIN_DB-dbl)/MIN_DB; +if (dbl<0.0) dbl=0.0; + else if (dbl>1.0)dbl=1.0; + +dbr=(MIN_DB-dbr)/MIN_DB; +if (dbr<0.0) dbr=0.0; + else if (dbr>1.0) dbr=1.0; + +dbl=dbl*0.4+olddbl*0.6; +dbr=dbr*0.4+olddbr*0.6; + +olddbl=dbl; +olddbr=dbr; + +\#define VULENX (lx-35) +\#define VULENY (ly/2-3) + +dbl*=VULENX;dbr*=VULENX; + +int idbl=(int) dbl; +int idbr=(int) dbr; + +//compute RMS - start +rmsdbl=(MIN_DB-rmsdbl)/MIN_DB; +if (rmsdbl<0.0) rmsdbl=0.0; + else if (rmsdbl>1.0) rmsdbl=1.0; + +rmsdbr=(MIN_DB-rmsdbr)/MIN_DB; +if (rmsdbr<0.0) rmsdbr=0.0; + else if (rmsdbr>1.0) rmsdbr=1.0; + +rmsdbl=rmsdbl*0.4+oldrmsdbl*0.6; +rmsdbr=rmsdbr*0.4+oldrmsdbr*0.6; + +oldrmsdbl=rmsdbl; +oldrmsdbr=rmsdbr; + + +rmsdbl*=VULENX;rmsdbr*=VULENX; + +int irmsdbl=(int) rmsdbl; +int irmsdbr=(int) rmsdbr; +//compute RMS - end + + + +//draw the vu-meter lines +//db +fl_rectf(ox,oy,idbr,VULENY,0,200,255); +fl_rectf(ox,oy+ly/2,idbl,VULENY,0,200,255); +//black +fl_rectf(ox+idbr,oy,VULENX-idbr,VULENY,0,0,0); +fl_rectf(ox+idbl,oy+ly/2,VULENX-idbl,VULENY,0,0,0); + +//draw the scales +REALTYPE tmp=VULENX*1.0/MIN_DB; +for (int i=1;i<1-MIN_DB;i++){ + int tx=VULENX+(int) (tmp*i); + fl_rectf(ox+tx,oy,1,VULENY+ly/2,0,160,200); + if (i%5==0) fl_rectf(ox+tx,oy,1,VULENY+ly/2,0,230,240); + if (i%10==0) fl_rectf(ox+tx-1,oy,2,VULENY+ly/2,0,225,255); +}; + +//rms +if (irmsdbr>2) fl_rectf(ox+irmsdbr-1,oy,3,VULENY,255,255,0); +if (irmsdbl>2) fl_rectf(ox+irmsdbl-1,oy+ly/2,3,VULENY,255,255,0); + + +//draw the red box if clipping has occured +if (clipped==0) fl_rectf(ox+VULENX+2,oy+1,lx-VULENX-3,ly-4,0,0,10); + else fl_rectf(ox+VULENX+2,oy+1,lx-VULENX-3,ly-4,250,10,10); + +//draw the maxdB +fl_font(FL_HELVETICA|FL_BOLD,10); +fl_color(255,255,255); +char tmpstr[10]; +if ((maxdbl>MIN_DB-20)){ + snprintf((char *)&tmpstr,10,"%ddB",(int)maxdbr); + fl_draw(tmpstr,ox+VULENX+1,oy+1,lx-VULENX-1,VULENY,FL_ALIGN_RIGHT,NULL,0); +}; +if ((maxdbr>MIN_DB-20)){ + snprintf((char *)&tmpstr,10,"%ddB",(int)maxdbl); + fl_draw(tmpstr,ox+VULENX+1,oy+ly/2+1,lx-VULENX-1,VULENY,FL_ALIGN_RIGHT,NULL,0); +};} {} + } + Function {draw_part()} {} { + code {\#define MIN_DB (-48) +int ox=x(); int oy=y(); int lx=w(); int ly=h(); + +if (!active_r()){ + pthread_mutex_lock(&master->mutex); + int fakedb=master->fakepeakpart[npart]; + pthread_mutex_unlock(&master->mutex); + fl_rectf(ox,oy,lx,ly,140,140,140); + if (fakedb>0){ + fakedb=(int)(fakedb/255.0*ly)+4; + fl_rectf(ox+2,oy+ly-fakedb,lx-4,fakedb,0,0,0); + }; + + return; +}; + +//draw the vu lines +pthread_mutex_lock(&master->mutex); + REALTYPE db=rap2dB(master->vuoutpeakpart[npart]); +pthread_mutex_unlock(&master->mutex); + +db=(MIN_DB-db)/MIN_DB; +if (db<0.0) db=0.0; + else if (db>1.0) db=1.0; + +db*=ly-2; + +int idb=(int) db; + +fl_rectf(ox,oy+ly-idb,lx,idb,0,200,255); +fl_rectf(ox,oy,lx,ly-idb,0,0,0); + + +//draw the scales +REALTYPE tmp=ly*1.0/MIN_DB; + for (int i=1;i<1-MIN_DB;i++){ + int ty=ly+(int) (tmp*i); + if (i%5==0) fl_rectf(ox,oy+ly-ty,lx,1,0,160,200); + if (i%10==0) fl_rectf(ox,oy+ly-ty,lx,1,0,230,240); +};} {} + } + Function {draw()} {} { + code {if (npart>=0) draw_part(); + else draw_master();} {} + } + Function {tickdraw(VUMeter *o)} {return_type {static void} + } { + code {o->redraw();} {} + } + Function {tick(void *v)} {return_type {static void} + } { + code {tickdraw((VUMeter *) v); +Fl::add_timeout(1.0/25.0,tick,v);//25 fps} {} + } + Function {handle(int event)} {return_type int + } { + code {switch(event){ + case FL_SHOW: + tick(this); + break; + case FL_HIDE: + Fl::remove_timeout(tick,this); + break; + case FL_PUSH: + if (npart>=0) break; + pthread_mutex_lock(&master->mutex); + master->vuresetpeaks(); + pthread_mutex_unlock(&master->mutex); + break; +}; +return(1);} {} + } + decl {Master *master;} {} + decl {int npart;} {} + decl {float olddbl,olddbr;} {} + decl {float oldrmsdbl,oldrmsdbr;} {} +} + +class SysEffSend {: {public WidgetPDial} +} { + Function {SysEffSend(int x,int y, int w, int h, const char *label=0):WidgetPDial(x,y,w,h,label)} {} { + code {master=NULL; +neff1=0; +neff2=0;} {} + } + Function {init(Master *master_,int neff1_,int neff2_)} {} { + code {neff1=neff1_; +neff2=neff2_; +master=master_; +minimum(0); +maximum(127); +step(1); +labelfont(1); +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));} {} + } + Function {~SysEffSend()} {} { + code {hide();} {} + } + Function {handle(int event)} {return_type int + } { + code {if ((event==FL_PUSH) || (event==FL_DRAG)){ + master->setPsysefxsend(neff1,neff2,(int) value()); +}; + +return(WidgetPDial::handle(event));} {} + } + decl {Master *master;} {} + decl {int neff1;} {} + decl {int neff2;} {} +} + +class Panellistitem {: {public Fl_Group} +} { + Function {make_window()} {private + } { + Fl_Window panellistitem { + private xywh {315 213 70 260} type Double hide + class Fl_Group + } { + Fl_Group panellistitemgroup { + private xywh {0 20 70 240} box PLASTIC_THIN_UP_BOX + code0 {if (master->part[npart]->Penabled==0) o->deactivate();} + } { + Fl_Group {} { + xywh {45 65 15 110} box ENGRAVED_FRAME + } { + Fl_Box {} { + label {V U} + xywh {45 65 15 110} box FLAT_BOX color 0 selection_color 75 labelcolor 55 align 128 + code0 {o->init(master,npart);} + class VUMeter + } + } + Fl_Button partname { + label { } + callback {if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); +}; +bankui->show();} + xywh {5 27 60 30} box THIN_DOWN_BOX down_box FLAT_BOX labelfont 1 labelsize 10 align 208 + } + Fl_Slider partvolume { + callback {master->part[npart]->setPvolume((int) o->value());} + xywh {10 65 30 110} type {Vert Knob} box FLAT_BOX minimum 127 maximum 0 step 1 value 127 + code0 {o->value(master->part[npart]->Pvolume);} + } + Fl_Dial partpanning { + callback {master->part[npart]->setPpanning((int) o->value());} + xywh {20 180 30 30} maximum 127 step 1 + code0 {o->value(master->part[npart]->Ppanning);} + class WidgetPDial + } + Fl_Button {} { + label edit + callback {if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); +};} + xywh {15 235 40 20} box PLASTIC_UP_BOX labelsize 10 + } + Fl_Choice partrcv { + callback {master->part[npart]->Prcvchn=(int) o->value();} open + 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;i<NUM_MIDI_CHANNELS;i++){sprintf(nrstr,"Ch%d",i+1);if (i!=9) o->add(nrstr); else o->add("Dr10");};} + code1 {o->value(master->part[npart]->Prcvchn);} + } {} + } + Fl_Check_Button partenabled { + label 01 + callback {pthread_mutex_lock(&master->mutex); + master->partonoff(npart,(int) o->value()); +pthread_mutex_unlock(&master->mutex); + +if ((int) o->value()==0) panellistitemgroup->deactivate(); + else { + panellistitemgroup->activate(); + if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); + }; +}; + +o->redraw();} + private xywh {5 0 45 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 24 + code0 {char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp));} + code1 {o->value(master->part[npart]->Penabled);} + } + } + } + Function {Panellistitem(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {npart=0; +master=NULL; +bankui=NULL;} {} + } + Function {init(Master *master_, int npart_,BankUI *bankui_)} {} { + code {npart=npart_; +master=master_; +bankui=bankui_; + +make_window(); +panellistitem->show(); +end();} {} + } + Function {refresh()} {open + } { + code {partenabled->value(master->part[npart]->Penabled); +if (master->part[npart]->Penabled!=0) panellistitemgroup->activate(); + else panellistitemgroup->deactivate(); + +partvolume->value(master->part[npart]->Pvolume); +partpanning->value(master->part[npart]->Ppanning); +partrcv->value(master->part[npart]->Prcvchn); + +partname->label((char *)master->part[npart]->Pname); + +if ((int)bankui->cbwig->value()!=(npart+1)) + panellistitemgroup->color(fl_rgb_color(160,160,160)); +else + panellistitemgroup->color(fl_rgb_color(50,190,240)); + +panellistitemgroup->redraw();} {} + } + Function {~Panellistitem()} {} { + code {panellistitem->hide(); +//delete(panellistitem);} {} + } + decl {int npart;} {} + decl {Master *master;} {} + decl {BankUI *bankui;} {} +} + +class MasterUI {} { + Function {make_window()} {} { + Fl_Window masterwindow { + label zynaddsubfx + callback {\#ifdef VSTAUDIOOUT +fl_alert("ZynAddSubFX could not be closed this way, because it's a VST plugin. Please use the host aplication to close it."); +\#else +if (fl_ask("Exit and leave the unsaved data?")) { + config.save(); + *exitprogram=1; +}; +\#endif} selected + xywh {353 127 390 465} type Double hide + } { + Fl_Menu_Bar mastermenu { + xywh {-5 0 690 25} + } { + submenu {} { + label {&File} + xywh {0 0 100 20} + } { + menuitem {} { + label {&New (erase all)...} + callback {do_new_master();} + xywh {20 20 100 20} + } + menuitem {} { + label {&Open Parameters...} + callback {do_load_master();} + xywh {20 20 100 20} + } + menuitem {} { + label {&Save All Parameters...} + callback {do_save_master();} + xywh {10 10 100 20} divider + } + menuitem {} { + label {&Load Scale Settings...} + callback {char *filename; +filename=fl_file_chooser("Open:","({*.xsz})",NULL,0); +if (filename==NULL) return; + +pthread_mutex_lock(&master->mutex); + //clear all parameters + master->microtonal.defaults(); + + //load the data + int result=master->microtonal.loadXML(filename); +pthread_mutex_unlock(&master->mutex); + + + delete microtonalui; + microtonalui=new MicrotonalUI(&master->microtonal); + +if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not a scale file."); + else if (result<0) fl_alert("Error: Could not load the file.");} + xywh {35 35 100 20} + } + menuitem {} { + label {Save Sc&ale Settings ..} + callback {char *filename; +int result=0; + +filename=fl_file_chooser("Save:","({*.xsz})",NULL,0); +if (filename==NULL) return; +filename=fl_filename_setext(filename,".xsz"); + +result=fileexists(filename); +if (result) { + result=0; + if (!fl_ask("The file exists. \\nOverwrite it?")) return; + +}; + + +pthread_mutex_lock(&master->mutex); +result=master->microtonal.saveXML(filename); +pthread_mutex_unlock(&master->mutex); + +if (result<0) fl_alert("Error: Could not save the file."); + + +updatepanel();} + xywh {25 25 100 20} + } + menuitem {} { + label {Show Scale Settings...} + callback {microtonalui->show();} + xywh {0 0 100 20} divider + } + menuitem {} { + label {&Settings...} + callback {configui->show();} + xywh {25 25 100 20} divider + } + menuitem {} { + label {&Copyright...} + callback {aboutwindow->show();} + xywh {15 15 100 20} divider + } + menuitem {} { + label {E&xit} + callback {masterwindow->do_callback();} + xywh {10 10 100 20} + } + } + submenu {} { + label {&Instrument} + xywh {10 10 100 20} + } { + menuitem {} { + label {&Clear Instrument...} + callback {if (fl_ask("Clear instrument's parameters ?")){ +// int npart=(int)npartcounter->value()-1; + pthread_mutex_lock(&master->mutex); + master->part[npart]->defaultsinstrument(); + pthread_mutex_unlock(&master->mutex); + + npartcounter->do_callback(); +}; + +updatepanel();} + xywh {35 35 100 20} + } + menuitem {} { + label {&Open Instrument...} + callback {const char *filename; +filename=fl_file_chooser("Load:","({*.xiz})",NULL,0); +if (filename==NULL) return; + + +pthread_mutex_lock(&master->mutex); +// int npart=(int)npartcounter->value()-1; + + //clear all instrument parameters, first + master->part[npart]->defaultsinstrument(); + + //load the instr. parameters + int result=master->part[npart]->loadXMLinstrument(filename); + +pthread_mutex_unlock(&master->mutex); +master->part[npart]->applyparameters(); + +npartcounter->do_callback(); +updatepanel(); + +if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not an instrument file."); + else if (result<0) fl_alert("Error: Could not load the file.");} + xywh {30 30 100 20} + } + menuitem {} { + label {&Save Instrument ...} + callback {char *filename; + +filename=fl_file_chooser("Save:","({*.xiz})",NULL,0); +if (filename==NULL) return; +filename=fl_filename_setext(filename,".xiz"); + +int result=fileexists(filename); +if (result) { + result=0; + if (!fl_ask("The file exists. \\nOverwrite it?")) return; + +}; + + +pthread_mutex_lock(&master->mutex); +result=master->part[npart]->saveXML(filename); +pthread_mutex_unlock(&master->mutex); + +if (result<0) fl_alert("Error: Could not save the file."); + +updatepanel();} + xywh {20 20 100 20} divider + } + menuitem {} { + label {Show Instrument &Bank...} + callback {bankui->show();} + xywh {0 0 100 20} divider + } + menuitem {} { + label {&Virtual Keyboard...} + callback {virkeyboard->show();} + xywh {10 10 100 20} + } + } + submenu recordmenu { + label {&Record} + xywh {0 0 100 20} + } { + menuitem {} { + label {&Choose WAV file...} + callback {char *filename; +recordbutton->deactivate(); +pausebutton->deactivate(); +pauselabel->deactivate(); +stopbutton->deactivate(); +filename=fl_file_chooser("Record to audio file:","(*.wav)",NULL,0); +if (filename==NULL) return; +fl_filename_setext(filename,".wav"); + +int result=master->HDDRecorder.preparefile(filename,0); +if (result==1) { + result=0; + if (fl_ask("The file exists. \\nOverwrite it?")) + master->HDDRecorder.preparefile(filename,1); +}; +if (result==0) recordbutton->activate(); + +if (result!=0) fl_alert("Error: Could not save the file.");} + xywh {0 0 100 20} + } + } + submenu {} { + label {&Sequencer} + xywh {0 0 100 20} hide + } { + menuitem {} { + label {Show &Sequencer...} + callback {sequi->show();} + xywh {0 0 100 20} + } + } + submenu {} { + label Misc + xywh {10 10 100 20} + } { + menuitem {} { + label {Switch User Interface Mode} + callback {if (fl_ask("Switch the User Interface to Beginner mode ?")){ + masterwindow->hide(); + refresh_master_ui(); + simplemasterwindow->show(); + config.cfg.UserInterfaceMode=2; +};} + xywh {10 10 100 20} + } + } + } + Fl_Dial mastervolumedial { + label {M.Vol} + callback {master->setPvolume((int) o->value());} + tooltip {Master Volume} xywh {5 30 30 30} box ROUND_UP_BOX labelfont 1 labelsize 12 align 130 maximum 127 step 1 + code0 {o->value(master->Pvolume);} + class WidgetPDial + } + Fl_Counter masterkeyshiftcounter { + label {Master KeyShift} + callback {master->setPkeyshift((int) o->value()+64);} + xywh {45 31 90 20} labelsize 12 minimum -64 maximum 64 step 1 + code0 {o->lstep(12);} + code1 {o->value(master->Pkeyshift-64);} + } + Fl_Button {} { + label {Panic!} + callback {virkeyboard->relaseallkeys(); +pthread_mutex_lock(&master->mutex); +master->shutup=1; +pthread_mutex_unlock(&master->mutex);} + xywh {293 29 92 31} box PLASTIC_UP_BOX color 231 labelfont 1 + } + Fl_Group partuigroup { + xywh {0 242 390 183} box ENGRAVED_FRAME + } { + Fl_Group partui { + xywh {4 245 383 175} box FLAT_BOX + code0 {o->init(master->part[0],master,0,bankui);} + code1 {o->show();} + class PartUI + } {} + } + Fl_Tabs {} { + xywh {0 80 390 160} + } { + Fl_Group {} { + label {System Effects} open + xywh {0 100 390 140} box ENGRAVED_FRAME labeltype EMBOSSED_LABEL labelsize 18 align 25 + } { + Fl_Counter syseffnocounter { + label {Sys.Effect No.} + callback {nsyseff=(int) o->value()-1; +sysefftype->value(master->sysefx[nsyseff]->geteffect()); +syseffectui->refresh(master->sysefx[nsyseff]);} + xywh {5 120 80 20} type Simple labelfont 1 labelsize 11 align 1 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_SYS_EFX);} + code1 {o->value(nsyseff+1);} + } + Fl_Choice sysefftype { + label EffType + callback {pthread_mutex_lock(&master->mutex); +master->sysefx[nsyseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +syseffectui->refresh(master->sysefx[nsyseff]);} + xywh {315 125 70 15} down_box BORDER_BOX labelsize 11 + code0 {o->value(master->sysefx[nsyseff]->geteffect());} + } { + menuitem {} { + label {No Effect} + xywh {10 10 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Reverb + xywh {20 20 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Echo + xywh {30 30 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Chorus + xywh {40 40 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Phaser + xywh {50 50 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label AlienWah + xywh {60 60 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Distortion + xywh {70 70 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label EQ + xywh {80 80 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label DynFilter + xywh {90 90 100 20} labelfont 1 labelsize 11 + } + } + Fl_Group syseffectuigroup { + xywh {5 140 380 95} box FLAT_BOX color 48 + } { + Fl_Group syseffectui { + xywh {5 140 380 95} + code0 {o->init(master->sysefx[nsyseff]);} + class EffUI + } {} + } + Fl_Button {} { + label {Send to...} + callback {syseffsendwindow->show();} + xywh {95 120 75 20} box THIN_UP_BOX labelfont 1 labelsize 12 + } + Fl_Button {} { + label C + callback {presetsui->copy(master->sysefx[nsyseff]);} + xywh {215 124 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Button {} { + label P + callback {pthread_mutex_lock(&master->mutex); +presetsui->paste(master->sysefx[nsyseff],syseffectui); +pthread_mutex_unlock(&master->mutex);} + xywh {245 124 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + } + Fl_Group {} { + label {Insertion Effects} + xywh {0 100 390 140} box ENGRAVED_FRAME labeltype EMBOSSED_LABEL labelsize 18 align 25 hide + } { + Fl_Counter inseffnocounter { + label {Ins.Effect No.} + callback {ninseff=(int) o->value()-1; +insefftype->value(master->insefx[ninseff]->geteffect()); +inseffpart->value(master->Pinsparts[ninseff]+2); +inseffectui->refresh(master->insefx[ninseff]); + +if (master->Pinsparts[ninseff]!=-1) { + insefftype->activate(); + inseffectui->activate(); + inseffectuigroup->activate(); +} else { + insefftype->deactivate(); + inseffectui->deactivate(); + inseffectuigroup->deactivate(); +};} + xywh {5 120 80 20} type Simple labelfont 1 labelsize 11 align 1 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_INS_EFX);} + code1 {o->value(ninseff+1);} + } + Fl_Choice insefftype { + label EffType + callback {pthread_mutex_lock(&master->mutex); +master->insefx[ninseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +inseffectui->refresh(master->insefx[ninseff]); +inseffectui->show();} + xywh {315 125 70 15} down_box BORDER_BOX labelsize 11 + code0 {o->value(master->insefx[ninseff]->geteffect());} + code1 {if (master->Pinsparts[ninseff]== -1) o->deactivate();} + } { + menuitem {} { + label {No Effect} + xywh {25 25 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Reverb + xywh {35 35 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Echo + xywh {45 45 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Chorus + xywh {55 55 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Phaser + xywh {60 60 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label AlienWah + xywh {70 70 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Distortion + xywh {80 80 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label EQ + xywh {90 90 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label DynFilter + xywh {100 100 100 20} labelfont 1 labelsize 11 + } + } + Fl_Group inseffectuigroup { + xywh {5 140 380 95} box FLAT_BOX color 48 + } { + Fl_Group inseffectui { + xywh {5 140 380 95} + code0 {o->init(master->insefx[ninseff]);} + code1 {if (master->Pinsparts[ninseff]== -1) o->deactivate();} + class EffUI + } {} + } + Fl_Choice inseffpart { + label {Insert To.} + callback {master->Pinsparts[ninseff]=(int) o->value()-2; +if ((int) o->value()==1){ + inseffectuigroup->deactivate(); + insefftype->deactivate(); + inseffectui->deactivate(); +} else { + inseffectuigroup->activate(); + insefftype->activate(); + inseffectui->activate(); +}; +master->insefx[ninseff]->cleanup();} open + xywh {95 120 80 20} down_box BORDER_BOX labelfont 1 labelsize 10 align 5 textsize 10 + code0 {o->add("Master Out");o->add("Off");} + code1 {char tmp[50]; for (int i=0;i<NUM_MIDI_PARTS;i++) {sprintf(tmp,"Part %2d",i+1);o->add(tmp);};} + code3 {o->value(master->Pinsparts[ninseff]+2);} + } {} + Fl_Button {} { + label C + callback {presetsui->copy(master->insefx[ninseff]);} + xywh {215 124 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Button {} { + label P + callback {pthread_mutex_lock(&master->mutex); +presetsui->paste(master->insefx[ninseff],inseffectui); +pthread_mutex_unlock(&master->mutex);} + xywh {245 124 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + } + } + Fl_Button {} { + label Scales + callback {microtonalui->show();} + xywh {330 80 56 19} box PLASTIC_UP_BOX color 231 labeltype ENGRAVED_LABEL labelfont 1 + } + Fl_Group {} { + xywh {172 30 117 45} box ENGRAVED_BOX + } { + Fl_Button recordbutton { + label {Rec.} + callback {o->deactivate(); +recordmenu->deactivate(); +recordmenu->label("&Record(*)"); +stopbutton->activate(); +pausebutton->activate(); +pauselabel->activate(); +master->HDDRecorder.start(); +master->vuresetpeaks(); +mastermenu->redraw();} + tooltip {Start Recording} xywh {181 36 21 21} box ROUND_UP_BOX color 88 labelfont 1 labelsize 10 align 2 deactivate + } + Fl_Button stopbutton { + label Stop + callback {o->deactivate(); +master->HDDRecorder.stop(); +recordbutton->deactivate(); +pausebutton->deactivate(); +pauselabel->deactivate(); +recordmenu->activate(); +recordmenu->label("&Record"); +mastermenu->redraw();} + tooltip {Stop Recording and close the audio file} xywh {259 36 21 21} box THIN_UP_BOX color 4 labelfont 1 labelsize 10 align 2 deactivate + } + Fl_Button pausebutton { + label {@||} + callback {o->deactivate(); +master->HDDRecorder.pause(); +recordbutton->activate(); +mastermenu->redraw();} + tooltip {Pause Recording} xywh {220 36 21 21} box THIN_UP_BOX color 4 selection_color 4 labelfont 1 labelcolor 3 align 16 deactivate + } + Fl_Box pauselabel { + label Pause + xywh {214 56 30 15} labelfont 1 labelsize 10 deactivate + } + } + Fl_Group {} { + xywh {1 427 389 33} box ENGRAVED_FRAME + } { + Fl_Box {} { + label {VU-Meter} + xywh {4 430 384 30} box FLAT_BOX color 48 selection_color 75 + code0 {o->init(master,-1);} + class VUMeter + } + } + Fl_Check_Button nrpnbutton { + label NRPN + callback {master->ctl.NRPN.receive=(int) o->value();} + tooltip {Receive NRPNs} xywh {45 65 47 10} down_box DOWN_BOX labelsize 10 + code0 {o->value(master->ctl.NRPN.receive);} + } + Fl_Counter npartcounter { + callback {int nval=(int) o->value()-1; +partuigroup->remove(partui); +delete partui; +partui=new PartUI(0,0,765,525); +partuigroup->add(partui); +partui->init(master->part[nval],master,nval,bankui); +partui->redraw(); +o->redraw(); +npart=nval; + +updatepanel(); +simplenpartcounter->value(nval+1); +simplenpartcounter->do_callback();} + tooltip {The part number} xywh {5 247 70 23} type Simple labelfont 1 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_MIDI_PARTS);} + code1 {bankui->init(o);} + } + Fl_Button {} { + label vK + callback {virkeyboard->show();} + tooltip {Virtual Keyboard} xywh {292 80 35 19} box PLASTIC_UP_BOX color 231 labeltype ENGRAVED_LABEL labelfont 1 + } + Fl_Button {} { + label {R.D.} + callback {globalfinedetuneslider->value(64.0); +globalfinedetuneslider->do_callback();} + tooltip {Master fine detune reset} xywh {140 65 30 10} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Dial globalfinedetuneslider { + label {F.Det.} + callback {master->microtonal.Pglobalfinedetune=(int) o->value();} + tooltip {global fine detune} xywh {143 30 20 20} box ROUND_UP_BOX labelsize 10 align 130 maximum 127 step 1 value 64 + code0 {o->value(master->microtonal.Pglobalfinedetune);} + class WidgetPDial + } + Fl_Button {} { + label {Panel Window} + callback {updatepanel(); +panelwindow->show();} + tooltip {Panel Window} xywh {293 62 92 16} box PLASTIC_UP_BOX color 183 labelfont 1 labelsize 10 + } + } + Fl_Window aboutwindow { + label {Copyright...} + xywh {629 278 330 210} type Double hide + } { + Fl_Box {} { + label {Copyright (c) 2002-2005 Nasca O. Paul} + xywh {5 35 320 25} labeltype EMBOSSED_LABEL labelsize 18 align 16 + } + Fl_Box {} { + label {This is free software; you may redistribute it and/or modify it under the terms of the +version 2 of the GNU General Public License as published by the Free Software Fundation. + This program comes with + ABSOLUTELY NO WARRANTY. + See the version 2 of the +GNU General Public License for details.} + xywh {0 60 325 115} labelfont 1 labelsize 12 align 144 + } + Fl_Button {} { + label {Close this window} + callback {aboutwindow->hide();} + xywh {80 180 180 25} box THIN_UP_BOX labelsize 12 + } + Fl_Box {} { + label ZynAddSubFX + xywh {5 5 325 30} labeltype EMBOSSED_LABEL labelfont 1 labelsize 24 labelcolor 0 align 16 + } + } + Fl_Window syseffsendwindow { + label {System Effects Send} + xywh {171 234 120 250} type Double hide resizable + } { + Fl_Scroll {} {open + xywh {0 45 120 170} box FLAT_BOX resizable + code0 {for (int neff1=0;neff1<NUM_SYS_EFX;neff1++) for (int neff2=neff1+1;neff2<NUM_SYS_EFX;neff2++)} + code1 {{syseffsend[neff1][neff2]=new SysEffSend(o->x()+(neff2-1)*35,o->y()+15+neff1*50,30,30);syseffsend[neff1][neff2]->label("aaa");syseffsend[neff1][neff2]->init(master,neff1,neff2);};} + } {} + Fl_Button {} { + label Close + callback {syseffsendwindow->hide();} + xywh {25 220 80 25} box THIN_UP_BOX + } + Fl_Box {} { + label {Send system effect's output to other system effects} + xywh {5 5 110 35} labelsize 10 align 192 + } + } + Fl_Window panelwindow { + label {ZynAddSubFX Panel} + xywh {72 60 630 635} type Double hide + } { + Fl_Scroll {} {open + xywh {0 5 570 310} type HORIZONTAL box THIN_UP_BOX + } { + Fl_Pack {} {open + xywh {5 10 560 285} type HORIZONTAL + code0 {for (int i=0;i<NUM_MIDI_PARTS/2;i++){panellistitem[i]=new Panellistitem(0,0,70,260,"");panellistitem[i]->init(master,i,bankui);}} + } {} + } + Fl_Scroll {} {open + xywh {0 320 570 310} type HORIZONTAL box THIN_UP_BOX + } { + Fl_Pack {} {open + xywh {5 325 560 285} type HORIZONTAL + code0 {for (int i=NUM_MIDI_PARTS/2;i<NUM_MIDI_PARTS;i++){panellistitem[i]=new Panellistitem(0,0,70,260,"");panellistitem[i]->init(master,i,bankui);}} + } {} + } + Fl_Button {} { + label Close + callback {panelwindow->hide(); +updatepanel();} + xywh {575 605 50 25} box THIN_UP_BOX + } + Fl_Button {} { + label Refresh + callback {updatepanel();} + xywh {575 570 55 25} box THIN_UP_BOX + } + } + Fl_Window simplemasterwindow { + label ZynAddSubFX + callback {\#ifdef VSTAUDIOOUT +fl_alert("ZynAddSubFX could not be closed this way, because it's a VST plugin. Please use the host aplication to close it."); +\#else +if (fl_ask("Exit and leave the unsaved data?")) { + config.save(); + *exitprogram=1; +}; +\#endif} + xywh {135 383 600 335} type Double hide + } { + Fl_Menu_Bar {} { + xywh {0 0 690 25} + } { + submenu {} { + label {&File} + xywh {10 10 100 20} + } { + menuitem {} { + label {&New (erase all)...} + callback {do_new_master();} + xywh {30 30 100 20} + } + menuitem {} { + label {&Open Parameters...} + callback {do_load_master();} + xywh {30 30 100 20} + } + menuitem {} { + label {&Save All Parameters...} + callback {do_save_master();} + xywh {20 20 100 20} divider + } + menuitem {} { + label {&Settings...} + callback {configui->show();} + xywh {35 35 100 20} divider + } + menuitem {} { + label {&Copyright...} + callback {aboutwindow->show();} + xywh {25 25 100 20} divider + } + menuitem {} { + label {E&xit} + callback {masterwindow->do_callback();} + xywh {20 20 100 20} + } + } + submenu {} { + label {&Instrument} + xywh {20 20 100 20} + } { + menuitem {} { + label {&Open Instrument...} + callback {const char *filename; +filename=fl_file_chooser("Load:","({*.xiz})",NULL,0); +if (filename==NULL) return; + + +pthread_mutex_lock(&master->mutex); +// int npart=(int)npartcounter->value()-1; + + //clear all instrument parameters, first + master->part[npart]->defaultsinstrument(); + + //load the instr. parameters + int result=master->part[npart]->loadXMLinstrument(filename); + +pthread_mutex_unlock(&master->mutex); +master->part[npart]->applyparameters(); + +simplenpartcounter->do_callback(); + +if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not an instrument file."); + else if (result<0) fl_alert("Error: Could not load the file.");} + xywh {40 40 100 20} + } + menuitem {} { + label {Show Instrument &Bank...} + callback {bankui->show();} + xywh {10 10 100 20} divider + } + } + submenu {} { + label Misc + xywh {0 0 100 20} + } { + menuitem {} { + label {Switch User Interface Mode} + callback {if (fl_ask("Switch the User Interface to Advanced mode ?")){ + simplemasterwindow->hide(); + refresh_master_ui(); + masterwindow->show(); + config.cfg.UserInterfaceMode=1; +};} + xywh {0 0 100 20} + } + } + } + Fl_Group simplelistitemgroup { + private xywh {125 65 215 150} box ENGRAVED_BOX + code0 {if (master->part[npart]->Penabled==0) o->deactivate();} + } { + Fl_Button partname { + callback {if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); +}; +bankui->show();} + xywh {130 72 205 18} box PLASTIC_THIN_DOWN_BOX down_box FLAT_BOX color 247 labelfont 1 labelsize 12 align 208 + } + Fl_Slider partpanning { + label Pan + callback {master->part[npart]->setPpanning((int) o->value());} + xywh {185 95 70 15} type {Horz Knob} box FLAT_BOX maximum 127 step 1 value 64 + code0 {o->value(master->part[npart]->Ppanning);} + } + Fl_Choice partrcv { + label {Midi Channel Receive} + callback {virkeys->relaseallkeys(0); +master->part[npart]->Prcvchn=(int) o->value(); +virkeys->midich=(int) o->value();} open + tooltip {receive from Midi channel} xywh {140 157 65 18} down_box BORDER_BOX labelsize 11 align 130 textfont 1 + code0 {char nrstr[10]; for(int i=0;i<NUM_MIDI_CHANNELS;i++){sprintf(nrstr,"Ch%d",i+1);if (i!=9) o->add(nrstr); else o->add("Dr10");};} + code1 {o->value(master->part[npart]->Prcvchn);} + } {} + Fl_Dial partvolume { + callback {master->part[npart]->setPvolume((int) o->value());} + xywh {145 95 30 30} maximum 127 step 1 + code0 {o->value(master->part[npart]->Pvolume);} + class WidgetPDial + } + Fl_Box {} { + label Volume + xywh {130 125 60 15} + } + Fl_Check_Button simplepartportamento { + label Portamento + callback {master->part[npart]->ctl.portamento.portamento=(int) o->value();} + tooltip {Enable/Disable the portamento} xywh {260 95 75 20} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(master->part[npart]->ctl.portamento.portamento);} + } + Fl_Counter simpleminkcounter { + label {Min.key} + callback {master->part[npart]->Pminkey=(int) o->value(); +if (master->part[npart]->Pminkey>master->part[npart]->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK);} + tooltip {Minimum key (that the part receives NoteOn messages)} xywh {210 158 40 15} type Simple labelfont 1 labelsize 10 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->value(master->part[npart]->Pminkey);} + } + Fl_Counter simplemaxkcounter { + label {Max.key} + callback {master->part[npart]->Pmaxkey=(int) o->value(); + +if (master->part[npart]->Pminkey>master->part[npart]->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK);} + tooltip {Maximum key (that the part receives NoteOn messages)} xywh {255 158 40 15} type Simple labelfont 1 labelsize 10 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->value(master->part[npart]->Pmaxkey);} + } + Fl_Button {} { + label m + callback {if (master->part[npart]->lastnote>=0) simpleminkcounter->value(master->part[npart]->lastnote); +simpleminkcounter->do_callback(); +simplemaxkcounter->do_callback();} + tooltip {set the minimum key to the last pressed key} xywh {230 188 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label M + callback {if (master->part[npart]->lastnote>=0) simplemaxkcounter->value(master->part[npart]->lastnote); +simplemaxkcounter->do_callback(); +simpleminkcounter->do_callback();} + tooltip {set the maximum key to the last pressed key} xywh {260 188 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label R + callback {simpleminkcounter->value(0); +simpleminkcounter->do_callback(); +simplemaxkcounter->value(127); +simplemaxkcounter->do_callback();} + tooltip {reset the minimum key to 0 and maximum key to 127} xywh {245 188 15 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Counter simplepartkeyshiftcounter { + label KeyShift + callback {master->part[npart]->Pkeyshift=(int) o->value()+64;} + xywh {240 120 90 20} labelsize 12 minimum -64 maximum 64 step 1 + code0 {o->lstep(12);} + code1 {o->value(master->part[npart]->Pkeyshift-64);} + } + Fl_Dial simplesyseffsend { + callback {master->setPsysefxvol(npart,nsyseff,(int) o->value());} + xywh {300 160 30 30} maximum 127 step 1 + class WidgetPDial + } + Fl_Box {} { + label Effect + xywh {295 190 40 15} + } + } + Fl_Check_Button partenabled { + label Enabled + callback {pthread_mutex_lock(&master->mutex); + master->partonoff(npart,(int) o->value()); +pthread_mutex_unlock(&master->mutex); + +if ((int) o->value()==0) simplelistitemgroup->deactivate(); + else { + simplelistitemgroup->activate(); + if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); + }; +}; + +o->redraw();} + private xywh {250 40 85 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 24 + code0 {//char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp));} + code1 {o->value(master->part[npart]->Penabled);} + } + Fl_Box virkeys { + label Keyboard + xywh {5 215 590 80} box BORDER_BOX color 17 + code0 {o->init(master);} + class VirKeys + } + Fl_Group {} { + xywh {340 30 255 185} box ENGRAVED_BOX + } { + Fl_Tabs {} { + xywh {345 35 245 175} align 18 + } { + Fl_Group {} { + label {System Effects} + xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 align 18 + } { + Fl_Counter simplesyseffnocounter { + label {Sys.Effect No.} + callback {nsyseff=(int) o->value()-1; +simplesysefftype->value(master->sysefx[nsyseff]->geteffect()); +simplesyseffectui->refresh(master->sysefx[nsyseff]); +simplerefresh();} + xywh {350 75 80 20} type Simple labelfont 1 labelsize 11 align 1 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_SYS_EFX);} + code1 {o->value(nsyseff+1);} + } + Fl_Choice simplesysefftype { + label EffType + callback {pthread_mutex_lock(&master->mutex); +master->sysefx[nsyseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +simplesyseffectui->refresh(master->sysefx[nsyseff]);} + xywh {515 80 70 15} down_box BORDER_BOX labelsize 11 align 5 + code0 {o->value(master->sysefx[nsyseff]->geteffect());} + } { + menuitem {} { + label {No Effect} + xywh {20 20 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Reverb + xywh {30 30 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Echo + xywh {40 40 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Chorus + xywh {50 50 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Phaser + xywh {60 60 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label AlienWah + xywh {70 70 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Distortion + xywh {80 80 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label EQ + xywh {90 90 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label DynFilter + xywh {100 100 100 20} labelfont 1 labelsize 11 + } + } + Fl_Group simplesyseffectuigroup { + xywh {350 95 235 95} box FLAT_BOX color 48 + } { + Fl_Group simplesyseffectui { + xywh {350 95 234 95} + code0 {o->init(master->sysefx[nsyseff]);} + class SimpleEffUI + } {} + } + Fl_Button {} { + label {Send to...} + callback {syseffsendwindow->show();} + xywh {435 75 75 20} box THIN_UP_BOX labelfont 1 labelsize 12 + } + Fl_Button {} { + label P + callback {pthread_mutex_lock(&master->mutex); +presetsui->paste(master->sysefx[nsyseff],simplesyseffectui); +pthread_mutex_unlock(&master->mutex);} + xywh {560 65 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + } + Fl_Group {} { + label {Insertion Effects} + xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 align 18 hide + } { + Fl_Counter simpleinseffnocounter { + label {Ins.Effect No.} + callback {ninseff=(int) o->value()-1; +simpleinsefftype->value(master->insefx[ninseff]->geteffect()); +simpleinseffpart->value(master->Pinsparts[ninseff]+2); +simpleinseffectui->refresh(master->insefx[ninseff]); + +if (master->Pinsparts[ninseff]!=-1) { + simpleinsefftype->activate(); + simpleinseffectui->activate(); + simpleinseffectuigroup->activate(); +} else { + simpleinsefftype->deactivate(); + simpleinseffectui->deactivate(); + simpleinseffectuigroup->deactivate(); +};} + xywh {350 75 80 20} type Simple labelfont 1 labelsize 11 align 1 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_INS_EFX);} + code1 {o->value(ninseff+1);} + } + Fl_Choice simpleinsefftype { + label EffType + callback {pthread_mutex_lock(&master->mutex); +master->insefx[ninseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +simpleinseffectui->refresh(master->insefx[ninseff]); +simpleinseffectui->show();} + xywh {515 80 70 15} down_box BORDER_BOX labelsize 11 align 5 + code0 {o->value(master->insefx[ninseff]->geteffect());} + code1 {if (master->Pinsparts[ninseff]== -1) o->deactivate();} + } { + menuitem {} { + label {No Effect} + xywh {35 35 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Reverb + xywh {45 45 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Echo + xywh {55 55 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Chorus + xywh {65 65 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Phaser + xywh {70 70 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label AlienWah + xywh {80 80 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Distortion + xywh {90 90 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label EQ + xywh {100 100 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label DynFilter + xywh {110 110 100 20} labelfont 1 labelsize 11 + } + } + Fl_Group simpleinseffectuigroup { + xywh {350 95 234 95} box FLAT_BOX color 48 + } { + Fl_Group simpleinseffectui { + xywh {350 95 234 95} + code0 {o->init(master->insefx[ninseff]);} + code1 {if (master->Pinsparts[ninseff]== -1) o->deactivate();} + class SimpleEffUI + } {} + } + Fl_Choice simpleinseffpart { + label {Insert To.} + callback {master->Pinsparts[ninseff]=(int) o->value()-2; +if ((int) o->value()==1){ + simpleinseffectuigroup->deactivate(); + simpleinsefftype->deactivate(); + simpleinseffectui->deactivate(); +} else { + simpleinseffectuigroup->activate(); + simpleinsefftype->activate(); + simpleinseffectui->activate(); +}; +master->insefx[ninseff]->cleanup();} open + xywh {435 75 80 20} down_box BORDER_BOX labelfont 1 labelsize 10 align 5 textsize 10 + code0 {o->add("Master Out");o->add("Off");} + code1 {char tmp[50]; for (int i=0;i<NUM_MIDI_PARTS;i++) {sprintf(tmp,"Part %2d",i+1);o->add(tmp);};} + code3 {o->value(master->Pinsparts[ninseff]+2);} + } {} + Fl_Button {} { + label P + callback {pthread_mutex_lock(&master->mutex); +presetsui->paste(master->insefx[ninseff],simpleinseffectui); +pthread_mutex_unlock(&master->mutex);} + xywh {560 65 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + } + } + } + Fl_Group {} { + xywh {5 300 590 30} box ENGRAVED_FRAME + } { + Fl_Box {} { + label {VU-Meter} + xywh {5 300 590 30} box FLAT_BOX color 41 selection_color 75 + code0 {o->init(master,-1);} + class VUMeter + } + } + Fl_Dial simplemastervolumedial { + label {Master Volume} + callback {master->setPvolume((int) o->value());} + tooltip {Master Volume} xywh {10 35 40 40} box ROUND_UP_BOX labelfont 1 labelsize 12 align 130 maximum 127 step 1 + code0 {o->value(master->Pvolume);} + class WidgetPDial + } + Fl_Counter simplemasterkeyshiftcounter { + label {Master KeyShift} + callback {master->setPkeyshift((int) o->value()+64);} + xywh {25 110 90 20} labelsize 12 minimum -64 maximum 64 step 1 + code0 {o->lstep(12);} + code1 {o->value(master->Pkeyshift-64);} + } + Fl_Button {} { + label {Stop ALL sounds!} + callback {virkeyboard->relaseallkeys(); +pthread_mutex_lock(&master->mutex); +master->shutup=1; +pthread_mutex_unlock(&master->mutex);} + xywh {5 149 115 31} box PLASTIC_UP_BOX color 231 labelfont 1 labelsize 12 + } + Fl_Button {} { + label Reset + callback {simpleglobalfinedetuneslider->value(64.0); +simpleglobalfinedetuneslider->do_callback();} + tooltip {Master fine detune reset} xywh {70 32 50 10} box THIN_UP_BOX labelfont 1 labelsize 12 align 128 + } + Fl_Dial simpleglobalfinedetuneslider { + label {Fine Detune} + callback {master->microtonal.Pglobalfinedetune=(int) o->value();} + tooltip {global fine detune} xywh {80 45 30 30} box ROUND_UP_BOX labelsize 12 align 130 maximum 127 step 1 value 64 + code0 {o->value(master->microtonal.Pglobalfinedetune);} + class WidgetPDial + } + Fl_Counter simplenpartcounter { + label Part + callback {virkeys->relaseallkeys(0); +npartcounter->value(o->value()); +npart=(int) o->value()-1; + +simplerefresh(); +virkeys->midich=master->part[npart]->Prcvchn;} + tooltip {The part number} xywh {170 40 70 20} type Simple labelfont 1 align 4 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_MIDI_PARTS);} + } + Fl_Counter {} { + label {Keyb.Oct.} + callback {virkeys->relaseallkeys(0); +virkeys->midioct=(int) o->value(); +virkeys->take_focus();} + tooltip {Midi Octave} xywh {5 195 55 20} type Simple labelsize 12 align 8 when 6 minimum 0 maximum 5 step 1 textfont 1 textsize 12 + code0 {o->value(virkeys->midioct);} + } + } + Fl_Window selectuiwindow { + label {User Interface mode} + callback {*exitprogram=1;} + xywh {342 246 430 250} type Double hide non_modal + } { + Fl_Box {} { + label {Welcome to ZynAddSubFX} + xywh {5 5 425 40} labeltype SHADOW_LABEL labelfont 1 labelsize 33 + } + Fl_Box {} { + label {Please choose the interface mode:} + xywh {10 50 265 25} labelfont 1 labelsize 16 + } + Fl_Button {} { + label Advanced + callback {config.cfg.UserInterfaceMode=1; +masterwindow->show(); +selectuiwindow->hide();} + xywh {10 165 100 35} box PLASTIC_UP_BOX color 229 labelfont 1 labelsize 20 + } + Fl_Box {} { + label {.. if you have used ZynAddSubFX before, or you like to have full controll to all parameters.} + xywh {110 165 310 35} labelfont 1 labelsize 13 align 144 + } + Fl_Button {} { + label Beginner + callback {simplemasterwindow->show(); +selectuiwindow->hide(); +config.cfg.UserInterfaceMode=2;} + xywh {10 80 100 65} box PLASTIC_UP_BOX color 238 labelfont 1 labelsize 20 + } + Fl_Box {} { + label {..if you are a beginner, you prefer using presets or you prefer to use simpler user interfaces. Most functionality of ZynAddSubFX will be hidden in this mode to make simple the learning/using it.} + xywh {110 75 320 75} labelfont 1 labelsize 13 align 144 + } + Fl_Box {} { + label {You can switch the interface modes anytime you want.} + xywh {30 215 360 25} box BORDER_BOX color 51 labelfont 1 labelsize 13 align 144 + } + } + } + Function {updatesendwindow()} {} { + code {for (int neff1=0;neff1<NUM_SYS_EFX;neff1++) + for (int neff2=neff1+1;neff2<NUM_SYS_EFX;neff2++) + syseffsend[neff1][neff2]->value(master->Psysefxsend[neff1][neff2]);} {} + } + Function {updatepanel()} {} { + code {for (int npart=0;npart<NUM_MIDI_PARTS;npart++){ + panellistitem[npart]->refresh(); +};} {} + } + Function {setfilelabel(const char *filename)} {} { + code {if (filename!=NULL) snprintf(&masterwindowlabel[0],100,"%s - ZynAddSubFX",fl_filename_name(filename)); + else snprintf(&masterwindowlabel[0],100,"%s","ZynAddSubFX (c)2002-2005 Nasca O. Paul"); +masterwindowlabel[99]='\\0'; +masterwindow->label(&masterwindowlabel[0]); +simplemasterwindow->label(&masterwindowlabel[0]);} {} + } + Function {MasterUI(Master *master_,int *exitprogram_)} {} { + code {master=master_; +exitprogram=exitprogram_; +ninseff=0; +nsyseff=0; +npart=0; + +for (int i=0;i<NUM_SYS_EFX;i++) + for (int j=0;j<NUM_SYS_EFX;j++) + syseffsend[i][j]=NULL; + +microtonalui=new MicrotonalUI(&master->microtonal); +virkeyboard=new VirKeyboard(master); +bankui=new BankUI(master,&npart); +configui=new ConfigUI(); +sequi=new SeqUI(master); + +make_window(); +presetsui=new PresetsUI(); +setfilelabel(NULL); +swapefftype=0; +simplerefresh();} {} + } + Function {~MasterUI()} {} { + code {masterwindow->hide(); +delete (masterwindow); +aboutwindow->hide(); +delete (aboutwindow); +syseffsendwindow->hide(); +delete(syseffsendwindow); + +delete (virkeyboard); +delete (microtonalui); +delete (bankui); +delete (configui); +delete (sequi); + +delete(presetsui);} {} + } + Function {showUI()} {} { + code {switch (config.cfg.UserInterfaceMode){ + case 0:selectuiwindow->show(); + break; + case 1:masterwindow->show(); + break; + case 2:simplemasterwindow->show(); + break; +};} {} + } + Function {simplerefresh()} {} { + code {partenabled->value(master->part[npart]->Penabled); +if (master->part[npart]->Penabled!=0) simplelistitemgroup->activate(); + else simplelistitemgroup->deactivate(); + +partvolume->value(master->part[npart]->Pvolume); +partpanning->value(master->part[npart]->Ppanning); +partrcv->value(master->part[npart]->Prcvchn); + +if (master->part[npart]->Pname[0]!=0) partname->label((char *)master->part[npart]->Pname); + else partname->label("Click here to load a instrument"); + +simplelistitemgroup->redraw(); +simplepartportamento->value(master->part[npart]->ctl.portamento.portamento); +simpleminkcounter->value(master->part[npart]->Pminkey); +simplemaxkcounter->value(master->part[npart]->Pmaxkey); + +simplepartkeyshiftcounter->value(master->part[npart]->Pkeyshift-64); +simplesyseffsend->value(master->Psysefxvol[nsyseff][npart]);} {} + } + Function {do_new_master()} {} { + code {if (fl_ask("Clear *ALL* the parameters ?")){ + delete microtonalui; + + pthread_mutex_lock(&master->mutex); + master->defaults(); + pthread_mutex_unlock(&master->mutex); + + npartcounter->value(1); + refresh_master_ui(); + +}; + +updatepanel();} {} + } + Function {do_load_master()} {} { + code {char *filename; +filename=fl_file_chooser("Open:","({*.xmz})",NULL,0); +if (filename==NULL) return; + + +pthread_mutex_lock(&master->mutex); + //clear all parameters + master->defaults(); + + //load the data + int result=master->loadXML(filename); +pthread_mutex_unlock(&master->mutex); +master->applyparameters(); + +npartcounter->value(1); +refresh_master_ui(); +updatepanel(); +if (result>=0) setfilelabel(filename); + + +if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not a zynaddsubfx parameters file."); + else if (result<0) fl_alert("Error: Could not load the file.");} {} + } + Function {do_save_master()} {} { + code {char *filename; +int result=0; + +filename=fl_file_chooser("Save:","({*.xmz})",NULL,0); +if (filename==NULL) return; +filename=fl_filename_setext(filename,".xmz"); + +result=fileexists(filename); +if (result) { + result=0; + if (!fl_ask("The file exists. \\nOverwrite it?")) return; + +}; + + +pthread_mutex_lock(&master->mutex); +result=master->saveXML(filename); +pthread_mutex_unlock(&master->mutex); + +if (result<0) fl_alert("Error: Could not save the file."); + else setfilelabel(filename); + +updatepanel();} {} + } + Function {refresh_master_ui()} {} { + code {ninseff=0; +nsyseff=0; +npart=0; + +//the Master UI +npartcounter->do_callback(); +syseffnocounter->do_callback(); +inseffnocounter->do_callback(); +masterkeyshiftcounter->value(master->Pkeyshift-64); +mastervolumedial->value(master->Pvolume); +globalfinedetuneslider->value(master->microtonal.Pglobalfinedetune); +microtonalui=new MicrotonalUI(&master->microtonal); +nrpnbutton->value(master->ctl.NRPN.receive); +updatesendwindow(); +updatepanel(); + +//the simle MasterUI +simplenpartcounter->value(1); +simplesyseffnocounter->value(1); +simpleinseffnocounter->value(1); +simplenpartcounter->do_callback(); +simplesyseffnocounter->do_callback(); +simpleinseffnocounter->do_callback(); +simplemasterkeyshiftcounter->value(master->Pkeyshift-64); +simplemastervolumedial->value(master->Pvolume); +simpleglobalfinedetuneslider->value(master->microtonal.Pglobalfinedetune); +virkeys->midich=master->part[npart]->Prcvchn; + +simplerefresh(); +bankui->hide();} {} + } + decl {Master *master;} {} + decl {MicrotonalUI *microtonalui;} {} + decl {SeqUI *sequi;} {} + decl {BankUI *bankui;} {} + decl {int ninseff,npart;} {} + decl {int nsyseff;} {} + decl {int *exitprogram;} {} + decl {SysEffSend *syseffsend[NUM_SYS_EFX][NUM_SYS_EFX];} {} + decl {VirKeyboard *virkeyboard;} {} + decl {ConfigUI *configui;} {} + decl {int swapefftype;} {} + decl {char masterwindowlabel[100];} {} + decl {Panellistitem *panellistitem[NUM_MIDI_PARTS];} {} +} diff --git a/muse/synti/zynaddsubfx/UI/MicrotonalUI.fl b/muse/synti/zynaddsubfx/UI/MicrotonalUI.fl new file mode 100644 index 00000000..750e7b51 --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/MicrotonalUI.fl @@ -0,0 +1,270 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <string.h>} {public +} + +decl {\#include <FL/Fl_File_Chooser.H>} {public +} + +decl {\#include <FL/fl_ask.H>} {public +} + +decl {\#include "../Misc/Microtonal.h"} {public +} + +class MicrotonalUI {} { + Function {make_window()} {} { + Fl_Window microtonaluiwindow { + label Scales + xywh {99 164 405 450} type Double hide + } { + Fl_Group {} { + tooltip {Center where the note's freqs. are turned upside-down} xywh {249 2 155 45} box ENGRAVED_FRAME + } { + Fl_Check_Button {} { + label {Invert keys} + callback {microtonal->Pinvertupdown=(int) o->value(); +if (microtonal->Pinvertupdown==0) centerinvertcounter->deactivate(); + else centerinvertcounter->activate();} + tooltip {Turn upside-down the note frequencies} xywh {254 13 55 30} down_box DOWN_BOX labelfont 1 labelsize 12 align 148 + code0 {o->value(microtonal->Pinvertupdown);} + } + Fl_Counter centerinvertcounter { + label Center + callback {microtonal->Pinvertupdowncenter=(int) o->value();} + xywh {319 13 80 20} labelfont 1 labelsize 12 align 130 minimum 0 maximum 127 step 1 textfont 1 + code0 {o->lstep(microtonal->getoctavesize());} + code1 {o->value(microtonal->Pinvertupdowncenter);} + code2 {if (microtonal->Pinvertupdown==0) o->deactivate();} + } + } + Fl_Group microtonalgroup {selected + xywh {3 49 402 398} box ENGRAVED_FRAME + code0 {if (microtonal->Penabled==0) o->deactivate();} + } { + Fl_Button applybutton { + label Retune + callback {apply();} + tooltip {Retune the synth accorging to the inputs from "Tunnings" and "Keyboard Mappings"} xywh {8 413 107 28} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 18 + } + Fl_Value_Output octavesizeoutput { + label {nts./oct.} + callback {o->value(microtonal->getoctavesize());} + tooltip {Notes/Octave} xywh {150 423 35 17} labelsize 10 align 5 maximum 500 step 1 value 12 textfont 1 + code0 {o->value(microtonal->getoctavesize());} + } + Fl_Input nameinput { + label {Name:} + callback {snprintf((char *)microtonal->Pname,MICROTONAL_MAX_NAME_LEN,"%s",o->value());} + xywh {8 64 285 25} labelfont 1 labelsize 12 align 5 + code0 {o->insert((char *)microtonal->Pname);} + } + Fl_Input tuningsinput { + label {Tunings:} + xywh {8 144 182 264} type Multiline labelfont 1 labelsize 12 align 5 when 2 + code0 {updateTuningsInput();} + } + Fl_Input commentinput { + label {Comment:} + callback {snprintf((char *)microtonal->Pcomment,MICROTONAL_MAX_NAME_LEN,"%s",o->value());} + xywh {8 104 391 25} labelfont 1 labelsize 12 align 5 + code0 {o->insert((char *)microtonal->Pcomment);} + } + Fl_Counter {} { + label Shift + callback {microtonal->Pscaleshift=(int) o->value()+64;} + xywh {313 69 70 20} type Simple labelsize 12 align 1 minimum -63 maximum 64 step 1 textfont 1 + code0 {o->value(microtonal->Pscaleshift-64);} + } + Fl_Button {} { + label {Import .SCL file} + callback {const char *filename; +filename=fl_file_chooser("Open:","(*.scl)",NULL,0); +if (filename==NULL) return; +int result=microtonal->loadscl(filename); +if (result==0) { + updateTuningsInput(); + nameinput->cut(0,nameinput->maximum_size()); + nameinput->insert((char *)microtonal->Pname); + nameinput->position(0); + commentinput->cut(0,commentinput->maximum_size()); + commentinput->insert((char *)microtonal->Pname); + commentinput->position(0); + tuningsinput->position(0); + octavesizeoutput->do_callback(); + } else { + fl_alert("Error: Could not load the file."); + };} + tooltip {Inport Scala .scl file (tunnings)} xywh {243 411 84 15} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Group keymappinggroup { + label {Keyboard Mapping} open + xywh {193 144 206 264} box ENGRAVED_BOX labelfont 1 labelsize 12 + } { + Fl_Input mappinginput { + xywh {250 147 146 258} type Multiline labelfont 1 labelsize 12 align 5 when 2 + code0 {updateMappingInput();} + } + Fl_Counter firstnotecounter { + label {First note} + callback {microtonal->Pfirstkey=(int) o->value();} + tooltip {First MIDI note number} xywh {199 195 42 18} type Simple labelsize 10 align 5 minimum 0 maximum 127 step 1 textfont 1 textsize 12 + code0 {o->value(microtonal->Pfirstkey);} + } + Fl_Counter lastnotecounter { + label {Last note} + callback {microtonal->Plastkey=(int) o->value();} + tooltip {Last MIDI note number} xywh {199 225 42 18} type Simple labelsize 10 align 5 minimum 0 maximum 127 step 1 value 127 textfont 1 textsize 12 + code0 {o->value(microtonal->Plastkey);} + } + Fl_Counter middlenotecounter { + label {Midle note} + callback {microtonal->Pmiddlenote=(int) o->value();} + tooltip {Midle note (where scale degree 0 is mapped to)} xywh {199 267 42 18} type Simple labelsize 10 align 5 minimum 0 maximum 127 step 1 value 60 textfont 1 textsize 12 + code0 {o->value(microtonal->Pmiddlenote);} + } + Fl_Value_Output mapsizeoutput { + label {Map Size} + callback {o->value(microtonal->Pmapsize);} + xywh {201 382 44 20} labelsize 10 align 5 maximum 500 step 1 value 12 textfont 1 + code0 {o->value(microtonal->Pmapsize);} + } + } + Fl_Check_Button mappingenabledbutton { + label ON + callback {int x=(int) o->value(); +microtonal->Pmappingenabled=x; +if (x==0) keymappinggroup->deactivate(); + else keymappinggroup->activate(); +o->show();} + tooltip {Enable the Mapping (otherwise the mapping is linear)} xywh {198 150 48 21} box FLAT_BOX down_box DOWN_BOX labelfont 1 + code0 {o->value(microtonal->Pmappingenabled);} + code1 {if (microtonal->Pmappingenabled==0) keymappinggroup->deactivate();} + } + Fl_Button {} { + label {Import .kbm file} + callback {const char *filename; +filename=fl_file_chooser("Open:","(*.kbm)",NULL,0); +if (filename==NULL) return; +int result=microtonal->loadkbm(filename); +if (result==0) { + updateMappingInput(); + mappinginput->position(0); + mapsizeoutput->do_callback(); + firstnotecounter->value(microtonal->Pfirstkey); + lastnotecounter->value(microtonal->Plastkey); + middlenotecounter->value(microtonal->Pmiddlenote); + mapsizeoutput->do_callback(); + mappingenabledbutton->value(microtonal->Pmappingenabled); + mappingenabledbutton->do_callback(); + afreqinput->value(microtonal->PAfreq); + anotecounter->value(microtonal->PAnote); + anotecounter->do_callback(); + } else { + fl_alert("Error: Could not load the file."); + };} + tooltip {Inport Scala .kbm file (keyboard mapping)} xywh {243 428 84 16} box THIN_UP_BOX labelfont 1 labelsize 10 + } + } + Fl_Group {} { + xywh {108 2 140 45} box ENGRAVED_FRAME + } { + Fl_Counter anotecounter { + label {"A" Note} + callback {microtonal->PAnote=(int) o->value(); +if (microtonal->getnotefreq(microtonal->PAnote,0)<0.0) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK); + +o->redraw();} + tooltip {The "A" note (the reference note for which freq. ("A" freq) is given)} xywh {173 17 65 20} labelfont 1 labelsize 10 align 129 minimum 0 maximum 127 step 1 value 69 textfont 1 textsize 11 + code0 {o->lstep(12);} + code1 {o->value(microtonal->PAnote);} + } + Fl_Value_Input afreqinput { + label {"A" Freq.} + callback {microtonal->PAfreq=o->value();} + tooltip {The freq. of "A" note (default=440.0)} xywh {118 17 45 20} labelfont 1 labelsize 10 align 1 minimum 1 maximum 20000 step 0.001 value 440 textfont 1 textsize 11 + code0 {o->value(microtonal->PAfreq);} + } + } + Fl_Button {} { + label Close + callback {microtonaluiwindow->hide();} + xywh {333 413 67 28} box THIN_UP_BOX + } + Fl_Check_Button {} { + label {Enable Microtonal} + callback {microtonal->Penabled=(int) o->value(); +if (microtonal->Penabled==0) microtonalgroup->deactivate(); + else microtonalgroup->activate();} + xywh {3 3 102 45} box PLASTIC_UP_BOX down_box DOWN_BOX labelfont 1 labelsize 12 align 148 + code0 {o->value(microtonal->Penabled);} + } + } + } + Function {updateTuningsInput()} {} { + code {char *tmpbuf=new char[100]; + +tuningsinput->cut(0,tuningsinput->maximum_size()); + +for (int i=0;i<microtonal->getoctavesize();i++){ + if (i!=0) tuningsinput->insert("\\n"); + microtonal->tuningtoline(i,tmpbuf,100); + tuningsinput->insert(tmpbuf); +}; + +delete(tmpbuf);} {} + } + Function {updateMappingInput()} {} { + code {char *tmpbuf=new char[100]; + +mappinginput->cut(0,tuningsinput->maximum_size()); + +for (int i=0;i<microtonal->Pmapsize;i++){ + if (i!=0) mappinginput->insert("\\n"); + if ((microtonal->Pmapping[i])==-1) + snprintf(tmpbuf,100,"x"); + else snprintf(tmpbuf,100,"%d",microtonal->Pmapping[i]); + mappinginput->insert(tmpbuf); +}; + +delete(tmpbuf);} {} + } + Function {MicrotonalUI(Microtonal *microtonal_)} {} { + code {microtonal=microtonal_; + +make_window();} {} + } + Function {~MicrotonalUI()} {} { + code {microtonaluiwindow->hide(); +delete(microtonaluiwindow);} {} + } + Function {show()} {} { + code {microtonaluiwindow->show();} {} + } + Function {apply()} {} { + code {int err=microtonal->texttotunings(tuningsinput->value()); +if (err>=0) fl_alert("Parse Error: The input may contain only numbers (like 232.59)\\n or divisions (like 121/64)."); +if (err==-2) fl_alert("Parse Error: The input is empty."); +octavesizeoutput->do_callback(); + +microtonal->texttomapping(mappinginput->value()); +mapsizeoutput->do_callback(); +anotecounter->do_callback(); + +//applybutton->color(FL_GRAY);} {} + } + decl {Microtonal *microtonal;} {} +} diff --git a/muse/synti/zynaddsubfx/UI/OscilGenUI.fl b/muse/synti/zynaddsubfx/UI/OscilGenUI.fl new file mode 100644 index 00000000..8527719a --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/OscilGenUI.fl @@ -0,0 +1,1131 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include "../Synth/OscilGen.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "ResonanceUI.h"} {public +} + +decl {\#include <FL/Fl_Box.H>} {public +} + +decl {\#include <FL/Fl_Group.H>} {public +} + +decl {\#include <FL/Fl_Slider.H>} {public +} + +decl {\#include <math.h>} {} + +decl {\#include <stdio.h>} {} + +decl {\#include <stdlib.h>} {} + +decl {\#include <string.h>} {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EnvelopeUI.h"} {public +} + +decl {\#include "LFOUI.h"} {public +} + +decl {\#include "FilterUI.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class OscilSpectrum {: {public Fl_Box} +} { + Function {OscilSpectrum(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {oscil=NULL;} {} + } + Function {init(OscilGen *oscil_,int oscbase_,Master *master_)} {} { + code {oscil=oscil_; +oscbase=oscbase_; +master=master_;} {} + } + Function {draw()} {} { + code {int ox=x(),oy=y(),lx=w(),ly=h(),i; +const int maxdb=60;//must be multiple of 10 +int GX=2; +int n=lx/GX-1; +if (n>OSCIL_SIZE/2) n=OSCIL_SIZE/2; + +REALTYPE x; +REALTYPE spc[n]; +for (i=0;i<n;i++) spc[i]=0.0; + +pthread_mutex_lock(&master->mutex); +if (oscbase==0) oscil->getspectrum(n,spc,0); + else oscil->getspectrum(n,spc,1); +pthread_mutex_unlock(&master->mutex); + +//normalize +REALTYPE max=0; +for (i=0;i<n;i++){ + x=fabs(spc[i]); + if (max<x) max=x; +} +if (max<0.000001) max=1.0; +max=max*1.05; + +//draw + +if (this->active_r()) fl_color(this->parent()->selection_color()); + else fl_color(this->parent()->color()); +fl_line_style(FL_DOT); + +for (i=1;i<maxdb/10;i++){ + int ky=(int)((REALTYPE)i*ly*10.0/maxdb)/2; + ky*=2; + fl_line(ox,oy+ky-1,ox+lx-2,oy+ky-1); +}; + +for (i=2;i<n;i++){ + int tmp=i*GX-2; + if (i%10==1) fl_line_style(0); + else fl_line_style(FL_DOT); + fl_line(ox+tmp,oy+2,ox+tmp,oy+ly-2); +} + +if (this->active_r()) fl_color(this->parent()->labelcolor()); + else fl_color(this->parent()->color()); +fl_line_style(0); + +//draws the spectrum +for (i=0;i<n;i++){ + int tmp=i*GX+2; + x=spc[i]/max; + + if (x>dB2rap(-maxdb)) x=rap2dB(x)/maxdb+1; + else x=0; + + int val=(int) ((ly-2)*x); + if (val>0) fl_line(ox+tmp,oy+ly-2-val,ox+tmp,oy+ly-2); +};} {} + } + decl {OscilGen *oscil;} {} + decl {int oscbase;} {} + decl {Master *master;} {} +} + +class PSlider {: {public Fl_Slider} +} { + Function {PSlider(int x,int y, int w, int h, const char *label=0):Fl_Slider(x,y,w,h,label)} {} {} + Function {handle(int event)} {return_type int + } { + code {int X=x(),Y=y(),W=w(),H=h(); + +if ((!Fl::event_buttons())|| (event==0)||(Fl::event_shift()==0)) return(Fl_Slider::handle(event)); + +if (!Fl::event_inside(X,Y,W,H)) { + if (event==FL_DRAG){ + Fl_Slider::handle(FL_RELEASE); + Fl_Slider::handle(FL_LEAVE); + deactivate(); + activate(); + return(1); + }else{ + return(Fl_Slider::handle(event)); + }; +} else { + //Fl_Slider::handle(FL_FOCUS); + Fl_Slider::handle(FL_PUSH); +}; + +return(1);} {} + } +} + +class Oscilloscope {: {public Fl_Box} +} { + Function {Oscilloscope(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {oscil=NULL; +phase=64; +oscbase=0;} {} + } + Function {init(OscilGen *oscil_,Master *master_)} {} { + code {oscil=oscil_; +master=master_;} {} + } + Function {init(OscilGen *oscil_,int oscbase_,Master *master_)} {} { + code {oscil=oscil_; +oscbase=oscbase_; +master=master_;} {} + } + Function {init(OscilGen *oscil_,int oscbase_,int phase_,Master *master_)} {} { + code {oscil=oscil_; +oscbase=oscbase_; +phase=phase_; +master=master_;} {} + } + Function {draw()} {} { + code {int ox=x(),oy=y(),lx=w(),ly=h()-1,i; +REALTYPE smps[OSCIL_SIZE]; +pthread_mutex_lock(&master->mutex); +if (oscbase==0) oscil->get(smps,-1.0); + else oscil->getcurrentbasefunction(smps); +pthread_mutex_unlock(&master->mutex); + +if (damage()!=1){ + fl_color(0,0,0); + fl_rectf(ox,oy,lx,ly); +}; + +//normalize +REALTYPE max=0; +for (i=0;i<OSCIL_SIZE;i++) + if (max<fabs(smps[i])) max=fabs(smps[i]); +//fprintf(stderr,"%.4f\\n",max); +if (max<0.00001) max=1.0; +max=-max*1.05; + +//draw +fl_line_style(FL_DASH); +if (this->active_r()) fl_color(this->parent()->labelcolor()); + else fl_color(this->parent()->color()); +int GX=16;if (lx<GX*3) GX=-1; +for (i=1;i<GX;i++){ + int tmp=(int)(lx/(REALTYPE)GX*i); + fl_line(ox+tmp,oy+2,ox+tmp,oy+ly-2); +}; +int GY=8;if (ly<GY*3) GY=-1; +for (i=1;i<GY;i++){ + int tmp=(int)(ly/(REALTYPE)GY*i); + fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp); +}; + +//draw the function +fl_line_style(0,1); +fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); +if (this->active_r()) fl_color(this->parent()->selection_color()); + else fl_color(this->parent()->labelcolor()); +int lw=1; +//if ((lx<135)||(ly<135)) lw=1; +fl_line_style(0,lw); +int ph=(int)((phase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE); +for (i=1;i<lx;i++){ + int k1=(int)((REALTYPE)OSCIL_SIZE*(i-1)/lx)+ph; + int k2=(int)((REALTYPE)OSCIL_SIZE*i/lx)+ph; + REALTYPE y1=smps[k1%OSCIL_SIZE]/max; + REALTYPE y2=smps[k2%OSCIL_SIZE]/max; + fl_line(i-1+ox,(int)(y1*ly/2.0)+oy+ly/2,i+ox,(int)(y2*ly/2.0)+oy+ly/2); +};} {} + } + decl {OscilGen *oscil;} {} + decl {int oscbase;} {} + decl {int phase;} {public + } + decl {Master *master;} {} +} + +class Oscilharmonic {: {public Fl_Group} +} { + Function {make_window()} {private + } { + Fl_Window harmonic { + private xywh {328 166 90 225} type Double hide + class Fl_Group + } { + Fl_Slider mag { + callback {int x=64; +if (Fl::event_button3()) o->value(x); + else x=127-(int)o->value(); +if (x==64) o->selection_color(0); + else o->selection_color(222); + +pthread_mutex_lock(&master->mutex); + oscil->Phmag[n]=x; + if (x==64) { + oscil->Phphase[n]=64; + phase->value(64); + }; + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +display->redraw(); +oldosc->redraw(); +if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +};} + xywh {0 15 15 115} type {Vert Knob} box FLAT_BOX selection_color 222 labelcolor 0 maximum 127 step 1 value 64 + code0 {o->value(127-oscil->Phmag[n]);} + code1 {if (oscil->Phmag[n]==64) o->selection_color(0);} + class PSlider + } + Fl_Slider phase { + callback {int x=64; +if (Fl::event_button3()) o->value(x); + else x=(int)o->value(); + +pthread_mutex_lock(&master->mutex); + oscil->Phphase[n]=x; + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +display->redraw(); +oldosc->redraw(); +if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +};} + xywh {0 135 15 75} type {Vert Knob} box FLAT_BOX selection_color 222 maximum 127 step 1 value 64 + code0 {o->value(oscil->Phphase[n]);} + class PSlider + } + Fl_Box {} { + xywh {15 70 5 5} box FLAT_BOX color 45 + } + Fl_Box {} { + xywh {15 170 5 5} box FLAT_BOX color 45 + } + Fl_Box {} { + label 01 + xywh {0 210 20 15} labelfont 1 labelsize 9 align 20 + code0 {char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp));} + } + Fl_Box {} { + label 01 + xywh {0 0 20 15} labelfont 1 labelsize 9 align 20 + code0 {char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp));} + } + } + } + Function {Oscilharmonic(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {n=0; +oscil=NULL; +display=NULL; +applybutton=NULL; +cbwidget=NULL;} {} + } + Function {init(OscilGen *oscil_,int n_,Fl_Group *display_,Fl_Widget *oldosc_,Fl_Widget *cbwidget_,Fl_Widget *applybutton_, Master *master_)} {} { + code {oscil=oscil_; +n=n_; +display=display_; +master=master_; +oldosc=oldosc_; +cbwidget=cbwidget_; +applybutton=applybutton_; +make_window(); +end(); +harmonic->show();} {} + } + Function {refresh()} {} { + code {mag->value(127-oscil->Phmag[n]); +phase->value(oscil->Phphase[n]); + +if (oscil->Phmag[n]==64) mag->selection_color(0); + else mag->selection_color(222);} {} + } + Function {~Oscilharmonic()} {} { + code {harmonic->hide(); +//delete(harmonic);} {} + } + decl {OscilGen *oscil;} {} + decl {Fl_Group *display;} {} + decl {int n;} {} + decl {Fl_Widget *oldosc,*cbwidget,*applybutton;} {} + decl {Master *master;} {} +} + +class OscilEditor {: {public PresetsUI_} +} { + Function {make_window()} {} { + Fl_Window osceditUI { + label {ADsynth Oscillator Editor} + xywh {131 90 735 595} type Double hide + code0 {if (oscil->ADvsPAD) o->label("PADsynth Harmonic Content Editor");} + } { + Fl_Button applybutton { + label Apply + callback {applybutton->color(FL_GRAY); +applybutton->redraw(); +if (cbapplywidget!=NULL) { + cbapplywidget->do_callback(); + cbapplywidget->color(FL_GRAY); + cbapplywidget->redraw(); +};} selected + xywh {300 280 60 20} box THIN_UP_BOX labelfont 1 + code0 {if (!oscil->ADvsPAD) o->hide();} + } + Fl_Group oscildisplaygroup { + xywh {5 5 360 300} box ENGRAVED_FRAME + } { + Fl_Group {} {open + xywh {10 85 350 190} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 + code0 {Oscilloscope *osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} + code1 {osc->init(oscil,master);} + } {} + Fl_Box {} { + label Oscillator + xywh {120 10 110 20} box FLAT_BOX labelfont 1 + } + Fl_Value_Slider rndslider { + label rnd + callback {oscil->Prand=(int)o->value()+64; +oscildisplaygroup->redraw(); +oldosc->redraw();} + tooltip {Oscilator Phase Randomness: smaller than 0 is "group", larger than 0 is for each harmonic} xywh {140 285 100 10} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum -64 maximum 63 step 1 + code0 {if (oscil->ADvsPAD) o->hide();} + } + Fl_Group {} {open + xywh {10 30 350 50} box THIN_DOWN_BOX color 32 selection_color 218 labelcolor 63 + code0 {OscilSpectrum *spc=new OscilSpectrum(o->x(),o->y(),o->w(),o->h(),"");} + code1 {spc->init(oscil,0,master);} + } {} + Fl_Group {} { + xywh {246 277 115 25} box ENGRAVED_BOX + code0 {if (oscil->ADvsPAD) o->hide();} + } { + Fl_Choice hrndtype { + label {H.rnd} + callback {oscil->Pamprandtype=(int) o->value();} + tooltip {Harmonic Amplitude Randomness} xywh {281 282 50 15} down_box BORDER_BOX labelsize 10 textsize 10 + } { + menuitem {} { + label None + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pow + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sin + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial hrnddial { + callback {oscil->Pamprandpower=(int) o->value();} + tooltip {Oscillator's spectrum adjust parameter} xywh {338 280 18 18} maximum 127 step 1 + class WidgetPDial + } + } + } + Fl_Box {} { + label {Base Func.} + xywh {495 15 110 20} box FLAT_BOX labelfont 1 + } + Fl_Group basefuncdisplaygroup { + xywh {365 5 360 300} box ENGRAVED_FRAME + } { + Fl_Group {} { + xywh {370 85 350 190} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 + code0 {Oscilloscope *osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} + code1 {osc->init(oscil,1,master);} + } {} + Fl_Dial bfslider { + callback {oscil->Pbasefuncpar=(int)o->value()+64; +basefuncdisplaygroup->redraw(); +bfparval->value(oscil->Pbasefuncpar-64); + +redrawoscil();} + tooltip {Base Function Parameter} xywh {520 280 20 20} minimum -64 maximum 63 step 1 + class WidgetPDial + } + Fl_Choice bftype { + label {Base.F..} + callback {oscil->Pcurrentbasefunc=(int) o->value(); + +basefuncdisplaygroup->redraw(); +redrawoscil(); + +if ((oscil->Pcurrentbasefunc==0)||(oscil->Pcurrentbasefunc==127)) basefuncmodulation->deactivate(); + else basefuncmodulation->activate();} + xywh {370 285 90 15} down_box BORDER_BOX labelsize 10 align 5 textsize 12 + } { + menuitem {} { + label Sine + xywh {10 10 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Triangle + xywh {20 20 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Pulse + xywh {30 30 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Saw + xywh {40 40 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Power + xywh {50 50 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Gauss + xywh {50 50 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Diode + xywh {60 60 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label AbsSine + xywh {70 70 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label PulseSine + xywh {80 80 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label StrchSine + xywh {90 90 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Chirp + xywh {100 100 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label AbsStrSine + xywh {102 102 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Chebyshev + xywh {112 112 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Sqr + xywh {122 122 100 20} labelfont 1 labelsize 12 + } + } + Fl_Box {} { + label {Base Func.} + xywh {480 10 110 20} box FLAT_BOX labelfont 1 + } + Fl_Group {} {open + xywh {370 30 350 50} box THIN_DOWN_BOX color 32 selection_color 218 labelcolor 63 + code0 {OscilSpectrum *spc=new OscilSpectrum (o->x(),o->y(),o->w(),o->h(),"");} + code1 {spc->init(oscil,1,master);} + } {} + Fl_Value_Output bfparval { + label {Par.} + xywh {490 285 25 15} labelsize 13 minimum -63 maximum 63 step 1 + } + Fl_Group basefuncmodulation { + xywh {550 276 169 25} box ENGRAVED_BOX + code0 {if ((oscil->Pcurrentbasefunc==0)||(oscil->Pcurrentbasefunc==127)) basefuncmodulation->deactivate();} + } { + Fl_Choice bfmodtype { + label {B.F.Mod.} + callback {oscil->Pbasefuncmodulation=(int) o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil();} + tooltip {Base function modulation} xywh {599 281 50 15} down_box BORDER_BOX labelsize 10 textsize 10 + } { + menuitem {} { + label None + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Rev + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sine + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pow + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial bfmodpar1 { + callback {oscil->Pbasefuncmodulationpar1=(int)o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil();} + tooltip {Oscillator's modulation parameter 1} xywh {659 281 15 15} maximum 127 step 1 + class WidgetPDial + } + Fl_Dial bfmodpar2 { + callback {oscil->Pbasefuncmodulationpar2=(int)o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil();} + tooltip {Oscillator's modulation parameter 2} xywh {679 281 15 15} maximum 127 step 1 + class WidgetPDial + } + Fl_Dial bfmodpar3 { + callback {oscil->Pbasefuncmodulationpar3=(int)o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil();} + tooltip {Oscillator's modulation parameter 3} xywh {699 281 15 15} maximum 127 step 1 + class WidgetPDial + } + } + } + Fl_Choice magtype { + label {Mag.Type} + callback {oscil->Phmagtype=(int) o->value(); +basefuncdisplaygroup->redraw(); + +redrawoscil();} + xywh {70 280 65 20} down_box BORDER_BOX labelsize 12 textsize 12 + } { + menuitem {} { + label Linear + xywh {0 0 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {-40dB} + xywh {10 10 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {-60dB} + xywh {20 20 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {-80dB} + xywh {30 30 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {-100dB} + xywh {40 40 100 20} labelfont 1 labelsize 12 + } + } + Fl_Button {} { + label {Use as base} + callback {oscil->useasbase(); +if (autoclearbutton->value()){ + for (int i=0;i<MAX_AD_HARMONICS;i++){ + h[i]->mag->value(64); + oscil->Phmag[i]=64; + h[i]->phase->value(64); + oscil->Phphase[i]=64; + }; + oscil->Phmag[0]=127; + + oscil->Pharmonicshift=0; + harmonicshiftcounter->value(0); + + h[0]->mag->value(0); + wshbutton->value(0); + wshbutton->do_callback(); + fltbutton->value(0); + fltbutton->do_callback(); + sabutton->value(0); + sabutton->do_callback(); +}; + +pthread_mutex_lock(&master->mutex); + for (int i=0;i<MAX_AD_HARMONICS;i++){ + if (oscil->Phmag[i]==64) h[i]->mag->selection_color(0); + else h[i]->mag->selection_color(222); + }; + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +basefuncdisplaygroup->redraw(); +redrawoscil();} + tooltip {Use this Oscillator as base function} xywh {5 313 85 20} box THIN_UP_BOX labelfont 1 labelsize 12 + } + Fl_Button {} { + label Close + callback {osceditUI->hide();} + xywh {668 565 62 25} box THIN_UP_BOX + } + Fl_Button {} { + label Clear + callback {if (!fl_ask("Clear the harmonics settings?")) return; + +for (int i=0;i<MAX_AD_HARMONICS;i++){ + h[i]->mag->value(64); + oscil->Phmag[i]=64; + h[i]->phase->value(64); + oscil->Phphase[i]=64; +}; +oscil->Phmag[0]=127; +h[0]->mag->value(0); + +for (int i=0;i<MAX_AD_HARMONICS;i++){ + if (oscil->Phmag[i]==64) h[i]->mag->selection_color(0); + else h[i]->mag->selection_color(222); +}; + +//harmonics->redraw(); + +pthread_mutex_lock(&master->mutex); + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +redrawoscil();} + xywh {670 505 55 15} box THIN_UP_BOX labelfont 1 labelsize 12 + } + Fl_Group {} { + xywh {135 308 150 30} box ENGRAVED_BOX + } { + Fl_Choice wshbutton { + label {Wsh.} + callback {oscil->Pwaveshapingfunction=(int) o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil();} open + tooltip {Waveshaping function} xywh {165 313 55 20} down_box BORDER_BOX labelsize 10 textsize 10 + } { + menuitem {} { + label None + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Atan + xywh {35 35 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Asym1 + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pow + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sine + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Qnts + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Zigzg + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Lmt + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LmtU + xywh {105 105 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LmtL + xywh {115 115 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label ILmt + xywh {127 127 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Clip + xywh {137 137 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Asym2 + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pow2 + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sgm + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial wshpar { + callback {oscil->Pwaveshaping=(int)o->value()+64; +wsparval->value(oscil->Pwaveshaping-64); +redrawoscil();} + tooltip {Waveshaping Parameter} xywh {260 313 20 20} minimum -64 maximum 63 step 1 + class WidgetPDial + } + Fl_Value_Output wsparval { + xywh {228 316 25 15} labelsize 13 minimum -63 maximum 63 step 1 + } + } + Fl_Light_Button autoclearbutton { + label {Clr.} + tooltip {Auto clear when using the oscillator as base function} xywh {95 313 35 20} box THIN_UP_BOX value 1 labelfont 1 labelsize 10 + } + Fl_Group {} { + xywh {285 308 155 30} box ENGRAVED_BOX + } { + Fl_Choice fltbutton { + label Filter + callback {oscil->Pfiltertype=(int) o->value(); + +redrawoscil();} + tooltip {Oscillator's filter type} xywh {315 313 50 20} down_box BORDER_BOX labelsize 10 textsize 10 + } { + menuitem {} { + label None + xywh {35 35 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LP1 + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label HP1a + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label HP1b + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label BP1 + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label BS1 + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LP2 + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label HP2 + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label BP2 + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label BS2 + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Cos + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sin + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LSh + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label S + xywh {105 105 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial filtervalue1 { + callback {oscil->Pfilterpar1=(int)o->value(); + +redrawoscil();} + tooltip {Oscillator's filter parameter1} xywh {367 313 20 20} maximum 127 step 1 + class WidgetPDial + } + Fl_Check_Button filterpref { + label p + callback {oscil->Pfilterbeforews=(int)o->value(); + +redrawoscil();} + tooltip {Apply the filter before the waveshaping} xywh {415 313 20 20} down_box DOWN_BOX labelsize 10 align 24 + } + Fl_Dial filtervalue2 { + callback {oscil->Pfilterpar2=(int)o->value(); + +redrawoscil();} + tooltip {Oscillator's filter parameter2} xywh {392 313 20 20} maximum 127 step 1 + class WidgetPDial + } + } + Fl_Group {} { + xywh {590 308 135 30} box ENGRAVED_BOX + } { + Fl_Choice sabutton { + label {Sp.adj.} + callback {oscil->Psatype=(int) o->value(); +redrawoscil();} + tooltip {Oscillator's spectrum adjust} xywh {630 313 60 20} down_box BORDER_BOX labelsize 10 textsize 10 + } { + menuitem {} { + label None + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pow + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label ThrsD + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label ThrsU + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial sadjpar { + callback {oscil->Psapar=(int)o->value(); +redrawoscil();} + tooltip {Oscillator's spectrum adjust parameter} xywh {695 313 20 20} maximum 127 step 1 + class WidgetPDial + } + } + Fl_Group {} { + xywh {665 340 65 65} box ENGRAVED_BOX + } { + Fl_Counter harmonicshiftcounter { + label {Harmonic Shift} + callback {oscil->Pharmonicshift=(int)o->value(); +redrawoscil();} + xywh {670 365 55 15} type Simple labelsize 10 align 129 minimum -64 maximum 64 step 1 textfont 1 textsize 10 + } + Fl_Check_Button harmonicshiftpre { + label preH + callback {oscil->Pharmonicshiftfirst=(int)o->value(); +redrawoscil();} + tooltip {Apply the harmonic shift before the waveshaping and filtering} xywh {690 385 34 15} down_box DOWN_BOX labelsize 10 align 24 + } + Fl_Button {} { + label R + callback {oscil->Pharmonicshift=0; +harmonicshiftcounter->value(0); +redrawoscil();} + xywh {670 385 20 15} box THIN_UP_BOX labelfont 1 labelsize 10 + } + } + Fl_Group {} { + xywh {665 410 65 90} box ENGRAVED_FRAME + } { + Fl_Choice adhrtype { + label {Adpt.Harm.} + callback {oscil->Padaptiveharmonics=(int) o->value(); +redrawoscil();} + tooltip {The type of the addaptive harmonics} xywh {670 425 55 15} down_box BORDER_BOX labelsize 10 align 129 when 6 textsize 10 + } { + menuitem {} { + label OFF + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label ON + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Square + xywh {100 100 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 2xSub + xywh {110 110 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 2xAdd + xywh {120 120 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 3xSub + xywh {120 120 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 3xAdd + xywh {130 130 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 4xSub + xywh {130 130 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 4xAdd + xywh {140 140 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial adhrpow { + label pow + callback {oscil->Padaptiveharmonicspower=(int)o->value(); +redrawoscil();} + tooltip {Adaptive harmonics power} xywh {700 460 25 25} labelsize 10 maximum 200 step 1 + class WidgetPDial + } + Fl_Dial adhrbf { + label baseF + callback {oscil->Padaptiveharmonicsbasefreq=(int)o->value(); +redrawoscil();} + tooltip {Adaptive harmonics base frequency} xywh {670 460 25 25} labelsize 10 maximum 255 step 1 + class WidgetPDial + } + Fl_Slider adhrpar { + callback {oscil->Padaptiveharmonicspar=(int)o->value(); +redrawoscil();} + xywh {670 445 55 10} type {Horz Knob} box FLAT_BOX maximum 100 step 1 value 50 + } + } + Fl_Group {} { + xywh {440 308 150 30} box ENGRAVED_BOX + } { + Fl_Choice modtype { + label {Mod.} + callback {oscil->Pmodulation=(int) o->value(); + +redrawoscil();} + tooltip modulation xywh {470 315 50 15} down_box BORDER_BOX labelsize 10 textsize 10 + } { + menuitem {} { + label None + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Rev + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sine + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Pow + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial modpar1 { + callback {oscil->Pmodulationpar1=(int)o->value(); + +redrawoscil();} + tooltip {Oscillator's modulation parameter 1} xywh {530 315 15 15} maximum 127 step 1 + class WidgetPDial + } + Fl_Dial modpar2 { + callback {oscil->Pmodulationpar2=(int)o->value(); + +redrawoscil();} + tooltip {Oscillator's modulation parameter 2} xywh {550 315 15 15} maximum 127 step 1 + class WidgetPDial + } + Fl_Dial modpar3 { + callback {oscil->Pmodulationpar3=(int)o->value(); +redrawoscil();} + tooltip {Oscillator's modulation parameter 3} xywh {570 315 15 15} maximum 127 step 1 + class WidgetPDial + } + } + Fl_Button {} { + label Sine + callback {if (!fl_ask("Convert to SINE?")) return; + +pthread_mutex_lock(&master->mutex); + oscil->convert2sine(0); +pthread_mutex_unlock(&master->mutex); + +redrawoscil(); +refresh();} + xywh {670 525 55 15} box THIN_UP_BOX labelfont 1 labelsize 12 + } + Fl_Button {} { + label C + callback {presetsui->copy(oscil);} + xywh {670 545 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(oscil,this);} + xywh {700 545 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Scroll _this_has_to_be_the_last { + xywh {5 340 660 250} type HORIZONTAL box ENGRAVED_BOX + } { + Fl_Pack harmonics {open + xywh {10 345 650 225} type HORIZONTAL + code0 {for (int i=0;i<MAX_AD_HARMONICS;i++){h[i]=new Oscilharmonic(0,0,20,o->h(),"");h[i]->init(oscil,i,oscildisplaygroup,oldosc,cbwidget,applybutton,master);}} + } {} + } + } + } + Function {OscilEditor(OscilGen *oscil_,Fl_Widget *oldosc_,Fl_Widget *cbwidget_,Fl_Widget *cbapplywidget_,Master *master_)} {} { + code {oscil=oscil_; +oldosc=oldosc_; +cbwidget=cbwidget_; +cbapplywidget=cbapplywidget_; +master=master_; + +make_window(); + +refresh(); +osceditUI->show();} {} + } + Function {~OscilEditor()} {} { + code {osceditUI->hide(); +//for (int i=0;i<MAX_AD_HARMONICS;i++) delete (h[i]); +delete (osceditUI);} {} + } + Function {refresh()} {} { + code {magtype->value(oscil->Phmagtype); +rndslider->value(oscil->Prand-64); + +hrndtype->value(oscil->Pamprandtype); +hrnddial->value(oscil->Pamprandpower); + +bftype->value(oscil->Pcurrentbasefunc); +bfparval->value(oscil->Pbasefuncpar-64); +bfslider->value(oscil->Pbasefuncpar-64); + +bfmodtype->value(oscil->Pbasefuncmodulation); +bfmodpar1->value(oscil->Pbasefuncmodulationpar1); +bfmodpar2->value(oscil->Pbasefuncmodulationpar2); +bfmodpar3->value(oscil->Pbasefuncmodulationpar3); + +wshbutton->value(oscil->Pwaveshapingfunction); +wsparval->value(oscil->Pwaveshaping-64); +wshpar->value(oscil->Pwaveshaping-64); + +fltbutton->value(oscil->Pfiltertype); +filtervalue1->value(oscil->Pfilterpar1); +filtervalue2->value(oscil->Pfilterpar2); +filterpref->value(oscil->Pfilterbeforews); + +modtype->value(oscil->Pmodulation); +modpar1->value(oscil->Pmodulationpar1); +modpar2->value(oscil->Pmodulationpar2); +modpar3->value(oscil->Pmodulationpar3); + +sabutton->value(oscil->Psatype); +sadjpar->value(oscil->Psapar); + +harmonicshiftcounter->value(oscil->Pharmonicshift); +harmonicshiftpre->value(oscil->Pharmonicshiftfirst); + +adhrtype->value(oscil->Padaptiveharmonics); +adhrbf->value(oscil->Padaptiveharmonicsbasefreq); +adhrpow->value(oscil->Padaptiveharmonicspower); +adhrtype->value(oscil->Padaptiveharmonicspar); + +for (int i=0;i<MAX_AD_HARMONICS;i++) h[i]->refresh(); + +pthread_mutex_lock(&master->mutex); + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +basefuncdisplaygroup->redraw(); +redrawoscil();} {} + } + Function {redrawoscil()} {} { + code {oscildisplaygroup->redraw(); +oldosc->redraw(); +if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +};} {} + } + decl {OscilGen *oscil;} {} + decl {Fl_Widget *oldosc,*cbwidget,*cbapplywidget;} {} + decl {Oscilharmonic *h[MAX_AD_HARMONICS];} {} + decl {Master *master;} {} +} diff --git a/muse/synti/zynaddsubfx/UI/PADnoteUI.fl b/muse/synti/zynaddsubfx/UI/PADnoteUI.fl new file mode 100644 index 00000000..12d34842 --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/PADnoteUI.fl @@ -0,0 +1,1086 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {\#include "../Params/PADnoteParameters.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "ResonanceUI.h"} {public +} + +decl {\#include <FL/Fl_Box.H>} {public +} + +decl {\#include <FL/Fl_Group.H>} {public +} + +decl {\#include <math.h>} {} + +decl {\#include <stdio.h>} {} + +decl {\#include <stdlib.h>} {} + +decl {\#include <string.h>} {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EnvelopeUI.h"} {public +} + +decl {\#include "LFOUI.h"} {public +} + +decl {\#include "FilterUI.h"} {public +} + +decl {\#include "OscilGenUI.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class PADnoteHarmonicProfile {: {public Fl_Box} +} { + Function {PADnoteHarmonicProfile(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {pars=NULL;} {} + } + Function {init(PADnoteParameters *pars,Master *master_)} {} { + code {master=master_; +this->pars=pars;} {} + } + Function {draw()} {} { + code {int ox=x(),oy=y(),lx=w(),ly=h(); +if (!visible()) return; +REALTYPE smps[lx]; + +REALTYPE realbw=pars->getprofile(smps,lx); +bool active=active_r(); + +//draw the equivalent bandwidth +if (active) fl_color(220,220,220); + else fl_color(160,165,165); +fl_line_style(0); +int rbw=(int)(realbw*(lx-1.0)/2.0); +for (int i=lx/2-rbw;i<(lx/2+rbw);i++) fl_line(ox+i,oy,ox+i,oy+ly-1); + +fl_line_style(0); +if (active) fl_color(200,200,200); + else fl_color(160,160,160); +for (int i=1;i<10;i++){ + int kx=(int)(lx/10.0*i); + fl_line(ox+kx,oy,ox+kx,oy+ly-1); +}; +for (int i=1;i<5;i++){ + int ky=(int)(ly/5.0*i); + fl_line(ox,oy+ly-ky,ox+lx,oy+ly-ky-1); +}; + + +fl_color(120,120,120); +fl_line_style(FL_DOT); +fl_line(ox+lx/2,oy,ox+lx/2,oy+ly); + +//draw the graph +fl_line_style(0); +int old=0; +for (int i=0;i<lx;i++){ + int val=(int) ((ly-2)*smps[i]); + if (active) fl_color(180,210,240); + else fl_color(150,150,155); + fl_line(ox+i,oy+ly-1,ox+i,oy+ly-1-val); + if (active) fl_color(0,0,100); + else fl_color(150,150,150); + if (i>0) fl_line(ox+i-1,oy+ly-2-old,ox+i,oy+ly-2-val); + old=val; +}; + + +fl_line_style(FL_DASH); +if (active) fl_color(0,100,220); + else fl_color(150,160,170); +fl_line(ox+lx/2-rbw,oy,ox+lx/2-rbw,oy+ly-1); +fl_line(ox+lx/2+rbw,oy,ox+lx/2+rbw,oy+ly-1); + +fl_line_style(0);} {} + } + decl {Master *master;} {} + decl {PADnoteParameters *pars;} {public + } +} + +class PADnoteOvertonePosition {: {public Fl_Box} +} { + Function {PADnoteOvertonePosition(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {pars=NULL;} {} + } + Function {init(PADnoteParameters *pars,Master *master_)} {} { + code {master=master_; +this->pars=pars;} {} + } + Function {draw()} {} { + code {if (!visible()) return; +const int maxdb=60; + +int ox=x(),oy=y(),lx=w(),ly=h(); +const int maxharmonic=64; + + +for (int i=1;i<maxharmonic;i++){ + fl_color(200,200,200); + fl_line_style(FL_DOT); + if (i%5==0) fl_line_style(0); + if (i%10==0) fl_color(160,160,160); + int kx=(int)(lx/(REALTYPE)maxharmonic*i); + fl_line(ox+kx,oy,ox+kx,oy+ly); +}; + + + +int n=OSCIL_SIZE/2; +REALTYPE spc[n]; +for (int i=0;i<n;i++) spc[i]=0.0; + +pthread_mutex_lock(&master->mutex); +pars->oscilgen->getspectrum(n,spc,0); +pthread_mutex_unlock(&master->mutex); + + +//normalize +REALTYPE max=0; +for (int i=0;i<n;i++){ + REALTYPE x=fabs(spc[i]); + if (max<x) max=x; +} +if (max<0.000001) max=1.0; +max=max*1.05; + +REALTYPE spectrum[lx]; +for (int i=0;i<lx;i++) spectrum[i]=0; + + +for (int i=1;i<n;i++){ + REALTYPE nhr=pars->getNhr(i); + int kx=(int)(lx/(REALTYPE)maxharmonic*nhr); + if ((kx<0)||(kx>lx)) continue; + + spectrum[kx]=spc[i-1]/max+1e-9; + +}; + +fl_color(180,0,0); +fl_line_style(0); + +if (pars->Pmode==2){ + int old=0; + for (int i=1;i<lx;i++){ + if ((spectrum[i]>1e-10)||(i==(lx-1))){ + int delta=i-old; + REALTYPE val1=spectrum[old]; + REALTYPE val2=spectrum[i]; + + REALTYPE idelta=1.0/delta; + for (int j=0;j<delta;j++){ + REALTYPE x=idelta*j; + spectrum[old+j]=val1*(1.0-x)+val2*x; + }; + old=i; + }; + + }; +}; + +for (int i=0;i<lx;i++){ + REALTYPE x=spectrum[i]; + if (x>dB2rap(-maxdb)) x=rap2dB(x)/maxdb+1; + else continue; + int yy=(int)(x*ly); + fl_line(ox+i,oy+ly-1-yy,ox+i,oy+ly-1); + +};} {} + } + decl {Master *master;} {} + decl {PADnoteParameters *pars;} {public + } +} + +class PADnoteUI {open : {public PresetsUI_} +} { + Function {PADnoteUI(PADnoteParameters *parameters,Master *master_)} {open + } { + code {pars=parameters; +master=master_; +oscui=NULL; +resui=new ResonanceUI(pars->resonance); +make_window();} {} + } + Function {make_window()} {open + } { + Fl_Window padnotewindow { + label {PAD synth Parameters} selected + xywh {76 165 535 450} type Double hide + } { + Fl_Tabs {} { + callback {if (o->value()!=harmonicstructuregroup) applybutton->hide(); + else applybutton->show();} + xywh {0 0 535 395} + } { + Fl_Group harmonicstructuregroup { + label {Harmonic Structure} + xywh {0 20 535 375} box ENGRAVED_BOX + } { + Fl_Group bwprofilegroup { + xywh {5 30 90 260} box ENGRAVED_BOX + code0 {if (pars->Pmode!=0) o->deactivate();} + } { + Fl_Dial hpbasepar1 { + label Width + callback {pars->Php.base.par1=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {20 75 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.base.par1);} + class WidgetPDial + } + Fl_Choice hpbasetype { + label {Base Type} + callback {pars->Php.base.type=o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {15 45 75 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code0 {o->value(pars->Php.base.type);} + } { + menuitem {} { + label Gauss + xywh {15 15 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Square + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label DoubleExp + xywh {35 35 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial hpfreqmult { + label FreqMlt + callback {pars->Php.freqmult=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {55 75 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.freqmult);} + class WidgetPDial + } + Fl_Dial hpmpar1 { + label Str + callback {pars->Php.modulator.par1=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {15 115 20 20} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.modulator.par1);} + class WidgetPDial + } + Fl_Dial hpmfreq { + label SFreq + callback {pars->Php.modulator.freq=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {40 115 20 20} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.modulator.freq);} + class WidgetPDial + } + Fl_Group {} { + xywh {10 160 80 105} box BORDER_BOX + } { + Fl_Choice hpamptype { + label AmpMultiplier + callback {pars->Php.amp.type=o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {15 175 70 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code0 {o->value(pars->Php.amp.type);} + } { + menuitem {} { + label OFF + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Gauss + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Sine + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Flat + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + } + Fl_Choice hpampmode { + label AmpMode + callback {pars->Php.amp.mode=o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {15 205 70 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code0 {o->value(pars->Php.amp.mode);} + } { + menuitem {} { + label Sum + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Mult + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Div1 + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Div2 + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial hpamppar1 { + label Par1 + callback {pars->Php.amp.par1=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {15 235 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.amp.par1);} + class WidgetPDial + } + Fl_Dial hpamppar2 { + label Par2 + callback {pars->Php.amp.par2=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {55 235 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.amp.par2);} + class WidgetPDial + } + } + Fl_Check_Button hpautoscale { + label autoscale + callback {pars->Php.autoscale=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {10 270 60 15} down_box DOWN_BOX labelsize 10 + code0 {o->value(pars->Php.autoscale);} + } + Fl_Choice hponehalf { + callback {pars->Php.onehalf=o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {10 143 80 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code0 {o->value(pars->Php.onehalf);} + } { + menuitem {} { + label Full + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {Upper Half} + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {Lower Half} + xywh {35 35 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial hpwidth { + label Size + callback {pars->Php.width=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {65 115 20 20} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.width);} + class WidgetPDial + } + } + Fl_Group {} { + xywh {100 155 270 135} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 align 6 + code0 {osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} + code1 {osc->init(pars->oscilgen,master);} + } {} + Fl_Button {} { + label Change + callback {if (oscui!=NULL) delete (oscui); +oscui=new OscilEditor(pars->oscilgen,osc,cbwidget,applybutton,master);} + xywh {375 270 60 20} box THIN_UP_BOX labelfont 1 labelsize 12 + } + Fl_Box cbwidget { + label {Harmonic Content} + callback {overtonepos->redraw(); +applybutton->color(FL_RED); +applybutton->redraw();} + xywh {125 135 205 20} align 16 + } + Fl_Button {} { + label Resonance + callback {resui->resonancewindow->redraw(); +resui->resonancewindow->show(); +resui->setcbwidget(cbwidget,applybutton);} + xywh {375 225 80 20} box THIN_UP_BOX + } + Fl_Dial bwdial { + label BandWidth + callback {bwcents->value(pars->setPbandwidth((int) o->value())); +cbwidget->do_callback();} + xywh {15 295 35 35} box ROUND_UP_BOX labelsize 11 maximum 1000 step 1 + code0 {o->value(pars->Pbandwidth);} + code1 {if (pars->Pmode!=0) o->deactivate();} + class WidgetPDial + } + Fl_Value_Output bwcents { + label cents + xywh {55 305 55 15} labelsize 10 align 6 maximum 10000 step 0.1 + code0 {o->value(pars->setPbandwidth(pars->Pbandwidth));} + code1 {if (pars->Pmode!=0) o->deactivate();} + } + Fl_Group {} { + xywh {315 295 215 45} box ENGRAVED_BOX + } { + Fl_Choice hrpostype { + label OvertonesPosition + callback {pars->Phrpos.type=o->value(); +overtonepos->redraw(); +cbwidget->do_callback();} + xywh {325 310 80 20} down_box BORDER_BOX labelsize 10 align 5 textsize 12 + code0 {o->value(pars->Phrpos.type);} + } { + menuitem {} { + label Harmonic + xywh {70 70 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label ShiftU + xywh {80 80 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label ShiftL + xywh {90 90 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label PowerU + xywh {90 90 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label PowerL + xywh {100 100 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Sine + xywh {110 110 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Power + xywh {120 120 100 20} labelfont 1 labelsize 12 + } + } + Fl_Dial hrpospar1 { + label Par1 + callback {pars->Phrpos.par1=(int) o->value(); +overtonepos->redraw(); +cbwidget->do_callback();} + xywh {425 310 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 255 step 1 + code0 {o->value(pars->Phrpos.par1);} + class WidgetPDial + } + Fl_Dial hrpospar2 { + label Par2 + callback {pars->Phrpos.par2=(int) o->value(); +overtonepos->redraw(); +cbwidget->do_callback();} + xywh {460 310 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 255 step 1 + code0 {o->value(pars->Phrpos.par2);} + class WidgetPDial + } + Fl_Dial hrpospar3 { + label ForceH + callback {pars->Phrpos.par3=(int) o->value(); +overtonepos->redraw(); +cbwidget->do_callback();} + xywh {495 310 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 255 step 1 + code0 {o->value(pars->Phrpos.par3);} + class WidgetPDial + } + } + Fl_Choice bwscale { + label {Bandwidth Scale} + callback {pars->Pbwscale=(int) o->value(); +cbwidget->do_callback();} + xywh {120 305 80 20} down_box BORDER_BOX labelsize 10 align 5 textsize 12 + code0 {o->value(pars->Pbwscale);} + code1 {if (pars->Pmode!=0) o->deactivate();} + } { + menuitem {} { + label Normal + xywh {95 95 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label EqualHz + xywh {105 105 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Quater + xywh {115 115 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Half + xywh {125 125 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {75%} + xywh {135 135 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {150%} + xywh {145 145 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Double + xywh {145 145 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {Inv.Half} + xywh {155 155 100 20} labelfont 1 labelsize 12 + } + } + Fl_Group overtonepos { + xywh {5 345 525 45} box FLAT_BOX color 54 selection_color 218 labelcolor 63 + code0 {PADnoteOvertonePosition *opui=new PADnoteOvertonePosition(o->x(),o->y(),o->w(),o->h(),"");} + code1 {opui->init(pars,master);} + } {} + Fl_Choice qsamplesize { + label {Sample Size} + callback {pars->Pquality.samplesize=(int) o->value(); +cbwidget->do_callback();} + xywh {375 190 115 20} down_box BORDER_BOX labelsize 10 align 5 textsize 12 + code0 {o->value(pars->Pquality.samplesize);} + } { + menuitem {} { + label {16k (Tiny)} + xywh {155 155 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 32k + xywh {165 165 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {64k (Small)} + xywh {175 175 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 128k + xywh {185 185 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {256k (Normal)} + xywh {205 205 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 512k + xywh {200 200 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {1M (Big)} + xywh {205 205 100 20} labelfont 1 labelsize 12 + } + } + Fl_Choice qsmpoct { + label {smp/oct} + callback {pars->Pquality.smpoct=(int) o->value(); +cbwidget->do_callback();} + xywh {430 155 45 20} down_box BORDER_BOX labelsize 12 align 5 textsize 12 + code0 {o->value(pars->Pquality.smpoct);} + } { + menuitem {} { + label {0.5} + xywh {10 10 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 1 + xywh {0 0 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 2 + xywh {10 10 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 3 + xywh {20 20 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 4 + xywh {30 30 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 6 + xywh {40 40 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 12 + xywh {50 50 100 20} labelfont 1 labelsize 12 + } + } + Fl_Choice qoct { + label {no.oct} + callback {pars->Pquality.oct=(int) o->value(); +cbwidget->do_callback();} + xywh {480 155 45 20} down_box BORDER_BOX labelsize 12 align 5 textsize 12 + code0 {o->value(pars->Pquality.oct);} + } { + menuitem {} { + label 1 + xywh {10 10 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 2 + xywh {20 20 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 3 + xywh {30 30 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 4 + xywh {40 40 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 5 + xywh {50 50 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 6 + xywh {60 60 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 7 + xywh {70 70 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label 8 + xywh {80 80 100 20} labelfont 1 labelsize 12 + } + } + Fl_Choice qbasenote { + label base + callback {pars->Pquality.basenote=(int) o->value(); +cbwidget->do_callback();} + xywh {375 155 50 20} down_box BORDER_BOX labelsize 12 align 5 textsize 12 + code0 {o->value(pars->Pquality.basenote);} + } { + menuitem {} { + label {C-2} + xywh {10 10 100 20} labelfont 1 + } + menuitem {} { + label {G-2} + xywh {20 20 100 20} labelfont 1 + } + menuitem {} { + label {C-3} + xywh {20 20 100 20} labelfont 1 + } + menuitem {} { + label {G-3} + xywh {30 30 100 20} labelfont 1 + } + menuitem {} { + label {C-4} + xywh {30 30 100 20} labelfont 1 + } + menuitem {} { + label {G-4} + xywh {40 40 100 20} labelfont 1 + } + menuitem {} { + label {C-5} + xywh {40 40 100 20} labelfont 1 + } + menuitem {} { + label {G-5} + xywh {50 50 100 20} labelfont 1 + } + menuitem {} { + label {G-6} + xywh {60 60 100 20} labelfont 1 + } + } + Fl_Group hprofile { + xywh {100 45 430 90} box FLAT_BOX color 54 selection_color 218 labelcolor 63 + code0 {PADnoteHarmonicProfile *hpui=new PADnoteHarmonicProfile(o->x(),o->y(),o->w(),o->h(),"");} + code1 {hpui->init(pars,master);} + code2 {if (pars->Pmode!=0) { o->deactivate(); o->color(48);};} + } {} + Fl_Box {} { + label {Profile of One Harmonic (Frequency Distribution)} + xywh {160 25 315 20} + } + Fl_Choice spectrummode { + label {Spectrum Mode} + callback {pars->Pmode=(int) o->value(); + +if (pars->Pmode==0){ + bwprofilegroup->activate(); + bwdial->activate(); + bwcents->activate(); + hprofile->activate(); + hprofile->color(54); + bwscale->activate(); +} else { + bwprofilegroup->deactivate(); + bwdial->deactivate(); + bwcents->deactivate(); + hprofile->deactivate(); + hprofile->color(48); + bwscale->deactivate(); +}; + +cbwidget->do_callback();} + xywh {220 305 90 20} down_box BORDER_BOX labelfont 1 labelsize 10 labelcolor 0 align 5 textsize 12 + code0 {o->value(pars->Pmode);} + } { + menuitem {} { + label Bandwidth + xywh {105 105 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Discrete + xywh {125 125 100 20} labelfont 1 labelsize 12 labelcolor 0 + } + menuitem {} { + label Continous + xywh {115 115 100 20} labelfont 1 labelsize 12 labelcolor 0 + } + } + } + Fl_Group {} { + label {Envelopes&LFOs} + xywh {0 20 535 375} box ENGRAVED_BOX hide + } { + Fl_Group {} { + label FREQUENCY + xywh {5 275 525 115} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + } { + Fl_Group freqenv { + label {PADSynth - Frequency Envelope} open + xywh {10 315 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->FreqEnvelope);} + class EnvelopeUI + } {} + Fl_Counter octave { + label Octave + callback {int k=(int) o->value(); +if (k<0) k+=16; +pars->PCoarseDetune = k*1024+ + pars->PCoarseDetune%1024;} + tooltip Octave xywh {470 295 45 15} type Simple labelsize 10 align 1 minimum -8 maximum 7 step 1 textfont 1 textsize 12 + code0 {int k=pars->PCoarseDetune/1024;} + code1 {if (k>=8) k-=16;} + code2 {o->value(k);} + } + Fl_Counter coarsedet { + label {Coarse det.} + callback {int k=(int) o->value(); +if (k<0) k+=1024; +pars->PCoarseDetune = k+ + (pars->PCoarseDetune/1024)*1024;} + tooltip {Coarse Detune} xywh {455 365 60 20} labelsize 10 align 5 minimum -64 maximum 63 step 1 textfont 1 textsize 12 + code0 {int k=pars->PCoarseDetune%1024;} + code1 {if (k>=512) k-=1024;} + code2 {o->value(k);} + code3 {o->lstep(10);} + } + Fl_Group freqlfo { + label {Frequency LFO } open + xywh {215 315 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->FreqLfo);} + class LFOUI + } {} + Fl_Slider detune { + callback {pars->PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {60 295 295 15} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->PDetune-8192);} + } + Fl_Value_Output detunevalueoutput { + label Detune + callback {o->value(getdetune(pars->PDetuneType,0,pars->PDetune));} + xywh {12 295 45 15} labelsize 10 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 10 + code0 {o->value(getdetune(pars->PDetuneType,0,pars->PDetune));} + } + Fl_Choice detunetype { + label {Detune Type} + callback {pars->PDetuneType=(int) o->value()+1; +detunevalueoutput->do_callback();} open + xywh {450 335 75 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");} + code1 {o->value(pars->PDetuneType-1);} + } {} + Fl_Check_Button hz440 { + label 440Hz + callback {int x=(int) o->value(); +pars->Pfixedfreq=x; +if (x==0) fixedfreqetdial->deactivate(); + else fixedfreqetdial->activate();} + tooltip {set the base frequency to 440Hz} xywh {365 295 50 15} down_box DOWN_BOX labelfont 1 labelsize 11 + code0 {o->value(pars->Pfixedfreq);} + } + Fl_Dial fixedfreqetdial { + label {Eq.T.} + callback {pars->PfixedfreqET=(int) o->value();} + tooltip {How the frequency varies acording to the keyboard (leftmost for fixed frequency)} xywh {420 295 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 + code0 {o->value(pars->PfixedfreqET);} + code1 {if (pars->Pfixedfreq==0) o->deactivate();} + class WidgetPDial + } + } + Fl_Group {} { + label AMPLITUDE + xywh {5 25 240 250} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + } { + Fl_Value_Slider volume { + label Vol + callback {pars->PVolume=(int)o->value();} + tooltip Volume xywh {10 50 160 15} type {Horz Knob} box FLAT_BOX labelsize 12 align 8 maximum 127 step 1 + code0 {o->value(pars->PVolume);} + } + Fl_Value_Slider vsns { + label {V.Sns} + callback {pars->PAmpVelocityScaleFunction=(int) o->value();} + tooltip {Velocity Sensing Function (rightmost to disable)} xywh {10 70 160 15} type {Horz Knob} box FLAT_BOX labelsize 12 align 8 maximum 127 step 1 + code0 {o->value(pars->PAmpVelocityScaleFunction);} + } + Fl_Dial pan { + label Pan + callback {pars->PPanning=(int) o->value();} + tooltip {Panning (leftmost is Random)} xywh {210 45 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(pars->PPanning);} + class WidgetPDial + } + Fl_Dial pstr { + label {P.Str.} + callback {pars->PPunchStrength=(int) o->value();} + tooltip {Punch Strength} xywh {125 247 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->PPunchStrength);} + class WidgetPDial + } + Fl_Dial pt { + label {P.t.} + callback {pars->PPunchTime=(int) o->value();} + tooltip {Punch Time (duration)} xywh {155 247 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->PPunchTime);} + class WidgetPDial + } + Fl_Dial pstc { + label {P.Stc.} + callback {pars->PPunchStretch=(int) o->value();} + tooltip {Punch Stretch} xywh {185 247 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->PPunchStretch);} + class WidgetPDial + } + Fl_Dial pvel { + label {P.Vel.} + callback {pars->PPunchVelocitySensing=(int) o->value();} + tooltip {Punch Velocity Sensing} xywh {215 247 25 25} box ROUND_UP_BOX labelsize 11 align 1 maximum 127 step 1 + code0 {o->value(pars->PPunchVelocitySensing);} + class WidgetPDial + } + Fl_Group ampenv { + label {PADSynth - Amplitude Envelope} open + xywh {10 95 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->AmpEnvelope);} + class EnvelopeUI + } {} + Fl_Group amplfo { + label {Amplitude LFO } open + xywh {10 165 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->AmpLfo);} + class LFOUI + } {} + Fl_Check_Button stereo { + label Stereo + callback {pars->PStereo=(int) o->value(); +hprofile->redraw();} + xywh {15 245 70 25} down_box DOWN_BOX + code0 {o->value(pars->PStereo);} + } + } + Fl_Group {} { + label FILTER + xywh {245 25 285 250} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + } { + Fl_Group filterenv { + label {PADSynth - Filter Envelope} open + xywh {250 130 275 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->FilterEnvelope);} + class EnvelopeUI + } {} + Fl_Group filterlfo { + label {Filter LFO } open + xywh {250 200 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->FilterLfo);} + class LFOUI + } {} + Fl_Group filterui { + label {PADsynth - Filter} open + xywh {250 55 275 75} box FLAT_BOX color 50 align 144 + code0 {o->init(pars->GlobalFilter,&pars->PFilterVelocityScale,&pars->PFilterVelocityScaleFunction);} + class FilterUI + } {} + } + } + } + Fl_Button applybutton { + label {Apply Changes} + callback {pars->applyparameters(true); +o->color(FL_GRAY); +if (oscui!=NULL) { + oscui->applybutton->color(FL_GRAY); + oscui->applybutton->redraw(); +}; +if (resui!=NULL) { + resui->applybutton->color(FL_GRAY); + resui->applybutton->redraw(); +};} + xywh {45 405 185 40} box THIN_UP_BOX labelfont 1 labelsize 23 + code0 {o->color(FL_RED);} + } + Fl_Button {} { + label Close + callback {padnotewindow->hide();} + xywh {320 405 175 40} box THIN_UP_BOX labelsize 20 + } + Fl_Button {} { + label C + callback {presetsui->copy(pars);} + xywh {240 430 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this);} + xywh {270 430 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + } + } + Function {refresh()} {} { + code {volume->value(pars->PVolume); +vsns->value(pars->PAmpVelocityScaleFunction); +pan->value(pars->PPanning); + +stereo->value(pars->PStereo); + + +pstr->value(pars->PPunchStrength); +pt->value(pars->PPunchTime); +pstc->value(pars->PPunchStretch); +pvel->value(pars->PPunchVelocitySensing); + +detunevalueoutput->value(getdetune(pars->PDetuneType,0,pars->PDetune)); +detune->value(pars->PDetune-8192); + +int k=pars->PCoarseDetune/1024;if (k>=8) k-=16; +octave->value(k); + +detunetype->value(pars->PDetuneType-1); +k=pars->PCoarseDetune%1024;if (k>=512) k-=1024; +coarsedet->value(k); + +hz440->value(pars->Pfixedfreq); +fixedfreqetdial->value(pars->PfixedfreqET); + +amplfo->refresh(); +freqlfo->refresh(); +filterlfo->refresh(); + +ampenv->refresh(); +freqenv->refresh(); +filterenv->refresh(); +filterui->refresh(); + + +/* harmonic structure parametrs */ + +resui->refresh(); +if (oscui!=NULL) oscui->refresh(); + +hpbasetype->value(pars->Php.base.type); +hpbasepar1->value(pars->Php.base.par1); +hpfreqmult->value(pars->Php.freqmult); + +hpmpar1->value(pars->Php.modulator.par1); +hpmfreq->value(pars->Php.modulator.freq); +hpwidth->value(pars->Php.width); + +hponehalf->value(pars->Php.onehalf); +hpamptype->value(pars->Php.amp.type); +hpampmode->value(pars->Php.amp.mode); +hpamppar1->value(pars->Php.amp.par1); +hpamppar2->value(pars->Php.amp.par2); +hpautoscale->value(pars->Php.autoscale); + +bwdial->value(pars->Pbandwidth); +if (pars->Pmode==0){ + bwprofilegroup->activate(); + bwdial->activate(); + bwcents->activate(); + hprofile->activate(); + hprofile->color(54); + bwscale->activate(); +} else { + bwprofilegroup->deactivate(); + bwdial->deactivate(); + bwcents->deactivate(); + hprofile->deactivate(); + hprofile->color(48); + bwscale->activate(); +}; + +spectrummode->value(pars->Pmode); + +qbasenote->value(pars->Pquality.basenote); +qsmpoct->value(pars->Pquality.smpoct); +qoct->value(pars->Pquality.oct); +qsamplesize->value(pars->Pquality.samplesize); + +hrpostype->value(pars->Phrpos.type); +hrpospar1->value(pars->Phrpos.par1); +hrpospar2->value(pars->Phrpos.par2); +hrpospar3->value(pars->Phrpos.par3); + +hprofile->redraw(); +overtonepos->redraw(); + +osc->redraw(); +pars->applyparameters(true); +applybutton->color(FL_GRAY); +applybutton->parent()->redraw();} {} + } + Function {~PADnoteUI()} {} { + code {delete(oscui); +delete(resui); + +padnotewindow->hide(); +delete(padnotewindow);} {} + } + decl {PADnoteParameters *pars;} {public + } + decl {Master *master;} {public + } + decl {OscilEditor *oscui;} {public + } + decl {Oscilloscope *osc;} {public + } + decl {ResonanceUI *resui;} {public + } +} diff --git a/muse/synti/zynaddsubfx/UI/PartUI.fl b/muse/synti/zynaddsubfx/UI/PartUI.fl new file mode 100644 index 00000000..f40d3de2 --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/PartUI.fl @@ -0,0 +1,1086 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0104 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <string.h>} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EffUI.h"} {public +} + +decl {\#include "BankUI.h"} {public +} + +decl {\#include "ADnoteUI.h"} {public +} + +decl {\#include "SUBnoteUI.h"} {public +} + +decl {\#include "PADnoteUI.h"} {public +} + +decl {\#include "../Misc/Config.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "../Misc/Part.h"} {public +} + +class PartSysEffSend {: {public Fl_Group} +} { + Function {make_window()} {private + } { + Fl_Window syseffsend { + private xywh {584 83 90 35} type Double hide + class Fl_Group + } { + Fl_Dial {} { + label 01 + callback {master->setPsysefxvol(npart,neff,(int) o->value());} + 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);o->label(strdup(tmp));} + class WidgetPDial + } + } + } + Function {PartSysEffSend(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {master=NULL; +neff=0; +npart=0;} {} + } + Function {init(Master *master_,int npart_,int neff_)} {} { + code {npart=npart_; +neff=neff_; +master=master_; +make_window(); +syseffsend->show(); +end();} {} + } + Function {~PartSysEffSend()} {} { + code {syseffsend->hide(); +//delete(syseffsend);} {} + } + decl {Master *master;} {} + decl {int neff;} {} + decl {int npart;} {} +} + +class PartUI_ {} { + Function {showparameters(int kititem,int engine)} {return_type virtual + } {} +} + +class PartKitItem {: {public Fl_Group} +} { + Function {make_window()} {private + } { + Fl_Window partkititem { + private xywh {113 271 670 30} type Double hide + class Fl_Group + } { + Fl_Group partkititemgroup { + private xywh {55 0 605 20} box FLAT_BOX + code0 {if (part->kit[n].Penabled==0) o->deactivate();} + } { + Fl_Counter minkcounter { + callback {part->kit[n].Pminkey=(int)o->value();} + xywh {225 0 55 15} type Simple minimum 0 maximum 128 step 1 + code0 {o->value(part->kit[n].Pminkey);} + } + Fl_Button {} { + label m + callback {if (part->lastnote>=0) minkcounter->value(part->lastnote); +minkcounter->do_callback(); +maxkcounter->do_callback();} + tooltip {set the minimum key to the last pressed key} xywh {285 3 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label M + callback {if (part->lastnote>=0) maxkcounter->value(part->lastnote); +maxkcounter->do_callback(); +minkcounter->do_callback();} + tooltip {set the maximum key to the last pressed key} xywh {315 3 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label R + callback {minkcounter->value(0); +minkcounter->do_callback(); +maxkcounter->value(127); +maxkcounter->do_callback();} + tooltip {reset the minimum key to 0 and maximum key to 127} xywh {300 3 15 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Button adeditbutton { + label edit + callback {partui->showparameters(n,0);} + xywh {420 0 40 15} box THIN_UP_BOX labelsize 12 + code0 {if (part->kit[n].Padenabled==0) o->deactivate();} + code1 {if (n==0) o->hide();} + } + Fl_Button subeditbutton { + label edit + callback {partui->showparameters(n,1);} + xywh {490 0 40 15} box THIN_UP_BOX labelsize 12 + code0 {if (part->kit[n].Psubenabled==0) o->deactivate();} + code1 {if (n==0) o->hide();} + } + Fl_Check_Button mutedcheck { + callback {part->kit[n].Pmuted=(int)o->value();} + private xywh {60 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 12 align 4 + code0 {o->value(part->kit[n].Pmuted);} + } + Fl_Counter maxkcounter { + callback {part->kit[n].Pmaxkey=(int)o->value();} + xywh {335 0 55 15} type Simple minimum 0 maximum 128 step 1 + code0 {o->value(part->kit[n].Pmaxkey);} + } + Fl_Button labelbutton { + label {Bass Drum} + callback {const char *tmp=fl_input("Kit item name:",(const char *)part->kit[n].Pname); +if (tmp!=NULL) snprintf((char *)part->kit[n].Pname,PART_MAX_NAME_LEN,"%s",tmp);} + xywh {90 0 130 15} box THIN_DOWN_BOX down_box FLAT_BOX labelfont 1 labelsize 11 align 20 + code0 {o->label((char *)part->kit[n].Pname);} + } + Fl_Check_Button adcheck { + callback {part->kit[n].Padenabled=(int)o->value(); +if (part->kit[n].Padenabled!=0) adeditbutton->activate(); + else adeditbutton->deactivate();} + private xywh {400 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 12 align 4 + code0 {o->value(part->kit[n].Padenabled);} + code1 {if (n==0) o->hide();} + } + Fl_Check_Button subcheck { + callback {part->kit[n].Psubenabled=(int)o->value(); +if (part->kit[n].Psubenabled!=0) subeditbutton->activate(); + else subeditbutton->deactivate();} + private xywh {470 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 12 align 4 + code0 {o->value(part->kit[n].Psubenabled);} + code1 {if (n==0) o->hide();} + } + Fl_Choice sendtoeffect { + callback {if (o->value()!=0) part->kit[n].Psendtoparteffect=(int)o->value()-1; + else part->kit[n].Psendtoparteffect=127;} open + xywh {615 0 45 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("OFF");char nrstr[10]; for(int i=0;i<NUM_PART_EFX;i++){sprintf(nrstr,"FX%d",i+1);o->add(nrstr);};} + code1 {o->value(part->kit[n].Psendtoparteffect+1);if (part->kit[n].Psendtoparteffect==127) o->value(0);} + } {} + Fl_Button padeditbutton { + label edit + callback {partui->showparameters(n,2);} + xywh {560 0 40 15} box THIN_UP_BOX labelsize 12 + code0 {if (part->kit[n].Ppadenabled==0) o->deactivate();} + code1 {if (n==0) o->hide();} + } + Fl_Check_Button padcheck { + callback {part->kit[n].Ppadenabled=(int)o->value(); +if (part->kit[n].Ppadenabled!=0) padeditbutton->activate(); + else padeditbutton->deactivate();} + private xywh {540 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 12 align 4 + code0 {o->value(part->kit[n].Ppadenabled);} + code1 {if (n==0) o->hide();} + } + } + Fl_Check_Button enabledcheck { + label 01 + callback {int answer=1; +if (o->value()==0) answer=fl_ask("Delete the item?"); +if (answer!=0){ +pthread_mutex_lock(&master->mutex); + part->setkititemstatus(n,(int) o->value()); +pthread_mutex_unlock(&master->mutex); + +if (o->value()==0) partkititemgroup->deactivate(); +else partkititemgroup->activate(); +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 16 align 4 + code0 {snprintf(label,10,"%d",n+1);o->label(strdup(label));} + code1 {o->value(part->kit[n].Penabled);} + code2 {if (n==0) o->deactivate();} + } + } + } + Function {PartKitItem(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {n=0; +part=NULL;} {} + } + Function {refresh()} {} { + code {enabledcheck->value(part->kit[n].Penabled); +if (part->kit[n].Penabled==0) partkititemgroup->deactivate(); +else partkititemgroup->activate(); + +mutedcheck->value(part->kit[n].Pmuted); +labelbutton->label((char *)part->kit[n].Pname); +minkcounter->value(part->kit[n].Pminkey); +maxkcounter->value(part->kit[n].Pmaxkey); +adcheck->value(part->kit[n].Padenabled); +adcheck->do_callback(); +subcheck->value(part->kit[n].Psubenabled); +subcheck->do_callback(); + +sendtoeffect->value(part->kit[n].Psendtoparteffect+1); +if (part->kit[n].Psendtoparteffect==127) sendtoeffect->value(0); + +this->redraw();} { + callback {int answer=1; +if (o->value()==0) answer=fl_ask("Delete the item?"); +if (answer!=0){ +pthread_mutex_lock(&master->mutex); + part->setkititemstatus(n,(int) o->value()); +pthread_mutex_unlock(&master->mutex); + +if (o->value()==0) partkititemgroup->deactivate(); +else partkititemgroup->activate(); +o->redraw(); +partui->showparameters(n,-1);//use to delete the ui, if it is not to item 0 +} else o->value(1);} + } + } + Function {init(Part *part_,int n_,Master *master_,PartUI_ *partui_)} {} { + code {part=part_; +n=n_; +partui=partui_; +master=master_; +make_window(); +//partkititem->show(); +end();} {} + } + Function {~PartKitItem()} {} { + code {partkititem->hide(); +//delete(partkititem);} {} + } + decl {Part *part;} {} + decl {int n;} {} + decl {Master *master;} {} + decl {char label[10];} {} + decl {PartUI_ *partui;} {} +} + +class PartUI {: {public Fl_Group,PartUI_} +} { + Function {make_window()} {private + } { + Fl_Window partgroup { + private xywh {107 533 385 180} type Double hide + class Fl_Group + } { + Fl_Group partgroupui { + xywh {0 0 385 180} + code0 {if (part->Penabled==0) o->deactivate();} + } { + Fl_Dial {} { + label Pan + callback {part->setPpanning((int) o->value());} + xywh {50 40 25 25} box ROUND_UP_BOX labelsize 12 maximum 127 step 1 + code0 {o->value(part->Ppanning);} + class WidgetPDial + } + Fl_Counter {} { + label KeyShift + callback {part->Pkeyshift=(int) o->value()+64;} + xywh {195 45 90 20} labelsize 12 align 1 minimum -64 maximum 64 step 1 + code0 {o->lstep(12);} + code1 {o->value(part->Pkeyshift-64);} + } + Fl_Scroll {} {open + xywh {166 91 125 60} box ENGRAVED_FRAME labelfont 1 labelsize 10 align 21 + } { + Fl_Pack {} {open + xywh {171 96 115 35} type HORIZONTAL + code0 {o->spacing(5);} + code1 {for (int i=0;i<NUM_SYS_EFX;i++){psyef[i]=new PartSysEffSend(0,0,25,35,"");psyef[i]->init(master,npart,i);}} + } {} + } + Fl_Button {} { + label {Grand Piano} + callback {int event=Fl::event_button(); +if (event==FL_RIGHT_MOUSE){ + const char *tmp=fl_input("Instrument name:",(const char *)part->Pname); + if (tmp!=NULL) snprintf((char *)part->Pname,PART_MAX_NAME_LEN,"%s",tmp); +} else { + if (event==FL_LEFT_MOUSE) bankui->show(); + else instrumenteditwindow->show(); +};} selected + tooltip {left mousebutton - to choose/save/.. from/to bank or right mousebutton to change the name or middle button to change the instrument information} xywh {195 5 185 20} box THIN_DOWN_BOX down_box FLAT_BOX labelfont 1 labelsize 12 align 84 + code0 {o->label((char *)part->Pname);} + } + Fl_Box {} { + label {To Sys.Efx.} + xywh {166 81 95 10} labelfont 1 labelsize 10 + } + Fl_Check_Button {} { + label NoteOn + callback {part->Pnoteon=(int) o->value();} + tooltip {set if the part receives NoteOn messages} xywh {0 155 65 20} down_box DOWN_BOX labelfont 1 labelsize 12 + code0 {o->value(part->Pnoteon);} + } + Fl_Counter minkcounter { + label {Min.k} + callback {part->Pminkey=(int) o->value(); +if (part->Pminkey>part->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK);} + tooltip {Minimum key (that the part receives NoteOn messages)} xywh {295 125 40 15} type Simple labelfont 1 labelsize 10 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->value(part->Pminkey);} + } + Fl_Counter maxkcounter { + label {Max.k} + callback {part->Pmaxkey=(int) o->value(); + +if (part->Pminkey>part->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK);} + tooltip {Maximum key (that the part receives NoteOn messages)} xywh {340 125 40 15} type Simple labelfont 1 labelsize 10 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->value(part->Pmaxkey);} + } + Fl_Dial {} { + label Volume + callback {part->setPvolume((int) o->value());} + tooltip {Part Volume} xywh {10 35 30 30} box ROUND_UP_BOX labelsize 12 maximum 127 step 1 + code0 {o->value(part->Pvolume);} + class WidgetPDial + } + Fl_Dial {} { + label {Vel.Ofs.} + callback {part->Pveloffs=(int) o->value();} + tooltip {Velocity Offset} xywh {135 40 25 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(part->Pveloffs);} + class WidgetPDial + } + Fl_Dial {} { + label {Vel.Sns.} + callback {part->Pvelsns=(int) o->value();} + tooltip {Velocity Sensing Function} xywh {95 40 25 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(part->Pvelsns);} + class WidgetPDial + } + Fl_Button {} { + label Controllers + callback {ctlwindow->show();} + xywh {295 90 85 30} box PLASTIC_UP_BOX labelfont 1 labelsize 12 + } + Fl_Check_Button {} { + label Poly + callback {part->Ppolymode=(int) o->value();} + tooltip {Part mode (mono/poly)} xywh {65 155 45 20} down_box DOWN_BOX labelfont 1 labelsize 12 + code0 {o->value(part->Ppolymode);} + } + Fl_Check_Button {} { + label Portamento + callback {part->ctl.portamento.portamento=(int) o->value();} + tooltip {Enable/Disable the portamento} xywh {115 155 85 20} down_box DOWN_BOX labelfont 1 labelsize 12 + code0 {o->value(part->ctl.portamento.portamento);} + } + Fl_Button {} { + label {Edit instrument} + callback {instrumenteditwindow->show();} + xywh {15 105 130 30} box PLASTIC_UP_BOX color 230 labelfont 1 labelsize 17 + } + Fl_Button {} { + label m + callback {if (part->lastnote>=0) minkcounter->value(part->lastnote); +minkcounter->do_callback(); +maxkcounter->do_callback();} + tooltip {set the minimum key to the last pressed key} xywh {315 155 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label M + callback {if (part->lastnote>=0) maxkcounter->value(part->lastnote); +maxkcounter->do_callback(); +minkcounter->do_callback();} + tooltip {set the maximum key to the last pressed key} xywh {345 155 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label R + callback {minkcounter->value(0); +minkcounter->do_callback(); +maxkcounter->value(127); +maxkcounter->do_callback();} + tooltip {reset the minimum key to 0 and maximum key to 127} xywh {330 155 15 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Choice {} { + label {MIDI Chn.Rcv.} + callback {part->Prcvchn=(int) o->value();} open + tooltip {receive from Midi channel} xywh {310 45 70 20} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {char nrstr[10]; for(int i=0;i<NUM_MIDI_CHANNELS;i++){sprintf(nrstr,"Chn%d",i+1);if (i!=9) o->add(nrstr); else o->add("Drms10");};} + code1 {o->value(part->Prcvchn);} + } {} + Fl_Choice keylimitlist { + label KLmt + callback {int val=0; +val=atoi(o->text()); +part->setkeylimit(val);} open + tooltip {Key Limit} xywh {210 155 50 20} down_box BORDER_BOX labelsize 10 align 8 textfont 1 textsize 10 + } {} + } + Fl_Check_Button {} { + label Enabled + callback {pthread_mutex_lock(&master->mutex); +master->partonoff(npart,(int) o->value()); +pthread_mutex_unlock(&master->mutex); +if (part->Penabled==0) partgroupui->deactivate(); + else partgroupui->activate();} + xywh {90 5 75 20} down_box DOWN_BOX labelfont 1 labelsize 12 + code0 {o->value(part->Penabled);} + } + } + Fl_Window ctlwindow { + label Controllers + private xywh {198 472 460 130} type Double hide + } { + Fl_Check_Button {} { + label Expr + callback {part->ctl.expression.receive=(int) o->value();} + tooltip {Expression enable} xywh {155 55 45 20} box THIN_UP_BOX down_box DOWN_BOX labelsize 10 + code0 {o->value(part->ctl.expression.receive);} + } + Fl_Dial {} { + label PanDpth + callback {part->ctl.panning.depth=(int) o->value();} + tooltip {Panning Depth} xywh {10 55 30 30} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.panning.depth);} + class WidgetPDial + } + Fl_Dial {} { + label FltCut + callback {part->ctl.filtercutoff.depth=(int) o->value();} + tooltip {Filter Cutoff depth} xywh {90 55 30 30} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.filtercutoff.depth);} + class WidgetPDial + } + Fl_Dial {} { + label FltQ + callback {part->ctl.filterq.depth=(int) o->value();} + tooltip {Filter Q depth} xywh {50 55 30 30} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.filterq.depth);} + class WidgetPDial + } + Fl_Dial {} { + label BwDpth + callback {part->ctl.bandwidth.depth=(int) o->value();} + tooltip {BandWidth depth} xywh {125 10 30 30} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.bandwidth.depth);} + class WidgetPDial + } + Fl_Dial {} { + label ModWh + callback {part->ctl.modwheel.depth=(int) o->value();} + tooltip {Modulation Wheel depth} xywh {50 10 30 30} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.modwheel.depth);} + class WidgetPDial + } + Fl_Counter {} { + label {PWheelB.Rng (cents)} + callback {part->ctl.pitchwheel.bendrange=(int) o->value();} + tooltip {Pitch Wheel Bend Range (cents)} xywh {165 15 110 20} labelsize 10 align 1 minimum -6400 maximum 6400 step 1 + code0 {o->value(part->ctl.pitchwheel.bendrange);} + code1 {o->lstep(100);} + } + Fl_Check_Button {} { + label FMamp + callback {part->ctl.fmamp.receive=(int) o->value();} + tooltip {FM amplitude enable} xywh {205 55 60 20} box THIN_UP_BOX down_box DOWN_BOX labelsize 10 + code0 {o->value(part->ctl.fmamp.receive);} + } + Fl_Check_Button {} { + label Vol + callback {part->ctl.volume.receive=(int) o->value();} + tooltip {Volume enable} xywh {155 80 45 20} box THIN_UP_BOX down_box DOWN_BOX labelsize 10 + code0 {o->value(part->ctl.volume.receive);} + } + Fl_Check_Button {} { + label Sustain + callback {part->ctl.sustain.receive=(int) o->value(); +if (part->ctl.sustain.receive==0) { + part->RelaseSustainedKeys(); + part->ctl.setsustain(0); +};} + tooltip {Sustain pedal enable} xywh {205 80 60 20} box THIN_UP_BOX down_box DOWN_BOX labelsize 10 + code0 {o->value(part->ctl.sustain.receive);} + } + Fl_Button {} { + label Close + callback {ctlwindow->hide();} + xywh {330 105 95 20} box THIN_UP_BOX + } + Fl_Button {} { + label {Reset all controllers} + callback {part->SetController(C_resetallcontrollers,0);} + xywh {5 105 210 20} box THIN_UP_BOX + } + Fl_Group {} { + label Portamento open + xywh {280 15 120 85} box ENGRAVED_FRAME labelfont 1 labelsize 10 + } { + Fl_Check_Button {} { + label Rcv + callback {part->ctl.portamento.receive=(int) o->value();} + tooltip {Receive Portamento Controllers} xywh {285 20 40 20} box THIN_UP_BOX down_box DOWN_BOX labelsize 10 + code0 {o->value(part->ctl.portamento.receive);} + } + Fl_Dial {} { + label time + callback {part->ctl.portamento.time=(int) o->value();} + tooltip {Portamento time} xywh {285 60 25 25} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.portamento.time);} + class WidgetPDial + } + Fl_Counter {} { + label thresh + callback {part->ctl.portamento.pitchthresh=(int) o->value();} + tooltip {Minimum or max. difference of the notes in order to do the portamento (x 100 cents)} xywh {340 20 50 20} type Simple labelsize 10 minimum 0 maximum 127 step 1 + code0 {o->value(part->ctl.portamento.pitchthresh);} + } + Fl_Check_Button {} { + label {th.type} + callback {part->ctl.portamento.pitchthreshtype=(int) o->value();} + tooltip {Threshold type (min/max)} xywh {370 70 15 15} down_box DOWN_BOX labelsize 10 align 2 + code0 {o->value(part->ctl.portamento.pitchthreshtype);} + } + Fl_Box {} { + label {x100 cnt.} + xywh {340 50 55 15} labelsize 10 align 16 + } + Fl_Dial {} { + label {t.dn/up} + callback {int x=(int) o->value(); + +part->ctl.portamento.updowntimestretch=x;} + tooltip {Portamento time stretch (up/down)} xywh {315 60 25 25} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.portamento.updowntimestretch);} + class WidgetPDial + } + } + Fl_Group {} { + label Resonance open + xywh {400 15 45 85} box ENGRAVED_BOX labelfont 1 labelsize 10 + } { + Fl_Dial {} { + label BWdpth + callback {part->ctl.resonancebandwidth.depth=(int) o->value();} + tooltip {BandWidth controller depth} xywh {410 60 25 25} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.resonancebandwidth.depth);} + class WidgetPDial + } + Fl_Dial {} { + label CFdpth + callback {part->ctl.resonancecenter.depth=(int) o->value();} + tooltip {Center Frequency controller Depth} xywh {410 20 25 25} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.resonancecenter.depth);} + class WidgetPDial + } + } + Fl_Check_Button {} { + label {Exp MWh} + callback {part->ctl.modwheel.exponential=(int) o->value();} + tooltip {Exponential modulation wheel} xywh {10 15 40 25} down_box DOWN_BOX labelsize 10 align 148 + code0 {o->value(part->ctl.modwheel.exponential);} + } + Fl_Check_Button {} { + label {Exp BW} + callback {part->ctl.bandwidth.exponential=(int) o->value();} + tooltip {Exponential BandWidth Controller} xywh {85 15 35 25} down_box DOWN_BOX labelsize 10 align 148 + code0 {o->value(part->ctl.bandwidth.exponential);} + } + } + Fl_Window partfx { + label {Part's Insert Effects} + private xywh {121 424 390 145} type Double hide + } { + Fl_Counter inseffnocounter { + label {FX No.} + callback {ninseff=(int) o->value()-1; +insefftype->value(part->partefx[ninseff]->geteffect()); +//insefftype->do_callback(); +inseffectui->refresh(part->partefx[ninseff]); +int x=part->Pefxroute[ninseff]; +if (x==127) x=1; +bypasseff->value(part->Pefxbypass[ninseff]); + +sendtochoice->value(x);} + xywh {5 110 80 20} type Simple labelfont 1 align 6 minimum 1 maximum 127 step 1 textfont 1 + code0 {o->bounds(1,NUM_PART_EFX);} + code1 {o->value(ninseff+1);} + } + Fl_Choice insefftype { + label EffType + callback {pthread_mutex_lock(part->mutex); +part->partefx[ninseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(part->mutex); +inseffectui->refresh(part->partefx[ninseff]);} + xywh {155 110 70 15} down_box BORDER_BOX labelsize 11 align 6 + code0 {o->value(part->partefx[ninseff]->geteffect());} + } { + menuitem {} { + label {No Effect} + xywh {35 35 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Reverb + xywh {45 45 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Echo + xywh {55 55 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Chorus + xywh {65 65 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Phaser + xywh {70 70 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label AlienWah + xywh {80 80 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Distortion + xywh {90 90 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label EQ + xywh {100 100 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label DynFilter + xywh {110 110 100 20} labelfont 1 labelsize 11 + } + } + Fl_Group inseffectuigroup { + xywh {5 5 380 100} box FLAT_BOX color 48 + } { + Fl_Group inseffectui { + xywh {5 5 380 95} + code0 {o->init(part->partefx[ninseff]);} + class EffUI + } {} + } + Fl_Button {} { + label Close + callback {partfx->hide();} + xywh {325 115 60 20} box THIN_UP_BOX + } + Fl_Choice sendtochoice { + label {Send To.} + callback {int x=(int) o->value(); +part->Pefxroute[ninseff]=x; +if (x==2) part->partefx[ninseff]->setdryonly(true); + else part->partefx[ninseff]->setdryonly(false);} + xywh {235 110 80 15} down_box BORDER_BOX labelsize 11 align 6 + code0 {int x=part->Pefxroute[ninseff]; if (x==127) x=1;} + code1 {o->value(x);} + } { + menuitem {} { + label {Next Effect} + xywh {45 45 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label {Part Out} + xywh {55 55 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label {Dry Out} + xywh {65 65 100 20} labelfont 1 labelsize 11 + } + } + Fl_Check_Button bypasseff { + label bypass + callback {part->Pefxbypass[ninseff]=(((int)o->value())!=0);} + tooltip {if the effect is not used (is bypassed)} xywh {90 110 60 15} down_box DOWN_BOX labelsize 12 + code0 {int x=part->Pefxbypass[ninseff];o->value(x);} + } + Fl_Button {} { + label C + callback {presetsui->copy(part->partefx[ninseff]);} + xywh {90 127 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Button {} { + label P + callback {pthread_mutex_lock(&master->mutex); +presetsui->paste(part->partefx[ninseff],inseffectui); +pthread_mutex_unlock(&master->mutex);} + xywh {120 127 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + } + Fl_Window instrumentkitlist { + label {Instrument Kit} + xywh {113 324 670 370} type Double hide + } { + Fl_Button {} { + label {Close Window} + callback {instrumentkitlist->hide();} + xywh {375 350 160 20} box THIN_UP_BOX + } + Fl_Scroll kitlist { + xywh {0 15 670 330} type VERTICAL box THIN_UP_BOX + code0 {if (part->Pkitmode==0) o->deactivate();} + } { + Fl_Pack {} { + xywh {0 20 670 320} + code0 {for (int i=0;i<NUM_KIT_ITEMS;i++){partkititem[i]=new PartKitItem(0,0,670,20,"");partkititem[i]->init(part,i,master,this);}} + } {} + } + Fl_Box {} { + label {No.} + xywh {5 0 25 15} labelfont 1 labelsize 12 align 18 + } + Fl_Box {} { + label {M.} + xywh {55 0 25 15} labelfont 1 labelsize 12 align 18 + } + Fl_Box {} { + label {Min.k} + xywh {235 0 40 15} labelfont 1 labelsize 12 align 18 + } + Fl_Box {} { + label {Max.k} + xywh {345 0 40 15} labelfont 1 labelsize 12 align 18 + } + Fl_Box {} { + label ADsynth + xywh {405 0 50 15} labelfont 1 labelsize 12 align 18 + } + Fl_Box {} { + label SUBsynth + xywh {470 0 60 15} labelfont 1 labelsize 12 align 18 + } + Fl_Choice {} { + label Mode + callback {part->Pkitmode=(int) o->value(); +if (part->Pkitmode==0) { + kitlist->deactivate(); + } else { + kitlist->activate(); +};} + xywh {35 350 70 15} down_box BORDER_BOX labelsize 12 textfont 1 textsize 12 + code0 {o->value(part->Pkitmode);} + } { + menuitem {} { + label OFF + xywh {0 0 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label MULTI + xywh {10 10 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label SINGLE + xywh {20 20 100 20} labelfont 1 labelsize 12 + } + } + Fl_Check_Button {} { + label {Drum mode} + callback {part->Pdrummode=(int) o->value();} + xywh {285 350 70 15} down_box DOWN_BOX labelsize 11 + code0 {o->value(part->Pdrummode);} + } + Fl_Box {} { + label {FX.r.} + xywh {620 0 30 15} labelfont 1 labelsize 12 align 18 + } + Fl_Box {} { + label PADsynth + xywh {540 0 60 15} labelfont 1 labelsize 12 align 18 + } + } + Fl_Window instrumenteditwindow { + label {Instrument Edit} + xywh {182 214 395 360} type Double hide + } { + Fl_Group {} { + xywh {0 220 395 110} box ENGRAVED_FRAME + } { + Fl_Group {} { + label PADsynth + xywh {205 245 100 80} box ENGRAVED_FRAME labelfont 1 + } { + Fl_Button padeditbutton { + label Edit + callback {showparameters(0,2);} + xywh {215 280 80 35} box PLASTIC_UP_BOX color 222 selection_color 220 labelfont 1 labelsize 18 align 128 + code0 {if (part->kit[0].Ppadenabled==0) o->deactivate();} + } + Fl_Check_Button padsynenabledcheck { + label Enabled + callback {int x=(int) o->value(); +part->kit[0].Ppadenabled=x; +if (x==0) padeditbutton->deactivate(); + else padeditbutton->activate();} + tooltip {enable/disable PADsynth} xywh {215 255 80 20} box PLASTIC_UP_BOX down_box DOWN_BOX color 222 selection_color 218 labelfont 1 labelsize 12 + code1 {o->value(part->kit[0].Ppadenabled);} + } + } + Fl_Group {} { + label ADDsynth + xywh {5 245 100 80} box ENGRAVED_FRAME labelfont 1 + } { + Fl_Check_Button adsynenabledcheck { + label Enabled + callback {int x=(int) o->value(); +part->kit[0].Padenabled=x; +if (x==0) adeditbutton->deactivate(); + else adeditbutton->activate();} + tooltip {enable/disable ADsynth} xywh {15 255 80 20} box PLASTIC_UP_BOX down_box DOWN_BOX color 222 selection_color 218 labelfont 1 labelsize 12 + code1 {o->value(part->kit[0].Padenabled);} + } + Fl_Button adeditbutton { + label Edit + callback {showparameters(0,0);} + xywh {15 281 80 34} box PLASTIC_UP_BOX color 222 selection_color 220 labelfont 1 labelsize 18 align 128 + code0 {if (part->kit[0].Padenabled==0) o->deactivate();} + } + } + Fl_Group {} { + label SUBsynth + xywh {105 245 100 80} box ENGRAVED_FRAME labelfont 1 + } { + Fl_Check_Button subsynenabledcheck { + label Enabled + callback {int x=(int) o->value(); +part->kit[0].Psubenabled=x; +if (x==0) subeditbutton->deactivate(); + else subeditbutton->activate();} + tooltip {enable/disable SUBsynth} xywh {115 255 80 20} box PLASTIC_UP_BOX down_box DOWN_BOX color 222 selection_color 218 labelfont 1 labelsize 12 + code1 {o->value(part->kit[0].Psubenabled);} + } + Fl_Button subeditbutton { + label Edit + callback {showparameters(0,1);} + xywh {115 280 80 35} box PLASTIC_UP_BOX color 222 selection_color 220 labelfont 1 labelsize 18 align 128 + code0 {if (part->kit[0].Psubenabled==0) o->deactivate();} + } + } + Fl_Button {} { + label {Kit Edit} + callback {instrumentkitlist->show();} + xywh {310 245 80 35} box PLASTIC_UP_BOX color 238 selection_color 220 labelfont 1 align 128 + } + Fl_Button {} { + label Effects + callback {partfx->show();} + xywh {310 290 80 35} box PLASTIC_UP_BOX color 230 labelfont 1 labelsize 16 + } + } + Fl_Group {} { + xywh {0 5 395 215} box ENGRAVED_FRAME + } { + Fl_Input {} { + label {Author and Copyright} + callback {snprintf((char *)part->info.Pauthor,MAX_INFO_TEXT_SIZE,"%s",o->value());} + xywh {5 60 385 50} type Multiline color 26 labelsize 10 align 5 + code0 {o->maximum_size(MAX_INFO_TEXT_SIZE);} + code1 {o->value((char *) &part->info.Pauthor);} + } + Fl_Input {} { + label Comments + callback {snprintf((char *)part->info.Pcomments,MAX_INFO_TEXT_SIZE,"%s",o->value());} + xywh {5 125 385 90} type Multiline color 26 labelsize 12 align 5 + code0 {o->maximum_size(MAX_INFO_TEXT_SIZE);} + code1 {o->value((char *) &part->info.Pcomments);} + } + Fl_Choice {} { + label {Type:} + callback {part->info.Ptype=o->value();} + xywh {5 25 155 20} down_box BORDER_BOX labelfont 1 labelsize 12 align 5 textsize 11 + code0 {o->value(part->info.Ptype);} + } { + menuitem {} { + label {--------------------------} + xywh {20 20 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Piano + xywh {10 10 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {Chromatic Percussion} + xywh {20 20 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Organ + xywh {30 30 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Guitar + xywh {40 40 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Bass + xywh {50 50 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {Solo Strings} + xywh {60 60 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Ensemble + xywh {70 70 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Brass + xywh {80 80 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Reed + xywh {90 90 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Pipe + xywh {100 100 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {Synth Lead} + xywh {110 110 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {Synth Pad} + xywh {120 120 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {Synth Effects} + xywh {130 130 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Ethnic + xywh {140 140 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label Percussive + xywh {150 150 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {Sound Effects} + xywh {160 160 100 20} labelfont 1 labelsize 12 + } + } + } + Fl_Button {} { + label Close + callback {instrumenteditwindow->hide();} + xywh {150 335 95 25} box THIN_UP_BOX + } + } + } + Function {PartUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {part=NULL; +adnoteui=NULL; +subnoteui=NULL; +padnoteui=NULL; +lastkititem=-1;} {} + } + Function {init(Part *part_,Master *master_,int npart_,BankUI *bankui_)} {} { + code {bankui=bankui_; +part=part_; +npart=npart_; +master=master_; +ninseff=0; + +make_window(); +partgroup->position(this->parent()->x()+2,this->parent()->y()+2); +partgroup->show(); +end(); + + +//if (config.ui.showinstrumentinfo!=0) instrumenteditwindow->show(); + +int klimits[]={1,2,3,4,5,6,7,8,9,10,15,20,30,50,100,0}; + +keylimitlist->add("OFF"); +int k=0; +int val=-1; +char tmp[10]; +while (klimits[k]!=0){ + sprintf(tmp,"%d",klimits[k]); + keylimitlist->add(tmp); + if ((val==-1)){ + if (klimits[k]>part->Pkeylimit) val=k; + }; + k++; +}; + +if (val==-1) val=k; +keylimitlist->value(val);} {} + } + Function {showparameters(int kititem,int engine)} {} { + code {if (engine==-1){//this is used if I want to clear the engine from the part + if (kititem==lastkititem) kititem=-1; + else kititem=lastkititem; +}; + +if (kititem!=lastkititem){ + if (adnoteui!=NULL) delete (adnoteui); + if (subnoteui!=NULL) delete (subnoteui); + if (padnoteui!=NULL) delete (padnoteui); + adnoteui=NULL;subnoteui=NULL;padnoteui=NULL; + lastkititem=kititem; + + if (kititem>=NUM_KIT_ITEMS) return;//bad kit item + if (kititem<0) return; + + if (part->kit[kititem].adpars!=NULL) + adnoteui=new ADnoteUI(part->kit[kititem].adpars,master); + + if (part->kit[kititem].subpars!=NULL) + subnoteui=new SUBnoteUI(part->kit[kititem].subpars); + + if (part->kit[kititem].padpars!=NULL) + padnoteui=new PADnoteUI(part->kit[kititem].padpars,master); + +}; + + + +if ((engine==0)&&(adnoteui!=NULL)) adnoteui->ADnoteGlobalParameters->show(); +if ((engine==1)&&(subnoteui!=NULL)) subnoteui->SUBparameters->show(); +if ((engine==2)&&(adnoteui!=NULL)) padnoteui->padnotewindow->show();} {} + } + Function {~PartUI()} {} { + code {if (adnoteui!=NULL) delete (adnoteui); +if (subnoteui!=NULL) delete (subnoteui); +if (padnoteui!=NULL) delete (padnoteui); + +partgroup->hide(); +//delete(partgroup); + +ctlwindow->hide(); +delete(ctlwindow); + +partfx->hide(); +delete(partfx); + +instrumentkitlist->hide(); +delete(instrumentkitlist); + +instrumenteditwindow->hide(); +delete(instrumenteditwindow);} {} + } + decl {Part *part;} {} + decl {Master *master;} {} + decl {BankUI *bankui;} {} + decl {ADnoteUI *adnoteui;} {} + decl {SUBnoteUI *subnoteui;} {} + decl {PADnoteUI *padnoteui;} {} + decl {PartSysEffSend *psyef[NUM_SYS_EFX];} {} + decl {int npart;} {} + decl {int ninseff;} {} + decl {int lastkititem;} {} + decl {PartKitItem *partkititem[NUM_KIT_ITEMS];} {} +} diff --git a/muse/synti/zynaddsubfx/UI/PresetsUI.fl b/muse/synti/zynaddsubfx/UI/PresetsUI.fl new file mode 100644 index 00000000..b527b9c4 --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/PresetsUI.fl @@ -0,0 +1,200 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0105 +header_name {.h} +code_name {.cc} +decl {\#include <FL/fl_ask.H>} {public +} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include "../Params/Presets.h"} {public +} + +class PresetsUI_ {} { + Function {refresh()} {open return_type {virtual void} + } {} + Function {~PresetsUI_()} {open return_type virtual + } {} +} + +class PresetsUI {} { + Function {PresetsUI()} {} { + code {p=NULL; +make_window();} {} + } + Function {~PresetsUI()} {} { + code {copywin->hide();delete(copywin); +pastewin->hide();delete(pastewin);} {} + } + Function {make_window()} {} { + Fl_Window copywin { + label {Copy to Clipboard/Preset} + xywh {190 173 265 430} type Double box PLASTIC_THIN_UP_BOX color 238 hide modal + } { + Fl_Browser copybrowse { + callback {int val=o->value(); +if (val!=0){ + presetname->cut(0,presetname->maximum_size()); + presetname->insert(o->text(val)); +};} + xywh {10 25 245 320} type Select + } + Fl_Button copypbutton { + label {Copy to Preset} + callback {const char *tmp=presetname->value(); +if (tmp!=NULL) { + if (strlen(tmp)>0){ + p->copy(tmp); + copywin->hide(); + }; +};} + xywh {145 355 110 20} box THIN_UP_BOX + } + Fl_Button copybutton { + label {Copy to Clipboard} + callback {p->copy(NULL); +copywin->hide();} + xywh {25 385 90 35} box THIN_UP_BOX align 192 + } + Fl_Button {} { + label Cancel + callback {copywin->hide();} + xywh {160 385 80 35} box THIN_UP_BOX align 192 + } + Fl_Box {} { + label {Type:} + xywh {10 5 40 15} labelsize 12 align 20 + } + Fl_Box copytypetext { + xywh {50 5 205 15} box FLAT_BOX color 238 labelfont 1 labelsize 12 align 20 + } + Fl_Input presetname { + callback {const char *tmp=o->value(); +if (tmp==NULL) tmp=""; +if (strlen(tmp)>0) { + copybutton->deactivate(); + copypbutton->activate(); +} else { + copybutton->activate(); + copypbutton->deactivate(); +};} + xywh {10 355 130 20} when 1 + } + } + Fl_Window pastewin { + label {Paste from Clipboard/Preset} + xywh {463 173 265 430} type Double box PLASTIC_THIN_UP_BOX color 238 hide modal + } { + Fl_Browser pastebrowse { + callback {if (o->value()==0) { + pastepbutton->deactivate(); + deletepbutton->deactivate(); +}else{ + pastepbutton->activate(); + deletepbutton->activate(); +};} selected + xywh {10 25 245 320} type Hold + } + Fl_Button pastepbutton { + label {Paste from Preset} + callback {int n=pastebrowse->value(); +if (n!=0) p->paste(n); +pastewin->hide(); +pui->refresh();} + xywh {10 355 160 20} box THIN_UP_BOX + } + Fl_Button pastebutton { + label {Paste from Clipboard} + callback {p->paste(0); +pastewin->hide(); +pui->refresh();} + xywh {25 385 90 35} box THIN_UP_BOX align 192 + } + Fl_Button {} { + label Cancel + callback {pastewin->hide();} + xywh {160 385 80 35} box THIN_UP_BOX align 192 + } + Fl_Box pastetypetext { + xywh {55 5 200 15} box FLAT_BOX color 238 labelfont 1 labelsize 12 align 20 + } + Fl_Box {} { + label {Type:} + xywh {15 5 40 15} labelsize 12 align 20 + } + Fl_Button deletepbutton { + label Delete + callback {int n=pastebrowse->value(); +if (n!=0) p->deletepreset(n); +rescan();} + xywh {180 355 75 20} box THIN_UP_BOX + } + } + } + Function {copy(Presets *p)} {} { + code {copybutton->activate(); +copypbutton->deactivate(); + + +this->p=p; +this->pui=NULL; +bool but=(Fl::event_button()!=FL_LEFT_MOUSE); +presetname->cut(0,presetname->maximum_size()); + +if (but) p->copy(NULL); + else { + rescan(); + copytypetext->label(&p->type[1]); + copywin->show(); + };} {} + } + Function {paste(Presets *p,PresetsUI_ *pui)} {} { + code {this->p=p; +this->pui=pui; +bool but=(Fl::event_button()!=FL_LEFT_MOUSE); +pastepbutton->deactivate(); +deletepbutton->deactivate(); + +if (but) { + p->paste(0); + pui->refresh(); +} else { + rescan(); + pastetypetext->label(&p->type[1]); + if (p->checkclipboardtype()) pastebutton->activate(); + else pastebutton->deactivate(); + pastewin->show(); + };} {} + } + Function {copy(Presets *p,int n)} {} { + code {p->setelement(n); +copy(p);} {} + } + Function {paste(Presets *p,PresetsUI_ *pui,int n)} {} { + code {p->setelement(n); +paste(p,pui);} {} + } + Function {rescan()} {} { + code {copybrowse->clear(); +pastebrowse->clear(); +p->rescanforpresets(); + +for (int i=0;i<MAX_PRESETS;i++){ + char *name=presetsstore.presets[i].name; + if (name==NULL) break; + copybrowse->add(name); + pastebrowse->add(name); +};} {} + } + decl {Presets *p;} {public + } + decl {PresetsUI_ *pui;} {public + } +} + +decl {PresetsUI *presetsui;} {public +} diff --git a/muse/synti/zynaddsubfx/UI/ResonanceUI.fl b/muse/synti/zynaddsubfx/UI/ResonanceUI.fl new file mode 100644 index 00000000..b9171a49 --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/ResonanceUI.fl @@ -0,0 +1,392 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include <FL/Fl_Box.H>} {public +} + +decl {\#include <FL/fl_draw.H>} {public +} + +decl {\#include <FL/Fl_Value_Output.H>} {public +} + +decl {\#include <math.h>} {} + +decl {\#include <stdio.h>} {} + +decl {\#include <stdlib.h>} {} + +decl {\#include <string.h>} {} + +decl {\#include "../Synth/Resonance.h"} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class ResonanceGraph {: {public Fl_Box} +} { + Function {ResonanceGraph(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {respar=NULL; +cbwidget=NULL; +applybutton=NULL;} {} + } + Function {init(Resonance *respar_,Fl_Value_Output *khzvalue_,Fl_Value_Output *dbvalue_)} {} { + code {respar=respar_; +khzvalue=khzvalue_; +dbvalue=dbvalue_; +oldx=-1; +khzval=-1;} {} + } + Function {draw_freq_line(REALTYPE freq,int type)} {} { + code {REALTYPE freqx=respar->getfreqpos(freq); +switch(type){ + case 0:fl_line_style(FL_SOLID);break; + case 1:fl_line_style(FL_DOT);break; + case 2:fl_line_style(FL_DASH);break; +}; + + +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(x()+(int) (freqx*w()),y(), + x()+(int) (freqx*w()),y()+h());} {} + } + Function {draw()} {} { + code {int ox=x(),oy=y(),lx=w(),ly=h(),i,ix,iy,oiy; +REALTYPE freqx; + +fl_color(FL_BLACK); +fl_rectf(ox,oy,lx,ly); + + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +freqx=respar->getfreqpos(1000.0); +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(ox+(int) (freqx*lx),oy, + ox+(int) (freqx*lx),oy+ly); + +for (i=1;i<10;i++){ + if(i==1){ + draw_freq_line(i*100.0,0); + draw_freq_line(i*1000.0,0); + }else + if (i==5){ + draw_freq_line(i*100.0,2); + draw_freq_line(i*1000.0,2); + }else{ + draw_freq_line(i*100.0,1); + draw_freq_line(i*1000.0,1); + }; +}; + +draw_freq_line(10000.0,0); +draw_freq_line(20000.0,1); + +fl_line_style(FL_DOT); +int GY=10;if (ly<GY*3) GY=-1; +for (i=1;i<GY;i++){ + int tmp=(int)(ly/(REALTYPE)GY*i); + fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp); +}; + + + +//draw the data +fl_color(FL_RED); +fl_line_style(FL_SOLID); +oiy=(int)(respar->Prespoints[0]/128.0*ly); +for (i=1;i<N_RES_POINTS;i++){ + ix=(int)(i*1.0/N_RES_POINTS*lx); + iy=(int)(respar->Prespoints[i]/128.0*ly); + fl_line(ox+ix-1,oy+ly-oiy,ox+ix,oy+ly-iy); + oiy=iy; +};} {} + } + Function {handle(int event)} {return_type int + } { + code {int x_=Fl::event_x()-x(); +int y_=Fl::event_y()-y(); +if ( (x_>=0)&&(x_<w()) && (y_>=0)&&(y_<h())){ + khzvalue->value(respar->getfreqx(x_*1.0/w())/1000.0); + dbvalue->value((1.0-y_*2.0/h())*respar->PmaxdB); +}; + +if ((event==FL_PUSH)||(event==FL_DRAG)){ + int leftbutton=1; + if (Fl::event_button()==FL_RIGHT_MOUSE) leftbutton=0; + if (x_<0) x_=0;if (y_<0) y_=0; + if (x_>=w()) x_=w();if (y_>=h()-1) y_=h()-1; + + if ((oldx<0)||(oldx==x_)){ + int sn=(int)(x_*1.0/w()*N_RES_POINTS); + int sp=127-(int)(y_*1.0/h()*127); + if (leftbutton!=0) respar->setpoint(sn,sp); + else respar->setpoint(sn,64); + } else { + int x1=oldx; + int x2=x_; + int y1=oldy; + int y2=y_; + if (oldx>x_){ + x1=x_;y1=y_; + x2=oldx;y2=oldy; + }; + for (int i=0;i<x2-x1;i++){ + int sn=(int)((i+x1)*1.0/w()*N_RES_POINTS); + REALTYPE yy=(y2-y1)*1.0/(x2-x1)*i; + int sp=127-(int)((y1+yy)/h()*127); + if (leftbutton!=0) respar->setpoint(sn,sp); + else respar->setpoint(sn,64); + }; + }; + + oldx=x_;oldy=y_; + redraw(); +}; + +if (event==FL_RELEASE) { + oldx=-1; + if (cbwidget!=NULL) { + cbwidget->do_callback(); + if (applybutton!=NULL) { + applybutton->color(FL_RED); + applybutton->redraw(); + + }; + }; +}; + +return(1);} {selected + } + } + Function {setcbwidget(Fl_Widget *cbwidget,Fl_Widget *applybutton)} {} { + code {this->cbwidget=cbwidget; +this->applybutton=applybutton;} {} + } + decl {Fl_Value_Output *khzvalue;} {} + decl {Fl_Value_Output *dbvalue;} {} + decl {Resonance *respar;} {} + decl {int oldx,oldy;} {} + decl {REALTYPE khzval;} {public + } + decl {Fl_Widget *cbwidget,*applybutton;} {} +} + +class ResonanceUI {: PresetsUI_ +} { + Function {make_window()} {} { + Fl_Window resonancewindow { + label Resonance + xywh {45 259 780 305} type Double visible + } { + Fl_Value_Output khzvalue { + label kHz + xywh {415 264 45 18} align 8 minimum 0.001 maximum 48 step 0.01 textfont 1 + code0 {//this widget must be before the calling widgets} + } + Fl_Value_Output dbvalue { + label dB + xywh {415 282 45 18} align 8 minimum -150 maximum 150 step 0.1 textfont 1 + code0 {//this widget must be before the calling widgets} + } + Fl_Group {} { + xywh {6 5 768 256} box BORDER_BOX + code0 {rg=new ResonanceGraph(o->x(),o->y(),o->w(),o->h(),"");} + code1 {rg->init(respar,khzvalue,dbvalue);} + code2 {rg->show();} + } {} + Fl_Button {} { + label Close + callback {resonancewindow->hide();} + xywh {690 283 84 17} box THIN_UP_BOX + } + Fl_Button {} { + label Zero + callback {for (int i=0;i<N_RES_POINTS;i++) + respar->setpoint(i,64); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Clear the resonance function} xywh {491 264 66 15} box THIN_UP_BOX labelfont 1 + } + Fl_Button {} { + label Smooth + callback {respar->smooth(); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Smooth the resonance function} xywh {491 282 66 18} box THIN_UP_BOX labelfont 1 + } + Fl_Check_Button enabled { + label Enable + callback {respar->Penabled=(int) o->value(); +redrawPADnoteApply();} + xywh {6 270 78 27} box THIN_UP_BOX down_box DOWN_BOX + code0 {o->value(respar->Penabled);} + } + Fl_Roller maxdb { + callback {maxdbvo->value(o->value()); +respar->PmaxdB=(int) o->value(); +redrawPADnoteApply();} + xywh {90 282 84 15} type Horizontal minimum 1 maximum 90 step 1 value 30 + } + Fl_Value_Output maxdbvo { + label {Max.} + callback {o->value(respar->PmaxdB);} + tooltip {The Maximum amplitude (dB)} xywh {126 264 24 18} minimum 1 maximum 127 step 1 value 30 textfont 1 + code0 {o->value(respar->PmaxdB);} + } + Fl_Box {} { + label dB + xywh {150 264 24 18} + } + Fl_Value_Output centerfreqvo { + label {C.f.} + callback {o->value(respar->getcenterfreq()/1000.0);} + tooltip {Center Frequency (kHz)} xywh {210 264 33 18} when 3 minimum 1 maximum 10 step 0.01 value 1 textfont 1 + code0 {o->value(respar->getcenterfreq()/1000.0);} + } + Fl_Value_Output octavesfreqvo { + label {Oct.} + callback {o->value(respar->getoctavesfreq());} + tooltip {No. of octaves} xywh {210 282 33 18} when 3 minimum 1 maximum 127 step 1 value 30 textfont 1 + code0 {o->value(respar->getoctavesfreq());} + } + Fl_Button {} { + label RND2 + callback {respar->randomize(1); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Randomize the resonance function} xywh {566 276 42 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Button {} { + label RND1 + callback {respar->randomize(0); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Randomize the resonance function} xywh {566 264 42 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Button {} { + label RND3 + callback {respar->randomize(2); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Randomize the resonance function} xywh {566 288 42 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Check_Button p1st { + label {P.1st} + callback {respar->Pprotectthefundamental=(int) o->value(); +redrawPADnoteApply();} + tooltip {Protect the fundamental frequency (do not damp the first harmonic)} xywh {365 285 45 15} down_box DOWN_BOX labelsize 10 + code0 {o->value(respar->Pprotectthefundamental);} + } + Fl_Button {} { + label InterpP + callback {int type; +if (Fl::event_button()==FL_LEFT_MOUSE) type=0; + else type=1; +respar->interpolatepeaks(type); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Interpolate the peaks} xywh {365 265 46 15} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Dial centerfreq { + label {C.f.} + callback {respar->Pcenterfreq=(int)o->value(); +centerfreqvo->do_callback(); +rg->redraw(); +redrawPADnoteApply();} + xywh {245 265 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(respar->Pcenterfreq);} + class WidgetPDial + } + Fl_Dial octavesfreq { + label {Oct.} + callback {respar->Poctavesfreq=(int)o->value(); +octavesfreqvo->do_callback(); +rg->redraw(); +redrawPADnoteApply();} + xywh {280 265 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(respar->Poctavesfreq);} + class WidgetPDial + } + Fl_Button {} { + label C + callback {presetsui->copy(respar);} + xywh {625 275 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(respar,this);} + xywh {655 275 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Button applybutton { + label Apply + callback {applybutton->color(FL_GRAY); +applybutton->redraw(); +if (cbapplywidget!=NULL) { + cbapplywidget->do_callback(); + cbapplywidget->color(FL_GRAY); + cbapplywidget->redraw(); +};} + xywh {690 265 85 15} box THIN_UP_BOX labelfont 1 labelsize 12 + } + } + } + Function {ResonanceUI(Resonance *respar_)} {} { + code {respar=respar_; +cbwidget=NULL; +cbapplywidget=NULL; +make_window(); +applybutton->hide();} {} + } + Function {~ResonanceUI()} {} { + code {resonancewindow->hide();} {} + } + Function {redrawPADnoteApply()} {} { + code {if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +};} {} + } + Function {setcbwidget(Fl_Widget *cbwidget,Fl_Widget *cbapplywidget)} {} { + code {this->cbwidget=cbwidget; +this->cbapplywidget=cbapplywidget; +rg->setcbwidget(cbwidget,applybutton); +applybutton->show();} {} + } + Function {refresh()} {} { + code {redrawPADnoteApply(); + +enabled->value(respar->Penabled); + +maxdb->value(respar->PmaxdB); +maxdbvo->value(respar->PmaxdB); + +centerfreqvo->value(respar->getcenterfreq()/1000.0); +octavesfreqvo->value(respar->getoctavesfreq()); + +centerfreq->value(respar->Pcenterfreq); +octavesfreq->value(respar->Poctavesfreq); + +p1st->value(respar->Pprotectthefundamental); + +rg->redraw();} {} + } + decl {Resonance *respar;} {public + } + decl {ResonanceGraph *rg;} {} + decl {Fl_Widget *cbwidget,*cbapplywidget;} {} +} diff --git a/muse/synti/zynaddsubfx/UI/SUBnoteUI.fl b/muse/synti/zynaddsubfx/UI/SUBnoteUI.fl new file mode 100644 index 00000000..fc915ae3 --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/SUBnoteUI.fl @@ -0,0 +1,449 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0105 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <string.h>} {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EnvelopeUI.h"} {public +} + +decl {\#include "FilterUI.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Params/SUBnoteParameters.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class SUBnoteharmonic {: {public Fl_Group} +} { + Function {make_window()} {private + } { + Fl_Window harmonic { + xywh {329 403 90 225} type Double hide + class Fl_Group + } { + Fl_Slider mag { + callback {int x=0; +if (Fl::event_button1()) x=127-(int)o->value(); + else o->value(127-x); +pars->Phmag[n]=x; +if (pars->Phmag[n]==0) o->selection_color(0); + else o->selection_color(222);} + tooltip {harmonic's magnitude} xywh {0 15 10 115} type {Vert Knob} box FLAT_BOX selection_color 222 labelcolor 0 maximum 127 step 1 value 127 + code0 {o->value(127-pars->Phmag[n]);} + code1 {if (pars->Phmag[n]==0) o->selection_color(0);} + } + Fl_Slider bw { + callback {int x=64; +if (Fl::event_button1()) x=127-(int)o->value(); + else o->value(x); +pars->Phrelbw[n]=x;} + tooltip {harmonic's bandwidth} xywh {0 135 10 75} type {Vert Knob} box FLAT_BOX selection_color 222 maximum 127 step 1 value 64 + code0 {o->value(127-pars->Phrelbw[n]);} + } + Fl_Box {} { + xywh {10 170 5 5} box FLAT_BOX color 45 + code0 {if (n+1==MAX_SUB_HARMONICS) o->hide();} + } + Fl_Box {} { + label 01 + xywh {0 210 10 15} labelfont 1 labelsize 9 align 20 + code0 {char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp));} + } + Fl_Box {} { + label 01 + xywh {0 0 10 15} labelfont 1 labelsize 9 align 20 + code0 {char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp));} + } + } + } + Function {SUBnoteharmonic(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {n=0;} {} + } + Function {init(SUBnoteParameters *pars_,int n_)} {} { + code {pars=pars_; +n=n_; +make_window(); +harmonic->show(); +end();} {} + } + Function {refresh()} {} { + code {mag->value(127-pars->Phmag[n]); +if (pars->Phmag[n]==0) mag->selection_color(0); +bw->value(127-pars->Phrelbw[n]);} {selected + } + } + Function {~SUBnoteharmonic()} {} { + code {harmonic->hide(); +hide(); +//delete(harmonic);} {} + } + decl {SUBnoteParameters *pars;} {} + decl {int n;} {} +} + +class SUBnoteUI {: {public PresetsUI_} +} { + Function {make_window()} {} { + Fl_Window SUBparameters { + label {SUBsynth Parameters} + xywh {26 214 735 390} type Double hide + } { + Fl_Scroll {} { + xywh {5 140 435 245} type HORIZONTAL box THIN_UP_BOX + } { + Fl_Pack harmonics {open + xywh {10 145 425 235} type HORIZONTAL + code0 {for (int i=0;i<MAX_SUB_HARMONICS;i++){h[i]=new SUBnoteharmonic(0,0,15,o->h(),"");h[i]->init(pars,i);}} + } {} + } + Fl_Button {} { + label Close + callback {SUBparameters->hide();} + xywh {625 365 105 20} box THIN_UP_BOX labelfont 1 labelsize 12 + } + Fl_Group {} { + label AMPLITUDE + xywh {5 5 215 135} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 align 17 + } { + Fl_Value_Slider vol { + label Vol + callback {pars->PVolume=(int)o->value();} + tooltip Volume xywh {10 25 140 15} type {Horz Knob} box FLAT_BOX labelsize 12 align 8 maximum 127 step 1 + code0 {o->value(pars->PVolume);} + } + Fl_Value_Slider vsns { + label {V.Sns} + callback {pars->PAmpVelocityScaleFunction=(int) o->value();} + tooltip {Velocity Sensing Function (rightmost to disable)} xywh {10 45 140 15} type {Horz Knob} box FLAT_BOX labelsize 12 align 8 maximum 127 step 1 + code0 {o->value(pars->PAmpVelocityScaleFunction);} + } + Fl_Dial pan { + label Pan + callback {pars->PPanning=(int) o->value();} + tooltip {Panning (leftmost is Random)} xywh {185 20 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(pars->PPanning);} + class WidgetPDial + } + Fl_Group ampenv { + label {SUBsynth - Amplitude Envelope} open + xywh {10 65 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->AmpEnvelope);} + class EnvelopeUI + } {} + } + Fl_Group {} { + xywh {495 325 235 35} box THIN_UP_FRAME + } { + Fl_Counter filterstages { + label {Filter Stages} + callback {pars->Pnumstages=(int) o->value();} + tooltip {How many times the noise is filtered} xywh {515 340 45 15} type Simple labelfont 1 labelsize 10 align 1 minimum 1 maximum 5 step 1 textsize 10 + code0 {o->value(pars->Pnumstages);} + } + Fl_Choice magtype { + label {Mag.Type} + callback {pars->Phmagtype=(int) o->value();} + xywh {585 340 65 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 1 textsize 12 + code0 {o->value(pars->Phmagtype);} + } { + menuitem {} { + label Linear + xywh {20 20 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {-40dB} + xywh {30 30 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {-60dB} + xywh {40 40 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {-80dB} + xywh {50 50 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {-100dB} + xywh {60 60 100 20} labelfont 1 labelsize 12 + } + } + Fl_Choice start { + label Start + callback {pars->Pstart=(int) o->value();} open + xywh {670 340 50 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 1 textsize 12 + code0 {o->value(pars->Pstart);} + } { + menuitem {} { + label Zero + xywh {30 30 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label RND + xywh {40 40 100 20} labelfont 1 labelsize 12 + } + menuitem {} { + label {Max.} + xywh {50 50 100 20} labelfont 1 labelsize 12 + } + } + } + Fl_Group freqsettingsui { + label FREQUENCY + xywh {440 5 290 135} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 align 17 + } { + Fl_Group freqenvelopegroup { + label {SUBsynth - Frequency Envelope} open + xywh {445 65 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->FreqEnvelope);} + code1 {if (pars->PFreqEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button freqee { + label Enabled + callback {pars->PFreqEnvelopeEnabled=o->value(); +if (o->value()==0) freqenvelopegroup->deactivate(); + else freqenvelopegroup->activate(); +o->show(); +freqsettingsui->redraw();} + xywh {445 68 55 15} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->PFreqEnvelopeEnabled);} + } + Fl_Counter octave { + label Octave + callback {int k=(int) o->value(); +if (k<0) k+=16; +pars->PCoarseDetune = k*1024+ + pars->PCoarseDetune%1024;} + tooltip Octave xywh {670 50 45 15} type Simple labelsize 10 align 1 minimum -8 maximum 7 step 1 textfont 1 textsize 12 + code0 {int k=pars->PCoarseDetune/1024;if (k>=8) k-=16;} + code2 {o->value(k);} + } + Fl_Counter coarsedet { + label {Coarse Det.} + callback {int k=(int) o->value(); +if (k<0) k+=1024; +pars->PCoarseDetune = k+ + (pars->PCoarseDetune/1024)*1024;} + tooltip {Coarse Detune} xywh {655 115 60 20} labelsize 11 align 1 minimum -64 maximum 63 step 1 textfont 1 textsize 12 + code0 {int k=pars->PCoarseDetune%1024;if (k>=512) k-=1024;} + code2 {o->value(k);} + code3 {o->lstep(10);} + } + Fl_Slider detune { + callback {pars->PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {495 25 230 15} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->PDetune-8192);} + } + Fl_Value_Output detunevalueoutput { + label Detune + callback {o->value(getdetune(pars->PDetuneType,0,pars->PDetune));} + xywh {448 25 45 15} labelsize 10 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 10 + code0 {o->value(getdetune(pars->PDetuneType,0,pars->PDetune));} + } + Fl_Check_Button hz440 { + label 440Hz + callback {int x=(int) o->value(); +pars->Pfixedfreq=x; +if (x==0) fixedfreqetdial->deactivate(); + else fixedfreqetdial->activate();} + tooltip {set the base frequency to 440Hz} xywh {555 45 50 15} down_box DOWN_BOX labelfont 1 labelsize 11 + code0 {o->value(pars->Pfixedfreq);} + } + Fl_Dial fixedfreqetdial { + label {Eq.T.} + callback {pars->PfixedfreqET=(int) o->value();} + tooltip {How the frequency varies acording to the keyboard (leftmost for fixed frequency)} xywh {610 45 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 + code0 {o->value(pars->PfixedfreqET);} + code1 {if (pars->Pfixedfreq==0) o->deactivate();} + class WidgetPDial + } + Fl_Choice detunetype { + label {Detune Type} + callback {pars->PDetuneType=(int) o->value()+1; +detunevalueoutput->do_callback();} open + xywh {655 85 70 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");} + code1 {o->value(pars->PDetuneType-1);} + } {} + } + Fl_Check_Button stereo { + label Stereo + callback {pars->Pstereo=(int) o->value();} + xywh {440 325 55 35} box THIN_UP_BOX down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->Pstereo);} + } + Fl_Button {} { + label Clear + callback {for (int i=0;i<MAX_SUB_HARMONICS;i++){ + h[i]->mag->value(127); + pars->Phmag[i]=0; + h[i]->bw->value(64); + pars->Phrelbw[i]=64; +}; +pars->Phmag[0]=127; +h[0]->mag->value(0); +SUBparameters->redraw();} + tooltip {Clear the harmonics} xywh {445 365 70 20} box THIN_UP_BOX labelfont 1 labelsize 12 + } + Fl_Group bandwidthsettingsui { + label BANDWIDTH + xywh {220 5 220 135} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 align 17 + } { + Fl_Group bandwidthenvelopegroup { + label {SUBsynth - BandWidth Envelope} open + xywh {225 65 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->BandWidthEnvelope);} + code1 {if (pars->PBandWidthEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button bwee { + label Enabled + callback {pars->PBandWidthEnvelopeEnabled=o->value(); +if (o->value()==0) bandwidthenvelopegroup->deactivate(); + else bandwidthenvelopegroup->activate(); +o->show(); +bandwidthsettingsui->redraw();} + xywh {225 67 55 15} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->PBandWidthEnvelopeEnabled);} + } + Fl_Value_Slider bandwidth { + label {Band Width} + callback {pars->Pbandwidth=(int) o->value();} + xywh {225 40 115 15} type {Horz Knob} box FLAT_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Pbandwidth);} + } + Fl_Value_Slider bwidthscale { + label {B.Width Scale} + callback {pars->Pbwscale=(int) o->value()+64;} + tooltip {How much I increase the BandWidth according to lower/higher harmonics} xywh {345 40 90 15} type {Horz Knob} box FLAT_BOX labelsize 10 align 1 minimum -64 maximum 63 step 1 + code0 {o->value(pars->Pbwscale-64);} + } + } + Fl_Group globalfiltergroup { + label FILTER + xywh {440 140 290 185} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 17 + code0 {if (pars->PGlobalFilterEnabled==0) o->deactivate();} + } { + Fl_Group filterenv { + label {SUBsynth - Filter Envelope} open + xywh {445 250 275 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->GlobalFilterEnvelope);} + class EnvelopeUI + } {} + Fl_Group filterui { + label {SUBsynthl - Filter} open + xywh {445 170 275 75} box FLAT_BOX color 50 align 144 + code0 {o->init(pars->GlobalFilter,&pars->PGlobalFilterVelocityScale,&pars->PGlobalFilterVelocityScaleFunction);} + class FilterUI + } {} + } + Fl_Check_Button filtere { + label Enabled + callback {pars->PGlobalFilterEnabled=o->value(); +if (o->value()==0) globalfiltergroup->deactivate(); + else globalfiltergroup->activate(); +o->show(); +globalfiltergroup->redraw();} + xywh {445 145 85 20} down_box DOWN_BOX labelfont 1 labelsize 12 + code0 {o->value(pars->PGlobalFilterEnabled);} + } + Fl_Button {} { + label C + callback {presetsui->copy(pars);} + xywh {540 370 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this);} + xywh {570 370 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 12 labelcolor 7 + } + } + } + Function {refresh()} {} { + code {for (int i=0;i<MAX_SUB_HARMONICS;i++) h[i]->refresh(); +vol->value(pars->PVolume); +vsns->value(pars->PAmpVelocityScaleFunction); +pan->value(pars->PPanning); + + +bandwidth->value(pars->Pbandwidth); +bwidthscale->value(pars->Pbwscale-64); +bwee->value(pars->PBandWidthEnvelopeEnabled); +if (pars->PBandWidthEnvelopeEnabled==0) bandwidthenvelopegroup->deactivate(); + else bandwidthenvelopegroup->activate(); +bwee->show(); +bandwidthsettingsui->redraw(); + +detunevalueoutput->value(getdetune(pars->PDetuneType,0,pars->PDetune)); +freqee->value(pars->PFreqEnvelopeEnabled); +if (pars->PFreqEnvelopeEnabled==0) freqenvelopegroup->deactivate(); + else freqenvelopegroup->activate(); +freqee->show(); +freqsettingsui->redraw(); + +detune->value(pars->PDetune-8192); +hz440->value(pars->Pfixedfreq); + +fixedfreqetdial->value(pars->PfixedfreqET); + +int k=pars->PCoarseDetune/1024;if (k>=8) k-=16; +octave->value(k); + +detunetype->value(pars->PDetuneType-1); + +k=pars->PCoarseDetune%1024;if (k>=512) k-=1024; +coarsedet->value(k); + +filtere->value(pars->PGlobalFilterEnabled); +if (pars->PGlobalFilterEnabled==0) globalfiltergroup->deactivate(); + else globalfiltergroup->activate(); +filtere->show(); +globalfiltergroup->redraw(); + +stereo->value(pars->Pstereo); +filterstages->value(pars->Pnumstages); +magtype->value(pars->Phmagtype); +start->value(pars->Pstart); + +ampenv->refresh(); +bandwidthenvelopegroup->refresh(); +freqenvelopegroup->refresh(); +filterui->refresh(); +filterenv->refresh();} {} + } + Function {SUBnoteUI(SUBnoteParameters *parameters)} {} { + code {pars=parameters; +make_window();} {} + } + Function {~SUBnoteUI()} {} { + code {//for (int i=0;i<MAX_SUB_HARMONICS;i++) delete (h[i]); +SUBparameters->hide(); +delete(SUBparameters);} {} + } + decl {SUBnoteParameters *pars;} {} + decl {SUBnoteharmonic *h[MAX_SUB_HARMONICS];} {} +} diff --git a/muse/synti/zynaddsubfx/UI/SeqUI.fl b/muse/synti/zynaddsubfx/UI/SeqUI.fl new file mode 100644 index 00000000..d30c6433 --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/SeqUI.fl @@ -0,0 +1,73 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0105 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include "../globals.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +class SeqUI {} { + Function {make_window()} {} { + Fl_Window seqwin { + label {Sequencer - ZynAddSubFX} + xywh {104 235 280 265} type Double hide + } { + Fl_Group {} { + label Player + xywh {120 20 100 65} box ENGRAVED_BOX labelfont 1 + } { + Fl_Button playbutton { + label Play + callback {o->deactivate(); +stopbutton_play->activate(); + +master->seq.startplay();} + tooltip {Start Playing} xywh {130 30 30 30} box DIAMOND_UP_BOX color 79 labelfont 1 labelsize 16 align 2 + } + Fl_Button stopbutton_play { + label Stop + callback {o->deactivate(); +playbutton->activate(); + +master->seq.stopplay();} + tooltip {Stop Playing} xywh {175 29 30 31} box THIN_UP_BOX color 4 labelfont 1 labelsize 16 align 2 deactivate + } + } + Fl_Button {} { + label {Open test.mid} + callback {master->seq.importmidifile("test.mid");} + xywh {20 25 75 55} align 128 + } + Fl_Value_Slider {} { + label {Play speed} + callback {master->seq.setplayspeed((int) o->value());} + xywh {15 105 190 20} type {Horz Knob} minimum -128 maximum 128 step 1 + code0 {o->value(master->seq.playspeed);} + } + Fl_Box {} { + label {This is not finished} selected + xywh {25 155 225 90} labelfont 1 labelsize 30 align 128 + } + } + } + Function {SeqUI(Master *master_)} {open + } { + code {master=master_; + +make_window();} {} + } + decl {Master *master} {} + Function {show()} {open + } { + code {seqwin->show();} {} + } +} diff --git a/muse/synti/zynaddsubfx/UI/VirKeyboard.fl b/muse/synti/zynaddsubfx/UI/VirKeyboard.fl new file mode 100644 index 00000000..bd0fa8ba --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/VirKeyboard.fl @@ -0,0 +1,400 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include <stdlib.h>} {public +} + +decl {\#include <FL/fl_draw.H>} {public +} + +decl {\#include <FL/Fl_Box.H>} {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "../Input/MidiIn.h"} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {const int keyspos[12]={0,-1,1,-2,2,3,-4,4,-5,5,-6,6};} {} + +decl {const int keysoct1qw[]={'q','2','w','3','e','r','5','t','6','y','7','u','i','9','o','0','p','[','=',']','\\\\',FL_Enter,0};} {} + +decl {const int keysoct2qw[]={'z','s','x','d','c','v','g','b','h','n','j','m',',','l','.',';','/',0};} {} + +decl {const int keysoct1dw[]={'\\'','2',',','3','.','p','5','y','6','f','7','g','c','9','r','0','l','/',']','=','\\\\',FL_Enter,0};} {} + +decl {const int keysoct2dw[]={';','o','q','e','j','k','i','x','d','b','h','m','w','n','v','s','z',0};} {} + +class VirKeys {: {public Fl_Box} +} { + decl {static const int N_OCT=6;} {} + decl {static const int SIZE_WHITE=14;} {} + decl {static const int SIZE_BLACK=8;} {} + Function {VirKeys(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {master=NULL;} {} + } + Function {init(Master *master_)} {} { + code {master=master_; +for (int i=0;i<N_OCT*12+1;i++) pressed[i]=0; +midich=0; +midivel=100; +midioct=2; + +keyoct1=3; +keyoct2=2; +rndvelocity=0;} {} + } + Function {draw()} {} { + code {int ox=x(),oy=y(),lx=w(),ly=h()-1,i; + +if (damage()!=1){ + fl_color(250,240,230); + fl_rectf(ox,oy,lx,ly); + + fl_color(FL_BLACK); + fl_line(ox,oy,ox+lx,oy); + fl_line(ox,oy+ly,ox+lx,oy+ly); + for (i=0;i<N_OCT*7+1;i++){ + fl_line(ox+i*SIZE_WHITE,oy,ox+i*SIZE_WHITE,oy+ly); + int ik=i%7; + if ((ik==1)||(ik==2)||(ik==4)||(ik==5)||(ik==6)) + fl_rectf(ox+i*SIZE_WHITE-SIZE_BLACK/2,oy, + SIZE_BLACK+1,ly*3/5); + }; +}; + + +for (i=0;i<N_OCT*12;i++){ + // if (pressed[i]==0) continue; + + int noct=i/12; + int kv=keyspos[i%12]; + + if (kv>=0){//white keys + if (pressed[i]==0) fl_color(250,240,230); + else fl_color(FL_BLUE); + fl_rectf(ox+(kv+7*noct)*SIZE_WHITE+3,oy+ly*3/5+2, + SIZE_WHITE-4,ly*2/5-3); + } else {//black keys + kv=keyspos[(i+1)%12]; + if (pressed[i]==0) fl_color(FL_BLACK); + else fl_color(FL_BLUE); + fl_rectf(ox+(kv+7*noct)*SIZE_WHITE-SIZE_BLACK/2+2,oy+2, + SIZE_BLACK-3,ly*3/5-5); + }; +};} {} + } + Function {handle(int event)} {return_type int + } { + code {int i; +int ly=h(); +int x_=Fl::event_x()-x(); +int y_=Fl::event_y()-y(); +if ( (x_<0)&&(x_>w()) && (y_<0)&&(y_>h())){ + return(0); +}; + + +if ((event==FL_PUSH)||(event==FL_DRAG)||(event==FL_RELEASE)){ + int kpos=-1; + + if (y_>ly*3/5){//white keys + int pos=x_/SIZE_WHITE; + if (pos<0) return(1); + for (i=0;i<12;i++) { + if (pos%7==keyspos[i]) { + kpos=pos/7*12+i; + break; + }; + }; + } else {//black keys + int pos=(x_+SIZE_WHITE/2)/SIZE_WHITE; + if (pos<0) return(1); + for (i=1;i<12;i++) { + if (pos%7==-keyspos[i]) { + kpos=pos/7*12+i; + break; + }; + }; + }; + + if (((event==FL_PUSH)||(event==FL_DRAG))&& + (Fl::event_shift()==0)) { + presskey(kpos,1,1); + }; + + if ((event==FL_PUSH)&&(Fl::event_shift()!=0)) { + if (pressed[kpos]==0) presskey(kpos,0,1); + else relasekey(kpos,1); + }; + if ((event==FL_RELEASE)&&(Fl::event_shift()==0)) + relaseallkeys(1); + take_focus(); +}; + + +const int *keysoct1=keysoct1qw; +const int *keysoct2=keysoct2qw; + +if (config.cfg.VirKeybLayout==2) { + keysoct1=keysoct1dw; + keysoct2=keysoct2dw; +}; + +if ((event==FL_KEYDOWN)||(event==FL_KEYUP)){ + int key=Fl::event_key(); + int kpos=-1; + for (i=0;keysoct1[i]!=0;i++) if (key==keysoct1[i]) kpos=i+12*keyoct1; + for (i=0;keysoct2[i]!=0;i++) if (key==keysoct2[i]) kpos=i+12*keyoct2; + + if (kpos==-1) return(0); + if (event==FL_KEYDOWN) presskey(kpos,0,2); + else relasekey(kpos,2); +}; + +return(1);} {} + } + Function {presskey(int nk,int exclusive,int type)} {} { + code {if (nk>=N_OCT*12) return; +if ((nk<0)&&(exclusive==0)) { + relaseallkeys(type); + return; +}; +if (pressed[nk]!=0) return;//the key is already pressed + +if (exclusive!=0) relaseallkeys(type); +pressed[nk]=type; + +damage(1); +float vel=midivel; +if (rndvelocity!=0){ + vel=midivel*(127.0-rndvelocity)/127.0+RND*rndvelocity; +}; + +pthread_mutex_lock(&master->mutex); + master->NoteOn(midich,nk+midioct*12,(int)vel); +pthread_mutex_unlock(&master->mutex);} {} + } + Function {relasekey(int nk,int type)} {} { + code {if ((nk<0)||(nk>=N_OCT*12)) return; +if (pressed[nk]==0) return;//the key is not pressed +if ((type!=0)&&(pressed[nk]!=type)) return; + +pressed[nk]=0; + + +damage(1); + +pthread_mutex_lock(&master->mutex); + master->NoteOff(midich,nk+12*midioct); +pthread_mutex_unlock(&master->mutex);} {} + } + Function {relaseallkeys(int type)} {} { + code {for (int i=0;i<N_OCT*12;i++) relasekey(i,type);} {} + } + decl {Master *master;} {} + decl {int pressed[N_OCT*12+1];} {} + decl {unsigned char midich;} {public + } + decl {unsigned char midivel;} {public + } + decl {char midioct,keyoct1,keyoct2;} {public + } + decl {unsigned char rndvelocity;} {public + } +} + +class VirKeyboard {selected +} { + Function {make_window()} {} { + Fl_Window virkeyboardwindow { + label {Virtual Keyboard - ZynAddSubFX} + callback {relaseallkeys(); +virkeyboardwindow->hide();} + xywh {95 563 650 130} type Double hide + } { + Fl_Box virkeys { + label Keyboard + xywh {10 10 590 80} box FLAT_BOX color 17 + code0 {o->init(master);} + class VirKeys + } + Fl_Counter {} { + label {"qwer.." Oct} + callback {relaseallkeys(); +virkeys->keyoct1=(int) o->value(); +virkeys->take_focus();} + tooltip {keys "q2w3er5t6y..." octave} xywh {380 95 45 15} type Simple labelsize 10 align 4 when 6 minimum 0 maximum 5 step 1 textfont 1 textsize 10 + code0 {o->value(virkeys->keyoct1);} + } + Fl_Counter {} { + label {"zxcv.." Oct} + callback {relaseallkeys(); +virkeys->keyoct2=(int) o->value(); +virkeys->take_focus();} + tooltip {keys "zsxdcvgbh..." octave} xywh {380 110 45 15} type Simple labelsize 10 align 4 when 6 minimum 0 maximum 5 step 1 textfont 1 textsize 10 + code0 {o->value(virkeys->keyoct2);} + } + Fl_Value_Slider {} { + label Vel + callback {virkeys->midivel=(int) o->value(); +virkeys->take_focus();} + tooltip Velocity xywh {95 105 100 15} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum 1 maximum 127 step 1 + code0 {o->value(virkeys->midivel);} + } + Fl_Counter {} { + label {Oct.} + callback {relaseallkeys(); +virkeys->midioct=(int) o->value(); +virkeys->take_focus();} + tooltip {Midi Octave} xywh {255 100 55 20} type Simple labelsize 12 align 4 when 6 minimum 0 maximum 5 step 1 textfont 1 textsize 12 + code0 {o->value(virkeys->midioct);} + } + Fl_Button {} { + label Close + callback {relaseallkeys(); +virkeyboardwindow->hide();} + xywh {545 105 55 20} box THIN_UP_BOX + } + Fl_Value_Slider {} { + label Cval + callback {int ctl=midictl; + +pthread_mutex_lock(&master->mutex); + master->SetController(virkeys->midich,ctl,(int) o->value()); +pthread_mutex_unlock(&master->mutex); +virkeys->take_focus();} + tooltip {Controller value} xywh {605 10 15 115} type {Vert Fill} box ENGRAVED_BOX selection_color 229 labelsize 8 align 5 minimum 127 maximum 0 step 1 value 64 textsize 7 + } + Fl_Choice {} { + label Controller + callback {switch((int) o->value()+1){ + case 1: midictl=C_modwheel; break; + case 2: midictl=C_volume; break; + case 3: midictl=C_panning; break; + case 4: midictl=C_expression; break; + case 5: midictl=C_sustain; break; + case 6: midictl=C_portamento; break; + case 7: midictl=C_filterq; break; + case 8: midictl=C_filtercutoff; break; + case 9: midictl=C_bandwidth; break; + case 10: midictl=C_fmamp; break; + case 11: midictl=C_resonance_center; break; + case 12: midictl=C_resonance_bandwidth; break; + default: midictl=C_NULL; break; + +}; + + + +virkeys->take_focus();} + xywh {435 105 100 15} down_box BORDER_BOX labelsize 10 align 5 when 6 textfont 1 textsize 10 + code0 {midictl=C_filtercutoff;o->value(7);} + } { + menuitem {} { + label {01: Mod.Wheel} + xywh {0 0 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {07: Volume} + xywh {10 10 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {10: Panning} + xywh {20 20 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {11: Expression} + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {64: Sustain} + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {65: Portamento} + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {71: Filter Q} + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {74: Filter Freq.} + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {75: Bandwidth} + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {76: FM Gain} + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {77: Res. c. freq} + xywh {100 100 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {78: Res. bw.} + xywh {110 110 100 20} labelfont 1 labelsize 10 + } + } + Fl_Roller pitchwheelroller { + label Pwh + callback {pthread_mutex_lock(&master->mutex); + master->SetController(virkeys->midich,C_pitchwheel,-(int) o->value()); +pthread_mutex_unlock(&master->mutex); +virkeys->take_focus();} + tooltip {Pitch Wheel} xywh {625 10 20 95} box PLASTIC_UP_BOX labelsize 8 align 1 when 3 minimum -8192 maximum 8192 step 64 + } + Fl_Button {} { + label R + callback {pitchwheelroller->value(0); +pitchwheelroller->do_callback();} + tooltip {Reset Pitch Bend} xywh {625 110 20 15} box THIN_UP_BOX labelfont 1 + } + Fl_Dial {} { + label Vrnd + callback {virkeys->rndvelocity=(int) o->value();} + tooltip {Velocity Randomness} xywh {205 105 20 20} box ROUND_UP_BOX labelsize 10 align 129 maximum 127 step 1 + code0 {o->value(virkeys->rndvelocity);} + class WidgetPDial + } + Fl_Choice partrcv { + label {MIDI Ch.} + callback {relaseallkeys(); +virkeys->midich=(int) o->value(); +virkeys->take_focus();} open + tooltip {Send to Midi Channel} xywh {20 105 65 20} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {char nrstr[10]; for(int i=0;i<NUM_MIDI_CHANNELS;i++){sprintf(nrstr,"Chn%d",i+1);if (i!=9) o->add(nrstr); else o->add("Drum10");};} + code1 {o->value(virkeys->midich);} + } {} + } + } + Function {VirKeyboard(Master *master_)} {} { + code {master=master_; +midictl=75; +make_window();} {} + } + Function {show()} {} { + code {virkeyboardwindow->show();} {} + } + Function {relaseallkeys()} {} { + code {virkeys->relaseallkeys(0);} {} + } + decl {Master *master;} {} + decl {int midictl;} {} +} diff --git a/muse/synti/zynaddsubfx/UI/WidgetPDial.fl b/muse/synti/zynaddsubfx/UI/WidgetPDial.fl new file mode 100644 index 00000000..8d8073bd --- /dev/null +++ b/muse/synti/zynaddsubfx/UI/WidgetPDial.fl @@ -0,0 +1,131 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0105 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2003-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2} {} + +decl {\#include <FL/Fl_Dial.H>} {public +} + +decl {\#include <FL/fl_draw.H>} {public +} + +decl {\#include <stdio.h>} {public +} + +decl {\#include <math.h>} {public +} + +class WidgetPDial {: {public Fl_Dial} +} { + Function {WidgetPDial(int x,int y, int w, int h, const char *label=0):Fl_Dial(x,y,w,h,label)} {} { + code {oldvalue=0.0;} {} + } + Function {handle(int event)} {return_type int + } { + code {double dragsize,v,min=minimum(),max=maximum(); +int my; + +switch (event){ +case FL_PUSH:oldvalue=value(); +case FL_DRAG: + my=-(Fl::event_y()-y()-h()/2); + + dragsize=200.0; + if (Fl::event_state(FL_BUTTON1)==0) dragsize*=10; + v=oldvalue+my/dragsize*(max-min); + if (v<min) v=min; + else if (v>max) v=max; + + //printf("%d %g %g\\n",my,v,oldvalue); + value(v); + value_damage(); + if (this->when()!=0) do_callback(); + return(1); + break; +case FL_RELEASE: + if (this->when()==0) do_callback(); + return(1); + break; +}; +return(0);} {selected + } + } + Function {drawgradient(int cx,int cy,int sx,double m1,double m2)} {return_type void + } { + code {for (int i=(int)(m1*sx);i<(int)(m2*sx);i++){ + double tmp=1.0-pow(i*1.0/sx,2.0); + pdialcolor(140+(int) (tmp*90),140+(int)(tmp*90),140+(int) (tmp*100)); + fl_arc(cx+sx/2-i/2,cy+sx/2-i/2,i,i,0,360); +};} {} + } + Function {draw()} {} { + code {int cx=x(),cy=y(),sx=w(),sy=h(); + + +//clears the button face +pdialcolor(190,190,200); +fl_pie(cx-1,cy-1,sx+2,sy+2,0,360); + +//Draws the button face (gradinet) +drawgradient(cx,cy,sx,0.5,1.0); + +double val=(value()-minimum())/(maximum()-minimum()); + +//draws the scale +pdialcolor(220,220,250); +double a1=angle1(),a2=angle2(); +for (int i=0;i<12;i++){ + double a=-i/12.0*360.0-val*(a2-a1)-a1; + fl_pie(cx,cy,sx,sy,a+270-3,a+3+270); +}; + +drawgradient(cx,cy,sx,0.0,0.75); + +//draws the value +double a=-(a2-a1)*val-a1; + + + + + +//draws the max and min points +pdialcolor(0,100,200); +int xp=(int)(cx+sx/2.0+sx/2.0*sin(angle1()/180.0*3.141592)); +int yp=(int)(cy+sy/2.0+sy/2.0*cos(angle1()/180.0*3.141592)); +fl_pie(xp-2,yp-2,4,4,0,360); + +xp=(int)(cx+sx/2.0+sx/2.0*sin(angle2()/180.0*3.141592)); +yp=(int)(cy+sy/2.0+sy/2.0*cos(angle2()/180.0*3.141592)); +fl_pie(xp-2,yp-2,4,4,0,360); + + + + + +fl_push_matrix(); + + fl_translate(cx+sx/2,cy+sy/2); + fl_rotate(a-90.0); + + fl_translate(sx/2,0); + + + fl_begin_polygon(); + pdialcolor(0,0,0); + fl_vertex(-10,-4); + fl_vertex(-10,4); + fl_vertex(0,0); + fl_end_polygon(); + + +fl_pop_matrix();} {} + } + Function {pdialcolor(int r,int g,int b)} {} { + code {if (active_r()) fl_color(r,g,b); + else fl_color(160-(160-r)/3,160-(160-b)/3,160-(160-b)/3);} {} + } + decl {double oldvalue;} {} +} diff --git a/muse/synti/zynaddsubfx/files b/muse/synti/zynaddsubfx/files new file mode 100644 index 00000000..20f93a6c --- /dev/null +++ b/muse/synti/zynaddsubfx/files @@ -0,0 +1,23 @@ + +rm ./UI/.qped +rm ./DSP/.qped +rm ./DSP/.Filter_.h, +rm ./Seq/.qped +rm ./Misc/.qped +rm ./Misc/.Master.C, +rm ./Misc/.Master.h, +rm ./.qped +rm ./Input/.qped +rm ./Input/.MidiIn.h, +rm ./Synth/.qped +rm ./Params/.qped +rm ./Params/.Presets.h, +rm ./.zynaddsubfx.cpp, +rm ./.launch_zynaddsubfx.bat, +rm ./.main.cpp, +rm ./Effects/.Effect.h, +rm ./Effects/.qped +rm ./.Makefile.inc, +rm ./.CMakeLists.txt, +rm ./zynaddsubfx_icon.svg + diff --git a/muse/synti/zynaddsubfx/globals.h b/muse/synti/zynaddsubfx/globals.h new file mode 100644 index 00000000..58b1669e --- /dev/null +++ b/muse/synti/zynaddsubfx/globals.h @@ -0,0 +1,212 @@ +/* + ZynAddSubFX - a software synthesizer + + globals.h - it contains program settings and the program capabilities + like number of parts, of effects + 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) 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 GLOBALS_H +#define GLOBALS_H + +//What float type I use for internal sampledata +#define REALTYPE float + +struct FFTFREQS{ + REALTYPE *s,*c;//sine and cosine components +}; + +extern void newFFTFREQS(FFTFREQS *f,int size); +extern void deleteFFTFREQS(FFTFREQS *f); + +// Sampling rate +extern int SAMPLE_RATE; + +/* + * The size of a sound buffer (or the granularity) + * All internal transfer of sound data use buffer of this size + * All parameters are constant during this period of time, exception + * some parameters(like amplitudes) which are linear interpolated. + * If you increase this you'll ecounter big latencies, but if you + * decrease this the CPU requirements gets high. + */ +extern int SOUND_BUFFER_SIZE; + + +/* + * The size of ADnote Oscillator + * Decrease this => poor quality + * Increase this => CPU requirements gets high (only at start of the note) + */ +extern int OSCIL_SIZE; + +/* + * The number of harmonics of additive synth + * This must be smaller than OSCIL_SIZE/2 + */ +#define MAX_AD_HARMONICS 128 + + +/* + * The number of harmonics of substractive + */ +#define MAX_SUB_HARMONICS 64 + + +/* + * The maximum number of samples that are used for 1 PADsynth instrument(or item) + */ +#define PAD_MAX_SAMPLES 64 + + +/* + * Number of parts + */ +#define NUM_MIDI_PARTS 16 + +/* + * Number of Midi channes + */ +#define NUM_MIDI_CHANNELS 16 + +/* + * The number of voices of additive synth for a single note + */ +#define NUM_VOICES 8 + +/* + * The poliphony (notes) + */ +#define POLIPHONY 60 + +/* + * Number of system effects + */ +#define NUM_SYS_EFX 4 + + +/* + * Number of insertion effects + */ +#define NUM_INS_EFX 8 + +/* + * Number of part's insertion effects + */ +#define NUM_PART_EFX 3 + +/* + * Maximum number of the instrument on a part + */ +#define NUM_KIT_ITEMS 16 + + +/* + * How is applied the velocity sensing + */ +#define VELOCITY_MAX_SCALE 8.0 + +/* + * The maximum length of instrument's name + */ +#define PART_MAX_NAME_LEN 30 + +/* + * The maximum number of bands of the equaliser + */ +#define MAX_EQ_BANDS 8 +#if (MAX_EQ_BANDS>=20) +#error "Too many EQ bands in globals.h" +#endif + + +/* + * Maximum filter stages + */ +#define MAX_FILTER_STAGES 5 + +/* + * Formant filter (FF) limits + */ +#define FF_MAX_VOWELS 6 +#define FF_MAX_FORMANTS 12 +#define FF_MAX_SEQUENCE 8 + +#define LOG_2 0.693147181 +#define PI 3.1415926536 +#define LOG_10 2.302585093 + +/* + * The threshold for the amplitude interpolation used if the amplitude + * is changed (by LFO's or Envelope's). If the change of the amplitude + * is below this, the amplitude is not interpolated + */ +#define AMPLITUDE_INTERPOLATION_THRESHOLD 0.0001 + +/* + * 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 ) + +/* + * Interpolate Amplitude + */ +#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)) + +/* + * The random generator (0.0..1.0) + */ +#define RND (rand()/(RAND_MAX+1.0)) + +#define ZERO(data,size) {char *data_=(char *) data;for (int i=0;i<size;i++) data_[i]=0;}; + +enum ONOFFTYPE{OFF=0,ON=1}; + +enum MidiControllers{C_NULL=0,C_pitchwheel=1000,C_expression=11,C_panning=10, + C_filtercutoff=74,C_filterq=71,C_bandwidth=75,C_modwheel=1,C_fmamp=76, + C_volume=7,C_sustain=64,C_allnotesoff=123,C_allsoundsoff=120,C_resetallcontrollers=121, + C_portamento=65,C_resonance_center=77,C_resonance_bandwidth=78, + + C_dataentryhi=0x06,C_dataentrylo=0x26,C_nrpnhi=99,C_nrpnlo=98}; + + +//is like i=(int)(floor(f)) +#ifdef ASM_F2I_YES +#define F2I(f,i) __asm__ __volatile__ ("fistpl %0" : "=m" (i) : "t" (f-0.49999999) : "st") ; +#else +#define F2I(f,i) (i)=((f>0) ? ( (int)(f) ) :( (int)(f-1.0) )); +#endif + + + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#endif + diff --git a/muse/synti/zynaddsubfx/main.cpp b/muse/synti/zynaddsubfx/main.cpp new file mode 100644 index 00000000..30844f01 --- /dev/null +++ b/muse/synti/zynaddsubfx/main.cpp @@ -0,0 +1,219 @@ +/* + ZynAddSubFX - a software synthesizer + + main.c - Main file of the synthesizer + 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) 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 <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> + +#include <unistd.h> +#include <pthread.h> + +#include "Misc/Master.h" +#include "Misc/Util.h" +#include "Misc/Dump.h" +extern Dump dump; + +#include "Input/NULLMidiIn.h" +#include "MasterUI.h" + +int swaplr=0; //1 for left-right swapping +MidiIn *Midi; +int Pexitprogram = 0;//if the UI set this to 1, the program will exit + +//========================================================= +// MESS interface +//========================================================= + +#include "synti/libsynti/mess.h" +int instances = -1; + +//--------------------------------------------------------- +// Zynadd +//--------------------------------------------------------- + +class Zynadd : public Mess { + virtual void process(float** buffer, int offset, int n); + virtual bool processEvent(const MidiEvent&); + virtual void getInitData(int*, const unsigned char**) const; + + public: + int Pexitprogram; + MasterUI* ui; + Master* vmaster; + pthread_t thr; + + Zynadd(); + ~Zynadd(); + }; + +void* guiThread(void *arg) + { + Zynadd* z = (Zynadd *) arg; + + z->ui = new MasterUI(z->vmaster, &z->Pexitprogram); + + z->ui->showUI(); + while (z->Pexitprogram == 0) + Fl::wait(0.01); + + delete(z->ui); + Fl::wait(0.01); + + pthread_exit(0); + return(0); + } + +//--------------------------------------------------------- +// Zynadd +//--------------------------------------------------------- + +Zynadd::Zynadd() : Mess(2) + { + instances++; + SAMPLE_RATE = sampleRate(); + swaplr = config.cfg.SwapStereo; + Pexitprogram = 0; + + vmaster = new Master(); + vmaster->swaplr = swaplr; + pthread_create(&thr, NULL, guiThread, this); + } + +//--------------------------------------------------------- +// ~Zynadd +//--------------------------------------------------------- + +Zynadd::~Zynadd() + { + Pexitprogram = 1; + sleep(2); //wait the thread to finish + instances--; + } + +//--------------------------------------------------------- +// getInitData +//--------------------------------------------------------- + +void Zynadd::getInitData(int* n, const unsigned char** data) const + { + *n = vmaster->getalldata((char **)data); + } + +//--------------------------------------------------------- +// process +// synthesize n samples into buffer+offset +//--------------------------------------------------------- + +void Zynadd::process(float** outputs, int offset, int n) + { + float* outl = outputs[0] + offset; + float* outr = outputs[1] + offset; + pthread_mutex_lock(&vmaster->mutex); + vmaster->GetAudioOutSamples(n, outl, outr); + pthread_mutex_unlock(&vmaster->mutex); + } + +//--------------------------------------------------------- +// processEvent +//--------------------------------------------------------- + +bool Zynadd::processEvent(const MidiEvent& e) + { + pthread_mutex_lock(&vmaster->mutex); + switch(e.type()) { + case 0x80: // note off + vmaster->NoteOff(e.channel(), e.dataA()); + break; + case 0x90: // note on + if (e.dataB() == 0) + vmaster->NoteOff(e.channel(), e.dataA()); + else + vmaster->NoteOn(e.channel(), e.dataA(), e.dataB()); + break; + case 0xb0: // controller + if (e.dataA() == 0x4000) + // vmaster->setcontroller(e.channel(), C_pitchwheel, data[1]+data[2]*(long int) 128-8192); + vmaster->SetController(e.channel(), C_pitchwheel, e.dataB()); + else { + int cntl = Midi->getcontroller(e.dataA()); + vmaster->SetController(e.channel(), cntl, e.dataB()); + } + break; + case 0xf0: + pthread_mutex_unlock(&vmaster->mutex); + vmaster->putalldata((char*)e.data(), e.len()); + pthread_mutex_lock(&vmaster->mutex); + break; + } + pthread_mutex_unlock(&vmaster->mutex); + return false; + } + +//--------------------------------------------------------- +// instantiate +//--------------------------------------------------------- + +class QWidget; + +static Mess* instantiate(int sr, QWidget*, const char*) + { + if (instances == -1) { + config.init(); + Midi = new NULLMidiIn(); + instances = 0; + srand(time(0)); + SOUND_BUFFER_SIZE = 256; + OSCIL_SIZE = 512; // config.cfg.OscilSize; + denormalkillbuf = new REALTYPE [SOUND_BUFFER_SIZE]; + for (int i = 0; i < SOUND_BUFFER_SIZE; i++) + denormalkillbuf[i] = (RND - 0.5) * 1e-16; + + OscilGen::tmpsmps = new REALTYPE[OSCIL_SIZE]; + newFFTFREQS(&OscilGen::outoscilFFTfreqs,OSCIL_SIZE/2); + } + if (instances != 0) + return 0; //don't allow multiple instances + + Zynadd* sintetizator = new Zynadd(); + sintetizator->setSampleRate(sr); + return sintetizator; + } + +extern "C" { + static MESS descriptor = { + "Zynaddsubfx", + "Zynaddsubfx Software Synthesizer", + "0.1", // version string + MESS_MAJOR_VERSION, MESS_MINOR_VERSION, + instantiate + }; + + // We must compile with -fvisibility=hidden to avoid namespace + // conflicts with global variables. + // Only visible symbol is "mess_descriptor". + // (TODO: all plugins should be compiled this way) + + __attribute__ ((visibility("default"))) + const MESS* mess_descriptor() { return &descriptor; } + } + |