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();
    }
}