ocarina/core/audio.cpp

207 lines
3.2 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 struct file audio_file;
static GstElement *audio_player = NULL;
static bool _pause_enabled = false;
static unsigned int _pause_count = 0;
static struct track *cur_track = NULL;
static AudioDriver *cur_driver = NULL;
static void save_state()
{
file_open(&audio_file, OPEN_WRITE);
file_writef(&audio_file, "%u\n", cur_track->tr_dbe.dbe_index);
file_close(&audio_file);
}
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(int *argc, char ***argv)
{
unsigned int track;
gst_init(argc, argv);
audio_player = gst_element_factory_make("playbin", "ocarina_player");
file_init(&audio_file, "cur_track", 0);
if (file_open(&audio_file, OPEN_READ)) {
file_readf(&audio_file, "%u", &track);
file_close(&audio_file);
audio :: load_track(track_get(track));
}
}
void audio_deinit()
{
gst_element_set_state(audio_player, GST_STATE_NULL);
gst_object_unref(audio_player);
audio_player = NULL;
gst_deinit();
}
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;
}
GstElement *audio_get_player()
{
return audio_player;
}