shithub: leaf

Download patch

ref: daea60c5d0a1be815d11368a236c9bdbe9e6bace
parent: 54e3a79a43f57c37f5756dc87fe8d6f4f53980e5
author: spiricom <jeff@snyderphonics.com>
date: Tue Mar 2 13:34:57 EST 2021

added tickEfficient for string2;

--- a/leaf/Inc/leaf-physical.h
+++ b/leaf/Inc/leaf-physical.h
@@ -559,6 +559,8 @@
     void    tLivingString2_free                  (tLivingString2* const);
     
     float   tLivingString2_tick                  (tLivingString2* const, float input);
+    float   tLivingString2_tickEfficient                 (tLivingString2* const, float input);
+    float   tLivingString2_udpateDelays(tLivingString2* const pl); //necessary if using tickEfficient (so that parameter setting can be put in a slower process). included in standard tick.
     float   tLivingString2_sample                (tLivingString2* const);
     void    tLivingString2_setFreq               (tLivingString2* const, float freq);
     void    tLivingString2_setWaveLength         (tLivingString2* const, float waveLength); // in samples
--- a/leaf/Src/leaf-analysis.c
+++ b/leaf/Src/leaf-analysis.c
@@ -259,10 +259,10 @@
     x->hopSize = period;
     x->blockSize = bs;
     
-    for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0;
+    for (i = 0; i < MAXOVERLAP; i++) x->x_sumbuf[i] = 0.0f;
     for (i = 0; i < npoints; i++)
-    x->buf[i] = (1.0f - cosf((2 * PI * i) / npoints))/npoints;
-    for (; i < npoints+INITVSTAKEN; i++) x->buf[i] = 0;
+    x->buf[i] = (1.0f - cosf((2.0f * PI * i) / npoints))/npoints;
+    for (; i < npoints+INITVSTAKEN; i++) x->buf[i] = 0.0f;
     
     x->x_f = 0;
     
@@ -317,7 +317,7 @@
         }
         *sump = sum;
     }
-    sump[0] = 0;
+    sump[0] = 0.0f;
     x->x_phase -= n;
     if (x->x_phase < 0)
     {
@@ -325,7 +325,7 @@
         for (count = x->x_realperiod, sump = x->x_sumbuf;
              count < x->x_npoints; count += x->x_realperiod, sump++)
         sump[0] = sump[1];
-        sump[0] = 0;
+        sump[0] = 0.0f;
         x->x_phase = x->x_realperiod - n;
     }
 }
--- a/leaf/Src/leaf-physical.c
+++ b/leaf/Src/leaf-physical.c
@@ -1003,6 +1003,87 @@
     return p->curr;
 }
 
