This email from Henrik Herranen at VLSI explains why I had problems with some songs that wouldn't play with the VS1001 chip.

/Jesper



The song 4_Non_Blondes_-_What_s_Going_On.mp3 starts with the following
bytes (big-endian bytes, i.e. bytes are in correct order (which is
different from many little-endian PC hexdumpers)):

offset  0 1  2 3  4 5  6 7  8 9  a b  c d  e f
0x0000 0000 0020 0000 0002 0000 ac44 0002 7100
0x0010 0000 0571 00c9 987c ffff ffff ffff ffff
0x0020 0002 0002 fffb a044 0000 0002 002b 8000
0x0030 0000 0000 0570 0000 0017 7a0c ae14 f480

The first actual MP3 header is the "0xFFFBA044" at offset 0x24. However,
a valid MP1 header "0xFFFF0002" is already at 0x1E! The problem is that
the encoder incorrectly puts some kind of a header of its own before the
MP3 file, and also puts several "0xFF" bytes before actual MP3 data. This
is always VERY DANGEROUS, because any byte sequences with an 0xFF byte
followed by a byte of 0xFn (where n is any value), may be interpreted
as an MP1, MP2 or MP3 header.

This particular header probably won't mess up other MP3 players, because
they don't support MP1. Thus, they don't make a miss-recognition.
However, if I try to play this broken file with  MPG123 0.59r (which also
has MP1 support), I get the following output:

Playing MPEG stream from 4_Non_Blondes_-_What_s_Going_On.mp3 ...
Junk at the beginning 00000020
Free format not supported: (head ffff0002)
Junk at the beginning 0002fffb
MPEG 1.0 layer I, 320 kbit/s, 44100 Hz joint-stereo
Illegal Audio-MPEG-Header 0xb1c9bde6 at offset 0x180.
Skipped 174 bytes in input.
Illegal Audio-MPEG-Header 0xa59abbec at offset 0x38e.
Skipped 171 bytes in input.
[etc etc etc until mpg123 gives up]

Notice that mpg123 thinks this is MPEG 1.0 layer I, in other words MP1
(MP3 is layer 3).


So, what are the solutions to this problem? The long-term solution is to
contact the writer of the broken encoder and tell that if it really is
necessary to put one's own headers, never use 0xFF bytes!

A mid-long term solution is to add stripping of this particular header
to the Windows driver when an MP3 file is written to the MMC (i.e. any
file that starts with 0x0 0x0 0x0 0x2 would be stripped). This, of
course, may again result in some files being treated accidentally and
is not a very nice and universal way, especially if we want later to be
able to also copy files _from_ the player back to the PC side.

A short-term solution is to strip by hand the first 0x24 bytes from the
file (everything before 0xFFFBA044). With the emacs editor this can be
done in just a few seconds very easily (search for the first occurance
of either \377\373 or \377\372 and remove anything before that), without
emacs you may have to write a very short program to do the same. The
program would be as follows (error checking should be added):

#include 
#include 

int main(void) {
  FILE *inFP = fopen("broken.mp3", "rb");
  FILE *outFP = fopen("correct.mp3", "wb");
  int c=0, d=0;

  /* Find first valid MP3 header */
  while (c!=0xff || (d&0xfe) != 0xfa) {
    c = d;
    d = fgetc(inFP);
    if (d < 0)
      exit(EXIT_FAILURE);
  }

  /* After header is found, copy rest of the file as-is */
  fputc(c, outFP);
  fputc(d, outFP);
  while ((c = fgetc(inFP)) >= 0)
    fputc(c, outFP);

  fclose(inFP);
  fclose(outFP);

  return EXIT_SUCCESS;
}

Note that this program solves this particular problem, but may again fail
with some other kinds of bad (or even correct) MP3 files. To make a
program that always works, one should know the header format better (what
header format is this? how to recognize it unambiguously? etc).

Kind regards,
- Henrik Herranen