gbuzz.csd
Written by Iain McCurdy, 2006

<CsoundSynthesizer>

<CsOptions>
;VIRTUAL MIDI
;-odac -dm0 -M0 -+rtmidi=virtual

;EXTERNAL MIDI
-odac -dm0 -M8
</CsOptions>

<CsInstruments>

sr 	= 	44100  
ksmps 	= 	32
nchnls 	= 	2	
0dbfs	=	1

;FLTK INTERFACE CODE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FLcolor	255, 255, 255, 0, 0, 0
;			LABEL     | WIDTH | HEIGHT | X | Y
		FLpanel	"gbuzz",     500,    400,    0,  0

;				FLBUTBANK 	TYPE | NUMX | NUMY | WIDTH | HEIGHT | X | Y | IOPCODE | P1 | P2 | P3
gkFLTK_MIDI, ihFLTK_MIDI	FLbutBank	4,      1,     2,     20,      40,    5,  5,     0,     1,    0,  -1
;TEXT BOXES					TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ih		 	FLbox  	"MIDI", 	1,      6,     17,     50,     20,   23,   4
ih		 	FLbox  	"FLTK", 	1,      6,     17,     50,     20,   23,  24

;NUMBER DISPLAY BOXES			WIDTH | HEIGHT | X | Y
idamp			FLvalue	" ",       80,    20,    5,  75
idmul			FLvalue	" ",       80,    20,    5, 125
idfreq			FLvalue	" ",       80,    20,    5, 175


;SLIDERS				     				MIN | MAX | EXP | TYPE | DISP | WIDTH | HEIGHT | X | Y
gkamp, ihamp		FLslider	"Amplitude",  			0,       1,   0,   23,   idamp,  490,    25,     5,  50
gkmul, gihmul		FLslider	"Amplitude Multiplier CC#1",	0,       2,   0,   23,   idmul,  490,    25,     5, 100
gkfreq, ihfreq		FLslider	"Osc. Frequency",    		1,    2000,  -1,   23,  idfreq,  490,    25,     5, 150

;COUNTERS						MIN | MAX | STEP1 | STEP2 | TYPE | WIDTH | HEIGHT | X | Y | OPCODE
gkharm, gihharm 	FLcount  "No. of Harmonics",	1,    200,    1,      1,      2,   120,      25,   380, 5,    -1
gklh, gihlh 		FLcount  "Lowest Harmonic",	1,    200,    1,      1,      2,   120,      25,   210, 5,    -1

;XY PANELS									MINX | MAXX | MINY | MAXY | EXPX | EXPY | DISPX | DISPY | WIDTH | HEIGHT | X  | Y
gkharm2, gklh2, ihharm2, ihlh2	FLjoy	"X - Num.Harms. Y - Lowest Harm.",	1,      200,  1,      200,   -1,    -1,    -1,     -1,    490,    180,     5, 200

;SET INITIAL VALUES		VALUE | HANDLE 
		FLsetVal_i	0.3, 	ihamp
		FLsetVal_i	30, 	gihharm
		FLsetVal_i	1, 	gihlh
		FLsetVal_i	30, 	ihharm2
		FLsetVal_i	1, 	ihlh2
		FLsetVal_i	0.8, 	gihmul
		FLsetVal_i	100, 	ihfreq

		FLpanel_end	;END OF PANEL CONTENTS

;INSTRUCTIONS AND INFO PANEL
				FLpanel	" ", 500, 420, 512, 0
;TEXT BOXES												TYPE | FONT | SIZE | WIDTH | HEIGHT | X | Y
ih		 	FLbox  	"                Miscellaneous Waveforms : gbuzz              ", 	1,      5,     14,    490,    15,     5,  0
ih		 	FLbox  	"-------------------------------------------------------------", 	1,      5,     14,    490,    15,     5,  20
ih		 	FLbox  	"gbuzz creates similar sounds to the buzz opcode by stacking  ", 	1,      5,     14,    490,    15,     5,  40
ih		 	FLbox  	"harmonically relates cosine waves but gbuzz offers some      ", 	1,      5,     14,    490,    15,     5,  60
ih		 	FLbox  	"additional possibilities.                                    ", 	1,      5,     14,    490,    15,     5,  80
ih		 	FLbox  	"In addition to allowing us to choose the number partials     ", 	1,      5,     14,    490,    15,     5, 100
ih		 	FLbox  	"above the fundemental that will be present gbuzz allows us to", 	1,      5,     14,    490,    15,     5, 120
ih	  	 	FLbox  	"choose what the lowest partial present will be.              ", 	1,      5,     14,    490,    15,     5, 140
ih		 	FLbox  	"The 'Amplitude Multiplier' control allows us to scale the    ", 	1,      5,     14,    490,    15,     5, 160
ih		 	FLbox  	"amplitudes of the sequence of partials. With a value of 1 all", 	1,      5,     14,    490,    15,     5, 180
ih		 	FLbox  	"amplitudes are equal, with values less than one the          ", 	1,      5,     14,    490,    15,     5, 200
ih		 	FLbox  	"amplitudes of higher partials are increasingly attenuated,   ", 	1,      5,     14,    490,    15,     5, 220
ih		 	FLbox  	"and with values greater than 1 the lower partials are        ", 	1,      5,     14,    490,    15,     5, 240
ih		 	FLbox  	"increasingly attenuated.                                     ", 	1,      5,     14,    490,    15,     5, 260
ih		 	FLbox  	"gbuzz requires us to supply it with a cosine wave function   ", 	1,      5,     14,    490,    15,     5, 280
ih		 	FLbox  	"table. This is done using GEN 09.                            ", 	1,      5,     14,    490,    15,     5, 300
ih		 	FLbox  	"gbuzz provides a useful source for subtractive synthesis.    ", 	1,      5,     14,    490,    15,     5, 320
ih		 	FLbox  	"This example can also be played from an external MIDI        ", 	1,      5,     14,    490,    15,     5, 340
ih		 	FLbox  	"keyboard. Pitch, note velocity and pitch bend and represented", 	1,      5,     14,    490,    15,     5, 360
ih		 	FLbox  	"appropriately. MIDI controller 1 (the modulation wheel) can  ", 	1,      5,     14,    490,    15,     5, 380
ih		 	FLbox  	"be used to modulate 'Amplitude Multiplier'.                  ", 	1,      5,     14,    490,    15,     5, 400
                                                           
				FLpanel_end

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

