Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beats: Add editing controls and show downbeats on scrolling waveforms [v2] #12343

Closed
wants to merge 8 commits into from
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions res/skins/LateNight/skin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@

<SetVariable name="AxesColor">#999</SetVariable>
<SetVariable name="BeatColor">#999</SetVariable>
<SetVariable name="DownbeatColor">#f00</SetVariable>
<SetVariable name="MarkerbeatColor">#f0f</SetVariable>
<SetVariable name="PlayPosColor">#00c6ff</SetVariable>
<SetVariable name="CueColor">#ff7a01</SetVariable>
<SetVariable name="LoopColor">#00b400</SetVariable>
Expand Down
14 changes: 10 additions & 4 deletions res/skins/LateNight/style_palemoon.qss
Original file line number Diff line number Diff line change
Expand Up @@ -2322,11 +2322,17 @@ WPushButton#PlayDeck[value="0"] {
image: url(skin:../LateNight/palemoon/buttons/btn__beatgrid_controls_collapse.svg) no-repeat center center;
}

#BeatCurposLarge[displayValue="0"] {
image: url(skin:../LateNight/palemoon/buttons/btn__beat_curpos_large.svg) no-repeat center center;
#BeatsSetMarker[displayValue="0"] {
image: url(skin:../LateNight/palemoon/buttons/btn__beats_set_marker.svg) no-repeat center center;
}
#BeatCurposLarge[pressed="true"] {
image: url(skin:../LateNight/palemoon/buttons/btn__beat_curpos_large_active.svg) no-repeat center center;
#BeatsSetMarker[pressed="true"] {
image: url(skin:../LateNight/palemoon/buttons/btn__beats_set_marker_active.svg) no-repeat center center;
}
#BeatsRemoveMarker[displayValue="0"] {
image: url(skin:../LateNight/palemoon/buttons/btn__beats_remove_marker.svg) no-repeat center center;
}
#BeatsRemoveMarker[pressed="true"] {
image: url(skin:../LateNight/palemoon/buttons/btn__beats_remove_marker_active.svg) no-repeat center center;
}

#BeatsEarlier {
Expand Down
29 changes: 20 additions & 9 deletions res/skins/LateNight/waveform.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
<SignalRGBMidColor><Variable name="SignalMidColor"/></SignalRGBMidColor>
<SignalRGBLowColor><Variable name="SignalLowColor"/></SignalRGBLowColor>
<BeatColor><Variable name="BeatColor"/></BeatColor>
<DownbeatColor><Variable name="DownbeatColor"/></DownbeatColor>
<MarkerbeatColor><Variable name="MarkerbeatColor"/></MarkerbeatColor>
<AxesColor><Variable name="AxesColor"/></AxesColor>
<BeatHighlightColor></BeatHighlightColor>
<PlayPosColor><Variable name="PlayPosColor"/></PlayPosColor>
Expand Down Expand Up @@ -153,15 +155,24 @@

<WidgetGroup><Size>1f,0min</Size></WidgetGroup>

<!-- CurPos -->
<Template src="skin:../LateNight/controls/button_1state_right.xml">
<SetVariable name="TooltipId">beats_translate_curpos</SetVariable>
<SetVariable name="ObjectName">BeatCurposLarge</SetVariable>
<SetVariable name="Size">26f,52f</SetVariable>
<SetVariable name="BtnSize">library_tall</SetVariable>
<SetVariable name="ConfigKey"><Variable name="Group"/>,beats_translate_curpos</SetVariable>
<SetVariable name="ConfigKeyRight"><Variable name="Group"/>,beats_translate_match_alignment</SetVariable>
</Template>
<WidgetGroup><!-- beats set & remove marker -->
<Layout>vertical</Layout>
<Size>26f,52f</Size>
<Children>
<Template src="skin:../LateNight/controls/button_1state.xml">
<SetVariable name="TooltipId">beats_set_marker</SetVariable>
<SetVariable name="ObjectName">BeatsSetMarker</SetVariable>
<SetVariable name="Size">26f,26f</SetVariable>
<SetVariable name="ConfigKey"><Variable name="Group"/>,beats_set_marker</SetVariable>
</Template>
<Template src="skin:../LateNight/controls/button_1state.xml">
<SetVariable name="TooltipId">beats_remove_marker</SetVariable>
<SetVariable name="ObjectName">BeatsRemoveMarker</SetVariable>
<SetVariable name="Size">26f,26f</SetVariable>
<SetVariable name="ConfigKey"><Variable name="Group"/>,beats_remove_marker</SetVariable>
</Template>
</Children>
</WidgetGroup><!-- /beats set & remove marker -->

