AlphaTab v1.8.1: Loop-boundary handling for vibrato, bend, whammy, and active voice tails #2801
Replies: 3 comments 1 reply
|
Lets step back on this matter first a bit before jumping into the level of detail you talk about. At this point I don't even understand what you are doing and testing. Can you provide one or two concrete examples with files on what you are doing and what you are experiencing. |
|
Yes, thank you. Let me simplify this to one concrete example first. Version note: Two songs tested but this is the main one with another listed at the bottom: “Ain’t Talkin’ ’Bout Love” Guitar Pro file alphaTab version: Track: Reproduction:
For convenience, I also have a public lightweight test harness based on https://github.com/AvaTheArchitect/louislam-borrowed-labs Note: The tick values and event logs below were captured in our production The same audible behavior was independently reproduced in the public test The repository is intentionally separate from Maestro.ai and provides a The Van Halen Guitar Pro file is already included in the repository. You can The effective tick range in our test is: startTick: 3840 The final included note: startTick: 5280 Observed: The loop returns to its start before the final vibrato note sounds fully With the Loop ending after beat 4, the final vibrato note sounds cut short. When the Loop is extended through beat 5, the vibrato note sounds complete, Control test: If I extend the same playback range through beat 5: startTick: 3840 the vibrato note sounds complete. The problem with using that as the solution is that beat 5 is supposed to be The final desired vibrato event appears at tick 6720, which is also the tick Expected: The final included note and its vibrato tail should finish, while the NoteOn Actual: The playback range wraps at that boundary and the final included note sounds Please let me know whether this is enough to reproduce the behavior on your Additional: The repository also contains a few additional expressive-note test locations, I have included screenshots of those locations Additional reference location 1 — Van Halen Here is an example of the main test steps showed above: |
|
Let me simplify this. The Audio is being truncated when the Loop is set at
the end of a vibrato or bend. Yet if I set Loop one note/beat over the
audio is not truncated. So in short I am trying to learn why as I don't
think that is the intended result of alphaTab?
I agree, I think the part I described poorly is that this is not mainly
about whether the vibrato or bend reaches the perfect final pitch. The
audible problem is that the whole final note sounds cut short when the Loop
ends on that beat.
Plain example:
1. Open “Ain’t Talkin’ ’Bout Love.”
2. Select and solo the Eddie Van Halen guitar track.
3. Set playback speed to 25%.
4. Loop measure 2 through beat 4.
The final vibrato note sounds noticeably shorter than its written duration.
Now the audio is not cut off by a huge amount, but if it is a 4 beat count
for example it would be like half a foot tap short. And it was caught in
those live scan logs above as well.
Then move the Loop end one beat later, and the same vibrato (or bend) note
now sounds complete, but the Loop also includes a beat that I do not want
played.
I hear the same difference in both Maestro and the separate lightweight
LouisLam ItsMyTabs test repository running on V1.8.3
So the question is simply:
Is there a supported way for the final included note to finish sounding
while preventing the next excluded beat from playing? Or is cutting the
final note at playbackRange.endTick the intended alphaTab behavior?
I can send a very short A/B recording if that would make the difference
easier to hear.
…On Sun, Aug 2, 2026 at 3:25 AM Daniel Kuschny ***@***.***> wrote:
Thanks for the clarification, even though I still cannot extract fully
what you are planning to find out or improve. To me it this topic sounds
again like a complex fabrication of an AI trying to make sense of a
question and already inventing ideas how to work around this matter.
In short: there is no special magic or highly sophisticated logic
regarding effects and loop boundaries. vibratos, bends and whammys simply
generate additional pitch-bend events during the beat plays.
- For vibratos we simply oscillate the pitch given a amplitude and
phase length (configurable via settings.player.vibrato) with a final
reset at end.
-
https://github.com/CoderLine/alphaTab/blob/develop/packages/alphatab/src/midi/MidiFileGenerator.ts#L1448C13-L1448C40
-
https://github.com/CoderLine/alphaTab/blob/develop/packages/alphatab/src/PlayerSettings.ts#L32
- Bends and Whammys spread pitch wheels according to the bend or
whammy done with a ~6millisecond interval for smooth transition.
The player works as simple: Emit midi events before the playback range
end-tick.
https://github.com/CoderLine/alphaTab/blob/develop/packages/alphatab/src/synth/MidiFileSequencer.ts#L375-L379
Then audio is synthesized accordingly. When the end is reached, and the
player seeks *back* to the start, all midi controllers are fully reset,
and a fast replay of all events from tick 0 to the playback range start are
reprocessed to have the expected midi state.
IMO: A difference of < vs <= shouldn't make a real audible difference on
looping compared to normal playback. When a note "ends" it ends on the
pitch depending on the effect generation logic above. A perfectionist would
maybe claim that the vibrato/bend/whammy effects should model the physical
release of the string-bending (or pitch-wheel-rotation), but that's just
not realistic as every musician plays such effects individually.
The only thing I could imagine as improvement is: a configurable threshold
how much "earlier" some effects should complete to emulate a human stopping
the effect earlier, or reaching the target pitch a bit earlier. e.g. on
bend-release or whammy dips ensure we complete a few milliseconds early
back to normal pitch to also have some audio on that pitch. If we reach the
expected pitch 100% precisely at the end of the note, there is no audio
generated at the target pitch as the note is already released at this exact
time.
Feel free to correct me if I understood the problem domain incorrect.
—
Reply to this email directly, view it on GitHub
<#2801?email_source=notifications&email_token=BNLESQFKTD3ZYYISFBDJV235H4JJ7A5CNFSNUABIM5UWIORPF5TWS5BNNB2WEL2ENFZWG5LTONUW63SDN5WW2ZLOOQXTCNZYGY4TGMJUUZZGKYLTN5XKMYLVORUG64VFMV3GK3TUVRTG633UMVZF6Y3MNFRWW#discussioncomment-17869314>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/BNLESQG3IEQQL257S6ZPZFT5H4JJ7AVCNFSNUABGKJSXA33TNF2G64TZHMYTIOJRGE4TEO2ENFZWG5LTONUW63R3GEYDKMZSGY2DPILWAI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|






