broadcast.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import socket
  2. import sys
  3. import struct
  4. import time
  5. import xml.etree.ElementTree as ET
  6. import threading
  7. from packet import Packet, CMD, itos
  8. PORT = 13676
  9. if len(sys.argv) > 2:
  10. factor = float(sys.argv[2])
  11. else:
  12. factor = 1
  13. print 'Factor:', factor
  14. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  15. s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
  16. clients = []
  17. s.sendto(str(Packet(CMD.PING)), ('255.255.255.255', PORT))
  18. s.settimeout(0.5)
  19. try:
  20. while True:
  21. data, src = s.recvfrom(4096)
  22. clients.append(src)
  23. except socket.timeout:
  24. pass
  25. print 'Clients:'
  26. for cl in clients:
  27. print cl,
  28. s.sendto(str(Packet(CMD.CAPS)), cl)
  29. data, _ = s.recvfrom(4096)
  30. pkt = Packet.FromStr(data)
  31. print 'ports', pkt.data[0],
  32. print 'type', itos(pkt.data[1]),
  33. print 'uid', ''.join([itos(i) for i in pkt.data[2:]]).rstrip('\x00')
  34. if sys.argv[1] == '-t':
  35. s.sendto(str(Packet(CMD.PLAY, 0, 250000, 440, 255)), cl)
  36. time.sleep(0.25)
  37. s.sendto(str(Packet(CMD.PLAY, 0, 250000, 880, 255)), cl)
  38. if sys.argv[1] == '-q':
  39. s.sendto(str(Packet(CMD.QUIT)), cl)
  40. try:
  41. iv = ET.parse(sys.argv[1]).getroot()
  42. except IOError:
  43. print 'Bad file'
  44. exit()
  45. notestreams = iv.findall("./streams/stream[@type='ns']")
  46. print len(notestreams), 'notestreams'
  47. print len(clients), 'clients'
  48. class NSThread(threading.Thread):
  49. def run(self):
  50. nsq, cl = self._Thread__args
  51. for note in nsq:
  52. ttime = float(note.get('time'))
  53. pitch = int(note.get('pitch'))
  54. vel = int(note.get('vel'))
  55. dur = factor*float(note.get('dur'))
  56. while time.time() - BASETIME < factor*ttime:
  57. time.sleep(factor*ttime - (time.time() - BASETIME))
  58. s.sendto(str(Packet(CMD.PLAY, int(dur), int((dur*1000000)%1000000), int(440.0 * 2**((pitch-69)/12.0)), vel*2)), cl)
  59. time.sleep(dur)
  60. threads = []
  61. for ns in notestreams:
  62. if not clients:
  63. print 'WARNING: Out of clients!',
  64. break
  65. nsq = ns.findall('note')
  66. threads.append(NSThread(args=(nsq, clients.pop(0))))
  67. BASETIME = time.time()
  68. for thr in threads:
  69. thr.start()
  70. for thr in threads:
  71. thr.join()