utils/pianoroll-client.py
author rougeronj
Sat, 18 Apr 2015 09:37:57 +0200
changeset 167 2b99fed0285e
parent 93 79ae42ad97d4
permissions -rw-r--r--
Update for 'Atelier 3 jour 3' and clean gulpfile

#!/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()