shithub: leaf

Download patch

ref: 4a5f186eccf9d72bd622975d2a135545dd9652c4
parent: 17938cf32356239d02625a3aa9b33321605aaf25
author: Matthew Wang <Matthew@nat-oitwireless-inside-vapornet100-10-9-124-2.princeton.edu>
date: Tue Oct 1 13:22:18 EDT 2019

added inductor, inverted (both untested) and nonlinear components; single diode seems to work; should maybe not have separate WDF nonlinear class

--- a/LEAF/Inc/leaf-WDF.h
+++ b/LEAF/Inc/leaf-WDF.h
@@ -19,9 +19,119 @@
 
 //==============================================================================
 
-//---
-//WDF resistor
+typedef enum WDFComponentType
+{
+    SeriesAdaptor = 0,
+    ParallelAdaptor,
+    Resistor,
+    Capacitor,
+    Inductor,
+    Inverter,
+    ResistiveSource,
+    ComponentNil
+} WDFComponentType;
 
+typedef enum WDFRootType
+{
+    IdealSource = 0,
+    Diode,
+    DiodePair,
+    RootNil
+} WDFRootType;
+
+typedef struct _tWDF tWDF; // needed to allow tWDF pointers in struct
+struct _tWDF
+{
+    WDFComponentType type;
+    float port_resistance_up;
+    float port_resistance_left;
+    float port_resistance_right;
+    float port_conductance_up;
+    float port_conductance_left;
+    float port_conductance_right;
+    float incident_wave_up;
+    float incident_wave_left;
+    float incident_wave_right;
+    float reflected_wave_up;
+    float reflected_wave_left;
+    float reflected_wave_right;
+    float gamma_zero;
+    float sample_rate;
+    float value;
+    tWDF* child_left;
+    tWDF* child_right;
+    tWDF* outpoint;
+    float (*get_port_resistance)(tWDF* const);
+    float (*get_reflected_wave)(tWDF* const);
+    void (*set_incident_wave)(tWDF* const, float);
+};
+
+typedef struct _tWDFNonlinear tWDFNonlinear;
+struct _tWDFNonlinear
+{
+    WDFRootType type;
+    tWDF* child;
+    float (*calculate_reflected_wave)(tWDFNonlinear* const, float, float);
+};
+
+//WDF Linear Components
+void tWDF_init(tWDF* const r, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR);
+float tWDF_tick(tWDF* const r, tWDFNonlinear* const n, float sample, uint8_t paramsChanged);
+
+void tWDF_setValue(tWDF* const r, float value);
+void tWDF_setSampleRate(tWDF* const r, float sample_rate);
+void tWDF_setOutputPoint(tWDF* const r, tWDF* const outpoint);
+uint8_t tWDF_isLeaf(tWDF* const r);
+
+tWDF* tWDF_findOutputPoint(tWDF* const r);
+
+float tWDF_getPortResistance(tWDF* const r);
+float tWDF_getReflectedWave(tWDF* const r);
+void tWDF_setIncidentWave(tWDF* const r, float incident_wave);
+
+float tWDF_getVoltage(tWDF* const r);
+float tWDF_getCurrent(tWDF* const r);
+
+static float get_port_resistance_for_resistor(tWDF* const r);
+static float get_port_resistance_for_capacitor(tWDF* const r);
+static float get_port_resistance_for_inductor(tWDF* const r);
+static float get_port_resistance_for_resistive(tWDF* const r);
+static float get_port_resistance_for_inverter(tWDF* const r);
+static float get_port_resistance_for_series(tWDF* const r);
+static float get_port_resistance_for_parallel(tWDF* const r);
+
+static void set_incident_wave_for_leaf(tWDF* const r, float incident_wave);
+static void set_incident_wave_for_leaf_inverted(tWDF* const r, float incident_wave);
+static void set_incident_wave_for_inverter(tWDF* const r, float incident_wave);
+static void set_incident_wave_for_series(tWDF* const r, float incident_wave);
+static void set_incident_wave_for_parallel(tWDF* const r, float incident_wave);
+
+static float get_reflected_wave_for_resistor(tWDF* const r);
+static float get_reflected_wave_for_capacitor(tWDF* const r);
+static float get_reflected_wave_for_resistive(tWDF* const r);
+static float get_reflected_wave_for_inverter(tWDF* const r);
+static float get_reflected_wave_for_series(tWDF* const r);
+static float get_reflected_wave_for_parallel(tWDF* const r);
+    
+//WDF Nonlinear Roots
+void tWDFNonlinear_init(tWDFNonlinear* const n, WDFRootType type, tWDF* const child);
+float tWDFNonlinear_calculateReflectedWave(tWDFNonlinear*  const n, float input, float incident_wave);
+
+static float calculate_reflected_wave_for_ideal(tWDFNonlinear* const n, float input, float incident_wave);
+static float calculate_reflected_wave_for_diode(tWDFNonlinear* const n, float input, float incident_wave);
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+//WDF resistor
 typedef struct _tWDFresistor
 {
 	float port_resistance;
@@ -110,75 +220,6 @@
 float tWDFseriesAdaptor_getReflectedWave(tWDFseriesAdaptor* const r);
 float tWDFseriesAdaptor_getVoltage(tWDFseriesAdaptor* const r);
 float tWDFseriesAdaptor_getCurrent(tWDFseriesAdaptor* const r);
-
-//WDF component
-typedef enum WDFComponentType
-{
-	SeriesAdaptor = 0,
-	ParallelAdaptor,
-	Resistor,
-	Capacitor,
-	ResistiveSource,
-	ComponentNil
-} WDFComponentType;
-
-typedef struct _tWDF tWDF; // needed to allow tWDF pointers in struct
-struct _tWDF
-{
-	WDFComponentType type;
-	float port_resistance_up;
-	float port_resistance_left;
-	float port_resistance_right;
-	float port_conductance_up;
-	float port_conductance_left;
-	float port_conductance_right;
-	float incident_wave_up;
-	float incident_wave_left;
-	float incident_wave_right;
-	float reflected_wave_up;
-	float reflected_wave_left;
-	float reflected_wave_right;
-	float gamma_zero;
-	float sample_rate;
-	float value;
-	tWDF* child_left;
-	tWDF* child_right;
-    tWDF* outpoint;
-	float (*get_port_resistance)(tWDF* const);
-	float (*get_reflected_wave)(tWDF* const);
-	void (*set_incident_wave)(tWDF* const, float);
-};
-
-void tWDF_init(tWDF* const r, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR);
-float tWDF_tick(tWDF* const r, float sample, uint8_t paramsChanged);
-    
-void tWDF_setValue(tWDF* const r, float value);
-void tWDF_setSampleRate(tWDF* const r, float sample_rate);
-void tWDF_setOutputPoint(tWDF* const r, tWDF* const outpoint);
-uint8_t tWDF_isLeaf(tWDF* const r);
-    
-tWDF* tWDF_findOutputPoint(tWDF* const r);
-    
-float tWDF_getPortResistance(tWDF* const r);
-float tWDF_getReflectedWave(tWDF* const r);
-void tWDF_setIncidentWave(tWDF* const r, float incident_wave);
-    
-float tWDF_getVoltage(tWDF* const r);
-float tWDF_getCurrent(tWDF* const r);
-
-static float get_port_resistance_for_resistor(tWDF* const r);
-static float get_port_resistance_for_capacitor(tWDF* const r);
-static float get_port_resistance_for_series(tWDF* const r);
-static float get_port_resistance_for_parallel(tWDF* const r);
-
-static void set_incident_wave_for_leaf(tWDF* const r, float incident_wave);
-static void set_incident_wave_for_series(tWDF* const r, float incident_wave);
-static void set_incident_wave_for_parallel(tWDF* const r, float incident_wave);
-
-static float get_reflected_wave_for_resistor(tWDF* const r);
-static float get_reflected_wave_for_capacitor(tWDF* const r);
-static float get_reflected_wave_for_series(tWDF* const r);
-static float get_reflected_wave_for_parallel(tWDF* const r);
 
 //==============================================================================
     
--- a/LEAF/Src/leaf-WDF.c
+++ b/LEAF/Src/leaf-WDF.c
@@ -9,7 +9,6 @@
 #include "../Inc/leaf-WDF.h"
 
 //WDF
-
 void tWDF_init(tWDF* const r, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR)
 {
 	r->type = type;
@@ -24,36 +23,8 @@
 	r->reflected_wave_right = 0.0f;
 	r->sample_rate = leaf.sampleRate;
 	r->value = value;
-	if (r->type == SeriesAdaptor)
+    if (r->type == Resistor)
 	{
-		r->port_resistance_left = tWDF_getPortResistance(rL);
-		r->port_resistance_right = tWDF_getPortResistance(rR);
-		r->port_resistance_up = r->port_resistance_left + r->port_resistance_right;
-		r->port_conductance_up  = 1.0f / r->port_resistance_up;
-		r->port_conductance_left = 1.0f / r->port_resistance_left;
-		r->port_conductance_right = 1.0f / r->port_resistance_right;
-		r->gamma_zero = 1.0f / (r->port_resistance_right + r->port_resistance_left);
-
-		r->get_port_resistance = &get_port_resistance_for_series;
-		r->get_reflected_wave = &get_reflected_wave_for_series;
-		r->set_incident_wave = &set_incident_wave_for_series;
-	}
-	else if (r->type == ParallelAdaptor)
-	{
-		r->port_resistance_left = tWDF_getPortResistance(rL);
-		r->port_resistance_right = tWDF_getPortResistance(rR);
-		r->port_resistance_up = (r->port_resistance_left * r->port_resistance_right) / (r->port_resistance_left + r->port_resistance_right);
-		r->port_conductance_up  = 1.0f / r->port_resistance_up;
-		r->port_conductance_left = 1.0f / r->port_resistance_left;
-		r->port_conductance_right = 1.0f / r->port_resistance_right;
-		r->gamma_zero = 1.0f / (r->port_resistance_right + r->port_resistance_left);
-
-		r->get_port_resistance = &get_port_resistance_for_parallel;
-		r->get_reflected_wave = &get_reflected_wave_for_parallel;
-		r->set_incident_wave = &set_incident_wave_for_parallel;
-	}
-	else if (r->type == Resistor)
-	{
 		r->port_resistance_up = r->value;
 		r->port_conductance_up = 1.0f / r->value;
 
@@ -63,20 +34,71 @@
 	}
 	else if (r->type == Capacitor)
 	{
-		r->port_resistance_up = 1.0f / (r->sample_rate * 2.0f * r->value); //based on trapezoidal discretization
-		r->port_conductance_up = (1.0f / r->port_resistance_up);
-
+        r->port_conductance_up = r->sample_rate * 2.0f * r->value;
+		r->port_resistance_up = 1.0f / r->port_conductance_up; //based on trapezoidal discretization
+    
 		r->get_port_resistance = &get_port_resistance_for_capacitor;
 		r->get_reflected_wave = &get_reflected_wave_for_capacitor;
 		r->set_incident_wave = &set_incident_wave_for_leaf;
 	}
+    else if (r->type == Inductor)
+    {
+        r->port_resistance_up = r->sample_rate * 2.0f * r->value; //based on trapezoidal discretization
+        r->port_conductance_up = 1.0f / r->port_resistance_up;
+        
+        r->get_port_resistance = &get_port_resistance_for_inductor;
+        r->get_reflected_wave = &get_reflected_wave_for_capacitor; // same as capacitor
+        r->set_incident_wave = &set_incident_wave_for_leaf_inverted;
+    }
 	else if (r->type == ResistiveSource)
 	{
-
+        r->port_resistance_up = 1.0f; // always use 1.0f for resistance
+        r->port_conductance_up = 1.0f / 1.0f;
+        // value is source voltage
+        r->get_port_resistance = &get_port_resistance_for_resistive;
+        r->get_reflected_wave = &get_reflected_wave_for_resistive;
+        r->set_incident_wave = &set_incident_wave_for_leaf;
 	}
+    else if (r->type == Inverter)
+    {
+        r->port_resistance_up = tWDF_getPortResistance(r->child_left);
+        r->port_conductance_up = 1.0f / r->port_resistance_up;
+        
+        r->get_port_resistance = &get_port_resistance_for_inverter;
+        r->get_reflected_wave = &get_reflected_wave_for_inverter;
+        r->set_incident_wave = &set_incident_wave_for_inverter;
+    }
+    else if (r->type == SeriesAdaptor)
+    {
+        r->port_resistance_left = tWDF_getPortResistance(r->child_left);
+        r->port_resistance_right = tWDF_getPortResistance(r->child_right);
+        r->port_resistance_up = r->port_resistance_left + r->port_resistance_right;
+        r->port_conductance_up  = 1.0f / r->port_resistance_up;
+        r->port_conductance_left = 1.0f / r->port_resistance_left;
+        r->port_conductance_right = 1.0f / r->port_resistance_right;
+        r->gamma_zero = 1.0f / (r->port_resistance_right + r->port_resistance_left);
+        
+        r->get_port_resistance = &get_port_resistance_for_series;
+        r->get_reflected_wave = &get_reflected_wave_for_series;
+        r->set_incident_wave = &set_incident_wave_for_series;
+    }
+    else if (r->type == ParallelAdaptor)
+    {
+        r->port_resistance_left = tWDF_getPortResistance(r->child_left);
+        r->port_resistance_right = tWDF_getPortResistance(r->child_right);
+        r->port_resistance_up = (r->port_resistance_left * r->port_resistance_right) / (r->port_resistance_left + r->port_resistance_right);
+        r->port_conductance_up  = 1.0f / r->port_resistance_up;
+        r->port_conductance_left = 1.0f / r->port_resistance_left;
+        r->port_conductance_right = 1.0f / r->port_resistance_right;
+        r->gamma_zero = 1.0f / (r->port_resistance_right + r->port_resistance_left);
+        
+        r->get_port_resistance = &get_port_resistance_for_parallel;
+        r->get_reflected_wave = &get_reflected_wave_for_parallel;
+        r->set_incident_wave = &set_incident_wave_for_parallel;
+    }
 }
 
-float tWDF_tick(tWDF* const r, float sample, uint8_t paramsChanged)
+float tWDF_tick(tWDF* const r, tWDFNonlinear* const n, float sample, uint8_t paramsChanged)
 {
 	//step 0 : update port resistances if something changed
 	if (paramsChanged) tWDF_getPortResistance(r);
@@ -88,13 +110,13 @@
 	float incident_wave = tWDF_getReflectedWave(r);
 
 	//step 3 : do root scattering computation
-	float reflected_wave = (2.0f * input) - incident_wave;
+	float reflected_wave = tWDFNonlinear_calculateReflectedWave(n, input, incident_wave);
 
-	//step 4 : propigate waves down the tree
+	//step 4 : propogate waves down the tree
 	tWDF_setIncidentWave(r, reflected_wave);
 
 	//step 5 : grab whatever voltages or currents we want as outputs
-	return -1.0f * tWDF_getVoltage(r->outpoint);
+    return reflected_wave*0.5f + incident_wave*0.5f;//tWDF_getVoltage(r->outpoint);
 }
 
 void tWDF_setValue(tWDF* const r, float value)
@@ -149,7 +171,10 @@
 	return (((r->incident_wave_up * 0.5f) - (r->reflected_wave_up * 0.5f)) * r->port_conductance_up);
 }
 
-// static functions to be pointed to
+//============ Static Functions to be Pointed To ====================
+//===================================================================
+//============ Get and Calculate Port Resistances ===================
+
 static float get_port_resistance_for_resistor(tWDF* const r)
 {
 	r->port_resistance_up = r->value;
@@ -160,12 +185,33 @@
 
 static float get_port_resistance_for_capacitor(tWDF* const r)
 {
-	r->port_resistance_up = 1.0f / (r->sample_rate * 2.0f * r->value); //based on trapezoidal discretization
-	r->port_conductance_up = (1.0f / r->port_resistance_up);
+	r->port_conductance_up = r->sample_rate * 2.0f * r->value; //based on trapezoidal discretization
+	r->port_resistance_up = (1.0f / r->port_conductance_up);
 
 	return r->port_resistance_up;
 }
 
+static float get_port_resistance_for_inductor(tWDF* const r)
+{
+    r->port_resistance_up = r->sample_rate * 2.0f * r->value; //based on trapezoidal discretization
+    r->port_conductance_up = (1.0f / r->port_resistance_up);
+    
+    return r->port_resistance_up;
+}
+
+static float get_port_resistance_for_resistive(tWDF* const r)
+{
+    return r->port_resistance_up;
+}
+
+static float get_port_resistance_for_inverter(tWDF* const r)
+{
+    r->port_resistance_up = tWDF_getPortResistance(r->child_left);
+    r->port_conductance_up = 1.0f / r->port_resistance_up;
+    
+    return r->port_resistance_up;
+}
+
 static float get_port_resistance_for_series(tWDF* const r)
 {
 	r->port_resistance_left = tWDF_getPortResistance(r->child_left);
@@ -192,11 +238,24 @@
 	return r->port_resistance_up;
 }
 
+//===================================================================
+//================ Set Incident Waves ===============================
+
 static void set_incident_wave_for_leaf(tWDF* const r, float incident_wave)
 {
 	r->incident_wave_up = incident_wave;
 }
 
+static void set_incident_wave_for_leaf_inverted(tWDF* const r, float incident_wave)
+{
+    r->incident_wave_up = -1.0f * incident_wave;
+}
+
+static void set_incident_wave_for_inverter(tWDF* const r, float incident_wave)
+{
+    tWDF_setIncidentWave(r->child_left, -1.0f * incident_wave);
+}
+
 static void set_incident_wave_for_series(tWDF* const r, float incident_wave)
 {
 	float gamma_left = r->port_resistance_left * r->gamma_zero;
@@ -225,6 +284,9 @@
 	tWDF_setIncidentWave(r->child_right, gamma_left * left_wave + (gamma_right - 1.0f) * right_wave + incident_wave);
 }
 
+//===================================================================
+//================ Get Reflected Waves ==============================
+
 static float get_reflected_wave_for_resistor(tWDF* const r)
 {
 	r->reflected_wave_up = 0.0f;
@@ -237,6 +299,18 @@
 	return r->reflected_wave_up;
 }
 
+static float get_reflected_wave_for_resistive(tWDF* const r)
+{
+    r->reflected_wave_up = r->value;
+    return r->reflected_wave_up;
+}
+
+static float get_reflected_wave_for_inverter(tWDF* const r)
+{
+    r->reflected_wave_up = -1.0f * tWDF_getReflectedWave(r->child_left);
+    return r->reflected_wave_up;
+}
+
 static float get_reflected_wave_for_series(tWDF* const r)
 {
 	//-( downPorts[0]->a + downPorts[1]->a );
@@ -249,6 +323,87 @@
 	float gamma_right = r->port_conductance_right * r->gamma_zero;
 	//return ( dl * downPorts[0]->a + dr * downPorts[1]->a );
 	return (gamma_left * tWDF_getReflectedWave(r->child_left) + gamma_right * tWDF_getReflectedWave(r->child_right));
+}
+
+// WDF Nonlinear
+void tWDFNonlinear_init(tWDFNonlinear* const n, WDFRootType type, tWDF* const child)
+{
+    n->type = type;
+    n->child = child;
+    if (n->type == IdealSource)
+    {
+        n->calculate_reflected_wave = &calculate_reflected_wave_for_ideal;
+    }
+    else if (n->type == Diode)
+    {
+        n->calculate_reflected_wave = &calculate_reflected_wave_for_diode;
+    }
+    else if (n->type == DiodePair)
+    {
+        //n->calculate_reflected_wave = &calculate_reflected_wave_for_ideal;
+    }
+}
+
+float tWDFNonlinear_calculateReflectedWave(tWDFNonlinear*  const n, float input, float incident_wave)
+{
+    return n->calculate_reflected_wave(n, input, incident_wave);
+}
+
+static float calculate_reflected_wave_for_ideal(tWDFNonlinear* const n, float input, float incident_wave)
+{
+    return (2.0f * input) - incident_wave;
+}
+
+static const float l2A = 0.1640425613334452f;
+static const float l2B = -1.098865286222744f;
+static const float l2Y = 3.148297929334117f;
+static const float l2K = -2.213475204444817f;
+static float log2Approximation(float x)
+{
+    return (l2A * x*x*x) + (l2B * x*x) + (l2Y * x) + l2K;
+}
+
+static const float wX1 = -3.684303659906469f;
+static const float wX2 = 1.972967391708859f;
+static const float wA = 0.009451797158780131f;
+static const float wB = 0.1126446405111627f;
+static const float wY = 0.4451353886588814f;
+static const float wK = 0.5836596684310648f;
+
+static float wrightOmega3(float x)
+{
+    if (x <= wX1)
+    {
+        return 0;
+    }
+    else if (x < wX2)
+    {
+        return (wA * x*x*x) + (wB * x*x) + (wY * x) + wK;
+    }
+    else
+    {
+        return x - logf(x);
+    }
+}
+
+static float wrightOmegaApproximation(float x)
+{
+    float w3 = wrightOmega3(x);
+    return w3 - ((w3 - expf(x - w3)) / (w3 + 1.0f));
+}
+
+static float lambertW(float a, float r, float I, float iVT)
+{
+    return wrightOmegaApproximation(((a + r*I) * iVT) + log((r * I) * iVT));
+}
+
+#define Is_DIODE    2.52e-9
+#define VT_DIODE    0.02585
+static float calculate_reflected_wave_for_diode(tWDFNonlinear* const n, float input, float incident_wave)
+{
+    float a = incident_wave;
+    float r = n->child->port_resistance_up;
+    return a + 2.0f*r*Is_DIODE - 2.0f*VT_DIODE*lambertW(a, r, Is_DIODE, 1.0f/VT_DIODE);
 }
 
 
--- a/LEAF_JUCEPlugin/Source/MyTest.cpp
+++ b/LEAF_JUCEPlugin/Source/MyTest.cpp
@@ -20,11 +20,14 @@
 tWDF r2;
 tWDF c1;
 tWDF c2;
+tWDF rs1;
 tWDF p1;
 tWDF s1;
 tWDF s2;
-
+tWDFNonlinear i;
+tWDFNonlinear d;
 tNoise noise;
+tCycle sine;
 
 float gain;
 bool buttonState;
@@ -35,8 +38,11 @@
     LEAF_init(sampleRate, blockSize, &getRandomFloat);
     
     tNoise_init(&noise, WhiteNoise);
+    tCycle_init(&sine);
+    tCycle_setFreq(&sine, 200);
     
     //Bandpass circuit 1
+    //use c1 for output voltage
 //    tWDF_init(&r1, Resistor, 10000.0f, NULL, NULL);
 //    tWDF_init(&r2, Resistor, 10000.0f, NULL, NULL);
 //    tWDF_init(&c1, Capacitor, 0.000000159154943f, NULL, NULL);
@@ -46,25 +52,35 @@
 //    tWDF_init(&s2, SeriesAdaptor, 0.0f, &s1, &p1);
     
     //Bandpass circuit 2
+//    tWDF_init(&r1, Resistor, 10000.0f, NULL, NULL);
+//    tWDF_init(&c1, Capacitor, 0.000000159154943f, NULL, NULL);
+//    tWDF_init(&s1, SeriesAdaptor, 0.0f, &c1, &r1);
+//    tWDF_init(&r2, Resistor, 10000.0f, NULL, NULL);
+//    tWDF_init(&p1, ParallelAdaptor, 10000.0f, &s1, &r2);
+//    tWDF_init(&c2, Capacitor, 0.000000159154943f, NULL, NULL);
+//    tWDF_init(&s2, SeriesAdaptor, 0.0f, &c2, &p1);
+    
+//    tWDF_setOutputPoint(&s2, &c1);
+    
+//    tWDFNonlinear_init(&i, IdealSource, &s2);
+    
     tWDF_init(&r1, Resistor, 10000.0f, NULL, NULL);
-    tWDF_init(&c1, Capacitor, 0.000000159154943f, NULL, NULL);
-    tWDF_init(&s1, SeriesAdaptor, 0.0f, &c1, &r1);
-    tWDF_init(&r2, Resistor, 10000.0f, NULL, NULL);
-    tWDF_init(&p1, ParallelAdaptor, 10000.0f, &s1, &r2);
-    tWDF_init(&c2, Capacitor, 0.000000159154943f, NULL, NULL);
-    tWDF_init(&s2, SeriesAdaptor, 0.0f, &c2, &p1);
-
+    tWDF_init(&rs1, ResistiveSource, 0.0f, NULL, NULL);
+    tWDF_init(&s1, SeriesAdaptor, 0.0f, &r1, &rs1);
     
-    tWDF_setOutputPoint(&s2, &c1);
+    tWDF_setOutputPoint(&s1, &r1);
     
+    tWDFNonlinear_init(&d, Diode, &r1);
+    
     leaf_pool_report();
 }
 
 float   LEAFTest_tick            (float input)
 {
-    float sample = tNoise_tick(&noise);
+    float sample = tCycle_tick(&sine);
     
-    sample = tWDF_tick(&s2, sample, 1);
+    tWDF_setValue(&rs1, sample*gain);
+    sample = tWDF_tick(&s1, &d, sample, 1);
     
     return sample;
 }
@@ -80,9 +96,9 @@
     tWDF_setValue(&r1, val);
     
     val = getSliderValue("mod depth");
-    val = 1.0f + 10000.0f * val;
-    
-    tWDF_setValue(&r2, val);
+    val = 10.0f * val;
+    gain = val;
+    //tWDF_setValue(&r2, val);
 }
 
 void    LEAFTest_controllerInput (int cnum, float cval)