aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrissess <grissess@nexusg.org>2016-06-12 22:49:51 -0400
committerGrissess <grissess@nexusg.org>2016-06-12 22:49:51 -0400
commit368b5db51d76c162656abd26c88991f0f7f8a556 (patch)
treece1155fca50f82bcea00d527171729068715ca4b
parentdc59723180707561e0f6a7e1fa7b1b33b4439104 (diff)
Removed track duplication kludge from mkiv and moved to broadcast
-rw-r--r--broadcast.py33
-rw-r--r--mkiv.py38
2 files changed, 37 insertions, 34 deletions
diff --git a/broadcast.py b/broadcast.py
index 714533d..c7d379d 100644
--- a/broadcast.py
+++ b/broadcast.py
@@ -7,6 +7,7 @@ import threading
import thread
import optparse
import random
+import itertools
from packet import Packet, CMD, itos
@@ -33,12 +34,14 @@ parser.add_option('-r', '--route', dest='routes', action='append', help='Add a r
parser.add_option('-v', '--verbose', dest='verbose', action='store_true', help='Be verbose; dump events and actual time (can slow down performance!)')
parser.add_option('-W', '--wait-time', dest='wait_time', type='float', help='How long to wait for clients to initially respond (delays all broadcasts)')
parser.add_option('-B', '--bind-addr', dest='bind_addr', help='The IP address (or IP:port) to bind to (influences the network to send to)')
+parser.add_option('--repeat', dest='repeat', action='store_true', help='Repeat the file playlist indefinitely')
+parser.add_option('-n', '--number', dest='number', type='int', help='Number of clients to use; if negative (default -1), use the product of stream count and the absolute value of this parameter')
parser.add_option('-G', '--gui', dest='gui', default='', help='set a GUI to use')
parser.add_option('--pg-fullscreen', dest='fullscreen', action='store_true', help='Use a full-screen video mode')
parser.add_option('--pg-width', dest='pg_width', type='int', help='Width of the pygame window')
parser.add_option('--pg-height', dest='pg_height', type='int', help='Width of the pygame window')
parser.add_option('--help-routes', dest='help_routes', action='store_true', help='Show help about routing directives')
-parser.set_defaults(routes=[], test_delay=0.25, random=0.0, rand_low=80, rand_high=2000, live=None, factor=1.0, duration=1.0, volume=255, wait_time=0.25, play=[], transpose=0, seek=0.0, bind_addr='', pg_width = 0, pg_height = 0)
+parser.set_defaults(routes=[], test_delay=0.25, random=0.0, rand_low=80, rand_high=2000, live=None, factor=1.0, duration=1.0, volume=255, wait_time=0.25, play=[], transpose=0, seek=0.0, bind_addr='', pg_width = 0, pg_height = 0, number=-1)
options, args = parser.parse_args()
if options.help_routes:
@@ -302,6 +305,9 @@ if options.live or options.list_live:
del active_set[pitch]
deferred_set.clear()
+if options.repeat:
+ args = itertools.cycle(args)
+
for fname in args:
try:
iv = ET.parse(fname).getroot()
@@ -313,9 +319,11 @@ for fname in args:
notestreams = iv.findall("./streams/stream[@type='ns']")
groups = set([ns.get('group') for ns in notestreams if 'group' in ns.keys()])
+ number = (len(notestreams) * abs(options.number) if options.number < 0 else options.number)
print len(notestreams), 'notestreams'
print len(clients), 'clients'
print len(groups), 'groups'
+ print number, 'clients used (number)'
class Route(object):
def __init__(self, fattr, fvalue, group, excl=False):
@@ -461,7 +469,7 @@ for fname in args:
return
time.sleep(t)
def run(self):
- nsq, cl = self._Thread__args
+ nsq, cls = self._Thread__args
for note in nsq:
ttime = float(note.get('time'))
pitch = float(note.get('pitch')) + options.transpose
@@ -469,7 +477,8 @@ for fname in args:
dur = factor*float(note.get('dur'))
while time.time() - BASETIME < factor*ttime:
self.wait_for(factor*ttime - (time.time() - BASETIME))
- s.sendto(str(Packet(CMD.PLAY, int(dur), int((dur*1000000)%1000000), int(440.0 * 2**((pitch-69)/12.0)), int(vel*2 * options.volume/255.0))), cl)
+ for cl in cls:
+ s.sendto(str(Packet(CMD.PLAY, int(dur), int((dur*1000000)%1000000), int(440.0 * 2**((pitch-69)/12.0)), int(vel*2 * options.volume/255.0))), cl)
if options.verbose:
print (time.time() - BASETIME), cl, ': PLAY', pitch, dur, vel
playing_notes[cl] = (pitch, vel*2)
@@ -478,24 +487,28 @@ for fname in args:
if options.verbose:
print '% 6.5f'%(time.time() - BASETIME,), cl, ': DONE'
- threads = []
- for ns in notestreams:
+ threads = {}
+ nscycle = itertools.cycle(notestreams)
+ for idx, ns in zip(xrange(number), nscycle):
cli = routeset.Route(ns)
if cli:
nsq = ns.findall('note')
- threads.append(NSThread(args=(nsq, cli)))
+ if ns in threads:
+ threads[ns]._Thread__args[1].add(cli)
+ else:
+ threads[ns] = NSThread(args=(nsq, set([cli])))
if options.verbose:
print 'Playback threads:'
- for thr in threads:
+ for thr in threads.values():
print thr._Thread__args[1]
BASETIME = time.time() - (options.seek*factor)
if options.seek > 0:
- for thr in threads:
+ for thr in threads.values():
thr.drop_missed()
- for thr in threads:
+ for thr in threads.values():
thr.start()
- for thr in threads:
+ for thr in threads.values():
thr.join()
print fname, ': Done!'
diff --git a/mkiv.py b/mkiv.py
index 03b3fdf..717220c 100644
--- a/mkiv.py
+++ b/mkiv.py
@@ -29,12 +29,11 @@ parser.add_option('--help-conds', dest='help_conds', action='store_true', help='
parser.add_option('-p', '--program-split', dest='tracks', action='append_const', const=PROGRAMS, help='Ensure all programs are on non-mutual streams (overrides -T presently)')
parser.add_option('-P', '--percussion', dest='perc', help='Which percussion standard to use to automatically filter to "perc" (GM, GM2, or none)')
parser.add_option('-f', '--fuckit', dest='fuckit', action='store_true', help='Use the Python Error Steamroller when importing MIDIs (useful for extended formats)')
-parser.add_option('-n', '--target-num', dest='repeaterNumber', type='int', help='Target count of devices')
parser.add_option('-v', '--verbose', dest='verbose', action='store_true', help='Be verbose; show important parts about the MIDI scheduling process')
-parser.add_option('-d', '--debug', dest='debug', action='store_true', help='Debugging output; show excessive output about the MIDI scheduling process')
+parser.add_option('-d', '--debug', dest='debug', action='store_true', help='Debugging output; show excessive output about the MIDI scheduling process (please use less or write to a file)')
parser.add_option('-D', '--deviation', dest='deviation', type='int', help='Amount (in semitones/MIDI pitch units) by which a fully deflected pitchbend modifies the base pitch (0 disables pitchbend processing)')
parser.add_option('--tempo', dest='tempo', help='Adjust interpretation of tempo (try "f1"/"global", "f2"/"track")')
-parser.set_defaults(tracks=[], repeaterNumber=1, perc='GM', deviation=2, tempo='global')
+parser.set_defaults(tracks=[], perc='GM', deviation=2, tempo='global')
options, args = parser.parse_args()
if options.tempo == 'f1':
options.tempo == 'global'
@@ -447,27 +446,18 @@ for fname in args:
ivstreams = ET.SubElement(iv, 'streams')
- x = 0
- while(x<options.repeaterNumber):
- for group in notegroups:
- for ns in group.streams:
- ivns = ET.SubElement(ivstreams, 'stream')
- ivns.set('type', 'ns')
- if group.name is not None:
- ivns.set('group', group.name)
- for note in ns.history:
- ivnote = ET.SubElement(ivns, 'note')
- ivnote.set('pitch', str(note.pitch))
- ivnote.set('vel', str(note.ev.velocity))
- ivnote.set('time', str(note.abstime))
- ivnote.set('dur', str(note.duration))
- x+=1
- if(x>=options.repeaterNumber and options.repeaterNumber!=1):
- break
- if(x>=options.repeaterNumber and options.repeaterNumber!=1):
- break
- if(x>=options.repeaterNumber and options.repeaterNumber!=1):
- break
+ for group in notegroups:
+ for ns in group.streams:
+ ivns = ET.SubElement(ivstreams, 'stream')
+ ivns.set('type', 'ns')
+ if group.name is not None:
+ ivns.set('group', group.name)
+ for note in ns.history:
+ ivnote = ET.SubElement(ivns, 'note')
+ ivnote.set('pitch', str(note.pitch))
+ ivnote.set('vel', str(note.ev.velocity))
+ ivnote.set('time', str(note.abstime))
+ ivnote.set('dur', str(note.duration))
ivtext = ET.SubElement(ivstreams, 'stream', type='text')
for tev in textstream: