diff options
-rw-r--r-- | host/matelight.py | 3 | ||||
-rwxr-xr-x | host/server.py | 133 | ||||
-rw-r--r-- | host/usb.c | 7 |
3 files changed, 89 insertions, 54 deletions
diff --git a/host/matelight.py b/host/matelight.py index 5b869e6..6d0f5bf 100644 --- a/host/matelight.py +++ b/host/matelight.py @@ -36,8 +36,9 @@ def sendframe(framedata): channel is ignored. """ # just use the first Mate Light available + w,h,c = framedata.shape buf = framedata.ctypes.data_as(POINTER(c_uint8)) - ml.matelight_send_frame(matelights, buf, c_size_t(CRATES_X), c_size_t(CRATES_Y), c_float(BRIGHTNESS), True) + ml.matelight_send_frame(matelights, buf, c_size_t(CRATES_X), c_size_t(CRATES_Y), c_float(BRIGHTNESS), c == 4) if __name__ == '__main__': #foo = np.array([[(0, 0, 0, 0)]*DISPLAY_WIDTH]*DISPLAY_HEIGHT) diff --git a/host/server.py b/host/server.py index 3b9590c..a8be98b 100755 --- a/host/server.py +++ b/host/server.py @@ -2,7 +2,7 @@ from socketserver import * from time import time, strftime, sleep -from collections import namedtuple +from collections import namedtuple, deque from itertools import product, cycle import threading import random @@ -58,16 +58,6 @@ def printframe(fb): print('\033[0m\033[KCurrently rendering', current_entry.entrytype, 'from', current_entry.remote, ':', current_entry.text, '\0338', end='') printlock.release() -def scroll(text): - """ Returns whether it could scroll all the text uninterrupted """ - #log('Scrolling', text) - w,h = compute_text_bounds(text) - for i in range(-DISPLAY_WIDTH,w+1): - fb = render_text(text, i); - sendframe(fb) - printframe(fb) - return True - QueueEntry = namedtuple('QueueEntry', ['entrytype', 'remote', 'timestamp', 'text']) defaultlines = [ QueueEntry('text', '127.0.0.1', 0, l[:-1].replace('\\x1B', '\x1B')) for l in open('default.lines').readlines() ] random.shuffle(defaultlines) @@ -81,29 +71,47 @@ def log(*args): print(strftime('\x1B[93m[%m-%d %H:%M:%S]\x1B[0m'), ' '.join(str(arg) for arg in args), '\x1B[0m') printlock.release() - class MateLightUDPServer(UDPServer): - """ - The server class for the SocketServer interface. - """ - def __init__(self, *args, **kwargs): - """ - Setup the deque for the frame - """ - super(MateLightUDPServer, self).__init__(*args, **kwargs) - self.frame_deque = collections.deque(maxlen=30) - - def get_next_frame(self): - try: - return self.frame_deque.popleft() - except IndexError: - return None - + """ + The server class for the SocketServer interface. + """ + def __init__(self, *args, **kwargs): + """ + Setup the deque for the frame + """ + super(MateLightUDPServer, self).__init__(*args, **kwargs) + self.frame_deque = deque(maxlen=30) + + def get_next_frame(self): + try: + return self.frame_deque.popleft() + except IndexError: + return None + +class MateLightTCPServer(TCPServer): + def __init__(self, *args, **kwargs): + super(MateLightTCPServer, self).__init__(*args, **kwargs) + # A deque for the texts, contains a tuple of the form (text, width, height) + self.text_deque = deque(maxlen=32) + self.current_text = None + + def get_next_frame(self): + if self.current_text is None or self.i > self.current_text[1][0]: + self.current_text = None + try: + self.current_text = self.text_deque.popleft() + self.i = -DISPLAY_WIDTH + except IndexError: + return None + + frame = render_text(self.current_text[0], self.i) + self.i += 1 + return frame class MateLightUDPHandler(BaseRequestHandler): - """ - Handles one UDP connection to the matelight - """ + """ + Handles one UDP connection to the matelight + """ def handle(self): try: # Housekeeping - FIXME: This is *so* the wrong place for this. @@ -132,10 +140,10 @@ class MateLightUDPHandler(BaseRequestHandler): conns[addr] = current_entry if current_entry.entrytype == 'udp' and current_entry.remote == addr: current_entry = conn - frame = a.reshape((DISPLAY_HEIGHT, DISPLAY_WIDTH, 3)) - self.server.frame_deque.append(frame) + frame = a.reshape((DISPLAY_WIDTH, DISPLAY_HEIGHT, 3)) + self.server.frame_deque.append(frame) #sendframe(frame) - #printframe(np.pad(frame, ((0,0),(0,0),(0,1)), 'constant', constant_values=(0,0))) + printframe(np.pad(frame, ((0,0),(0,0),(0,1)), 'constant', constant_values=(0,0))) except Exception as e: log('Error receiving UDP frame:', e) @@ -149,14 +157,15 @@ class MateLightTCPTextHandler(BaseRequestHandler): self.request.sendall('TOO MUCH INFORMATION!\n') return log('\x1B[95mText from\x1B[0m {}: {}\x1B[0m'.format(addr, data)) - textqueue.append(QueueEntry('text', addr, timestamp, data)) + #textqueue.append(QueueEntry('text', addr, timestamp, data)) + self.server.text_deque.append((data, compute_text_bounds(data))) self.request.sendall(b'KTHXBYE!\n') -#TCPServer.allow_reuse_address = True -#server = TCPServer(('', 1337), MateLightTCPTextHandler) -#t = threading.Thread(target=server.serve_forever) -#t.daemon = True -#t.start() +TCPServer.allow_reuse_address = True +tserver = MateLightTCPServer(('', 1337), MateLightTCPTextHandler) +t = threading.Thread(target=tserver.serve_forever) +t.daemon = True +t.start() UDPServer.allow_reuse_address = True userver = MateLightUDPServer(('', 1337), MateLightUDPHandler) @@ -164,19 +173,39 @@ t = threading.Thread(target=userver.serve_forever) t.daemon = True t.start() +def udp_sub_loop(): + """ + If we can get at least one frame from get_next_frame() we will wait + for 1000 frame cycles till we return. If we do not get a valid frame + in the first loop, we return immediatly. + """ + invalid_frames = 300 + while True: + next_frame = userver.get_next_frame() + if next_frame is not None: + invalid_frames = 0 + sendframe(next_frame) + sleep(0.01) + else: + invalid_frames += 1 + sleep(0.01) + if invalid_frames > 300: + break + +def tcp_sub_loop(): + while True: + next_frame = tserver.get_next_frame() + if next_frame is not None: + sendframe(next_frame) + else: + break + if __name__ == '__main__': - while True: - millis = int(round(time.time() * 1000)) - - next_frame = userver.get_next_frame() - if next_frame: - sendframe(next_frame) - - while int(round(time.time() * 1000)) - millis < 50: - // do nothing - pass - - + while True: + udp_sub_loop() + tcp_sub_loop() + + def bla(): print('\033[2J'+'\n'*9) while True: @@ -116,7 +116,12 @@ int matelight_send_frame(matelight_handle *ml, void *buf, size_t w, size_t h, fl for(size_t y=0; y<CRATE_HEIGHT; y++){ size_t dpos = y*CRATE_WIDTH + x; size_t spos = w*CRATE_WIDTH*(cy*CRATE_HEIGHT+y) + cx*CRATE_WIDTH+x; - color_t *src = (((color_t*)buf)+spos); + color_t *src; + if(alpha){ + src = (((color_t*)buf)+spos); + }else{ + src = (color_t*)(((rgb_t*)buf)+spos); + } rgb_t *dst = frame.buf+dpos; /* Gamma correction */ #define GAMMA_APPLY(c) ((uint8_t)roundf(powf((c/255.0F), GAMMA) * brightness * 255)) |