5

I am currently working on a project that plays music for you. My question for this thread is, is it possible to retrieve the names of the songs within the micro SD card that is inserted into the shield?

Currently I am renaming the song files to track001, track002, track003, etc. As can be seen in the following code:

const int arraySize = 5;
char songs[arraySize][15] =
{
  {"track001.mp3"},
  {"track002.mp3"},
  {"track003.mp3"},
  {"track004.mp3"},
  {"track005.mp3"}
};

That is how am I currently playing music with this shield. I am not too happy with this as I would like to be able to insert different micro SD cards into the shield without having to rename them to track00X or without having to change the code every time to match the song names.

So, is it possible to code it to retrieve the song names from the SD card instead of having to specify their name in the code?

Below you can see my full code:

#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

#define BREAKOUT_RESET  9      // VS1053 reset pin (output)
#define BREAKOUT_CS     10     // VS1053 chip select pin (output)
#define BREAKOUT_DCS    8      // VS1053 Data/command select pin (output)

#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

#define CARDCS 4     // Card chip select pin
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

Adafruit_VS1053_FilePlayer musicPlayer = Adafruit_VS1053_FilePlayer(SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);

int volume = 20;
const int arraySize = 5;
char songs[arraySize][15] =
{
  {"track001.mp3"},
  {"track002.mp3"},
  {"track003.mp3"},
  {"track004.mp3"},
  {"track005.mp3"}
};

int songNumber = 0;

void setup()
{
  Serial.begin(9600);
  musicPlayer.begin();
  SD.begin(CARDCS);
  musicPlayer.setVolume(volume, volume);
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);
}

void loop()
{
  // Lower Volume
  if (musicPlayer.GPIO_digitalRead(7) == HIGH)
  {
    if (volume < 70)
    {
      volume = volume + 1;
      musicPlayer.setVolume(volume, volume);
      delay(50);
    }
  }

  // Increase Volume
  if (musicPlayer.GPIO_digitalRead(6) == HIGH)
  {
    if (volume > 0)
    {
      volume = volume - 1;
      musicPlayer.setVolume(volume, volume);
      delay(50);
    }
  }

  // Start Music Player
  if (musicPlayer.GPIO_digitalRead(5) == HIGH)
  {
    if (! musicPlayer.playingMusic)
    {
      musicPlayer.startPlayingFile(songs[songNumber]);
    }
  }

  // Pause / Resume
  if (musicPlayer.GPIO_digitalRead(4) == HIGH)
  {
    if (! musicPlayer.paused())
    {
      musicPlayer.pausePlaying(true);
    }
    else
    {
      musicPlayer.pausePlaying(false);
    }
    delay(500);
  }

  // Prev Song
  if (musicPlayer.GPIO_digitalRead(3) == HIGH)
  {
    if (songNumber - 1 >= 0)
    {
      songNumber = songNumber - 1;
    }
    else
    {
      songNumber = arraySize - 1;
    }
    Serial.println(songNumber);
    musicPlayer.startPlayingFile(songs[songNumber]);

    delay(500);
  }

  // Next Song
  if (musicPlayer.GPIO_digitalRead(2) == HIGH)
  {
    if (songNumber + 1 < arraySize)
    {
      songNumber = songNumber + 1;
    }
    else
    {
      songNumber = 0;
    }
    Serial.println(songNumber);
    musicPlayer.startPlayingFile(songs[songNumber]);
    delay(500);
  }
}

If this is possible and someone reading this knows how to do so, I would truly appreciate it if you explained it to me and even provided an example or even edit my own code if you want. Thank you! :)

1

The adafruit library was is similar to the prior SFEMP3shield library (disclosure I am the main author of that). That said either library can work on either Adafruit or SFE shield or breakout board. AdaFruit's library is cleaner re-write. But in doing so it is minimal in its functions. The SFE library demonstrates many more features of the VS1053 chip.

That said; the ./Example/fileplayer.ino does exactly what you are asking. The directory command lists out the files with an enumerating number. Entering 0[number] plays that file. This is how I broke away from "track###.mp3", without having to implement a command prompt parser. And it also allows other file formats.

The bulk of this feature is in the LOOP() and not in the constrained to the library. So one can cut and paste it into a sketch using the Adafruit library in place of the SFEMP3 or any sketch with an SdCard. That said it would actually be easier to replace the play file calls and include in the FilePlayer.ino example. Or just use it straight up.

The SFEmp3 library is bit overwhelming because it supports so many features of the VS1053. And uses a different SdCard library, which is more upto date than the IDE's SD". While the Adafruit library is a very nice re-write and cleans much hte confusing #define's making it much easier code to read, it is not as feature rich. But most feature beyond play and stop are not really needed.

Good luck.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.