text/plain
•
2.13 KB
•
69 lines
#include "audio_metadata.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Implemented in metadata/
bool parse_m4a(const char *path, audio_metadata_t *meta);
bool parse_mp3(const char *path, audio_metadata_t *meta);
bool parse_wav(const char *path, audio_metadata_t *meta);
bool parse_flac(const char *path, audio_metadata_t *meta);
bool parse_ogg(const char *path, audio_metadata_t *meta);
// Helper to get file extension (lowercase)
static const char *get_extension(const char *path) {
const char *dot = strrchr(path, '.');
return dot ? dot + 1 : "";
}
// Helper to extract filename without extension for fallback title
static void extract_filename(const char *path, char *buf, size_t buf_size) {
const char *name = strrchr(path, '/');
name = name ? name + 1 : path;
const char *dot = strrchr(name, '.');
size_t len = dot ? (size_t)(dot - name) : strlen(name);
if (len >= buf_size)
len = buf_size - 1;
memcpy(buf, name, len);
buf[len] = '\0';
}
bool audio_metadata_get(const char *path, audio_metadata_t *meta) {
if (!path || !meta)
return false;
// Initialize metadata
memset(meta, 0, sizeof(*meta));
// Set filename as fallback title
extract_filename(path, meta->title, sizeof(meta->title));
// Get extension
const char *ext = get_extension(path);
// Dispatch to format-specific parser
bool success = false;
if (strcasecmp(ext, "mp3") == 0) {
success = parse_mp3(path, meta);
} else if (strcasecmp(ext, "m4a") == 0 || strcasecmp(ext, "m4b") == 0 ||
strcasecmp(ext, "mp4") == 0 || strcasecmp(ext, "aac") == 0) {
success = parse_m4a(path, meta);
} else if (strcasecmp(ext, "wav") == 0) {
success = parse_wav(path, meta);
} else if (strcasecmp(ext, "flac") == 0) {
success = parse_flac(path, meta);
} else if (strcasecmp(ext, "ogg") == 0 || strcasecmp(ext, "opus") == 0 || strcasecmp(ext, "opu") == 0) {
success = parse_ogg(path, meta);
}
// If parsing failed but we have a filename, still return partial success
if (!success && meta->title[0] != '\0') {
meta->valid = false; // Indicate metadata is incomplete
}
return success;
}