/* * Copyright 2013 (c) Anna Schumaker. */ #include #include #include #include #include #include #include static bool player_playing = false; static bool track_loaded = false; static unsigned int cur_trackid = 0; static bool o_pause_enabled = false; static unsigned int o_pause_count = 0; static bool o_should_pause = false; static File f_cur_track("cur_track", 0); static void handle_pause_count() { if (o_pause_enabled == false) return; else if (o_pause_count == 0) { o_should_pause = true; o_pause_enabled = false; get_callbacks()->on_pause(); } else o_pause_count--; get_callbacks()->on_pause_count_changed(o_pause_enabled, o_pause_count); } static void on_error() { audio :: next(); audio :: play(); } static void on_eos() { Track *track; handle_pause_count(); track = tagdb :: lookup(cur_trackid); if (track) { track->played(); library :: get_queue()->updated(track); } audio :: next(); audio :: seek_to(0); } static void save_state() { f_cur_track.open(OPEN_WRITE); f_cur_track << cur_trackid << std::endl; f_cur_track.close(); } static bool load_song(Track *track) { bool start_playback; if (o_should_pause) start_playback = false; else start_playback = driver :: get_driver()->is_playing(); driver :: get_driver()->load(track->path()); get_callbacks()->on_track_loaded(track); if (start_playback) return driver :: get_driver()->play(); else return driver :: get_driver()->pause(); } void audio :: init(int *argc, char ***argv) { driver :: get_driver()->init(argc, argv, on_eos, on_error); } void audio :: load_state() { unsigned int id; if (f_cur_track.exists()) { f_cur_track.open(OPEN_READ); f_cur_track >> id; f_cur_track.close(); audio :: load_trackid(id); } } void audio :: quit() { } void audio :: play() { if (track_loaded == false) return; if (driver :: get_driver()->play()) get_callbacks()->on_play(); } void audio :: pause() { if (track_loaded == false) return; if (driver :: get_driver()->pause()) get_callbacks()->on_pause(); } void audio :: toggle_play() { if (player_playing == true) pause(); else play(); } void audio :: stop() { pause(); seek_to(0); } void audio :: seek_to(long pos) { if (track_loaded == false) return; driver :: get_driver()->seek_to(pos); } void audio :: next() { Track *track; track_loaded = false; track = deck :: next(); load_song(track); track_loaded = true; cur_trackid = track->id; save_state(); } void audio :: previous() { Track *track = deck :: prev(); if (track->id == cur_trackid) return; load_song(track); cur_trackid = track->id; save_state(); } void audio :: load_trackid(unsigned int track_id) { Track *track; if ((track_id == cur_trackid) && (track_loaded == true)) return; track_loaded = false; try { track = tagdb :: lookup(track_id); } catch (int err) { return; } load_song(track); track_loaded = true; cur_trackid = track_id; save_state(); deck :: get_queue()->add(track); } unsigned int audio :: current_trackid() { if (track_loaded == false) throw -E_EXIST; return cur_trackid; } long audio :: position() { if (track_loaded == false) return 0; return driver :: get_driver()->position(); } std::string audio :: position_str() { std::stringstream ss; long cur = position() / GST_SECOND; unsigned int minutes = cur / 60; unsigned int seconds = cur % 60; ss << minutes << ":"; if (seconds < 10) ss << "0"; ss << seconds; return ss.str(); } long audio :: duration() { if (track_loaded == false) return 0; return driver :: get_driver()->duration(); } void audio :: pause_after(bool enabled, unsigned int n) { if (n > o_pause_count) enabled = true; o_pause_enabled = enabled; o_pause_count = n; get_callbacks()->on_pause_count_changed(enabled, n); } bool audio :: pause_enabled() { return o_pause_enabled; } unsigned int audio :: pause_count() { return o_pause_count; }