summaryrefslogtreecommitdiffstats
path: root/Scripts/text_to_text_demo.py
blob: 48103612c9d2b31e1c3372822ea3df7b18d0fe40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/env python3
# python3 -m pip install python-osc pillow

from math import ceil
from paging import MultiLinePager
from pythonosc import udp_client

import generate_utils
import osc_ctrl
import time

class AppConfig:
    def __init__(self,
            rows: int = 4,
            cols: int = 40,
            chars_per_sync: int = 10,
            osc_sync_rate_hz: int = 3):
        self.rows = rows
        self.cols = cols
        self.chars_per_sync = chars_per_sync
        self.osc_sync_rate_hz = osc_sync_rate_hz
        self.client = osc_ctrl.getClient()

def encodeMessage(msg):
    encoded = []
    for char in msg:
        encoded.append(ord(char))
    return encoded

class OSCSyncHelper:
    def __init__(self,
            config: AppConfig):
        self.sync_delay_s = 1.0 / config.osc_sync_rate_hz
        self.last = time.time() - self.sync_delay_s

    def waitForSync(self) -> None:
        # sleep() can sleep for too short a time, so use a loop to ensure that
        # we sleep at least a full sync window's worth of time.
        while time.time() - self.last < self.sync_delay_s:
            time.sleep(0.01)
        self.last = time.time()

def sendMessage(msg: str, cfg: AppConfig, osc: OSCSyncHelper) -> None:
    num_cells = cfg.rows * cfg.cols
    num_regions = ceil(num_cells / cfg.chars_per_sync)

    pager = MultiLinePager(cfg.chars_per_sync, cfg.rows, cfg.cols)

    # Show the chatbox
    osc.waitForSync()
    osc_ctrl.toggleBoard(cfg.client, True)
    osc_ctrl.ellipsis(cfg.client, False)
    osc_ctrl.disable(cfg.client)

    # Ensure that the chatbox is cleared.
    addr="/avatar/parameters/" + generate_utils.getClearBoardParam()
    cfg.client.send_message(addr, True)
    osc.waitForSync()
    cfg.client.send_message(addr, False)

    slice_idx = 0
    while slice_idx != -1:

        msg_slice, slice_idx = pager.getNextSlice(msg)
        which_region = slice_idx % num_regions

        print(f"Sending slice '{msg_slice}' to region {which_region}")

        # Wait until OSC has had enough time to sync the previous window of
        # data.
        osc.waitForSync()

        # Enable chatbox animations.
        osc_ctrl.enable(cfg.client)

        # Seek to the current region.
        addr="/avatar/parameters/" + generate_utils.getSelectParam()
        cfg.client.send_message(addr, which_region)

        # Send all characters in the current region.
        encoded = encodeMessage(msg_slice)
        for i in range(0, len(msg_slice)):
            print(f"Sending char {msg_slice[i]} / {encoded[i]}")
            addr="/avatar/parameters/" + generate_utils.getBlendParam(i, 0)
            letter_remapped = (-127.5 + encoded[i]) / 127.5
            cfg.client.send_message(addr, letter_remapped)

    # Disable chatbox animations to ensure stability.
    osc.waitForSync()
    osc_ctrl.disable(cfg.client)

if __name__ == "__main__":
    cfg = AppConfig()
    osc = OSCSyncHelper(cfg)
    sendMessage("Hello, world! aiueo aiueo aiueo aiueo aiueo eeeeeeeeeeeeeeeeeeeeeeee", cfg, osc)