1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Yoshihisa Uchida
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 ****************************************************************************/
29 #include "metadata_common.h"
30 #include "metadata_parsers.h"
31 #include "rbunicode.h"
34 static int basebits
[4] = { 4, 8, 12, 16 };
36 static int frequency
[5] = { 4000, 8000, 11025, 22050, 44100 };
38 static int support_codepages
[7] = {
39 SJIS
, ISO_8859_1
, -1, GB_2312
, BIG_5
, -1, -1,
43 #define UCS_2 (NUM_CODEPAGES + 1)
44 #define UTF_16 (NUM_CODEPAGES + 2)
47 #define TAG_TITLE (('S'<<8)|'T')
48 #define TAG_ARTIST (('A'<<8)|'N')
49 #define TAG_COMPOSER (('S'<<8)|'W')
51 static unsigned char smafbuf
[1024];
53 static bool read_datachunk(unsigned char *src
, int size
, unsigned short tag
,
54 int codepage
, unsigned char *dst
)
59 while(size
> datasize
+ 4)
61 datasize
= (src
[2] << 8) | src
[3];
62 if (tag
== ((src
[0] << 8) | src
[1]))
65 if (codepage
< NUM_CODEPAGES
)
66 utf8
= iso_decode(src
, dst
, codepage
, datasize
);
67 else /* codepage == UTF_16, UCS_2 */
68 utf8
= utf16BEdecode(src
, dst
, datasize
);
73 src
+= (datasize
+ 4);
78 static bool read_option(unsigned char *src
, int size
, unsigned short tag
,
79 int codepage
, unsigned char *dst
)
82 unsigned char *endsrc
= src
+ size
;
90 while (*src
!= ',' || *(src
-1) == '\\')
95 if (tag
== ((utf8
[0] << 8) | utf8
[1]) && utf8
[2] == ':')
98 if (codepage
< NUM_CODEPAGES
)
99 utf8
= iso_decode(utf8
, dst
, codepage
, datasize
);
100 else /* codepage == UTF_16, UCS_2 */
101 utf8
= utf16BEdecode(utf8
, dst
, datasize
);
111 static int convert_smaf_audio_frequency(unsigned int freq
)
115 return frequency
[freq
];
118 static int convert_smaf_audio_basebit(unsigned int basebit
)
122 return basebits
[basebit
];
125 static int convert_smaf_codetype(unsigned int codetype
)
128 return support_codepages
[codetype
];
129 else if (codetype
< 0x20)
131 else if (codetype
== 0x20)
133 else if (codetype
== 0x23)
135 else if (codetype
== 0x24)
137 else if (codetype
== 0xff)
142 static bool get_smaf_metadata_audio_track(struct mp3entry
*id3
,
143 unsigned char* buf
, unsigned char *endbuf
)
149 unsigned long totalsamples
;
151 channels
= ((buf
[10] & 0x80) >> 7) + 1;
152 bitspersample
= convert_smaf_audio_basebit(buf
[11] >> 4);
153 if (bitspersample
== 0)
155 DEBUGF("metada error: smaf unsupport basebit %d\n", buf
[11] >> 4);
158 id3
->frequency
= convert_smaf_audio_frequency(buf
[10] & 0x0f);
163 chunksize
= get_long_be(buf
+ 4) + 8;
164 if (memcmp(buf
, "Awa", 3) == 0)
166 numbytes
= get_long_be(buf
+ 4) - 3;
167 totalsamples
= (numbytes
<< 3) / (bitspersample
* channels
);
169 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
170 id3
->length
= ((int64_t)totalsamples
* 1000LL) / id3
->frequency
;
176 DEBUGF("metada error: smaf does not include pcm audio data\n");
180 static bool get_smaf_metadata_score_track(struct mp3entry
*id3
,
181 unsigned char* buf
, unsigned char *endbuf
)
187 unsigned long totalsamples
;
190 * skip to the next chunk.
191 * MA-2/MA-3/MA-5: padding 16 bytes
192 * MA-7: padding 32 bytes
199 while (buf
+ 10 < endbuf
)
201 chunksize
= get_long_be(buf
+ 4) + 8;
202 if (memcmp(buf
, "Mtsp", 4) == 0)
205 if (memcmp(buf
, "Mwa", 3) != 0)
207 DEBUGF("metada error: smaf unsupport format: %c%c%c%c\n",
208 buf
[0], buf
[1], buf
[2], buf
[3]);
212 channels
= ((buf
[8] & 0x80) >> 7) + 1;
213 bitspersample
= convert_smaf_audio_basebit(buf
[8] & 0x0f);
214 if (bitspersample
== 0)
216 DEBUGF("metada error: smaf unsupport basebit %d\n", buf
[8] & 0x0f);
220 numbytes
= get_long_be(buf
+ 4) - 3;
221 totalsamples
= numbytes
* 8 / (bitspersample
* channels
);
223 id3
->frequency
= (buf
[9] << 8) | buf
[10];
225 /* Calculate track length (in ms) and estimate the bitrate (in kbit/s) */
226 id3
->length
= ((int64_t) totalsamples
* 1000) / id3
->frequency
;
232 DEBUGF("metada error: smaf does not include pcm audio data\n");
236 bool get_smaf_metadata(int fd
, struct mp3entry
* id3
)
238 /* Use the trackname part of the id3 structure as a temporary buffer */
239 unsigned char* buf
= (unsigned char *)id3
->path
;
240 unsigned char *endbuf
= smafbuf
+ 1024;
243 int codepage
= ISO_8859_1
;
247 id3
->composer
= NULL
;
249 id3
->vbr
= false; /* All SMAF files are CBR */
250 id3
->filesize
= filesize(fd
);
252 /* get RIFF chunk header */
253 if ((lseek(fd
, 0, SEEK_SET
) < 0) || (read(fd
, buf
, 21) < 21))
258 if ((memcmp(buf
, "MMMD", 4) != 0) || (memcmp(&buf
[8], "CNTI", 4) != 0))
260 DEBUGF("metada error: does not smaf format\n");
264 contents_size
= get_long_be(buf
+ 12);
265 if (contents_size
< 5)
267 DEBUGF("metada error: CNTI chunk size is small %d\n", contents_size
);
276 if (memcmp(buf
, "OPDA", 4) != 0)
278 DEBUGF("metada error: smaf does not include OPDA chunk\n");
281 contents_size
= get_long_be(buf
+ 4) - 8;
283 if (memcmp(buf
+ 8, "Dch", 3) != 0)
285 DEBUGF("metada error: smaf does not include Dch chunk\n");
288 codepage
= convert_smaf_codetype(buf
[11]);
291 DEBUGF("metada error: smaf unsupport codetype: %d\n", buf
[11]);
295 i
= get_long_be(buf
+ 12);
299 DEBUGF("metada warning: smaf contents size is big %d\n", i
);
302 if (read(fd
, buf
, i
) < i
)
306 if (read_datachunk(buf
, i
, TAG_TITLE
, codepage
, id3
->id3v1buf
[0]))
307 id3
->title
= id3
->id3v1buf
[0];
310 if (read_datachunk(buf
, i
, TAG_ARTIST
, codepage
, id3
->id3v1buf
[1]))
311 id3
->artist
= id3
->id3v1buf
[1];
314 if (read_datachunk(buf
, i
, TAG_COMPOSER
, codepage
, id3
->id3v1buf
[2]))
315 id3
->composer
= id3
->id3v1buf
[2];
319 codepage
= convert_smaf_codetype(buf
[14]);
322 DEBUGF("metada error: smaf unsupport codetype: %d\n", buf
[11]);
328 DEBUGF("metada warning: smaf contents size is big %d\n", i
);
331 if (read(fd
, buf
, i
) < i
)
335 if (read_option(buf
, i
, TAG_TITLE
, codepage
, id3
->id3v1buf
[0]))
336 id3
->title
= id3
->id3v1buf
[0];
339 if (read_option(buf
, i
, TAG_ARTIST
, codepage
, id3
->id3v1buf
[1]))
340 id3
->artist
= id3
->id3v1buf
[1];
343 if (read_option(buf
, i
, TAG_COMPOSER
, codepage
, id3
->id3v1buf
[2]))
344 id3
->composer
= id3
->id3v1buf
[2];
347 if (contents_size
> i
)
348 lseek(fd
, contents_size
- i
, SEEK_CUR
);
350 /* assume the SMAF pcm data position is less than 1024 bytes */
351 if (read(fd
, smafbuf
, 1024) < 1024)
355 while (buf
+ 8 < endbuf
)
357 i
= get_long_be(buf
+ 4) + 8;
359 if (memcmp(buf
, "ATR", 3) == 0)
360 return get_smaf_metadata_audio_track(id3
, buf
, endbuf
);
361 else if (memcmp(buf
, "MTR", 3) == 0)
362 return get_smaf_metadata_score_track(id3
, buf
, endbuf
);
367 DEBUGF("metada error: smaf does not include track chunk\n");