broadcast.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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
  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. if sys.argv[1] == '-t':
  29. s.sendto(str(Packet(CMD.PLAY, 0, 250000, 440, 255)), cl)
  30. time.sleep(0.25)
  31. s.sendto(str(Packet(CMD.PLAY, 0, 250000, 880, 255)), cl)
  32. if sys.argv[1] == '-q':
  33. s.sendto(str(Packet(CMD.QUIT)), cl)
  34. try:
  35. iv = ET.parse(sys.argv[1]).getroot()
  36. except IOError:
  37. print 'Bad file'
  38. exit()
  39. notestreams = iv.findall("./streams/stream[@type='ns']")
  40. class NSThread(threading.Thread):
  41. def run(self):
  42. nsq, cl = self._Thread__args
  43. for note in nsq:
  44. ttime = float(note.get('time'))
  45. pitch = int(note.get('pitch'))
  46. vel = int(note.get('vel'))
  47. dur = factor*float(note.get('dur'))
  48. while time.time() - BASETIME < factor*ttime:
  49. time.sleep(factor*ttime - (time.time() - BASETIME))
  50. s.sendto(str(Packet(CMD.PLAY, int(dur), int((dur*1000000)%1000000), int(440.0 * 2**((pitch-69)/12.0)), vel*2)), cl)
  51. time.sleep(dur)
  52. threads = []
  53. for ns in notestreams:
  54. if not clients:
  55. print 'WARNING: Out of clients!'
  56. break
  57. nsq = ns.findall('note')
  58. threads.append(NSThread(args=(nsq, clients.pop(0))))
  59. BASETIME = time.time()
  60. for thr in threads:
  61. thr.start()
  62. for thr in threads:
  63. thr.join()