<WidgetGroup><!-- beats earlier & faster -->
<Layout>vertical</Layout>
Expand Down
93 changes: 74 additions & 19 deletions src/engine/controls/bpmcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ constexpr double kBpmRangeMax = 200.0;
constexpr double kBpmRangeStep = 1.0;
constexpr double kBpmRangeSmallStep = 0.1;

constexpr double kBpmAdjustMin = kBpmRangeMin;
constexpr double kBpmAdjustStep = 0.01;
constexpr double kBpmTabRounding = 1 / 12.0;

// Maximum allowed interval between beats (calculated from kBpmTapMin).
Expand Down Expand Up @@ -93,6 +91,18 @@ BpmControl::BpmControl(const QString& group,
this,
&BpmControl::slotTranslateBeatsMove,
Qt::DirectConnection);
m_pBeatsSetMarker = new ControlPushButton(ConfigKey(group, "beats_set_marker"), false);
connect(m_pBeatsSetMarker,
&ControlObject::valueChanged,
this,
&BpmControl::slotBeatsSetMarker,
Qt::DirectConnection);
m_pBeatsRemoveMarker = new ControlPushButton(ConfigKey(group, "beats_remove_marker"), false);
connect(m_pBeatsRemoveMarker,
&ControlObject::valueChanged,
this,
&BpmControl::slotBeatsRemoveMarker,
Qt::DirectConnection);

// Pick a wide range (kBpmRangeMin to kBpmRangeMax) and allow out of bounds sets. This lets you
// map a soft-takeover MIDI knob to the BPM. This also creates bpm_up and
Expand Down Expand Up @@ -144,6 +154,8 @@ BpmControl::~BpmControl() {
delete m_pTranslateBeatsEarlier;
delete m_pTranslateBeatsLater;
delete m_pTranslateBeatsMove;
delete m_pBeatsSetMarker;
delete m_pBeatsRemoveMarker;
delete m_pAdjustBeatsFaster;
delete m_pAdjustBeatsSlower;
}
Expand All @@ -152,7 +164,11 @@ mixxx::Bpm BpmControl::getBpm() const {
return mixxx::Bpm(m_pEngineBpm->get());
}

