class EchoTransform:
def g2g_process(self, buf, width, height, fmt, meta):
mv = memoryview(buf)
assert not mv.readonly, "frame buffer must be writable"
assert mv.nbytes == width * height * 4, "expected RGBA geometry"
mv[0] = (mv[0] + 1) % 256
meta.add_object(7, 1.0, 2.0, 3.0, 4.0, 0.9)
meta.add_blob("embedding", bytes([1, 2, 3, 4]))
def g2g_process_batch(self, buffers, width, height, fmt, meta):
total = 0
for b in buffers:
total = (total + memoryview(b)[0]) % 256
memoryview(buffers[0])[0] = total
meta.add_object(len(buffers), 0.0, 0.0, 1.0, 1.0, 1.0)
class AudioTranscriber:
def g2g_process_payload(self, buffers, caps, meta):
samples = memoryview(buffers[0])
assert not samples.readonly, "payload buffer must be writable"
meta.add_blob("caps", caps.encode("utf-8"))
meta.emit(("heard %d bytes" % samples.nbytes).encode("utf-8"))
class SpeechSynthesizer:
SAMPLE_RATE = 16000
SAMPLES_PER_CHARACTER = 100
BYTES_PER_SAMPLE = 2
def g2g_process_payload(self, buffers, caps, meta):
text = bytes(memoryview(buffers[0]))
samples = len(text) * self.SAMPLES_PER_CHARACTER
meta.emit(
bytes(samples * self.BYTES_PER_SAMPLE),
duration_ns=samples * 1_000_000_000 // self.SAMPLE_RATE,
)
class ChunkedSynthesizer:
CHUNKS = 3
def g2g_process_payload(self, buffers, caps, meta):
text = bytes(memoryview(buffers[0]))
for chunk in range(self.CHUNKS):
meta.emit(text + str(chunk).encode("utf-8"))
class StreamingSynthesizer:
def g2g_process_payload(self, buffers, caps, meta):
text = bytes(memoryview(buffers[0]))
for chunk in range(self.chunks):
meta.emit(
text + str(chunk).encode("utf-8"),
duration_ns=self.chunk_duration,
pts_ns=self.first_pts + chunk * self.chunk_duration,
)
class UnstampedSynthesizer:
def g2g_process_payload(self, buffers, caps, meta):
import g2g
meta.emit(bytes(memoryview(buffers[0])), pts_ns=g2g.PTS_NONE)
class ThreadedTransform:
def g2g_process(self, buf, width, height, fmt, meta):
import threading
err = []
def work():
try:
meta.add_object(11, 0.0, 0.0, 1.0, 1.0, 0.5)
except BaseException as e: err.append(repr(e))
t = threading.Thread(target=work)
t.start()
t.join() if err:
raise RuntimeError("cross-thread add_object failed: " + err[0])
class RetainingTransform:
def g2g_process(self, buf, width, height, fmt, meta):
self.saved = memoryview(buf)
class CounterSource:
def __init__(self):
self.n = 0
def g2g_produce(self, buf, width, height, fmt, meta):
if self.n >= 3:
return False memoryview(buf)[0] = self.n
self.n += 1
return True
class PropEcho:
def g2g_process(self, buf, width, height, fmt, meta):
model = getattr(self, "model_name", "<unset>")
device = getattr(self, "device", "<unset>")
batch = getattr(self, "batch_size", 0)
meta.add_blob("model_name", model.encode("utf-8"))
meta.add_blob("device", device.encode("utf-8"))
meta.add_blob("language", getattr(self, "language", "<unset>").encode("utf-8"))
meta.add_object(batch, 0.0, 0.0, 1.0, 1.0, 1.0)
def g2g_process_batch(self, buffers, width, height, fmt, meta):
self.g2g_process(buffers[0], width, height, fmt, meta)
class DeclaredProps:
def g2g_properties(self):
return ["model_name", "device"]
def g2g_process(self, buf, width, height, fmt, meta):
meta.add_blob("model_name", getattr(self, "model_name", "<unset>").encode("utf-8"))