Every signal Slot connection makes the code a little more confusing because you cannot generate a call tree in the IDE. 
Dynamically connected signals makes the thing worse.

For me it looks like that the RateControl is the key Object of the Sync feature. So why not register the EngineSync object at the RateControl and use direct calls to EngineSync.  

This is the current call tree, pRateControl is passed thought the call stack, but pRateControl is the owner of CO "sync_state" and knows already how to behave. 

RateControl::m_pSyncState = new ControlObject(ConfigKey(_group, "sync_state"));
m_pSyncState, SIGNAL(valueChanged(double)
RateControl::slotSyncStateChanged
emit(channelSyncStateChanged(RateControl*, double)
EngineSync::slotChannelSyncStateChanged(RateControl* pRateControl, double state)
EngineSync::setMaster
EngineSync::setChannelMaster(RateControl* pRateControl)
-> dynamic connections 

With a RateControl::m_pEngineSync RateControl can decide itself if it has to make master or slave calls.  
I hope the code get much easer to read then and we can get rid of some of the call tree above.