Skip to content

(fix) FX units not working on all samplers - #15971

Merged
ywwg merged 1 commit into
mixxxdj:2.5from
ronso0:sampler-fx-fix
Feb 23, 2026
Merged

(fix) FX units not working on all samplers#15971
ywwg merged 1 commit into
mixxxdj:2.5from
ronso0:sampler-fx-fix

Conversation

@ronso0

@ronso0 ronso0 commented Feb 12, 2026

Copy link
Copy Markdown
Member

Fixes #15799

  • new profile (or just no effects.xml and effects dir)
  • load a track into sampler 5, play
  • assign FX1, load Echo etc., turn all on and turn Meta so there's some good feedback/filter effect
  • close, restart
  • enable Echo, press Play on sampler 5
    -> this PR: enjoy the noise : )
    -> 2.5: no echo. toggle Fx1 Off and On before engaging Echo & Co, then it works.

The root cause:
short: the fx I/O routing table is not updated instantly when additional samplers are added to the engine (or any inputs actually).

long:

  • CoreServices adds the default inputs (4 decks, 4 samplers, mics, aux etc.) and upon creation they are registered in EffectsManager
  • CoreServices then calls m_pEffectsManager->setup() which initializes all EngineEffectChains with the registred inputs/outputs
  • then samplers.xml is parsed and maybe more samplers are created -- same when a sampler bank is loaded manually or when we switch to a skin with more samplers
  • new inputs are registered in EffectsManager, then in each (standard) effect chain and the Fx routing CO states are also restored correctly (see GUI, FX1 on sampler 5)
    -> BUT the I/O maps used by EngineEffectChains are not updated, hence engaging an effect has no ..effect for those new inputs
    -> the I/O maps are extended for the new key, but ChannelHandleMap::maybeExpand abviously can't initialize the outputs map

The fix:

  • store the outputs map when creating EngineEffectChain(it won't change as no new outputs are added after EffectsManager::setup()-- afaict)
  • when registering and enabling a new input, use ChannelHandleMap[input] as before but then assign the stored output map

Maybe alternatively we could add a method EngineEffectChain::registerInputChannel and use a new EffectsRequest::MessageType to send the request via the message pipe.
But I doubt it has any benefits over the current fix. Does it?

@ronso0 ronso0 linked an issue Feb 12, 2026 that may be closed by this pull request
@ronso0 ronso0 added the effects label Feb 12, 2026
@ronso0 ronso0 added this to the 2.6.0 milestone Feb 16, 2026
Comment on lines +149 to +158
auto& outputMap = m_chainStatusForChannelMatrix[inputHandle];

if (outputMap.isEmpty()) {
// Apparently a request to enable an unregistered input.
// ChannelHandleMap's operator[] does maybeExpand(), so we now have an
// inputHandle key and we can assign our outputmap to it.
// Now request the map reference again and we're ready to roll...
m_chainStatusForChannelMatrix[inputHandle] = m_outputChannelMap;
outputMap = m_chainStatusForChannelMatrix[inputHandle];
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to avoid this pattern where we create a new variable, and then check to see ok, and then fix it if not. This creates an in-between state where the variable is invalid, and later down the line someone may accidentally put code in between.

By reordering this a little, we can do the assignment once and outputMap is always valid. It does technically do two lookups, but this map lookup is extremely fast, the map is small, and this function is not in a hot path.

Suggested change
auto& outputMap = m_chainStatusForChannelMatrix[inputHandle];
if (outputMap.isEmpty()) {
// Apparently a request to enable an unregistered input.
// ChannelHandleMap's operator[] does maybeExpand(), so we now have an
// inputHandle key and we can assign our outputmap to it.
// Now request the map reference again and we're ready to roll...
m_chainStatusForChannelMatrix[inputHandle] = m_outputChannelMap;
outputMap = m_chainStatusForChannelMatrix[inputHandle];
}
if (m_chainStatusForChannelMatrix[inputHandle].isEmpty()) {
// Apparently a request to enable an unregistered input.
// ChannelHandleMap's operator[] does maybeExpand(), so we now have an
// inputHandle key and we can assign our outputmap to it.
// Now request the map reference again and we're ready to roll...
m_chainStatusForChannelMatrix[inputHandle] = m_outputChannelMap;
}
auto& outputMap = m_chainStatusForChannelMatrix[inputHandle];

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, makes sense

@tuulikauri

Copy link
Copy Markdown

I tested the build artifact on Windows 11 x64. I confirmed these steps work. However I will note that when I first reloaded Mixxx, FX1 was not enabled on sampler 5. I believe that I had enabled it and left it enabled before quitting but I'm not 100% sure.

  • installed Windows x64 build artifact
  • new profile (or just no effects.xml and effects dir) -> Ran Mixxx from the Start Menu without changing any profile; I'm not sure how to make a new profile or check to have no effects dir? If this is important I can retest. Is it the same as creating a backup of the user settings directory (hmm.. manual is still down for me), ie rename the settings folder so Mixxx creates a new fresh directory?
  • load a track into sampler 5, play -> yup
  • assign FX1, load Echo etc., turn all on and turn Meta so there's some good feedback/filter effect -> yup
  • close, restart -> yup. When mixxx is restarted (after the first time? or user error maybe?) FX1 is enabled on deck 5 but the effects rack itself has everything turned off on restart
  • enable Echo, press Play on sampler 5
    -> this PR: enjoy the noise : ) -> yup
    -> 2.5: no echo. toggle Fx1 Off and On before engaging Echo & Co, then it works. -> didnt test

I didnt confirm the pre-fix (bugged) case.
Cheers!

@ronso0

ronso0 commented Feb 20, 2026

Copy link
Copy Markdown
Member Author

Thanks for testing!

FX1 is enabled on deck 5 but the effects rack itself has everything turned off on restart

That is on purpose so you can start playback whitout any potentially hidden effects being enabled.

@ronso0

ronso0 commented Feb 20, 2026

Copy link
Copy Markdown
Member Author

@ywwg You approved, let's merge?

@ywwg
ywwg merged commit 0a57d78 into mixxxdj:2.5 Feb 23, 2026
13 checks passed
@ronso0
ronso0 deleted the sampler-fx-fix branch February 23, 2026 17:58
@acolombier acolombier modified the milestones: 2.6.0, 2.5.5 Feb 25, 2026
@github-project-automation github-project-automation Bot moved this to Done in Releases Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

FX units not working on all samplers

4 participants