'''
Script to run a GUI for a ringbuffer, imports Scikits Audiolab and a previous library developed with all the pertinent obejects
Jason Kaszpurenko
'''

#Importing of the pertinent files
try:	
	import numpy as np
	import pylab as pyl
	from scikits.audiolab import Format, Sndfile
	import speakerfiles as ringb

except ImportError, msg:	# catch any import exceptions, print error message
	print 'Error importing modules:', msg

def ringbuffer(seed, speaker1, speaker2, speaker3, runtime):
	#Takes an input signal (seed which is a list) and runs it through a loop of speakers that will have given parameters defined individually
	#This is than run for the duration of runtime and is than outputed in a list
	gt = []
	for i in xrange(runtime):
		if i < np.shape(seed)[0]:
			gt.append(speaker1.output(gt, i) + speaker2.output(gt, i) + speaker3.output(gt, i) + seed[i])
		else:
			gt.append(speaker1.output(gt, i) + speaker2.output(gt, i) + speaker3.output(gt, i))
	return gt

def wave_output(gt, filename, Signal_sample_rate):
#Outputs the processed signal, which is a list, into a wave file
	gt = np.array(gt)
	format = Format('wav')
	f = Sndfile(filename, 'w', format, 1, Signal_sample_rate)
	f.write_frames(gt)
	f.close()

#Setting up a Dictionary with three possible inputs, this will help us determine what wavefunctions will be available
maps = {
	'1' : ['Linear amplification: f(x)=r*x*(1-x)', ringb.linear],
	'2' : ['Logistic Map amplification: f(x)=r*x*(1-x)', ringb.logistic],
	'3' : ['Speaker turned off', ringb.off_switch]
}

# Signal_sample_rate would be the number of Hz a wave file would be and the 'seconds' are how long the program will run
# These two are multiplied together so that we get the total runtime
Signal_sample_rate = 6000
seconds = 40
runtime = Signal_sample_rate * seconds

#Description of the 3 speakers, choosing what type of amplification they will each have

func1 = maps['1'][1]()
func2 = maps['1'][1]()
func3 = maps['3'][1]()

speaker1 = func1
speaker2 = func2
speaker3 = func3

#time delays of the various speakers
time1 = 5000
time2 = 8000
time3 = 50000

speaker1.settime_delay(time1)
speaker2.settime_delay(time2)
speaker3.settime_delay(time3)

#Varying the values for r in our various functions, doesn't affect off_switch
r1 = .5
r2 = .5
r3 = .98

speaker1.setr(r1)
speaker2.setr(r2)
speaker3.setr(r3)

#Seed is the signal that will originally be used in the ring buffer



seed = np.arange(0, 500, 0.1)
seed = (np.sin(seed)+1.)/.5


processed_signal = ringbuffer(seed, speaker1, speaker2, speaker3, runtime)

for i in xrange(np.shape(processed_signal)[0]):
	processed_signal[i] = processed_signal[i]/2.-1


pyl.plot(processed_signal)
pyl.xlabel('time')
pyl.ylabel('Microphone signal')
pyl.title('2 speakers with a sine wave, processed so that it stays within +-1')
pyl.show()

filename = 'Simple sine wave repeating.wav'
wave_output(processed_signal, filename, Signal_sample_rate)