Final Project Code - Saulnier


/*

 * example sketch to play audio file(s) in a directory, using the mp3 library

 * for playback and the arduino sd library to read files from a microsd card.

 * pins are setup to work well for teensy 2.0. double-check if using arduino.

 * 

 * originally based on frank zhao's player: http://frank.circleofcurrent.com/

 * utilities adapted from previous versions of the functions by matthew seal.

 *

 * (c) 2011 david sirkin sirkin@cdr.stanford.edu

 *          akil srinivasan akils@stanford.edu

 */

 

// check that the microsd card is present, can be initialized and has a valid

// root volume. a pointer to the card's root object is returned as sd_root.

 

void sd_card_setup() {

  if (!SD.begin(sd_cs)) {

    Serial.println("Card failed, or isn't present.");

    return;

  }

  if (!card.init(SPI_HALF_SPEED, sd_cs)) {

    Serial.println("Card found, but initialization failed.");

    return;

  }

  if (!volume.init(card)) {

    Serial.println("Initialized, but couldn't find partition.");

    return;

  }

  if (!sd_root.openRoot(&volume)) {

    Serial.println("Partition found, but couldn't open root");

    return;

  }

}

 

// for each song file in the current directory, store its file name in eeprom

// for later retrieval. this saves on using program memory for the same task,

// which is helpful as you add more functionality to the program.

 

void sd_dir_setup() {

  dir_t p;

  num_songs = 0;

 

  sd_root.rewind();

 

  while (sd_root.readDir(&p) > 0 && num_songs < max_num_songs) {

    // break out of while loop when we wrote all files (past the last entry).

 

    if (p.name[0] == DIR_NAME_FREE) {

      break;

    }

 

    // only store current (not deleted) file entries, and ignore the . and ..

    // sub-directory entries. also ignore any sub-directories.

 

    if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.' || !DIR_IS_FILE(&p)) {

      continue;

    }

 

    // only store mp3 or wav files in eeprom (for now). if you add other file

    // types, you should add their extension here.

 

    // it's okay to hard-code the 8, 9 and 10 as indices here, since SdFatLib

    // pads shorter file names with a ' ' to fill 8 characters. the result is

    // that file extensions are always stored in the last 3 positions.

 

    if ((p.name[8] == 'M' && p.name[9] == 'P' && p.name[10] == '3') ||

        (p.name[8] == 'W' && p.name[9] == 'A' && p.name[10] == 'V')) {

 

      // store each character of the file name into an individual byte in the

      // eeprom. sd_file->name doesn't return the '.' part of the name, so we

      // add that back later when we read the file from eeprom.

 

      unsigned char pos = 0;

 

      for (unsigned char i = 0; i < 11; i++) {

        if (p.name[i] != ' ') {

          EEPROM.write(num_songs * max_name_len + pos, p.name[i]);

          pos++;

        }

      }

 

      // add an 'end of string' character to signal the end of the file name.

 

      EEPROM.write(num_songs * max_name_len + pos, '\0');

      num_songs++;

 

      // seed the start number

      EEPROM.write(num_songs * max_name_len - 1  , 127);

    }

  }

}

 

// given the numerical index of a particular song to play, go to its location

// in eeprom, retrieve its file name and set the global variable 'fn' to it.

 

void map_current_song_to_fn() {

  int fnln = max_name_len;

 

  // based on the current_song index, get song's name and length from eeprom.

 

  for (int i = 0; i < max_name_len - 1; i++) {

    fn[i] = EEPROM.read(current_song * max_name_len + i);

 

    // break if we reach the end of the file name, or if we have a directory.

    // keep track of the file name length (fnln), so we can put the '.' back.

 

    if (fn[i] == '\0') {

      fnln = i;

      i = max_name_len;

      break;

    }

    else

    if (fn[i] == '/') {

      fn[0] = '\0';

      fnln = 0;

      i = max_name_len;

      break;

    }

  }

 

  // now restore the '.' that sd_file->name didn't store in its array for us.

 

  if (fnln > 4) {

    fn[fnln + 1] = '\0';

    fn[fnln]     = fn[fnln - 1];

    fn[fnln - 1] = fn[fnln - 2];

    fn[fnln - 2] = fn[fnln - 3];

    fn[fnln - 3] = '.';

  }

}

 

