summaryrefslogtreecommitdiff
path: root/apps/metadata.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/metadata.c')
-rw-r--r--apps/metadata.c70
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
72unsigned 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 */
78unsigned 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
75bool get_metadata(struct track_info* track, int fd, const char* trackname, 88bool 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));