From b8a1adaa55a357d2c3b55f2ce691f63c910ebcea Mon Sep 17 00:00:00 2001 From: ronso0 Date: Thu, 2 Nov 2023 12:32:38 +0100 Subject: [PATCH 1/8] BpmControl: use std::unique_ptr --- src/engine/controls/bpmcontrol.cpp | 116 +++++++++++++++-------------- src/engine/controls/bpmcontrol.h | 40 +++++----- 2 files changed, 81 insertions(+), 75 deletions(-) diff --git a/src/engine/controls/bpmcontrol.cpp b/src/engine/controls/bpmcontrol.cpp index aba923fcb71..e89ef9f1170 100644 --- a/src/engine/controls/bpmcontrol.cpp +++ b/src/engine/controls/bpmcontrol.cpp @@ -51,9 +51,9 @@ BpmControl::BpmControl(const QString& group, m_dSyncTargetBeatDistance.setValue(0.0); m_dUserOffset.setValue(0.0); - m_pPlayButton = new ControlProxy(group, "play", this); - m_pReverseButton = new ControlProxy(group, "reverse", this); - m_pRateRatio = new ControlProxy(group, "rate_ratio", this); + m_pPlayButton = std::make_unique(group, "play", this); + m_pReverseButton = std::make_unique(group, "reverse", this); + m_pRateRatio = std::make_unique(group, "rate_ratio", this); m_pRateRatio->connectValueChanged(this, &BpmControl::slotUpdateEngineBpm, Qt::DirectConnection); @@ -62,33 +62,46 @@ BpmControl::BpmControl(const QString& group, m_pPrevBeat.reset(new ControlProxy(group, "beat_prev")); m_pNextBeat.reset(new ControlProxy(group, "beat_next")); - m_pLoopEnabled = new ControlProxy(group, "loop_enabled", this); - m_pLoopStartPosition = new ControlProxy(group, "loop_start_position", this); - m_pLoopEndPosition = new ControlProxy(group, "loop_end_position", this); + m_pLoopEnabled = std::make_unique(group, "loop_enabled", this); + m_pLoopStartPosition = std::make_unique(group, "loop_start_position", this); + m_pLoopEndPosition = std::make_unique(group, "loop_end_position", this); - m_pLocalBpm = new ControlObject(ConfigKey(group, "local_bpm")); - m_pAdjustBeatsFaster = new ControlPushButton(ConfigKey(group, "beats_adjust_faster"), false); + m_pLocalBpm = std::make_unique(ConfigKey(group, "local_bpm")); + m_pAdjustBeatsFaster = std::make_unique( + ConfigKey(group, "beats_adjust_faster"), false); m_pAdjustBeatsFaster->setKbdRepeatable(true); - connect(m_pAdjustBeatsFaster, &ControlObject::valueChanged, - this, &BpmControl::slotAdjustBeatsFaster, + connect(m_pAdjustBeatsFaster.get(), + &ControlObject::valueChanged, + this, + &BpmControl::slotAdjustBeatsFaster, Qt::DirectConnection); - m_pAdjustBeatsSlower = new ControlPushButton(ConfigKey(group, "beats_adjust_slower"), false); + m_pAdjustBeatsSlower = std::make_unique( + ConfigKey(group, "beats_adjust_slower"), false); m_pAdjustBeatsSlower->setKbdRepeatable(true); - connect(m_pAdjustBeatsSlower, &ControlObject::valueChanged, - this, &BpmControl::slotAdjustBeatsSlower, + connect(m_pAdjustBeatsSlower.get(), + &ControlObject::valueChanged, + this, + &BpmControl::slotAdjustBeatsSlower, Qt::DirectConnection); - m_pTranslateBeatsEarlier = new ControlPushButton(ConfigKey(group, "beats_translate_earlier"), false); + m_pTranslateBeatsEarlier = std::make_unique( + ConfigKey(group, "beats_translate_earlier"), false); m_pTranslateBeatsEarlier->setKbdRepeatable(true); - connect(m_pTranslateBeatsEarlier, &ControlObject::valueChanged, - this, &BpmControl::slotTranslateBeatsEarlier, + connect(m_pTranslateBeatsEarlier.get(), + &ControlObject::valueChanged, + this, + &BpmControl::slotTranslateBeatsEarlier, Qt::DirectConnection); - m_pTranslateBeatsLater = new ControlPushButton(ConfigKey(group, "beats_translate_later"), false); + m_pTranslateBeatsLater = std::make_unique( + ConfigKey(group, "beats_translate_later"), false); m_pTranslateBeatsLater->setKbdRepeatable(true); - connect(m_pTranslateBeatsLater, &ControlObject::valueChanged, - this, &BpmControl::slotTranslateBeatsLater, + connect(m_pTranslateBeatsLater.get(), + &ControlObject::valueChanged, + this, + &BpmControl::slotTranslateBeatsLater, Qt::DirectConnection); - m_pTranslateBeatsMove = new ControlEncoder(ConfigKey(group, "beats_translate_move"), false); - connect(m_pTranslateBeatsMove, + m_pTranslateBeatsMove = std::make_unique( + ConfigKey(group, "beats_translate_move"), false); + connect(m_pTranslateBeatsMove.get(), &ControlObject::valueChanged, this, &BpmControl::slotTranslateBeatsMove, @@ -99,7 +112,7 @@ BpmControl::BpmControl(const QString& group, // bpm_down controls. // bpm_up / bpm_down steps by kBpmRangeStep // bpm_up_small / bpm_down_small steps by kBpmRangeSmallStep - m_pEngineBpm = new ControlLinPotmeter( + m_pEngineBpm = std::make_unique( ConfigKey(group, "bpm"), kBpmRangeMin, kBpmRangeMax, @@ -107,27 +120,33 @@ BpmControl::BpmControl(const QString& group, kBpmRangeSmallStep, true); m_pEngineBpm->set(0.0); - connect(m_pEngineBpm, &ControlObject::valueChanged, - this, &BpmControl::slotUpdateRateSlider, - Qt::DirectConnection); - - m_pButtonTap = new ControlPushButton(ConfigKey(group, "bpm_tap")); - connect(m_pButtonTap, &ControlObject::valueChanged, - this, &BpmControl::slotBpmTap, + connect(m_pEngineBpm.get(), + &ControlObject::valueChanged, + this, + &BpmControl::slotUpdateRateSlider, Qt::DirectConnection); - m_pTranslateBeats = new ControlPushButton(ConfigKey(group, "beats_translate_curpos")); - connect(m_pTranslateBeats, &ControlObject::valueChanged, - this, &BpmControl::slotBeatsTranslate, + m_pBpmTap = std::make_unique(ConfigKey(group, "bpm_tap")); + connect(m_pBpmTap.get(), + &ControlObject::valueChanged, + this, + &BpmControl::slotBpmTap, Qt::DirectConnection); - m_pBeatsTranslateMatchAlignment = new ControlPushButton(ConfigKey(group, "beats_translate_match_alignment")); - connect(m_pBeatsTranslateMatchAlignment, &ControlObject::valueChanged, - this, &BpmControl::slotBeatsTranslateMatchAlignment, + m_pTranslateBeats = std::make_unique( + ConfigKey(group, "beats_translate_curpos")); + connect(m_pTranslateBeats.get(), + &ControlObject::valueChanged, + this, + &BpmControl::slotBeatsTranslate, Qt::DirectConnection); - connect(&m_tapFilter, &TapFilter::tapped, - this, &BpmControl::slotTapFilter, + m_pBeatsTranslateMatchAlignment = std::make_unique( + ConfigKey(group, "beats_translate_match_alignment")); + connect(m_pBeatsTranslateMatchAlignment.get(), + &ControlObject::valueChanged, + this, + &BpmControl::slotBeatsTranslateMatchAlignment, Qt::DirectConnection); m_pBpmLock = std::make_unique( @@ -138,30 +157,17 @@ BpmControl::BpmControl(const QString& group, &BpmControl::slotToggleBpmLock, Qt::DirectConnection); - m_pBeatsUndo = new ControlPushButton(ConfigKey(group, "beats_undo_adjustment")); - connect(m_pBeatsUndo, + m_pBeatsUndo = std::make_unique( + ConfigKey(group, "beats_undo_adjustment")); + connect(m_pBeatsUndo.get(), &ControlObject::valueChanged, this, &BpmControl::slotBeatsUndoAdjustment, Qt::DirectConnection); // Measures distance from last beat in percentage: 0.5 = half-beat away. - m_pThisBeatDistance = new ControlProxy(group, "beat_distance", this); - m_pSyncMode = new ControlProxy(group, "sync_mode", this); -} - -BpmControl::~BpmControl() { - delete m_pLocalBpm; - delete m_pEngineBpm; - delete m_pButtonTap; - delete m_pTranslateBeats; - delete m_pBeatsTranslateMatchAlignment; - delete m_pTranslateBeatsEarlier; - delete m_pTranslateBeatsLater; - delete m_pTranslateBeatsMove; - delete m_pAdjustBeatsFaster; - delete m_pAdjustBeatsSlower; - delete m_pBeatsUndo; + m_pThisBeatDistance = std::make_unique(group, "beat_distance", this); + m_pSyncMode = std::make_unique(group, "sync_mode", this); } mixxx::Bpm BpmControl::getBpm() const { diff --git a/src/engine/controls/bpmcontrol.h b/src/engine/controls/bpmcontrol.h index d5fa7c08a88..3c5fa9271ce 100644 --- a/src/engine/controls/bpmcontrol.h +++ b/src/engine/controls/bpmcontrol.h @@ -21,7 +21,6 @@ class BpmControl : public EngineControl { public: BpmControl(const QString& group, UserSettingsPointer pConfig); - ~BpmControl() override; mixxx::Bpm getBpm() const; mixxx::Bpm getLocalBpm() const { @@ -125,10 +124,10 @@ class BpmControl : public EngineControl { friend class SyncControl; // ControlObjects that come from EngineBuffer - ControlProxy* m_pPlayButton; + std::unique_ptr m_pPlayButton; QAtomicInt m_oldPlayButton; - ControlProxy* m_pReverseButton; - ControlProxy* m_pRateRatio; + std::unique_ptr m_pReverseButton; + std::unique_ptr m_pRateRatio; ControlObject* m_pQuantize; // ControlObjects that come from QuantizeControl @@ -136,41 +135,42 @@ class BpmControl : public EngineControl { QScopedPointer m_pPrevBeat; // ControlObjects that come from LoopingControl - ControlProxy* m_pLoopEnabled; - ControlProxy* m_pLoopStartPosition; - ControlProxy* m_pLoopEndPosition; + std::unique_ptr m_pLoopEnabled; + std::unique_ptr m_pLoopStartPosition; + std::unique_ptr m_pLoopEndPosition; // The average bpm around the current playposition; - ControlObject* m_pLocalBpm; - ControlPushButton* m_pAdjustBeatsFaster; - ControlPushButton* m_pAdjustBeatsSlower; - ControlPushButton* m_pTranslateBeatsEarlier; - ControlPushButton* m_pTranslateBeatsLater; - ControlEncoder* m_pTranslateBeatsMove; - ControlPushButton* m_pBeatsUndo; + std::unique_ptr m_pLocalBpm; + std::unique_ptr m_pAdjustBeatsFaster; + std::unique_ptr m_pAdjustBeatsSlower; + std::unique_ptr m_pTranslateBeatsEarlier; + std::unique_ptr m_pTranslateBeatsLater; + std::unique_ptr m_pTranslateBeatsMove; + std::unique_ptr m_pBeatsUndo; std::unique_ptr m_pBpmLock; // The current effective BPM of the engine - ControlLinPotmeter* m_pEngineBpm; + std::unique_ptr m_pEngineBpm; // Used for bpm tapping from GUI and MIDI - ControlPushButton* m_pButtonTap; + std::unique_ptr m_pBpmTap; // File BPM + std::unique_ptr m_pRateTap; // Enigne BPM (playback rate) // Button that translates the beats so the nearest beat is on the current // playposition. - ControlPushButton* m_pTranslateBeats; + std::unique_ptr m_pTranslateBeats; // Button that translates beats to match another playing deck - ControlPushButton* m_pBeatsTranslateMatchAlignment; + std::unique_ptr m_pBeatsTranslateMatchAlignment; - ControlProxy* m_pThisBeatDistance; + std::unique_ptr m_pThisBeatDistance; ControlValueAtomic m_dSyncTargetBeatDistance; // The user offset is a beat distance percentage value that the user has tweaked a deck // to bring it in sync with the other decks. This value is added to the reported beat // distance to get the virtual beat distance used for sync. ControlValueAtomic m_dUserOffset; QAtomicInt m_resetSyncAdjustment; - ControlProxy* m_pSyncMode; + std::unique_ptr m_pSyncMode; TapFilter m_tapFilter; // threadsafe From 1f67d57379e9c3a4db1bd5d3003535e080ad2571 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Thu, 2 Nov 2023 13:13:28 +0100 Subject: [PATCH 2/8] BpmControl: add 'tempo_tap' control for tapping the playback speed --- src/engine/controls/bpmcontrol.cpp | 69 ++++++++++++++++++++++++++---- src/engine/controls/bpmcontrol.h | 15 ++++--- 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/src/engine/controls/bpmcontrol.cpp b/src/engine/controls/bpmcontrol.cpp index e89ef9f1170..5541e2c3747 100644 --- a/src/engine/controls/bpmcontrol.cpp +++ b/src/engine/controls/bpmcontrol.cpp @@ -24,7 +24,7 @@ constexpr double kBpmRangeSmallStep = 0.1; constexpr double kBpmAdjustMin = kBpmRangeMin; constexpr double kBpmAdjustStep = 0.01; -constexpr double kBpmTabRounding = 1 / 12.0; +constexpr double kBpmTapRounding = 1 / 12.0; // Maximum allowed interval between beats (calculated from kBpmTapMin). constexpr double kBpmTapMin = 30.0; @@ -40,12 +40,24 @@ constexpr int kLocalBpmSpan = 4; // of the next beat. constexpr double kPastBeatMatchThreshold = 1 / 8.0; +mixxx::Bpm averageBpmRoundedWithinRange(double averageLength, double rateRatio) { + // (60 seconds per minute) * (1000 milliseconds per second) / + // (X millis per beat) + // = Y beats/minute + auto averageBpm = mixxx::Bpm(60.0 * 1000.0 / averageLength / rateRatio); + averageBpm = BeatUtils::roundBpmWithinRange(averageBpm - kBpmTapRounding, + averageBpm, + averageBpm + kBpmTapRounding); + return averageBpm; +} + } // namespace BpmControl::BpmControl(const QString& group, UserSettingsPointer pConfig) : EngineControl(group, pConfig), - m_tapFilter(this, kBpmTapFilterLength, kBpmTapMaxInterval), + m_bpmTapFilter(this, kBpmTapFilterLength, kBpmTapMaxInterval), + m_tempoTapFilter(this, kBpmTapFilterLength, kBpmTapMaxInterval), m_dSyncInstantaneousBpm(0.0), m_dLastSyncAdjustment(1.0) { m_dSyncTargetBeatDistance.setValue(0.0); @@ -126,12 +138,31 @@ BpmControl::BpmControl(const QString& group, &BpmControl::slotUpdateRateSlider, Qt::DirectConnection); + // Tap the (file) BPM m_pBpmTap = std::make_unique(ConfigKey(group, "bpm_tap")); connect(m_pBpmTap.get(), &ControlObject::valueChanged, this, &BpmControl::slotBpmTap, Qt::DirectConnection); + connect(&m_bpmTapFilter, + &TapFilter::tapped, + this, + &BpmControl::slotBpmTapFilter, + Qt::DirectConnection); + + // Tap the tempo (playback speed) + m_pTempoTap = std::make_unique(ConfigKey(group, "tempo_tap")); + connect(m_pTempoTap.get(), + &ControlObject::valueChanged, + this, + &BpmControl::slotTempoTap, + Qt::DirectConnection); + connect(&m_tempoTapFilter, + &TapFilter::tapped, + this, + &BpmControl::slotTempoTapFilter, + Qt::DirectConnection); m_pTranslateBeats = std::make_unique( ConfigKey(group, "beats_translate_curpos")); @@ -259,11 +290,11 @@ void BpmControl::slotBeatsUndoAdjustment(double v) { void BpmControl::slotBpmTap(double v) { if (v > 0) { - m_tapFilter.tap(); + m_bpmTapFilter.tap(); } } -void BpmControl::slotTapFilter(double averageLength, int numSamples) { +void BpmControl::slotBpmTapFilter(double averageLength, int numSamples) { // averageLength is the average interval in milliseconds tapped over // numSamples samples. Have to convert to BPM now: @@ -286,16 +317,38 @@ void BpmControl::slotTapFilter(double averageLength, int numSamples) { // (60 seconds per minute) * (1000 milliseconds per second) / (X millis per // beat) = Y beats/minute - auto averageBpm = mixxx::Bpm(60.0 * 1000.0 / averageLength / rateRatio); - averageBpm = BeatUtils::roundBpmWithinRange(averageBpm - kBpmTabRounding, - averageBpm, - averageBpm + kBpmTabRounding); + auto averageBpm = averageBpmRoundedWithinRange(averageLength, rateRatio); const auto newBeats = pBeats->trySetBpm(averageBpm); if (!newBeats) { return; } pTrack->trySetBeats(*newBeats); } +void BpmControl::slotTempoTap(double v) { + if (v > 0) { + m_tempoTapFilter.tap(); + } +} + +void BpmControl::slotTempoTapFilter(double averageLength, int numSamples) { + // averageLength is the average interval in milliseconds tapped over + // numSamples samples. Have to convert to BPM now: + if (averageLength <= 0 || numSamples < 4) { + return; + } + + const TrackPointer pTrack = getEngineBuffer()->getLoadedTrack(); + if (!pTrack) { + return; + } + + auto averageBpm = averageBpmRoundedWithinRange(averageLength, 1.0); + m_pEngineBpm->set(averageBpm.value()); + // NOTE(ronso0) When setting the control, m_pEngineBpm->valueChanged() + // is not emitted (with Qt6) (it is when setting via a ControlProxy), + // so call the slot directly. + slotUpdateRateSlider(averageBpm.value()); +} // static double BpmControl::shortestPercentageChange(const double& current_percentage, diff --git a/src/engine/controls/bpmcontrol.h b/src/engine/controls/bpmcontrol.h index 3c5fa9271ce..f3f3f00fd15 100644 --- a/src/engine/controls/bpmcontrol.h +++ b/src/engine/controls/bpmcontrol.h @@ -102,8 +102,12 @@ class BpmControl : public EngineControl { void slotTranslateBeatsEarlier(double); void slotTranslateBeatsLater(double); void slotTranslateBeatsMove(double); - void slotTapFilter(double,int); - void slotBpmTap(double); + + void slotBpmTap(double value); + void slotBpmTapFilter(double averageLength, int numSamples); + void slotTempoTap(double value); + void slotTempoTapFilter(double averageLength, int numSamples); + void slotUpdateRateSlider(double v = 0.0); void slotUpdateEngineBpm(double v = 0.0); void slotBeatsTranslate(double); @@ -154,8 +158,8 @@ class BpmControl : public EngineControl { std::unique_ptr m_pEngineBpm; // Used for bpm tapping from GUI and MIDI - std::unique_ptr m_pBpmTap; // File BPM - std::unique_ptr m_pRateTap; // Enigne BPM (playback rate) + std::unique_ptr m_pBpmTap; // File BPM + std::unique_ptr m_pTempoTap; // Enigne BPM (playback rate) // Button that translates the beats so the nearest beat is on the current // playposition. @@ -172,7 +176,8 @@ class BpmControl : public EngineControl { QAtomicInt m_resetSyncAdjustment; std::unique_ptr m_pSyncMode; - TapFilter m_tapFilter; // threadsafe + TapFilter m_bpmTapFilter; // threadsafe + TapFilter m_tempoTapFilter; // threadsafe // used in the engine thread only double m_dSyncInstantaneousBpm; From af85602903820a34206288da02d9deebd003670a Mon Sep 17 00:00:00 2001 From: ronso0 Date: Thu, 2 Nov 2023 13:50:31 +0100 Subject: [PATCH 3/8] add 'tempo_tap' tooltip, as well as some useful combinations --- src/skin/legacy/tooltips.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/skin/legacy/tooltips.cpp b/src/skin/legacy/tooltips.cpp index fceeca1883e..6720f2b1097 100644 --- a/src/skin/legacy/tooltips.cpp +++ b/src/skin/legacy/tooltips.cpp @@ -397,6 +397,11 @@ void Tooltips::addStandardTooltips() { << eqKillLatch; QString tempoDisplay = tr("Displays the tempo of the loaded track in BPM (beats per minute)."); + // TODO Clarify this refers to 'file BPM', not playback rate? + QString bpmTapButton = tr("When tapped repeatedly, adjusts the BPM to match the tapped BPM."); + QString tempoTapButton = + tr("When tapped repeatedly, adjusts the tempo to match the tapped " + "BPM."); add("visual_bpm") << tr("Tempo") << tempoDisplay; @@ -408,7 +413,14 @@ void Tooltips::addStandardTooltips() { add("bpm_tap") << tr("BPM Tap") - << tr("When tapped repeatedly, adjusts the BPM to match the tapped BPM."); + << bpmTapButton; + add("tempo_tap") + << tr("Tempo Tap") + << tempoTapButton; + add("tempo_tap_bpm_tap") + << tr("Rate Tap and BPM Tap") + << QString("%1: %2").arg(leftClick, tempoTapButton) + << QString("%1: %2").arg(rightClick, bpmTapButton); add("beats_adjust_slower") << tr("Adjust BPM Down") @@ -439,11 +451,22 @@ void Tooltips::addStandardTooltips() { << tr("Revert last BPM/Beatgrid Change") << tr("Revert last BPM/Beatgrid Change of the loaded track."); - //this is a special case, in some skins we might display a transparent png for bpm_tap on top of visual_bpm + // These are special cases: + // in some skins we display a transparent button for tempo_tap and/or bpm_tap + // on top of the visual_bpm display. add("bpm_tap_visual_bpm") << tr("Tempo and BPM Tap") << tempoDisplay - << tr("When tapped repeatedly, adjusts the BPM to match the tapped BPM."); + << bpmTapButton; + add("tempo_tap_visual_bpm") + << tr("Tempo and Rate Tap") + << tempoDisplay + << tempoTapButton; + add("tempo_tap_bpm_tap_visual_bpm") + << tr("Tempo, Rate Tap and BPM Tap") + << tempoDisplay + << QString("%1: %2").arg(leftClick, tempoTapButton) + << QString("%1: %2").arg(rightClick, bpmTapButton); add("shift_cues_earlier") << tr("Shift cues earlier") From fcd407da60ea63a540ff9cba6f2bcae7bd139dd4 Mon Sep 17 00:00:00 2001 From: ronso0 Date: Thu, 2 Nov 2023 13:56:35 +0100 Subject: [PATCH 4/8] Skins: use new tempo_tap button (right-click is bpm_tap), adjust tooltips --- res/skins/Deere/deck_text_row.xml | 8 +++++--- res/skins/LateNight/decks/rate_controls.xml | 9 ++++++--- .../LateNight/decks/rate_controls_compact.xml | 16 +++++++++------- res/skins/Shade/sampler.xml | 15 ++++++--------- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/res/skins/Deere/deck_text_row.xml b/res/skins/Deere/deck_text_row.xml index cac79290177..d8809788a3b 100644 --- a/res/skins/Deere/deck_text_row.xml +++ b/res/skins/Deere/deck_text_row.xml @@ -258,7 +258,7 @@ - bpm_tap + tempo_tap_bpm_tap 30,20 60,30 me,me @@ -267,10 +267,12 @@ 0 TAP + + ,tempo_tap + ,bpm_tap - true - LeftButton + RightButton diff --git a/res/skins/LateNight/decks/rate_controls.xml b/res/skins/LateNight/decks/rate_controls.xml index d74e0550f8a..8736cf01feb 100644 --- a/res/skins/LateNight/decks/rate_controls.xml +++ b/res/skins/LateNight/decks/rate_controls.xml @@ -31,15 +31,18 @@ stacked 57f,-1me - + - bpm_tap_visual_bpm + tempo_tap_bpm_tap_visual_bpm BpmTap 57f,-1me 1 + + ,tempo_tap + ,bpm_tap + RightButton diff --git a/res/skins/LateNight/decks/rate_controls_compact.xml b/res/skins/LateNight/decks/rate_controls_compact.xml index 24ee0960ed5..77a92533863 100644 --- a/res/skins/LateNight/decks/rate_controls_compact.xml +++ b/res/skins/LateNight/decks/rate_controls_compact.xml @@ -25,17 +25,19 @@ stacked 60f,40f - + - bpm_tap_visual_bpm + tempo_tap_bpm_tap_visual_bpm BpmTap me,me 1 - - ,bpm_tap - true - + + ,tempo_tap + + + ,bpm_tap + RightButton + AlignCenter diff --git a/res/skins/Shade/sampler.xml b/res/skins/Shade/sampler.xml index 251dcb16489..ec147651d11 100644 --- a/res/skins/Shade/sampler.xml +++ b/res/skins/Shade/sampler.xml @@ -58,6 +58,7 @@ 35f,24f + visual_bpm