musescore / musescore/MuseScore
Mixer: manual volume resets to 0 dB after enabling Solo and playing back
@RomanPudashkin is already working on this.
Since Aug 25, 2026.
- Dominant language
- C++
- Stars
- 15.1k
- Forks
- 3.3k
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 91
Description
Issue type
UX/Interaction bug (incorrect behaviour)
Description with steps to reproduce
Manually setting an instrument's volume in the Mixer gets silently discarded and reset to the default (0 dB) shortly after playback runs — even when no volume-automation curve was ever drawn on that track.
Steps to reproduce:
- Open the Mixer.
- Set an instrument's volume to -6 dB.
- Enable Solo on that instrument.
- Close the Mixer.
- Start playback, let it play 1-2 measures, then stop.
- Reopen the Mixer.
Actual behaviour:
The instrument's volume has reset to 0 dB (default), discarding the manual adjustment made in step 2.
Expected behaviour:
The manually set volume (-6 dB) should be preserved across playback, regardless of Solo/Mute state changes or automation.
Supporting files, videos and screenshots
https://github.com/user-attachments/assets/0d6c84e2-f29a-400c-a1a5-c0d18c12843b
In which versions of MuseScore Studio is this issue present?
MS 5 current main branch
Regression
Yes, this used to work in a previous version of MuseScore 4.x
Operating system
macos 26.2
Additional context
This appears to be an unintended side effect of the new Volume/Pan automation feature (PR #34474), not related to automation curve evaluation itself.
Code analysis (as of main):
PlaybackController::updateSoloMuteStates()(src/playback/internal/playbackcontroller.cpp, ~line 1629) is triggered by the Solo/Mute toggle. It rebuilds control params by callingtrackOutputParams(), which returns the value stored inIProjectAudioSettings::trackOutputParams()— i.e. the persisted value — rather than whatever the user last set live in the Mixer.MixerChannelItem::setVolumeLevel()/mixerpanelmodel.cpp(controlParamsChangedhandlers, ~lines 520/578/616) only push the new value to the live audio engine viaplayback()->setControlParams(...). They never callIProjectAudioSettings::setTrackOutputParams()to persist it — unlike fx-chain parameters, which ARE persisted correctly via a dedicated subscription inPlaybackController::subscribeOnAudioParamsChanges()(~lines 1491-1541).- As a result, any later call to
updateSoloMuteStates()(orresendAutomatedControlParams(), triggered by tempo/duration changes) re-sends the stale/default persisted value and overwrites the manual fader setting. - I verified this is NOT related to automation curve evaluation:
trackControlParams()only builds an automation envelope when explicitly asked to rebuild (rebuildVolume/rebuildPan = true), andupdateSoloMuteStates()calls it with both flagsfalse. No automation curve was drawn in the reproduction steps above, confirming the automation engine itself is not involved. - The PR #34474 description mentioned an intent to "restore manual values when automation ends," but I could not find this restoration logic currently implemented in
mixerchannelitem.cpp.
Suggested fix scope (not yet attempted, for information only):
Add a call to IProjectAudioSettings::setTrackOutputParams(instrumentTrackId, params) inside the controlParamsChanged handlers in mixerpanelmodel.cpp (~lines 520, 578, 616), alongside the existing live playback()->setControlParams(...) call, so manual Mixer changes are persisted at the moment they're made. This setter already exists and is used elsewhere (fx-chain persistence) — no new engine-side plumbing appears to be required.
Checklist
- This report follows the guidelines for reporting bugs and issues
- I have verified that this issue has not been logged before, by searching the issue tracker for similar issues
- I have attached all requested files and information to this report
- I have attempted to identify the root problem as concisely as possible, and have used minimal reproducible examples where possible
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.