Understanding the Effect Chain


I’ve been browsing the source code to try to understand the audio routing thought the effect chain. From zynthian_gui_engine.py lines 119ff:

if eng not in self.zyngines:

it seems that every plugin and therefore every effect is instantiated only ever once. But the screen tells me different: a hashtag sign and a number is appended for every new instance. Where does that happen?

From zynthian_autoconnect.py lines 171ff:

def get_fxchain_end(self, exclude=[]):
    for eng in reversed(self.zyngines):
        if eng in exclude:
        if 'system' in self.zyngines[eng].audio_out:
            return self.zyngines[eng]

I read that a new effect is first only connected to the next previous plugin? But that can be changed in the Layer Options.

Does it make a difference, which midi Channel I put an effect on?

The routing is redone every 2 seconds by zynthian_autoconnect.py including disconnecting and reconnedting everything. Does that not hurt audio continuity?


Hi @jgeisler0303!

Currently, there are some architectural limitations in the zynthian software. The next standalone engines:

  • ZynAddSubFX
  • FluidSynth
  • LinuxSampler
  • setBfree
  • Aeolus

Run as “multi-timbrical” engines, so only one instance exists and all layers using the same engine will use the same instance, having common audio/midi input/output.

It has advantages and drawbacks;


  • Lower memory usage
  • Faster layer creation
  • Allows using internal inter-layer routing, System FX and other related features (ZynAddSubFX)


  • common audio/midi input/output, that limit the routing possibilities
  • in some cases (ZynAddSubFX!!), limit to 1 CPU-core. Having several instances would allow every instance to use a different CPU-core.

Probably, sooner or later, the balance (having more memory!!) will end driving the development towards a multi-instance approach, but until then, we have to know and accept such limitations.

I’ve to improve this because is not very nice now. FX layers are really newcomers to Zynthian-UI …
Right now, MIDI channel should be relevant only for receiving MIDI CC messages (MIDI-learning).

Noooo! Not everything is disconnected my friend. Only what it’s not connected :wink:

#Connect to assigned ports and disconnect from the rest ...
for ao in input_ports:
		if ao in zyngine.audio_out:
			#logger.debug("Connecting to {} ...".format(ao))

Anyway, you shouldn’t be adding new FX layers in the middle of a performance, unless it’s a experimental Jam :crazy_face:

It’s better to do that work at home and save everything as snapshots.

Kind Regards,


Thanks for the detailed reply. That helps a lot in understanding!


Hi @jgeisler0303!

As you can read here:

and here:

the situation has improved quite a bit and now 2 of the more used engines have per-layer audio output, so you can set independent FX-chains for its layers.



Great stuff.

I’m currently digging into MIDI routing and getting a step sequencer to run.