From 2e525fe9eda0a160612fba53d22f3719af2ec168 Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Wed, 3 Jul 2002 21:04:09 +0000 Subject: Added Xing VBR frame parsing git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1324 a1c6a512-1295-4272-9138-f99709370657 --- firmware/id3.c | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/firmware/id3.c b/firmware/id3.c index c913404ae3..4a40ff89d9 100644 --- a/firmware/id3.c +++ b/firmware/id3.c @@ -366,8 +366,12 @@ getid3v1len(int fd) static int getsonglength(int fd, struct mp3entry *entry) { + unsigned int filetime = 0; unsigned long header=0; unsigned char tmp; + unsigned char frame[200]; + unsigned int framecount; + int version; int layer; int bitindex; @@ -402,7 +406,7 @@ getsonglength(int fd, struct mp3entry *entry) /* * Some files are filled with garbage in the beginning, * if the bitrate index of the header is binary 1111 - * that is a good is a good indicator + * that is a good indicator */ if((header & 0xF000) == 0xF000) goto restart; @@ -481,12 +485,39 @@ getsonglength(int fd, struct mp3entry *entry) /* Calculate time per frame */ tpf = bs[layer] / freqtab[version-1][freqindex] << (version - 1); + + /* OK, we have found a frame. Let's see if it has a Xing header */ + if(read(fd, frame, 200) < 0) + return -1; - /* - * Now song length is - * ((filesize)/(bytes per frame))*(time per frame) - */ - return entry->filesize/bpf*tpf; + if(frame[32] == 'X' && + frame[33] == 'i' && + frame[34] == 'n' && + frame[35] == 'g') + { + if(frame[39] & 0x01) /* Is the frame count there? */ + { + framecount = (frame[40] << 24) | (frame[41] << 16) | + (frame[42] << 8) | frame[43]; + + filetime = framecount * tpf; + } + /* We don't care about the file size and the TOC just yet. Maybe + another time. */ + } + + /* If the file time hasn't been established, this may be a fixed + rate MP3, so just use the default formula */ + if(filetime == 0) + { + /* + * Now song length is + * ((filesize)/(bytes per frame))*(time per frame) + */ + filetime = entry->filesize/bpf*tpf; + } + + return filetime; } -- cgit v1.2.3