summaryrefslogtreecommitdiff
path: root/lib/rbcodec/metadata/rm.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/metadata/rm.c')
-rw-r--r--lib/rbcodec/metadata/rm.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/lib/rbcodec/metadata/rm.c b/lib/rbcodec/metadata/rm.c
index 2a5a2892a3..1e33f0b0ac 100644
--- a/lib/rbcodec/metadata/rm.c
+++ b/lib/rbcodec/metadata/rm.c
@@ -89,7 +89,7 @@ static char* fourcc2str(uint32_t f)
89} 89}
90#endif 90#endif
91 91
92static inline int real_read_audio_stream_info(int fd, RMContext *rmctx) 92static int real_read_audio_stream_info(int fd, RMContext *rmctx)
93{ 93{
94 int skipped = 0; 94 int skipped = 0;
95 uint32_t version; 95 uint32_t version;
@@ -111,6 +111,7 @@ static inline int real_read_audio_stream_info(int fd, RMContext *rmctx)
111 DEBUGF(" version=0x%04lx\n",((version >> 16) & 0xff)); 111 DEBUGF(" version=0x%04lx\n",((version >> 16) & 0xff));
112 if (((version >> 16) & 0xff) == 3) { 112 if (((version >> 16) & 0xff) == 3) {
113 /* Very old version */ 113 /* Very old version */
114 return -1;
114 } else { 115 } else {
115#ifdef SIMULATOR 116#ifdef SIMULATOR
116 real_read_object_header(fd, &obj); 117 real_read_object_header(fd, &obj);
@@ -218,7 +219,7 @@ static inline int real_read_audio_stream_info(int fd, RMContext *rmctx)
218 return skipped; 219 return skipped;
219} 220}
220 221
221static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3) 222static inline int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3)
222{ 223{
223 struct real_object_t obj; 224 struct real_object_t obj;
224 int res; 225 int res;
@@ -242,6 +243,7 @@ static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3)
242 uint32_t max_bitrate; 243 uint32_t max_bitrate;
243 uint16_t num_streams; 244 uint16_t num_streams;
244 uint32_t next_data_off; 245 uint32_t next_data_off;
246 uint16_t pkt_version;
245 uint8_t header_end; 247 uint8_t header_end;
246 248
247 memset(&obj,0,sizeof(obj)); 249 memset(&obj,0,sizeof(obj));
@@ -250,6 +252,35 @@ static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3)
250 252
251 if (obj.fourcc == FOURCC('.','r','a',0xfd)) 253 if (obj.fourcc == FOURCC('.','r','a',0xfd))
252 { 254 {
255 lseek(fd, 4, SEEK_SET);
256 skipped = real_read_audio_stream_info(fd, rmctx);
257 if (skipped > 0 && rmctx->codec_type == CODEC_AC3)
258 {
259 read_uint8(fd,&len);
260 skipped += (int)read_string(fd, id3->id3v1buf[0], sizeof(id3->id3v1buf[0]), '\0', len);
261 read_uint8(fd,&len);
262 skipped += (int)read_string(fd, id3->id3v1buf[1], sizeof(id3->id3v1buf[1]), '\0', len);
263 read_uint8(fd,&len);
264 skipped += (int)read_string(fd, id3->id3v1buf[2], sizeof(id3->id3v1buf[2]), '\0', len);
265 read_uint8(fd,&len);
266 skipped += (int)read_string(fd, id3->id3v1buf[3], sizeof(id3->id3v1buf[3]), '\0', len);
267 rmctx->data_offset = skipped + 8;
268 rmctx->bit_rate = rmctx->block_align * rmctx->sample_rate / 192;
269 if (rmctx->block_align)
270 rmctx->nb_packets = (filesize(fd) - rmctx->data_offset) / rmctx->block_align;
271 if (rmctx->sample_rate)
272 rmctx->duration = (uint32_t)(256LL * 6 * 1000 * rmctx->nb_packets / rmctx->sample_rate);
273 rmctx->flags |= RM_RAW_DATASTREAM;
274
275 DEBUGF(" data_offset = %ld\n",rmctx->data_offset);
276 DEBUGF(" avg_bitrate = %ld\n",rmctx->bit_rate);
277 DEBUGF(" duration = %ld\n",rmctx->duration);
278 DEBUGF(" title=\"%s\"\n",id3->id3v1buf[0]);
279 DEBUGF(" author=\"%s\"\n",id3->id3v1buf[1]);
280 DEBUGF(" copyright=\"%s\"\n",id3->id3v1buf[2]);
281 DEBUGF(" comment=\"%s\"\n",id3->id3v1buf[3]);
282 return 0;
283 }
253 /* Very old .ra format - not yet supported */ 284 /* Very old .ra format - not yet supported */
254 return -1; 285 return -1;
255 } 286 }
@@ -305,6 +336,8 @@ static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3)
305 DEBUGF(" data_offset = %ld\n",rmctx->data_offset); 336 DEBUGF(" data_offset = %ld\n",rmctx->data_offset);
306 DEBUGF(" num_streams = %d\n",num_streams); 337 DEBUGF(" num_streams = %d\n",num_streams);
307 DEBUGF(" flags=0x%04x\n",rmctx->flags); 338 DEBUGF(" flags=0x%04x\n",rmctx->flags);
339
340 rmctx->flags &= 0x00FF;
308 break; 341 break;
309 342
310 case FOURCC('C','O','N','T'): 343 case FOURCC('C','O','N','T'):
@@ -409,7 +442,22 @@ static int rm_parse_header(int fd, RMContext *rmctx, struct mp3entry *id3)
409 442
410 DEBUGF(" data_nb_packets = %ld\n",rmctx->nb_packets); 443 DEBUGF(" data_nb_packets = %ld\n",rmctx->nb_packets);
411 DEBUGF(" next DATA offset = %ld\n",next_data_off); 444 DEBUGF(" next DATA offset = %ld\n",next_data_off);
412 header_end = 1; 445
446 if (!next_data_off)
447 {
448 if (rmctx->duration == 0 && rmctx->bit_rate != 0)
449 {
450 rmctx->duration = (uint32_t)(8000LL * rmctx->nb_packets * rmctx->block_align / rmctx->bit_rate);
451 DEBUGF(" estimated duration = %ld\n",rmctx->duration);
452 }
453 read_uint16be(fd, &pkt_version);
454 skipped += 2;
455 DEBUGF(" pkt_version=0x%04x\n", pkt_version);
456 if (pkt_version)
457 rmctx->flags |= RM_PKT_V1;
458 rmctx->data_offset = curpos;
459 header_end = 1;
460 }
413 break; 461 break;
414 } 462 }
415 if(header_end) break; 463 if(header_end) break;
@@ -456,7 +504,7 @@ bool get_rm_metadata(int fd, struct mp3entry* id3)
456 504
457 id3->channels = rmctx->nb_channels; 505 id3->channels = rmctx->nb_channels;
458 id3->extradata_size = rmctx->extradata_size; 506 id3->extradata_size = rmctx->extradata_size;
459 id3->bitrate = rmctx->bit_rate / 1000; 507 id3->bitrate = (rmctx->bit_rate + 500) / 1000;
460 id3->frequency = rmctx->sample_rate; 508 id3->frequency = rmctx->sample_rate;
461 id3->length = rmctx->duration; 509 id3->length = rmctx->duration;
462 id3->filesize = filesize(fd); 510 id3->filesize = filesize(fd);