utils/pianoroll-client.py
author rougeronj
Thu, 22 Jan 2015 09:26:43 +0100
changeset 111 a7b72620d227
parent 93 79ae42ad97d4
permissions -rw-r--r--
Add variable "wait". When this variable set, the annotsroll wait ignore some annotations, and wait before printing an otherone so there is no superposition. Can be passed as an options
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
#!/usr/bin/env python
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
"""
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
Example of a UDP txosc sender with Twisted.
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
This example is in the public domain.
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
"""
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
73
2a6590aeac15 Add argument for events on pianoroll client
ymh <ymh.work@gmail.com>
parents: 68
diff changeset
     8
import argparse
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
import csv
93
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    10
import signal
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
import time
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
85
eff9460bd4f2 add new visualization + small corrections
ymh <ymh.work@gmail.com>
parents: 73
diff changeset
    13
import ntplib
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
from twisted.internet import reactor
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
from txosc import osc
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
from txosc import async
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
class UDPSenderApplication(object):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
    """
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
    Example that sends UDP messages.
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
    """
93
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    23
    def __init__(self, port, host, address, rows, shift, token):
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
        self.port = port
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
        self.host = host
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
        self.client = async.DatagramClientProtocol()
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
        self._client_port = reactor.listenUDP(0, self.client)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
        self.rows = rows
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
        self.address = address
85
eff9460bd4f2 add new visualization + small corrections
ymh <ymh.work@gmail.com>
parents: 73
diff changeset
    30
        self.shift = shift
93
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    31
        self.token = token
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
        reactor.callLater(0, self.send_messages)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
    def _send(self, element):
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
        # This method is defined only to simplify the example
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
        self.client.send(element, (self.host, self.port))
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
        print("Sent %s to %s:%d" % (element, self.host, self.port))
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
    def send_messages(self):
85
eff9460bd4f2 add new visualization + small corrections
ymh <ymh.work@gmail.com>
parents: 73
diff changeset
    40
        t0 = time.time()
93
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    41
        #tc = 0
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
        for row in self.rows:
93
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    43
            if not self.token.running:
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    44
                break
85
eff9460bd4f2 add new visualization + small corrections
ymh <ymh.work@gmail.com>
parents: 73
diff changeset
    45
            if self.shift:
93
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    46
                row[0] = ntplib.system_to_ntp_time(t0 + float(row[1])/1000.0)
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
            row_conv = [ osc.TimeTagArgument(float(row[0]))] + [osc.IntArgument(int(a)) for a in row[1:]]
93
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    48
            #time.sleep((row_conv[1].value-tc)/1000.0)
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    49
            sleep_time = t0+float(row[1])/1000.0-time.time()
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    50
            if sleep_time > 0:
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    51
                time.sleep(sleep_time)
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    52
            #time.sleep(0.1)
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    53
            tc = row_conv[1].value
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
            self._send(osc.Message(self.address,*row_conv))
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
        print("Goodbye.")
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
        reactor.callLater(0.1, reactor.stop)
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
93
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    58
class Token(object):
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    59
    def __init__(self):
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    60
        self.running = True
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    61
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
if __name__ == "__main__":
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
93
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    64
    token = Token()
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    65
73
2a6590aeac15 Add argument for events on pianoroll client
ymh <ymh.work@gmail.com>
parents: 68
diff changeset
    66
    parser = argparse.ArgumentParser(description='Simulate an (osc) pianoroll client.')
2a6590aeac15 Add argument for events on pianoroll client
ymh <ymh.work@gmail.com>
parents: 68
diff changeset
    67
    parser.add_argument('datafile', metavar='DATAFILE', help='The file containing the pianoroll data (CSV).')
2a6590aeac15 Add argument for events on pianoroll client
ymh <ymh.work@gmail.com>
parents: 68
diff changeset
    68
    parser.add_argument('-e', '--event', dest='event', metavar='EVENT', required=True, help='the event code.')
85
eff9460bd4f2 add new visualization + small corrections
ymh <ymh.work@gmail.com>
parents: 73
diff changeset
    69
    parser.add_argument('-s', '--shift', dest='shift', action='store_true', required=False, help='Shift the data.', default=False)
73
2a6590aeac15 Add argument for events on pianoroll client
ymh <ymh.work@gmail.com>
parents: 68
diff changeset
    70
2a6590aeac15 Add argument for events on pianoroll client
ymh <ymh.work@gmail.com>
parents: 68
diff changeset
    71
    args = parser.parse_args()
2a6590aeac15 Add argument for events on pianoroll client
ymh <ymh.work@gmail.com>
parents: 68
diff changeset
    72
93
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    73
    def customHandler(signum, _):
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    74
        print("Got signal: %s" % signum)
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    75
        token.running = False
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    76
        if reactor.running:
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    77
            reactor.callFromThread(reactor.stop) # to stop twisted code when in the reactor loop
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    78
    signal.signal(signal.SIGINT, customHandler)
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    79
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    80
73
2a6590aeac15 Add argument for events on pianoroll client
ymh <ymh.work@gmail.com>
parents: 68
diff changeset
    81
    with open(args.datafile, 'rU') as datafile:
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
        reader = csv.reader(datafile, delimiter=' ')
93
79ae42ad97d4 optimize and refactor pianoroll component
ymh <ymh.work@gmail.com>
parents: 85
diff changeset
    83
        app = UDPSenderApplication(9090, "127.0.0.1", "/pianoroll/%s/" % args.event, list(reader), args.shift, token)
0
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
e1d4d7a8255a First shareable version
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
    reactor.run()