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
//==============================================================================