ocarina/libsaria/audio/audio.cpp

118 lines
2.5 KiB
C++

#include <libsaria/audio.h>
#include <libsaria/controls.h>
#include <libsaria/print.h>
#include <libsaria/library.h>
#include <libsaria/callback.h>
#include "audio.h"
GstElement *player = NULL;
GstBus *bus = NULL;
static bool restoring_state = false;
static void parse_error(GstMessage *error)
{
GError *err;
gchar *debug;
gst_message_parse_error(error, &err, &debug);
g_print("Error: %s\n", err->message);
g_error_free(err);
g_free(debug);
}
static void notify_audio_changed()
{
println("Notify audio changed");
if (libsaria::get_pause_after()) {
libsaria::audio::pause();
libsaria::set_pause_after(false);
}
if (restoring_state == false)
trigger_callback(TRACK_LOADED);
}
static gboolean on_message(GstBus *bus, GstMessage *message, gpointer data)
{
switch (GST_MESSAGE_TYPE(message)) {
case GST_MESSAGE_ERROR:
parse_error(message);
case GST_MESSAGE_EOS:
libsaria::next();
default:
break;
}
return TRUE;
}
static void about_to_finish(GstElement *playbin, gpointer data)
{
string file;
println("About to finish!");
file = libsaria::next_file();
if (file != "")
load_file(playbin, file);
}
static void audio_changed(GstElement *playbin, gpointer data)
{
notify_audio_changed();
}
/*
* Set sink to NULL to use the default sink
*/
void set_audio_sink(GstElement *sink)
{
g_object_set(G_OBJECT(player), "audio-sink", sink, NULL);
}
void save_audio_state(struct StoredAudioState *state)
{
state->cur_file = libsaria::audio::get_current_file();
state->position = libsaria::audio::position();
state->was_playing = libsaria::audio::is_playing();
}
void load_audio_state(struct StoredAudioState *state)
{
restoring_state = true;
libsaria::audio::load(state->cur_file);
if (state->was_playing == true)
libsaria::audio::play();
else
libsaria::audio::pause();
/*
* Wait for async play() or pause() to finish, otherwise
* the seek won't succeed
*/
gst_element_get_state(GST_ELEMENT(player), NULL, NULL, GST_CLOCK_TIME_NONE);
libsaria::audio::seek_to(state->position);
restoring_state = false;
}
namespace libsaria
{
void audio::init(int argc, char **argv)
{
println("Initializing audio driver");
gst_init(&argc, &argv);
player = gst_element_factory_make("playbin2", "player");
bus = gst_pipeline_get_bus(GST_PIPELINE(player));
gst_bus_add_watch(bus, on_message, NULL);
g_signal_connect(player, "about-to-finish", G_CALLBACK(about_to_finish), NULL);
g_signal_connect(player, "audio-changed", G_CALLBACK(audio_changed), NULL);
init_volume();
init_alsa();
}
};