+float   tLivingString2_tickEfficient(tLivingString2* const pl, float input)
+{
+    _tLivingString2* p = *pl;
+
+    input = input * 0.5f; // drop gain by half since we'll be equally adding it at half amplitude to forward and backward waveguides
+    // from prepPos upwards=forwards
+    //float pickupPos=tExpSmooth_tick(&p->puSmooth);
+    float wLen = p->wlSmooth->dest;
+
+    float pickP = p->ppSmooth->dest;
+
+    //need to determine which delay line to put it into (should be half amplitude into forward and backward lines for the correct portion of string)
+    float prepP = p->prpSmooth->dest;
+    float lowLen=p->prpSmooth->dest*p->wlSmooth->dest;
+    float upLen=(1.0f-p->prpSmooth->dest)*p->wlSmooth->dest;
+    uint32_t pickPInt;
+    if (pickP > prepP)
+    {
+        float fullPickPoint =  ((pickP*wLen) - lowLen);
+        pickPInt = (uint32_t) fullPickPoint; // where does the input go? that's the pick point
+
+        tHermiteDelay_addTo(&p->delUF, input, pickPInt);
+        tHermiteDelay_addTo(&p->delUB, input, (uint32_t) (upLen - pickPInt));
+    }
+    else
+    {
+        float fullPickPoint =  pickP * wLen;
+        pickPInt = (uint32_t) fullPickPoint; // where does the input go? that's the pick point
+
+        tHermiteDelay_addTo(&p->delLF, input, pickPInt);
+        tHermiteDelay_addTo(&p->delLB, input, (uint32_t) (lowLen - pickPInt));
+    }
+    float fromLF=tHermiteDelay_tickOut(&p->delLF);
+    float fromUF=tHermiteDelay_tickOut(&p->delUF);
+    float fromUB=tHermiteDelay_tickOut(&p->delUB);
+    float fromLB=tHermiteDelay_tickOut(&p->delLB);
+    // into upper half of string, from bridge, going backwards
+    //float fromBridge=-tFeedbackLeveler_tick(&p->fbLevU, (p->levMode==0?p->decay:1.0f)*tHighpass_tick(&p->DCblockerU, tTwoZero_tick(&p->bridgeFilter, fromUF)));
+    float fromBridge=-tFeedbackLeveler_tick(&p->fbLevU,tHighpass_tick(&p->DCblockerU, tTwoZero_tick(&p->bridgeFilter, fromUF)));
+    tHermiteDelay_tickIn(&p->delUB, fromBridge);
+    // into lower half of string, from prepPoint, going backwards
+    float fromLowerPrep=-tTwoZero_tick(&p->prepFilterL, fromLF);
+    float intoLower=(p->prepIndex*fromLowerPrep)+((1.0f - p->prepIndex)*fromUB); //used to add input here
+    tHermiteDelay_tickIn(&p->delLB, intoLower);
+    // into lower half of string, from nut
+    //float fromNut=-tFeedbackLeveler_tick(&p->fbLevL, (p->levMode==0?p->decay:1.0f)*tHighpass_tick(&p->DCblockerL, tTwoZero_tick(&p->nutFilter, fromLB)));
+    float fromNut=-tFeedbackLeveler_tick(&p->fbLevL,tHighpass_tick(&p->DCblockerL, tTwoZero_tick(&p->nutFilter, fromLB)));
+    tHermiteDelay_tickIn(&p->delLF, fromNut);
+    // into upper half of string, from prepPoint, going forwards/upwards
+    float fromUpperPrep=-tTwoZero_tick(&p->prepFilterU, fromUB);
+    float intoUpper=(p->prepIndex*fromUpperPrep)+((1.0f - p->prepIndex)*fromLF);
+    tHermiteDelay_tickIn(&p->delUF, intoUpper);
+    // update all delay lengths
+
+    p->curr = fromBridge;
+
+    //p->curr = fromBridge;
+    //p->curr += fromNut;
+
+    return p->curr;
+}
+
+float   tLivingString2_udpateDelays(tLivingString2* const pl)
+{
+    _tLivingString2* p = *pl;
+
+
+
+    //need to determine which delay line to put it into (should be half amplitude into forward and backward lines for the correct portion of string)
+
+    float lowLen=p->prpSmooth->dest*p->wlSmooth->dest;
+    float upLen=(1.0f-p->prpSmooth->dest)*p->wlSmooth->dest;
+
+
+
+	tHermiteDelay_setDelay(&p->delLF, lowLen);
+    tHermiteDelay_setDelay(&p->delLB, lowLen);
+    tHermiteDelay_setDelay(&p->delUF, upLen);
+    tHermiteDelay_setDelay(&p->delUB, upLen);
+}
+
 float   tLivingString2_sample(tLivingString2* const pl)
 {
     _tLivingString2* p = *pl;
--- a/leaf/leaf-config.h
+++ b/leaf/leaf-config.h
@@ -59,7 +59,7 @@
 #define LEAF_USE_CMSIS 0
 
 //! Use stdlib malloc() and free() internally instead of LEAF's normal mempool behavior for when you want to avoid being limited to and managing mempool a fixed mempool size. Usage of all object remains essentially the same.
-#define LEAF_USE_DYNAMIC_ALLOCATION 1
+#define LEAF_USE_DYNAMIC_ALLOCATION 0
 
 //==============================================================================