diff options
author | Daniel Schürmann <daschuer@mixxx.org> | 2019-02-15 22:57:25 +0100 |
---|---|---|
committer | Daniel Schürmann <daschuer@mixxx.org> | 2019-02-15 22:57:25 +0100 |
commit | 2f882bd605f2fef18f9069e27f181bc67aea9ce0 (patch) | |
tree | 92524603ef02d226c9c12089d45aa5e4fc2aa959 /src/engine/controls/bpmcontrol.h | |
parent | 9335fadeea1f2f8271137c8337f512ab5e146f14 (diff) | |
parent | 15e11e24033382ff9bcc63c8a43333095741d846 (diff) |
Merge remote-tracking branch 'upstream/master' into lp1777667
Diffstat (limited to 'src/engine/controls/bpmcontrol.h')
-rw-r--r-- | src/engine/controls/bpmcontrol.h | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/engine/controls/bpmcontrol.h b/src/engine/controls/bpmcontrol.h new file mode 100644 index 0000000000..ad5e55a558 --- /dev/null +++ b/src/engine/controls/bpmcontrol.h @@ -0,0 +1,173 @@ +#ifndef BPMCONTROL_H +#define BPMCONTROL_H + +#include <gtest/gtest_prod.h> + +#include "control/controlobject.h" +#include "engine/controls/enginecontrol.h" +#include "engine/sync/syncable.h" +#include "util/tapfilter.h" + +class ControlObject; +class ControlLinPotmeter; +class ControlProxy; +class ControlPushButton; +class EngineBuffer; +class SyncControl; + +class BpmControl : public EngineControl { + Q_OBJECT + + public: + BpmControl(QString group, UserSettingsPointer pConfig); + ~BpmControl() override; + + double getBpm() const; + double getLocalBpm() const { return m_pLocalBpm ? m_pLocalBpm->get() : 0.0; } + // When in master sync mode, ratecontrol calls calcSyncedRate to figure out + // how fast the track should play back. The returned rate is usually just + // the correct pitch to match bpms. The usertweak argument represents + // how much the user is nudging the pitch to get two tracks into sync, and + // that value is added to the rate by bpmcontrol. The rate may be + // further adjusted if bpmcontrol discovers that the tracks have fallen + // out of sync. + double calcSyncedRate(double userTweak); + // Get the phase offset from the specified position. + double getNearestPositionInPhase(double dThisPosition, bool respectLoops, bool playing); + double getBeatMatchPosition(double dThisPosition, bool respectLoops, bool playing); + double getPhaseOffset(double dThisPosition); + double getBeatDistance(double dThisPosition) const; + + void setTargetBeatDistance(double beatDistance); + void setInstantaneousBpm(double instantaneousBpm); + void resetSyncAdjustment(); + double updateLocalBpm(); + double updateBeatDistance(); + + void collectFeatures(GroupFeatureState* pGroupFeatures) const; + + // Calculates contextual information about beats: the previous beat, the + // next beat, the current beat length, and the beat ratio (how far dPosition + // lies within the current beat). Returns false if a previous or next beat + // does not exist. NULL arguments are safe and ignored. + static bool getBeatContext(const BeatsPointer& pBeats, + const double dPosition, + double* dpPrevBeat, + double* dpNextBeat, + double* dpBeatLength, + double* dpBeatPercentage); + + // Alternative version that works if the next and previous beat positions + // are already known. + static bool getBeatContextNoLookup( + const double dPosition, + const double dPrevBeat, + const double dNextBeat, + double* dpBeatLength, + double* dpBeatPercentage); + + // Returns the shortest change in percentage needed to achieve + // target_percentage. + // Example: shortestPercentageChange(0.99, 0.01) == 0.02 + static double shortestPercentageChange(const double& current_percentage, + const double& target_percentage); + double calcRateRatio() const; + void trackLoaded(TrackPointer pNewTrack) override; + + private slots: + void slotFileBpmChanged(double); + void slotAdjustBeatsFaster(double); + void slotAdjustBeatsSlower(double); + void slotTranslateBeatsEarlier(double); + void slotTranslateBeatsLater(double); + void slotControlBeatSync(double); + void slotControlBeatSyncPhase(double); + void slotControlBeatSyncTempo(double); + void slotTapFilter(double,int); + void slotBpmTap(double); + void slotUpdateRateSlider(double v = 0.0); + void slotUpdateEngineBpm(double v = 0.0); + void slotUpdatedTrackBeats(); + void slotBeatsTranslate(double); + void slotBeatsTranslateMatchAlignment(double); + + private: + SyncMode getSyncMode() const { + return syncModeFromDouble(m_pSyncMode->get()); + } + inline bool isSynchronized() const { + return toSynchronized(getSyncMode()); + } + bool syncTempo(); + double calcSyncAdjustment(double my_percentage, bool userTweakingSync); + + friend class SyncControl; + + // ControlObjects that come from EngineBuffer + ControlProxy* m_pPlayButton; + QAtomicInt m_oldPlayButton; + ControlProxy* m_pReverseButton; + ControlProxy* m_pRateSlider; + ControlObject* m_pQuantize; + ControlProxy* m_pRateRange; + ControlProxy* m_pRateDir; + + // ControlObjects that come from QuantizeControl + QScopedPointer<ControlProxy> m_pNextBeat; + QScopedPointer<ControlProxy> m_pPrevBeat; + QScopedPointer<ControlProxy> m_pClosestBeat; + + // ControlObjects that come from LoopingControl + ControlProxy* m_pLoopEnabled; + ControlProxy* m_pLoopStartPosition; + ControlProxy* m_pLoopEndPosition; + + // The current loaded file's detected BPM + ControlObject* m_pFileBpm; + // The average bpm around the current playposition; + ControlObject* m_pLocalBpm; + ControlPushButton* m_pAdjustBeatsFaster; + ControlPushButton* m_pAdjustBeatsSlower; + ControlPushButton* m_pTranslateBeatsEarlier; + ControlPushButton* m_pTranslateBeatsLater; + + // The current effective BPM of the engine + ControlLinPotmeter* m_pEngineBpm; + + // Used for bpm tapping from GUI and MIDI + ControlPushButton* m_pButtonTap; + + // Button for sync'ing with the other EngineBuffer + ControlPushButton* m_pButtonSync; + ControlPushButton* m_pButtonSyncPhase; + ControlPushButton* m_pButtonSyncTempo; + + // Button that translates the beats so the nearest beat is on the current + // playposition. + ControlPushButton* m_pTranslateBeats; + // Button that translates beats to match another playing deck + ControlPushButton* m_pBeatsTranslateMatchAlignment; + + ControlProxy* m_pThisBeatDistance; + ControlValueAtomic<double> m_dSyncTargetBeatDistance; + ControlValueAtomic<double> m_dUserOffset; + QAtomicInt m_resetSyncAdjustment; + ControlProxy* m_pSyncMode; + + TapFilter m_tapFilter; // threadsave + + // used in the engine thread only + double m_dSyncInstantaneousBpm; + double m_dLastSyncAdjustment; + + // objects below are written from an engine worker thread + TrackPointer m_pTrack; + BeatsPointer m_pBeats; + + const QString m_sGroup; + + FRIEND_TEST(EngineSyncTest, UserTweakBeatDistance); +}; + + +#endif // BPMCONTROL_H |