#include <gtest/gtest.h>
#include <QtDebug>
#include <QScopedPointer>
#include "mixxxtest.h"
#include "control/controlobject.h"
#include "control/controlpushbutton.h"
#include "control/controlproxy.h"
#include "engine/controls/loopingcontrol.h"
#include "test/mockedenginebackendtest.h"
#include "util/memory.h"
// Due to rounding errors loop positions should be compared with EXPECT_NEAR instead of EXPECT_EQ.
// NOTE(uklotzde, 2017-12-10): The rounding errors currently only appeared with GCC 7.2.1.
constexpr double kLoopPositionMaxAbsError = 0.000000001;
class LoopingControlTest : public MockedEngineBackendTest {
public:
LoopingControlTest()
: kTrackLengthSamples(300000000) {
}
protected:
void SetUp() override {
MockedEngineBackendTest::SetUp();
m_pQuantizeEnabled = std::make_unique<ControlProxy>(m_sGroup1, "quantize");
m_pQuantizeEnabled->set(1.0);
m_pNextBeat = std::make_unique<ControlProxy>(m_sGroup1, "beat_next");
m_pNextBeat->set(-1);
m_pClosestBeat = std::make_unique<ControlProxy>(m_sGroup1, "beat_closest");
m_pClosestBeat->set(-1);
m_pTrackSamples = std::make_unique<ControlProxy>(m_sGroup1, "track_samples");
m_pTrackSamples->set(kTrackLengthSamples);
m_pButtonLoopIn = std::make_unique<ControlProxy>(m_sGroup1, "loop_in");
m_pButtonLoopOut = std::make_unique<ControlProxy>(m_sGroup1, "loop_out");
m_pButtonLoopExit = std::make_unique<ControlProxy>(m_sGroup1, "loop_exit");
m_pButtonReloopToggle = std::make_unique<ControlProxy>(m_sGroup1, "reloop_toggle");
m_pButtonReloopAndStop = std::make_unique<ControlProxy>(m_sGroup1, "reloop_andstop");
m_pButtonLoopDouble = std::make_unique<ControlProxy>(m_sGroup1, "loop_double");
m_pButtonLoopHalve = std::make_unique<ControlProxy>(m_sGroup1, "loop_halve");
m_pLoopEnabled = std::make_unique<ControlProxy>(m_sGroup1, "loop_enabled");
m_pLoopStartPoint = std::make_unique<ControlProxy>(m_sGroup1, "loop_start_position");
m_pLoopEndPoint = std::make_unique<ControlProxy>(m_sGroup1, "loop_end_position");
m_pLoopScale = std::make_unique<ControlProxy>(m_sGroup1, "loop_scale");
m_pButtonPlay = std::make_unique<ControlProxy>(m_sGroup1, "play");
m_pPlayPosition = std::make_unique<ControlProxy>(m_sGroup1, "playposition");
m_pButtonBeatMoveForward = std::make_unique<ControlProxy>(m_sGroup1, "loop_move_1_forward");
m_pButtonBeatMoveBackward = std::make_unique<ControlProxy>(m_sGroup1, "loop_move_1_backward");
m_pButtonBeatLoop2Activate = std::make_unique<ControlProxy>(m_sGroup1, "beatloop_2_activate");
m_pButtonBeatLoop4Activate = std::make_unique<ControlProxy>(m_sGroup1, "beatloop_4_activate");
m_pBeatLoop1Enabled = std::make_unique<ControlProxy>(m_sGroup1, "beatloop_1_enabled");
m_pBeatLoop2Enabled = std::make_unique<ControlProxy>(m_sGroup1, "beatloop_2_enabled");
m_pBeatLoop4Enabled = std::make_unique<ControlProxy>(m_sGroup1, "beatloop_4_enabled");
m_pBeatLoop64Enabled = std::make_unique<ControlProxy>(m_sGroup1, "beatloop_64_enabled");
m_pBeatLoop = std::make_unique<ControlProxy>(m_sGroup1, "beatloop");
m_pBeatLoopSize = std::make_unique<ControlProxy>(m_sGroup1, "beatloop_size");
m_pButtonBeatLoopActivate = std::make_unique<ControlProxy>(m_sGroup1, "beatloop_activate");
m_pBeatJumpSize = std::make_unique<ControlProxy>(m_sGroup1, "beatjump_size");
m_pButtonBeatJumpForward = std::make_unique<ControlProxy>(m_sGroup1, "beatjump_forward");
m_pButtonBeatJumpBackward = std::make_unique<ControlProxy>(m_sGroup1, "beatjump_backward");
m_pButtonBeatLoopRoll1Activate = std::make_unique<ControlProxy>(m_sGroup1, "beatlooproll_1_activate");
m_pButtonBeatLoopRoll2Activate = std::make_unique<ControlProxy>(m_sGroup1, "beatlooproll_2_activate");
m_pButtonBeatLoopRoll4Activate = std::make_unique<ControlProxy>(m_sGroup1, "beatlooproll_4_activate");
}
bool isLoopEnabled() {
return m_pLoopEnabled->get() > 0.0;
}
void seekToSampleAndProcess(double new_pos) {
m_pChannel1->getEngineBuffer()->queueNewPlaypos(new_pos, EngineBuffer::SEEK_STANDARD);