;Written by Iain McCurdy

<CsoundSynthesizer>

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

<CsInstruments>

sr	= 	44100
ksmps	= 	100
nchnls	= 	2
0dbfs	=	1	;MAXIMUM SOUND INTENSITY LEVEL REGARDLESS OF BIT DEPTH

;FLTK INTERFACE CODE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FLcolor	255, 255, 255, 0, 0, 0
;		LABEL                 | WIDTH | HEIGHT | X | Y
	FLpanel	"pvshift -> pvscale",    500,    500,    0,  0

;BORDERS				TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ih		 	FLbox  	" ", 	6,      9,     15,    490,    130,    5, 360	;BORDER AROUND FFT ATTRIBUTES

;SWITCHES						ON | OFF | TYPE | WIDTH | HEIGHT | X  | Y | OPCODE | INS | STARTTIM | DUR
gkOnOff,ihOnOff		FLbutton	"On/Off",	1,    0,    22,    120,     25,    5,    5,    0,     1,      0,      3600
FLsetColor2	255, 255, 50, ihOnOff	;SET SECONDARY COLOUR TO YELLOW
                                               
;VALUE DISPLAY BOXES		LABEL | WIDTH | HEIGHT | X | Y
idshift			FLvalue	" ",	 80,      20,    5, 125
idgain			FLvalue	" ",	 80,      20,    5, 175
idlowest		FLvalue	" ",	 80,      20,    5, 225
idscal			FLvalue	" ",	 80,      20,    5, 275
idOutGain		FLvalue	" ",	 80,      20,    5, 325

;SLIDERS				            		MIN   |  MAX | EXP | TYPE |   DISP   | WIDTH | HEIGHT | X  | Y
gkshift, ihshift	FLslider 	"Frequency Shift",	-5000,  5000,   0,    23,    idshift,   490,     25,    5,  100
gkgain, ihgain		FLslider 	"Gain Rescale",		0,         4,   0,    23,     idgain,   490,     25,    5,  150
gklowest, ihlowest	FLslider 	"Lowest Frequency",	1,     20000,  -1,    23,   idlowest,   490,     25,    5,  200
gkscal, ihscal		FLslider 	"Frequency Rescale",	.125,      8,  -1,    23,     idscal,   490,     25,    5,  250
gkOutGain, ihOutGain	FLslider 	"Output Gain",		0,         1,   0,    23,  idOutGain,   490,     25,    5,  300

;GENERAL_TEXT_SETTINGS			SIZE | FONT |  ALIGN | RED | GREEN | BLUE
			FLlabel		13,      1,       1,   255,   255,   255		;NUMBERS MADE INVISIBLE

;BUTTON BANKS			 			TYPE | NUMX | NUMY | WIDTH | HEIGHT | X | Y | OPCODE
gkkeepform, ihkeepform			FLbutBank	14,     1,     3,     18,      60,   200,  1,   -1
gkinput, ihinput			FLbutBank	14,     1,     3,     18,      60,     5, 32,   -1
gkFFTattributes, ihFFTattributes	FLbutBank	14,     1,     4,     18,      78,   120,400,   -1

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

;TEXT BOXES						TYPE | FONT | SIZE | WIDTH | HEIGHT | X |  Y
ih		 	FLbox  	"Live Input", 		1,       5,    11,    70,      22,   25,  30
ih		 	FLbox  	"Voice     ", 		1,       5,    11,    70,      22,   25,  50
ih		 	FLbox  	"Drum Loop ", 		1,       5,    11,    70,      22,   25,  70
ih		 	FLbox  	"FFT Attributes",       1,       4,    14,   100,      25,   15,  365
;TEXT BOXES										TYPE | FONT | SIZE | WIDTH | HEIGHT | X |  Y
ih		 	FLbox  	"FFT Size - Overlap - Window Size - Window Type",	1,       5,    11,    340,      20,  140,  380
ih		 	FLbox  	"  512        256        1024            1     ",	1,       5,    11,    340,      20,  140,  398
ih		 	FLbox  	" 1024        256        1024            1     ",	1,       5,    11,    340,      20,  140,  418
ih		 	FLbox  	" 2048        128        2048            1     ",	1,       5,    11,    340,      20,  140,  438
ih		 	FLbox  	" 4096        128        4096            1     ",	1,       5,    11,    340,      20,  140,  458
ih		 	FLbox  	"Do not preserve formants       ",			1,       5,    12,    240,      20,  220,    0
ih		 	FLbox  	"Impose original amplitudes     ",			1,       5,    12,    240,      20,  220,   20
ih		 	FLbox  	"Keep original spectral envelope",			1,       5,    12,    240,      20,  220,   40

;SET INITIAL VALUES FOR SLIDERS 	|VALUE | HANDLE
			FLsetVal_i	1, 	ihinput
			FLsetVal_i	0, 	ihshift
			FLsetVal_i	1, 	ihgain
			FLsetVal_i	0, 	ihkeepform
			FLsetVal_i	10, 	ihlowest
			FLsetVal_i	1, 	ihscal
			FLsetVal_i	0.7, 	ihOutGain
			FLsetVal_i	1, 	ihFFTattributes

			FLpanel_end

;INSTRUCTIONS AND INFO PANEL                 WIDTH | HEIGHT | X | Y
				FLpanel	" ", 500,     320,   512, 0
;TEXT BOXES												TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ih		 	FLbox  	"                 pvshift -> pvscale                          ", 	1,      5,     14,    490,    15,     5,  0
ih		 	FLbox  	"-------------------------------------------------------------", 	1,      5,     14,    490,    15,     5,  20
ih		 	FLbox  	"This example places pvshift and pvscale in a serial          ", 	1,      5,     14,    490,    15,     5,  40
ih		 	FLbox  	"arrangement for your further experimentation.                ", 	1,      5,     14,    490,    15,     5,  60
ih		 	FLbox  	"The two opcodes share the 'Formant Mode' and 'Gain Rescale'  ", 	1,      5,     14,    490,    15,     5,  80
ih		 	FLbox  	"controls.                                                    ", 	1,      5,     14,    490,    15,     5, 100
ih		 	FLbox  	"Typically the spectrum can be compressed and raised by giving", 	1,      5,     14,    490,    15,     5, 120
ih		 	FLbox  	"'Frequency Shift' a positive value and then transposed down  ", 	1,      5,     14,    490,    15,     5, 140
ih		 	FLbox  	"by giving 'Frequency Rescale' a value less than 1 to bring   ", 	1,      5,     14,    490,    15,     5, 160
ih		 	FLbox  	"the fundemental of the spectrum back to its original value.  ", 	1,      5,     14,    490,    15,     5, 180
ih		 	FLbox  	"A variety of combinations of FFT analysis attributes are     ", 	1,      5,     14,    490,    15,     5, 200
ih		 	FLbox  	"selectable using radio button selectors. It can be observed  ", 	1,      5,     14,    490,    15,     5, 220
ih		 	FLbox  	"that smaller FFT size and window sizes result in less time   ", 	1,      5,     14,    490,    15,     5, 240
ih		 	FLbox  	"smearing but greater harmonic distortion whereas larger FFT  ", 	1,      5,     14,    490,    15,     5, 260
ih		 	FLbox  	"sizes and window sizes result in greater time smearing but   ", 	1,      5,     14,    490,    15,     5, 280
ih		 	FLbox  	"less harmonic distortion.                                    ", 	1,      5,     14,    490,    15,     5, 300

				FLpanel_end

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

gasig		init		0

giFFTattributes0	ftgen	1, 0, 4, -2,  512, 256, 1024, 1
giFFTattributes1	ftgen	2, 0, 4, -2, 1024, 256, 1024, 1
giFFTattributes2	ftgen	3, 0, 4, -2, 2048, 128, 2048, 1
giFFTattributes3	ftgen	4, 0, 4, -2, 4096, 128, 4096, 1

