1 // playermanager.h 2 // Created 6/1/2010 by RJ Ryan (rryan@mit.edu) 3 4 #ifndef MIXER_PLAYERMANAGER_H 5 #define MIXER_PLAYERMANAGER_H 6 7 #include <QList> 8 #include <QMap> 9 #include <QMutex> 10 #include <QObject> 11 12 #include "analyzer/trackanalysisscheduler.h" 13 #include "preferences/usersettings.h" 14 #include "track/track_decl.h" 15 #include "util/parented_ptr.h" 16 #include "util/performancetimer.h" 17 18 class Auxiliary; 19 class BaseTrackPlayer; 20 class ControlObject; 21 class Deck; 22 class EffectsManager; 23 class EngineMaster; 24 class Library; 25 class Microphone; 26 class PreviewDeck; 27 class Sampler; 28 class SamplerBank; 29 class SoundManager; 30 class VisualsManager; 31 class ControlProxy; 32 33 // For mocking PlayerManager. 34 class PlayerManagerInterface { 35 public: 36 virtual ~PlayerManagerInterface() = default; 37 38 // Get a BaseTrackPlayer (i.e. a Deck or a Sampler) by its group 39 virtual BaseTrackPlayer* getPlayer(const QString& group) const = 0; 40 41 // Get the deck by its deck number. Decks are numbered starting with 1. 42 virtual Deck* getDeck(unsigned int player) const = 0; 43 44 // Returns the number of decks. 45 virtual unsigned int numberOfDecks() const = 0; 46 47 // Get the preview deck by its deck number. Preview decks are numbered 48 // starting with 1. 49 virtual PreviewDeck* getPreviewDeck(unsigned int libPreviewPlayer) const = 0; 50 51 // Returns the number of preview decks. 52 virtual unsigned int numberOfPreviewDecks() const = 0; 53 54 // Get the sampler by its number. Samplers are numbered starting with 1. 55 virtual Sampler* getSampler(unsigned int sampler) const = 0; 56 57 // Returns the number of sampler decks. 58 virtual unsigned int numberOfSamplers() const = 0; 59 }; 60 61 class PlayerManager : public QObject, public PlayerManagerInterface { 62 Q_OBJECT 63 public: 64 PlayerManager(UserSettingsPointer pConfig, 65 SoundManager* pSoundManager, 66 EffectsManager* pEffectsManager, 67 VisualsManager* pVisualsManager, 68 EngineMaster* pEngine); 69 ~PlayerManager() override; 70 71 // Add a deck to the PlayerManager 72 // (currently unused, kept for consistency with other types) 73 void addDeck(); 74 75 // Add number of decks according to configuration. 76 void addConfiguredDecks(); 77 78 // Add a sampler to the PlayerManager 79 void addSampler(); 80 81 // Load samplers from samplers.xml file in config directory 82 void loadSamplers(); 83 84 // Add a PreviewDeck to the PlayerManager 85 void addPreviewDeck(); 86 87 // Add a microphone to the PlayerManager 88 void addMicrophone(); 89 90 // Add an auxiliary input to the PlayerManager 91 void addAuxiliary(); 92 93 // Return the number of players. Thread-safe. 94 static unsigned int numDecks(); 95 numberOfDecks()96 unsigned int numberOfDecks() const override { 97 return numDecks(); 98 } 99 100 // Returns true if the group is a deck group. If index is non-NULL, 101 // populates it with the deck number (1-indexed). 102 static bool isDeckGroup(const QString& group, int* number=NULL); 103 104 // Returns true if the group is a sampler group. If index is non-NULL, 105 // populates it with the deck number (1-indexed). 106 static bool isSamplerGroup(const QString& group, int* number=nullptr); 107 108 // Returns true if the group is a preview deck group. If index is non-NULL, 109 // populates it with the deck number (1-indexed). 110 static bool isPreviewDeckGroup(const QString& group, int* number=NULL); 111 112 // Return the number of samplers. Thread-safe. 113 static unsigned int numSamplers(); 114 numberOfSamplers()115 unsigned int numberOfSamplers() const override { 116 return numSamplers(); 117 } 118 119 // Return the number of preview decks. Thread-safe. 120 static unsigned int numPreviewDecks(); 121 numberOfPreviewDecks()122 unsigned int numberOfPreviewDecks() const override { 123 return numPreviewDecks(); 124 } 125 126 // Get a BaseTrackPlayer (i.e. a Deck, Sampler or PreviewDeck) by its 127 // group. Auxiliaries and microphones are not players. 128 BaseTrackPlayer* getPlayer(const QString& group) const override; 129 130 // Get the deck by its deck number. Decks are numbered starting with 1. 131 Deck* getDeck(unsigned int player) const override; 132 133 PreviewDeck* getPreviewDeck(unsigned int libPreviewPlayer) const override; 134 135 // Get the sampler by its number. Samplers are numbered starting with 1. 136 Sampler* getSampler(unsigned int sampler) const override; 137 138 // Get the microphone by its number. Microphones are numbered starting with 1. 139 Microphone* getMicrophone(unsigned int microphone) const; 140 141 // Get the auxiliary by its number. Auxiliaries are numbered starting with 1. 142 Auxiliary* getAuxiliary(unsigned int auxiliary) const; 143 144 // Binds signals between PlayerManager and Library. The library 145 // must exist at least for the lifetime of this instance. 146 void bindToLibrary(Library* pLibrary); 147 148 // Returns the group for the ith sampler where i is zero indexed groupForSampler(int i)149 static QString groupForSampler(int i) { 150 DEBUG_ASSERT(i >= 0); 151 return QStringLiteral("[Sampler") + QString::number(i + 1) + ']'; 152 } 153 154 // Returns the group for the ith deck where i is zero indexed groupForDeck(int i)155 static QString groupForDeck(int i) { 156 DEBUG_ASSERT(i >= 0); 157 return QStringLiteral("[Channel") + QString::number(i + 1) + ']'; 158 } 159 160 // Returns the group for the ith PreviewDeck where i is zero indexed groupForPreviewDeck(int i)161 static QString groupForPreviewDeck(int i) { 162 DEBUG_ASSERT(i >= 0); 163 return QStringLiteral("[PreviewDeck") + QString::number(i + 1) + ']'; 164 } 165 166 // Returns the group for the ith Microphone where i is zero indexed groupForMicrophone(int i)167 static QString groupForMicrophone(int i) { 168 DEBUG_ASSERT(i >= 0); 169 // Before Mixxx had multiple microphone support the first microphone had 170 // the group [Microphone]. For backwards compatibility we keep it that 171 // way. 172 if (i > 0) { 173 return QStringLiteral("[Microphone") + QString::number(i + 1) + ']'; 174 } else { 175 return QStringLiteral("[Microphone]"); 176 } 177 } 178 179 // Returns the group for the ith Auxiliary where i is zero indexed groupForAuxiliary(int i)180 static QString groupForAuxiliary(int i) { 181 DEBUG_ASSERT(i >= 0); 182 return QStringLiteral("[Auxiliary") + QString::number(i + 1) + ']'; 183 } 184 185 static QAtomicPointer<ControlProxy> m_pCOPNumDecks; 186 static QAtomicPointer<ControlProxy> m_pCOPNumSamplers; 187 static QAtomicPointer<ControlProxy> m_pCOPNumPreviewDecks; 188 189 public slots: 190 // Slots for loading tracks into a Player, which is either a Sampler or a Deck 191 void slotLoadTrackToPlayer(TrackPointer pTrack, const QString& group, bool play = false); 192 void slotLoadToPlayer(const QString& location, const QString& group); 193 void slotCloneDeck(const QString& source_group, const QString& target_group); 194 195 // Slots for loading tracks to decks 196 void slotLoadTrackIntoNextAvailableDeck(TrackPointer pTrack); 197 // Loads the location to the deck. deckNumber is 1-indexed 198 void slotLoadToDeck(const QString& location, int deckNumber); 199 200 // Loads the location to the preview deck. previewDeckNumber is 1-indexed 201 void slotLoadToPreviewDeck(const QString& location, int previewDeckNumber); 202 // Slots for loading tracks to samplers 203 void slotLoadTrackIntoNextAvailableSampler(TrackPointer pTrack); 204 // Loads the location to the sampler. samplerNumber is 1-indexed 205 void slotLoadToSampler(const QString& location, int samplerNumber); 206 207 void slotChangeNumDecks(double v); 208 void slotChangeNumSamplers(double v); 209 void slotChangeNumPreviewDecks(double v); 210 void slotChangeNumMicrophones(double v); 211 void slotChangeNumAuxiliaries(double v); 212 213 private slots: 214 void slotAnalyzeTrack(TrackPointer track); 215 216 void onTrackAnalysisProgress(TrackId trackId, AnalyzerProgress analyzerProgress); 217 void onTrackAnalysisFinished(); 218 219 signals: 220 void loadLocationToPlayer(const QString& location, const QString& group); 221 222 // Emitted when the user tries to enable a microphone talkover control when 223 // there is no input configured. 224 void noMicrophoneInputConfigured(); 225 226 // Emitted when the user tries to enable an auxiliary master control when 227 // there is no input configured. 228 void noAuxiliaryInputConfigured(); 229 230 // Emitted when the user tries to enable deck passthrough when there is no 231 // input configured. 232 void noDeckPassthroughInputConfigured(); 233 234 // Emitted when the user tries to enable vinyl control when there is no 235 // input configured. 236 void noVinylControlInputConfigured(); 237 238 // Emitted when the number of decks changes. 239 void numberOfDecksChanged(int decks); 240 241 void trackAnalyzerProgress(TrackId trackId, AnalyzerProgress analyzerProgress); 242 void trackAnalyzerIdle(); 243 244 private: 245 TrackPointer lookupTrack(QString location); 246 // Must hold m_mutex before calling this method. Internal method that 247 // creates a new deck. 248 void addDeckInner(); 249 // Must hold m_mutex before calling this method. Internal method that 250 // creates a new sampler. 251 void addSamplerInner(); 252 // Must hold m_mutex before calling this method. Internal method that 253 // creates a new preview deck. 254 void addPreviewDeckInner(); 255 // Must hold m_mutex before calling this method. Internal method that 256 // creates a new microphone. 257 void addMicrophoneInner(); 258 // Must hold m_mutex before calling this method. Internal method that 259 // creates a new auxiliary. 260 void addAuxiliaryInner(); 261 262 // Used to protect access to PlayerManager state across threads. 263 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) 264 mutable QRecursiveMutex m_mutex; 265 #else 266 mutable QMutex m_mutex; 267 #endif 268 269 PerformanceTimer m_cloneTimer; 270 QString m_lastLoadedPlayer; 271 272 UserSettingsPointer m_pConfig; 273 SoundManager* m_pSoundManager; 274 EffectsManager* m_pEffectsManager; 275 VisualsManager* m_pVisualsManager; 276 EngineMaster* m_pEngine; 277 SamplerBank* m_pSamplerBank; 278 ControlObject* m_pCONumDecks; 279 ControlObject* m_pCONumSamplers; 280 ControlObject* m_pCONumPreviewDecks; 281 ControlObject* m_pCONumMicrophones; 282 ControlObject* m_pCONumAuxiliaries; 283 parented_ptr<ControlProxy> m_pAutoDjEnabled; 284 285 TrackAnalysisScheduler::Pointer m_pTrackAnalysisScheduler; 286 287 QList<Deck*> m_decks; 288 QList<Sampler*> m_samplers; 289 QList<PreviewDeck*> m_preview_decks; 290 QList<Microphone*> m_microphones; 291 QList<Auxiliary*> m_auxiliaries; 292 QMap<QString, BaseTrackPlayer*> m_players; 293 }; 294 295 #endif // MIXER_PLAYERMANAGER_H 296