Uh oh!
There was an error while loading. Please reload this page.
Hi Daniel,
We are auditing expressive-note completion at playbackRange Loop boundaries in
an AlphaTab v1.8.1 integration. Yes, I am still running a few versions behind here.
We have two distinct runtime findings and would appreciate guidance on the
supported AlphaTab behavior and APIs.
CONFIRMED ENGINE PATH
From the installed AlphaTab source, native Loop wrap follows:
AlphaSynth.checkForFinish()
→ this.tickPosition = playbackRange.startTick
→ timePosition setter
→ mainSeek()
→ noteOffAll(true)
→ voice.endQuick()
This appears to use the same backward-seek/reset family as an application-issued
api.tickPosition seek.
REPRODUCTION A — PURE VIBRATO AT THE LOOP BOUNDARY
Song:
Ain't Talkin' 'Bout Love
Final included beat:
M2B4
Runtime note data:
Using AlphaTab's midiEventsPlayed stream, the tight Loop emitted vibrato
NoteBendEvents through:
6608, 6624, 6640, 6656, 6672, 6688, 6704
The expected final automation event at tick 6720 was not emitted before wrap.
When we moved the Loop endpoint one beat later to 7200, the same note emitted
its tick-6720 event and audibly completed.
This produces a same-tick conflict:
A blanket endTick extension therefore admits both the desired trailing
automation and the undesired next note.
REPRODUCTION B — ORDINARY NON-TIED BEND
A second reproduction uses an ordinary, non-tied, non-grace bend:
The generated bend and NoteOff finish 480 ticks before the beat's structural
playback end. The Loop boundary does not truncate this note.
At reduced playback speed the note can still sound shorter than its expected
notated duration, so this appears to be a separate note-duration-generation
question rather than a Loop-wrap issue.
Note: At normal speed I didn't quite notice it as much but then as I slowed it down to 25% speed with the Loop a the beat boundary for any of the above type notes played and using a live scan on the logs to capture the audio.
QUESTIONS
Is playbackRange interpreted as a half-open interval where MIDI events at
exactly endTick are intentionally excluded?
Is there a supported API for obtaining the final generated MIDI-event tick
for a specific Note or Beat, including vibrato, bend, whammy, ties, grace
notes, slides, and controller automation?
Can AlphaTab allow already-active pitch automation or voice output to finish
at or beyond endTick while still suppressing new NoteOn events whose start
tick is at or beyond the original Loop endpoint?
When a trailing automation event and the next excluded NoteOn share the same
tick, is there a supported event-priority or filtering mechanism that lets
the trailing event complete without admitting the new note?
Is native Loop wrap required to use the same
mainSeek() → noteOffAll(true) → endQuick() path as an application-issued
backward seek?
Does AlphaSynth expose or support a softer Loop-wrap mode where the previous
iteration's already-active voice may release or finish briefly after the
visual/tick cursor has returned to the Loop start?
We observed another commercial player visually restart its Loop while the
previous note tail continued briefly. We are not assuming its internal
implementation; we are asking whether AlphaTab supports an equivalent
voice-tail carryover model.
For an ordinary non-tied bend, should the generated bend automation and
NoteOff normally extend to the note or beat's full playbackDuration?
If so, can you help reconcile an observed case where both the final bend
event and NoteOff occurred at tick 168000 while the beat's
playbackDuration ended at tick 168480—a 480-tick gap?
Is that 480-tick gap expected from AlphaTab's noteOnly duration calculation,
bend-point offsets, gate-time logic, or another percentage-based duration
rule?
songBookBendDuration is documented as a millisecond-based setting associated
with SongBook bend behavior. We cannot enable SongBook mode because it causes
unrelated integration regressions in our application.
Is any part of AlphaTab's expressive-duration calculation available or safe
to reproduce independently without enabling SongBook display mode?
For pure vibrato, should the final pitch-reset or automation event normally
occur exactly at the note's structural end tick? If so, is its exclusion at
playbackRange.endTick expected under the current half-open boundary
semantics?
Our immediate goal is not to change AlphaSynth or enable SongBook mode. We need
to determine the supported host-side strategy that preserves an exact musical
Loop endpoint without either hard-cutting trailing expressive automation or
playing the first excluded note.
We can provide a minimal GP reproduction, exact note flags, raw event streams,
and source locations if useful.
Thank you.
All reactions