diff --git a/include/AutomationPattern.h b/include/AutomationPattern.h index 391283bf2..62bf92d06 100644 --- a/include/AutomationPattern.h +++ b/include/AutomationPattern.h @@ -2,7 +2,7 @@ * AutomationPattern.h - declaration of class AutomationPattern, which contains * all information about an automation pattern * - * Copyright (c) 2008-2010 Tobias Doerffel + * Copyright (c) 2008-2013 Tobias Doerffel * Copyright (c) 2006-2008 Javier Serrano Polo * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -109,6 +109,8 @@ public slots: private: + void cleanObjects(); + AutomationTrack * m_autoTrack; QVector m_idsToResolve; objectVector m_objects; diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index 003f75856..6ec1ce319 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -2,7 +2,7 @@ * AutomationPattern.cpp - implementation of class AutomationPattern which * holds dynamic values * - * Copyright (c) 2008-2010 Tobias Doerffel + * Copyright (c) 2008-2013 Tobias Doerffel * Copyright (c) 2006-2008 Javier Serrano Polo * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -45,7 +45,6 @@ AutomationPattern::AutomationPattern( AutomationTrack * _auto_track ) : m_hasAutomation( false ) { changeLength( midiTime( 1, 0 ) ); - m_timeMap[0] = 0; } @@ -101,12 +100,6 @@ void AutomationPattern::addObject( AutomatableModel * _obj, bool _search_dup ) if( addIt ) { m_objects += _obj; - // been empty before? - if( m_objects.size() == 1 && !hasAutomation() ) - { - // then initialize default-value - putValue( 0, _obj->value(), false ); - } connect( _obj, SIGNAL( destroyed( jo_id_t ) ), this, SLOT( objectDestroyed( jo_id_t ) ), Qt::DirectConnection ); @@ -152,6 +145,8 @@ midiTime AutomationPattern::putValue( const midiTime & _time, const float _value, const bool _quant_pos ) { + cleanObjects(); + midiTime newTime = _quant_pos && engine::automationEditor() ? note::quantized( _time, engine::automationEditor()->quantization() ) : @@ -159,43 +154,7 @@ midiTime AutomationPattern::putValue( const midiTime & _time, m_timeMap[newTime] = _value; - if( newTime == 0 ) - { - for( objectVector::iterator it = m_objects.begin(); - it != m_objects.end(); ) - { - if( *it ) - { - ( *it )->setValue( _value ); - ++it; - } - else - { - it = m_objects.erase( it ); - } - } - } - - // just one automation value? - if( m_timeMap.size() == 1 ) - { - m_hasAutomation = m_objects.isEmpty(); // usually false - for( objectVector::iterator it = m_objects.begin(); - it != m_objects.end(); ++it ) - { - // default value differs from current value? - if( *it && _value != ( *it )->initValue() ) - { - // then enable automating this object - m_hasAutomation = true; - } - } - } - else - { - // in all other cases assume we have automation - m_hasAutomation = true; - } + m_hasAutomation = true; // we need to maximize our length in case we're part of a hidden // automation track as the user can't resize this pattern @@ -214,41 +173,22 @@ midiTime AutomationPattern::putValue( const midiTime & _time, void AutomationPattern::removeValue( const midiTime & _time ) { - if( _time != 0 ) + cleanObjects(); + + m_timeMap.remove( _time ); + + if( getTrack() && + getTrack()->type() == track::HiddenAutomationTrack ) { - m_timeMap.remove( _time ); - - if( m_timeMap.size() == 1 ) - { - const float val = m_timeMap[0]; - m_hasAutomation = false; - for( objectVector::iterator it = m_objects.begin(); - it != m_objects.end(); ) - { - if( *it ) - { - ( *it )->setValue( val ); - if( ( *it )->initValue() != val ) - { - m_hasAutomation = true; - } - ++it; - } - else - { - it = m_objects.erase( it ); - } - } - } - - if( getTrack() && - getTrack()->type() == track::HiddenAutomationTrack ) - { - changeLength( length() ); - } - - emit dataChanged(); + changeLength( length() ); } + + if( m_timeMap.isEmpty() ) + { + m_hasAutomation = false; + } + + emit dataChanged(); } @@ -260,10 +200,22 @@ float AutomationPattern::valueAt( const midiTime & _time ) const { return 0; } - timeMap::const_iterator v = m_timeMap.lowerBound( _time ); + + if( m_timeMap.contains( _time ) ) + { + return m_timeMap[_time]; + } + // lowerBound returns next value with greater key, therefore we take // the previous element to get the current value - return ( v != m_timeMap.begin() ) ? (v-1).value() : v.value(); + timeMap::ConstIterator v = m_timeMap.lowerBound( _time ); + + if( v == m_timeMap.begin() ) + { + return 0; + } + + return (v-1).value(); } @@ -326,17 +278,7 @@ void AutomationPattern::loadSettings( const QDomElement & _this ) } m_hasAutomation = m_timeMap.size() > 0; - if( m_hasAutomation == false ) - { - for( objectVector::iterator it = m_objects.begin(); - it != m_objects.end(); ++it ) - { - if( *it ) - { - ( *it )->setValue( m_timeMap[0] ); - } - } - } + int len = _this.attribute( "len" ).toInt(); if( len <= 0 ) { @@ -366,7 +308,7 @@ const QString AutomationPattern::name() const void AutomationPattern::processMidiTime( const midiTime & _time ) { - if( _time >= 0 && m_hasAutomation ) + if( _time >= 0 && hasAutomation() ) { const float val = valueAt( _time ); for( objectVector::iterator it = m_objects.begin(); @@ -502,9 +444,9 @@ void AutomationPattern::resolveAllIDs() void AutomationPattern::clear() { - const float val = firstObject()->value(); m_timeMap.clear(); - putValue( 0, val ); + + emit dataChanged(); if( engine::automationEditor() && engine::automationEditor()->currentPattern() == this ) @@ -537,6 +479,21 @@ void AutomationPattern::objectDestroyed( jo_id_t _id ) +void AutomationPattern::cleanObjects() +{ + for( objectVector::iterator it = m_objects.begin(); it != m_objects.end(); ) + { + if( *it ) + { + ++it; + } + else + { + it = m_objects.erase( it ); + } + } +} + #include "moc_AutomationPattern.cxx"