Program and libraries to run the MusicPlay game designed for ECE 4180 in Spring 2020.
Dependencies: Speaker mbed mbed-rtos 4DGL-uLCD-SE PinDetect
main.cpp
- Committer:
- onsideiut
- Date:
- 2020-04-30
- Revision:
- 1:e84293b09274
- Parent:
- 0:9439ccb44422
File content as of revision 1:e84293b09274:
#include "mbed.h" #include "rtos.h" #include "uLCD_4DGL.h" #include "Speaker.h" #include "SongPlayer.h" DigitalOut myled(LED1); PwmOut myled2(LED2); PwmOut myled3(LED3); PwmOut myled4(LED4); uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin; AnalogIn touchg(p17); AnalogIn touchr(p16); AnalogIn touchb(p15); float gVal = 0.0; float rVal = 0.0; float bVal = 0.0; Mutex stdio_mutex; Speaker mySpeaker(p21); SongPlayer mySpeakerSP(p21); //States: {STARTSCREEN = 0, MENU = 1, SONG1 = 2, SONG2 = 3, LISTENMODE = 4}; int currState = 0; int prevState = 0; int selected = 1; float score = 10.0; int numPlayedS1 = 0; int numPlayedS2 = 0; int passedPlayS1 = 0; int passedPlayS2 = 0; float t = 2.5; // tempo controller DigitalIn pbL(p9); DigitalIn pbR(p8); float ramblinFirst[] = {783.991, 698.456,622.254,622.254,622.254,698.456, 783.991,783.991,783.991,698.456,622.254,698.456, 698.456,698.456,622.254,587.330,622.254}; float ramblinSecond[] = {1.0/t,0.5/t,0.9/t,0.4/t,1.0/t,0.5/t,0.9/t, 0.4/t,0.5/t,0.5/t,0.5/t,0.4/t,0.4/t, 0.5/t,1.0/t,0.5/t,2.5/t}; float ramblinThird[] = {0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1, 0.1,0.1,0.1,0.1,0.1,0.1,0.1}; //int ramblinRows[24]; //int imagineRows[70]; // //int ramblinColors[24]; //int imagineColors[70]; class MovingNotes { protected: int y_pos; int x_pos; int moving; float freq; float dur; float val; public: void setStart(int h) {y_pos = h;} void setWidth (int w) {x_pos = w;} void setMoving (int m) {moving = m;} void setFreq(float f) {freq = f;} void setDur (float d) {dur = d;} void setVal (float v) {val = v;} // int getFreq() {return freq;} // int getDur() {return dur;} // int getVal() {return val;} virtual void draw()= 0; virtual void update(){} }; MovingNotes * ramb_ptr[17]; class redNotes: public MovingNotes { virtual void draw() { uLCD.filled_circle(x_pos, y_pos, 10, RED); } virtual void update() { if (moving == 1) { gVal = touchg.read(); rVal = touchr.read(); bVal = touchb.read(); if (x_pos == 18 && y_pos > 90 && y_pos < 144 && gVal >0.5f) { score++; mySpeaker.PlayNote(freq,dur,val); } else if (x_pos == 64 && y_pos > 90 && y_pos < 144 && rVal >0.5f) { score++; mySpeaker.PlayNote(freq,dur,val); } else if (x_pos == 110 && y_pos > 90 && y_pos < 144 && bVal >0.5f) { score++; mySpeaker.PlayNote(freq,dur,val); } if (y_pos < 144) { Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 11; uLCD.filled_circle(x_pos, y_pos, 10, RED); Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 11; uLCD.filled_circle(x_pos, y_pos, 10, RED); Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 11; uLCD.filled_circle(x_pos, y_pos, 10, RED); Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 11; uLCD.filled_circle(x_pos, y_pos, 10, RED); } else { setMoving(0); y_pos = 35; } } } }; class blueNotes: public MovingNotes { virtual void draw() { uLCD.filled_circle(x_pos, y_pos, 10, BLUE); } virtual void update() { if (moving == 1) { gVal = touchg.read(); rVal = touchr.read(); bVal = touchb.read(); if (x_pos == 18 && y_pos > 90 && y_pos < 144 && gVal >0.5f) { score++; mySpeaker.PlayNote(freq,dur,val); } else if (x_pos == 64 && y_pos > 90 && y_pos < 144 && rVal >0.5f) { score++; mySpeaker.PlayNote(freq,dur,val); } else if (x_pos == 110 && y_pos > 90 && y_pos < 144 && bVal >0.5f) { score++; mySpeaker.PlayNote(freq,dur,val); } if (y_pos < 144) { Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 9; uLCD.filled_circle(x_pos, y_pos, 10, BLUE); Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 9; uLCD.filled_circle(x_pos, y_pos, 10, BLUE); Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 9; uLCD.filled_circle(x_pos, y_pos, 10, BLUE); Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 9; uLCD.filled_circle(x_pos, y_pos, 10, BLUE); } else { setMoving(0); y_pos = 35; } } } }; class greenNotes: public MovingNotes { virtual void draw() { uLCD.filled_circle(x_pos, y_pos, 10, GREEN); } virtual void update() { if (moving == 1) { gVal = touchg.read(); rVal = touchr.read(); bVal = touchb.read(); if (x_pos == 18 && y_pos > 90 && y_pos < 144 && gVal >0.5f) { score++; mySpeaker.PlayNote(freq,dur,val); } else if (x_pos == 64 && y_pos > 90 && y_pos < 144 && rVal >0.5f) { score++; mySpeaker.PlayNote(freq,dur,val); } else if (x_pos == 110 && y_pos > 90 && y_pos < 144 && bVal >0.5f) { score++; mySpeaker.PlayNote(freq,dur,val); } if (y_pos < 144) { Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 18; uLCD.filled_circle(x_pos, y_pos, 10, GREEN); Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 18; uLCD.filled_circle(x_pos, y_pos, 10, GREEN); Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 18; uLCD.filled_circle(x_pos, y_pos, 10, GREEN); Thread::wait(1000.00*0.1); uLCD.filled_circle(x_pos, y_pos, 10, BLACK); y_pos += 18; uLCD.filled_circle(x_pos, y_pos, 10, GREEN); } else { setMoving(0); y_pos = 35; } } } }; void beacon(void const *args){ while(1) { if (!pbL) { if (currState == 0) { prevState = 0; currState = 1; Thread::wait(1000.00*0.5); } else if (currState == 1) { if (selected == 1) { printf("play ramblin wreck"); currState = 2; prevState = 1; Thread::wait(1000.00*0.5); } else if (selected == 2) { printf("play other song"); currState = 3; prevState = 1; Thread::wait(1000.00*0.5); } else if (selected == 3) { currState = 4; prevState = 1; Thread::wait(1000.00*0.5); } else if (selected == 4) { currState = 0; prevState = 1; Thread::wait(1000.00*0.5); } } else if (currState == 2 || currState == 3 || currState == 4) { score = 0; numPlayedS1 = 0; numPlayedS2 = 0; currState = 1; Thread::wait(1000.00*0.5); } printf("pbL "); printf("currState: %d", currState); printf(" prevstate: %d\n", prevState); } else if (!pbR) { if (currState == 0) { prevState = 0; currState = 1; Thread::wait(1000.00*0.2); } else if (currState == 1) { selected++; if (selected >= 5) { selected = 1; } Thread::wait(1000.00*0.5); } printf("pbR "); printf("currState: %d", currState); printf(" prevstate: %d\n", prevState); } } } void welding(void const *args) { while(1) { if (currState == 4) { // Listen to RW stdio_mutex.lock(); Thread::wait(1000.00*1); if (prevState != 4) { uLCD.cls(); } mySpeaker.PlayNote(783.991,1.0/t,0.1); // G mySpeaker.PlayNote(698.456,0.5/t,0.1); //F mySpeaker.PlayNote(622.254,0.9/t,0.1); //E flat mySpeaker.PlayNote(0.0,0.1/t,0.0); //separation between the same notes mySpeaker.PlayNote(622.254,0.4/t,0.1); //E flat mySpeaker.PlayNote(0.0,0.1/t,0.0); mySpeaker.PlayNote(622.254,1.0/t,0.1); //E flat mySpeaker.PlayNote(698.456,0.5/t,0.1); //F mySpeaker.PlayNote(783.991,0.9/t,0.1); // G mySpeaker.PlayNote(0.0,0.1/t,0.0); mySpeaker.PlayNote(783.991,0.4/t,0.1); // G mySpeaker.PlayNote(0.0,0.1/t,0.0); mySpeaker.PlayNote(783.991,0.5/t,0.1); // G mySpeaker.PlayNote(698.456,0.5/t,0.1); //F mySpeaker.PlayNote(622.254,0.5/t,0.1); //E flat mySpeaker.PlayNote(698.456,0.4/t,0.1); //F mySpeaker.PlayNote(0.0,0.1/t,0.0); mySpeaker.PlayNote(698.456,0.4/t,0.1); //F mySpeaker.PlayNote(0.0,0.1/t,0.0); mySpeaker.PlayNote(698.456,0.5/t,0.1); //F mySpeaker.PlayNote(622.254,1.0/t,0.1); //E flat mySpeaker.PlayNote(587.330,0.5/t,0.1); //D mySpeaker.PlayNote(622.254,2.5/t,0.1); //E flat mySpeaker.PlayNote(0.0,0.5/t,0.0); //rest then repeat Thread::wait(1000.00*0.5); prevState = 4; stdio_mutex.unlock(); break; } else if (currState == 2) { //Playing Ramblin Wreck stdio_mutex.lock(); if (prevState != 2) { uLCD.text_width(1); uLCD.text_height(2); uLCD.locate(5,5); uLCD.color(RED); uLCD.printf("3 "); Thread::wait(1000.00*0.4); uLCD.printf("2 "); Thread::wait(1000.00*0.4); uLCD.printf("1 "); Thread::wait(1000.00*0.4); uLCD.printf("GO!"); Thread::wait(1000.00*0.3); uLCD.cls(); } // Set up Background uLCD.line(42,25-4,42,127,WHITE); uLCD.line(2*42+1,25-4,2*42+1,127,WHITE); uLCD.circle(20,127-20,20,GREEN); uLCD.circle(64,127-20,20,RED); uLCD.circle(127-20,127-20,20,BLUE); uLCD.rectangle(2,20,127,2,WHITE); uLCD.locate(1,1); uLCD.printf("Score: %f",score); if (numPlayedS1 < 17) { ramb_ptr[numPlayedS1] -> draw(); ramb_ptr[numPlayedS1] -> setMoving(1); numPlayedS1++; float waitTime = 0.17 - numPlayedS1*0.01; Thread::wait(1000.00*waitTime); } for (int i=0; i < 17; i++) { ramb_ptr[i] -> update(); } gVal = touchg.read(); rVal = touchr.read(); bVal = touchb.read(); if (gVal > 0.5f) { uLCD.circle(20,107,19,GREEN); uLCD.circle(20,107,21,GREEN); } else { uLCD.circle(20,107,19,BLACK); uLCD.circle(20,107,21,BLACK); } if (rVal > 0.5f) { uLCD.circle(64,107,19,RED); uLCD.circle(64,107,21,RED); } else { uLCD.circle(64,107,19,BLACK); uLCD.circle(64,107,21,BLACK); } if (bVal > 0.5f) { uLCD.circle(107,107,19,BLUE); uLCD.circle(107,107,21,BLUE); } else { uLCD.circle(107,107,19,BLACK); uLCD.circle(107,107,21,BLACK); } stdio_mutex.unlock(); prevState = 2; } else if (currState == 3) { //Playing Song2 //stdio_mutex.lock(); Thread::wait(1000.00*1); prevState = 3; //stdio_mutex.unlock(); } } } int main() { // Set up PushButtons pbL.mode(PullUp); pbR.mode(PullUp); Thread thread2(beacon); Thread thread3(welding); //Thread thread4(lighthouse); // Set up Random Note Positions set_time(1256729738); // by updating this creates new values each compilation srand( static_cast<unsigned int>(time(0))); // create random assigner for each note for (int i=0; i < 17; i++) { int ramblinColors = rand() % 3; int ramblinRows = rand() % 3; int x = 0; if (ramblinRows == 0) { x = 18; } else if (ramblinRows == 1) { x = 64; } else if (ramblinRows == 2) { x = 110; } if (ramblinColors == 0) { ramb_ptr[i] = new redNotes; } else if (ramblinColors == 1) { ramb_ptr[i] = new greenNotes; } else if (ramblinColors == 2) { ramb_ptr[i] = new blueNotes; } ramb_ptr[i] -> setStart(35); ramb_ptr[i] -> setWidth(x); ramb_ptr[i] -> setFreq(ramblinFirst[i]); ramb_ptr[i] -> setDur(ramblinSecond[i]); ramb_ptr[i] -> setVal(ramblinThird[i]); } while(1) { gVal = touchg.read(); rVal = touchr.read(); bVal = touchb.read(); // LED to Indicate Program Running myled = 1; Thread::wait(1000.0*0.2); myled = 0; Thread::wait(1000.0*0.2); // Display Startup Page stdio_mutex.lock(); if (currState == 0) { if (prevState != 0) { uLCD.cls(); } uLCD.text_width(2); uLCD.text_height(3); uLCD.color(BLUE); uLCD.locate(1.4, 0); uLCD.printf("Welcome to \nMusicPlay"); uLCD.text_width(1); uLCD.text_height(1); uLCD.color(RED); uLCD.locate(3.5, 12); uLCD.printf("Press Either Button to Start"); prevState = 0; } else if (currState == 1) { // Display Menu if (prevState != 1) { uLCD.cls(); } uLCD.text_width(1); uLCD.text_height(1); if (selected == 1) { uLCD.color(RED); } else { uLCD.color(BLUE); } uLCD.locate(2, 1); uLCD.printf("Ramblin Wreck"); if (selected == 2) { uLCD.color(RED); } else { uLCD.color(BLUE); } uLCD.locate(6, 3); uLCD.printf("Song2"); if (selected == 3) { uLCD.color(RED); } else { uLCD.color(BLUE); } uLCD.locate(3, 5); uLCD.printf("Just Listen!"); if (selected == 4) { uLCD.color(RED); } else { uLCD.color(BLUE); } uLCD.locate(7, 7); uLCD.printf("Back"); prevState = 1; } stdio_mutex.unlock(); } }