# Copyright (c) 2014 Adafruit Industries
# Author: Tony DiCola
#
# Extended by (c) 2015 Georg Mill (https://blog.georgmill.de)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import sys
import time

import Adafruit_MPR121.MPR121 as MPR121

import rtmidi
from rtmidi.midiutil import open_midiport
from rtmidi.midiconstants import *


print 'Adafruit MPR121 Capacitive Touch Sensor Test with MIDI on four MPR121 Touch Sensos'
try:
    midiout, port_name = open_midiport(4, "output",
	    api=rtmidi.API_UNIX_JACK,
            client_name="sensors", port_name="MIDI Out")
except (EOFError, KeyboardInterrupt):
    sys.exit()

# Create MPR121 instances.
cap = MPR121.MPR121()
cap1 = MPR121.MPR121()
cap2 = MPR121.MPR121()
cap3 = MPR121.MPR121()

cap.begin(address=0x5A)
cap1.begin(address=0x5B)
cap2.begin(address=0x5C)
cap3.begin(address=0x5D)

# Initialize communication with MPR121 using default I2C bus of device, and 
# default I2C address (0x5A).  On BeagleBone Black will default to I2C bus 0.
if not cap.begin(address=0x5A):
    print 'Error initializing MPR121 #1.  Check your wiring!'
    sys.exit(1)
else:
   print 'Initializing MPR121 #1'

if not cap1.begin(address=0x5B):
    print 'Error initializing MPR121 #2.  Check your wiring!'
    sys.exit(1)
else:
   print 'Initializing MPR121 #2'

if not cap2.begin(address=0x5C):
    print 'Error initializing MPR121 #3.  Check your wiring!'
    sys.exit(1)
else:
   print 'Initializing MPR121 #3'

if not cap3.begin(address=0x5D):
    print 'Error initializing MPR121 #4.  Check your wiring!'
    sys.exit(1)
else:
   print 'Initializing MPR121 #4'


# Alternatively, specify a custom I2C address such as 0x5B (ADDR tied to 3.3V),
# 0x5C (ADDR tied to SDA), or 0x5D (ADDR tied to SCL).
#cap.begin(address=0x5B)

# Also you can specify an optional I2C bus with the bus keyword parameter.
#cap.begin(bus=1)

# Main loop to print a message every time a pin is touched.
print 'Press Ctrl-C to quit.'
last_touched = cap.touched()
last_touched1 = cap1.touched()
last_touched2 = cap2.touched()
last_touched3 = cap3.touched()
while True:
    current_touched = cap.touched()
    # Check each pin's last and current state to see if it was pressed or released.
    for i in range(12):
        # Each pin is represented by a bit in the touched value.  A value of 1
        # means the pin is being touched, and 0 means it is not being touched.
        pin_bit = 1 << i
        # First check if transitioned from not touched to touched.
        if current_touched & pin_bit and not last_touched & pin_bit:
            print '{0} from mpr121 #1 touched!'.format(i)
	    note_on = [NOTE_ON, 40+i, 112] # channel 1, middle C, velocity 112
	    midiout.send_message(note_on)
	    #time.sleep(1)
        # Next check if transitioned from touched to not touched.
        if not current_touched & pin_bit and last_touched & pin_bit:
	    note_off = [NOTE_OFF, 40+i, 0]
	    midiout.send_message(note_off)
	   # time.sleep(1)
            print '{0}  from mpr121 #1 released!'.format(i)
    # Update last state and wait a short period before repeating.
    last_touched = current_touched
   # time.sleep(0.1)

    current_touched1 = cap1.touched()
    # Check each pin's last and current state to see if it was pressed or released.
    for i in range(12):
        # Each pin is represented by a bit in the touched value.  A value of 1
        # means the pin is being touched, and 0 means it is not being touched.
        pin_bit = 1 << i
        # First check if transitioned from not touched to touched.
        if current_touched1 & pin_bit and not last_touched1 & pin_bit:
            print '{0}  from mpr121 #2 touched!'.format(i)
	    note_on = [NOTE_ON, 50+i, 112] # channel 1, middle C, velocity 112
	    midiout.send_message(note_on)
	    #time.sleep(1)
        # Next check if transitioned from touched to not touched.
        if not current_touched1 & pin_bit and last_touched1 & pin_bit:
	    note_off = [NOTE_OFF, 50+i, 0]
	    midiout.send_message(note_off)
	   # time.sleep(1)
            print '{0}  from mpr121 #2 released!'.format(i)
    # Update last state and wait a short period before repeating.
    last_touched1 = current_touched1
   # time.sleep(0.1)

    current_touched2 = cap2.touched()
    # Check each pin's last and current state to see if it was pressed or released.
    for i in range(12):
        # Each pin is represented by a bit in the touched value.  A value of 1
        # means the pin is being touched, and 0 means it is not being touched.
        pin_bit = 1 << i
        # First check if transitioned from not touched to touched.
        if current_touched2 & pin_bit and not last_touched2 & pin_bit:
            print '{0}  from mpr121 #3 touched!'.format(i)
	    note_on = [NOTE_ON, 60+i, 112] # channel 1, middle C, velocity 112
	    midiout.send_message(note_on)
	    #time.sleep(1)
        # Next check if transitioned from touched to not touched.
        if not current_touched2 & pin_bit and last_touched2 & pin_bit:
	    note_off = [NOTE_OFF, 60+i, 0]
	    midiout.send_message(note_off)
	   # time.sleep(1)
            print '{0}  from mpr121 #3 released!'.format(i)
    # Update last state and wait a short period before repeating.
    last_touched2 = current_touched2
   # time.sleep(0.1)

    current_touched3 = cap3.touched()
    # Check each pin's last and current state to see if it was pressed or released.
    for i in range(12):
        # Each pin is represented by a bit in the touched value.  A value of 1
        # means the pin is being touched, and 0 means it is not being touched.
        pin_bit = 1 << i
        # First check if transitioned from not touched to touched.
        if current_touched3 & pin_bit and not last_touched3 & pin_bit:
            print '{0}  from mpr121 #4 touched!'.format(i)
	    note_on = [NOTE_ON, 70+i, 112] # channel 1, middle C, velocity 112
	    midiout.send_message(note_on)
	    #time.sleep(1)
        # Next check if transitioned from touched to not touched.
        if not current_touched3 & pin_bit and last_touched3 & pin_bit:
	    note_off = [NOTE_OFF, 70+i, 0]
	    midiout.send_message(note_off)
	   # time.sleep(1)
            print '{0}  from mpr121 #4 released!'.format(i)
    # Update last state and wait a short period before repeating.
    last_touched3 = current_touched3
   # time.sleep(0.1)

    # Alternatively, if you only care about checking one or a few pins you can 
    # call the is_touched method with a pin number to directly check that pin.
    # This will be a little slower than the above code for checking a lot of pins.
    #if cap.is_touched(0):
    #    print 'Pin 0 is being touched!'
    
    # If you're curious or want to see debug info for each pin, uncomment the
    # following lines:
    #print '\t\t\t\t\t\t\t\t\t\t\t\t\t 0x{0:0X}'.format(cap.touched())
    #filtered = [cap.filtered_data(i) for i in range(12)]
    #print 'Filt:', '\t'.join(map(str, filtered))
    #base = [cap.baseline_data(i) for i in range(12)]
    #print 'Base:', '\t'.join(map(str, base))
