VS1053 audio player with lcd and rotary encoder

Dependencies:   LibMenu PinDetect SDFileSystem TextLCD VS1053lib mRotaryEncoder mbed

Revision:
0:389ef088650e
Child:
1:0040f640281c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed May 29 13:15:22 2013 +0000
@@ -0,0 +1,214 @@
+#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();
+    }
+}
\ No newline at end of file