#include <glib.h>
#include <glib/gi18n-lib.h>
#include <libchimara/glk.h>
-#ifdef GSTREAMER_SOUND
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
#include <gst/gst.h>
-#endif
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
#include "magic.h"
#include "schannel.h"
#include "chimara-glk-private.h"
#define VOLUME_TIMER_RESOLUTION 1.0 /* In milliseconds */
-extern GPrivate *glk_data_key;
+#ifdef GSTREAMER_0_10_SOUND
+#define OGG_MIMETYPE "application/ogg"
+#endif
+#ifdef GSTREAMER_1_0_SOUND
+#define OGG_MIMETYPE "audio/ogg"
+#endif
+
+extern GPrivate glk_data_key;
-#ifdef GSTREAMER_SOUND
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
/* Stop any currently playing sound on this channel, and remove any
format-specific GStreamer elements from the channel. */
static void
{
if(!gst_element_set_state(chan->pipeline, GST_STATE_NULL))
WARNING_S(_("Could not set GstElement state to"), "NULL");
+ if(chan->source)
+ {
+ gst_bin_remove(GST_BIN(chan->pipeline), chan->source);
+ chan->source = NULL;
+ }
if(chan->demux)
{
gst_bin_remove(GST_BIN(chan->pipeline), chan->demux);
on_type_found(GstElement *typefind, guint probability, GstCaps *caps, schanid_t s)
{
gchar *type = gst_caps_to_string(caps);
- if(strcmp(type, "application/ogg") == 0) {
+ if(strcmp(type, OGG_MIMETYPE) == 0) {
s->demux = gst_element_factory_make("oggdemux", NULL);
s->decode = gst_element_factory_make("vorbisdec", NULL);
if(!s->demux || !s->decode) {
finally:
g_free(type);
}
-#endif /* GSTREAMER_SOUND */
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
/**
* glk_schannel_create:
schanid_t
glk_schannel_create_ext(glui32 rock, glui32 volume)
{
-#ifdef GSTREAMER_SOUND
- ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
+ ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
schanid_t s = g_new0(struct glk_schannel_struct, 1);
s->magic = MAGIC_SCHANNEL;
gst_object_unref(bus);
/* Create GStreamer elements to put in the pipeline */
- s->source = gst_element_factory_make("giostreamsrc", NULL);
s->typefind = gst_element_factory_make("typefind", NULL);
s->convert = gst_element_factory_make("audioconvert", NULL);
s->filter = gst_element_factory_make("volume", NULL);
s->sink = gst_element_factory_make("autoaudiosink", NULL);
- if(!s->source || !s->typefind || !s->convert || !s->filter || !s->sink) {
+ if(!s->typefind || !s->convert || !s->filter || !s->sink) {
WARNING(_("Could not create one or more GStreamer elements"));
goto fail;
}
/* Put the elements in the pipeline and link as many together as we can
without knowing the type of the audio stream */
- gst_bin_add_many(GST_BIN(s->pipeline), s->source, s->typefind, s->convert, s->filter, s->sink, NULL);
- /* Link elements: Source -> typefinder -> ??? -> Converter -> Volume filter -> Sink */
- if(!gst_element_link(s->source, s->typefind) || !gst_element_link_many(s->convert, s->filter, s->sink, NULL)) {
+ gst_bin_add_many(GST_BIN(s->pipeline), s->typefind, s->convert, s->filter, s->sink, NULL);
+
+ /* Link elements: ??? -> Converter -> Volume filter -> Sink */
+ if(!gst_element_link_many(s->convert, s->filter, s->sink, NULL)) {
WARNING(_("Could not link GStreamer elements"));
goto fail;
}
return NULL;
#else
return NULL;
-#endif /* GSTREAMER_SOUND */
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
}
/**
{
VALID_SCHANNEL(chan, return);
-#ifdef GSTREAMER_SOUND
- ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
+ ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
if(!gst_element_set_state(chan->pipeline, GST_STATE_NULL))
WARNING_S(_("Could not set GstElement state to"), "NULL");
chan->magic = MAGIC_FREE;
g_free(chan);
-#endif
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
}
/**
{
VALID_SCHANNEL_OR_NULL(chan, return NULL);
-#ifdef GSTREAMER_SOUND
- ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
+ ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
GList *retnode;
if(chan == NULL)
return retval;
#else
return NULL;
-#endif /* GSTREAMER_SOUND */
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
}
/**
glk_schannel_play_ext(schanid_t chan, glui32 snd, glui32 repeats, glui32 notify)
{
VALID_SCHANNEL(chan, return 0);
-#ifdef GSTREAMER_SOUND
- ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
+ ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
GInputStream *stream;
/* Stop the previous sound */
stream = g_memory_input_stream_new_from_data(resource.data.ptr, resource.length, NULL);
}
+ chan->source = gst_element_factory_make("giostreamsrc", NULL);
+ g_object_set(chan->source, "stream", stream, NULL);
+ g_object_unref(stream); /* Now owned by GStreamer element */
+ gst_bin_add(GST_BIN(chan->pipeline), chan->source);
+ if(!gst_element_link(chan->source, chan->typefind)) {
+ WARNING(_("Could not link GStreamer elements"));
+ clean_up_after_playing_sound(chan);
+ return 0;
+ }
+
chan->repeats = repeats;
chan->resource = snd;
chan->notify = notify;
- g_object_set(chan->source, "stream", stream, NULL);
- g_object_unref(stream); /* Now owned by GStreamer element */
/* Play the sound; unless the channel is paused, then pause it instead */
if(!gst_element_set_state(chan->pipeline, chan->paused? GST_STATE_PAUSED : GST_STATE_PLAYING)) {
WARNING_S(_("Could not set GstElement state to"), chan->paused? "PAUSED" : "PLAYING");
+ clean_up_after_playing_sound(chan);
return 0;
}
return 1;
#else
return 0;
-#endif
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
}
/**
for(count = 0; count < chancount; count++)
VALID_SCHANNEL(chanarray[count], return 0);
-#ifdef GSTREAMER_SOUND
- ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
+ ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
GInputStream *stream;
if(!glk_data->resource_map && !glk_data->resource_load_callback) {
stream = g_memory_input_stream_new_from_data(resource.data.ptr, resource.length, NULL);
}
+ chanarray[count]->source = gst_element_factory_make("giostreamsrc", NULL);
+ g_object_set(chanarray[count]->source, "stream", stream, NULL);
+ g_object_unref(stream); /* Now owned by GStreamer element */
+ gst_bin_add(GST_BIN(chanarray[count]->pipeline), chanarray[count]->source);
+ if(!gst_element_link(chanarray[count]->source, chanarray[count]->typefind)) {
+ WARNING(_("Could not link GStreamer elements"));
+ clean_up_after_playing_sound(chanarray[count]);
+ }
+
chanarray[count]->repeats = 1;
chanarray[count]->resource = sndarray[count];
chanarray[count]->notify = notify;
- g_object_set(chanarray[count]->source, "stream", stream, NULL);
- g_object_unref(stream); /* Now owned by GStreamer element */
}
/* Start all the sounds as close to each other as possible. */
if(!gst_element_set_state(chanarray[count]->pipeline, chanarray[count]->paused? GST_STATE_PAUSED : GST_STATE_PLAYING)) {
WARNING_S(_("Could not set GstElement state to"), chanarray[count]->paused? "PAUSED" : "PLAYING");
skiparray[count] = TRUE;
+ clean_up_after_playing_sound(chanarray[count]);
continue;
}
successes++;
return successes;
#else
return 0;
-#endif
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
}
/**
glk_schannel_stop(schanid_t chan)
{
VALID_SCHANNEL(chan, return);
-#ifdef GSTREAMER_SOUND
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
clean_up_after_playing_sound(chan);
#endif
}
/* Mark the channel as paused even if there is no sound playing yet */
chan->paused = TRUE;
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
GstState state;
if(gst_element_get_state(chan->pipeline, &state, NULL, GST_CLOCK_TIME_NONE) != GST_STATE_CHANGE_SUCCESS) {
WARNING(_("Could not get GstElement state"));
WARNING_S(_("Could not set GstElement state to"), "PAUSED");
return;
}
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
}
/**
/* Mark the channel as not paused in any case */
chan->paused = FALSE;
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
GstState state;
if(gst_element_get_state(chan->pipeline, &state, NULL, GST_CLOCK_TIME_NONE) != GST_STATE_CHANGE_SUCCESS) {
WARNING(_("Could not get GstElement state"));
WARNING_S(_("Could not set GstElement state to"), "PLAYING");
return;
}
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
}
/**
return CLAMP(((double)volume_glk / 0x10000), 0.0, 10.0);
}
-#ifdef GSTREAMER_SOUND
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
static gboolean
volume_change_timeout(schanid_t chan)
{
return TRUE;
}
-#endif /* GSTREAMER_SOUND */
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
/**
* glk_schannel_set_volume_ext:
VALID_SCHANNEL(chan, return);
/* Silently ignore out-of-range volume values */
-#ifdef GSTREAMER_SOUND
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
/* Interrupt a previous volume change */
if(chan->volume_timer_id > 0)
g_source_remove(chan->volume_timer_id);
/* Set up a timer for the volume */
chan->volume_timer_id = g_timeout_add(VOLUME_TIMER_RESOLUTION, (GSourceFunc)volume_change_timeout, chan);
-#endif
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
}
/**
void
glk_sound_load_hint(glui32 snd, glui32 flag)
{
-#ifdef GSTREAMER_SOUND
- ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
+#if defined(GSTREAMER_0_10_SOUND) || defined(GSTREAMER_1_0_SOUND)
+ ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key);
giblorb_result_t resource;
giblorb_err_t result;
return;
}
}
-#endif /* GSTREAMER_SOUND */
+#endif /* GSTREAMER_0_10_SOUND || GSTREAMER_1_0_SOUND */
}