
import util
import math
import sampler

## Audio sample generators

def beep(frequency=440):
	for sample in util.crop_with_fades(tone(440), seconds=0.25):
		yield sample

def tone(frequency=440):
	# todo limit length in seconds or cycles
	period = int(sampler.FRAME_RATE / frequency) 
	time_scale = 2 * math.pi / period # period * scale = 2 * pi
	samples = [math.sin(i * time_scale) for i in xrange(period)]
	while True:
		for i in xrange(period):
			yield samples[i]

def synth(freq, angles):
	if isinstance(angles, (int, float)):
		# argument was just the end angle
		angles = [0, angles]
	gen = tone(freq)
	loop = list(itertools.islice(gen, (sampler.FRAME_RATE / freq) * (angles[1] / (2.0 * math.pi))))[int((sampler.FRAME_RATE / freq) * (angles[0] / (2.0 * math.pi))):]
	while True:
		for sample in loop:
			yield sample

def silence(seconds=None):
	if seconds != None:
		for i in range(int(sampler.FRAME_RATE * seconds)):
			yield 0
	else:
		while True:
			yield 0


@@ -1,24 +1,86 @@
-%0Aimport util
+# coding=utf8%0A%0A'''%0AAssorted generators %0A'''%0A%0Aimport math%0Aimport itertools%0A
 %0Aimport 
 math
@@ -67,36 +67,36 @@
 ertools%0A%0Aimport 
-math
+util
 %0Aimport sampler%0A
@@ -96,16 +96,38 @@
 ampler%0A%0A
+TWO_PI = 2 * math.pi%0A%0A
 ## Audio
@@ -275,53 +275,57 @@
 =440
-):%0A%09# todo limit length in seconds or cycles%0A
+, min_=-1, max_=1):%0A%09def fixed_tone(frequency):%0A%09
 %09per
@@ -367,16 +367,17 @@
 uency) %0A
+%09
 %09time_sc
@@ -429,16 +429,93 @@
  2 * pi%0A
+%09%09# precompute fixed tone samples # TODO: what about phase glitches at end?%0A%09
 %09samples
@@ -568,16 +568,17 @@
 eriod)%5D%0A
+%09
 %09while T
@@ -580,24 +580,25 @@
 ile True:%0A%09%09
+%09
 for i in xra
@@ -609,24 +609,25 @@
 period):%0A%09%09%09
+%09
 yield sample
@@ -630,16 +630,457 @@
 mples%5Bi%5D
+%0A%09def variable_tone(frequency):%0A%09%09time_scale = TWO_PI / sampler.FRAME_RATE%0A%09%09phase = 0%0A%09%09for f in frequency:%0A%09%09%09yield math.sin(phase)%0A%0A%09%09%09phase += time_scale * f%0A%0A%09%09%09# don't reset hard to zero %E2%80%93%C2%A0avoids sudden phase glitches due to rounding error%0A%09%09%09if phase %3E TWO_PI:%0A%09%09%09%09phase -= TWO_PI%0A%0A%09if not hasattr(frequency, 'next'):%0A%09%09gen = fixed_tone(frequency)%0A%09else:%0A%09%09gen = variable_tone(frequency)%0A%09return util.normalize(gen, -1, 1, min_, max_)
 %0A%0Adef sy

Add variable freq, custom output range to tone()