diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index 4bca72891..4a1e6d2b5 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -60,7 +60,6 @@ class ControllerConnection; -#include class EXPORT AutomatableModel : public Model, public JournallingObject { Q_OBJECT @@ -182,12 +181,11 @@ public: void setRange( const float min, const float max, const float step = 1 ); void setScaleType( ScaleType sc ) { - printf("Settings scale to: %d\n", (int)sc); m_scaleType = sc; } - void setScaleLogarithmic( bool set_to_true = true ) + void setScaleLogarithmic( bool setToTrue = true ) { - setScaleType(set_to_true ? Logarithmic : Linear); + setScaleType( setToTrue ? Logarithmic : Linear ); } void setStep( const float step ); @@ -251,6 +249,10 @@ public slots: protected: + //! returns a value which is in range between min() and + //! max() and aligned according to the step size (step size 0.05 -> value + //! 0.12345 becomes 0.10 etc.). You should always call it at the end after + //! doing your own calculations. float fittedValue( float value ) const; @@ -268,9 +270,13 @@ private: void linkModel( AutomatableModel* model ); void unlinkModel( AutomatableModel* model ); + //! @brief Scales @value from linear to logarithmic. + //! Value should be within [0,1] + template T logToLinearScale( T value ) const; + //! rounds @a value to @a where if it is close to it //! @param value will be modified to rounded value - template void round_at(T &value, const T &where) const; + template void roundAt( T &value, const T &where ) const; DataType m_dataType; diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index 20f81229d..a647b3451 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -86,7 +86,7 @@ bool AutomatableModel::isAutomated() const void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, const QString& name ) { - bool automated_or_controlled = false; + bool automatedOrControlled = false; if( isAutomated() ) { @@ -97,7 +97,7 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co me.setAttribute( "value", m_value ); element.appendChild( me ); - automated_or_controlled = true; + automatedOrControlled = true; } else { @@ -126,14 +126,15 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co controllerElement.appendChild( element ); - automated_or_controlled = true; + automatedOrControlled = true; } - if(automated_or_controlled && (m_scaleType != Linear)) + if( automatedOrControlled && ( m_scaleType != Linear ) ) { // note: if we have more scale types than two, make // a mapper function enums <-> string - if(m_scaleType == Logarithmic) - element.setAttribute("scale_type", "log"); + if(m_scaleType == Logarithmic) { + element.setAttribute( "scale_type", "log" ); + } } } @@ -143,13 +144,14 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co void AutomatableModel::loadSettings( const QDomElement& element, const QString& name ) { // read scale type and overwrite default scale type - if(element.hasAttribute("scale_type")) // wrong in most cases + if( element.hasAttribute("scale_type") ) // wrong in most cases { - if(element.attribute("scale_type") == "log") - setScaleType(Logarithmic); + if( element.attribute("scale_type") == "log" ) + setScaleType( Logarithmic ); + } + else { + setScaleType( Linear ); } - else - setScaleType(Linear); // compat code QDomNode node = element.namedItem( AutomationPattern::classNodeName() ); @@ -246,11 +248,41 @@ void AutomatableModel::setValue( const float value ) //! @brief Scales @value from linear to logarithmic. //! Value should be within [0,1] -template T log_to_linear_scale(T min, T max, T value) -// we get min and max from the class => TODO +//! @todo This should be moved into a maths header +template T logToLinearScale(T min, T max, T value) { - printf("scale: in: %f, out: %f\n",value, exp((log(max)-log(min)) * value + log(min))); - return exp((log(max)-log(min)) * value + log(min)); + return exp( ( log(max) - log(min) ) * value + log(min) ); +} + + + + +template T AutomatableModel::logToLinearScale(T value) const +{ + return ::logToLinearScale( minValue(), maxValue(), value ); +} + + + + +//! @todo: this should be moved into a maths header +template +void roundAt( T& value, const T& where, const T& step_size ) +{ + if( qAbs( value - where ) + < typeInfo::minEps() * qAbs( step_size ) ) + { + value = where; + } +} + + + + +template +void AutomatableModel::roundAt( T& value, const T& where ) const +{ + ::roundAt(value, where, m_step); } @@ -262,11 +294,10 @@ void AutomatableModel::setAutomatedValue( const float value ) const float oldValue = m_value; const float scaled_value = - (m_scaleType == Linear) + ( m_scaleType == Linear ) ? value - : log_to_linear_scale( - minValue(), maxValue(), - // fit value into [0,1]: + : logToLinearScale( + // fits value into [0,1]: (value - minValue()) / maxValue() ); @@ -332,19 +363,6 @@ void AutomatableModel::setStep( const float step ) -template -void AutomatableModel::round_at(T& value, const T& where) const -{ - if( qAbs( value - where ) - < typeInfo::minEps() * qAbs( m_step ) ) - { - value = where; - } -} - - - - float AutomatableModel::fittedValue( float value ) const { value = tLimit( value, m_minValue, m_maxValue ); @@ -354,9 +372,9 @@ float AutomatableModel::fittedValue( float value ) const value = nearbyintf( value / m_step ) * m_step; } - round_at(value, m_maxValue); - round_at(value, m_minValue); - round_at(value, 0.0f); + roundAt( value, m_maxValue ); + roundAt( value, m_minValue ); + roundAt( value, 0.0f ); if( value < m_minValue ) { @@ -455,20 +473,19 @@ float AutomatableModel::controllerValue( int frameOffset ) const { if( m_controllerConnection ) { - float v; + float v = 0; switch(m_scaleType) { case Linear: v = minValue() + ( range() * controllerConnection()->currentValue( frameOffset ) ); break; case Logarithmic: - v = log_to_linear_scale(minValue(), maxValue(), + v = logToLinearScale( controllerConnection()->currentValue( frameOffset )); break; default: qFatal("AutomatableModel::controllerValue(int)" "lacks implementation for a scale type"); - v = 0; // suppress warning... break; } if( typeInfo::isEqual( m_step, 1 ) ) diff --git a/src/core/LadspaControl.cpp b/src/core/LadspaControl.cpp index 1b9e69393..8d31f55d6 100644 --- a/src/core/LadspaControl.cpp +++ b/src/core/LadspaControl.cpp @@ -55,7 +55,7 @@ LadspaControl::LadspaControl( Model * _parent, port_desc_t * _port, m_toggledModel.setValue( true ); } // TODO: careful: we must prevent saved scales - m_toggledModel.setScaleLogarithmic(m_port->suggests_logscale); + m_toggledModel.setScaleLogarithmic( m_port->suggests_logscale ); break; case INTEGER: @@ -68,7 +68,7 @@ LadspaControl::LadspaControl( Model * _parent, port_desc_t * _port, connect( &m_knobModel, SIGNAL( dataChanged() ), this, SLOT( knobChanged() ) ); // TODO: careful: we must prevent saved scales - m_knobModel.setScaleLogarithmic(m_port->suggests_logscale); + m_knobModel.setScaleLogarithmic( m_port->suggests_logscale ); break; case FLOATING: @@ -81,7 +81,7 @@ LadspaControl::LadspaControl( Model * _parent, port_desc_t * _port, connect( &m_knobModel, SIGNAL( dataChanged() ), this, SLOT( knobChanged() ) ); // TODO: careful: we must prevent saved scales - m_knobModel.setScaleLogarithmic(m_port->suggests_logscale); + m_knobModel.setScaleLogarithmic( m_port->suggests_logscale ); break; case TIME: @@ -92,7 +92,7 @@ LadspaControl::LadspaControl( Model * _parent, port_desc_t * _port, connect( &m_tempoSyncKnobModel, SIGNAL( dataChanged() ), this, SLOT( tempoKnobChanged() ) ); // TODO: careful: we must prevent saved scales - m_tempoSyncKnobModel.setScaleLogarithmic(m_port->suggests_logscale); + m_tempoSyncKnobModel.setScaleLogarithmic( m_port->suggests_logscale ); break; default: