<CsoundSynthesizer>

<CsOptions>
-odevaudio -b200 --nodisplays -m0	;DISPLAYS CAN BE RATHER DENSE SO ARE SUPPRESSED
</CsOptions>

<CsInstruments>

sr 	= 	44100
ksmps 	= 	8
nchnls 	= 	2

;FLTK INTERFACE CODE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	FLpanel	"Schedkwhen Granulation", 1000, 750, 0, 0
FLcolor	250, 250, 250, 100, 100, 100

;BORDERS				TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ihmainpanel	 	FLbox  	"", 	6,      9,     15,    500,   190,     0,   1	;MAIN
ihreverbpanel	 	FLbox  	"", 	6,      9,     15,    500,    75,     0, 640	;REVERB
ihpointerpanel	 	FLbox  	"",	6,      9,     15,    500,   230,     0, 200	;POINTER
ihdenssizepanel	 	FLbox  	"",	6,      9,     15,    500,   180,     0, 440	;GRAIN DENSITY AND SIZE
ihenvelopepanel	 	FLbox  	"",	6,      9,     15,    500,   180,   500,   5	;GRAIN ENVELOPE
ihpitchpanel	 	FLbox  	"",	6,      9,     15,    500,   130,   500, 195	;GRAIN PITCH
ihRMpanel	 	FLbox  	"",	6,      9,     15,    500,   135,   500, 335	;GRAIN-BY-GRAIN RING MODULATION
ihBPFpanel	 	FLbox  	"",	6,      9,     15,    500,   125,   500, 480	;GRAIN-BY-GRAIN BAND-PASS FILTERING 
ihfiltpanel	 	FLbox  	"",	6,      9,     15,    500,   135,   500, 610	;GLOBAL FILTER

;TEXT BOXES								TYPE | FONT | SIZE | WIDTH | HEIGHT | X |  Y
ihreverblabel	 	FLbox  	"Reverb",				1,       4,    15,    65,      25,    5,  642
ihpointerlabel	 	FLbox  	"Grain Pointer",			1,       4,    15,   105,      25,    5,  202
ihdenssizelabel	 	FLbox  	"Grain Density and Grain Size",		1,       4,    15,   215,      25,    5,  442
ihenvelopelabel	 	FLbox  	"Grain Envelope",			1,       4,    15,   125,      25,  505,    7
ihpitchlabel	 	FLbox  	"Grain Pitch",				1,       4,    15,   105,      25,  505,  197
ihRMlabel	 	FLbox  	"Grain-by-Grain Ring Modulation",	1,       4,    15,   230,      25,  505,  337
ihBPFlabel	 	FLbox  	"Grain-by-Grain Band-pass Filtering",	1,       4,    15,   250,      25,  505,  485
ihfiltlabel	 	FLbox  	"Global Filtering",			1,       4,    15,   110,      25,  505,  613

;COLOURIZE PANELS 	RED | GREEN | BLUE |  HANDLE
FLsetColor 		190,   190,   150,  ihmainpanel
FLsetColor 		230,   150,   150,  ihreverbpanel
FLsetColor 		230,   150,   150,  ihreverblabel
FLsetColor 		230,   230,   100,  ihpointerpanel
FLsetColor 		230,   230,   100,  ihpointerlabel
FLsetColor 		200,   230,   230,  ihdenssizepanel
FLsetColor 		200,   230,   230,  ihdenssizelabel
FLsetColor 		230,   200,   230,  ihenvelopepanel
FLsetColor 		230,   200,   230,  ihenvelopelabel
FLsetColor 		230,   230,   200,  ihpitchpanel
FLsetColor 		230,   230,   200,  ihpitchlabel
FLsetColor 		150,   230,   150,  ihRMpanel
FLsetColor 		150,   230,   150,  ihRMlabel
FLsetColor 		150,   250,   250,  ihBPFpanel
FLsetColor 		150,   250,   250,  ihBPFlabel
FLsetColor 		250,   150,   250,  ihfiltpanel
FLsetColor 		250,   150,   250,  ihfiltlabel

