From 4b524b179b09e56ca34841e35ccb507aba6fd7f6 Mon Sep 17 00:00:00 2001 From: image-et-son Date: Sun, 27 Feb 2022 15:19:49 +0100 Subject: [PATCH] Performance improvements (for #67) and minor fixes (#111 and #112) --- common/potmux.c | 151 +++++++++++++++++++---------- common/potmux.h | 2 +- common/storage.c | 21 ++-- common/synth.c | 244 ++++++++++++++++++++++++++--------------------- 4 files changed, 248 insertions(+), 170 deletions(-) diff --git a/common/potmux.c b/common/potmux.c index 8323226..547ae3a 100644 --- a/common/potmux.c +++ b/common/potmux.c @@ -10,24 +10,78 @@ static const int8_t potBitDepth[POTMUX_POT_COUNT]= { - /*Mixer*/8, /*Cutoff*/12,/*Resonance*/8,/*FilEnvAmt*/10,/*FilRel*/8,/*FilSus*/10, - /*FilDec*/8,/*FilAtt*/8,/*AmpRel*/8,/*AmpSus*/10,/*AmpDec*/8,/*AmpAtt*/8, - /*Glide*/8,/*BPW*/10,/*MVol*/8,/*MTune*/12,/*PitchWheel*/12,0,0,0,0,0,/*ModWheel*/8, - /*Speed*/12,/*APW*/10,/*PModFilEnv*/10,/*LFOFreq*/10,/*PModOscB*/10,/*LFOAmt*/12,/*FreqB*/12,/*FreqA*/12,/*FreqBFine*/12 -}; + /*Mixer*/8, + /*Cutoff*/12, + /*Resonance*/8, + /*FilEnvAmt*/10, + /*FilRel*/8, + /*FilSus*/10, + /*FilDec*/8, + /*FilAtt*/8, + /*AmpRel*/8, + /*AmpSus*/10, + /*AmpDec*/8, + /*AmpAtt*/8, + /*Glide*/8, + /*BPW*/10, + /*MVol*/8, + /*MTune*/12, + /*PitchWheel*/12, + 0, + 0, + 0, + 0, + 0, + /*ModWheel*/8, + /*Speed*/12, + /*APW*/10, + /*PModFilEnv*/10, + /*LFOFreq*/10, + /*PModOscB*/10, + /*LFOAmt*/12, + /*FreqB*/12, + /*FreqA*/12, + /*FreqBFine*/12, -static const p600Pot_t priorityPots[6]= -{ - ppPitchWheel, ppMVol, ppFreqA, ppFreqB, - ppModWheel, - ppNone }; -static const p600Pot_t regularPots[23]= +static const int8_t response[POTMUX_POT_COUNT]= { - ppMixer, ppResonance, ppFilEnvAmt, ppGlide, ppBPW, ppAPW, ppPModFilEnv, ppLFOFreq, ppPModOscB, ppLFOAmt, ppSpeed, ppAmpRel, ppAmpSus, ppAmpDec, ppAmpAtt, ppFilAtt, ppFilDec, ppFilSus, ppFilRel, ppMTune, ppFreqBFine, ppCutoff, ppNone + /*Vol A*/6, + /*Cutoff*/4, + /*Resonance*/3, + /*Fil Env Amt*/6, + /*Filter Release */35, + /*Filter Sustain*/6, + /*Filter Decay*/35, + /*Filter Attack*/35, + /*Amp Release*/35, + /*Amp Sustain*/6, + /*Amp Decay*/35, + /*Amp Attack*/35, + /*Vol B*/6, + /*BPW*/7, + /*Master Vol*/6, + /*Master Tune*/11, + /*Pitch Bender*/3, + 0, + 0, + 0, + 0, + 0, + /*Mod Wheel*/3, + /*Data Dial*/8, + /*APW*/7, + /*Poly-Mod Env*/8, + /*Poly-Mod OSC B*/3, + /*LFO Frequency*/20, + /*LFO Amount*/6, + /*Frequeny B*/3, + /*Frequeny A*/3, + /*Frequency B Fine*/20, }; + static struct { uint32_t potChanged; @@ -35,7 +89,7 @@ static struct uint16_t pots[POTMUX_POT_COUNT]; uint8_t potExcited[POTMUX_POT_COUNT]; - uint8_t potExcitedCount[POTMUX_POT_COUNT]; + uint8_t potcounter[POTMUX_POT_COUNT]; int8_t currentRegularPot; int8_t lastChanged; int8_t lastInAction; @@ -50,7 +104,7 @@ static void updatePot(int8_t pot) uint16_t bit; if (pot<0) return; - + BLOCK_INT { // successive approximations using DAC and comparator @@ -74,7 +128,7 @@ static void updatePot(int8_t pot) for(i=0;i<=bitDepth;++i) { - dac_write(estimate); + dac_write(estimate); // let comparator get correct voltage (don't remove me!) CYCLE_WAIT(2); @@ -96,26 +150,31 @@ static void updatePot(int8_t pot) io_write(0x0a,0xff); CYCLE_WAIT(4); - + // suppress the bits beyond the measurement accuracy estimate&=badMask; // change detector cdv=estimate>>8; diff = abs(potmux.changeDetect[pot]-cdv); - if (potmux.lastInAction!=pot && potmux.potExcitedCount[pot]>0) potmux.potExcitedCount[pot]--; - potmux.potExcited[pot]=potmux.potExcitedCount[pot]>0?1:0; - if(diff>CHANGE_DETECT_THRESHOLD || potmux.potExcitedCount[pot]>0) + if (potmux.lastInAction!=pot) potmux.potExcited[pot]=0; + if(diff>CHANGE_DETECT_THRESHOLD || (potmux.potExcited[pot] && pot!=ppPitchWheel)) { potmux.changeDetect[pot]=cdv; potmux.potChanged|=(uint32_t)1<CHANGE_DETECT_THRESHOLD) potmux.potExcitedCount[pot]=10; // keep up excited state for some cycles only if change not too small - potmux.lastChanged=pot; // this is reset in every cycle + potmux.potExcited[pot]=1; + potmux.lastChanged=pot; // this is reset in every cycle, this is used to decide which value to show on the display potmux.lastInAction=pot; // this stays and is only reset for a change of mode } - if (estimate>=0xFC00) estimate=badMask; // choose max value above the threshold UINT16_t - CHANGE_DETECT_THRESHOLD - potmux.pots[pot]=estimate; + if (estimate>=0xFC00) + { + potmux.pots[pot]=badMask; // choose max value above the threshold UINT16_t - CHANGE_DETECT_THRESHOLD + } + else + { + potmux.pots[pot]=estimate; + } } } @@ -148,7 +207,6 @@ void potmux_resetChangedFull(void) for (i=0;i1400)?(pwPotValue-1400):0; - //outVal-=(outVal>>5); // extend the range by 2^11 - //return outVal; - return pwPotValue; -} - static void addWheelToTunedCVs(void) // this function is specific for the case in which there are only wheel changes. Could also be moved to inside wheel event... { uint16_t cva,cvb,cvf; @@ -408,15 +401,7 @@ static void computeTunedCVs(int8_t force, int8_t forceVoice) // division operation. // so instead of doing foo*=32768; foo/=factor; we precalculate // precalc=32768<<16/factor, and do foo*=precalc; foo>>=16; runtime. -/*static void precalcDeadband(struct deadband *d) -{ - uint16_t middleLow=d->middle-d->deadband; - uint16_t middleHigh=d->middle+d->deadband; - - d->precalcLow=HALF_RANGE_L/(middleLow-d->guard); - d->precalcHigh=HALF_RANGE_L/(FULL_RANGE-d->guard-middleHigh); -}*/ - +// when "rise" >0 then this is not a strict Deadband but rather als Slowband static void precalcDeadband(struct deadband *d) { uint16_t middleLow=d->middle-d->deadband; @@ -567,19 +552,27 @@ static void refreshModulationDelay(int8_t refreshTickCount) static void handleFinishedVoices(void) { - int8_t v; + int8_t v, waitFlag; + for(v=0; v=synth.modulationDelayStart+synth.modulationDelayTickCount) { elapsed=currentTick-(synth.modulationDelayStart+synth.modulationDelayTickCount); if(elapsed>=synth.modulationDelayTickCount) - dlyAmt=UINT16_MAX; + synth.dlyAmt=UINT16_MAX; else - dlyAmt=attackCurveLookup[(elapsed<<8)/synth.modulationDelayTickCount]; + synth.dlyAmt=attackCurveLookup[(elapsed<<8)/synth.modulationDelayTickCount]; } } +} + +static void refreshLfoSettings(void) +{ + lfoShape_t shape; + + shape=currentPreset.steppedParameters[spLFOShape]; + + lfo_setShape(&synth.lfo,shape); synth.lfoAmt=currentPreset.continuousParameters[cpLFOAmt]; synth.lfoAmt=(synth.lfoAmt>2; - } - else // VCA - { - ampLfoVal=synth.vibrato.output+(UINT16_MAX-(synth.vibrato.levelCV>>1)); - } if(currentPreset.steppedParameters[spLFOTargets]&mtVCO) { @@ -1400,13 +1425,16 @@ void synth_timerInterrupt(void) if(currentPreset.steppedParameters[spLFOTargets]&mtVCF) filterLfoVal=synth.lfo.output; + if(currentPreset.steppedParameters[spLFOTargets]&mtVCA) + { + ampLfoVal=scaleU16U16(ampLfoVal, synth.lfo.output+(UINT16_MAX-(synth.lfo.levelCV>>1))); + } + // global env computations - vf=currentPreset.continuousParameters[cpFilEnvAmt]; vf+=INT16_MIN; filEnvAmt=vf; - oscEnvAmt=0; if(currentPreset.steppedParameters[spPModFA]) { @@ -1435,7 +1463,6 @@ void synth_timerInterrupt(void) hz63=(frc&0x1c)==0; hz250=(frc&0x04)==0; - switch(frc&0x03) // 4 phases, each 500hz { case 0: @@ -1447,6 +1474,7 @@ void synth_timerInterrupt(void) // ticker inc ++currentTick; + break; case 1: @@ -1463,12 +1491,15 @@ void synth_timerInterrupt(void) // sync of the LFO using the clockBar counter synth.clockBar=(synth.clockBar+1)%0x9; // make sure the counter stays within the counter range, here 0...9 - if((seq_getMode(0)!=smOff || seq_getMode(1)!=smOff || arp_getMode()!=amOff) && currentPreset.steppedParameters[spLFOSync]!=0) + if (currentPreset.steppedParameters[spLFOSync]!=0) { - if ((synth.clockBar==8 && currentPreset.steppedParameters[spLFOSync]==7) || synth.clockBar==currentPreset.steppedParameters[spLFOSync]) + if(seq_getMode(0)!=smOff || seq_getMode(1)!=smOff || arp_getMode()!=amOff) { - synth.clockBar=0; - lfo_resetPhase(&synth.lfo); + if ((synth.clockBar==8 && currentPreset.steppedParameters[spLFOSync]==7) || synth.clockBar==currentPreset.steppedParameters[spLFOSync]) + { + synth.clockBar=0; + lfo_resetPhase(&synth.lfo); + } } } @@ -1499,20 +1530,17 @@ void synth_timerInterrupt(void) break; case 2: lfo_update(&synth.vibrato); - refreshPulseWidth(currentPreset.steppedParameters[spLFOTargets]&mtPW); - - if(currentPreset.steppedParameters[spLFOTargets]&mtVCA) + if (currentPreset.steppedParameters[spVibTarget]==0) // VCO { - // ampLfoVal=synth.lfo.output+(UINT16_MAX-(synth.lfo.levelCV>>1)); // original application. This is later scaled into pre-amp (pcAmp1) - sh_setCV(pcVolA,scaleU16U16(currentPreset.continuousParameters[cpVolA], synth.lfo.output+(UINT16_MAX-(synth.lfo.levelCV>>1))),SH_FLAG_IMMEDIATE); - sh_setCV(pcVolB,scaleU16U16(currentPreset.continuousParameters[cpVolB], synth.lfo.output+(UINT16_MAX-(synth.lfo.levelCV>>1))),SH_FLAG_IMMEDIATE); + synth.vibPitch=synth.vibrato.output>>2; + synth.vibAmp=UINT16_MAX; } - else + else // VCA { - sh_setCV(pcVolA,currentPreset.continuousParameters[cpVolA],SH_FLAG_IMMEDIATE); - sh_setCV(pcVolB,currentPreset.continuousParameters[cpVolB],SH_FLAG_IMMEDIATE); + synth.vibAmp=synth.vibrato.output+(UINT16_MAX-(synth.vibrato.levelCV>>1)); + synth.vibPitch=0; } - + refreshPulseWidth(currentPreset.steppedParameters[spLFOTargets]&mtPW); break; case 3: if(hz250) @@ -1528,13 +1556,13 @@ void synth_timerInterrupt(void) ++frc; // for performance measurement - /*frc2=(frc2+1)%0x07d0; // 1 second + // frc2=(frc2+1)%0x07d0; // 1 second //frc2=(frc2+1)%0x03e8; // 1/2 second //frc2=(frc2+1)%0x07d; // 1/16 second - if(frc2==0) + /*if(frc2==0) { - midi_sendThreeBytes(15,synth.updateCounter); + midi_sendThreeBytes(0,(uint16_t)synth.updateCounter); synth.updateCounter=0; }*/ }