;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)


;FLTK INTERFACE CODE======================================================================================================================================================
FLcolor	255, 255, 255, 0, 0, 0
;			LABEL       | WIDTH | HEIGHT | X | Y
		FLpanel	"syncloop",    500,    820,    0   0

;SWITCHES                       				ON | OFF | TYPE | WIDTH | HEIGHT | X | Y | OPCODE | INS | STARTTIM | DUR
gkOnOff,ihOnOff			FLbutton	"On/Off",	1,    0,    22,    140,     25,    5,  5,    0,      1,     0,       -1
gkfreeze,ihfreeze		FLbutton	"Freeze",	0,    1,    22,     80,     20,  415,225,    -1
FLsetColor2	255, 255, 50, ihOnOff		;SET SECONDARY COLOUR TO YELLOW
FLsetColor2	255, 255, 50, ihfreeze		;SET SECONDARY COLOUR TO YELLOW

;VALUE DISPLAY BOXES			LABEL | WIDTH | HEIGHT | X |  Y
idamp				FLvalue	" ",      70,    20,     5,   75
idfreq				FLvalue	" ",      70,    20,     5,  125
idpitch				FLvalue	" ",      70,    20,     5,  175
idprate				FLvalue	" ",      70,    20,     5,  225
idgrsize			FLvalue	" ",      70,    20,     5,  275
idlstart			FLvalue	" ",      70,    20,     5,  595
idlend				FLvalue	" ",      70,    20,     5,  645
idnoloop			FLvalue	" ",      70,    20,     5,  795

;SLIDERS				            				MIN |   MAX  | EXP | TYPE |  DISP    | WIDTH | HEIGHT | X | Y
gkamp, ihamp			FLslider 	"Amplitude",			0,    30000,    0,    23,  idamp,       490,     25,    5,  50
gkfreq, ihfreq			FLslider 	"Density (Grain per Sec.)",	1,      200,    0,    23,  idfreq,      490,     25,    5, 100
gkpitch, ihpitch		FLslider 	"Pitch",			-2,       2,    0,    23,  idpitch,     490,     25,    5, 150
gkprate, gihprate		FLslider 	"Progress Rate",		-2,       2,    0,    23,  idprate,     490,     25,    5, 200
gkgrsize, ihgrsize		FLslider 	"Grain Size",			.001,     1,    0,    23,  idgrsize,    490,     25,    5, 250
gklstart, gihlstart		FLslider 	"Loop Start",			0,        1,    0,    23,  idlstart,    490,     25,    5, 570
gklend, gihlend			FLslider 	"Loop End",			0,        1,    0,    23,  idlend,      490,     25,    5, 620
gkfreqOS, ihfreqOS		FLslider 	"Grain Density Offset",		0,        1,    0,    23,  -1,          490,     25,    5, 670
gksizeOS, ihsizeOS		FLslider 	"Grain Size Random Offset",	0,        1,    0,    23,  -1,          490,     25,    5, 720
gknoloop, ihnoloop		FLslider 	"Loop Start & End",		0,        1,    0,    23,  idnoloop,    490,     25,    5, 770

;COUNTERS					MIN | MAX | STEP1 | STEP2 | TYPE | WIDTH | HEIGHT | X |  Y  | OPCODE P1 P2  P3
gkfun2, ihfun2	FLcount  "Grain Envelope", 	1,     6,     1,     100,     2,    150,     27,    5,  303,    -1 
gkfun1, ihfun1	FLcount  "Source Sound", 	1,     2,     1,     100,     2,    150,     27,    5,  473,    -1

;TEXT BOXES              									TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y 
ih		 FLbox  "Grain Envelopes: 1 - Half Sine                                     ", 	1,      5,     12,    500,     20,    0, 350
ih		 FLbox  "                 2 - Percussive (straight segments)                ", 	1,      5,     12,    500,     20,    0, 370
ih		 FLbox  "                 3 - Percussive (exponential segments)             ", 	1,      5,     12,    500,     20,    0, 390
ih		 FLbox  "                 4 - Gate (with anti click ramp up and ramp down)  ", 	1,      5,     12,    500,     20,    0, 410
ih		 FLbox  "                 5 - Reverse Percussive (straight segments)        ", 	1,      5,     12,    500,     20,    0, 430
ih		 FLbox  "                 6 - Reverse Percussive (exponential segments)     ", 	1,      5,     12,    500,     20,    0, 450
ih		 FLbox  "Source Sounds    1 - Classical Guitar                              ", 	1,      5,     12,    500,     20,    0, 520
ih		 FLbox  "                 2 - Drums                                         ", 	1,      5,     12,    500,     20,    0, 535

		FLsetVal_i	16000, 	ihamp
		FLsetVal_i	40, 	ihfreq
		FLsetVal_i	1, 	ihpitch
		FLsetVal_i	0.5, 	gihprate
		FLsetVal_i	.05, 	ihgrsize
		FLsetVal_i   	1, 	ihfun2
		FLsetVal_i   	1, 	ihfun1
		FLsetVal_i   	0, 	gihlstart
		FLsetVal_i   	1, 	gihlend
		
		FLpanel_end	;END OF PANEL CONTENTS

;INSTRUCTIONS AND INFO PANEL
				FLpanel	" ", 500, 320, 512, 0
;TEXT BOXES												TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ih		 	FLbox  	"                           syncloop                          ", 	1,      5,     14,    490,    15,     5,   0
ih		 	FLbox  	"-------------------------------------------------------------", 	1,      5,     14,    490,    15,     5,  20
ih		 	FLbox  	"syncloop is a variation of syncgrain. For further information", 	1,      5,     14,    490,    15,     5,  40
ih		 	FLbox  	"see the example for syncgrain first.                         ", 	1,      5,     14,    490,    15,     5,  60
ih		 	FLbox  	"syncloop adds start and end loop points which are k-rate and ", 	1,      5,     14,    490,    15,     5,  80
ih		 	FLbox  	"therefore editable in real-time.                             ", 	1,      5,     14,    490,    15,     5, 100
ih		 	FLbox  	"Some additional functions have been added that are not part  ", 	1,      5,     14,    490,    15,     5, 120
ih		 	FLbox  	"of the original opcode: 'Grain Density' (frequency) and      ", 	1,      5,     14,    490,    15,     5, 140
ih		 	FLbox  	"'Grain Size' can be randomized. The 'Freeze' button sets     ", 	1,      5,     14,    490,    15,     5, 160
ih		 	FLbox  	"the 'Progress Rate' slider to zero thereby effectively       ", 	1,      5,     14,    490,    15,     5, 180
ih		 	FLbox  	"freezing progress through the sound file. The 'Loop Start &  ", 	1,      5,     14,    490,    15,     5, 200
ih		 	FLbox  	"End' slider controls both the 'Loop Start' and 'Loop End'    ", 	1,      5,     14,    490,    15,     5, 220
ih		 	FLbox  	"sliders simultaneously - the loop size will be zero so again ", 	1,      5,     14,    490,    15,     5, 240
ih		 	FLbox  	"progress through the sound file will be zero, the difference ", 	1,      5,     14,    490,    15,     5, 260
ih		 	FLbox  	"this time is that the user can freely define where within the", 	1,      5,     14,    490,    15,     5, 280
ih		 	FLbox  	"sound file freezing is taking place.                         ", 	1,      5,     14,    490,    15,     5, 300

				FLpanel_end

				FLrun	;RUN THE FLTK WIDGET THREAD
