Merge pull request #720 from diizy/master

Initial implementation for two additional methods in AutomatableModel, A...
This commit is contained in:
Tobias Doerffel
2014-05-18 15:15:49 +02:00
4 changed files with 112 additions and 0 deletions

View File

@@ -29,6 +29,7 @@
#include "JournallingObject.h"
#include "Model.h"
#include "MidiTime.h"
// simple way to map a property of a view to a model
@@ -239,6 +240,7 @@ public:
return m_hasLinkedModels;
}
float globalAutomationValueAt( const MidiTime& time );
public slots:
virtual void reset();

View File

@@ -152,6 +152,7 @@ public:
static bool isAutomated( const AutomatableModel * _m );
static QVector<AutomationPattern *> patternsForModel( const AutomatableModel * _m );
static AutomationPattern * globalAutomationPattern( AutomatableModel * _m );
static void resolveAllIDs();

View File

@@ -555,6 +555,70 @@ void AutomatableModel::pasteValue()
float AutomatableModel::globalAutomationValueAt( const MidiTime& time )
{
// get patterns that connect to this model
QVector<AutomationPattern *> patterns = AutomationPattern::patternsForModel( this );
if( patterns.isEmpty() )
{
// if no such patterns exist, return current value
return m_value;
}
else
{
// of those patterns:
// find the patterns which overlap with the miditime position
QVector<AutomationPattern *> patterns_in_range;
for( QVector<AutomationPattern *>::ConstIterator it = patterns.begin(); it != patterns.end(); it++ )
{
int s = ( *it )->startPosition();
int e = ( *it )->endPosition();
if( s <= time && e >= time ) { patterns_in_range += ( *it ); }
}
AutomationPattern * latest_pattern = NULL;
if( ! patterns_in_range.isEmpty() )
{
// if there are more than one overlapping patterns, just use the first one because
// multiple pattern behaviour is undefined anyway
latest_pattern = patterns_in_range[0];
}
else
// if we find no patterns at the exact miditime, we need to search for the last pattern before time and use that
{
int latest_position = 0;
for( QVector<AutomationPattern *>::ConstIterator it = patterns.begin(); it != patterns.end(); it++ )
{
int e = ( *it )->endPosition();
if( e <= time && e > latest_position )
{
latest_position = e;
latest_pattern = ( *it );
}
}
}
if( latest_pattern )
{
// scale/fit the value appropriately and return it
const float value = latest_pattern->valueAt( time );
const float scaled_value =
( m_scaleType == Linear )
? value
: logToLinearScale(
// fits value into [0,1]:
(value - minValue<float>()) / maxValue<float>()
);
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
else return m_value;
}
}
#include "moc_AutomatableModel.cxx"

View File

@@ -551,6 +551,51 @@ bool AutomationPattern::isAutomated( const AutomatableModel * _m )
}
/*! \brief returns a list of all the automation patterns everywhere that are connected to a specific model
* \param _m the model we want to look for
*/
QVector<AutomationPattern *> AutomationPattern::patternsForModel( const AutomatableModel * _m )
{
QVector<AutomationPattern *> patterns;
TrackContainer::TrackList l;
l += engine::getSong()->tracks();
l += engine::getBBTrackContainer()->tracks();
l += engine::getSong()->globalAutomationTrack();
// go through all tracks...
for( TrackContainer::TrackList::ConstIterator it = l.begin(); it != l.end(); ++it )
{
// we want only automation tracks...
if( ( *it )->type() == track::AutomationTrack ||
( *it )->type() == track::HiddenAutomationTrack )
{
// get patterns in those tracks....
const track::tcoVector & v = ( *it )->getTCOs();
// go through all the patterns...
for( track::tcoVector::ConstIterator j = v.begin(); j != v.end(); ++j )
{
AutomationPattern * a = dynamic_cast<AutomationPattern *>( *j );
// check that the pattern has automation
if( a && a->hasAutomation() )
{
// now check is the pattern is connected to the model we want by going through all the connections
// of the pattern
bool has_object = false;
for( objectVector::const_iterator k = a->m_objects.begin(); k != a->m_objects.end(); ++k )
{
if( *k == _m )
{
has_object = true;
}
}
// if the patterns is connected to the model, add it to the list
if( has_object ) { patterns += a; }
}
}
}
}
return patterns;
}