Luke Cartwright / Mbed 2 deprecated ELEC2645_Project_el18loc_nearlythere

Dependencies:   mbed

Front/Front.cpp

Committer:
lukeocarwright
Date:
2020-05-26
Revision:
33:e7635c8a58a8
Parent:
31:cfdb014ff086

File content as of revision 33:e7635c8a58a8:

#include "mbed.h"
#include "Front.h"

//Objects-----------------------------------------------------------------------
Sound sound;
Envelope envelope;
Filter filter;

//Sprites-----------------------------------------------------------------------
const int fader[35][5] =   { //Fader Sprite
    { 1,1,1,1,1 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 1,1,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 1,1,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 1,1,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 1,1,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 1,1,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 1,1,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 0,0,1,0,0 },
    { 1,1,1,1,1 },
};

const int sin_wav[6][28] =   {//sub 1 sin sprite
    { 0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0 },
    { 0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0 },
    { 1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0 },
    { 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1 },
    { 0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 },
};
const int tri_wav[6][28] =   {//sub 2 tri sprite
    { 0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0 },
    { 0,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0 },
    { 0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0 },
    { 1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0 },
    { 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1 },
    { 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0 },
};
const int square_wav[6][28] =   {//sub 3 sqr sprite
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1 },
    { 0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0 },
    { 0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0 },
    { 0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
};

const int Low_pass[19][29]= {//LPF plot
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0 },
};

const int High_pass[19][29]= {//HPF plot
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
};

const int Band_pass[19][29]= {//BPF plot
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0 },
    { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0 },
    { 0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0 },
    { 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 },
    { 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0 },
    { 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0 },
    { 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0 },
    { 0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0 },
    { 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 },
    { 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 },
    { 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 },
};

//Gloabal Variables
volatile int g_isr_flag; //used for sound generation
volatile extern int silent_flag; //used for note release


//constructor/destructor
Front::Front()
{
}
Front::~Front()
{
}
//PUBLIC------------------------------------------------------------------------

void Front::frontrun(N5110 &lcd, Gamepad &pad, int submenu)
{
    frontsetup(lcd, pad, submenu,0, true);  //Initialises front pannel display
    frequency=frequency_convert(pad,oct); //collects initial frequency
    release_flag=silent_flag=0; //Flags setup
    used=menuflag=1;  //initialises vairables
    filter_type=envelope_in=0;
    a=d=s=r=17; //starting adsr values (1->35)
    noteon=false;
    oct=3; //starting octave
#ifdef CSV
    itterator=0; //sets itterator for CSV OUTPUT
#endif

    while (menuflag==1) {
#ifdef SLOW_TIME
        print_SLOWTIME_out(out,noteon,a,d,s,r,release_flag,silent_flag); //debug terminal print function
#endif
        if (noteon==true && g_isr_flag == 1) { //isr triggered and note on
            pad.write_u16(out); //writes Output in uns short format 
            envelope_in=(sound.sound_main(false,submenu,frequency)-32767); //int around 0
            envelope_in=filter.filter_run(envelope_in,filter_type,false);
            if (release_flag==0) { //Note still on
                out=(envelope.env_in(a,d,s,r,envelope_in,false));//Uint around 32767
            }  else { //Note off
                out=envelope.release(s,r,envelope_in,false); //release rubnthrough
                if (silent_flag==1) { //release transient finished
                    release_flag=0; //resets variables
                    silent_flag=0;
                    noteon=false;
                    out=envelope.env_in(a,d,s,r,out,true); //initialises
                    out=0;
                }
            }
            g_isr_flag=0; //resets ISR flag
#ifdef CSV //generates CSV out
            printf("%d,%d\n",itterator,out);
            itterator++;
#endif
        }
        dir=pad.get_direction(); //checks joystick
        if (dir!=dir_1) {
            //printf("dir =%d\n",dir); //debug
            switch (dir) {
                case 3:
                    used=fader_select(used,1); break; //itterates Fader (R)
                case 7:
                    used=fader_select(used,-1); break; //itterates fader(L)
                case 1:
                    if (used==1) {
                        a=incrament_adsr(used,a,1); //Attack up
                    }
                    if (used==2) {
                        d=incrament_adsr(used,d,1); //Decay up
                    }
                    if (used==3) {
                        s=incrament_adsr(used,s,1); //Sustain Up
                    }
                    if (used==4) {
                        r=incrament_adsr(used,r,1); //Release Up
                    }
                    if (used==5) { //Filter UP
                        filter_type=incrament_adsr(used,filter_type,-1);
                        //printf("FILTER_TYPE=%d\n",filter_type);
                    }
                    break;
                case 5:
                    if (used==1) {
                        a=incrament_adsr(used,a,-1); //Attack Down
                    }
                    if (used==2) {
                        d=incrament_adsr(used,d,-1); //Decay Down
                    }
                    if (used==3) {
                        s=incrament_adsr(used,s,-1); //Sustain Down
                    }
                    if (used==4) {
                        r=incrament_adsr(used,r,-1); //Release Down
                    }
                    if (used==5) { //Filter Down
                        filter_type=incrament_adsr(used,filter_type,1);
                        //printf("FILTER_TYPE=%d\n",filter_type);
                    }
                    break;
            }
            frontsetup(lcd,pad,submenu,filter_type,false); //reprints Front Panel
            printsliders(lcd,a,d,s,r,used); //Prints Sliders
            wait_ms(100); //Debounce
        } //END if DIR
        if ( pad.A_pressed())  { //NOTE ON
            //printf("NOTE_ON\n");
            noteon=true;
            out=envelope.env_in(a,d,s,r,out,true); //Initiialises
            frequency=frequency_convert(pad,oct); //Checks Frequnecy
        }
        if ( pad.B_pressed())  { //NOTE OFF
            release_flag=1; //Begins release
            envelope_in=envelope.release(s,r,envelope_in,true); //initialises
            pad.reset_buttons();
        }
        if ( pad.X_pressed())  { //Down Octave
            oct--;
            if (oct<0) { //Min Value
                oct++;
            }
            //printf("OCTAVE %d\n",oct);
            pad.reset_buttons();
        }
        if ( pad.Y_pressed())  { //Octave Up
            oct++;
            if (oct>5) { //Max Value
                oct--;
            }
            //printf("OCTAVE %d\n",oct);
            pad.reset_buttons();
        }

        if (pad.start_pressed())  { //Main Menu Select
            //printf("Main selected\n"); //debug
            noteon=false;
            menuflag=0; //sets flag to exit
            break;
        }
        dir=dir_1;
        sleep(); //puts sleep until ISR wakes up
    }
}