gicos	ftgen 0, 0, 65536, 9, 1, 1, 90		;FUNCTION TABLE THAT STORES A SINGLE CYCLE OF A COSINE WAVE

instr	1		;GBUZZ INSTRUMENT
	kporttime	linseg	0,0.01,0.01			;RAMPING UP FROM ZERO VERSION OF PORTAMENTO TIME VARIABLE
	iMIDIActiveValue	=	1			;IF MIDI ACTIVATED
	iMIDIflag		=	0			;IF FLTK ACTIVATED
	mididefault	iMIDIActiveValue, iMIDIflag		;IF NOTE IS MIDI ACTIVATED REPLACE iMIDIflag WITH iMIDIActiveValue 
	icps	cpsmidi						;READ CYCLES PER SECOND VALUE FROM MIDI INPUT
	kMIDIflag	init	iMIDIflag
	if	gkFLTK_MIDI=0&&kMIDIflag=0	then 		;SENSE FLTK ON/OFF SWITCH & WHETHER THIS IS A MIDI NOTE ITS STATUS WILL BE IGNORED
		turnoff						;TURNOFF THIS INSTRUMENT IMMEDIATELY
	endif							;END OF THIS CONDITIONAL BRANCH
	if kMIDIflag=1 then					;IF THIS IS A MIDI ACTIVATED NOTE...
		kfreq	=	icps				;MAP MIDI NOTE VALUE TO WGUIDE1 FREQUENCY
		iamp	veloc	0,1				;READ IN MIDI NOTE VELOCITY
		kamp	portk	gkamp*iamp,kporttime		;SMOOTH VARIABLE CHANGES WITH PORTK
	else							;OTHERWISE...
		kfreq		portk	gkfreq,kporttime	;SMOOTH VARIABLE CHANGES WITH PORTK
		kamp		portk	gkamp,kporttime		;SMOOTH VARIABLE CHANGES WITH PORTK
	endif							;END OF THIS CONDITIONAL BRANCH

	;MIDI INPUT============================================================================================================================================================
        ;OUTPUT                 OPCODE          CHANNEL | CC.NUMBER | MIN | MAX
        kmul                    ctrl7           1,            1,      0,    1	;READ IN MIDI CONTROLLER
        ktrig                   changed         kmul    ;IF THE VARIABLE 'kptr' CHANGES FROM ITS PREVIOUS VALUE,
	kmul			scale		kmul, 2, 0	;RESCALE VARIABLE
                                                        ;I.E. IF THE MIDI SLIDER IS MOVED THEN THE VARIABLE ktrig WILL ASSUME THE VALUE '1', OTHERWISE IT WILL BE ZERO.
        ;                       OPCODE      |   TRIGGER | VALUE | HANDLE
                                FLsetVal        ktrig,     kmul,  gihmul	;UPDATE WIDGET WHEN A TRIGGER IS RECEIVED
        ;======================================================================================================================================================================

	;PITCH BEND===========================================================================================================================================================
	iSemitoneBendRange = 2			;PITCH BEND RANGE IN SEMITONES (WILL BE DEFINED FURTHER LATER) - SUGGESTION - THIS COULD BE CONTROLLED BY AN FLTK COUNTER
	kbend	pchbend	0, iSemitoneBendRange*2	;PITCH BEND VARIABLE
	kfreq	=	kfreq*semitone(kbend)	;COMBINE PITCH BEND AND FREQUENCY
	;=====================================================================================================================================================================

	kmul		portk	gkmul, kporttime		;APPLY PORTAMENTO SMOOTHING

	;OUTPUT	OPCODE	AMPLITUDE | FREQUENCY | NO.OF_HARMONICS | LOWEST_HARMONIC | POWER | FUNCTION_TABLE
	asig	gbuzz 	gkamp,        kfreq,        gkharm,            gklh,       kmul,       gicos
	aenv	linsegr	0,0.01,1,0.01,0		;ANTI-CLICK ENVELOPE
	outs	asig * aenv, asig * aenv	;SEND AUDIO OUTPUT TO THE SPEAKERS
endin

instr	2; UPDATE FLTK TEXT BOXES
	klh	=	int(gklh2)
	kharm	=	int(gkharm2)
	ktrig	changed	klh
		FLsetVal	ktrig,klh,gihlh
	ktrig	changed	kharm
		FLsetVal	ktrig,kharm,gihharm		
endin

</CsInstruments>

<CsScore>
f 0 3600		;DUMMY SCORE EVENT - ALLOW REALTIME PERFORMANCE FOR UP TO 1 HOUR 
i 2 1 3600		;UPDATE FLTK COUNTERS FROM FLTK X-Y PANEL
</CsScore>

</CsoundSynthesizer>
