'jdl+cdk 11.28.05: mutliplexed play+menu for 18F252


'************************************************************************
'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 = %00000001       ' Set PORTA.0 to input
    ADCON1 = %10000010      ' Set PORTA analog and right justify result
    
    TRISC = %10110000       'Set RC0-RC3 and RC6 to output    
    inhibitPin VAR PORTA.1
    inputPin CON 0
    
    GREENLEDpin VAR PORTB.6
    REDLEDpin VAR PORTB.7
    PLAYMENUpin VAR PORTB.5
'************************************************************************
'END Setup
'************************************************************************

'************************************************************************
'Declare Variables
'************************************************************************
    'Declare Size of Array CONSTANTS
        numinput CON 16
        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 = PLAYMENUpin
    	   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 GREENLEDpin 'Turn on green LED indicate play mode on
        LOW REDLEDpin  'Turn off red LED
    	'code:
    	
        FOR i=0 TO (numinput-1)
        'Turn off inputs:
            HIGH inhibitPin
        'Set the address you want to read
            PORTC = i 'channelVar
        'Turn on inputs
            LOW inhibitPin
    
            'Get reading from FSR (assume 0-1000):
            ADCIN inputPin, 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 inputPin, 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
        'NO NEED TO MULTIPLEX
        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 GREENLEDpin  'Turn off green LED
    	HIGH REDLEDpin 'Turn on red LED indicate menu mode on
    	'code:
    	
        FOR i = 0  TO (numinput-1)
        'Turn off inputs:
            HIGH inhibitPin
        'Set the address you want to read
            PORTC = i 'channelVar
        'Turn on inputs
            LOW inhibitPin
    
        		timecount=0
        		'read input
        		ADCIN inputPin, ADCVar
        		IF ADCVar > menuth THEN
        			WHILE ADCVar > menuth
        				timecount=timecount+1
        				'pause
        				PAUSE 2
        				ADCIN inputPin, 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
'************************************************************************