'jdl+cdk 11.7.05: play+menu
'place a toggle switch at D2 and a Red LED at D1
'and a Green LED at D0. Green is in play mode. Red is
'in menu mode.
'PLAY:
'Controls 8 FSRs (A0-A7) to MIDI Drum sounds. Modifies volume
'Looks for crossing of threshold and then 6 times more.
'MENU:
'All fingers begin locked. To unlock a finger hold down for
'One second. Then tapping the finger will cycle through the
'drum sounds. Once you find the one you like hold the finger
'down again for one second and the finger locks

'************************************************************************
'Setup
'************************************************************************
    DEFINE OSC 20

    ' Define ADCIN parameters
    DEFINE  ADC_BITS        10     ' Set number of bits in result
    DEFINE  ADC_CLOCK       3      ' Set clock source (3=rc)
    DEFINE  ADC_SAMPLEUS    15'50     ' Set sampling time in uS

    'Enable communication out to MIDI
    DEFINE HSER_RCSTA 90h ' enable the receive register
    DEFINE HSER_TXSTA 20h  ' enable the transmit register
    DEFINE HSER_BAUD 31250 ' set the baud rate

    TRISA = %11111111       ' Set PORTA to all input
    ADCON1 = %10000010      ' Set PORTA analog and right justify result
'************************************************************************
'END Setup
'************************************************************************

'************************************************************************
'Declare Variables
'************************************************************************
    'Declare CONSTANTS AND COUNTER VARIABLEs
        numinput CON 8
        numlibrary CON 12
        locktime CON 300
        menuth CON 300
        threshold CON 125
        resetthreshold CON threshold*3/4
        volumemin CON 25
        i VAR BYTE
        timecount VAR WORD
    
    'Declare VARIABLES
        ADCVar VAR WORD
        volume VAR BYTE
    
    'Declare ARRAYS
        hold VAR WORD[numinput]
        impulsetoggle VAR BYTE[numinput]
        sounds VAR BYTE[numinput]  
        finger VAR BYTE[numinput] 
        mutetoggle VAR BYTE[numinput]
        soundlib VAR BYTE[35]
        lock VAR BIT[numinput]  '1 is open to change, 0 is locked
         
    'initialize volume and toggle ARRAYS:
        volume=50 'mid volume
        FOR i=0 TO numinput
            impulsetoggle[i] = 0 'means okay to go
            mutetoggle[i]=0 'means don't sound off
        NEXT
    
    'initialize soundlib ARRAY

    soundlib[0]=25  '!!real kick
    soundlib[1]=27  '!side kick
    soundlib[2]=31  '!!hard snare
    soundlib[3]=32  '!drum sticks together
    soundlib[4]=33  '!kick drum
    soundlib[5]=34  '!!hard sharp drum
    soundlib[6]=35  '!!Kick drum
    soundlib[7]=36  '!duller kick drum
    soundlib[8]=37  '!two sticks snare
    soundlib[9]=38  '!hard snare
    soundlib[10]=40  '!!nice snare
    soundlib[11]=41  '!!hollowish boong drum
    soundlib[12]=42  '!!tssst high hat
    soundlib[13]=43  '!kick drum
    soundlib[14]=44  '!tsst high hat
    soundlib[15]=45  '!hollowish bong drum
    soundlib[16]=46  '!!lounder cymbal
    soundlib[17]=47  '!hollowish bong drum
    soundlib[18]=48  '!higher hollowish bong drum
    soundlib[19]=49  '!!loud cymbal
    soundlib[20]=50  '!hollow shalllow boong
    soundlib[21]=51  '!!cymbal tap
    soundlib[22]=53  '!traingle like tap
    soundlib[23]=54  '!tamborunie shake
    soundlib[24]=55  '!lower tambourine shake
    soundlib[25]=56  '!tin can smack
    soundlib[26]=57  '!!louder cmybal crash
    soundlib[27]=59  '!soft cymbal hit
    soundlib[28]=60  '!hollow bongo
    soundlib[29]=61  '!lower hollow bongo
    soundlib[30]=62  '!muted bongo
    soundlib[31]=63  '!!nice bongo
    soundlib[32]=64  '!!nice2 bongo
    soundlib[33]=65  '!!steel drum
    soundlib[34]=66  '!!steel drum2
 
          'initialize the finger sound locator
     'this is arbitrary for right now
    finger[0] = 1
    finger[1] = 5
    finger[2] = 8
    finger[3] = 20
    finger[4] = 25
    finger[5] = 33  
    finger[6] = 34
    finger[7] = 4

        'initialize sounds ARRAY
     'this is arbitrary for right now
  
        FOR i=0 TO (numinput-1)
    	   sounds[i] = soundlib[finger[i]]
  	     'SEROUT2 PORTD.3, 16468, ["FINGER ",DEC i+1,44, 32, DEC sounds[i], 10, 13]
        NEXT
    'intialize lock as locked
        FOR i=0 TO (numinput-1)
    	   lock[i]=0
        NEXT
        
    '*************************
    'Declare Play/Menu toggle variable
        playmenu VAR BIT  ' 0 play, 1 menu
        lastplaymenu VAR BIT 
    ' initialize playmenu
        playmenu=0