instr	1	;
	if	gkOnOff=0	then			;IF On/Off SWITCH IS SET TO 'Off'
		turnoff					;TURN THIS INSTRUMENT
	endif						;END OF CONDITIONAL BRANCHING
	if		gkinput=0	then			;IF 'INPUT' SWITCH IS SET TO 'Live Input' THEN IMPLEMENT THE NEXT LINE OF CODE
		asig		inch		1				;READ AUDIO FROM THE COMPUTER'S LIVE INPUT CHANNEL 1 (LEFT)
	elseif		gkinput=1 	then			;IF 'INPUT' SWITCH IS SET TO 'Voice' THEN IMPLEMENT THE NEXT LINE OF CODE
		;OUTPUT		OPCODE		FILE_PATH       | SPEED | INSKIP | WRAPAROUND (1=ON)
		asig		diskin2		"AndItsAll.wav",    1,      0,        1			;READ A STORED AUDIO FILE FROM THE HARD DRIVE
	else						;IF 'INPUT' SWITCH IS NOT SET TO 'STORED FILE' THEN IMPLEMENT THE NEXT LINE OF CODE
		;OUTPUT		OPCODE		FILE_PATH       | SPEED | INSKIP | WRAPAROUND (1=ON)
		asig		diskin2		"808loopMono.wav",    1,      0,        1			;READ A STORED AUDIO FILE FROM THE HARD DRIVE
	endif						;END OF 'IF'...'THEN' BRANCHING
	kSwitch		changed		gkgain, gkkeepform, gkFFTattributes	;GENERATE A MOMENTARY '1' PULSE IN OUTPUT 'kSwitch' IF ANY OF THE SCANNED INPUT VARIABLES CHANGE. (OUTPUT 'kSwitch' IS NORMALLY ZERO)
	if	kSwitch=1	then		;IF I-RATE VARIABLE CHANGE TRIGGER IS '1'...
		reinit	START			;BEGIN A REINITIALISATION PASS FROM LABEL 'START'
	endif
	START:
	iFFTsize	table	0, i(gkFFTattributes)+1
	ioverlap	table	1, i(gkFFTattributes)+1
	iwinsize	table	2, i(gkFFTattributes)+1
	iwintype	table	3, i(gkFFTattributes)+1	
	fsig1  		pvsanal		asig, iFFTsize, ioverlap, iwinsize, iwintype		;ANALYSE THE AUDIO SIGNAL THAT WAS CREATED IN INSTRUMENT 1. OUTPUT AN F-SIGNAL.
	;OUTPUT		OPCODE		INPUT | SHIFT_AMOUNT | LOWEST_EXPECTED_FREQUENCY | FORMANT_MODE  |   GAIN
	fsig2 		pvshift 	fsig1,    gkshift,              gklowest,          i(gkkeepform),  i(gkgain)	;SHIFT FREQUENCIES OF THE INPUT F-SIGNAL
	;OUTPUT		OPCODE		INPUT | RESCALE_VALUE | FORMANT_MODE |   GAIN
	fsig3 		pvscale 	fsig2,      gkscal,     i(gkkeepform), i(gkgain)	;RESCALE THE FREQUENCY VALUES ACCORDING TO THE INPUT ARGUMENT gkscal.
	rireturn	;RETURN FROM REINITIALISATION PASS TO PERFORMANCE TIME PASSES
	;OUTPUT		OPCODE		INPUT
	aresyn 		pvsynth  	fsig3                      	;RESYNTHESIZE THE f-SIGNAL AS AN AUDIO SIGNAL
			outs		aresyn * gkOutGain, aresyn * gkOutGain	;SEND THE RESCALED, RESYNTHESIZED SIGNAL TO THE AUDIO OUTPUTS
endin

</CsInstruments>

<CsScore>
f 0 3600	;DUMMY SCORE EVENT KEEPS PERFORMANCE GOING FOR 1 HOUR
</CsScore>

</CsoundSynthesizer>