2014-09-12 16:08:58 -04:00
|
|
|
/**
|
|
|
|
* @file
|
2013-12-24 20:17:44 -05:00
|
|
|
* Copyright 2013 (c) Anna Schumaker.
|
|
|
|
*/
|
2014-06-05 10:19:22 -04:00
|
|
|
#include <core/audio.h>
|
|
|
|
#include <core/callback.h>
|
|
|
|
#include <core/deck.h>
|
|
|
|
#include <core/driver.h>
|
2013-12-24 20:17:44 -05:00
|
|
|
|
2014-01-22 22:31:42 -05:00
|
|
|
#include <sstream>
|
2013-12-24 20:17:44 -05:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
static bool _pause_enabled = false;
|
|
|
|
static unsigned int _pause_count = 0;
|
2013-12-25 14:35:33 -05:00
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
static Track *cur_track = NULL;
|
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-12-19 14:37:47 -05:00
|
|
|
static Driver *cur_driver = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
Driver :: Driver()
|
|
|
|
{
|
|
|
|
cur_driver = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Driver :: ~Driver()
|
|
|
|
{
|
|
|
|
cur_driver = NULL;
|
|
|
|
}
|
|
|
|
|
2014-05-11 10:53:48 -04:00
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
static void save_state()
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
2014-06-01 17:52:49 -04:00
|
|
|
f_cur_track.open(OPEN_WRITE);
|
2014-11-02 10:02:35 -05:00
|
|
|
f_cur_track << cur_track->index() << std::endl;
|
2014-06-01 17:52:49 -04:00
|
|
|
f_cur_track.close();
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
static void _load_track(Track *track, bool start_playback)
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
2014-06-01 17:52:49 -04:00
|
|
|
cur_track = track;
|
|
|
|
if (!track)
|
|
|
|
return;
|
2014-05-31 20:52:40 -04:00
|
|
|
|
2014-12-19 14:53:42 -05:00
|
|
|
cur_driver->load(track->path());
|
2014-06-01 17:52:49 -04:00
|
|
|
get_callbacks()->on_track_loaded(track);
|
|
|
|
if (start_playback)
|
|
|
|
audio :: play();
|
|
|
|
else
|
|
|
|
audio :: pause();
|
|
|
|
save_state();
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
static inline void _load_track_default(Track *track)
|
2014-04-01 21:00:30 -04:00
|
|
|
{
|
2014-12-19 14:53:42 -05:00
|
|
|
_load_track(track, cur_driver->is_playing());
|
2014-04-01 21:00:30 -04:00
|
|
|
}
|
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
static bool continue_playback()
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
2014-06-01 17:52:49 -04:00
|
|
|
bool ret = true;
|
2013-12-24 20:17:44 -05:00
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
if (_pause_enabled) {
|
|
|
|
if (_pause_count == 0) {
|
|
|
|
ret = false;
|
|
|
|
_pause_enabled = false;
|
|
|
|
} else
|
|
|
|
_pause_count--;
|
|
|
|
get_callbacks()->on_pause_count_changed(_pause_enabled, _pause_count);
|
|
|
|
}
|
2014-05-31 20:52:40 -04:00
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
return ret;
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
static void on_eos()
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
2014-06-01 17:52:49 -04:00
|
|
|
if (cur_track) {
|
|
|
|
cur_track->played();
|
|
|
|
library :: get_queue()->updated(cur_track);
|
|
|
|
}
|
|
|
|
|
|
|
|
_load_track(deck :: next(), continue_playback());
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-12-20 10:16:44 -05:00
|
|
|
void audio :: init()
|
2014-04-01 21:00:30 -04:00
|
|
|
{
|
|
|
|
unsigned int id;
|
2014-06-01 17:52:49 -04:00
|
|
|
|
2014-12-20 10:16:44 -05:00
|
|
|
cur_driver->init(on_eos);
|
2014-04-01 21:00:30 -04:00
|
|
|
if (f_cur_track.exists()) {
|
|
|
|
f_cur_track.open(OPEN_READ);
|
|
|
|
f_cur_track >> id;
|
|
|
|
f_cur_track.close();
|
2014-12-02 08:16:22 -05:00
|
|
|
audio :: load_track(tags :: get_track(id));
|
2014-04-01 21:00:30 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-04 13:09:44 -05:00
|
|
|
void audio :: play()
|
2013-12-24 20:17:44 -05:00
|
|
|
{
|
2014-09-08 17:25:56 -04:00
|
|
|
if (cur_track)
|
2014-12-19 14:53:42 -05:00
|
|
|
cur_driver->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
|
|
|
{
|
2014-09-10 08:24:34 -04:00
|
|
|
if (cur_track)
|
2014-12-19 14:53:42 -05:00
|
|
|
cur_driver->pause();
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-01-04 13:09:44 -05:00
|
|
|
void audio :: seek_to(long pos)
|
2013-12-24 22:07:23 -05:00
|
|
|
{
|
2014-06-01 17:52:49 -04:00
|
|
|
if (!cur_track)
|
2014-01-04 13:09:44 -05:00
|
|
|
return;
|
2014-12-19 14:53:42 -05:00
|
|
|
cur_driver->seek_to(pos);
|
2013-12-24 20:17:44 -05:00
|
|
|
}
|
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
void audio :: stop()
|
2014-01-26 12:42:13 -05:00
|
|
|
{
|
2014-06-01 17:52:49 -04:00
|
|
|
pause();
|
|
|
|
seek_to(0);
|
2014-01-26 12:42:13 -05:00
|
|
|
}
|
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
long audio :: position()
|
2013-12-24 22:07:23 -05:00
|
|
|
{
|
2014-06-01 17:52:49 -04:00
|
|
|
if (!cur_track)
|
|
|
|
return 0;
|
2014-12-19 14:53:42 -05:00
|
|
|
return cur_driver->position();
|
2013-12-24 22:07:23 -05:00
|
|
|
}
|
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
long audio :: duration()
|
2013-12-24 22:07:23 -05:00
|
|
|
{
|
2014-06-01 17:52:49 -04:00
|
|
|
if (!cur_track)
|
2013-12-24 22:07:23 -05:00
|
|
|
return 0;
|
2014-12-19 14:53:42 -05:00
|
|
|
return cur_driver->duration();
|
2013-12-24 22:07:23 -05:00
|
|
|
}
|
|
|
|
|
2014-01-22 22:31:42 -05:00
|
|
|
std::string audio :: position_str()
|
|
|
|
{
|
|
|
|
std::stringstream ss;
|
2014-06-01 17:52:49 -04:00
|
|
|
long cur = position() / O_SECOND;
|
2014-01-22 22:31:42 -05:00
|
|
|
unsigned int minutes = cur / 60;
|
|
|
|
unsigned int seconds = cur % 60;
|
|
|
|
|
|
|
|
ss << minutes << ":";
|
|
|
|
if (seconds < 10)
|
|
|
|
ss << "0";
|
|
|
|
ss << seconds;
|
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
void audio :: next()
|
2013-12-24 22:07:23 -05:00
|
|
|
{
|
2014-06-01 17:52:49 -04:00
|
|
|
_load_track_default(deck :: next());
|
|
|
|
}
|
|
|
|
|
|
|
|
void audio :: prev()
|
|
|
|
{
|
|
|
|
_load_track_default(deck :: prev());
|
|
|
|
}
|
|
|
|
|
|
|
|
void audio :: load_track(Track *track)
|
|
|
|
{
|
|
|
|
if (!track || track == cur_track)
|
|
|
|
return;
|
|
|
|
|
2014-12-19 14:53:42 -05:00
|
|
|
_load_track(track, cur_driver->is_playing());
|
2014-06-01 17:52:49 -04:00
|
|
|
deck :: get_queue()->add(cur_track);
|
|
|
|
}
|
|
|
|
|
|
|
|
Track *audio :: current_track()
|
|
|
|
{
|
|
|
|
return cur_track;
|
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-06-01 17:52:49 -04:00
|
|
|
if (n > _pause_count)
|
2014-01-24 09:20:08 -05:00
|
|
|
enabled = true;
|
|
|
|
|
2014-06-01 17:52:49 -04:00
|
|
|
_pause_enabled = enabled;
|
|
|
|
_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()
|
|
|
|
{
|
2014-06-01 17:52:49 -04:00
|
|
|
return _pause_enabled;
|
2013-12-25 14:35:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int audio :: pause_count()
|
|
|
|
{
|
2014-06-01 17:52:49 -04:00
|
|
|
return _pause_count;
|
2013-12-25 14:35:33 -05:00
|
|
|
}
|
2014-12-19 14:53:42 -05:00
|
|
|
|
|
|
|
Driver *audio :: get_driver()
|
|
|
|
{
|
|
|
|
return cur_driver;
|
|
|
|
}
|