diff options
Diffstat (limited to 'apps')
-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) | |||
69 | 69 | ||
70 | } | 70 | } |
71 | 71 | ||
72 | unsigned short a52_bitrates[]={32,40,48,56,64,80,96, | ||
73 | 112,128,160,192,224,256,320, | ||
74 | 384,448,512,576,640}; | ||
75 | |||
76 | /* Only store frame sizes for 44.1KHz - others are simply multiples | ||
77 | of the bitrate */ | ||
78 | unsigned short a52_441framesizes[]= | ||
79 | {69*2,70*2,87*2,88*2,104*2,105*2,121*2,122*2, | ||
80 | 139*2,140*2,174*2,175*2,208*2,209*2,243*2,244*2, | ||
81 | 278*2,279*2,348*2,349*2,417*2,418*2,487*2,488*2, | ||
82 | 557*2,558*2,696*2,697*2,835*2,836*2,975*2,976*2, | ||
83 | 1114*2,1115*2,1253*2,1254*2,1393*2,1394*2}; | ||
84 | |||
72 | /* Get metadata for track - return false if parsing showed problems with the | 85 | /* Get metadata for track - return false if parsing showed problems with the |
73 | file that would prevent playback. */ | 86 | file that would prevent playback. */ |
74 | 87 | ||
75 | bool get_metadata(struct track_info* track, int fd, const char* trackname, | 88 | bool get_metadata(struct track_info* track, int fd, const char* trackname, |
76 | bool v1first) { | 89 | bool v1first) { |
77 | unsigned long totalsamples,bytespersample,channels,bitspersample,numbytes; | 90 | unsigned long totalsamples,bytespersample,channels,bitspersample,numbytes; |
91 | int bytesperframe; | ||
78 | unsigned char* buf; | 92 | unsigned char* buf; |
79 | int i,j,eof; | 93 | int i,j,eof; |
80 | int rc; | 94 | int rc; |
@@ -331,6 +345,62 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname, | |||
331 | track->taginfo_ready = true; | 345 | track->taginfo_ready = true; |
332 | break; | 346 | break; |
333 | 347 | ||
348 | case AFMT_A52: | ||
349 | /* Use the trackname part of the id3 structure as a temporary buffer */ | ||
350 | buf=track->id3.path; | ||
351 | |||
352 | lseek(fd, 0, SEEK_SET); | ||
353 | |||
354 | /* We just need the first 5 bytes */ | ||
355 | rc = read(fd, buf, 5); | ||
356 | if (rc < 5) { | ||
357 | return false; | ||
358 | } | ||
359 | |||
360 | if ((buf[0]!=0x0b) || (buf[1]!=0x77)) { | ||
361 | logf("%s is not an A52/AC3 file\n",trackname); | ||
362 | return false; | ||
363 | } | ||
364 | |||
365 | i = buf[4]&0x3e; | ||
366 | if (i > 36) { | ||
367 | logf("A52: Invalid frmsizecod: %d\n",i); | ||
368 | return false; | ||
369 | } | ||
370 | track->id3.bitrate=a52_bitrates[i>>1]; | ||
371 | |||
372 | track->id3.vbr=false; | ||
373 | track->id3.filesize = filesize (fd); | ||
374 | |||
375 | switch (buf[4]&0xc0) { | ||
376 | case 0x00: | ||
377 | track->id3.frequency=48000; | ||
378 | bytesperframe=track->id3.bitrate*2*2; | ||
379 | break; | ||
380 | case 0x40: | ||
381 | track->id3.frequency=44100; | ||
382 | bytesperframe=a52_441framesizes[i]; | ||
383 | break; | ||
384 | case 0x80: | ||
385 | track->id3.frequency=32000; | ||
386 | bytesperframe=track->id3.bitrate*3*2; | ||
387 | break; | ||
388 | default: | ||
389 | logf("A52: Invalid samplerate code: 0x%02x\n",buf[4]&0xc0); | ||
390 | return false; | ||
391 | break; | ||
392 | } | ||
393 | |||
394 | /* One A52 frame contains 6 blocks, each containing 256 samples */ | ||
395 | totalsamples=(track->filesize/bytesperframe)*6*256; | ||
396 | |||
397 | track->id3.length=(totalsamples/track->id3.frequency)*1000; | ||
398 | |||
399 | lseek(fd, 0, SEEK_SET); | ||
400 | strncpy(track->id3.path,trackname,sizeof(track->id3.path)); | ||
401 | track->taginfo_ready = true; | ||
402 | break; | ||
403 | |||
334 | /* If we don't know how to read the metadata, just store the filename */ | 404 | /* If we don't know how to read the metadata, just store the filename */ |
335 | default: | 405 | default: |
336 | strncpy(track->id3.path,trackname,sizeof(track->id3.path)); | 406 | strncpy(track->id3.path,trackname,sizeof(track->id3.path)); |