diff options
author | Dave Chapman <dave@dchapman.com> | 2005-06-14 23:12:34 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2005-06-14 23:12:34 +0000 |
commit | 5b9eb29d123baebd5927b50d7a2675d540530902 (patch) | |
tree | 134615cb24f67222a568aa8fd7e07f1e6395964a | |
parent | 3ad485b15a51e92a23540429b64e89656555bba6 (diff) |
Add A52/AC3 metadata parsing (samplerate, bitrate, track length)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6715 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/metadata.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/apps/metadata.c b/apps/metadata.c index 35ed900efb..a4b373c716 100644 --- a/apps/metadata.c +++ b/apps/metadata.c @@ -69,12 +69,26 @@ int probe_file_format(const char *filename) } +unsigned short a52_bitrates[]={32,40,48,56,64,80,96, + 112,128,160,192,224,256,320, + 384,448,512,576,640}; + +/* Only store frame sizes for 44.1KHz - others are simply multiples + of the bitrate */ +unsigned short a52_441framesizes[]= + {69*2,70*2,87*2,88*2,104*2,105*2,121*2,122*2, + 139*2,140*2,174*2,175*2,208*2,209*2,243*2,244*2, + 278*2,279*2,348*2,349*2,417*2,418*2,487*2,488*2, + 557*2,558*2,696*2,697*2,835*2,836*2,975*2,976*2, + 1114*2,1115*2,1253*2,1254*2,1393*2,1394*2}; + /* Get metadata for track - return false if parsing showed problems with the file that would prevent playback. */ bool get_metadata(struct track_info* track, int fd, const char* trackname, bool v1first) { unsigned long totalsamples,bytespersample,channels,bitspersample,numbytes; + int bytesperframe; unsigned char* buf; int i,j,eof; int rc; @@ -331,6 +345,62 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname, track->taginfo_ready = true; break; + case AFMT_A52: + /* Use the trackname part of the id3 structure as a temporary buffer */ + buf=track->id3.path; + + lseek(fd, 0, SEEK_SET); + + /* We just need the first 5 bytes */ + rc = read(fd, buf, 5); + if (rc < 5) { + return false; + } + + if ((buf[0]!=0x0b) || (buf[1]!=0x77)) { + logf("%s is not an A52/AC3 file\n",trackname); + return false; + } + + i = buf[4]&0x3e; + if (i > 36) { + logf("A52: Invalid frmsizecod: %d\n",i); + return false; + } + track->id3.bitrate=a52_bitrates[i>>1]; + + track->id3.vbr=false; + track->id3.filesize = filesize (fd); + + switch (buf[4]&0xc0) { + case 0x00: + track->id3.frequency=48000; + bytesperframe=track->id3.bitrate*2*2; + break; + case 0x40: + track->id3.frequency=44100; + bytesperframe=a52_441framesizes[i]; + break; + case 0x80: + track->id3.frequency=32000; + bytesperframe=track->id3.bitrate*3*2; + break; + default: + logf("A52: Invalid samplerate code: 0x%02x\n",buf[4]&0xc0); + return false; + break; + } + + /* One A52 frame contains 6 blocks, each containing 256 samples */ + totalsamples=(track->filesize/bytesperframe)*6*256; + + track->id3.length=(totalsamples/track->id3.frequency)*1000; + + lseek(fd, 0, SEEK_SET); + strncpy(track->id3.path,trackname,sizeof(track->id3.path)); + track->taginfo_ready = true; + break; + /* If we don't know how to read the metadata, just store the filename */ default: strncpy(track->id3.path,trackname,sizeof(track->id3.path)); |