/* * Copyright 2013 (c) Anna Schumaker. */ #include #include #include #include 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; }