VS1053 audio player with lcd and rotary encoder

Dependencies:   LibMenu PinDetect SDFileSystem TextLCD VS1053lib mRotaryEncoder mbed

main.cpp

Committer:
ollie8
Date:
2013-05-29
Revision:
0:389ef088650e
Child:
1:0040f640281c

File content as of revision 0:389ef088650e:

#include "mbed.h"
#include "SDFileSystem.h"
#include "VLSIcodec.h"
#include "TextLCD.h"
#include "RPG.h"
#include "Menu.h"
#include "PinDetect.h"

enum PlayState {
    IDLE,
    CUED,
    PLAYING,
    PAUSED
};

TextLCD lcd(p24, p25, p26, p27, p28, p29);
SDFileSystem sd(p5, p6, p7, p8, "sd");
// PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dreq, PinName rst, PinName xdcs
VS1053Codec vs1053(p11, p12, p13, p14, p15, p17, p16);
RPG rpg(p21, p22, p23);
Serial pc(USBTX, USBRX);
Menu *current;
PlayState state = IDLE;
char* currentfile;
PinDetect  button(p23);

void select(MenuItem *item) {
    lcd.cls();
    lcd.printf(item->getName());
    pc.printf("Selected - %s\n\r", item->getName());
}

void cueItem(MenuItem *item) {
    currentfile = item->getName();
    state = CUED;
    pc.printf("Cueing menu item - %s\n\r", item->getName());
}

void setVolume(MenuItem *item) {

}

void setBass(MenuItem *item) {
 
}

void setTreble(MenuItem *item) {

}

void enterMenu(Menu *menu) {
    current = menu;
    pc.printf("Entered menu - %s\n\r", menu->getName());
    menu->getItem(0).select();
}

Menu root(&enterMenu, &select, "ROOT", 5);

void buttonPress() {
    pc.printf("Button press");
    switch (state) {
        case IDLE:
            current->selectedRow().enter();
        break;
        case CUED:
            // do nothing until we start playing;
            break;
        case PLAYING:
            state = PAUSED;
        break;
        case PAUSED:
            state = PLAYING;
        break;
    }
}

void buttonHeld() {
    pc.printf("Button held");
    state = IDLE;
    root.enter();
}

void buildLibrary(Menu *libmenu) {
    DIR *d;
    struct dirent *p;
    d = opendir("/sd");
    if (d != NULL) {
        while ((p = readdir(d)) != NULL) {
            pc.printf("Makning item\n\r");
            char * name = p->d_name;
            if (sizeof(name) > 0) {
                MenuItem *item = new MenuItem(&cueItem, &select, name);
                pc.printf("Makning item done\n\r");
                libmenu->addMenuItem(*item);
                pc.printf("Item added\n\r");
                pc.printf(" - %s\n\r", name);
            } else {
                pc.printf("BLANK NAME");            
            }
        }
    } else {
        pc.printf("Could not open directory!\n");
    }
    closedir(d);
}

void setupMenu() {
    pc.printf("Building menus...\n\r");
    pc.printf("Menu size - %d\r\n", root.size());
    Menu *library = new Menu(&enterMenu, &select, "Library", 6);
    root.addMenuItem(*library);
    buildLibrary(library);
    pc.printf("Menu size - %d\r\n", root.size());
    Menu *settings = new Menu(&enterMenu, &select, "Settings", 3);
    root.addMenuItem(*settings);
    Menu *test = new Menu(&enterMenu, &select, "Test", 2);
    root.addMenuItem(*test);
    MenuItem *volume = new MenuItem(&setVolume, &select, "Volume");
    settings->addMenuItem(*volume);
    MenuItem *bass = new MenuItem(&setBass, &select, "Bass");
    settings->addMenuItem(*bass);
    MenuItem *treble = new MenuItem(&setTreble, &select, "Treble");
    settings->addMenuItem(*treble);
    pc.printf("Menu size - %d\r\n", root.size());
    root.enter();
    pc.printf("Done.\n\r");
}

void checkControl() {
/*    if (rpg.pb()) {
        wait(0.5);
        if (!rpg.pb()) {
            pc.printf("button press on\n\r");
            current->selectedRow().enter();        
        } else {
            wait(1.0);
            if (rpg.pb()) {
                root.enter();            
            }
        }
        wait(0.4);
    } */
    if (rpg.dir() > 0) {
        wait(0.001);
        pc.printf("forward\n\r");
        current->up();      
    } else if (rpg.dir() < 0) {
        wait(0.001);
        pc.printf("back\n\r");
        current->down();
    }
}

void checkCued() {
    if (state == CUED) {
        pc.printf("Opening file %s\n\r", currentfile);
        unsigned char buff[32];
        char abs[16];
        strcpy(abs, "/sd/");
        strcat(abs, currentfile);
        FILE *song = fopen(abs, "r");
        if (song == NULL) {
            pc.printf("Cannot find file\n\r");
            lcd.cls();
            lcd.printf("File not found.");
            wait(1.5);
            root.enter();
        } else {
            pc.printf("File open\n\r");
            lcd.cls();
            lcd.printf("Now playing:");
            lcd.locate(0, 1);
            lcd.printf(currentfile);
            state = PLAYING;
            while(!feof(song)) {
                if (state == IDLE) {
                    break;
                } else if (state == PLAYING) {
                    if (vs1053.checkdreq()) {
                        fread(&buff, 1, 32, song);
                        //vs1053.testdreq();
                        for (int i = 0; i < 32; i++) {
                            vs1053.writedata(buff[i]);
                        }
                    } else {
                        // we have some free time so do something else
                    }
                }
            }
            fclose(song);
            state = IDLE;
            root.enter();
        }
    }
}

int main() {
    lcd.printf("Initialising...");
    lcd.locate(0, 1);
    lcd.printf("O pod v0.1");
    pc.printf("Starting...\n\r");
    vs1053.init();
    vs1053.loadpatch();
    button.mode(PullUp);
    button.setAssertValue(0);
    button.attach_asserted(&buttonPress);
    button.attach_asserted_held(&buttonHeld);
    button.setSampleFrequency();
    setupMenu();
    while (1) {
        checkControl();
        checkCued();
    }
}