;Written by Iain McCurdy, 2006

<CsoundSynthesizer>

<CsOptions>
-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	;MAXIMUM SOUND INTENSITY LEVEL REGARDLESS OF BIT DEPTH

;FLTK INTERFACE CODE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FLcolor	255, 255, 255, 0, 0, 0	;SET INTERFACE COLOURS
;		LABEL | WIDTH | HEIGHT | X | Y
	FLpanel	"grain3",500,    700,   0,  0

;SWITCHES                       						ON | OFF | TYPE | WIDTH | HEIGHT | X | Y | OPCODE | INS | STARTTIM | IDUR
gkOnOff,ihOnOff		FLbutton	"On/Off",				1,    0,    22,    140,     25,    5,  5,    0,      1,      0,      3600
gkSyncCPS,ihoptions1	FLbutton	"Sync Start Phase to CPS",		64,   0,    22,    166,     50,    0,500,    0,      1,      0,      -1
gkIntegerLoc,ihoptions2	FLbutton	"Start All Grains at Integer Location",	32,   0,    22,    166,     50,  166,500,    0,      1,      0,      -1
gkLessZero,ihoptions3	FLbutton	"Ignore Grains Starting at Phase<0",	16,   0,    22,    166,     50,  333,500,    0,      1,      0,      -1
gkInterp,ihoptions4	FLbutton	"Interpolate Window",			8,    0,    22,    166,     50,    0,550,    0,      1,      0,      -1
gkNoInterp,ihoptions5	FLbutton	"No Interpolate Waveform",		4,    0,    22,    166,     50,  166,550,    0,      1,      0,      -1
gkFreqCont,ihoptions6	FLbutton	"Continual Freq. Modification",		2,    0,    22,    166,     50,  333,550,    0,      1,      0,      -1
gkSkipInit,ihoptions7	FLbutton	"Skip Initialisation",			1,    0,    22,    166,     50,    0,600,    0,      1,      0,      -1
FLsetColor2	255, 255, 50, ihOnOff		;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihoptions1	;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihoptions2	;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihoptions3	;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihoptions4	;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihoptions5	;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihoptions6	;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihoptions7	;SET SECONDARY COLOUR TO YELLOW

;NUMBER DISPLAY BOXES		WIDTH | HEIGHT | X | Y
idamp	  FLvalue   " ",     	80,       20,    5,  75
iddur	  FLvalue   " ",     	80,       20,    5, 125
idpch	  FLvalue   " ",     	80,       20,    5, 175
idfmd	  FLvalue   " ",     	80,       20,    5, 225
iddens	  FLvalue   " ",     	80,       20,    5, 275
idphs	  FLvalue   " ",     	80,       20,    5, 325
idpmd	  FLvalue   " ",     	80,       20,    5, 375
idfrpow	  FLvalue   " ",     	80,       20,    5, 425
idprpow	  FLvalue   " ",     	80,       20,    5, 475
idseed	  FLvalue   " ",     	80,       17,  305,  30

;SLIDERS										MIN     |    MAX    | EXP | TYPE |   DISP   | WIDTH | HEIGHT | X   | Y
gkamp, ihamp		FLslider	"Amplitude",    				0,                1,   0,    23,     idamp,     490,     25,    5,    50
gkdur, ihdur		FLslider	"Grain Duration (ms.)",				.001,             1,   0,    23,     iddur,     490,     25,    5,   100
gkpch, ihpch		FLslider	"Pitch",					.016125,         16,  -1,    23,     idpch,     490,     25,    5,   150
gkfmd, ihfmd		FLslider	"Pitch Offset",					0,               .3,   0,    23,     idfmd,     490,     25,    5,   200
gkdens, ihdens		FLslider	"Density",					1,              500,   0,    23,     iddens,    490,     25,    5,   250
gkphs, ihphs		FLslider	"Grain Phase",					0,                1,   0,    23,     idphs,     490,     25,    5,   300
gkpmd, ihpmd		FLslider	"Grain Phase Random Offset",			0,                1,   0,    23,     idpmd,     490,     25,    5,   350
gkfrpow, ihfrpow	FLslider	"Distribution of Random Frequency Variation",	-2,               2,   0,    23,     idfrpow,   490,     25,    5,   400
gkprpow,ihprpow		FLslider	"Distribution of Random Phase Variation",	-2,               2,   0,    23,     idprpow,   490,     25,    5,   450
gkseedL,ihseedL		FLslider	" ",						0,       2147483646,   0,    23,     idseed,    190,     12,  305,     5
gkseedR,ihseedR		FLslider	"Seed Value L/R",				0,       2147483646,   0,    23,     idseed,    190,     12,  305,    17