;END OF FLTK INTERFACE CODE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		
instr	1
	kSwitch		changed		gkfun2, gkfun1	;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 IS CHANGED...
		reinit	UPDATE		;BEGIN A REINITIALISATION PASS IN ORDER TO EFFECT THIS CHANGE. BEGIN THIS PASS AT LABEL ENTITLED 'UPDATE' AND CONTINUE UNTIL rireturn OPCODE 
	endif				;END OF CONDITIONAL BRANCHING
	UPDATE:				;LABEL

	ktrigloop	changed	gknoloop		;IF FLTK SLIDER 'Loop Start & End' IS MOVED GENERATE A MOMENTARY '1'
	FLsetVal	ktrigloop, gknoloop, gihlstart	;IF ktrigloop IS '1' UPDATE 'Loop Start' SLIDER WITH THE VALUE OF gknoloop ('Loop Start & End')
	FLsetVal	ktrigloop, gknoloop, gihlend	;IF ktrigloop IS '1' UPDATE 'Loop End' SLIDER WITH THE VALUE OF gknoloop ('Loop Start & End')
	
	if	gkOnOff!=0	goto	CONTINUE 	;SENSE FLTK ON/OFF SWITCH - IF ON
		turnoff					;TURN OFF THIS INSTRUMENT IMMEDIATELY
	CONTINUE:					;LABEL
	ilen		=	nsamp(i(gkfun1))/sr	;LENGTH OF THE SOURCE SOUND FILE
	ifun1		=		1	;SOURCE SOUND FUNCTION TABLE
	ifun2		=		2	;WINDOWING FUNCTION USED TO DYNAMICALLY SHAPE THE GRAINS
	iolaps		=		1000	;NUMBER OF ALLOWED OVERLAPS - BEST JUST TO GIVE THIS A LARGE CONSTANT VALUE
	
	kfreqOS		rand		gkfreqOS		;kfreqOS IS A K-RATE RANDOM NUMBER WITHIN THE RANGE -gkfreqOS TO gkfreqOS
	kfreqOS		=		kfreqOS * gkfreq	;kfreqOS IS REDEFINED RELATIVE TO THE CURRENT VALUE OF gkfreq 
	
	kgrsizeOS	gauss		gksizeOS		;kgrsizeOS IS A K-RATE GAUSSIAN RANDOM NUMBER WITHIN THE RANGE -gksizeOS TO gksizeOS
	kgrsizeOS	=		kgrsizeOS * gkgrsize	;kgrsizeOS IS REDEFINED RELATIVE TO THE CURRENT VALUE OF gkgrsize 
	
	asigL 		syncloop 	gkamp, gkfreq+kfreqOS, gkpitch, gkgrsize+kgrsizeOS, gkprate*gkfreeze, gklstart*ilen, gklend*ilen, i(gkfun1),    i(gkfun2)+99, iolaps	;LEFT CHANNEL GRANULAR SYNTHESIS
	asigR 		syncloop 	gkamp, gkfreq+kfreqOS, gkpitch, gkgrsize+kgrsizeOS, gkprate*gkfreeze, gklstart*ilen, gklend*ilen, i(gkfun1)+10, i(gkfun2)+99, iolaps	;RIGHT CHANNEL GRANULAR SYNTHESIS
			outs 		asigL, asigR	;SEND AUDIO TO OUTPUTS
	rireturn	;DENOTES THE END OF A REINITIALISATION PASS
endin

</CsInstruments>

<CsScore>
; THE SOUND FILES USED IN THE GRANULATION
; NUM | INIT_TIME | SIZE  | GEN_ROUTINE |      FILE_PATH       | IN_SKIP | FORMAT | CHANNEL
f  1        0      1048576       1       "ClassicalGuitar.wav"     0         4        1 	;LEFT CHANNELS
f  2        0       524288       1       "808loop.wav"             0         4        1         ;LEFT CHANNELS
f  11       0      1048576       1       "ClassicalGuitar.wav"     0         4        2         ;RIGHT CHANNELS
f  12       0       524288       1       "808loop.wav"             0         4        2         ;RIGHT CHANNELS

; WINDOWING FUNCTIONS USED TO DYNAMICALLY SHAPE THE GRAINS
; NUM | INIT_TIME | SIZE | GEN_ROUTINE | PARTIAL_NUM | STRENGTH | PHASE
;GRAIN ENVELOPE WINDOW FUNCTION TABLES:
f100  0 131072  9   .5 1 0 				; HALF SINE
f101  0 131072  7    0 3072   1 128000    0		; PERCUSSIVE - STRAIGHT SEGMENTS
f102  0 131072  5 .001 3072   1 128000 .001		; PERCUSSIVE - EXPONENTIAL SEGMENTS
f103  0 131072  7    0 1536   1 128000    1 1536 0	; GATE - WITH ANTI-CLICK RAMP UP AND RAMP DOWN SEGMENTS
f104  0 131072  7    0 128000 1 3072      0		; REVERSE PERCUSSIVE - STRAIGHT SEGMENTS
f105  0 131072  5 .001 128000 1 3072   .001		; REVERSE PERCUSSIVE - EXPONENTIAL SEGMENTS

f 0 3600		;DUMMY SCORE EVENT - SUSTAINS REALTIME PERFORMANCE FOR 1 HOUR
</CsScore>

</CsoundSynthesizer>