libossia
libossia copied to clipboard
ossia.device/client : add option to buffer parameter's value into bundle with data rate limitation
this should allow to limit the data rate for some protocol for specific use. Typical use case is to expose a device to Score over oscquery and over osc to Open Stage Control. Then Open Stage Control could run on a device connected over Wifi and we need to limit the data rate for that specific device / protocol.
To do so, we need to buffer all the messages and put them into a bundle and send that bundle at some rate. Bundle should contain only one value per parameter.
here is a proposal of messages syntax to expose a device to multiple protocols, and how to deal with bundles :
----------begin_max5_patcher----------
2303.3oc6b07iihiE+bZo9+AKNrpGozYwFyWygQZFs6kU6HMZu16nHGhSJOi
AyBlpqZGs+uuFaf.TjTDBjNGlCckDaC9898d98g8y8e7wOrxZm3EZtE36AeA
rZ0enZYktsxVVU2vJqXxKQbRtdfVQh3XZhzZcUmR5KRcGehc.jyER.KGP3YT
x9WArDPQNcMHhKxofHQRBMRxDI.RxdPFMkShn.l76ZdablZDhhD8qDU2ZZFM
WMmjxGc6vCIoHlkvoRMQBadPhL5IVxwsYp40vmHj2Fj6ZfCBtQ8AL.swV8K7
Favu15kIJj0uM65lOHRjIjXplc+wLFga0tqCJloCMw1qGoX2u8YOnktw+2G+
P4mpOVe6H9e+kTEr1gFxY+WMM.81Xe0PCztDJfNk3R.t76H2QBK07tyP7t8B
v6+TQxdtR2c1Xdrgimct2Mb5beI2tqPJEIM7ohpM.f0UygtNPMWE3n+vt9um
iEcNudO3mD78MTPlZ03dplk8rOA8b5QRzqk7PjfKx5PdloQ9ZJ0PaJ1w7OM6
8qsE2MO7W.1abvg1n0C7EXa9fcLQn3aNK526AJYJ1PRy1RSH63zNBx1xrfFd
a2wVyuF+r23GDfbbK+F121MHn2r2ni5r.58J6f6A4hXJngYxmfpfm1pGDEpU
B78dOcgAQI+GLM6Z14O0rOuls2rnYidXj7Pshr2eZR68D7tyhf+FBi4.WnDF
SYwsqQrpkttFYL57xXzIYbVLQ+R7tnLZGI4XKAzXQTbvzwhD5WUuh2ZcWjmy
HaxnwBIED+5OK1S4+03W+kRRZCZBXWnIjtvfVebIvy4c0lagTsAivuYJFPO2
GKECW66rhAb5JFFCmKnhgKb9AizZDXX919B7cPUNN9gkg466+dr8fK78s5LC
zrJlnlKTZXLN8YUjYp7UaKIVYQRSa09p1OTIy+aFyxAqO0FKwzF5TaYzmY0u
B6SMSxTbqTwpEYF+Zu3gsZ8lTHVVRASSPUsVJNpIMMtW5SLOsJcFs7oo+1JO
ZLzVid9HctRXXaTrzICWD86FOnMznkHklvRZmNe292SOPJ3xscxlCsY3ATm0
0v8Nbh5qrNlw1KRJIjtRlx1qmRkaQioE2N7jdHIjzgdbkhgBeNWu4JlsHeGI
qTvUY5nQfZIEBd29N8jb5AYU+orjj9.pTjdgdyXGe5RO8Ngp23K950ckusHw
z8VkRhbaN44dHujv4UKW6MCuPRXJqsTIyHOT9wa50XG8o7nLAm2kuMc87Pcs
Wo9GQ+Jau7I8j0Q8P8.rzZEKqSh88rizbYuFkji48ZJW9pQDztshcUKz2Jow
obE2zaDpUNrbY9ShulWMxZ0uNPwo8ZqyB+1FB61wE8TddK9WZuuJM3YL2OfG
yK307LdNGq2y20CZeqrvJGGqN47n1h02b7y7wCN9Y+3geXrIOMuvGe7ye9gu
twybw.75Ew+Df5pP57zNog3fwf0NuKn1MPu9XVviqJmM7wWky6APkCdypbvv
v6nJG9aAl0HTmiUp0NULFEg9WuJ5vv1YgLmGCHCdyPVsl1xCYnuEPVYBa79o
5d8fkuYUoiISer2XvJ3kwpyhSmMlsVYQUd9smKNXM4WNfyff4hhrnZxvnKuF
ziST4.HYIMIW9klvI0ib7xwqlVPilVrWbZIXrzh+hSJ9ikTBVbRAOVRwawIE
uwRJ3KRJ0cbZibrJSNe+Vy9QrkHkYrcERyJtN6Q0Ulq7QtXGg2K61Ayktghl
+S+7ye9GL0XxD1xSHBZJ7CiWCeyut1C8D6s.GpKI6XQYO.1AP0liAxSoQrCL
ZdUQ0reBbrJ1WMOFXNWTO2obLuX2Efi+JiyqpJHptJV.h7nqmC8cqDhlZ2vE
NIFDeuXv+SAM60IykPywzOQtz4FNtpXZdN4HcfpQPJRO2ZQzkJBKcU1TI1vv
2aW3uvYrN3gNfVhEo2hsGDz1HBctEaOH7BHBOocprP5uQQRafpu4fAXGzjEs
ULJrpVilSYqyRoGaOYl0rvb90iggKfdrxGSh.T6xYMPaopPoBHehBNvxxk.x
yDFub2JLJ7ex96lfyGOScVVcLQSz4CzaQU4ufA4QH1MbFzNb1k6KQLFJo7oR
FSI+ofcEGNPyn6AehkTYZSMRErLAwsmqSqBwwAOIgcvBv2Fev+Eftv41oqZT
vmJK+3HNkjAXIxxvY4Ufwz475xpzcZrt+BnmqY8JVdBVxcUrhI7QMmEV4zZN
0yWrPKynxhrDv2e8hSUrxkroK1VGhho9xtZw4RDRYZlPJhDbU5f0ltLNpCC7
892IMcC64L20yOnqy7arD58zEOgqmweGb7EPeaDBs.J7GoRPMLjOUy5tlRDw
e1sp+3E.N10eYBbw+gKFMGr6xvpKQL4kEPxMX2Fara6sTlswNKbdHSVHWs0N
y9RWL5dk4Uiw5aXUMp5b3l8buvvkOZ7StztgE6POc.5dyuhf8c.AlLeWsQeK
PFIN9KR.MpnuAblJiSwA.nLCERjj8b6aJ3YtgWnIc81vZ+61FrxT2hNtW6E+
6eRjBv+hdrfSxrNeU8ut0e5VI+s1KiV2ynhc8p8uplJeywpr0YlRJzd9qlVs
TvbjilRqaB6uUkGmppMw1YJ0UKbIR68W5nicZiMZBSr7Np9yjWJU4xEb57ot
EX2xKLJv9at1Fz9Nps8NF6lfEtJULctG3Y2.m6RUy9lkTf3W+aiYsUGoJD4h
C02NmPOa+fxuEDhgv92NmKfVNlPAle75MADYFU2S2uB+5e3n0n3aNTT2NGJ5
YNPTTqCDcPw0nmN38c5PN2Y1K7Nyed224yw+9NeX6677cmmNzcd9tyK+tyZK
A2Yz7ZLtTOnX19TgJ9n75M70YiuaS7atHTqn4p9kGRuOJNlQ5Y9uHg4vXk6L
P+dsnpEfFG0BjNEZ1MJSGkAbbv7MgiRoslrlgIzcT1.bsmuIbT1vcGVFVEhS
u6vmdt5e285eu8F3N6cg6q2atqdUk2k41I0O7plbE9GjXQLY6SriJr33Sxxx
.KijzDEd88iqGHQhhToN816Dt95faWEqYMTrtFvyTOyatrTVwpWulps6hYm4
xE9wOnFx+GXi5TeH
-----------end_max5_patcher-----------
this should be done on libossia network implementation layer, and this is not trivial
I think that maybe a way for that would be to have a custom "parameter" class ; when the device needs rate limiting it would create "rate_limited_parameter"'s which would have an internal timer to handle this properly.
the big question with timer is that there is always the issue of how to handle the last value, e.g. if we have :
x x x x x x x x x x y
messages being sent as a short burst and we only want e.g.
T T T T
we still likely also want the very last message to be sent at some point to make sure that the remote side is seeing the same thing:
x x x y
but now it is not just sufficient to do
if(current_time - last_time > rate_limit)
push_value(...)
but we also have to set a timer event that fires after "some time" when no message has been received
I just wrote another implementation : I added a buffer option to OSC protocol, when enabled all parameters changes are recorded and then sent inside a single bundle when needed.
This is exposed into Max with message [enable_buffering <index> <0|1>( and [send_buffer(.
Will test & push tomorrow
here is a patcher and an OpenStageControl setup to demonstrate this new feature osc_bundle_test.zip
@matcham could you check out this example and tell me if it works for you ?
Many thanks for exhuming this topic :-)
Looks like all received parameters values are stored and sent in the bundle ; in my experience , most of the time I only need the latest state of the parameter to be sent, and all intermediate values. That's how it works with Max openSoundControl external and with CNMAT odot library) typically, when used with openStageControl, no need to send all states to a slider, only the most recent one is needed. The goal of using bundle is this case is to spare some cpu cycle on the client, avoiding to redraw slider too often ; if all values are sent in the bundle, I guess that the slider will be redraw for each message.. so it probably won't improve anything :-s
Would it be possible to store only the latest state of a parameter in the bundle ? Or add an option to make it work this way ? (IMHO this should be the default behavior ; having multiple values for one parameter inside one bundle make sens when using timetag... but that's another story ;-)
Ircam spat5 has it's own OSC collection of external too.
Last year I sent them a FR on this topic
https://discussion.forum.ircam.fr/t/how-to-make-spat5-osc-collect-behave-like-o-collect-remove-duplicated-addresses/26258/3
and they added these cool feature to spat5.osc.unique :
3 different modes to deal with duplicate address pattern in a bundle
this is very nice, and I think it covers all cases.
Looks like all received parameters values are stored and sent in the bundle
yes, that's how it has been implemented
if all values are sent in the bundle, I guess that the slider will be redraw for each message..
not if it has been well designed :-) usually GUI refresh rate is limited by the screen refresh rate at most
Would it be possible to store only the latest state of a parameter in the bundle ?
yes, but it is a bit harder and slower to implement ;-) and spat options are nice I'll think about implementing them as well