void BpmControl::adjustBeatsBpm(double deltaBpm) {
void BpmControl::slotAdjustBeatsFaster(double v) {
if (v <= 0) {
return;
}

const TrackPointer pTrack = getEngineBuffer()->getLoadedTrack();
if (!pTrack) {
return;
Expand All @@ -162,31 +178,32 @@ void BpmControl::adjustBeatsBpm(double deltaBpm) {
return;
}

const mixxx::Bpm bpm = pBeats->getBpmInRange(
mixxx::audio::kStartFramePos, frameInfo().trackEndPosition);
// FIXME: calling bpm.value() without checking bpm.isValid()
const auto centerBpm = mixxx::Bpm(math_max(kBpmAdjustMin, bpm.value() + deltaBpm));
mixxx::Bpm adjustedBpm = BeatUtils::roundBpmWithinRange(
centerBpm - kBpmAdjustStep / 2, centerBpm, centerBpm + kBpmAdjustStep / 2);
const auto newBeats = pBeats->trySetBpm(adjustedBpm);
if (!newBeats) {
return;
const auto adjustedBeats = pBeats->tryAdjustTempo(
frameInfo().currentPosition, mixxx::Beats::TempoAdjustment::Faster);
if (adjustedBeats) {
pTrack->trySetBeats(*adjustedBeats);
}
pTrack->trySetBeats(*newBeats);
}

void BpmControl::slotAdjustBeatsFaster(double v) {
void BpmControl::slotAdjustBeatsSlower(double v) {
if (v <= 0) {
return;
}
adjustBeatsBpm(kBpmAdjustStep);
}

void BpmControl::slotAdjustBeatsSlower(double v) {
if (v <= 0) {
const TrackPointer pTrack = getEngineBuffer()->getLoadedTrack();
if (!pTrack) {
return;
}
const mixxx::BeatsPointer pBeats = pTrack->getBeats();
if (!pBeats) {
return;
}
adjustBeatsBpm(-kBpmAdjustStep);

const auto adjustedBeats = pBeats->tryAdjustTempo(
frameInfo().currentPosition, mixxx::Beats::TempoAdjustment::Slower);
if (adjustedBeats) {
pTrack->trySetBeats(*adjustedBeats);
}
}

void BpmControl::slotTranslateBeatsEarlier(double v) {
Expand Down Expand Up @@ -224,6 +241,44 @@ void BpmControl::slotTranslateBeatsMove(double v) {
}
}

void BpmControl::slotBeatsSetMarker(double v) {
if (v <= 0) {
return;
}
const TrackPointer pTrack = getEngineBuffer()->getLoadedTrack();
if (!pTrack) {
return;
}
const mixxx::BeatsPointer pBeats = pTrack->getBeats();
if (!pBeats) {
return;
}

const auto modifiedBeats = pBeats->trySetMarker(frameInfo().currentPosition);
if (modifiedBeats) {
pTrack->trySetBeats(*modifiedBeats);
}
}

void BpmControl::slotBeatsRemoveMarker(double v) {
if (v <= 0) {
return;
}
const TrackPointer pTrack = getEngineBuffer()->getLoadedTrack();
if (!pTrack) {
return;
}
const mixxx::BeatsPointer pBeats = pTrack->getBeats();
if (!pBeats) {
return;
}

const auto modifiedBeats = pBeats->tryRemoveMarker(frameInfo().currentPosition);
if (modifiedBeats) {
pTrack->trySetBeats(*modifiedBeats);
}
}

void BpmControl::slotBpmTap(double v) {
if (v > 0) {
m_tapFilter.tap();
Expand Down
4 changes: 4 additions & 0 deletions src/engine/controls/bpmcontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ class BpmControl : public EngineControl {
void slotTranslateBeatsEarlier(double);
void slotTranslateBeatsLater(double);
void slotTranslateBeatsMove(double);
void slotBeatsSetMarker(double);
void slotBeatsRemoveMarker(double);
void slotTapFilter(double,int);
void slotBpmTap(double);
void slotUpdateRateSlider(double v = 0.0);
Expand Down Expand Up @@ -144,6 +146,8 @@ class BpmControl : public EngineControl {
ControlPushButton* m_pTranslateBeatsEarlier;
ControlPushButton* m_pTranslateBeatsLater;
ControlEncoder* m_pTranslateBeatsMove;
ControlPushButton* m_pBeatsSetMarker;
ControlPushButton* m_pBeatsRemoveMarker;

// The current effective BPM of the engine
ControlLinPotmeter* m_pEngineBpm;
Expand Down
14 changes: 12 additions & 2 deletions src/skin/legacy/tooltips.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,13 +393,23 @@ void Tooltips::addStandardTooltips() {
<< tr("BPM Tap")
<< tr("When tapped repeatedly, adjusts the BPM to match the tapped BPM.");

add("beats_set_marker")
<< tr("Set Beat Marker")
<< tr("Set a beat marker at the current play position.");

add("beats_remove_marker")
<< tr("Remove Beat Marker")
<< tr("Remove the beat marker at the current play position.");

add("beats_adjust_slower")
<< tr("Adjust BPM Down")
<< tr("When tapped, adjusts the average BPM down by a small amount.");
<< tr("When tapped, decrease the BPM of the region around the "
"current play position by a small amount.");

add("beats_adjust_faster")
<< tr("Adjust BPM Up")
<< tr("When tapped, adjusts the average BPM up by a small amount.");
<< tr("When tapped, increases the BPM of the region around the "
"current play position by a small amount.");

add("beats_translate_earlier")
<< tr("Adjust Beats Earlier")
Expand Down
Loading
Loading