2013-12-24 20:17:44 -05:00
|
|
|
/*
|
|
|
|
* Copyright 2013 (c) Anna Schumaker.
|
|
|
|
*/
|
|
|
|
#include <audio.h>
|
2014-01-22 22:31:42 -05:00
|
|
|
#include <callback.h>
|
2013-12-24 20:17:44 -05:00
|
|
|
#include <deck.h>
|
2014-05-31 20:52:40 -04:00
|
|
|
#include <driver.h>
|
2013-12-24 20:17:44 -05:00
|
|
|
#include <library.h>
|
|
|
|
|
2014-01-22 22:31:42 -05:00
|
|
|
#include <sstream>
|
2013-12-24 20:17:44 -05:00
|
|
|
#include <string.h>
|
|
|
|
|
2014-01-30 21:25:36 -05:00
|
|
|
static bool player_playing = false;
|
2013-12-24 20:17:44 -05:00
|
|
|
static bool track_loaded = false;
|
2013-12-24 22:07:23 -05:00
|
|
|
static unsigned int cur_trackid = 0;
|
2013-12-24 20:17:44 -05:00
|
|
|
|
2013-12-25 14:35:33 -05:00
|
|
|
static bool o_pause_enabled = false;
|
2014-01-30 21:25:36 -05:00
|
|
|
static unsigned int o_pause_count = 0;
|
2013-12-25 14:35:33 -05:00
|
|
|
static bool o_should_pause = false;
|
|
|
|
|
2014-05-26 12:10:36 -04:00
|
|
|
static File f_cur_track("cur_track", 0);
|
2014-01-04 13:57:51 -05:00
|
|
|
|
2014-05-11 10:53:48 -04:00
|
|
|
|
2013-12-25 14:35:33 -05:00
|
|
|
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;
|
2014-01-24 16:22:55 -05:00
|
|
|
get_callbacks()->on_pause();
|
2013-12-25 14:35:33 -05:00
|
|
|
} else
|
|
|
|
o_pause_count--;
|
2014-01-24 09:20:08 -05:00
|
|
|
get_callbacks()->on_pause_count_changed(o_pause_enabled, o_pause_count);
|
2013-12-25 14:35:33 -05:00
|
|
|
}
|
|
|
|
|
2014-05-31 20:52:40 -04:00
|
|
|
static void on_error()
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
2014-05-31 20:52:40 -04:00
|
|
|
audio :: next();
|
|
|
|
audio :: play();
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-05-31 20:52:40 -04:00
|
|
|
static void on_eos()
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
2014-05-31 20:52:40 -04:00
|
|
|
Track *track;
|
|
|
|
|
|
|
|
handle_pause_count();
|
|
|
|
track = tagdb :: lookup(cur_trackid);
|
|
|
|
if (track) {
|
|
|
|
track->played();
|
|
|
|
library :: get_queue()->updated(track);
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
2014-05-31 20:52:40 -04:00
|
|
|
audio :: next();
|
|
|
|
audio :: seek_to(0);
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-04-01 21:00:30 -04:00
|
|
|
static void save_state()
|
|
|
|
{
|
|
|
|
f_cur_track.open(OPEN_WRITE);
|
|
|
|
f_cur_track << cur_trackid << std::endl;
|
|
|
|
f_cur_track.close();
|
|
|
|
}
|
|
|
|
|
2014-03-29 11:44:39 -04:00
|
|
|
static bool load_song(Track *track)
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
2014-05-31 20:52:40 -04:00
|
|
|
bool start_playback;
|
2013-12-24 20:17:44 -05:00
|
|
|
|
2014-05-31 20:52:40 -04:00
|
|
|
if (o_should_pause)
|
|
|
|
start_playback = false;
|
|
|
|
else
|
|
|
|
start_playback = driver :: get_driver()->is_playing();
|
2013-12-24 20:17:44 -05:00
|
|
|
|
2014-05-31 20:52:40 -04:00
|
|
|
driver :: get_driver()->load(track->path());
|
2014-03-29 11:44:39 -04:00
|
|
|
get_callbacks()->on_track_loaded(track);
|
2014-05-31 20:52:40 -04:00
|
|
|
|
|
|
|
if (start_playback)
|
|
|
|
return driver :: get_driver()->play();
|
|
|
|
else
|
|
|
|
return driver :: get_driver()->pause();
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void audio :: init(int *argc, char ***argv)
|
|
|
|
{
|
2014-05-31 20:52:40 -04:00
|
|
|
driver :: get_driver()->init(argc, argv, on_eos, on_error);
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-04-01 21:00:30 -04:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-25 14:35:33 -05:00
|
|
|
void audio :: quit()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-01-04 13:09:44 -05:00
|
|
|
void audio :: play()
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
|
|
|
if (track_loaded == false)
|
2014-01-04 13:09:44 -05:00
|
|
|
return;
|
2014-05-31 20:52:40 -04:00
|
|
|
if (driver :: get_driver()->play())
|
2014-01-22 22:31:42 -05:00
|
|
|
get_callbacks()->on_play();
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-01-04 13:09:44 -05:00
|
|
|
void audio :: pause()
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
|
|
|
if (track_loaded == false)
|
2014-01-04 13:09:44 -05:00
|
|
|
return;
|
2014-05-31 20:52:40 -04:00
|
|
|
if (driver :: get_driver()->pause())
|
2014-01-22 22:31:42 -05:00
|
|
|
get_callbacks()->on_pause();
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-01-30 21:25:36 -05:00
|
|
|
void audio :: toggle_play()
|
|
|
|
{
|
|
|
|
if (player_playing == true)
|
|
|
|
pause();
|
|
|
|
else
|
|
|
|
play();
|
|
|
|
}
|
|
|
|
|
2014-01-04 13:09:44 -05:00
|
|
|
void audio :: stop()
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
2014-01-04 13:09:44 -05:00
|
|
|
pause();
|
|
|
|
seek_to(0);
|
2013-12-24 22:07:23 -05:00
|
|
|
}
|
|
|
|
|
2014-01-04 13:09:44 -05:00
|
|
|
void audio :: seek_to(long pos)
|
2013-12-24 22:07:23 -05:00
|
|
|
{
|
2013-12-24 20:17:44 -05:00
|
|
|
if (track_loaded == false)
|
2014-01-04 13:09:44 -05:00
|
|
|
return;
|
2014-05-31 20:52:40 -04:00
|
|
|
driver :: get_driver()->seek_to(pos);
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-01-04 13:09:44 -05:00
|
|
|
void audio :: next()
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
2014-03-29 11:44:39 -04:00
|
|
|
Track *track;
|
2013-12-24 22:07:23 -05:00
|
|
|
|
2014-01-04 13:09:44 -05:00
|
|
|
track_loaded = false;
|
2014-04-13 12:26:32 -04:00
|
|
|
track = deck :: next();
|
2014-03-29 11:44:39 -04:00
|
|
|
load_song(track);
|
2014-01-04 13:09:44 -05:00
|
|
|
track_loaded = true;
|
2014-01-04 13:57:51 -05:00
|
|
|
|
2014-04-13 12:26:32 -04:00
|
|
|
cur_trackid = track->id;
|
2014-04-01 21:00:30 -04:00
|
|
|
save_state();
|
2014-01-04 13:57:51 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void audio :: previous()
|
|
|
|
{
|
2014-05-26 22:32:19 -04:00
|
|
|
Track *track = deck :: prev();
|
2014-04-13 12:26:32 -04:00
|
|
|
if (track->id == cur_trackid)
|
2014-01-04 13:57:51 -05:00
|
|
|
return;
|
|
|
|
|
2014-03-29 11:44:39 -04:00
|
|
|
load_song(track);
|
2014-04-13 12:26:32 -04:00
|
|
|
cur_trackid = track->id;
|
2014-04-01 21:00:30 -04:00
|
|
|
save_state();
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
2013-12-24 22:07:23 -05:00
|
|
|
|
2014-01-26 12:42:13 -05:00
|
|
|
void audio :: load_trackid(unsigned int track_id)
|
|
|
|
{
|
2014-03-29 11:44:39 -04:00
|
|
|
Track *track;
|
2014-01-26 12:42:13 -05:00
|
|
|
|
2014-04-01 21:00:30 -04:00
|
|
|
if ((track_id == cur_trackid) && (track_loaded == true))
|
2014-01-26 12:42:13 -05:00
|
|
|
return;
|
|
|
|
|
|
|
|
track_loaded = false;
|
2014-04-09 19:32:46 -04:00
|
|
|
try {
|
2014-03-29 11:44:39 -04:00
|
|
|
track = tagdb :: lookup(track_id);
|
2014-04-09 19:32:46 -04:00
|
|
|
} catch (int err) {
|
|
|
|
return;
|
|
|
|
}
|
2014-03-29 11:44:39 -04:00
|
|
|
load_song(track);
|
2014-01-26 12:42:13 -05:00
|
|
|
track_loaded = true;
|
|
|
|
|
|
|
|
cur_trackid = track_id;
|
2014-04-01 21:00:30 -04:00
|
|
|
save_state();
|
2014-05-26 22:32:19 -04:00
|
|
|
deck :: get_queue()->add(track);
|
2014-01-26 12:42:13 -05:00
|
|
|
}
|
|
|
|
|
2013-12-24 22:07:23 -05:00
|
|
|
unsigned int audio :: current_trackid()
|
|
|
|
{
|
|
|
|
if (track_loaded == false)
|
2014-01-04 13:09:44 -05:00
|
|
|
throw -E_EXIST;
|
2013-12-24 22:07:23 -05:00
|
|
|
return cur_trackid;
|
|
|
|
}
|
|
|
|
|
|
|
|
long audio :: position()
|
|
|
|
{
|
|
|
|
if (track_loaded == false)
|
|
|
|
return 0;
|
2014-05-31 20:52:40 -04:00
|
|
|
return driver :: get_driver()->position();
|
2013-12-24 22:07:23 -05:00
|
|
|
}
|
|
|
|
|
2014-01-22 22:31:42 -05:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2013-12-24 22:07:23 -05:00
|
|
|
long audio :: duration()
|
|
|
|
{
|
|
|
|
if (track_loaded == false)
|
|
|
|
return 0;
|
2014-05-31 20:52:40 -04:00
|
|
|
return driver :: get_driver()->duration();
|
2013-12-24 22:07:23 -05:00
|
|
|
}
|
2013-12-25 14:35:33 -05:00
|
|
|
|
|
|
|
void audio :: pause_after(bool enabled, unsigned int n)
|
|
|
|
{
|
2014-01-24 09:20:08 -05:00
|
|
|
if (n > o_pause_count)
|
|
|
|
enabled = true;
|
|
|
|
|
2013-12-25 14:35:33 -05:00
|
|
|
o_pause_enabled = enabled;
|
|
|
|
o_pause_count = n;
|
2014-01-24 09:20:08 -05:00
|
|
|
get_callbacks()->on_pause_count_changed(enabled, n);
|
2013-12-25 14:35:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
bool audio :: pause_enabled()
|
|
|
|
{
|
|
|
|
return o_pause_enabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int audio :: pause_count()
|
|
|
|
{
|
|
|
|
return o_pause_count;
|
|
|
|
}
|