Final patch for logscales and knob with def ctors.

This commit is contained in:
Johannes Lorenz
2014-04-09 13:18:01 +02:00
3 changed files with 70 additions and 47 deletions

View File

@@ -60,7 +60,6 @@
class ControllerConnection;
#include <cstdio>
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<class T> 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<class T> void round_at(T &value, const T &where) const;
template<class T> void roundAt( T &value, const T &where ) const;
DataType m_dataType;

View File

@@ -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<class T> 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<class T> 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<class T> T AutomatableModel::logToLinearScale(T value) const
{
return ::logToLinearScale( minValue<float>(), maxValue<float>(), value );
}
//! @todo: this should be moved into a maths header
template<class T>
void roundAt( T& value, const T& where, const T& step_size )
{
if( qAbs<float>( value - where )
< typeInfo<float>::minEps() * qAbs<float>( step_size ) )
{
value = where;
}
}
template<class T>
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<float>(), maxValue<float>(),
// fit value into [0,1]:
: logToLinearScale(
// fits value into [0,1]:
(value - minValue<float>()) / maxValue<float>()
);
@@ -332,19 +363,6 @@ void AutomatableModel::setStep( const float step )
template<class T>
void AutomatableModel::round_at(T& value, const T& where) const
{
if( qAbs<float>( value - where )
< typeInfo<float>::minEps() * qAbs<float>( m_step ) )
{
value = where;
}
}
float AutomatableModel::fittedValue( float value ) const
{
value = tLimit<float>( 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<float>() + ( range() * controllerConnection()->currentValue( frameOffset ) );
break;
case Logarithmic:
v = log_to_linear_scale(minValue<float>(), maxValue<float>(),
v = logToLinearScale(
controllerConnection()->currentValue( frameOffset ));
break;
default:
qFatal("AutomatableModel::controllerValue(int)"
"lacks implementation for a scale type");
v = 0; // suppress warning...
break;
}
if( typeInfo<float>::isEqual( m_step, 1 ) )

View File

@@ -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: