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.
Diff: main.cpp
- Revision:
- 0:e33f18af0471
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Oct 13 06:17:30 2011 +0000 @@ -0,0 +1,257 @@ +#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]; +} \ No newline at end of file