Login
1 branch 0 tags
Ben (Desktop/Arch) Improved files handling a50a05f 1 month ago 21 Commits
moon / firmware / sdl_src / audio_player_sdl.c
#include "../src/audio_player.h"
#include <SDL.h>
#include <SDL_mixer.h>
#include <string.h>
#include <stdio.h>

static Mix_Music *current_music = NULL;
static audio_state_t current_state = AUDIO_STATE_STOPPED;
static uint8_t current_volume = 100;
static char current_filename[64] = {0};

bool audio_player_init(void) {
    if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) {
        fprintf(stderr, "SDL_mixer init failed: %s\n", Mix_GetError());
        return false;
    }
    return true;
}

bool audio_player_play(const char *path) {
    audio_player_stop();

    // Build path relative to sdcard directory
    char full_path[256];
    snprintf(full_path, sizeof(full_path), "./sdcard%s", path);

    current_music = Mix_LoadMUS(full_path);
    if (!current_music) {
        fprintf(stderr, "Failed to load %s: %s\n", full_path, Mix_GetError());
        return false;
    }

    // Extract filename for display
    const char *name = strrchr(path, '/');
    name = name ? name + 1 : path;
    strncpy(current_filename, name, sizeof(current_filename) - 1);
    current_filename[sizeof(current_filename) - 1] = '\0';

    // Set volume and play
    Mix_VolumeMusic((int)(current_volume * MIX_MAX_VOLUME / 100));
    if (Mix_PlayMusic(current_music, 0) < 0) {
        fprintf(stderr, "Failed to play: %s\n", Mix_GetError());
        Mix_FreeMusic(current_music);
        current_music = NULL;
        return false;
    }

    current_state = AUDIO_STATE_PLAYING;
    return true;
}

void audio_player_stop(void) {
    if (current_music) {
        Mix_HaltMusic();
        Mix_FreeMusic(current_music);
        current_music = NULL;
    }
    current_state = AUDIO_STATE_STOPPED;
    current_filename[0] = '\0';
}

void audio_player_pause(void) {
    if (current_state == AUDIO_STATE_PLAYING) {
        Mix_PauseMusic();
        current_state = AUDIO_STATE_PAUSED;
    }
}

void audio_player_resume(void) {
    if (current_state == AUDIO_STATE_PAUSED) {
        Mix_ResumeMusic();
        current_state = AUDIO_STATE_PLAYING;
    }
}

audio_state_t audio_player_get_state(void) {
    // Check if music finished playing
    if (current_state == AUDIO_STATE_PLAYING && !Mix_PlayingMusic()) {
        current_state = AUDIO_STATE_STOPPED;
        if (current_music) {
            Mix_FreeMusic(current_music);
            current_music = NULL;
        }
        current_filename[0] = '\0';
    }
    return current_state;
}

void audio_player_set_volume(uint8_t volume) {
    current_volume = volume > 100 ? 100 : volume;
    Mix_VolumeMusic((int)(current_volume * MIX_MAX_VOLUME / 100));
}

const char *audio_player_get_filename(void) {
    return current_filename[0] ? current_filename : NULL;
}

const char *audio_player_get_title(void) {
    // SDL version doesn't parse metadata, just return filename
    return current_filename[0] ? current_filename : NULL;
}

void audio_player_update(void) {
    // Check if music finished
    audio_player_get_state();
}

uint32_t audio_player_get_position_ms(void) {
    // SDL_mixer has Mix_GetMusicPosition but it's not reliable for all formats
    // Return 0 for now - focus on ESP32 implementation
    return 0;
}

uint32_t audio_player_get_duration_ms(void) {
    // SDL_mixer has Mix_MusicDuration but it's not available in all versions
    // Return 0 for now - focus on ESP32 implementation
    return 0;
}

uint8_t audio_player_get_progress(void) {
    // Return 0 for SDL - focus on ESP32 implementation
    return 0;
}