diff options
author | Mohamed Tarek <mt@rockbox.org> | 2009-10-24 23:53:01 +0000 |
---|---|---|
committer | Mohamed Tarek <mt@rockbox.org> | 2009-10-24 23:53:01 +0000 |
commit | 027e7634bfc0bf21a74f10570a040ed258ec4dc3 (patch) | |
tree | e6b3dd017685533c5968c73c0391632d412cef16 | |
parent | c9dd93e2868a34c223c3c9da1e04817f1848212c (diff) | |
download | rockbox-027e7634bfc0bf21a74f10570a040ed258ec4dc3.tar.gz rockbox-027e7634bfc0bf21a74f10570a040ed258ec4dc3.zip |
Add support for ID3v1 metadta tags in Real Media container.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23339 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/metadata/rm.c | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/apps/metadata/rm.c b/apps/metadata/rm.c index 740ec1b1ed..c9afa1efab 100644 --- a/apps/metadata/rm.c +++ b/apps/metadata/rm.c | |||
@@ -38,6 +38,9 @@ | |||
38 | #define DEBUGF(...) | 38 | #define DEBUGF(...) |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #define ID3V1_OFFSET -128 | ||
42 | #define METADATA_FOOTER_OFFSET -140 | ||
43 | |||
41 | static inline void print_cook_extradata(RMContext *rmctx) { | 44 | static inline void print_cook_extradata(RMContext *rmctx) { |
42 | 45 | ||
43 | DEBUGF(" cook_version = 0x%08lx\n", rm_get_uint32be(rmctx->codec_extradata)); | 46 | DEBUGF(" cook_version = 0x%08lx\n", rm_get_uint32be(rmctx->codec_extradata)); |
@@ -85,6 +88,52 @@ static char* fourcc2str(uint32_t f) | |||
85 | } | 88 | } |
86 | #endif | 89 | #endif |
87 | 90 | ||
91 | static inline int real_read_id3v1_tags(int fd, struct mp3entry *id3) | ||
92 | { | ||
93 | /* ID3v1 Standard : http://id3.org/id3v1.html */ | ||
94 | char temp[31]; | ||
95 | char *buf = &id3->id3v1buf[0][0]; | ||
96 | long buf_remaining = sizeof(id3->id3v1buf); | ||
97 | |||
98 | lseek(fd, ID3V1_OFFSET, SEEK_END); | ||
99 | read(fd, temp, 3); | ||
100 | temp[3] = '\0'; | ||
101 | if(!strcmp(temp, "TAG")) | ||
102 | { | ||
103 | read_string(fd, temp, sizeof(temp), -1, 30); | ||
104 | parse_tag("title", temp, id3, buf, buf_remaining, 0); | ||
105 | buf += 30; | ||
106 | buf_remaining -= 30; | ||
107 | |||
108 | read_string(fd, temp, sizeof(temp), -1, 30); | ||
109 | parse_tag("artist", temp, id3, buf, buf_remaining, 0); | ||
110 | buf += 30; | ||
111 | buf_remaining -= 30; | ||
112 | |||
113 | read_string(fd, temp, sizeof(temp), -1, 30); | ||
114 | parse_tag("album", temp, id3, buf, buf_remaining, 0); | ||
115 | buf += 30; | ||
116 | buf_remaining -= 30; | ||
117 | |||
118 | read_string(fd, temp, sizeof(temp), -1, 4); | ||
119 | parse_tag("year", temp, id3, buf, buf_remaining, 0); | ||
120 | buf += 4; | ||
121 | buf_remaining -= 4; | ||
122 | |||
123 | read_string(fd, temp, sizeof(temp), -1, 30); | ||
124 | parse_tag("comment", temp, id3, buf, buf_remaining, 0); | ||
125 | buf += 30; | ||
126 | buf_remaining -= 30; | ||
127 | |||
128 | read_string(fd, temp, sizeof(temp), -1, 1); | ||
129 | parse_tag("genre", temp, id3, buf, buf_remaining, 0); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | return -1; | ||
135 | } | ||
136 | |||
88 | static inline int real_read_audio_stream_info(int fd, RMContext *rmctx) | 137 | static inline int real_read_audio_stream_info(int fd, RMContext *rmctx) |
89 | { | 138 | { |
90 | int skipped = 0; | 139 | int skipped = 0; |
@@ -348,7 +397,6 @@ static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3) | |||
348 | lseek(fd, len + 4, SEEK_CUR); | 397 | lseek(fd, len + 4, SEEK_CUR); |
349 | #endif | 398 | #endif |
350 | skipped += len + 4; | 399 | skipped += len + 4; |
351 | //From ffmpeg: codec_pos = url_ftell(pb); | ||
352 | read_uint32be(fd,&v); | 400 | read_uint32be(fd,&v); |
353 | skipped += 4; | 401 | skipped += 4; |
354 | 402 | ||
@@ -409,11 +457,13 @@ bool get_rm_metadata(int fd, struct mp3entry* id3) | |||
409 | memset(rmctx,0,sizeof(RMContext)); | 457 | memset(rmctx,0,sizeof(RMContext)); |
410 | if(rm_parse_header(fd, rmctx, id3) < 0) | 458 | if(rm_parse_header(fd, rmctx, id3) < 0) |
411 | return false; | 459 | return false; |
412 | 460 | ||
413 | /* Copy tags */ | 461 | if(real_read_id3v1_tags(fd, id3)) { |
414 | id3->title = id3->id3v1buf[0]; | 462 | /* file has no id3v1 tags, use the tags from CONT chunk */ |
415 | id3->artist = id3->id3v1buf[1]; | 463 | id3->title = id3->id3v1buf[0]; |
416 | id3->comment = id3->id3v1buf[3]; | 464 | id3->artist = id3->id3v1buf[1]; |
465 | id3->comment= id3->id3v1buf[3]; | ||
466 | } | ||
417 | 467 | ||
418 | switch(rmctx->codec_type) | 468 | switch(rmctx->codec_type) |
419 | { | 469 | { |
@@ -432,7 +482,7 @@ bool get_rm_metadata(int fd, struct mp3entry* id3) | |||
432 | id3->codectype = AFMT_RM_ATRAC3; | 482 | id3->codectype = AFMT_RM_ATRAC3; |
433 | break; | 483 | break; |
434 | } | 484 | } |
435 | 485 | ||
436 | id3->bitrate = rmctx->bit_rate / 1000; | 486 | id3->bitrate = rmctx->bit_rate / 1000; |
437 | id3->frequency = rmctx->sample_rate; | 487 | id3->frequency = rmctx->sample_rate; |
438 | id3->length = rmctx->duration; | 488 | id3->length = rmctx->duration; |