5 This example is in the public domain. |
5 This example is in the public domain. |
6 """ |
6 """ |
7 |
7 |
8 import argparse |
8 import argparse |
9 import csv |
9 import csv |
10 import sys |
|
11 import time |
10 import time |
12 |
11 |
|
12 import ntplib |
13 from twisted.internet import reactor |
13 from twisted.internet import reactor |
14 from txosc import osc |
14 from txosc import osc |
15 from txosc import dispatch |
|
16 from txosc import async |
15 from txosc import async |
17 |
16 |
18 |
17 |
19 class UDPSenderApplication(object): |
18 class UDPSenderApplication(object): |
20 """ |
19 """ |
21 Example that sends UDP messages. |
20 Example that sends UDP messages. |
22 """ |
21 """ |
23 def __init__(self, port, host, address, rows): |
22 def __init__(self, port, host, address, rows, shift): |
24 self.port = port |
23 self.port = port |
25 self.host = host |
24 self.host = host |
26 self.client = async.DatagramClientProtocol() |
25 self.client = async.DatagramClientProtocol() |
27 self._client_port = reactor.listenUDP(0, self.client) |
26 self._client_port = reactor.listenUDP(0, self.client) |
28 self.rows = rows |
27 self.rows = rows |
29 self.address = address |
28 self.address = address |
|
29 self.shift = shift |
30 reactor.callLater(0, self.send_messages) |
30 reactor.callLater(0, self.send_messages) |
31 |
31 |
32 def _send(self, element): |
32 def _send(self, element): |
33 # This method is defined only to simplify the example |
33 # This method is defined only to simplify the example |
34 self.client.send(element, (self.host, self.port)) |
34 self.client.send(element, (self.host, self.port)) |
35 print("Sent %s to %s:%d" % (element, self.host, self.port)) |
35 print("Sent %s to %s:%d" % (element, self.host, self.port)) |
36 |
36 |
37 def send_messages(self): |
37 def send_messages(self): |
38 tc = 0 |
38 t0 = time.time() |
39 for row in self.rows: |
39 for row in self.rows: |
|
40 if self.shift: |
|
41 row[0] = ntplib.system_to_ntp_time(t0 + float(row[1])/10**3) |
40 row_conv = [ osc.TimeTagArgument(float(row[0]))] + [osc.IntArgument(int(a)) for a in row[1:]] |
42 row_conv = [ osc.TimeTagArgument(float(row[0]))] + [osc.IntArgument(int(a)) for a in row[1:]] |
41 #time.sleep((row_conv[1].value-tc)/10**3) |
43 #time.sleep((row_conv[1].value-tc)/10**3) |
42 time.sleep(0.1) |
44 time.sleep(0.1) |
43 #tc = row_conv[1].value |
45 #tc = row_conv[1].value |
44 self._send(osc.Message(self.address,*row_conv)) |
46 self._send(osc.Message(self.address,*row_conv)) |
48 if __name__ == "__main__": |
50 if __name__ == "__main__": |
49 |
51 |
50 parser = argparse.ArgumentParser(description='Simulate an (osc) pianoroll client.') |
52 parser = argparse.ArgumentParser(description='Simulate an (osc) pianoroll client.') |
51 parser.add_argument('datafile', metavar='DATAFILE', help='The file containing the pianoroll data (CSV).') |
53 parser.add_argument('datafile', metavar='DATAFILE', help='The file containing the pianoroll data (CSV).') |
52 parser.add_argument('-e', '--event', dest='event', metavar='EVENT', required=True, help='the event code.') |
54 parser.add_argument('-e', '--event', dest='event', metavar='EVENT', required=True, help='the event code.') |
|
55 parser.add_argument('-s', '--shift', dest='shift', action='store_true', required=False, help='Shift the data.', default=False) |
53 |
56 |
54 args = parser.parse_args() |
57 args = parser.parse_args() |
55 |
58 |
56 with open(args.datafile, 'rU') as datafile: |
59 with open(args.datafile, 'rU') as datafile: |
57 reader = csv.reader(datafile, delimiter=' ') |
60 reader = csv.reader(datafile, delimiter=' ') |
58 app = UDPSenderApplication(9090, "127.0.0.1", "/pianoroll/%s/" % args.event, list(reader)) |
61 app = UDPSenderApplication(9090, "127.0.0.1", "/pianoroll/%s/" % args.event, list(reader), args.shift) |
59 |
62 |
60 reactor.run() |
63 reactor.run() |