'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
'************************************************************************