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)
112 /* set dest pointer */
116 *buf
+= strlen(*buf
)+1;
119 if(*buf
>= *buffer_end
)
121 DEBUGF("Buffer full\n");
127 static bool parse_sap_header(int fd
, struct mp3entry
* id3
, int file_len
)
129 int module_index
= 0;
130 int sap_signature
= -1;
131 int duration_index
= 0;
132 unsigned char cur_char
= 0;
139 int durations
[MAX_SONGS
];
140 int loops
[MAX_SONGS
];
141 for (i
= 0; i
< MAX_SONGS
; i
++) {
146 /* use id3v2 buffer for our strings */
147 char* buffer
= id3
->id3v2buf
;
148 char* buffer_end
= id3
->id3v2buf
+ ID3V2_BUF_SIZE
;
156 if (module_index
+ 8 >= file_len
)
159 read(fd
,&cur_char
,1);
161 if (cur_char
== 0xff)
165 while (cur_char
!= 0x0d)
167 line
[i
++] = cur_char
;
169 if (module_index
>= file_len
|| (unsigned)i
>= sizeof(line
) - 1)
172 read(fd
,&cur_char
,1);
174 if (++module_index
>= file_len
)
177 read(fd
,&cur_char
,1);
178 if ( cur_char
!= 0x0a)
182 for (p
= line
; *p
!= '\0'; p
++) {
190 if(strcmp(line
, "SAP") == 0)
192 if (sap_signature
== -1)
194 if (strcmp(line
, "AUTHOR") == 0)
196 if(read_asap_string(p
, &buffer
, &buffer_end
, &id3
->artist
) == false)
199 else if(strcmp(line
, "NAME") == 0)
201 if(read_asap_string(p
, &buffer
, &buffer_end
, &id3
->title
) == false)
204 else if(strcmp(line
, "DATE") == 0)
206 if(read_asap_string(p
, &buffer
, &buffer_end
, &id3
->year_string
) == false)
209 else if (strcmp(line
, "SONGS") == 0)
211 if (parse_dec(&numSongs
, p
, 1, MAX_SONGS
) == false )
214 else if (strcmp(line
, "DEFSONG") == 0)
216 if (parse_dec(&defSong
, p
, 0, MAX_SONGS
) == false)
219 else if (strcmp(line
, "STEREO") == 0)
223 else if (strcmp(line
, "TIME") == 0)
225 int durationTemp
= ASAP_ParseDuration(p
);
226 if (durationTemp
< 0 || duration_index
>= MAX_SONGS
)
228 durations
[duration_index
] = durationTemp
;
229 if (strstr(p
, "LOOP") != NULL
)
230 loops
[duration_index
] = 1;
236 int length
= durations
[defSong
];
239 id3
->length
= length
;
241 lseek(fd
, 0, SEEK_SET
);
246 bool get_asap_metadata(int fd
, struct mp3entry
* id3
)
249 int filelength
= filesize(fd
);
251 if(parse_sap_header(fd
, id3
, filelength
) == false)
253 DEBUGF("parse sap header failed.\n");
258 id3
->frequency
= 44100;
261 id3
->filesize
= filelength
;