1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 Dominik Wenger
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"
48 static bool parse_dec(int *retval
, const char *p
, int minval
, int maxval
)
53 if (c
>= '0' && c
<= '9')
59 } while (*++p
!= '\0');
66 static bool parse_text(char *retval
, const char *p
)
72 if (p
[0] == '<' && p
[1] == '?' && p
[2] == '>' && p
[3] == '"')
86 static int ASAP_ParseDuration(const char *s
)
89 if (*s
< '0' || *s
> '9')
92 if (*s
>= '0' && *s
<= '9')
93 r
= 10 * r
+ *s
++ - '0';
96 if (*s
< '0' || *s
> '5')
98 r
= 60 * r
+ (*s
++ - '0') * 10;
99 if (*s
< '0' || *s
> '9')
107 if (*s
< '0' || *s
> '9')
109 r
+= 100 * (*s
++ - '0');
110 if (*s
< '0' || *s
> '9')
112 r
+= 10 * (*s
++ - '0');
113 if (*s
< '0' || *s
> '9')
119 static bool parse_sap_header(int fd
,struct module_info
* info
,int file_len
)
121 int module_index
= 0;
122 int sap_signature
= -1;
123 int duration_index
= 0;
124 unsigned char cur_char
= 0;
132 for (i
= 0; i
< MAX_SONGS
; i
++) {
133 info
->durations
[i
] = -1;
143 if (module_index
+ 8 >= file_len
)
146 read(fd
,&cur_char
,1);
148 if (cur_char
== 0xff)
152 while (cur_char
!= 0x0d)
154 line
[i
++] = cur_char
;
156 if (module_index
>= file_len
|| (unsigned)i
>= sizeof(line
) - 1)
159 read(fd
,&cur_char
,1);
161 if (++module_index
>= file_len
)
164 read(fd
,&cur_char
,1);
165 if ( cur_char
!= 0x0a)
169 for (p
= line
; *p
!= '\0'; p
++) {
177 if(strcmp(line
, "SAP") == 0)
179 if (sap_signature
== -1)
181 if (strcmp(line
,"AUTHOR") == 0)
183 if (parse_text(info
->author
, p
) == false )
186 else if(strcmp(line
,"NAME")==0)
188 if (parse_text(info
->name
, p
) == false)
191 else if(strcmp(line
,"DATE")==0)
193 if (parse_text(info
->date
, p
) == false)
196 else if (strcmp(line
,"SONGS")==0)
198 if (parse_dec(&info
->numSongs
, p
,1,MAX_SONGS
) == false )
201 else if (strcmp(line
,"DEFSONG")==0)
203 if (parse_dec(&info
->defSong
, p
,0,MAX_SONGS
) == false)
206 else if (strcmp(line
,"STEREO")==0)
208 info
->numChannels
= 2;
210 else if (strcmp(line
,"TIME") == 0)
212 int duration
= ASAP_ParseDuration(p
);
213 if (duration
< 0 || duration_index
>= MAX_SONGS
)
215 info
->durations
[duration_index
] = duration
;
216 if (strstr(p
, "LOOP") != NULL
)
217 info
->loops
[duration_index
] = 1;
222 lseek(fd
,0,SEEK_SET
);
227 bool get_asap_metadata(int fd
, struct mp3entry
* id3
)
229 char *buf
= id3
->id3v2buf
;
231 int filelength
= filesize(fd
);
232 struct module_info
*info
;
233 info
= (struct module_info
*) buf
;
235 if(parse_sap_header(fd
,info
,filelength
) == false)
237 DEBUGF("parse sap header failed.\n");
241 id3
->title
= info
->name
;
242 id3
->artist
= info
->author
;
243 id3
->year_string
= info
->date
;
244 int length
= info
->durations
[info
->defSong
];
247 id3
->length
= length
;
250 id3
->frequency
= 44100;
253 id3
->filesize
= filelength
;