;BUTTONS                                               	ON | OFF | TYPE | WIDTH | HEIGHT | X | Y | OPCODE | I | STARTTIM | DUR | p4 | p5
gkOnOff,ihOnOff		FLbutton	"On/Off",	1,    0,    22,    150,    25,     5,  5,     0,     1,     0,     -1
gkRvbOnOff,ihRvbOnOff	FLbutton	"On/Off",	1,    0,    22,     80,    20,   410,650,    -1
gkRMOnOff,ihRMOnOff	FLbutton	"On/Off",	1,    0,    22,     80,    20,   910,342,    -1
gkBPFOnOff,ihBPFOnOff	FLbutton	"On/Off",	1,    0,    22,     80,    20,   910,487,    -1
gkFiltOnOff,ihFiltOnOff	FLbutton	"On/Off",	1,    0,    22,     80,    20,   910,618,    -1
FLsetColor2	255, 255, 50, ihOnOff		;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihRvbOnOff	;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihRMOnOff		;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihBPFOnOff	;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihFiltOnOff	;SET SECONDARY COLOUR TO YELLOW

;VALUATOR OUTPUT DISPLAY BOXES				WIDTH | HEIGHT |  X   | Y
idgain			FLvalue	" ",     	70,       17,     5,    65
idampdepth		FLvalue	" ",     	70,       17,     5,   115
idwidth			FLvalue	" ",     	70,       17,     5,   165
idptr			FLvalue	" ",     	70,       17,     5,   255
idptr_OS		FLvalue	" ",     	70,       17,     5,   305 
idLFOamp		FLvalue	" ",     	70,       17,     5,   355 
idLFOfrq		FLvalue	" ",     	70,       17,     5,   405
idGPS			FLvalue	" ",     	70,       17,     5,   495
idgap_OS		FLvalue	" ",     	70,       17,     5,   545
iddurMin		FLvalue	" ",     	70,       17,     5,   595
iddurMax		FLvalue	" ",     	70,       17,   405,   595
idatt			FLvalue	" ",     	70,       18,    505,   60
iddec			FLvalue	" ",     	70,       18,    505,  110
idEnvType		FLvalue	" ",     	70,       18,    505,  160
idoct			FLvalue	" ",     	70,       18,    505,  250
idrndoctavemin		FLvalue	" ",     	50,       18,    750,  250
idrndoctavemax		FLvalue	" ",     	50,       18,    945,  250                                           
idpchosrange		FLvalue	" ",     	70,       18,    505,  300
idRMmix			FLvalue	" ",     	70,       18,    505,  395
idRMfreqmin		FLvalue	" ",     	70,       18,    505,  445
idRMfreqmax		FLvalue	" ",     	70,       18,    905,  445
idHPFcf			FLvalue	" ",     	70,       18,    505,  670
idLPFcf			FLvalue	" ",     	70,       18,    505,  720

;SLIDERS				            				MIN   |   MAX   |   EXP | TYPE |   DISP     | WIDTH | HEIGHT |  X  | Y
gkgain,ihgain			FLslider 	"Output Amplitude",		0,	    1,       0,   23,   idgain,        490,     25,     5,   40
gkampdepth,ihampdepth		FLslider 	"Amplitude Random Offset", 	0,          1,       0,   23,   idampdepth,    490,     25,     5,   90
gkwidth,ihwidth			FLslider 	"Random Panning Amount", 	0,    	   .5,       0,   23,   idwidth,       490,     25,     5,  140
gkptr,ihptr			FLslider 	"Pointer",		 	0,          1,       0,   23,   idptr,         490,     25,     5,  230
gkptr_OS,ihptr_OS		FLslider 	"Grain Pointer Offset", 	0,         .5,       0,   23,   idptr_OS,      490,     25,     5,  280
gkLFOamp,ihLFOamp		FLslider 	"Pointer LFO Amplitude",	0,          1,       0,   23,   idLFOamp,      490,     25,     5,  330                                                                                                                                             
gkLFOfrq,ihLFOfrq		FLslider 	"Pointer LFO Frequency",	.00001,     1,      -1,   23,   idLFOfrq,      490,     25,     5,  380
gkGPS,ihGPS			FLslider 	"Grains per Second",	 	0.5,	 1000,      -1,   23,   idGPS,         490,     25,     5,  470
gkgap_OS,ihgap_OS		FLslider 	"Grain Gap Jitter",		0,	    2,       0,   23,   idgap_OS,      490,     25,     5,  520
gkdurMin,ihdurMin		FLslider 	" ",	 			.003,	    1,      -1,   23,   iddurMin,      490,     13,     5,  570
gkdurMax,ihdurMax		FLslider 	"Grain Duration",	 	.003,	    1,      -1,   23,   iddurMax,      490,     13,     5,  583
gkatt,ihatt			FLslider 	"Attack",		 	.0001,	0.999,       0,   23,   idatt,         490,     25,   505,   35
gkdec,ihdec			FLslider 	"Decay",		 	.0001,  0.999,       0,   23,   iddec,         490,     25,   505,   85
gkEnvType,ihEnvType		FLslider 	"Envelope Lin:Exp",	 	0,	    1,       0,   23,   idEnvType,     490,     25,   505,  135
gkoct,ihoct			FLslider 	"Pitch (oct)", 			-3,         3,       0,   23,   idoct,         245,     25,   505,  225
gkrndoctavemin,ihrndoctavemin	FLslider 	" ", 		 		-3,         3,       0,   23,   idrndoctavemin,245,     13,   750,  225
gkrndoctavemax,ihrndoctavemax	FLslider 	"Random Octave",	 	-3,         3,       0,   23,   idrndoctavemax,245,     13,   750,  238
gkpchosrange,ihpchosrange	FLslider 	"Pitch Offset Range (Octaves)",	0,	    3,       0,   23,   idpchosrange,  490,     25,   505,  275
gkRMmix,gihRMmix		FLslider 	"Mix",		 		0,	    1,       0,   23,   idRMmix,       490,     25,   505,  370
gkRMfreqmin,gihRMfreqmin	FLslider 	" ",				20,     20000,       0,   23,   idRMfreqmin,   490,     13,   505,  420
gkRMfreqmax,gihRMfreqmax	FLslider 	"Random RM Frequency",		20,     20000,       0,   23,   idRMfreqmax,   490,     13,   505,  433
gkBPFmix,ihBPFmix		FLslider 	"Mix",				0,          1,       0,   23,   -1,            150,     25,   510,  513
gkBPFcutmin,ihBPFcutmin		FLslider 	"",				4,         14,       0,   23,   -1,            150,     13,   670,  513
gkBPFcutmax,ihBPFcutmax		FLslider 	"Cutoff",			4,         14,       0,   23,   -1,            150,     13,   670,  526
gkBPFbwmin,ihBPFbwmin		FLslider 	"",				0.001,     10,      -1,   23,   -1,            150,     13,   830,  513
gkBPFbwmax,ihBPFbwmax		FLslider 	"Bandwidth",			0.001,     30,      -1,   23,   -1,            150,     13,   830,  526
gkBPFgain,ihBPFgain		FLslider 	"Gain",				0,         30,       0,   23,   -1,            150,     25,   510,  553
gkHPFcf,gihHPFcf		FLslider 	"HPF Cutoff",			20,     20000,      -1,   23,   idHPFcf,       490,     25,   505,  645
gkLPFcf,gihLPFcf		FLslider 	"LPF Cutoff",			20,     20000,      -1,   23,   idLPFcf,       490,     25,   505,  695
gkRvbDryWet,ihRvbDryWet		FLslider 	"Mix",				0,          1,       0,   23,   -1,            150,     20,    10,  675
gkfblvl,ihfblvl			FLslider 	"Size",				0,          1,       0,   23,   -1,            150,     20,   170,  675
gkfco,ihfco			FLslider 	"Cutoff",			20,     20000,       0,   23,   -1,            150,     20,   330,  675

;SET INITIAL VALUES FOR VALUATORS
				FLsetVal_i	.5,		ihptr
				FLsetVal_i	.4, 		ihatt
				FLsetVal_i	.5, 		ihdec
				FLsetVal_i	0.3, 		ihgain
				FLsetVal_i	.25, 		ihwidth
				FLsetVal_i	0, 		ihampdepth
				FLsetVal_i	20, 		gihHPFcf
				FLsetVal_i	20000, 		gihLPFcf
				FLsetVal_i	.00263, 	ihptr_OS
				FLsetVal_i	0, 		ihoct
				FLsetVal_i	-2,    		ihrndoctavemin
				FLsetVal_i	0,    		ihrndoctavemax
				FLsetVal_i	100, 		ihGPS
				FLsetVal_i	0.838, 		ihgap_OS
				FLsetVal_i	.6, 		ihdurMin
				FLsetVal_i	.6, 		ihdurMax
				FLsetVal_i	0, 		ihpchosrange
				FLsetVal_i	0, 		gihRMmix
				FLsetVal_i	500, 		gihRMfreqmin
				FLsetVal_i	8000, 		gihRMfreqmax
				FLsetVal_i	1, 		ihLFOamp
				FLsetVal_i	.0025, 		ihLFOfrq
				FLsetVal_i	.4,    		ihRvbDryWet
				FLsetVal_i	.9,    		ihfblvl
				FLsetVal_i	10000, 		ihfco
				FLsetVal_i	0,    		ihEnvType
				FLsetVal_i	1,    		ihRvbOnOff
				FLsetVal_i	1,    		ihRMOnOff
				FLsetVal_i	1,    		ihBPFOnOff
				FLsetVal_i	1,    		ihFiltOnOff
				FLsetVal_i	0,    		ihBPFmix
				FLsetVal_i	6,   		ihBPFcutmin
				FLsetVal_i	14,  		ihBPFcutmax
				FLsetVal_i	0.005, 		ihBPFbwmin
				FLsetVal_i	0.01,  		ihBPFbwmax
				FLsetVal_i	19,  		ihBPFgain
				FLpanel_end

;INSTRUCTIONS AND INFO PANEL
				FLpanel	" ", 500, 720, 612, 10
