ocarina/lib/audio.cpp

238 lines
3.9 KiB
C++
Raw Normal View History

/*
* Copyright 2013 (c) Anna Schumaker.
*/
#include <audio.h>
#include <callback.h>
#include <deck.h>
#include <driver.h>
#include <library.h>
#include <sstream>
#include <string.h>
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;
}