소스 검색

Added new filters/generators to client

(Also fixed a crasher in mkarduino)
Graham Northup 7 년 전
부모
커밋
d19490798f
2개의 변경된 파일73개의 추가작업 그리고 3개의 파일을 삭제
  1. 70 0
      client.py
  2. 3 3
      mkarduino.py

+ 70 - 0
client.py

@@ -314,6 +314,76 @@ class phase_off(object):
     def __call__(self, theta):
         return self.gen((theta + self.offset) % (2*math.pi))
 
+@generator('Normally distributed random-inversion square waves (chorus effect)', '(<sigma>)')
+class nd_square_wave(object):
+    def __init__(self, sig):
+        self.sig = sig
+        self.invt = 0
+        self.lastp = 2*math.pi
+    def __call__(self, theta):
+        if theta < self.lastp:
+            self.invt = random.normalvariate(math.pi, self.sig)
+        self.lastp = theta
+        return -1 if theta < self.invt else 1
+
+@generator('Normally distributed random-point triangle waves (chorus effect)', '(<sigma>)')
+class nd_tri_wave(object):
+    def __init__(self, sig):
+        self.sig = sig
+        self.p1 = 0.5*math.pi
+        self.p2 = 1.5*math.pi
+        self.lastp = 2*math.pi
+    def __call__(self, theta):
+        if theta < self.lastp:
+            self.p1 = random.normalvariate(0.5*math.pi, self.sig)
+            self.p2 = random.normalvariate(1.5*math.pi, self.sig)
+        self.lastp = theta
+        if theta < self.p1:
+            return lin_interp(0, 1, theta / self.p1)
+        elif theta < self.p2:
+            return lin_interp(1, -1, (theta - self.p1) / (self.p2 - self.p1))
+        else:
+            return lin_interp(-1, 0, (theta - self.p2) / (2*math.pi - self.p2))
+
+@generator('Random phase offset', '(<generator>, <noise factor>)')
+class rand_phase_off(object):
+    def __init__(self, gen, fac):
+        self.gen = gen
+        self.fac = fac
+    def __call__(self, theta):
+        return self.gen((theta + self.fac * random.random()) % (2*math.pi))
+
+@generator('Infinite Impulse Response low pass filter', '(<generator>, <RC normalized to dt=1 sample>)')
+class lowpass(object):
+    def __init__(self, gen, rc):
+        self.gen = gen
+        self.alpha = 1.0 / (rc + 1)
+        self.last = 0
+    def __call__(self, theta):
+        self.last += self.alpha * (self.gen(theta) - self.last)
+        return self.last
+
+@generator('Infinite Impulse Response high pass filter', '(<generator>, <RC normalized to dt=1 sample>)')
+class highpass(object):
+    def __init__(self, gen, rc):
+        self.gen = gen
+        self.alpha = rc / (rc + 1.0)
+        self.last = 0
+        self.lastx = 0
+    def __call__(self, theta):
+        x = self.gen(theta)
+        self.last = self.alpha * (self.last + x - self.lastx)
+        self.lastx = x
+        return self.last
+
+@generator('Applies a function to itself repeatedly; often used with filters', '(<times>, <func>, <inner>, <extra arg 1>, <extra arg 2>, ...)')
+def order(n, f, i, *args):
+    cur = f(i, *args)
+    while n > 0:
+        cur = f(cur, *args)
+        n -= 1
+    return cur
+
 if options.generators:
     for item in GENERATORS:
         print item['name'],

+ 3 - 3
mkarduino.py

@@ -18,12 +18,12 @@ for i in xrange(min(3, len(streams))):
 
 # For the first note, write out the delay needed to get there
     if notes[0].get('time') > 0:
-        sys.stdout.write('%d, 0,\n'%(int(float(notes[0].get('time'))*1000),))
+        sys.stdout.write('\t%d, 0,\n'%(int(float(notes[0].get('time'))*1000),))
 
     for idx, note in enumerate(notes):
-        sys.stdout.write('%d, FREQ(%d),\n'%(int(float(note.get('dur'))*1000), int(440.0 * 2**((int(note.get('pitch'))-69)/12.0))))
+        sys.stdout.write('\t%d, FREQ(%d),\n'%(int(float(note.get('dur'))*1000), int(440.0 * 2**((float(note.get('pitch'))-69)/12.0))))
         if idx < len(notes)-1 and float(note.get('time'))+float(note.get('dur')) < float(notes[idx+1].get('time')):
-            sys.stdout.write('%d, 0,\n'%(int(1000*(float(notes[idx+1].get('time')) - (float(note.get('time')) + float(note.get('dur'))))),))
+            sys.stdout.write('\t%d, 0,\n'%(int(1000*(float(notes[idx+1].get('time')) - (float(note.get('time')) + float(note.get('dur'))))),))
 
 # Finish up the stream
     sys.stdout.write('};\n\n')