1bfa299e08
This patch reworks the unit test using the TestDriver audio driver. I also recode the audio layer to match the design and drastically clean up the code. Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
186 lines
3.0 KiB
C++
186 lines
3.0 KiB
C++
/*
|
|
* Copyright 2013 (c) Anna Schumaker.
|
|
*/
|
|
#include <audio.h>
|
|
#include <callback.h>
|
|
#include <deck.h>
|
|
#include <driver.h>
|
|
|
|
#include <sstream>
|
|
#include <string.h>
|
|
|
|
|
|
static bool _pause_enabled = false;
|
|
static unsigned int _pause_count = 0;
|
|
|
|
static Track *cur_track = NULL;
|
|
static File f_cur_track("cur_track", 0);
|
|
|
|
|
|
static void save_state()
|
|
{
|
|
f_cur_track.open(OPEN_WRITE);
|
|
f_cur_track << cur_track->id << std::endl;
|
|
f_cur_track.close();
|
|
}
|
|
|
|
static void _load_track(Track *track, bool start_playback)
|
|
{
|
|
cur_track = track;
|
|
if (!track)
|
|
return;
|
|
|
|
driver :: get_driver()->load(track->path());
|
|
get_callbacks()->on_track_loaded(track);
|
|
if (start_playback)
|
|
audio :: play();
|
|
else
|
|
audio :: pause();
|
|
save_state();
|
|
}
|
|
|
|
static inline void _load_track_default(Track *track)
|
|
{
|
|
_load_track(track, driver :: get_driver()->is_playing());
|
|
}
|
|
|
|
static bool continue_playback()
|
|
{
|
|
bool ret = true;
|
|
|
|
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);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void on_eos()
|
|
{
|
|
if (cur_track) {
|
|
cur_track->played();
|
|
library :: get_queue()->updated(cur_track);
|
|
}
|
|
|
|
_load_track(deck :: next(), continue_playback());
|
|
}
|
|
|
|
void audio :: init(int *argc, char ***argv)
|
|
{
|
|
unsigned int id;
|
|
|
|
driver :: get_driver()->init(argc, argv, on_eos, audio :: next);
|
|
if (f_cur_track.exists()) {
|
|
f_cur_track.open(OPEN_READ);
|
|
f_cur_track >> id;
|
|
f_cur_track.close();
|
|
audio :: load_track(tagdb :: lookup(id));
|
|
}
|
|
}
|
|
|
|
void audio :: play()
|
|
{
|
|
if (!cur_track)
|
|
return;
|
|
if (driver :: get_driver()->play())
|
|
get_callbacks()->on_play();
|
|
}
|
|
|
|
void audio :: pause()
|
|
{
|
|
if (!cur_track)
|
|
return;
|
|
if (driver :: get_driver()->pause())
|
|
get_callbacks()->on_pause();
|
|
}
|
|
|
|
void audio :: seek_to(long pos)
|
|
{
|
|
if (!cur_track)
|
|
return;
|
|
driver :: get_driver()->seek_to(pos);
|
|
}
|
|
|
|
void audio :: stop()
|
|
{
|
|
pause();
|
|
seek_to(0);
|
|
}
|
|
|
|
long audio :: position()
|
|
{
|
|
if (!cur_track)
|
|
return 0;
|
|
return driver :: get_driver()->position();
|
|
}
|
|
|
|
long audio :: duration()
|
|
{
|
|
if (!cur_track)
|
|
return 0;
|
|
return driver :: get_driver()->duration();
|
|
}
|
|
|
|
std::string audio :: position_str()
|
|
{
|
|
std::stringstream ss;
|
|
long cur = position() / O_SECOND;
|
|
unsigned int minutes = cur / 60;
|
|
unsigned int seconds = cur % 60;
|
|
|
|
ss << minutes << ":";
|
|
if (seconds < 10)
|
|
ss << "0";
|
|
ss << seconds;
|
|
return ss.str();
|
|
}
|
|
|
|
void audio :: next()
|
|
{
|
|
_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;
|
|
|
|
_load_track(track, driver :: get_driver()->is_playing());
|
|
deck :: get_queue()->add(cur_track);
|
|
}
|
|
|
|
Track *audio :: current_track()
|
|
{
|
|
return cur_track;
|
|
}
|
|
|
|
void audio :: pause_after(bool enabled, unsigned int n)
|
|
{
|
|
if (n > _pause_count)
|
|
enabled = true;
|
|
|
|
_pause_enabled = enabled;
|
|
_pause_count = n;
|
|
get_callbacks()->on_pause_count_changed(enabled, n);
|
|
}
|
|
|
|
bool audio :: pause_enabled()
|
|
{
|
|
return _pause_enabled;
|
|
}
|
|
|
|
unsigned int audio :: pause_count()
|
|
{
|
|
return _pause_count;
|
|
}
|