File size: 3,238 Bytes
c051af2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
from Queue import PriorityQueue, Queue, Full
import numpy as np
from dspy.generator import Generator
from dspy.lib import rechannel, t2f
class Player(Generator):
def __init__(self, sequence=[], channels=2, live=True, loop=False, clip=True, max_size=0):
Generator.__init__(self)
self.max_size = max_size
self._generators = PriorityQueue(max_size)
self._finished = Queue()
self._gain = 0.1
self._live = live
self._length_cache = max([f+g.length() for (f, g) in sequence] + [0])
self.loop = loop
self.clip = clip
self.num_channels = channels
self.num_gens = 0
if sequence:
for (f, g) in sequence:
self._append_gen(f, g)
if live:
assert(not loop)
self.auto_reset = loop
def _append_gen(self, frame, gen):
try:
self._generators.put((t2f(frame), gen), False)
except Full:
print('Too many generators to append another')
return
def add(self, gen, time=None):
if time is None:
frame = self.frame
else:
frame = t2f(time)
self._length_cache = max(self._length_cache, gen.length() + frame)
if self.num_gens < self.max_size or self.max_size == 0:
self.num_gens += 1
self._append_gen(frame, gen)
def _reset(self):
if self._live:
raise Exception('Cannot reset if Player is live')
sequence = []
while not self._finished.empty():
frame, gen = self._finished.get()
gen.reset()
sequence.append((frame, gen))
while not self._generators.empty():
frame, gen = self._generators.get()
gen.reset()
sequence.append((frame, gen))
for frame, gen in sequence:
self._append_gen(frame, gen)
def _length(self):
if self._live:
return float('inf')
return self._length_cache
@property
def gain(self):
return self._gain
@gain.setter
def gain(self, value):
self._gain = np.clip(value, 0, 1)
def _generate(self, frame_count):
output = np.zeros(frame_count * self.num_channels, dtype=np.float32)
not_done = []
while not self._generators.empty():
frame, gen = self._generators.get()
if frame > self.frame + frame_count:
not_done.append((frame, gen))
break
delay = 0
if frame > self.frame:
delay = frame - self.frame
signal, continue_flag = gen.generate(frame_count - delay)
signal = rechannel(signal, gen.num_channels, self.num_channels)
output[delay * self.num_channels:] += signal
if continue_flag:
not_done.append((frame, gen))
else:
if not self._live:
self._finished.put((frame, gen))
self.num_gens -= 1
for frame, gen in not_done:
self._append_gen(frame, gen)
output *= self.gain
if self.clip:
output = np.clip(output, -1, 1)
return output
|