In the image below (also see the patch further down):
TModClockGen = class( TMod) strict private const i_reset = 0; i_tempo = 1; i_swing = 2; i_mute = 3; i_div = 4; const o_16 = 0; o_96 = 1; o_sync = 2; o_phase16 = 3; o_phase96 = 4; private FPhase16 : TSignal; // Phase acuumulator for * 16 output FPhase96 : TSignal; // Phase acuumulator for * 96 output FOldRes : Boolean; // Old reset value FOldMute : Boolean; // Old mute state FEven : Boolean; // Even / Odd cycle for * 16 output FState : Boolean; // * 96 state FSwing : TSignal; // Current Swing value FDividerSync : Integer; // Divider for sync output FResCount : Integer; // Reset LED counter public constructor Create( aParent: TSynthPatch; const aName: string); override; procedure DoSlowTick; override; procedure GatherLights( const aPrefix: string; const aCallback: TLightsHandler); override; function InputName ( anIndex: Integer): string; override; function OutputName( anIndex: Integer): string; override; end; procedure TModClockGen.DoSlowTick; // override; var Delta96 : TSignal; Delta16 : TSignal; DidWrap : Boolean; Muted : Boolean; Reset : Boolean; SyncDiv : Integer; begin Reset := SignalToLogic( FInputs[ i_reset]); Muted := SignalToMute ( FInputs[ i_mute ]) < 0.5; SyncDiv := Round( FInputs[ i_div]); if ResetFlag or ( not FOldRes and Reset) or ( FOldMute and not Muted) then begin FPhase96 := 0.0; FPhase16 := 0.0; FEven := True; FState := True; FDividerSync := 0; FResCount := Round( SlowTimeToSampleCount( 125e-3)); FSwing := 0.5; end; ResetFlag := False; FOldRes := Reset; FOldMute := Muted; Delta96 := LookupLfoBPMPhaseDelta( FInputs[ i_tempo]) * 24; Delta16 := LookupLfoBPMPhaseDelta( FInputs[ i_tempo]) * 4; FPhase96 := FPhase96 + Delta96; FPhase16 := FPhase16 + Delta16; DidWrap := False; while FPhase96 > 1.0 do begin if not DidWrap then begin DidWrap := True; FState := True; Inc( FDividerSync); if FDividerSync > 24 * SyncDiv - 1 then FDividerSync := 0; end; FPhase96 := FPhase96 - 1.0; end; if FState then begin if FPhase96 > 0.5 then FState := False; end; DidWrap := False; while FPhase16 > 1.0 do begin if not DidWrap then begin DidWrap := True; FEven := not FEven; if FEven then FSwing := 0.5 else FSwing := FInputs[ i_swing]; end; FPhase16 := FPhase16 - 1.0; end; if FResCount > 0 then Dec( FResCount); if Muted then begin FOutputs[ o_16 ] := LogicToSignal( False); FOutputs[ o_96 ] := LogicToSignal( False); FOutputs[ o_sync ] := LogicToSignal( False); FOutputs[ o_phase16] := 0; FOutputs[ o_phase96] := 0; end else begin FOutputs[ o_16 ] := LogicToSignal( FPhase16 > FSwing); FOutputs[ o_96 ] := LogicToSignal( FState ); FOutputs[ o_sync ] := LogicToSignal( FDividerSync = 0 ); FOutputs[ o_phase16] := FPhase16; FOutputs[ o_phase96] := FPhase96; end; end;