0

I'm using an Adafruit Music Maker with a TFT screen on my Mega 2560. I can pull ID3v1 data from the end of an MP3, but I'd like to get the ID3v2 data as I can then push the album cover art to the TFT along with the title/artist/album/etc.

My initial searches have turned up nothing for a library that pulls the ID3v2 headers. Before I start to crack that nut on my own, I want to make sure I am not overlooking something.

Has anyone used a library to pull ID3v2 data from an MP3?

2 Answers 2

1

Here's what I have written so far. This pulls data from the ID3v2 header at the start of the mp3 file.

void frameInfo(File track, char tvalue[64], char albval[64], char artval[64], 
char fname[30], bool showpic) {
uint32_t start = 10;
uint32_t lastfrm = 10;
bool done = false;

track.getName(fname,max_chars);

while (!done) {
 uint8_t buff[4];
 uint32_t ltwo[4];
 char tag[5];
 uint32_t fsize;
 track.seek(start);
 track.read((uint8_t *)tag, 4);
 tag[5] = 0;

 track.seek(start + 4);
 track.read((uint8_t *)buff,4); 
 ltwo[0] = buff[0];
 ltwo[1] = buff[1];
 ltwo[2] = buff[2];
 ltwo[3] = buff[3];

 fsize = (ltwo[0] << 24) | (ltwo[1] << 16) | (ltwo[2] << 8) | ltwo[3];
 start = start + 10;

if (tag[0] == 'T' && tag[1] == 'I' && tag[2] == 'T' && tag[3] == '2') {
  uint32_t i;
  int vlen = 0;
  char val[fsize];

  track.seek(start);
  track.read((uint8_t *)val, fsize);
  for (i=0;i<fsize;i++) {
    if (isAlphaNumeric(val[i])) {
      tvalue[vlen] = val[i];
      vlen++;
    }
    else if (val[i] == '(' || val[i] == ')' || val[i] == ' ') {
      tvalue[vlen] = val[i];
      vlen++;
    }      
  }
  tvalue[vlen] = '\0';
}
else if (tag[0] == 'T' && tag[1] == 'A' && tag[2] == 'L' && tag[3] == 'B') {
  uint32_t i;
  int vlen = 0;
  char val[fsize];

  track.seek(start);
  track.read((uint8_t *)val, fsize);
  for (i=0;i<fsize;i++) {
    if (isAlphaNumeric(val[i])) {
      albval[vlen] = val[i];
      vlen++;
    }
    else if (val[i] == '(' || val[i] == ')' || val[i] == ' ') {
      albval[vlen] = val[i];
      vlen++;
    }      
  }
  albval[vlen] = '\0';
}
else if (tag[0] == 'T' && tag[1] == 'P' && tag[2] == 'E' && tag[3] == '1') {
  uint32_t i;
  int vlen = 0;
  char val[fsize];

  track.seek(start);
  track.read((uint8_t *)val, fsize);
  for (i=0;i<fsize;i++) {
    if (isAlphaNumeric(val[i])) {
      artval[vlen] = val[i];
      vlen++;
    }
    else if (val[i] == '(' || val[i] == ')' || val[i] == ' ') {
      artval[vlen] = val[i];
      vlen++;
    }      
  }
  artval[vlen] = '\0';
}

else if (tag[0] == 'A' && tag[1] == 'P' && tag[2] == 'I' && tag[3] == 'C') {
  uint32_t i;
  int vlen = 0;
  char val[30];
  char test[30];
  uint8_t raw[fsize - 11];

  track.seek(start);
  track.read((uint8_t *)val, 11);
  for (i=0;i<11;i++) {
    if (isAlphaNumeric(val[i])) {
      test[vlen] = val[i];
      vlen++;
    }
    else if (val[i] == '(' || val[i] == ')' || val[i] == ' ') {
      test[vlen] = val[i];
      vlen++;
    }      
  }
  test[vlen] = '\0';

  if (fsize < 200000) {
    track.seek(start+11);
    Serial.println(fsize+11);
    //track.read((uint8_t *)pic, fsize-11);
  }
  
  
}
else {

}

start = start + fsize;
if ((start == lastfrm + 10) || start > musicPlayer.mp3_ID3Jumper(track)) {
  done = true;
}
else {
  lastfrm = start;
}

}
track.rewind();
}

This pulls the text data for title/artist/album, but the problem is how to read the image from the header without overloading the Mega. Most of the images are around 30K bytes, but there is no room in RAM on the Mega for that kind of space. I have my sketch set to read the jpeg format, convert it to BMP, then write it to the TFT. Is there some method I could use to have the sketch write the bytes to a file on the SD card, then read them from there?

-1

There is an SD library meant for use with the VS1053 which has some extra id3 tag support. Check it out here : https://github.com/mpflaga/Arduino_Library-vs1053_for_SdFat

1
  • 1
    I did find that, but it only reads ID3v1 tags, which are at the end of the file and only contain the artist/title/album information. Commented Jan 21, 2022 at 2:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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