From 03b38585bbe2e2f1a523d01a6d16d1b677a3536b Mon Sep 17 00:00:00 2001 From: Steve Lascos Date: Sat, 21 Apr 2018 20:17:03 -0400 Subject: [PATCH] Parameter automation cleanup --- src/LibBasicFunctions.h | 8 +-- src/common/ParameterAutomation.cpp | 79 +++++++++++------------------- src/effects/AudioEffectSOS.cpp | 8 +-- 3 files changed, 37 insertions(+), 58 deletions(-) diff --git a/src/LibBasicFunctions.h b/src/LibBasicFunctions.h index 140022f..381b2f8 100644 --- a/src/LibBasicFunctions.h +++ b/src/LibBasicFunctions.h @@ -328,8 +328,8 @@ public: NOT_CONFIGURED = 0, ///< Initial, unconfigured stage HOLD, ///< f(x) = constant LINEAR, ///< f(x) = x - EXPONENTIAL, ///< f(x) = e^x - LOGARITHMIC, ///< f(x) = ln(x) + EXPONENTIAL, ///< f(x) = exp(-k*x) + LOGARITHMIC, ///< f(x) = PARABOLIC, ///< f(x) = x^2 LOOKUP_TABLE ///< f(x) = lut(x) }; @@ -362,7 +362,9 @@ private: bool m_running = false; float m_currentValueX; ///< the current value of x in f(x) size_t m_duration; - float m_coeffs[3]; ///< some general coefficient storage + //float m_coeffs[3]; ///< some general coefficient storage + float m_slopeX; + float m_scaleY; bool m_positiveSlope = true; }; diff --git a/src/common/ParameterAutomation.cpp b/src/common/ParameterAutomation.cpp index f56ce99..649e356 100644 --- a/src/common/ParameterAutomation.cpp +++ b/src/common/ParameterAutomation.cpp @@ -28,6 +28,7 @@ namespace BALibrary { // ParameterAutomation /////////////////////////////////////////////////////////////////////////////// constexpr int LINEAR_SLOPE = 0; +constexpr float EXPONENTIAL_K = 5.0f; template ParameterAutomation::ParameterAutomation() @@ -65,10 +66,13 @@ void ParameterAutomation::reconfigure(T startValue, T endValue, size_t durati m_function = function; m_startValue = startValue; m_endValue = endValue; - m_currentValueX = static_cast(startValue); + m_currentValueX = 0.0f; m_duration = durationSamples; m_running = false; + float duration = m_duration / static_cast(AUDIO_BLOCK_SAMPLES); + m_slopeX = (1.0f / static_cast(duration)); + m_scaleY = abs(endValue - startValue); if (endValue >= startValue) { // value is increasing m_positiveSlope = true; @@ -76,46 +80,14 @@ void ParameterAutomation::reconfigure(T startValue, T endValue, size_t durati // value is decreasing m_positiveSlope = false; } - - float duration = m_duration / static_cast(AUDIO_BLOCK_SAMPLES); - - // Pre-compute any necessary coefficients - switch(m_function) { - case Function::EXPONENTIAL : - break; - case Function::LOGARITHMIC : - break; - case Function::PARABOLIC : - break; - case Function::LOOKUP_TABLE : - break; - - // Default will be same as LINEAR - case Function::HOLD : - m_coeffs[LINEAR_SLOPE] = (1.0f / static_cast(duration)); // convert duration from ms to sec - break; - case Function::LINEAR : - default : - // The number of parameter updates will be duration in samples divided by audio sample block size since - // we only update once per block. - m_coeffs[LINEAR_SLOPE] = static_cast(endValue - startValue) / duration; // convert duration from ms to sec - break; - } } template void ParameterAutomation::trigger() { - if (m_function == Function::HOLD) { - // The HOLD function will move currentValueX from 0 to 1.0 over the desired duration, - // but will always return the startValue. - m_currentValueX = 0.0f; - } else { - m_currentValueX = static_cast(m_startValue); - } + m_currentValueX = 0.0f; m_running = true; - //Serial.println("ParameterAutomation::trigger() called"); } template @@ -125,43 +97,44 @@ T ParameterAutomation::getNextValue() return m_startValue; } - if (m_function == Function::HOLD) { - // HOLD is treated as a special case - m_currentValueX += m_coeffs[LINEAR_SLOPE]; - if (m_currentValueX >= 1.0) { - m_running = false; - } - return m_startValue; - } + m_currentValueX += m_slopeX; + float value; switch(m_function) { case Function::EXPONENTIAL : - break; - case Function::LOGARITHMIC : + // f(x) = exp(-k*x) + value = 1.0f - expf(-EXPONENTIAL_K*m_currentValueX); break; case Function::PARABOLIC : + value = m_currentValueX*m_currentValueX; break; case Function::LOOKUP_TABLE : - break; case Function::LINEAR : default : - // output = m_currentValueX + slope - m_currentValueX += m_coeffs[LINEAR_SLOPE]; + value = m_currentValueX; break; } // Check if the automation is finished. - if ( ( m_positiveSlope && (m_currentValueX >= m_endValue)) || - (!m_positiveSlope && (m_currentValueX <= m_endValue)) ) { + if (m_currentValueX >= 1.0f) { + m_currentValueX = 0.0f; m_running = false; return m_endValue; + } + + float returnValue; + if (m_positiveSlope) { + returnValue = m_startValue + (m_scaleY*value); } else { - return static_cast(m_currentValueX); + returnValue = m_startValue - (m_scaleY*value); } +// Serial.println(String("Start/End values: ") + m_startValue + String(":") + m_endValue); +// Serial.print("Parameter m_currentValueX is "); Serial.println(m_currentValueX, 6); +// Serial.print("Parameter returnValue is "); Serial.println(returnValue, 6); + return returnValue; } // Template instantiation -//template class MyStack; template class ParameterAutomation; template class ParameterAutomation; template class ParameterAutomation; @@ -196,6 +169,7 @@ ParameterAutomationSequence::~ParameterAutomationSequence() template void ParameterAutomationSequence::setupParameter(int index, T startValue, T endValue, size_t durationSamples, typename ParameterAutomation::Function function) { + Serial.println("setupParameter() called"); m_paramArray[index]->reconfigure(startValue, endValue, durationSamples, function); m_currentIndex = 0; } @@ -203,6 +177,7 @@ void ParameterAutomationSequence::setupParameter(int index, T startValue, T e template void ParameterAutomationSequence::setupParameter(int index, T startValue, T endValue, float durationMilliseconds, typename ParameterAutomation::Function function) { + Serial.println("setupParameter() called"); m_paramArray[index]->reconfigure(startValue, endValue, durationMilliseconds, function); m_currentIndex = 0; } @@ -261,5 +236,7 @@ bool ParameterAutomationSequence::isFinished() // Template instantiation template class ParameterAutomationSequence; +template class ParameterAutomationSequence; +template class ParameterAutomationSequence; } diff --git a/src/effects/AudioEffectSOS.cpp b/src/effects/AudioEffectSOS.cpp index bd7ba33..06d9504 100644 --- a/src/effects/AudioEffectSOS.cpp +++ b/src/effects/AudioEffectSOS.cpp @@ -61,9 +61,9 @@ void AudioEffectSOS::enable(void) Serial.println(String("SOS Enabled with delay length ") + m_maxDelaySamples + String(" samples")); } m_delaySamples = m_maxDelaySamples; - m_inputGateAuto.setupParameter(GATE_OPEN_STAGE, 0.0f, 1.0f, 1000.0f, ParameterAutomation::Function::LINEAR); + m_inputGateAuto.setupParameter(GATE_OPEN_STAGE, 0.0f, 1.0f, 1000.0f, ParameterAutomation::Function::EXPONENTIAL); m_inputGateAuto.setupParameter(GATE_HOLD_STAGE, 1.0f, 1.0f, 1000.0f, ParameterAutomation::Function::HOLD); - m_inputGateAuto.setupParameter(GATE_CLOSE_STAGE, 1.0f, 0.0f, 1000.0f, ParameterAutomation::Function::LINEAR); + m_inputGateAuto.setupParameter(GATE_CLOSE_STAGE, 1.0f, 0.0f, 1000.0f, ParameterAutomation::Function::EXPONENTIAL); } void AudioEffectSOS::update(void) @@ -166,13 +166,13 @@ void AudioEffectSOS::gateOpenTime(float milliseconds) { // TODO - change the paramter automation to an automation sequence m_openTimeMs = milliseconds; - m_inputGateAuto.setupParameter(GATE_OPEN_STAGE, 0.0f, 1.0f, m_openTimeMs, ParameterAutomation::Function::LINEAR); + m_inputGateAuto.setupParameter(GATE_OPEN_STAGE, 0.0f, 1.0f, m_openTimeMs, ParameterAutomation::Function::EXPONENTIAL); } void AudioEffectSOS::gateCloseTime(float milliseconds) { m_closeTimeMs = milliseconds; - m_inputGateAuto.setupParameter(GATE_CLOSE_STAGE, 1.0f, 0.0f, m_closeTimeMs, ParameterAutomation::Function::LINEAR); + m_inputGateAuto.setupParameter(GATE_CLOSE_STAGE, 1.0f, 0.0f, m_closeTimeMs, ParameterAutomation::Function::EXPONENTIAL); } ////////////////////////////////////////////////////////////////////////