utils/pianoroll-client.py
author rougeronj
Thu, 16 Apr 2015 12:15:33 +0200
changeset 153 60bd2b36b9dc
parent 93 79ae42ad97d4
permissions -rw-r--r--
put showTime as an option and add it to static pianoroll template on server

#!/usr/bin/env python
"""
Example of a UDP txosc sender with Twisted.

This example is in the public domain.
"""

import argparse
import csv
import signal
import time

import ntplib
from twisted.internet import reactor
from txosc import osc
from txosc import async


class UDPSenderApplication(object):
    """
    Example that sends UDP messages.
    """
    def __init__(self, port, host, address, rows, shift, token):
        self.port = port
        self.host = host
        self.client = async.DatagramClientProtocol()
        self._client_port = reactor.listenUDP(0, self.client)
        self.rows = rows
        self.address = address
        self.shift = shift
        self.token = token
        reactor.callLater(0, self.send_messages)

    def _send(self, element):
        # This method is defined only to simplify the example
        self.client.send(element, (self.host, self.port))
        print("Sent %s to %s:%d" % (element, self.host, self.port))

    def send_messages(self):
        t0 = time.time()
        #tc = 0
        for row in self.rows:
            if not self.token.running:
                break
            if self.shift:
                row[0] = ntplib.system_to_ntp_time(t0 + float(row[1])/1000.0)
            row_conv = [ osc.TimeTagArgument(float(row[0]))] + [osc.IntArgument(int(a)) for a in row[1:]]
            #time.sleep((row_conv[1].value-tc)/1000.0)
            sleep_time = t0+float(row[1])/1000.0-time.time()
            if sleep_time > 0:
                time.sleep(sleep_time)
            #time.sleep(0.1)
            tc = row_conv[1].value
            self._send(osc.Message(self.address,*row_conv))
        print("Goodbye.")
        reactor.callLater(0.1, reactor.stop)

class Token(object):
    def __init__(self):
        self.running = True

if __name__ == "__main__":

    token = Token()

    parser = argparse.ArgumentParser(description='Simulate an (osc) pianoroll client.')
    parser.add_argument('datafile', metavar='DATAFILE', help='The file containing the pianoroll data (CSV).')
    parser.add_argument('-e', '--event', dest='event', metavar='EVENT', required=True, help='the event code.')
    parser.add_argument('-s', '--shift', dest='shift', action='store_true', required=False, help='Shift the data.', default=False)

    args = parser.parse_args()

    def customHandler(signum, _):
        print("Got signal: %s" % signum)
        token.running = False
        if reactor.running:
            reactor.callFromThread(reactor.stop) # to stop twisted code when in the reactor loop
    signal.signal(signal.SIGINT, customHandler)


    with open(args.datafile, 'rU') as datafile:
        reader = csv.reader(datafile, delimiter=' ')
        app = UDPSenderApplication(9090, "127.0.0.1", "/pianoroll/%s/" % args.event, list(reader), args.shift, token)

    reactor.run()