;Written by Iain McCurdy, 2010

<CsoundSynthesizer>

<CsOptions>
-idevaudio -odevaudio -b400
</CsOptions>

<CsInstruments>

sr 		= 	44100	;SAMPLE RATE
ksmps 		= 	100	;NUMBER OF AUDIO SAMPLES IN EACH CONTROL CYCLE
nchnls 		= 	2	;NUMBER OF CHANNELS (2=STEREO)
0dbfs		=	1

;FLTK INTERFACE CODE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FLcolor	255, 255, 255, 0, 0, 0
;					LABEL   | WIDTH | HEIGHT | X | Y
				FLpanel	"wguide2", 500,    400,    0,  0
 
;SWITCHES                       				ON | OFF | TYPE | WIDTH | HEIGHT | X | Y | OPCODE | INS | STARTTIM | IDUR
gkOnOff,ihOnOff			FLbutton	"On/Off",	1,    0,    22,    150,     28,    5,  5,    0,      1,      0,       -1
FLsetColor2	255, 255, 50, ihOnOff	;SET SECONDARY COLOUR TO YELLOW

;GENERAL_TEXT_SETTINGS			SIZE | FONT |  ALIGN | RED | GREEN | BLUE
			FLlabel		13,      1,      3,    255,   255,   255		;LABELS MADE INVISIBLE (I.E. SAME COLOR AS PANEL)

;BUTTON BANKS					TYPE | NUMX | NUMY | WIDTH | HEIGHT | X | Y | OPCODE | INS | STARTTIM | DUR
gkinput, ihinput		FLbutBank	14,     1,     3,     18,      45,   250, 0,   -1

;GENERAL_TEXT_SETTINGS			SIZE | FONT |  ALIGN | RED | GREEN | BLUE
			FLlabel		13,      1,      3,     0,     0,     0			;LABELS MADE VISIBLE AGAIN

;TEXT BOXES						TYPE | FONT | SIZE | WIDTH | HEIGHT | X |  Y
ih		 	FLbox  	"Input", 		1,       5,    14,     50,      20, 200,   0
ih		 	FLbox  	"Seashore", 		1,       5,    11,     60,      13, 270,   0
ih		 	FLbox  	"Live    ", 		1,       5,    11,     60,      13, 270,  15
ih		 	FLbox  	"Impulses", 		1,       5,    11,     60,      13, 270,  30

;VALUE DISPLAY BOXES			LABEL  | WIDTH | HEIGHT | X | Y
idfreq1				FLvalue	" ",       80,     20,    5,  75
idfreq2				FLvalue	" ",       80,     20,    5, 125
idcutoff1			FLvalue	" ",       80,     20,    5, 175
idcutoff2			FLvalue	" ",       80,     20,    5, 225
idfeedback1			FLvalue	" ",       80,     20,    5, 275
idfeedback2			FLvalue	" ",       80,     20,    5, 325
idamp				FLvalue	" ",       80,     20,    5, 375

;SLIDERS					            			MIN | MAX | EXP | TYPE |  DISP     | WIDTH | HEIGHT | X   | Y
gkfreq1,ihfreq1			FLslider 	"Frequency 1",			20,  10000, -1,    23,   idfreq1,     490,      25,   5,    50
gkfreq2,ihfreq2			FLslider 	"Frequency 2",			20,  10000, -1,    23,   idfreq2,     490,      25,   5,   100
gkcutoff1,ihcutoff1		FLslider 	"LPF Cutoff Frequency 1",	20,  20000, -1,    23,   idcutoff1,   490,      25,   5,   150
gkcutoff2,ihcutoff2		FLslider 	"LPF Cutoff Frequency 2",	20,  20000, -1,    23,   idcutoff2,   490,      25,   5,   200
gkfeedback1,ihfeedback1		FLslider 	"Feedback 1",			0,    .999,  0,    23,   idfeedback1, 490,      25,   5,   250
gkfeedback2,ihfeedback2		FLslider 	"Feedback 2",			0,    .999,  0,    23,   idfeedback2, 490,      25,   5,   300
gkamp,ihamp			FLslider 	"Output Amplitude Scaling",	0,       1,  0,    23,   idamp,       490,      25,   5,   350
gkingain,ihingain		FLslider 	"Live Input Gain",		0,       1,  0,    23,   -1,          140,      20, 350,     5

