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"
36 static bool parse_dec(int *retval
, const char *p
, int minval
, int maxval
)
41 if (c
>= '0' && c
<= '9')
47 } while (*++p
!= '\0');
54 static bool parse_text(char *retval
, const char *p
)
60 if (p
[0] == '<' && p
[1] == '?' && p
[2] == '>' && p
[3] == '"')
74 static int ASAP_ParseDuration(const char *s
)
77 if (*s
< '0' || *s
> '9')
80 if (*s
>= '0' && *s
<= '9')
81 r
= 10 * r
+ *s
++ - '0';
84 if (*s
< '0' || *s
> '5')
86 r
= 60 * r
+ (*s
++ - '0') * 10;
87 if (*s
< '0' || *s
> '9')
95 if (*s
< '0' || *s
> '9')
97 r
+= 100 * (*s
++ - '0');
98 if (*s
< '0' || *s
> '9')
100 r
+= 10 * (*s
++ - '0');
101 if (*s
< '0' || *s
> '9')
107 static bool read_asap_string(char* source
,char** buf
,char** buffer_end
,char** dest
)
109 if(parse_text(*buf
,source
) == false) return false;
111 /* set dest pointer */
115 *buf
+= strlen(*buf
)+1;
118 if(*buf
>= *buffer_end
)
120 DEBUGF("Buffer full\n");
126 static bool parse_sap_header(int fd
,struct mp3entry
* id3
,int file_len
)
128 int module_index
= 0;
129 int sap_signature
= -1;
130 int duration_index
= 0;
131 unsigned char cur_char
= 0;
138 int durations
[MAX_SONGS
];
139 int loops
[MAX_SONGS
];
140 for (i
= 0; i
< MAX_SONGS
; i
++) {
145 /* use id3v2 buffer for our strings */
146 char* buffer
= id3
->id3v2buf
;
147 char* buffer_end
= id3
->id3v2buf
+ ID3V2_BUF_SIZE
;
155 if (module_index
+ 8 >= file_len
)
158 read(fd
,&cur_char
,1);
160 if (cur_char
== 0xff)
164 while (cur_char
!= 0x0d)
166 line
[i
++] = cur_char
;
168 if (module_index
>= file_len
|| (unsigned)i
>= sizeof(line
) - 1)
171 read(fd
,&cur_char
,1);
173 if (++module_index
>= file_len
)
176 read(fd
,&cur_char
,1);
177 if ( cur_char
!= 0x0a)
181 for (p
= line
; *p
!= '\0'; p
++) {
189 if(strcmp(line
, "SAP") == 0)
191 if (sap_signature
== -1)
193 if (strcmp(line
,"AUTHOR") == 0)
195 if(read_asap_string(p
,&buffer
,&buffer_end
,&id3
->artist
) == false)
198 else if(strcmp(line
,"NAME")==0)
200 if(read_asap_string(p
,&buffer
,&buffer_end
,&id3
->title
) == false)
203 else if(strcmp(line
,"DATE")==0)
205 if(read_asap_string(p
,&buffer
,&buffer_end
,&id3
->year_string
) == false)
208 else if (strcmp(line
,"SONGS")==0)
210 if (parse_dec(&numSongs
, p
,1,MAX_SONGS
) == false )
213 else if (strcmp(line
,"DEFSONG")==0)
215 if (parse_dec(&defSong
, p
,0,MAX_SONGS
) == false)
218 else if (strcmp(line
,"STEREO")==0)
222 else if (strcmp(line
,"TIME") == 0)
224 int durationTemp
= ASAP_ParseDuration(p
);
225 if (durationTemp
< 0 || duration_index
>= MAX_SONGS
)
227 durations
[duration_index
] = durationTemp
;
228 if (strstr(p
, "LOOP") != NULL
)
229 loops
[duration_index
] = 1;
235 int length
= durations
[defSong
];
238 id3
->length
= length
;
240 lseek(fd
,0,SEEK_SET
);
245 bool get_asap_metadata(int fd
, struct mp3entry
* id3
)
248 int filelength
= filesize(fd
);
250 if(parse_sap_header(fd
,id3
,filelength
) == false)
252 DEBUGF("parse sap header failed.\n");
257 id3
->frequency
= 44100;
260 id3
->filesize
= filelength
;