;Written by Iain McCurdy

<CsoundSynthesizer>

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

<CsInstruments>
sr		=	44100
kr		=	441
ksmps		=	100
nchnls		=	2

;FLTK INTERFACE CODE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;			LABEL    | WIDTH | HEIGHT | X | Y
		FLpanel	"follow2",  500,     450,   0,  0

;SWITCHES                       				ON | OFF | TYPE | WIDTH | HEIGHT | X | Y | OPCODE | INS | STARTTIM | IDUR
gkOnOff,ihOnOff			FLbutton	"On/Off",	1,  -1,     2,    150,     30,    0,   0,    0,      1,     0,        -1

;				WIDTH | HEIGHT | X | Y
idatt		FLvalue	" ",	80,       20,    0,  80
idrel		FLvalue	" ",	80,       20,    0, 130
idsensitivity	FLvalue	" ",	80,       20,    0, 180
idoffset	FLvalue	" ",	80,       20,    0, 230
idres		FLvalue	" ",	80,       20,    0, 280
idspeed		FLvalue	" ",	80,       20,    0, 330
idmix		FLvalue	" ",	80,       20,    0, 380
idamp		FLvalue	" ",	80,       20,    0, 430

;					     					MIN |  MAX   | EXP | TYPE |  DISP       | WIDTH | HEIGHT | X |  Y
gkatt, ihatt			FLslider	"Envelope Follow Attack",	.001,    .5,    0,    3,   idatt,          500,     30,    0,  50
gkrel, ihrel			FLslider	"Envelope Follow Release",	.001,    .5,    0,    3,   idrel,          500,     30,    0, 100
gksensitivity, ihsensitivity	FLslider	"Envelope Follow Sensitivity",  0,       50,    0,    3,   idsensitivity,  500,     30,    0, 150
gkoffset ihoffset		FLslider	"Filter Cutoff Offset",     	4,       14,    0,    3,   idoffset,       500,     30,    0, 200
gkres, ihres			FLslider	"Filter Resonance",          	0,        1,    0,    3,   idres,          500,     30,    0, 250
gkspeed, ihspeed		FLslider	"File Playback Speed",		.125,     2,    0,    3,   idspeed,        500,     30,    0, 300
gkmix, ihmix			FLslider	"Filter Dry/Wet Mix",          	0,        1,    0,    3,   idmix,          500,     30,    0, 350
gkamp, ihamp			FLslider   	"Output Gain",			0,        2,    0,    3,   idamp,          500,     30,    0, 400

;GENERAL_TEXT_SETTINGS			SIZE | FONT |  ALIGN | RED | GREEN | BLUE
			FLlabel		13,      1,      1,    190,   190,   190	;LABELS MADE INVISIBLE

;			FLBUTBANK 	TYPE | NUMX | NUMY | WIDTH | HEIGHT | X | Y | OPCODE
gkinput,   ihinput	FLbutBank	12,     1,     2,     30,    40,    150,  0,   -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,       2,    12,    70,      20,   180,  0
ih		 	FLbox  	"Sound File", 		1,       2,    12,    70,      20,   180, 20

		FLsetVal_i	.025,	ihatt
		FLsetVal_i	.3,	ihrel
		FLsetVal_i	36,	ihsensitivity
		FLsetVal_i	6.5,	ihoffset
		FLsetVal_i	.5,	ihres
		FLsetVal_i	.5,	ihspeed
		FLsetVal_i	1,	ihmix
		FLsetVal_i	1,	ihamp
		FLsetVal_i	1,	ihinput
		
		FLpanel_end	;END OF PANEL CONTENTS

;INSTRUCTIONS AND INFO PANEL
				FLpanel	" ", 515, 320, 512, 0
