
VS1053 audio player with lcd and rotary encoder
Dependencies: LibMenu PinDetect SDFileSystem TextLCD VS1053lib mRotaryEncoder mbed
Revision 1:0040f640281c, committed 2013-06-18
- Comitter:
- ollie8
- Date:
- Tue Jun 18 17:01:22 2013 +0000
- Parent:
- 0:389ef088650e
- Child:
- 2:1c751f044ecd
- Commit message:
- Changed control to use interrupts. Added paused menu.
Changed in this revision
--- a/LibMenu.lib Wed May 29 13:15:22 2013 +0000 +++ b/LibMenu.lib Tue Jun 18 17:01:22 2013 +0000 @@ -1,1 +1,1 @@ -LibMenu#3f4d33765f10 +http://mbed.org/users/ollie8/code/LibMenu/#7828182dbc9f
--- a/RPG.lib Wed May 29 13:15:22 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/canderson199/code/RPG/#0b389c2c21b5
--- a/VS1053lib.lib Wed May 29 13:15:22 2013 +0000 +++ b/VS1053lib.lib Tue Jun 18 17:01:22 2013 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/clemente/code/VS1053lib/#59076bd8a066 +http://mbed.org/users/clemente/code/VS1053lib/#59c27531f18e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mRotaryEncoder.lib Tue Jun 18 17:01:22 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/charly/code/mRotaryEncoder/#75ddffaf3721
--- a/main.cpp Wed May 29 13:15:22 2013 +0000 +++ b/main.cpp Tue Jun 18 17:01:22 2013 +0000 @@ -2,9 +2,11 @@ #include "SDFileSystem.h" #include "VLSIcodec.h" #include "TextLCD.h" -#include "RPG.h" #include "Menu.h" -#include "PinDetect.h" +#include "mRotaryEncoder.h" + +#define BUFFER_SIZE 512 +#define MAX_BUF_WRITE 32 enum PlayState { IDLE, @@ -17,59 +19,71 @@ 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); +mRotaryEncoder rot(p21, p22, p23); Serial pc(USBTX, USBRX); Menu *current; PlayState state = IDLE; char* currentfile; -PinDetect button(p23); +char* lastPlaytime = (char*) malloc(6); +unsigned char volume = 0x00; -void select(MenuItem *item) { +void select(MenuNode *node) { lcd.cls(); - lcd.printf(item->getName()); - pc.printf("Selected - %s\n\r", item->getName()); + lcd.printf(node->getName()); + pc.printf("Selected - %s\n\r", node->getName()); } -void cueItem(MenuItem *item) { - currentfile = item->getName(); +void cueNode(MenuNode *node) { + currentfile = node->getName(); state = CUED; - pc.printf("Cueing menu item - %s\n\r", item->getName()); + pc.printf("Cueing menu node - %s\n\r", node->getName()); } -void setVolume(MenuItem *item) { +void setVolume(MenuNode *node) { } -void setBass(MenuItem *item) { +void setBass(MenuNode *node) { } -void setTreble(MenuItem *item) { +void setTreble(MenuNode *node) { } +void continuePlay(MenuNode *node) { + state = PLAYING; +} + + 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); +Menu pausedMenu(&enterMenu, &select, "PAUSED", 2); + +void cancelPlay(MenuNode *node) { + state = IDLE; + root.enter(); +} void buttonPress() { pc.printf("Button press"); switch (state) { case IDLE: - current->selectedRow().enter(); + current->getSelectedNode().enter(); break; case CUED: // do nothing until we start playing; break; case PLAYING: state = PAUSED; + pausedMenu.enter(); break; case PAUSED: - state = PLAYING; + current->getSelectedNode().enter(); break; } } @@ -80,19 +94,27 @@ root.enter(); } -void buildLibrary(Menu *libmenu) { +void buildLibrary() { DIR *d; struct dirent *p; d = opendir("/sd"); if (d != NULL) { + int dircount = 0; while ((p = readdir(d)) != NULL) { - pc.printf("Makning item\n\r"); + dircount++; + } + closedir(d); + Menu *library = new Menu(&enterMenu, &select, "Library", dircount); + root.addMenuNode(*library); + d = opendir("/sd"); + while ((p = readdir(d)) != NULL) { + pc.printf("Makning node\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"); + MenuNode *node = new MenuNode(&cueNode, &select, name); + pc.printf("Makning node done\n\r"); + library->addMenuNode(*node); + pc.printf("Node added\n\r"); pc.printf(" - %s\n\r", name); } else { pc.printf("BLANK NAME"); @@ -107,54 +129,72 @@ 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); + buildLibrary(); pc.printf("Menu size - %d\r\n", root.size()); Menu *settings = new Menu(&enterMenu, &select, "Settings", 3); - root.addMenuItem(*settings); + root.addMenuNode(*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); + root.addMenuNode(*test); + MenuNode *volume = new MenuNode(&setVolume, &select, "Volume"); + settings->addMenuNode(*volume); + MenuNode *bass = new MenuNode(&setBass, &select, "Bass"); + settings->addMenuNode(*bass); + MenuNode *treble = new MenuNode(&setTreble, &select, "Treble"); + settings->addMenuNode(*treble); pc.printf("Menu size - %d\r\n", root.size()); + MenuNode *contPlay = new MenuNode(&continuePlay, &select, "Continue"); + MenuNode *cancPlay = new MenuNode(&cancelPlay, &select, "Cancel"); + pausedMenu.addMenuNode(*contPlay); + pausedMenu.addMenuNode(*cancPlay); 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(); - } +void control() { + int val = rot.Get(); + pc.printf("Enc val - %d", val); + if (state == PLAYING) { + pc.printf("\r\n"); + if (val > 1) { + pc.printf("Going up...\r\n"); + volume -= 0x05; + rot.Set(0); + } else if (val < -1) { + pc.printf("Going down...\r\n"); + volume += 0x05; + rot.Set(0); } - 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(); + pc.printf("Setting volume - %d", volume); + vs1053.setvolume(volume, volume); + } else if (state == IDLE || state == PAUSED) { + if (val > 1) { + pc.printf("forward\n\r"); + current->up(); + rot.Set(0); + } else if (val < -1) { + pc.printf("back\n\r"); + current->down(); + rot.Set(0); + } + } +} + +void drawNowPlaying(char* playtime) { + if (strcmp(playtime, lastPlaytime) != 0) { + lcd.cls(); + lcd.printf("Playing:"); + lcd.locate(11, 0); + lcd.printf(playtime); + lcd.locate(0, 1); + lcd.printf(currentfile); + strcpy(lastPlaytime, playtime); } } void checkCued() { if (state == CUED) { pc.printf("Opening file %s\n\r", currentfile); - unsigned char buff[32]; + unsigned char buff[BUFFER_SIZE]; char abs[16]; strcpy(abs, "/sd/"); strcat(abs, currentfile); @@ -166,28 +206,36 @@ wait(1.5); root.enter(); } else { + char* playtime = (char*) malloc(6); pc.printf("File open\n\r"); - lcd.cls(); - lcd.printf("Now playing:"); - lcd.locate(0, 1); - lcd.printf(currentfile); + drawNowPlaying("00:00"); state = PLAYING; while(!feof(song)) { if (state == IDLE) { + // empty the buffer on the VS1053 then break out of the loop + // TODO add cancel play methos to vs1053 lib 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]); + fread(&buff, 1, BUFFER_SIZE, song); + int i= 0; + while (i < BUFFER_SIZE) { + vs1053.writedata(buff[i++]); + if (i % MAX_BUF_WRITE == 0) { + bool checkPlaytime = true; + while (!vs1053.checkdreq()) { + if (checkPlaytime) { + vs1053.getplaytime(playtime); + playtime[5] = NULL; + drawNowPlaying(playtime); + checkPlaytime = false; + } + } } - } else { - // we have some free time so do something else } } } fclose(song); + vs1053.resetplaytime(); state = IDLE; root.enter(); } @@ -198,17 +246,16 @@ lcd.printf("Initialising..."); lcd.locate(0, 1); lcd.printf("O pod v0.1"); + wait(1.0); 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(); + rot.Set(0); + rot.attachSW(&buttonPress); + //rot.attachSWHeld(&buttonHeld); + rot.attachROT(&control); setupMenu(); while (1) { - checkControl(); checkCued(); } } \ No newline at end of file