Merge branch 'stable-1.1'

Conflicts:
	src/core/AutomatableModel.cpp
This commit is contained in:
Vesa
2014-06-23 22:10:27 +03:00
9 changed files with 123 additions and 67 deletions

View File

@@ -176,7 +176,11 @@ public:
{
return castValue<T>( m_step );
}
//! @brief Returns value scaled with the scale type and min/max values of this model
float scaledValue( float value ) const;
//! @brief Returns value applied with the inverse of this model's scale type
float inverseScaledValue( float value ) const;
void setInitValue( const float value );
@@ -201,6 +205,10 @@ public:
{
setScaleType( setToTrue ? Logarithmic : Linear );
}
bool isScaleLogarithmic() const
{
return m_scaleType == Logarithmic;
}
void setStep( const float step );
@@ -238,16 +246,7 @@ public:
return "automatablemodel";
}
QString displayValue( const float val ) const
{
switch( m_dataType )
{
case Float: return QString::number( castValue<float>( val ) );
case Integer: return QString::number( castValue<int>( val ) );
case Bool: return QString::number( castValue<bool>( val ) );
}
return "0";
}
QString displayValue( const float val ) const;
bool hasLinkedModels() const
{

View File

@@ -22,10 +22,11 @@
*
*/
#ifndef _LMMS_CONSTANTS_H
#define _LMMS_CONSTANTS_H
#ifndef LMMS_CONSTANTS_H
#define LMMS_CONSTANTS_H
const float F_PI = 3.1415926535f;
const float F_E = 2.718281828459045f;
const float F_2PI = 2*F_PI;
const float F_PI_2 = F_PI*0.5;

View File

@@ -128,5 +128,40 @@ static inline double sinc( double _x )
}
//! @brief Exponential function that deals with negative bases
static inline float signedPowf( float v, float e )
{
return v < 0
? powf( -v, e ) * -1.0f
: powf( v, e );
}
//! @brief Scales @value from linear to logarithmic.
//! Value should be within [0,1]
static inline float logToLinearScale( float min, float max, float value )
{
if( min < 0 )
{
const float mmax = qMax( qAbs( min ), qAbs( max ) );
const float val = value * ( max - min ) + min;
return signedPowf( val / mmax, F_E ) * mmax;
}
return powf( value, F_E ) * ( max - min ) + min;
}
//! @brief Scales value from logarithmic to linear. Value should be in min-max range.
static inline float linearToLogScale( float min, float max, float value )
{
static const float EXP = 1.0f / F_E;
const float val = ( value - min ) / ( max - min );
if( min < 0 )
{
const float mmax = qMax( qAbs( min ), qAbs( max ) );
return signedPowf( value / mmax, EXP ) * mmax;
}
return powf( val, EXP ) * ( max - min ) + min;
}
#endif

View File

@@ -24,8 +24,8 @@
*
*/
#ifndef _LADSPA_CONTROL_DIALOG_H
#define _LADSPA_CONTROL_DIALOG_H
#ifndef LADSPA_CONTROL_DIALOG_H
#define LADSPA_CONTROL_DIALOG_H
#include "EffectControlDialog.h"

View File

@@ -22,8 +22,8 @@
*
*/
#ifndef _LADSPA_CONTROLS_H
#define _LADSPA_CONTROLS_H
#ifndef LADSPA_CONTROLS_H
#define LADSPA_CONTROLS_H
#include "EffectControls.h"
#include "LadspaControl.h"

View File

@@ -27,7 +27,7 @@
#include "AutomatableModel.h"
#include "AutomationPattern.h"
#include "ControllerConnection.h"
#include "lmms_math.h"
float AutomatableModel::s_copiedValue = 0;
@@ -283,25 +283,42 @@ void AutomatableModel::setValue( const float value )
//! @brief Scales @value from linear to logarithmic.
//! Value should be within [0,1]
//! @todo This should be moved into a maths header
template<class T> T logToLinearScale(T min, T max, T value)
template<class T> T AutomatableModel::logToLinearScale( T value ) const
{
return exp( ( log(max) - log(min) ) * value + log(min) );
return castValue<T>( ::logToLinearScale( minValue<float>(), maxValue<float>(), static_cast<float>( value ) ) );
}
float AutomatableModel::scaledValue( float value ) const
{
return m_scaleType == Linear
? value
: logToLinearScale<float>( ( value - minValue<float>() ) / m_range );
}
float AutomatableModel::inverseScaledValue( float value ) const
{
return m_scaleType == Linear
? value
: ::linearToLogScale( minValue<float>(), maxValue<float>(), value );
}
template<class T> T AutomatableModel::logToLinearScale(T value) const
QString AutomatableModel::displayValue( const float val ) const
{
return ::logToLinearScale( minValue<float>(), maxValue<float>(), value );
switch( m_dataType )
{
case Float: return QString::number( castValue<float>( scaledValue( val ) ) );
case Integer: return QString::number( castValue<int>( scaledValue( val ) ) );
case Bool: return QString::number( castValue<bool>( scaledValue( val ) ) );
}
return "0";
}
//! @todo: this should be moved into a maths header
template<class T>
void roundAt( T& value, const T& where, const T& step_size )
@@ -331,15 +348,9 @@ void AutomatableModel::setAutomatedValue( const float value )
++m_setValueDepth;
const float oldValue = m_value;
const float scaledValue =
( m_scaleType == Linear )
? value
: logToLinearScale(
// fits value into [0,1]:
(value - minValue<float>()) / maxValue<float>()
);
const float scaled_value = scaledValue( value );
m_value = fittedValue( scaledValue );
m_value = fittedValue( scaled_value );
if( oldValue != m_value )
{
@@ -351,9 +362,7 @@ void AutomatableModel::setAutomatedValue( const float value )
!(*it)->fittedValue( m_value ) !=
(*it)->m_value )
{
// @TOBY: don't take m_value, but better: value,
// otherwise, we convert to log twice?
(*it)->setAutomatedValue( m_value );
(*it)->setAutomatedValue( value );
}
}
emit dataChanged();
@@ -703,14 +712,8 @@ float AutomatableModel::globalAutomationValueAt( const MidiTime& time )
{
// scale/fit the value appropriately and return it
const float value = latestPattern->valueAt( time - latestPattern->startPosition() );
const float scaledValue =
( m_scaleType == Linear )
? value
: logToLinearScale(
// fits value into [0,1]:
(value - minValue<float>()) / maxValue<float>()
);
return fittedValue( scaledValue );
const float scaled_value = scaledValue( value );
return fittedValue( scaled_value );
}
// if we still find no pattern, the value at that time is undefined so
// just return current value as the best we can do

