ref: ab2f66165913c6ea18e105ce5da7431fb21a2fbd
parent: 54e3a79a43f57c37f5756dc87fe8d6f4f53980e5
author: spiricom <jeff@snyderphonics.com>
date: Mon Mar 15 18:49:32 EDT 2021
added livingstring2_tickEfficient
--- a/leaf/Inc/leaf-physical.h
+++ b/leaf/Inc/leaf-physical.h
@@ -452,7 +452,7 @@
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
- /*!
+ /*!
@defgroup tlivingstring2 tLivingString2
@ingroup physical
@brief String model with preparation and pick position separated.
@@ -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
@@ -573,8 +575,6 @@
void tLivingString2_setLevStrength (tLivingString2* const, float levStrength);
void tLivingString2_setLevMode (tLivingString2* const, int levMode);
void tLivingString2_setSampleRate (tLivingString2* const, float sr);
-
-
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
--- 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;
@@ -1022,6 +1103,7 @@
tHighpass_setSampleRate(&p->DCblockerU, p->sampleRate);
tHighpass_setSampleRate(&p->DCblockerL, p->sampleRate);
}
+
//////////---------------------------