;SET INITIAL VALUES OF FLTK VALUATORS
;						VALUE | HANDLE
				FLsetVal_i	113, 	ihfreq1
				FLsetVal_i	20000, 	ihcutoff1
				FLsetVal_i	0.27, 	ihfeedback1
				FLsetVal_i	273, 	ihfreq2
				FLsetVal_i	20000, 	ihcutoff2
				FLsetVal_i	0.23, 	ihfeedback2
				FLsetVal_i	0.7, 	ihamp
			
				FLpanel_end
;INSTRUCTIONS AND INFO PANEL
				FLpanel	" ", 500, 540, 512, 0
;TEXT BOXES												TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ih		 	FLbox  	"                           wguide2                           ", 	1,      5,     14,    490,    15,     5,   0
ih		 	FLbox  	"-------------------------------------------------------------", 	1,      5,     14,    490,    15,     5,  20
ih		 	FLbox  	"Wguide2 implements 2 delays and first order lowpass filters  ", 	1,      5,     14,    490,    15,     5,  40
ih		 	FLbox  	"with feedback in a single unit opcode. This arrangement is as", 	1,      5,     14,    490,    15,     5,  60
ih		 	FLbox  	"shown below:                                                 ", 	1,      5,     14,    490,    15,     5,  80
ih		 	FLbox  	"              +-----<-----[FEEDBACK]<-------+                ", 	1,      5,     14,    490,    15,     5, 100
ih		 	FLbox  	"              |                             |                ", 	1,      5,     14,    490,    15,     5, 120
ih		 	FLbox  	"              |  +-----+  +--------------+  |                ", 	1,      5,    14,    490,    15,     5, 140
ih		 	FLbox  	"              +->+DELAY+->+LOWPASS FILTER+->+                ", 	1,      5,     14,    490,    15,     5, 160
ih		 	FLbox  	"                 +-----+  +--------------+                   ", 	1,      5,     14,    490,    15,     5, 180
ih		 	FLbox  	"                 |                                           ", 	1,      5,     14,    490,    15,     5, 200
ih		 	FLbox  	"             IN->+------------------------------>OUT         ", 	1,      5,     14,    490,    15,     5, 220
ih		 	FLbox  	"                 |                                           ", 	1,      5,     14,    490,    15,     5, 240
ih		 	FLbox  	"                 +-----+  +--------------+                   ", 	1,      5,     14,    490,    15,     5, 260
ih		 	FLbox  	"              +->+DELAY+->+LOWPASS FILTER+->+                ", 	1,      5,     14,    490,    15,     5, 280
ih		 	FLbox  	"              ^  +-----+  +--------------+  |                ", 	1,      5,     14,    490,    15,     5, 300
ih		 	FLbox  	"              |                             |                ", 	1,      5,     14,    490,    15,     5, 320
ih		 	FLbox  	"              +-----<-----[FEEDBACK]<-------+                ", 	1,      5,     14,    490,    15,     5, 340
ih		 	FLbox  	"Wguide2 can imbue the resosnant characteristics of a metal   ", 	1,      5,     14,    490,    15,     5, 360
ih		 	FLbox  	"plate to an impulse signal.                                  ", 	1,      5,     14,    490,    15,     5, 380
ih		 	FLbox  	"In this implementation three options for the impulse (input) ", 	1,      5,     14,    490,    15,     5, 400
ih		 	FLbox  	"signal are provided: (1) Sound file (2) Live input and (3)   ", 	1,      5,     14,    490,    15,     5, 420
ih		 	FLbox  	"a stream of click impulses.                                  ", 	1,      5,     14,    490,    15,     5, 440
ih		 	FLbox  	"As both feedback loops impact upon the feedback of the entire", 	1,      5,     14,    490,    15,     5, 460
ih		 	FLbox  	"system care should be taken in adjusting them. To prevent out", 	1,      5,     14,    490,    15,     5, 480
ih		 	FLbox  	"of control resonance, the sum of both feedback parameters    ", 	1,      5,     14,    490,    15,     5, 500
ih		 	FLbox  	"should not exceed 0.5.                                       ", 	1,      5,     14,    490,    15,     5, 520

				FLpanel_end

				FLrun	;RUN THE FLTK WIDGET THREAD
