desc:Filther tags: Filther version: 1.90 author: Joep Vanlier changelog: + Allow dragging noise floor FFT + Allow changing zoom on goniometer with dragging + Allow setting smoothing factor with scrollwheel provides: Filther.jsfx.rpl Copyright (C) 2018 Joep Vanlier License: MIT Filter attribution: LP Diode Ladder (MIT Licensed) Copyright (c) 2012 Dominique Wurtz (www.blaukraut.info) Karlsen Fast Ladder III Copyright (c) Ove Hy Karlsen Weeping Demon emulation by Chet Gnegy (https://ccrma.stanford.edu/~chet/) slider1:2<2,9,1>-Nodes negative slider2:2<2,9,1>-Nodes positive slider3:0.15<0,1,.01>-Pos1x slider4:0.15<0,1,.01>-Pos1y slider5:0.25<0,1,.01>-Pos2x slider6:0.25<0,1,.01>-Pos2y slider7:0.35<0,1,.01>-Pos3x slider8:0.35<0,1,.01>-Pos3y slider9:0.5<0,1,.01> -Pos4x slider10:0.5<0,1,.01>-Pos4y slider11:0.6<0,1,.01>-Pos5x slider12:0.6<0,1,.01>-Pos5y slider13:0.7<0,1,.01>-Pos6x slider14:0.7<0,1,.01>-Pos6y slider15:0.8<0,1,.01>-Pos7x slider16:0.8<0,1,.01>-Pos7y slider17:0<-1,1,.01>-Pre-Gain Mod % slider18:0.9<0,1,.01>-Pos8y slider19:0.15<0,1,.01>-Neg1x slider20:0.15<0,1,.01>-Neg1y slider21:0.25<0,1,.01>-Neg2x slider22:0.25<0,1,.01>-Neg2y slider23:0.35<0,1,.01>-Neg3x slider24:0.35<0,1,.01>-Neg3y slider25:0.5<0,1,.01>-Neg4x slider26:0.5<0,1,.01>-Neg4y slider27:0.6<0,1,.01>-Neg5x slider28:0.6<0,1,.01>-Neg5y slider29:0.7<0,1,.01>-Neg6x slider30:0.7<0,1,.01>-Neg6y slider31:0.8<0,1,.01>-Neg7x slider32:0.8<0,1,.01>-Neg7y slider33:1.0<0,2,.01>-Key follow amount slider34:0.9<0,1,.01>-Neg8y // This one secretly has the information folded in whether pre-gain modulation is being used. // Mask: 1 = lookahead, 2 = MGM, 3 = BYPASS 1, 4 = BYPASS 2 slider35:0<0,15,1>-Toggles (DO NOT AUTOMATE) slider36:0<0,26,1>-LFO type slider37:0<0,1,0.001>-LFO freq slider38:0<0,7,1{No reset,Reset,No reset + temposync,Reset + temposync,No reset + centered,Reset + centered,No reset + temposync + centered,Reset + temposync + centered>-Reset LFO slider39:1<0,4,.00001>-Modulation range slider40:<0,51,1{OFF,LP RC-C,Diode Ladder,Vowel,Karlsen,Karlsen S,WS LP,WS HP,WS BP,Moog (ZDF),Ch. Moog (unstable),Notch,Narsty,Modulator,Phaser (OTA),Phaser (FET),Delay Feedbok,Phase Mangler,MS20 LP lin (ZDF),MS20 BP lin(ZDF),MS20 HP lin (ZDF),MS20 LP NL (ZDF),MS20 BP NL (ZDF),MS20 HP NL (ZDF),Experimental,Rezzy (ZDF),SSM LP NL (ZDF),ch. SSM LP NL (Approx),CEM LP NL (ZDF),SSM LP lin (ZDF),CEM LP lin (ZDF),Sine,FM FB,FM-ish,Broken conn,Broken FB (ZDF),Waspey Lin (ZDF),Waspey LP NL(ZDF),Waspey BP NL (ZDF),SVF LP (ZDF),SVF BP (ZDF),SVF HP (ZDF),SVF Notch (ZDF),SVF Peak (ZDF),Saw (ZDF),SVF w/WS Res (ZDF),Voodoo,Junk (ZDF),Comb,Combres (LP),Combedres (BP)}>-Filter2 Type slider41:<0,1,.001>-Filter2 Cutoff slider42:<0,1,.001>-Filter2 Reso slider43:.5<-1,1,.01>-Filter2 Cutoff Mod % slider44:0<-1,1,.01>-Filter2 Reso Mod % slider45:0<0,5,1{Dynamic RMS,Direct RMS,MIDI poly,MIDI legato,MIDI poly vel,MIDI legato vel>-Dynamics mode slider46:<0,8,1>-Filter Operation Mode slider47:<0,54,1{OFF,LP RC-C,Diode Ladder,Vowel,Karlsen,Karlsen S,WS LP,WS HP,WS BP,Moog (ZDF),Ch. Moog (unstable),Notch,Narsty,Modulator,Phaser (OTA),Phaser (FET),Delay Feedbok,Phase Mangler,MS20 LP lin (ZDF),MS20 BP lin(ZDF),MS20 HP lin (ZDF),MS20 LP NL (ZDF),MS20 BP NL (ZDF),MS20 HP NL (ZDF),Experimental,Rezzy (ZDF),SSM LP NL (ZDF),ch. SSM LP NL (Approx),CEM LP NL (ZDF),SSM LP lin (ZDF),CEM LP lin (ZDF),Sine,FM FB,FM-ish,Broken conn,Broken FB (ZDF),Waspey Lin (ZDF),Waspey LP NL(ZDF),Waspey BP NL (ZDF),SVF LP (ZDF),SVF BP (ZDF),SVF HP (ZDF),SVF Notch (ZDF),SVF Peak (ZDF),Saw (ZDF),SVF w/WS Res (ZDF),Voodoo,Junk (ZDF),Comb,Combres (LP),Combedres (BP),MS-20 LP2,MS-20 BP2,MS-20 HP2}>-Filter Type slider48:<0,1,.001>-Cutoff slider49:<0,1,.001>-Reso slider50:0<0,6,1>-FIR resampling and linking mode // {FIR off,FIR on,FIR off parallel,FIR on parallel //slider50:1<0,2,1{Sample & Hold per block,Good,Linear per block}>-Parameter Interpolation slider51:0<-1,1,.01>-Pre-Gain/Drive Mod % slider52:0<-40,40,.01>-PreGain slider53:0<-40,40,.01>-PostGain slider54:1<1,8,1>-Oversampling slider55:0<0,7,1{No clipping,Input clipping,Output clipping,Input/output clipping,No clipping + Inertia,Input clipping + Inertia,Output clipping + Inertia,Input/output clipping + Inertia}>-Clipping and Inertia slider56:0<0,4,4{Spline,Tanh,Fast Tanh,None,Sine}>-Waveshaping Mode slider57:0<0,63,1{Attack x1 Decay x1 RMS x1,Attack x8 Decay x1 RMS x1,Attack x4 Decay x1 RMS x1,Attack x32 Decay x1 RMS x1,Attack x1 Decay x8 RMS x1,Attack x8 Decay x8 RMS x1,Attack x4 Decay x8 RMS x1,Attack x32 Decay x8 RMS x1,Attack x1 Decay x4 RMS x1,Attack x8 Decay x4 RMS x1,Attack x4 Decay x4 RMS x1,Attack x32 Decay x4 RMS x1,Attack x1 Decay x32 RMS x1,Attack x8 Decay x32 RMS x1,Attack x4 Decay x32 RMS x1,Attack x32 Decay x32 RMS x1,Attack x1 Decay x1 RMS x8,Attack x8 Decay x1 RMS x8,Attack x4 Decay x1 RMS x8,Attack x32 Decay x1 RMS x8,Attack x1 Decay x8 RMS x8,Attack x8 Decay x8 RMS x8,Attack x4 Decay x8 RMS x8,Attackx32 Decay x8 RMS x8,Attack x1 Decay x4 RMS x8,Attack x8 Decay x4 RMS x8,Attack x4 Decay x4 RMS x8,Attack x32 Decay x4 RMS x8,Attack x1 Decay x32 RMS x8,Attack x8 Decay x32 RMS x8,Attack x4 Decay x32 RMS x8,Attack x32 Decay x32 RMS x8,Attack x1 Decay x1 RMS x4,Attack x8 Decay x1 RMS x4,Attack x4 Decay x1 RMS x4,Attack x32 Decay x1 RMS x4,Attack x1 Decay x8 RMS x4,Attack x8 Decay x8 RMS x4,Attack x4 Decay x8 RMS x4,Attack x32 Decay x8 RMS x4,Attack x1 Decay x4 RMS x4,Attack x8 Decay x4 RMS x4,Attack x4 Decay x4 RMS x4,Attack x32 Decay x4 RMS x4,Attack x1 Decay x32 RMS x4,Attack x8 Decay x32 RMS x4,Attack x4 Decay x32 RMS x4,Attack x32 Decay x32 RMS x4,Attack x1 Decay x1 RMS x32,Attack x8 Decay x1 RMS x32,Attack x4 Decay x1 RMS x32,Attack x32 Decay x1 RMS x32,Attack x1 Decay x8 RMS x32,Attack x8 Decay x8 RMS x32,Attack x4 Decay x8 RMS x32,Attack x32 Decay x8 RMS x32,Attack x1 Decay x4 RMS x32,Attack x8 Decay x4 RMS x32,Attack x4 Decay x4 RMS x32,Attack x32 Decay x4 RMS x32,Attack x1 Decay x32 RMS x32,Attack x8 Decay x32 RMS x32,Attack x4 Decay x32 RMS x32,Attack x32 Decay x32 RMS x3}>-Multipliers slider58:1<0,1024,1{OFF,F1F2DYN-LFO,SHAPER,F1F2DYN-LFO-SHAPER,F1DYN-LFO,F1F2DYN-LFO,F1DYN-LFO-SHAPER,F1F2DYN-LFO-SHAPER,F1LFO,F1F2DYN-F1LFO,F1LFO-SHAPER,F1F2DYN-F1LFO-SHAPER,F1DYN-F1LFO,F1F2DYN-F1LFO,F1DYN-F1LFO-SHAPER,F1F2DYN-F1LFO-SHAPER,F2DYN-LFO,F1F2DYN-LFO,F2DYN-LFO-SHAPER,F1F2DYN-LFO-SHAPER,F1F2DYN-LFO,F1F2DYN-LFO,F1F2DYN-LFO-SHAPER,F1F2DYN-LFO-SHAPER,F2DYN-F1LFO,F1F2DYN-F1LFO,F2DYN-F1LFO-SHAPER,F1F2DYN-F1LFO-SHAPER,F1F2DYN-F1LFO,F1F2DYN-F1LFO,F1F2DYN-F1LFO-SHAPER,F1F2DYN-F1LFO-SHAPER,F2LFO,F1F2DYN-F2LFO,F2LFO-SHAPER,F1F2DYN-F2LFO-SHAPER,F1DYN-F2LFO,F1F2DYN-F2LFO,F1DYN-F2LFO-SHAPER,F1F2DYN-F2LFO-SHAPER,F1F2LFO,F1F2DYN-F1F2LFO,F1F2LFO-SHAPER,F1F2DYN-F1F2LFO-SHAPER,F1DYN-F1F2LFO,F1F2DYN-F1F2LFO,F1DYN-F1F2LFO-SHAPER,F1F2DYN-F1F2LFO-SHAPER,F2DYN-F2LFO,F1F2DYN-F2LFO,F2DYN-F2LFO-SHAPER,F1F2DYN-F2LFO-SHAPER,F1F2DYN-F2LFO,F1F2DYN-F2LFO,F1F2DYN-F2LFO-SHAPER,F1F2DYN-F2LFO-SHAPER,F2DYN-F1F2LFO,F1F2DYN-F1F2LFO,F2DYN-F1F2LFO-SHAPER,F1F2DYN-F1F2LFO-SHAPER,F1F2DYN-F1F2LFO,F1F2DYN-F1F2LFO,F1F2DYN-F1F2LFO-SHAPER,F1F2DYN-F1F2LFO-SHAPER}>-Dynamics slider59:1<0,1,.001>-Thresh slider60:1<0,50,.1>-Attack slider61:1<0.1,50,.1>-Decay slider62:.5<-1,1,.01>-Filt Cutoff Mod % slider63:0<-1,1,.01>-Filt Reso Mod % slider64:.34<0.02,40,0.001>-RMS Integration time in_pin:left input in_pin:right input out_pin:left output out_pin:right output options:no_meter @serialize file_var(0,extraScale); file_var(0,hideToolTips); file_var(0,linuxMode); file_var(0,dnoisefloor_freq); file_var(0,dsteps_fft); file_var(0,dgonio_zoom); @init // Colors fft_out_r = .8; fft_out_g = .8; fft_out_b = .8; fft_out_a = 1.0; fft_in_r = .13; fft_in_g = .13; fft_in_b = .13; fft_in_a = .6; spline_r = .7; spline_g = .7; spline_b = .7; spline_a = .7; dyn_color_r = .8; dyn_color_g = .8; dyn_color_b = .2; dyn_color_a = .3; filter_description_r = 0.6; filter_description_g = 0.6; filter_description_b = 1.0; filter_description_a = 1.0; font_color_r = .8; font_color_g = .8; font_color_b = .8; font_color_a = .8; highlight_color_r = .9; highlight_color_g = .7; highlight_color_b = .7; highlight_color_a = .7; slider_marker_r = .9; slider_marker_g = .9; slider_marker_b = .7; slider_marker_a = .7; grid_color_r = .3; grid_color_g = .3; grid_color_b = .6; grid_color_a = .2; backface_color_r = .2; backface_color_g = .2; backface_color_b = .3; backface_color_a = .1; thresh_color_r = 0.9; thresh_color_g = 0.3; thresh_color_b = 0.3; thresh_color_a = 1.0; gonio_out_r = .8; gonio_out_g = .8; gonio_out_b = .8; gonio_out_a = .24; gonio_in_r = .23; gonio_in_g = .23; gonio_in_b = .23; gonio_in_a = .36; logo_color_r = .8; logo_color_g = .9; logo_color_b = 1.5; rms_in_r = 1; rms_in_g = .3; rms_in_b = .3; rms_in_a = .3; rms_out_r = .6; rms_out_g = .3; rms_out_b = 1; rms_out_a = .9; widgetcolor_r = .7; widgetcolor_g = .7; widgetcolor_b = .9; widgetcolor_a = .7; group_color_r = .7; group_color_g = .7; group_color_b = .9; group_color_a = 0.05; selectionbutton_color_r = .3; selectionbutton_color_g = .4; selectionbutton_color_b = .8; selectionbutton_color_a = .3; filter_description_bg_r = 0.1; filter_description_bg_g = 0.1; filter_description_bg_b = 0.2; filter_description_bg_a = 0.05; MAXOVERSAMPLING = 8; MAXBUFFERSIZE = MAXOVERSAMPLING*10000; gfx_ext_retina = 1.0; plugname = "FILTHER 1.90"; //fontface = "Sans Serif"; fontface = "Arial"; newUI = 1; refreshDynMode = -1; nFilters = 65; nModes = 9; nModes2 = 4; nLFO = 27; lastOversample = 0; lastpdcDelay = -1000; lastIntegrationTime = -1000; nTapSinc = slider54 < 5 ? 16 : slider54*4; modulator.t = 0; modulator.lastt = -1; notesOn = 0; israte = 1/srate; log2 = log(2); function comboStrings(stridx, curitem) local(str) global() instance() ( str = ""; (stridx == 0) ? ( ( curitem == 0 ) ? ( str = "OFF" ) : ( curitem == 1 ) ? ( str = "LP RC-C" ) : ( curitem == 2 ) ? ( str = "Diode Ladder" ) : ( curitem == 3 ) ? ( str = "Vowel" ) : ( curitem == 4 ) ? ( str = "Karlsen Ladder III (303)" ) : ( curitem == 5 ) ? ( str = "Karlsen Ladder IIIs (303)" ) : ( curitem == 6 ) ? ( str = "Sai'ke Waveshaped LP" ) : ( curitem == 7 ) ? ( str = "Sai'ke Waveshaped HP" ) : ( curitem == 8 ) ? ( str = "Sai'ke Waveshaped BP" ) : ( curitem == 9 ) ? ( str = "Expensive Moog (ZDF)" ) : ( curitem == 10 ) ? ( str = "Cheap Moog (unstable)" ) : ( curitem == 11 ) ? ( str = "Notch" ) : ( curitem == 12 ) ? ( str = "Narsty" ) : ( curitem == 13 ) ? ( str = "Modulator" ) : ( curitem == 14 ) ? ( str = "Phaser (OTA)" ) : ( curitem == 15 ) ? ( str = "Phaser (FET)" ) : ( curitem == 16 ) ? ( str = "Delay Feedbok" ) : ( curitem == 17 ) ? ( str = "Phase Mangler" ) : ( curitem == 18 ) ? ( str = "Kr0g MS-20 linear LP (ZDF)" ) : ( curitem == 19 ) ? ( str = "Kr0g MS-20 linear BP (ZDF)" ) : ( curitem == 20 ) ? ( str = "Kr0g MS-20 linear HP (ZDF)" ) : ( curitem == 21 ) ? ( str = "Kr0g MS-20 nonlin LP (ZDF)" ) : ( curitem == 22 ) ? ( str = "Kr0g MS-20 nonlin BP (ZDF)" ) : ( curitem == 23 ) ? ( str = "Kr0g MS-20 nonlin HP (ZDF)" ) : ( curitem == 24 ) ? ( str = "Experimental" ) : ( curitem == 25 ) ? ( str = "Rezzy (ZDF)" ) : ( curitem == 26 ) ? ( str = "4p LP SSM 2020 NL (ZDF)" ) : ( curitem == 27 ) ? ( str = "4p LP SSM 2020 NL (Approx)" ) : ( curitem == 28 ) ? ( str = "4p LP CEM 3389 NL (ZDF)" ) : ( curitem == 29 ) ? ( str = "4p LP SSM 2020 L (ZDF)" ) : ( curitem == 30 ) ? ( str = "4p LP CEM 3389 L (ZDF)" ) : ( curitem == 31 ) ? ( str = "Sine" ) : ( curitem == 32 ) ? ( str = "FM Feedback" ) : ( curitem == 33 ) ? ( str = "Filter FM-ish 2" ) : ( curitem == 34 ) ? ( str = "Broken connection" ) : ( curitem == 35 ) ? ( str = "Broken feedback (ZDF)" ) : ( curitem == 36 ) ? ( str = "Waspey Linear (ZDF)" ) : ( curitem == 37 ) ? ( str = "Waspey Non-Linear LP(ZDF)" ) : ( curitem == 38 ) ? ( str = "Waspey Non-Linear BP (ZDF)" ) : ( curitem == 39 ) ? ( str = "Linear SVF LP (ZDF)" ) : ( curitem == 40 ) ? ( str = "Linear SVF BP (ZDF)" ) : ( curitem == 41 ) ? ( str = "Linear SVF HP (ZDF)" ) : ( curitem == 42 ) ? ( str = "Linear SVF Notch (ZDF)" ) : ( curitem == 43 ) ? ( str = "Linear SVF Peak (ZDF)" ) : ( curitem == 44 ) ? ( str = "Everything is a saw (ZDF)" ) : ( curitem == 45 ) ? ( str = "SVF with waveshaped resonance (ZDF)" ) : ( curitem == 46 ) ? ( str = "Voodoo" ) : ( curitem == 47 ) ? ( str = "Junk (ZDF)" ) : ( curitem == 48 ) ? ( str = "Comb" ) : ( curitem == 49 ) ? ( str = "Combed resonance (LP)" ) : ( curitem == 50 ) ? ( str = "Combed resonance (BP)" ) : ( curitem == 51 ) ? ( str = "Kr0g MS-20 nonlin LP MK ][ (ZDF)" ) : ( curitem == 52 ) ? ( str = "Kr0g MS-20 nonlin BP MK ][ (ZDF)" ) : ( curitem == 53 ) ? ( str = "Kr0g MS-20 nonlin HP MK ][ (ZDF)" ) : ( curitem == 54 ) ? ( str = "Weeping Demon" ) : ( curitem == 55 ) ? ( str = "PWM Potatoes LP" ) : ( curitem == 56 ) ? ( str = "PWM Potatoes BP" ) : ( curitem == 57 ) ? ( str = "Bit reduction" ) : ( curitem == 58 ) ? ( str = "Muck" ) : ( curitem == 59 ) ? ( str = "Weeping Demon ][" ) : ( curitem == 60 ) ? ( str = "Crybaby" ) : ( curitem == 61 ) ? ( str = "Crybaby (Circuit bent for higher pitch)" ) : ( curitem == 62 ) ? ( str = "Crybaby (Circuit bent for lower pitch)" ) : ( curitem == 63 ) ? ( str = "Vowel SVF" ) : ( curitem == 64 ) ? ( str = "Monstro" ); ) : (stridx == 1) ? ( ( curitem == 0 ) ? ( str = "Stereo" ) : ( curitem == 1 ) ? ( str = "Mono double" ) : ( curitem == 2 ) ? ( str = "M1/S2" ) : ( curitem == 3 ) ? ( str = "M2/S1" ) : ( curitem == 4 ) ? ( str = "Only side" ) : ( curitem == 5 ) ? ( str = "Only mid" ) : ( curitem == 6 ) ? ( str = "Stereo Boost" ) : ( curitem == 7 ) ? ( str = "Stereoize" ) : ( curitem == 8 ) ? ( str = "Subtle Stereo" ); ) : (stridx == 2) ? ( ( curitem == 0 ) ? ( str = "OFF" ) : ( curitem == 1 ) ? ( str = "Cosine" ) : ( curitem == 2 ) ? ( str = "Sine" ) : ( curitem == 3 ) ? ( str = "Cos^2" ) : ( curitem == 4 ) ? ( str = "Sin^2" ) : ( curitem == 5 ) ? ( str = "Ramp up" ) : ( curitem == 6 ) ? ( str = "Ramp down" ) : ( curitem == 7 ) ? ( str = "Exponential" ) : ( curitem == 8 ) ? ( str = "Exp + Atk" ) : ( curitem == 9 ) ? ( str = "1-Exponential" ) : ( curitem == 10 ) ? ( str = "Random" ) : ( curitem == 11 ) ? ( str = "Random Exps" ) : ( curitem == 12 ) ? ( str = "Rand Exps + Atk" ) : ( curitem == 13 ) ? ( str = "Single Exp" ) : ( curitem == 14 ) ? ( str = "Single Exp + Atk" ) : ( curitem == 15 ) ? ( str = "Sixteenth pulse" ) : ( curitem == 16 ) ? ( str = "Eighth pulse" ) : ( curitem == 17 ) ? ( str = "Quarter pulse" ) : ( curitem == 18 ) ? ( str = "Half pulse" ) : ( curitem == 19 ) ? ( str = "Triplet" ) : ( curitem == 20 ) ? ( str = "Sine Pulse" ) : ( curitem == 21 ) ? ( str = "Polyrhythm" ) : ( curitem == 22 ) ? ( str = "Polyrhythm ][" ) : ( curitem == 23 ) ? ( str = "Polyrhythm ]|[" ) : ( curitem == 24 ) ? ( str = "Triangle" ) : ( curitem == 25 ) ? ( str = "Two harmonics" ) : ( curitem == 26 ) ? ( str = "Three harmonics" ) ) : (stridx == 3) ? ( ( curitem == 0 ) ? ( str = "Serial Dual Dist" ) : ( curitem == 1 ) ? ( str = "Serial" ) : ( curitem == 2 ) ? ( str = "Parallel Dual Dist" ) : ( curitem == 3 ) ? ( str = "Parallel" ); ); str; ); function modulator() global(srate) local() instance( invpi2, twopi, invsrate, reset, modvalue, modrate, t, modmax ) ( modvalue = 0; reset = 1; modmax = 1; invsrate = 1.0/srate; invpi2 = .5/$pi; twopi = 2*$pi; ); function setmodrate(val) global() local() instance( invsrate, reset, modvalue, modrate, t ) ( modrate = val; ); modulator.modulator(); function updateModulator() instance( invpi2, twopi, invsrate, reset, modvalue, modrate, t, lastt, lastrand ) global( slider38, slider39, slider36, modulatorDynamics) local(ct, st) ( slider36 > 0 ? ( modulatorDynamics = 1; t = t + modrate*invsrate; (slider38 & 1) && reset == 1 ? ( t = 0; reset = 0; lastt = -1; ); modvalue = slider36 == 1 ? .5 + .5 * cos(twopi*t) : ( slider36==2 ) ? .5 + .5 * sin(twopi*t) : ( slider36==3 ) ? ( ct = cos($pi*t); ct*ct ) : ( slider36==4 ) ? ( st = sin($pi*t); st*st ) : ( slider36==5 ) ? ( t-floor(t) ) : ( slider36==6 ) ? ( 1-t+floor(t) ) : ( slider36==7 ) ? ( exp(-4*(t-floor(t))) ) : ( slider36==8 ) ? ( min((15*(t-floor(t))),1)*exp(-4*(t-floor(t))) ) : ( slider36==9 ) ? ( 1-exp(-4*(t-floor(t))) ) : ( slider36==10 ) ? ( ( t > (lastt+1) ) ? ( lastt = lastt+1; lastrand=rand() ); lastrand ) : ( slider36==11 ) ? ( ( t > (lastt+1) ) ? ( lastt = lastt+1; lastrand=rand() ); exp(-4*lastrand*(t-floor(t))) ) : ( slider36==12 ) ? ( ( t > (lastt+1) ) ? ( lastt = lastt+1; lastrand=rand() ); min((15*(.2+.8*lastrand)*(t-floor(t))),1)*exp(-4*lastrand*(t-floor(t))) ) : ( slider36==13 ) ? ( exp(-t) ) : ( slider36==14 ) ? ( min((15*t),1)*exp(-t) ) : ( slider36==15 ) ? ( (t-floor(t)) < .0625 ) : ( slider36==16 ) ? ( (t-floor(t)) < .125 ) : ( slider36==17 ) ? ( (t-floor(t)) < .25 ) : ( slider36==18 ) ? ( (t-floor(t)) < .5 ) : ( slider36==19 ) ? ( (3*t-floor(3*t)) < .5 ) : ( slider36==20 ) ? ( ((8*t-floor(8*t)) < .5) * (.5 + .5*cos(twopi*t)) ) : ( slider36==21 ) ? ( ((4*t-floor(4*t)) < .25) * (.5 + .5*cos(twopi*t)) * .5 + .5 * ((3*t-floor(3*t)) > .25) * (.5 + .5*sin(twopi*t)) ) : ( slider36==22 ) ? ( ((8*t-floor(8*t)) < .25) * (.5 + .5*cos(twopi*t)) * .5 + .5 * ((6*t-floor(6*t)) > .25) * (.5 + .5*sin(twopi*t)) ) : ( slider36==23 ) ? ( ((8*t-floor(8*t)) < .5) * .5 + .5 * ((3*t-floor(6*t)) < .5) * (.5+.5*sin(twopi*t)) ) : ( slider36==24 ) ? ( 1-2*abs(t-floor(t)-0.5) ) : ( slider36==25 ) ? ( sin(twopi*t)*.3+.5 + sin(2*twopi*t)*.2 ) : ( slider36==26 ) ? ( sin(twopi*t)*.2+.5 + sin(2*twopi*t)*.2 + sin(4*twopi*t)*.1 ) ; slider38 & 4 ? modvalue -= .5 ) : ( modvalue = 0; modulatorDynamics = 0; ); ); function getvalue( tval ) instance( t, modvalue ) global(slider38) local() ( t = tval; this.updateModulator(); modvalue + (slider38 & 4 ? .5 : 0) ); function create_mod_window(_x, _y, _w, _h, _r, _g, _b, _a) instance(x, y, w, h, mod, r, g, b, a) local() global() ( mod.modulator(); x = _x; y = _y+1; w = _w; h = _h-2; r = _r; g = _g; b = _b; a = _a; ); //modulatorDisplay.create_mod_window(5, 5, 10, 10); //modulatorDisplay.draw_modulator(); function draw_modulator() instance(x, y, w, h, mod, r, g, b, a) local(dx, t, lx, ly, nx, ny) global() ( gfx_set( 0, 0, 0, .1 ); gfx_rect( x, y, w, h ); gfx_set( r, g, b, a*.8 ); gfx_line(x, y, x, y+h); gfx_line(x+1, y, x+w-1, y); gfx_line(x+w, y, x+w, y+h); gfx_line(x+1, y+h, x+w-1, y+h); gfx_set( r, g, b, a ); dx = .5/w; lx = x; ly = 0.5 * h + y; t = 0; loop(2*w, ny = y + h - h*mod.getValue(t); nx = lx + .5; gfx_line( lx, ly, nx, ny ); lx = nx; ly = ny; t = t + dx; ); ); function gfx_wrapprint(str, maxlen) global(gfx_x, gfx_y) local(mp, len, str, lastLineStart, lastWordStart, cpos, tmp, mx, my, xref, yref) ( xref = gfx_x; yref = gfx_y; len = strlen(str); lastLineStart = 0; lastWordStart = 0; cpos = 0; tmp = 1; mp = 0; loop(len, // Found end of a word! ( str_getchar(str, cpos) == 32 ) ? ( // Is the current line too long? gfx_measurestr( strcpy_substr( tmp, str, lastLineStart, cpos-lastLineStart ), mx, my ); ( mx > maxlen ) ? ( strcpy_substr( tmp, str, lastLineStart+mp, lastWordStart - lastLineStart ); gfx_printf( tmp ); // Yeah, terminate here lastLineStart = lastWordStart; gfx_x = xref; gfx_y += my; mp = 1; ) : ( // Nope keep going lastWordStart = cpos; ); ); cpos += 1; ); strcpy_substr(tmp, str, lastLineStart+mp, cpos - lastLineStart); gfx_printf(tmp); ); function filterDescription(filteridx, yloc) global(gfx_x, gfx_y, slider47, wndX, wndY, wndPad, retina_scaling, fontface filter_description_r, filter_description_g, filter_description_b, filter_description_a) local(fx, fy, wx, wx2, wy) ( fx = 30*retina_scaling; wx = 3*wndX + 2*wndPad; wx2 = wx - fx; gfx_x = fx+5; gfx_y = yloc; gfx_set(filter_description_r, filter_description_g, filter_description_b, filter_description_a); gfx_setfont(2, fontface, 12*retina_scaling); ( filteridx == 0 ) ? ( gfx_printf("OFF") ) : ( filteridx == 1 ) ? ( gfx_printf("Filter: LP RC-C\n\n"); gfx_x = fx+5; gfx_wrapprint("Simple state space filter. This filter does not use internal waveshaping and the output of the filter is waveshaped instead.", wx2); ) : ( filteridx == 2 ) ? ( gfx_printf("Filter: LP Diode Ladder (not unconditionally stable)\n\n"); gfx_x = fx+5; gfx_wrapprint("This filter was based on a model by Dominique Wurtz which modelled the 303 diode ladder. The only modification is that rather than input clipping, the waveshaper is used.", wx2); ) : ( filteridx == 3 ) ? ( gfx_printf("Filter: Vowel filter\n\n"); gfx_x = fx+5; gfx_wrapprint("This filter uses 3 band pass filters to imitate vowel sounds.", wx2); ) : ( filteridx == 4 ) ? ( gfx_printf("Filter: LP Karlsen Fast Ladder III\n\n"); gfx_x = fx+5; gfx_wrapprint("This filter is based on a 303 diode ladder. The filter uses the waveshaper as non/ideal part rather than just clipping. Note that this filter doesn't completely maintain its tone when using different levels of supersampling.", wx2); ) : ( filteridx == 5 ) ? ( gfx_printf("Filter: LP Karlsen Fast Ladder III (sat)\n\n"); gfx_x = fx+5; gfx_wrapprint("This filter combines the 303 diode ladder filter with a fixed shelf filter. The filter uses the waveshaper as non/ideal part rather than just clipping. Note that this filter doesn't completely maintain its tone when using different levels of supersampling.", wx2); ) : ( filteridx == 6 ) ? ( gfx_printf("Filter: Saike`s Waveshaped Resonance (LP) (not unconditionally stable)\n\n"); gfx_x = fx+5; gfx_wrapprint("This filter consists of two first order low-pass filters. The difference in filter outputs is distorted through the waveshaper and fed back to give a resonant peak. The output is then subsequently distorted again. This filter can get very mean depending on the waveshaping curve. Be careful! Note that this filter forces oversampling to be at least 2x.", wx2); ) : ( filteridx == 7 ) ? ( gfx_printf("Filter: Saike`s Waveshaped Resonance (HP) (not unconditionally stable)\n\n"); gfx_x = fx+5; gfx_wrapprint("This is a waveshaped highpass filter. The difference in filter outputs is distorted through the waveshaper and fed back to give a resonant peak. The output is then subsequently distorted again. Stability can be enhanced by oversampling. Note that this filter forces oversampling to be at least 2x.", wx2); ) : ( filteridx == 8 ) ? ( gfx_printf("Filter: Saike`s Waveshaped Resonance (BP) (not unconditionally stable)\n\n"); gfx_x = fx+5; gfx_wrapprint("This is a waveshaped bandpass filter. Sort of. The difference in filter outputs is distorted through the waveshaper and fed back to give a resonant peak. The output is then subsequently distorted again. Stability can be enhanced by oversampling. Note that this filter forces oversampling to be at least 2x.", wx2); ) : ( filteridx == 9 ) ? ( gfx_printf("Filter: Model of a Moog filter (not unconditionally stable)\n\n"); gfx_x = fx+5; gfx_wrapprint("This filter is based on the paper Modeling and measuring a Moog voltage-cont\rolled filter by Paschou et al. This filter requires 2x upsampling to remain stable. This version is more stable than the cheap version, but still be careful. High gain with high resonance can be problematic.", wx2); ) : ( filteridx == 10 ) ? ( gfx_printf("Filter: Approximate model of a Moog filter (not unconditionally stable)\n\n"); gfx_x = fx+5; gfx_wrapprint("Based on the paper Modeling and measuring a Moog voltage-controlled filter by Paschou et al. Note that at a minimum, this filter requires 2x upsampling to remain stable. Higher values will bring in higher quality as the non-linearity makes it sensitive to aliasing problems. This version does not correctly compute the Jacobian. Be careful though!", wx2); ) : ( filteridx == 11 ) ? ( gfx_printf("Filter: Basic notch filter\n\n"); gfx_x = fx+5; ) : ( filteridx == 12 ) ? ( gfx_printf("Filter: Narsty (not unconditionally stable)\n\n"); gfx_x = fx+5; gfx_wrapprint("Saike's make things nasty filter. Combination of 3 filters with varying interacting resonances. No guarantees that this thing won´t blow up in your face. Exclusively meant for basses. Note that this one does not maintain its character when changing the sampling rate.", wx2); ) : ( filteridx == 13 ) ? ( gfx_printf("Filter: Modulator\n\n"); gfx_x = fx+5; gfx_wrapprint("Passes a lowpassed version of the signal and modulates it with the signal itself. Second bandpass filtered version is added to provide the resonance peak. This filter is meant for sounds with limited high frequency content as it will sound awful with rich sounds.\n", wx2); ) : ( filteridx == 14 ) ? ( gfx_printf("Filter: Phaser (not unconditionally stable)\n\n"); gfx_x = fx+5; gfx_wrapprint("4 pass phaser based on operational transconductance amplifiers. Note that this one frequently has problem with spline voltage curves.", wx2); ) : ( filteridx == 15 ) ? ( gfx_printf("Filter: Phaser based on FET (not unconditionally stable)\n\n"); gfx_x = fx+5; gfx_wrapprint("4 pass phaser based on Field Effect Transistor elements.", wx2); ) : ( filteridx == 16 ) ? ( gfx_printf("Filter: Phaser-like\n\n"); gfx_x = fx+5; gfx_wrapprint("Non-linear phaser like filter with relatively long delays and distortion of difference signal.", wx2); ) : ( filteridx == 17 ) ? ( gfx_printf("Filter: Phase mangler\n\n"); gfx_x = fx+5; gfx_wrapprint("Magic??? I honestly forgot what the idea was behind this one.", wx2); ) : ( filteridx == 18 ) ? ( gfx_printf("Filter: MS-20 linear LP\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback MS-20 emulation. Note that this filter doesn't saturate or self-oscillate in the way the non-linear emulation would. The computational cost is much lower however.", wx2); ) : ( filteridx == 19 ) ? ( gfx_printf("Filter: MS-20 linear BP\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback MS-20 emulation. Note that this filter doesn't saturate or self-oscillate in the way the non-linear emulation would. The computational cost is much lower however.", wx2); ) : ( filteridx == 20 ) ? ( gfx_printf("Filter: MS-20 linear HP\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback MS-20 emulation. Note that this filter doesn't saturate or self-oscillate in the way the non-linear emulation would. The computational cost is much lower however.", wx2); ) : ( filteridx == 21 ) ? ( gfx_printf("Filter: MS-20 non-linear LP\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback MS-20 emulation with non-linearity. This thing sounds great when overdriven, especially without waveshaper. The non-linear elements consist of arctans that saturate at each stage, and a nice diode clipper in the feedback. It can sound raw, yet clean, if that makes sense.", wx2); ) : ( filteridx == 22 ) ? ( gfx_printf("Filter: MS-20 non-linear BP\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback MS-20 emulation with non-linearity. This thing sounds great when overdriven, especially without waveshaper. The non-linear elements consist of arctans that saturate at each stage, and a nice diode clipper in the feedback. It can sound raw, yet clean, if that makes sense.", wx2); ) : ( filteridx == 23 ) ? ( gfx_printf("Filter: MS-20 non-linear HP\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback MS-20 emulation with non-linearity. This thing sounds great when overdriven, especially without waveshaper. The non-linear elements consist of arctans that saturate at each stage, and a nice diode clipper in the feedback. It can sound raw, yet clean, if that makes sense.", wx2); ) : ( filteridx == 24 ) ? ( gfx_printf("Filter: Multiphase\n\n"); gfx_x = fx+5; gfx_wrapprint("Experimental thingamabob. Bits of phaser, bits of a saturating lowpass, some distortion gibberish and some ugly ass feedback. Be careful with this thing. Especially when you're combining it with a waveshaper. It has plenty of bite. P.S. It self-oscillates too. ;_;", wx2); ) : ( filteridx == 25 ) ? ( gfx_printf("Filter: Rezzy\n\n"); gfx_x = fx+5; gfx_wrapprint("Honestly, I forgot what this one represents really. It came around after an afternoon of screwing around with the feedback mechanism in the MS-20. It can sound quite bitey, which I like.", wx2); ) : ( filteridx == 26 ) ? ( gfx_printf("Filter: 4 pole non-linear LP\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback 4-pole SSM2020 emulation with non-linearity (tanh) in the model. The waveshaper is applied to the output and can be used to tame the output.", wx2); ) : ( filteridx == 27 ) ? ( gfx_printf("Filter: Cheaper 4 pole non-linear LP\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback 4-pole SSM2020 emulation with non-linearity (cheap tanh) in the model. The waveshaper is applied to the output and can be used to tame the output.", wx2); ) : ( filteridx == 28 ) ? ( gfx_printf("Filter: 4 pole non-linear LP\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback 4-pole CEM 3389 emulation with non-linearity (tanh) in the model. The waveshaper is applied to the output and can be used to tame the output.", wx2); ) : ( filteridx == 29 ) ? ( gfx_printf("Filter: Linearized 4 pole non-linear LP\n\n"); gfx_x = fx+5; gfx_wrapprint("Linearized zero delay feedback 4-pole SSM2020 emulation. The waveshaper is applied to the output and can be used to tame the output. Note that this filter doesn't saturate or self-oscillate in the way the non-linear emulation would. The computational cost is much lower however.", wx2); ) : ( filteridx == 30 ) ? ( gfx_printf("Filter: Linearized 4 pole non-linear LP\n\n"); gfx_x = fx+5; gfx_wrapprint("Linearized zero delay feedback 4-pole CEM 3389 emulation. The waveshaper is applied to the output and can be used to tame the output. Note that this filter doesn't saturate or self-oscillate in the way the non-linear emulation would. The computational cost is much lower however.", wx2); ) : ( filteridx == 31 ) ? ( gfx_printf("Filter: Sine\n\n"); gfx_x = fx+5; gfx_wrapprint("Take the sine of the signal. Cutoff controls frequency, resonance controls mix. Simple, but surprisingly satisfying. Use on basses, not high frequency content.", wx2); ) : ( filteridx == 32 ) ? ( gfx_printf("Filter: FM feedback\n\n"); gfx_x = fx+5; gfx_wrapprint("Non-linear MS-20 but with the feedback signal FM modulated. I've had lucky sweet spots with this thing, but it's horrible. Most of the times it'll just sound horrendous.", wx2); ) : ( filteridx == 33 ) ? ( gfx_printf("Filter: FM MS-20\n\n"); gfx_x = fx+5; gfx_wrapprint("This filter uses the input signal as modulation source for the cutoff of an MS-20 linear which then modifies the input signal. Huh?", wx2); ) : ( filteridx == 34 ) ? ( gfx_printf("Filter: Broken Connection\n\n"); gfx_x = fx+5; gfx_wrapprint("Messy filter. Be careful with this one. It was actually sort of an accident, but it seems pretty stable and pretty unique. It is not invariant under oversampling particularly in the low frequency regions where it likes to lead a life of its own. It's based on the kr0g filter, but including a voltage inversion step in the feedback path (low to high, high to low, not just polarity switch).", wx2); ) : ( filteridx == 35 ) ? ( gfx_printf("Filter: Borked Waspey feedback (not unconditionally stable)\n\n"); gfx_x = fx+5; gfx_wrapprint("Circuit bended version of the non-linear WASP, makes for growly resonance, but be careful, is not unconditionally stable!.", wx2); ) : ( filteridx == 36 ) ? ( gfx_printf("Filter: Wasp emulation (linearized)\n\n"); gfx_x = fx+5; gfx_wrapprint("Linearized approximation of the wasp filter.", wx2); ) : ( filteridx == 37 ) ? ( gfx_printf("Filter: Wasp emulation LP\n\n"); gfx_x = fx+5; gfx_wrapprint("Approximation of the wasp filter.", wx2); ) : ( filteridx == 38 ) ? ( gfx_printf("Filter: Wasp emulation BP\n\n"); gfx_x = fx+5; gfx_wrapprint("Approximation of the wasp filter.", wx2); ) : ( filteridx == 39 ) ? ( gfx_printf("Filter: SVF Lowpass filter (ZDF)\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback filter based on Andy Simper's (Cytomic) SVF filter algorithms.", wx2); ) : ( filteridx == 40 ) ? ( gfx_printf("Filter: SVF Bandpass filter (ZDF)\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback filter based on Andy Simper's (Cytomic) SVF filter algorithms.", wx2); ) : ( filteridx == 41 ) ? ( gfx_printf("Filter: SVF Highpass filter (ZDF)\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback filter based on Andy Simper's (Cytomic) SVF filter algorithms.", wx2); ) : ( filteridx == 42 ) ? ( gfx_printf("Filter: SVF Notch filter (ZDF)\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback filter based on Andy Simper's (Cytomic) SVF filter algorithms.", wx2); ) : ( filteridx == 43 ) ? ( gfx_printf("Filter: SVF Peak (ZDF)\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback filter based on Andy Simper's (Cytomic) SVF filter algorithms.", wx2); ) : ( filteridx == 44 ) ? ( gfx_printf("Filter: Everything is a saw (not unconditionally stable!)\n\n"); gfx_x = fx+5; gfx_wrapprint("Weird filter that tends to convert most things to saws. Based on biasing the wasp emulation severely. It can work pretty nicely with basses and high resonance, but be careful, it is pretty unpredictable.", wx2); ) : ( filteridx == 45 ) ? ( gfx_printf("Filter: SVF with waveshaped resonance (ZDF)\n\n"); gfx_x = fx+5; gfx_wrapprint("ZDF filter that lowpasses the signal twice. Once with and once without resonance. Subsequently it waveshapes the version with resonance minus the version without and adds the waveshaped resonance to the no resonance lowpass mix.", wx2); ) : ( filteridx == 46 ) ? ( gfx_printf("Filter: Voodoo\n\n"); gfx_x = fx+5; gfx_wrapprint("This one is a meanie. It filters the signal with and without resonance, computes the difference, amplifies it, saturates it and then adds it to a moving average that gets added to the signal. The result is then waveshaped. Yum.", wx2); ) : ( filteridx == 47 ) ? ( gfx_printf("Filter: Junk (ZDF)\n\n"); gfx_x = fx+5; gfx_wrapprint("This one is fickle. It filters the signal with and without resonance, computes the difference, amplifies it, saturates it and then adds it back to the signal. The result is then waveshaped. Yum.", wx2); ) : ( filteridx == 48 ) ? ( gfx_printf("Filter: Comb\n\n"); gfx_x = fx+5; gfx_wrapprint("Basic comb filter. Set resonance one to have alternating notches between left and right (wide) or zero for mono phasing. Waveshaper is applied before the comb.", wx2); ) : ( filteridx == 49 ) ? ( gfx_printf("Filter: Combed resonance (ZDF)\n\n"); gfx_x = fx+5; gfx_wrapprint("Signal is lowpassed twice with and without resonance. Resonance is lifted by differencing the signal, this resonance is amplified, saturated and mixed with a delayed copy of itself before being added to the signal. Waveshaper is applied after the filter.", wx2); ) : ( filteridx == 50 ) ? ( gfx_printf("Filter: Combed BP (ZDF)\n\n"); gfx_x = fx+5; gfx_wrapprint("Signal is BP passed twice with and without resonance. Resonance is lifted by differencing the signal, this resonance is mixed with a delayed copy of itself before being added to the signal. Waveshaper is applied after the filter. Not nearly as fun as the lowpassed version (previous).", wx2); ) : ( filteridx == 51 ) ? ( gfx_printf("Filter: MS-20 non-linear LP MK ][\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback MS-20 emulation with non-linearity (tanh). This thing sounds great when overdriven, especially without waveshaper. The non-linear elements consist of arctans that saturate at each stage, and a nice diode clipper in the feedback. It can sound raw, yet clean, if that makes sense.", wx2); ) : ( filteridx == 52 ) ? ( gfx_printf("Filter: MS-20 non-linear BP MK ][\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback MS-20 emulation with non-linearity (tanh). This thing sounds great when overdriven, especially without waveshaper. The non-linear elements consist of arctans that saturate at each stage, and a nice diode clipper in the feedback. It can sound raw, yet clean, if that makes sense.", wx2); ) : ( filteridx == 53 ) ? ( gfx_printf("Filter: MS-20 non-linear HP MK ][\n\n"); gfx_x = fx+5; gfx_wrapprint("Zero delay feedback MS-20 emulation with non-linearity (tanh). This thing sounds great when overdriven, especially without waveshaper. The non-linear elements consist of arctans that saturate at each stage, and a nice diode clipper in the feedback. It can sound raw, yet clean, if that makes sense.", wx2); ) : ( filteridx == 54 ) ? ( gfx_printf("Filter: Weeping\n\n"); gfx_x = fx+5; gfx_wrapprint("This is a model of the weeping demon wah pedal, originally modelled by Chet Gnegy and used with permission. Cutoff controls the wah level. Cutoff controls the pre-highpass.", wx2); ) : ( filteridx == 55 ) ? ( gfx_printf("Filter: PWM Potatoes LP\n\n"); gfx_x = fx+5; gfx_wrapprint("Emulation of PWM modulation. Can be used to make scrunchy sounds. Cutoff controls cutoff of the post-PWM filter, resonance controls the oversampling of the pulse generator.", wx2); ) : ( filteridx == 56 ) ? ( gfx_printf("Filter: PWM Potatoes BP\n\n"); gfx_x = fx+5; gfx_wrapprint("Emulation of PWM modulation. Can be used to make scrunchy sounds. Cutoff controls cutoff of the post-PWM filter, resonance controls the oversampling of the pulse generator.", wx2); ) : ( filteridx == 57 ) ? ( gfx_printf("Filter: Bit reduction\n\n"); gfx_x = fx+5; gfx_wrapprint("Bitdepth reduction. Cutoff slider reduces the bitdepth. A filter is run before the bitcrusher which splits off the bass, to add it back later after the bitcrusher. Setting the resonance to zero disables this filter. Note: This thing sounds nice paired with some tanh distortion.", wx2); ) : ( filteridx == 58 ) ? ( gfx_printf("Filter: Muck\n\n"); gfx_x = fx+5; gfx_wrapprint("Muck (tiny bit of multiplicative noise).", wx2); ) : ( filteridx == 59 ) ? ( gfx_printf("Filter: Weeping Demon Mode II\n\n"); gfx_x = fx+5; gfx_wrapprint("This is a model of the weeping demon wah pedal, originally modelled by Chet Gnegy and used with permission. Cutoff controls the wah level. Cutoff controls the pre-highpass. Prone to high resonance peaks.", wx2); ) : ( filteridx == 60 ) ? ( gfx_printf("Crybaby emulation\nEmulation of a wah-wah filter based on a paper by M. Holters, this one took quite some doing to get to work. It's heavy on the CPU, but sounds pretty authentic."); ) : ( filteridx == 61 ) ? ( gfx_printf("Modified Crybaby emulation\nEmulation of a wah-wah filter based on a paper by M. Holters, this one took quite some doing to get to work. It's heavy on the CPU, but sounds pretty authentic."); ) : ( filteridx == 62 ) ? ( gfx_printf("Modified Crybaby emulation\nEmulation of a wah-wah filter based on a paper by M. Holters, this one took quite some doing to get to work. It's heavy on the CPU, but sounds pretty authentic."); ) : ( filteridx == 63 ) ? ( gfx_printf("Vowel filter SVF"); ) : ( filteridx == 64 ) ? ( gfx_printf("Monstro (vowel madness)"); ); ); function initBuffer(scopebuffer_in, scopebuffermax_in) local() global() instance(scopeptr, scopebuffermax, scopebuffer) ( scopeptr = scopebuffer_in; scopebuffer = scopebuffer_in; scopebuffermax = scopebuffermax_in; ); function getBuffer() local() global() instance(scopeptr, scopebuffermax, scopebuffer) ( scopeptr[]; ); function updateBuffer(M) local() global() instance(scopeptr, scopebuffermax, scopebuffer) ( scopeptr[] = M; scopeptr += 1; scopeptr > scopebuffermax ? scopeptr = scopebuffer; M ); function clearBuffer() local() global(MAXBUFFERSIZE) instance(scopeptr, scopebuffermax, scopebuffer) ( scopeptr = scopebuffer; //loop(scopebuffermax - scopebuffer + 1, loop(MAXBUFFERSIZE, scopeptr[] = 0; scopeptr += 1; ); scopeptr = scopebuffer; ); function initBufferNoReset(scopebuffer_in, scopebuffermax_in) local() global() instance(scopeptr, scopebuffermax, scopebuffer) ( scopebuffer = scopebuffer_in; scopebuffermax = scopebuffermax_in; ); function tanh(s) local(c) global() instance() ( c = exp(8*s); s = 0.25*(c - 1) / (c + 1); ); function actual_tanh(x) local(em2x) global() instance() ( em2x = exp(-2*x); (2/(1+em2x))-1 ); function fasttanh(x) local() global() instance() ( x = x / (1 + abs(2*x)); /*( x < -3 ) ? ( x = -1; ) : ( x > 3 ) ? ( x = 1; ) : ( x = x * ( 27 + x * x ) / ( 27 + 9 * x * x ); )*/ // x = (-.0000067436811832+(.2468149110712040+(.0583691066395175+.03357335044280075*x)*x)*x)/(.2464845986383725+(.0609347197060491+(.1086202599228572+.02874707922475963*x)*x)*x); ); //---------------------------------------------- // Filter initialization section //---------------------------------------------- function initRC(freq, q) instance(len, v0, v1, a1, c) local(r) global(srate, slider54) ( c = pow(0.5, (128-freq*128) / 16.0)/ max(slider54,1); r = pow(0.5, (q*128+24) / 16.0); a1 = (1.0-r*c); ); function init303(freq, q) local(dwc, dwc2, dwc3, qwc2, qwc3) global(slider54) instance(wc, wc2, wc3, wc4, A, k, b, g, z0, z1, z2, z3, y1, y2, y3, y4, b0, a0, a1, a2, a3, b10, a10, a11, a12, a13, b20, a20, a21, a22, a23, c2, c3 ) ( // This specific filter came from // Copyright (c) 2012 Dominique Wurtz (www.blaukraut.info) wc = .25 * (pow(10, freq)-1)/9 * $pi / max(slider54,1); wc2 = wc*wc; wc3 = wc2*wc; wc4 = wc3*wc; b = 1 / ( 1 + 8*wc + 20*wc2 + 16*wc3 + 2*wc4); g = 2 * wc4 * b; k = 20*q; A = 1 + 0.5 * k; dwc = 2*wc; dwc2 = 2*wc2; qwc2 = 4*wc2; dwc3 = 2*wc3; qwc3 = 4*wc3; b0 = dwc+12*wc2+20*wc3+8*wc4; a0 = 1+6*wc+10*wc2+qwc3; a1 = dwc+8*wc2+6*wc3; a2 = dwc2+wc3; a3 = dwc3; b10 = dwc2+8*wc3+6*wc4; a10 = wc+4*wc2+3*wc3; a11 = 1+6*wc+11*wc2+6*wc3; a12 = wc+qwc2+qwc3; a13 = wc2+dwc3; b20 = dwc3+4*wc4; a20 = a13; a21 = wc+qwc2+4*wc3; a22 = 1+6*wc+10*wc2+qwc3; a23 = wc+qwc2+dwc3; c2 = a21 - a3; c3 = 1+6*wc+9*wc2+dwc3; ); function reset303() local(Kbig) global(slider54) instance(wc, wc2, wc3, wc4, A, k, b, g, z0, z1, z2, z3, y1, y2, y3, y4, b0, a0, a1, a2, a3, b10, a10, a11, a12, a13, b20, a20, a21, a22, a23, c2, c3 ) ( z1 = z2 = z3 = 0; y1 = y2 = y3 = y4 = 0; ); function initmoog(freq, q) local(f, t, t2, cutoff, res) global(slider54) instance(r, p, k, oldx, oldy1, oldy2, oldy3, y1, y2, y3, y4) ( cutoff = pow(0.5, (128-freq*128) / 16.0)/ max(slider54,1); res = .1 * q; f = (cutoff+cutoff); p = f*(1.8-0.8*f); k = 2.0 * sin(cutoff * $pi * 0.5) - 1.0; t = (1.-p)*1.386249; t2 = 12.+t*t; r = res*(t2+6.*t)/(t2-6.*t); ); function resetmoog() local(f, t, t2, cutoff, res) global(slider54) instance(r, p, k, oldx, oldy1, oldy2, oldy3, y1, y2, y3, y4) ( oldy1=oldy2=oldy3=y1=y2=y3=y4=oldx=0; ); // Karlsen Fast Ladder III // Ove Hy Karlsen function initkarlsen(freq, res) local(f, t, t2, cutoff, res) global(slider54) instance(b_fres, b_fenv, b_aflt1, b_aflt2, b_aflt3, b_aflt4) ( b_fenv = pow(0.5, (128-freq*128) / 16.0)/ max(slider54,1); b_fres = 4 * res; ); function resetkarlsen() local(f, t, t2, cutoff, res) global(slider54) instance(b_fres, b_fenv, b_aflt1, b_aflt2, b_aflt3, b_aflt4, b_lfcut, b_lf, b_lf1hp, b_lfhp, b_lfgain) ( b_aflt1 = b_aflt2 = b_aflt3 = b_aflt4 = 0; ); // Karlsen Fast Ladder III // Ove Hy Karlsen function initkarlsen_sat(freq, res) local(f, t, t2, cutoff, res) global(slider54) instance(b_fres, b_fenv, b_aflt1, b_aflt2, b_aflt3, b_aflt4, b_lfcut, b_lf, b_lf1hp, b_lfhp, b_lfgain) ( b_fenv = pow(0.5, (128-freq*128) / 16.0)/ max(slider54,1); b_fres = 4 * res; ); function resetkarlsen_sat() local(f, t, t2, cutoff, res) global(slider54) instance(b_fres, b_fenv, b_aflt1, b_aflt2, b_aflt3, b_aflt4, b_lfcut, b_lf, b_lf1hp, b_lfhp, b_lfgain) ( b_aflt1 = b_aflt2 = b_aflt3 = b_aflt4 = b_lfcut = b_lf = b_lf1hp = b_lfhp = b_lfgain = 0; ); function initdualfilt(freq, res) local(q) global(slider54) instance(fb, f, d0, d1) ( f = (pow(10, freq)-1)/9 * $pi / (max(1,slider54)); q = res; //set feedback amount given f and q between 0 and 1 fb = q + q/(1.0 - f); fb = max(0, min(4, fb)); ); function resetdualfilt() local(q) global(slider54) instance(fb, f, d0, d1) ( d0 = d1 = 0.0000001; ); function initfancymoog(freq, q) local(S0, S1, S2, S3, S4, F1, F2, F3, F4, WS0, WS1, WS2, WS3, WS4, gJ0, gJ1, gJ2, gJ3, gJ4, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, A0_0_0, A0_0_1, A0_0_2, A0_0_3, A0_1_0, A0_1_1, A0_1_2, A0_1_3, A0_2_0, A0_2_1, A0_2_2, A0_2_3, A0_3_0, A0_3_1, A0_3_2, A0_3_3, VT, fs ) global(srate, slider54, tmp) instance(A, k, omega, hA, g, wc, wcT, T, y0, y1, y2, y3, y4, d0, d1, d2, d3, d4, ftarget) ( fs = max(slider54,1) * srate; //ftarget = 24*(pow(10, freq)-1)/9; //24 ftarget = .5*(srate/1000)*(pow(10, freq)-1)/9; //ftarget = 6*freq; VT = 26/1000; A = 0.5 * VT; hA = 0.5 * A; T = 1.0/fs; wc = 4*$pi*ftarget*srate; wcT = wc*T; g = wcT*hA; k = 1.1*q*4; // [0..4] ); function resetfancymoog() local() global() instance(A, k, omega, hA, g, wc, wcT, T, y0, y1, y2, y3, y4, d0, d1, d2, d3, d4) ( y0 = y1 = y2 = y3 = y4 = d0 = d1 = d2 = d3 = d4 = 0; ); function bootvowel() instance() local(c, ptr) global(vowel_src, vowel_A, vowel_E, vowel_I, vowel_O, vowel_U, vowel_EE) ( c = vowel_src; c[0] = vowel_A; c[1] = vowel_E; c[2] = vowel_I; c[3] = vowel_O; c[4] = vowel_U; c[5] = vowel_EE; // 34 39 57 ptr = vowel_A; ptr[] = 660; ptr += 1; ptr[] = 1700; ptr += 1; ptr[] = 2400; ptr += 1; ptr[] = 2^(0/6); ptr += 1; // gain ptr[] = 2^(-15/6); ptr += 1; // gain ptr[] = 2^(-15/6); ptr += 1; // gain ptr[] = 5; ptr += 1; // Q ptr[] = 20; ptr += 1; // Q ptr[] = 20; ptr += 1; // Q ptr = vowel_E; ptr[] = 530; ptr += 1; ptr[] = 1850; ptr += 1; ptr[] = 2500; ptr += 1; ptr[] = 2^(0/6); ptr += 1; // gain ptr[] = 2^(-15/6); ptr += 1; // gain ptr[] = 2^(-9/6); ptr += 1; // gain ptr[] = 5; ptr += 1; // Q ptr[] = 20; ptr += 1; // Q ptr[] = 50; ptr += 1; // Q ptr = vowel_I; ptr[] = 400; ptr += 1; ptr[] = 2000; ptr += 1; ptr[] = 2550; ptr += 1; ptr[] = 2^(0/6); ptr += 1; // gain ptr[] = 2^(-15/6); ptr += 1; // gain ptr[] = 2^(-9/6); ptr += 1; // gain ptr[] = 5; ptr += 1; // Q ptr[] = 20; ptr += 1; // Q ptr[] = 50; ptr += 1; // Q ptr = vowel_O; ptr[] = 300; ptr += 1; ptr[] = 870; ptr += 1; ptr[] = 2250; ptr += 1; ptr[] = 2^(0/6); ptr += 1; // gain ptr[] = 2^(-15/6); ptr += 1; // gain ptr[] = 2^(-9/6); ptr += 1; // gain ptr[] = 5; ptr += 1; // Q ptr[] = 20; ptr += 1; // Q ptr[] = 50; ptr += 1; // Q ptr = vowel_U; ptr[] = 640; ptr += 1; ptr[] = 1200; ptr += 1; ptr[] = 2400; ptr += 1; ptr[] = 2^(0/6); ptr += 1; // gain ptr[] = 2^(-11/6); ptr += 1; // gain ptr[] = 2^(-13/6); ptr += 1; // gain ptr[] = 9; ptr += 1; // Q ptr[] = 10; ptr += 1; // Q ptr[] = 20; ptr += 1; // Q ptr = vowel_EE; // These are correct ptr[] = 207; ptr += 1; // freq ptr[] = 2300; ptr += 1; // freq ptr[] = 3000; ptr += 1; // freq ptr[] = 2^(0/6); ptr += 1; // gain ptr[] = 2^(-15/6); ptr += 1; // gain ptr[] = 2^(-9/6); ptr += 1; // gain ptr[] = 5; ptr += 1; // Q ptr[] = 20; ptr += 1; // Q ptr[] = 50; ptr += 1; // Q ); function rfn(q,qq) ( q * (1+2*qq); ); function resetvowel() instance( c, amp1, amp2, amp3, Ab0, Ab1, Ab2, Aa1, Aa2, Bb0, Bb1, Bb2, Ba1, Ba2, Cb0, Cb1, Cb2, Ca1, Ca2, d1x, d2x, d1yA, d2yA, d1yB, d2yB, d1yC, d2yC ) local(out, outA, outB, outC) global() ( d2x = d1x = 0; d2yA = d1yA = 0; d2yB = d1yB = 0; d2yC = d1yC = 0; ); function initvowel(freq, qin) instance( c, amp1, amp2, amp3, Ab0, Ab1, Ab2, Aa1, Aa2, Bb0, Bb1, Bb2, Ba1, Ba2, Cb0, Cb1, Cb2, Ca1, Ca2, d1x, d2x, d1yA, d2yA, d1yB, d2yB, d1yC, d2yC ) local(ampfac, idx, ptr, loc, rloc, fact, fr1, fr2, fr3, q1, q2, q3, w0, cw, sw, alpha, a0, a0i, Q ) global(slider54, srate, rfn, vowel_src) ( c = vowel_src; loc = 5 * freq; idx = floor( loc - 0.0001 ); rloc = loc-idx; rloc = 1.0 - rloc; fact = 2 * $pi / ( srate * ( max(1,slider54) ) ); ampfac = 6; ptr = c[idx]; fr1 = ptr[]*rloc; ptr+=1; fr2 = ptr[]*rloc; ptr+=1; fr3 = ptr[]*rloc; ptr+=1; amp1 = ampfac*ptr[]*rloc; ptr+=1; amp2 = ampfac*ptr[]*rloc; ptr+=1; amp3 = ampfac*ptr[]*rloc; ptr+=1; q1 = ptr[]*rloc; ptr+=1; q2 = ptr[]*rloc; ptr+=1; q3 = ptr[]*rloc; ptr+=1; ptr = c[idx+1]; rloc = 1 - rloc; fr1 += ptr[]*rloc; ptr+=1; fr2 += ptr[]*rloc; ptr+=1; fr3 += ptr[]*rloc; ptr+=1; amp1 += ampfac*ptr[]*rloc; ptr+=1; amp2 += ampfac*ptr[]*rloc; ptr+=1; amp3 += ampfac*ptr[]*rloc; ptr+=1; q1 += ptr[]*rloc; ptr+=1; q2 += ptr[]*rloc; ptr+=1; q3 += ptr[]*rloc; ptr+=1; // Biquads RBJ BP Q = rfn(q1, qin); w0 = fr1 * fact; cw = cos(w0); sw = sin(w0); alpha = 0.5 * sw / Q; a0 = 1 + alpha; a0i = 1 / a0; Ab0 = alpha*a0i; Ab1 = 0; Ab2 = - alpha*a0i; Aa1 = - (2 * cw)*a0i; Aa2 = (1 - alpha)*a0i; Q = rfn(q2, qin); w0 = fr2 * fact; cw = cos(w0); sw = sin(w0); alpha = 0.5 * sw / Q; a0 = 1 + alpha; a0i = 1 / a0; Bb0 = alpha*a0i; Bb1 = 0; Bb2 = - alpha*a0i; Ba1 = - (2 * cw)*a0i; Ba2 = (1 - alpha)*a0i; Q = rfn(q3, qin); w0 = fr3 * fact; cw = cos(w0); sw = sin(w0); alpha = 0.5 * sw / Q; a0 = 1 + alpha; a0i = 1 / a0; Cb0 = alpha*a0i; Cb1 = 0; Cb2 = - alpha*a0i; Ca1 = - (2 * cw)*a0i; Ca2 = (1 - alpha)*a0i; ); // Biquads RBJ Notch function initnotch(freq, q) instance( c, b0, b1, b2, a1, a2, d1x, d2x, d1y, d2y ) local( out, w0, cw, sw, alpha, a0, a0i ) global(srate, slider54) ( w0 = (pow(10, freq)-1)/9 * $pi / max(slider54,1); q = q*0.9 + .1; cw = cos(w0); sw = sin(w0); alpha = 0.5 * sw / q; a0 = 1 + alpha; a0i = 1 / a0; b0 = 1 * a0i; b1 = -2 * cw * a0i; b2 = a0i; a1 = -2 * cw * a0i; a2 = (1 - alpha) * a0i; ); function initsai0(freq, qin) instance( c, amp1, amp2, amp3, Ab0, Ab1, Ab2, Aa1, Aa2, Bb0, Bb1, Bb2, Ba1, Ba2, Cb0, Cb1, Cb2, Ca1, Ca2, d1x, d2x, d1yA, d2yA, d1yB, d2yB, d1yC, d2yC ) local(idx, ptr, fact, w0, w0c, cw, sw, alpha, a0, a0i, Q, qav, fact ) global(slider54, srate, rfn) ( fact = 1 / max(slider54,1); w0c = .1*(pow(10, freq)-1)/9 * $pi * fact + .025*5*fact; qav = qin*1.5 + .5; amp1 = 1; amp2 = 1; amp3 = 1; // Biquads RBJ BP Q = qav*8; w0 = w0c; cw = cos(w0); sw = sin(w0); alpha = 0.5 * sw / Q; a0 = 1 + alpha; a0i = 1 / a0; Ab0 = alpha*a0i; Ab1 = 0; Ab2 = - alpha*a0i; Aa1 = - (2 * cw)*a0i; Aa2 = (1 - alpha)*a0i; Q = qav*12; w0 = w0c*2; cw = cos(w0); sw = sin(w0); alpha = 0.5 * sw / Q; a0 = 1 + alpha; a0i = 1 / a0; Bb0 = alpha*a0i; Bb1 = 0; Bb2 = - alpha*a0i; Ba1 = - (2 * cw)*a0i; Ba2 = (1 - alpha)*a0i; Q = qav*12; w0 = w0c/2; cw = cos(w0); sw = sin(w0); alpha = 0.5 * sw / Q; a0 = 1 + alpha; a0i = 1 / a0; Cb0 = alpha*a0i; Cb1 = 0; Cb2 = - alpha*a0i; Ca1 = - (2 * cw)*a0i; Ca2 = (1 - alpha)*a0i; ); function resetsai0() global() instance( c, amp1, amp2, amp3, Ab0, Ab1, Ab2, Aa1, Aa2, Bb0, Bb1, Bb2, Ba1, Ba2, Cb0, Cb1, Cb2, Ca1, Ca2, d1x, d2x, d1yA, d2yA, d1yB, d2yB, d1yC, d2yC ) local( ) ( c = amp1 = amp2 = amp3 = Ab0 = Ab1 = Ab2 = Aa1 = Aa2 = Bb0 = Bb1 = Bb2 = Ba1 = Ba2 = Cb0 = Cb1 = Cb2 = Ca1 = Ca2 = d1x = d2x = d1yA = d2yA = d1yB = d2yB = d1yC = d2yC = 0; ); function initmodulator(freq, qin) instance( c, Ab0, Ab1, Ab2, Aa1, Aa2, Bb0, Bb1, Bb2, Ba1, Ba2 d1x, d2x, d1yA, d2yA, d1yB, d2yB, amp ) local(idx, ptr, fact, w0, w0c, cw, sw, alpha, a0, a0i, Q, qav, fact ) global(slider54, srate, rfn) ( fact = 1 / (max(slider54,1)); w0c = .1*(pow(10, freq)-1)/9 * $pi * fact + .25*fact; Q = qin*15 + 20; amp = qin*2; // Biquads RBJ BP w0 = w0c; cw = cos(w0); sw = sin(w0); alpha = 0.5 * sw / Q; a0 = 1 + alpha; a0i = 1 / a0; Ab0 = Q * alpha * a0i; Ab1 = 0 * a0i; Ab2 = - alpha * Q * a0i; Aa1 = -2 * cw * a0i; Aa2 = (1 - alpha) * a0i; Q = 5+qin*15; fact = $pi / ( srate * ( max(1,slider54) ) ); w0 = w0c*.25; cw = cos(w0); sw = sin(w0); alpha = 0.5 * sw / Q; a0 = 1 + alpha; a0i = 1 / a0; Bb0 = 0.5*(1-cw)*a0i; Bb1 = (1-cw)*a0i; Bb2 = 0.5*(1-cw)*a0i; Ba1 = -2*cw*a0i; Ba2 = (1 - alpha)*a0i; ); function resetmodulator() global() local() instance( c, Ab0, Ab1, Ab2, Aa1, Aa2, Bb0, Bb1, Bb2, Ba1, Ba2, d1x, d2x, d1yA, d2yA, d1yB, d2yB, amp ) ( c = Ab0 = Ab1 = Ab2 = Aa1 = Aa2 = Bb0 = Bb1 = Bb2 = Ba1 = Ba2 = d1x = d2x = d1yA = d2yA = d1yB = d2yB = amp = 0; ); function initphaserOTA(freq, reso) global(slider54) local(Rf, g) instance(C1, C2, dw, dx, sq) ( Rf = 25/1000; g = 1 - exp( - $pi * ( freq / max(slider54,1) ) ); sq = .2*reso; // Rf = R1*Vt/R2 C1 = Rf * g; C2 = - 1 / Rf; ); function resetphaserOTA() global() local() instance(C1, C2, dw, dx, sq) ( dw = dx = 0; ); // Trapezoidal integrator function TPT_step(g, x) local() global() instance(s, y) ( y = g * x + s; s = y + g * x; y; ); function init_MS20lin(freq, reso) global(slider54) local(fg, invTerm, smallg, Gsq, norm) instance(a0, a1, a2, s1, s2, G, k) ( // fg = 1 - exp( - $pi * ( freq / max(slider54,1) ) ); smallg = .5 * (pow(10, freq)-1)/9 * $pi / max(slider54,1); k = 2*reso; invTerm = 1.0 / ( 1.0 + smallg ); G = smallg * invTerm; Gsq = G*G; norm = 1.0 / ( 1.0 + Gsq * k - G * k ); a0 = Gsq * norm; a1 = G * norm; a2 = norm; ); function reset_MS20lin() global() local() instance(a0, a1, a2, s1, s2, G, k) ( s1 = s2 = 0; ); function init_MS20(freq, reso) global(slider54) local(fg, invTerm) instance(s1, s2, G, Gsq, Gsqk, Gk, k, smallg) ( // fg = 1 - exp( - $pi * ( freq / max(slider54,1) ) ); smallg = .5 * (pow(10, freq)-1)/9 * $pi / max(slider54,1); k = 2*reso; invTerm = 1.0 / ( 1.0 + smallg ); G = smallg * invTerm; Gsq = G*G; Gsqk = Gsq * k; Gk = G*k; ); function init_ssm_nonlin(freq, reso) global(slider54, srate) local(h, K1, KOTA, C, dG, R, wrel) instance(hh, itau, K2, hhitau, f, rate, Kout) ( rate = srate * max(slider54,1); h = 1.0 / rate; // Prewarping wrel = 2 * $pi * 22050 * ( ( pow(10, freq) - 1 ) / 9 ); f = 20 * rate * tan( .5 * wrel * h ); dG = f; KOTA = .00192; R = 10000; K1 = 50; Kout = 1; K2 = 5 * reso; hh = 0.5 * h; itau = KOTA*K1*dG; hhitau = hh * itau; ); function reset_ssm_nonlin() global() local() instance(hh, itau, K2, hhitau, U0, U1, U2, U3, D0, D1, D2, D3, Di, Kout) ( D0 = D1 = D2 = D3 = Di = 0; ); function init_cem_nonlin(freq, reso) global(slider54, srate) local(h, K1, KOTA, C1, C2, dG1, dG2, R, wrel) instance(hh, itau, itau2, K2, hhitau, hhitau2, f, rate, Kout, res) ( rate = srate * max(slider54,1); h = 1.0 / rate; // Prewarping wrel = 2 * $pi * 22050 * ( ( pow(10, freq) - 1 ) / 9 ); f = 20 * rate * tan( .5 * wrel * h ); dG1 = f; dG2 = f * 75; KOTA = .00192; R = 10000; K1 = 50; Kout = 1; res = .5*reso; K2 = res * 20; hh = 0.5 * h; itau = KOTA*K1*dG1; itau2 = KOTA*K1*dG2; hhitau = hh * itau; hhitau2 = hh * itau2; ); function reset_cem_nonlin() global() local() instance(hh, itau, K2, hhitau, hhitau2, itau2, U0, U1, U2, U3, D0, D1, D2, D3, Di, Kout, res, ifdbk) ( D0 = D1 = D2 = D3 = Di = 0; ); function init_ssm_lin(freq, reso) global(slider54, srate) local(h, K1, KOTA, C, dG, R, wrel, rate, f, hh, hh2, hh3, hh4, itau, itau2, itau3, itau4) instance(x0, x1, x15, x2, x6, x7, x11, x13, x14, K2) ( rate = srate * max(slider54,1); h = 1.0 / rate; // Prewarping wrel = 2 * $pi * 22050 * ( ( pow(10, freq) - 1 ) / 9 ); f = 20 * rate * tan( .5 * wrel * h ); dG = f; KOTA = .00192; R = 10000; K1 = 50; K2 = 3*reso; hh = 0.5*h; itau = KOTA*K1*dG; itau2 = itau*itau; itau3 = itau2*itau; itau4 = itau2*itau2; hh2 = hh*hh; hh3 = hh*hh2; hh4 = hh2*hh2; x0 = hh*itau; x1 = x0 + 1; x15 = x1*x1*x1; x2 = 1/(K2*hh4*itau4 + x15*x1); x6 = hh3*itau3; x7 = K2*x6; x11 = x0*x1*x1; x13 = hh2*itau2*x1; x14 = K2*x13; ); function reset_ssm_lin() global() local() instance(x0, x1, x15, x2, x6, x7, x11, x13, x14, x16, Di, D0, D1, D2, D3, U0, U1, U2, U3, K2) ( D0 = D1 = D2 = D3 = Di = 0; ); function init_cem_lin(freq, reso) global(slider54, srate) local(rate, f, h, hh, hh2, hh3, hh4, itau, itau2, hhitau, hhitau2, K1, KOTA, C1, C2, dG1, dG2, R, wrel) instance(res, x0, x1, x2, x3, x4, x5, x6, x11, x12, x13, x14, x15, x19, x27, x22, x23, x28, hh2, hh3, K2 ) ( rate = srate * max(slider54,1); h = 1.0 / rate; // Prewarping wrel = 2 * $pi * 22050 * ( ( pow(10, freq) - 1 ) / 9 ); f = 20 * rate * tan( .5 * wrel * h ); dG1 = f; dG2 = f * 75; KOTA = .00192; R = 10000; K1 = 50; res = .25*reso; K2 = res * 20; hh = 0.5*h; itau = KOTA*K1*dG1; itau2 = KOTA*K1*dG2; hh2 = hh*hh; hh3 = hh*hh2; hh4 = hh2*hh2; x0 = K2*itau*itau*itau; x1 = hh*itau2; x2 = x1 + 1; x3 = hh*itau; x4 = x3 + 1; x5 = x4*x4*x4; x6 = 1/(hh4*itau2*x0 + x2*x5); x11 = itau2*hh3; x12 = itau*itau; x13 = K2*x12; x14 = x11*x13; x15 = x4*x4; x19 = K2*x3; x27 = x15*x2; x22 = hh2*x4; x23 = itau*itau2*x22; x28 = x2*x3*x4; ); function reset_cem_lin() global() local() instance(K2, res, x0, x1, x2, x3, x4, x5, x6, x11, x12, x13, x14, x15, x19, x27, x22, x23, x28, hh2, hh3, D0, D1, D2, D3, U0, U1, U2, U3, Di) ( D0 = D1 = D2 = D3 = Di = 0; ); function init_MS20_nonlin(freq, reso) global(slider54) local() instance(y1, y2, d1, d2, h, hh, k, f) ( f = .5 * (pow(10, freq)-1)/9 * $pi; h = f / max(slider54,1); hh = 0.5 * h; k = 2*reso; ); function init_MS20_nonlin_2(freq, reso) global(slider54) local() instance(y1, y2, d1, d2, h, hh, k, f) ( f = (pow(10, freq)-1)/9 * $pi; h = f / max(slider54,1); hh = 0.5 * h; k = 2*reso; ); function reset_MS20_nonlin() global() local() instance(y1, y2, d1, d2, h, hh, k, f) ( d1 = d2 = 0; ); function resetrbj(sample) instance( c, b0, b1, b2, a1, a2, d1x, d2x, d1y, d2y ) local() global() ( c = b0 = b1 = b2 = a1 = a2 = d1x = d2x = d1y = d2y = 0; ); function initphaserFET(freq, reso) global(srate, slider54) local(IDSS, Vt, Vp, Fs, Vg, Rp, Q1, g ) instance(C1, C2, dw, dx, thresh, iVpsq, IDSSdivVpSq, thresh) ( /*IDSS = .001; // 1 mA Vt = 0.025; // 25mV Vp = -3; Vg = - 2 - reso; Rp = 1; // ? iVpsq = 1 / (Vp * Vp); Q1 = 2 * IDSS * (Vg-Vt) * iVpsq; C2 = 1 / Rp; g = 1 - exp( - 2 * $pi * freq/max(slider54,1) ); thresh = Vg - Vp; IDSSdivVpSq = IDSS * iVpsq; // We seek C1. // Q1*C1 - C2*C1 = g; Eq. 24 from the paper C1 = g / (Q1-C2);*/ C1=.5*freq/max(1,slider54);C2=1; ); function initSine(f, r) global(srate, slider54) local() instance(freq, res, fraw) ( freq = 80 * $pi * ( ( pow(10, f) - 1 ) / 9 ); res = r; fraw = f; ); function init_linearSVF(freq, res) global(srate, slider54) local(g, fn) instance(ic1eq, ic2eq, k, a1, a2, a3) ( fn = ( ( pow(10, freq) - 1 ) / 9 ); g = tan(.5 * $pi * fn / max(slider54,1)); k = 2 - 2*res; a1 = 1/(1+g*(g+k)); a2 = g*a1; a3 = g*a2; ); function init_linearSVF_direct(freq, res) global(srate, slider54) local(g, fn) instance(ic1eq, ic2eq, k, a1, a2, a3) ( fn = freq; g = tan(.5 * $pi * fn / max(slider54,1)); k = 2 - 2*res; a1 = 1/(1+g*(g+k)); a2 = g*a1; a3 = g*a2; ); function reset_linearSVF() global() local() instance(ic1eq, ic2eq, k, a1, a2, a3) ( ic1eq = ic2eq = 0; ); function initvowelSVF(freq, qin) instance( c, svf1, svf2, svf3, svf4, svf5, svf6, amp1, amp2, amp3, fr1, fr2, fr3, q1, q2, q3 ) local(loc, idx, rloc, fact, ampfac, sr, sq, ptr) global(vowel_src) ( c = vowel_src; loc = 5 * freq; idx = floor( loc - 0.0001 ); rloc = loc-idx; rloc = 1.0 - rloc; sr = 1/22050; sq = .02; ampfac = .1; ptr = c[idx]; fr1 = ptr[]*rloc; ptr+=1; fr2 = ptr[]*rloc; ptr+=1; fr3 = ptr[]*rloc; ptr+=1; amp1 = ampfac*ptr[]*rloc; ptr+=1; amp2 = ampfac*ptr[]*rloc; ptr+=1; amp3 = ampfac*ptr[]*rloc; ptr+=1; q1 = ptr[]*rloc; ptr+=1; q2 = ptr[]*rloc; ptr+=1; q3 = ptr[]*rloc; ptr+=1; ptr = c[idx+1]; rloc = 1 - rloc; fr1 += ptr[]*rloc; ptr+=1; fr2 += ptr[]*rloc; ptr+=1; fr3 += ptr[]*rloc; ptr+=1; amp1 += ampfac*ptr[]*rloc; ptr+=1; amp2 += ampfac*ptr[]*rloc; ptr+=1; amp3 += ampfac*ptr[]*rloc; ptr+=1; q1 += ptr[]*rloc; ptr+=1; q2 += ptr[]*rloc; ptr+=1; q3 += ptr[]*rloc; ptr+=1; fr1 = fr1 * sr; fr2 = fr2 * sr; fr3 = fr3 * sr; q1 = 1-sqrt(q1)*sq; q2 = 1-sqrt(q2)*sq; q3 = 1-sqrt(q3)*sq; q1 = q1 * (.7+.28*qin); q2 = q2 * (.7+.28*qin); q3 = q3 * (.7+.28*qin); this.svf1.init_linearSVF_direct(fr1, q1); this.svf2.init_linearSVF_direct(fr2, q2); this.svf3.init_linearSVF_direct(fr3, q3); this.svf4.init_linearSVF_direct(fr1, q1); this.svf5.init_linearSVF_direct(fr2, q2); this.svf6.init_linearSVF_direct(fr3, q3); ); function resetvowelSVF() instance( c, svf1, svf2, svf3, svf4, svf5, svf6, amp1, amp2, amp3 ) local(loc, idx, rloc, fact, ampfac, ptr, fr1, fr2, fr3, q1, q2, q3) global() ( this.svf1.reset_linearSVF(); this.svf2.reset_linearSVF(); this.svf3.reset_linearSVF(); this.svf4.reset_linearSVF(); this.svf5.reset_linearSVF(); this.svf6.reset_linearSVF(); ); function init_wasp_nonlin(freq, res) local(a, h) global(slider54, srate) instance(nl, hah, hahnl, rate, wrel, f, r, offset) ( rate = srate * max(slider54,1); h = 1.0 / rate; // Prewarping offset = 0.01; wrel = 2 * $pi * 22050 * ( ( pow(10, freq) - 1 ) / 9 ); f = 40 * rate * tan( .5 * wrel * h ); r = .8-.6*res; nl = .35; a = .08 * f; hah = .5*a*h; hahnl = hah*nl; ); function reset_wasp_nonlin() global() local() instance(nl, hah, hahnl, D2, D1, Di, r, offset) ( Di = D1 = D2 = 0; ); function init_wasp_nonlin_saw(freq, res) local(a, h) global(slider54, srate) instance(nl, hah, hahnl, rate, wrel, f, r, offset) ( rate = srate * max(slider54,1); h = 1.0 / rate; // Prewarping offset = .4+res*.4; wrel = 2 * $pi * 22050 * ( ( pow(10, freq) - 1 ) / 9 ); f = 40 * rate * tan( .5 * wrel * h ); r = .8-.6*res; nl = .35; a = .08 * f; hah = .5*a*h; hahnl = hah*nl; ); function reset_wasp_nonlin_saw() global() local() instance(nl, hah, hahnl, D2, D1, Di, r, offset) ( Di = D1 = D2 = 0; ); function clamp(x) ( x = 0.8 * x; y = 0.5 * (abs(x + 1) - abs(x - 1)); x = y + .3*(x-y); //x = 1.5 * x - 0.5 * x * x * x; x = 1.25 * x; ); function Dclamp(x) ( 1 ); function eval_wasp_nonlin_extrareso(Vi) local(idet, Ja, Jb, Jc, tv1nl, tv2nl, ttd1nl, td1nl, td2nl, shrterm, fixterm, clterm, clterm2, V1, V2, f0, f1, resclamp) instance(nl, hah, hahnl, D2, D1, Di, r, offset) global() ( Vi = clamp(Vi); offset = 0.1; tv1nl = tanh(V1*nl+offset); tv2nl = tanh(V2*nl+offset); td1nl = fasttanh(D1*nl+offset); td2nl = fasttanh(D2*nl+offset); ttd1nl = tanh(td1nl); fixterm = fasttanh(fasttanh(nl*(Di + clamp(-r*td1nl) - td2nl))); loop(3, resclamp= clamp(-r*tv1nl); clterm = fasttanh(nl*(Vi + resclamp - tv2nl)); clterm2 = fasttanh(clterm); f0 = -D1 + V1 - hah*(fixterm + clterm2); f1 = -D2 + V2 - hah*(ttd1nl + tanh(tv1nl)); shrterm = hahnl*nl*(1-clterm*clterm)*(1-clterm2*clterm2); Jb = shrterm*(1-tv2nl*tv2nl); Ja = r*shrterm*(1-tv1nl*tv1nl)*Dclamp(-r*tv1nl) + 1; Jc = -hahnl*(1-tv1nl*tv1nl)*(1-tv1nl*tv1nl); idet = 1.0 / (Ja - Jb*Jc); V1 = V1 - (-Jb*f1 + f0)*idet; V2 = V2 - (Ja*f1 - Jc*f0)*idet; tv1nl = fasttanh(V1*nl)*(1-.8*V2); tv2nl = tanh(V2*nl); ); // Forced to do this to keep things stable :( V1 = clamp(V1); V2 = clamp(V2); Di = Vi; D1 = V1; D2 = V2; -V2; ); function eval_wasp_nonlin_realatanh(Vi) local(idet, Ja, Jb, Jc, tv1nl, tv2nl, ttd1nl, td1nl, td2nl, shrterm, fixterm, clterm, clterm2, V1, V2, f0, f1, resclamp) instance(nl, hah, hahnl, D2, D1, Di, r, offset) global() ( Vi = clamp(Vi); tv1nl = tanh(V1*nl+offset); tv2nl = tanh(V2*nl+offset); td1nl = tanh(D1*nl+offset); td2nl = tanh(D2*nl+offset); ttd1nl = tanh(td1nl); fixterm = tanh(fasttanh(nl*(Di + clamp(-r*td1nl) - td2nl))); loop(3, resclamp= clamp(-r*tv1nl); clterm = tanh(nl*(Vi + resclamp - tv2nl)); clterm2 = fasttanh(clterm); f0 = -D1 + V1 - hah*(fixterm + clterm2); f1 = -D2 + V2 - hah*(ttd1nl + tanh(tv1nl)); shrterm = hahnl*nl*(1-clterm*clterm)*(1-clterm2*clterm2); Jb = shrterm*(1-tv2nl*tv2nl); Ja = r*shrterm*(1-tv1nl*tv1nl)*Dclamp(-r*tv1nl) + 1; Jc = -hahnl*(1-tv1nl*tv1nl)*(1-tv1nl*tv1nl); idet = 1.0 / (Ja - Jb*Jc); V1 = V1 - (-Jb*f1 + f0)*idet; V2 = V2 - (Ja*f1 - Jc*f0)*idet; tv1nl = tanh(V1*nl); tv2nl = tanh(V2*nl); ); // Forced to do this to keep things stable :( V1 = clamp(V1); V2 = clamp(V2); Di = Vi; D1 = V1; D2 = V2; -V2; ); function eval_wasp_nonlin_expensive(Vi) local(idet, Ja, Jb, Jc, tv1nl, tv2nl, ttd1nl, td1nl, td2nl, shrterm, fixterm, clterm, clterm2, V1, V2, f0, f1, resclamp) instance(nl, hah, hahnl, D2, D1, Di, r, offset) global() ( Vi = clamp(Vi); tv1nl = tanh(V1*nl+offset); tv2nl = tanh(V2*nl+offset); td1nl = fasttanh(D1*nl+offset); td2nl = fasttanh(D2*nl+offset); ttd1nl = tanh(td1nl); fixterm = fasttanh(fasttanh(nl*(Di + clamp(-r*td1nl) - td2nl))); loop(3, resclamp= clamp(-r*tv1nl); clterm = fasttanh(nl*(Vi + resclamp - tv2nl)); clterm2 = fasttanh(clterm); f0 = -D1 + V1 - hah*(fixterm + clterm2); f1 = -D2 + V2 - hah*(ttd1nl + fasttanh(tv1nl)); shrterm = hahnl*nl*(1-clterm*clterm)*(1-clterm2*clterm2); Jb = shrterm*(1-tv2nl*tv2nl); Ja = r*shrterm*(1-tv1nl*tv1nl)*Dclamp(-r*tv1nl) + 1; Jc = -hahnl*(1-tv1nl*tv1nl)*(1-tv1nl*tv1nl); idet = 1.0 / (Ja - Jb*Jc); V1 = V1 - (-Jb*f1 + f0)*idet; V2 = V2 - (Ja*f1 - Jc*f0)*idet; tv1nl = fasttanh(V1*nl); tv2nl = tanh(V2*nl); ); // Forced to do this to keep things stable :( V1 = clamp(V1); V2 = clamp(V2); Di = Vi; D1 = V1; D2 = V2; -V2; ); // Checked for effect of tanh vs true_tanh function eval_wasp_nonlin(Vi) local(idet, Ja, Jb, Jc, tv1nl, tv2nl, ttd1nl, td1nl, td2nl, shrterm, fixterm, clterm, clterm2, V1, V2, f0, f1, resclamp) instance(nl, hah, hahnl, D2, D1, Di, r, offset) global() ( Vi = clamp(Vi); tv1nl = fasttanh(V1*nl+offset); tv2nl = fasttanh(V2*nl+offset); td1nl = fasttanh(D1*nl+offset); td2nl = fasttanh(D2*nl+offset); ttd1nl = tanh(td1nl); fixterm = fasttanh(nl*(Di + clamp(-r*td1nl) - td2nl)); // fasttanh ignored loop(3, resclamp= clamp(-r*tv1nl); clterm = nl*(Vi + resclamp - tv2nl); // nonlinearity ignored around whole eq clterm2 = clterm; // nonlinearity ignored around whole eq f0 = -D1 + V1 - hah*(fixterm + clterm2); f1 = -D2 + V2 - hah*(ttd1nl + tv1nl); // nonlinearity ignored around tv1nl shrterm = hahnl*nl*(1-clterm*clterm)*(1-clterm2*clterm2); Jb = shrterm*(1-tv2nl*tv2nl); Ja = r*shrterm*(1-tv1nl*tv1nl)*Dclamp(-r*tv1nl) + 1; Jc = -hahnl*(1-tv1nl*tv1nl)*(1-tv1nl*tv1nl); idet = 1.0 / (Ja - Jb*Jc); V1 = V1 - (-Jb*f1 + f0)*idet; V2 = V2 - (Ja*f1 - Jc*f0)*idet; tv1nl = fasttanh(V1*nl); tv2nl = tanh(V2*nl); ); // Forced to do this to keep things stable :( V1 = clamp(V1); V2 = clamp(V2); Di = Vi; D1 = V1; D2 = V2; -V2; ); function eval_wasp_nonlin_BP_old(Vi) local(idet, Ja, Jb, Jc, tv1nl, tv2nl, ttd1nl, td1nl, td2nl, shrterm, fixterm, clterm, clterm2, V1, V2, f0, f1, resclamp) instance(nl, hah, hahnl, D2, D1, Di, r, offset) global() ( Vi = clamp(Vi); tv1nl = tanh(V1*nl+offset); tv2nl = tanh(V2*nl+offset); td1nl = fasttanh(D1*nl+offset); td2nl = fasttanh(D2*nl+offset); ttd1nl = tanh(td1nl); fixterm = fasttanh(fasttanh(nl*(Di + clamp(-r*td1nl) - td2nl))); loop(3, resclamp= clamp(-r*tv1nl); clterm = fasttanh(nl*(Vi + resclamp - tv2nl)); clterm2 = fasttanh(clterm); f0 = -D1 + V1 - hah*(fixterm + clterm2); f1 = -D2 + V2 - hah*(ttd1nl + fasttanh(tv1nl)); shrterm = hahnl*nl*(1-clterm*clterm)*(1-clterm2*clterm2); Jb = shrterm*(1-tv2nl*tv2nl); Ja = r*shrterm*(1-tv1nl*tv1nl)*Dclamp(-r*tv1nl) + 1; Jc = -hahnl*(1-tv1nl*tv1nl)*(1-tv1nl*tv1nl); idet = 1.0 / (Ja - Jb*Jc); V1 = V1 - (-Jb*f1 + f0)*idet; V2 = V2 - (Ja*f1 - Jc*f0)*idet; tv1nl = fasttanh(V1*nl); tv2nl = tanh(V2*nl); ); // Forced to do this to keep things stable :( V1 = clamp(V1); V2 = clamp(V2); Di = Vi; D1 = V1; D2 = V2; -V1; ); // Optimized based on coefficient magnitude // Checked for effect of tanh vs true_tanh function eval_wasp_nonlin_BP(Vi) local(idet, tv1nl, tv2nl, ttd1nl, td1nl, td2nl, fixterm, V1, V2, f0, f1, resclamp, shrterm, clterm, clterm2) instance(nl, hah, hahnl, D2, D1, Di, r, offset, Jc) global() ( Vi = clamp(Vi); tv1nl = tanh(V1*nl+offset); tv2nl = tanh(V2*nl+offset); td1nl = fasttanh(D1*nl+offset); td2nl = fasttanh(D2*nl+offset); ttd1nl = tanh(td1nl); fixterm = fasttanh(fasttanh(nl*(Di + clamp(-r*td1nl) - td2nl))); loop(3, resclamp= clamp(-r*tv1nl); clterm = fasttanh(nl*(Vi + resclamp - tv2nl)); clterm2 = fasttanh(clterm); f0 = -D1 + V1 - hah*(fixterm + clterm2); f1 = -D2 + V2 - hah*(ttd1nl + fasttanh(tv1nl)); Jc = -hahnl*(1-tv1nl*tv1nl)*(1-tv1nl*tv1nl); idet = 1.0 / (1.0 - Jc); V1 = V1 - f0*idet; V2 = V2 - (f1 - Jc*f0)*idet; tv1nl = fasttanh(V1*nl); tv2nl = tanh(V2*nl); ); // Forced to do this to keep things stable :( V1 = clamp(V1); V2 = clamp(V2); Di = Vi; D1 = V1; D2 = V2; -V1; ); function init_wasplin(freq, res) global(srate, slider54) local(f, h, hh, itau, wrel, rate) instance(U0, U1, Di, D0, D1, x0, x1, x2, x3, i1, K2) ( rate = (srate * max(slider54,1)); wrel = 2 * $pi * 22050 * ( ( pow(10, freq) - 1 ) / 9 ); f = 20 * rate * tan( .5 * wrel * h ); h = 1.0 / rate; hh = 0.5 * h; itau = .08 * f; K2 = .8-.6*res; x0 = hh*itau; x1 = 2*x0; x2 = K2*x1; x3 = 4*x0*x0; i1 = 1.0/(x2 + x3 + 1); ); function pwm_init(freq, reso) instance(len, ilen, c, svf) local() global(srate, slider54) ( this.filter_SVF.init_linearSVF( freq, 0 ); len = floor(8*reso)+2;//(1-freq)*(srate * max(slider54,1)); ilen = 1/len; ); function bit_init(freq, reso) instance(depth, idepth, res) local() global() ( depth = 2^(freq*freq*freq * 16); idepth = 1/depth; res = reso; this.filter_SVF.init_linearSVF( reso, 0 ); ); function muck_init(freq, reso) instance(f, res) local() global() ( f = freq; res = reso; this.filter_SVF.init_linearSVF( f, res ); ); function weeping_init(freq, res, bass) instance( a_0, a_1, a_2, a_3, b_0, b_1, b_2, b_3, ia_0, dx0, dx1, dx2, dx3, dy0, dy1, dy2, dy3 ) local( x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21 A0, A1, A2, A3, B0, B1, B2, bass, WAH, m_fudge, e_fudge, f, f2, f3, R108, R109, R110, R111, R113, R114, R115, R117, R120, R122, R123, C104, C105, C118, C119, VR6, VR7, WAH_theta, LO, LEVEL, Q, RANGE ) global(srate, slider54) ( LEVEL = 10000.0; LO = 100 + 99900 * res; WAH_theta = 5 + 12*freq; Q = 100 + 249900*(.75*freq+.25); RANGE = 2500*freq; R108 = 9790; // 10e3; R109 = 21300; // 22e3; R110 = 23900; // 24e3; R111 = 46400; // 47e3; R113 = 197000; // 200e3; R114 = 10970; // 11e3; R115 = 982; // 1e3; R117 = 14770; // 15e3; R120 = 3520; // 3.6e3; R122 = 4950; // 5.1e3; R123 = 4650; // 4.7e3; C104 = .00000000276; // 2.7e-9; C105 = .0000000103; // 10e-9; C118 = .0000000195; // 18e-9; C119 = .0000000101; // 10e-9; VR6 = 0; // 20e3; VR7 = 449000; // 500e3; m_fudge = 1.1; e_fudge = 0.95*(1+.1*res); WAH = m_fudge * 16933367000 * pow(WAH_theta,(-4.45855*e_fudge)); bass ? ( LEVEL = 10000; Q = 10000*freq; LO = 100; x0 = LO + R122 + R123; x1 = C105*R117*x0; x2 = Q + R114; x3 = R109 + R110; x4 = R113 + VR7; x5 = WAH + x4; x6 = R108 + x2; x7 = R115 + RANGE + VR6; B2 = 0.0; A3 = 0.0; B1 = LEVEL*x1*x2*x3*x5; B0 = R123*x2*x3*x5*(LEVEL + R120); A2 = R109*R120*x1*x6*(C104 + C119)*(WAH*(x4 + x7) + x4*x7); A1 = C105*R108*R117*R120*x0*x3*x5; A0 = R110*R120*x0*x5*x6; ) : ( x0 = LO + R122 + R123; x1 = C105*R111*R117*x0; x2 = Q + R114; x3 = R109 + R110; x4 = R113 + VR7; x5 = WAH + x4; x6 = x2*x3*x5; x7 = C118*R111*R123; x8 = C105*R117; x9 = x0*x8; x10 = R108 + x2; x11 = R115 + RANGE + VR6; x12 = WAH*(x11 + x4) + x11*x4; x13 = R110*R111; x14 = C118*R108*x5; x15 = C104*x12; x16 = R120*x0*x5; x17 = R108 + R111; B2 = C118*LEVEL*x1*x2*x3*x5; B1 = x6*(LEVEL*(x7 + x9) + R120*x7); B0 = R123*x6*(LEVEL + R120); A3 = C104*C118*R109*R120*x1*x10*x12; A2 = R120*x9*(R109*(R111*(x14 + x15) + x10*x15) + x13*x14); A1 = x16*(C118*x10*x13 + x17*x3*x8); A0 = R110*x16*(x17 + x2); ); //double az0,az1,az2,az3,bz0,bz1,bz2,bz3; f = srate * max(1, slider54); f2 = f*f; f3 = f2*f; // Bilinear transform a_0 = 8*A3*f3 + 4*A2*f2 + 2*A1*f + A0; ia_0 = 1/a_0; a_3 = (-8*A3*f3 + 4*A2*f2 - 2*A1*f + A0)*ia_0; a_2 = (24*A3*f3 -4*A2*f2 - 2*A1*f + 3*A0)*ia_0; a_1 = (-24*A3*f3 -4*A2*f2 +2*A1*f + 3*A0)*ia_0; b_3 = (4*B2*f2 - 2*B1*f + B0)*ia_0; b_2 = (-4*B2*f2 - 2*B1*f + 3*B0)*ia_0; b_1 = (-4*B2*f2 +2*B1*f + 3*B0)*ia_0; b_0 = (4*B2*f2 + 2*B1*f + B0)*ia_0; a_0 = 1; ); function weeping_eval(sample) instance( a_0, a_1, a_2, a_3, b_0, b_1, b_2, b_3, ia_0, dx0, dx1, dx2, dx3, dy0, dy1, dy2, dy3 ) global(srate) local() ( dx3 = dx2; dx2 = dx1; dx1 = dx0; dx0 = sample; dy3 = dy2; dy2 = dy1; dy1 = dy0; dy0 = -a_1 * dy1 - a_2 * dy2 - a_3 * dy3 + (b_0 * dx0 + b_1 * dx1 + b_2 * dx2 + b_3 * dx3 ); dy0 ); function weeping_reset() instance( a_0, a_1, a_2, a_3, b_0, b_1, b_2, b_3, ia_0, dx0, dx1, dx2, dx3, dy0, dy1, dy2, dy3 ) local() global() ( dx3 = dx2 = dx1 = dx0 = 0; dy3 = dy2 = dy1 = dy0 = 0; ); /* Run only when samplerate changes */ function dlop_init_srate(inrate) global() instance( A0_0_0, A0_0_1, A0_0_2, A0_0_5, A0_1_0, A0_1_1, A0_1_2, A0_1_5, A0_2_0, A0_2_1, A0_2_2, A0_2_5, A0_3_3, A0_4_4, A0_5_0, A0_5_1, A0_5_2, A0_5_5, A_0_0, A_0_1, A_0_2, A_0_3, A_0_4, A_0_5, A_1_0, A_1_1, A_1_2, A_1_3, A_1_4, A_1_5, A_2_0, A_2_1, A_2_2, A_2_3, A_2_4, A_2_5, A_3_0, A_3_1, A_3_2, A_3_3, A_3_4, A_3_5, A_4_0, A_4_1, A_4_2, A_4_3, A_4_4, A_4_5, A_5_0, A_5_1, A_5_2, A_5_3, A_5_4, A_5_5, B0_0_0, B0_0_1, B0_1_0, B0_1_1, B0_2_0, B0_2_1, B0_5_0, B0_5_1, B_0_0, B_0_1, B_1_0, B_1_1, B_2_0, B_2_1, B_3_0, B_3_1, B_4_0, B_4_1, B_5_0, B_5_1, C0_0_0, C0_0_1, C0_0_2, C0_0_3, C0_1_0, C0_1_1, C0_1_2, C0_1_3, C0_2_0, C0_2_1, C0_2_2, C0_2_3, C0_5_0, C0_5_1, C0_5_2, C0_5_3, C_0_0, C_0_1, C_0_2, C_0_3, C_1_0, C_1_1, C_1_2, C_1_3, C_2_0, C_2_1, C_2_2, C_2_3, C_3_0, C_3_1, C_3_2, C_3_3, C_4_0, C_4_1, C_4_2, C_4_3, C_5_0, C_5_1, C_5_2, C_5_3, D0_0_0, D0_0_1, D0_0_2, D0_0_3, D0_0_5, D_0_0, D_0_1, D_0_2, D_0_3, D_0_4, D_0_5, E0_0_0, E0_0_1, E_0_0, E_0_1, F0_0_0, F0_0_1, F0_0_2, F0_0_3, F_0_0, F_0_1, F_0_2, F_0_3, G0_0_0, G0_0_1, G0_0_2, G0_0_5, G0_1_0, G0_1_1, G0_1_2, G0_1_5, G0_2_0, G0_2_1, G0_2_2, G0_2_5, G0_3_0, G0_3_1, G0_3_2, G0_3_5, GX_0_0, GX_1_1, GX_2_2, GX_3_3, GX_4_4, GX_5_5, G_0_0, G_0_1, G_0_2, G_0_3, G_0_4, G_0_5, G_1_0, G_1_1, G_1_2, G_1_3, G_1_4, G_1_5, G_2_0, G_2_1, G_2_2, G_2_3, G_2_4, G_2_5, G_3_0, G_3_1, G_3_2, G_3_3, G_3_4, G_3_5, H0_0_0, H0_0_1, H0_1_0, H0_1_1, H0_2_0, H0_2_1, H0_3_0, H0_3_1, H_0_0, H_0_1, H_1_0, H_1_1, H_2_0, H_2_1, H_3_0, H_3_1, K0_0_0, K0_0_1, K0_0_2, K0_0_3, K0_1_0, K0_1_1, K0_1_2, K0_1_3, K0_2_0, K0_2_1, K0_2_2, K0_2_3, K0_3_0, K0_3_1, K0_3_2, K0_3_3, K_0_0, K_0_1, K_0_2, K_0_3, K_1_0, K_1_1, K_1_2, K_1_3, K_2_0, K_2_1, K_2_2, K_2_3, K_3_0, K_3_1, K_3_2, K_3_3, Q_0_0, Q_0_1, Q_1_0, Q_1_1, U0_0_0, U0_0_1, UN_0_1, UN_1_1, UN_2_0, UN_2_1, UN_3_1, UU_0_1, UU_1_1, UX_0_1, UX_1_1, UX_2_1, UX_3_0, UX_4_0, UX_4_1, UX_5_1, Ui, x_0_0, x_1_0, x_2_0, x_3_0, x_4_0, x_5_0, xnm1_1, xnm1_2, xnm1_3, xnm1_4, xnm1_5, xnm1_6, y_0_0, l_srate ) local( inv_S0_0_13, inv_S0_10_10, inv_S0_10_14, inv_S0_11_1, inv_S0_11_11, inv_S0_11_13, inv_S0_11_14, inv_S0_11_2, inv_S0_11_3, inv_S0_11_5, inv_S0_11_6, inv_S0_11_7, inv_S0_11_8, inv_S0_11_9, inv_S0_12_14, inv_S0_13_0, inv_S0_13_1, inv_S0_13_11, inv_S0_13_13, inv_S0_13_14, inv_S0_13_2, inv_S0_13_3, inv_S0_13_5, inv_S0_13_6, inv_S0_13_7, inv_S0_13_8, inv_S0_13_9, inv_S0_14_1, inv_S0_14_10, inv_S0_14_11, inv_S0_14_12, inv_S0_14_13, inv_S0_14_14, inv_S0_14_2, inv_S0_14_3, inv_S0_14_5, inv_S0_14_6, inv_S0_14_7, inv_S0_14_8, inv_S0_14_9, inv_S0_1_1, inv_S0_1_11, inv_S0_1_13, inv_S0_1_14, inv_S0_1_2, inv_S0_1_3, inv_S0_1_5, inv_S0_1_6, inv_S0_1_7, inv_S0_1_8, inv_S0_1_9, inv_S0_2_1, inv_S0_2_11, inv_S0_2_13, inv_S0_2_14, inv_S0_2_2, inv_S0_2_3, inv_S0_2_5, inv_S0_2_6, inv_S0_2_7, inv_S0_2_8, inv_S0_2_9, inv_S0_3_1, inv_S0_3_11, inv_S0_3_13, inv_S0_3_14, inv_S0_3_2, inv_S0_3_3, inv_S0_3_5, inv_S0_3_6, inv_S0_3_7, inv_S0_3_8, inv_S0_3_9, inv_S0_4_4, inv_S0_5_1, inv_S0_5_11, inv_S0_5_13, inv_S0_5_14, inv_S0_5_2, inv_S0_5_3, inv_S0_5_5, inv_S0_5_6, inv_S0_5_7, inv_S0_5_8, inv_S0_5_9, inv_S0_6_1, inv_S0_6_11, inv_S0_6_13, inv_S0_6_14, inv_S0_6_2, inv_S0_6_3, inv_S0_6_5, inv_S0_6_6, inv_S0_6_7, inv_S0_6_8, inv_S0_6_9, inv_S0_7_1, inv_S0_7_11, inv_S0_7_13, inv_S0_7_14, inv_S0_7_2, inv_S0_7_3, inv_S0_7_5, inv_S0_7_6, inv_S0_7_7, inv_S0_7_8, inv_S0_7_9, inv_S0_8_1, inv_S0_8_11, inv_S0_8_13, inv_S0_8_14, inv_S0_8_2, inv_S0_8_3, inv_S0_8_5, inv_S0_8_6, inv_S0_8_7, inv_S0_8_8, inv_S0_8_9, inv_S0_9_1, inv_S0_9_11, inv_S0_9_13, inv_S0_9_14, inv_S0_9_2, inv_S0_9_3, inv_S0_9_5, inv_S0_9_6, inv_S0_9_7, inv_S0_9_8, inv_S0_9_9, csrate, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31, t32, t33, t34, t35, t36, t37, t38, t39, t40, t41, t42, t43, t44, t45, t46, t47, t48, t49, t50, t51, t52, t53, t54, t55, t56, t57, t58, t59, t60, t61, t62, t63, t64, t65, t66, t67, t68, t69, t70, t71, t72, t73, t74, t75, t76, t77, t78, t79, t80, t81, t82, t83, t84, t85, t86, t87, t88, t89, t90, t91, t92, t93, t94, t95, t96, t97, t98, t99, t100, t101, t102, t103, t104, t105, t106, t107, t108, t109, t110, t111, t112, t113, t114, t115, t116, t117, t118, t119, t120, t121, t122, t123, t124, t125, t126, t127, t128, t129, t130, t131, t132, t133, t134, t135, t136, t137, t138, t139, t140, t141, t142, t143, t144, t145, t146, t147, t148 ) ( csrate = l_srate = inrate; t2 = csrate*0.0000000200000000000000000; t3 = csrate*0.0000004400000000000000200; GX_0_0 = t2; GX_1_1 = csrate*0.0000093999999999999998000; GX_2_2 = t2; GX_3_3 = t3; GX_4_4 = t3; GX_5_5 = 1.0/csrate; t2 = csrate*csrate; t3 = t2*t2; t4 = csrate*104148997837773310000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t5 = t2*168049188362960990000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t6 = csrate*t2*37900260583325013000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t7 = t3*4161400794005249200000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t8 = t4+t5+t6+t7+156587379389530910000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t9 = 1.0/t8; t10 = csrate*311676187869396580000000000.0000000000000000000000000; t11 = t2*71779970539618612000000.0000000000000000000000000; t12 = csrate*t2*1888946593147857900.0000000000000000000000000; t13 = t10+t11+t12; t14 = t9*t13*2147418458039436100000000000000000000000000000000000000000000000.0000000000000000000000000; t15 = csrate*1028165922870751900000000000000000000000000000.0000000000000000000000000; t16 = t2*45784920068708670000000000000000000000000.0000000000000000000000000; t17 = csrate*t2*9664759674985072600000000000000000000000.0000000000000000000000000; t18 = t15+t16+t17; t19 = csrate*103936039001803500000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t20 = t2*27001923363579069000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t21 = csrate*t2*5482265284429159900000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t22 = t3*494703213269570820000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t23 = t19+t20+t21+t22+156587379389530910000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t24 = csrate*198359885140591300000000000000000000000000000000000000000000000000000.0000000000000000000000000; t25 = t2*2792704785718975200000000000000000000000000000000000000000000000000.0000000000000000000000000; t26 = csrate*t2*2458305008225491000000000000000000000000000000000000000000000000.0000000000000000000000000; t27 = t3*436489500783226260000000000000000000000000000000000000000000.0000000000000000000000000; t28 = t24+t25+t26+t27; t29 = t9*t28*77069021000432611000000.0000000000000000000000000; t30 = csrate*2340686216037774100000000000000000000000000000.0000000000000000000000000; t31 = t2*469921302823437300000000000000000000000000.0000000000000000000000000; t32 = csrate*t2*12131605388000659000000000000000000000.0000000000000000000000000; t33 = t30+t31+t32+1471849183103021100000000000000000000000000000000.0000000000000000000000000; t34 = csrate*1888946593147857900.0000000000000000000000000; t35 = t34+9444732965739290400000.0000000000000000000000000; t36 = t9*t33*334362901746586200000000000000000000000000000.0000000000000000000000000; t37 = csrate*6422418416702718000.0000000000000000000000000; t38 = t37+4722366482869645200000.0000000000000000000000000; t39 = csrate*45784920068708670000000000000000000000000.0000000000000000000000000; t40 = t2*9664759674985072600000000000000000000000.0000000000000000000000000; t41 = t39+t40+1028165922870751900000000000000000000000000000.0000000000000000000000000; t42 = csrate*2696778064686603100000000000000000000000000000000000000000000000000000.0000000000000000000000000; t43 = t2*4351314231925824000000000000000000000000000000000000000000000000000.0000000000000000000000000; t44 = csrate*t2*981354042057917920000000000000000000000000000000000000000000000.0000000000000000000000000; t45 = t3*107751315918617600000000000000000000000000000000000000000000.0000000000000000000000000; t46 = t42+t43+t44+t45+4081635542626462800000000000000000000000000000000000000000000000000000.0000000000000000000000000; t47 = t9*t46*811656739243220270000000.0000000000000000000000000; t48 = csrate*52512715289510461000.0000000000000000000000000; t49 = t48+37778931862957162000000.0000000000000000000000000; t50 = csrate+33000.0000000000000000000000000; t51 = t9*t13*48024085516154660000000000000000000000000000000000000000000000000.0000000000000000000000000; t52 = t9*t33*7477570348150926100000000000000000000000000000.0000000000000000000000000; t53 = csrate*38157467064493842000000000000000000000000000000.0000000000000000000000000; t54 = t2*8623430559329410300000000000000000000000000.0000000000000000000000000; t55 = csrate*t2*947264293648945560000000000000000000000.0000000000000000000000000; t56 = t53+t54+t55+23549586929648338000000000000000000000000000000000.0000000000000000000000000; t57 = t9*t56*20897681359161640000000000000000000000000000.0000000000000000000000000; t58 = csrate*19078733532246921000000000000000000000000000000.0000000000000000000000000; t59 = t2*3840723541071737800000000000000000000000000.0000000000000000000000000; t60 = csrate*t2*99193714643064222000000000000000000000.0000000000000000000000000; t61 = t58+t59+t60+11774793464824169000000000000000000000000000000000.0000000000000000000000000; t62 = t9*t61*41795362718323270000000000000000000000000000.0000000000000000000000000; t63 = csrate*9444732965739290400000.0000000000000000000000000; t64 = t2*1888946593147857900.0000000000000000000000000; t65 = t63+t64; t66 = t9*t35*t49*t50*41795362718323270000000000000000000000000000.0000000000000000000000000; t67 = csrate*t9*t49*t50*78949208016155746000000000000000000000000000000000000000000000.0000000000000000000000000; t68 = t9*t13*31579683206462300000000000000000000000000000000000000000000.0000000000000000000000000; t69 = t9*t46*36893488147419099000.0000000000000000000000000; t70 = csrate*156587379389530910000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t71 = t2*104148997837773310000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t72 = csrate*t2*168049188362960990000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t73 = t3*37900260583325013000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t74 = csrate*t3*4161400794005249200000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t75 = t70+t71+t72+t73+t74; t76 = 1.0/t75; t77 = csrate*435224570844252000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t78 = t2*702254400438290970000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t79 = csrate*t2*158379958263682010000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t80 = t3*17389918765192671000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t81 = t77+t78+t79+t80+654544300496910220000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000; t82 = t9*t81*117500.0000000000000000000000000; t83 = csrate*t9*t18*2911585293120157700000000000000000000000000.0000000000000000000000000; t84 = csrate*1246704751477586100000000000.0000000000000000000000000; t85 = t2*1770698536416802100000000.0000000000000000000000000; t86 = csrate*t2*52512715289510461000.0000000000000000000000000; t87 = t84+t85+t86; t88 = t9*t87*78949208016155746000000000000000000000000000000000000000000000.0000000000000000000000000; t89 = t9*t23; t90 = t9*t28*1133367955888715000.0000000000000000000000000; t91 = t9*t13*706236551708156790000000000000000000000000000000000000000000.0000000000000000000000000; t92 = csrate*t9*t18*42817430781178802000000000000000000000.0000000000000000000000000; t93 = t9*t13*97609929910883467000000000000000000000000000000000000000000.0000000000000000000000000; t94 = t9*t33*15198313715753920000000000000000000000000.0000000000000000000000000; t95 = t9*t56*949894607234619870000000000000000000000.0000000000000000000000000; t96 = t9*t13*1435440145748286000000000000000000000000000000000000000.0000000000000000000000000; inv_S0_0_13 = 1.0; inv_S0_1_1 = t9*t23*68000.0000000000000000000000000; inv_S0_1_2 = t29; inv_S0_1_3 = t14; inv_S0_1_5 = t51; inv_S0_1_6 = t9*t18*t35*1541380420008652100000000.0000000000000000000000000; inv_S0_1_7 = t14; inv_S0_1_8 = t14; inv_S0_1_9 = t14; inv_S0_1_11 = t83; inv_S0_1_13 = t89; inv_S0_1_14 = t93; inv_S0_2_1 = t29; inv_S0_2_2 = t9*(csrate*14462125656090909000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+t2*29544935823730000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+t3*2803318208527567900000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+csrate*t2*17849526747323131000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+936728073133800930000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000)*12000.0000000000000000000000000; inv_S0_2_3 = t36; inv_S0_2_5 = t52; inv_S0_2_6 = t9*t35*t38*t41*240000.0000000000000000000000000; inv_S0_2_7 = t36; inv_S0_2_8 = t36; inv_S0_2_9 = t36; inv_S0_2_11 = csrate*t9*t38*t41*453347182355486010000000.0000000000000000000000000; inv_S0_2_13 = t90; inv_S0_2_14 = t94; inv_S0_3_1 = t14; inv_S0_3_2 = t36; inv_S0_3_3 = t47; inv_S0_3_5 = t57; inv_S0_3_6 = t66; inv_S0_3_7 = t47; inv_S0_3_8 = t47; inv_S0_3_9 = t47; inv_S0_3_11 = t67; inv_S0_3_13 = t68; inv_S0_3_14 = t69; inv_S0_4_4 = 390.0000000000000000000000000; inv_S0_5_1 = t51; inv_S0_5_2 = t52; inv_S0_5_3 = t57; inv_S0_5_5 = t9*t56*467348146759432880000000000000000000000000000.0000000000000000000000000; inv_S0_5_6 = t9*t35*t49*t50*934696293518865770000000000000000000000000000.0000000000000000000000000; inv_S0_5_7 = t57; inv_S0_5_8 = t57; inv_S0_5_9 = t57; inv_S0_5_11 = csrate*t9*t49*t50*1765591379270392000000000000000000000000000000000000000000000000.0000000000000000000000000; inv_S0_5_13 = t91; inv_S0_5_14 = t95; inv_S0_6_1 = t9*t41*t65*1541380420008652100000000.0000000000000000000000000; inv_S0_6_2 = t9*t41*(csrate*69578325019415553000000000000000000000000.0000000000000000000000000+t2*12131605388000659000000000000000000000.0000000000000000000000000+44601490397061246000000000000000000000000000.0000000000000000000000000)*240000.0000000000000000000000000; inv_S0_6_3 = t62; inv_S0_6_5 = t9*t61*934696293518865770000000000000000000000000000.0000000000000000000000000; inv_S0_6_6 = t9*t35*t41*t49*30000.0000000000000000000000000; inv_S0_6_7 = t62; inv_S0_6_8 = t62; inv_S0_6_9 = t62; inv_S0_6_11 = csrate*t9*t41*t49*56668397794435743000000.0000000000000000000000000; inv_S0_6_13 = t9*t41*t65*22667359117774299000.0000000000000000000000000; inv_S0_6_14 = t9*t61*1899789214469240000000000000000000000000.0000000000000000000000000; inv_S0_7_1 = t14; inv_S0_7_2 = t36; inv_S0_7_3 = t47; inv_S0_7_5 = t57; inv_S0_7_6 = t66; inv_S0_7_7 = t76*(csrate*211213336231417100000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+t2*2262293496318552100000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+t3*709262708789508200000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+csrate*t2*3183761219565277800000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+csrate*t3*76962231920350745000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+313174758779061810000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000)*1136363.6363636360000000000000000; inv_S0_7_8 = t47; inv_S0_7_9 = t47; inv_S0_7_11 = t67; inv_S0_7_13 = t68; inv_S0_7_14 = t69; inv_S0_8_1 = t14; inv_S0_8_2 = t36; inv_S0_8_3 = t47; inv_S0_8_5 = t57; inv_S0_8_6 = t66; inv_S0_8_7 = t47; inv_S0_8_8 = t76*(csrate*1386456035398161900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+t2*227770380898722010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+t3*82313914752666519000000000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+csrate*t2*365174096951867380000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+csrate*t3*9033372646822891300000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+1573325515041519100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000)*0.0000000002261962984145006; inv_S0_8_9 = t82; inv_S0_8_11 = t67; inv_S0_8_13 = t68; inv_S0_8_14 = t69; inv_S0_9_1 = t14; inv_S0_9_2 = t36; inv_S0_9_3 = t47; inv_S0_9_5 = t57; inv_S0_9_6 = t66; inv_S0_9_7 = t47; inv_S0_9_8 = t82; inv_S0_9_9 = t82; inv_S0_9_11 = t67; inv_S0_9_13 = t68; inv_S0_9_14 = t69; inv_S0_10_10 = 1000.0000000000000000000000000; inv_S0_10_14 = 1.0; inv_S0_11_1 = t83; inv_S0_11_2 = t9*t18*t38*453347182355486010000000.0000000000000000000000000; inv_S0_11_3 = t88; inv_S0_11_5 = t9*t87*1765591379270392000000000000000000000000000000000000000000000000.0000000000000000000000000; inv_S0_11_6 = t9*t18*t49*56668397794435743000000.0000000000000000000000000; inv_S0_11_7 = t88; inv_S0_11_8 = t88; inv_S0_11_9 = t88; inv_S0_11_11 = t9*(csrate*104117680361895400000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+t2*147269675713816010000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+t3*2876050239882790100000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+csrate*t2*8509478391503055200000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000+156587379389530910000000000000000000000000000000000000000000000000000000000000000000000000.0000000000000000000000000)*10000.0000000000000000000000000; inv_S0_11_13 = t92; inv_S0_11_14 = t9*t87*3588600364370715800000000000000000000000000000000000000000.0000000000000000000000000; inv_S0_12_14 = 1.0; inv_S0_13_0 = 1.0; inv_S0_13_1 = t89; inv_S0_13_2 = t90; inv_S0_13_3 = t68; inv_S0_13_5 = t91; inv_S0_13_6 = t9*t18*t35*22667359117774299000.0000000000000000000000000; inv_S0_13_7 = t68; inv_S0_13_8 = t68; inv_S0_13_9 = t68; inv_S0_13_11 = t92; inv_S0_13_13 = t9*(csrate*4144833420848175700000000000000000000000000000000000000000000000000.0000000000000000000000000+t2*2745213248496893100000000000000000000000000000000000000000000000000.0000000000000000000000000+t3*71365203550109241000000000000000000000000000000000000000000.0000000000000000000000000+csrate*t2*630953816684278590000000000000000000000000000000000000000000000.0000000000000000000000000)*(-755578637259143.2500000000000000000000000); inv_S0_13_14 = t96; inv_S0_14_1 = t93; inv_S0_14_2 = t94; inv_S0_14_3 = t69; inv_S0_14_5 = t95; inv_S0_14_6 = t9*t35*t49*t50*1899789214469240000000000000000000000000.0000000000000000000000000; inv_S0_14_7 = t69; inv_S0_14_8 = t69; inv_S0_14_9 = t69; inv_S0_14_10 = 1.0; inv_S0_14_11 = csrate*t9*t49*t50*3588600364370715800000000000000000000000000000000000000000.0000000000000000000000000; inv_S0_14_12 = 1.0; inv_S0_14_13 = t96; inv_S0_14_14 = t9*(csrate*673948906620952620000000000000000000000000000000000000000000000000000.0000000000000000000000000+t2*1087773051233548000000000000000000000000000000000000000000000000000.0000000000000000000000000+t3*26937828979654412000000000000000000000000000000000000000000.0000000000000000000000000+csrate*t2*245332413224081180000000000000000000000000000000000000000000000.0000000000000000000000000+868826406265596790000000000000000000000000000000000000000000000000000.0000000000000000000000000)*(-313987133169524.3100000000000000000000000); UX_0_1 = -inv_S0_1_8+inv_S0_2_8; UX_1_1 = inv_S0_5_8; UX_2_1 = inv_S0_6_8-inv_S0_11_8; UX_3_0 = inv_S0_3_7-inv_S0_3_8-inv_S0_7_7+inv_S0_7_8; UX_4_0 = inv_S0_8_7-inv_S0_8_8-inv_S0_9_7+inv_S0_9_8; UX_4_1 = inv_S0_8_8-inv_S0_9_8; UX_5_1 = inv_S0_5_8-inv_S0_6_8; U0_0_0 = inv_S0_7_7-inv_S0_7_8; U0_0_1 = inv_S0_7_8; UN_0_1 = -inv_S0_2_8+inv_S0_3_8; UN_1_1 = inv_S0_3_8; UN_2_0 = -inv_S0_9_7+inv_S0_9_8; UN_2_1 = -inv_S0_9_8; UN_3_1 = -inv_S0_11_8; UU_0_1 = inv_S0_13_8; UU_1_1 = inv_S0_14_8; t2 = csrate*inv_S0_2_5*0.0000000400000000000000010; t3 = csrate*inv_S0_2_6*0.0000000400000000000000010; t4 = csrate*inv_S0_5_5*0.0000188000000000000000000; t5 = csrate*inv_S0_5_6*0.0000188000000000000000000; t6 = csrate*inv_S0_6_5*0.0000000400000000000000010; t7 = csrate*inv_S0_6_6*0.0000000400000000000000010; t8 = 1.0/csrate; t9 = inv_S0_6_5*t8*2.0; t10 = inv_S0_6_6*t8*2.0; A0_0_0 = csrate*inv_S0_1_1*0.0000000400000000000000010-csrate*inv_S0_1_2*0.0000000400000000000000010-csrate*inv_S0_2_1*0.0000000400000000000000010+csrate*inv_S0_2_2*0.0000000400000000000000010-1.0; A0_0_1 = t2-csrate*inv_S0_1_5*0.0000000400000000000000010; A0_0_2 = t3-csrate*inv_S0_1_6*0.0000000400000000000000010+csrate*inv_S0_1_11*0.0000000400000000000000010-csrate*inv_S0_2_11*0.0000000400000000000000010; A0_0_5 = t2-t3-csrate*inv_S0_1_5*0.0000000400000000000000010+csrate*inv_S0_1_6*0.0000000400000000000000010; A0_1_0 = csrate*inv_S0_5_1*(-0.0000188000000000000000000)+csrate*inv_S0_5_2*0.0000188000000000000000000; A0_1_1 = t4-1.0; A0_1_2 = t5-csrate*inv_S0_5_11*0.0000188000000000000000000; A0_1_5 = t4-t5; A0_2_0 = csrate*inv_S0_6_1*(-0.0000000400000000000000010)+csrate*inv_S0_6_2*0.0000000400000000000000010+csrate*inv_S0_11_1*0.0000000400000000000000010-csrate*inv_S0_11_2*0.0000000400000000000000010; A0_2_1 = t6-csrate*inv_S0_11_5*0.0000000400000000000000010; A0_2_2 = t7-csrate*inv_S0_11_6*0.0000000400000000000000010-csrate*inv_S0_6_11*0.0000000400000000000000010+csrate*inv_S0_11_11*0.0000000400000000000000010-1.0; A0_2_5 = t6-t7-csrate*inv_S0_11_5*0.0000000400000000000000010+csrate*inv_S0_11_6*0.0000000400000000000000010; A0_3_3 = csrate*inv_S0_3_3*0.0000008800000000000000400-csrate*inv_S0_3_7*0.0000008800000000000000400-csrate*inv_S0_7_3*0.0000008800000000000000400+csrate*inv_S0_7_7*0.0000008800000000000000400-1.0; A0_4_4 = csrate*inv_S0_8_8*0.0000008800000000000000400-csrate*inv_S0_8_9*0.0000008800000000000000400-csrate*inv_S0_9_8*0.0000008800000000000000400+csrate*inv_S0_9_9*0.0000008800000000000000400-1.0; A0_5_0 = inv_S0_5_1*t8*2.0-inv_S0_5_2*t8*2.0-inv_S0_6_1*t8*2.0+inv_S0_6_2*t8*2.0; A0_5_1 = t9-inv_S0_5_5*t8*2.0; A0_5_2 = t10-inv_S0_5_6*t8*2.0+inv_S0_5_11*t8*2.0-inv_S0_6_11*t8*2.0; A0_5_5 = t9-t10-inv_S0_5_5*t8*2.0+inv_S0_5_6*t8*2.0+1.0; t2 = 1.0/csrate; B0_0_0 = csrate*inv_S0_1_13*(-0.0000000400000000000000010)+csrate*inv_S0_2_13*0.0000000400000000000000010; B0_0_1 = csrate*inv_S0_1_14*(-0.0000000400000000000000010)+csrate*inv_S0_2_14*0.0000000400000000000000010; B0_1_0 = csrate*inv_S0_5_13*0.0000188000000000000000000; B0_1_1 = csrate*inv_S0_5_14*0.0000188000000000000000000; B0_2_0 = csrate*inv_S0_6_13*0.0000000400000000000000010-csrate*inv_S0_11_13*0.0000000400000000000000010; B0_2_1 = csrate*inv_S0_6_14*0.0000000400000000000000010-csrate*inv_S0_11_14*0.0000000400000000000000010; B0_5_0 = inv_S0_5_13*t2*-2.0+inv_S0_6_13*t2*2.0; B0_5_1 = inv_S0_5_14*t2*-2.0+inv_S0_6_14*t2*2.0; t2 = csrate*inv_S0_2_3*0.0000000400000000000000010; t3 = csrate*inv_S0_5_3*0.0000188000000000000000000; t4 = csrate*inv_S0_6_3*0.0000000400000000000000010; t5 = 1.0/csrate; t6 = inv_S0_6_3*t5*2.0; C0_0_0 = t2+csrate*inv_S0_1_2*0.0000000400000000000000010-csrate*inv_S0_1_3*0.0000000400000000000000010-csrate*inv_S0_2_2*0.0000000400000000000000010; C0_0_1 = t2-csrate*inv_S0_1_3*0.0000000400000000000000010; C0_0_2 = csrate*inv_S0_1_9*0.0000000400000000000000010-csrate*inv_S0_2_9*0.0000000400000000000000010; C0_0_3 = csrate*inv_S0_1_11*0.0000000400000000000000010-csrate*inv_S0_2_11*0.0000000400000000000000010; C0_1_0 = t3-csrate*inv_S0_5_2*0.0000188000000000000000000; C0_1_1 = t3; C0_1_2 = csrate*inv_S0_5_9*(-0.0000188000000000000000000); C0_1_3 = csrate*inv_S0_5_11*(-0.0000188000000000000000000); C0_2_0 = t4-csrate*inv_S0_6_2*0.0000000400000000000000010+csrate*inv_S0_11_2*0.0000000400000000000000010-csrate*inv_S0_11_3*0.0000000400000000000000010; C0_2_1 = t4-csrate*inv_S0_11_3*0.0000000400000000000000010; C0_2_2 = csrate*inv_S0_6_9*(-0.0000000400000000000000010)+csrate*inv_S0_11_9*0.0000000400000000000000010; C0_2_3 = csrate*inv_S0_6_11*(-0.0000000400000000000000010)+csrate*inv_S0_11_11*0.0000000400000000000000010; C0_5_0 = t6+inv_S0_5_2*t5*2.0-inv_S0_5_3*t5*2.0-inv_S0_6_2*t5*2.0; C0_5_1 = t6-inv_S0_5_3*t5*2.0; C0_5_2 = inv_S0_5_9*t5*2.0-inv_S0_6_9*t5*2.0; C0_5_3 = inv_S0_5_11*t5*2.0-inv_S0_6_11*t5*2.0; D0_0_0 = -inv_S0_7_1+inv_S0_7_2; D0_0_1 = inv_S0_7_5; D0_0_2 = inv_S0_7_6-inv_S0_7_11; D0_0_3 = inv_S0_7_3-inv_S0_7_7; D0_0_5 = inv_S0_7_5-inv_S0_7_6; E0_0_0 = inv_S0_7_13; E0_0_1 = inv_S0_7_14; F0_0_0 = -inv_S0_7_2+inv_S0_7_3; F0_0_1 = inv_S0_7_3; F0_0_2 = -inv_S0_7_9; F0_0_3 = -inv_S0_7_11; G0_0_0 = inv_S0_2_1-inv_S0_2_2-inv_S0_3_1+inv_S0_3_2; G0_0_1 = -inv_S0_2_5+inv_S0_3_5; G0_0_2 = -inv_S0_2_6+inv_S0_3_6+inv_S0_2_11-inv_S0_3_11; G0_0_5 = -inv_S0_2_5+inv_S0_2_6+inv_S0_3_5-inv_S0_3_6; G0_1_0 = -inv_S0_3_1+inv_S0_3_2; G0_1_1 = inv_S0_3_5; G0_1_2 = inv_S0_3_6-inv_S0_3_11; G0_1_5 = inv_S0_3_5-inv_S0_3_6; G0_2_0 = inv_S0_9_1-inv_S0_9_2; G0_2_1 = -inv_S0_9_5; G0_2_2 = -inv_S0_9_6+inv_S0_9_11; G0_2_5 = -inv_S0_9_5+inv_S0_9_6; G0_3_0 = inv_S0_11_1-inv_S0_11_2; G0_3_1 = -inv_S0_11_5; G0_3_2 = -inv_S0_11_6+inv_S0_11_11; G0_3_5 = -inv_S0_11_5+inv_S0_11_6; H0_0_0 = -inv_S0_2_13+inv_S0_3_13; H0_0_1 = -inv_S0_2_14+inv_S0_3_14; H0_1_0 = inv_S0_3_13; H0_1_1 = inv_S0_3_14; H0_2_0 = -inv_S0_9_13; H0_2_1 = -inv_S0_9_14+inv_S0_10_14; H0_3_0 = -inv_S0_11_13; H0_3_1 = inv_S0_10_14-inv_S0_11_14; K0_0_0 = inv_S0_2_2-inv_S0_2_3-inv_S0_3_2+inv_S0_3_3; K0_0_1 = -inv_S0_2_3+inv_S0_3_3; K0_0_2 = inv_S0_2_9-inv_S0_3_9; K0_0_3 = inv_S0_2_11-inv_S0_3_11; K0_1_0 = -inv_S0_3_2+inv_S0_3_3; K0_1_1 = inv_S0_3_3+inv_S0_4_4; K0_1_2 = -inv_S0_3_9; K0_1_3 = -inv_S0_3_11; K0_2_0 = inv_S0_9_2-inv_S0_9_3; K0_2_1 = -inv_S0_9_3; K0_2_2 = inv_S0_9_9+inv_S0_10_10; K0_2_3 = inv_S0_9_11+inv_S0_10_10; K0_3_0 = inv_S0_11_2-inv_S0_11_3; K0_3_1 = -inv_S0_11_3; K0_3_2 = inv_S0_11_9+inv_S0_10_10; K0_3_3 = inv_S0_10_10+inv_S0_11_11; Q_0_0 = inv_S0_7_7-inv_S0_7_8-inv_S0_8_7+inv_S0_8_8; Q_0_1 = inv_S0_7_8-inv_S0_8_8; Q_1_0 = inv_S0_8_7-inv_S0_8_8; Q_1_1 = inv_S0_8_8; ); /* Run only when samplerate changes */ function dlop_init_cutoff(filterFreq, reso) global(srate) instance( A0_0_0, A0_0_1, A0_0_2, A0_0_5, A0_1_0, A0_1_1, A0_1_2, A0_1_5, A0_2_0, A0_2_1, A0_2_2, A0_2_5, A0_3_3, A0_4_4, A0_5_0, A0_5_1, A0_5_2, A0_5_5, A_0_0, A_0_1, A_0_2, A_0_3, A_0_4, A_0_5, A_1_0, A_1_1, A_1_2, A_1_3, A_1_4, A_1_5, A_2_0, A_2_1, A_2_2, A_2_3, A_2_4, A_2_5, A_3_0, A_3_1, A_3_2, A_3_3, A_3_4, A_3_5, A_4_0, A_4_1, A_4_2, A_4_3, A_4_4, A_4_5, A_5_0, A_5_1, A_5_2, A_5_3, A_5_4, A_5_5, B0_0_0, B0_0_1, B0_1_0, B0_1_1, B0_2_0, B0_2_1, B0_5_0, B0_5_1, B_0_0, B_0_1, B_1_0, B_1_1, B_2_0, B_2_1, B_3_0, B_3_1, B_4_0, B_4_1, B_5_0, B_5_1, C0_0_0, C0_0_1, C0_0_2, C0_0_3, C0_1_0, C0_1_1, C0_1_2, C0_1_3, C0_2_0, C0_2_1, C0_2_2, C0_2_3, C0_5_0, C0_5_1, C0_5_2, C0_5_3, C_0_0, C_0_1, C_0_2, C_0_3, C_1_0, C_1_1, C_1_2, C_1_3, C_2_0, C_2_1, C_2_2, C_2_3, C_3_0, C_3_1, C_3_2, C_3_3, C_4_0, C_4_1, C_4_2, C_4_3, C_5_0, C_5_1, C_5_2, C_5_3, D0_0_0, D0_0_1, D0_0_2, D0_0_3, D0_0_5, D_0_0, D_0_1, D_0_2, D_0_3, D_0_4, D_0_5, E0_0_0, E0_0_1, E_0_0, E_0_1, F0_0_0, F0_0_1, F0_0_2, F0_0_3, F_0_0, F_0_1, F_0_2, F_0_3, G0_0_0, G0_0_1, G0_0_2, G0_0_5, G0_1_0, G0_1_1, G0_1_2, G0_1_5, G0_2_0, G0_2_1, G0_2_2, G0_2_5, G0_3_0, G0_3_1, G0_3_2, G0_3_5, GX_0_0, GX_1_1, GX_2_2, GX_3_3, GX_4_4, GX_5_5, G_0_0, G_0_1, G_0_2, G_0_3, G_0_4, G_0_5, G_1_0, G_1_1, G_1_2, G_1_3, G_1_4, G_1_5, G_2_0, G_2_1, G_2_2, G_2_3, G_2_4, G_2_5, G_3_0, G_3_1, G_3_2, G_3_3, G_3_4, G_3_5, H0_0_0, H0_0_1, H0_1_0, H0_1_1, H0_2_0, H0_2_1, H0_3_0, H0_3_1, H_0_0, H_0_1, H_1_0, H_1_1, H_2_0, H_2_1, H_3_0, H_3_1, K0_0_0, K0_0_1, K0_0_2, K0_0_3, K0_1_0, K0_1_1, K0_1_2, K0_1_3, K0_2_0, K0_2_1, K0_2_2, K0_2_3, K0_3_0, K0_3_1, K0_3_2, K0_3_3, K_0_0, K_0_1, K_0_2, K_0_3, K_1_0, K_1_1, K_1_2, K_1_3, K_2_0, K_2_1, K_2_2, K_2_3, K_3_0, K_3_1, K_3_2, K_3_3, Q_0_0, Q_0_1, Q_1_0, Q_1_1, U0_0_0, U0_0_1, UN_0_1, UN_1_1, UN_2_0, UN_2_1, UN_3_1, UU_0_1, UU_1_1, UX_0_1, UX_1_1, UX_2_1, UX_3_0, UX_4_0, UX_4_1, UX_5_1, Ui, x_0_0, x_1_0, x_2_0, x_3_0, x_4_0, x_5_0, xnm1_1, xnm1_2, xnm1_3, xnm1_4, xnm1_5, xnm1_6, y_0_0, l_srate ) local( I1_0_0, I1_0_1, I1_1_0, I1_1_1, T1_0_0, T1_0_1, T1_1_0, T1_1_1, T1_2_0, T1_2_1, T1_3_0, T1_3_1, T1_4_0, T1_4_1, T1_5_0, T1_5_1, U0I1_0_0, U0I1_0_1, UNI1_0_0, UNI1_0_1, UNI1_1_0, UNI1_1_1, UNI1_2_0, UNI1_2_1, UNI1_3_0, UNI1_3_1, alpha, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11 ) ( alpha = filterFreq; t2 = Q_0_0*100000.0000000000000000000000000; t3 = alpha*10000000000.0000000000000000000000000; t4 = Q_0_0*Q_1_1; t5 = Q_1_1*alpha*100000.0000000000000000000000000; t6 = alpha*alpha; t9 = Q_0_1*Q_1_0; t10 = Q_0_0*alpha*100000.0000000000000000000000000; t11 = t6*10000000000.0000000000000000000000000; t7 = t2+t3+t4+t5-t9-t10-t11; t8 = 1.0/t7; I1_0_0 = t8*(Q_1_1-alpha*100000.0000000000000000000000000+100000.0000000000000000000000000); I1_0_1 = -Q_0_1*t8; I1_1_0 = -Q_1_0*t8; I1_1_1 = t8*(Q_0_0+alpha*100000.0000000000000000000000000); T1_0_0 = GX_0_0*I1_1_0*UX_0_1*2.0; T1_0_1 = GX_0_0*I1_1_1*UX_0_1*2.0; T1_1_0 = GX_1_1*I1_1_0*UX_1_1*2.0; T1_1_1 = GX_1_1*I1_1_1*UX_1_1*2.0; T1_2_0 = GX_2_2*I1_1_0*UX_2_1*2.0; T1_2_1 = GX_2_2*I1_1_1*UX_2_1*2.0; T1_3_0 = GX_3_3*I1_0_0*UX_3_0*2.0; T1_3_1 = GX_3_3*I1_0_1*UX_3_0*2.0; T1_4_0 = GX_4_4*I1_0_0*UX_4_0*2.0+GX_4_4*I1_1_0*UX_4_1*2.0; T1_4_1 = GX_4_4*I1_0_1*UX_4_0*2.0+GX_4_4*I1_1_1*UX_4_1*2.0; T1_5_0 = GX_5_5*I1_1_0*UX_5_1*-2.0; T1_5_1 = GX_5_5*I1_1_1*UX_5_1*-2.0; U0I1_0_0 = I1_0_0*U0_0_0+I1_1_0*U0_0_1; U0I1_0_1 = I1_0_1*U0_0_0+I1_1_1*U0_0_1; UNI1_0_0 = I1_1_0*UN_0_1; UNI1_0_1 = I1_1_1*UN_0_1; UNI1_1_0 = I1_1_0*UN_1_1; UNI1_1_1 = I1_1_1*UN_1_1; UNI1_2_0 = I1_0_0*UN_2_0+I1_1_0*UN_2_1; UNI1_2_1 = I1_0_1*UN_2_0+I1_1_1*UN_2_1; UNI1_3_0 = I1_1_0*UN_3_1; UNI1_3_1 = I1_1_1*UN_3_1; A_0_0 = A0_0_0-T1_0_1*UX_0_1; A_0_1 = A0_0_1-T1_0_1*UX_1_1; A_0_2 = A0_0_2-T1_0_1*UX_2_1; A_0_3 = -T1_0_0*UX_3_0; A_0_4 = -T1_0_0*UX_4_0-T1_0_1*UX_4_1; A_0_5 = A0_0_5-T1_0_1*UX_5_1; A_1_0 = A0_1_0-T1_1_1*UX_0_1; A_1_1 = A0_1_1-T1_1_1*UX_1_1; A_1_2 = A0_1_2-T1_1_1*UX_2_1; A_1_3 = -T1_1_0*UX_3_0; A_1_4 = -T1_1_0*UX_4_0-T1_1_1*UX_4_1; A_1_5 = A0_1_5-T1_1_1*UX_5_1; A_2_0 = A0_2_0-T1_2_1*UX_0_1; A_2_1 = A0_2_1-T1_2_1*UX_1_1; A_2_2 = A0_2_2-T1_2_1*UX_2_1; A_2_3 = -T1_2_0*UX_3_0; A_2_4 = -T1_2_0*UX_4_0-T1_2_1*UX_4_1; A_2_5 = A0_2_5-T1_2_1*UX_5_1; A_3_0 = -T1_3_1*UX_0_1; A_3_1 = -T1_3_1*UX_1_1; A_3_2 = -T1_3_1*UX_2_1; A_3_3 = A0_3_3-T1_3_0*UX_3_0; A_3_4 = -T1_3_0*UX_4_0-T1_3_1*UX_4_1; A_3_5 = -T1_3_1*UX_5_1; A_4_0 = -T1_4_1*UX_0_1; A_4_1 = -T1_4_1*UX_1_1; A_4_2 = -T1_4_1*UX_2_1; A_4_3 = -T1_4_0*UX_3_0; A_4_4 = A0_4_4-T1_4_0*UX_4_0-T1_4_1*UX_4_1; A_4_5 = -T1_4_1*UX_5_1; A_5_0 = A0_5_0-T1_5_1*UX_0_1; A_5_1 = A0_5_1-T1_5_1*UX_1_1; A_5_2 = A0_5_2-T1_5_1*UX_2_1; A_5_3 = -T1_5_0*UX_3_0; A_5_4 = -T1_5_0*UX_4_0-T1_5_1*UX_4_1; A_5_5 = A0_5_5-T1_5_1*UX_5_1; B_0_0 = B0_0_0-T1_0_1*UU_0_1; B_0_1 = B0_0_1-T1_0_1*UU_1_1; B_1_0 = B0_1_0-T1_1_1*UU_0_1; B_1_1 = B0_1_1-T1_1_1*UU_1_1; B_2_0 = B0_2_0-T1_2_1*UU_0_1; B_2_1 = B0_2_1-T1_2_1*UU_1_1; B_3_0 = -T1_3_1*UU_0_1; B_3_1 = -T1_3_1*UU_1_1; B_4_0 = -T1_4_1*UU_0_1; B_4_1 = -T1_4_1*UU_1_1; B_5_0 = B0_5_0-T1_5_1*UU_0_1; B_5_1 = B0_5_1-T1_5_1*UU_1_1; C_0_0 = C0_0_0-T1_0_1*UN_0_1; C_0_1 = C0_0_1-T1_0_1*UN_1_1; C_0_2 = C0_0_2-T1_0_0*UN_2_0-T1_0_1*UN_2_1; C_0_3 = C0_0_3-T1_0_1*UN_3_1; C_1_0 = C0_1_0-T1_1_1*UN_0_1; C_1_1 = C0_1_1-T1_1_1*UN_1_1; C_1_2 = C0_1_2-T1_1_0*UN_2_0-T1_1_1*UN_2_1; C_1_3 = C0_1_3-T1_1_1*UN_3_1; C_2_0 = C0_2_0-T1_2_1*UN_0_1; C_2_1 = C0_2_1-T1_2_1*UN_1_1; C_2_2 = C0_2_2-T1_2_0*UN_2_0-T1_2_1*UN_2_1; C_2_3 = C0_2_3-T1_2_1*UN_3_1; C_3_0 = -T1_3_1*UN_0_1; C_3_1 = -T1_3_1*UN_1_1; C_3_2 = -T1_3_0*UN_2_0-T1_3_1*UN_2_1; C_3_3 = -T1_3_1*UN_3_1; C_4_0 = -T1_4_1*UN_0_1; C_4_1 = -T1_4_1*UN_1_1; C_4_2 = -T1_4_0*UN_2_0-T1_4_1*UN_2_1; C_4_3 = -T1_4_1*UN_3_1; C_5_0 = C0_5_0-T1_5_1*UN_0_1; C_5_1 = C0_5_1-T1_5_1*UN_1_1; C_5_2 = C0_5_2-T1_5_0*UN_2_0-T1_5_1*UN_2_1; C_5_3 = C0_5_3-T1_5_1*UN_3_1; D_0_0 = D0_0_0-U0I1_0_1*UX_0_1; D_0_1 = D0_0_1-U0I1_0_1*UX_1_1; D_0_2 = D0_0_2-U0I1_0_1*UX_2_1; D_0_3 = D0_0_3-U0I1_0_0*UX_3_0; D_0_4 = -U0I1_0_0*UX_4_0-U0I1_0_1*UX_4_1; D_0_5 = D0_0_5-U0I1_0_1*UX_5_1; E_0_0 = E0_0_0-U0I1_0_1*UU_0_1; E_0_1 = E0_0_1-U0I1_0_1*UU_1_1; F_0_0 = F0_0_0-U0I1_0_1*UN_0_1; F_0_1 = F0_0_1-U0I1_0_1*UN_1_1; F_0_2 = F0_0_2-U0I1_0_0*UN_2_0-U0I1_0_1*UN_2_1; F_0_3 = F0_0_3-U0I1_0_1*UN_3_1; G_0_0 = G0_0_0-UNI1_0_1*UX_0_1; G_0_1 = G0_0_1-UNI1_0_1*UX_1_1; G_0_2 = G0_0_2-UNI1_0_1*UX_2_1; G_0_3 = -UNI1_0_0*UX_3_0; G_0_4 = -UNI1_0_0*UX_4_0-UNI1_0_1*UX_4_1; G_0_5 = G0_0_5-UNI1_0_1*UX_5_1; G_1_0 = G0_1_0-UNI1_1_1*UX_0_1; G_1_1 = G0_1_1-UNI1_1_1*UX_1_1; G_1_2 = G0_1_2-UNI1_1_1*UX_2_1; G_1_3 = -UNI1_1_0*UX_3_0; G_1_4 = -UNI1_1_0*UX_4_0-UNI1_1_1*UX_4_1; G_1_5 = G0_1_5-UNI1_1_1*UX_5_1; G_2_0 = G0_2_0-UNI1_2_1*UX_0_1; G_2_1 = G0_2_1-UNI1_2_1*UX_1_1; G_2_2 = G0_2_2-UNI1_2_1*UX_2_1; G_2_3 = -UNI1_2_0*UX_3_0; G_2_4 = -UNI1_2_0*UX_4_0-UNI1_2_1*UX_4_1; G_2_5 = G0_2_5-UNI1_2_1*UX_5_1; G_3_0 = G0_3_0-UNI1_3_1*UX_0_1; G_3_1 = G0_3_1-UNI1_3_1*UX_1_1; G_3_2 = G0_3_2-UNI1_3_1*UX_2_1; G_3_3 = -UNI1_3_0*UX_3_0; G_3_4 = -UNI1_3_0*UX_4_0-UNI1_3_1*UX_4_1; G_3_5 = G0_3_5-UNI1_3_1*UX_5_1; H_0_0 = H0_0_0-UNI1_0_1*UU_0_1; H_0_1 = H0_0_1-UNI1_0_1*UU_1_1; H_1_0 = H0_1_0-UNI1_1_1*UU_0_1; H_1_1 = H0_1_1-UNI1_1_1*UU_1_1; H_2_0 = H0_2_0-UNI1_2_1*UU_0_1; H_2_1 = H0_2_1-UNI1_2_1*UU_1_1; H_3_0 = H0_3_0-UNI1_3_1*UU_0_1; H_3_1 = H0_3_1-UNI1_3_1*UU_1_1; K_0_0 = K0_0_0-UNI1_0_1*UN_0_1; K_0_1 = K0_0_1-UNI1_0_1*UN_1_1; K_0_2 = K0_0_2-UNI1_0_0*UN_2_0-UNI1_0_1*UN_2_1; K_0_3 = K0_0_3-UNI1_0_1*UN_3_1; K_1_0 = K0_1_0-UNI1_1_1*UN_0_1; K_1_1 = K0_1_1-UNI1_1_1*UN_1_1; K_1_2 = K0_1_2-UNI1_1_0*UN_2_0-UNI1_1_1*UN_2_1; K_1_3 = K0_1_3-UNI1_1_1*UN_3_1; K_2_0 = K0_2_0-UNI1_2_1*UN_0_1; K_2_1 = K0_2_1-UNI1_2_1*UN_1_1; K_2_2 = K0_2_2-UNI1_2_0*UN_2_0-UNI1_2_1*UN_2_1; K_2_3 = K0_2_3-UNI1_2_1*UN_3_1; K_3_0 = K0_3_0-UNI1_3_1*UN_0_1; K_3_1 = K0_3_1-UNI1_3_1*UN_1_1; K_3_2 = K0_3_2-UNI1_3_0*UN_2_0-UNI1_3_1*UN_2_1; K_3_3 = K0_3_3-UNI1_3_1*UN_3_1; ); function dlop_vclamp(v) instance() global() local(Is, mxmx, q) ( Is = 0.0000000000000203000000000; mxmx = .001; q = Is*(exp(v)+.0000000000001); q < mxmx ? q : min(q,mxmx) ); function dlop_res(i1, i2, i3, i4) global() instance( df0Trial, df1Trial, df2Trial, df3Trial, J_0_0, J_0_1, J_0_2, J_0_3, J_1_0, J_1_1, J_1_2, J_1_3, J_2_0, J_2_1, J_2_2, J_2_3, J_3_0, J_3_1, J_3_2, J_3_3, p_0_0, p_1_0, p_2_0, p_3_0, K_0_0, K_0_1, K_0_2, K_0_3, K_1_0, K_1_1, K_1_2, K_1_3, K_2_0, K_2_1, K_2_2, K_2_3, K_3_0, K_3_1, K_3_2, K_3_3, v1, v2, v3, v4, beta_f, beta_r, Is, mv, mxmx, ) local( r500d13, t2, t3, t4, t5, t6, t7, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t29, t30, t31, t32, t33, t34, t35, t36, t37, t38, t39, t40, t41, t42, t43, t44, t45, t46, t47, t48, t49, t50, t51, t52, t53, t54, t55, t56, t9I, t12I, t29I, t31I, ) ( r500d13 = 500/13; beta_r = 4; beta_f = 1430; Is = 0.0000000000000203000000000; mxmx = .001; t2 = r500d13; t3 = K_0_0*i1; t4 = K_0_1*i2; t5 = K_0_2*i3; t6 = K_0_3*i4; t7 = 1.0/beta_r; v1 = p_0_0+t3+t4+t5+t6; t13 = t2*v1; t9I = dlop_vclamp(-t13); t10 = 1.0/beta_f; t14 = K_1_0*i1; t15 = K_1_1*i2; t16 = K_1_2*i3; t17 = K_1_3*i4; v2 = p_1_0+t14+t15+t16+t17; t11 = (v1-v2); t18 = t2*t11; t12I = dlop_vclamp(-t18); t19 = K_0_0-K_1_0; t20 = K_0_1-K_1_1; t21 = beta_r-1.0; t22 = K_0_2-K_1_2; t23 = K_0_3-K_1_3; t24 = K_2_0*i1; t25 = K_2_1*i2; t26 = K_2_2*i3; t27 = K_2_3*i4; v3 = p_2_0+t24+t25+t26+t27; t32 = t2*v3; t29I = dlop_vclamp(-t32); t33 = K_3_0*i1; t34 = K_3_1*i2; t35 = K_3_2*i3; t36 = K_3_3*i4; v4 = p_3_0+t33+t34+t35+t36; t30 = (v3-v4); t37 = t2*t30; t31I = dlop_vclamp(-t37); t38 = K_2_0-K_3_0; t39 = K_2_1-K_3_1; t40 = K_2_2-K_3_2; t41 = K_2_3-K_3_3; t42 = t12I-Is; t43 = t9I-Is; t44 = t31I-Is; t45 = t29I-Is; J_0_0 = -(K_0_0*t2*t7*t9I+t2*t10*t12I*t19)-1.0; J_0_1 = -(K_0_1*t2*t7*t9I+t2*t10*t12I*t20); J_0_2 = -(K_0_2*t2*t7*t9I+t2*t10*t12I*t22); J_0_3 = -(K_0_3*t2*t7*t9I+t2*t10*t12I*t23); J_1_0 = (t2*t12I*t19-K_0_0*t2*t7*t9I*t21); J_1_1 = (t2*t12I*t20-K_0_1*t2*t7*t9I*t21)-1.0; J_1_2 = (t2*t12I*t22-K_0_2*t2*t7*t9I*t21); J_1_3 = (t2*t12I*t23-K_0_3*t2*t7*t9I*t21); J_2_0 = -(K_2_0*t2*t7*t29I+t2*t10*t31I*t38); J_2_1 = -(K_2_1*t2*t7*t29I+t2*t10*t31I*t39); J_2_2 = -(K_2_2*t2*t7*t29I+t2*t10*t31I*t40)-1.0; J_2_3 = -(K_2_3*t2*t7*t29I+t2*t10*t31I*t41); J_3_0 = (t2*t31I*t38-K_2_0*t2*t7*t21*t29I); J_3_1 = (t2*t31I*t39-K_2_1*t2*t7*t21*t29I); J_3_2 = (t2*t31I*t40-K_2_2*t2*t7*t21*t29I); J_3_3 = (t2*t31I*t41-K_2_3*t2*t7*t21*t29I)-1.0; df0Trial = -i1 + t7*t43 + t10*t42; df1Trial = -i2 - t42 + t7*t21*t43; df2Trial = -i3 + t7*t45 + t10*t44; df3Trial = -i4 - t44 + t7*t21*t45; ); function dlop_eval( Ui ) global() instance( A0_0_0, A0_0_1, A0_0_2, A0_0_5, A0_1_0, A0_1_1, A0_1_2, A0_1_5, A0_2_0, A0_2_1, A0_2_2, A0_2_5, A0_3_3, A0_4_4, A0_5_0, A0_5_1, A0_5_2, A0_5_5, A_0_0, A_0_1, A_0_2, A_0_3, A_0_4, A_0_5, A_1_0, A_1_1, A_1_2, A_1_3, A_1_4, A_1_5, A_2_0, A_2_1, A_2_2, A_2_3, A_2_4, A_2_5, A_3_0, A_3_1, A_3_2, A_3_3, A_3_4, A_3_5, A_4_0, A_4_1, A_4_2, A_4_3, A_4_4, A_4_5, A_5_0, A_5_1, A_5_2, A_5_3, A_5_4, A_5_5, B0_0_0, B0_0_1, B0_1_0, B0_1_1, B0_2_0, B0_2_1, B0_5_0, B0_5_1, B_0_0, B_0_1, B_1_0, B_1_1, B_2_0, B_2_1, B_3_0, B_3_1, B_4_0, B_4_1, B_5_0, B_5_1, C0_0_0, C0_0_1, C0_0_2, C0_0_3, C0_1_0, C0_1_1, C0_1_2, C0_1_3, C0_2_0, C0_2_1, C0_2_2, C0_2_3, C0_5_0, C0_5_1, C0_5_2, C0_5_3, C_0_0, C_0_1, C_0_2, C_0_3, C_1_0, C_1_1, C_1_2, C_1_3, C_2_0, C_2_1, C_2_2, C_2_3, C_3_0, C_3_1, C_3_2, C_3_3, C_4_0, C_4_1, C_4_2, C_4_3, C_5_0, C_5_1, C_5_2, C_5_3, D0_0_0, D0_0_1, D0_0_2, D0_0_3, D0_0_5, D_0_0, D_0_1, D_0_2, D_0_3, D_0_4, D_0_5, E0_0_0, E0_0_1, E_0_0, E_0_1, F0_0_0, F0_0_1, F0_0_2, F0_0_3, F_0_0, F_0_1, F_0_2, F_0_3, G0_0_0, G0_0_1, G0_0_2, G0_0_5, G0_1_0, G0_1_1, G0_1_2, G0_1_5, G0_2_0, G0_2_1, G0_2_2, G0_2_5, G0_3_0, G0_3_1, G0_3_2, G0_3_5, GX_0_0, GX_1_1, GX_2_2, GX_3_3, GX_4_4, GX_5_5, G_0_0, G_0_1, G_0_2, G_0_3, G_0_4, G_0_5, G_1_0, G_1_1, G_1_2, G_1_3, G_1_4, G_1_5, G_2_0, G_2_1, G_2_2, G_2_3, G_2_4, G_2_5, G_3_0, G_3_1, G_3_2, G_3_3, G_3_4, G_3_5, H0_0_0, H0_0_1, H0_1_0, H0_1_1, H0_2_0, H0_2_1, H0_3_0, H0_3_1, H_0_0, H_0_1, H_1_0, H_1_1, H_2_0, H_2_1, H_3_0, H_3_1, K0_0_0, K0_0_1, K0_0_2, K0_0_3, K0_1_0, K0_1_1, K0_1_2, K0_1_3, K0_2_0, K0_2_1, K0_2_2, K0_2_3, K0_3_0, K0_3_1, K0_3_2, K0_3_3, K_0_0, K_0_1, K_0_2, K_0_3, K_1_0, K_1_1, K_1_2, K_1_3, K_2_0, K_2_1, K_2_2, K_2_3, K_3_0, K_3_1, K_3_2, K_3_3, Q_0_0, Q_0_1, Q_1_0, Q_1_1, U0_0_0, U0_0_1, UN_0_1, UN_1_1, UN_2_0, UN_2_1, UN_3_1, UU_0_1, UU_1_1, UX_0_1, UX_1_1, UX_2_1, UX_3_0, UX_4_0, UX_4_1, UX_5_1, // States x_0_0, x_1_0, x_2_0, x_3_0, x_4_0, x_5_0, Ui, xh0, xh1, xh2, xh3, xh4, xh5 i1, i2, i3, i4, // Trial residual df0Trial, df1Trial, df2Trial, df3Trial, // Trial currents i1Trial, i2Trial, i3Trial, i4Trial, // Jacobian J_0_0, J_0_1, J_0_2, J_0_3, J_1_0, J_1_1, J_1_2, J_1_3, J_2_0, J_2_1, J_2_2, J_2_3, J_3_0, J_3_1, J_3_2, J_3_3, // Transformed state p_0_0, p_1_0, p_2_0, p_3_0, // Current residual df0, df1, df2, df3, output, // Step step1, step2, step3, step4, diff, step, nRej, err, newErr, iter ) local(r163d20, r500d13, // Temporary storage for the inverse x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32, x33, x34, x35, x36 ) ( r163d20 = 163/20; r500d13 = 500/13; //this.reset_dlop(); Ui = tanh(Ui); p_0_0 = H_0_1*r163d20+G_0_0*xh0+G_0_1*xh1+G_0_2*xh2+G_0_3*xh3+G_0_4*xh4+G_0_5*xh5+H_0_0*Ui; p_1_0 = H_1_1*r163d20+G_1_0*xh0+G_1_1*xh1+G_1_2*xh2+G_1_3*xh3+G_1_4*xh4+G_1_5*xh5+H_1_0*Ui; p_2_0 = H_2_1*r163d20+G_2_0*xh0+G_2_1*xh1+G_2_2*xh2+G_2_3*xh3+G_2_4*xh4+G_2_5*xh5+H_2_0*Ui; p_3_0 = H_3_1*r163d20+G_3_0*xh0+G_3_1*xh1+G_3_2*xh2+G_3_3*xh3+G_3_4*xh4+G_3_5*xh5+H_3_0*Ui; // Calculate residual and Jacobian this.dlop_res(i1, i2, i3, i4); df0 = df0Trial; df1 = df1Trial; df2 = df2Trial; df3 = df3Trial; err = abs(df0) + abs(df1) + abs(df2) + abs(df3); step = 1; nRej = 0; iter = 0; while( iter < 35 && err > 0.00001 ) ( // Calculate inverse x0 = J_0_0*J_1_1; x1 = -J_0_1*J_1_0 + x0; x2 = J_0_0*J_1_3 - J_0_3*J_1_0; x3 = J_0_0*J_1_2 - J_0_2*J_1_0; x4 = J_0_0*J_2_1 - J_0_1*J_2_0; x5 = x3*x4; x6 = x1*(J_0_0*J_2_2 - J_0_2*J_2_0) - x5; x7 = -J_0_1*x3 + J_0_2*x1; x8 = x1*(J_0_0*J_2_3 - J_0_3*J_2_0) - x2*x4; x9 = x6*(-J_0_1*x2 + J_0_3*x1) - x7*x8; x10 = J_0_0*J_3_1 - J_0_1*J_3_0; x11 = x1*(J_0_0*J_3_2 - J_0_2*J_3_0) - x10*x3; x12 = x11*x8; x13 = -x12 + x6*(x1*(J_0_0*J_3_3 - J_0_3*J_3_0) - x10*x2); x14 = 1.0/x13; x15 = df3*x14; x16 = 1.0/J_0_0; x17 = J_0_0*x1; x18 = x11*x17; x19 = x13*x17; x20 = 1.0/x1; x21 = 1.0/x6; x22 = df2*x14; x23 = x21*x22; x24 = x20*x23; x25 = J_0_0*x4; x26 = J_0_0*x6; x27 = -x10*x26 + x11*x25; x28 = df1*x14; x29 = x21*x28; x30 = x20*x29; x31 = J_1_0*x4 - J_2_0*x1; x32 = -x11*x31 + x6*(J_1_0*x10 - J_3_0*x1); x33 = df0*x14; x34 = x21*x33; x35 = x20*x34; x36 = x2*x6 - x3*x8; // Calculate next trial point step1 = x15*x9 - x16*x24*(x18*x9 - x19*x7) - x16*x30*(x13*(-J_0_1*x26 + x25*x7) - x27*x9) - x16*x35*(x13*(x0*x6 - x31*x7) - x32*x9); step2 = J_0_0*x15*x36 - x24*(x18*x36 - x19*x3) - x30*(x13*(J_0_0*x5 + x26) - x27*x36) - x35*(x13*(-J_1_0*x6 - x3*x31) - x32*x36); step3 = x15*x17*x8 - x23*(x12*x17 + x19) - x29*(-x13*x25 - x27*x8) - x34*(x13*x31 - x32*x8); step4 = -x1*x15*x26 + x18*x22 - x27*x28 - x32*x33; i1Trial = i1 + step1; i2Trial = i2 + step2; i3Trial = i3 + step3; i4Trial = i4 + step4; // Calculate residual at new trial point this.dlop_res(i1Trial, i2Trial, i3Trial, i4Trial); newErr = abs(df0Trial) + abs(df1Trial) + abs(df2Trial) + abs(df3Trial); // Did we get closer to the solution? newErr < err ? ( // Accept step i1 = i1Trial; i2 = i2Trial; i3 = i3Trial; i4 = i4Trial; df0 = df0Trial; df1 = df1Trial; df2 = df2Trial; df3 = df3Trial; err = newErr; step = min(1, step*2); ) : ( // Reject step and lower stepsize step = step * .5; nRej += 1; ); iter += 1; ); output = E_0_1*r163d20+F_0_0*i1+F_0_1*i2+F_0_2*i3+F_0_3*i4+D_0_0*xh0+D_0_1*xh1+D_0_2*xh2+D_0_3*xh3+D_0_4*xh4+D_0_5*xh5+E_0_0*Ui; x_0_0 = B_0_1*r163d20+C_0_0*i1+C_0_1*i2+C_0_2*i3+C_0_3*i4+A_0_0*xh0+A_0_1*xh1+A_0_2*xh2+A_0_3*xh3+A_0_4*xh4+A_0_5*xh5+B_0_0*Ui; x_1_0 = B_1_1*r163d20+C_1_0*i1+C_1_1*i2+C_1_2*i3+C_1_3*i4+A_1_0*xh0+A_1_1*xh1+A_1_2*xh2+A_1_3*xh3+A_1_4*xh4+A_1_5*xh5+B_1_0*Ui; x_2_0 = B_2_1*r163d20+C_2_0*i1+C_2_1*i2+C_2_2*i3+C_2_3*i4+A_2_0*xh0+A_2_1*xh1+A_2_2*xh2+A_2_3*xh3+A_2_4*xh4+A_2_5*xh5+B_2_0*Ui; x_3_0 = B_3_1*r163d20+C_3_0*i1+C_3_1*i2+C_3_2*i3+C_3_3*i4+A_3_0*xh0+A_3_1*xh1+A_3_2*xh2+A_3_3*xh3+A_3_4*xh4+A_3_5*xh5+B_3_0*Ui; x_4_0 = B_4_1*r163d20+C_4_0*i1+C_4_1*i2+C_4_2*i3+C_4_3*i4+A_4_0*xh0+A_4_1*xh1+A_4_2*xh2+A_4_3*xh3+A_4_4*xh4+A_4_5*xh5+B_4_0*Ui; x_5_0 = B_5_1*r163d20+C_5_0*i1+C_5_1*i2+C_5_2*i3+C_5_3*i4+A_5_0*xh0+A_5_1*xh1+A_5_2*xh2+A_5_3*xh3+A_5_4*xh4+A_5_5*xh5+B_5_0*Ui; xh0 = x_0_0; xh1 = x_1_0; xh2 = x_2_0; xh3 = x_3_0; xh4 = x_4_0; xh5 = x_5_0; output ); function reset_dlop() instance(i1,i2,i3,i4,xh0, xh1, xh2, xh3, xh4, xh5, xh6) ( i1 = .00000011; i2 = -.00016; i3 = .00000026; i4 = -.000373; xh0 = 0.0011; xh1 = 0.54; xh2 = -0.005; xh3 = 0.173; xh4 = -0.168; xh5 = 0.000002; ); function reset_dlopH() instance(i1,i2,i3,i4,xh0, xh1, xh2, xh3, xh4, xh5, xh6) ( i1 = .00000011; i2 = -.00016; i3 = .00000026; i4 = -.000373; xh0 = 0.0004; xh1 = 0.2715; xh2 = -0.0026; xh3 = 0.086; xh4 = -0.084; xh5 = 0.000002; ); function reset_dlopL() instance(i1,i2,i3,i4,xh0, xh1, xh2, xh3, xh4, xh5, xh6) ( i1 = .00000011; i2 = -.00016; i3 = .00000026; i4 = -.000373; xh0 = 0.002; xh1 = 1.085; xh2 = -0.0106; xh3 = 0.346; xh4 = -0.336; xh5 = 0.000006; ); function reset_wasplin() global() local() instance(U0, U1, Di, D0, D1, x0, x1, x2, x3, i1) ( U0 = U1 = Di = D0 = D1 = x0 = x1 = x2 = x3 = i1 = 0; ); function resetphaserFET() global() local() instance(C1, C2, dw, dx, thresh, iVpsq, IDSSdivVpSq, thresh) ( dw = dx = 0; ); // Generate windowed sinc filter at memory location FIR // Inputs are: // fir - Memory location to store windowed sinc // nt - Number of taps // bw - Fractional bandwidth // g - Gain function sinc(fir, nt, bw, g) local(a, ys, yg, yw, i, pibw2, pifc2, pidnt2, hnt) global() ( pibw2 = 2.0*$pi*bw; pidnt2 = 2.0*$pi/nt; hnt = 0.5*nt; i = 1; loop(nt-1, // Sinc width a = (i - hnt) * pibw2; // Sinc ys = (a != 0) ? sin(a)/a : 1.0; // Window gain yg = g * (4.0 * bw); // Hamming window (could be replaced with Kaiser in the future) yw = 0.54 - 0.46 * cos(i * pidnt2); // Calc FIR coeffs fir[i-1] = yw * yg * ys; i += 1; ); ); // Generate sinc filters for a specific upsampling ratio // // Upsampling leads to a sample followed by N-1 zeroes. Hence // to compute each subsample, we only need 1/Nth of the taps. // This is why we set up a specific filter for each subsample. // i.e. for N=4, you get something like f1*Zn + f5*Zn-1 + ... // // Inputs: // N_in - oversampling factor // tapsPerFilter - Taps per subfilter (should be 8 in this implementation) // targetmem - Location to store the coefficients // tmp - Working memory function updateSincFilter(N_in, tapsPerFilter, targetmem, tmp) local(nHist, iFilt, nTaps) instance(h0, h1, h2, h3, h4, h5, h6, coeffs, loc, N, delta) global() ( N = N_in; nHist = tapsPerFilter; loc = 0; coeffs = targetmem; nTaps = N*nHist; // Memory being set is conservatively large. memset(coeffs,0,10000); memset(tmp,0,10000); sinc(tmp, nTaps, .5/N, .5*N); // Divide sinc over the different filters iFilt = 0; // Filter idx for which subsample this filter is delta = 0; // Sample idx loop(nTaps, coeffs[delta + iFilt*100] = tmp[]; iFilt += 1; iFilt == N ? ( iFilt = 0; delta += 1 ); tmp += 1; ); ); // Generate downsample filter // Here, the full N*nHist tap filter has to be evaluated for every sample, // but only every Nth sample has to be evaluated. function updateSincDownsampleFilter(N_in, nTaps_in, histmem, coeffmem) global() instance(hist, hend, hptr, coeffs, loc, N, delta, nTaps) local() ( N = N_in; hist = histmem; coeffs = coeffmem; nTaps = nTaps_in; hptr = hist; hend = hist + nTaps; memset(coeffs,0,10000); sinc(coeffs, nTaps, .5/N, .5); ); function advanceHist(sample) global() instance(hist, hptr, hend, coeffs, loc, N, delta, nTaps) local(nHist, nTaps) ( hptr += 1; ( hptr == hend ) ? hptr = hist; hptr[] = sample; ); function sincDownSample() global() instance(hist, hptr, hend, coeffs, loc, N, delta, nTaps) local(nHist, hm1, hptr2, out, cfptr) ( hm1 = hist-1; hptr2 = hptr; cfptr = coeffs; out = 0; loop(nTaps, out = out + hptr2[] * cfptr[]; cfptr += 1; hptr2 -= 1; ( hptr2 == hm1 ) ? hptr2 = hend-1; ); out ); function resetSincDown() global() instance(hist, hptr, hend, coeffs, loc, N, delta, nTaps) local(nHist, hm1, hptr2) ( hm1 = hist-1; hptr2 = hptr; loop(nTaps, hptr2[] = 0; hptr2 -= 1; ( hptr2 == hm1 ) ? hptr2 = hend-1; ); ); // Maintain input sample history. Hardcoded for speed. // Note h7 is omitted because for integer upsampling it is always zero! function advanceSinc(sample) instance(h0, h1, h2, h3, h4, h5, h6, coeffs, loc, N) global() local(filt) ( h6 = h5; h5 = h4; h4 = h3; h3 = h2; h2 = h1; h1 = h0; h0 = sample; loc = 0; ); function resetSincUp() instance(h0, h1, h2, h3, h4, h5, h6, coeffs, loc, N) global() local(filt) ( h0 = h1 = h2 = h3 = h4 = h5 = h6 = 0; ); // Note h7 is omitted because for integer upsampling it is always zero! function getSubSample() instance(h0, h1, h2, h3, h4, h5, h6, coeffs, loc, N) global() local(filt, out) ( filt = coeffs + loc; //out = filt[] * h0 + (filt+=1)[] * h1 + (filt+=1)[] * h2 + (filt+=1)[] * h3 + (filt+=1)[] * h4 + (filt+=1)[] * h5 + (filt+=1)[] * h6; out = filt[] * h0 + filt[1] * h1 + filt[2] * h2 + filt[3] * h3 + filt[4] * h4 + filt[5] * h5 + filt[6] * h6; loc += 100; out ); // IIR RBJ based up/down sampling function updateFilter(newlen) instance(len, d1, d2, d3, d4, o1, o2, o3, o4, a1, a2, b0, b1, b2) local (Q, sc, pos, cpos, spos, alpha) global () ( ( newlen != len ) ? ( len = newlen; Q = 0.707; pos = 0.85 / len * $pi; cpos = cos(pos); spos = sin(pos); alpha = spos/(2.0*Q); sc = 1.0 / (1+alpha); a1 = -2 * cpos * sc; a2 = (1-alpha) * sc; b1 = (1-cpos) * sc; b2 = b0 = b1 * 0.5; // Input taps d1 = d2 = d3 = d4 = 0; // Output taps o1 = o2 = o3 = o4 = 0; ) ); function inputFilter(sample) instance(len, d1, d2, d3, d4, o1, o2, o3, o4, a1, a2, b0, b1, b2) local (out) global () ( out = sample*b0 + d1*b1 + d2*b2 - d3*a1 - d4*a2; d2 = d1; d1 = sample; d4 = d3; d3 = out; ); function resetioFilter() instance(len, d1, d2, d3, d4, o1, o2, o3, o4, a1, a2, b0, b1, b2) local (out) global () ( d1 = d2 = d3 = d4 = o1 = o2 = o3 = o4 = 0; ); function outputFilter(sample) instance(len, d1, d2, d3, d4, o1, o2, o3, o4, a1, a2, b0, b1, b2) local (out) global () ( out = sample*b0 + o1*b1 + o2*b2 - o3*a1 - o4*a2; o2 = o1; o1 = sample; o4 = o3; o3 = out; ); function getTuning(filterChoice, lastNote, cutoff) local(refNote, scalar, approxNoteFrequency, tmp) global(srate) instance() ( refNote = lastNote-69+9+24; ( filterChoice == 1 ) ? ( approxNoteFrequency = ( log( 2^(refNote/12)*(440/srate) ) + log(256*$pi) ) / ( 8 * log(2) ); ) : ( filterChoice == 2 ) ? ( tmp = 10^-cutoff; approxNoteFrequency = log( tmp + ( 1 - tmp ) * 2^(refNote/12) ) / log(10); ) : ( filterChoice == 3 ) ? ( // Note follow makes no sense in vowel context approxNoteFrequency = 0; ) : ( filterChoice == 4 ) ? ( approxNoteFrequency = ( log( 2^(refNote/12)*(4*440/srate) ) + log(256*$pi) ) / ( 8 * log(2) ); ) : ( filterChoice == 5 ) ? ( approxNoteFrequency = ( log( 2^(refNote/12)*(4*440/srate) ) + log(256*$pi) ) / ( 8 * log(2) ); ) : ( filterChoice > 5 && filterChoice < 16 ) ? ( tmp = 10^-cutoff; approxNoteFrequency = log( tmp + ( 1 - tmp ) * 2^(refNote/12) ) / log(10); ) : ( filterChoice == 16 ) ? ( approxNoteFrequency = 0; ) : ( filterChoice == 17 ) ? ( approxNoteFrequency = 0; ) : ( filterChoice > 17 && filterChoice < 24 ) ? ( tmp = 10^-cutoff; approxNoteFrequency = log( tmp + ( 1 - tmp ) * 2^(refNote/12) ) / log(10); ) : ( filterChoice == 24 ) ? ( approxNoteFrequency = 0; // Experimental (untuneable) ) : ( filterChoice > 24 && filterChoice < 31 ) ? ( tmp = 10^-cutoff; approxNoteFrequency = log( tmp + ( 1 - tmp ) * 2^(refNote/12) ) / log(10); ) : ( filterChoice == 31 ) ? ( approxNoteFrequency = 0;//2^(refNote/12); // Unclear, no resonant peak ) : ( filterChoice == 32 ) ? ( approxNoteFrequency = 0; // Unclear, no resonant peak ) : ( filterChoice > 32 ) ? ( // SVF pitch function (derivation) // tmp = .5 * ( ( pow(10, cutoff) - 1 ) / 9 ) * srate; // scalar = 9*tmp/(.5*srate); // approxNoteFrequency = log( 10^(-cutoff)* (scalar*2^(refNote/12)+1) ) / log(10); // approxNoteFrequency = log( 10^(-cutoff) * ((10^cutoff - 1)*2^(refNote/12)+1) ) / log(10); tmp = 10^-cutoff; approxNoteFrequency = log( tmp + ( 1 - tmp ) * 2^(refNote/12) ) / log(10); ); approxNoteFrequency; ); function getHz(filterChoice, f) global(srate, slider54, lastFilterReso, lastFilterFreq, hzin) local(outHz, f) instance() ( outHz = 0; hzin = f; ( filterChoice == 1 ) ? ( outHz = pow(0.5, (128-f*128) / 16.0)*srate/$pi; ) : ( filterChoice == 2 ) ? ( // filterFreq = max(filterFreq, 0.005); outHz = 0; ) : ( filterChoice == 3 ) ? ( outHz = 0; ) : ( filterChoice == 4 ) ? ( // filterFreq = max(filterFreq, 0.005); outHz = 0; ) : ( filterChoice == 5 ) ? ( // filterFreq = max(filterFreq, 0.005); outHz = 0; ) : ( filterChoice == 6 ) ? ( f = max(f, 0.003); outHz = srate * (pow(10, f)-1)/9 / 2.185; // dualFilt LP ) : ( filterChoice == 7 ) ? ( f = max(f, 0.003); outHz = srate * (pow(10, f)-1)/9 / 2.25; // dualFilt HP ) : ( filterChoice == 8 ) ? ( f = max(f, 0.003); outHz = srate * (pow(10, f)-1)/9 / 2.058; // dualFilt BP ) : ( filterChoice == 9 || filterChoice == 10 ) ? ( f = max(f, 0.003); outHz = srate * (pow(10, f)-1)/9 / 1.75; // moogs ) : ( filterChoice == 11 ) ? ( f = max(f, 0.003); outHz = .5 * srate * (pow(10, f)-1)/9; // notch ) : ( filterChoice == 12 ) ? ( outHz = 1111*(pow(10, f)-1)/9 + 440; // narsty ) : ( filterChoice == 13 ) ? ( outHz = 0; // modulator ) : ( filterChoice == 14 ) ? ( outHz = 0; // Phaser ) : ( filterChoice == 15 ) ? ( outHz=.025*f*srate; // Phaser ) : ( filterChoice == 16 ) ? ( outHz = 0; ) : ( filterChoice == 17 ) ? ( outHz = 0; ) : ( filterChoice == 18 ) ? ( f = max(f, 0.003); outHz = .5 * srate * (pow(10, f)-1)/9; // ms-20 linear ) : ( filterChoice == 19 ) ? ( f = max(f, 0.003); outHz = .5 * srate * (pow(10, f)-1)/9; // ms-20 linear ) : ( filterChoice == 20 ) ? ( f = max(f, 0.003); outHz = .5 * srate * (pow(10, f)-1)/9; // ms-20 linear ) : ( filterChoice == 21 ) ? ( f = max(f, 0.006); outHz = .227 * srate * (pow(10, f)-1)/9; // ms-20 non-linear LP ) : ( filterChoice == 22 ) ? ( f = max(f, 0.004); outHz = .227 * srate * (pow(10, f)-1)/9; // ms-20 non-linear BP ) : ( filterChoice == 23 ) ? ( f = max(f, 0.004); outHz = .227 * srate * (pow(10, f)-1)/9; // ms-20 non-linear HP ) : ( filterChoice == 24 ) ? ( outHz = 0; // Experimental (untuneable) ) : ( filterChoice == 25 ) ? ( f = max(f, 0.004); outHz = .215 * srate * (pow(10, f)-1)/9; // strange thing based on ms-20 ) : ( filterChoice == 26 ) ? ( f = max(f, 0.0045); outHz = 2 * .203 * srate * (pow(10, f)-1)/9; // ssm ) : ( filterChoice == 27 ) ? ( f = max(f, 0.0045); outHz = 2 * .203 * srate * (pow(10, f)-1)/9; // ssm ) : ( filterChoice == 28 ) ? ( f = max(f, 0.007); outHz = 2 * .3333 * srate * (pow(10, f)-1)/9; // cem (very approximate) ) : ( filterChoice == 29 ) ? ( f = max(f, 0.01); outHz = .444 * srate * (pow(10, f)-1)/9; // ssm linear ) : ( filterChoice == 30 ) ? ( f = max(f, 0.01); outHz = .716 * srate * (pow(10, f)-1)/9; // cem linear ) : ( filterChoice == 31 ) ? ( outHz = 0; // Unclear, no resonant peak ) : ( filterChoice == 32 ) ? ( outHz = 0; // Unclear, no resonant peak ) : ( filterChoice == 33 ) ? ( f = max(f, 0.007); outHz = 0.135 * srate * (pow(10, f)-1)/9; // very rough (poorly tuned) ) : ( filterChoice == 34 ) ? ( // filterFreq = max(filterFreq, 0.004); outHz = 0; // Too inaccurate ) : ( filterChoice == 35 ) ? ( //filterFreq = max(filterFreq, 0.0048); outHz = 0; // Too inaccurate ) : ( filterChoice == 36 ) ? ( outHz = .77 * srate * ( ( pow(10, f) - 1 ) / 9 ); // Wasp linear ) : ( filterChoice == 37 ) ? ( // filterFreq = max(filterFreq, 0.006); outHz = 0; // Too inaccurate ) : ( filterChoice == 38 ) ? ( // filterFreq = max(filterFreq, 0.006); outHz = 0; // Too inaccurate ) : ( ( filterChoice > 38 ) && ( filterChoice < 44 ) ) ? ( f = max(f, 0.0035); outHz = .5 * ( ( pow(10, f) - 1 ) / 9 ) * srate; ) : ( filterChoice == 44 ) ? ( // filterFreq = max(filterFreq, 0.02); outHz = 0; // Too inaccurate ) : ( filterChoice == 45 ) ? ( f = max(f, 0.0035); outHz = .5 * ( ( pow(10, f) - 1 ) / 9 ) * srate; ) : ( filterChoice == 46 ) ? ( f = max(f, 0.0035); outHz = .5 * ( ( pow(10, f) - 1 ) / 9 ) * srate; ) : ( filterChoice == 47 ) ? ( f = max(f, 0.0035); outHz = .5 * ( ( pow(10, f) - 1 ) / 9 ) * srate; ) : ( filterChoice == 48 ) ? ( outHz = 0; // comb (inaccurate) ) : ( filterChoice == 49 ) ? ( outHz = .5 * ( ( pow(10, f) - 1 ) / 9 ) * srate; // combed resonance ) : ( filterChoice == 50 ) ? ( outHz = .5 * ( ( pow(10, f) - 1 ) / 9 ) * srate; // combed resonance ) : ( filterChoice == 51 ) ? ( f = max(f, 0.004); outHz = .444 * srate * (pow(10, f)-1)/9; ) : ( filterChoice == 52 ) ? ( f = max(f, 0.004); outHz = .444 * srate * (pow(10, f)-1)/9; ) : ( filterChoice == 53 ) ? ( f = max(f, 0.004); outHz = .444 * srate * (pow(10, f)-1)/9; ); outHz ); function prepLerp(slideridx_in, memloc_in, currentValue, linear) instance(slideridx, ptr, memloc, cur_x, cur_y, next, delta, nextVal, prevVal) local(next_x, next_y, dx) global(samplesblock) ( ( linear ) ? ( slideridx = slideridx_in; memloc = memloc_in; nextVal = currentValue; (samplesblock > 0) && ( samplesblock < 44100 ) ? ( delta = (nextVal - prevVal) / (samplesblock); cur_y = prevVal; ) : ( delta = 0; cur_y = nextVal; ); // This ensures we never change delta (curSample is never negative) next = -10000; prevVal = nextVal; ) : ( slideridx = slideridx_in; memloc = memloc_in; cur_x = 0; cur_y = currentValue; // Fetch the points ptr = memloc; while( (next_x = slider_next_chg(slideridx, next_y)) > -1 ) ( ptr[] = cur_x; ptr += 1; ptr[] = (next_y - cur_y) / (next_x - cur_x); ptr += 1; cur_x = next_x; cur_y = next_y; ); ptr[] = samplesblock; ptr[1] = 0; ptr[2] = -100; ptr = memloc; cur_y = currentValue; delta = 0; next = ptr[]; prevVal = cur_y; ); ); /*function prepLerp(slideridx_in, memloc_in, currentValue) instance(slideridx, ptr, memloc, cur_x, cur_y, next, delta) local(next_x, next_y, dx) global(F1, F2, F3, F4, F5, F6, F7, F8, F9, samplesblock) global(samplesblock) ( F1 = memloc[0]; F2 = memloc[1]; F3 = memloc[2]; F4 = memloc[3]; F5 = memloc[4]; F6 = memloc[5]; F7 = memloc[6]; F8 = memloc[7]; F9 = memloc[8]; );*/ function lerpSample() instance(slideridx, ptr, memloc, cur_x, cur_y, delta, next) global(curSample, potato) local() ( ( next == curSample ) ? ( ptr += 1; delta = ptr[]; ptr += 1; next = ptr[]; ); cur_y += delta ); function selectBuffer(isR, isFilt2) global(delay_buf1, delay_buf2, delay_buf3, delay_buf4) ( (isFilt2 == 1) ? ( (isR == 1) ? ( delay_buf4 ) : ( delay_buf3 ) ) : ( (isR == 1) ? ( delay_buf2 ) : ( delay_buf1 ) ) ); function updateActiveFilter(sliderValue, filterFreq, filterReso, isR, isFilt2) global(filter_delay1, filter_delay2, slider54, slider56, forceUpdate, selectBuffer filter_delay1.initBufferNoReset, filter_delay2.initBufferNoReset, srate, postResetWaitSamples) local(val, delayBuffer, delayBuffer2) instance() ( this.filtertype = sliderValue; ( sliderValue == 1 ) ? ( this.rc_filter.initRC(filterFreq, filterReso); ) : ( sliderValue == 2 ) ? ( filterFreq = max(filterFreq, 0.005); this.filter_303.init303(filterFreq, filterReso); ) : ( sliderValue == 3 ) ? ( this.filter_vowel.initvowel(filterFreq, filterReso); ) : ( sliderValue == 4 ) ? ( filterFreq = max(filterFreq, 0.005); this.filter_karlsen.initkarlsen(filterFreq, filterReso); ) : ( sliderValue == 5 ) ? ( filterFreq = max(filterFreq, 0.005); this.filter_karlsen_sat.initkarlsen_sat(filterFreq, filterReso); ) : ( sliderValue == 6 ) ? ( ( slider54 < 2 ) ? ( slider54 = 2; slider_automate(slider54); forceUpdate = 1; ); filterFreq = max(filterFreq, 0.003); this.filter_dualfilt.initdualfilt(filterFreq, filterReso); ) : ( sliderValue == 7 ) ? ( ( slider54 < 2 ) ? ( slider54 = 2; slider_automate(slider54); forceUpdate = 1; ); filterFreq = max(filterFreq, 0.003); this.filter_dualfiltHP.initdualfilt(filterFreq, filterReso); ) : ( sliderValue == 8 ) ? ( ( slider54 < 2 ) ? ( slider54 = 2; slider_automate(slider54); forceUpdate = 1; ); filterFreq = max(filterFreq, 0.003); this.filter_dualfiltBP.initdualfilt(filterFreq, filterReso); ) : ( sliderValue == 9 || sliderValue == 10 ) ? ( ( slider54 < 2 ) ? ( slider54 = 2; slider_automate(slider54); forceUpdate = 1; ); filterFreq = max(filterFreq, 0.003); this.filter_fancymoog.initfancymoog(filterFreq, filterReso); ) : ( sliderValue == 11 ) ? ( filterFreq = max(filterFreq, 0.003); this.filter_notch.initnotch(filterFreq, filterReso); ) : ( sliderValue == 12 ) ? ( this.filter_sai0.initsai0(filterFreq, filterReso); ( slider56 == 3 ) ? ( slider56 = 1; slider_automate(slider56); forceUpdate = 1; ); ) : ( sliderValue == 13 ) ? ( this.filter_modulator.initmodulator(filterFreq, filterReso); ) : ( sliderValue == 14 ) ? ( this.filter_phaser.initphaserOTA(filterFreq, filterReso); this.filter_phaser2.initphaserOTA(filterFreq*2, filterReso); this.filter_phaser3.initphaserOTA(filterFreq/2, filterReso); this.filter_phaser4.initphaserOTA(filterFreq/3, filterReso); ) : ( sliderValue == 15 ) ? ( this.filter_phaser.initphaserFET(filterFreq, filterReso); this.filter_phaser2.initphaserFET(filterFreq*2, filterReso); this.filter_phaser3.initphaserFET(filterFreq/2, filterReso); this.filter_phaser4.initphaserFET(filterFreq/3, filterReso); ) : ( sliderValue == 16 ) ? ( this.filter_dualfilt.initdualfilt(max(filterFreq, 0.0001), filterReso); delayBuffer = selectBuffer( 0, isFilt2 ); delayBuffer2 = selectBuffer( 1, isFilt2 ); filter_delay1.initBufferNoReset(delayBuffer, delayBuffer + max(1,slider54)*filterFreq * 1000); filter_delay2.initBufferNoReset(delayBuffer2, delayBuffer2 + max(1,slider54)*filterReso * 2000); ) : ( sliderValue == 17 ) ? ( this.filter_dualfilt.initdualfilt(max(filterFreq, 0.0001), filterReso); delayBuffer = selectBuffer( 0, isFilt2 ); delayBuffer2 = selectBuffer( 1, isFilt2 ); filter_delay1.initBufferNoReset(delayBuffer, delayBuffer + max(1,slider54)*filterFreq*(1000+4000*filterReso)); filter_delay2.initBufferNoReset(delayBuffer2, delayBuffer2 + max(1,slider54)*filterFreq*(1000+4000*filterReso)); ) : ( sliderValue == 18 ) ? ( filterFreq = max(filterFreq, 0.003); this.filter_ms20lin.init_MS20lin(filterFreq, filterReso); ) : ( sliderValue == 19 ) ? ( filterFreq = max(filterFreq, 0.003); this.filter_ms20lin.init_MS20lin(filterFreq, filterReso); ) : ( sliderValue == 20 ) ? ( filterFreq = max(filterFreq, 0.003); this.filter_ms20lin.init_MS20lin(filterFreq, filterReso); ) : ( sliderValue == 21 ) ? ( filterFreq = max(filterFreq, 0.006); this.filter_ms20.init_MS20_nonlin(filterFreq, filterReso); ) : ( sliderValue == 22 ) ? ( filterFreq = max(filterFreq, 0.004); this.filter_ms20.init_MS20_nonlin(filterFreq, filterReso); ) : ( sliderValue == 23 ) ? ( filterFreq = max(filterFreq, 0.004); this.filter_ms20.init_MS20_nonlin(filterFreq, filterReso); ) : ( sliderValue == 24 ) ? ( this.filter_ms20.init_MS20_nonlin(max(filterFreq, 0.003), filterReso); this.filter_phaser.initphaserFET(max(filterFreq, 0.003), filterReso); this.filter_phaser2.initphaserFET(max(filterFreq, 0.003)*2, filterReso); delayBuffer = selectBuffer( isR, isFilt2 ); this.filter_delay.initBufferNoReset(delayBuffer, delayBuffer + max(1,slider54)*filterReso * (50+isR)); ) : ( sliderValue == 25 ) ? ( filterFreq = max(filterFreq, 0.004); this.filter_ms20.init_MS20_nonlin(filterFreq, filterReso); ) : ( sliderValue == 26 ) ? ( filterFreq = max(filterFreq, 0.0045); this.filter_ssm.init_ssm_nonlin(filterFreq, filterReso); ) : ( sliderValue == 27 ) ? ( filterFreq = max(filterFreq, 0.0045); this.filter_ssm.init_ssm_nonlin(filterFreq, filterReso); ) : ( sliderValue == 28 ) ? ( filterFreq = max(filterFreq, 0.007); this.filter_cem.init_cem_nonlin(filterFreq, filterReso); ) : ( sliderValue == 29 ) ? ( filterFreq = max(filterFreq, 0.01); this.filter_ssm_lin.init_ssm_lin(filterFreq, filterReso); ) : ( sliderValue == 30 ) ? ( filterFreq = max(filterFreq, 0.01); this.filter_cem_lin.init_cem_lin(filterFreq, filterReso); ) : ( sliderValue == 31 ) ? ( this.filter_sine.initSine(filterFreq, filterReso); ) : ( sliderValue == 32 ) ? ( this.filter_ms20.init_MS20_nonlin(filterFreq, filterReso); this.filter_sine.initSine(filterFreq, filterReso); ) : ( sliderValue == 33 ) ? ( filterFreq = max(filterFreq, 0.007); this.filter_ms20.init_MS20_nonlin(filterFreq, filterReso); this.filter_sine.initSine(filterFreq, filterReso); ) : ( sliderValue == 34 ) ? ( filterFreq = max(filterFreq, 0.004); this.filter_broken.init_MS20_nonlin(.5*filterFreq, filterReso); ) : ( sliderValue == 35 ) ? ( filterFreq = max(filterFreq, 0.0048); this.filter_wasp.init_wasp_nonlin(filterFreq, filterReso); ) : ( sliderValue == 36 ) ? ( this.filter_wasp_lin.init_wasplin(filterFreq, filterReso); ) : ( sliderValue == 37 ) ? ( filterFreq = max(filterFreq, 0.006); this.filter_wasp.init_wasp_nonlin(filterFreq, filterReso); ) : ( sliderValue == 38 ) ? ( filterFreq = max(filterFreq, 0.006); this.filter_wasp.init_wasp_nonlin(filterFreq, filterReso); ) : ( ( sliderValue > 38 ) && ( sliderValue < 44 ) ) ? ( filterFreq = max(filterFreq, 0.0035); this.filter_SVF.init_linearSVF( filterFreq, filterReso ); ) : ( sliderValue == 44 ) ? ( filterFreq = max(filterFreq, 0.02); this.filter_wasp.init_wasp_nonlin_saw(filterFreq, filterReso); ) : ( sliderValue == 45 ) ? ( filterFreq = max(filterFreq, 0.0035); this.filter_SVF_nores.init_linearSVF( filterFreq, 0 ); this.filter_SVF.init_linearSVF( filterFreq, filterReso ); ) : ( sliderValue == 46 ) ? ( filterFreq = max(filterFreq, 0.0035); this.filter_SVF_nores.init_linearSVF( filterFreq, 0 ); this.filter_SVF.init_linearSVF( filterFreq, filterReso ); ) : ( sliderValue == 47 ) ? ( filterFreq = max(filterFreq, 0.0035); this.filter_SVF_nores.init_linearSVF( filterFreq, 0 ); this.filter_SVF.init_linearSVF( filterFreq, filterReso ); this.filter_SVF2.init_linearSVF( filterFreq*.5, filterReso*.5 ); ) : ( sliderValue == 48 ) ? ( val = ( pow(10, filterFreq) - 1 ) / 9; delayBuffer = selectBuffer( isR, isFilt2 ); this.chan = isR; this.stereoize = filterReso > 0.5 ? 1 : 0; this.filter_delay.initBufferNoReset(delayBuffer, delayBuffer + max(1,slider54)*val * 250); ) : ( sliderValue == 49 ) ? ( val = ( pow(10, filterFreq) - 1 ) / 9; delayBuffer = selectBuffer( isR, isFilt2 ); this.chan = isR; this.filter_delay.initBufferNoReset(delayBuffer, delayBuffer + max(1,slider54)*val * 250); this.filter_SVF_nores.init_linearSVF( max(filterFreq, 0.0035), 0 ); this.filter_SVF.init_linearSVF( max(filterFreq, 0.0035), filterReso ); ) : ( sliderValue == 50 ) ? ( val = ( pow(10, filterFreq) - 1 ) / 9; delayBuffer = selectBuffer( isR, isFilt2 ); this.chan = isR; this.stereoize = filterReso; this.filter_delay.initBufferNoReset(delayBuffer, delayBuffer + max(1,slider54)*val * 250); this.filter_SVF_nores.init_linearSVF( max(filterFreq, 0.0035), 0 ); this.filter_SVF.init_linearSVF( max(filterFreq, 0.0035), filterReso ); ) : ( sliderValue == 51 ) ? ( filterFreq = max(filterFreq, 0.004); this.filter_ms20.init_MS20_nonlin_2(filterFreq, filterReso); ) : ( sliderValue == 52 ) ? ( filterFreq = max(filterFreq, 0.004); this.filter_ms20.init_MS20_nonlin_2(filterFreq, filterReso); ) : ( sliderValue == 53 ) ? ( filterFreq = max(filterFreq, 0.004); this.filter_ms20.init_MS20_nonlin_2(filterFreq, filterReso); ) : ( sliderValue == 54 ) ? ( this.weeping.weeping_init(filterFreq, filterReso, 0); ) : ( sliderValue == 55 ) ? ( this.pwm.pwm_init(filterFreq, filterReso); sliderValue=sliderValue; ) : ( sliderValue == 56 ) ? ( this.pwm.pwm_init(filterFreq, filterReso); sliderValue=sliderValue; ) : ( sliderValue == 57 ) ? ( this.bit.bit_init(filterFreq, filterReso); ) : ( sliderValue == 58 ) ? ( this.muck.muck_init(filterFreq, filterReso); ) : ( slidervalue == 59 ) ? ( this.weeping.weeping_init(filterFreq, filterReso, 1); ) : ( sliderValue == 60 ) ? ( slider54 > 2 ? ( slider_automate( slider54 = 2 ); forceUpdate = 1; ); (this.wah.l_srate != srate * max(1,slider54) ) ? ( this.wah.dlop_init_srate(srate * max(1,slider54)); postResetWaitSamples = 8192; ); this.wah.dlop_init_cutoff(.8*filterFreq, filterReso); ) : ( sliderValue == 61 ) ? ( slider54 != 2 ? ( slider_automate( slider54 = 2 ); forceUpdate = 1; ); (this.wah.l_srate != .5 * srate * max(1,slider54) ) ? ( this.wah.dlop_init_srate(.5 * srate * max(1,slider54)); postResetWaitSamples = 8192; ); this.wah.dlop_init_cutoff(.8*filterFreq, filterReso); ) : ( sliderValue == 62 ) ? ( slider54 > 2 ? ( slider_automate( slider54 = 2 ); forceUpdate = 1; ); (this.wah.l_srate != 2 * srate * max(1,slider54) ) ? ( this.wah.dlop_init_srate(2 * srate * max(1,slider54)); postResetWaitSamples = 8192; ); this.wah.dlop_init_cutoff(.8*filterFreq, filterReso); ) : ( sliderValue == 63 ) ? ( this.vowel_svf.initvowelSVF(filterFreq, filterReso); ) : ( sliderValue == 64 ) ? ( this.vowel_svf.initvowelSVF(filterFreq, filterReso); ); ); function updateActiveFilters( force ) ( filteredDynval = 0.1 * dynval + 0.9 * filteredDynval; // Avoid too steep transitions. modval = gainDynamics * filteredDynval + gainLFO * modulator.modvalue * slider39; pregain = 2^((slider52 + 40 * dyn_mod_gain * modval)/6); postgain = 2^((slider53 + 40 * dyn_mod_outgain * modval)/6); gaincompensation = 1/pregain; // Cutoff and resonance handling filter 1 ( slider47 > 0 ) ? ( sliderCutoff = cutoffLerp.lerpSample(); sliderReso = resoLerp.lerpSample(); followKey1 ? sliderCutoff = sliderCutoff + approxNoteFrequencyFilter1 * slider33; modval = filterDynamics1 * filteredDynval + filterLFO1 * modulator.modvalue * slider39; filterFreq = max( 0, min( 1, sliderCutoff + dyn_mod_filt * modval ) ); filterReso = max( 0, min( .99, sliderReso + dyn_mod_reso * modval ) ); ); updateFiltersNow = ( filterFreq != lastFilterFreq ) || ( filterReso != lastFilterReso ) || force; ( updateFiltersNow ) ? ( lastFilterReso = filterReso; lastFilterFreq = filterFreq; L.updateActiveFilter(slider47, filterFreq, filterReso, 0, 0); R.updateActiveFilter(slider47, filterFreq, filterReso, 1, 0); ); // Cutoff and resonance handling filter 2 ( slider40 > 0 ) ? ( sliderCutoff2 = cutoffLerp2.lerpSample(); sliderReso2 = resoLerp2.lerpSample(); followKey2 ? sliderCutoff2 = sliderCutoff2 + approxNoteFrequencyFilter2 * slider33; modval = filterDynamics2 * filteredDynval + filterLFO2 * modulator.modvalue * slider39; filterFreq2 = max( 0, min( 1, sliderCutoff2 + dyn_mod_filt2 * modval ) ); filterReso2 = max( 0, min( .99, sliderReso2 + dyn_mod_reso2 * modval ) ); ); updateFiltersNow = ( filterFreq2 != lastFilterFreq2 ) || ( filterReso2 != lastFilterReso2 ) || force; ( updateFiltersNow ) ? ( lastFilterReso2 = filterReso2; lastFilterFreq2 = filterFreq2; L2.updateActiveFilter(slider40, filterFreq2, filterReso2, 0, 1); R2.updateActiveFilter(slider40, filterFreq2, filterReso2, 1, 1); ); // Delay /*( lookAhead ) ? ( oldFreq = cutoffBuffer.getBuffer(); oldReso = resoBuffer.getBuffer(); cutoffBuffer.updateBuffer( filterFreq ); resoBuffer.updateBuffer( filterReso ); filterFreq = oldFreq; filterReso = oldReso; );*/ ); function resetActiveFilter(filterType) local(maxOversampling) ( maxOversampling = 8; ( filterType == 1 ) ? ( maxOversampling = maxOversampling; ) : ( filterType == 2 ) ? ( this.filter_303.reset303(); ) : ( filterType == 3 ) ? ( this.filter_vowel.resetvowel(); ) : ( filterType == 4 ) ? ( this.filter_karlsen.resetkarlsen(); ) : ( filterType == 5 ) ? ( this.filter_karlsen_sat.resetkarlsen_sat(); ) : ( filterType == 6 ) ? ( this.filter_dualfilt.resetdualfilt(); ) : ( filterType == 7 ) ? ( this.filter_dualfiltHP.resetdualfilt(); ) : ( filterType == 8 ) ? ( this.filter_dualfiltBP.resetdualfilt(); ) : ( filterType == 9 ) ? ( this.filter_fancymoog.resetfancymoog(); ) : ( filterType == 10 ) ? ( this.filter_fancymoog.resetfancymoog(); ) : ( filterType == 11 ) ? ( this.filter_notch.resetrbj(); ) : ( filterType == 12 ) ? ( this.filter_sai0.resetsai0(0); ) : ( filterType == 13 ) ? ( this.filter_modulator.resetmodulator(); ) : ( filterType == 14 ) ? ( os = 0; jnk = 0; this.filter_phaser.resetphaserOTA(); ) : ( filterType == 15 ) ? ( os = 0; this.filter_phaser.resetphaserFET(); ) : ( filterType == 16 ) ? ( os1 = os2 = ys1 = 0; this.filter_dualfilt.resetdualfilt(); filter_delay1.clearBuffer(); filter_delay2.clearBuffer(); ) : ( filterType == 17 ) ? ( os1 = os2 = os3 = 0; this.filter_dualfilt.resetdualfilt(); filter_delay1.clearBuffer(); filter_delay2.clearBuffer(); ) : ( filterType == 18 ) ? ( this.filter_ms20lin.reset_MS20lin(); ) : ( filterType == 19 ) ? ( this.filter_ms20lin.reset_MS20lin(); ) : ( filterType == 20 ) ? ( this.filter_ms20lin.reset_MS20lin(); ) : ( filterType == 21 ) ? ( this.filter_ms20.reset_MS20_nonlin(); ) : ( filterType == 22 ) ? ( this.filter_ms20.reset_MS20_nonlin(); ) : ( filterType == 23 ) ? ( this.filter_ms20.reset_MS20_nonlin(); ) : ( filterType == 24 ) ? ( this.filter_ms20.reset_MS20_nonlin(); this.filter_phaser.resetphaserFET(); this.filter_phaser2.resetphaserFET(); this.filter_delay.clearBuffer(); ) : ( filterType == 25 ) ? ( this.filter_ms20.reset_MS20_nonlin(); ) : ( filterType == 26 ) ? ( this.filter_ssm.reset_ssm_nonlin(); ) : ( filterType == 27 ) ? ( this.filter_ssm.reset_ssm_nonlin(); ) : ( filterType == 28 ) ? ( this.filter_cem.reset_cem_nonlin(); ) : ( filterType == 29 ) ? ( this.filter_ssm_lin.reset_ssm_lin(); ) : ( filterType == 30 ) ? ( this.filter_cem_lin.reset_cem_lin(); ) : ( filterType == 32 ) ? ( this.filter_ms20.reset_MS20_nonlin(); ) : ( filterType == 33 ) ? ( this.filter_ms20.reset_MS20_nonlin(); ) : ( filterType == 34 ) ? ( this.filter_broken.reset_MS20_nonlin(); ) : ( filterType == 35 ) ? ( this.filter_wasp.reset_wasp_nonlin(); ) : ( filterType == 36 ) ? ( this.filter_wasp_lin.reset_wasplin(); ) : ( filterType == 37 ) ? ( this.filter_wasp.reset_wasp_nonlin(); ) : ( filterType == 38 ) ? ( this.filter_wasp.reset_wasp_nonlin(); ) : ( ( filterType > 38 ) && ( filterType < 44 ) ) ? ( this.filter_SVF.reset_linearSVF( ); ) : ( filterType == 44 ) ? ( this.filter_wasp.reset_wasp_nonlin_saw(); ) : ( filterType == 45 ) ? ( this.filter_SVF_nores.reset_linearSVF(); this.filter_SVF.reset_linearSVF(); ) : ( filterType == 46 ) ? ( this.filter_SVF_nores.reset_linearSVF(); this.filter_SVF.reset_linearSVF(); this.resoint = 0; ) : ( filterType == 47 ) ? ( this.filter_SVF_nores.reset_linearSVF(); this.filter_SVF.reset_linearSVF(); this.filter_SVF2.reset_linearSVF(); ) : ( filterType == 48 ) ? ( this.filter_delay.clearBuffer(); ) : ( filterType == 49 ) ? ( this.filter_SVF_nores.reset_linearSVF(); this.filter_SVF.reset_linearSVF(); this.filter_delay.clearBuffer(); ) : ( filterType == 50 ) ? ( this.filter_SVF_nores.reset_linearSVF(); this.filter_SVF.reset_linearSVF(); this.filter_delay.clearBuffer(); ) : ( filterType > 50 && filterType < 54 ) ? ( this.filter_ms20.reset_MS20_nonlin(); ) : ( filterType == 54 || filterType == 59 ) ? ( this.weeping_reset(); ) : ( filterType == 60 ) ? ( this.wah.reset_dlop(); postResetWaitSamples = 8192; ) : ( filterType == 61 ) ? ( this.wah.reset_dlopH(); postResetWaitSamples = 8192; ) : ( filterType == 62 ) ? ( this.wah.reset_dlopL(); postResetWaitSamples = 8192; ) : ( sliderValue == 63 ) ? ( this.vowel_svf.resetvowelSVF(); ) : ( sliderValue == 64 ) ? ( this.vowel_svf.resetvowelSVF(); ); ); function resetActiveFilters() ( // Reset the offset correction otm1 = otm2 = itm1 = itm2 = 0; // Reset up and downsampling filters sincFilterL.resetSincUp(); sincFilterR.resetSincUp(); sincDownL.resetSincDown(); sincDownR.resetSincDown(); filterL.resetioFilter(); filterR.resetioFilter(); L.resetActiveFilter( slider47 ); R.resetActiveFilter( slider47 ); L2.resetActiveFilter( slider40 ); R2.resetActiveFilter( slider40 ); ); itm1=itm2=otm1=otm2=0; forceUpdate=0; movavgLN = 0; movavgLP = 0; movavgRN = 0; movavgRP = 0; updateActiveFilters(1); function setN(S, N) local(changed) global(slider1, slider2) ( ( S == 1 ) ? ( slider1=N; slider_automate(slider1); ) : ( S == 2 ) ? ( slider2=N; slider_automate(slider2); ); ); function manipulateXYSliders(S, i, x, y) ( // gfx_set(1,1,1,1); // gfx_x=0; // gfx_y=50; // gfx_printf("HEY %d, %d, %f, %f", S, i, x, y); (S == 2) ? ( (i==1) ? ( slider3=x; slider_automate(slider3); slider4=y; slider_automate(slider4); ) :(i==2) ? ( slider5=x; slider_automate(slider5); slider6=y; slider_automate(slider6); ) :(i==3) ? ( slider7=x; slider_automate(slider7); slider8=y; slider_automate(slider8); ) :(i==4) ? ( slider9=x; slider_automate(slider9); slider10=y; slider_automate(slider10); ) :(i==5) ? ( slider11=x; slider_automate(slider11); slider12=y; slider_automate(slider12); ) :(i==6) ? ( slider13=x; slider_automate(slider13); slider14=y; slider_automate(slider14); ) :(i==7) ? ( slider15=x; slider_automate(slider15); slider16=y; slider_automate(slider16); ) :(i==8) ? ( slider18=y; slider_automate(slider18); ) ) : ( S==1 ) ? ( (i==1) ? ( slider19=x; slider_automate(slider19); slider20=y; slider_automate(slider20); ) :(i==2) ? ( slider21=x; slider_automate(slider21); slider22=y; slider_automate(slider22); ) :(i==3) ? ( slider23=x; slider_automate(slider23); slider24=y; slider_automate(slider24); ) :(i==4) ? ( slider25=x; slider_automate(slider25); slider26=y; slider_automate(slider26); ) :(i==5) ? ( slider27=x; slider_automate(slider27); slider28=y; slider_automate(slider28); ) :(i==6) ? ( slider29=x; slider_automate(slider29); slider30=y; slider_automate(slider30); ) :(i==7) ? ( slider31=x; slider_automate(slider31); slider32=y; slider_automate(slider32); ) :(i==8) ? ( slider34=y; slider_automate(slider34); ) ); forceUpdate = 1; ); function manipulateYSlider(S, i, y) ( // gfx_set(1,1,1,1); // gfx_x=0; // gfx_y=50; // gfx_printf("HEY %d, %d, %f, %f", S, i, x, y); (S == 2) ? ( (i==1) ? ( slider4=y; slider_automate(slider4); ) :(i==2) ? ( slider6=y; slider_automate(slider6); ) :(i==3) ? ( slider8=y; slider_automate(slider8); ) :(i==4) ? ( slider10=y; slider_automate(slider10); ) :(i==5) ? ( slider12=y; slider_automate(slider12); ) :(i==6) ? ( slider14=y; slider_automate(slider14); ) :(i==7) ? ( slider16=y; slider_automate(slider16); ) :(i==8) ? ( slider18=y; slider_automate(slider18); ) ) : ( S==1 ) ? ( (i==1) ? ( slider20=y; slider_automate(slider20); ) :(i==2) ? ( slider22=y; slider_automate(slider22); ) :(i==3) ? ( slider24=y; slider_automate(slider24); ) :(i==4) ? ( slider26=y; slider_automate(slider26); ) :(i==5) ? ( slider28=y; slider_automate(slider28); ) :(i==6) ? ( slider30=y; slider_automate(slider30); ) :(i==7) ? ( slider32=y; slider_automate(slider32); ) :(i==8) ? ( slider34=y; slider_automate(slider34); ) ); forceUpdate = 1; ); function grabY(S, i) ( (S == 2) ? ( (i==1) ? ( slider4; ) :(i==2) ? ( slider6; ) :(i==3) ? ( slider8; ) :(i==4) ? ( slider10; ) :(i==5) ? ( slider12; ) :(i==6) ? ( slider14; ) :(i==7) ? ( slider16; ) :(i==8) ? ( slider18; ) ) : ( S==1 ) ? ( (i==1) ? ( slider20 ) :(i==2) ? ( slider22 ) :(i==3) ? ( slider24 ) :(i==4) ? ( slider26 ) :(i==5) ? ( slider28 ) :(i==6) ? ( slider30 ) :(i==7) ? ( slider32 ) :(i==8) ? ( slider34 ) ); ); function grabFinalY(S) ( (S == 2) ? grabY(S, slider2-1) : grabY(S, slider1-1) ); // Really dumb sorting algorithm // Double buffered to make sure that we don't get clicks function sort_spline() instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(last, mini, iter, tmp, eps, shift) global(gfx_x, gfx_y) ( // First copy it to temp ptr_from_X = xloc_write; ptr_from_Y = yloc_write; ptr_to_X = tempx; ptr_to_Y = tempy; ptr_to_Z = tempz; iter = 0; loop(N_write, ptr_to_X[] = ptr_from_X[]; ptr_to_X += 1; ptr_from_X += 1; ptr_to_Y[] = ptr_from_Y[]; ptr_to_Y += 1; ptr_from_Y += 1; ptr_to_Z[] = iter; ptr_to_Z += 1; iter += 1; ); // Make sure there are no duplicate x'es ptr_to_X = tempx; eps = 0.001; shift = 0.001; loop(N_write, ptr_from_X = tempx; loop(N_write, ( abs(ptr_to_X[] - ptr_from_X[]) < eps ) ? ( ptr_to_X[] += shift; shift = shift / 2; ); ptr_from_X += 1; ); ptr_to_X += 1; ); // Sort it ptr_to_X = xloc_write; ptr_to_Y = yloc_write; ptr_to_Z = indices; last = -1; loop(N_write, ptr_from_X = tempx; ptr_from_Y = tempy; ptr_from_Z = tempz; mini = 1000; loop(N_write, ( ( ptr_from_X[] > last ) && ( ptr_from_X[] < mini ) ) ? ( mini = ptr_from_X[]; ptr_to_X[] = mini; ptr_to_Y[] = ptr_from_Y[]; ptr_to_Z[] = ptr_from_Z[]; ); ptr_from_X += 1; ptr_from_Y += 1; ptr_from_Z += 1; ); last = mini; ptr_to_X += 1; ptr_to_Y += 1; ptr_to_Z += 1; ); tmp = xloc_read; xloc_read = xloc_write; xloc_write = tmp; tmp = yloc_read; yloc_read = yloc_write; yloc_write = tmp; ); function update_spline() instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(cc1, m, mNext, cm, dx, dxNext, invdx, tmp) global(gfx_x, gfx_y) ( // Initialize coeffs ptr_to_X = c1_write; loop(9, ptr_to_X[] = 0; ptr_to_X += 1; ); ptr_to_X = c2_write; loop(9, ptr_to_X[] = 0; ptr_to_X += 1; ); ptr_to_X = c3_write; loop(9, ptr_to_X[] = 0; ptr_to_X += 1; ); // Calculate differences ptr_from_X = xloc_read; ptr_from_Y = yloc_read; ptr_to_X = tempx; ptr_to_Y = tempy; // tempx contains dxs, tempy the slopes (dy/dx) loop(N_write-1, ptr_to_X[] = ptr_from_X[1] - ptr_from_X[]; ptr_to_Y[] = ( ptr_from_Y[1] - ptr_from_Y[] ) / ptr_to_X[]; ptr_to_X += 1; ptr_to_Y += 1; ptr_from_X += 1; ptr_from_Y += 1; ); // calculate first degree coefficients ptr_from_X = tempx; // dx ptr_from_Y = tempy; // dy/dx (ms) ptr_to_X = c1_write; ptr_to_X[] = ptr_from_Y[]; ptr_to_X += 1; loop(N_write-2, m = ptr_from_Y[]; mNext = ptr_from_Y[1]; ( m * mNext <= 0 ) ? ( ptr_to_X[] = 0; ): ( dx = ptr_from_X[]; dxNext = ptr_from_X[1]; cm = dx + dxNext; ptr_to_X[] = 3.0*cm/((cm+dxNext)/m + (cm+dx)/mNext); ); ptr_to_X += 1; ptr_from_X += 1; ptr_from_Y += 1; ); ptr_to_X[] = ptr_from_Y[]; // calculate second degree coefficients ptr_from_X = tempx; // dx ptr_from_Y = tempy; // dy/dx (ms) ptr_from_Z = c1_write; // c1s ptr_to_X = c2_write; ptr_to_Y = c3_write; loop(N_write-1, invdx = 1 / ptr_from_X[]; cc1 = ptr_from_Z[]; m = ptr_from_Y[]; cm = cc1 + ptr_from_Z[1] - m - m; ptr_to_X[] = (m - cc1 - cm)*invdx; ptr_to_Y[] = cm*invdx*invdx; ptr_from_X += 1; ptr_from_Y += 1; ptr_from_Z += 1; ptr_to_X += 1; ptr_to_Y += 1; ); tmp = c1_read; c1_read = c1_write; c1_write = tmp; tmp = c2_read; c2_read = c2_write; c2_write = tmp; tmp = c3_read; c3_read = c3_write; c3_write = tmp; N_read = N_write; ); function evalSplineBin(x) instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(low, high, xHere, i, diff, diffSq, mid, out) global() ( // Out of bounds means return 1 (x > 1) ? out = yloc_read[N_read-1] : ( ( x < 0 ) ? out = 0 : ( // Search for the correct interval by binary search low = 0; high = N_read; while( mid = floor( 0.5*(low+high) ); xHere = xloc_read[mid]; ( xHere < x ) ? low = mid + 1 : ( // else ( xHere > x ) ? high = mid - 1 : ( //else high = yloc_read[mid]; low = high+1; // Manual termination ); ); low <= high; ); i = max( 0, high ); diff = x - xloc_read[i]; diffSq = diff * diff; out = yloc_read[i] + c1_read[i]*diff + c2_read[i]*diffSq + c3_read[i]*diff*diffSq; ) ); out; ); // Linear search empirically turned out to be faster than binary search (small number of nodes, less branching I guess). function evalSplineLin(x) instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(low, high, xHere, i, diff, diffSq, mid, out) global() ( i = -1; xHere = xloc_read-1; while( i += 1; xHere += 1; x >= xHere[] && ( i < N_read ) ); i = max( 0, i-1 ); diff = x - xloc_read[i]; diffSq = diff * diff; out = yloc_read[i] + c1_read[i]*diff + c2_read[i]*diffSq + c3_read[i]*diff*diffSq; out; ); function evalSplineAudioBin(x) instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(lowAudio, highAudio, xHereAudio, diffAudio, diffSqAudio, out, midAudio) global() ( // Out of bounds means return 1 ( x > 1 ) ? out = yloc_read[N_read-1] : ( ( x < 0 ) ? out = 0 : ( // Search for the correct interval by binary search lowAudio = 0; highAudio = N_read; while( midAudio = floor( 0.5*(lowAudio+highAudio) ); xHereAudio = xloc_read[midAudio]; ( xHereAudio < x ) ? lowAudio = midAudio + 1 : ( // else ( xHereAudio > x ) ? highAudio = midAudio - 1 : ( //else highAudio = yloc_read[midAudio]; lowAudio = highAudio+1; // Manual termination ); ); lowAudio <= highAudio; ); iAudio = max( 0, highAudio ); diffAudio = x - xloc_read[iAudio]; diffSqAudio = diffAudio * diffAudio; out = yloc_read[iAudio] + c1_read[iAudio]*diffAudio + c2_read[iAudio]*diffSqAudio + c3_read[iAudio]*diffAudio*diffSqAudio; ) ); out; ); function evalSplineAudioLin(x) instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(lowAudio, highAudio, xHereAudio, diffAudio, diffSqAudio, out, midAudio) global(gfx_x, gfx_y) ( iAudio = -1; xHereAudio = xloc_read-1; while( iAudio += 1; xHereAudio += 1; x >= xHereAudio[] && ( iAudio < N_read ) ); iAudio = max(0, iAudio-1); diffAudio = x - xloc_read[iAudio]; diffSqAudio = diffAudio * diffAudio; out = yloc_read[iAudio] + c1_read[iAudio]*diffAudio + c2_read[iAudio]*diffSqAudio + c3_read[iAudio]*diffAudio*diffSqAudio; out; ); // Get first derivative of the spline (needed for some analog models) function evalSplineAudioDiff(x) instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(lowAudio, highAudio, interpAudio, xHereAudio, diffAudio, out, midAudio) global() ( // Out of bounds means return 1 ( x > 1 ) ? out = yloc_read[N_read-1] : ( ( x < 0 ) ? out = 0 : ( iAudio = max( 0, highAudio ); diffAudio = x - xloc_read[iAudio]; out = c1_read[iAudio] + diffAudio*(2*c2_read[iAudio] + 3*diffAudio*c3_read[iAudio]); ) ); out; ); // Plot the spline nodes function plot_spline(x, y, w, h) instance(ldyn, ldyn2, ldyn3, ldyn4, N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(dhere, xx, res, lastx, lasty, dx, yout, nx, ny, epsx, epsy, xc, yc, yout) global(gfx_x, gfx_y, distortPlot, slider56, dynval, distortionDynamics spline_r, spline_g, spline_b, spline_a dyn_color_r, dyn_color_g, dyn_color_b, dyn_color_a) ( epsx = 3; epsy = 3; ptr_from_X = xloc_read; ptr_from_Y = yloc_read; ptr_from_Z = indices; gfx_set( spline_r, spline_g, spline_b, spline_a ); gfx_x = 0; gfx_y = 0; ( slider56 == 0 ) ? ( loop(N_read, xc = x + w*ptr_from_X[] - epsx; yc = y + h*(1-ptr_from_Y[]) - epsy; gfx_rect(xc, yc, epsx, epsy); gfx_x = xc; gfx_y = yc-14; gfx_printf("%d", ptr_from_Z[]); ptr_from_X += 1; ptr_from_Y += 1; ptr_from_Z += 1; ); ); ( slider56 == 4 ) ? ( gfx_rect( x+.75*w - 5, y + .5*h, 10, 2 ); gfx_rect( x+.25*w - 5, y + .5*h, 10, 2 ); gfx_rect( x+.25*w - 2, y + .5*h-4, 4, 10 ); ); xx = 0; res = 500; lastx = x; lasty = y+h; dx = 1/res; loop(res, xx = xx + dx; ( slider56 == 0 ) ? ( yout = this.evalSplineLin(xx); ) : ( slider56 == 1 ) ? ( yout = tanh(xx); ) : ( slider56 == 2 ) ? ( yout = fasttanh(xx); ) : ( slider56 == 4 ) ? ( yout = xx < 0.5 ? sin(2*$pi*xx) : sin(2*$pi*(-xx)); ) : ( yout = xx; ); nx = x + w*xx - 1; ny = y + h*(1-yout) - 1; gfx_line(lastx, lasty, nx, ny, 0); lastx = nx; lasty = ny; ); // Draw intermediate if dynamically processed ( distortionDynamics ) ? ( // Graph interpolant xx = 0; res = 500; lastx = x; lasty = y+h; dx = 1/res; dhere = dynval; gfx_set( dyn_color_r, dyn_color_g, dyn_color_b, dyn_color_a ); loop(res, xx = xx + dx; ( slider56 == 0 ) ? ( yout = xx * (1-dhere) + dhere * this.evalSplineLin(xx); ) : ( slider56 == 1 ) ? ( yout = xx * (1-dhere) + dhere * tanh(xx); ) : ( slider56 == 2 ) ? ( yout = xx * (1-dhere) + dhere * fasttanh(xx); ) : ( slider56 == 4 ) ? ( yout = xx * (1-dhere) + dhere * (xx < 0.5 ? sin(2*$pi*xx) : sin(2*$pi*(-xx))); ) : ( yout = xx; ); nx = x + w*xx - 1; ny = y + h*(1-yout) - 1; gfx_line(lastx, lasty, nx, ny, 0); lastx = nx; lasty = ny; ); xx = 0; res = 500; lastx = x; lasty = y+h; dx = 1/res; gfx_set( dyn_color_r, dyn_color_g, dyn_color_b, dyn_color_a * .24 ); loop(res, xx = xx + dx; ( slider56 == 0 ) ? ( yout = xx * (1-ldyn2) + ldyn2 * this.evalSplineLin(xx); ) : ( slider56 == 1 ) ? ( yout = xx * (1-ldyn2) + ldyn2 * tanh(xx); ) : ( slider56 == 2 ) ? ( yout = xx * (1-ldyn2) + ldyn2 * fasttanh(xx); ) : ( slider56 == 4 ) ? ( yout = xx * (1-ldyn2) + ldyn2 * (xx < 0.5 ? sin(2*$pi*xx) : sin(2*$pi*(-xx))); ) : ( yout = xx; ); nx = x + w*xx - 1; ny = y + h*(1-yout) - 1; gfx_line(lastx, lasty, nx, ny, 0); lastx = nx; lasty = ny; ); xx = 0; res = 500; lastx = x; lasty = y+h; dx = 1/res; gfx_set( dyn_color_r, dyn_color_g, dyn_color_b, dyn_color_a * .12 ); loop(res, xx = xx + dx; ( slider56 == 0 ) ? ( yout = xx * (1-ldyn4) + ldyn4 * this.evalSplineLin(xx); ) : ( slider56 == 1 ) ? ( yout = xx * (1-ldyn4) + ldyn4 * tanh(xx); ) : ( slider56 == 2 ) ? ( yout = xx * (1-ldyn4) + ldyn4 * fasttanh(xx); ) : ( slider56 == 4 ) ? ( yout = xx * (1-ldyn4) + ldyn4 * (xx < 0.5 ? sin(2*$pi*xx) : sin(2*$pi*(-xx))); ) : ( yout = xx; ); nx = x + w*xx - 1; ny = y + h*(1-yout) - 1; gfx_line(lastx, lasty, nx, ny, 0); lastx = nx; lasty = ny; ); ldyn4 = ldyn3; ldyn3 = ldyn2; ldyn2 = ldyn; ldyn = dhere; ); ); function evalDist(xx) instance(x, y, w, h, spline) global() ( spline.evalSplineLin(xx); ); function evalDistAudio(xx) instance(x, y, w, h, spline) global() ( spline.evalSplineAudioLin(xx); ); function evalDiff(xx) instance(x, y, w, h, spline) global() ( spline.evalSplineAudioDiff(xx); ); //NODE_PROXIMITY = 5; function findNearest(x, y) instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(minDist, best, dx, dy, dist, left, i, right) global() ( // Find nearest point that may have been clicked i = 0; minDist = 100000000000000; best = -1; loop(N_read, dx = (x - xloc_read[i]); dy = ((1-y) - yloc_read[i]); dist = dx*dx + dy*dy; ( dist < minDist ) ? ( minDist = dist; best = i; ); i = i + 1; ); // Found a point, then we change the capture mode ( minDist < .001 ) ? ( drag_node = best; ) : drag_node = -1; ); //NODE_PROXIMITY = 5; function killNode(i) instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(i, lastY) global() ( lastY = grabFinalY(splineIdx); i = 0; while( i += 1; (indices[i]!=(N_read-2))&&(i<(N_read+1)) ); manipulateXYSliders(splineIdx, indices[drag_node], xloc_read[i], yloc_read[i]); manipulateYSlider(splineIdx, N_read-2, lastY); setN(splineIdx, N_read-1); ); function addNode(x, y) instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(i) global() ( i = 0; while( i += 1; (indices[i]!=(N_read-1))&&(i<(N_read+2)) ); manipulateXYSliders(splineIdx, indices[N_read], xloc_read[i], yloc_read[i]); manipulateXYSliders(splineIdx, indices[N_read-1], x, y); setN(splineIdx, N_read+1); ); //NODE_PROXIMITY = 5; function processMouse(x, y, dx, dy, mc, lmc) instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) local(left, right, lastleft, lastright, i) global(manipulateXYSliders, gfx_x, gfx_y) ( left = mc & 1; right = mc & 2; lastleft = lmc & 1; lastright = lmc & 2; ( left ) ? ( ( cap_mode == 0 && !lastleft ) ? ( this.findNearest(x, y); ( drag_node > -1 ) ? ( drag_node = indices[drag_node]; cap_mode = 1; ) ) : ( cap_mode == 1 ) ? ( // We've already selected a node. x = max( min( x, .9999 ), 0.00001 ); y = max( min( y, .9999 ), 0.00001 ); manipulateXYSliders(splineIdx, drag_node, x, (1-y)); ); ) : ( ( right && !lastright ) ? ( ( cap_mode == 0 ) ? ( this.findNearest(x, y); // Are we clicking an existing one? ( drag_node > -1 ) ? ( // Kill it! ( N_read > 2 ) ? ( this.killNode(drag_node); cap_mode = 2; ) ):( // Add one? ( N_read < 9 ) ? ( ( x > 0 && y > 0 && x < 1 && y < 1 ) ? ( this.addNode(x, 1-y); cap_mode = 2; ) ); ); ); ) : ( cap_mode = 0; ) ) ); // Generate a spline object function gen_spline(N_in, splineIdx_in, xloc_in, yloc_in, xloc_in2, yloc_in2, indices_in, tempx_in, tempy_in, tempz_in, c1_in, c2_in, c3_in, c1_in2, c2_in2, c3_in2) instance(N_read, N_write, splineIdx, xloc_read, yloc_read, xloc_write, yloc_write, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) global() ( N_read = N_in; N_write = N_in; xloc_read = xloc_in; yloc_read = yloc_in; xloc_write = xloc_in2; yloc_write = yloc_in2; indices = indices_in; tempx = tempx_in; tempy = tempy_in; tempz = tempz_in; c1_read = c1_in; c2_read = c2_in; c3_read = c3_in; c1_write = c1_in2; c2_write = c2_in2; c3_write = c3_in2; splineIdx = splineIdx_in; cap_mode = 0; ); function setN(N_new) local() global() instance(N_read, N_write, splineIdx, xloc, yloc, indices, tempx, tempy, tempz, c1_read, c2_read, c3_read, c1_write, c2_write, c3_write, ptr_from_X, ptr_from_Y, ptr_from_Z, ptr_to_X, ptr_to_Y, ptr_to_Z, cap_mode, drag_node, iAudio) ( N_write = N_new; ); function wsetN(N_new) local() global() instance(x, y, w, h, spline) ( spline.setN(N_new) ); function groupWidget(x_in, y_in, w_in, h_in, label_in, r_in, g_in, b_in, a_in) local(siz, jnk) global(fontface, retina_scaling, widgetFontSize) instance(x, y, w, h, r, g, b, a, label) ( x = x_in-2; y = y_in-6; w = w_in+4; h = h_in+4; r = r_in; g = g_in; b = b_in; a = a_in; label = label_in; gfx_setfont(1, fontface, widgetFontSize*retina_scaling); gfx_measurestr(label, siz, jnk); x + 8 + siz ); function groupWidget_draw() local(siz, jnk) global(gfx_x, gfx_y, retina_scaling, widgetFontSize, fontface, font_color_r, font_color_g, font_color_b, font_color_a, group_color_r, group_color_g, group_color_b, group_color_a ) instance(x, y, w, h, r, g, b, a, label ) ( gfx_set( group_color_r, group_color_g, group_color_b, group_color_a ); gfx_rect( x, y, w, h ); gfx_setfont(1, fontface, widgetFontSize*retina_scaling); gfx_set( font_color_r, font_color_g, font_color_b, font_color_a ); gfx_measurestr(label, siz, jnk); gfx_x = x + 8; gfx_y = y - .5*jnk + 1; gfx_printf(label); gfx_set( r, g, b, .4 ); gfx_line(x, y, x, y+h); gfx_line(x+1, y, x+5, y); gfx_line(x+siz+10, y, x+w-1, y); gfx_line(x+w, y, x+w, y+h); gfx_line(x+1, y+h, x+w-1, y+h); ); function toggleLight(x_in, y_in, w_in, h_in, label_in, align_in, r_in, g_in, b_in, a_in, active_in) local(jnk, jnk1) global() instance(x, y, w, h, r, g, b, a, active, label, align, lastleft) ( x = x_in; y = y_in; w = w_in; h = h_in; r = r_in; g = g_in; b = b_in; a = a_in; label = label_in; align = align_in; active = active_in; lastleft = 0; ); function toggleLight_processMouse(xx, yy, mc) local(left) global(gfx_x, gfx_y) instance(x, y, w, h, r, g, b, a, active, label, align, lastleft) ( left = mc & 1; left ? ( ( (lastleft ~= 1 ) && ( xx > x ) && ( xx < (x+w) ) && ( yy > y ) && ( yy < (y+h) ) ) ? ( active = 1 - active; ); ); lastleft = left; ); function toggleLight_draw() local(jnk, siz) global(gfx_x, gfx_y, font_color_r, font_color_g, font_color_b, font_color_a ) instance(x, y, w, h, r, g, b, a, active, label, align, lastleft) ( gfx_set( r, g, b, .2 + .5*active ); gfx_rect( x, y, w, h ); gfx_set( r, g, b, a ); gfx_line(x, y, x, y+h); gfx_line(x+1, y, x+w-1, y); gfx_line(x+w, y, x+w, y+h); gfx_line(x+1, y+h, x+w-1, y+h); gfx_set( font_color_r, font_color_g, font_color_b, font_color_a ); ( align == 0 ) ? ( gfx_x = x+15; gfx_y = y+2; ) : ( gfx_measurestr(label, siz, jnk); gfx_x = x - siz-3; gfx_y = y+1; ); gfx_printf( label ); ); function selectionButton(x_in, y_in, w_in, h_in, label_in, r_in, g_in, b_in, a_in, hint_in) local() global() instance(x, y, w, h, r, g, b, a, active, label, lastleft, hint, htime) ( x = x_in; y = y_in; w = w_in; h = h_in; r = r_in; g = g_in; b = b_in; a = a_in; htime = 0; label = label_in; lastleft = 0; hint = hint_in; ); function setLabel( _label ) local() global() instance(label) ( label = _label; ); function drawHint_draw() global(gfx_x, gfx_y, gfx_w, gfx_h, mouse_x, mouse_y, hintTime, currentHint, retina_scaling, fontface, font_color_r, font_color_g, font_color_b, font_color_a) local(w, h) global() ( ( hintTime > .99 ) ? ( gfx_setfont(1, fontface, 14*retina_scaling); gfx_measurestr(currentHint,w,h); gfx_x = mouse_x+15; gfx_y = mouse_y+15; ( gfx_x > 0.5*gfx_w ) ? gfx_x = mouse_x - w - 8; ( gfx_y > 0.5*gfx_h ) ? gfx_y = mouse_y - h - 8; gfx_set( 0.05, 0.05, 0.1, .8 ); gfx_rect(gfx_x-2, gfx_y-2, w+4, h+4); gfx_set( font_color_r, font_color_g, font_color_b, font_color_a ); gfx_printf(currentHint); ); ); function updateHintTime(hint) global(gfx_x, gfx_y, mouse_x, mouse_y, hintTime, currentHint, delta_time, lx, ly) local() global() ( ( (lx - mouse_x) || ( ly - mouse_y ) ) > 0 ? hintTime = 0; hint != 0 ? ( currentHint = hint; hintTime = hintTime + 1 * delta_time; hintTime = min(1, hintTime) ) : ( 0 ) ); function selectionButton_draw() local(jnk, siz, hln) global(gfx_x, gfx_y, buttonFontSize, retina_scaling, fontface, font_color_r, font_color_g, font_color_b, font_color_a ) instance(x, y, w, h, r, g, b, a, active, label, lastleft, htime, style) ( style == 2 ? ( hln = (.17 + .3*(1-active))*htime; gfx_set( 0, 0, 0, 1 ); gfx_rect( x, y, ceil(w), ceil(h) ); ); hln = (.17 + .3*(1-active))*htime; gfx_set( min(1,r + hln), min(1,g + hln), min(1,b + hln), .2 + .5*active ); gfx_rect( x, y, ceil(w), ceil(h) ); gfx_set( r, g, b, a ); gfx_line(x, y, x, y+h); gfx_line(x+1, y, x+w-1, y); gfx_line(x+w, y, x+w, y+h); gfx_line(x+1, y+h, x+w-1, y+h); gfx_set( font_color_r, font_color_g, font_color_b, font_color_a ); retina_scaling > 1 ? gfx_setfont(1, fontface, buttonFontSize*retina_scaling); gfx_measurestr(label, siz, jnk); gfx_x = x + .5 * (w-siz); gfx_y = y - .5*(jnk-h) + 1; gfx_printf( label ); ); function selectionButton_linkbutton() local(jnk, siz, hln) global(gfx_x, gfx_y, buttonFontSize, retina_scaling, fontface, font_color_r, font_color_g, font_color_b, font_color_a ) instance(x, y, w, h, r, g, b, a, active, label, lastleft, htime) ( retina_scaling > 1 ? gfx_setfont(1, fontface, buttonFontSize*retina_scaling); gfx_measurestr(label, siz, jnk); gfx_x = x + .5 * (w-siz); gfx_y = y - .5*(jnk-h) + 1; //gfx_set( .3, .3, .3, 1 ); //gfx_roundrect( floor(x+.35*w)+2, floor(y + .33*h)+1, ceil(.55*w), floor(.2*h), 4); //gfx_roundrect( floor(x+.35*w)+2, floor(y + .47*h)+1, ceil(.55*w), floor(.2*h), 4); active ? gfx_set( font_color_r, font_color_g, font_color_b, font_color_a ) : gfx_set( min(1,.4 + hln), min(1,.4 + hln), min(1,.4 + hln), 1 ); gfx_arc( floor(x), floor(y + w+.05*h), floor(.6*w), 0*$pi, .5*$pi, 1); gfx_arc( floor(x), floor(y + w+.55*h), floor(.6*w), .5*$pi, $pi, 1); gfx_roundrect( floor(x+.35*w), floor(y + .33*h), ceil(.55*w), floor(.2*h), 4); gfx_roundrect( floor(x+.35*w), floor(y + .47*h), ceil(.55*w), floor(.2*h), 4); //gfx_arc( x+.8*w, y + 5*h, .35*w, 0, 2*$pi, 1); //gfx_arc( x+.8*w, y + .5*h, .35*w, 0, 2*$pi, 1); ); function highlightNow() global() local() instance(htime) ( htime = 1; ); function selectionButton_processMouse(xx, yy, mc) local(left, change) global(updateHintTime, gfx_x, gfx_y, delta_time) instance(x, y, w, h, r, g, b, a, active, label, align, lastleft, htime, hint) ( change = 0; left = mc & 1; ( xx > x ) && ( xx < (x+w) ) && ( yy > y ) && ( yy < (y+h) ) ? ( left ? ( ( (lastleft ~= 1 ) ) ? ( active = 1 - active; change = 1; ); ); htime = updateHintTime(hint); ) : htime = max( 0.6 * htime, updateHintTime(0) ); lastleft = left; change ); function selectionButton_setActive(active_in) local() global(gfx_x, gfx_y) instance(x, y, w, h, r, g, b, a, active, label, align, lastleft) ( active = active_in; ); function combobox(x_in, y_in, w_in, h_in, r_in, g_in, b_in, a_in, nitems_in, stridx_in, goup_in, cols_in, hint_in ) local() global(newUI) instance(x, y, w, h, r, g, b, a, open, curitem, nitems, cap, hover, stridx, lastleft, hasfocus, goup, cols, thisUI, htime, hint) ( thisUI = newUI+=1; x = x_in; y = y_in+1; w = w_in; h = ceil(h_in-2); r = r_in; g = g_in; b = b_in; a = a_in; nitems = nitems_in; cap = 0; curitem = 0; hover = 8; open = 0; stridx = stridx_in; lastleft = 0; hasfocus = 0; goup = goup_in; cols = cols_in; htime = 0; hint = hint_in; ); function combobox_setcuritem( item ) local(i, xtxt) global(gfx_x, gfx_y) instance(x, y, w, h, r, g, b, a, open, curitem, nitems, cap, hover, stridx, hasfocus) ( curitem = item; ); function combobox_draw() local(i, xtxt, x1, x2, x3, y1, y2, y3, pad, wi) global(gfx_x, gfx_y, lastUI, retina_scaling highlight_color_r, highlight_color_g, highlight_color_b, highlight_color_a, font_color_r, font_color_g, font_color_b, font_color_a ) instance(x, y, w, h, r, g, b, a, open, curitem, nitems, cap, hover, stridx, hasfocus, goup, cols, thisUI, htime) ( gfx_set( min(1,r + .15*htime), min(1,g + .15*htime), min(1,b + .25*htime), .1 ); gfx_rect( x, y, w, h ); lastUI == thisUI ? gfx_set( highlight_color_r, highlight_color_g, highlight_color_b, highlight_color_a ) : gfx_set( r, g, b, a ); gfx_line(x, y, x, y+h); gfx_line(x+1, y, x+w-1, y); gfx_line(x+w, y, x+w, y+h); gfx_line(x+1, y+h, x+w-1, y+h); pad = .3*h; wi = .5 * (h-pad); x1 = x+w-wi-pad; x2 = x+w-pad; x3 = x+w-.5*wi-pad; y1 = y+pad; y2 = y+pad; y3 = y+h-pad; gfx_line(x1, y1, x2, y2); gfx_line(x2, y2, x3, y3); gfx_line(x3, y3, x1, y1); xtxt = x+3*retina_scaling; gfx_x = xtxt; gfx_y = y+4*retina_scaling; gfx_set( font_color_r, font_color_g, font_color_b, font_color_a ); gfx_printf(comboStrings(stridx, curitem)); ); function combobox_draw_top() local(i, j, xtxt, x1, x2, x3, y1, y2, y3, pad, wi, delta, ny) global(gfx_x, gfx_y, font_color_r, font_color_g, font_color_b, font_color_a ) instance(x, y, w, h, r, g, b, a, open, curitem, nitems, cap, hover, stridx, hasfocus, goup, cols) ( xtxt = x+3; delta = goup ? (nitems/cols+1)*h : 0; gfx_x = xtxt; gfx_y = y + 4 - delta; ny = ceil(nitems/cols); open ? ( gfx_set( r*.3, g*.3, b*.3, 1 ); gfx_rect( x - (cols-1)*w, y-delta+h-1, cols*w+2, h * ny + 2 ); gfx_set( r*.1, g*.1, b*.1, 1 ); gfx_rect( x - (cols-1)*w+1, y-delta+h, cols*w, h * ny ); i = 0; j = 0; gfx_set( r, g, b, a, 0.95 ); loop( cols, loop( ny, gfx_x = xtxt - (cols-1-j)*w + 1; gfx_y += h; hover == i ? ( gfx_rect( gfx_x-3, gfx_y - 3, w, h ); gfx_set( 0, 0, 0, a, 0.95 ); ) : gfx_set( font_color_r, font_color_g, font_color_b, font_color_a ); gfx_printf(comboStrings(stridx, i)); i += 1; ); gfx_y = y + 4 - delta; j += 1; ); gfx_set( 1, 1, 1, .1 ); ) ); function combobox_processMouse(xx, yy, mc) local(over, left, right, change, delta, xmin, xmax, ymin, ymax, xl, yl, ny) global(gfx_x, gfx_y, lastUI, lastChar) instance(x, y, w, h, r, g, b, a, open, curitem, nitems, cap, hover, stridx, lastleft, hasfocus, goup, cols, thisUI, htime, hint) ( delta = goup ? (nitems/cols+1)*h : 0; change = 0; left = mc & 1; xmin = x - (cols-1)*w; ymin = y + h - delta; xmax = x + w; ny = ceil(nitems/cols); ymax = ymin + ny*h; // ( y+((nitems)/cols+1)*h-delta ); ( lastUI == thisUI ) ? ( ( lastChar == 1685026670 ) ? ( curitem = curitem + 1; curitem > nitems - 1 ? curitem = 0; change = 1; ) : ( ( lastChar == 30064 ) ? ( curitem = curitem - 1; curitem < 0 ? curitem = nitems-1; change = 1; ); ); ); over = xx > x && xx < ( x+w ) && yy > y && yy < ( y + h ); over ? ( htime = updateHintTime(hint); ) : htime = updateHintTime(0); open ? ( xl = min( max( 0, floor((xx - xmin)/w)), cols-1 ); yl = floor((yy-ymin)/h); // hover = min( nitems-1, max( 0, xl * floor(nitems/cols) + floor((max(ymin,min(ymax-h,yy)) - (y-delta))/h) - 1 ) ); hover = min( nitems-1, max( 0, xl * ny + max(0, min(ny-1, yl)) ) ); !lastleft && left ? ( open = 0; ( xx > xmin && xx < xmax && yy > (y+h-delta) && yy < ( ymax ) ) ? ( curitem = hover; change = 1 ); ) ) : ( ( lastleft == 0 && left && over ) ? ( open = 1; hasfocus = 1; lastUI = thisUI; ) ); ( !left && !open ) ? hasfocus = 0; lastleft = left; change ); function sliderWidget(x_in, y_in, w_in, h_in, label_in, r_in, g_in, b_in, a_in, two_values, minval_in, maxval_in, default_in, unit_in, isInteger_in, hint_in ) local() global(newUI) instance(x, y, w, h, r, g, b, a, default, minval, maxval, value, value2, label, lastleft, lastright, lastclick, yslidercenter, cap, twoval, unit, isInteger, thisUI, htime, hint, onmarker) ( thisUI = newUI+=1; x = x_in+2; y = y_in; w = w_in-4; h = h_in; r = r_in; g = g_in; b = b_in; a = a_in; label = label_in; lastleft = 0; lastright = 0; value = 0; value2 = 0; yslidercenter = y + 0.3 * h; cap = 0; twoval = two_values; /* Do we have two values? */ minval = minval_in; maxval = maxval_in; default = ( default_in - minval ) / ( maxval - minval ); lastclick = 0; unit = unit_in; isInteger = isInteger_in; htime = 0; hint = hint_in; onmarker = 0; ); function sliderWidget_setValue(value_in) local() global(gfx_x, gfx_y) instance(x, y, w, h, r, g, b, a, default, minval, maxval, value, value2, label, lastleft, lastclick, yslidercenter, cap, twoval) ( value = ( value_in - minval ) / ( maxval - minval ) ); function sliderWidget_getValue() local(v) global(gfx_x, gfx_y) instance(x, y, w, h, r, g, b, a, default, minval, maxval, value, value2, label, lastleft, lastclick, yslidercenter, cap, twoval, isInteger) ( v = value * ( maxval - minval ) + minval; v = isInteger ? floor(v+0.499999) : v; v ); function sliderWidget_draw() local(jnk, siz, q, str, modmax, modmin, modoffset, tmp) global(slider38, gfx_x, gfx_y, lastUI, retina_scaling,widgetFontSize, dynval, modulator.modvalue, mlevel, fontface, slider39, modulatorDynamics, font_color_r, font_color_g, font_color_b, font_color_a, slider_marker_r, slider_marker_g, slider_marker_b, slider_marker_a, highlight_color_r, highlight_color_g, highlight_color_b, highlight_color_a ) instance(x, y, w, h, r, g, b, a, default, minval, maxval, value, value2, label, lastleft, lastclick, yslidercenter, cap, twoval, unit, thisUI, htime, overridevalue, overrideunit, onmarker, hasFilterDynamics, hasModulatorDynamics) ( gfx_setfont(1, fontface, widgetFontSize*retina_scaling); //gfx_set( r, g, b, .1 ); gfx_set( min(1,r + .25*htime), min(1,g + .25*htime), min(1,b + .25*htime), .1 ); gfx_rect( x-3*retina_scaling, yslidercenter-.25*h, w+6*retina_scaling, h*.5 ); ( modulatorDynamics && hasModulatorDynamics == 1 ) ? ( gfx_set( r, g, b, .4 ); modoffset = slider38 & 4 ? .5 * value2*w * slider39; modmax = x + (1+slider39) * value2 * w + value*w - modoffset; modmin = x + value*w - modoffset; modmax < modmin ? ( tmp = modmax; modmax = modmin; modmin = tmp; ); modmin = max( x, min( x+w, modmin ) ); modmax = max( x, min( x+w, modmax ) ); gfx_rect( modmin, yslidercenter - 2, modmax - modmin, 1 ); gfx_rect( modmin, yslidercenter + 2, modmax - modmin, 1 ); ); lastUI == thisUI ? gfx_set( highlight_color_r, highlight_color_g, highlight_color_b, highlight_color_a ) : gfx_set( r, g, b, 0.8 ); gfx_line(x, yslidercenter, x+w, yslidercenter); gfx_set( r*.3, g*.3, b*.3, 0.8 ); gfx_line(x + retina_scaling, yslidercenter + 1, x+w + retina_scaling, yslidercenter + 1); gfx_set( r, g, b, 1.0 ); gfx_rect( x-2*retina_scaling + value*w, yslidercenter - .2*h, 4*retina_scaling, h*.4 ); gfx_set( r*.2, g*.2, b*.2, 0.4 ); gfx_rect( x-retina_scaling + value*w, yslidercenter - .2*h + 1, 2*retina_scaling, h*.4-2 ); onmarker == 1 ? ( gfx_set( 1, 1, 1, 0.4 ); gfx_rect( x-2*retina_scaling + value*w-1, yslidercenter - .2*h-1, 4*retina_scaling+2, h*.4+2 ); ); gfx_set( r, g, b, 0.4 ); value2 > 0 ? gfx_rect( x + value*w, yslidercenter - .1*h, value2*w+1, h*.3 ) : gfx_rect( x + (value+value2)*w, yslidercenter - .1*h, abs(value2)*w, h*.3 ); gfx_set( slider_marker_r, slider_marker_g, slider_marker_b, slider_marker_a ); mlevel = hasModulatorDynamics*modulator.modvalue*slider39 + (hasFilterDynamics > 0 ? dynval : 0); mlevel = x + (value+value2*mlevel)*w; mlevel = max( x, min( x+w, mlevel ) ); gfx_rect( mlevel-1, yslidercenter - .2*h, 2, h*.4 ); gfx_set( font_color_r, font_color_g, font_color_b, font_color_a ); gfx_x = x; gfx_y = y + 11*retina_scaling; gfx_printf( label ); ( overridevalue == 0 ) ? ( sprintf( str, "%2.3g%s", this.sliderWidget_getValue(), unit ); ) : ( ( overridevalue == -1000 ) ? ( sprintf( str, "%2.3g (%s)", this.sliderWidget_getValue(), overrideunit ); ) : ( ( overridevalue > 1000 ) ? ( sprintf( str, "%2.3g (%2.3g k%s)", this.sliderWidget_getValue(), overridevalue/1000, overrideunit ); ) : ( sprintf( str, "%2.3g (%2.3g %s)", this.sliderWidget_getValue(), overridevalue, overrideunit ); ) ); ); gfx_measurestr(str, siz, jnk); gfx_x = x + w - siz; gfx_y = y + 11*retina_scaling; gfx_printf( str ); ); function sliderWidget_setValue2(value_in) local() global(gfx_x, gfx_y) instance(x, y, w, h, r, g, b, a, default, minval, maxval, value, value2, label, lastleft, lastclick, yslidercenter, cap, twoval) ( value2 = value_in; ); // Set value in a non-normalized manner function sliderWidget_setValue2_nn(value_in) local() global(gfx_x, gfx_y) instance(x, y, w, h, r, g, b, a, default, minval, maxval, value, value2, label, lastleft, lastclick, yslidercenter, cap, twoval) ( value2 = ( value_in > 0 ) ? value_in * (1.0 - value) : value_in * value; ); function sliderWidget_getValue2() local() global(gfx_x, gfx_y) instance(x, y, w, h, r, g, b, a, default, minval, maxval, value, value2, label, lastleft, lastclick, yslidercenter, cap, twoval) ( value2 ); function sliderWidget_getValue2_nn() local() global(gfx_x, gfx_y) instance(x, y, w, h, r, g, b, a, default, minval, maxval, value, value2, label, lastleft, lastclick, yslidercenter, cap, twoval) ( value2 > 0 ? value2 / (1.0 - value) : value2 / value ); function sliderWidget_processMouse(xx, yy, dx, dy, mc) local(left, right, change, newcap, onslider, shft) global(gfx_x, gfx_y, mouse_wheel, mouse_cap, lastUI, lastChar, retina_scaling) instance(x, y, w, h, r, g, b, a, default, minval, maxval, value, value2, label, lastleft, lastright, lastclick, yslidercenter, cap, twoval, thisUI, htime, hint, onmarker, lastrightclick) ( left = mc & 1; right = mc & 2; shft = mc & 8; change = 0; newcap = 0; onslider = ( ( xx > x ) && ( xx < (x+w) ) && ( yy > (yslidercenter-.2*h) ) && ( yy < (yslidercenter+.2*h) ) ); onmarker = abs( value * w + x - xx ) < 5*retina_scaling && ( yy > (yslidercenter-.2*h) ) && ( yy < (yslidercenter+.2*h) ); onslider ? ( htime = updateHintTime(hint); ) : htime = updateHintTime(0); ( lastUI == thisUI ) ? ( ( lastChar == 1919379572 ) ? value = value + .001; ( lastChar == 1818584692 ) ? value = value - .001; ); left ? ( ( ( lastleft == 0 ) && ( time_precise() - lastclick ) < .2 ) ? ( value = default; change = 1; ) : ( ( cap == 1 ) || ( ( onslider || onmarker ) && lastleft == 0 ) ) ? ( (mouse_cap & 8 == 0) ? ( value = (xx-x)/w; ) : ( value = value - .125*dx/w; ); change = 1; newcap = 1; lastclick = time_precise(); lastUI = thisUI; ); ) : ( twoval && right ? ( ( ( cap == 2 ) || ((onmarker || onslider) && lastright == 0) ) ? ( ( ( lastright == 0 ) && ( time_precise() - lastrightclick ) < .15 ) ? ( value2 = 0; change = 2; lastrightclick = time_precise(); ) : ( value2 = (xx-x)/w - value; change = 2; newcap = 2; lastrightclick = time_precise(); ) ); ) : ( (mouse_wheel ~= 0) && onslider ) ? ( ( shft && twoval ) ? ( value2 = value2 + .00001 * mouse_wheel; change = 1; ) : ( value = value + .00001 * mouse_wheel; change = 1; ); mouse_wheel = 0; ); ); lastleft = left; lastright = right; cap = newcap; value = value > 1.0 ? 1 : value; value = value < 0.0 ? 0 : value; twoval ? ( value2 = (value2+value) > 1.0 ? 1.0-value : value2; value2 = (value2+value) < 0.0 ? -value : value2; ); change ); function init_window(xp, yp, wp, hp, N, splineIdx, splineCoordsX, splineCoordsY, splineCoordsX2, splineCoordsY2, indices, tempCoordStorageX, tempCoordStorageY, tempCoordStorageZ, c1_storage, c2_storage, c3_storage, c1_storage2, c2_storage2, c3_storage2) instance(x, y, w, h, spline, buttonOff, buttonArctan, buttonFast, buttonSpline, buttonSine) global(buttonOff.selectionButton, retina_scaling) local(hy, bw, bh) ( spline = spline.gen_spline(N, splineIdx, splineCoordsX, splineCoordsY, splineCoordsX2, splineCoordsY2, indices, tempCoordStorageX, tempCoordStorageY, tempCoordStorageZ, c1_storage, c2_storage, c3_storage, c1_storage2, c2_storage2, c3_storage2); ); function gen_window(xp, yp, wp, hp, N, splineIdx, splineCoordsX, splineCoordsY, splineCoordsX2, splineCoordsY2, indices, tempCoordStorageX, tempCoordStorageY, tempCoordStorageZ, c1_storage, c2_storage, c3_storage, c1_storage2, c2_storage2, c3_storage2) instance(x, y, w, h, spline, buttonOff, buttonArctan, buttonFast, buttonSpline, buttonSine) global(buttonOff.selectionButton, retina_scaling, selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a ) local(hy, bw, bh) ( x = xp; y = yp; w = wp; h = hp; hy = 15*retina_scaling; bw = 55*retina_scaling; bh = 10*retina_scaling; buttonOff.selectionButton(x+5, y+4, bw, bh, "OFF", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "No waveshaping"); buttonArctan.selectionButton(x+5, y+4+hy, bw, bh, "Tanh", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Tanh waveshaper"); buttonFast.selectionButton(x+5, y+4+2*hy, bw, bh, "Fast", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Tanh approximation"); buttonSpline.selectionButton(x+5, y+4+3*hy, bw, bh, "Spline", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Spline waveshaping"); buttonSine.selectionButton(x+5, y+4+4*hy, bw, bh, "Sine", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Sine waveshaping (FM-like)"); ); function gen_dynamics(xp, yp, wp, hp) instance(x, y, w, h, yref, sc, cap_mode, inLight, outLight, dynLight, lastleft, RMSButton, MIDIButton, MIDIButton2) global(inLight.toggleLight, retina_scaling,RMSButton.selectionButton,MIDIButton.selectionButton,MIDIButton2.selectionButton, selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, rms_in_r, rms_in_g, rms_in_b, rms_in_a, rms_out_r, rms_out_g, rms_out_b, rms_out_a, dyn_color_r, dyn_color_g, dyn_color_b, dyn_color_a ) local(hy, bw, bh, ych, xoff, yoff) ( x = xp; y = yp; w = wp; h = hp; cap_mode = 0; lastleft = 0; bw = 10*retina_scaling; bh = 10*retina_scaling; ych = 2*bh; xoff = x+w-15*retina_scaling; yoff = y+5*retina_scaling; inLight.toggleLight(xoff, yoff, bw, bh, "In", 1, rms_in_r, rms_in_g, rms_in_b, rms_in_a, 1); outLight.toggleLight(xoff, yoff+ych, bw, bh, "Out", 1, rms_out_r, rms_out_g, rms_out_b, rms_out_a, 1); dynLight.toggleLight(xoff, yoff+2*ych, bw, bh, "Dynamics", 1, dyn_color_r, dyn_color_g, dyn_color_b, dyn_color_a, 1); hy = 15*retina_scaling; bw = 55*retina_scaling; bh = 10*retina_scaling; RMSButton.selectionButton(x+5, y+4, bw, bh, "RMS", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "RMS trigger\n\nSelecting this mode bases dynamics on RMS value of incoming signal."); MIDIButton.selectionButton(x+5, y+4 + hy, bw, bh, "MIDI", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Note trigger\n\nSelecting this mode bases dynamics on MIDI note triggers."); MIDIButton2.selectionButton(x+5, y+4 + 2*hy, bw, bh, "MIDI2", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Note trigger\n\nSelecting this mode bases dynamics on MIDI notes\nand uses the velocity information from the notes."); sc = h; ); function processMouse(mx, my, dx, dy, mc, lmc) instance(x, y, w, h, spline, buttonOff, buttonArctan, buttonFast, buttonSpline, buttonSine) global(slider56, buttonOff.selectionButton_processMouse, buttonOff.selectionButton_setActive) local() ( buttonOff.selectionButton_setActive(0); buttonArctan.selectionButton_setActive(0); buttonFast.selectionButton_setActive(0); buttonSpline.selectionButton_setActive(0); buttonSine.selectionButton_setActive(0); buttonSine.selectionButton_processMouse(mx, my, mc) ? ( slider56 = 4; slider_automate(slider56); ); buttonOff.selectionButton_processMouse(mx, my, mc) ? ( slider56 = 3; slider_automate(slider56); ); buttonArctan.selectionButton_processMouse(mx, my, mc) ? ( slider56 = 1; slider_automate(slider56); ); buttonFast.selectionButton_processMouse(mx, my, mc) ? ( slider56 = 2; slider_automate(slider56); ); buttonSpline.selectionButton_processMouse(mx, my, mc) ? ( slider56 = 0; slider_automate(slider56); ); (slider56 == 0) ? ( buttonSpline.selectionButton_setActive(1); ) : ( slider56 == 1 ) ? ( buttonArctan.selectionButton_setActive(1); ) : ( slider56 == 2 ) ? ( buttonFast.selectionButton_setActive(1); ) : ( slider56 == 3 ) ? ( buttonOff.selectionButton_setActive(1); ) : ( slider56 == 4 ) ? ( buttonSine.selectionButton_setActive(1); ); spline.processMouse((mx-x)/w, (my-y)/h, dx/w, dy/h, mc, lmc); ); function sort_spline() instance(x, y, w, h, spline) global() local() ( spline.sort_spline(); ); function update_spline() instance(x, y, w, h, spline) global() local() ( spline.update_spline(); ); function rotatedPrint(x, y, str, rot) local(sw,sh) global(gfx_x, gfx_y, gfx_dest, gfx_mode, font_color_r, font_color_g, font_color_b, font_color_a) ( gfx_measurestr(str, sw, sh); gfx_dest = 1; gfx_setimgdim(1, sw, sw); gfx_set( 0, 0, 0, 1 ); gfx_rect(0, 0, sw, sw); gfx_x = 1; gfx_y = 1; gfx_set( font_color_r, font_color_g, font_color_b, font_color_a ); gfx_printf(str); gfx_dest = -1; gfx_mode = 1; gfx_x = x; gfx_y = y; gfx_blit(1, 1.0, rot); gfx_mode = 0; ); function ylabel(str) instance(x, y, w, h) globals(gfx_r, gfx_g, gfx_b, gfx_x, gfx_y, gfx_dest, rotatedPrint, retina_scaling) local(sw, sh) ( gfx_measurestr(str, sw, sh); rotatedPrint(x-16*retina_scaling, y+0.5*(h-sw), str, -.5*$pi); ); function xlabel(str) instance(x, y, w, h) globals(gfx_r, gfx_g, gfx_b, gfx_x, gfx_y, font_color_r, font_color_g, font_color_b, font_color_a ) local(sw, sh) ( gfx_set( font_color_r, font_color_g, font_color_b, font_color_a ); gfx_measurestr(str, sw, sh); gfx_x = x + 0.5*(w-sw); gfx_y = y + h + 12; gfx_printf(str); ); function draw_text(str, rx, ry) instance(x, y, w, h, spline) globals(gfx_r, gfx_g, gfx_b, gfx_x, gfx_y, font_color_r, font_color_g, font_color_b, font_color_a ) local() ( gfx_set( font_color_r, font_color_g, font_color_b, font_color_a ); gfx_x = x + w*rx; gfx_y = y + h*ry; gfx_printf(str); ); function draw_grid(N) instance(x, y, w, h, spline) globals(gfx_r, gfx_g, gfx_b, gfx_x, gfx_y grid_color_r, grid_color_g, grid_color_b, grid_color_a ) local(dx, dy) ( gfx_set( grid_color_r, grid_color_g, grid_color_b, grid_color_a ); dx = w/(N-1); dy = h/(N-1); gfx_x = x; gfx_y = y; loop(N, gfx_line(gfx_x, gfx_y, gfx_x, gfx_y+h); gfx_x += dx; ); gfx_x = x; gfx_y = y+h; loop(N, gfx_line(gfx_x, gfx_y, gfx_x+w, gfx_y); gfx_y -= dy; ); ); function draw_grid(N, dy) instance(x, y, w, h, spline) globals(gfx_r, gfx_g, gfx_b, gfx_x, gfx_y, grid_color_r, grid_color_g, grid_color_b, grid_color_a ) local(dx, dy) ( gfx_set( grid_color_r, grid_color_g, grid_color_b, grid_color_a ); dx = w/(N-1); gfx_x = x; gfx_y = y; loop(N, gfx_line(gfx_x, gfx_y, gfx_x, gfx_y+h); gfx_x += dx; ); gfx_x = x; gfx_y = y+h; loop(min(100, floor(h/dy)), gfx_line(gfx_x, gfx_y, gfx_x+w, gfx_y); gfx_y -= dy; ); ); function draw_back() instance(x, y, w, h, yref, sc) globals(gfx_r, gfx_g, gfx_b, gfx_x, gfx_y, backface_color_r, backface_color_g, backface_color_b, backface_color_a ) local() ( gfx_set( backface_color_r, backface_color_g, backface_color_b, backface_color_a ); gfx_rect(x, y, w, h); ); function draw_window(movAvgL, movAvgR, movAvgOL, movAvgOR) instance(x, y, w, h, spline, buttonOff, buttonArctan, buttonFast, buttonSpline, buttonSine) globals(gfx_r, gfx_g, gfx_b, gfx_x, gfx_y, buttonOff.selectionButton_draw) ( this.draw_back(); this.draw_grid(10); spline.plot_spline(x, y, w, h); gfx_set( 0.6 + max(-.2,(movAvgL - 1)), .1, .1, 1.0); gfx_rect(x,y+h+2,w*min(1,movAvgL),2); gfx_rect(x,y+h+4,w*min(1,movAvgR),2); gfx_set( 0.2, .2, 0.9 + max(movAvgOL - 1, -.5), 1.0); movAvgOL = min(movAvgOL, 1); movAvgOR = min(movAvgOR, 1); gfx_rect(x-2,y+h-h*movAvgOL,2,h*movAvgOL); gfx_rect(x-4,y+h-h*movAvgOR,2,h*movAvgOR); buttonOff.selectionButton_draw(); buttonArctan.selectionButton_draw(); buttonFast.selectionButton_draw(); buttonSpline.selectionButton_draw(); buttonSine.selectionButton_draw(); ); function draw_buffer(scopeptr, scopebuffer, scopebuffermax, mul) instance(x, y, w, h, yref, sc, cap_mode) globals(gfx_r, gfx_g, gfx_b, gfx_x, gfx_y) local(xx, dx, lptr, yy, lastx, lasty, scale, isc) ( xx = x; dx = w/(scopebuffermax-scopebuffer); lptr = scopeptr; scale = (mul > 0) ? mul*h : sc; gfx_x = xx; gfx_y = yref; isc = h/scale; loop(scopebuffermax-scopeptr, yy = yref - scale*min(isc,lptr[]); gfx_lineto(xx, yy); lptr += 1; xx += dx; ); lptr = scopebuffer; loop(scopeptr - scopebuffer, yy = yref - scale*min(isc,lptr[]); gfx_lineto(xx, yy); lptr += 1; xx += dx; ); ); function draw_dynamics(thresh) instance(x, y, w, h, yref, sc, cap_mode, highlight, inLight, outLight, dynLight, RMSButton, MIDIButton, MIDIButton2) globals(slider45, gfx_r, gfx_g, gfx_b, gfx_x, gfx_y, inLight.toggleLight_draw, RMSButton.selectionButton_draw, MIDIButton.selectionButton_draw, MIDIButton2.selectionButton_draw, thresh_color_r, thresh_color_g, thresh_color_b, thresh_color_a ) local(texloc, lineloc) ( yref = y+h; this.draw_grid(10, 10*sc/h); gfx_set( 0.0, 0.0, 0.0, 1.0 ); slider45 < 2 ? ( gfx_x = x; texloc = yref-sc*thresh-9; ( texloc > y ) ? ( gfx_y = texloc; gfx_printf( "Thresh" ); ); lineloc = yref - sc*thresh+1; ( lineloc > y ) ? gfx_line( x, lineloc, x + w, yref -sc * thresh + 1 ); gfx_set( thresh_color_r, thresh_color_g, thresh_color_b, thresh_color_a ); gfx_x = x+2; ( texloc > y ) ? ( gfx_y = texloc-1; gfx_printf( "Thresh" ); ); ( lineloc > y ) ? ( gfx_line( x, yref - sc*thresh, x + w, yref -sc*thresh ); ( highlight == 1 ) ? gfx_rect( x, yref - sc*thresh-1, w, 2 ); ); ); inLight.toggleLight_draw(); outLight.toggleLight_draw(); dynLight.toggleLight_draw(); RMSButton.selectionButton_draw(); MIDIButton.selectionButton_draw(); MIDIButton2.selectionButton_draw(); ); function processMouseDynamics(xx, yy, dx, dy, mc, thresh) instance(x, y, w, h, yref, sc, cap_mode, highlight, inLight, outLight, dynLight, lastleft, RMSButton, MIDIButton, MIDIButton2) local(left, right, buttonClicked) global(slider45, forceUpdate, gfx_x, gfx_y, mouse_wheel, slider59, inLight.toggleLight_processMouse, outLight.toggleLight_processMouse, dynLight.toggleLight_processMouse, RMSButton.selectionButton_setActive, MIDIButton.selectionButton_setActive, MIDIButton2.selectionButton_setActive, RMSButton.selectionButton_processMouse, MIDIButton.selectionButton_processMouse, MIDIButton2.selectionButton_processMouse) ( left = mc & 1; right = mc & 2; inLight.toggleLight_processMouse(xx, yy, mc); outLight.toggleLight_processMouse(xx, yy, mc); dynLight.toggleLight_processMouse(xx, yy, mc); buttonClicked = 0; RMSButton.selectionButton_processMouse(xx, yy, mc) ? ( slider45 = slider45 & 1; slider_automate(slider45); buttonClicked = 1; ); MIDIButton.selectionButton_processMouse(xx, yy, mc) ? ( slider45 = 2 + (slider45 & 1); slider_automate(slider45); buttonClicked = 1; ); MIDIButton2.selectionButton_processMouse(xx, yy, mc) ? ( slider45 = 4 + (slider45 & 1); slider_automate(slider45); buttonClicked = 1; ); RMSButton.selectionButton_setActive(slider45<2); MIDIButton.selectionButton_setActive(slider45>1&&slider45<4); MIDIButton2.selectionButton_setActive(slider45>3); ( buttonClicked == 0 ) ? ( highlight = 0; ( (mouse_wheel ~= 0) && xx > x && yy > y && xx < (x+w) && yy < (y+h) ) ? ( sc += .5*mouse_wheel; mouse_wheel = 0; ( sc < 0 ) ? sc = 0.01; ); ( left ) ? ( ( cap_mode == 0 ) ? ( ( xx > x && yy > (y-8) && xx < (x+w) && yy < (y+h) && lastleft == 0 ) ? ( ( yy > (yref - sc*thresh - 8) ) && ( yy < (yref - sc*thresh + 8) ) ? ( cap_mode = 2; ) : ( cap_mode = 1; ); ); ) : ( cap_mode == 1 ) ? ( sc += 15 * dy; ( sc < 100 ) ? sc = 100; ( sc > 5000 ) ? sc = 5000; ) : ( thresh += dy/h/(sc/h); ( thresh < 0 ) ? thresh = 0; ( thresh > h/sc ) ? thresh = h/sc; ( thresh > 1 ) ? thresh = 1; slider59 = thresh; slider_automate(slider59); forceUpdate = 1; ); ) : ( cap_mode = 0; ( xx > 0 && yy > 0 && xx < (x+w) && yy < (y+h) ) ? ( ( yy > (yref - sc*thresh-10) ) && ( yy < (yref - sc*thresh+10) ) ? ( highlight = 1; ); ); ); ); lastleft = left; thresh ); function initRMS(N, loc_in) local() global() instance(loc, loc_end, ptr, movavg, sc) ( sc = 1.0/N; ptr = loc_in; loc = loc_in; loc_end = loc_in + N; loop(N+1, ptr[] = 0; ptr += 1; ); ptr = loc_in; movavg = 0; ); function updateRMS(sr, sl) local( M ) global() instance(loc, loc_end, ptr, movavg, sc) ( M = max(sr*sr, sl*sl); M = sc * min(M, 2.4); movAvg -= ptr[]; movAvg = 0.999999999*movAvg; // Very simple DC corr (dissipate energy) ptr[] = M; movAvg += M; ptr += 1; ptr > loc_end ? ptr = loc; movAvg ); function updateIntegrationTime() ( integrationTime = ( 1 + 7*rms_x4_1.active ) * ( 1 + 3*rms_x4_2.active ) * slider64; ( (lastIntegrationTime != integrationTime) || (slider35 & 1 != lookAhead) ) ? ( lastIntegrationTime = integrationTime; lookAhead = slider35 & 1; ndelay = ceil(srate*lastIntegrationTime/1000); RMS1.initRMS(ndelay, 100000); RMS2.initRMS(ndelay, 200000); ndelay = ndelay * 0.5; preBufferL.initBuffer(300000, 300000 + ndelay); preBufferR.initBuffer(400000, 400000 + ndelay); preBufferMod.initBuffer(1600000, mod_buffer + ndelay); lookAhead ? ( // delays the first two channels (spl0/spl1). lookAheadDelay = ndelay; ) : ( lookAheadDelay = 0; ); ); ); ////////////////////////////////////////////////////////// // Spectrum code ////////////////////////////////////////////////////////// function feedSample(sample) global(fftSize) instance(recPtr, window, rStart, rEnd, fftLoc) local() ( recPtr[] = sample; recPtr = (recPtr+1) >= rEnd ? rStart : recPtr + 1; ); function initWindow(windowtype) global(fftSize) instance(recPtr, window, rStart, rEnd, fftLoc) local(i, pwr, dwindowpos, windowpos) ( windowpos = 0; dwindowpos = $pi*2/fftSize; i = 0; pwr = 0; loop(fftSize*.5+1, pwr += (window[i] = ( windowtype==1 ? ( 0.53836 - cos(windowpos)*0.46164 ) : windowtype==2 ? ( 0.35875 - 0.48829 * cos(windowpos) + 0.14128 * cos(2*windowpos) - 0.01168 * cos(3*windowpos) ) : windowtype==3 ? ( 0.42 - 0.50 * cos(windowpos) + 0.08 * cos(2.0*windowpos) ) : windowtype==4 ? ( 1.0 ) : ( .21557895 - 0.41663158 * cos(windowpos) + 0.277263158 * cos(2*windowpos) - 0.083578947 * cos(3*windowpos) + 0.006947368 * cos(4*windowpos) ) ) ); i+=1; windowpos+=dwindowpos; ); pwr=.5/(pwr*2-window[i-1]); loop(fftsize*.5+1,window[i-=1]*=pwr); ); function calcFFT() global(fftSize) instance(recPtr, window, rStart, rEnd, fftLoc, slope, yshift) local(buf1, buf2, buf3, yOut, i, prec, ty) ( slope = 3; buf1=recPtr-fftSize; buf1= rEnd ? buf1 -= (rEnd-rStart); ); buf2-=1; loop(fftSize*.5 - 1, buf3[] = buf1[]*(buf2-=1)[]; buf3+=1; (buf1+=1) >= rEnd ? buf1 -= (rEnd-rStart); ); fft_real(fftLoc,fftSize); fft_permute(fftLoc,fftSize/2); buf3 = fftLoc; yOut = fftLoc; i = 0; slope = .5*log(2)*slope; yshift = slope*log(1.0+.5*fftSize); prec = (10^(-500/20*2)); loop(fftSize*0.5, ty = sqr(buf3[0])+sqr(buf3[1]); ty = log(max(ty,prec)); ty = ty + slope*log(1.0+i) - yshift; yOut[] = ty; yOut += 1; buf3 += 2; i += 1; ); // fftLoc[0]=-100; ); function setWindowLocation(_x, _y, _w, _h) global() instance(x, y, w, h, cap) local() ( cap = 0; x = _x; y = _y; w = _w; h = _h; ); function drawGrid() global( fftSize, srate, grid_color_r, grid_color_g, grid_color_b, grid_color_a, backface_color_r, backface_color_g, backface_color_b, backface_color_a ) instance(x, y, w, h, recPtr, window, rStart, rEnd, fftLoc, floorLevel, hzoffset ) local(xx, i, wsc, N) ( i = 0; gfx_set( backface_color_r, backface_color_g, backface_color_b, backface_color_a ); gfx_rect(x, y, w, h); gfx_set( grid_color_r, grid_color_g, grid_color_b, grid_color_a ); gfx_line(x, y, x+w, y); gfx_line(x, y+h, x+w, y+h); gfx_line(x, y, x, y+h); gfx_line(x+w, y, x+w, y+h); i = 0; wsc = w/log(1+fftSize*0.5-hzoffset); loop(21, xx = x + log(1+i*fftSize/srate-hzoffset)*wsc; gfx_line(xx, y, xx, y+h); i < 10 ? i += 2 : i < 100 ? i += 20 : i < 1000 ? i += 200 : i < 10000 ? i += 2000 : i < 100000 ? i += 20000; ); N = 8; xx = y; loop(N, xx += h/8; gfx_line(x, xx, x+w, xx); ); ); function drawLine(x1, y1, x2, y2) local(dx, dy, x, smooth) global(gfx_x, gfx_y) instance() ( smooth = 1; gfx_x=x1; gfx_y=y1; smooth ? ( (x2 - x1) > 2 ? ( dx = 1/(x2-x1); dy = (y2 - y1)*6*dx; x = 0; loop(x2-x1, x2 = x1 + 1; y2 = y1 + dy * ( x - x*x ); gfx_line(x1, y1-1, x2, y2-1, 1); gfx_lineto(x2,y2,1); x1 = x2; y1 = y2; x = x + dx; ); ) : ( gfx_line(x1, y1-1, x2, y2-1, 1); gfx_lineto(x2,y2,1); ); ) : ( gfx_line(x1, y1-1, x2, y2-1, 1); gfx_lineto(x2,y2,1); ); ); function fftWindow_processMouse(mouse_x, mouse_y, mouse_cap) instance(x, y, w, h, ly, lcap, cap) global(dnoisefloor_freq, dsteps_fft, mouse_wheel) local() ( ( cap == 1 && mouse_cap & 1 == 1 ) ? ( dnoisefloor_freq -= .5*(mouse_y-ly); dnoisefloor_freq > 35 ? dnoisefloor_freq = 35; dnoisefloor_freq < -15 ? dnoisefloor_freq = -15; ) : ( cap = 0; ( mouse_cap & 1 == 1 && lcap & 1 == 0 && mouse_x > x && mouse_y > y && mouse_x < (x+w) && mouse_y < (y+h) ) ? ( cap = 1; ); ); abs(floor(mouse_wheel/240)) > 0 && mouse_x > x && mouse_y > y && mouse_x < (x+w) && mouse_y < (y+h) ? ( dsteps_fft += floor(mouse_wheel/240); dsteps_fft > 8 ? dsteps_fft = 8; dsteps_fft < -6 ? dsteps_fft = -6; mouse_wheel = 0; ); ly = mouse_y; lcap = mouse_cap; ); function drawFFT(fill) global(retina_scaling, fftSize, gfx_x, gfx_y, gfx_r, gfx_g, gfx_b, gfx_a, srate, dnoisefloor_freq, fft_out_r, fft_out_g, fft_out_b, fft_out_a, fft_in_r, fft_in_g, fft_in_b, fft_in_a, dsteps_fft ) instance(x, y, w, h, recPtr, window, rStart, rEnd, fftLoc, floorLevel, hzoffset) local(copyval, stepsize, buf, i, ixsc, txl, tx, ty, wsc, fill, tx0, lx0, lx, ly, ty2, ly2, fill_slast, fill_slmin, cum, cumelem) ( this.initWindow(3); this.calcFFT(); floorLevel = 25 + dnoisefloor_freq; cum = -10000000; cumelem = 0; i = 0; ixsc = 0; wsc = w/log(1+fftsize*0.5-hzoffset); fill_slmin = y; buf = fftLoc + fftsize*0.5 - 2; stepsize = floor((7+dsteps_fft)*retina_scaling); copyval = buf[]; loop( stepsize*200, (buf+=1)[] = copyval; ); buf = fftLoc; txl = x; lx = x; ly = y - max(buf[], -floorLevel)*h / floorLevel; buf += 1; loop(fftsize*0.5+stepsize*200, tx = floor(x + log(1.0+ixsc-hzoffset)*wsc); cum = max(cum, buf[]); cumelem += 1; ( (tx != txl) && (tx-txl > stepsize) && tx > x && i && ( tx < (x+w+stepsize) ) ) ? // ( ty = y - max(cum, -floorLevel)*h / floorLevel; txl = floor(tx); gfx_r=fft_in_r; gfx_g=fft_in_g; gfx_b=fft_in_b; gfx_a=fft_in_a; tx = min(tx, x+w); fill ? ( tx0=tx|0; lx0=lx|0; tx0>lx0 ? ( gfx_triangle(lx0,max(y+h,ly),lx0,ly,tx0-1,ty,tx0-1,max(y+h,ty)); ) : ( tx0 > fill_slast ? ( fill_slast < h ? gfx_line(fill_slast,h,fill_slast,fill_slmin); fill_slmin=h; ) : ( fill_slmin=min(fill_slmin,ty); ); ); fill_slast=tx0; ); gfx_set( fft_out_r, fft_out_g, fft_out_b, fft_out_a ); !fill ? drawLine(lx, ly, tx, ty); lx=tx; ly=ty; ly2=ty2; cum = -1000000; cumelem = 0; ); buf+=1; i+=1; ixsc+=1; ) ); function initSpectrum(memoryOffset) global(fftSize, srate) instance(recPtr, window, rStart, rEnd, fftLoc, hzoffset) local() ( hzoffset = 20*fftSize/srate; window = memoryOffset + fftSize + (fftSize*0.5 - 1); // Start and end of the buffer rStart = memoryOffset; // rpos rEnd = window; // hsize fftLoc = memoryOffset + window + (fftSize*0.5 + 1); // fftw recPtr = rStart; this.initWindow(3) ); function initGonioMeter(in, sampleCount) global(sampleCount, srate) instance(rStart, rEnd, recPtr, samples) local() ( samples = sampleCount; rStart = in; rEnd = in + sampleCount - 1; recPtr = in; ); function feedGonio(l1, r1) global() instance(rStart, rEnd, recPtr) local() ( recPtr[] = l1; (recPtr+=1)[] = r1; recPtr = (recPtr+1) >= rEnd ? rStart : recPtr + 1; ); function drawGonioWindow(recPtr) global( grid_color_r, grid_color_g, grid_color_b, grid_color_a, backface_color_r, backface_color_g, backface_color_b, backface_color_a ) instance(x, y, w, h) local() ( gfx_set( backface_color_r, backface_color_g, backface_color_b, backface_color_a ); gfx_rect(x, y, w, h); gfx_set( grid_color_r, grid_color_g, grid_color_b, grid_color_a ); gfx_line(x, y, x+w, y); gfx_line(x, y+h, x+w, y+h); gfx_line(x, y, x, y+h); gfx_line(x+w, y, x+w, y+h); ); function gonio_processMouse(mouse_x, mouse_y, mouse_cap) instance(x, y, w, h, ly, lcap, cap) local() global(dgonio_zoom) ( ( cap == 1 && mouse_cap & 1 == 1 ) ? ( dgonio_zoom -= .03*(mouse_y-ly); dgonio_zoom < -.9 ? dgonio_zoom = -.9; dgonio_zoom > 9 ? dgonio_zoom = 9; ) : ( cap = 0; ( mouse_cap & 1 == 1 && lcap & 1 == 0 && mouse_x > x && mouse_y > y && mouse_x < (x+w) && mouse_y < (y+h) ) ? ( cap = 1; ); ); ly = mouse_y; lcap = mouse_cap; ); function drawGonioMeter(cl) global( gonio_out_r, gonio_out_g, gonio_out_b, gonio_out_a, gonio_in_r, gonio_in_g, gonio_in_b, gonio_in_a, dgonio_zoom ) local(step, ptr, sign0, sign1, s0, s1, angle, vert, horiz, radius, xx, yy, cx, cy) instance(x, y, w, h, recPtr, rStart, rEnd, samples) ( ptr = recPtr+2; cx = x + 0.5*w; cy = y + 0.5*h; cl == 1 ? gfx_set( gonio_out_r, gonio_out_g, gonio_out_b, gonio_out_a ) : gfx_set( gonio_in_r, gonio_in_g, gonio_in_b, gonio_in_a ); loop(samples, s0 = ptr[]; s1 = (ptr+=1)[]; sign0 = sign( s0 ); sign1 = sign( s1 ); angle = atan( s0 / s1 ); (sign0 == 1 && sign1 == -1) || (sign0 == -1 && sign1 == -1) ? angle += 3.141592654; (sign0 == -1 && sign1 == 1) ? angle += 6.283185307; s1 == 0 ? s0 > 0 ? angle = 1.570796327 : angle = 4.71238898; s0 == 0 ? s1 > 0 ? angle = 0 : angle = 3.141592654; radius = (1+dgonio_zoom) * sqrt( sqr(s0)+sqr(s1) ) ; radius > 1 ? radius = 1; angle -= .25*$pi; xx = cx + .5*h*sin(angle)*radius; yy = cy + .5*h*cos(angle)*radius; gfx_circle(xx, yy, 1.5, 1); gfx_circle(xx, yy, 1, 1); ptr += 1; ptr > rEnd ? ptr = rStart; ); ); ////////////////////////////////////////////////////////// // Memory layout ////////////////////////////////////////////////////////// //RMS1 = 100000; //RMS2 = 200000; //preBufferL = 300000; //preBufferR = 400000; delay_buf1 = 500000; delay_buf2 = 600000; delay_buf3 = 700000; delay_buf4 = 800000; sinc_tmp = 900000; sinc_flt = 910000; // Upsample filters are spaced at 100 difference. There are N filters, with 8 taps per filter. sinc_flt2 = 920000; sinc_flt3 = 930000; // Downsamplers sinc_flt4 = 940000; sinc_hist1 = 950000; // Downsampler history sinc_hist2 = 960000; note_mem = 970000; memset(note_mem, -1337, 10000); cutoff_mem = 1000000; reso_mem = 1100000; cutoff_mem2 = 1200000; reso_mem2 = 1300000; memset(cutoff_mem, -1337, 10000); memset(reso_mem, -1337, 10000); memset(cutoff_mem2, -1337, 10000); memset(reso_mem2, -1337, 10000); cutoff_buffer = 1400000; reso_buffer = 1500000; // Keep this stuff away from clobber risks (0) splineOffset = 2097152; negative_xloc = 100 + splineOffset; negative_yloc = 200 + splineOffset; positive_xloc = 300 + splineOffset; positive_yloc = 400 + splineOffset; negative_xloc2 = 500 + splineOffset; negative_yloc2 = 600 + splineOffset; positive_xloc2 = 700 + splineOffset; positive_yloc2 = 800 + splineOffset; temp_xloc = 900 + splineOffset; temp_yloc = 1000 + splineOffset; pos_c1s = 1100 + splineOffset; pos_c2s = 1200 + splineOffset; pos_c3s = 1300 + splineOffset; neg_c1s = 1400 + splineOffset; neg_c2s = 1500 + splineOffset; neg_c3s = 1600 + splineOffset; pos_c1s2 = 1700 + splineOffset; pos_c2s2 = 1800 + splineOffset; pos_c3s2 = 1900 + splineOffset; neg_c1s2 = 2000 + splineOffset; neg_c2s2 = 2100 + splineOffset; neg_c3s2 = 2200 + splineOffset; temp_indices = 2300 + splineOffset; pos_indices = 2400 + splineOffset; neg_indices = 2500 + splineOffset; vowel_A = 2600 + splineOffset; vowel_E = 2650 + splineOffset; vowel_I = 2700 + splineOffset; vowel_O = 2750 + splineOffset; vowel_U = 2800 + splineOffset; vowel_EE = 2850 + splineOffset; vowel_src = 2900 + splineOffset; bootvowel(); Nbuf = 20000; fftSize = 32768; bufferDist = 65536; audioBufIn = 40*bufferDist; audioBufOut = 42*bufferDist; gonioBuffer1 = 44*bufferDist; gonioBuffer2 = 46*bufferDist; spectrumIn.initSpectrum(audioBufIn); spectrumOut.initSpectrum(audioBufOut); gonioIn.initGonioMeter(gonioBuffer1, 1000); gonioOut.initGonioMeter(gonioBuffer2, 1000); fftSize = 2*8192; inVol.initBuffer(20000, 20000+Nbuf-1); outVol.initBuffer(20000+Nbuf, 20000+2*Nbuf-1); dynBuf.initBuffer(20000+Nbuf*2, 20000+3*Nbuf-1); filter_delay1.initBuffer(delay_buf1, delay_buf1 + filterFreq * 1000); filter_delay2.initBuffer(delay_buf2, delay_buf2 + filterReso * 2000); L.filter_delay.initBuffer(delay_buf1, delay_buf1 + filterFreq * 1000); R.filter_delay.initBuffer(delay_buf2, delay_buf2 + filterReso * 2000); stereo_delay_bufferL.initBuffer(delay_buf1, delay_buf1 + 1000); stereo_delay_bufferR.initBuffer(delay_buf1, delay_buf1 + 1000); dynval = 0; n_pos = 8; n_neg = 8; initialized = 1; function updateSliders( hard ) ( slider54 < 1 ? slider54 = 1; (slider38&2) == 0 ? ( modulator.setModRate( (1+2*slider37)^4 - 1 ); ) : ( cTime = slider37; ( cTime < 0.0196078 ) ? ( tempoLabel = "256"; cRate = 256; ) : ( cTime < 0.0392157 ) ? ( tempoLabel = "224"; cRate = 224; ) : ( cTime < 0.0588235 ) ? ( tempoLabel = "192"; cRate = 192; ) : ( cTime < 0.0784314 ) ? ( tempoLabel = "160"; cRate = 160; ) : ( cTime < 0.0980392 ) ? ( tempoLabel = "144"; cRate = 144; ) : ( cTime < 0.117647 ) ? ( tempoLabel = "128"; cRate = 128; ) : ( cTime < 0.137255 ) ? ( tempoLabel = "112"; cRate = 112; ) : ( cTime < 0.156863 ) ? ( tempoLabel = "96"; cRate = 96; ) : ( cTime < 0.176471 ) ? ( tempoLabel = "80"; cRate = 80; ) : ( cTime < 0.196078 ) ? ( tempoLabel = "64"; cRate = 64; ) : ( cTime < 0.215686 ) ? ( tempoLabel = "56"; cRate = 56; ) : ( cTime < 0.235294 ) ? ( tempoLabel = "48"; cRate = 48; ) : ( cTime < 0.254902 ) ? ( tempoLabel = "40"; cRate = 40; ) : ( cTime < 0.27451 ) ? ( tempoLabel = "32"; cRate = 32; ) : ( cTime < 0.294118 ) ? ( tempoLabel = "28"; cRate = 28; ) : ( cTime < 0.313725 ) ? ( tempoLabel = "24"; cRate = 24; ) : ( cTime < 0.333333 ) ? ( tempoLabel = "16"; cRate = 16; ) : ( cTime < 0.352941 ) ? ( tempoLabel = "8"; cRate = 8; ) : ( cTime < 0.372549 ) ? ( tempoLabel = "7"; cRate = 7; ) : ( cTime < 0.392157 ) ? ( tempoLabel = "6"; cRate = 6; ) : ( cTime < 0.411765 ) ? ( tempoLabel = "16/3"; cRate = 5.33333; ) : ( cTime < 0.431373 ) ? ( tempoLabel = "5"; cRate = 5; ) : ( cTime < 0.45098 ) ? ( tempoLabel = "4"; cRate = 4; ) : ( cTime < 0.470588 ) ? ( tempoLabel = "3"; cRate = 3; ) : ( cTime < 0.490196 ) ? ( tempoLabel = "8/3"; cRate = 2.66667; ) : ( cTime < 0.509804 ) ? ( tempoLabel = "4/3"; cRate = 1.33333; ) : ( cTime < 0.529412 ) ? ( tempoLabel = "7/6"; cRate = 1.16667; ) : ( cTime < 0.54902 ) ? ( tempoLabel = "1"; cRate = 1; ) : ( cTime < 0.568627 ) ? ( tempoLabel = "15/16"; cRate = 0.9375; ) : ( cTime < 0.588235 ) ? ( tempoLabel = "7/8"; cRate = 0.875; ) : ( cTime < 0.607843 ) ? ( tempoLabel = "5/6"; cRate = 0.833333; ) : ( cTime < 0.627451 ) ? ( tempoLabel = "13/16"; cRate = 0.8125; ) : ( cTime < 0.647059 ) ? ( tempoLabel = "3/4"; cRate = 0.75; ) : ( cTime < 0.666667 ) ? ( tempoLabel = "11/16"; cRate = 0.6875; ) : ( cTime < 0.686275 ) ? ( tempoLabel = "2/3"; cRate = 0.666667; ) : ( cTime < 0.705882 ) ? ( tempoLabel = "5/8"; cRate = 0.625; ) : ( cTime < 0.72549 ) ? ( tempoLabel = "9/16"; cRate = 0.5625; ) : ( cTime < 0.745098 ) ? ( tempoLabel = "1/2"; cRate = 0.5; ) : ( cTime < 0.764706 ) ? ( tempoLabel = "7/16"; cRate = 0.4375; ) : ( cTime < 0.784314 ) ? ( tempoLabel = "3/8"; cRate = 0.375; ) : ( cTime < 0.803922 ) ? ( tempoLabel = "1/3"; cRate = 0.333333; ) : ( cTime < 0.823529 ) ? ( tempoLabel = "5/16"; cRate = 0.3125; ) : ( cTime < 0.843137 ) ? ( tempoLabel = "1/4"; cRate = 0.25; ) : ( cTime < 0.862745 ) ? ( tempoLabel = "3/16"; cRate = 0.1875; ) : ( cTime < 0.882353 ) ? ( tempoLabel = "1/6"; cRate = 0.166667; ) : ( cTime < 0.901961 ) ? ( tempoLabel = "1/8"; cRate = 0.125; ) : ( cTime < 0.921569 ) ? ( tempoLabel = "1/12"; cRate = 0.0833333; ) : ( cTime < 0.941176 ) ? ( tempoLabel = "1/16"; cRate = 0.0625; ) : ( cTime < 0.960784 ) ? ( tempoLabel = "1/24"; cRate = 0.0416667; ) : ( cTime < 0.980392 ) ? ( tempoLabel = "1/32"; cRate = 0.03125; ) : ( tempoLabel = "1/64"; cRate = 0.015625; ); modulator.setModRate( .25 * (cTempo/60) / cRate ); ); overSampling.sliderWidget_setValue(slider54); inGain.sliderWidget_setValue(slider52); inGain.sliderWidget_setValue2_nn(slider51); outGain.sliderWidget_setValue(slider53); keyAmount.sliderWidget_setValue(slider33); slider35 & 2 == 0 ? outGain.sliderWidget_setValue2_nn(0) : outGain.sliderWidget_setValue2_nn(slider17); // Filter 1 filterSelect.combobox_setcuritem(slider47); modeSelect.combobox_setcuritem(slider46); lfoSelect.combobox_setcuritem(slider36); cutoffSlider.sliderWidget_setValue(slider48); resonanceSlider.sliderWidget_setValue(slider49); cutoffSlider.sliderWidget_setValue2_nn(slider62); resonanceSlider.sliderWidget_setValue2_nn(slider63); // Filter 2 filterSelect2.combobox_setcuritem(slider40); modeSelect2.combobox_setcuritem(floor(slider50*.5)); cutoffSlider2.sliderWidget_setValue(slider41); resonanceSlider2.sliderWidget_setValue(slider42); cutoffSlider2.sliderWidget_setValue2_nn(slider43); resonanceSlider2.sliderWidget_setValue2_nn(slider44); threshSlider.sliderWidget_setValue(slider59); attackSlider.sliderWidget_setValue(slider60); decaySlider.sliderWidget_setValue(slider61); rmsSlider.sliderWidget_setValue(slider64); lookAheadButton.active = slider35 & 1 ? 1 : 0; inClip.active = slider55 & 1 ? 1 : 0; outClip.active = slider55 & 2 ? 1 : 0; inertia.active = slider55 & 4 ? 1 : 0; dynButton.active = slider45 & 1 ? 1 : 0; atk_x4_1.active = slider57 & 1 ? 1 : 0; atk_x4_2.active = slider57 & 2 ? 1 : 0; decay_x4_1.active = slider57 & 4 ? 1 : 0; decay_x4_2.active = slider57 & 8 ? 1 : 0; rms_x4_1.active = slider57 & 16 ? 1 : 0; rms_x4_2.active = slider57 & 32 ? 1 : 0; firButton.active = slider50&1 ? 1 : 0; lfoResetButton.active = (slider38&1) ? 1 : 0; tempoLFOButton.active = (slider38&2) ? 1 : 0; centeredLFOButton.active = (slider38&4) ? 1 : 0; lfoFrequency.sliderWidget_setValue(slider37); modulationFactor.sliderWidget_setValue(slider39); dynamics = slider58; dynamicsEnabled = dynamics > 0; ( dynamicsEnabled ) ? ( atkmul = ( 1 + 7*atk_x4_1.active ) * ( 1 + 3*atk_x4_2.active ); dyn_thresh = slider59; ( slider45 == 1 ) ? ( dyn_atk = (2^(2*(atkmul * slider60-25)/25)); dyn_decay = slider61/50; ) : ( decaymul = ( 1 + 7*decay_x4_1.active ) * ( 1 + 3*decay_x4_2.active ); dyn_atk_time = max(5,atkmul * slider60 * srate / 100); dyn_atk = 1 / dyn_atk_time; dyn_decay_time = log2 * max(.05, decaymul * slider61) * srate / 100 + 0.0001; dyn_decay = 1 / dyn_decay_time; ( slider45 == 2 || slider45 == 4 ) ? ( dyn_hold_time = max(5, slider59 * srate); dyn_hold_end = dyn_hold_time + dyn_atk_time; ) ); ); dyn_mod_filt = cutoffSlider.sliderWidget_getValue2(); dyn_mod_reso = resonanceSlider.sliderWidget_getValue2(); dyn_mod_filt2 = cutoffSlider2.sliderWidget_getValue2(); dyn_mod_reso2 = resonanceSlider2.sliderWidget_getValue2(); dyn_mod_gain = inGain.sliderWidget_getValue2(); dyn_mod_outgain = outGain.sliderWidget_getValue2_nn(); filterDynamics1 = 0; filterDynamics2 = 0; distortionDynamics = dynamics & 2 > 0; filterDynamics1 = dynamics & 4 > 0; filterLFO1 = dynamics & 8 > 0; filterDynamics2 = dynamics & 16 > 0; filterLFO2 = dynamics & 32 > 0; gainDynamics = dynamics & 64 > 0; gainLFO = dynamics & 128 > 0; followKey1 = dynamics & 256 > 0; followKey2 = dynamics & 512 > 0; // For legacy purposes (there used to be only filters on/off) ( dynamics & 1 ) ? ( filterDynamics1 = filterDynamics2 = filterLFO1 = filterLFO2 = gainDynamics = gainLFO = 1; followKey1 = followKey2 = 0; ); dynamicFilterButton.active = filterDynamics1; dynamicFilterButton2.active = filterDynamics2; lfoFilterButton.active = filterLFO1; lfoFilterButton2.active = filterLFO2; dynamicWaveShapingButton.active = distortionDynamics; dynamicGainButton.active = gainDynamics; lfoGainButton.active = gainLFO; keyFollow1.active = followKey1; keyFollow2.active = followKey2; setter = window2.spline.xloc_write; setter[] = 0; setter += 1; setter[] = slider3; setter += 1; setter[] = slider5; setter += 1; setter[] = slider7; setter += 1; setter[] = slider9; setter += 1; setter[] = slider11; setter += 1; setter[] = slider13; setter += 1; setter[] = slider15; setter += 1; setter[] = 1; setter += 1; setter[] = 1; setter += 1; setter = window2.spline.yloc_write; setter[] = 0; setter += 1; setter[] = slider4; setter += 1; setter[] = slider6; setter += 1; setter[] = slider8; setter += 1; setter[] = slider10; setter += 1; setter[] = slider12; setter += 1; setter[] = slider14; setter += 1; setter[] = slider16; setter += 1; setter[] = slider18; setter += 1; setter[] = 1; setter += 1; setter = window1.spline.xloc_write; setter[] = 0; setter += 1; setter[] = slider19; setter += 1; setter[] = slider21; setter += 1; setter[] = slider23; setter += 1; setter[] = slider25; setter += 1; setter[] = slider27; setter += 1; setter[] = slider29; setter += 1; setter[] = slider31; setter += 1; setter[] = 1; setter += 1; setter[] = 1; setter += 1; setter = window1.spline.yloc_write; setter[] = 0; setter += 1; setter[] = slider20; setter += 1; setter[] = slider22; setter += 1; setter[] = slider24; setter += 1; setter[] = slider26; setter += 1; setter[] = slider28; setter += 1; setter[] = slider30; setter += 1; setter[] = slider32; setter += 1; setter[] = slider34; setter += 1; setter[] = 1; setter += 1; ( slider56 == 0 || hard == 1 ) ? ( window1.wsetN(slider1); window2.wsetN(slider2); window1.spline.xloc_write[slider1-1] = 1; window2.spline.xloc_write[slider2-1] = 1; window1.sort_spline(); window2.sort_spline(); window1.update_spline(); window2.update_spline(); ); // Only update the oversampling filters when needed. ( slider54 != lastOversample ) ? ( lastOversample = slider54; filterL.updateFilter(slider54); filterR.updateFilter(slider54); // Memory for the sincs is located at sinc_tmp, sinc_flt, sinc_flt2, sinc_flt3 and sinc_flt4 sincFilterL.updateSincFilter(slider54, 8, sinc_flt, sinc_tmp); sincFilterR.updateSincFilter(slider54, 8, sinc_flt2, sinc_tmp); nTapSinc = slider54 < 5 ? 16 : slider54*4; sincDownL.updateSincDownsampleFilter(slider54, nTapSinc, sinc_hist1, sinc_flt3); sincDownR.updateSincDownsampleFilter(slider54, nTapSinc, sinc_hist2, sinc_flt4); ); // Calculate group delay incurred by sincs iN = 1.0 / slider54; cDelay = (slider50 & 1) ? iN * (.5 * 7 * slider54 - 1) : 0; cDelay += (slider50 & 1) ? iN * (.5 * nTapSinc - 1) : 0; updateIntegrationTime(); // updates lookAheadDelay cDelay += lookAheadDelay; pdcDelay = cDelay; ); function initGUI() ( // Initialize object instances window1.init_window(wndPad, wndPad, wndX, wndY, 10, 1, negative_xloc, negative_yloc, negative_xloc2, negative_yloc2, pos_indices, temp_xloc, temp_yloc, temp_indices, neg_c1s, neg_c2s, neg_c3s, neg_c1s2, neg_c2s2, neg_c3s2); window2.init_window(2*wndPad+wndX, wndPad, wndX, wndY, 10, 2, positive_xloc, positive_yloc, positive_xloc2, positive_yloc2, neg_indices, temp_xloc, temp_yloc, temp_indices, pos_c1s, pos_c2s, pos_c3s, pos_c1s2, pos_c2s2, pos_c3s2); updateSliders(1); updateActiveFilters(1); ); function setupGUI() ( UI_Loaded = 1; retina_scaling = gfx_ext_retina * (1+extraScale); widgetFontSize = 12 + linuxMode; buttonFontSize = 11; gfx_setfont(1, fontface, widgetFontSize); gfx_measurestr("LookAhead", str_width, str_height); font_factor = 47 / str_width; // 47 is the button text area widgetFontSize = widgetFontSize * font_factor * ( 1 + linuxMode * .2 ); buttonFontSize = buttonFontSize * font_factor; // Initialize object instances wndX = 250 * retina_scaling; wndY = 250 * retina_scaling; wndPad = 30 * retina_scaling; window1.gen_window(wndPad, wndPad, wndX, wndY, 10, 1, negative_xloc, negative_yloc, negative_xloc2, negative_yloc2, pos_indices, temp_xloc, temp_yloc, temp_indices, neg_c1s, neg_c2s, neg_c3s, neg_c1s2, neg_c2s2, neg_c3s2); window2.gen_window(2*wndPad+wndX, wndPad, wndX, wndY, 10, 2, positive_xloc, positive_yloc, positive_xloc2, positive_yloc2, neg_indices, temp_xloc, temp_yloc, temp_indices, pos_c1s, pos_c2s, pos_c3s, pos_c1s2, pos_c2s2, pos_c3s2); window3.gen_dynamics(3*wndPad+2*wndX, wndPad, wndX, wndY ); copyright_h = .8*sliderHeight; copyRight.selectionButton(1.5*wndPad+wndX - .25*wndPad, wndPad + .15*wndY - .5*copyright_h, .5*wndPad, copyright_h, ">", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Copy spline curve to right"); copyLeft.selectionButton(1.5*wndPad+wndX - .25*wndPad, wndPad + .85*wndY - .5*copyright_h, .5*wndPad, copyright_h, "<", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Copy spline curve to left"); spectrumIn.setWindowLocation(wndPad, 2.4*wndPad + wndY, 2*wndX + wndPad, wndY * .9); spectrumOut.setWindowLocation(wndPad, 2.4*wndPad + wndY, 2*wndX + wndPad, wndY * .9); gonioIn.setWindowLocation(3*wndPad+2*wndX, 2.4*wndPad + wndY, wndX, wndY * .9); gonioOut.setWindowLocation(3*wndPad+2*wndX, 2.4*wndPad + wndY, wndX, wndY * .9); wR = widgetcolor_r; wG = widgetcolor_g; wB = widgetcolor_b; wA = widgetcolor_a; masterPanelX = 4*wndPad+3*wndX; masterPanelY = (30 + 5) * retina_scaling; masterPanelH = sliderHeight*4+6*sliderPad; sliderWidth = 234 * retina_scaling; sliderHeight= 20 * retina_scaling; sliderPad = 5 * retina_scaling; masterPanel.groupWidget(masterPanelX, masterPanelY, sliderWidth, masterPanelH, "MASTER", wR, wG, wB, wA ); lfoGainButton.selectionButton(masterPanelX + .82*sliderWidth, masterPanelY-buttonHeight, .2*sliderWidth-2*sliderPad, buttonHeight, "LFO", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Enable dynamic filter manipulation.\n\nWhen activated, the gain responds to changes in the LFO."); dynamicGainButton.selectionButton(masterPanelX + .82*sliderWidth - .185*sliderWidth, masterPanelY-buttonHeight, .2*sliderWidth-2*sliderPad, buttonHeight, "DYN", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Enable dynamic gain manipulation.\n\nWhen activated, the gain responds to changes in the dynamic\nvariable (shown with the yellow curve). This value changes based\non the settings set in the dynamics panel. It is either modulated\nby an attack/decay mechanism based on thresholding the input RMS\nvalue, or directly set to some function of the RMS value (RMS mode)."); inGain.sliderWidget(masterPanelX+sliderPad, masterPanelY+sliderPad, .78*sliderWidth-2*sliderPad, sliderHeight, "Pre-Gain / Drive", wR, wG, wB, wA, 40, -40, 40, 0, " dB", 0, "Input gain\n(Post upsampling, pre-effect)"); inClip.selectionButton(masterPanelX+sliderPad+ + .8*sliderWidth, 3+masterPanelY+sliderPad, .2*sliderWidth-2*sliderPad, sliderHeight-4, "Clip", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Toggle input clipping"); outGain.sliderWidget(masterPanelX+sliderPad, masterPanelY+2*sliderPad+sliderHeight, .78*sliderWidth-2*sliderPad, sliderHeight, "Post-Gain", wR, wG, wB, wA, 40, -40, 40, 0, " dB", 0, "Output gain"); outClip.selectionButton(masterPanelX+sliderPad + .8*sliderWidth, 3+masterPanelY+2*sliderPad+sliderHeight, .2*sliderWidth-2*sliderPad, sliderHeight-4, "Clip", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Toggle output clipping"); overSampling.sliderWidget(masterPanelX+sliderPad, masterPanelY+3*sliderPad+2*sliderHeight, .82*sliderWidth-2*sliderPad, sliderHeight, "Oversampling", wR, wG, wB, wA, 0, 1, 8, 1, "x", 1, "Oversampling factor\nOversampling reduces aliasing that occurs when distorting heavily\nand is required for the stability of a few filters.\nUse FIR version if phase is important (stabby sounds).\n"); keyAmount.sliderWidget(masterPanelX+sliderPad, masterPanelY+4*sliderPad+3*sliderHeight, sliderWidth-2*sliderPad, sliderHeight, "Keyfollow amount", wR, wG, wB, wA, 0, 0, 2, 1, "x", 0, "Keyfollow amount.\n\nDetermines how strongly the filters follow\nthe last note played when KEY toggles are activated.\n"); firButton.selectionButton(masterPanelX+sliderPad + .8*sliderWidth, 3+masterPanelY+3*sliderPad+2*sliderHeight, .2*sliderWidth-2*sliderPad, sliderHeight-4, "FIR", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Enable FIR up/downsampling\n(preserves phase but expensive)"); linkButton.selectionButton(masterPanelX+sliderPad + .745*sliderWidth, masterPanelY+sliderPad+1, .028*sliderWidth, sliderHeight+3*sliderPad+2, "", .3, .4, .8, .3, "Link"); filterPanelX = masterPanelX; filterPanelY = masterPanelY + masterPanelH + sliderHeight; filterPanelH = sliderHeight*4+7*sliderPad; postTextLoc = filterPanel.groupWidget(filterPanelX, filterPanelY, sliderWidth, filterPanelH, "FILTER", wR, wG, wB, wA ); keyFollow1.selectionButton(filterPanelX + .82*sliderWidth - .370*sliderWidth, filterPanelY-buttonHeight, .2*sliderWidth-2*sliderPad, buttonHeight, "KEY", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Enable keyfollow for this filter.\n\nWhen activated, the filter follows the note pitch\nof the last note sent to it over MIDI."); dynamicFilterButton.selectionButton(filterPanelX + .82*sliderWidth - .185*sliderWidth, filterPanelY-buttonHeight, .2*sliderWidth-2*sliderPad, buttonHeight, "DYN", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Enable dynamic filter manipulation.\n\nWhen activated, the filter responds to changes in the dynamic\nvariable (shown with the yellow curve). This value changes based\non the settings set in the dynamics panel. It is either modulated\nby an attack/decay mechanism based on thresholding the input RMS\nvalue, or directly set to some function of the RMS value (RMS mode)."); lfoFilterButton.selectionButton(filterPanelX + .82*sliderWidth, filterPanelY-buttonHeight, .2*sliderWidth-2*sliderPad, buttonHeight, "LFO", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Enable dynamic filter manipulation.\n\nWhen activated, the filter responds to changes in the LFO."); filterSelect.combobox(filterPanelX+sliderPad, filterPanelY+sliderPad, sliderWidth-2*sliderPad, sliderHeight, wR, wG, wB, wA, nFilters, 0, 0, 3, "Filter selection.\nNon-linear (NL) filters are more expensive and benefit more from oversampling.\nTheir character comes out when driven (increase the pre-gain without enabling clipping).\nZero Delay Feedback (ZDF) filters behave better with rapid modulation.\nAll filters are IIR filters, meaning they do not preserve linear phase.\n\nWARNING: Not all filters are stable under rapid modulation!\nRemember to read the filter description to avoid being hit by instability.\nInstability manifests itself as there suddenly being a spike and then no sound." ); inertia.selectionButton(filterPanelX+sliderPad + .8 * sliderWidth, filterPanelY+sliderPad*2+sliderHeight*1.05, .2*sliderWidth-2*sliderPad, .95*sliderHeight, "Inertia", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Toggle cutoff and resonance inertia"); modeSelect.combobox(filterPanelX+sliderPad, filterPanelY+sliderPad*2+sliderHeight, .82*sliderWidth-2*sliderPad, sliderHeight, wR, wG, wB, wA, nModes, 1, 0, 1, "Filter mode selection.\nStereo - Default mode. Process left and right independently.\nMono double - Interleave samples and process.\nM1/S2 - Process mid regularly, feed side samples to filter twice.\nM2/S1 - Feed mid to filter twice, process side regularly.\nOnly side - Only filter the side channel.\nOnly mid - Only filter the mid channel.\nStereoize - Filter both, but pre-amplify side channel." ); cutoffSlider.sliderWidget(filterPanelX+sliderPad, filterPanelY+4*sliderPad+2*sliderHeight, sliderWidth-2*sliderPad, sliderHeight, "Cutoff", wR, wG, wB, wA, 1, 0, 1, 0, "", 0, "Filter cutoff.\nLMB sets filter cutoff.\nRMB sets range for modulation.\n\nFor more info on modulation, hover over the Filter button in the dynamics panel.\nNote that when LFO and dynamics are both active, the modulation range is twice what is diplayed."); resonanceSlider.sliderWidget(filterPanelX+sliderPad, filterPanelY+5*sliderPad+3*sliderHeight, sliderWidth-2*sliderPad, sliderHeight, "Resonance", wR, wG, wB, wA, 1, 0, 1, 0, "", 0, "Filter resonance.\nLMB sets filter cutoff.\nRMB sets range for modulation.\n\nFor more info on modulation, hover over the Shaper button in the dynamics panel.\nNote that when LFO and dynamics are both active, the modulation range is twice what is diplayed."); bypassFilter1.selectionButton(postTextLoc + .015 * sliderWidth, filterPanelY-buttonHeight, .1*sliderWidth-2*sliderPad, buttonHeight, "B", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Bypass filter."); filterPanelX = masterPanelX; filterPanelY = filterPanelY + filterPanelH + sliderHeight; filterPanelH = sliderHeight*4+7*sliderPad; postTextLoc = filterPanel2.groupWidget(filterPanelX, filterPanelY, sliderWidth, filterPanelH, "FILTER", wR, wG, wB, wA ); keyFollow2.selectionButton(filterPanelX + .82*sliderWidth - .370*sliderWidth, filterPanelY-buttonHeight, .2*sliderWidth-2*sliderPad, buttonHeight, "KEY", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Enable keyfollow for this filter.\n\nWhen activated, the filter follows the note pitch\nof the last note sent to it over MIDI."); dynamicFilterButton2.selectionButton(filterPanelX + .82*sliderWidth - .185*sliderWidth, filterPanelY-buttonHeight, .2*sliderWidth-2*sliderPad, buttonHeight, "DYN", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Enable dynamic filter manipulation.\n\nWhen activated, the filter responds to changes in the dynamic\nvariable (shown with the yellow curve). This value changes based\non the settings set in the dynamics panel. It is either modulated\nby an attack/decay mechanism based on thresholding the input RMS\nvalue, or directly set to some function of the RMS value (RMS mode)."); lfoFilterButton2.selectionButton(filterPanelX + .82*sliderWidth, filterPanelY-buttonHeight, .2*sliderWidth-2*sliderPad, buttonHeight, "LFO", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Enable dynamic filter manipulation.\n\nWhen activated, the filter responds to changes in the LFO."); filterSelect2.combobox(filterPanelX+sliderPad, filterPanelY+sliderPad, sliderWidth-2*sliderPad, sliderHeight, wR, wG, wB, wA, nFilters, 0, 0, 3, "Filter selection.\nNon-linear (NL) filters are more expensive and benefit more from oversampling.\nTheir character comes out when driven (increase the pre-gain without enabling clipping).\nZero Delay Feedback (ZDF) filters behave better with rapid modulation.\nAll filters are IIR filters, meaning they do not preserve linear phase.\n\nWARNING: Not all filters are stable under rapid modulation!\nRemember to read the filter description to avoid being hit by instability.\nInstability manifests itself as there suddenly being a spike and then no sound." ); modeSelect2.combobox(filterPanelX+sliderPad, filterPanelY+sliderPad*2+sliderHeight, sliderWidth-2*sliderPad, sliderHeight, wR, wG, wB, wA, nModes2, 3, 0, 1, "Filter routing mode.\n\nSerial Dual Dist - Both filters are in series. Both with waveshaper enabled.\nSerial - Both filters are placed in series. The second filter does not use the waveshaper.\nParallel Dual Dist - Both filters are in series. Both filters have the waveshaper enabled.\nParallel - Both filters are in series. The second filter does not use the waveshaper.\n" ); cutoffSlider2.sliderWidget(filterPanelX+sliderPad, filterPanelY+4*sliderPad+2*sliderHeight, sliderWidth-2*sliderPad, sliderHeight, "Cutoff", wR, wG, wB, wA, 1, 0, 1, 0, "", 0, "Filter cutoff.\nLMB sets filter cutoff.\nRMB sets range for modulation.\n\nFor more info on modulation, hover over the Filter button in the dynamics panel.\nNote that when LFO and dynamics are both active, the modulation range is twice what is diplayed."); resonanceSlider2.sliderWidget(filterPanelX+sliderPad, filterPanelY+5*sliderPad+3*sliderHeight, sliderWidth-2*sliderPad, sliderHeight, "Resonance", wR, wG, wB, wA, 1, 0, 1, 0, "", 0, "Filter resonance.\nLMB sets filter cutoff.\nRMB sets range for modulation.\n\nFor more info on modulation, hover over the Shaper button in the dynamics panel.\nNote that when LFO and dynamics are both active, the modulation range is twice what is diplayed."); bypassFilter2.selectionButton(postTextLoc + .015 * sliderWidth, filterPanelY-buttonHeight, .1*sliderWidth-2*sliderPad, buttonHeight, "B", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Bypass filter."); dynamicGainButton.style = 2; lfoGainButton.style = 2; dynamicFilterButton.style = 2; lfoFilterButton.style = 2; dynamicFilterButton2.style = 2; lfoFilterButton2.style = 2; keyFollow1.style = 2; keyFollow2.style = 2; dynamicsPanelX = masterPanelX; dynamicsPanelY = filterPanelY + filterPanelH + sliderHeight; dynamicsPanelH = buttonHeight+sliderHeight*4+7*sliderPad; buttonHeight = 12 * retina_scaling; buttonWidth = 70 * retina_scaling; buttonPad = 6 * retina_scaling; dynamicsPanel.groupWidget(dynamicsPanelX, dynamicsPanelY, sliderWidth, dynamicsPanelH, "DYNAMICS", wR, wG, wB, wA ); //dynamicFilterButton.selectionButton(dynamicsPanelX+sliderPad, dynamicsPanelY+sliderPad+1, buttonWidth, buttonHeight, "DYN", .3, .4, .8, .3, "Enable dynamic filter manipulation.\n\nWhen activated, the filter responds to changes in the dynamic\nvariable (shown with the yellow curve). This value changes based\non the settings set in the dynamics panel. It is either modulated\nby an attack/decay mechanism based on thresholding the input RMS\nvalue, or directly set to some function of the RMS value (RMS mode)."); dynamicWaveShapingButton.selectionButton(dynamicsPanelX+buttonPad, dynamicsPanelY+sliderPad+1, buttonWidth, buttonHeight, "Shaper", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Enable dynamic waveshaper activation.\n\nWhen activated, the waveshaper responds to changes in the dynamic\nvariable (shown with the yellow curve). Based on the dynamic variable,\nthe waveshaper interpolates between no waveshaping and the curve set\nby the user. This can be used to simulate compressors for instance.\n\nThe dynamic variable changes based on the settings set in the dynamics\npanel. It is either modulated by an attack/decay mechanism based on\nthresholding the input RMS value or directly set to some function of\nthe RMS value (RMS mode).\n"); lookaheadButton.selectionButton(dynamicsPanelX+sliderPad+buttonWidth+buttonPad, dynamicsPanelY+sliderPad+1, buttonWidth, buttonHeight, "LookAhead", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Prevent lag in RMS estimate.\n\nNote that enabling lookahead increases the\npdc_delay of the plugin and is therefore not\nrecommended for live recording."); dynButton.selectionButton(dynamicsPanelX+sliderPad+2*buttonWidth+2*buttonPad, dynamicsPanelY+sliderPad+1, buttonWidth, buttonHeight, "RMS Mode", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Use threshold or modulate directly by RMS.\n\nThe dynamic variable (shown with the yellow curve) changes based\non one of two mechanisms. Either it changes based on an attack/decay\nmechanism based on thresholding the input RMS value (RMS mode off),\nor it is directly set (without transient) to a function of the RMS \nvalue (RMS mode on)."); threshSlider.sliderWidget(dynamicsPanelX+sliderPad, dynamicsPanelY+3*sliderPad+buttonHeight, sliderWidth-2*sliderPad, sliderHeight, "Threshold", wR, wG, wB, wA, 0, 0, 1, 1, " V", 0, "Threshold value.\nWhen input RMS exceeds this value, the dynamic variable begins to accumulate.\n"); mulWidth = .06 * sliderWidth; mulPad = 4 * retina_scaling; attackSlider.sliderWidget(dynamicsPanelX+sliderPad, dynamicsPanelY+4*sliderPad+sliderHeight+buttonHeight, sliderWidth-2*sliderPad - 2*mulWidth-2*mulPad, sliderHeight, "Attack", wR, wG, wB, wA, 0, 0, 50, 0, "", 0, "Attack\nHow long does the dynamic variable take to change\nto its maximal value once over the threshold."); atk_x4_1.selectionButton(dynamicsPanelX-sliderPad+sliderWidth-mulWidth, dynamicsPanelY+4*sliderPad+sliderHeight+buttonHeight, mulWidth, sliderHeight-4, "x8", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Multiply value by 8"); atk_x4_2.selectionButton(dynamicsPanelX-sliderPad+sliderWidth-2*mulWidth-mulPad, dynamicsPanelY+4*sliderPad+sliderHeight+buttonHeight, mulWidth, sliderHeight-4, "x4", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Multiply value by 8"); decaySlider.sliderWidget(dynamicsPanelX+sliderPad, dynamicsPanelY+5*sliderPad+2*sliderHeight+buttonHeight, sliderWidth-2*sliderPad - 2*mulWidth-2*mulPad, sliderHeight, "Decay", wR, wG, wB, wA, 0, 0, 50, 0, "", 0, "Decay\nHow long does the dynamic variable take to\ndecay when below the threshold."); decay_x4_1.selectionButton(dynamicsPanelX-sliderPad+sliderWidth-mulWidth, dynamicsPanelY+5*sliderPad+2*sliderHeight+buttonHeight, mulWidth, sliderHeight-4, "x8", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Multiply value by 8"); decay_x4_2.selectionButton(dynamicsPanelX-sliderPad+sliderWidth-2*mulWidth-mulPad, dynamicsPanelY+5*sliderPad+2*sliderHeight+buttonHeight, mulWidth, sliderHeight-4, "x4", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Multiply value by 4"); rmsSlider.sliderWidget(dynamicsPanelX+sliderPad, dynamicsPanelY+6*sliderPad+3*sliderHeight+buttonHeight, sliderWidth-2*sliderPad - 2*mulWidth-2*mulPad, sliderHeight, "RMS time", wR, wG, wB, wA, 0, 0.02, 40, 0, "", 0, "RMS time\nSets over how much time is the RMS computed"); rms_x4_1.selectionButton(dynamicsPanelX-sliderPad+sliderWidth-mulWidth, dynamicsPanelY+6*sliderPad+3*sliderHeight+buttonHeight, mulWidth, sliderHeight-4, "x8", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Multiply value by 8"); rms_x4_2.selectionButton(dynamicsPanelX-sliderPad+sliderWidth-2*mulWidth-mulPad, dynamicsPanelY+6*sliderPad+3*sliderHeight+buttonHeight, mulWidth, sliderHeight-4, "x4", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Multiply value by 4"); lfoPanelX = masterPanelX; lfoPanelY = dynamicsPanelY + dynamicsPanelH + sliderHeight; buttonHeight = 12 * retina_scaling; lfoPanel.groupWidget(lfoPanelX, lfoPanelY, sliderWidth, buttonHeight+sliderHeight*3+3*sliderPad, "LFO", wR, wG, wB, wA ); lfoSelect.combobox(lfoPanelX+sliderPad, lfoPanelY+sliderPad, .62*sliderWidth-2*sliderPad, sliderHeight, wR, wG, wB, wA, nLFO, 2, 1, 1, "Select LFO type" ); modulatorDisplay.create_mod_window(lfoPanelX+.62*sliderWidth, lfoPanelY+sliderPad, .2*sliderWidth - sliderPad, sliderHeight, wR, wG, wB, wA); lfoResetButton.selectionButton(lfoPanelX+sliderPad+.8*sliderWidth, lfoPanelY+sliderPad, .2*sliderWidth-2*sliderPad, sliderHeight, "MIDI", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Reset LFO phase on incoming MIDI note."); modulationFactor.sliderWidget(lfoPanelX+sliderPad, lfoPanelY+4*sliderPad+2*sliderHeight, .82*sliderWidth-2*sliderPad, sliderHeight, "Modulation Range", wR, wG, wB, wA, 0, 0, 4, 1, "", 0, "Modulation range"); lfoFrequency.sliderWidget(lfoPanelX+sliderPad, lfoPanelY+3*sliderPad+sliderHeight, .82*sliderWidth-2*sliderPad, sliderHeight, "Rate", wR, wG, wB, wA, 0, 0, 1, 0, "", 0, "LFO rate"); tempoLFOButton.selectionButton(lfoPanelX+sliderPad + .8*sliderWidth, lfoPanelY+3*sliderPad+sliderHeight, .2*sliderWidth-2*sliderPad, sliderHeight-4, "Tempo", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Synchronize to tempo"); centeredLFOButton.selectionButton(lfoPanelX+sliderPad + .8*sliderWidth, lfoPanelY+4*sliderPad+2*sliderHeight, .2*sliderWidth-2*sliderPad, sliderHeight-4, "Center", selectionbutton_color_r, selectionbutton_color_g, selectionbutton_color_b, selectionbutton_color_a, "Centered"); updateSliders(1); updateActiveFilters(1); ); // Initialize the splines initGUI(); function distort(s) global(window1.evalDistAudio, window2.evalDistAudio, rc_filter.evalRC2) local(os) global(slider55, slider56, dynval, distortionDynamics) ( ( slider56 == 0 ) ? ( os = s; s = ( s > 0 ) ? s = window1.evalDistAudio(s) : ( s = -window2.evalDistAudio(-s); ); distortionDynamics ? s = (1.0-dynval) * os + dynval * s; ) : ( slider56 == 1 ) ? ( os = s; s = tanh(s); distortionDynamics ? s = (1.0-dynval) * os + dynval * s; ) : ( slider56 == 2 ) ? ( os = s; s = fasttanh(s); distortionDynamics ? s = (1.0-dynval) * os + dynval * s; ) : ( slider56 == 4 ) ? ( os = s; s = sin(2*$pi*s); distortionDynamics ? s = (1.0-dynval) * os + dynval * s; ); s ); function distortderiv(s) global(window1.evalDiff, window2.evalDiff, rc_filter.evalRC2) local(th) global(slider56, dynval) ( ( slider56 == 0 ) ? ( s = ( s > 0 ) ? s = window1.evalDiff(s) : ( s = -window2.evalDiff(-s); ); ) : ( slider56 == 1 ) ? ( th = tanh(s); s = 1.0 - th*th; ) : ( slider56 == 2 ) ? ( th = fasttanh(s); s = 1.0 - th*th; ); (1.0-dynval) + dynval * s ); //--------------------------- // Filter usage section //--------------------------- function evalRC(input) instance(len, v0, v1, a1, c) local(output, tmp) global(srate) ( v0 = a1*v0 - c*v1 + c*input; v1 = a1*v1 + c*v0; tmp = v1; v0 = a1*v0 - c*v1 + c*input; v1 = a1*v1 + c*v0; output = (tmp+v1)*0.5; ); function eval303(input) local(y0, s0, s) instance(wc, wc2, wc3, wc4, A, k, b, g, z0, z1, z2, z3, y1, y2, y3, y4 b0, a0, a1, a2, a3, b10, a10, a11, a12, a13, b20, a20, a21, a22, a23, c2, c3 ) global(distort) ( s = (z0*wc3 + z1*a20 + z2*c2 + z3*c3) * b; // *b was missing in prev y4 = (g*input + s)/(1 + g*k); y0 = max(-1,min(1,(distort(input) - k*y4))); //y0 = fasttanh((distort(input) - k*y4)); y1 = b * ( y0*b0 + z0*a0 + z1*a1 + z2*a2 + z3*a3 ); // #OK y2 = b * (y0*b10 + z0*a10 + z1*a11 + z2*a12 + z3*a13); // #OK y3 = b * (y0*b20 + z0*a20 + z1*a21 + z2*a22 + z3*a23); // y4 = g*y0 + s; z0 += 4*wc*(y0 - y1 + y2); z1 += 2*wc*(y1 - 2*y2 + y3); z2 += 2*wc*(y2 - 2*y3 + y4); z3 += 2*wc*(y3 - 2*y4); A*y4; ); function evalmoog(input) local(x) global() instance(r, p, k, oldx, oldy1, oldy2, oldy3, y1, y2, y3, y4) ( // Process input x = input - r*y4; // Four cascaded onepole filters (bilinear transform) y1= x*p + oldx*p - k*y1; y2=y1*p + oldy1*p - k*y2; y3=y2*p + oldy2*p - k*y3; y4=y3*p + oldy3*p - k*y4; // Clipper band limited sigmoid y4-=(y4*y4*y4)/6.; //y4 -= distort(y4); oldx = x; oldy1 = y1; oldy2 = y2; oldy3 = y3; y4; ); //filter_karlsen function evalkarlsen(b_v) local(f, t, t2, cutoff, res, b_rez, b_vnc) global(slider54) instance(b_fres, b_fenv, b_aflt1, b_aflt2, b_aflt3, b_aflt4) ( b_rez = b_aflt4 - b_v; // no attenuation with rez, makes a stabler filter. b_v = b_v - (b_rez*b_fres); // b_fres = resonance amount. 0..4 typical "to selfoscillation", 0.6 covers a more saturated range. b_vnc = b_v; // clip, and adding back some nonclipped, to get a dynamic like analog. b_v = distort(b_v); b_v = min(max(b_v, 0),1); //if (b_v > 1) {b_v = 1;} else if (b_v < -1) {b_v = -1;} b_v = b_vnc + ((-b_vnc + b_v) * 0.9840); b_aflt1 = b_aflt1 + ((-b_aflt1 + b_v) * b_fenv); // straightforward 4 pole filter, (4 normalized feedback paths in series) b_aflt2 = b_aflt2 + ((-b_aflt2 + b_aflt1) * b_fenv); b_aflt3 = b_aflt3 + ((-b_aflt3 + b_aflt2) * b_fenv); b_aflt4 = b_aflt4 + ((-b_aflt4 + b_aflt3) * b_fenv); b_v = b_aflt4; ); //filter_karlsen function evalkarlsen_sat(b_v) local(f, t, t2, cutoff, res, b_rez, b_vnc) global(slider54) instance(b_fres, b_fenv, b_aflt1, b_aflt2, b_aflt3, b_aflt4, b_lfcut, b_lf, b_lf1hp, b_lfhp, b_lfgain) ( // for nice low sat, or sharper type low deemphasis saturation, one can use a onepole shelf before the filter. b_lfcut = .001; b_lf = b_lf + ((-b_lf + b_v) * b_lfcut); // b_lfcut 0..1 b_lfhp = b_v - b_lf; b_v = b_lf + (b_lf1hp * ((b_lfgain*0.5)+1)); b_rez = b_aflt4 - b_v; // no attenuation with rez, makes a stabler filter. b_v = b_v - (b_rez*b_fres); // b_fres = resonance amount. 0..4 typical "to selfoscillation", 0.6 covers a more saturated range. b_vnc = b_v; // clip, and adding back some nonclipped, to get a dynamic like analog. b_v = distort(b_v); b_v = min(max(b_v, 0),1); //if (b_v > 1) {b_v = 1;} else if (b_v < -1) {b_v = -1;} b_v = b_vnc + ((-b_vnc + b_v) * 0.9840); b_aflt1 = b_aflt1 + ((-b_aflt1 + b_v) * b_fenv); // straightforward 4 pole filter, (4 normalized feedback paths in series) b_aflt2 = b_aflt2 + ((-b_aflt2 + b_aflt1) * b_fenv); b_aflt3 = b_aflt3 + ((-b_aflt3 + b_aflt2) * b_fenv); b_aflt4 = b_aflt4 + ((-b_aflt4 + b_aflt3) * b_fenv); b_v = 4*b_aflt4; ); function evaldualfilt(sample) local(out, fbs) global(distort) instance(fb, f, d0, d1) ( fbs = fb * .5*(distort(d0 - d1) + (d0-d1) + 0.15 * out ); fbs = max(-2, min(2, fbs)); d0 = d0 + f * (sample - d0 + fbs ); d1 = d1 + f * ( d0 - d1 ); out = distort(d1)*0.9 + d1*0.1; ); function evaldualfiltHP(sample) local(out, hp, bp, fbs) global(distort) instance(fb, f, d0, d1) ( hp = sample - d0; bp = d0 - d1; fbs = fb * .5*(distort(d0 - d1) + (d0-d1) + 0.15 * out ); fbs = max(-2, min(2, fbs)); d0 = d0 + f * ( hp + fbs ); d1 = d1 + f * ( d0 - d1 ); out = distort(hp)*0.9 + hp*0.51; ); function evaldualfiltBP(sample) local(out, hp, bp, fbs) global(distor) instance(fb, f, d0, d1) ( hp = sample - d0; bp = d0 - d1; fbs = fb * (.6*distort(d0 - d1) + .4*(d0-d1) + 0.15 * out ); fbs = max(-2, min(2, fbs)); d0 = d0 + f * ( hp + fbs ); d1 = d1 + f * ( d0 - d1 ); out = distort(bp)*.7 + bp*0.3 + 0.05*hp + 0.05*d1; ); function evalfancymoog(y0) local(S0, S2, S3, S4, F1, F2, F3, F4, WS0, WS1, WS2, WS3, WS4, gJ0, gJ1, gJ2, gJ3, gJ4, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, A0_0_0, A0_0_1, A0_0_2, A0_0_3, A0_1_0, A0_1_1, A0_1_2, A0_1_3, A0_2_0, A0_2_1, A0_2_2, A0_2_3, A0_3_0, A0_3_1, A0_3_2, A0_3_3 ) global(distort, distortderivt) instance(A, k, omega, hA, g, wc, wcT, T, y0, y1, y2, y3, y4, d0, d1, d2, d3, d4, S1) ( loop(3, S0 = hA * (y0 + d0 + k * ( y4 + d4 ) ); S1 = hA * (y1 + d1); S2 = hA * (y2 + d2); S3 = hA * (y3 + d3); S4 = hA * (y4 + d4); // Do not separate these, the index found during binary search for the original waveshaping // is used again in the derivate function. /*WS0 = distort(S0); gJ0 = g*distortderiv(S0); WS1 = distort(S1); gJ1 = g*distortderiv(S1); WS2 = distort(S2); gJ2 = g*distortderiv(S2); WS3 = distort(S3); gJ3 = g*distortderiv(S3); WS4 = distort(S4); gJ4 = g*distortderiv(S4);*/ WS0 = actual_tanh(S0); gJ0 = g*(1-WS0*WS0); WS1 = actual_tanh(S1); gJ1 = g*(1-WS1*WS1); WS2 = actual_tanh(S2); gJ2 = g*(1-WS2*WS2); WS3 = actual_tanh(S3); gJ3 = g*(1-WS3*WS3); WS4 = actual_tanh(S4); gJ4 = g*(1-WS4*WS4); F1 = y1 - d1 + wcT * ( WS1 + WS0 ); F2 = y2 - d2 - wcT * ( WS1 - WS2 ); F3 = y3 - d3 - wcT * ( WS2 - WS3 ); F4 = y4 - d4 - wcT * ( WS3 - WS4 ); // Jacobian subexpressions t2 = gJ2*gJ3; t3 = gJ2*gJ4; t4 = gJ3*gJ4; t5 = gJ2*gJ3*gJ4; t6 = gJ1*gJ2; t7 = gJ1*gJ3; t8 = gJ1*gJ4; t9 = gJ1*gJ2*gJ3; t10 = gJ1*gJ2*gJ4; t11 = gJ1*gJ3*gJ4; t12 = gJ1*gJ2*gJ3*gJ4; t13 = gJ0*gJ1*gJ2*gJ3*k; t14 = gJ1+gJ2+gJ3+gJ4+t2+t3+t4+t5+t6+t7+t8+t9+t10+t11+t12+t13+1.0; t15 = 1.0/t14; t16 = gJ2+1.0; t17 = gJ3+1.0; t18 = gJ1+1.0; // Jacobian A0_0_0 = t15*(gJ2+gJ3+gJ4+t2+t3+t4+t5+1.0); A0_0_1 = -gJ0*gJ2*gJ3*k*t15; A0_0_2 = -gJ0*gJ3*k*t15*t16; A0_0_3 = -gJ0*k*t15*t16*t17; A0_1_0 = t15*(gJ1+t7+t8+t11); A0_1_1 = t15*(gJ1+gJ3+gJ4+t4+t7+t8+t11+1.0); A0_1_2 = -gJ0*gJ1*gJ3*k*t15; A0_1_3 = -gJ0*gJ1*k*t15*t17; A0_2_0 = t15*(t6+t10); A0_2_1 = t15*(gJ2+t3+t6+t10); A0_2_2 = t15*(gJ1+gJ2+gJ4+t3+t6+t8+t10+1.0); A0_2_3 = -gJ0*gJ1*gJ2*k*t15; A0_3_0 = gJ1*gJ2*gJ3*t15; A0_3_1 = gJ2*gJ3*t15*t18; A0_3_2 = gJ3*t15*t16*t18; A0_3_3 = t15*t16*t17*t18; // Newton Raphson update //y1 = y1 - ( A0_0_0 * F1 + A0_1_0 * F2 + A0_2_0 * F3 + A0_3_0 * F4 ); //y2 = y2 - ( A0_0_1 * F1 + A0_1_1 * F2 + A0_2_1 * F3 + A0_3_1 * F4 ); //y3 = y3 - ( A0_0_2 * F1 + A0_1_2 * F2 + A0_2_2 * F3 + A0_3_2 * F4 ); //y4 = y4 - ( A0_0_3 * F1 + A0_1_3 * F2 + A0_2_3 * F3 + A0_3_3 * F4 ); y1 = y1 - ( A0_0_0 * F1 + A0_0_1 * F2 + A0_0_2 * F3 + A0_0_3 * F4 ); y2 = y2 - ( A0_1_0 * F1 + A0_1_1 * F2 + A0_1_2 * F3 + A0_1_3 * F4 ); y3 = y3 - ( A0_2_0 * F1 + A0_2_1 * F2 + A0_2_2 * F3 + A0_2_3 * F4 ); y4 = y4 - ( A0_3_0 * F1 + A0_3_1 * F2 + A0_3_2 * F3 + A0_3_3 * F4 ); ); // Update history d0 = y0; d1 = y1; d2 = y2; d3 = y3; d4 = y4; y4; ); function evalfancymoog_noJac(y0) local(S0, S1, S2, S3, S4, F1, F2, F3, F4, WS0, WS1, WS2, WS3, WS4) global(distort, distortderiv) instance(A, k, omega, hA, g, wc, wcT, T, y0, y1, y2, y3, y4, d0, d1, d2, d3, d4) ( loop(3, S0 = hA * (y0 + d0 + k * ( y4 + d4 ) ); S1 = hA * (y1 + d1); S2 = hA * (y2 + d2); S3 = hA * (y3 + d3); S4 = hA * (y4 + d4); WS0 = actual_tanh(S0); WS1 = actual_tanh(S1); WS2 = actual_tanh(S2); WS3 = actual_tanh(S3); WS4 = actual_tanh(S4); F1 = y1 - d1 + wcT * ( WS1 + WS0 ); F2 = y2 - d2 - wcT * ( WS1 - WS2 ); F3 = y3 - d3 - wcT * ( WS2 - WS3 ); F4 = y4 - d4 - wcT * ( WS3 - WS4 ); // Newton Raphson update (assuming derivatives 0) y1 = y1 - F1; y2 = y2 - F1 - F2; y3 = y3 - F3; y4 = y4 - F4; ); // Update history d0 = y0; d1 = y1; d2 = y2; d3 = y3; d4 = y4; y4; ); function evalvowel(sample) instance( c, amp1, amp2, amp3, Ab0, Ab1, Ab2, Aa1, Aa2, Bb0, Bb1, Bb2, Ba1, Ba2, Cb0, Cb1, Cb2, Ca1, Ca2, d1x, d2x, d1yA, d2yA, d1yB, d2yB, d1yC, d2yC, ) local(out, outA, outB, outC) global() ( outA = Ab0 * sample + Ab1 * d1x + Ab2 * d2x - Aa1 * d1yA - Aa2 * d2yA; outB = Bb0 * sample + Bb1 * d1x + Bb2 * d2x - Ba1 * d1yB - Ba2 * d2yB; outC = Ab0 * sample + Cb1 * d1x + Cb2 * d2x - Ca1 * d1yC - Ca2 * d2yC; d2x = d1x; d1x = sample; d2yA = d1yA; d1yA = outA; d2yB = d1yB; d1yB = outB; d2yC = d1yC; d1yC = outC; out = amp1 * outA + amp2 * outB + amp3 * outC; ); function evalsai0(sample) instance( c, amp1, amp2, amp3, Ab0, Ab1, Ab2, Aa1, Aa2, Bb0, Bb1, Bb2, Ba1, Ba2, Cb0, Cb1, Cb2, Ca1, Ca2, d1x, d2x, d1yA, d2yA, d1yB, d2yB, d1yC, d2yC, ) local(out, outA, outB, outC) global() ( sample = distort(sample); outA = Ab0 * sample + Ab1 * d1x + Ab2 * d2x - Aa1 * d1yA - Aa2 * d2yA; outB = Bb0 * sample + Bb1 * d1x + Bb2 * d2x - Ba1 * d1yB - Ba2 * d2yB; outC = Ab0 * sample + Cb1 * d1x + Cb2 * d2x - Ca1 * d1yC - Ca2 * d2yC; d2x = d1x; d1x = sample; d2yA = d1yA; d1yA = outA; d2yB = d1yB; d1yB = outB; d2yC = d1yC; d1yC = outC - .01 * ( outA - outB ); out = outA-.6*distort(outC-outB); out = 0.4*out; ); function evalmodulator(sample) instance( c, Ab0, Ab1, Ab2, Aa1, Aa2, Bb0, Bb1, Bb2, Ba1, Ba2, d1x, d2x, d1yA, d2yA, d1yB, d2yB, amp, d2x2, d1x2 ) local(out, dS, outA, outB, modo) global() ( // Modulator LP outB = Bb0 * sample + Bb1 * d1x + Bb2 * d2x - Ba1 * d1yB - Ba2 * d2yB; d2yB = d1yB; d1yB = outB; d2x = d1x; d1x = sample; modo = sample * outB; outA = Ab0 * modo + Ab1 * d1x2 + Ab2 * d2x2 - Aa1 * d1yA - Aa2 * d2yA; d2yA = d1yA; d1yA = outA; d2x2 = d1x2; d1x2 = modo; out = distort(outB * distort(sample+amp*outA)*2); ); function evalrbj(sample) instance( c, b0, b1, b2, a1, a2, d1x, d2x, d1y, d2y ) local(out) global() ( out = b0 * sample + b1 * d1x + b2 * d2x - a1 * d1y - a2 * d2y; d2x = d1x; d1x = sample; d2y = d1y; d1y = out; out; ); function evalphaserOTA(sample, jnk) global(distort) local(w) instance(C1, C2, dw, dx, sq) ( sample = sample - sq * jnk; w = dw + C1 * ( C2 * ( sample + dx + dw ) ); // removed distort here (was causing problems in a lot of cases) dx = sample; dw = w; w + sample ); function evalphaserFET(sample) global(distort) local(w, u, I_ds, out) instance(C1, C2, dw, IDSSdivVpSq, thresh) ( u = sample - dw; I_ds = ( u < thresh ) ? ( IDSSdivVpSq * 2 * thresh * u - u*u; ):( IDSSdivVpSq * thresh * thresh * u; ); w = dw + C1 * ( C2 * u + I_ds ); w = min(3, max(-3, w)); out = sample - w - dw; dw = w; out ); // One-pole zero-delay LP filter function zdf(G, x) global() local() instance(tpt, y) ( y = G*x + tpt.s; tpt.TPT_step(G, x-y); ); function eval_MS20lin(x) global() local(y, ky) instance(a0, a1, a2, s1, s2, g, k, onepole1, onepole2) ( x = distort(x); y = a0 * x + a1 * s1 + a2 * s2; ky = k*y; onepole1.zdf(g, x - ky); onepole2.zdf(g, onepole1.y + ky); s1 = onepole1.tpt.s; s2 = onepole2.tpt.s; y ); function eval_MS20linBP(x) global() local(y, ky) instance(a0, a1, a2, s1, s2, g, k, onepole1, onepole2) ( x = distort(x); y = -a0 * x + a1 * (s1 + x) + a2 * s2; ky = k*y; onepole1.zdf(g, -x - ky); onepole2.zdf(g, onepole1.y + ky + x); s1 = onepole1.tpt.s; s2 = onepole2.tpt.s; y ); function eval_MS20linHP(x) global() local(y, ky) instance(a0, a1, a2, s1, s2, g, k, onepole1, onepole2) ( x = distort(x); y = a1 * (s1 - x) + x + s2; ky = k*y; onepole1.zdf(g, - ky); onepole2.zdf(g, onepole1.y + ky - x); s1 = onepole1.tpt.s; s2 = onepole2.tpt.s; y ); function eval_MS20(x) global() local(ky, y, fy, fyprime, distky, ddistky) instance(s1, s2, G, Gsq, Gsqk, Gk, k, onepole1, onepole2) ( //fyprime = 1.0 - d/dy(Gsq*x*k*distort(y)) - d/dy(G*k*distort(y)); //x = distort(x); loop(3, ky = k*y; distky = distort(ky); ddistky = distortderiv(ky); fy = y - Gsq*x + Gsq*distky - G * S1 - G*distky - S2; fyprime = 1.0 + Gsq*ddistky - G*ddistky; y = y - fy/fyprime; ); //y = (Gsq*x + G*S1 + S2)/(1+Gsqk-Gk); ky = k*y; onepole1.zdf(g, x - distky); onepole2.zdf(g, onepole1.y + distky); s1 = onepole1.tpt.s; s2 = onepole2.tpt.s; y ); function eval_MS20_nonlin(x) global() local(hk, sig1, sig2, a, b, c, d, norm, f1, f2, gkd2, gky2, dgky2, sfunsq, sub3, sub3i, sub4sq, sub5, atanterm1, atanterm2) instance(y1, y2, d1, d2, h, hh, k, obs) ( gkd2 = k*d2; // g(k*d2) gkd2 = max(-1,min(1,gkd2)); hk = h*k; atanterm1 = atan(d1 - x + gkd2); atanterm2 = atan(d1 - d2 + gkd2); loop(3, //gky2 = distort(k*y2); //dgky2 = distortderiv(k*y2); gky2 = k*y2; dgky2 = 1 - ( abs(gky2) > 1 ); // Note that the chain ruled k part is already in the eqs (hk) gky2 = max(-1,min(1,gky2)); sig1 = y1 - y2 + gky2; sig2 = y1 - x + gky2; f1 = y1 - d1 + hh*(atanterm1 + atan(sig2)); f2 = y2 - d2 - hh*(atanterm2 + atan(sig1)); sfunsq = sig2 * sig2; sub3 = 2*(sfunsq + 1); sub3i = 1 / sub3; sub4sq = sig1*sig1; sub5 = 1/(2*(sub4sq + 1)); a = h*sub3i + 1; b = hk*dgky2*sub3i; c = -h*sub5; d = 1.0 - (hk*dgky2 - h)*sub5; norm = 1.0 / ( a*d - b*c ); y1 = y1 - ( d*f1 - b*f2 ) * norm; y2 = y2 - ( a*f2 - c*f1 ) * norm; ); d1 = y1; d2 = y2; distort(y2) ); function eval_MS20_nonlin_FM(x) global() local(mag, hk, sig1, sig2, a, b, c, d, norm, f1, f2, gkd2, gky2, dgky2, sfunsq, sub3, sub3i, sub4sq, sub5, atanterm1, atanterm2) instance(y1, y2, d1, d2, h, hh, k, obs, f) ( mag = f*5; gkd2 = k * sin(mag*d2); // g(k*d2) gkd2 = mag * k * cos(mag*d2); hk = h*k; atanterm1 = atan(d1 - x + gkd2); atanterm2 = atan(d1 - d2 + gkd2); loop(3, //gky2 = distort(k*y2); //dgky2 = distortderiv(k*y2); gky2 = k*sin(mag*y2); //k*y2; dgky2 = mag * k * cos(mag*y2); gky2 = max(-1,min(1,gky2)); sig1 = y1 - y2 + gky2; sig2 = y1 - x + gky2; f1 = y1 - d1 + hh*(atanterm1 + atan(sig2)); f2 = y2 - d2 - hh*(atanterm2 + atan(sig1)); sfunsq = sig2 * sig2; sub3 = 2*(sfunsq + 1); sub3i = 1 / sub3; sub4sq = sig1*sig1; sub5 = 1/(2*(sub4sq + 1)); a = h*sub3i + 1; b = hk*dgky2*sub3i; c = -h*sub5; d = 1.0 - (hk*dgky2 - h)*sub5; norm = 1.0 / ( a*d - b*c ); y1 = y1 - ( d*f1 - b*f2 ) * norm; y2 = y2 - ( a*f2 - c*f1 ) * norm; ); d1 = y1; d2 = y2; distort(y2) ); function eval_MS20_nonlin_mod(x) global() local(hk, sig1, sig2, a, b, c, d, norm, f1, f2, gkd2, gky2, dgky2, sfunsq, sub3, sub3i, sub4sq, sub5, atanterm1, atanterm2) instance(y1, y2, d1, d2, h, hh, k, obs) ( gkd2 = k*d2; // g(k*d2) gkd2 = max(-1,min(1,gkd2)); hk = h*k; atanterm1 = atan(d1 - x + gkd2); atanterm2 = atan(d1 - d2 + gkd2); loop(3, //gky2 = distort(k*y2); //dgky2 = distortderiv(k*y2); gky2 = k*y2-2*k*(y2*y2-y2*y2*y2)-.1*k*y1; dgky2 = 1 - ( abs(gky2) > 1 ); // Note that the chain ruled k part is already in the eqs (hk) gky2 = max(-1,min(1,gky2)); sig1 = y1 - y2 + gky2; sig2 = y1 - x + gky2; f1 = y1 - d1 + hh*(atanterm1 + atan(sig2)); f2 = y2 - d2 - hh*(atanterm2 + atan(sig1)); sfunsq = sig2 * sig2; sub3 = 2*(sfunsq + 1); sub3i = 1 / sub3; sub4sq = sig1*sig1; sub5 = 1/(2*(sub4sq + 1)); a = h*sub3i + 1; b = hk*dgky2*sub3i; c = -h*sub5; d = 1.0 - (hk*dgky2 - h)*sub5; norm = 1.0 / ( a*d - b*c ); y1 = y1 - ( d*f1 - b*f2 ) * norm; y2 = y2 - ( a*f2 - c*f1 ) * norm; ); d1 = y1; d2 = y2; distort(y2) ); function eval_MS20_nonlinBP(x) global() local(hk, sig1, sig2, a, b, c, d, norm, f1, f2, gkd2, gky2, dgky2, sfunsq, sub3, sub3i, sub4sq, sub5, atanterm1, atanterm2) instance(y1, y2, d1, d2, h, hh, k, obs) ( gkd2 = k*d2; // g(k*d2) gkd2 = max(-1,min(1,gkd2)); atanterm1 = atan(d1 + x + gkd2); atanterm2 = atan(d1 - d2 + x + gkd2); hk = h * k; loop(3, //gky2 = distort(k*y2); //dgky2 = distortderiv(k*y2); gky2 = k*y2; dgky2 = 1 - ( abs(gky2) > 1 ); // Note that the chain ruled k part is already in the eqs (hk) gky2 = max(-1,min(1,gky2)); sig1 = y1 + x + gky2; sig2 = x + y1 - y2 + gky2; f1 = y1 - d1 + hh*(atanterm1 + atan(sig1)); f2 = y2 - d2 - hh*(atanterm2 + atan(sig2)); sfunsq = sig1*sig1; sub3 = (2*(sfunsq + 1)); sub3i = 1/sub3; sub4sq = sig2*sig2; sub5 = 1 / (2*(sub4sq + 1)); a = h*sub3i + 1; b = hk*dgky2*sub3i; c = -h*sub5; d = 1 - (hk*dgky2 - h)*sub5; norm = 1.0 / ( a*d - b*c ); y1 = y1 - ( d*f1 - b*f2 ) * norm; y2 = y2 - ( a*f2 - c*f1 ) * norm; ); d1 = y1; d2 = y2; distort(y2) ); function eval_MS20_nonlinHP(x) global() local(hk, sig1, sig2, a, b, c, d, norm, f1, f2, gkd2px, gky2px, dgky2px, sub1sq, sub1i sub4sq, sub4i, atanterm1, atanterm2) instance(y1, y2, d1, d2, h, hh, k, obs) ( gkd2px = k*(d2 + x); // g(k*(d2 + x)) gkd2px = max(-1,min(1,gkd2px)); hk = h * k; atanterm1 = atan(d1 + gkd2px); atanterm2 = atan(d1 - d2 - x + gkd2px); loop(5, //gky2 = distort(k*y2); //dgky2 = distortderiv(k*y2); gky2px = k*(x + y2); // g(k*(x + y2)) // Clipper (g(y)) gky2px = max(-1,min(1,gky2px)); // Derivative dgky2px = 1 - ( abs(gky2px) > 1 ); // Note that the chain ruled k part is already in the eqs (hk) sig1 = y1 + gky2px; sig2 = x + y2 - sig1; f1 = y1 - d1 + hh*(atanterm1 + atan(sig1)); f2 = y2 - d2 - hh*(atanterm2 - atan(sig2)); sub1sq = sig1*sig1; sub1i = 1/(2*(sub1sq + 1)); sub4sq = sig2*sig2; sub4i = 1/(2*(sub4sq + 1)); a = h*sub1i + 1; b = hk*dgky2px*sub1i; c = -h*sub4i; d = 1 - (hk*dgky2px - h)*sub4i; norm = 1.0 / ( a*d - b*c ); y1 = y1 - ( d*f1 - b*f2 ) * norm; y2 = y2 - ( a*f2 - c*f1 ) * norm; ); d1 = y1; d2 = y2; distort(y2+x) ); // Checked for effect of tanh vs true_tanh function eval_ssm_nonlin_cheap(Ui) global() local(a, b, c, d, e, f, g, h, f0, f1, f2, f3, bias, idet, distd0d1, distd1d2, distd2d3, distk2d3, distd0difb, distu0u1, distu1u2, distu2u3, distu0uifb, fbterm, ddistu0uifb, ddistu0u1, ddistu1u2, ddistu2u3, dfbterm, term ) instance(hh, itau, K2, hhitau, U0, U1, U2, U3, D0, D1, D2, D3, Di, Kout) ( term = D0 + D1; term = term + term*term*term; distd0d1 = term / ( 1 + abs(term) ); term = D1 + D2; term = term + term*term*term; distd1d2 = term / ( 1 + abs(term) ); term = D2 + D3; term = term + term*term*term; distd2d3 = term / ( 1 + abs(term) ); term = K2 * D3; term = term + term*term*term; distk2d3 = term / ( 1 + abs(term) ); term = (D0 + Di - distk2d3); term = term + term*term*term; distd0difb = term / ( 1 + abs(term) ); loop(3, term = U0 + U1; term = term + term*term*term; distu0u1 = term / ( 1 + abs(term) ); term = U1 + U2; term = term + term*term*term; distu1u2 = term / ( 1 + abs(term) ); term = U2 + U3; term = term + term*term*term; distu2u3 = term / ( 1 + abs(term) ); term = K2 * U3; term = term + term*term*term; fbterm = term / ( 1 + abs(term) ); term = U0 + Ui - fbterm; term = term + term*term*term; distu0uifb = term / ( 1 + abs(term) ); ddistu0uifb = 1 - distu0uifb*distu0uifb; ddistu0u1 = 1 - distu0u1*distu0u1; ddistu1u2 = 1 - distu1u2*distu1u2; ddistu2u3 = 1 - distu2u3*distu2u3; dfbterm = 1 - fbterm*fbterm; f0 = -D0 + U0 + hhitau * (distd0difb + distu0uifb); f1 = -D1 + U1 + hhitau * (distd0d1 + distu0u1); f2 = -D2 + U2 + hhitau * (distd1d2 + distu1u2); f3 = -D3 + U3 + hhitau * (distd2d3 + distu2u3); a = hhitau*ddistu0uifb + 1; b = -K2*hhitau*dfbterm*ddistu0uifb; c = hhitau*ddistu0u1; d = c + 1; e = hhitau*ddistu1u2; f = e + 1; g = hhitau*ddistu2u3; h = g + 1; idet = 1.0/(a*d*f*h - b*c*e*g); U0 = U0 - (-b*d*f*f3 + b*d*f2*g - b*e*f1*g + d*f*f0*h)*idet; U1 = U1 - (a*f*f1*h + b*c*f*f3 - b*c*f2*g - c*f*f0*h)*idet; U2 = U2 - (a*d*f2*h - a*e*f1*h - b*c*e*f3 + c*e*f0*h)*idet; U3 = U3 - (a*d*f*f3 - a*d*f2*g + a*e*f1*g - c*e*f0*g)*idet; ); D0 = U0; D1 = U1; D2 = U2; D3 = U3; Di = Ui; Kout * U3 ); function eval_ssm_nonlin(Ui) global() local(a, b, c, d, e, f, g, h, f0, f1, f2, f3, bias, idet, distd0d1, distd1d2, distd2d3, distd0difb, distu0u1, distu1u2, distu2u3, distu0uifb, fbterm, ddistu0uifb, ddistu0u1, ddistu1u2, ddistu2u3, dfbterm) instance(hh, itau, K2, hhitau, U0, U1, U2, U3, D0, D1, D2, D3, Di, Kout) ( distd0d1 = actual_tanh(D0 + D1); distd1d2 = actual_tanh(D1 + D2); distd2d3 = actual_tanh(D2 + D3); distd0difb = actual_tanh(D0 + Di - actual_tanh(K2*D3)); loop(3, distu0u1 = actual_tanh(U0 + U1); distu1u2 = actual_tanh(U1 + U2); distu2u3 = actual_tanh(U2 + U3); fbterm = actual_tanh(K2 * U3); distu0uifb = actual_tanh(U0 + Ui - fbterm); ddistu0uifb = 1 - distu0uifb*distu0uifb; ddistu0u1 = 1 - distu0u1*distu0u1; ddistu1u2 = 1 - distu1u2*distu1u2; ddistu2u3 = 1 - distu2u3*distu2u3; dfbterm = 1 - fbterm*fbterm; f0 = -D0 + U0 + hhitau * (distd0difb + distu0uifb); f1 = -D1 + U1 + hhitau * (distd0d1 + distu0u1); f2 = -D2 + U2 + hhitau * (distd1d2 + distu1u2); f3 = -D3 + U3 + hhitau * (distd2d3 + distu2u3); a = hhitau*ddistu0uifb + 1; b = -K2*hhitau*dfbterm*ddistu0uifb; c = hhitau*ddistu0u1; d = c + 1; e = hhitau*ddistu1u2; f = e + 1; g = hhitau*ddistu2u3; h = g + 1; idet = 1.0/(a*d*f*h - b*c*e*g); U0 = U0 - (-b*d*f*f3 + b*d*f2*g - b*e*f1*g + d*f*f0*h)*idet; U1 = U1 - (a*f*f1*h + b*c*f*f3 - b*c*f2*g - c*f*f0*h)*idet; U2 = U2 - (a*d*f2*h - a*e*f1*h - b*c*e*f3 + c*e*f0*h)*idet; U3 = U3 - (a*d*f*f3 - a*d*f2*g + a*e*f1*g - c*e*f0*g)*idet; ); D0 = U0; D1 = U1; D2 = U2; D3 = U3; Di = Ui; Kout * U3 ); function ftanh2(x) global() local(sgn, ax) ( sgn = sign(x); ax = abs(x); // sgn*(-.0000067436811832+(.2468149110712040+(.0583691066395175+.03357335044280075*ax)*ax)*ax)/(.2464845986383725+(.060934719706049+(.1086202599228572+.02874707922475963*ax)*ax)*ax) sgn*(-.0000067436811832+(.2468149110712040+(.0583691066395175+.03357335044280075*ax)*ax)*ax)/(.2464845986383725+(.0609347197060491+(.1086202599228572+.02874707922475963*ax)*ax)*ax) ); function cmosFun(x) global() local(absterm, signterm, taa, tab, tasc) ( taa = 11.25; tab = -8; tasc = 0.6; absterm = abs(x); signterm = sign(x); tasc * (1-tanh( tab + taa*absterm )) * signterm; ); function cmosDeriv(fun) global() local(absterm, signterm, taa, tab, tasc, taadsc, taatasc) ( taa = 11.25; tab = -8; tasc = 0.6; taadsc = taa/tasc; taatasc = taa*tasc; (taadsc*fun*fun - taatasc) ); function cmosFun2(x) global() local(absterm, signterm, taa, tab, tasc, t) ( taa = 11.25; tab = -8; tasc = 0.6; absterm = abs(x); signterm = sign(x); t = tasc * x - tasc * (1-tanh( tab + taa*absterm ))*signterm; ); function cmosDeriv2(fun) global() local(absterm, signterm, taa, tab, tasc, taadsc, taatasc) ( taa = 11.25; tab = -8; tasc = 0.6; taadsc = taa/tasc; taatasc = taa*tasc; tasc - (taadsc*fun*fun - taatasc) ); function eval_broken_nonlin_LP(x) global(slider54, srate) local(hk, sig1, sig2, a, b, c, d, norm, f1, f2, gkd2, gky2, dgky2, sfunsq, sub3, sub3i, sub4sq, sub5, atanterm1, atanterm2) instance(y1, y2, d1, d2, h, hh, k, obs) ( // taa = 7.5*1.5 = 11.25 // tab = -8 // tasc = 4.8/7.5 = 0.6 // Empirical cmos func tasc * ( 1.0 - tanh(taa*x+tab) ) gkd2 = cmosFun(k*d2); // g(k*d2) hk = h*k; atanterm1 = cmosFun(d1 - x + gkd2); atanterm2 = cmosFun(d1 - d2 + gkd2); // BP //atanterm1 = cmosFun(d1 + x + gkd2); //atanterm2 = cmosFun(d1 - d2 + x + gkd2); loop(3, gky2 = cmosFun(k*y2); dgky2 = cmosDeriv(gky2); sig1 = y1 - y2 + gky2; sig2 = y1 - x + gky2; // BP //sig1 = y1 + x + gky2; //sig2 = x + y1 - y2 + gky2; f1 = y1 - d1 + hh*(atanterm1 + cmosFun(sig2)); f2 = y2 - d2 - hh*(atanterm2 + cmosFun(sig1)); sfunsq = sig2 * sig2; sub3 = 2*(sfunsq + 1); sub3i = 1 / sub3; sub4sq = sig1*sig1; sub5 = 1/(2*(sub4sq + 1)); a = h*sub3i + 1; b = hk*dgky2*sub3i; c = -h*sub5; d = 1.0 - (hk*dgky2 - h)*sub5; norm = 1.0 / ( a*d - b*c ); y1 = y1 - ( d*f1 - b*f2 ) * norm; y2 = y2 - ( a*f2 - c*f1 ) * norm; ); d1 = y1; d2 = y2; ); function eval_broken_nonlin_BP(x) global(slider54) local(hk, sig1, sig2, a, b, c, d, norm, f1, f2, gkd2, gky2, dgky2, sfunsq, sub3, sub3i, sub4sq, sub5, atanterm1, atanterm2) instance(y1, y2, d1, d2, h, hh, k, obs) ( gkd2 = cmosFun(k*d2); // g(k*d2) gkd2 = min(3,max(-3,gkd2)); atanterm1 = cmosFun(d1 + x + gkd2); atanterm2 = cmosFun(d1 - d2 + x + gkd2); hk = h * k; loop(3, //gky2 = distort(k*y2); //dgky2 = distortderiv(k*y2); gky2 = min(3,max(-3,cmosFun(k*y2))); dgky2 = cmosDeriv(gky2); sig1 = y1 + x + gky2; sig2 = x + y1 - y2 + gky2; f1 = y1 - d1 + hh*(atanterm1 + cmosFun(sig1)); f2 = y2 - d2 - hh*(atanterm2 + cmosFun(sig2)); sfunsq = sig1*sig1; sub3 = (2*(sfunsq + 1)); sub3i = 1/sub3; sub4sq = sig2*sig2; sub5 = 1 / (2*(sub4sq + 1)); a = h*sub3i + 1; b = hk*dgky2*sub3i; c = -h*sub5; d = 1 - (hk*dgky2 - h)*sub5; norm = 1.0 / ( a*d - b*c ); y1 = y1 - ( d*f1 - b*f2 ) * norm; y2 = y2 - ( a*f2 - c*f1 ) * norm; ); d1 = y1; d2 = y2; distort(y2) ); function eval_wasp_nonlin2(Ui) global(slider54, srate) local(a, b, c, d, e, f, g, h, f0, f1, f2, f3, bias, idet, distd0d1, distd1d2, distd2d3, distd0difb, distu0u1, distu1u2, distu2u3, distu0uifb, fbterm, fb1, ddistu0uifb, ddistu0u1, ddistu1u2, ddistu2u3, dfbterm) instance(hh, itau, K2, hhitau, U0, U1, U2, U3, D0, D1, D2, D3, Di, Kout) ( // taa = 7.5*1.5 = 11.25 // tab = -8 // tasc = 4.8/7.5 = 0.6 // Empirical cmos func tasc * ( 1.0 - tanh(taa*x+tab) ) distd0d1 = cmosFun2(D0 + D1); distd1d2 = cmosFun2(D1 + D2); distd2d3 = cmosFun2(D2 + D3); fb1 = cmosFun2(K2 * D3); distd0difb = cmosFun2(D0 + Di - fb1); // We desire: a*sc*(tanh(a*|x| + b)**2 - 1)*sign(x)*dabs(x)/dx // a dist term squared will be tasc^2 * tanh(tab + taa*abs(x))^2 // This is one tasc too many, but one taa too little. sign(x)*dabs(x)/dx cancel out (sort of). loop(3, distu0u1 = cmosFun2(U0+U1); distu1u2 = cmosFun2(U1+U2); distu2u3 = cmosFun2(U2+U3); fbterm = cmosFun2(K2 * U3); distu0uifb = cmosFun2(U0+Ui-fbterm); ddistu0uifb = cmosDeriv2(distu0uifb); ddistu0u1 = cmosDeriv2(distu0u1); ddistu1u2 = cmosDeriv2(distu1u2); ddistu2u3 = cmosDeriv2(distu2u3); dfbterm = cmosDeriv2(fbterm); f0 = -D0 + U0 + hhitau * (distd0difb + distu0uifb); f1 = -D1 + U1 + hhitau * (distd0d1 + distu0u1); f2 = -D2 + U2 + hhitau * (distd1d2 + distu1u2); f3 = -D3 + U3 + hhitau * (distd2d3 + distu2u3); a = hhitau*ddistu0uifb + 1; b = -K2*hhitau*dfbterm*ddistu0uifb; c = hhitau*ddistu0u1; d = c + 1; e = hhitau*ddistu1u2; f = e + 1; g = hhitau*ddistu2u3; h = g + 1; idet = 1.0/(a*d*f*h - b*c*e*g); U0 = U0 - (-b*d*f*f3 + b*d*f2*g - b*e*f1*g + d*f*f0*h)*idet; U1 = U1 - (a*f*f1*h + b*c*f*f3 - b*c*f2*g - c*f*f0*h)*idet; U2 = U2 - (a*d*f2*h - a*e*f1*h - b*c*e*f3 + c*e*f0*h)*idet; U3 = U3 - (a*d*f*f3 - a*d*f2*g + a*e*f1*g - c*e*f0*g)*idet; ); D0 = U0; D1 = U1; D2 = U2; D3 = U3; Di = Ui; Kout * U3 ); // Checked for effect of tanh vs true_tanh function eval_cem_nonlin(Ui) global(slider54, srate) local(a, b, c, d, e, f, g, h, f0, f1, f2, f3, bias, idet, distd0d1, distd1d2, distd2d3, distd0difb, distu0u1, distu1u2, distu2u3, distu0uifb, fbterm, ddistu0uifb, ddistu0u1, ddistu1u2, ddistu2u3, dfbterm, f0h, ad, bc) instance(hh, itau, K2, hhitau, hhitau2, itau2, U0, U1, U2, U3, D0, D1, D2, D3, Di, Kout, res, ifdbk) ( ifdbk = 2*res; /*distd0d1 = tanh(D0 + D1); distd1d2 = (D1 + D2); distd2d3 = (D2 + D3); fbterm = tanh(K2 * D3 - Di * ifdbk); distd0difb = fasttanh(D0 + Di - fbterm);*/ distd0d1 = tanh(D0 + D1); distd1d2 = (D1 + D2); distd2d3 = (D2 + D3); fbterm = tanh(K2 * D3 - Di * ifdbk); distd0difb = tanh(D0 + Di - fbterm); loop(3, // All of these had tanh /*distu0u1 = fasttanh(U0 + U1); distu1u2 = (U1 + U2); distu2u3 = (U2 + U3); fbterm = tanh(K2 * U3 - Ui * ifdbk); distu0uifb = fasttanh(U0 + Ui - fbterm);*/ distu0u1 = tanh(U0 + U1); distu1u2 = (U1 + U2); distu2u3 = (U2 + U3); fbterm = tanh(K2 * U3 - Ui * ifdbk); distu0uifb = tanh(U0 + Ui - fbterm); // The factor 16 is to correct for the fact that tanh actually computes 0.25 tanh(4*x). // This leads to a derivative given by 1-tanh(4*x)^2, but given that we have stored a term that // has this 0.25, we have to add this factor 4 back and square it. ddistu0uifb = 1 - 16*distu0uifb*distu0uifb; ddistu0u1 = 1 - 16*distu0u1*distu0u1; ddistu1u2 = 1;// - 16*distu1u2*distu1u2; ddistu2u3 = 1;// - 16*distu2u3*distu2u3; dfbterm = 1 - 16*fbterm*fbterm; f0 = -D0 + U0 + hhitau * (distd0difb + distu0uifb); f1 = -D1 + U1 + hhitau * (distd0d1 + distu0u1); f2 = -D2 + U2 + hhitau * (distd1d2 + distu1u2); f3 = -D3 + U3 + hhitau2 * (distd2d3 + distu2u3); a = hhitau*ddistu0uifb + 1; b = -K2*hhitau*dfbterm*ddistu0uifb; c = hhitau*ddistu0u1; d = c + 1; e = hhitau*ddistu1u2; f = e + 1; g = hhitau2*ddistu2u3; h = g + 1; f0h = f0*h; ad = a*d; bc = b*c; idet = 1.0/(ad*f*h - bc*e*g); U0 = U0 - (-b*d*f*f3 + b*d*f2*g - b*e*f1*g + d*f*f0h)*idet; U1 = U1 - (a*f*f1*h + bc*f*f3 - bc*f2*g - c*f*f0h)*idet; U2 = U2 - (ad*f2*h - a*e*f1*h - bc*e*f3 + c*e*f0h)*idet; U3 = U3 - (ad*f*f3 - ad*f2*g + a*e*f1*g - c*e*f0*g)*idet; ); D0 = U0; D1 = U1; D2 = U2; D3 = U3; Di = Ui; Kout * U3 ); // instance(hh, itau, itau2, K2, hhitau, hhitau2, f, rate, Kout) function eval_ssm_lin(Ui) global(slider54, srate) local(x3, x4, x5, x8, x9, x10, x12, x16, x17, x18, x19, x20, x21, x22) instance(x0, x1, x15, x2, x6, x7, x11, x13, x14, x16, Di, D0, D1, D2, D3, U0, U1, U2, U3, K2) ( x3 = D0*x0; x4 = D1*x0; x5 = -D1 + x3 + x4; x8 = D2*x0; x9 = D3*x0; x10 = -D3 + x8 + x9; x12 = -D2 + x4 + x8; x16 = -x3; x17 = Di*x0; x18 = Ui*x0; x19 = K2*x9; x20 = -x4; x21 = -D0 + x17 + x18 - x19 + x3; x22 = -x8; U0 = x2*(-K2*x10*x11 + x12*x14 + x15*(D0 + x16 - x17 - x18 + x19) - x5*x7); U1 = x2*(x10*x14 + x11*x21 - x12*x7 + x15*(D1 + x16 + x20)); U2 = x2*(-x10*x7 + x11*x5 - x13*x21 + x15*(D2 + x20 + x22)); U3 = x2*(x11*x12 - x13*x5 + x15*(D3 + x22 - x9) + x21*x6); D0 = U0; D1 = U1; D2 = U2; D3 = U3; Di = Ui; U3 ); function eval_cem_lin(Ui) global(slider54, srate) local(x7, x8, x9, x16, x17, x18, x20, x24, x25, x26, x29, iG) instance(K2, res, x0, x1, x2, x3, x4, x5, x6, x11, x12, x13, x14, x15, x19, x27, x22, x23, x28, hh2, hh3 D0, D1, D2, D3, U0, U1, U2, U3, Di) ( iG = 2*res; x7 = D0*x3; x8 = D1*x3; x9 = -D1 + x7 + x8; x16 = D2*x1; x17 = D3*x1; x18 = -D3 + x16 + x17; x20 = D2*x3 - D2 + x8; x24 = Di*x3; x25 = Ui*x3; x26 = -D0 - D3*x19 + iG*x24 + iG*x25 + x24 + x25 + x7; x29 = x12*x26; U0 = x6*(K2*x20*x23 - x14*x9 - x15*x18*x19 - x26*x27); U1 = x6*(x13*x18*x22 - x14*x20 + x26*x28 - x27*x9); U2 = x6*(-x0*hh3*x18 - x2*hh2*x29 - x20*x27 + x28*x9); U3 = x6*(x1*x15*x20 + x11*x29 - x23*x9 + x5*(D3 - x16 - x17)); D0 = U0; D1 = U1; D2 = U2; D3 = U3; Di = Ui; U3 ); function eval_linearSVF_LP(v0) global() local(v1, v2, v3) instance(ic1eq, ic2eq, k, a1, a2, a3) ( v3 = v0 - ic2eq; v1 = a1 * ic1eq + a2 * v3; v2 = ic2eq + a2 * ic1eq + a3*v3; ic1eq = 2*v1 - ic1eq; ic2eq = 2*v2 - ic2eq; v2 ); function eval_linearSVF_BP(v0) global() local(v1, v2, v3) instance(ic1eq, ic2eq, k, a1, a2, a3) ( v3 = v0 - ic2eq; v1 = a1 * ic1eq + a2 * v3; v2 = ic2eq + a2 * ic1eq + a3*v3; ic1eq = 2*v1 - ic1eq; ic2eq = 2*v2 - ic2eq; v1 ); function pwm_eval(sample) instance(len, ilen, c, out, spunk, gain) local(s) global() ( sample = 8*sample; out = this.filter_SVF.eval_linearSVF_LP(abs(sample) < (len-1)*ilen); s = len-1; loop(ilen-2, s -= 1; this.filter_SVF.eval_linearSVF_LP(abs(sample) < s*ilen); ); out ); function pwm_eval_BP(sample) instance(len, ilen, c, out, spunk, gain) local(s) global() ( sample = 8*sample; out = this.filter_SVF.eval_linearSVF_BP(abs(sample) < (len-1)*ilen); s = len-1; loop(ilen-2, s -= 1; this.filter_SVF.eval_linearSVF_BP(abs(sample) < s*ilen); ); out ); function bit_eval(sample) instance(depth, idepth, res) local(s, bass) global() ( res > 0.01 ? ( bass = this.filter_SVF.eval_linearSVF_LP(sample); sample = sample - bass; ); sample = floor( sample * depth ) * idepth; res > 0.01 ? sample = sample + bass; sample ); function muck_eval(sample) instance(f, res) local(s, bass) global() ( bass = this.filter_SVF.eval_linearSVF_LP(sample); sample = sample - bass; bass = bass * (1+.1*res*rand()*rand()*rand()); sample = sample + bass; sample ); function eval_linearSVF_HP(v0) global() local(v1, v2, v3) instance(ic1eq, ic2eq, k, a1, a2, a3) ( v3 = v0 - ic2eq; v1 = a1 * ic1eq + a2 * v3; v2 = ic2eq + a2 * ic1eq + a3*v3; ic1eq = 2*v1 - ic1eq; ic2eq = 2*v2 - ic2eq; v0 - k*v1 - v2 ); function eval_linearSVF_notch(v0) global() local(v1, v2, v3) instance(ic1eq, ic2eq, k, a1, a2, a3) ( v3 = v0 - ic2eq; v1 = a1 * ic1eq + a2 * v3; v2 = ic2eq + a2 * ic1eq + a3*v3; ic1eq = 2*v1 - ic1eq; ic2eq = 2*v2 - ic2eq; v0 - k*v1 ); function eval_linearSVF_peak(v0) global() local(v1, v2, v3) instance(ic1eq, ic2eq, k, a1, a2, a3) ( v3 = v0 - ic2eq; v1 = a1 * ic1eq + a2 * v3; v2 = ic2eq + a2 * ic1eq + a3*v3; ic1eq = 2*v1 - ic1eq; ic2eq = 2*v2 - ic2eq; v0 - k*v1 -2*v2 ); function evalvowelSVF(sample) instance( c, svf1, svf2, svf3, svf4, svf5, svf6, amp1, amp2, amp3 ) local(outA, outB, outC) global() ( outA = this.svf1.eval_linearSVF_peak(sample); outB = this.svf2.eval_linearSVF_BP(sample); outC = this.svf3.eval_linearSVF_BP(sample); outA = this.svf4.eval_linearSVF_BP(outA); outB = this.svf5.eval_linearSVF_BP(outB); outC = this.svf6.eval_linearSVF_BP(outC); amp1 * outA + amp2 * outB + amp3 * outC; ); function evalvowelSVF2(sample) instance( c, svf1, svf2, svf3, svf4, svf5, svf6, amp1, amp2, amp3 ) local(outA, outB, outC) global() ( outA = this.svf1.eval_linearSVF_peak(sample); outB = this.svf2.eval_linearSVF_BP(sample); outC = this.svf3.eval_linearSVF_BP(sample); outA = this.svf4.eval_linearSVF_LP(outA); outB = this.svf5.eval_linearSVF_LP(outB); outC = this.svf6.eval_linearSVF_LP(outC); amp1 * outA + amp2 * outB + amp3 * outC; ); function eval_wasplin(Ui) global() local() instance(U0, U1, Di, D0, D1, x0, x1, x2, x3, i1) ( U0 = (-D0*x2 - D0*x3 + D0 - 4*D1*x0 - Di*x1 - Ui*x1)*i1; U1 = (4*D0*x0 + D1*x2 - D1*x3 + D1 - Di*x3 - Ui*x3)*i1; D0 = U0; D1 = U1; Di = Ui; -U1; ); function f_g(s) local() global(slider8) instance() ( ( slider8 == 0 ) ? max(-1,min(1,s)) : abs(s) > 1 ? s - .75*sign(s)*(abs(s)-1) : s; ); function f_dg(s) local() global(slider8) instance() ( ( slider8 == 0 ) ? 1 - 1 * (abs(s)>1) : abs(s) > 1 ? .25 : 1; ); function eval_MS20_nonlin_tanh(x) global() local(gd2k, ky2, gky2, dgky2, f1, f2, a, b, c, d, norm, sig1, thsig1, thsig1sq, sig2, thsig2, thsig2sq, tanhterm1, tanhterm2, hhthsig1sqm1, hhthsig2sqm1 ) instance(i, y1, y2, d1, d2, h, hh, k, obs) ( gd2k = f_g(d2*k); tanhterm1 = actual_tanh((-d1 + x - gd2k)); tanhterm2 = actual_tanh((d1 - d2 + gd2k)); loop(4, ky2 = k*y2; gky2 = f_g(ky2); dgky2 = f_dg(ky2); sig1 = x - y1 - gky2; thsig1 = actual_tanh(sig1); thsig1sq = thsig1 * thsig1; sig2 = y1 - y2 + gky2; thsig2 = actual_tanh(sig2); thsig2sq = thsig2 * thsig2; hhthsig1sqm1 = hh*(thsig1sq - 1); hhthsig2sqm1 = hh*(thsig2sq - 1); f1 = y1 - d1 - hh*(tanhterm1 + thsig1); f2 = y2 - d2 - hh*(tanhterm2 + thsig2); a = -hhthsig1sqm1 + 1; b = -k*hhthsig1sqm1*dgky2; c = hhthsig2sqm1; d = (k*dgky2 - 1)*hhthsig2sqm1 + 1; norm = 1 / ( a*d - b*c ); y1 = y1 - ( d*f1 - b*f2 ) * norm; y2 = y2 - ( a*f2 - c*f1 ) * norm; ); d1 = y1; d2 = y2; ); function eval_MS20_nonlinBP_tanh(x) global() local(gd2k, ky2, gky2, dgky2, f1, f2, a, b, c, d, norm, sig1, thsig1, thsig1sq, sig2, thsig2, thsig2sq, tanhterm1, tanhterm2, hhthsig1sqm1, hhthsig2sqm1 ) instance(i, y1, y2, d1, d2, h, hh, k, obs) ( gd2k = f_g(d2*k); tanhterm1 = actual_tanh(-d1 - x - gd2k); tanhterm2 = actual_tanh(d1 - d2 + x + gd2k); loop(4, ky2 = k*y2; gky2 = f_g(ky2); dgky2 = f_dg(ky2); sig1 = -x - y1 - gky2; thsig1 = actual_tanh(sig1); thsig1sq = thsig1 * thsig1; sig2 = x + y1 - y2 + gky2; thsig2 = actual_tanh(sig2); thsig2sq = thsig2 * thsig2; hhthsig1sqm1 = hh*(thsig1sq - 1); hhthsig2sqm1 = hh*(thsig2sq - 1); f1 = y1 - d1 - hh*(tanhterm1 + thsig1); f2 = y2 - d2 - hh*(tanhterm2 + thsig2); a = 1 - hhthsig1sqm1; b = -k*hhthsig1sqm1*dgky2; c = hhthsig2sqm1; d = (k*dgky2 - 1)*hhthsig2sqm1 + 1; norm = 1 / ( a*d - b*c ); y1 = y1 - ( d*f1 - b*f2 ) * norm; y2 = y2 - ( a*f2 - c*f1 ) * norm; ); d1 = y1; d2 = y2; ); function eval_MS20_nonlinHP_tanh(x) global() local(gkd2px, kxpy2, gkxpy2, dgky2px, f1, f2, a, b, c, d, norm, sig1, thsig1, thsig1sq, sig2, thsig2, thsig2sq, tanhterm1, tanhterm2, hhthsig1sqm1, hhthsig2sqm1 ) instance(i, y1, y2, d1, d2, h, hh, k, obs) ( gkd2px = f_g(k*(d2 + x)); tanhterm1 = actual_tanh(-d1 - gkd2px); tanhterm2 = actual_tanh(d1 - d2 - x + gkd2px); loop(4, kxpy2 = k*(x + y2); gkxpy2 = f_g(kxpy2); dgky2px = f_dg(kxpy2); sig1 = -y1 - gkxpy2; thsig1 = actual_tanh(sig1); thsig2sq = thsig2 * thsig2; sig2 = -x + y1 - y2 + gkxpy2; thsig2 = actual_tanh(sig2); thsig2sq = thsig2 * thsig2; hhthsig1sqm1 = (thsig1sq - 1); hhthsig2sqm1 = (thsig2sq - 1); f1 = y1 - d1 - hh*(tanhterm1 + thsig1); f2 = y2 - d2 - hh*(tanhterm2 + thsig2); a = -hhthsig1sqm1 + 1; b = -k*hhthsig1sqm1*dgky2px; c = hhthsig2sqm1; d = (k*dgky2px - 1)*hhthsig2sqm1 + 1; norm = 1 / ( a*d - b*c ); y1 = y1 - ( d*f1 - b*f2 ) * norm; y2 = y2 - ( a*f2 - c*f1 ) * norm; ); d1 = y1; d2 = y2; ); function bufferFun(sample, delay1, delay2) global(distort) local(h) instance() ( h = 5; ); //global(window1.evalDist, window2.evalDist, filter_303.eval303) function process(sample, dist) ( sample+=0.00000001; // DeNorm fix // Optional clipping ( slider55 & 1 ) ? sample = min(1,max(-1,sample)); ( this.filtertype == 0 ) ? ( dist ? sample = distort(sample); ) : ( this.filtertype == 1 ) ? ( sample = this.rc_filter.evalRC(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 2 ) ? ( sample = this.filter_303.eval303(sample); ) : ( this.filtertype == 3 ) ? ( dist ? sample = distort(sample); sample = this.filter_vowel.evalvowel(sample); ) : ( this.filtertype == 4 ) ? ( sample = this.filter_karlsen.evalkarlsen(sample); ) : ( this.filtertype == 5 ) ? ( sample = this.filter_karlsen_sat.evalkarlsen_sat(sample); ) : ( this.filtertype == 6 ) ? ( sample = this.filter_dualfilt.evaldualfilt(sample); ) : ( this.filtertype == 7 ) ? ( sample = this.filter_dualfiltHP.evaldualfiltHP(sample); ) : ( this.filtertype == 8 ) ? ( sample = this.filter_dualfiltBP.evaldualfiltBP(sample); ) : ( this.filtertype == 9 ) ? ( sample = gaincompensation * this.filter_fancymoog.evalfancymoog(40*sample)/40; dist ? sample = distort(sample); ) : ( this.filtertype == 10 ) ? ( sample = gaincompensation * this.filter_fancymoog.evalfancymoog_noJac(40*sample)/40; dist ? sample = distort(sample); ) : ( this.filtertype == 11 ) ? ( sample = this.filter_notch.evalrbj(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 12 ) ? ( sample = this.filter_sai0.evalsai0(sample); ) : ( this.filtertype == 13 ) ? ( sample = this.filter_modulator.evalmodulator(sample); ) : ( this.filtertype == 14 ) ? ( os = sample; sample = this.filter_phaser.evalphaserOTA(sample, jnk); sample = this.filter_phaser2.evalphaserOTA(sample, 0); sample = this.filter_phaser3.evalphaserOTA(sample, 0); sample = this.filter_phaser4.evalphaserOTA(sample, 0); jnk = sample; sample = (os + sample)*.5; dist ? sample = distort(sample); ) : ( this.filtertype == 15 ) ? ( os = sample; sample = this.filter_phaser.evalphaserFET(sample); sample = this.filter_phaser2.evalphaserFET(sample); sample = this.filter_phaser3.evalphaserFET(sample); sample = this.filter_phaser4.evalphaserFET(sample); sample = (os + sample)*.5; dist ? sample = distort(sample); ) : ( this.filtertype == 16 ) ? ( os1 = filter_delay1.getBuffer(); os2 = filter_delay2.getBuffer(); ys1 = sample - .2 * distort(os1-os2); filter_delay1.updateBuffer(sample); filter_delay2.updateBuffer(ys1-sample); sample = ys1 + os2; ) : ( this.filtertype == 17 ) ? ( os1 = filter_delay1.getBuffer(); os2 = filter_delay2.getBuffer(); os3 = 0.001 * abs(sample) + 0.999 * abs(os3); filter_delay1.updateBuffer(sample); filter_delay2.updateBuffer(sample); sample = tanh(5*os3*sample + distort(sample-os1)); ) : ( this.filtertype == 18 ) ? ( sample = this.filter_ms20lin.eval_MS20lin(sample); ) : ( this.filtertype == 19 ) ? ( sample = this.filter_ms20lin.eval_MS20linBP(sample); ) : ( this.filtertype == 20 ) ? ( sample = this.filter_ms20lin.eval_MS20linHP(sample); ) : ( this.filtertype == 21 ) ? ( sample = this.filter_ms20.eval_MS20_nonlin(sample); ) : ( this.filtertype == 22 ) ? ( sample = this.filter_ms20.eval_MS20_nonlinBP(sample); ) : ( this.filtertype == 23 ) ? ( sample = this.filter_ms20.eval_MS20_nonlinHP(sample); ) : ( this.filtertype == 24 ) ? ( sample += 0.8 * this.filter_phaser.evalphaserFET(this.filter_delay.getBuffer()); flt = this.filter_ms20.eval_MS20_nonlin(sample); flt = this.filter_phaser2.evalphaserFET(flt); this.filter_delay.updateBuffer(distort(flt-.7*sample)); sample = this.filter_ms20.eval_MS20_nonlin(sample+flt); sample = this.filter_ms20.eval_MS20_nonlin(sample+flt); ) : ( this.filtertype == 25 ) ? ( sample = this.filter_ms20.eval_MS20_nonlin_mod(sample); ) : ( this.filtertype == 26 ) ? ( sample = this.filter_ssm.eval_ssm_nonlin(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 27 ) ? ( sample = this.filter_ssm.eval_ssm_nonlin_cheap(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 28 ) ? ( sample = this.filter_cem.eval_cem_nonlin(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 29 ) ? ( sample = this.filter_ssm_lin.eval_ssm_lin(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 30 ) ? ( sample = this.filter_cem_lin.eval_cem_lin(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 31 ) ? ( sample = ( 1 - this.filter_sine.res ) * sample + this.filter_sine.res * sin(sample * this.filter_sine.freq); dist ? sample = distort(sample); ) : ( this.filtertype == 32 ) ? ( sample = ( 1 - this.filter_sine.res ) * sample + this.filter_sine.res * this.filter_ms20.eval_MS20_nonlin_FM(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 33 ) ? ( os = .7 + .3* sin(.5*sample * this.filter_sine.freq); this.filter_ms20.init_MS20_nonlin(os*this.filter_sine.fraw, this.filter_sine.res); sample = this.filter_ms20.eval_MS20_nonlin(sample); ) : ( this.filtertype == 34 ) ? ( sample = this.filter_broken.eval_broken_nonlin_LP(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 35 ) ? ( //sample = this.filter_wasp2.eval_wasp_nonlin2(sample); sample = this.filter_wasp.eval_wasp_nonlin_extrareso(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 36 ) ? ( sample = this.filter_wasp_lin.eval_wasplin(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 37 ) ? ( sample = this.filter_wasp.eval_wasp_nonlin(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 38 ) ? ( sample = this.filter_wasp.eval_wasp_nonlin_BP(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 39 ) ? ( sample = this.filter_SVF.eval_linearSVF_LP(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 40 ) ? ( sample = this.filter_SVF.eval_linearSVF_BP(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 41 ) ? ( sample = this.filter_SVF.eval_linearSVF_HP(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 42 ) ? ( sample = this.filter_SVF.eval_linearSVF_notch(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 43 ) ? ( sample = this.filter_SVF.eval_linearSVF_peak(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 44 ) ? ( sample = this.filter_wasp.eval_wasp_nonlin(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 45 ) ? ( reso = this.filter_SVF.eval_linearSVF_LP( sample ); lp = this.filter_SVF_nores.eval_linearSVF_LP( sample ); sample = lp + .2*distort(5*(reso-lp)); ) : ( this.filtertype == 46 ) ? ( reso = this.filter_SVF.eval_linearSVF_LP( sample ); lp = this.filter_SVF_nores.eval_linearSVF_LP( sample ); diff = 10*(reso-lp); this.resoint = .5*tanh(this.resoint + tanh(diff)); sample = lp + this.resoint; dist ? sample = distort(sample); ) : ( this.filtertype == 47 ) ? ( reso = this.filter_SVF.eval_linearSVF_LP( sample ); lp = this.filter_SVF_nores.eval_linearSVF_LP( sample ); diff = tanh(10*(reso-lp)); diff = this.filter_SVF2.eval_linearSVF_LP( sample+diff ); diff = this.filter_SVF2.eval_linearSVF_LP( diff ); sample = (lp + diff)*.7; dist ? sample = distort(sample); ) : ( this.filtertype == 48 ) ? ( //sample = distort(sample); dist ? sample = distort(sample); os = this.filter_delay.getBuffer(); this.filter_delay.updateBuffer(sample); sample = (this.chan > 0) ? (sample + os) : (sample + os - 2 * this.stereoize * os); ) : ( this.filtertype == 49 ) ? ( reso = this.filter_SVF.eval_linearSVF_LP( sample ); lp = this.filter_SVF_nores.eval_linearSVF_LP( sample ); diff = tanh(3*(reso-lp)); sample = lp; os = this.filter_delay.getBuffer(); this.filter_delay.updateBuffer(diff); sample = sample+(diff+os); dist ? sample = distort(sample); ) : ( this.filtertype == 50 ) ? ( reso = this.filter_SVF.eval_linearSVF_BP( sample ); lp = this.filter_SVF_nores.eval_linearSVF_BP( sample ); diff = reso-lp; sample = lp; os = this.filter_delay.getBuffer(); this.filter_delay.updateBuffer(diff); sample = sample+(diff+os); dist ? sample = distort(sample); ) : ( this.filtertype == 51 ) ? ( sample = this.filter_ms20.eval_MS20_nonlin_tanh(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 52 ) ? ( sample = this.filter_ms20.eval_MS20_nonlinBP_tanh(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 53 ) ? ( sample = this.filter_ms20.eval_MS20_nonlinHP_tanh(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 54 ) ? ( sample = this.weeping.weeping_eval(sample); dist ? sample = 4*distort(.25*sample); ) : ( this.filtertype == 55 ) ? ( sample = this.pwm.pwm_eval(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 56 ) ? ( sample = this.pwm.pwm_eval_BP(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 57 ) ? ( sample = this.bit.bit_eval(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 58 ) ? ( sample = this.muck.muck_eval(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 59 ) ? ( sample = this.weeping.weeping_eval(sample); dist ? sample = 4*distort(.25*sample); ) : ( this.filtertype == 60 ) ? ( sample = this.wah.dlop_eval(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 61 ) ? ( sample = this.wah.dlop_eval(sample); dist ? sample = distort(sample); ) : ( this.filtertype == 62 ) ? ( sample = this.wah.dlop_eval(sample); dist ? sample = distort(sample); ) : ( this.filterType == 63 ) ? ( dist ? sample = distort(sample); sample = this.vowel_svf.evalvowelSVF(sample); ) : ( this.filterType == 64 ) ? ( sample = sample + tanh( -(this.vowel_svf.evalvowelSVF2(sample) + sample) + this.xxos ); this.xxos = sample; dist ? sample = distort(sample); ); sample; ); function processSamples() ( sl_in = ssl; sr_in = ssr; //( slider47 > 0 ) ? //( ( slider35 & 4 == 4 ) ? ( ssl = distort(ssl); ssr = distort(ssr); ) : ( slider46 == 0 ) ? ( ssl = L.process(ssl, 1); ssr = R.process(ssr, 1); ) : ( slider46 == 1 ) ? ( ssl = L.process(ssl, 1); ssr = L.process(ssr, 1); ) : ( slider46 == 2 ) ? ( side = .5 * ( ssl - ssr ); mid = .5 * ( ssl + ssr ); side = L.process(side, 1); side = L.process(side, 1); mid = R.process(mid, 1); ssl = mid + side; ssr = mid - side; ) : ( slider46 == 3 ) ? ( side = .5 * ( ssl - ssr ); mid = .5 * ( ssl + ssr ); side = L.process(side, 1); mid = R.process(mid, 1); mid = R.process(mid, 1); ssl = mid + side; ssr = mid - side; ) : ( slider46 == 4 ) ? ( side = .5 * ( ssl - ssr ); mid = .5 * ( ssl + ssr ); side = L.process(side, 1); mid = mid; ssl = mid + side; ssr = mid - side; ) : ( slider46 == 5 ) ? ( side = .5 * ( ssl - ssr ); mid = .5 * ( ssl + ssr ); mid = R.process(mid, 1); side = side; ssl = mid + side; ssr = mid - side; ) : ( slider46 == 6 ) ? ( side = .5 * ( ssl - ssr ); mid = .5 * ( ssl + ssr ); mid = R.process(mid, 1); side = L.process(1.5*side, 1); ssl = mid + side; ssr = mid - side; ) : ( slider46 == 7 ) ? ( side = .5 * ( ssl - d4ssr ); mid = .5 * ( ssl + ssr ); mid = R.process(mid, 1); side = L.process(4*side, 1); d4ssr = d3ssr; d3ssr = d2ssr; d2ssr = dssr; dssr = ssr; ssl = mid + side; ssr = mid - side; ) : ( slider46 == 8 ) ? ( side = .5 * ( ssl - d2ssr ); mid = .5 * ( ssl + ssr ); mid = R.process(mid, 1); side = L.process(side, 1); d3ssr = d2ssr; d2ssr = dssr; dssr = ssr; ssl = mid + side; ssr = mid - side; ); //); (slider40 > 0)? ( ( slider35 & 8 == 8 ) ? ( ssl = ssl; ) : ( secondFilterMode == 0 ) ? ( // Serial dual dist ssl = L2.process(ssl, 1); ssr = R2.process(ssr, 1); ) : ( secondFilterMode == 1 ) ? ( // Serial single dist ssl = L2.process(ssl, 0); ssr = R2.process(ssr, 0); ) : ( secondFilterMode == 2 ) ? ( // Parallel dual dist ssl = .5*ssl + .5*L2.process(sl_in, 1); ssr = .5*ssr + .5*R2.process(sr_in, 1); ) : ( secondFilterMode == 3 ) ? ( // Parallel single dist ssl = .5*ssl + .5*L2.process(sl_in, 0); ssr = .5*ssr + .5*R2.process(sr_in, 0); ); ); ); //ext_nodenorm = 1; gfx_clear = -1; updateSliders(); // Quick hacky fix until I can refactor this. // The UI is now initialized before it is ever opened. The reason is that the // maximum and minimum for the dynamic variable are stored in the slider, and the // actual mod range is taken from the widget. This is a bit of a design fail. setupGUI(); UI_Loaded = 0; @slider updateSliders(); updateActiveFilters(1); @block cTempo = tempo; blockSize = samplesblock; secondFilterMode = floor(slider50*.5); function inertiaSmoothing(newval) instance(prev, val, boost) global() local(error, diff) ( error = (val - newval); diff = val - prev; prev = val; boost = min(1, max(0, 15*abs(diff)-.1)); val = val - .3 * error - .7 * error * boost; ); // Sample accurate lerp slider55 & 4 ? ( resoLerp.prepLerp(49, reso_mem, inertia_s49.inertiaSmoothing( slider49 ), 1); cutoffLerp.prepLerp(48, cutoff_mem, inertia_s48.inertiaSmoothing( slider48 ), 1); resoLerp2.prepLerp(42, reso_mem2, inertia_s42.inertiaSmoothing( slider42 ), 1); cutoffLerp2.prepLerp(41, cutoff_mem2, inertia_s41.inertiaSmoothing( slider41 ), 1); ) : ( resoLerp.prepLerp(49, reso_mem, slider49, interpReso); cutoffLerp.prepLerp(48, cutoff_mem, slider48, interpCutoff); resoLerp2.prepLerp(42, reso_mem2, slider42, interpReso2); cutoffLerp2.prepLerp(41, cutoff_mem2, slider41, interpCutoff2); ); // Check if the filter or filter mode changed flushIt = ( slider46 != currentMode ) || ( slider47 != currentFilter ) || ( slider40 != currentFilter2 ); ( flushIt == 1 ) ? ( currentMode = slider46; currentFilter = slider47; currentFilter2 = slider40; resetActiveFilters(); updateSliders(); updateActiveFilters(1); resetActiveFilters(); ) : ( forceUpdate==1 ) ? ( forceUpdate = 0; updateSliders(); updateActiveFilters(1); ); ( pdcDelay != lastpdcDelay ) ? ( lastpdcDelay = pdcDelay; pdc_bot_ch=0; pdc_top_ch=2; pdc_delay = pdcDelay; ); handlesMIDI = (slider38&1) || (slider45 > 1) || followKey1 || followKey2; notePtr = note_mem; while (midirecv(offset,msg1,msg2,msg3)) ( msg1>$x89&&msg1<$xA0 && msg3!=0 ? ( notePtr[] = offset; notePtr += 1; notePtr[] = msg3; notePtr += 1; notePtr[] = msg2; notePtr += 1; ) : ( msg1>$x79&&msg1<$x90 ) ? ( notePtr[] = offset; notePtr += 1; notePtr[] = -1; notePtr += 1; ); midisend(offset,msg1,msg2,msg3); // passthrough MIDI events ); notePtr[] = -1337; // Signal end of note buffer notePtr = note_mem; curSample = 0; // Current sample in block notes_remain = 1; // End of the note buffer? note_next = notePtr[]; @sample sl = spl0 * pregain; sr = spl1 * pregain; spectrumIn.feedSample(sl+sr); gonioIn.feedGonio(sl, sr); modulator.updateModulator(); // Does this plugin respond to MIDI signals? // Take notes from the stack until we hit the end marker -1 (handlesMIDI && notes_remain) ? ( while( note_next == curSample ) ( notePtr += 1; (notePtr[] > 0) ? ( // note-on modulator.reset=1; LFO_was_reset = 1; notesOn = notesOn + 1; lastVel = slider45 > 3 ? notePtr[]/127 : 1; (slider45 == 2 || slider45 == 4) ? ( tDynamic = 0; dynval = 0; ); notePtr += 1; lastNote = notePtr[]; approxNoteFrequencyFilter1 = getTuning(slider47, lastNote, slider48); approxNoteFrequencyFilter2 = getTuning(slider40, lastNote, slider41); ) : (notePtr[] == -1) ? ( // note-off notesOn = notesOn - 1; notesOn = max(0, notesOn); ); notePtr += 1; // Avoid constantly dereferencing by picking up the next one note_next = notePtr[]; notes_remain = note_next != -1337; ); ); notePtrAtEnd=note_next; // Dynamics // Optional input clipping // Note that this input clipping is just for the dynamics and that the real clipping // is done on the oversampled samples to avoid aliasing issues. ( slider55 & 1 ) ? ( sbl = min(1,max(-1,sl)); sbr = min(1,max(-1,sr)); ) : ( sbl = sl; sbr = sr; ); inV = inVol.updateBuffer( RMS1.updateRMS(sbl, sbr) ); // Calculation of the dynamic variable ( dynamicsEnabled ) ? ( ( slider45 == 0 ) ? ( // Regular threshold mode ( inV > dyn_thresh ) ? ( dynval = dynval + dyn_atk; dynval = min(1, dynval); ) : ( dynval = dynval - dyn_decay * dynval; ); ) : ( slider45 == 1 ) ? ( // Direct RMS based mode dynval = min(1, (abs(inV)/dyn_thresh)^dyn_atk); dynval = (1 - dyn_decay) * dynval + dyn_decay * (1-dynval); ) : ( slider45 == 2 || slider45 == 4 ) ? ( // Fixed envelope that plays on note on tDynamic = tDynamic + 1; (tDynamic < dyn_atk_time) ? ( dynval = dynval + dyn_atk * lastVel; ) : ( tDynamic > dyn_hold_end ) ? ( dynval = dynval - dyn_decay * dynval; ) : dynval = lastVel; dynval = min(1, dynval); ) : ( slider45 == 3 || slider45 == 5 ) ? ( // Note mode (Legato) ( notesOn > 0 ) ? ( dynval = dynval + dyn_atk * ( 1-dyn_thresh ) + 3*dyn_thresh * dyn_atk*(1-dynval); currentVel = currentVel == 0 ? lastVel : currentVel; dynval = min(currentVel, dynval); ) : ( currentVel = 0; dynval = dynval - dyn_decay * dynval; ); ); dynBuf.updateBuffer(filteredDynval); ) : ( dynval = 1 ); // Update active filter only if cutoff changed updateActiveFilters(0); ( lookAhead ) ? ( oldl = preBufferL.getBuffer(); oldr = preBufferR.getBuffer(); oldreset = preBufferMod.getBuffer(); preBufferL.updateBuffer( sl ); preBufferR.updateBuffer( sr ); preBufferMod.updateBuffer( modulator.reset ); sl = oldl; sr = oldr; modulator.reset = oldreset; ); alpha = .9999; movavgLN = max(alpha*movavgLN, -sl); movavgLP = max(alpha*movavgLP, sl); movavgRN = max(alpha*movavgRN, -sr); movavgRP = max(alpha*movavgRP, sr); ( slider54 < 1.5 ) ? ( // Without oversampling ssl = sl; ssr = sr; processSamples(); sl = ssl; sr = ssr; // ) : ( slider54 == 1 ) ? ( // // With oversampling // os.os_up2(sl); // os.y1 = process(os.y1); // os.y0 = process(os.y0); // sl = os.os_down2(); // os.os_up2(sr); // os.y1 = process(os.y1); // os.y0 = process(os.y0); // sr = os.os_down2(); ) : ( q = 0; // N>1 oversampling sli = sl; sri = sr; ( slider50 & 1 ) ? ( sincFilterL.advanceSinc(sli); sincFilterR.advanceSinc(sri); ); loop( slider54, // Upsampling ( slider50 & 1 ) ? ( ssl = sincFilterL.getSubSample(); ssr = sincFilterR.getSubSample(); ) : ( ssl = filterL.inputFilter(sli); ssr = filterR.inputFilter(sri); ); processSamples(); // IIR downsampling? ( slider50 & 1 ) ? ( sincDownL.advanceHist(ssl); sincDownR.advanceHist(ssr); ) : ( (q += 1)==1 ? ( sl = filterL.outputFilter(ssl); sr = filterR.outputFilter(ssr); ) : ( filterL.outputFilter(ssl); filterR.outputFilter(ssr); ); ); ); // FIR downsampling? ( slider50 & 1 ) ? ( sl = sincDownL.sincDownSample(); sr = sincDownR.sincDownSample(); ); ); // DC correction otm1=0.999*otm1 + sl - itm1; itm1=sl; sl=otm1; otm2=0.999*otm2 + sr - itm2; itm2=sr; sr=otm2; movavgOLN = max(alpha*movavgOLN, -sl); movavgOLP = max(alpha*movavgOLP, sl); movavgORN = max(alpha*movavgORN, -sr); movavgORP = max(alpha*movavgORP, sr); postResetWaitSamples == 0 ? ( spl0 = sl * postgain; spl1 = sr * postgain; spectrumOut.feedSample(spl0+spl1); gonioOut.feedGonio(spl0, spl1); // Optional output clipping ( slider55 & 2 ) ? ( spl0 = min(1,max(-1,spl0)); spl1 = min(1,max(-1,spl1)); ); ) : ( spl0 = 0; spl1 = 0; postResetWaitSamples -= 1; ); // Scope outVol.updateBuffer( RMS2.updateRMS(spl0, spl1) ); curSample += 1; @gfx 1135 680 function angle_line(x, y, d1, d2, angle) local(ca, cb) ( sx = sin(angle); cx = cos(angle); gfx_line( x + d1 * cx, y + d1 * sx, x + d2 * cx, y + d2 * sx ); ); function randomize() ( // SPLINE slider1 = 2+floor(rand(7)); slider2 = 2+floor(rand(7)); slider4 = rand(1); slider5 = rand(1); slider6 = rand(1); slider7 = rand(1); slider8 = rand(1); slider9 = rand(1); slider10 = rand(1); slider11 = rand(1); slider12 = rand(1); slider13 = rand(1); slider14 = rand(1); slider15 = rand(1); slider16 = rand(1); slider18 = rand(1); slider19 = rand(1); slider20 = rand(1); slider21 = rand(1); slider22 = rand(1); slider23 = rand(1); slider24 = rand(1); slider25 = rand(1); slider26 = rand(1); slider27 = rand(1); slider28 = rand(1); slider29 = rand(1); slider30 = rand(1); slider31 = rand(1); slider32 = rand(1); slider34 = rand(1); // Second filter routing slider50 = floor(rand(3)); // Enabled toggles slider58 = floor(rand(1023)); // x4 x8 etc slider57 = floor(rand(63)); // Waveshaper type slider56 = floor(rand(4)); // Keyfollow slider33 = rand(1) + 1; // Pre-Gain Mod% slider17 = rand(1)*0.1; // Lookahead on slider35 = 3; // LFO type slider36 = floor(rand(nLFO)); // LFO freq slider37 = rand(1); // LFO flags slider38 = floor(rand(7)); // Mod range slider39 = rand(4); // Filter2 slider40 = floor(rand(nFilters)); slider41 = rand(1); slider42 = rand(1)*.6; slider43 = rand(1); slider44 = rand(1); // Filter 1 slider47 = floor(rand(nFilters)); slider48 = rand(1); slider49 = rand(1)*.6; slider62 = rand(1); slider63 = rand(1); // Filter 1 mode slider46 = floor(rand(6)); slider46 == 1 ? slider46 = 0; // Don't use mono double, too buggy! slider46 == 2 ? slider46 = 7; // Don't use M1/S2, too buggy! slider46 == 3 ? slider46 = 7; // Don't use M2/S1, too buggy! // Integration time slider64 = rand(40); // Attack/Decay/Thresh slider59 = rand(1); slider60 = rand(50); slider61 = rand(50); // Gains //slider52 = rand(25)-10; //slider53 = rand(25)-10; // Clipping options slider55 = floor(rand(7)); // MIDI mode slider45 = floor(rand(5)); forceUpdate = 1; ); function swapSlider(idx1, idx2) ( t = slider(idx1); slider(idx1) = slider(idx2); slider(idx2) = t; ); function swapFilters() ( swapSlider(40, 47); swapSlider(41, 48); swapSlider(42, 49); swapSlider(43, 62); swapSlider(44, 63); forceUpdate = 1; ); function randomizeFilters() ( // Filter2 slider40 = floor(rand(nFilters)); slider41 = rand(1); slider42 = rand(1)*.7; slider43 = rand(2)-1; // CMOD slider44 = rand(2)*.7-1; // RMOD // Filter 1 slider47 = floor(rand(nFilters)); slider48 = rand(1); slider49 = rand(1)*.7; slider62 = rand(2)-1; slider63 = rand(2)*.7-1; // Filter 1 mode slider46 = floor(rand(6)); // Second filter routing slider50 = floor(rand(3)); slider46 == 1 ? slider46 = 0; // Don't use mono double, too buggy! slider46 == 2 ? slider46 = 7; // Don't use M1/S2, too buggy! slider46 == 3 ? slider46 = 7; // Don't use M2/S1, too buggy! forceUpdate = 1; ); function randomizeWaveshaper() ( // SPLINE slider1 = 2+floor(rand(7)); slider2 = 2+floor(rand(7)); slider4 = rand(1); slider5 = rand(1); slider6 = rand(1); slider7 = rand(1); slider8 = rand(1); slider9 = rand(1); slider10 = rand(1); slider11 = rand(1); slider12 = rand(1); slider13 = rand(1); slider14 = rand(1); slider15 = rand(1); slider16 = rand(1); slider18 = rand(1); slider19 = rand(1); slider20 = rand(1); slider21 = rand(1); slider22 = rand(1); slider23 = rand(1); slider24 = rand(1); slider25 = rand(1); slider26 = rand(1); slider27 = rand(1); slider28 = rand(1); slider29 = rand(1); slider30 = rand(1); slider31 = rand(1); slider32 = rand(1); slider34 = rand(1); forceUpdate = 1; ); function randomizeLFO() ( // LFO type slider36 = floor(rand(nLFO)); // LFO freq slider37 = rand(1); // LFO flags slider38 = floor(rand(7)); // Mod range slider39 = rand(4); forceUpdate = 1; ); function draw_logo(x, y, size) global(gfx_x, gfx_y, gfx_r, gfx_g, gfx_b, gfx_a, retina_scaling, plugname, fontface, logo_color_r, logo_color_g, logo_color_b ) local(t1, t2, t3, a, ang1, ang2, dif, range) ( gfx_set(logo_color_r, logo_color_g, logo_color_b,.7); gfx_circle( x, y, size*.2 ); t1 = .4*size; t2 = .6*size; t3 = .7*size; a = 5*time_precise(); ang1 = a; ang2 = ang1 + .5*$pi; range = (1/12)*$pi; angle_line( x, y, t1, t2, ang1 ); gfx_arc(x, y, t3, ang2 - range, ang2 + range ); ang1 += (2/3)*$pi; ang2 += (2/3)*$pi; angle_line( x, y, t1, t2, ang1 ); gfx_arc(x, y, t3, ang2 - range, ang2 + range ); ang1 += (2/3)*$pi; ang2 += (2/3)*$pi; angle_line( x, y, t1, t2, ang1 ); gfx_arc(x, y, t3, ang2 - range, ang2 + range ); gfx_set(logo_color_r, logo_color_g, logo_color_b,1); a = 8*time_precise(); t1 = .5*size; t2 = size; t3 = 1.3*size; ang1 = (1/3)*$pi + a; ang2 = ang1 + .5*$pi; range = (1/12)*$pi; angle_line( x, y, t1, t2, ang1 ); gfx_line( x + t2 * cos(ang1-range), y + t2 * sin(ang1-range), x + t3 * cos(ang1), y + t3 * sin(ang1) ); gfx_line( x + t2 * cos(ang1+range), y + t2 * sin(ang1+range), x + t3 * cos(ang1), y + t3 * sin(ang1) ); gfx_arc(x, y, t2, ang2 - range, ang2 + range ); ang1 += (2/3)*$pi; ang2 += (2/3)*$pi; angle_line( x, y, t1, t2, ang1 ); gfx_line( x + t2 * cos(ang1-range), y + t2 * sin(ang1-range), x + t3 * cos(ang1), y + t3 * sin(ang1) ); gfx_line( x + t2 * cos(ang1+range), y + t2 * sin(ang1+range), x + t3 * cos(ang1), y + t3 * sin(ang1) ); gfx_arc(x, y, t2, ang2 - range, ang2 + range ); ang1 += (2/3)*$pi; ang2 += (2/3)*$pi; angle_line( x, y, t1, t2, ang1 ); gfx_line( x + t2 * cos(ang1-range), y + t2 * sin(ang1-range), x + t3 * cos(ang1), y + t3 * sin(ang1) ); gfx_line( x + t2 * cos(ang1+range), y + t2 * sin(ang1+range), x + t3 * cos(ang1), y + t3 * sin(ang1) ); gfx_arc(x, y, t2, ang2 - range, ang2 + range ); gfx_set(logo_color_r, logo_color_g, logo_color_b,.5); a = -1*time_precise(); ang2 = a + .5*$pi; range = (3/12)*$pi; gfx_arc(x, y, t3, ang2 - range, ang2 + range ); ang2 += (2/3)*$pi; gfx_arc(x, y, t3, ang2 - range, ang2 + range ); ang2 += (2/3)*$pi; gfx_arc(x, y, t3, ang2 - range, ang2 + range ); t3 = 1.5*size; gfx_set(logo_color_r, logo_color_g, logo_color_b,.7); a = -1*time_precise(); ang2 = a + .5*$pi; range = (3/12)*$pi; gfx_arc(x, y, t3, ang2 - range, ang2 + range ); ang2 += (2/3)*$pi; gfx_arc(x, y, t3, ang2 - range, ang2 + range ); ang2 += (2/3)*$pi; gfx_arc(x, y, t3, ang2 - range, ang2 + range ); gfx_setfont(1, fontface, 10*retina_scaling); gfx_measurestr( "FILTHER", t1, t2 ); gfx_x = x + 18; gfx_y = y - .5*t2; gfx_a = .3 + .5 * sin(a); gfx_printf(plugname) ); UI_Loaded == 0 ? SetupGUI(); lastChar = gfx_getchar(); //gfx_ext_retina>1 ? gfx_setfont(1,"Arial",16*gfx_ext_retina,'b') : gfx_setfont(0); //function draw_button(xp, yp, str) // instance(w,h,x,y) // globals(gfx_r,gfx_g,gfx_b,gfx_x,gfx_y,bgcolor) visible = gfx_getchar(65536) & 4 > 0; updating == 0 ? ( gfx_clear = -1; updating = 1; draw_logo(17*retina_scaling, 17*retina_scaling, 9*retina_scaling); // Clear screen first gfx_r=gfx_g=gfx_b=0; gfx_a=.6; gfx_x=gfx_y=0; gfx_rectto(gfx_w,gfx_h); fx = 30*retina_scaling; fy = wndPad*2.2 + wndY*2 + 3*retina_scaling; hh = 35 * retina_scaling; fy2 = hh + 15 * retina_scaling; wx = 3*wndX + 2*wndPad; gfx_set(filter_description_bg_r, filter_description_bg_g, filter_description_bg_b, filter_description_bg_a); gfx_rect(fx, fy, wx, hh); gfx_rect(fx, fy + fy2, wx, hh); filterDescription(slider47, fy + 5 * retina_scaling); filterDescription(slider40, fy + fy2 + 5*retina_scaling); window3.draw_back(); window3.inLight.active ? ( gfx_set( rms_in_r, rms_in_g, rms_in_b, rms_in_a ); window3.draw_buffer(inVol.scopeptr, inVol.scopebuffer, inVol.scopebuffermax, 0); ); window3.outLight.active ? ( gfx_set( rms_out_r, rms_out_g, rms_out_b, rms_out_a ); window3.draw_buffer(outVol.scopeptr, outVol.scopebuffer, outVol.scopebuffermax, 0); ); window3.dynLight.active ? ( dynamicsEnabled ? ( gfx_set( dyn_color_r, dyn_color_g, dyn_color_b, dyn_color_a ); window3.draw_buffer(dynBuf.scopeptr, dynBuf.scopebuffer, dynBuf.scopebuffermax, 1); ); ); retina_scaling > 1 ? gfx_setfont(1, fontface, 10*retina_scaling) : gfx_setfont(0); window3.draw_dynamics(dyn_thresh); retina_scaling > 1 ? gfx_setfont(1, fontface, 10*retina_scaling) : gfx_setfont(0); //window3.draw_text("Dynamics", .025, .025); spectrumIn.drawGrid(); spectrumIn.drawFFT(1); spectrumOut.drawFFT(0); spectrumIn.fftWindow_processMouse(mouse_x, mouse_y, mouse_cap); spectrumIn.xlabel("Frequency"); spectrumIn.ylabel("Level"); gonioIn.drawGonioWindow(); gonioIn.drawGonioMeter(0); gonioOut.drawGonioMeter(1); gonioOut.gonio_processMouse(mouse_x, mouse_y, mouse_cap); window3.xlabel("Time"); window3.ylabel("RMS / Level"); window1.draw_window(movAvgLN, movAvgRN, movavgOLN, movavgORN); window2.draw_window(movAvgLP, movAvgRP, movavgOLP, movavgORP); gfx_measurestr("Negative", ws, h); window1.draw_text("Negative", .985-ws/window1.w, .025); window1.xlabel("In Voltage (-)"); window1.ylabel("Out Voltage (-)"); gfx_measurestr("Positive", ws, h); window2.draw_text("Positive", .985-ws/window2.w, .025); window2.xlabel("In Voltage (+)"); window2.ylabel("Out Voltage (+)"); slider56 == 0 ? ( copyRight.selectionButton_draw(); copyLeft.selectionButton_draw(); ); masterPanel.groupWidget_draw(); filterPanel.groupWidget_draw(); filterPanel2.groupWidget_draw(); dynamicsPanel.groupWidget_draw(); lfoPanel.groupWidget_draw(); inGain.sliderWidget_draw(); inClip.selectionButton_draw(); linkButton.selectionButton_linkbutton(); outGain.sliderWidget_draw(); outClip.selectionButton_draw(); inertia.selectionButton_draw(); firButton.selectionButton_draw(); overSampling.sliderWidget_draw(); tempoLFOButton.selectionButton_draw(); centeredLFOButton.selectionButton_draw(); keyAmount.sliderWidget_draw(); lfoFrequency.sliderWidget_draw(); modulationFactor.sliderWidget_draw(); keyFollow1.selectionButton_draw(); keyFollow2.selectionButton_draw(); dynamicFilterButton.selectionButton_draw(); dynamicFilterButton2.selectionButton_draw(); bypassFilter1.selectionButton_draw(); bypassFilter2.selectionButton_draw(); lfoFilterButton.selectionButton_draw(); lfoFilterButton2.selectionButton_draw(); dynamicGainButton.selectionButton_draw(); lfoGainButton.selectionButton_draw(); dynamicWaveShapingButton.selectionButton_draw(); lookaheadButton.selectionButton_draw(); dynButton.selectionButton_draw(); lfoResetButton.selectionButton_draw(); atk_x4_1.selectionButton_draw(); atk_x4_2.selectionButton_draw(); decay_x4_1.selectionButton_draw(); decay_x4_2.selectionButton_draw(); rms_x4_1.selectionButton_draw(); rms_x4_2.selectionButton_draw(); modulatorDisplay.draw_modulator(); threshSlider.sliderWidget_draw(); attackSlider.sliderWidget_draw(); decaySlider.sliderWidget_draw(); rmsSlider.sliderWidget_draw(); /* These flags determine whether these values have an animated slider and mod range on top or not */ inGain.hasFilterDynamics = dynamicGainButton.active; inGain.hasModulatorDynamics = lfoGainButton.active; outGain.hasFilterDynamics = dynamicGainButton.active; outGain.hasModulatorDynamics = lfoGainButton.active; cutoffSlider.hasFilterDynamics = dynamicFilterButton.active; cutoffSlider.hasModulatorDynamics = lfoFilterButton.active; resonanceSlider.hasFilterDynamics = dynamicFilterButton.active; resonanceSlider.hasModulatorDynamics = lfoFilterButton.active; // GO HERE /* Display appropriate Hertzage for the cutoff sliders */ hz = getHz(slider47, cutoffSlider.sliderWidget_getValue()); cutoffSlider.overridevalue = hz; cutoffSlider.overrideunit = "Hz"; cutoffSlider.sliderWidget_draw(); resonanceSlider.sliderWidget_draw(); cutoffSlider2.hasFilterDynamics = dynamicFilterButton2.active; cutoffSlider2.hasModulatorDynamics = lfoFilterButton2.active; resonanceSlider2.hasFilterDynamics = dynamicFilterButton2.active; resonanceSlider2.hasModulatorDynamics = lfoFilterButton2.active; hz = getHz(slider40, cutoffSlider2.sliderWidget_getValue()); cutoffSlider2.overridevalue = hz; cutoffSlider2.overrideunit = "Hz"; cutoffSlider2.sliderWidget_draw(); resonanceSlider2.sliderWidget_draw(); lfoFrequency.overridevalue = modulator.modrate; (slider38&2) == 0 ? ( lfoFrequency.overridevalue = ((1+2*slider37)^4 - 1); lfoFrequency.overrideunit = "Hz"; ) : ( lfoFrequency.overridevalue = -1000; lfoFrequency.overrideunit = tempoLabel; ); // Combobox should be the last to draw lfoSelect.combobox_draw(); modeSelect.combobox_draw(); modeSelect2.combobox_draw(); filterSelect.combobox_draw(); filterSelect2.combobox_draw(); lfoSelect.combobox_draw_top(); modeSelect.combobox_draw_top(); modeSelect2.combobox_draw_top(); filterSelect.combobox_draw_top(); filterSelect2.combobox_draw_top(); (filterSelect.hasfocus == 0) ? ( ( modeSelect.hasFocus == 0 && modeSelect2.hasFocus == 0 ) ? ( ( filterSelect2.hasFocus == 0 ) ? ( ( lfoSelect.hasFocus == 0 ) ? ( change = inGain.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap); change == 1 ? ( slider_automate( slider51=inGain.sliderWidget_getValue2_nn(); ); preChange = slider52; slider_automate( slider52=inGain.sliderWidget_getValue(); ); linkButton.active == 1 ? slider_automate( slider53=slider53 - (slider52 - preChange); ); forceUpdate = 1; ) : change == 2 ? ( slider_automate( slider52=inGain.sliderWidget_getValue(); ); slider_automate( slider51=inGain.sliderWidget_getValue2_nn(); ); forceUpdate = 1; ); change = outGain.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap); change == 1 ? ( slider_automate( slider17=outGain.sliderWidget_getValue2_nn(); ); preChange = slider53; slider_automate( slider53=outGain.sliderWidget_getValue(); ); linkButton.active == 1 ? slider_automate( slider52=slider52 - (slider53 - preChange); ); forceUpdate = 1; ) : change == 2 ? ( preChange = slider53; slider_automate( slider53=outGain.sliderWidget_getValue(); ); linkButton.active == 1 ? slider_automate( slider52=slider52 - (slider53 - preChange); ); forceUpdate = 1; slider_automate( slider35=slider35-(slider35&2)+2 ); /* Signal that we did this and it wasn't an old preset */ slider_automate( slider17=outGain.sliderWidget_getValue2_nn(); ); ); slider56 == 0 ? ( copyRight.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) ? ( copyRight.active = 0; slider_automate( slider2 = slider1; slider3 = slider19; slider4 = slider20; slider5 = slider21; slider6 = slider22; slider7 = slider23; slider8 = slider24; slider9 = slider25; slider10 = slider26; slider11 = slider27; slider12 = slider28; slider13 = slider29; slider14 = slider30; slider15 = slider31; slider16 = slider32; slider18 = slider34; ); forceUpdate = 1; ); copyLeft.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) ? ( copyLeft.active = 0; slider_automate( slider1 = slider2; slider19 = slider3; slider20 = slider4; slider21 = slider5; slider22 = slider6; slider23 = slider7; slider24 = slider8; slider25 = slider9; slider26 = slider10; slider27 = slider11; slider28 = slider12; slider29 = slider13; slider30 = slider14; slider31 = slider15; slider32 = slider16; slider34 = slider18; ); forceUpdate = 1; ); ); change = cutoffSlider.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap); change == 1 ? ( slider_automate( slider62=cutoffSlider.sliderWidget_getValue2_nn(); ); slider_automate( slider48=cutoffSlider.sliderWidget_getValue(); ); interpCutoff = 1; forceUpdate = 1; ) : ( interpCutoff = 0 ); change == 2 ? ( slider_automate( slider48=cutoffSlider.sliderWidget_getValue(); ); slider_automate( slider62=cutoffSlider.sliderWidget_getValue2_nn(); ); interpCutoff = 1; forceUpdate = 1; ) : ( interpCutoff = 0 ); change = resonanceSlider.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap); change == 1 ? ( slider_automate( slider63=resonanceSlider.sliderWidget_getValue2_nn() ); slider_automate( slider49=resonanceSlider.sliderWidget_getValue(); ); interpReso = 1; forceUpdate = 1; ) : ( interpReso = 0 ); change == 2 ? ( slider_automate( slider49=resonanceSlider.sliderWidget_getValue(); ); slider_automate( slider63=resonanceSlider.sliderWidget_getValue2_nn() ); interpReso = 1; forceUpdate = 1; ) : ( interpReso = 0 ); change = cutoffSlider2.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap); change == 1 ? ( slider_automate( slider43=cutoffSlider2.sliderWidget_getValue2_nn(); ); slider_automate( slider41=cutoffSlider2.sliderWidget_getValue(); ); interpCutoff2 = 1; forceUpdate = 1; ) : ( interpCutoff2 = 0 ); change == 2 ? ( slider_automate( slider41=cutoffSlider2.sliderWidget_getValue(); ); slider_automate( slider43=cutoffSlider2.sliderWidget_getValue2_nn(); ); interpCutoff2 = 1; forceUpdate = 1; ) : ( interpCutoff2 = 0 ); change = resonanceSlider2.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap); change == 1 ? ( slider_automate( slider44=resonanceSlider2.sliderWidget_getValue2_nn() ); slider_automate( slider42=resonanceSlider2.sliderWidget_getValue(); ); interpReso2 = 1; forceUpdate = 1; ) : ( interpReso2 = 0 ); change == 2 ? ( slider_automate( slider42=resonanceSlider2.sliderWidget_getValue(); ); slider_automate( slider44=resonanceSlider2.sliderWidget_getValue2_nn() ); interpReso2 = 1; forceUpdate = 1; ) : ( interpReso2 = 0 ); overSampling.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap) ? ( slider_automate( slider54=overSampling.sliderWidget_getValue(); ); forceUpdate = 1; ); keyAmount.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap) ? ( slider_automate( slider33=keyAmount.sliderWidget_getValue(); ); forceUpdate = 1; ); threshSlider.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap) ? ( slider_automate( slider59=threshSlider.sliderWidget_getValue(); ); forceUpdate = 1; ); attackSlider.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap) ? ( slider_automate( slider60=attackSlider.sliderWidget_getValue(); ); forceUpdate = 1; ); decaySlider.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap) ? ( slider_automate( slider61=decaySlider.sliderWidget_getValue(); ); forceUpdate = 1; ); rmsSlider.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap) ? ( slider_automate( slider64=rmsSlider.sliderWidget_getValue(); ); forceUpdate = 1; ); linkButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); inClip.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); outClip.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); inertia.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); newClipMode = inClip.active + 2 * outClip.active + 4 * inertia.active; ( slider55 != newClipMode ) ? ( slider_automate( slider55=newClipMode; ); forceUpdate = 1; ); firButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); ( slider50 & 1 != firButton.active ) ? ( slider_automate( slider50=slider50 - (slider50&1) + firButton.active; ); forceUpdate = 1; ); atk_x4_1.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); atk_x4_2.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); decay_x4_1.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); decay_x4_2.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); rms_x4_1.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); rms_x4_2.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); newMultiplierMode = atk_x4_1.active + 2*atk_x4_2.active + 4 * decay_x4_1.active + 8 * decay_x4_2.active + 16 * rms_x4_1.active + 32 * rms_x4_2.active; ( slider57 != newMultiplierMode ) ? ( slider_automate( slider57=newMultiplierMode; ); forceUpdate = 1; ); lookAheadButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) ? ( slider_automate( slider35=(slider35 - (slider35&1))+lookAheadButton.active; ); forceUpdate = 1; ); bypassFilter1.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) ? ( slider_automate( slider35=(slider35 - (slider35&4))+4*bypassFilter1.active; ); forceUpdate = 1; ); bypassFilter2.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) ? ( slider_automate( slider35=(slider35 - (slider35&8))+8*bypassFilter2.active; ); forceUpdate = 1; ); dynButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) ? ( slider_automate( slider45 = dynButton.active + (slider45 & 2) + ( slider45 & 4 ); ); forceUpdate = 1; ); lfoResetButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); tempoLFOButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); centeredLFOButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap); newLFOMode = lfoResetButton.active + 2*tempoLFOButton.active + 4 * centeredLFOButton.active; ( slider38 != newLFOMode ) ? ( slider_automate( slider38=newLFOMode ); forceUpdate = 1; ); lfoFrequency.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap) ? ( slider_automate( slider37=lfoFrequency.sliderWidget_getValue(); ); forceUpdate = 1; ); modulationFactor.sliderWidget_processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap) ? ( slider_automate( slider39=modulationFactor.sliderWidget_getValue(); ); forceUpdate = 1; ); // Something changed w.r.t. dynamics dynamicFilterButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) || dynamicFilterButton2.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) || lfoFilterButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) || lfoFilterButton2.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) || dynamicWaveShapingButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) || dynamicGainButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) || lfoGainButton.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap) || keyFollow1.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap ) || keyFollow2.selectionButton_processMouse(mouse_x, mouse_y, mouse_cap ) ? ( slider58 = 2 * dynamicWaveShapingButton.active + 4 * dynamicFilterButton.active + 8 * lfoFilterButton.active + 16 * dynamicFilterButton2.active + 32 * lfoFilterButton2.active + 64 * dynamicGainButton.active + 128 * lfoGainButton.active + 256 * keyFollow1.active + 512 * keyFollow2.active; slider_automate(slider58); forceUpdate = 1; ); window1.processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap, last_mouse_cap); window2.processMouse(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap, last_mouse_cap); dyn_thresh = window3.processMouseDynamics(mouse_x, mouse_y, lx-mouse_x, ly-mouse_y, mouse_cap, dyn_thresh); ); ); ); ); ( modeSelect2.hasFocus == 0 && filterSelect.hasFocus == 0 && lfoSelect.hasFocus == 0 && filterSelect2.hasFocus == 0 ) ? modeSelect.combobox_processMouse(mouse_x, mouse_y, mouse_cap) ? ( slider_automate( slider46=modeSelect.curitem; ); ); ( modeSelect.hasFocus == 0 && filterSelect.hasFocus == 0 && lfoSelect.hasFocus == 0 && filterSelect2.hasFocus == 0 ) ? modeSelect2.combobox_processMouse(mouse_x, mouse_y, mouse_cap) ? ( slider_automate( slider50=((slider50&1) + modeSelect2.curitem*2); ); ); ( modeSelect2.hasFocus == 0 && modeSelect.hasFocus == 0 && lfoSelect.hasFocus == 0 && filterSelect2.hasFocus == 0 ) ? filterSelect.combobox_processMouse(mouse_x, mouse_y, mouse_cap) ? ( slider_automate( slider47=filterSelect.curitem; ); forceUpdate = 1; ); ( modeSelect2.hasFocus == 0 && modeSelect.hasFocus == 0 && filterSelect.hasFocus == 0 && filterSelect2.hasFocus == 0 ) ? lfoSelect.combobox_processMouse(mouse_x, mouse_y, mouse_cap) ? ( slider_automate( slider36=lfoSelect.curitem; ); forceUpdate = 1; ); ( modeSelect2.hasFocus == 0 && modeSelect.hasFocus == 0 && filterSelect.hasFocus == 0 && lfoSelect.hasFocus == 0 ) ? filterSelect2.combobox_processMouse(mouse_x, mouse_y, mouse_cap) ? ( slider_automate( slider40=filterSelect2.curitem; ); forceUpdate = 1; ); lx = mouse_x; ly = mouse_y; ( refreshDynMode != slider45 ) ? ( ( slider45 == 0 ) ? ( threshSlider.setLabel("Threshold"); attackSlider.setLabel("Attack"); decaySlider.setLabel("Decay"); dynButton.setLabel("RMS Mode"); dynButton.hint = "Use threshold or modulate directly by RMS.\n\nThe dynamic variable (shown with the yellow curve) changes based\non one of two mechanisms. Either it changes based on an attack/decay\nmechanism based on thresholding the input RMS value (RMS mode off),\nor it is directly set (without transient) to a function of the RMS \nvalue (RMS mode on)."; threshSlider.hint = "Threshold value.\nWhen input RMS exceeds this value,\nthe dynamic variable begins to accumulate.\n"; attackSlider.hint = "Attack\nHow long does the dynamic variable take to change\nto its maximal value once over the threshold.."; decaySlider.hint = "Decay\nHow long does the dynamic variable take to\ndecay when below the threshold"; ) : ( slider45 == 1 ) ? ( threshSlider.setLabel("Maximum"); attackSlider.setLabel("Curve / Attack"); decaySlider.setLabel("Inversion"); dynButton.setLabel("RMS Mode"); dynButton.hint = "Use threshold or modulate directly by RMS.\n\nThe dynamic variable (shown with the yellow curve) changes based\non one of two mechanisms. Either it changes based on an attack/decay\nmechanism based on thresholding the input RMS value (RMS mode off),\nor it is directly set (without transient) to a function of the RMS \nvalue (RMS mode on)."; threshSlider.hint = "Maximum\nAt which RMS signal value should\nthe dynamic modulation be 1.\n"; attackSlider.hint = "Curve\nSets how steep the non-linearity between\nRMS value and dynamic variable is."; decaySlider.hint = "Inversion\nChange polarity. 25 results in no dynamic modulation."; ) : ( slider45 == 2 || slider45 == 4 ) ? ( threshSlider.setLabel("Hold"); attackSlider.setLabel("Attack"); decaySlider.setLabel("Decay"); dynButton.setLabel("Legato"); dynButton.hint = "Play fixed envelope and restart envelope\nupon each MIDI note or play legato style."; threshSlider.hint = "Shape.\nShape of the envelope (0.5 = linear).\n"; attackSlider.hint = "Attack\nHow long does the dynamic variable take to change\nto its maximal value once over the threshold.."; decaySlider.hint = "Decay\nHow long does the dynamic variable take to\ndecay when below the threshold"; ) : ( slider45 == 3 || slider45 == 5 ) ? ( threshSlider.setLabel("Shape"); attackSlider.setLabel("Attack"); decaySlider.setLabel("Decay"); dynButton.setLabel("Legato"); dynButton.hint = "Play fixed envelope and restart envelope\nupon each MIDI note or play legato style."; threshSlider.hint = "Shape.\nShape of the envelope (0.5 = linear).\n"; attackSlider.hint = "Attack\nHow long does the dynamic variable take to change\nto its maximal value once over the threshold.."; decaySlider.hint = "Decay\nHow long does the dynamic variable take to\ndecay when below the threshold"; ); updateSliders(1); refreshDynMode = slider45; ); ( LFO_was_reset == 1 ) ? ( lfoResetButton.highlightNow(); LFO_was_reset = 0; ); ( slider45 == 0 ) ? ( threshSlider.overridevalue = 0; threshSlider.unit = " V"; attackSlider.overridevalue = dyn_atk_time / srate; attackSlider.overrideunit = "s"; decaySlider.overridevalue = dyn_decay_time / srate; decaySlider.overrideunit = "s"; ) : ( slider45 == 1 ) ? ( threshSlider.overridevalue = 0; threshSlider.unit = " V"; attackSlider.overridevalue = 0; decaySlider.overridevalue = 0; ) : ( slider45 == 2 || slider45 == 4 ) ? ( threshSlider.overridevalue = dyn_hold_time / srate; threshSlider.overrideunit = "s"; attackSlider.overridevalue = dyn_atk_time / srate; attackSlider.overrideunit = "s"; decaySlider.overridevalue = 2*dyn_decay_time / srate; decaySlider.overrideunit = "s"; ) : ( slider45 == 3 || slider45 == 5 ) ? ( threshSlider.overridevalue = 0; threshSlider.unit = "-"; attackSlider.overridevalue = dyn_atk_time / srate; attackSlider.overrideunit = "s"; decaySlider.overridevalue = 2*dyn_decay_time / srate; decaySlider.overrideunit = "s"; ); globalTime = time_precise(); delta_time = globalTime - lastGlobalTime; rts = 35*retina_scaling; ( (mouse_cap & 1) ) ? ( (lastLMB == 0) && (mouse_x < rts) && (mouse_y < rts) ? ( tc = time_precise(); lastLMB = 1; ( (tc-lastLogoClick) < .2 ) ? ( extraScale = (extraScale == 0) ? .2 : 0; SetupGUI(); ) : lastLogoClick = tc; ) ) : ( lastLMB = 0; ); lastGlobalTime = globalTime; hideToolTips == 0 ? drawHint_draw(); ( lastChar == 82 && ((mouse_cap & 8)>0) ) ? randomize(); ( lastChar == 83 && ((mouse_cap & 8)>0) ) ? swapFilters(); ( lastChar == 70 && ((mouse_cap & 8)>0) ) ? randomizeFilters(); ( lastChar == 87 && ((mouse_cap & 8)>0) ) ? randomizeWaveshaper(); ( lastChar == 76 && ((mouse_cap & 8)>0) ) ? randomizeLFO(); ( lastChar == 116 ) ? hideToolTips = 1 - hideToolTips; ( lastChar == 108 ) ? ( linuxMode = 1 - linuxMode; setupGUI(); ); last_mouse_cap = mouse_cap; updating = 0; );