   Stream& mStream;
 };
 
-class MusicBoxPip
-{
-public:
-  static const int kMaxTime = 1000;
+/**
+ */
+class Key
+{
+public:
+  static const unsigned int kMaxTime = 1000;
   static const int kMinVelocity = 1;
   static const int kMaxVelocity = 128;
   

// 5) Set LoopBe1 Internal output as an Input to Ableton
//

class MidiStream
{
public:

  int mVelocity;
};

/**
 */
template <int KeyCount>
class KeyWiring
{
public:
  KeyWiring()
  {
  }
  
  void begin(const int pinFromKey[KeyCount])
  {
    for (int key = 0; key < KeyCount; key++)
    {
      mPinFromKey[key] = pinFromKey[key];
    }
  }
  
  int pin(int key)
  {
    return mPinFromKey[key];
  }
  
private:
  int mPinFromKey[KeyCount];
};

/**
 */
template <int KeyCount>
class PitchMap
{
public:
  PitchMap()
  {
  }
  
  void begin(byte startPitch, byte stopPitch)
  {
    for (int key = 0; key < KeyCount; key++)
    {
      mPitchMap[key] = map(key, 0, KeyCount - 1, startPitch, stopPitch);
    }
  }
  
  byte pitch(int key)
  {
    return mPitchMap[key];
  }
  
private:
  byte mPitchMap[KeyCount];
};

/**
 */
template <int KeyCount>
class KeyBoard
{
public:
  KeyBoard() :
    mPitchMap(NULL),
    mMidiStream(NULL)
  {
  }
  
  void begin(KeyWiring<KeyCount>& keyWiring, PitchMap<KeyCount>& pitchMap, MidiStream& stream)
  {
    mPitchMap = &pitchMap;
    mMidiStream = &stream;
    
    for (int key = 0; key < KeyCount; key++)
    {
      mKey[key].begin(keyWiring.pin(key));
    }
  }
  
  int keyCount()
  {
    return KeyCount;
  }
  
  void sample(int channel = 0)
  {
    for (int key = 0; key < KeyCount; key++)
    {
      Key::Transition transition = mKey[key].checkTransition();
      
      if (transition == Key::eTransitioned_On)
      {
        mMidiStream->sendNoteOn(channel, mPitchMap->pitch(key), mKey[key].transitionVelocity());
      }
      else if (transition == Key::eTransitioned_Off)
      {
        mMidiStream->sendNoteOff(channel, mPitchMap->pitch(key), mKey[key].transitionVelocity());
      }
    }
  }
  
private:
  Key mKey[KeyCount];
  PitchMap<KeyCount>* mPitchMap;
  MidiStream* mMidiStream;
};

//
// Serial MIDI device:
//  Baud: 9600
//  Channel: 1
static const int kMidiBaud = 9600;
static const int kMidiChannel = 0;

static const int kMidiNoteBegin = 52;
static const int kMidiNoteEnd = 58;

#define kKeyCount 6

static MidiStream sMidiStream;
static KeyWiring<kKeyCount> sKeyWiring;
static KeyBoard<kKeyCount> sKeyboard;
static PitchMap<kKeyCount> sPitchMap;

void setup()
{
  int pins[kKeyCount] = {13, 12, 11, 10, 9, 8};
  sKeyWiring.begin(pins);
  
  Serial.begin(kMidiBaud);
  sPitchMap.begin(kMidiNoteBegin, kMidiNoteEnd);
  sMidiStream.begin(Serial);
  sKeyboard.begin(sKeyWiring, sPitchMap, sMidiStream);
}

void loop()
{
  sKeyboard.sample(kMidiChannel);
}


