Subscribe to the playhead and meters¶
Goal: get a live push feed of where the transport is and how loud the master
bus is — for a meter bridge, a progress display, a sync tool, or just to watch a
render. This is the streaming half of the gRPC lane:
Gloopy pushes Events to you rather than you polling.
Every subscription is one Subscribe call that opens a server stream. You choose
which event kinds you want and how often position updates arrive (interval_ms);
the stream runs until you stop reading it.
Event kinds¶
| Kind | Fields | When |
|---|---|---|
transport |
playing, bpm, position_beats |
Every interval_ms while subscribed |
meters |
peak_l, peak_r (per-channel), clipped |
Every interval_ms |
change |
kind, track_id, insert |
When the structure of the project changes |
Ask only for what you need — a meter bridge wants meters; a "reload when
someone else edits" tool wants change.
Python¶
subscribe is a generator that yields one dict per event until you stop
iterating. Bound it yourself — here with itertools.islice:
import itertools
from gloopy import Gloopy
with Gloopy() as g:
g.play()
for event in itertools.islice(g.subscribe(transport=True, meters=True), 20):
if event["kind"] == "transport":
print(f"beat {event['position_beats']:.2f}")
elif event["kind"] == "meters":
print(f"peak L/R {event['peak_l']} {event['peak_r']}")
g.stop()
interval_ms (default 100) controls how often transport/meters events fire.
To watch a whole render, iterate without islice and break when
position_beats passes the end of your song.
Common Lisp¶
subscribe collects events for roughly :seconds seconds and returns them as a
list of plists; pass :on-event to react to each as it streams in:
(in-package :gloopy)
(play)
(subscribe :transport t :meters t :seconds 3
:on-event (lambda (ev)
(case (getf ev :kind)
(:transport (format t "~&beat ~,2f~%" (getf ev :position-beats)))
(:meters (format t "~&peak ~a ~a~%"
(getf ev :peak-l) (getf ev :peak-r))))))
(stop)
:interval-ms (default 200) sets the update rate. The full return value is the
list of collected event plists, so you can also just bind it and inspect it at
the REPL:
See the Common Lisp client reference.
Raw gRPC (grpcurl)¶
No client library needed — the stream is a normal server-streaming RPC:
grpcurl -plaintext -proto proto/gloopy.proto -import-path proto \
-d '{"transport": true, "meters": true, "interval_ms": 200}' \
127.0.0.1:50051 gloopy.v1.Gloopy/Subscribe
Each streamed message is one Event; grpcurl prints them as JSON as they
arrive. Stop with Ctrl-C.
Notes¶
- Reads are gRPC, not OSC. The live OSC lane is send-only; to read transport or meters you subscribe over gRPC. (The Lisp OSC package is encode-only for the same reason.)
- Rendering doesn't need a subscription. An offline render is deterministic and blocks until done — subscribe only when you want to watch live playback.