Created with the help of Claude…
Summary
“Set Loop In/Out” (Transport → Looping → Set Loop In/Out) always opens a dialog requiring both the loop-in and loop-out times to be typed in manually. There’s no way to set either value to the current playhead/cursor position without reading the time off the transport clock and re-entering it digit by digit.
Current behavior
PlaybackController::setLoopRegionInOut() pre-fills both dialog fields from the existing loop region, not the playhead:
// src/playback/internal/playbackcontroller.cpp
void PlaybackController::setLoopRegionInOut()
{
PlaybackRegion region = player()->loopRegion();
muse::UriQuery loopRegionInOutUri("audacity://playback/loop_region_in_out");
loopRegionInOutUri.addParam("title", muse::Val(muse::trc("trackedit", "Set looping region in/out")));
loopRegionInOutUri.addParam("start", muse::Val(static_cast<double>(region.start)));
loopRegionInOutUri.addParam("end", muse::Val(static_cast<double>(region.end)));
...
}
The dialog itself (LoopRegionInOut.qml) uses the same segmented, digit-by-digit Timecode/NumericView widget used elsewhere in the app for timecode entry. That widget has no clipboard paste handling, so there’s also no quick copy-from-elsewhere-and-paste workaround - each field has to be typed by hand.
Desired behavior
A way to set the loop-in and/or loop-out point to wherever the playhead currently is, without manually reading and re-typing a timecode. For example:
- A “Set Loop In to Playhead” / “Set Loop Out to Playhead” pair of commands (bindable to their own keyboard shortcuts, since neither has a default shortcut today), that set one edge of the loop region to
playbackState()->playbackPosition()immediately, leaving the other edge untouched - similar in spirit to how a punch-in/punch-out point is set in most DAWs. - Alternatively/additionally, a button or field-level action inside the existing Set Loop In/Out dialog that fills the focused field from the current playhead position, for people who prefer the dialog workflow.
Why this matters
Looping a specific stretch of a long recording to review it repeatedly (e.g. while doing accuracy/QA passes on transcription or diarization output) is much easier when you can just park the playhead where you want a boundary and hit one key, rather than pausing, reading the transport clock, opening a dialog, and typing the exact time into a segmented field twice (once for in, once for out).
Precedent already in the codebase
The capability to read the live playhead value directly already exists and is used elsewhere - it just isn’t wired up for the loop-in/out dialog. TrackeditActionsController::selectLeftOfPlaybackPos() / selectRightOfPlaybackPos() (src/trackedit/internal/trackeditactionscontroller.cpp) both call playbackState()->playbackPosition() directly to set one edge of a selection to the current playhead. The same pattern would work for the loop region.
Suggested implementation sketch
Add two new dispatcher actions (e.g. set-loop-in-to-playhead, set-loop-out-to-playhead) alongside the existing set-loop-region-in-out action in trackeditactionscontroller.cpp / playbackcontroller.cpp, each reading playbackState()->playbackPosition() and calling player()->setLoopRegion({...}) with only the relevant edge replaced - no dialog involved. Register them in shortcuts.xml (currently unbound, like set-loop-region-in-out itself) and add corresponding menu items under Transport → Looping.
Environment
- Audacity version: 3.7.8
- OS: Windows