;WRITTEN BY IAIN MCCURDY, 2008

<CsoundSynthesizer>

<CsOptions>
;UNCOMMENT THE FOLLOWING LINE OF CODE IF YOU DO NOT HAVE A MIDI KEYBOARD CONNECTED
;-odevaudio -b400 -M0 -+rtmidi=virtual
;UNCOMMENT THE FOLLOWING LINE OF CODE IF YOU HAVE A MIDI KEYBOARD CONNECTED
-odevaudio -b400 -M0
</CsOptions>

<CsInstruments>

sr 	= 	44100  
ksmps 	= 	2
nchnls 	= 	2
0dbfs	=	1	;MAXIMUM AMPLITUDE REGARDLESS OF BIT DEPTH

		FLpanel	" ", 500, 225, 0, 0

;                                                      ON | OFF | TYPE | WIDTH | HEIGHT | X | Y | OPCODE | INS | STARTTIM | IDUR
gkExit,ihExit	FLbutton	"Exit",			1,   0,    21,    100,     25,   400, 200,    0,    999,      0,    0.001

;VALUE DISPLAY BOXES				WIDTH | HEIGHT | X |  Y
idatt			FLvalue	" ",     	60,       20,    5,   25
iddec			FLvalue	" ",     	60,       20,    5,   75
idsus			FLvalue	" ",     	60,       20,    5,  125
idrel			FLvalue	" ",     	60,       20,    5,  175

;				            			MIN  | MAX | EXP | TYPE |  DISP  | WIDTH | HEIGHT | X | Y
gkatt, ihatt		FLslider 	"Attack Time",		0.01,   2,   -1,    23,   idatt,    490,    25,     5,   0
gkdec, ihdec		FLslider 	"Decay Time",		0.01,   8,   -1,    23,   iddec,    490,    25,     5,  50
gksus, ihsus		FLslider 	"Sustain Level",	0,      1,    0,    23,   idsus,    490,    25,     5, 100	;SUSTAIN LEVEL CANNOT BE ZERO FOR mxadsr OPCODE
gkrel, ihrel		FLslider 	"Release Time",		0.01,   2,   -1,    23,   idrel,    490,    25,     5, 150

			FLsetVal_i	0.1, 	ihatt
			FLsetVal_i	4, 	ihdec
			FLsetVal_i	0.6, 	ihsus
			FLsetVal_i	0.3, 	ihrel

		FLpanel_end	;END OF PANEL CONTENTS

;INSTRUCTIONS AND INFO PANEL
				FLpanel	" ", 500, 460, 512, 0
;TEXT BOXES												TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ih		 	FLbox  	"     Monophonic Instrument with Overlapping Note Releases    ", 	1,      5,     14,    490,    15,     5,  0
ih		 	FLbox  	"-------------------------------------------------------------", 	1,      5,     14,    490,    15,     5,  20
ih		 	FLbox  	"This example demonstrates how to design a monophonic         ", 	1,      5,     14,    490,    15,     5,  40
ih		 	FLbox  	"instrument that allows the release portion of the envelope   ", 	1,      5,     14,    490,    15,     5,  60
ih		 	FLbox  	"of the previous note to complete whilst a new note begins.   ", 	1,      5,     14,    490,    15,     5,  80
ih		 	FLbox  	"This method prevents clicks that can result from more basic  ", 	1,      5,     14,    490,    15,     5, 100
ih		 	FLbox  	"designs for monophonic instruments.                          ", 	1,      5,     14,    490,    15,     5, 120
ih	  	 	FLbox  	"Studying the code, you will see that there are actually two  ", 	1,      5,     14,    490,    15,     5, 140
ih		 	FLbox  	"separate but identical sound generating instruments (instrs 2", 	1,      5,     14,    490,    15,     5, 160
ih		 	FLbox  	"and 3). As notes are played on a keyboard instr 1 alternately", 	1,      5,     14,    490,    15,     5, 180
ih		 	FLbox  	"directs this note activity to instr 2 and 3. If instr 2 is   ", 	1,      5,     14,    490,    15,     5, 200
ih		 	FLbox  	"triggered, instr 3 is stopped (but allowed to release) and   ", 	1,      5,     14,    490,    15,     5, 220
ih		 	FLbox  	"vice versa.                                                  ", 	1,      5,     14,    490,    15,     5, 240
ih		 	FLbox  	"This technique could be expanded to implement polyphony      ", 	1,      5,     14,    490,    15,     5, 260
ih		 	FLbox  	"limitation beyond monophonic.                                ", 	1,      5,     14,    490,    15,     5, 280
ih		 	FLbox  	"There are controls for an ADSR envelope that is applied to   ", 	1,      5,     14,    490,    15,     5, 300
ih		 	FLbox  	"audio oscillators. The mxadsr opcode is used to implement the", 	1,      5,     14,    490,    15,     5, 320
ih		 	FLbox  	"envelope in this example. With this opcode, envelope segments", 	1,      5,     14,    490,    15,     5, 340
ih		 	FLbox  	"are exponential and the envelope waits for a MIDI note-off   ", 	1,      5,     14,    490,    15,     5, 360
ih		 	FLbox  	"before entering its release stage.                           ", 	1,      5,     14,    490,    15,     5, 380
ih		 	FLbox  	"This example requires input from an external MIDI keyboard   ", 	1,      5,     14,    490,    15,     5, 400
ih		 	FLbox  	"but with a small change to the <CsOptions> part of the code  ", 	1,      5,     14,    490,    15,     5, 420
ih		 	FLbox  	"can also be driven by Csound's virtual MIDI keyboard.        ", 	1,      5,     14,    490,    15,     5, 440

				FLpanel_end

		FLrun		;RUN THE WIDGET THREAD!
	
giwaveform		ftgen		0,0,4096,10,1,.5,.25,.125,.0625	;A RICH HARMONIC WAVEFORM
gkvoice		init		1	;GLOBAL VARIABLE USED TO DEFINE WHETHER VOICE 1 OR VOICE 2 IS CURRENT 

instr	1	; NOTE TRIGGERING INSTRUMENT
	icps	cpsmidi				;READ CYCLES PER SECOND VALUES FROM MIDI KEYBOARD INPUT
	asig	subinstr	i(gkvoice)+1 , icps	;CALL SOUND GENERATING INSTRUMENT AS A SUB-INSTRUMENT
	outs	asig, asig	;SEND AUDIO TO OUTPUTS
endin

instr	2,3	;SOUND GENERATING INSTRUMENTS
	gkvoice	init	(i(gkvoice)=1?2:1)	;FLIP VOICE ALLOCATION AT INIT TIME
if	gkvoice=p1-1	then	;IF THE OTHER VOICE IS NOW PLAYING...
	turnoff			;...TURN THIS INSTRUMENT OFF (ENVELOPE RELEASE STAGE WILL BE ALLOWED TO COMPLETE) 
endif				;END OF CONDITIONAL BRANCHING
	;                ATT      |  DEC    |  SUS    |   REL
	aenv 	madsr 	i(gkatt),  i(gkdec), i(gksus),  i(gkrel)	;MIDI SENSING ADSR ENVELOPE WITH EXPONENTIALLY SHAPED SEGMENTS
	;OUTPUT OPCODE   AMP       CPS FUNCTION_TABLE
	asig	oscili	0.1*aenv, p4, giwaveform			;AUDIO OSCILLATOR
	outch	1, asig			;SEND AUDIO BACK TO INSTR 1
endin

instr	999	;QUIT
	exitnow		;EXIT CSOUND IMMEDIATELY
endin

</CsInstruments>

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

</CsoundSynthesizer>