summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/metadata/rm.c64
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
41static inline void print_cook_extradata(RMContext *rmctx) { 44static 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
91static 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
88static inline int real_read_audio_stream_info(int fd, RMContext *rmctx) 137static 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;