Song_Utilities:

 

/*

 * example sketch to play audio file(s) in a directory, using the mp3 library

 * for playback and the arduino sd library to read files from a microsd card.

 * pins are setup to work well for teensy 2.0. double-check if using arduino.

 * 

 * originally based on frank zhao's player: http://frank.circleofcurrent.com/

 * utilities adapted from previous versions of the functions by matthew seal.

 *

 * (c) 2011 david sirkin sirkin@cdr.stanford.edu

 *          akil srinivasan akils@stanford.edu

 */

 

// check that the microsd card is present, can be initialized and has a valid

// root volume. a pointer to the card's root object is returned as sd_root.

 

void sd_card_setup() {

  if (!SD.begin(sd_cs)) {

    Serial.println("Card failed, or isn't present.");

    return;

  }

  if (!card.init(SPI_HALF_SPEED, sd_cs)) {

    Serial.println("Card found, but initialization failed.");

    return;

  }

  if (!volume.init(card)) {

    Serial.println("Initialized, but couldn't find partition.");

    return;

  }

  if (!sd_root.openRoot(&volume)) {

    Serial.println("Partition found, but couldn't open root");

    return;

  }

}

 

// for each song file in the current directory, store its file name in eeprom

// for later retrieval. this saves on using program memory for the same task,

// which is helpful as you add more functionality to the program.

 

void sd_dir_setup() {

  dir_t p;

  num_songs = 0;

 

  sd_root.rewind();

 

  while (sd_root.readDir(&p) > 0 && num_songs < max_num_songs) {

    // break out of while loop when we wrote all files (past the last entry).

 

    if (p.name[0] == DIR_NAME_FREE) {

      break;

    }

 

    // only store current (not deleted) file entries, and ignore the . and ..

    // sub-directory entries. also ignore any sub-directories.

 

    if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.' || !DIR_IS_FILE(&p)) {

      continue;

    }

 

    // only store mp3 or wav files in eeprom (for now). if you add other file

    // types, you should add their extension here.

 

    // it's okay to hard-code the 8, 9 and 10 as indices here, since SdFatLib

    // pads shorter file names with a ' ' to fill 8 characters. the result is

    // that file extensions are always stored in the last 3 positions.

 

    if ((p.name[8] == 'M' && p.name[9] == 'P' && p.name[10] == '3') ||

        (p.name[8] == 'W' && p.name[9] == 'A' && p.name[10] == 'V')) {

 

      // store each character of the file name into an individual byte in the

      // eeprom. sd_file->name doesn't return the '.' part of the name, so we

      // add that back later when we read the file from eeprom.

 

      unsigned char pos = 0;

 

      for (unsigned char i = 0; i < 11; i++) {

        if (p.name[i] != ' ') {

          EEPROM.write(num_songs * max_name_len + pos, p.name[i]);

          pos++;

        }

      }

 

      // add an 'end of string' character to signal the end of the file name.

 

      EEPROM.write(num_songs * max_name_len + pos, '\0');

      num_songs++;

 

      // seed the start number

      EEPROM.write(num_songs * max_name_len - 1  , 127);

    }

  }

}

 

// given the numerical index of a particular song to play, go to its location

// in eeprom, retrieve its file name and set the global variable 'fn' to it.

 

void map_current_song_to_fn() {

  int fnln = max_name_len;

 

  // based on the current_song index, get song's name and length from eeprom.

 

  for (int i = 0; i < max_name_len - 1; i++) {

    fn[i] = EEPROM.read(current_song * max_name_len + i);

 

    // break if we reach the end of the file name, or if we have a directory.

    // keep track of the file name length (fnln), so we can put the '.' back.

 

    if (fn[i] == '\0') {

      fnln = i;

      i = max_name_len;

      break;

    }

    else

    if (fn[i] == '/') {

      fn[0] = '\0';

      fnln = 0;

      i = max_name_len;

      break;

    }

  }

 

  // now restore the '.' that sd_file->name didn't store in its array for us.

 

  if (fnln > 4) {

    fn[fnln + 1] = '\0';

    fn[fnln]     = fn[fnln - 1];

    fn[fnln - 1] = fn[fnln - 2];

    fn[fnln - 2] = fn[fnln - 3];

    fn[fnln - 3] = '.';

  }

}