View File

@@ -76,7 +76,7 @@ LadspaControl::LadspaControl( Model * _parent, port_desc_t * _port,
( m_port->max - m_port->min )
/ ( m_port->name.toUpper() == "GAIN"
&& m_port->max == 10.0f ? 4000.0f :
400.0f ) );
( m_port->suggests_logscale ? 8000.0f : 800.0f ) ) );
m_knobModel.setInitValue( m_port->def );
connect( &m_knobModel, SIGNAL( dataChanged() ),
this, SLOT( knobChanged() ) );
@@ -87,7 +87,7 @@ LadspaControl::LadspaControl( Model * _parent, port_desc_t * _port,
case TIME:
m_tempoSyncKnobModel.setRange( m_port->min, m_port->max,
( m_port->max -
m_port->min ) / 400.0f );
m_port->min ) / 800.0f );
m_tempoSyncKnobModel.setInitValue( m_port->def );
connect( &m_tempoSyncKnobModel, SIGNAL( dataChanged() ),
this, SLOT( tempoKnobChanged() ) );

View File

@@ -1359,7 +1359,8 @@ inline void AutomationEditor::drawCross( QPainter & _p )
QPoint tt_pos = QCursor::pos();
tt_pos.ry() -= 64;
tt_pos.rx() += 32;
QToolTip::showText( tt_pos,QString::number( level ),this);
float scaledLevel = m_pattern->firstObject()->scaledValue( level );
QToolTip::showText( tt_pos, QString::number( scaledLevel ), this );
}
@@ -1896,17 +1897,10 @@ float AutomationEditor::getLevel( int _y )
// pressed level
float level = roundf( ( m_bottomLevel + ( m_y_auto ?
( m_maxLevel - m_minLevel ) * ( level_line_y - _y )
/ (float)( level_line_y - TOP_MARGIN ) :
/ (float)( level_line_y - ( TOP_MARGIN + 2 ) ) :
( level_line_y - _y ) / (float)m_y_delta ) ) / m_step ) * m_step;
// some range-checking-stuff
if( level < m_bottomLevel )
{
level = m_bottomLevel;
}
else if( level > m_topLevel )
{
level = m_topLevel;
}
level = qBound( m_bottomLevel, level, m_topLevel );
return( level );
}

View File

@@ -34,8 +34,8 @@
#ifndef __USE_XOPEN
#define __USE_XOPEN
#endif
#include <math.h>
#include "lmms_math.h"
#include "knob.h"
#include "caption_menu.h"
#include "config_mgr.h"
@@ -320,7 +320,7 @@ bool knob::updateAngle()
int angle = 0;
if( model() && model()->maxValue() != model()->minValue() )
{
angle = angleFromValue( model()->value(), model()->minValue(), model()->maxValue(), m_totalAngle );
angle = angleFromValue( model()->inverseScaledValue( model()->value() ), model()->minValue(), model()->maxValue(), m_totalAngle );
}
if( qAbs( angle - m_angle ) > 3 )
{
@@ -388,7 +388,7 @@ void knob::drawKnob( QPainter * _p )
p.setRenderHint( QPainter::Antialiasing );
const int centerAngle = angleFromValue( model()->centerValue(), model()->minValue(), model()->maxValue(), m_totalAngle );
const int centerAngle = angleFromValue( model()->inverseScaledValue( model()->centerValue() ), model()->minValue(), model()->maxValue(), m_totalAngle );
const int arcLineWidth = 2;
const int arcRectSize = m_knobPixmap->width() - arcLineWidth;
@@ -669,15 +669,39 @@ void knob::setPosition( const QPoint & _p )
{
const float value = getValue( _p ) + m_leftOver;
const float step = model()->step<float>();
if( qAbs( value ) >= step )
const float oldValue = model()->value();
if( model()->isScaleLogarithmic() ) // logarithmic code
{
model()->setValue( model()->value() - value );
m_leftOver = 0.0f;
const float pos = model()->minValue() < 0
? oldValue / qMax( qAbs( model()->maxValue() ), qAbs( model()->minValue() ) )
: ( oldValue - model()->minValue() ) / model()->range();
const float ratio = 0.1f + qAbs( pos ) * 15.f;
float newValue = value * ratio;
if( qAbs( newValue ) >= step )
{
model()->setValue( oldValue - newValue );
m_leftOver = 0.0f;
}
else
{
m_leftOver = value;
}
}
else
else // linear code
{
m_leftOver = value;
if( qAbs( value ) >= step )
{
model()->setValue( oldValue - value );
m_leftOver = 0.0f;
}
else
{
m_leftOver = value;
}
}
}