;			FLsetAlign ialign, ihandle
			FLsetAlign 9,      ihseedR	; (BOTTOM RIGHT)

;COUNTERS				     		MIN | MAX | STEP1 | STEP2 | TYPE | WIDTH | HEIGHT | X | Y | OPCODE 
gkmaxolap, ihmaxolap	FLcount  "Maximum Overlaps", 	1,   1000,    1,     100,     1,    140,     25,   155, 5,    -1 
gkwfn, ihwfn		FLcount  "Grain Envelope", 	1,      6,    1,     100,     2,    166,     25,   166,605,   -1 

;TEXT BOXES              																														TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y 
ih		 FLbox  "Grain Envelopes: 1 - Hanning . 2 - Percussive (straight segments) . 3 - Percussive (exponential segments) . 4 - Gate (with anti click ramp up and ramp down) . 5 - Reverse Percussive (straight segments) . 6 - Reverse Percussive (exponential segments)", 	1,     1,      12,    500,     30,    0, 655

; INITIAL VALUES OF SLIDERS
;OPCODE		VALUE | HANDLE
FLsetVal_i   	0.25, 	ihamp
FLsetVal_i   	600, 	ihmaxolap
FLsetVal_i   	.25, 	ihdur
FLsetVal_i   	1, 	ihpch
FLsetVal_i   	0, 	ihfmd
FLsetVal_i   	5, 	ihdens
FLsetVal_i   	.45, 	ihphs
FLsetVal_i   	.0055, 	ihpmd
FLsetVal_i   	.01, 	ihfrpow
FLsetVal_i   	-2, 	ihprpow
FLsetVal_i   	0, 	ihseedL
FLsetVal_i   	0, 	ihseedR
FLsetVal_i   	1, 	ihwfn

	FLpanel_end

;INSTRUCTIONS AND INFO PANEL
				FLpanel	" ", 515, 700, 512, 0
				FLscroll     515, 700, 0, 0