//PRIVATE-----------------------------------------------------------------------

void Front::frontsetup(N5110 &lcd, Gamepad &pad, int submenu, int filter_type, bool initial)
{
    if (initial==true) { //intial Setup
        printsliders(lcd,17,17,17,17,1); 
        initialise(pad,lcd,submenu); //Initialises functions

    }
    lcd.clear(); //Draws Front Pannel
    lcd.printString("A D S R",3,5);
    printfader(lcd,3,3);
    printfader(lcd,15,3);
    printfader(lcd,27,3);
    printfader(lcd,39,3);
    lcd.drawRect(50,3,30,8,FILL_TRANSPARENT);
    printwav(lcd,submenu); //Prints Waveform
    printfilter(lcd, filter_type); //Prints Filter Type
    lcd.refresh();
}

void Front::initialise(Gamepad &pad, N5110 &lcd, int submenu)
{
    out=sound.sound_main(true,submenu,440); //initialises external variables
    out = filter.filter_run(out,1,true); //initialises LPF Filter
    out = filter.filter_run(out,2,true); //initialises HPF Filter
    out = filter.filter_run(out,3,true); //initialises BPF Filter
    out=envelope.env_in(17,17,17,17,out,true);
    out=envelope.release(17,17,out,true);
    printsliders(lcd,17,17,17,17,1);  //prints initialsliders
    pad.reset_buttons();
}

void Front::printsliders(N5110 &lcd, int a, int d, int s, int r, int used)
{
    //printf("USED(SLIDERS)=%d\n",used);
    if(used==0) { //NONE
        printslider(lcd,3,a,false);
        printslider(lcd,15,d,false);
        printslider(lcd,27,s,false);
        printslider(lcd,39,r,false);
    }
    if(used==1) { //ATTACK
        printslider(lcd,3,a,true);
        printslider(lcd,15,d,false);
        printslider(lcd,27,s,false);
        printslider(lcd,39,r,false);
    }
    if(used==2) { //DECAY
        printslider(lcd,3,a,false);
        printslider(lcd,15,d,true);
        printslider(lcd,27,s,false);
        printslider(lcd,39,r,false);
    }
    if(used==3) { //SUSTAIN
        printslider(lcd,3,a,false);
        printslider(lcd,15,d,false);
        printslider(lcd,27,s,true);
        printslider(lcd,39,r,false);
    }
    if(used==4) { //Relase
        printslider(lcd,3,a,false);
        printslider(lcd,15,d,false);
        printslider(lcd,27,s,false);
        printslider(lcd,39,r,true);
    }
    if(used>=5) {
        printslider(lcd,3,a,false);
        printslider(lcd,15,d,false);
        printslider(lcd,27,s,false);
        printslider(lcd,39,r,false);
    }
    lcd.refresh();
}

