summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2005-06-09 00:23:50 +0000
committerDave Chapman <dave@dchapman.com>2005-06-09 00:23:50 +0000
commit1971ee6765220872d4ba233557af441481a96882 (patch)
tree634bedac30ee31740378a1ddf896d362e91e739a
parent2d8e7f20d469e2e069afa5979430f9d1bcfe72dc (diff)
downloadrockbox-1971ee6765220872d4ba233557af441481a96882.tar.gz
rockbox-1971ee6765220872d4ba233557af441481a96882.zip
Parse the metadata in a FLAC file to populate the "id3" struct (currently only length, samplerate etc)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6627 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/playback.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/apps/playback.c b/apps/playback.c
index 87287e57ab..3a9f229e15 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -572,6 +572,9 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
572 off_t size; 572 off_t size;
573 int rc, i; 573 int rc, i;
574 int copy_n; 574 int copy_n;
575 /* Used by the FLAC metadata parser */
576 unsigned long totalsamples;
577 unsigned char* buf;
575 578
576 if (track_count >= MAX_TRACK) 579 if (track_count >= MAX_TRACK)
577 return false; 580 return false;
@@ -638,6 +641,70 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
638 tracks[track_widx].taginfo_ready = true; 641 tracks[track_widx].taginfo_ready = true;
639 break ; 642 break ;
640 643
644 case AFMT_FLAC:
645 /* A simple parser to read vital metadata from a FLAC file - length, frequency, bitrate etc. */
646 /* This code should either be moved to a seperate file, or discarded in favour of the libFLAC code */
647 /* The FLAC stream specification can be found at http://flac.sourceforge.net/format.html#stream */
648
649 /* Use the trackname part of the id3 structure as a temporary buffer */
650 buf=tracks[track_widx].id3.path;
651
652 lseek(fd, 0, SEEK_SET);
653
654 rc = read(fd, buf, 4);
655 if (rc < 4) {
656 close(fd);
657 return false;
658 }
659
660 if (memcmp(buf,"fLaC",4)!=0) {
661 logf("%s is not a FLAC file\n",trackname);
662 close(fd);
663 return(false);
664 }
665
666 while (1) {
667 rc = read(fd, buf, 4);
668 i = (buf[1]<<16)|(buf[2]<<8)|buf[3]; /* The length of the block */
669
670 if ((buf[0]&0x7f)==0) { /* 0 is the STREAMINFO block */
671 rc = read(fd, buf, i); /* FIXME: Don't trust the value of i */
672 if (rc < 0) {
673 close(fd);
674 return false;
675 }
676 tracks[track_widx].id3.vbr=true; /* All FLAC files are VBR */
677 tracks[track_widx].id3.filesize=filesize(fd);
678
679 tracks[track_widx].id3.frequency=(buf[10]<<12)|(buf[11]<<4)|((buf[12]&0xf0)>>4);
680
681 /* NOT NEEDED: bitspersample=(((buf[12]&0x01)<<4)|((buf[13]&0xf0)>>4))+1; */
682
683 /* totalsamples is a 36-bit field, but we assume <= 32 bits are used */
684 totalsamples=(buf[14]<<24)|(buf[15]<<16)|(buf[16]<<8)|buf[17];
685
686 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
687 tracks[track_widx].id3.length=(totalsamples/tracks[track_widx].id3.frequency)*1000;
688 tracks[track_widx].id3.bitrate=(filesize(fd)*8)/tracks[track_widx].id3.length;
689 } else if ((buf[0]&0x7f)==4) { /* 4 is the VORBIS_COMMENT block */
690
691 /* The next i bytes of the file contain the VORBIS COMMENTS - just skip them for now. */
692 lseek(fd, i, SEEK_CUR);
693
694 } else {
695 if (buf[0]&0x80) { /* If we have reached the last metadata block, abort. */
696 break;
697 } else {
698 lseek(fd, i, SEEK_CUR); /* Skip to next metadata block */
699 }
700 }
701 }
702
703 lseek(fd, 0, SEEK_SET);
704 strncpy(tracks[track_widx].id3.path,trackname,sizeof(tracks[track_widx].id3.path));
705 tracks[track_widx].taginfo_ready = true;
706 break;
707
641 /* If we don't know how to read the metadata, just store the filename */ 708 /* If we don't know how to read the metadata, just store the filename */
642 default: 709 default:
643 strncpy(tracks[track_widx].id3.path,trackname,sizeof(tracks[track_widx].id3.path)); 710 strncpy(tracks[track_widx].id3.path,trackname,sizeof(tracks[track_widx].id3.path));