;Written by Iain McCurdy, 2009

<CsoundSynthesizer>

<CsOptions>
-odevaudio -b400
</CsOptions>

<CsInstruments>

sr 		= 	44100	;SAMPLE RATE
kr 		= 	441	;CONTROL 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	"fog",   500,     830,   0,  0

;TEXT BOXES              					TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y 
ihtmodelabel	 FLbox  "0-Grain-by-Grain  1-Continuous", 	1,     9,      12,   150,     30,    150, 50

;COUNTERS							MIN | MAX | STEP1 | STEP2 | TYPE | WIDTH | HEIGHT | X | Y | OPCODE 
gktransmode, ihtransmode	FLcount  "Transposition Mode",	0,     1,     1,      1,     2,     140,    25,    155, 5,   -1

;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

FLsetColor2	255, 255, 50, ihOnOff		;SET SECONDARY COLOUR TO YELLOW

;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
gkinput,   ihinput			FLbutBank	4,     1,     3,     20,      45,    45, 35,   -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  	"File:", 	1,       5,    12,     40,     15,    5,   34
ih		 	FLbox  	"Voice ", 	1,       5,    12,     40,     15,   65,   34
ih		 	FLbox  	"Drums ", 	1,       5,    12,     40,     15,   65,   49
ih		 	FLbox  	"Guitar", 	1,       5,    12,     40,     15,   65,   64



;NUMBER DISPLAY BOXES		WIDTH | HEIGHT | X | Y
idoct		FLvalue	" ",      90,     20,    0, 455
idtrans		FLvalue	" ",      90,     20,    0, 505
iddur		FLvalue	" ",      90,     20,    0, 555
idris		FLvalue	" ",      90,     20,    0, 605
iddec		FLvalue	" ",      90,     20,    0, 655
idband		FLvalue	" ",      90,     20,    0, 705
idamp		FLvalue	" ",      90,     20,    0, 755
idphs		FLvalue	" ",      90,     20,    0, 805

;SLIDERS					      					MIN | MAX | EXP | TYPE |     DISP   | WIDTH | HEIGHT | X   | Y
gkoct, ihoct		FLslider	"Octaviation Index",  				0,    4,     0,    23,      idoct,     490,     25,    0, 430
gktrans, ihtrans	FLslider	"Transposition Factor (portamento applied)",  	-2,   2,     0,    23,      idtrans,   490,     25,    0, 480
gkdur, ihdur		FLslider	"Grain Duration",  				.01,  .2,    0,    23,      iddur,     490,     25,    0, 530
gkris, ihris		FLslider	"Grain Rise Time",  				.001, .2,    0,    23,      idris,     490,     25,    0, 580
gkdec, ihdec		FLslider	"Grain Decay Time",  				.001, .2,    0,    23,      iddec,     490,     25,    0, 630
gkband, ihband		FLslider	"Bandwidth (Grain Exponential Decay)",  	0,    100,   0,    23,      idband,    490,     25,    0, 680
gkamp, ihamp		FLslider	"Amplitude",  					0,    1, 0,    23,      idamp,     490,     25,    0, 730
gkphs, ihphs		FLslider	"Initial Phase Of Fundamental (i-rate)",	0,    1,     0,    23,      idphs,     490,     25,    0, 780
gkporttime,ihporttime	FLslider 	"Portamento Amount",				0,    1,     0,    23,      -1,        190,     15,  305,  10

;NUMBER DISPLAY BOXES			WIDTH | HEIGHT | X | Y
idfund			FLvalue	"Pointer",70,      20,     5,  380
idform			FLvalue	"Density",70,      20,   425,  380

;XY PANELS								MINX | MAXX | MINY | MAXY | EXPX | EXPY | DISPX | DISPY | WIDTH | HEIGHT | X | Y
gkptr, gkdens, ihptr, ihdens	FLjoy	"X - Pointer  Y - Density",	0,        1,  0.5,    400,    0,    -1,  idfund, idform,   490,    280,    5, 100
FLsetColor2	255, 0, 0, ihptr		;SET SECONDARY COLOUR TO RED
FLsetColor2	255, 0, 0, ihdens		;SET SECONDARY COLOUR TO RED

; INITIALISATION OF SLIDERS
			FLsetVal_i   	0,	ihtransmode
			FLsetVal_i   	.3,	ihptr
			FLsetVal_i   	20,	ihdens
			FLsetVal_i   	0,	ihoct
			FLsetVal_i   	1,	ihtrans
			FLsetVal_i   	.1,	ihdur
			FLsetVal_i   	.01,	ihris
			FLsetVal_i   	.01,	ihdec
			FLsetVal_i   	10,	ihband
			FLsetVal_i   	0.2,	ihamp
			FLsetVal_i   	0,	ihphs
			FLsetVal_i	0.1, 	ihporttime

	FLpanel_end