;TEXT BOXES												TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ih		 	FLbox  	"                          grain3                             ", 	1,      5,     14,    490,    20,     5,  0
ih		 	FLbox  	"-------------------------------------------------------------", 	1,      5,     14,    490,    20,     5,  20
ih		 	FLbox  	"grain3 performs granular synthesis upon a stored function    ", 	1,      5,     14,    490,    20,     5,  40
ih		 	FLbox  	"table. The function table used can contain a simple single   ", 	1,      5,     14,    490,    20,     5,  60
ih		 	FLbox  	"cycle waveform or it can contain a stored sample. In this    ", 	1,      5,     14,    490,    20,     5,  80
ih		 	FLbox  	"example a sound sample stored within a GEN 1 function table  ", 	1,      5,     14,    490,    20,     5, 100
ih		 	FLbox  	"is used. By studying the code it is seen that interrogation  ", 	1,      5,     14,    490,    20,     5, 120
ih		 	FLbox  	"of the sample's duration is needed in order for the 'phase'  ", 	1,      5,     14,    490,    20,     5, 140
ih		 	FLbox  	"parameter to be used effectively. 'Phase' effectively defines", 	1,      5,     14,    490,    20,     5, 160
ih		 	FLbox  	"to the location within the waveform or function table from   ", 	1,      5,     14,    490,    20,     5, 180
ih		 	FLbox  	"which samples will be read.                                  ", 	1,      5,     14,    490,    20,     5, 200
ih		 	FLbox  	"In this example pitch is reinterpretted mathematically so    ", 	1,      5,     14,    490,    20,     5, 220
ih		 	FLbox  	"that the values inputted via the interface are ratios to the ", 	1,      5,     14,    490,    20,     5, 240
ih		 	FLbox  	"original pitch of the sample. i.e. a value of represents no  ", 	1,      5,     14,    490,    20,     5, 260
ih		 	FLbox  	"transposition, a value of 2 represents a transposition up 1  ", 	1,      5,     14,    490,    20,     5, 280
ih		 	FLbox  	"octave, a value of .5 represents a transposition down 1      ", 	1,      5,     14,    490,    20,     5, 300
ih		 	FLbox  	"octave and so on.                                            ", 	1,      5,     14,    490,    20,     5, 320
ih		 	FLbox  	"The grain3 opcode allows for user modification of what sort  ", 	1,      5,     14,    490,    20,     5, 340
ih		 	FLbox  	"of random distribution it uses in its randomisation          ", 	1,      5,     14,    490,    20,     5, 360
ih		 	FLbox  	"precedures for pitch and phase. This example allows the user ", 	1,      5,     14,    490,    20,     5, 380
ih		 	FLbox  	"to modify these setting but for a more in depth explanation  ", 	1,      5,     14,    490,    20,     5, 400
ih		 	FLbox  	"of what exactly these values represent the user is directed  ", 	1,      5,     14,    490,    20,     5, 420
ih		 	FLbox  	"to the Csound Manual.                                        ", 	1,      5,     14,    490,    20,     5, 440
ih		 	FLbox  	"The 'seed value' (optional) is used to seed the pseudo-random", 	1,      5,     14,    490,    20,     5, 460
ih		 	FLbox  	"number generator that is used in the randomization of pitch  ", 	1,      5,     14,    490,    20,     5, 480
ih		 	FLbox  	"and phase. A value of zero means that the system clock       ", 	1,      5,     14,    490,    20,     5, 500
ih		 	FLbox  	"reading will be used as a seed value.                        ", 	1,      5,     14,    490,    20,     5, 520
ih		 	FLbox  	"Another optional input argument, called 'imode' in the manual", 	1,      5,     14,    490,    20,     5, 540
ih		 	FLbox  	"allows for the setting of a variety of subtle options in the ", 	1,      5,     14,    490,    20,     5, 560
ih		 	FLbox  	"precise way in which grains are produced. For convenience    ", 	1,      5,     14,    490,    20,     5, 580
ih		 	FLbox  	"these options are represented individually with a series of  ", 	1,      5,     14,    490,    20,     5, 600
ih		 	FLbox  	"switches in this example.                                    ", 	1,      5,     14,    490,    20,     5, 620
ih		 	FLbox  	"The user must supply a windowing function via a function     ", 	1,      5,     14,    490,    20,     5, 640
ih		 	FLbox  	"table that the opcode will use to apply an amplitude envelope", 	1,      5,     14,    490,    20,     5, 660
ih		 	FLbox  	"to each grain. In this example six different envelope types  ", 	1,      5,     14,    490,    20,     5, 680
ih		 	FLbox  	"are offerred for experimentation. Descriptions of the        ", 	1,      5,     14,    490,    20,     5, 700
ih		 	FLbox  	"different types on offer are included on the main panel. To  ", 	1,      5,     14,    490,    20,     5, 720
ih		 	FLbox  	"hear most clearly the effect of using different grain        ", 	1,      5,     14,    490,    20,     5, 740
ih		 	FLbox  	"envelopes set 'Density' to a low value and set 'Grain        ", 	1,      5,     14,    490,    20,     5, 760
ih		 	FLbox  	"Duration' to a high setting.                                 ", 	1,      5,     14,    490,    20,     5, 780

				FLscrollEnd
				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
	;OUTPUTS	OPCODE	FILE           | SPEED | INSKIP | LOOPING (0=OFF 1=ON)
	asigL, asigR	diskin2	"Seashore.wav",    1,       0,         1	;GENERATE 2 AUDIO SIGNALS FROM A STEREO SOUND FILE
	kSwitch		changed	gkmaxolap, gkseedL, gkseedR, gkSyncCPS, gkIntegerLoc, gkLessZero, gkInterp, gkNoInterp, gkFreqCont, gkFreqCont, gkSkipInit, gkwfn
	if	kSwitch=1	then		;IF I-RATE VARIABLE CHANGE TRIGGER IS '1'...
		reinit	START			;BEGIN A REINITIALISATION PASS FROM LABEL 'START'
	endif
	START:
	ifn 		= 	1	;SOURCE SOUND/WAVEFORM FUNCTION TABLE
	kpitch 		= 	(sr*gkpch)/ftlen(ifn)	;MATHEMATICALLY REINTERPRET USER INPUTTED PITCH RATIO VALUE INTO A FORMAT THAT IS USABLE AS AN INPUT ARGUMENT BY THE grain3 OPCODE - ftlen(x) FUNCTION RETURNS THE LENGTH OF A FUNCTION TABLE (no. x), REFER TO MANUAL FOR MORE INFO.
	imaxovr 	= 	i(gkmaxolap)	;MAXIMUM NUMBER OF OVERLAPS
	kphs 		= 	gkphs*(nsamp(ifn)/ftlen(ifn))	;MATHREMATICALLY REINTERPRET USER INPUTTED PHASE VALUE INTO A FORMAT THAT IS USABLE AS AN INPUT ARGUMENT  BY THE grain3 OPCODE
	imode	=	i(gkSyncCPS) + i(gkIntegerLoc) + i(gkLessZero) + i(gkInterp) + i(gkNoInterp) + i(gkFreqCont) + i(gkFreqCont) + i(gkSkipInit)	;SUM THE MODE BUTTON OUTPUTS
	aSignalL	grain3	kpitch, kphs, gkfmd, gkpmd, gkdur, gkdens, imaxovr, ifn, i(gkwfn)+99, gkfrpow, gkprpow , i(gkseedL), int(imode)
	aSignalR	grain3	kpitch, kphs, gkfmd, gkpmd, gkdur, gkdens, imaxovr, ifn, i(gkwfn)+99, gkfrpow, gkprpow , i(gkseedR), int(imode)
	rireturn	;RETURN TO PERFORMANCE TIME PASSES
		outs 	aSignalL * gkamp, aSignalR * gkamp
