ocarina/lib/audio.cpp

145 lines
2.6 KiB
C++
Raw Normal View History

/*
* Copyright 2013 (c) Anna Schumaker.
*/
#include <audio.h>
#include <deck.h>
#include <library.h>
#include <string.h>
static GstElement *ocarina_player;
static bool track_loaded = false;
static unsigned int cur_trackid = 0;
static gboolean on_message(GstBus *bus, GstMessage *message, gpointer data)
{
return TRUE;
}
static bool change_state(GstState state)
{
GstStateChangeReturn ret;
ret = gst_element_set_state(GST_ELEMENT(ocarina_player), state);
switch (ret) {
case GST_STATE_CHANGE_SUCCESS:
case GST_STATE_CHANGE_ASYNC:
return true;
default:
return false;
}
}
static bool load_song(library :: Song &song)
{
GstState state;
gchar *escaped;
std::string filepath = song.library->root_path + "/" + song.track->filepath;
gst_element_get_state(GST_ELEMENT(ocarina_player), &state,
NULL, GST_CLOCK_TIME_NONE);
escaped = gst_filename_to_uri(filepath.c_str(), NULL);
g_object_set(G_OBJECT(ocarina_player), "uri", escaped, NULL);
g_free(escaped);
return change_state(state);
}
void audio :: init(int *argc, char ***argv)
{
GstBus *bus;
gst_init(argc, argv);
ocarina_player = gst_element_factory_make("playbin", "ocarina_player");
bus = gst_pipeline_get_bus(GST_PIPELINE(ocarina_player));
gst_bus_add_watch(bus, on_message, NULL);
}
bool audio :: play()
{
if (track_loaded == false)
return false;
return change_state(GST_STATE_PLAYING);
}
bool audio :: pause()
{
if (track_loaded == false)
return false;
return change_state(GST_STATE_PAUSED);
}
bool audio :: stop()
{
if (pause() == false)
return false;
return seek_to(0);
}
bool audio :: seek_to(long pos)
{
bool ret;
if (track_loaded == false)
return false;
ret = gst_element_seek_simple(GST_ELEMENT(ocarina_player),
GST_FORMAT_TIME,
GST_SEEK_FLAG_FLUSH,
pos);
return ret;
}
static bool _next()
{
library :: Song song;
unsigned int id = deck :: next();
if (library :: lookup(id, &song) == false)
return false;
if (load_song(song) == false)
return false;
cur_trackid = id;
return true;
}
bool audio :: next()
{
try {
track_loaded = _next();
} catch (int) {
track_loaded = false;
}
return track_loaded;
}
unsigned int audio :: current_trackid()
{
if (track_loaded == false)
throw -1;
return cur_trackid;
}
long audio :: position()
{
long position;
if (track_loaded == false)
return 0;
if (!gst_element_query_position(GST_ELEMENT(ocarina_player), GST_FORMAT_TIME, &position))
return 0;
return position;
}
long audio :: duration()
{
long duration;
if (track_loaded == false)
return 0;
if (!gst_element_query_duration(ocarina_player, GST_FORMAT_TIME, &duration))
return 0;
return duration;
}