Skip to content

Rate limit outgoing OSC messages per route#53

Open
paul-toben wants to merge 1 commit into
ETCLabs:masterfrom
paul-toben:rate-limit
Open

Rate limit outgoing OSC messages per route#53
paul-toben wants to merge 1 commit into
ETCLabs:masterfrom
paul-toben:rate-limit

Conversation

@paul-toben
Copy link
Copy Markdown

@paul-toben paul-toben commented May 8, 2026

Adds a per-destination Max Rate (Hz) field to each route. When set, the route emits at most N OSC messages per second to that destination.

Behavior

  • OSC outputs only. sACN/ArtNet/MIDI/OTP/PSN destinations are unaffected.
  • 0 = unlimited. Existing configs are unchanged.
  • The rate-limit timer only advances on a real send, so a long stationary period followed by a sudden change emits immediately rather than waiting another full period.

Implementation

  • Per-destination dispatch in ProcessRecvPacket was extracted into DispatchBuiltPacket, which returns whether a real send happened. Both the immediate-send path and the deferred-flush path go through it.
  • FlushPendingRateLimited runs once per main loop iteration after the TCP-clients section and emits any pending coalesced packets whose period has elapsed.
  • Config: one new optional trailing column in .osc.txt (maxRateHz). Old configs load unchanged; new configs round-trip.
  • UI: one new "Max Rate (Hz)" column in the route table editor.

Notes

  • Send-on-change is a related feature that pairs well with this, but in its own PR to follow

Adds a per-destination "Max Rate (Hz)" field that caps how often a route
emits OSC messages. Coalesce semantics: when input arrives faster than
the configured rate, only the most recent message survives the period
and is emitted at the next interval boundary; nothing is sent during
silence.

Useful for streaming sources (PSN, ArtNet/sACN-driven OSC bridges) where
the input rate can saturate downstream consoles.

Scope: OSC outputs only. sACN, ArtNet, MIDI, OTP, and PSN destinations
are unaffected. Default 0 = unlimited; existing configs are unchanged.

Refactor: per-destination dispatch in ProcessRecvPacket extracted into
DispatchBuiltPacket, which returns whether a real send happened so the
rate-limit timer only advances on actual sends. The flush pass runs
once per main loop iteration after the TCP-clients section.
@paul-toben
Copy link
Copy Markdown
Author

@MizPlusPlus This code is 99% written with AI and while I've looked it over and tested it, I haven't written any C since college. If the code is helpful, great. If it's not, I hope the framework for the features might be.

@paul-toben paul-toben marked this pull request as ready for review May 8, 2026 01:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant