1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Dave Chapman
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
32 #if CONFIG_CODEC == SWCODEC
34 /* For trailing tag stripping */
35 #include "buffering.h"
37 #include "metadata/metadata_common.h"
38 #include "metadata/metadata_parsers.h"
40 #endif /* CONFIG_CODEC == SWCODEC */
43 /* Simple file type probing by looking at the filename extension. */
44 unsigned int probe_file_format(const char *filename
)
49 suffix
= strrchr(filename
, '.');
59 for (i
= 1; i
< AFMT_NUM_CODECS
; i
++)
61 /* search extension list for type */
62 const char *ext
= audio_formats
[i
].ext_list
;
66 if (strcasecmp(suffix
, ext
) == 0)
71 ext
+= strlen(ext
) + 1;
79 /* Get metadata for track - return false if parsing showed problems with the
80 * file that would prevent playback.
82 bool get_metadata(struct mp3entry
* id3
, int fd
, const char* trackname
)
84 #if CONFIG_CODEC == SWCODEC
88 /* Clear the mp3entry to avoid having bogus pointers appear */
89 memset(id3
, 0, sizeof(struct mp3entry
));
91 /* Take our best guess at the codec type based on file extension */
92 id3
->codectype
= probe_file_format(trackname
);
94 /* Load codec specific track tag information and confirm the codec type. */
95 switch (id3
->codectype
)
100 if (!get_mp3_metadata(fd
, id3
, trackname
))
107 #if CONFIG_CODEC == SWCODEC
109 if (!get_flac_metadata(fd
, id3
))
117 if (!get_asf_metadata(fd
, id3
))
124 if (!get_monkeys_metadata(fd
, id3
))
128 read_ape_tags(fd
, id3
);
132 if (!get_musepack_metadata(fd
, id3
))
134 read_ape_tags(fd
, id3
);
137 case AFMT_OGG_VORBIS
:
138 if (!get_ogg_metadata(fd
, id3
))/*detects and handles Ogg/Speex files*/
146 if (!get_ogg_metadata(fd
, id3
))
154 if (!get_wave_metadata(fd
, id3
))
162 if (!get_wavpack_metadata(fd
, id3
))
167 read_ape_tags(fd
, id3
); /* use any apetag info we find */
171 if (!get_a52_metadata(fd
, id3
))
180 if (!get_mp4_metadata(fd
, id3
))
188 if (!get_mod_metadata(fd
, id3
))
197 id3
->filesize
= filesize(fd
);
198 if (!skip_id3v2(fd
, id3
))
202 /* TODO: read the id3v2 header if it exists */
206 if (!get_sid_metadata(fd
, id3
))
213 if (!get_spc_metadata(fd
, id3
))
215 DEBUGF("get_spc_metadata error\n");
218 id3
->filesize
= filesize(fd
);
219 id3
->genre_string
= id3_get_num_genre(36);
223 if (!get_adx_metadata(fd
, id3
))
225 DEBUGF("get_adx_metadata error\n");
232 buf
= (unsigned char *)id3
->path
;
233 if ((lseek(fd
, 0, SEEK_SET
) < 0) || ((read(fd
, buf
, 8)) < 8))
235 DEBUGF("lseek or read failed\n");
239 id3
->filesize
= filesize(fd
);
240 if (memcmp(buf
,"NESM",4) && memcmp(buf
,"NSFE",4)) return false;
244 if (!get_aiff_metadata(fd
, id3
))
251 #endif /* CONFIG_CODEC == SWCODEC */
254 /* If we don't know how to read the metadata, assume we can't play
260 /* We have successfully read the metadata from the file */
263 if (cuesheet_is_enabled() && look_for_cuesheet_file(trackname
, NULL
))
265 id3
->cuesheet_type
= 1;
269 lseek(fd
, 0, SEEK_SET
);
270 strncpy(id3
->path
, trackname
, sizeof(id3
->path
));
275 #if CONFIG_CODEC == SWCODEC
276 void strip_tags(int handle_id
)
278 static const unsigned char tag
[] = "TAG";
279 static const unsigned char apetag
[] = "APETAGEX";
283 if (bufgettail(handle_id
, 128, &tail
) != 128)
286 if (memcmp(tail
, tag
, 3) == 0)
289 logf("Cutting off ID3v1 tag");
290 bufcuttail(handle_id
, 128);
293 /* Get a new tail, as the old one may have been cut */
294 if (bufgettail(handle_id
, 32, &tail
) != 32)
297 /* Check for APE tag (look for the APE tag footer) */
298 if (memcmp(tail
, apetag
, 8) != 0)
301 /* Read the version and length from the footer */
302 version
= get_long_le(&((unsigned char *)tail
)[8]);
303 len
= get_long_le(&((unsigned char *)tail
)[12]);
305 len
+= 32; /* APEv2 has a 32 byte header */
308 logf("Cutting off APE tag (%ldB)", len
);
309 bufcuttail(handle_id
, len
);
311 #endif /* CONFIG_CODEC == SWCODEC */