broadcast.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. class NSThread(threading.Thread):
  47. def run(self):
  48. nsq, cl = self._Thread__args
  49. for note in nsq:
  50. ttime = float(note.get('time'))
  51. pitch = int(note.get('pitch'))
  52. vel = int(note.get('vel'))
  53. dur = factor*float(note.get('dur'))
  54. while time.time() - BASETIME < factor*ttime:
  55. time.sleep(factor*ttime - (time.time() - BASETIME))
  56. s.sendto(str(Packet(CMD.PLAY, int(dur), int((dur*1000000)%1000000), int(440.0 * 2**((pitch-69)/12.0)), vel*2)), cl)
  57. time.sleep(dur)
  58. threads = []
  59. for ns in notestreams:
  60. if not clients:
  61. print 'WARNING: Out of clients!'
  62. break
  63. nsq = ns.findall('note')
  64. threads.append(NSThread(args=(nsq, clients.pop(0))))
  65. BASETIME = time.time()
  66. for thr in threads:
  67. thr.start()
  68. for thr in threads:
  69. thr.join()