1 #include "engine/sync/basesyncablelistener.h"
2 
3 #include <QMetaType>
4 
5 #include "engine/sync/internalclock.h"
6 
7 namespace {
8 
9 const QString kInternalClockGroup = QStringLiteral("[InternalClock]");
10 
11 } // anonymous namespace
12 
BaseSyncableListener(UserSettingsPointer pConfig)13 BaseSyncableListener::BaseSyncableListener(UserSettingsPointer pConfig)
14         : m_pConfig(pConfig),
15           m_pInternalClock(new InternalClock(kInternalClockGroup, this)),
16           m_pMasterSyncable(nullptr) {
17     qRegisterMetaType<SyncMode>("SyncMode");
18     m_pInternalClock->setMasterBpm(124.0);
19 }
20 
~BaseSyncableListener()21 BaseSyncableListener::~BaseSyncableListener() {
22     // We use the slider value because that is never set to 0.0.
23     m_pConfig->set(ConfigKey("[InternalClock]", "bpm"), ConfigValue(
24         m_pInternalClock->getBpm()));
25     delete m_pInternalClock;
26 }
27 
addSyncableDeck(Syncable * pSyncable)28 void BaseSyncableListener::addSyncableDeck(Syncable* pSyncable) {
29     if (m_syncables.contains(pSyncable)) {
30         qDebug() << "BaseSyncableListener: already has" << pSyncable;
31         return;
32     }
33     m_syncables.append(pSyncable);
34 }
35 
onCallbackStart(int sampleRate,int bufferSize)36 void BaseSyncableListener::onCallbackStart(int sampleRate, int bufferSize) {
37     m_pInternalClock->onCallbackStart(sampleRate, bufferSize);
38 }
39 
onCallbackEnd(int sampleRate,int bufferSize)40 void BaseSyncableListener::onCallbackEnd(int sampleRate, int bufferSize) {
41     m_pInternalClock->onCallbackEnd(sampleRate, bufferSize);
42 }
43 
getMaster() const44 EngineChannel* BaseSyncableListener::getMaster() const {
45     return m_pMasterSyncable ? m_pMasterSyncable->getChannel() : nullptr;
46 }
47 
getSyncableForGroup(const QString & group)48 Syncable* BaseSyncableListener::getSyncableForGroup(const QString& group) {
49     foreach (Syncable* pSyncable, m_syncables) {
50         if (pSyncable->getGroup() == group) {
51             return pSyncable;
52         }
53     }
54     return nullptr;
55 }
56 
syncDeckExists() const57 bool BaseSyncableListener::syncDeckExists() const {
58     for (const auto& pSyncable : qAsConst(m_syncables)) {
59         if (pSyncable->isSynchronized() && pSyncable->getBaseBpm() > 0) {
60             return true;
61         }
62     }
63     return false;
64 }
65 
masterBpm() const66 double BaseSyncableListener::masterBpm() const {
67     if (m_pMasterSyncable) {
68         return m_pMasterSyncable->getBpm();
69     }
70     return m_pInternalClock->getBpm();
71 }
72 
masterBeatDistance() const73 double BaseSyncableListener::masterBeatDistance() const {
74     if (m_pMasterSyncable) {
75         return m_pMasterSyncable->getBeatDistance();
76     }
77     return m_pInternalClock->getBeatDistance();
78 }
79 
masterBaseBpm() const80 double BaseSyncableListener::masterBaseBpm() const {
81     if (m_pMasterSyncable) {
82         return m_pMasterSyncable->getBaseBpm();
83     }
84     return m_pInternalClock->getBaseBpm();
85 }
86 
setMasterBpm(Syncable * pSource,double bpm)87 void BaseSyncableListener::setMasterBpm(Syncable* pSource, double bpm) {
88     //qDebug() << "BaseSyncableListener::setMasterBpm" << pSource << bpm;
89     if (pSource != m_pInternalClock) {
90         m_pInternalClock->setMasterBpm(bpm);
91     }
92     foreach (Syncable* pSyncable, m_syncables) {
93         if (pSyncable == pSource ||
94                 !pSyncable->isSynchronized()) {
95             continue;
96         }
97         pSyncable->setMasterBpm(bpm);
98     }
99 }
100 
setMasterInstantaneousBpm(Syncable * pSource,double bpm)101 void BaseSyncableListener::setMasterInstantaneousBpm(Syncable* pSource, double bpm) {
102     if (pSource != m_pInternalClock) {
103         m_pInternalClock->setInstantaneousBpm(bpm);
104     }
105     foreach (Syncable* pSyncable, m_syncables) {
106         if (pSyncable == pSource ||
107                 !pSyncable->isSynchronized()) {
108             continue;
109         }
110         pSyncable->setInstantaneousBpm(bpm);
111     }
112 }
113 
setMasterBeatDistance(Syncable * pSource,double beat_distance)114 void BaseSyncableListener::setMasterBeatDistance(Syncable* pSource, double beat_distance) {
115     if (pSource != m_pInternalClock) {
116         m_pInternalClock->setMasterBeatDistance(beat_distance);
117     }
118     foreach (Syncable* pSyncable, m_syncables) {
119         if (pSyncable == pSource ||
120                 !pSyncable->isSynchronized()) {
121             continue;
122         }
123         pSyncable->setMasterBeatDistance(beat_distance);
124     }
125 }
126 
setMasterParams(Syncable * pSource,double beat_distance,double base_bpm,double bpm)127 void BaseSyncableListener::setMasterParams(Syncable* pSource, double beat_distance,
128                                            double base_bpm, double bpm) {
129     //qDebug() << "BaseSyncableListener::setMasterParams, source is" << pSource->getGroup() << beat_distance << base_bpm << bpm;
130     if (pSource != m_pInternalClock) {
131         m_pInternalClock->setMasterParams(beat_distance, base_bpm, bpm);
132     }
133     foreach (Syncable* pSyncable, m_syncables) {
134         if (pSyncable == pSource ||
135                 !pSyncable->isSynchronized()) {
136             continue;
137         }
138         pSyncable->setMasterParams(beat_distance, base_bpm, bpm);
139     }
140 }
141 
checkUniquePlayingSyncable()142 void BaseSyncableListener::checkUniquePlayingSyncable() {
143     int playing_sync_decks = 0;
144     Syncable* unique_syncable = nullptr;
145     foreach (Syncable* pSyncable, m_syncables) {
146         if (!pSyncable->isSynchronized()) {
147             continue;
148         }
149 
150         if (pSyncable->isPlaying()) {
151             if (playing_sync_decks > 0) {
152                 return;
153             }
154             unique_syncable = pSyncable;
155             ++playing_sync_decks;
156         }
157     }
158     if (playing_sync_decks == 1) {
159         unique_syncable->notifyOnlyPlayingSyncable();
160     }
161 }
162