diff options
Diffstat (limited to 'apps/metadata.c')
-rw-r--r-- | apps/metadata.c | 130 |
1 files changed, 128 insertions, 2 deletions
diff --git a/apps/metadata.c b/apps/metadata.c index 46b9482bc7..e88603721b 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | #if CONFIG_CODEC == SWCODEC | 34 | #if CONFIG_CODEC == SWCODEC |
35 | 35 | ||
36 | /* For trailing tag stripping */ | 36 | /* For trailing tag stripping and base audio data types */ |
37 | #include "buffering.h" | 37 | #include "buffering.h" |
38 | 38 | ||
39 | #include "metadata/metadata_common.h" | 39 | #include "metadata/metadata_common.h" |
@@ -239,6 +239,94 @@ const int afmt_rec_format[AFMT_NUM_CODECS] = | |||
239 | }; | 239 | }; |
240 | #endif /* CONFIG_CODEC == SWCODEC && defined (HAVE_RECORDING) */ | 240 | #endif /* CONFIG_CODEC == SWCODEC && defined (HAVE_RECORDING) */ |
241 | 241 | ||
242 | #if CONFIG_CODEC == SWCODEC | ||
243 | /* Get the canonical AFMT type */ | ||
244 | int get_audio_base_codec_type(int type) | ||
245 | { | ||
246 | int base_type = type; | ||
247 | switch (type) { | ||
248 | case AFMT_MPA_L1: | ||
249 | case AFMT_MPA_L2: | ||
250 | case AFMT_MPA_L3: | ||
251 | base_type = AFMT_MPA_L3; | ||
252 | break; | ||
253 | case AFMT_MPC_SV7: | ||
254 | case AFMT_MPC_SV8: | ||
255 | base_type = AFMT_MPC_SV7; | ||
256 | break; | ||
257 | case AFMT_MP4_AAC: | ||
258 | case AFMT_MP4_AAC_HE: | ||
259 | base_type = AFMT_MP4_AAC; | ||
260 | break; | ||
261 | case AFMT_SAP: | ||
262 | case AFMT_CMC: | ||
263 | case AFMT_CM3: | ||
264 | case AFMT_CMR: | ||
265 | case AFMT_CMS: | ||
266 | case AFMT_DMC: | ||
267 | case AFMT_DLT: | ||
268 | case AFMT_MPT: | ||
269 | case AFMT_MPD: | ||
270 | case AFMT_RMT: | ||
271 | case AFMT_TMC: | ||
272 | case AFMT_TM8: | ||
273 | case AFMT_TM2: | ||
274 | base_type = AFMT_SAP; | ||
275 | break; | ||
276 | default: | ||
277 | break; | ||
278 | } | ||
279 | |||
280 | return base_type; | ||
281 | } | ||
282 | |||
283 | /* Get the basic audio type */ | ||
284 | enum data_type get_audio_base_data_type(int afmt) | ||
285 | { | ||
286 | if ((unsigned)afmt >= AFMT_NUM_CODECS) | ||
287 | return TYPE_UNKNOWN; | ||
288 | |||
289 | switch (get_audio_base_codec_type(afmt)) | ||
290 | { | ||
291 | case AFMT_NSF: | ||
292 | case AFMT_SPC: | ||
293 | case AFMT_SID: | ||
294 | case AFMT_MOD: | ||
295 | case AFMT_SAP: | ||
296 | /* Type must be allocated and loaded in its entirety onto | ||
297 | the buffer */ | ||
298 | return TYPE_ATOMIC_AUDIO; | ||
299 | |||
300 | default: | ||
301 | /* Assume type may be loaded and discarded incrementally */ | ||
302 | return TYPE_PACKET_AUDIO; | ||
303 | |||
304 | case AFMT_UNKNOWN: | ||
305 | /* Have no idea at all */ | ||
306 | return TYPE_UNKNOWN; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | /* Is the format allowed to buffer starting at some offset other than 0 | ||
311 | or first frame only for resume purposes? */ | ||
312 | bool format_buffers_with_offset(int afmt) | ||
313 | { | ||
314 | switch (afmt) | ||
315 | { | ||
316 | case AFMT_MPA_L1: | ||
317 | case AFMT_MPA_L2: | ||
318 | case AFMT_MPA_L3: | ||
319 | case AFMT_WAVPACK: | ||
320 | /* Format may be loaded at the first needed frame */ | ||
321 | return true; | ||
322 | default: | ||
323 | /* Format must be loaded from the beginning of the file | ||
324 | (does not imply 'atomic', while 'atomic' implies 'no offset') */ | ||
325 | return false; | ||
326 | } | ||
327 | } | ||
328 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
329 | |||
242 | 330 | ||
243 | /* Simple file type probing by looking at the filename extension. */ | 331 | /* Simple file type probing by looking at the filename extension. */ |
244 | unsigned int probe_file_format(const char *filename) | 332 | unsigned int probe_file_format(const char *filename) |
@@ -313,7 +401,7 @@ bool get_metadata(struct mp3entry* id3, int fd, const char* trackname) | |||
313 | } | 401 | } |
314 | 402 | ||
315 | /* Clear the mp3entry to avoid having bogus pointers appear */ | 403 | /* Clear the mp3entry to avoid having bogus pointers appear */ |
316 | memset(id3, 0, sizeof(struct mp3entry)); | 404 | wipe_mp3entry(id3); |
317 | 405 | ||
318 | /* Take our best guess at the codec type based on file extension */ | 406 | /* Take our best guess at the codec type based on file extension */ |
319 | id3->codectype = probe_file_format(trackname); | 407 | id3->codectype = probe_file_format(trackname); |
@@ -414,6 +502,44 @@ void copy_mp3entry(struct mp3entry *dest, const struct mp3entry *orig) | |||
414 | adjust_mp3entry(dest, dest, orig); | 502 | adjust_mp3entry(dest, dest, orig); |
415 | } | 503 | } |
416 | 504 | ||
505 | /* A shortcut to simplify the common task of clearing the struct */ | ||
506 | void wipe_mp3entry(struct mp3entry *id3) | ||
507 | { | ||
508 | memset(id3, 0, sizeof (struct mp3entry)); | ||
509 | } | ||
510 | |||
511 | #if CONFIG_CODEC == SWCODEC | ||
512 | /* Glean what is possible from the filename alone - does not parse metadata */ | ||
513 | void fill_metadata_from_path(struct mp3entry *id3, const char *trackname) | ||
514 | { | ||
515 | char *p; | ||
516 | |||
517 | /* Clear the mp3entry to avoid having bogus pointers appear */ | ||
518 | wipe_mp3entry(id3); | ||
519 | |||
520 | /* Find the filename portion of the path */ | ||
521 | p = strrchr(trackname, '/'); | ||
522 | strlcpy(id3->id3v2buf, p ? ++p : id3->path, ID3V2_BUF_SIZE); | ||
523 | |||
524 | /* Get the format from the extension and trim it off */ | ||
525 | p = strrchr(id3->id3v2buf, '.'); | ||
526 | if (p) | ||
527 | { | ||
528 | /* Might be wrong for container formats - should we bother? */ | ||
529 | id3->codectype = probe_file_format(p); | ||
530 | |||
531 | if (id3->codectype != AFMT_UNKNOWN) | ||
532 | *p = '\0'; | ||
533 | } | ||
534 | |||
535 | /* Set the filename as the title */ | ||
536 | id3->title = id3->id3v2buf; | ||
537 | |||
538 | /* Copy the path info */ | ||
539 | strlcpy(id3->path, trackname, sizeof (id3->path)); | ||
540 | } | ||
541 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
542 | |||
417 | #ifndef __PCTOOL__ | 543 | #ifndef __PCTOOL__ |
418 | #ifdef HAVE_TAGCACHE | 544 | #ifdef HAVE_TAGCACHE |
419 | #if CONFIG_CODEC == SWCODEC | 545 | #if CONFIG_CODEC == SWCODEC |