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
|
#include "engine/clockcontrol.h"
#include "controlobject.h"
#include "configobject.h"
#include "cachingreader.h"
#include "engine/enginecontrol.h"
#include "controlobjectslave.h"
ClockControl::ClockControl(QString group, ConfigObject<ConfigValue>* pConfig)
: EngineControl(group, pConfig) {
m_pCOBeatActive = new ControlObject(ConfigKey(group, "beat_active"));
m_pCOBeatActive->set(0.0);
m_pCOSampleRate = new ControlObjectSlave("[Master]","samplerate");
}
ClockControl::~ClockControl() {
delete m_pCOBeatActive;
delete m_pCOSampleRate;
}
void ClockControl::trackLoaded(TrackPointer pTrack) {
// Clear on-beat control
m_pCOBeatActive->set(0.0);
// Disconnect any previously loaded track/beats
if (m_pTrack) {
disconnect(m_pTrack.data(), SIGNAL(beatsUpdated()),
this, SLOT(slotBeatsUpdated()));
}
m_pBeats.clear();
m_pTrack.clear();
if (pTrack) {
m_pTrack = pTrack;
m_pBeats = m_pTrack->getBeats();
connect(m_pTrack.data(), SIGNAL(beatsUpdated()),
this, SLOT(slotBeatsUpdated()));
}
}
void ClockControl::trackUnloaded(TrackPointer pTrack) {
Q_UNUSED(pTrack)
trackLoaded(TrackPointer());
}
void ClockControl::slotBeatsUpdated() {
if(m_pTrack) {
m_pBeats = m_pTrack->getBeats();
}
}
double ClockControl::process(const double dRate,
const double currentSample,
const double totalSamples,
const int iBuffersize) {
Q_UNUSED(totalSamples);
Q_UNUSED(iBuffersize);
double samplerate = m_pCOSampleRate->get();
// TODO(XXX) should this be customizable, or latency dependent?
const double blinkSeconds = 0.100;
// Multiply by two to get samples from frames. Interval is scaled linearly
// by the rate.
const double blinkIntervalSamples = 2.0 * samplerate * (1.0 * dRate) * blinkSeconds;
if (m_pBeats) {
double closestBeat = m_pBeats->findClosestBeat(currentSample);
double distanceToClosestBeat = fabs(currentSample - closestBeat);
m_pCOBeatActive->set(distanceToClosestBeat < blinkIntervalSamples / 2.0);
}
return kNoTrigger;
}
|