Guitar Solo: Observed tick discontinuities during dense bend / whammy section #2577
Replies: 3 comments 1 reply
-
|
You could use the new custom cursor handler functionality to mitigate such problems. It allows implementing custom cursor placement logic but relying on sone optimizations done by alphaTab. (docs pending but they are similar to the scroll handlers). Additionally alphaTab opted to place cursors using css transforms. Profiling in the past has shown that this has the least performance impact . Classical positioning can trigger expensive layout updates. |
Beta Was this translation helpful? Give feedback.
-
|
Thank you Daniel!
Is that different than the ICursorhandler I am using now?
…On Sun, Feb 22, 2026 at 10:10 PM Daniel Kuschny ***@***.***> wrote:
You could use the new custom cursor handler functionality to mitigate such
problems. It allows implementing custom cursor placement logic but relying
on sone optimizations done by alphaTab.
(docs pending but they are similar to the scroll handlers).
Additionally alphaTab opted to place cursors using css transforms.
Profiling in the past has shown that this has the least performance impact
. Classical positioning can trigger expensive layout updates.
—
Reply to this email directly, view it on GitHub
<#2577 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/BNLESQH3BWBOWT4TRYOAVLT4NKKW3AVCNFSM6AAAAACV4ARQSWVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTKOBZGMZTMOI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
|
Hi Daniel,
Thanks for the suggestion — I can confirm we are already using the
temporary customCursorHandler workaround (the onNotesX fix from #2546), and
that did resolve the off-center cursor issue for both LouisLam and us.
However, the guitar solo case appears to be a different class of issue.
*In our setup we are:*
-
Using a fully custom cursor (repeat-aware)
-
Overriding tick resolution
-
Handling expanded timelines (repeat passes)
-
Using audio clock authority
-
Intercepting playerPositionChanged
-
Running custom interpolation logic
*The observed behavior was related to:*
-
Expanded tick mismatches
-
Timeline discontinuities
-
Repeat boundary re-seek timing
-
Worker dead-zone exposure
*So it doesn’t appear to be a visual placement issue.*
*To the best of my understanding, api.customCursorHandler only affects
cursor placement (setBounds) and does not interact with:*
-
tickCache
-
Repeat expansion
-
playbackRange
-
Master bar traversal
-
Audio clock authority
-
playerPositionChanged
The temporary handler fixed the GP3 off-center bug (#2546) for both the
native and custom cursor, but this solo issue seems to originate at the
timeline level rather than the visual placement layer.
// ============================================
// 🩹 TEMP FIX: AlphaTab 1.8.1 Cursor Bug (GitHub #2546)
// Remove once AlphaTab releases official fix for startBeatX
// ✅ Uses onNotesX instead of incorrect startBeatX
// ✅ Affects native cursor (hidden, but used for events)
// ✅ MaestroCursor unaffected (calculates independently)
// ============================================
api.customCursorHandler = {
onAttach() { },
onDetach() { },
placeBeatCursor(beatCursor: any, beatBounds: any) {
const barBounds = beatBounds.barBounds.masterBarBounds.visualBounds;
beatCursor.setBounds(beatBounds.onNotesX, barBounds.y, 1, barBounds.h);
},
placeBarCursor(barCursor: any, beatBounds: any) {
const barBounds = beatBounds.barBounds.masterBarBounds.visualBounds;
barCursor.setBounds(barBounds.x, barBounds.y, barBounds.w, barBounds.h);
},
transitionBeatCursor(beatCursor: any, beatBounds: any) {
this.placeBeatCursor(beatCursor, beatBounds);
}
};
if (DEBUG) {
console.log('🩹 Applied AlphaTab 1.8.1 cursor positioning fix');
}
// ============================================
// 🔒 END TEMP FIX 🔒
// ============================================
Just wanted to clarify the distinction in case that helps narrow things
down.
Thanks again for your help.
…On Sun, Feb 22, 2026 at 10:10 PM Daniel Kuschny ***@***.***> wrote:
You could use the new custom cursor handler functionality to mitigate such
problems. It allows implementing custom cursor placement logic but relying
on sone optimizations done by alphaTab.
(docs pending but they are similar to the scroll handlers).
Additionally alphaTab opted to place cursors using css transforms.
Profiling in the past has shown that this has the least performance impact
. Classical positioning can trigger expensive layout updates.
—
Reply to this email directly, view it on GitHub
<#2577 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/BNLESQH3BWBOWT4TRYOAVLT4NKKW3AVCNFSM6AAAAACV4ARQSWVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTKOBZGMZTMOI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
While resolving repeat-aware cursor synchronization (3x repeat sections), we observed a separate and unrelated transport behavior during the guitar bridge and solo sections of “Extreme – Rise” (dense bend / whammy passages).
This behavior does not appear to be connected to repeat handling.
During long sustained beats (e.g. ~3840 tick duration), we initially observed:
• Cursor would stutter or jerk back and forth rapidly before jumping back, and appearing to freeze on a note (0) or (15)
• Then jumping forward several beats
• Native alphaTab cursor remaining visually correct
After investigation, we determined this was not an alphaTab transport bug, but rather a performance issue in our own playerPositionChanged handler.
Specifically:
• We were running two tickCache.findBeat() scans (backward + forward)
• On every playerPositionChanged event (~30fps)
• For long sustained beats (~4 seconds)
• Resulting in ~720,000 findBeat() calls during a single beat
This caused main-thread stalls during dense solo sections. Audio continued smoothly, but JS temporarily blocked — which made the custom cursor appear to "shake" "stutter" "jump back" then "freeze” and then teleport.
After gating both scans behind an O(1) beat-identity check (running them once per beat entry instead of once per frame), the issue disappeared entirely.
This suggests:
• Long-duration beats (bends / whammy passages) expose performance-sensitive patterns in playerPositionChanged
• Repeated heavy use of tickCache.findBeat() per frame can become very expensive
• The transport itself remained correct throughout
We are sharing this as a general implementation note in case it helps others building custom cursor systems on top of alphaTab.
Beta Was this translation helpful? Give feedback.
All reactions