;INSTRUCTIONS AND INFO PANEL
				FLpanel	" ", 500, 680, 512, 0
;TEXT BOXES												TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ih		 	FLbox  	"                            fog                              ", 	1,      5,     14,    490,    20,     5,  0
ih		 	FLbox  	"-------------------------------------------------------------", 	1,      5,     14,    490,    20,     5,  20
ih		 	FLbox  	"Fog performs granular synthesis upon sound material stored   ", 	1,      5,     14,    490,    20,     5,  40
ih		 	FLbox  	"within a GEN 1 function table using a method that bears many ", 	1,      5,     14,    490,    20,     5,  60
ih		 	FLbox  	"simularities to the fof opcode.                              ", 	1,      5,     14,    490,    20,     5,  80
ih		 	FLbox  	"The amplitude envelope that is applied to each grain is      ", 	1,      5,     14,    490,    20,     5, 100
ih		 	FLbox  	"controlled by a combination of the 'Grain Duration' (kdur),  ", 	1,      5,     14,    490,    20,     5, 120
ih		 	FLbox  	"'Grain Rise Time' (kris), 'Grain Decay Time' (kdec) and      ", 	1,      5,     14,    490,    20,     5, 140
ih		 	FLbox  	"'Bandwidth (Grain Exponential Decay)' (kband). Bandwidth     ", 	1,      5,     14,    490,    20,     5, 160
ih		 	FLbox  	"controls how an exponential curve defined in a separate      ", 	1,      5,     14,    490,    20,     5, 180
ih		 	FLbox  	"function is applied to the decay of each grain.              ", 	1,      5,     14,    490,    20,     5, 200
ih		 	FLbox  	"'Pointer' (aspd) defines the point from within the stored    ", 	1,      5,     14,    490,    20,     5, 220
ih		 	FLbox  	"sound file (range 0-1) that grains will be read.             ", 	1,      5,     14,    490,    20,     5, 240
ih		 	FLbox  	"'Density' (kdens) controls the frequency of grain duration in", 	1,      5,     14,    490,    20,     5, 260
ih		 	FLbox  	"grains per second.                                           ", 	1,      5,     14,    490,    20,     5, 280
ih		 	FLbox  	"'Transposition Factor' (ktrans) controls the transposition of", 	1,      5,     14,    490,    20,     5, 300
ih		 	FLbox  	"each grain. 1=no transposition. 2=up one octave. 0.5=down one", 	1,      5,     14,    490,    20,     5, 320
ih		 	FLbox  	"octave and so on... A minus sign indicates that grains will  ", 	1,      5,     14,    490,    20,     5, 340
ih		 	FLbox  	"be played backwards, the numerical part functions in the same", 	1,      5,     14,    490,    20,     5, 360
ih		 	FLbox  	"way.                                                         ", 	1,      5,     14,    490,    20,     5, 380
ih		 	FLbox  	"'Transposition Mode' (itmode) is a 2-way switch defining     ", 	1,      5,     14,    490,    20,     5, 400
ih		 	FLbox  	"whether transposition modulation is carried out on a grain by", 	1,      5,     14,    490,    20,     5, 420
ih		 	FLbox  	"grain basis or continually, even within the duration of a    ", 	1,      5,     14,    490,    20,     5, 440
ih		 	FLbox  	"grain. To appreciate this effect first create a texture with ", 	1,      5,     14,    490,    20,     5, 460
ih		 	FLbox  	"large sparse grains.                                         ", 	1,      5,     14,    490,    20,     5, 480
ih		 	FLbox  	"'Octaviation Index' (koct) is typically zero but as it tends ", 	1,      5,     14,    490,    20,     5, 500
ih		 	FLbox  	"to 1 every other grain is increasingly attenuated. When it is", 	1,      5,     14,    490,    20,     5, 520
ih		 	FLbox  	"exactly 1 the grain density is effectively halved. From 1 to ", 	1,      5,     14,    490,    20,     5, 540
ih		 	FLbox  	"2 the process is repeated and the density is halved again and", 	1,      5,     14,    490,    20,     5, 560
ih		 	FLbox  	"so on from 2 to 3 and beyond. This effect is perceived quite ", 	1,      5,     14,    490,    20,     5, 580
ih		 	FLbox  	"differently for dense and sparse textures.                   ", 	1,      5,     14,    490,    20,     5, 600
ih		 	FLbox  	"In this example a controllable amount of portamento is       ", 	1,      5,     14,    490,    20,     5, 620
ih		 	FLbox  	"applied to 'Pointer', 'Transposition Factor' and 'Density' in", 	1,      5,     14,    490,    20,     5, 640
ih		 	FLbox  	"order to allow smoother changes of their values.             ", 	1,      5,     14,    490,    20,     5, 660

				FLpanel_end

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

