207 lines
3.2 KiB
C++
207 lines
3.2 KiB
C++
/**
|
|
* 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;
|
|
}
|