Arduino music player

/*****************************************************************************

  VS100X-based MP3 player
  Plays mp3 files that must be in the SD formatted as FAT32
  Uses a module based on a VS100X chip and a 20x4 LCD
 *******************************************************************************/
#include <SPI.h>
#include <SD.h>

#include <AGMp3.h>
#include <LiquidCrystal.h>

// Pins  for the lcd
#define LCD_RS  3
#define LCD_Enable 4
#define LCD_D4  A0
#define LCD_D5  A1
#define LCD_D6  A2
#define LCD_D7  A3

//Encoder pins
#define ENC_A 8
#define ENC_B 10
//Button pins
#define button_FORAWARD 0
#define button_BACK 1

// Minimum volume in db
#define MIN_VOL 60

// Maximum no of entries in a catalog
#define MAX_ENTRIES  15
// No of characters in each entry
#define MAX_LONG 20
#define MAX_LONGMAS1 21

// Defining characters for song progress
byte bar1[8] = { B10001, B10001, B10001,  B10001,  B10001,  B10001,  B10001,  B10001 };
byte bar2[8] = { B11001, B11001, B11001,  B11001,  B11001,  B11001,  B11001,  B11001 };
byte bar3[8] = { B11101, B11101, B11101,  B11101,  B11101,  B11101,  B11101,  B11101 };
byte bar4[8] = { B11111, B11111, B11111,  B11111,  B11111,  B11111,  B11111,  B11111 };
byte bar5[8] = { B11111, B11111, B11111,  B11111,  B11111,  B11111,  B11111,  B11111 };
byte barV[8] = { B00001, B00001, B00001,  B00001,  B00001,  B00001,  B00001,  B00001 };

// Initialiding liquid crystal display
LiquidCrystal lcd(LCD_RS, LCD_Enable, A0, A1, A2, A3);

//Creating object MP3
AGMp3Player MP3player;

//Catalog file
File fText;
char FileName[31];

byte temp;
byte result;

//Variab
char strArtist[MAX_LONGMAS1];
char strAlbum[MAX_LONGMAS1];
char strTitle[MAX_LONGMAS1];

// Variables to know the current and previous catalog entry, as well as the tenth of entries
byte Entry = 0;
byte Entry A = 0;
byte maxEntries =  0;

// Variables to control the encoder
byte posOn = 0;
byte encoderAon = LOW;

// Actual volume
byte vol = 20;

// Catalog of entries
char catalog[MAX_ENTRIES][MAX_LONGMAS1];

byte level, artist, album, track = 0;
char strLine [30];

void errorCard() {
  lcd.setCursor(0, 4);
  lcd.print("Error in SD card or card not present.");
}

void showProgress() {
  byte pos = MP3player.getPosition() ;
  if ( pos == posOn )
    return;
  posOn = pos;
  byte pos10 = pos / 10 ;

  lcd.setCursor(0, 4);
  for (byte i = 0; i < 10; i++)
    lcd.write(5);
  lcd.setCursor(0, 4);
  for (byte i = 0; i < pos10; i++)
    lcd.write(4);
  lcd.write((pos - 10 * pos10) / 2);

  lcd.setCursor(12, 4);
  lcd.print("Vol:");
  lcd.print(map(vol, 0, MIN_VOL, 10, 0), DEC);
  //lcd.print(FreeRam(),DEC);
  lcd.print(" ");
}

// Debouncing of the buttons
int buttonClick (byte button) {
  if (digitalRead(button) == LOW) {
    delay(100);
    return digitalRead(button) == LOW;
  }
  return 0;
}

// Reads a line of text from the file
char* readLine(File myFile, char* line) {
  byte idx = 0;
  uint16_t letter = myFile.read();
  // we eliminate carriage and if returns
  while (myFile.available() && (l == 13 || letter == 10))
    letter = myFile.read();
  while (myFile.available() && (letter != 13)) {
    if (letter == '�') {
      letter = 'n' + 125;
    }
    line[idx] = letter;
    letter = myFile.read();
    idx++;
  }
  line[idx] = 0;
  return line;
}

// reads  a catalog file and stores it in the catalog variable
void readFile(char* number) {
  byte index = 0;
  byte len = 0;
  memset(strLine, 0, sizeof(strLine));
  memset(catalog, 0, sizeof(catalog));
  if (fText = SD.open(number)) {
    while ( fText.available() ) {
      leerLinea(fText, strLine);
      len = min(strlen(strLinea), MAX_LONG);
      if ( len > 0 ) {
        strncpy(catalog[indice], strLinea, len);
        indice++;
      }
    }
    fText.close();
    maxEntries = index;
    entryA = -1;
    entry = 0;
    encoderAOn = HIGH;
  }
  else {
    errorCard();
  }
}

// Routine to read the encoder and modify the catalog entry
void leerEncoder() {
  byte n = digitalRead(ENC_A);
  if ((encoderAOn == LOW) && (n == HIGH)) {
    if (digitalRead(ENC_B) == LOW) {
      entrance = max(entrance - 1, 0);
    } else {
      entrance = min(entrance + 1, maxEntradas - 1);
    }
  }
  encoderAOn = n;
}