;TEXT BOXES												TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ih		 	FLbox  	"                   Schedkwhen Granulation                    ", 	1,       5,     14,    490,    20,     5,   0
ih		 	FLbox  	"-------------------------------------------------------------", 	1,       5,     14,    490,    20,     5,  20
ih		 	FLbox  	"This example implements granular synthesis by using          ", 	1,       5,     14,    490,    20,     5,  40
ih		 	FLbox  	"schedkwhen to create note events from within the orchestra in", 	1,       5,     14,    490,    20,     5,  60
ih		 	FLbox  	"realtime. None of Csound's built-in opcodes for granular     ", 	1,       5,     14,    490,    20,     5,  80
ih		 	FLbox  	"synthesis are used.                                          ", 	1,       5,     14,    490,    20,     5, 100
ih		 	FLbox  	"The advantage of this approach is that the method of grain   ", 	1,       5,     14,    490,    20,     5, 120
ih		 	FLbox  	"generation is not defined by the opcode and that further     ", 	1,       5,     14,    490,    20,     5, 140
ih		 	FLbox  	"processing can be applied to individual grains rather than   ", 	1,       5,     14,    490,    20,     5, 160
ih		 	FLbox  	"just to the accumulated output of grains. The downside is    ", 	1,       5,     14,    490,    20,     5, 180
ih		 	FLbox  	"that there is likely to be greater CPU strain for dense      ", 	1,       5,     14,    490,    20,     5, 200
ih		 	FLbox  	"granulations.                                                ", 	1,       5,     14,    490,    20,     5, 220
ih		 	FLbox  	"In this implemenation grain-by-grain procedures are          ", 	1,       5,     14,    490,    20,     5, 240
ih		 	FLbox  	"represented through ring modulation and band-pass filtering. ", 	1,       5,     14,    490,    20,     5, 260
ih		 	FLbox  	"Processes upon the accumlated output of the granular         ", 	1,       5,     14,    490,    20,     5, 280
ih		 	FLbox  	"synthesizer are represented by global filtering (low-pass and", 	1,       5,     14,    490,    20,     5, 300
ih		 	FLbox  	"high-pass) and by reverb. Grain-by-grain processes are       ", 	1,       5,     14,    490,    20,     5, 320
ih		 	FLbox  	"carried out in the instrument that actually renders the audio", 	1,       5,     14,    490,    20,     5, 340
ih		 	FLbox  	"for grains whereas global procedures are carried out in a    ", 	1,       5,     14,    490,    20,     5, 360
ih		 	FLbox  	"separate, always on, instrument.                             ", 	1,       5,     14,    490,    20,     5, 380
ih		 	FLbox  	"The pointer which defines the location within the sound file ", 	1,       5,     14,    490,    20,     5, 400
ih		 	FLbox  	"from which grains are read is defined by the FLTK slider     ", 	1,       5,     14,    490,    20,     5, 420
ih		 	FLbox  	"'Pointer'. The pointer can also be modulated by an LFO. To   ", 	1,       5,     14,    490,    20,     5, 440
ih		 	FLbox  	"deactivate the LFO reduce its amplitude to zero.             ", 	1,       5,     14,    490,    20,     5, 460
ih		 	FLbox  	"Certain paramaters of the ring modulator and the band-pass   ", 	1,       5,     14,    490,    20,     5, 480
ih		 	FLbox  	"filter can be randomized from grain to grain. The range from ", 	1,       5,     14,    490,    20,     5, 500
ih		 	FLbox  	"which random values are chosen are represented by two mini   ", 	1,       5,     14,    490,    20,     5, 520
ih		 	FLbox  	"sliders stacked one upon the other.                          ", 	1,       5,     14,    490,    20,     5, 540
ih		 	FLbox  	"The pitch of grains can me modulated in a variety of ways.   ", 	1,       5,     14,    490,    20,     5, 560
ih		 	FLbox  	"'Pitch (oct)' modulates the pitch of all grains by the same  ", 	1,       5,     14,    490,    20,     5, 580
ih		 	FLbox  	"constant number of octaves. 'Random Octave' defines a range  ", 	1,       5,     14,    490,    20,     5, 600
ih		 	FLbox  	"from which random modulations on a grain-by-grain basis are  ", 	1,       5,     14,    490,    20,     5, 620
ih		 	FLbox  	"applied. 'Pitch Offset Range (Octaves)' define the range from", 	1,       5,     14,    490,    20,     5, 640
ih		 	FLbox  	"which transpositions by octave intervals are applied.        ", 	1,       5,     14,    490,    20,     5, 640
ih		 	FLbox  	"The attack and the decay portions of each grain envelope are ", 	1,       5,     14,    490,    20,     5, 660
ih		 	FLbox  	"defined as well as a continuous morph between straight and   ", 	1,       5,     14,    490,    20,     5, 680
ih		 	FLbox  	"exponential envelope segements.                              ", 	1,       5,     14,    490,    20,     5, 700

				FLpanel_end

				FLrun

gasendL		init		0	;INITIALIZE GLOBAL AUDIO VARIABLES USED TO SEND AUDIO FROM GRAIN RENDERING INSTRUMENT
gasendR		init		0       ;INITIALIZE GLOBAL AUDIO VARIABLES USED TO SEND AUDIO FROM GRAIN RENDERING INSTRUMENT
gifn		=		1	;THE FUNCTION TABLE NUMBER OF THE SOURCE SOUND FILE FOR GRANULATION
0dbfs		=		1	;MAXIMUM AMPLITUDE=1

;;;USER DEFINED OPCODES (UDOS);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;A USER DEFINED OPCODE IS CREATED FOR REVERB SO THAT ksmps CAN BE SET TO 1
opcode	reverbsr, aa, aakk
	setksmps	1
	ainsigL, ainsigR, kfblvl, kfco	xin
	arvbL, arvbR 	reverbsc 	ainsigL, ainsigR, kfblvl, kfco
	xout	arvbL, arvbR
endop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




