Files
lmms/tests/src/tracks/AutomationTrackTest.cpp
Alexandre Almeida 55d361fb65 Rename TCO and related to Clip (#6226)
This PR renames

    TCO -> Clip
    Pattern -> MidiClip
    *TCO and *TCOView -> *Clip and *ClipView

The savefiles are not yet modified by this PR.
2022-01-14 05:45:21 +01:00

223 lines
6.4 KiB
C++

/*
* AutomationTrackTest.cpp
*
* Copyright (c) 2017 Lukas W <lukaswhl/at/gmail.com>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include "QTestSuite.h"
#include "QCoreApplication"
#include "AutomationClip.h"
#include "AutomationTrack.h"
#include "BBTrack.h"
#include "BBTrackContainer.h"
#include "DetuningHelper.h"
#include "InstrumentTrack.h"
#include "MidiClip.h"
#include "TrackContainer.h"
#include "Engine.h"
#include "Song.h"
class AutomationTrackTest : QTestSuite
{
Q_OBJECT
private slots:
void initTestCase()
{
}
void testClipLinear()
{
AutomationClip c(nullptr);
c.setProgressionType(AutomationClip::LinearProgression);
c.putValue(0, 0.0, false);
c.putValue(100, 1.0, false);
QCOMPARE(c.valueAt(0), 0.0f);
QCOMPARE(c.valueAt(25), 0.25f);
QCOMPARE(c.valueAt(50), 0.5f);
QCOMPARE(c.valueAt(75), 0.75f);
QCOMPARE(c.valueAt(100), 1.0f);
QCOMPARE(c.valueAt(150), 1.0f);
}
void testClipDiscrete()
{
AutomationClip c(nullptr);
c.setProgressionType(AutomationClip::DiscreteProgression);
c.putValue(0, 0.0, false);
c.putValue(100, 1.0, false);
QCOMPARE(c.valueAt(0), 0.0f);
QCOMPARE(c.valueAt(50), 0.0f);
QCOMPARE(c.valueAt(100), 1.0f);
QCOMPARE(c.valueAt(150), 1.0f);
}
void testClips()
{
FloatModel model;
auto song = Engine::getSong();
AutomationTrack track(song);
AutomationClip c1(&track);
c1.setProgressionType(AutomationClip::LinearProgression);
c1.putValue(0, 0.0, false);
c1.putValue(10, 1.0, false);
c1.movePosition(0);
c1.addObject(&model);
AutomationClip c2(&track);
c2.setProgressionType(AutomationClip::LinearProgression);
c2.putValue(0, 0.0, false);
c2.putValue(100, 1.0, false);
c2.movePosition(100);
c2.addObject(&model);
AutomationClip c3(&track);
c3.addObject(&model);
//XXX: Why is this even necessary?
c3.clear();
QCOMPARE(song->automatedValuesAt( 0)[&model], 0.0f);
QCOMPARE(song->automatedValuesAt( 5)[&model], 0.5f);
QCOMPARE(song->automatedValuesAt( 10)[&model], 1.0f);
QCOMPARE(song->automatedValuesAt( 50)[&model], 1.0f);
QCOMPARE(song->automatedValuesAt(100)[&model], 0.0f);
QCOMPARE(song->automatedValuesAt(150)[&model], 0.5f);
}
void testLengthRespected()
{
FloatModel model;
auto song = Engine::getSong();
AutomationTrack track(song);
AutomationClip c(&track);
c.setProgressionType(AutomationClip::LinearProgression);
c.addObject(&model);
c.putValue(0, 0.0, false);
c.putValue(100, 1.0, false);
c.changeLength(100);
QCOMPARE(song->automatedValuesAt( 0)[&model], 0.0f);
QCOMPARE(song->automatedValuesAt( 50)[&model], 0.5f);
QCOMPARE(song->automatedValuesAt(100)[&model], 1.0f);
c.changeLength(50);
QCOMPARE(song->automatedValuesAt( 0)[&model], 0.0f);
QCOMPARE(song->automatedValuesAt( 50)[&model], 0.5f);
QCOMPARE(song->automatedValuesAt(100)[&model], 0.5f);
}
void testInlineAutomation()
{
auto song = Engine::getSong();
InstrumentTrack* instrumentTrack =
dynamic_cast<InstrumentTrack*>(Track::create(Track::InstrumentTrack, song));
MidiClip* midiClip = dynamic_cast<MidiClip*>(instrumentTrack->createClip(0));
midiClip->changeLength(TimePos(4, 0));
Note* note = midiClip->addNote(Note(TimePos(4, 0)), false);
note->createDetuning();
DetuningHelper* dh = note->detuning();
auto clip = dh->automationClip();
clip->setProgressionType( AutomationClip::LinearProgression );
clip->putValue(TimePos(0, 0), 0.0);
clip->putValue(TimePos(4, 0), 1.0);
QCOMPARE(clip->valueAt(TimePos(0, 0)), 0.0f);
QCOMPARE(clip->valueAt(TimePos(1, 0)), 0.25f);
QCOMPARE(clip->valueAt(TimePos(2, 0)), 0.5f);
QCOMPARE(clip->valueAt(TimePos(4, 0)), 1.0f);
}
void testBBTrack()
{
auto song = Engine::getSong();
auto bbContainer = Engine::getBBTrackContainer();
BBTrack bbTrack(song);
Track* automationTrack = Track::create(Track::AutomationTrack, bbContainer);
QVERIFY(automationTrack->numOfClips());
AutomationClip* c1 = dynamic_cast<AutomationClip*>(automationTrack->getClip(0));
QVERIFY(c1);
FloatModel model;
c1->setProgressionType(AutomationClip::LinearProgression);
c1->putValue(0, 0.0, false);
c1->putValue(10, 1.0, false);
c1->addObject(&model);
QCOMPARE(bbContainer->automatedValuesAt( 0, bbTrack.index())[&model], 0.0f);
QCOMPARE(bbContainer->automatedValuesAt( 5, bbTrack.index())[&model], 0.5f);
QCOMPARE(bbContainer->automatedValuesAt(10, bbTrack.index())[&model], 1.0f);
QCOMPARE(bbContainer->automatedValuesAt(50, bbTrack.index())[&model], 1.0f);
BBTrack bbTrack2(song);
QCOMPARE(bbContainer->automatedValuesAt(5, bbTrack.index())[&model], 0.5f);
QVERIFY(! bbContainer->automatedValuesAt(5, bbTrack2.index()).size());
BBClip clip(&bbTrack);
clip.changeLength(TimePos::ticksPerBar() * 2);
clip.movePosition(0);
QCOMPARE(song->automatedValuesAt(0)[&model], 0.0f);
QCOMPARE(song->automatedValuesAt(5)[&model], 0.5f);
QCOMPARE(song->automatedValuesAt(TimePos::ticksPerBar() + 5)[&model], 0.5f);
}
void testGlobalAutomation()
{
// 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::DiscreteProgression);
localClip.setProgressionType(AutomationClip::DiscreteProgression);
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);
}
} AutomationTrackTest;
#include "AutomationTrackTest.moc"