Dynamic effect chains
The goal of this part of the project is to make changes in the effects chain have effect immediately, so if you add a ladspa plugin, or Eq to the chain, you won’t have to wait for the next song, when the chain is rebuilt, to hear it.
So, I’ve been looking at the code that builds the xform chain, the code that processes the chain, and the code that handles changes in effect chain config properties (currently only the effect.order.X properties exist).
Chains are created in the xmms_output_filler() function in output.c. This function runs a loop continuously filling the output buffer from the output of the xform chain, but it checks if the chain exists before doing this. If the chain doesn’t exist, it calls the xmms_xform_chain_setup() function from xform.c.This function returns the pointer to the last element of the chain. It calls xmms_xform_chain_setup_url() which finds the correct decoder for the current media, inserts a segment plugin (to keep track of time) after it and then builds the effects chain by calling add_effects(). This function needs to be passed as arguments the last xform, where the effects chain will be attached, the medialib entry url and the goal formats. Finally, the add_effects() function scans the effect.order.X config properties, intializing the plugins.
In the xform.c file, the update_effect_properties() function is the callback when effect chain properties change. This callback currently only checks whether the plugin exists, registers the “enabled” property for it and creates a new empty effect.order slot after the last one.
What needs to be done
My plan is that when a change in the effect.order.X config properties takes place (the update_effect_propeties() function is called), it will force a rebuild of the effects part of the xform chain. I toyed with the idea of just moving and inserting new items, but that would require more subtantial modifications to the xform basic structures, to make the chain more aware of its members and its state. This is something I think is unnecessary in this context, as rebuilding the chain should be fast enough for most situations and where there could be minor glitches in the audio, that could be something the user would expect and accept since he is adding or removing an effect.
What will happen is that whenever the config property is changed, the xform object will be marked as needing refresh. This will be picked up by the loop in xmms_output_filler and thelower part of the chain will be rebuilt.
The data passed to the update_effect_properties callback needs to be changed to include enough to do number 1 above and to mark that the chain needs remaking. Currently the callback data is used to pass only the number of effects in the chain, to be able to add an empty element at the end.
For each effect, their seek function must be called, in case they depend on the current song position and time. The value must be acquired from the segment plugin just before building the chain.