;TEXT BOXES												TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ih		 	FLbox  	"                           follow2                           ", 	1,      5,     14,    490,    15,     5,  0
ih		 	FLbox  	"-------------------------------------------------------------", 	1,      5,     14,    490,    15,     5,  20
ih		 	FLbox  	"The follow2 opcode outputs an amplitude following signal     ", 	1,      5,     14,    490,    15,     5,  40
ih		 	FLbox  	"based on an imput audio signal. The output signal will be    ", 	1,      5,     14,    490,    15,     5,  60
ih		 	FLbox  	"unipolar (i.e. only positive values) and the response of the ", 	1,      5,     14,    490,    15,     5,  80
ih		 	FLbox  	"envelope follower to dynamic transients can be tailored using", 	1,      5,     14,    490,    15,     5, 100
ih		 	FLbox  	"follow2's input arguments for attack time and release time.  ", 	1,      5,     14,    490,    15,     5, 120
ih	  	 	FLbox  	"This example demonstrates a very common use of this control  ", 	1,      5,     14,    490,    15,     5, 140
ih		 	FLbox  	"signal in that it is used to derive the cutoff frequency of a", 	1,      5,     14,    490,    15,     5, 160
ih		 	FLbox  	"lowpass filter. Therefore as the amplitude of the input      ", 	1,      5,     14,    490,    15,     5, 180
ih		 	FLbox  	"signal increases the cutoff frequency of the filter also     ", 	1,      5,     14,    490,    15,     5, 200
ih		 	FLbox  	"rises. Some additional controls are offered to allow the user", 	1,      5,     14,    490,    15,     5, 220
ih		 	FLbox  	"to further refine the envelope follower response and some    ", 	1,      5,     14,    490,    15,     5, 240
ih		 	FLbox  	"other aspects of the effect.                                 ", 	1,      5,     14,    490,    15,     5, 260
ih		 	FLbox  	"The user can choose between using a stored file or the live  ", 	1,      5,     14,    490,    15,     5, 280
ih		 	FLbox  	"input as the source signal for the envelope follower.        ", 	1,      5,     14,    490,    15,     5, 300

				FLpanel_end

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

		instr 1
if	gkOnOff!=-1	goto	CONTINUE 	;SENSE IF FLTK ON/OFF SWITCH IS ON, IF IT IS 'ON', SKIP TO 'CONTINUE' LABEL
			turnoff			;TURNOFF THIS INSTRUMENT IMMEDIATELY
			CONTINUE:		;LABEL 'CONTINUE'
if		gkinput=0	then		;IF INPUT SWITCH IS SET TO 'LIVE INPUT' THEN... 
asig, aR	ins				;READ THE LIVE AUDIO INPUT TO THE COMPUTER
elseif		gkinput=1	then		;OR ELSE IF INPUT SWITCH IS SET TO 'SOUND FILE' THEN... 
;OUTPUT		OPCODE		FILE_PATH |  SPEED  | INSKIP | LOOPING_0=OFF/1=ON
asig		diskin2		"loop.wav", gkspeed,     0,        1		;CREATE AN AUDIO SIGNAL
endif						;END OF IF BRANCHING
afollow		follow2		asig, gkatt, gkrel	;CREATE AN ENVELOPE FOLLOWING SIGNAL FROM THE AUDIO SIGNAL
kfollow		downsamp	afollow			;DOWNSAMPLE AMPLITUDE FOLLOWING SIGNAL DOWN TO K-RATE					
kcfoct		=		((kfollow/32768) * gksensitivity) + gkoffset	;RE-SCALE THIS SIGNAL USING THE SENSITIVITY AND OFFSET SETTINGS - OUTPUT WILL BE USED AS A FILTER CUTOFF VALUE IN OCT FORMAT
kcfoct		limit		kcfoct, 4, 14	;LIMIT THE RANGE OF THE CUTOFF FREQUENCY (REMEMBER: OCT FORMAT)
afilt		moogladder	asig, cpsoct(kcfoct), gkres	;FILTER THE AUDIO SIGNAL USING THE moogladder RESONANT LOWPASS FILTER
amix		ntrpol		asig, afilt, gkmix		;CREATE A DRY/WET MIX BETWEEN THE ORIGINAL SIGNAL AND THE FILTERED SIGNAL
		outs		amix * gkamp, amix * gkamp	;SEND DRY/WET MIX TO THE SPEAKERS - RESCALE WITH GAIN CONTROL
		endin
		
</CsInstruments>

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

</CsoundSynthesizer>