Editing a Library

Here's the new code (library):

#include <Keypad.h>

// <<constructor>> Allows custom keymap, pin configuration, and keypad sizes.
Keypad::Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols) {
    rowPins = row;
    columnPins = col;
    sizeKpd.rows = numRows;
    sizeKpd.columns = numCols;
	
    begin(userKeymap);
	
    setDebounceTime(10);
    setHoldTime(500);
	keypadEventListener = 0;
	
    initializePins();
	
	startTime = 0;
}

// Let the user define a keymap - assume the same row/column count as defined in constructor
void Keypad::begin(char *userKeymap) {
    keymap = userKeymap;
}

// Returns a single key only. Retained for backwards compatibility.
char Keypad::getKey() {
	if (scanKeys() && (key[0].kstate==PRESSED) && key[0].stateChanged)
		return key[0].kchar;
	return NO_KEY;
}

bool Keypad::getKeys() {
	if (scanKeys()) {
		for (byte i=0; i<LIST_MAX; i++) {
			if (key[i].stateChanged) {
				return true;
			}
		}
	}
	return false;
}

// Private
// Scan the keypad.  Rerturn whether a key has been pressed or not.
bool Keypad::scanKeys() {
	static unsigned int allKeys = 0;
	byte curKey = 0;
	boolean anyKey;
	
	// Scan keypad once every XX mS. This makes the loop() count
	// go from about 4,000 loops per second to about 40,000.
	initializePins(); 
	
	for (int c = 0; c < sizeKpd.columns; c++) {
		pinMode(columnPins[c], OUTPUT);
		digitalWrite(columnPins[c], LOW);
		for (int r = 0; r <sizeKpd.rows; r++) {
			curKey = digitalRead(rowPins[r]);
			allKeys += curKey;
			if (curKey == 0) curKey = keymap[c+(r*sizeKpd.columns)];
			
			if (r==(sizeKpd.rows-1) && c==(sizeKpd.columns-1)) {
				if (allKeys == (sizeKpd.rows*sizeKpd.columns))
					anyKey = OPEN;
				else
					anyKey = CLOSED;
			}
		}
		pinMode(columnPins[c], INPUT);
		digitalWrite(columnPins[c], HIGH);
	}	
	allKeys = 0;
	return anyKey;
}

// Manage the key list. Any keys already on the list stay in their current slot
// and empty slots get filled with new keys.
void Keypad::updateList() {
	
	// Delete Idle keys
	for (byte i=0; i<LIST_MAX; i++) {
		if (key[i].kstate==IDLE) {
			key[i].kchar = NO_KEY;
			key[i].stateChanged = false;
		}
	} =
	
	// Fill the empty slots in key[] list with new CLOSED keys.
	for (byte r=0; r<sizeKpd.rows; r++) {
		for (byte c=0; c<sizeKpd.columns; c++) {
			boolean button = bitRead(bitMap[r],c);
			char keyChar = keymap[r * sizeKpd.columns + c];
			int idx = findInList (keyChar);				// -1 = not on list, else returns key index
			// Update any key that was found on the list.
			if (idx>=0)
				setKeyState (idx, button);
			// Add a key to the list when the button is CLOSED.
			if ((idx==-1) && button) {
				// Check the whole list for an empty key slot and put it there.
				for (byte i=0; i<LIST_MAX; i++) {
					if (key[i].kchar==NO_KEY) {
						key[i].kchar = keyChar;
						key[i].kstate = IDLE;
						// All keys not on the list are considered IDLE. Using setKeyState
						// on new key will transition the key to the PRESSED state as expected.
						setKeyState (i, button);
						break;	// only fill the first empty slot.
					}
				}
			}
		}
	}
}

// Private
void Keypad::setKeyState(byte idx, boolean button) {
	// Clear stateChanged.
	key[idx].stateChanged = false;
	
	switch (key[idx].kstate) {
		case IDLE:		// Waiting for a keypress.
			if (button==CLOSED) {
				transitionTo (idx, PRESSED);
			holdTimer = millis(); }		// Get ready for next HOLD state.
			break;
		case PRESSED:
			if ((millis()-holdTimer)>holdTime)	// Waiting for a key HOLD...
				transitionTo (idx, HOLD);
			else if (button==OPEN)				// or for a key to be RELEASED.
				transitionTo (idx, RELEASED);
			break;
		case HOLD:
			// Waiting for a key to be RELEASED.
			if (button==OPEN)
				transitionTo (idx, RELEASED);
			break;
		case RELEASED:
			transitionTo (idx, IDLE);
			break;
	}
}

