ref: e586373df54e57b080fb59c06b72ba1f50e975ff
parent: 72b60cd5518efcd33d3c99dfcee0bd463ec2c224
author: spiricom <jeff@snyderphonics.com>
date: Sat Feb 29 17:57:12 EST 2020
fixed issues with tPoly where stolen voices werent updated properly, and made tCycle capable of goings through zero in frequency so that proper FM is possible
binary files a/.DS_Store b/.DS_Store differ
binary files a/LEAF/.DS_Store b/LEAF/.DS_Store differ
--- a/LEAF/Inc/leaf-midi.h
+++ b/LEAF/Inc/leaf-midi.h
@@ -107,6 +107,8 @@
void tPoly_setPitchBend (tPoly* const, float pitchBend);
void tPoly_setPitchGlideActive (tPoly* const, oBool isActive);
void tPoly_setPitchGlideTime (tPoly* const, float t);
+ void tPoly_setBendGlideTime (tPoly* const polyh, float t);
+ void tPoly_setBendSamplesPerTick (tPoly* const polyh, float t);
void tPoly_tickPitch (tPoly* const);
void tPoly_tickPitchGlide (tPoly* const);
void tPoly_tickPitchBend (tPoly* const);
--- a/LEAF/Src/leaf-effects.c
+++ b/LEAF/Src/leaf-effects.c
@@ -254,15 +254,7 @@
v->pos = p0;
v->FX = fx;
- float den = 1.0e-10f; //(float)pow(10.0f, -10.0f * param[4]);
- if(fabs(v->d0) < den) v->d0 = 0.0f; //anti-denormal (doesn't seem necessary but P4?)
- if(fabs(v->d1) < den) v->d1 = 0.0f;
- if(fabs(v->d2) < den) v->d2 = 0.0f;
- if(fabs(v->d3) < den) v->d3 = 0.0f;
- if(fabs(v->u0) < den) v->u0 = 0.0f;
- if(fabs(v->u1) < den) v->u1 = 0.0f;
- if(fabs(v->u2) < den) v->u2 = 0.0f;
- if(fabs(v->u3) < den) v->u3 = 0.0f;
+
return o;
}
--- a/LEAF/Src/leaf-envelopes.c
+++ b/LEAF/Src/leaf-envelopes.c
@@ -399,7 +399,7 @@
adsr->attackInc = adsr->inc_buff[attackIndex];
}
-void tADSR_detDecay(tADSR* const adsrenv, float decay)
+void tADSR_setDecay(tADSR* const adsrenv, float decay)
{
_tADSR* adsr = *adsrenv;
@@ -657,14 +657,11 @@
r->curr += r->inc;
- if (((r->curr >= r->dest) && (r->inc > 0.0f)) || ((r->curr <= r->dest) && (r->inc < 0.0f)))
+ if (((r->curr >= r->dest) && (r->inc >= 0.0f)) || ((r->curr <= r->dest) && (r->inc < 0.0f)))
{
r->inc = 0.0f;
r->curr=r->dest;
}
-
- // Palle: There is a slight risk that you overshoot here and stay on dest+inc, which with a large inc value could be a real problem
- // I suggest you add: r->curr=r->dest in the true if case
return r->curr;
}
--- a/LEAF/Src/leaf-midi.c
+++ b/LEAF/Src/leaf-midi.c
@@ -425,7 +425,6 @@
tRamp_tick(&poly->pitchBendRamp);
}
-//instead of including in dacsend, should have a separate pitch bend ramp, that is added when the ramps are ticked and sent to DAC
void tPoly_setPitchBend(tPoly* const polyh, float pitchBend)
{
_tPoly* poly = *polyh;
@@ -480,7 +479,7 @@
whichVoice = poly->notes[whichNote][1];
if (whichVoice >= 0)
{
- poly->lastVoiceToChange = j;
+ poly->lastVoiceToChange = whichVoice;
int oldNote = poly->voices[whichVoice][0];
poly->voices[whichVoice][0] = note;
poly->voices[whichVoice][1] = vel;
@@ -488,7 +487,14 @@
poly->notes[note][0] = vel;
poly->notes[note][1] = whichVoice;
- tRamp_setTime(&poly->ramps[whichVoice], poly->glideTime);
+ if (poly->pitchGlideIsActive)
+ {
+ tRamp_setTime(&poly->ramps[whichVoice], poly->glideTime);
+ }
+ else
+ {
+ tRamp_setVal(&poly->ramps[whichVoice], note);
+ }
tRamp_setDest(&poly->ramps[whichVoice], poly->voices[whichVoice][0]);
alteredVoice = whichVoice;
@@ -546,6 +552,14 @@
if (poly->notes[noteToTest][1] < 0) //if there is a stolen note waiting (marked inactive but on the stack)
{
poly->voices[deactivatedVoice][0] = noteToTest; //set the newly free voice to use the old stolen note
+ if (poly->pitchGlideIsActive)
+ {
+ tRamp_setTime(&poly->ramps[deactivatedVoice], poly->glideTime);
+ }
+ else
+ {
+ tRamp_setVal(&poly->ramps[deactivatedVoice], noteToTest);
+ }
tRamp_setDest(&poly->ramps[deactivatedVoice], poly->voices[deactivatedVoice][0]);
poly->voices[deactivatedVoice][1] = poly->notes[noteToTest][0]; // set the velocity of the voice to be the velocity of that note
poly->notes[noteToTest][1] = deactivatedVoice; //mark that it is no longer stolen and is now active
@@ -616,6 +630,18 @@
{
tRamp_setTime(&poly->ramps[i], poly->glideTime);
}
+}
+
+void tPoly_setBendGlideTime(tPoly* const polyh, float t)
+{
+ _tPoly* poly = *polyh;
+ tRamp_setTime(&poly->pitchBendRamp, t);
+}
+
+void tPoly_setBendSamplesPerTick(tPoly* const polyh, float t)
+{
+ _tPoly* poly = *polyh;
+ poly->pitchBendRamp->samples_per_tick = t;
}
int tPoly_getNumVoices(tPoly* const polyh)
--- a/LEAF/Src/leaf-oscillators.c
+++ b/LEAF/Src/leaf-oscillators.c
@@ -25,6 +25,7 @@
c->inc = 0.0f;
c->phase = 0.0f;
+
}
void tCycle_free(tCycle* const cy)
@@ -41,6 +42,7 @@
c->inc = 0.0f;
c->phase = 0.0f;
+
}
void tCycle_freeFromPool (tCycle* const cy, tMempool* const mp)
@@ -55,8 +57,6 @@
{
_tCycle* c = *cy;
- if (freq < 0.0f) freq = 0.0f;
-
c->freq = freq;
c->inc = freq * leaf.invSampleRate;
@@ -63,22 +63,32 @@
return 0;
}
+//need to check bounds and wrap table properly to allow through-zero FM
float tCycle_tick(tCycle* const cy)
{
_tCycle* c = *cy;
+ float temp;;
+ int intPart;;
+ float fracPart;
+ float samp0;
+ float samp1;
// Phasor increment
c->phase += c->inc;
while (c->phase >= 1.0f) c->phase -= 1.0f;
-
+ while (c->phase <= 0.0f) c->phase += 1.0f;
+
// Wavetable synthesis
- float temp = SINE_TABLE_SIZE * c->phase;
- int intPart = (int)temp;
- float fracPart = temp - (float)intPart;
- float samp0 = sinewave[intPart];
- if (++intPart >= SINE_TABLE_SIZE) intPart = 0;
- float samp1 = sinewave[intPart];
+
+ temp = SINE_TABLE_SIZE * c->phase;
+ intPart = (int)temp;
+ fracPart = temp - (float)intPart;
+ samp0 = sinewave[intPart];
+ if (++intPart >= SINE_TABLE_SIZE) intPart = 0;
+ samp1 = sinewave[intPart];
+
return (samp0 + (samp1 - samp0) * fracPart);
+
}
void tCycleSampleRateChanged (tCycle* const cy)