Skip to content

fix(midi): fade via expression and restore it with the voice's next note - #2995

Merged
Danielku15 merged 1 commit into
developfrom
feature/issue-2978
Oct 29, 2026
Merged

Danielku15 merged 1 commit into
developfrom
feature/issue-2978

Conversation

@Danielku15

@Danielku15 Danielku15 commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

Note

AI-authored disclosure (alphatab-ai-authored-v1)

Portions of this content were authored by an AI agent. The agent has read
AGENTS.md and the human submitter accepts responsibility for
compliance with the rules in that document.

Issues

Fixes #2978

Proposed changes

Fade in, fade out and volume swell ramped the channel volume (CC7) and never restored it. After a fade out or volume swell the rest of the track was silent, and changeTrackVolume could not help because it scales that zeroed volume. Fades also ramped from or to the static track volume, ignoring volume automations.

Fades now ramp the expression controller (CC11) instead. The synth multiplies volume and expression, so a fade scales whatever volume is in effect, and volume automations and the track volume keep working. This is also the usual split in MIDI (CC7 for the mixer level, CC11 for performance dynamics), so exported MIDI files behave the same way in other software.

After a fade out or volume swell, the expression is restored when the same voice plays its next non-rest beat, at that beat's real start tick. Restoring at the end of the faded beat would make the release of the faded note audible again (about −7 dB for roughly 250 ms with the default SoundFont) whenever a rest follows. Because generation follows play order, repeats, jumps, triplet feel and grace notes need no extra handling. A following fade beat sets the expression with its own ramp. Single-beat playback restores at the end of the beat.

Known limitations, accepted to keep this simple:

  • Expression is per channel: other voices or staves of the same track stay faded until the fading voice plays its next note.
  • A note tied out of a faded beat comes back at full level at its tie destination.

Tests cover the fade ramps, the restore after rests across bars, repeats, Scottish triplet feel, a fade out into a fade in, volume automation staying intact, and an audio render checking that the rest after a fade out stays silent and the following notes are audible.

Checklist

  • I consent that this change becomes part of alphaTab under its current or any future open source license
  • This PR is linked to an accepted issue (see above)
  • Changes are implemented
  • New tests were added
  • I have read AGENTS.md if an AI helped draft any part of this PR

AI authorship disclosure

  • No AI agent authored any part of this PR (description, code, tests, or commit messages)
  • An AI agent contributed to this PR. The AI-authored disclosure block
    (alphatab-ai-authored-v1) is present at the top of this body, and I have
    personally reviewed every change and can explain each one

Further details

  • This is a breaking change
  • This change will require update of the documentation/website

@Danielku15 Danielku15 changed the title fix(midi): fade via expression and restore it before the next note fix(midi): fade via expression and restore it with the voice's next note Oct 29, 2026
Fade in, fade out and volume swell ramped the channel volume and never
restored it, silencing the rest of the track and overriding volume
automations. Fades now ramp the expression controller, and after a fade out
or volume swell the expression is restored when the same voice plays its
next non-rest beat.

Fixes #2978
@Danielku15
Danielku15 merged commit 3984b32 into develop Oct 29, 2026
5 checks passed
@Danielku15
Danielku15 deleted the feature/issue-2978 branch October 29, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fade out: track silent until the end

1 participant