'jdl+cdk 11.19.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     ' 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 Size of Array CONSTANTS
        numinput CON 8
        numlibrary CON 35
    
    'Declare CONSTANTS AND COUNTER VARIABLEs
        locktime CON 300
        menuth CON 300
        threshold CON 125
        resetthreshold CON threshold*3/4
        volumemin CON 25
        i VAR BYTE
        timecount VAR WORD
    
    'Declare ADC 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[numlibrary]
        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
        finger[0] = 1
        finger[1] = 5
        finger[2] = 8
        finger[3] = 20
        finger[4] = 25
        finger[5] = 33  
        finger[6] = 34
        finger[7] = 4
  
    'Load sounds[] using finger[] as reference to soundlib[]
        FOR i=0 TO (numinput-1)
    	   sounds[i] = soundlib[finger[i]]
        NEXT
        
    'intialize all elements of 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
                'set all lock[] to locked
                FOR i=0 TO (numinput-1)
    	           lock[i]=0
                NEXT
            ENDIF
    	
    	lastplaymenu=playmenu
    	
    	IF playmenu == 0 THEN
    		GOTO PLAY
    	ELSE
    		GOTO MENU
    	ENDIF
    
    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
                 
                 FOR  timecount=0 TO 6
                      ADCIN i, ADCVar
                      IF ADCVar > hold[i] THEN
                            hold[i]=ADCVar
                      ENDIF 
                 NEXT
                           
                '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
        		IF ADCVar > menuth THEN
        			WHILE ADCVar > menuth
        				timecount=timecount+1
        				'pause
        				PAUSE 2
        				ADCIN 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)//numlibrary
                            sounds[i]=soundlib[finger[i]]
        				ENDIF			
        	           	HSEROUT [$80, sounds[i-1] ,00] 'use constant volume
                		HSEROUT [$90, sounds[i] ,90] 'use constant volume	
        			ENDIF
        		ENDIF
    	   NEXT
    
           PAUSE 100 'Helps get rid of noise
   	
    GOTO MAIN
'************************************************************************
'END MENU
'************************************************************************