// Routine to read the encoder and modify the Volume
void readEncoderVol() {
  byte n = digitalRead(ENC_A);
  if ((encoderAOn == LOW) && (n == HIGH)) {
    if (digitalRead(ENC_B) == LOW) {
      vol = min(vol + 5, MIN_VOL);
      MP3player.setVolume(vol, vol);
    } else {
      vol = max(vol - 5, 0);
      MP3player.setVolume(vol, vol);
    }
  }
  encoderAOn = n;
}

void setup() {

  pinMode(9, OUTPUT);
  pinMode(button_FORAWARD, INPUT);
  pinMode(button_BACK, INPUT);
  pinMode(ENC_A, INPUT);
  pinMode(ENC_B, INPUT);
  digitalWrite(ENC_A, HIGH);
  digitalWrite(ENC_B, HIGH);
  digitalWrite(button_FORAWARD, HIGH);
  digitalWrite(button_BACK, HIGH);

  if ( MP3player.initialize() != 0 ) {
    errorCard();
  }

  MP3player.setVolume(vol, vol);

  lcd.begin(16, 4);

  memset(strArtist, 0, MAX_LONGMAS1);
  memset(strArtist, 0, MAX_LONGMAS1);
  memset(strAlbum, 0, MAX_LONGMAS1);

  lcd.createChar(0, bar1);
  lcd.createChar(1, bar2);
  lcd.createChar(2, bar3);
  lcd.createChar(3, bar4);
  lcd.createChar(4, bar5);
  lcd.createChar(5, barV);

  readFile("artist.txt");

}

void printLCD (byte col, byte fila, byte numEntry) {
  if ( numEntry <= maxEntry - 1) {
    char line[MAX_LONGMAS1];
    memset(line, 0, sizeof(line));
    strncpy(line, catalogo[numEntrada], 20 - col);
    lcd.setCursor(col, file);
    lcd.print(line);
  }
}

void showCatalog(byte force) {
  if ( (entrance != entranceA) || force) {
    lcd.clear();
    switch (nivel) {
      case 0:
        lcd.write('z' + 4);
        printLCD (1, 0, entrance);
        printLCD (1, 1, entrance + 1);
        printLCD (1, 2, entrance + 2);
        printLCD (1, 3, entrance + 3);
        break;
      case 1:
        lcd.print(strArtiste);
        lcd.setCursor(0, 1);
        lcd.print(' ');
        lcd.write('z' + 4);
        printLCD (2, 1, entrance);
        printLCD (2, 2, entrance + 1);
        printLCD (2, 3, entrance + 2);
        break;
      case 2:
        lcd.print(strArtist);
        lcd.setCursor(0, 1);
        lcd.print(strAlbum);
        lcd.setCursor(0, 2);
        lcd.print(' ');
        lcd.write('z' + 4);
        printLCD (2, 2, entrance);
        printLCD (2, 3, entrance + 1);
        break;
      case 3:
        lcd.print(strArtist);
        lcd.setCursor(0, 1);
        lcd.print(strAlbum);
        lcd.setCursor(0, 2);
        lcd.print(strTitle);
        break;
    }
    entranceA = entrance;
  }
}

void update(byte foward) {
  byte result;
  switch (level) {
    case 0:
      readFile("artistas.txt");
      if (!foward) {
        entrance = artist - 1;
      }
      break;
    case 1:
      if (forward) {
        artist = entrance + 1;
        strcpy(strArtist, catalog[entrance]);
      }
      sprintf(fileName, "ARTIST%02d/album.txt", artist);
      readFile(fileName);
      if (!forward) {
        entrance = album - 1;
      }
      break;
    case 2:
      if (forward) {
        album = entrance + 1;
        strcpy(strAlbum, catalog[entrance]);
      }
      sprintf(fileName, "ARTIST%02d/ALBUM%02d/track.txt", artist, album);
      readFile(fileName);
      if (!forward) {
        entrance = track - 1;
      }
      break;
    case 3:
      track = entrance + 1;
      strcpy(strTitle, catalog[entrance]);
      sprintf(fileName, "ARTIST%02d/ALBUM%02d/track%03d.mp3", artist, album, track);
      result = MP3player.tocaMP3(fileName);
      if (result == 0) {
        errorCard();
      }
      break;
  }
  showCatalog(true);
}

void loop() {
  if (buttonClick(button_FORAWARD) ) {
    if ( levels < 3) {
      levels++;
      update(1);
    }
    else if (MP3player.isPla()) {
      MP3player.paraMp3();
    }
  }
  if (buttonPulsado(button_BACK) ) {
    if ( MP3player.isPlaying() ) {
      MP3player.forMp3();
    }
    if ( level > 0) {
      level--;
    }
    update(0);
  }
  if ( (level == 3) &&  !MP3player.iisPlaying() ) {
    if ( entrance < maxEntry ) {
      entrance++;
    } else {
      level = 2;
    }
    update(0);
  }
  if (MP3player.isPlaying()) {
    readEncoderVol();
  } else {
    readEncoder();
  }
  showCatalog(false);
  showProgress();
}

i did use the sparkfun mp3 shield library from sparkfun