'************************************************************************
'END Declare Variables
'************************************************************************

'************************************************************************
'MAIN
'************************************************************************
    MAIN:
    	playmenu = PORTD.2
    	   IF lastplaymenu ==1 AND playmenu ==0 THEN
                'lock down all locked
                'DOESN'T SEEM TO BE WORKING
                FOR i=0 TO (numinput-1)
    	           lock[i]=0
                NEXT
            ENDIF
    	
    	IF playmenu == 0 THEN
    		GOTO PLAY
    	ELSE
    		GOTO MENU
    	ENDIF
    
        lastplaymenu=playmenu
    
    GOTO MAIN
'************************************************************************
'END MAIN
'************************************************************************

'************************************************************************
'PLAY
'************************************************************************
    PLAY:
        'SET STATUS LEDS
    	HIGH PORTD.0 'Turn on green LED indicate play mode on
    	LOW PORTD.1  'Turn off red LED
    	'code:
    	
        	FOR i=0 TO (numinput-1)
            'Get reading from FSR (assume 0-1000):
            ADCIN i, ADCVar
            hold[i]=ADCVar'This is an extra step
        
            IF hold[i]>threshold AND impulsetoggle[i]=0 THEN
                'Here we look 6 more times to find peak
                 ADCIN i, ADCVar
                    IF ADCVar > hold[i] THEN
                        hold[i]=ADCVar
                    ENDIF
                 ADCIN i, ADCVar
                    IF ADCVar > hold[i] THEN
                        hold[i]=ADCVar
                    ENDIF
                 ADCIN i, ADCVar
                    IF ADCVar > hold[i] THEN
                        hold[i]=ADCVar
                    ENDIF
                 ADCIN i, ADCVar
                    IF ADCVar > hold[i] THEN
                        hold[i]=ADCVar
                    ENDIF
                 ADCIN i, ADCVar
                    IF ADCVar > hold[i] THEN
                        hold[i]=ADCVar
                    ENDIF
                 ADCIN i, ADCVar
                    IF ADCVar > hold[i] THEN
                        hold[i]=ADCVar
                    ENDIF
                           
                'Convert hold to volume
                 volume=hold[i]/8
                 volume=volume+volumemin
                 IF volume>125 THEN
                    volume=125
                 ENDIF
                ' noteon channel 1
                HSEROUT [$90, sounds[i] ,volume] 
                'reset impulsetoggle
                impulsetoggle[i]=1
                'set mutetoggle to trigger
                mutetoggle[i]=1
            ENDIF
        NEXT
        
        'Reset Toggles and Noteoff Loop
        FOR i=0 TO (numinput-1)
            'Send Noteoff signal and reset mutetoggle
            IF hold[i]<threshold AND mutetoggle[i]==1 THEN
                 HSEROUT [$80, sounds[i], $00]
                 mutetoggle[i]=0
            ENDIF
            'RESET impulsetoggle
            IF hold[i]<resetthreshold THEN
                impulsetoggle[i]=0
            ENDIF
        NEXT
   	
    GOTO MAIN
'************************************************************************
'END PLAY
'************************************************************************

'************************************************************************
'MENU
'************************************************************************
    MENU:
    	'SET STATUS LEDS
        LOW PORTD.0  'Turn off green LED
    	HIGH PORTD.1 'Turn on red LED indicate menu mode on
    	'code:
    	
            FOR i = 0  TO (numinput-1)
    		timecount=0
    		'read input
    		ADCIN i, ADCVar
    		hold[i]=ADCVar	
    		IF hold[i] > menuth THEN
    			WHILE hold[i] > menuth
    				timecount=timecount+1
    				'pause
    				PAUSE 2
    				ADCIN i, ADCVar
    				hold[i]= ADCVar
    			WEND
    			IF timecount > locktime THEN
    				lock[i]=lock[i] +1  'lock is a bit so this flips it
    			ELSE
    				IF lock[i]==1 THEN 'system open: change note
    					finger[i]=finger[i]+1
    					IF finger[i] > 35 THEN finger[i] = 0
                        sounds[i]=soundlib[finger[i]]
    				ENDIF			
    	           	HSEROUT [$80, sounds[i-1] ,00] 'use constant volume
            		HSEROUT [$90, sounds[i] ,70] 'use constant volume
                    'SEROUT2 PORTD.3, 16468, ["FINGER ",DEC i+1,44, 32, DEC sounds[i], 10, 13]	
    			ENDIF
    		ENDIF
    	NEXT
    
        PAUSE 100 'Helps get rid of noise
   	
    GOTO MAIN
'************************************************************************
'END MENU
'************************************************************************