Control-Rate Envelope Generator
python
posted: Apr, 29th 2010 | jump to bottom
#!/usr/bin/env python # Copyright (c) 2010 Jacob Joaquin, jacobjoaquin@gmail.com # Visit Slipmat -- http://slipmat.noisepages.com/ import math sr = 44100 ksmps = 10 class Multiply: '''Multiplies multiples signals.''' def __init__(self, *ins): self.ins = ins def __iter__(self): self.index = 0 self.iters = [(j for j in i) for i in self.ins] return self def next(self): if self.index >= ksmps: raise StopIteration self.index += 1 return reduce(lambda x, y: x*y, (i.next() for i in self.iters)) class RiseFall: '''A rise-fall envelope generator.''' def __init__(self, dur, peak=0.5): self.frames = int(dur * sr / float(ksmps)) self.rise = int(peak * self.frames) self.fall = int(self.frames - self.rise) self.inc = 0 self.v = 0 def __iter__(self): self.index = 0 if self.inc <= self.rise and self.rise != 0: self.v = self.inc / float(self.rise) else: self.v = (self.fall - (self.inc - self.rise)) / float(self.fall) self.inc += 1 return self def next(self): if self.index >= ksmps: raise StopIteration self.index += 1 return self.v class Run: '''Render frames over time.''' def __init__(self, dur=1.0): self.frames = int(dur * sr / float(ksmps)) def __iter__(self): self.index = 0 return self def next(self): if self.index >= self.frames: raise StopIteration self.index += 1 return self.index class Sine: '''A sine wave oscillator.''' def __init__(self, amp=1.0, freq=440, phase=0.0): self.amp = amp self.freq = float(freq) self.phase = phase def __iter__(self): self.index = 0 return self def next(self): if self.index >= ksmps: raise StopIteration self.index += 1 v = math.sin(self.phase * 2 * math.pi) self.phase += self.freq / sr return v * self.amp class Sum: '''Sums multiples signals.''' def __init__(self, *ins): self.ins = ins def __iter__(self): self.index = 0 self.iters = [(j for j in i) for i in self.ins] return self def next(self): if self.index >= ksmps: raise StopIteration self.index += 1 return reduce(lambda x, y: x+y, (i.next() for i in self.iters)) if __name__ == "__main__": t = 0.002 a1 = Sine(0.5, 440) a2 = Sine(0.5, 440 * 2 ** (7 / 12.0)) amix = Sum(a1, a2) aenv = RiseFall(t, 0.5) aout = Multiply(amix, aenv) for frame in Run(t): print '%d:' % frame for i in aout: print '\t%.8f' % i
127 views