endin

</CsInstruments>

<CsScore>
; THE SOUND FILE USED IN THE GRANULATION
; NUM | INIT_TIME | SIZE | GEN_ROUTINE | FILE_PATH     | IN_SKIP | FORMAT | CHANNEL
f  1        0      524288       1       "AndItsAll.wav"     0         4        1 

;GRAIN ENVELOPE WINDOW FUNCTION TABLES:
f100  0 512  20 2			; HANNING WINDOW
f101  0 512  7 0 12 1 500 0		; PERCUSSIVE - STRAIGHT SEGMENTS
f102  0 512  5 .001 12 1 500 .001	; PERCUSSIVE - EXPONENTIAL SEGMENTS
f103  0 512  7 0 6 1 500 1 6 0		; GATE - WITH ANTI-CLICK RAMP UP AND RAMP DOWN SEGMENTS
f104  0 512  7 0 500 1 12 0		; REVERSE PERCUSSIVE - STRAIGHT SEGMENTS
f105  0 512  5 .001 500 1 12 .001	; REVERSE PERCUSSIVE - EXPONENTIAL SEGMENTS

f 0 3600	;DUMMY SCORE EVENT ALLOWS REAL-TIME PERFORMANCE FOR 1 HOUR
</CsScore>

</CsoundSynthesizer>