;END OF FLTK INTERFACE CODE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

instr	1
	if	gkOnOff=0	then	;IF On/Off SWITCH IS SET TO 'OFF'...
		turnoff			;TURN THIS INSTRUMENT OFF
	endif				;END OF CONDITIONAL BRANCHING
	if	gkinput==0	then	;IF INPUT 'Seashore' IS SELECTED...
		gasigL, gasigR	diskin2	"Seashore.wav",    1,       0,         1	;GENERATE 2 AUDIO SIGNALS FROM A STEREO SOUND FILE (NOTE THE USE OF GLOBAL VARIABLES)		
	elseif	gkinput==1	then	;IF INPUT 'Live' IS SELECTED...
		asigL, asigR	ins	;TAKE INPUT FROM COMPUTER'S AUDIO INPUT
		gasigL	=	asigL * gkingain	;SCALE USING 'Input Gain' SLIDER
		gasigR	=	asigR * gkingain	;SCALE USING 'Input Gain' SLIDER						;END OF CONDITIONAL BRANCHING
	else	;OTHERWISE...
		kint	random	0.1,0.4	;INTERVAL BETWEEN IMPULSES IS RANDOMISED SLIGHTLY
		a1	mpulse	4,kint	;GENERATE IMPULSES
		kcfoct	randomi	6,12,2	;GENERATE RANDOM VALUES FOR FILTER CUTOFF FREQUENCY (OCT FORMAT)
		gasigL	butlp	a1, cpsoct(kcfoct)	;LOWPASS FILTER STREAM OF CLICKS
		gasigR	=	gasigL			;SET RIGHT CHANNEL SIGNAL TO THE SAME AS THE LEFT CHANNEL SIGNAL
	endif
endin
		
instr	2	;WGUIDE2 INSTRUMENT (ALWAYS ON)
	iporttime	=	0.1				;I-RATE VARIABLE DEFINITION OF PORTAMENTO TIME
	kporttime	linseg	0,0.01,iporttime,1,iporttime	;RAMPING UP FROM ZERO VERSION OF PORTAMENTO TIME VARIABLE
	kfreq1		portk	gkfreq1, kporttime		;SMOOTH VARIABLE CHANGES WITH PORTK
	afreq1		interp	kfreq1				;INTERPOLATE TO CREATE A-RATE VERSION OF K-RATE VARIABLE
	kfreq2		portk	gkfreq2, kporttime		;SMOOTH VARIABLE CHANGES WITH PORTK
	afreq2		interp	kfreq2				;INTERPOLATE TO CREATE A-RATE VERSION OF K-RATE VARIABLE
	;OUTPUT	OPCODE | INPUT | FREQ1&2       | LPF_CUTOFF_FREQ 1&2 | FEEDBACK_RATIO 1&2
	aresL	wguide2 gasigL, afreq1, afreq2, gkcutoff1, gkcutoff2, gkfeedback1, gkfeedback2
	aresR	wguide2 gasigR, afreq1, afreq2, gkcutoff1, gkcutoff2, gkfeedback1, gkfeedback2
	aresL	dcblock2	aresL	;BLOCK DC OFFSET
	aresR	dcblock2	aresR	;BLOCK DC OFFSET           
		outs	aresL * gkamp, aresR * gkamp	;SEND wguide2 OUTPUT TO THE AUDIO OUTPUTS AND SCALE USING THE FLTK SLIDER VARIABLE gkamp
	clear	gasigL, gasigR	;CLEAR GLOBAL AUDIO VARIABLES
endin
  	
</CsInstruments>

<CsScore>
;INSTR | START | DURATION
i  2       0       3600	;INSTRUMENT 2 PLAYS FOR 1 HOUR (AND KEEPS REALTIME PERFORMANCE GOING)
</CsScore>

</CsoundSynthesizer>