1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#pragma once
#include <gtest/gtest_prod.h>
#include <QList>
#include <QObject>
#include "control/controlvalue.h"
#include "engine/cachingreader/cachingreader.h"
#include "engine/effects/groupfeaturestate.h"
#include "engine/sync/syncable.h"
#include "preferences/usersettings.h"
#include "track/beats.h"
#include "track/track_decl.h"
class EngineMaster;
class EngineBuffer;
const int kNoTrigger = -1;
/**
* EngineControl is an abstract base class for objects which implement
* functionality pertaining to EngineBuffer. An EngineControl is meant to be a
* succinct implementation of a given EngineBuffer feature. Previously,
* EngineBuffer was an example of feature creep -- this is the result.
*
* When writing an EngineControl class, the following two properties hold:
*
* EngineControl::process will only be called during an EngineBuffer::process
* callback from the sound engine. This implies that any ControlObject accesses
* made in either of these methods are mutually exclusive, since one is
* exclusively in the call graph of the other.
*/
class EngineControl : public QObject {
Q_OBJECT
public:
EngineControl(const QString& group,
UserSettingsPointer pConfig);
~EngineControl() override;
// Called by EngineBuffer::process every latency period. See the above
// comments for information about guarantees that hold during this call. An
// EngineControl can perform any upkeep operations that are necessary during
// this call.
virtual void process(const double dRate,
const double dCurrentSample,
const int iBufferSize);
// hintReader allows the EngineControl to provide hints to the reader to
// indicate that the given portion of a song is a potential imminent seek
// target.
virtual void hintReader(HintVector* pHintList);
virtual void setEngineMaster(EngineMaster* pEngineMaster);
void setEngineBuffer(EngineBuffer* pEngineBuffer);
virtual void setCurrentSample(const double dCurrentSample,
const double dTotalSamples, const double dTrackSampleRate);
QString getGroup() const;
// Called to collect player features for effects processing.
virtual void collectFeatureState(GroupFeatureState* pGroupFeatures) const {
Q_UNUSED(pGroupFeatures);
}
// Called whenever a seek occurs to allow the EngineControl to respond.
virtual void notifySeek(double dNewPlaypos);
virtual void trackLoaded(TrackPointer pNewTrack);
virtual void trackBeatsUpdated(mixxx::BeatsPointer pBeats);
protected:
struct SampleOfTrack {
double current;
double total;
double rate;
};
SampleOfTrack getSampleOfTrack() const {
return m_sampleOfTrack.getValue();
}
void seek(double fractionalPosition);
void seekAbs(double sample);
// Seek to an exact sample and don't allow quantizing adjustment.
void seekExact(double sample);
// Returns an EngineBuffer to target for syncing. Returns nullptr if none found
EngineBuffer* pickSyncTarget();
UserSettingsPointer getConfig();
EngineMaster* getEngineMaster();
EngineBuffer* getEngineBuffer();
const QString m_group;
UserSettingsPointer m_pConfig;
private:
ControlValueAtomic<SampleOfTrack> m_sampleOfTrack;
EngineMaster* m_pEngineMaster;
EngineBuffer* m_pEngineBuffer;
friend class CueControlTest;
FRIEND_TEST(LoopingControlTest, ReloopToggleButton_DoesNotJumpAhead);
FRIEND_TEST(LoopingControlTest, ReloopAndStopButton);
FRIEND_TEST(LoopingControlTest, LoopScale_HalvesLoop);
FRIEND_TEST(LoopingControlTest, LoopMoveTest);
FRIEND_TEST(LoopingControlTest, LoopResizeSeek);
FRIEND_TEST(LoopingControlTest, Beatjump_JumpsByBeats);
};
|