This is a MIDI synthesizer with touchpads used for playing the notes. mbed will capture the touchpad press and release events and sends the appropriate MIDI commands to the PC. By using the C# windows forms application created by us, one can compose songs as though they were composed on a piano. We support all types of standard MIDI piano types.

Dependencies:   mbed

main.cpp

Committer:
thejasvi3
Date:
2011-10-13
Revision:
0:e33f18af0471

File content as of revision 0:e33f18af0471:

#include <mbed.h>
#include <string>
#include <list>

#include <mpr121.h>
#include "NokiaLCD.h"


DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

// Pushbuttons to change the octaves of the touchpads
InterruptIn octavePlus1(p18);   // Pushbutton that increments the octave of touchpad1
InterruptIn octaveMinus1(p17);  // Pushbutton that decrements the octave of touchpad1
InterruptIn octavePlus2(p16);   // Pushbutton that increments the octave of touchpad2
InterruptIn octaveMinus2(p15);  // Pushbutton that decrements the octave of touchpad2

// Create the interrupt receiver object on pin 26
InterruptIn interrupt1(p26);    // IRQ of touchpad1
InterruptIn interrupt2(p8);     // IRQ of touchpad2

// Setup the Serial to the PC for debugging
Serial pc(USBTX, USBRX);

// Setup the i2c bus on pins 28 and 27
I2C i2c1(p28, p27);
I2C i2c2(p9,p10);


//Setup NOKIA LCD
NokiaLCD lcd(p5, p7, p12, p11, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type


// Setup the Mpr121:
// constructor(i2c object, i2c address of the mpr121)
Mpr121 mpr121_1(&i2c1, Mpr121::ADD_VSS);
Mpr121 mpr121_2(&i2c2, Mpr121::ADD_VSS);

Timer t1;   // to calulate delta time

void midiEventGenerator1();
void midiEventGenerator2();


volatile char octave[2] = {0,1};    // Stores the current octave of both the touchpads
volatile int prev_val[2] = {0,0};   // Stores the previous touchpad values
volatile int cur_val[2] = {0,0};    // Stores the current touchpad values
volatile int time_us = 0;           // Stores the time between different events of the same touchpad


const int backgroundColor = 0x0000FF;
const int graphBarColor = 0xFFFFFF;
const int graphAxesColor = 0xFFFFFF;

int t = 0;

// Key hit/release interrupt routine for touch pad 1
void fallInterrupt1()
{
      time_us = t1.read_us();
      t1.stop();
      t1.reset();
      t1.start();
      cur_val[0] = mpr121_1.read(0x00);
      cur_val[0] += mpr121_1.read(0x01)<<8;
      
      midiEventGenerator1();      
}


// Key hit/release interrupt routine for touch pad 2
void fallInterrupt2()
{
      time_us = t1.read_us();
      t1.stop();
      t1.reset();
      t1.start();
      cur_val[1] = mpr121_2.read(0x00);
      cur_val[1] += mpr121_2.read(0x01)<<8;
      
      midiEventGenerator2();
}

void octaveIncrement1()
{
    if(octave[0] < 9)
        octave[0]++;
        
    // Update the octave number on the LCD
    lcd.fill(48,8,8,8,backgroundColor);
    lcd.locate(6,1);
    lcd.printf("%d",octave[0]);
        
    wait(0.5);
}

void octaveIncrement2()
{
    if(octave[1] < 9)
        octave[1]++;
        
    lcd.fill(112,8,8,8,backgroundColor);
    lcd.locate(14,1);
    lcd.printf("%d",octave[1]);
        
    wait(0.5);
}

void octaveDecrement1()
{
    if(octave[0] > 0)
        octave[0]--;
        
    lcd.fill(48,8,8,8,backgroundColor);
    lcd.locate(6,1);
    lcd.printf("%d",octave[0]);
        
    wait(0.5);        
}

void octaveDecrement2()
{
    if(octave[1] > 0)
        octave[1]--;
        
    lcd.fill(112,8,8,8,backgroundColor);
    lcd.locate(14,1);
    lcd.printf("%d",octave[1]);
        
    wait(0.5);        
}

void rx()
{
    // reset timer when new file is to be created
    t1.stop();
    t1.reset();
    t1.start();
    
    char temp = pc.getc();
}

int main()
{
  // Initialize LCD
  lcd.background(backgroundColor);
  lcd.cls();
  
  lcd.fill(5,35,55,1,graphAxesColor);
  lcd.fill(5,35,1,85,graphAxesColor);
  
  lcd.fill(65,35,55,1,graphAxesColor);
  lcd.fill(65,35,1,85,graphAxesColor);
  
  lcd.locate(0,1);
  lcd.printf("Octv: %d",octave[0]);
  
  lcd.locate(8,1);
  lcd.printf("Octv: %d",octave[1]);
  
  // Initialize the pushbutton interrupts
  octavePlus1.mode(PullUp);
  octavePlus1.fall(&octaveIncrement1);
  octavePlus2.mode(PullUp);
  octavePlus2.fall(&octaveIncrement2);
  octaveMinus1.mode(PullUp);
  octaveMinus1.fall(&octaveDecrement1);
  octaveMinus2.mode(PullUp);
  octaveMinus2.fall(&octaveDecrement2);
  
     
  // for touch pad 1
  interrupt1.mode(PullUp);
  interrupt1.fall(&fallInterrupt1);
  t1.reset();
  t1.start();
  

  // for touch pad 2
  interrupt2.mode(PullUp);
  interrupt2.fall(&fallInterrupt2);

  // Setup interrupt for serial port rx. This is used to reset the deltatime timer when a new file is created on the PC
  pc.attach(&rx);
  
  int temp = 0;
  while (1)
  {
        temp ^= 1;
        led1 = temp;;
        wait(0.5);
  }
}


void midiEventGenerator1()
{
    int temp;
    
    // Evaluate for touch pad 1
    temp = cur_val[0] ^ prev_val[0];
    
    for(int i = 0; i < 12; i++)
    {
        if((temp & 1) == 1)
        {
            int mask = (1 << i);
            
            if((cur_val[0] & mask) == mask)
            {
                pc.printf("on%01d%03d%010d",0,((octave[0] * 12) + i), time_us); // sending format: channel, note, deltaTime_uS
                lcd.fill(6,(36 + (7 * i)),50,6,graphBarColor);                  // Display the FFT
            }
            else
            {
                pc.printf("of%01d%03d%010d",0,((octave[0] * 12) + i), time_us);
                lcd.fill(6,(36 + (7 * i)),50,6,backgroundColor);
            }
        }
        temp = temp >> 1;
    }
    
    prev_val[0] = cur_val[0];

}

void midiEventGenerator2()
{
    int temp;
    
    // Evaluate for touch pad 2
    temp = cur_val[1] ^ prev_val[1];
    
    for(int i = 0; i < 12; i++)
    {
        if((temp & 1) == 1)
        {
            int mask = (1 << i);
            
            if((cur_val[1] & mask) == mask)
            {
                pc.printf("on%01d%03d%010d",0,((octave[1] * 12) + i), time_us);
                lcd.fill(66,(36 + (7 * i)),50,6,graphBarColor);
            }
            else
            {
                pc.printf("of%01d%03d%010d",0,((octave[1] * 12) + i), time_us);
                lcd.fill(66,(36 + (7 * i)),50,6,backgroundColor);
            }
        }
        temp = temp >> 1;
    }
    
    prev_val[1] = cur_val[1];
}