Skip to content

Commit

Permalink
Remove global automation feature
Browse files Browse the repository at this point in the history
  • Loading branch information
PhysSong committed Sep 16, 2024
1 parent ce7e44b commit 1903d6f
Show file tree
Hide file tree
Showing 8 changed files with 3 additions and 167 deletions.
2 changes: 0 additions & 2 deletions include/AutomatableModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,6 @@ class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject
return false;
}

float globalAutomationValueAt( const TimePos& time );

void setStrictStepSize( const bool b )
{
m_hasStrictStepSize = b;
Expand Down
1 change: 0 additions & 1 deletion include/AutomationClip.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ class LMMS_EXPORT AutomationClip : public Clip

static bool isAutomated( const AutomatableModel * _m );
static std::vector<AutomationClip*> clipsForModel(const AutomatableModel* _m);
static AutomationClip * globalAutomationClip( AutomatableModel * _m );
static void resolveAllIDs();

bool isRecording() const { return m_isRecording; }
Expand Down
7 changes: 0 additions & 7 deletions include/Song.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,6 @@ class LMMS_EXPORT Song : public TrackContainer

bpm_t getTempo();

AutomationTrack * globalAutomationTrack()
{
return m_globalAutomationTrack;
}

//TODO: Add Q_DECL_OVERRIDE when Qt4 is dropped
AutomatedValueMap automatedValuesAt(TimePos time, int clipNum = -1) const override;

Expand Down Expand Up @@ -457,8 +452,6 @@ private slots:

void setProjectFileName(QString const & projectFileName);

AutomationTrack * m_globalAutomationTrack;

IntModel m_tempoModel;
MeterModel m_timeSigModel;
int m_oldTicksPerBar;
Expand Down
87 changes: 2 additions & 85 deletions src/core/AutomatableModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,28 +178,6 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co

void AutomatableModel::loadSettings( const QDomElement& element, const QString& name )
{
// compat code
QDomNode node = element.namedItem( AutomationClip::classNodeName() );
if( node.isElement() )
{
node = node.namedItem( name );
if( node.isElement() )
{
AutomationClip * p = AutomationClip::globalAutomationClip( this );
p->loadSettings( node.toElement() );
setValue( p->valueAt( 0 ) );
// in older projects we sometimes have odd automations
// with just one value in - eliminate if necessary
if( !p->hasAutomation() )
{
delete p;
}
return;
}
// logscales were not existing at this point of time
// so they can be ignored
}

QDomNode connectionNode = element.namedItem( "connection" );
// reads controller connection
if( connectionNode.isElement() )
Expand Down Expand Up @@ -230,7 +208,7 @@ void AutomatableModel::loadSettings( const QDomElement& element, const QString&
// </ladspacontrols>
// element => there is automation data, or scaletype information

node = element.namedItem( name ); // maybe we have luck?
QDomNode node = element.namedItem( name ); // maybe we have luck?

// either: no node with name "name" found
// => look for nodes with attribute name="nodename"
Expand Down Expand Up @@ -703,67 +681,6 @@ void AutomatableModel::reset()
setValue( initValue<float>() );
}




float AutomatableModel::globalAutomationValueAt( const TimePos& time )
{
// get clips that connect to this model
auto clips = AutomationClip::clipsForModel(this);
if (clips.empty())
{
// if no such clips exist, return current value
return m_value;
}
else
{
// of those clips:
// find the clips which overlap with the time position
std::vector<AutomationClip*> clipsInRange;
for (const auto& clip : clips)
{
int s = clip->startPosition();
int e = clip->endPosition();
if (s <= time && e >= time) { clipsInRange.push_back(clip); }
}

AutomationClip * latestClip = nullptr;

if (!clipsInRange.empty())
{
// if there are more than one overlapping clips, just use the first one because
// multiple clip behaviour is undefined anyway
latestClip = clipsInRange[0];
}
else
// if we find no clips at the exact time, we need to search for the last clip before time and use that
{
int latestPosition = 0;

for (const auto& clip : clips)
{
int e = clip->endPosition();
if (e <= time && e > latestPosition)
{
latestPosition = e;
latestClip = clip;
}
}
}

if( latestClip )
{
// scale/fit the value appropriately and return it
const float value = latestClip->valueAt( time - latestClip->startPosition() );
const float scaled_value = scaledValue( value );
return fittedValue( scaled_value );
}
// if we still find no clip, the value at that time is undefined so
// just return current value as the best we can do
else return m_value;
}
}

void AutomatableModel::setUseControllerValue(bool b)
{
if (b)
Expand Down Expand Up @@ -816,4 +733,4 @@ QString BoolModel::displayValue( const float val ) const
}


} // namespace lmms
} // namespace lmms
24 changes: 0 additions & 24 deletions src/core/AutomationClip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1040,29 +1040,6 @@ std::vector<AutomationClip *> AutomationClip::clipsForModel(const AutomatableMod



AutomationClip * AutomationClip::globalAutomationClip(
AutomatableModel * _m )
{
AutomationTrack * t = Engine::getSong()->globalAutomationTrack();
for (const auto& clip : t->getClips())
{
auto a = dynamic_cast<AutomationClip*>(clip);
if( a )
{
for (const auto& object : a->m_objects)
{
if (object == _m) { return a; }
}
}
}

auto a = new AutomationClip(t);
a->addObject( _m, false );
return a;
}




void AutomationClip::resolveAllIDs()
{
Expand Down Expand Up @@ -1251,7 +1228,6 @@ std::vector<Track*> AutomationClip::combineAllTracks()

combinedTrackList.insert(combinedTrackList.end(), songTracks.begin(), songTracks.end());
combinedTrackList.insert(combinedTrackList.end(), patternStoreTracks.begin(), patternStoreTracks.end());
combinedTrackList.push_back(Engine::getSong()->globalAutomationTrack());

return combinedTrackList;
}
Expand Down
3 changes: 0 additions & 3 deletions src/core/MeterModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ void MeterModel::reset()
{
m_numeratorModel.setValue( 4 );
m_denominatorModel.setValue( 4 );

AutomationClip::globalAutomationClip( &m_numeratorModel )->clear();
AutomationClip::globalAutomationClip( &m_denominatorModel )->clear();
}


Expand Down
21 changes: 1 addition & 20 deletions src/core/Song.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ tick_t TimePos::s_ticksPerBar = DefaultTicksPerBar;

Song::Song() :
TrackContainer(),
m_globalAutomationTrack( dynamic_cast<AutomationTrack *>(
Track::create( Track::Type::HiddenAutomation,
this ) ) ),
m_tempoModel( DefaultTempo, MinTempo, MaxTempo, this, tr( "Tempo" ) ),
m_timeSigModel( this ),
m_oldTicksPerBar( DefaultTicksPerBar ),
Expand Down Expand Up @@ -129,7 +126,6 @@ Song::Song() :
Song::~Song()
{
m_playing = false;
delete m_globalAutomationTrack;
}


Expand Down Expand Up @@ -838,9 +834,7 @@ bpm_t Song::getTempo()

AutomatedValueMap Song::automatedValuesAt(TimePos time, int clipNum) const
{
auto trackList = TrackList{m_globalAutomationTrack};
trackList.insert(trackList.end(), tracks().begin(), tracks().end());
return TrackContainer::automatedValuesFromTracks(trackList, time, clipNum);
return TrackContainer::automatedValuesFromTracks(tracks(), time, clipNum);
}


Expand Down Expand Up @@ -901,12 +895,6 @@ void Song::clearProject()
// Clear the m_oldAutomatedValues AutomatedValueMap
m_oldAutomatedValues.clear();

AutomationClip::globalAutomationClip( &m_tempoModel )->clear();
AutomationClip::globalAutomationClip( &m_masterVolumeModel )->
clear();
AutomationClip::globalAutomationClip( &m_masterPitchModel )->
clear();

Engine::audioEngine()->doneChangeInModel();

if( getGUI() != nullptr && getGUI()->getProjectNotes() )
Expand Down Expand Up @@ -1079,12 +1067,6 @@ void Song::loadProject( const QString & fileName )

getTimeline(PlayMode::Song).setLoopEnabled(false);

if( !dataFile.content().firstChildElement( "track" ).isNull() )
{
m_globalAutomationTrack->restoreState( dataFile.content().
firstChildElement( "track" ) );
}

//Backward compatibility for LMMS <= 0.4.15
PeakController::initGetControllerBySetting();

Expand Down Expand Up @@ -1239,7 +1221,6 @@ bool Song::saveProjectFile(const QString & filename, bool withResources)

saveState( dataFile, dataFile.content() );

m_globalAutomationTrack->saveState( dataFile, dataFile.content() );
Engine::mixer()->saveState( dataFile, dataFile.content() );
if( getGUI() != nullptr )
{
Expand Down
25 changes: 0 additions & 25 deletions tests/src/tracks/AutomationTrackTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,31 +215,6 @@ private slots:
QCOMPARE(song->automatedValuesAt(TimePos::ticksPerBar() + 5)[&model], 0.5f);
}

void testGlobalAutomation()
{
using namespace lmms;

// Global automation should not have priority, see https://github.com/LMMS/lmms/issues/4268
// Tests regression caused by 75077f6200a5aee3a5821aae48a3b8466ed8714a
auto song = Engine::getSong();

auto globalTrack = song->globalAutomationTrack();
AutomationClip globalClip(globalTrack);

AutomationTrack localTrack(song);
AutomationClip localClip(&localTrack);

FloatModel model;
globalClip.setProgressionType(AutomationClip::ProgressionType::Discrete);
localClip.setProgressionType(AutomationClip::ProgressionType::Discrete);
globalClip.addObject(&model);
localClip.addObject(&model);
globalClip.putValue(0, 100.0f, false);
localClip.putValue(0, 50.0f, false);

QCOMPARE(song->automatedValuesAt(0)[&model], 50.0f);
}

};

QTEST_GUILESS_MAIN(AutomationTrackTest)
Expand Down

0 comments on commit 1903d6f

Please sign in to comment.