summaryrefslogtreecommitdiffstats
path: root/osc_ctrl.py
blob: 3c19cd96089db0667a9e4497267dee289ef3d005 (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env python3

import argparse
import random
import time
import fileinput

from pythonosc import udp_client
from math import ceil
from math import floor
from generate_utils import getLayerParam
from generate_utils import getSelectParam
from generate_utils import getEnableParam
from generate_utils import getBoardIndex
from generate_utils import NUM_LAYERS
from generate_utils import BOARD_ROWS
from generate_utils import BOARD_COLS

def usage():
    print("python3 -m pip install python-osc")
    print("python3 ./osc_ctrl.py")

parser = argparse.ArgumentParser()
parser.add_argument("-i", default="127.0.0.1", help="OSC server IP")
parser.add_argument("-p", type=int, default=9000, help="OSC server port")
args = parser.parse_args()

client = udp_client.SimpleUDPClient(args.i, args.p)

def encodeMessage(msg):
    result = []
    for char in msg:
        char_int = ord(char)
        if char_int >= ord('A') and char_int <= ord('Z'):
            result.append(ord(char) - ord('A'))
        elif char >= 'a' and char <= 'z':
            result.append((ord(char) - ord('a')) + 26)
        elif char >= '0' and char <= '9':
            result.append((ord(char) - ord('0')) + 52)
        elif char == '.':
            result.append(62)
        elif char == ',':
            result.append(63)
        elif char == ' ':
            result.append(64)
    # Pad message with spaces so that it overwrites any leftover text.
    result += [65] * (BOARD_ROWS * BOARD_COLS - len(result))
    return result

# `which_cell` is an integer in the range [0,8).
def sendMessageCell(msg_cell, which_cell):

    s0 = ((floor(which_cell / 4) % 2) == 1)
    s1 = ((floor(which_cell / 2) % 2) == 1)
    s2 = ((floor(which_cell / 1) % 2) == 1)

    print("Cell s0/s1/s2: {}/{}/{}".format(s0,s1,s2))
    # Seek each layer to the current cell.
    for i in range(0, len(msg_cell)):
        print("Board index: {}".format(getBoardIndex(i, s0, s1, s2)))

        addr="/avatar/parameters/" + getLayerParam(i)
        client.send_message(addr, msg_cell[i])

        addr="/avatar/parameters/" + getSelectParam(i, 0)
        client.send_message(addr, (floor(which_cell / 4) % 2) == 1)

        addr="/avatar/parameters/" + getSelectParam(i, 1)
        client.send_message(addr, (floor(which_cell / 2) % 2) == 1)

        addr="/avatar/parameters/" + getSelectParam(i, 2)
        client.send_message(addr, (which_cell % 2) == 1)

    # Wait for convergence.
    time.sleep(0.3)

    # Enable each layer.
    # TODO(yum_food) for some reason, if we don't active every layer, the
    # desired subset won't reliably fire. Why?
    for i in range(0, NUM_LAYERS):
        addr="/avatar/parameters/" + getEnableParam(i)
        client.send_message(addr, True)

    # Wait for convergence.
    time.sleep(0.3)

    # Disable each layer.
    for i in range(0, NUM_LAYERS):
        addr="/avatar/parameters/" + getEnableParam(i)
        client.send_message(addr, False)

    # Wait for convergence.
    time.sleep(0.3)

def sendMessage(msg):
    # The board is broken down into contiguous collections of characters called
    # cells. Each cell contains `NUM_LAYERS` characters. We can update one cell
    # every ~1.0 seconds; going faster causes the board to display garbage to
    # remote players.
    msg = encodeMessage(msg)

    n_cells = ceil(len(msg) / NUM_LAYERS)
    for cell in range(0, n_cells):
        cell_begin = cell * NUM_LAYERS
        cell_end = (cell + 1) * NUM_LAYERS
        cell_msg = msg[cell_begin:cell_end]
        print("Send cell {}".format(cell))
        sendMessageCell(cell_msg, cell)

for line in fileinput.input():
    sendMessage(line)

sendMessage("")