fixing width
This commit is contained in:
parent
787f084b74
commit
ed79c8e3b9
1 changed files with 25 additions and 27 deletions
38
src/Gate.cpp
38
src/Gate.cpp
|
|
@ -294,59 +294,58 @@ void Gate::update() {
|
|||
// 1. EXIT EARLY IF OFF
|
||||
if (!state && !sticky) {
|
||||
lastOutVal = 0.0f;
|
||||
// Make sure we actually write 0 if we aren't sticky
|
||||
writeAnalog(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. LIVE WIDTH MODULATION
|
||||
// We calculate the 'stopTick' every frame.
|
||||
// IMPORTANT: Cap at 98% to ensure the gate has a "low" period before next beat.
|
||||
float effectiveWidth = (float)width + (widthMod * 100.0f);
|
||||
if (effectiveWidth > 98.0f) effectiveWidth = 98.0f;
|
||||
if (effectiveWidth < 1.0f) effectiveWidth = 1.0f;
|
||||
if (effectiveWidth > 100.0f) effectiveWidth = 100.0f;
|
||||
if (effectiveWidth < 0.0f) effectiveWidth = 0.0f;
|
||||
|
||||
uint32_t modulatedTicks = (uint32_t)((float)this->tickInterval * (effectiveWidth / 100.0f));
|
||||
if (modulatedTicks < 1) modulatedTicks = 1;
|
||||
|
||||
// This is our "Target" end point
|
||||
this->stopTick = startTick + modulatedTicks;
|
||||
|
||||
// 3. THE HARD SYNC (THE FIX)
|
||||
// If the Master Tick reached stopTick, kill the gate.
|
||||
// 3. THE HARD SYNC
|
||||
// Only kill the gate if width is strictly less than 100%
|
||||
if (effectiveWidth < 100.0f) {
|
||||
if (MASTER_TICK >= stopTick) {
|
||||
state = 0;
|
||||
// Don't reset lastTriggerTick here, otherwise turnOn() might re-fire
|
||||
// on the same tick that we just finished.
|
||||
if (!sticky) {
|
||||
lastOutVal = 0.0f;
|
||||
writeAnalog(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. HYBRID SMOOTHNESS MATH
|
||||
uint64_t now = time_us_64();
|
||||
// Ensure we don't underflow if now < last_clk_us (jitter)
|
||||
uint64_t usSinceLastTick = (now > last_clk_us) ? (now - last_clk_us) : 0;
|
||||
|
||||
double current_BPM_for_math = (double)filteredBPM;
|
||||
if (current_BPM_for_math < 1.0) current_BPM_for_math = 1.0;
|
||||
|
||||
double us_per_tick = 60000000.0 / (current_BPM_for_math * (double)PPQN);
|
||||
|
||||
float subTick = (float)usSinceLastTick / (float)us_per_tick;
|
||||
if (subTick > 0.98f) subTick = 0.98f;
|
||||
if (subTick > 0.99f) subTick = 0.99f;
|
||||
|
||||
// Calculate phase (0.0 to 1.0)
|
||||
// --- THE SINE WAVE FIX ---
|
||||
// If width is 100%, we calculate phase based on the WHOLE interval.
|
||||
// If width < 100%, we calculate phase based on the PULSE duration.
|
||||
float elapsedTicks = (float)(MASTER_TICK - startTick) + subTick;
|
||||
float totalDurationTicks = (float)(stopTick - startTick);
|
||||
float totalDurationTicks = (effectiveWidth >= 100.0f) ? (float)tickInterval : (float)(stopTick - startTick);
|
||||
|
||||
// Safety check for division by zero
|
||||
if (totalDurationTicks < 1.0f) totalDurationTicks = 1.0f;
|
||||
|
||||
float phase = elapsedTicks / totalDurationTicks;
|
||||
|
||||
// Keep phase looping if we are at 100% width (so LFOs/Sines keep moving)
|
||||
if (effectiveWidth >= 100.0f) {
|
||||
while (phase >= 1.0f) phase -= 1.0f;
|
||||
} else {
|
||||
if (phase > 1.0f) phase = 1.0f;
|
||||
}
|
||||
if (phase < 0.0f) phase = 0.0f;
|
||||
|
||||
// 5. WAVEFORM GENERATION
|
||||
|
|
@ -360,7 +359,7 @@ void Gate::update() {
|
|||
case EXP: outVal = expf(-5.0f * phase); break;
|
||||
case REXP: outVal = expf(5.0f * (phase - 1.0f)); break;
|
||||
case LOG: outVal = 1.0f - expf(-5.0f * phase); break;
|
||||
case SQUARE: outVal = 1.0f; break; // Square is simple ON
|
||||
case SQUARE: outVal = 1.0f; break;
|
||||
case BOUNCE: outVal = fabsf(sinf(phase * 3.14159265f * 2.0f)); break;
|
||||
case SIGMO: outVal = phase * phase * (3.0f - 2.0f * phase); break;
|
||||
case WOBBLE: outVal = expf(-3.0f * phase) * cosf(phase * 3.14159265f * 4.0f);
|
||||
|
|
@ -378,7 +377,6 @@ void Gate::update() {
|
|||
if (finalLevel > 1.0f) finalLevel = 1.0f;
|
||||
if (finalLevel < 0.0f) finalLevel = 0.0f;
|
||||
|
||||
// Use (uint16_t) cast to ensure the PWM driver gets a clean integer
|
||||
writeAnalog((uint16_t)(outVal * 1023.0f * finalLevel));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue