1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Dave Chapman
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 ****************************************************************************/
34 #if CONFIG_CODEC == SWCODEC
36 /* For trailing tag stripping */
37 #include "buffering.h"
39 #include "metadata/metadata_common.h"
40 #include "metadata/metadata_parsers.h"
42 #endif /* CONFIG_CODEC == SWCODEC */
45 /* Simple file type probing by looking at the filename extension. */
46 unsigned int probe_file_format(const char *filename
)
51 suffix
= strrchr(filename
, '.');
61 for (i
= 1; i
< AFMT_NUM_CODECS
; i
++)
63 /* search extension list for type */
64 const char *ext
= audio_formats
[i
].ext_list
;
68 if (strcasecmp(suffix
, ext
) == 0)
73 ext
+= strlen(ext
) + 1;
81 /* Get metadata for track - return false if parsing showed problems with the
82 * file that would prevent playback.
84 bool get_metadata(struct mp3entry
* id3
, int fd
, const char* trackname
)
86 #if CONFIG_CODEC == SWCODEC
90 /* Clear the mp3entry to avoid having bogus pointers appear */
91 memset(id3
, 0, sizeof(struct mp3entry
));
93 /* Take our best guess at the codec type based on file extension */
94 id3
->codectype
= probe_file_format(trackname
);
96 /* Load codec specific track tag information and confirm the codec type. */
97 switch (id3
->codectype
)
102 if (!get_mp3_metadata(fd
, id3
, trackname
))
109 #if CONFIG_CODEC == SWCODEC
111 if (!get_flac_metadata(fd
, id3
))
119 if (!get_asf_metadata(fd
, id3
))
126 if (!get_monkeys_metadata(fd
, id3
))
130 read_ape_tags(fd
, id3
);
134 if (!get_musepack_metadata(fd
, id3
))
136 read_ape_tags(fd
, id3
);
139 case AFMT_OGG_VORBIS
:
140 if (!get_ogg_metadata(fd
, id3
))/*detects and handles Ogg/Speex files*/
148 if (!get_ogg_metadata(fd
, id3
))
156 if (!get_wave_metadata(fd
, id3
))
164 if (!get_wavpack_metadata(fd
, id3
))
169 read_ape_tags(fd
, id3
); /* use any apetag info we find */
173 if (!get_a52_metadata(fd
, id3
))
182 if (!get_mp4_metadata(fd
, id3
))
190 if (!get_mod_metadata(fd
, id3
))
199 id3
->filesize
= filesize(fd
);
200 if (!skip_id3v2(fd
, id3
))
204 /* TODO: read the id3v2 header if it exists */
208 if (!get_sid_metadata(fd
, id3
))
215 if (!get_spc_metadata(fd
, id3
))
217 DEBUGF("get_spc_metadata error\n");
220 id3
->filesize
= filesize(fd
);
221 id3
->genre_string
= id3_get_num_genre(36);
225 if (!get_adx_metadata(fd
, id3
))
227 DEBUGF("get_adx_metadata error\n");
234 buf
= (unsigned char *)id3
->path
;
235 if ((lseek(fd
, 0, SEEK_SET
) < 0) || ((read(fd
, buf
, 8)) < 8))
237 DEBUGF("lseek or read failed\n");
241 id3
->filesize
= filesize(fd
);
242 if (memcmp(buf
,"NESM",4) && memcmp(buf
,"NSFE",4)) return false;
246 if (!get_aiff_metadata(fd
, id3
))
253 #endif /* CONFIG_CODEC == SWCODEC */
256 /* If we don't know how to read the metadata, assume we can't play
262 /* We have successfully read the metadata from the file */
265 if (cuesheet_is_enabled() && look_for_cuesheet_file(trackname
, NULL
))
267 id3
->cuesheet_type
= 1;
271 lseek(fd
, 0, SEEK_SET
);
272 strncpy(id3
->path
, trackname
, sizeof(id3
->path
));
277 #if CONFIG_CODEC == SWCODEC
278 void strip_tags(int handle_id
)
280 static const unsigned char tag
[] = "TAG";
281 static const unsigned char apetag
[] = "APETAGEX";
285 if (bufgettail(handle_id
, 128, &tail
) != 128)
288 if (memcmp(tail
, tag
, 3) == 0)
291 logf("Cutting off ID3v1 tag");
292 bufcuttail(handle_id
, 128);
295 /* Get a new tail, as the old one may have been cut */
296 if (bufgettail(handle_id
, 32, &tail
) != 32)
299 /* Check for APE tag (look for the APE tag footer) */
300 if (memcmp(tail
, apetag
, 8) != 0)
303 /* Read the version and length from the footer */
304 version
= get_long_le(&((unsigned char *)tail
)[8]);
305 len
= get_long_le(&((unsigned char *)tail
)[12]);
307 len
+= 32; /* APEv2 has a 32 byte header */
310 logf("Cutting off APE tag (%ldB)", len
);
311 bufcuttail(handle_id
, len
);
313 #endif /* CONFIG_CODEC == SWCODEC */