Login
1 branch 0 tags
Ben (Desktop/Arch) Improved sdkconfig cf03f41 1 month ago 25 Commits
moon / firmware / src / audio_metadata.c
#include "audio_metadata.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// Implemented in metadata/
bool parse_m4a(const char *path, audio_metadata_t *meta);
bool parse_mp3(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, "mp4") == 0 ||
               strcasecmp(ext, "aac") == 0) {
        success = parse_m4a(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;
}