VS1053 audio player with lcd and rotary encoder

Dependencies:   LibMenu PinDetect SDFileSystem TextLCD VS1053lib mRotaryEncoder mbed

Committer:
ollie8
Date:
Wed May 29 13:15:22 2013 +0000
Revision:
0:389ef088650e
Child:
1:0040f640281c
Check in of vs1053 player

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ollie8 0:389ef088650e 1 #include "mbed.h"
ollie8 0:389ef088650e 2 #include "SDFileSystem.h"
ollie8 0:389ef088650e 3 #include "VLSIcodec.h"
ollie8 0:389ef088650e 4 #include "TextLCD.h"
ollie8 0:389ef088650e 5 #include "RPG.h"
ollie8 0:389ef088650e 6 #include "Menu.h"
ollie8 0:389ef088650e 7 #include "PinDetect.h"
ollie8 0:389ef088650e 8
ollie8 0:389ef088650e 9 enum PlayState {
ollie8 0:389ef088650e 10 IDLE,
ollie8 0:389ef088650e 11 CUED,
ollie8 0:389ef088650e 12 PLAYING,
ollie8 0:389ef088650e 13 PAUSED
ollie8 0:389ef088650e 14 };
ollie8 0:389ef088650e 15
ollie8 0:389ef088650e 16 TextLCD lcd(p24, p25, p26, p27, p28, p29);
ollie8 0:389ef088650e 17 SDFileSystem sd(p5, p6, p7, p8, "sd");
ollie8 0:389ef088650e 18 // PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dreq, PinName rst, PinName xdcs
ollie8 0:389ef088650e 19 VS1053Codec vs1053(p11, p12, p13, p14, p15, p17, p16);
ollie8 0:389ef088650e 20 RPG rpg(p21, p22, p23);
ollie8 0:389ef088650e 21 Serial pc(USBTX, USBRX);
ollie8 0:389ef088650e 22 Menu *current;
ollie8 0:389ef088650e 23 PlayState state = IDLE;
ollie8 0:389ef088650e 24 char* currentfile;
ollie8 0:389ef088650e 25 PinDetect button(p23);
ollie8 0:389ef088650e 26
ollie8 0:389ef088650e 27 void select(MenuItem *item) {
ollie8 0:389ef088650e 28 lcd.cls();
ollie8 0:389ef088650e 29 lcd.printf(item->getName());
ollie8 0:389ef088650e 30 pc.printf("Selected - %s\n\r", item->getName());
ollie8 0:389ef088650e 31 }
ollie8 0:389ef088650e 32
ollie8 0:389ef088650e 33 void cueItem(MenuItem *item) {
ollie8 0:389ef088650e 34 currentfile = item->getName();
ollie8 0:389ef088650e 35 state = CUED;
ollie8 0:389ef088650e 36 pc.printf("Cueing menu item - %s\n\r", item->getName());
ollie8 0:389ef088650e 37 }
ollie8 0:389ef088650e 38
ollie8 0:389ef088650e 39 void setVolume(MenuItem *item) {
ollie8 0:389ef088650e 40
ollie8 0:389ef088650e 41 }
ollie8 0:389ef088650e 42
ollie8 0:389ef088650e 43 void setBass(MenuItem *item) {
ollie8 0:389ef088650e 44
ollie8 0:389ef088650e 45 }
ollie8 0:389ef088650e 46
ollie8 0:389ef088650e 47 void setTreble(MenuItem *item) {
ollie8 0:389ef088650e 48
ollie8 0:389ef088650e 49 }
ollie8 0:389ef088650e 50
ollie8 0:389ef088650e 51 void enterMenu(Menu *menu) {
ollie8 0:389ef088650e 52 current = menu;
ollie8 0:389ef088650e 53 pc.printf("Entered menu - %s\n\r", menu->getName());
ollie8 0:389ef088650e 54 menu->getItem(0).select();
ollie8 0:389ef088650e 55 }
ollie8 0:389ef088650e 56
ollie8 0:389ef088650e 57 Menu root(&enterMenu, &select, "ROOT", 5);
ollie8 0:389ef088650e 58
ollie8 0:389ef088650e 59 void buttonPress() {
ollie8 0:389ef088650e 60 pc.printf("Button press");
ollie8 0:389ef088650e 61 switch (state) {
ollie8 0:389ef088650e 62 case IDLE:
ollie8 0:389ef088650e 63 current->selectedRow().enter();
ollie8 0:389ef088650e 64 break;
ollie8 0:389ef088650e 65 case CUED:
ollie8 0:389ef088650e 66 // do nothing until we start playing;
ollie8 0:389ef088650e 67 break;
ollie8 0:389ef088650e 68 case PLAYING:
ollie8 0:389ef088650e 69 state = PAUSED;
ollie8 0:389ef088650e 70 break;
ollie8 0:389ef088650e 71 case PAUSED:
ollie8 0:389ef088650e 72 state = PLAYING;
ollie8 0:389ef088650e 73 break;
ollie8 0:389ef088650e 74 }
ollie8 0:389ef088650e 75 }
ollie8 0:389ef088650e 76
ollie8 0:389ef088650e 77 void buttonHeld() {
ollie8 0:389ef088650e 78 pc.printf("Button held");
ollie8 0:389ef088650e 79 state = IDLE;
ollie8 0:389ef088650e 80 root.enter();
ollie8 0:389ef088650e 81 }
ollie8 0:389ef088650e 82
ollie8 0:389ef088650e 83 void buildLibrary(Menu *libmenu) {
ollie8 0:389ef088650e 84 DIR *d;
ollie8 0:389ef088650e 85 struct dirent *p;
ollie8 0:389ef088650e 86 d = opendir("/sd");
ollie8 0:389ef088650e 87 if (d != NULL) {
ollie8 0:389ef088650e 88 while ((p = readdir(d)) != NULL) {
ollie8 0:389ef088650e 89 pc.printf("Makning item\n\r");
ollie8 0:389ef088650e 90 char * name = p->d_name;
ollie8 0:389ef088650e 91 if (sizeof(name) > 0) {
ollie8 0:389ef088650e 92 MenuItem *item = new MenuItem(&cueItem, &select, name);
ollie8 0:389ef088650e 93 pc.printf("Makning item done\n\r");
ollie8 0:389ef088650e 94 libmenu->addMenuItem(*item);
ollie8 0:389ef088650e 95 pc.printf("Item added\n\r");
ollie8 0:389ef088650e 96 pc.printf(" - %s\n\r", name);
ollie8 0:389ef088650e 97 } else {
ollie8 0:389ef088650e 98 pc.printf("BLANK NAME");
ollie8 0:389ef088650e 99 }
ollie8 0:389ef088650e 100 }
ollie8 0:389ef088650e 101 } else {
ollie8 0:389ef088650e 102 pc.printf("Could not open directory!\n");
ollie8 0:389ef088650e 103 }
ollie8 0:389ef088650e 104 closedir(d);
ollie8 0:389ef088650e 105 }
ollie8 0:389ef088650e 106
ollie8 0:389ef088650e 107 void setupMenu() {
ollie8 0:389ef088650e 108 pc.printf("Building menus...\n\r");
ollie8 0:389ef088650e 109 pc.printf("Menu size - %d\r\n", root.size());
ollie8 0:389ef088650e 110 Menu *library = new Menu(&enterMenu, &select, "Library", 6);
ollie8 0:389ef088650e 111 root.addMenuItem(*library);
ollie8 0:389ef088650e 112 buildLibrary(library);
ollie8 0:389ef088650e 113 pc.printf("Menu size - %d\r\n", root.size());
ollie8 0:389ef088650e 114 Menu *settings = new Menu(&enterMenu, &select, "Settings", 3);
ollie8 0:389ef088650e 115 root.addMenuItem(*settings);
ollie8 0:389ef088650e 116 Menu *test = new Menu(&enterMenu, &select, "Test", 2);
ollie8 0:389ef088650e 117 root.addMenuItem(*test);
ollie8 0:389ef088650e 118 MenuItem *volume = new MenuItem(&setVolume, &select, "Volume");
ollie8 0:389ef088650e 119 settings->addMenuItem(*volume);
ollie8 0:389ef088650e 120 MenuItem *bass = new MenuItem(&setBass, &select, "Bass");
ollie8 0:389ef088650e 121 settings->addMenuItem(*bass);
ollie8 0:389ef088650e 122 MenuItem *treble = new MenuItem(&setTreble, &select, "Treble");
ollie8 0:389ef088650e 123 settings->addMenuItem(*treble);
ollie8 0:389ef088650e 124 pc.printf("Menu size - %d\r\n", root.size());
ollie8 0:389ef088650e 125 root.enter();
ollie8 0:389ef088650e 126 pc.printf("Done.\n\r");
ollie8 0:389ef088650e 127 }
ollie8 0:389ef088650e 128
ollie8 0:389ef088650e 129 void checkControl() {
ollie8 0:389ef088650e 130 /* if (rpg.pb()) {
ollie8 0:389ef088650e 131 wait(0.5);
ollie8 0:389ef088650e 132 if (!rpg.pb()) {
ollie8 0:389ef088650e 133 pc.printf("button press on\n\r");
ollie8 0:389ef088650e 134 current->selectedRow().enter();
ollie8 0:389ef088650e 135 } else {
ollie8 0:389ef088650e 136 wait(1.0);
ollie8 0:389ef088650e 137 if (rpg.pb()) {
ollie8 0:389ef088650e 138 root.enter();
ollie8 0:389ef088650e 139 }
ollie8 0:389ef088650e 140 }
ollie8 0:389ef088650e 141 wait(0.4);
ollie8 0:389ef088650e 142 } */
ollie8 0:389ef088650e 143 if (rpg.dir() > 0) {
ollie8 0:389ef088650e 144 wait(0.001);
ollie8 0:389ef088650e 145 pc.printf("forward\n\r");
ollie8 0:389ef088650e 146 current->up();
ollie8 0:389ef088650e 147 } else if (rpg.dir() < 0) {
ollie8 0:389ef088650e 148 wait(0.001);
ollie8 0:389ef088650e 149 pc.printf("back\n\r");
ollie8 0:389ef088650e 150 current->down();
ollie8 0:389ef088650e 151 }
ollie8 0:389ef088650e 152 }
ollie8 0:389ef088650e 153
ollie8 0:389ef088650e 154 void checkCued() {
ollie8 0:389ef088650e 155 if (state == CUED) {
ollie8 0:389ef088650e 156 pc.printf("Opening file %s\n\r", currentfile);
ollie8 0:389ef088650e 157 unsigned char buff[32];
ollie8 0:389ef088650e 158 char abs[16];
ollie8 0:389ef088650e 159 strcpy(abs, "/sd/");
ollie8 0:389ef088650e 160 strcat(abs, currentfile);
ollie8 0:389ef088650e 161 FILE *song = fopen(abs, "r");
ollie8 0:389ef088650e 162 if (song == NULL) {
ollie8 0:389ef088650e 163 pc.printf("Cannot find file\n\r");
ollie8 0:389ef088650e 164 lcd.cls();
ollie8 0:389ef088650e 165 lcd.printf("File not found.");
ollie8 0:389ef088650e 166 wait(1.5);
ollie8 0:389ef088650e 167 root.enter();
ollie8 0:389ef088650e 168 } else {
ollie8 0:389ef088650e 169 pc.printf("File open\n\r");
ollie8 0:389ef088650e 170 lcd.cls();
ollie8 0:389ef088650e 171 lcd.printf("Now playing:");
ollie8 0:389ef088650e 172 lcd.locate(0, 1);
ollie8 0:389ef088650e 173 lcd.printf(currentfile);
ollie8 0:389ef088650e 174 state = PLAYING;
ollie8 0:389ef088650e 175 while(!feof(song)) {
ollie8 0:389ef088650e 176 if (state == IDLE) {
ollie8 0:389ef088650e 177 break;
ollie8 0:389ef088650e 178 } else if (state == PLAYING) {
ollie8 0:389ef088650e 179 if (vs1053.checkdreq()) {
ollie8 0:389ef088650e 180 fread(&buff, 1, 32, song);
ollie8 0:389ef088650e 181 //vs1053.testdreq();
ollie8 0:389ef088650e 182 for (int i = 0; i < 32; i++) {
ollie8 0:389ef088650e 183 vs1053.writedata(buff[i]);
ollie8 0:389ef088650e 184 }
ollie8 0:389ef088650e 185 } else {
ollie8 0:389ef088650e 186 // we have some free time so do something else
ollie8 0:389ef088650e 187 }
ollie8 0:389ef088650e 188 }
ollie8 0:389ef088650e 189 }
ollie8 0:389ef088650e 190 fclose(song);
ollie8 0:389ef088650e 191 state = IDLE;
ollie8 0:389ef088650e 192 root.enter();
ollie8 0:389ef088650e 193 }
ollie8 0:389ef088650e 194 }
ollie8 0:389ef088650e 195 }
ollie8 0:389ef088650e 196
ollie8 0:389ef088650e 197 int main() {
ollie8 0:389ef088650e 198 lcd.printf("Initialising...");
ollie8 0:389ef088650e 199 lcd.locate(0, 1);
ollie8 0:389ef088650e 200 lcd.printf("O pod v0.1");
ollie8 0:389ef088650e 201 pc.printf("Starting...\n\r");
ollie8 0:389ef088650e 202 vs1053.init();
ollie8 0:389ef088650e 203 vs1053.loadpatch();
ollie8 0:389ef088650e 204 button.mode(PullUp);
ollie8 0:389ef088650e 205 button.setAssertValue(0);
ollie8 0:389ef088650e 206 button.attach_asserted(&buttonPress);
ollie8 0:389ef088650e 207 button.attach_asserted_held(&buttonHeld);
ollie8 0:389ef088650e 208 button.setSampleFrequency();
ollie8 0:389ef088650e 209 setupMenu();
ollie8 0:389ef088650e 210 while (1) {
ollie8 0:389ef088650e 211 checkControl();
ollie8 0:389ef088650e 212 checkCued();
ollie8 0:389ef088650e 213 }
ollie8 0:389ef088650e 214 }