instr		1	;GRAIN TRIGGERING INSTRUMENT (ALWAYS ON)
		if		gkOnOff!=0	kgoto	CONTINUE		;IF ON/OFF BUTTON IS NOT OFF, SKIP THE NEXT LINE
		turnoff								;TURN THIS INSTRUMENT OFF IMMEDIATELY
		CONTINUE:							;LABEL CALLED 'CONTINUE'
		iporttime	=		0.05				;PORTAMENTO TIME
		gkporttime	linseg		0,.01,iporttime,1,iporttime	;gkporttime WILL RAMP UP AND HOLD THE VALUE iporttime
		kGPS		portk		gkGPS, gkporttime		;APPLY PORTAMENTO TO GRAINS-PER-SECOND VARIABLE
		ktrigger	metro		gkGPS				;CREATE A METRICAL TRIGGER (MOMENTARY 1s) USING GRAINS-PER-SECOND AS A FREQUENCY CONTROL
		kptr		portk		gkptr, gkporttime		;APPLY PORTAMENTO TO POINTER VARIABLE
		kLFO		lfo		(gkLFOamp * 0.5), gkLFOfrq, 1	;TRIANGLE WAVEFORM LFO TO CREATE AN LFO POINTER
		kptr		=		kptr + (kLFO + 0.5)		;ADD POINTER VARIABLE TO POINTER LFO
		kptr		wrap		kptr, 0, 1			;WRAP OUT OF RANGE VALUE FOR POINTER BETWEEN ZERO AND 1
		giSampleLen 	= 		(nsamp(gifn))/sr		;DERIVE SAMPLE LENGTH IN SECONDS
		kptr		=		kptr * giSampleLen		;RESCALE POINTER ACCORDING TO SAMPLE LENGTH
		;               OPCODE	 	KTRIGGER, KMINTIME, KMAXNUM, KINSNUM, KWHEN, KDUR,  P4
				schedkwhen	ktrigger,    0,        0,       2,      0,     0,  kptr	;TRIGGER INSTR 2 ACCORDING TO TRIGGER. SEND POINTER VALUE VIA P-FIELD 4
endin
	
instr		2	;SCHEDKWHEN TRIGGERED INSTRUMENT. ON FOR JUST AN INSTANCE. THIS INSTRUMENT DEFINES GRAIN DURATION, ADDS GRAIN GAP OFFSET, AND TRIGGERS THE GRAIN SOUNDING INSTRUMENT
		idur		random		i(gkdurMin), i(gkdurMax)	;DERIVE A GRAIN DURATION ACCORDING TO DURATION RANGE SETTINGS 
		igap_OS		random		0, i(gkgap_OS)			;DERIVE A GRAIN GAP OFFSET ACCORDING TO FLTK VARIABLE "Grain Gap Offset"
				event_i		"i", 3, igap_OS, idur, p4	;TRIGGER INSTRUMENT 3 (GRAIN SOUNDING INSTRUMENT). PASS POINTER VALUE VIA P-FIELD 4. GRAIN GAP OFFSET IS IMPLEMENTED USING P2/'WHEN' PARAMETER FIELD. 
endin
		
