ocarina/core/audio.cpp

189 lines
2.8 KiB
C++
Raw Normal View History

/**
* Copyright 2013 (c) Anna Schumaker.
*/
#include <core/audio.h>
extern "C" {
#include <core/collection.h>
#include <core/history.h>
#include <core/tempq.h>
#include <core/string.h>
}
static bool _pause_enabled = false;
static unsigned int _pause_count = 0;
static struct track *cur_track = NULL;
static struct file f_cur_track;
static AudioDriver *cur_driver = NULL;
static void save_state()
{
file_open(&f_cur_track, OPEN_WRITE);
file_writef(&f_cur_track, "%u\n", cur_track->tr_dbe.dbe_index);
file_close(&f_cur_track);
}
static void _load_track(struct track *track, bool start_playback)
{
cur_track = track;
if (!track)
return;
cur_driver->load(track);
if (start_playback)
audio :: play();
else
audio :: pause();
save_state();
}
static bool continue_playback()
{
bool ret = true;
if (_pause_enabled) {
if (_pause_count == 0) {
ret = false;
_pause_enabled = false;
} else
_pause_count--;
}
return ret;
}
AudioDriver :: AudioDriver()
{
cur_driver = this;
}
AudioDriver :: ~AudioDriver()
{
cur_driver = NULL;
}
void AudioDriver :: eos()
{
struct track *track;
if (cur_track) {
track_played(cur_track);
queue_updated(collection_get_queue(), cur_track);
}
track = tempq_next();
if (!track)
track = queue_next(collection_get_queue());
_load_track(track, continue_playback());
}
void audio :: init()
{
unsigned int id;
file_init(&f_cur_track, "cur_track", 0);
if (file_exists(&f_cur_track)) {
file_open(&f_cur_track, OPEN_READ);
file_readf(&f_cur_track, "%u", &id);
file_close(&f_cur_track);
audio :: load_track(track_get(id));
}
}
void audio :: play()
{
if (cur_track)
cur_driver->play();
}
void audio :: pause()
{
if (cur_track)
cur_driver->pause();
}
void audio :: seek_to(int64_t pos)
{
if (cur_track)
cur_driver->seek_to(pos);
}
void audio :: stop()
{
pause();
seek_to(0);
}
int64_t audio :: position()
{
if (cur_track)
return cur_driver->position();
return 0;
}
int64_t audio :: duration()
{
if (cur_track)
return cur_driver->duration();
return 0;
}
void audio :: next()
{
struct track *track = tempq_next();
if (!track)
track = queue_next(collection_get_queue());
_load_track(track, cur_driver->is_playing());
if (cur_track)
history_add(cur_track);
}
void audio :: prev()
{
_load_track(history_prev(), cur_driver->is_playing());
}
void audio :: load_track(struct track *track)
{
if (!track || track == cur_track)
return;
_load_track(track, cur_driver->is_playing());
history_add(cur_track);
}
struct 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;
}
bool audio :: pause_enabled()
{
return _pause_enabled;
}
unsigned int audio :: pause_count()
{
return _pause_count;
}
AudioDriver *audio :: get_driver()
{
return cur_driver;
}