// New in 2.1
bool Keypad::isPressed(char keyChar) {
	for (byte i=0; i<LIST_MAX; i++) {
		if ( (key[i].kchar == keyChar) && (key[i].kstate == PRESSED) )
			return true;
	}
	return false;	// Not pressed.
}

// New in 2.0
char Keypad::waitForKey() {
	char waitKey = NO_KEY;
	while( (waitKey = getKey()) == NO_KEY );	// Block everything while waiting for a keypress.
	return waitKey;
}

KeyState Keypad::getState() {
	return key[0].kstate;
}

// The end user can test for any changes in state before deciding
// if any variables, etc. needs to be updated in their code.
// Useful for keypads/keyboards returning a single key only.
bool Keypad::keyStateChanged() {
	return key[0].stateChanged;
}

// The number of keys on the key list, key[LIST_MAX], equals the number
// of bytes in the key list divided by the number of bytes in a key.
byte Keypad::numKeys() {
	return sizeof(key)/sizeof(Key);
}

// Minimum debounceTime is 10 mS. Any lower *will* slow down the loop().
void Keypad::setDebounceTime(uint debounce) {
	debounce<1 ? debounceTime=1 : debounceTime=debounce;
}

void Keypad::setHoldTime(uint hold) {
    holdTime = hold;
}

void Keypad::addEventListener(void (*listener)(char)){
	keypadEventListener = listener;
}

void Keypad::transitionTo(byte n, KeyState nextState) {
	key[n].kstate = nextState;
	key[n].stateChanged = true;
	
	if (keypadEventListener!=NULL)
		keypadEventListener(key[0].kchar);
}

void Keypad::initializePins() {
	for (byte r = 0; r < sizeKpd.rows; r++) {
		pinMode(rowPins[r], INPUT);
		digitalWrite(rowPins[r], HIGH);
	}
	for (byte c = 0; c < sizeKpd.columns; c++) {
		pinMode(columnPins[c], INPUT);
		digitalWrite(columnPins[c], HIGH);
	}
}


// Search for a key in the list of active keys.
// Returns -1 if not found or the index into the list of active keys.
int Keypad::findInList (char keyChar) {
	for (byte i=0; i<LIST_MAX; i++) {
		if (key[i].kchar == keyChar) {
			return i;
		}
	}
	return -1;	// No matching key in list.
}

Here's my own code (which calls from the libraries):

//extend Keypad class
#include <Keypad.h>

//initialize rows and columns
const byte ROWS = 4; 
const byte COLS = 4; 

//define the symbols on the buttons
char hexaKeys[ROWS][COLS] = {
  {'0','1','2','3'},
  {'4','5','6','7'},
  {'8','9','A','B'},
  {'C','D','E','F'}
};

//row pinouts
byte rowPins[ROWS] = {5, 4, 3, 2}; 
//column pinouts
byte colPins[COLS] = {9, 8, 7, 6};

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

int MIDInotes[16] = {60, 62, 64, 65, 67, 69, 71, 72, 74, 76, 77, 79, 81, 83, 84, 86};

//SOME METHODS:
//MIDIiu noteON
void noteOn(int channel, int pitch, int velocity) {
  Serial.write(channel);
  Serial.write(pitch);
  Serial.write(velocity);
  delay(1);
}
  
void setup() {
    
  Serial.begin(31250);
  } 
  
void loop() {
  
  char customKey = customKeypad.getKey();
  
  if (customKey){
 
    char testChar = customKey;
    int someInt;
    if (testChar >= 'A' && testChar <= 'F')
    {
      someInt = 10 + (int)(testChar- 'A');
    }
    else
    {
      someInt = (int)(customKey - '0');
    }

  noteOn(144, MIDInotes[someInt], 127); 
  delay(100); 
 } 
}