instr		3	;GRAIN SOUNDING INSTRUMENT
		iwidth 		=	i(gkwidth)						;DERIVE AN I-RATE VERSION OF gkwidth
		iampdepth 	=	i(gkampdepth)						;DERIVE AN I-RATE VERSION OF gkampdepth
		iptr_OS		=	i(gkptr_OS)						;DERIVE AN I-RATE VERSION OF gkptr_OS (POINTER OFFSET)
		ioct_OS		random	-i(gkpchosrange), i(gkpchosrange)			;DERIVE CONTINUOUS TRANSPOSITION CONSTANT
		irndoctave	random	i(gkrndoctavemin), i(gkrndoctavemax)                    ;DERIVE OCTAVE INTERVAL TRANSPOSITION CONSTANT
		ipchrto		=	cpsoct(8+int(irndoctave)+i(gkoct)+ioct_OS)/cpsoct(8)    ;CREATE A PITCH RATIO (TO UNISON) CONSTANT COMBINING ALL TRANSPOSITION CONSTANTS
		iskip		=	p4 + rnd(iptr_OS)					;DEFINE 'IN-SKIP' INTO THE SOUND FILE (IN SECONDS) FROM POINTER VALUE PASSED FROM CALLER INSTRUMENT AND RANDOM POINTER OFFSET	
		iatt		=	i(gkatt)						;DERIVE AN I-RATE VERSION OF gkatt (ATTACK TIME)
		idec		=	i(gkdec)                                                ;DERIVE AN I-RATE VERSION OF gkdec (DECAY TIME)
		if		iatt+idec>1	then		;IF ATTACK TIME AND DECAY TIME ARE GREATER THAN 1 THEN THE VALUES SHOULD BE RESCALED SO THAT THE SUM IS EQUAL TO 1
			iatt	=	iatt/(iatt+idec)	;RESCALE iatt
			idec	=	idec/(iatt+idec)	;RESCALE idec
		endif						;END OF CONDITIONAL BRANCHING
		aenvL		linseg	0,	(iatt * p3),	1,	((1 - iatt - idec) * p3),	1,	(idec * p3),	0	;DEFINE GRAIN AMPLITUDE ENVELOPE (STRAIGHT SEGMENTS)
		aenvE		expsega	.0001,	(iatt * p3),	1,	((1 - iatt - idec) * p3),	1,	(idec * p3),	.0001	;DEFINE GRAIN AMPLITUDE ENVELOPE (EXPONENTIAL SEGMENTS)	
		aenv		ntrpol	aenvL, aenvE, gkEnvType										;CREATE A RESULTANT ENVELOPE THAT IS A CONTINUOUS MORPH BETWEEN THE STRAIGHT AND EXPONENTIAL VERSIONS ABOVE
		iamp 		= 	(1 - rnd(iampdepth))*i(gkgain)	;DERIVE AMPLITUDE FROM 'Gain' SLIDER AND FROM 'Random Amplitude Depth' SLIDER
		ipan		random	-iwidth, iwidth			;DERIVE A PANNING POSITION FOR THIS GRAIN FROM 'Random Panning Amount' SLIDER
		ipan 		= 	ipan + .5			;OFFSET ipan by +0.5
		aptr		line	iskip,   p3 / ipchrto,   iskip+p3	;DEFINE A MOVING POINTER FUNCTION TO READ GRAIN FROM FUNCTION TABLE CONTAINING SOURCE AUDIO
		asig  		tablei	aptr * sr, gifn				;READ AUDIO FROM SOURCE SOUND FUNCTION TABLE. I.E. CREATE GRAIN
		;GRAIN-BY-GRAIN RING MODULATION;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		if	gkRMOnOff=1	then						;IF BAND-PASS FILTERING ON/OFF SWITCH IS ON...
			iRMfreq		random	i(gkRMfreqmin), i(gkRMfreqmax)		;DEFINE RANDOM RING MODULATION FREQUENCY
			anoRM		=	1					;A-RATE CONSTANT VALUE OF '1'
			amod		oscil	1, iRMfreq, 11				;CREATE RING MODULATING OSCILATOR
			amod		ntrpol	anoRM, amod, gkRMmix			;CREATE A MIX BETWEEN RING MODULATING OSCILATOR AND CONSTANT VALUE '1'
			asig		=	asig * amod				;RING MODULATE AUDIO SIGNAL
		endif									;END OF CONDITIONAL BRANCHING
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		;GRAIN-BY-GRAIN BAND-PASS FILTERING;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		if	gkBPFOnOff=1	then						;IF BAND-PASS FILTERING ON/OFF SWITCH IS ON...
			iBPFcut		random	i(gkBPFcutmin), i(gkBPFcutmax)		;DEFINE RANDOM FILTER CUTOFF VALUE (IN OCT FORMAT)
			iBPFfrq		=	cpsoct(iBPFcut)				;CONVERT TO CPS FORMAT
			iBPFbw		random	i(gkBPFbwmin), i(gkBPFbwmax)		;DEFINE RANDOM BANDWIDTH VALUE
			aBPF 		reson 	asig, iBPFfrq, iBPFbw*iBPFfrq, 1	;FILTER AUDIO USING reson OPCODE
			asig		ntrpol	asig, aBPF*i(gkBPFgain), gkBPFmix	;CREATE MIX BETWEEN THE FILTERED SOUND AND THE DRY SOUND
		endif									;END OF CONDITIONAL BRANCHING
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;		
		asig 		= 	asig * aenv * iamp				;APPLY AMPLITUDE CONSTANT AND GRAIN ENVELOPE
		gasendL		=	gasendL + (asig * ipan)				;APPLY PANNING VARIABLE AND CREATE LEFT CHANNEL ACCUMULATED OUTPUT 
		gasendR		=	gasendR + (asig * (1 - ipan))			;APPLY PANNING VARIABLE AND CREATE RIGHT CHANNEL ACCUMULATED OUTPUT
