I built an iterator class from the graph in yesterday’s example. Read and download the full script here. Let’s take a look at the class, then discuss the implications:
class MyInstr: '''My Instrument''' def __init__(self, dur, amp=1.0, freq=440, tune=12): a1 = Sine(amp * 0.5, freq) a2 = Sine(amp * 0.5, freq * 2 ** (tune / 12.0)) self.out = Multiply(Sum(a1, a2), RiseFall(dur, 0.5)) def __iter__(self): self.index = 0 self._iter = (i for i in self.out) return self def next(self): if self.index >= ksmps: raise StopIteration self.index += 1 return self._iter.next()
What good is a graph defined as an iterator class? The class essentially works like a Csound instrument. Multiple instances with varied input can be created, like Csound score i-events. It is also, more or less, a new unit generator that can be patched into a new graph. Most importantly, they can be easily shared with others in the Slipmat community. Import. Reuse. Remix.
There is a downside. If you’re not familiar with Python code or Python iterator classes, then you probably can’t make heads or tails out of this. One of the fundamental principles of the Slipmat philosophy is that the code needs to be user-friendly. Iterator classes as graphs, well, that’s a big technical hurdle, especially for n00bs. I don’t like hurdles; they restrict the creative flow, and can be a show stopper.
Fortunately, there is a solution, which I’ll post later today. If you happen to follow my twitter feed, then you probably have figured out where I’m going.
Here’s the the new __main__:
if __name__ == "__main__": t = 0.002 my_instr = MyInstr(t, 1, 440, 7) for frame in Run(t): print '%d:' % frame for i in my_instr: print 't%.8f' % i
This produces identical results to yesterday’s script. The only difference is that the code has been refactored to increase modularity and possibly clarity.
Pingback: Slipmat » Instruments Simplified with Python Decorators