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
|
/***************************************************************************
enginesync.h - master sync control for
maintaining beatmatching amongst n decks
-------------------
begin : Mon Mar 12 2012
copyright : (C) 2012 by Owen Williams
email : owilliams@mixxx.org
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#pragma once
#include "preferences/usersettings.h"
#include "engine/sync/syncable.h"
#include "engine/sync/basesyncablelistener.h"
/// EngineSync is the heart of the Mixxx Master Sync engine. It knows which objects
/// (Decks, Internal Clock, etc) are participating in Sync and what their statuses
/// are. It also orchestrates sync handoffs between different decks as they play,
/// stop, or request their status to change.
class EngineSync : public BaseSyncableListener {
public:
explicit EngineSync(UserSettingsPointer pConfig);
~EngineSync() override;
// Used by Syncables to tell EngineSync it wants to be enabled in a
// specific mode. If the state change is accepted, EngineSync calls
// Syncable::notifySyncModeChanged.
void requestSyncMode(Syncable* pSyncable, SyncMode state) override;
// Used by Syncables to tell EngineSync it wants to be enabled in any mode
// (master/follower).
void requestEnableSync(Syncable* pSyncable, bool enabled) override;
// Syncables notify EngineSync directly about various events. EngineSync
// does not have a say in whether these succeed or not, they are simply
// notifications.
void notifyBpmChanged(Syncable* pSyncable, double bpm) override;
void requestBpmUpdate(Syncable* pSyncable, double bpm) override;
void notifyInstantaneousBpmChanged(Syncable* pSyncable, double bpm) override;
void notifyBeatDistanceChanged(Syncable* pSyncable, double beatDistance) override;
void notifyPlaying(Syncable* pSyncable, bool playing) override;
void notifyScratching(Syncable* pSyncable, bool scratching) override;
// Used to pick a sync target for cases where master sync mode is not sufficient.
// Guaranteed to pick a Syncable that is a real deck and has an EngineBuffer,
// but can return nullptr if there are no choices.
// First choice is master sync, if it's a real deck,
// then it will fall back to the first playing syncable deck,
// then it will fall back to the first playing deck,
// then it will fall back to the first non-playing deck.
// If there is literally nothing loaded, returns nullptr.
Syncable* pickNonSyncSyncTarget(EngineChannel* pDontPick) const;
// Used to test whether changing the rate of a Syncable would change the rate
// of other Syncables that are playing
bool otherSyncedPlaying(const QString& group);
private:
// Iterate over decks, and based on sync and play status, pick a new master.
// if enabling_syncable is not null, we treat it as if it were enabled because we may
// be in the process of enabling it.
Syncable* pickMaster(Syncable* enabling_syncable);
// Find a deck to match against, used in the case where there is no sync master.
// Looks first for a playing deck, and falls back to the first non-playing deck.
// Returns nullptr if none can be found.
Syncable* findBpmMatchTarget(Syncable* requester);
// Activate a specific syncable as master.
void activateMaster(Syncable* pSyncable, bool explicitMaster);
// Activate a specific channel as Follower. Sets the syncable's bpm and
// beat_distance to match the master.
void activateFollower(Syncable* pSyncable);
// Unsets all sync state on a Syncable.
void deactivateSync(Syncable* pSyncable);
};
|