endin
		
instr		4	;GLOBAL PROCESSING OF GRANULAR OUTPUT & REVERB INSTRUMENT
		asigL	=	gasendL					;READ ACCUMULATED AUDIO SENT BY GRAIN RENDERING INSTRUMENT AND CREATE A LOCAL AUDIO VARIABLE OUTPUT (THIS IS TO ALLOW REDEFINITION OF THE VARIABLE WITHIN THE SAME LINE OF CODE - NOT POSSIBLE WITH GLOBAL VARIABLES)
		asigR	=	gasendR					;READ ACCUMULATED AUDIO SENT BY GRAIN RENDERING INSTRUMENT AND CREATE A LOCAL AUDIO VARIABLE OUTPUT (THIS IS TO ALLOW REDEFINITION OF THE VARIABLE WITHIN THE SAME LINE OF CODE - NOT POSSIBLE WITH GLOBAL VARIABLES)
		if		gkFiltOnOff=1	then			;IF GLOBAL FILTERING ON/OFF SWITCH IS ON...
			kHPFcf		portk	gkHPFcf, gkporttime	;APPLY PORTAMENTO TO HIGH-PASS FILTER CUTOFF VARIABLE
			kLPFcf		portk	gkLPFcf, gkporttime     ;APPLY PORTAMENTO TO LOW-PASS FILTER CUTOFF VARIABLE
			asigL		buthp	asigL, kHPFcf		;APPLY HIGH-PASS FILTER TO LEFT CHANNEL AUDIO...
			asigL		buthp	asigL, kHPFcf		;...AND AGAIN TO SHARPEN CUTOFF SLOPE
			asigR		buthp	asigR, kHPFcf           ;APPLY HIGH-PASS FILTER TO LEFT CHANNEL AUDIO...
			asigR		buthp	asigR, kHPFcf		;...AND AGAIN TO SHARPEN CUTOFF SLOPE           	
			asigL		butlp	asigL, kLPFcf		;APPLY LOW-PASS FILTER TO LEFT CHANNEL AUDIO...
			asigL		butlp	asigL, kLPFcf           ;...AND AGAIN TO SHARPEN CUTOFF SLOPE           
			asigR		butlp	asigR, kLPFcf           ;APPLY LOW-PASS FILTER TO RIGHT CHANNEL AUDIO...
			asigR		butlp	asigR, kLPFcf           ;...AND AGAIN TO SHARPEN CUTOFF SLOPE           
                endif							;END OF CONDITIONAL BRANCHING
		outs 		asigL * (1 - gkRvbDryWet), asigR * (1 - gkRvbDryWet)	;SEND DRY AUDIO TO OUTPUTS

		if		gkRvbOnOff=1	then			;IF REVERB ON/OFF SWITCH IS ON...
			denorm		asigL, asigR			;...DENORMALIZE BOTH CHANNELS OF AUDIO SIGNAL
			arvbL, arvbR 	reverbsr 	asigL  * gkRvbDryWet, asigR  * gkRvbDryWet, gkfblvl, gkfco	;CREATE REVERBERATED SIGNAL (USING UDO DEFINED ABOVE)
					outs	arvbL, arvbR								;SEND REVERBERATED SIGNAL TO AUDIO OUTPUTS
		endif							;END OF CONDITIONAL BRANCHING
		clear	gasendL, gasendR	;ZERO GLOBAL AUDIO VARIABLES USED TO SEND ACCUMULATED GRAINS
endin
		
</CsInstruments>

<CsScore>
f 1 0 1048576 1 "ClassicalGuitar.wav" 0 4 1	;THE SOUND FILE
f 11 0 512 10 1					;SINE WAVE
i 4 0 3600	;GLOBAL PROCESSING OF GRANULAR OUTPUT & REVERB
</CsScore>

</CsoundSynthesizer>