void Front::printslider(N5110 &lcd, int x_val, int y_val, bool use)
{
    if (use==true) {
        lcd.drawRect(x_val,37-y_val,5,2,FILL_BLACK);
    }
    if (use==false) {
        lcd.drawRect(x_val,37-y_val,5,1,FILL_BLACK);
    }
}


void Front::printfader(N5110 &lcd, int x, int y)
{
    // x origin, y origin, rows, cols, sprite
    lcd.drawSprite(x,y,35,5,(int *)fader);
}

void Front::printwav(N5110 &lcd, int submenu)
{
    if (submenu==1) {
        // x origin, y origin, rows, cols, sprite
        lcd.drawSprite(51,4,6,28,(int *)sin_wav); //sin
    }
    if (submenu==2) {
        // x origin, y origin, rows, cols, sprite
        lcd.drawSprite(51,4,6,28,(int *)tri_wav); //tri
    }
    if (submenu==3) {
        // x origin, y origin, rows, cols, sprite
        lcd.drawSprite(51,4,6,28,(int *)square_wav); //sqr
    }
}

void Front::printfilter(N5110 &lcd, int filter_type)
{
    if (filter_type>=1) {
        lcd.drawLine(51,32,51,12,1); //y axis
        lcd.drawLine(51,32,81,32,1); //x axis
        if (filter_type==1) {
            lcd.drawSprite(52,13,19,29,(int *)Low_pass); //LPF
            lcd.printString("L",45,2);
        }
        if (filter_type==2) {
            lcd.drawSprite(52,13,19,29,(int *)High_pass); //HPF
            lcd.printString("H",45,2);
        }
        if (filter_type==3) {
            lcd.drawSprite(52,13,19,29,(int *)Band_pass); //BPF
            lcd.printString("B",45,2);
        }
    }
}

int Front::incrament_adsr(int used, int adsr, int ud)
{
    if (used<=4) { //Num of Faders
        if (ud==1) { //Up
            adsr++;
            if (adsr>35) {
                adsr--;
            }
        }
        if (ud==-1) {//Down
            adsr--;
            if (adsr<1) {
                adsr++;
            }
        }
    }
    if (used==5) {
        adsr=incrament_filter(adsr,ud); //Filter Type Change
    }
    return(adsr);
}

int Front::incrament_filter(int adsr, int ud)
{
    if (ud==1) { //UP
        adsr++;
        if (adsr>3) { //Max Filters
            adsr--;
        }
    }
    if (ud==-1) { //down
        adsr--;
        if (adsr<0) {
            adsr++;
        }
    }
    return(adsr);
}

int Front::frequency_convert(Gamepad &pad,int oct)
{
    frequency=55*(pow(2.0,oct)); //Converts to correct Octave Start
    frequency=(frequency+(pad.read_pot1()*frequency)); //Generates Exact Frequency
    return(frequency);
}

int Front::fader_select(int used,int lr)
{
    if (lr==1) { //Right
        used++;
        if (used>5) { //Max
            used=5;
        }
    }
    if(lr==-1) { ///Left
        used--;
        if(used<1) { //Min
            used=1;
        }
    }
    //printf("INCRAMENT USED= %d\n",used); //debug
    return(used);
}

#ifdef SLOW_TIME
void Front::print_SLOWTIME_out (uint16_t out, bool noteon, int a, int d, int s, int r, int release_flag, int silent_flag)
{
    //Prints all data required in SLOW_TIME
    printf("OUTPUT:%d\n",out);
    printf("NOTEON: %d\n",noteon);
    printf("A:%d,D:%d,S:%d,R:%d\n",a,d,s,r);
    printf("RelFlag=%d, SilFlag=%d\n\n",release_flag,silent_flag);
}
#endif