; THE SOUND FILES USED IN THE GRANULATION
;              NUM | INIT_TIME | SIZE | GEN_ROUTINE | FILE_PATH          | IN_SKIP | FORMAT | CHANNEL
gifile1L ftgen 0,        0,     524288,       1,    "AndItsAll.wav",          0,        4,        1 
gifile2L ftgen 0,        0,     524288,       1,    "loop.wav",               0,        4,        1 
gifile3L ftgen 0,        0,     1048576,      1,    "ClassicalGuitar.wav",    0,        4,        1 

gifile1R ftgen 0,        0,     524288,       1,    "AndItsAll.wav",          0,        4,        1 
gifile2R ftgen 0,        0,     524288,       1,    "loop.wav",               0,        4,        1 
gifile3R ftgen 0,        0,     1048576,      1,    "ClassicalGuitar.wav",    0,        4,        2 

; CURVE USED TO FORM ATTACK AND DECAY PORTIONS OF EACH GRAIN
;              NUM | INIT_TIME | SIZE | GEN_ROUTINE |  PARTIAL_NUMBER_1 | STRENGTH_1 | PHASE_1 | DC_OFFSET_1
giattdec ftgen  0,        0,     524288,     19,             0.5,             0.5,        270,         0.5	; I.E. A RISING SIGMOID

instr	1
	if	gkOnOff=0	then	;IF On/Off SWITCH IS SET TO 'OFF'...
		turnoff			;TURN THIS INSTRUMENT OFF
	endif				;END OF CONDITIONAL BRANCHING
	kporttime	linseg	0,0.001,1,1,1	;CREATE A VARIABLE FUNCTION THAT RAPIDLY RAMPS UP TO A SET VALUE	
	kporttime	=		kporttime * gkporttime	;FLTK SLIDER FOR PORTAMENTO TIME MULTIPLIED TO kporttime FUNCTION
	;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	gktransmode, gkphs, gkinput	;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:

	ifnSoundFileL	=	gifile1L+i(gkinput)	; FUNCTION TABLE NUMBER OF THE SOUND FILE THAT WILL BE GRANULATED
	ifnSoundFileR	=	gifile1R+i(gkinput)	; FUNCTION TABLE NUMBER OF THE SOUND FILE THAT WILL BE GRANULATED
	ifnRiseDecayShape=	giattdec	; FUNCTION TABLE THAT DEFINES THE SHAPE OF THE ATTACK AND DECAY OF EACH GRAIN

	kptr		=	gkptr * (nsamp(ifnSoundFileL)/ftlen(ifnSoundFileL))	;KPTR VALUE IS RESCALED TO ACCOUNT FOR UNUSED SAMPLES
									;IN THE FUNCTION TABLE
	iNumOverLaps	=	200	; MAXIMUM NUMBER OF OVERLAPS (OVERESTIMATATION IS A GOOD IDEA HERE TO PREVENT CRASHES)
	
	itotdur		=	3600	; JUST PUT A LARGE NUMBER HERE FOR REAL TIME - FOR NON-REAL TIME GIVE IT p3
	
	kdens		portk	gkdens,  kporttime	;PORTAMENTO IS APPLIED TO SMOOTH VALUE CHANGES VIA THE FLTK SLIDERS
	ktrans		portk	gktrans, kporttime      ;PORTAMENTO IS APPLIED TO SMOOTH VALUE CHANGES VIA THE FLTK SLIDERS
	kptr		portk	kptr,    kporttime      ;PORTAMENTO IS APPLIED TO SMOOTH VALUE CHANGES VIA THE FLTK SLIDERS
	aptr		interp	kptr			;A NEW A-RATE VARIABLE (aptr) IS CREATED BASE ON kptr
	
	;                                                                                                                                       OPTIONAL->
	asignalL	fog	gkamp, kdens, ktrans, aptr, gkoct, gkband, gkris, gkdur, gkdec, iNumOverLaps, ifnSoundFileL, ifnRiseDecayShape, itotdur, i(gkphs), i(gktransmode)
	asignalR	fog	gkamp, kdens, ktrans, aptr, gkoct, gkband, gkris, gkdur, gkdec, iNumOverLaps, ifnSoundFileR, ifnRiseDecayShape, itotdur, i(gkphs), i(gktransmode)
	rireturn	;RETURN TO PERFORMANCE TIME PASSES
			outs	asignalL, asignalR	;OUTPUT OF fog OPCODE IS SENT TO THE OUTPUTS
endin

</CsInstruments>

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

</CsoundSynthesizer>