Index SD Card?!

Hey there...
I have a question. I've been trying to index an SD Card. Bassically my plan is to have a functions which gives me two string arrays, one containing the short names, and one containing the long names.
I found this code

#include <SdFat.h>
SdFat sd;
const uint8_t SD_CS_PIN = SS;
//------------------------------------------------------------------------------
// does not implement directory byte 12 for lowercase bits with 8.3 names.
// bit 0X10 means lowercase extension and bit 0X08 lowercase basename
//
void listLfn(SdBaseFile* dirFile) {
  uint8_t offset[] = {1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30};
  char name[13];
  char lfn[131];
  bool haveLong = false;
  dir_t dir;
  uint8_t i;
  uint8_t lfnIn = 130;
  uint8_t ndir;
  uint8_t sum;
  uint8_t test;

  dirFile->rewind();
  while (dirFile->read(&dir, 32) == 32) {
    if (DIR_IS_LONG_NAME(&dir)) {
      if (!haveLong) {
        if ((dir.name[0] & 0XE0) != 0X40) continue;
        ndir = dir.name[0] & 0X1F;
        test = dir.creationTimeTenths;
        haveLong = true;
        lfnIn = 130;
        lfn[lfnIn] = 0;
      } else if (dir.name[0] != --ndir || test != dir.creationTimeTenths) {
        haveLong = false;
        continue;
      }
      char *p = (char*)&dir;
      if (lfnIn > 0) {
        lfnIn -= 13;
        for (i = 0; i < 13; i++) {
          lfn[lfnIn + i] = p[offset[i]];
        }
      }
    } else if (DIR_IS_FILE_OR_SUBDIR(&dir) 
      && dir.name[0] != DIR_NAME_DELETED 
      && dir.name[0] != DIR_NAME_FREE) {
      if (haveLong) {
        for (sum = i = 0; i < 11; i++) {
           sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + dir.name[i];
        }
        if (sum != test || ndir != 1) haveLong = false;
      }
      SdFile::dirName(dir, name);
      Serial.print(name);
      if (haveLong) {
        Serial.print("  ");
        Serial.print(lfn + lfnIn);
      } else if (dir.reservedNT) {
        Serial.print(" 8.3 lowercase bits: ");
        Serial.print(dir.reservedNT, HEX);
      }
      Serial.println();
      haveLong = false;
    } else {
      if (dir.name[0] == DIR_NAME_FREE) return;
      haveLong = false;
    }
  }
}
//------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  if (!sd.begin(SD_CS_PIN)) sd.initErrorHalt();
  // list files in root directory (volume working directory)
  listLfn(sd.vwd());
  Serial.println("Done");
}
void loop() {}

in this thread How to read full name of a file with SdFat - Storage - Arduino Forum
Which gives me all filenames of the root, but i need a funtion that i can call in the setup that would write the paths of all files to two array (short path array, and long path array), and i just can't get it figured out. The problem is i don't fully understand the code from that thread, which wouldn't be to much of an issue as long as it would work... :slight_smile:
Anyhow, why i need to index the card, is because i'm trying to build an mp3 player which this shield SparkFun MP3 Player Shield - DEV-12660 - SparkFun Electronics and i don't want to have to name all the mp3 files "track1.mp3, track2.mp3, track3.mp3, etc." or similar. I want it to play whatever supported audiofiles it can find, and it should also be able to display the filename (the long one of course).
And so far it plays music just fine, but it doesn't play files that don't follow a certain "name rule", which is not the idea...

Anyhow, any help would be appriciated!
Thanks in advance!

Regards,
Delphiño

What board are you using this with? You need to bear in mind that storing an array of paths could take more memory than you have...

Are you sure that this is the way you really want to do it?

I assume the SD card will be set up on some other device and just installed in the Arduino to provide it with the tracks.

In that case I suggest that you include a text file on the card which contains display name / file name pairs. You could do that quite easily by putting each mapping on a separate line (terminated by a newline) and encode it as filename;display name. To avoid trying to hold lots of data in memory, only process the mapping file at the point you need to actually display the display name and design your sketch so that you process the whole file just by reading through it line by line and processing each line as you read it. You can use strtok() to separate the filename and display name parts from each mapping line.

Thanks for the responces!
Yes, i already considered the memory problem. But i thought i'd just get it to work this way first, and see more or less how many files the Arduino can handle before it runs out of memory. And if i can't find any better solution i would try to index the sd card and save it to a index file on the sd card itself. But i would like to try to avoid writing to the sd card, to avoid problems when suddently removing the sd card.
I don't want to have to preload an index file to the sd card so the arduino can handle it, because that would make it to complicated to just add/remove/rename a few tracks. It's fairly essential that the arduino can manage the files itself.
I'm using an Arduino Uno right now because it makes it easy to test (since the shield is for an uno), but i may end up using an Arduino Mega, or maybe even an Arduino Due (although a Due may not even need the mp3 decoder) if there is no other way to handle the data efficiently enough.
My plan is to take a simple Standalove Audio Amplifier, and be able to play music from an sd card (without having to connect it to some kind of source).
The shield just buffers 32bytes of the file, that get sent by the arduino. The SD card is only accessed by the arduino. I'm using this shield because i wanted to have full access to header information of the track currently being played.
Anyhow, it's fairly important that it can deal with an sd card with randomly named mp3 files and no index files of any kind...
I could try and only index the short names, but that way i couldn't display the name of the actual mp3 file being played.

Is anyone able to write a function that would index the sd card (regardless of if the memory would be sufficient), or could anyone at least point me in the right direction?
I think i can handle all the rest myself, for now i only need the short and long paths of all files (not only mp3 files, and not only the files in the root).

Thanks for your time! :slight_smile:

Well, there's two main ways of doing it. You have the basics there with that function - it gets the files and directories for a given folder. The simplest, though most memory intensive, way of expanding it would be to use recursion - whenever it finds a directory in its list, instead of just adding it to the array, it calls the same function again but with the directory as its parameter. You may want to expand the function to take a path prefix to prepend to the names for you.

The better way would be to do it iteratively, where you maintain a stack of directories to scan, and whenever you find a directory you push it onto the stack, then when the current directory is finished you pop a folder off the stack and scan that. Uses less memory that recursion, but is harder to program.

If you don't want to write the index file yourself, then where are the display names going to come from?