1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2009 Mohamed Tarek
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
27 #include <codecs/librm/rm.h>
30 #include "metadata_common.h"
31 #include "metadata_parsers.h"
34 /* Uncomment the following line for debugging */
41 #define ID3V1_OFFSET -128
42 #define METADATA_FOOTER_OFFSET -140
44 static inline void print_cook_extradata(RMContext
*rmctx
) {
46 DEBUGF(" cook_version = 0x%08lx\n", rm_get_uint32be(rmctx
->codec_extradata
));
47 DEBUGF(" samples_per_frame_per_channel = %d\n", rm_get_uint16be(&rmctx
->codec_extradata
[4]));
48 DEBUGF(" number_of_subbands_in_freq_domain = %d\n", rm_get_uint16be(&rmctx
->codec_extradata
[6]));
49 if(rmctx
->extradata_size
== 16) {
50 DEBUGF(" joint_stereo_subband_start = %d\n",rm_get_uint16be(&rmctx
->codec_extradata
[12]));
51 DEBUGF(" joint_stereo_vlc_bits = %d\n", rm_get_uint16be(&rmctx
->codec_extradata
[14]));
63 static int real_read_object_header(int fd
, struct real_object_t
* obj
)
67 if ((n
= read_uint32be(fd
, &obj
->fourcc
)) <= 0)
69 if ((n
= read_uint32be(fd
, &obj
->size
)) <= 0)
71 if ((n
= read_uint16be(fd
, &obj
->version
)) <= 0)
77 #if (defined(SIMULATOR) && defined(DEBUG_RM))
78 static char* fourcc2str(uint32_t f
)
82 res
[0] = (f
& 0xff000000) >> 24;
83 res
[1] = (f
& 0xff0000) >> 16;
84 res
[2] = (f
& 0xff00) >> 8;
92 static inline int real_read_audio_stream_info(int fd
, RMContext
*rmctx
)
96 struct real_object_t obj
;
100 uint32_t coded_framesize
;
101 uint8_t interleaver_id_length
;
102 uint8_t fourcc_length
;
104 uint32_t interleaver_id
;
107 memset(&obj
,0,sizeof(obj
));
108 read_uint32be(fd
, &version
);
111 DEBUGF(" version=0x%04lx\n",((version
>> 16) & 0xff));
112 if (((version
>> 16) & 0xff) == 3) {
113 /* Very old version */
116 real_read_object_header(fd
, &obj
);
117 read_uint32be(fd
, &header_size
);
118 /* obj.size will be filled with an unknown value, replaced with header_size */
119 DEBUGF(" Object: %s, size: %ld bytes, version: 0x%04x\n",fourcc2str(obj
.fourcc
),header_size
,obj
.version
);
121 read_uint16be(fd
, &flavor
);
122 read_uint32be(fd
, &coded_framesize
);
124 lseek(fd
, 20, SEEK_CUR
);
126 lseek(fd
, 12, SEEK_CUR
); /* unknown */
127 read_uint16be(fd
, &rmctx
->sub_packet_h
);
128 read_uint16be(fd
, &rmctx
->block_align
);
129 read_uint16be(fd
, &rmctx
->sub_packet_size
);
130 lseek(fd
, 2, SEEK_CUR
); /* unknown */
132 if (((version
>> 16) & 0xff) == 5)
134 lseek(fd
, 6, SEEK_CUR
); /* unknown */
137 read_uint16be(fd
, &rmctx
->sample_rate
);
138 lseek(fd
, 4, SEEK_CUR
); /* unknown */
139 read_uint16be(fd
, &rmctx
->nb_channels
);
141 if (((version
>> 16) & 0xff) == 4)
144 read_uint8(fd
, &interleaver_id_length
);
145 read_uint32be(fd
, &interleaver_id
);
146 read_uint8(fd
, &fourcc_length
);
148 lseek(fd
, 6, SEEK_CUR
);
150 read_uint32be(fd
, &fourcc
);
153 if (((version
>> 16) & 0xff) == 5)
155 read_uint32be(fd
, &interleaver_id
);
156 read_uint32be(fd
, &fourcc
);
159 lseek(fd
, 3, SEEK_CUR
); /* unknown */
161 if (((version
>> 16) & 0xff) == 5)
163 lseek(fd
, 1, SEEK_CUR
); /* unknown */
168 case FOURCC('c','o','o','k'):
169 rmctx
->codec_type
= CODEC_COOK
;
170 read_uint32be(fd
, &rmctx
->extradata_size
);
172 read(fd
, rmctx
->codec_extradata
, rmctx
->extradata_size
);
173 skipped
+= rmctx
->extradata_size
;
176 case FOURCC('r','a','a','c'):
177 case FOURCC('r','a','c','p'):
178 rmctx
->codec_type
= CODEC_AAC
;
179 read_uint32be(fd
, &rmctx
->extradata_size
);
181 read(fd
, rmctx
->codec_extradata
, rmctx
->extradata_size
);
182 skipped
+= rmctx
->extradata_size
;
185 case FOURCC('d','n','e','t'):
186 rmctx
->codec_type
= CODEC_AC3
;
189 case FOURCC('a','t','r','c'):
190 rmctx
->codec_type
= CODEC_ATRAC
;
191 read_uint32be(fd
, &rmctx
->extradata_size
);
193 read(fd
, rmctx
->codec_extradata
, rmctx
->extradata_size
);
194 skipped
+= rmctx
->extradata_size
;
197 default: /* Not a supported codec */
201 DEBUGF(" flavor = %d\n",flavor
);
202 DEBUGF(" coded_frame_size = %ld\n",coded_framesize
);
203 DEBUGF(" sub_packet_h = %d\n",rmctx
->sub_packet_h
);
204 DEBUGF(" frame_size = %d\n",rmctx
->block_align
);
205 DEBUGF(" sub_packet_size = %d\n",rmctx
->sub_packet_size
);
206 DEBUGF(" sample_rate= %d\n",rmctx
->sample_rate
);
207 DEBUGF(" channels= %d\n",rmctx
->nb_channels
);
208 DEBUGF(" fourcc = %s\n",fourcc2str(fourcc
));
209 DEBUGF(" codec_extra_data_length = %ld\n",rmctx
->extradata_size
);
210 DEBUGF(" codec_extradata :\n");
211 if(rmctx
->codec_type
== CODEC_COOK
) {
212 DEBUGF(" cook_extradata :\n");
213 print_cook_extradata(rmctx
);
221 static int rm_parse_header(int fd
, RMContext
*rmctx
, struct mp3entry
*id3
)
223 struct real_object_t obj
;
227 uint8_t len
; /* Holds a string_length, which is then passed to read_string() */
230 uint32_t avg_bitrate
= 0;
231 uint32_t max_packet_size
;
232 uint32_t avg_packet_size
;
233 uint32_t packet_count
;
236 uint32_t index_offset
;
239 uint32_t codec_data_size
;
242 uint32_t max_bitrate
;
243 uint16_t num_streams
;
244 uint32_t next_data_off
;
247 memset(&obj
,0,sizeof(obj
));
248 curpos
= lseek(fd
, 0, SEEK_SET
);
249 res
= real_read_object_header(fd
, &obj
);
251 if (obj
.fourcc
== FOURCC('.','r','a',0xfd))
253 /* Very old .ra format - not yet supported */
256 else if (obj
.fourcc
!= FOURCC('.','R','M','F'))
261 lseek(fd
, 8, SEEK_CUR
); /* unknown */
263 DEBUGF("Object: %s, size: %d bytes, version: 0x%04x, pos: %d\n",fourcc2str(obj
.fourcc
),(int)obj
.size
,obj
.version
,(int)curpos
);
265 res
= real_read_object_header(fd
, &obj
);
269 DEBUGF("Object: %s, size: %d bytes, version: 0x%04x, pos: %d\n",fourcc2str(obj
.fourcc
),(int)obj
.size
,obj
.version
,(int)curpos
);
271 if(obj
.fourcc
== FOURCC('I','N','D','X'))
275 case FOURCC('P','R','O','P'): /* File properties */
276 read_uint32be(fd
, &max_bitrate
);
277 read_uint32be(fd
, &rmctx
->bit_rate
); /*avg bitrate*/
279 read_uint32be(fd
, &max_packet_size
);
280 read_uint32be(fd
, &avg_packet_size
);
281 read_uint32be(fd
, &packet_count
);
283 lseek(fd
, 3*sizeof(uint32_t), SEEK_CUR
);
285 read_uint32be(fd
, &rmctx
->duration
);
287 read_uint32be(fd
, &preroll
);
288 read_uint32be(fd
, &index_offset
);
290 lseek(fd
, 2*sizeof(uint32_t), SEEK_CUR
);
292 read_uint32be(fd
, &rmctx
->data_offset
);
293 read_uint16be(fd
, &num_streams
);
294 read_uint16be(fd
, &rmctx
->flags
);
297 DEBUGF(" max_bitrate = %ld\n",max_bitrate
);
298 DEBUGF(" avg_bitrate = %ld\n",rmctx
->bit_rate
);
299 DEBUGF(" max_packet_size = %ld\n",max_packet_size
);
300 DEBUGF(" avg_packet_size = %ld\n",avg_packet_size
);
301 DEBUGF(" packet_count = %ld\n",packet_count
);
302 DEBUGF(" duration = %ld\n",rmctx
->duration
);
303 DEBUGF(" preroll = %ld\n",preroll
);
304 DEBUGF(" index_offset = %ld\n",index_offset
);
305 DEBUGF(" data_offset = %ld\n",rmctx
->data_offset
);
306 DEBUGF(" num_streams = %d\n",num_streams
);
307 DEBUGF(" flags=0x%04x\n",rmctx
->flags
);
310 case FOURCC('C','O','N','T'):
311 /* Four strings - Title, Author, Copyright, Comment */
313 skipped
+= (int)read_string(fd
, id3
->id3v1buf
[0], sizeof(id3
->id3v1buf
[0]), '\0', len
);
315 skipped
+= (int)read_string(fd
, id3
->id3v1buf
[1], sizeof(id3
->id3v1buf
[1]), '\0', len
);
317 skipped
+= (int)read_string(fd
, id3
->id3v1buf
[2], sizeof(id3
->id3v1buf
[2]), '\0', len
);
319 skipped
+= (int)read_string(fd
, id3
->id3v1buf
[3], sizeof(id3
->id3v1buf
[3]), '\0', len
);
322 DEBUGF(" title=\"%s\"\n",id3
->id3v1buf
[0]);
323 DEBUGF(" author=\"%s\"\n",id3
->id3v1buf
[1]);
324 DEBUGF(" copyright=\"%s\"\n",id3
->id3v1buf
[2]);
325 DEBUGF(" comment=\"%s\"\n",id3
->id3v1buf
[3]);
328 case FOURCC('M','D','P','R'): /* Media properties */
330 read_uint16be(fd
,&stream_id
);
331 read_uint32be(fd
,&max_bitrate
);
332 read_uint32be(fd
,&avg_bitrate
);
333 read_uint32be(fd
,&max_packet_size
);
334 read_uint32be(fd
,&avg_packet_size
);
335 read_uint32be(fd
,&start_time
);
336 read_uint32be(fd
,&preroll
);
337 read_uint32be(fd
,&duration
);
339 lseek(fd
, 30, SEEK_CUR
);
344 lseek(fd
, len
, SEEK_CUR
); /* desc */
349 lseek(fd
, len
, SEEK_CUR
); /* mimetype */
350 read_uint32be(fd
,&codec_data_size
);
352 lseek(fd
, len
+ 4, SEEK_CUR
);
355 read_uint32be(fd
,&v
);
358 DEBUGF(" stream_id = 0x%04x\n",stream_id
);
359 DEBUGF(" max_bitrate = %ld\n",max_bitrate
);
360 DEBUGF(" avg_bitrate = %ld\n",avg_bitrate
);
361 DEBUGF(" max_packet_size = %ld\n",max_packet_size
);
362 DEBUGF(" avg_packet_size = %ld\n",avg_packet_size
);
363 DEBUGF(" start_time = %ld\n",start_time
);
364 DEBUGF(" preroll = %ld\n",preroll
);
365 DEBUGF(" duration = %ld\n",duration
);
366 DEBUGF(" codec_data_size = %ld\n",codec_data_size
);
367 DEBUGF(" v=\"%s\"\n", fourcc2str(v
));
369 if (v
== FOURCC('.','r','a',0xfd))
372 temp
= real_read_audio_stream_info(fd
, rmctx
);
378 else if (v
== FOURCC('L','S','D',':'))
380 DEBUGF("Real audio lossless is not supported.");
385 /* We shall not abort with -1 here. *.rm file often seem
386 * to have a second media properties header that contains
388 DEBUGF("Unknown header signature :\"%s\"\n", fourcc2str(v
));
394 case FOURCC('D','A','T','A'):
395 read_uint32be(fd
,&rmctx
->nb_packets
);
397 read_uint32be(fd
,&next_data_off
);
401 * nb_packets correction :
402 * in some samples, number of packets may not exactly form
403 * an integer number of scrambling units. This is corrected
404 * by constructing a partially filled unit out of the few
405 * remaining samples at the end of decoding.
407 if(rmctx
->nb_packets
% rmctx
->sub_packet_h
)
408 rmctx
->nb_packets
+= rmctx
->sub_packet_h
- (rmctx
->nb_packets
% rmctx
->sub_packet_h
);
410 DEBUGF(" data_nb_packets = %ld\n",rmctx
->nb_packets
);
411 DEBUGF(" next DATA offset = %ld\n",next_data_off
);
415 if(header_end
) break;
416 curpos
= lseek(fd
, obj
.size
- skipped
, SEEK_CUR
);
417 res
= real_read_object_header(fd
, &obj
);
425 bool get_rm_metadata(int fd
, struct mp3entry
* id3
)
427 RMContext
*rmctx
= (RMContext
*) (( (intptr_t)id3
->id3v2buf
+ 3 ) &~ 3);
428 memset(rmctx
,0,sizeof(RMContext
));
429 if(rm_parse_header(fd
, rmctx
, id3
) < 0)
432 if (!setid3v1title(fd
, id3
)) {
433 /* file has no id3v1 tags, use the tags from CONT chunk */
434 id3
->title
= id3
->id3v1buf
[0];
435 id3
->artist
= id3
->id3v1buf
[1];
436 id3
->comment
= id3
->id3v1buf
[3];
439 switch(rmctx
->codec_type
)
442 /* Already set, do nothing */
445 id3
->codectype
= AFMT_RM_AAC
;
449 id3
->codectype
= AFMT_RM_AC3
;
453 id3
->codectype
= AFMT_RM_ATRAC3
;
457 id3
->channels
= rmctx
->nb_channels
;
458 id3
->extradata_size
= rmctx
->extradata_size
;
459 id3
->bitrate
= rmctx
->bit_rate
/ 1000;
460 id3
->frequency
= rmctx
->sample_rate
;
461 id3
->length
= rmctx
->duration
;
462 id3
->filesize
= filesize(fd
);