/* sound.c generated by valac 0.56.19, the Vala compiler
 * generated from sound.vala, do not modify */

/*
 * Copyright (c) 2016,2024 focus-timer contributors
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *
 * Authors: Kamil Prusko <kamilprusko@gmail.com>
 */

#include "ft_core.h"
#include <glib-object.h>
#include <glib.h>
#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <config.h>
#include <gio/gio.h>
#include <gst/gst.h>
#include <glib/gi18n-lib.h>

#define FT_VOLUME_ANIMATION_INTERVAL ((guint) 50)
#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

typedef struct _FtVolumeAnimation FtVolumeAnimation;
typedef struct _FtVolumeAnimationClass FtVolumeAnimationClass;
typedef struct _FtVolumeAnimationPrivate FtVolumeAnimationPrivate;
enum  {
	FT_VOLUME_ANIMATION_0_PROPERTY,
	FT_VOLUME_ANIMATION_VALUE_PROPERTY,
	FT_VOLUME_ANIMATION_VALUE_TO_PROPERTY,
	FT_VOLUME_ANIMATION_NUM_PROPERTIES
};
static GParamSpec* ft_volume_animation_properties[FT_VOLUME_ANIMATION_NUM_PROPERTIES];
enum  {
	FT_VOLUME_ANIMATION_DONE_SIGNAL,
	FT_VOLUME_ANIMATION_NUM_SIGNALS
};
static guint ft_volume_animation_signals[FT_VOLUME_ANIMATION_NUM_SIGNALS] = {0};
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
typedef enum  {
	FT_GST_PLAY_FLAGS_VIDEO = 0x00000001,
	FT_GST_PLAY_FLAGS_AUDIO = 0x00000002,
	FT_GST_PLAY_FLAGS_TEXT = 0x00000004,
	FT_GST_PLAY_FLAGS_VIS = 0x00000008,
	FT_GST_PLAY_FLAGS_SOFT_VOLUME = 0x00000010,
	FT_GST_PLAY_FLAGS_NATIVE_AUDIO = 0x00000020,
	FT_GST_PLAY_FLAGS_NATIVE_VIDEO = 0x00000040,
	FT_GST_PLAY_FLAGS_DOWNLOAD = 0x00000080,
	FT_GST_PLAY_FLAGS_BUFFERING = 0x00000100,
	FT_GST_PLAY_FLAGS_DEINTERLACE = 0x00000200,
	FT_GST_PLAY_FLAGS_SOFT_COLORBALANCE = 0x00000400,
	FT_GST_PLAY_FLAGS_FORCE_FILTERS = 0x00000800
} FtGstPlayFlags;

#define FT_TYPE_GST_PLAY_FLAGS (ft_gst_play_flags_get_type ())
enum  {
	FT_SOUND_BACKEND_PLAYBACK_STARTED_SIGNAL,
	FT_SOUND_BACKEND_PLAYBACK_STOPPED_SIGNAL,
	FT_SOUND_BACKEND_PLAYBACK_ERROR_SIGNAL,
	FT_SOUND_BACKEND_NUM_SIGNALS
};
static guint ft_sound_backend_signals[FT_SOUND_BACKEND_NUM_SIGNALS] = {0};

#define FT_TYPE_GSTREAMER_BACKEND (ft_gstreamer_backend_get_type ())
#define FT_GSTREAMER_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FT_TYPE_GSTREAMER_BACKEND, FtGStreamerBackend))
#define FT_GSTREAMER_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FT_TYPE_GSTREAMER_BACKEND, FtGStreamerBackendClass))
#define FT_IS_GSTREAMER_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FT_TYPE_GSTREAMER_BACKEND))
#define FT_IS_GSTREAMER_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FT_TYPE_GSTREAMER_BACKEND))
#define FT_GSTREAMER_BACKEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FT_TYPE_GSTREAMER_BACKEND, FtGStreamerBackendClass))

typedef struct _FtGStreamerBackend FtGStreamerBackend;
typedef struct _FtGStreamerBackendClass FtGStreamerBackendClass;
typedef struct _FtGStreamerBackendPrivate FtGStreamerBackendPrivate;
enum  {
	FT_GSTREAMER_BACKEND_0_PROPERTY,
	FT_GSTREAMER_BACKEND_URI_PROPERTY,
	FT_GSTREAMER_BACKEND_VOLUME_PROPERTY,
	FT_GSTREAMER_BACKEND_VOLUME_FADE_PROPERTY,
	FT_GSTREAMER_BACKEND_REPEAT_PROPERTY,
	FT_GSTREAMER_BACKEND_NUM_PROPERTIES
};
static GParamSpec* ft_gstreamer_backend_properties[FT_GSTREAMER_BACKEND_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
enum  {
	FT_SOUND_0_PROPERTY,
	FT_SOUND_URI_PROPERTY,
	FT_SOUND_VOLUME_PROPERTY,
	FT_SOUND_BACKEND_PROPERTY,
	FT_SOUND_ERROR_PROPERTY,
	FT_SOUND_NUM_PROPERTIES
};
static GParamSpec* ft_sound_properties[FT_SOUND_NUM_PROPERTIES];
enum  {
	FT_ALERT_SOUND_0_PROPERTY,
	FT_ALERT_SOUND_EVENT_ID_PROPERTY,
	FT_ALERT_SOUND_NUM_PROPERTIES
};
static GParamSpec* ft_alert_sound_properties[FT_ALERT_SOUND_NUM_PROPERTIES];
enum  {
	FT_BACKGROUND_SOUND_0_PROPERTY,
	FT_BACKGROUND_SOUND_REPEAT_PROPERTY,
	FT_BACKGROUND_SOUND_NUM_PROPERTIES
};
static GParamSpec* ft_background_sound_properties[FT_BACKGROUND_SOUND_NUM_PROPERTIES];
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _FtVolumeAnimation {
	GObject parent_instance;
	FtVolumeAnimationPrivate * priv;
};

struct _FtVolumeAnimationClass {
	GObjectClass parent_class;
};

struct _FtVolumeAnimationPrivate {
	gdouble _value;
	gdouble _value_from;
	gdouble _value_to;
	gint64 monotonic_time_from;
	gint64 monotonic_time_to;
	FtEasing easing;
	gdouble slope;
	guint timeout_id;
};

struct _FtGStreamerBackend {
	GObject parent_instance;
	FtGStreamerBackendPrivate * priv;
};

struct _FtGStreamerBackendClass {
	GObjectClass parent_class;
};

struct _FtGStreamerBackendPrivate {
	gboolean _repeat;
	GstElement* pipeline;
	GstElement* volume_filter;
	gboolean _is_playing;
	gboolean is_about_to_finish;
	guint instance_id;
};

struct _FtSoundPrivate {
	gdouble _volume;
	GError* _error;
	gchar* _uri;
	FtSoundBackend* _backend;
};

struct _FtAlertSoundPrivate {
	gchar* _event_id;
};

struct _FtBackgroundSoundPrivate {
	gboolean _repeat;
	FtVolumeAnimation* volume_animation;
	gint64 pending_fade_out_duration;
	gint64 pending_fade_out_easing;
};

static gint FtVolumeAnimation_private_offset;
static gpointer ft_volume_animation_parent_class = NULL;
static gint FtGStreamerBackend_private_offset;
static gpointer ft_gstreamer_backend_parent_class = NULL;
static gboolean ft_gstreamer_backend_is_gstreamer_initialized;
static gboolean ft_gstreamer_backend_is_gstreamer_initialized = FALSE;
static guint ft_gstreamer_backend_next_instance_id;
static guint ft_gstreamer_backend_next_instance_id = (guint) 1;
static FtSoundBackendIface * ft_gstreamer_backend_ft_sound_backend_parent_iface = NULL;
static gint FtSound_private_offset;
static gpointer ft_sound_parent_class = NULL;
static gint FtAlertSound_private_offset;
static gpointer ft_alert_sound_parent_class = NULL;
static gint FtBackgroundSound_private_offset;
static gpointer ft_background_sound_parent_class = NULL;

static void ft_volume_animation_done (FtVolumeAnimation* self);
VALA_EXTERN void ft_volume_animation_animate_to (FtVolumeAnimation* self,
                                     gdouble value,
                                     gint64 duration,
                                     FtEasing easing);
static gdouble ft_volume_animation_calculate_slope (FtVolumeAnimation* self,
                                             gint64 monotonic_time);
static gboolean ft_volume_animation_on_timeout (FtVolumeAnimation* self);
static gboolean _ft_volume_animation_on_timeout_gsource_func (gpointer self);
static gdouble ft_volume_animation_calculate_value (FtVolumeAnimation* self,
                                             gint64 monotonic_time);
VALA_EXTERN void ft_volume_animation_stop (FtVolumeAnimation* self);
VALA_EXTERN void ft_volume_animation_skip (FtVolumeAnimation* self);
static void ft_volume_animation_real_dispose (GObject* base);
VALA_EXTERN FtVolumeAnimation* ft_volume_animation_new (void);
VALA_EXTERN FtVolumeAnimation* ft_volume_animation_construct (GType object_type);
VALA_EXTERN gdouble ft_volume_animation_get_value (FtVolumeAnimation* self);
VALA_EXTERN void ft_volume_animation_set_value (FtVolumeAnimation* self,
                                    gdouble value);
VALA_EXTERN gdouble ft_volume_animation_get_value_to (FtVolumeAnimation* self);
static void ft_volume_animation_finalize (GObject * obj);
static GType ft_volume_animation_get_type_once (void);
static void _vala_ft_volume_animation_get_property (GObject * object,
                                             guint property_id,
                                             GValue * value,
                                             GParamSpec * pspec);
static void _vala_ft_volume_animation_set_property (GObject * object,
                                             guint property_id,
                                             const GValue * value,
                                             GParamSpec * pspec);
VALA_EXTERN gchar* ft_build_absolute_path (const gchar* path);
VALA_EXTERN gchar* ft_build_absolute_uri (const gchar* uri);
VALA_EXTERN gboolean ft_transform_uri_to_uri (GBinding* binding,
                                  GValue* source_value,
                                  GValue* target_value);
VALA_EXTERN gboolean ft_is_mime_type (const gchar* content_type,
                          gchar** mime_types,
                          gint mime_types_length1);
VALA_EXTERN GType ft_gst_play_flags_get_type (void) G_GNUC_CONST ;
static GType ft_sound_backend_get_type_once (void);
VALA_EXTERN GType ft_gstreamer_backend_get_type (void) G_GNUC_CONST ;
VALA_EXTERN FtGStreamerBackend* ft_gstreamer_backend_new (GError** error);
VALA_EXTERN FtGStreamerBackend* ft_gstreamer_backend_construct (GType object_type,
                                                    GError** error);
static void ft_gstreamer_backend_on_about_to_finish (FtGStreamerBackend* self);
static void _ft_gstreamer_backend_on_about_to_finish_dynamic_about_to_finish0_ (GstElement* _sender,
                                                                         gpointer self);
static gboolean ft_gstreamer_backend_on_bus_callback (FtGStreamerBackend* self,
                                               GstBus* bus,
                                               GstMessage* message);
static gboolean _ft_gstreamer_backend_on_bus_callback_gst_bus_func (GstBus* bus,
                                                             GstMessage* message,
                                                             gpointer self);
VALA_EXTERN gchar** ft_gstreamer_backend_get_supported_mime_types (gint* result_length1);
VALA_EXTERN gboolean ft_gstreamer_backend_can_play (FtSound* sound,
                                        GFile* file,
                                        const gchar* content_type);
static gchar* ft_gstreamer_backend_get_debug_name (FtGStreamerBackend* self);
static void ft_gstreamer_backend_finished (FtGStreamerBackend* self);
VALA_EXTERN gboolean ft_gstreamer_backend_get_repeat (FtGStreamerBackend* self);
static void ft_gstreamer_backend_real_play (FtSoundBackend* base);
VALA_EXTERN const gchar* ft_gstreamer_backend_get_uri (FtGStreamerBackend* self);
static void ft_gstreamer_backend_real_stop (FtSoundBackend* base);
static gboolean ft_gstreamer_backend_real_is_playing (FtSoundBackend* base);
static void ft_gstreamer_backend_real_dispose (GObject* base);
VALA_EXTERN void ft_gstreamer_backend_set_uri (FtGStreamerBackend* self,
                                   const gchar* value);
VALA_EXTERN gdouble ft_gstreamer_backend_get_volume (FtGStreamerBackend* self);
VALA_EXTERN void ft_gstreamer_backend_set_volume (FtGStreamerBackend* self,
                                      gdouble value);
VALA_EXTERN gdouble ft_gstreamer_backend_get_volume_fade (FtGStreamerBackend* self);
VALA_EXTERN void ft_gstreamer_backend_set_volume_fade (FtGStreamerBackend* self,
                                           gdouble value);
VALA_EXTERN void ft_gstreamer_backend_set_repeat (FtGStreamerBackend* self,
                                      gboolean value);
static void ft_gstreamer_backend_finalize (GObject * obj);
static GType ft_gstreamer_backend_get_type_once (void);
static void _vala_ft_gstreamer_backend_get_property (GObject * object,
                                              guint property_id,
                                              GValue * value,
                                              GParamSpec * pspec);
static void _vala_ft_gstreamer_backend_set_property (GObject * object,
                                              guint property_id,
                                              const GValue * value,
                                              GParamSpec * pspec);
static gchar* ft_sound_real_get_debug_name (FtSound* self);
static void ft_sound_on_playback_error (FtSound* self,
                                 GError* _error_);
static void ft_sound_set_error (FtSound* self,
                         GError* value);
static void ft_sound_prepare (FtSound* self);
static void ft_sound_real_initialize_backend (FtSound* self);
static void _ft_sound_on_playback_error_ft_sound_backend_playback_error (FtSoundBackend* _sender,
                                                                  GError* _error_,
                                                                  gpointer self);
static void ft_sound_real_destroy_backend (FtSound* self);
static void ft_sound_real_destroy (FtSound* self);
static void ft_sound_finalize (GObject * obj);
static GType ft_sound_get_type_once (void);
static void _vala_ft_sound_get_property (GObject * object,
                                  guint property_id,
                                  GValue * value,
                                  GParamSpec * pspec);
static void _vala_ft_sound_set_property (GObject * object,
                                  guint property_id,
                                  const GValue * value,
                                  GParamSpec * pspec);
static gchar* ft_alert_sound_real_get_debug_name (FtSound* base);
static void ft_alert_sound_real_initialize_backend (FtSound* base);
static gboolean _ft_transform_uri_to_uri_gbinding_transform_func (GBinding* binding,
                                                           GValue* from_value,
                                                           GValue* to_value,
                                                           gpointer self);
static void ft_alert_sound_finalize (GObject * obj);
static GType ft_alert_sound_get_type_once (void);
static void _vala_ft_alert_sound_get_property (GObject * object,
                                        guint property_id,
                                        GValue * value,
                                        GParamSpec * pspec);
static void _vala_ft_alert_sound_set_property (GObject * object,
                                        guint property_id,
                                        const GValue * value,
                                        GParamSpec * pspec);
static void ft_background_sound_on_volume_animation_done (FtBackgroundSound* self,
                                                   FtVolumeAnimation* volume_animation);
static void ft_background_sound_real_initialize_backend (FtSound* base);
static void ft_background_sound_real_destroy_backend (FtSound* base);
static void _ft_volume_animation_skip_ft_sound_backend_playback_stopped (FtSoundBackend* _sender,
                                                                  gpointer self);
static void ft_background_sound_real_dispose (GObject* base);
static GObject * ft_background_sound_constructor (GType type,
                                           guint n_construct_properties,
                                           GObjectConstructParam * construct_properties);
static void _ft_background_sound_on_volume_animation_done_ft_volume_animation_done (FtVolumeAnimation* _sender,
                                                                             gpointer self);
static void ft_background_sound_finalize (GObject * obj);
static GType ft_background_sound_get_type_once (void);
static void _vala_ft_background_sound_get_property (GObject * object,
                                             guint property_id,
                                             GValue * value,
                                             GParamSpec * pspec);
static void _vala_ft_background_sound_set_property (GObject * object,
                                             guint property_id,
                                             const GValue * value,
                                             GParamSpec * pspec);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static GType
ft_easing_get_type_once (void)
{
	static const GEnumValue values[] = {{FT_EASING_IN, "FT_EASING_IN", "in"}, {FT_EASING_OUT, "FT_EASING_OUT", "out"}, {FT_EASING_IN_OUT, "FT_EASING_IN_OUT", "in-out"}, {0, NULL, NULL}};
	GType ft_easing_type_id;
	ft_easing_type_id = g_enum_register_static ("FtEasing", values);
	return ft_easing_type_id;
}

GType
ft_easing_get_type (void)
{
	static volatile gsize ft_easing_type_id__once = 0;
	if (g_once_init_enter (&ft_easing_type_id__once)) {
		GType ft_easing_type_id;
		ft_easing_type_id = ft_easing_get_type_once ();
		g_once_init_leave (&ft_easing_type_id__once, ft_easing_type_id);
	}
	return ft_easing_type_id__once;
}

static inline gpointer
ft_volume_animation_get_instance_private (FtVolumeAnimation* self)
{
	return G_STRUCT_MEMBER_P (self, FtVolumeAnimation_private_offset);
}

static gboolean
_ft_volume_animation_on_timeout_gsource_func (gpointer self)
{
	gboolean result;
	result = ft_volume_animation_on_timeout ((FtVolumeAnimation*) self);
	return result;
}

void
ft_volume_animation_animate_to (FtVolumeAnimation* self,
                                gdouble value,
                                gint64 duration,
                                FtEasing easing)
{
	gint64 monotonic_time = 0LL;
	gboolean _tmp0_ = FALSE;
	GEqualFunc _tmp1_;
	g_return_if_fail (self != NULL);
	monotonic_time = g_get_monotonic_time ();
	_tmp1_ = g_double_equal;
	if (!_tmp1_ (&value, &self->priv->_value)) {
		_tmp0_ = duration > ((gint64) 0);
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		guint interval = 0U;
		self->priv->slope = ft_volume_animation_calculate_slope (self, monotonic_time);
		self->priv->monotonic_time_from = monotonic_time;
		self->priv->monotonic_time_to = monotonic_time + duration;
		self->priv->_value_from = self->priv->_value;
		self->priv->_value_to = value;
		self->priv->easing = easing;
		interval = (guint) round ((((gdouble) duration) / 500000.0) / fabs (self->priv->_value_to - self->priv->_value_from));
		if (self->priv->timeout_id == ((guint) 0)) {
			self->priv->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, MAX (interval, (guint) 10), _ft_volume_animation_on_timeout_gsource_func, g_object_ref (self), g_object_unref);
			g_source_set_name_by_id (self->priv->timeout_id, "Ft.VolumeAnimation.on_timeout");
		}
		g_object_notify ((GObject*) self, "value-to");
	} else {
		self->priv->slope = 0.0;
		self->priv->monotonic_time_from = monotonic_time;
		self->priv->monotonic_time_to = monotonic_time;
		self->priv->_value = value;
		self->priv->_value_from = value;
		self->priv->_value_to = value;
		self->priv->easing = easing;
		g_object_notify ((GObject*) self, "value-to");
		g_object_notify ((GObject*) self, "value");
		g_signal_emit (self, ft_volume_animation_signals[FT_VOLUME_ANIMATION_DONE_SIGNAL], 0);
	}
}

static gdouble
ft_volume_animation_calculate_slope (FtVolumeAnimation* self,
                                     gint64 monotonic_time)
{
	gdouble t = 0.0;
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	t = ((gdouble) (monotonic_time - self->priv->monotonic_time_from)) / ((gdouble) (self->priv->monotonic_time_to - self->priv->monotonic_time_from));
	t = CLAMP (t, 0.0, 1.0);
	switch (self->priv->easing) {
		case FT_EASING_OUT:
		{
			result = (((2.0 * (1.0 - t)) * (self->priv->_value_to - self->priv->_value_from)) + ((((3.0 * t) - 4.0) * self->priv->slope) * t)) + self->priv->slope;
			return result;
		}
		case FT_EASING_IN:
		{
			result = (((2.0 * ((self->priv->_value_to - self->priv->_value_from) - (self->priv->slope * t))) - self->priv->slope) * t) + self->priv->slope;
			return result;
		}
		case FT_EASING_IN_OUT:
		{
			result = ((6.0 * (1.0 - t)) * t) * ((self->priv->_value_to - self->priv->_value_from) - (self->priv->slope * t));
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

static gdouble
ft_volume_animation_calculate_value (FtVolumeAnimation* self,
                                     gint64 monotonic_time)
{
	gdouble t = 0.0;
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	t = ((gdouble) (monotonic_time - self->priv->monotonic_time_from)) / ((gdouble) (self->priv->monotonic_time_to - self->priv->monotonic_time_from));
	t = CLAMP (t, 0.0, 1.0);
	switch (self->priv->easing) {
		case FT_EASING_OUT:
		{
			result = ft_lerp (self->priv->_value_from + (self->priv->slope * t), self->priv->_value_to, (2.0 - t) * t);
			return result;
		}
		case FT_EASING_IN:
		{
			result = ft_lerp (self->priv->_value_from + (self->priv->slope * t), self->priv->_value_to, t * t);
			return result;
		}
		case FT_EASING_IN_OUT:
		{
			result = ft_lerp (self->priv->_value_from + (self->priv->slope * t), self->priv->_value_to, (3.0 - (2.0 * t)) * (t * t));
			return result;
		}
		default:
		{
			g_assert_not_reached ();
		}
	}
}

static gboolean
ft_volume_animation_on_timeout (FtVolumeAnimation* self)
{
	gint64 monotonic_time = 0LL;
	GSource* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = g_main_current_source ();
	monotonic_time = g_source_get_time (_tmp0_);
	if (monotonic_time < self->priv->monotonic_time_to) {
		self->priv->_value = ft_volume_animation_calculate_value (self, monotonic_time);
		g_object_notify ((GObject*) self, "value");
		result = G_SOURCE_CONTINUE;
		return result;
	} else {
		self->priv->_value = self->priv->_value_to;
		g_object_notify ((GObject*) self, "value");
		self->priv->timeout_id = (guint) 0;
		g_signal_emit (self, ft_volume_animation_signals[FT_VOLUME_ANIMATION_DONE_SIGNAL], 0);
		result = G_SOURCE_REMOVE;
		return result;
	}
}

void
ft_volume_animation_stop (FtVolumeAnimation* self)
{
	g_return_if_fail (self != NULL);
	if (self->priv->timeout_id != ((guint) 0)) {
		g_source_remove (self->priv->timeout_id);
		self->priv->timeout_id = (guint) 0;
	}
}

void
ft_volume_animation_skip (FtVolumeAnimation* self)
{
	g_return_if_fail (self != NULL);
	ft_volume_animation_stop (self);
	if (self->priv->_value != self->priv->_value_to) {
		self->priv->_value = self->priv->_value_to;
		g_object_notify ((GObject*) self, "value");
		g_signal_emit (self, ft_volume_animation_signals[FT_VOLUME_ANIMATION_DONE_SIGNAL], 0);
	}
}

static void
ft_volume_animation_real_dispose (GObject* base)
{
	FtVolumeAnimation * self;
	self = (FtVolumeAnimation*) base;
	ft_volume_animation_stop (self);
	G_OBJECT_CLASS (ft_volume_animation_parent_class)->dispose (G_TYPE_CHECK_INSTANCE_CAST (self, G_TYPE_OBJECT, GObject));
}

FtVolumeAnimation*
ft_volume_animation_construct (GType object_type)
{
	FtVolumeAnimation * self = NULL;
	self = (FtVolumeAnimation*) g_object_new (object_type, NULL);
	return self;
}

FtVolumeAnimation*
ft_volume_animation_new (void)
{
	return ft_volume_animation_construct (FT_TYPE_VOLUME_ANIMATION);
}

gdouble
ft_volume_animation_get_value (FtVolumeAnimation* self)
{
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	result = self->priv->_value;
	return result;
}

void
ft_volume_animation_set_value (FtVolumeAnimation* self,
                               gdouble value)
{
	gboolean _tmp0_ = FALSE;
	g_return_if_fail (self != NULL);
	if (self->priv->_value == value) {
		_tmp0_ = self->priv->_value_to == value;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		return;
	}
	self->priv->slope = 0.0;
	self->priv->_value = value;
	self->priv->_value_from = value;
	self->priv->_value_to = value;
	g_object_notify ((GObject*) self, "value-to");
	g_object_notify ((GObject*) self, "value");
	g_signal_emit (self, ft_volume_animation_signals[FT_VOLUME_ANIMATION_DONE_SIGNAL], 0);
}

gdouble
ft_volume_animation_get_value_to (FtVolumeAnimation* self)
{
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	result = self->priv->_value_to;
	return result;
}

static void
ft_volume_animation_real_done (FtVolumeAnimation* self)
{
	g_return_if_fail (self != NULL);
	ft_volume_animation_stop (self);
}

static void
ft_volume_animation_class_init (FtVolumeAnimationClass * klass,
                                gpointer klass_data)
{
	ft_volume_animation_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &FtVolumeAnimation_private_offset);
	((GObjectClass *) klass)->dispose = (void (*) (GObject*)) ft_volume_animation_real_dispose;
	G_OBJECT_CLASS (klass)->get_property = _vala_ft_volume_animation_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_ft_volume_animation_set_property;
	G_OBJECT_CLASS (klass)->finalize = ft_volume_animation_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_VOLUME_ANIMATION_VALUE_PROPERTY, ft_volume_animation_properties[FT_VOLUME_ANIMATION_VALUE_PROPERTY] = g_param_spec_double ("value", "value", "value", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_VOLUME_ANIMATION_VALUE_TO_PROPERTY, ft_volume_animation_properties[FT_VOLUME_ANIMATION_VALUE_TO_PROPERTY] = g_param_spec_double ("value-to", "value-to", "value-to", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	ft_volume_animation_signals[FT_VOLUME_ANIMATION_DONE_SIGNAL] = g_signal_new_class_handler ("done", FT_TYPE_VOLUME_ANIMATION, G_SIGNAL_RUN_LAST, (GCallback) ft_volume_animation_real_done, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}

static void
ft_volume_animation_instance_init (FtVolumeAnimation * self,
                                   gpointer klass)
{
	self->priv = ft_volume_animation_get_instance_private (self);
	self->priv->_value = 1.0;
	self->priv->_value_from = 1.0;
	self->priv->_value_to = 1.0;
	self->priv->monotonic_time_from = FT_TIMESTAMP_UNDEFINED;
	self->priv->monotonic_time_to = FT_TIMESTAMP_UNDEFINED;
	self->priv->easing = FT_EASING_IN;
	self->priv->slope = 0.0;
	self->priv->timeout_id = (guint) 0;
}

static void
ft_volume_animation_finalize (GObject * obj)
{
	FtVolumeAnimation * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, FT_TYPE_VOLUME_ANIMATION, FtVolumeAnimation);
	G_OBJECT_CLASS (ft_volume_animation_parent_class)->finalize (obj);
}

static GType
ft_volume_animation_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (FtVolumeAnimationClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ft_volume_animation_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FtVolumeAnimation), 0, (GInstanceInitFunc) ft_volume_animation_instance_init, NULL };
	GType ft_volume_animation_type_id;
	ft_volume_animation_type_id = g_type_register_static (G_TYPE_OBJECT, "FtVolumeAnimation", &g_define_type_info, 0);
	FtVolumeAnimation_private_offset = g_type_add_instance_private (ft_volume_animation_type_id, sizeof (FtVolumeAnimationPrivate));
	return ft_volume_animation_type_id;
}

GType
ft_volume_animation_get_type (void)
{
	static volatile gsize ft_volume_animation_type_id__once = 0;
	if (g_once_init_enter (&ft_volume_animation_type_id__once)) {
		GType ft_volume_animation_type_id;
		ft_volume_animation_type_id = ft_volume_animation_get_type_once ();
		g_once_init_leave (&ft_volume_animation_type_id__once, ft_volume_animation_type_id);
	}
	return ft_volume_animation_type_id__once;
}

static void
_vala_ft_volume_animation_get_property (GObject * object,
                                        guint property_id,
                                        GValue * value,
                                        GParamSpec * pspec)
{
	FtVolumeAnimation * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_VOLUME_ANIMATION, FtVolumeAnimation);
	switch (property_id) {
		case FT_VOLUME_ANIMATION_VALUE_PROPERTY:
		g_value_set_double (value, ft_volume_animation_get_value (self));
		break;
		case FT_VOLUME_ANIMATION_VALUE_TO_PROPERTY:
		g_value_set_double (value, ft_volume_animation_get_value_to (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_ft_volume_animation_set_property (GObject * object,
                                        guint property_id,
                                        const GValue * value,
                                        GParamSpec * pspec)
{
	FtVolumeAnimation * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_VOLUME_ANIMATION, FtVolumeAnimation);
	switch (property_id) {
		case FT_VOLUME_ANIMATION_VALUE_PROPERTY:
		ft_volume_animation_set_value (self, g_value_get_double (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

gchar*
ft_build_absolute_path (const gchar* path)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (path != NULL, NULL);
	_tmp0_ = g_build_filename (PACKAGE_DATA_DIR, "sounds", path, NULL);
	result = _tmp0_;
	return result;
}

gchar*
ft_build_absolute_uri (const gchar* uri)
{
	gchar* scheme = NULL;
	gchar* _tmp0_;
	gboolean _tmp1_ = FALSE;
	const gchar* _tmp2_;
	gchar* _tmp13_;
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (uri != NULL, NULL);
	_tmp0_ = g_uri_parse_scheme (uri);
	scheme = _tmp0_;
	_tmp2_ = scheme;
	if (_tmp2_ == NULL) {
		_tmp1_ = g_strcmp0 (uri, "") != 0;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		gchar* preset_filename = NULL;
		gchar* _tmp3_;
		gchar* preset_path = NULL;
		const gchar* _tmp4_;
		gchar* _tmp5_;
		_tmp3_ = g_strdup (uri);
		preset_filename = _tmp3_;
		_tmp4_ = preset_filename;
		_tmp5_ = ft_build_absolute_path (_tmp4_);
		preset_path = _tmp5_;
		{
			gchar* _tmp6_ = NULL;
			const gchar* _tmp7_;
			gchar* _tmp8_;
			gchar* _tmp9_;
			_tmp7_ = preset_path;
			_tmp8_ = g_filename_to_uri (_tmp7_, NULL, &_inner_error0_);
			_tmp6_ = _tmp8_;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				if (_inner_error0_->domain == G_CONVERT_ERROR) {
					goto __catch0_g_convert_error;
				}
				_g_free0 (preset_path);
				_g_free0 (preset_filename);
				_g_free0 (scheme);
				g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
				g_clear_error (&_inner_error0_);
				return NULL;
			}
			_tmp9_ = _tmp6_;
			_tmp6_ = NULL;
			result = _tmp9_;
			_g_free0 (_tmp6_);
			_g_free0 (preset_path);
			_g_free0 (preset_filename);
			_g_free0 (scheme);
			return result;
		}
		goto __finally0;
		__catch0_g_convert_error:
		{
			GError* _error_ = NULL;
			const gchar* _tmp10_;
			GError* _tmp11_;
			const gchar* _tmp12_;
			_error_ = _inner_error0_;
			_inner_error0_ = NULL;
			_tmp10_ = preset_path;
			_tmp11_ = _error_;
			_tmp12_ = _tmp11_->message;
			g_warning ("sound.vala:231: Failed to convert \"%s\" to URI: %s", _tmp10_, _tmp12_);
			_g_error_free0 (_error_);
		}
		__finally0:
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_free0 (preset_path);
			_g_free0 (preset_filename);
			_g_free0 (scheme);
			g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
			g_clear_error (&_inner_error0_);
			return NULL;
		}
		_g_free0 (preset_path);
		_g_free0 (preset_filename);
	}
	_tmp13_ = g_strdup (uri);
	result = _tmp13_;
	_g_free0 (scheme);
	return result;
}

gboolean
ft_transform_uri_to_uri (GBinding* binding,
                         GValue* source_value,
                         GValue* target_value)
{
	gchar* uri = NULL;
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gboolean result;
	g_return_val_if_fail (binding != NULL, FALSE);
	g_return_val_if_fail (source_value != NULL, FALSE);
	g_return_val_if_fail (target_value != NULL, FALSE);
	_tmp0_ = g_value_get_string (source_value);
	_tmp1_ = g_strdup (_tmp0_);
	uri = _tmp1_;
	_tmp2_ = ft_build_absolute_uri (uri);
	_tmp3_ = _tmp2_;
	g_value_set_string (target_value, _tmp3_);
	_g_free0 (_tmp3_);
	result = TRUE;
	_g_free0 (uri);
	return result;
}

gboolean
ft_is_mime_type (const gchar* content_type,
                 gchar** mime_types,
                 gint mime_types_length1)
{
	gboolean result;
	g_return_val_if_fail (content_type != NULL, FALSE);
	if (g_content_type_is_unknown (content_type)) {
		result = FALSE;
		return result;
	}
	{
		gchar** mime_type_collection = NULL;
		gint mime_type_collection_length1 = 0;
		gint _mime_type_collection_size_ = 0;
		gint mime_type_it = 0;
		mime_type_collection = mime_types;
		mime_type_collection_length1 = mime_types_length1;
		for (mime_type_it = 0; mime_type_it < mime_type_collection_length1; mime_type_it = mime_type_it + 1) {
			gchar* _tmp0_;
			gchar* mime_type = NULL;
			_tmp0_ = g_strdup (mime_type_collection[mime_type_it]);
			mime_type = _tmp0_;
			{
				const gchar* _tmp1_;
				_tmp1_ = mime_type;
				if (g_content_type_is_mime_type (content_type, _tmp1_)) {
					result = TRUE;
					_g_free0 (mime_type);
					return result;
				}
				_g_free0 (mime_type);
			}
		}
	}
	result = FALSE;
	return result;
}

static GType
ft_gst_play_flags_get_type_once (void)
{
	static const GFlagsValue values[] = {{FT_GST_PLAY_FLAGS_VIDEO, "FT_GST_PLAY_FLAGS_VIDEO", "video"}, {FT_GST_PLAY_FLAGS_AUDIO, "FT_GST_PLAY_FLAGS_AUDIO", "audio"}, {FT_GST_PLAY_FLAGS_TEXT, "FT_GST_PLAY_FLAGS_TEXT", "text"}, {FT_GST_PLAY_FLAGS_VIS, "FT_GST_PLAY_FLAGS_VIS", "vis"}, {FT_GST_PLAY_FLAGS_SOFT_VOLUME, "FT_GST_PLAY_FLAGS_SOFT_VOLUME", "soft-volume"}, {FT_GST_PLAY_FLAGS_NATIVE_AUDIO, "FT_GST_PLAY_FLAGS_NATIVE_AUDIO", "native-audio"}, {FT_GST_PLAY_FLAGS_NATIVE_VIDEO, "FT_GST_PLAY_FLAGS_NATIVE_VIDEO", "native-video"}, {FT_GST_PLAY_FLAGS_DOWNLOAD, "FT_GST_PLAY_FLAGS_DOWNLOAD", "download"}, {FT_GST_PLAY_FLAGS_BUFFERING, "FT_GST_PLAY_FLAGS_BUFFERING", "buffering"}, {FT_GST_PLAY_FLAGS_DEINTERLACE, "FT_GST_PLAY_FLAGS_DEINTERLACE", "deinterlace"}, {FT_GST_PLAY_FLAGS_SOFT_COLORBALANCE, "FT_GST_PLAY_FLAGS_SOFT_COLORBALANCE", "soft-colorbalance"}, {FT_GST_PLAY_FLAGS_FORCE_FILTERS, "FT_GST_PLAY_FLAGS_FORCE_FILTERS", "force-filters"}, {0, NULL, NULL}};
	GType ft_gst_play_flags_type_id;
	ft_gst_play_flags_type_id = g_flags_register_static ("FtGstPlayFlags", values);
	return ft_gst_play_flags_type_id;
}

GType
ft_gst_play_flags_get_type (void)
{
	static volatile gsize ft_gst_play_flags_type_id__once = 0;
	if (g_once_init_enter (&ft_gst_play_flags_type_id__once)) {
		GType ft_gst_play_flags_type_id;
		ft_gst_play_flags_type_id = ft_gst_play_flags_get_type_once ();
		g_once_init_leave (&ft_gst_play_flags_type_id__once, ft_gst_play_flags_type_id);
	}
	return ft_gst_play_flags_type_id__once;
}

void
ft_sound_backend_play (FtSoundBackend* self)
{
	FtSoundBackendIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = FT_SOUND_BACKEND_GET_INTERFACE (self);
	if (_iface_->play) {
		_iface_->play (self);
	}
}

void
ft_sound_backend_stop (FtSoundBackend* self)
{
	FtSoundBackendIface* _iface_;
	g_return_if_fail (self != NULL);
	_iface_ = FT_SOUND_BACKEND_GET_INTERFACE (self);
	if (_iface_->stop) {
		_iface_->stop (self);
	}
}

gboolean
ft_sound_backend_is_playing (FtSoundBackend* self)
{
	FtSoundBackendIface* _iface_;
	g_return_val_if_fail (self != NULL, FALSE);
	_iface_ = FT_SOUND_BACKEND_GET_INTERFACE (self);
	if (_iface_->is_playing) {
		return _iface_->is_playing (self);
	}
	return FALSE;
}

static void
ft_sound_backend_default_init (FtSoundBackendIface * iface,
                               gpointer iface_data)
{
	ft_sound_backend_signals[FT_SOUND_BACKEND_PLAYBACK_STARTED_SIGNAL] = g_signal_new ("playback-started", FT_TYPE_SOUND_BACKEND, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	ft_sound_backend_signals[FT_SOUND_BACKEND_PLAYBACK_STOPPED_SIGNAL] = g_signal_new ("playback-stopped", FT_TYPE_SOUND_BACKEND, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	ft_sound_backend_signals[FT_SOUND_BACKEND_PLAYBACK_ERROR_SIGNAL] = g_signal_new ("playback-error", FT_TYPE_SOUND_BACKEND, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, G_TYPE_ERROR);
}

static GType
ft_sound_backend_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (FtSoundBackendIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ft_sound_backend_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType ft_sound_backend_type_id;
	ft_sound_backend_type_id = g_type_register_static (G_TYPE_INTERFACE, "FtSoundBackend", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (ft_sound_backend_type_id, G_TYPE_OBJECT);
	return ft_sound_backend_type_id;
}

GType
ft_sound_backend_get_type (void)
{
	static volatile gsize ft_sound_backend_type_id__once = 0;
	if (g_once_init_enter (&ft_sound_backend_type_id__once)) {
		GType ft_sound_backend_type_id;
		ft_sound_backend_type_id = ft_sound_backend_get_type_once ();
		g_once_init_leave (&ft_sound_backend_type_id__once, ft_sound_backend_type_id);
	}
	return ft_sound_backend_type_id__once;
}

static inline gpointer
ft_gstreamer_backend_get_instance_private (FtGStreamerBackend* self)
{
	return G_STRUCT_MEMBER_P (self, FtGStreamerBackend_private_offset);
}

static void
_ft_gstreamer_backend_on_about_to_finish_dynamic_about_to_finish0_ (GstElement* _sender,
                                                                    gpointer self)
{
	ft_gstreamer_backend_on_about_to_finish ((FtGStreamerBackend*) self);
}

static gboolean
_ft_gstreamer_backend_on_bus_callback_gst_bus_func (GstBus* bus,
                                                    GstMessage* message,
                                                    gpointer self)
{
	gboolean result;
	result = ft_gstreamer_backend_on_bus_callback ((FtGStreamerBackend*) self, bus, message);
	return result;
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

FtGStreamerBackend*
ft_gstreamer_backend_construct (GType object_type,
                                GError** error)
{
	FtGStreamerBackend * self = NULL;
	GstElement* pipeline = NULL;
	GstElement* _tmp0_;
	GstElement* volume_filter = NULL;
	GstElement* _tmp1_;
	gboolean _tmp2_ = FALSE;
	GstElement* _tmp3_;
	GstElement* _tmp6_;
	GstElement* _tmp7_;
	GstElement* _tmp8_;
	GstElement* _tmp9_;
	GstElement* _tmp10_;
	GstBus* _tmp11_;
	GstBus* _tmp12_;
	GstElement* _tmp13_;
	GstElement* _tmp14_;
	GstElement* _tmp15_;
	GstElement* _tmp16_;
	guint _tmp17_;
	GError* _inner_error0_ = NULL;
	self = (FtGStreamerBackend*) g_object_new (object_type, NULL);
	if (!ft_gstreamer_backend_is_gstreamer_initialized) {
		gchar** args_unowned = NULL;
		gint args_unowned_length1;
		gint _args_unowned_size_;
		args_unowned = NULL;
		args_unowned_length1 = 0;
		_args_unowned_size_ = args_unowned_length1;
		gst_init ((gint*) (&args_unowned_length1), &args_unowned);
		_args_unowned_size_ = args_unowned_length1;
		ft_gstreamer_backend_is_gstreamer_initialized = TRUE;
	}
	_tmp0_ = gst_element_factory_make ("playbin", "player");
	if (_tmp0_ != NULL) {
		g_object_ref_sink (_tmp0_);
	}
	pipeline = _tmp0_;
	_tmp1_ = gst_element_factory_make ("volume", "volume");
	if (_tmp1_ != NULL) {
		g_object_ref_sink (_tmp1_);
	}
	volume_filter = _tmp1_;
	_tmp3_ = pipeline;
	if (_tmp3_ == NULL) {
		_tmp2_ = TRUE;
	} else {
		GstElement* _tmp4_;
		_tmp4_ = volume_filter;
		_tmp2_ = _tmp4_ == NULL;
	}
	if (_tmp2_) {
		GError* _tmp5_;
		_tmp5_ = g_error_new_literal (FT_SOUND_ERROR, FT_SOUND_ERROR_NOT_INITIALIZED, _ ("Failed to initialize playback"));
		_inner_error0_ = _tmp5_;
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (volume_filter);
		_g_object_unref0 (pipeline);
		_g_object_unref0 (self);
		return NULL;
	}
	_tmp6_ = pipeline;
	((GstObject*) _tmp6_)->flags = (guint32) FT_GST_PLAY_FLAGS_AUDIO;
	_tmp7_ = pipeline;
	_tmp8_ = volume_filter;
	g_object_set (_tmp7_, "audio-filter", _tmp8_, NULL);
	_tmp9_ = pipeline;
	g_signal_connect_object (_tmp9_, "about-to-finish", (GCallback) _ft_gstreamer_backend_on_about_to_finish_dynamic_about_to_finish0_, self, 0);
	_tmp10_ = pipeline;
	_tmp11_ = gst_element_get_bus (_tmp10_);
	_tmp12_ = _tmp11_;
	gst_bus_add_watch_full (_tmp12_, G_PRIORITY_DEFAULT, _ft_gstreamer_backend_on_bus_callback_gst_bus_func, g_object_ref (self), g_object_unref);
	_g_object_unref0 (_tmp12_);
	_tmp13_ = pipeline;
	_tmp14_ = _g_object_ref0 (_tmp13_);
	_g_object_unref0 (self->priv->pipeline);
	self->priv->pipeline = _tmp14_;
	_tmp15_ = volume_filter;
	_tmp16_ = _g_object_ref0 (_tmp15_);
	_g_object_unref0 (self->priv->volume_filter);
	self->priv->volume_filter = _tmp16_;
	_tmp17_ = ft_gstreamer_backend_next_instance_id;
	ft_gstreamer_backend_next_instance_id = _tmp17_ + 1;
	self->priv->instance_id = _tmp17_;
	_g_object_unref0 (volume_filter);
	_g_object_unref0 (pipeline);
	return self;
}

FtGStreamerBackend*
ft_gstreamer_backend_new (GError** error)
{
	return ft_gstreamer_backend_construct (FT_TYPE_GSTREAMER_BACKEND, error);
}

gchar**
ft_gstreamer_backend_get_supported_mime_types (gint* result_length1)
{
	gchar* _tmp0_;
	gchar** _tmp1_;
	gchar** _tmp2_;
	gint _tmp2__length1;
	gchar** result;
	_tmp0_ = g_strdup ("audio/*");
	_tmp1_ = g_new0 (gchar*, 1 + 1);
	_tmp1_[0] = _tmp0_;
	_tmp2_ = _tmp1_;
	_tmp2__length1 = 1;
	if (result_length1) {
		*result_length1 = _tmp2__length1;
	}
	result = _tmp2_;
	return result;
}

gboolean
ft_gstreamer_backend_can_play (FtSound* sound,
                               GFile* file,
                               const gchar* content_type)
{
	gboolean _tmp0_ = FALSE;
	gboolean result;
	g_return_val_if_fail (sound != NULL, FALSE);
	g_return_val_if_fail (content_type != NULL, FALSE);
	if (file != NULL) {
		gint _tmp1_ = 0;
		gchar** _tmp2_;
		gchar** _tmp3_;
		gint _tmp3__length1;
		_tmp2_ = ft_gstreamer_backend_get_supported_mime_types (&_tmp1_);
		_tmp3_ = _tmp2_;
		_tmp3__length1 = _tmp1_;
		_tmp0_ = ft_is_mime_type (content_type, _tmp3_, (gint) _tmp1_);
		_tmp3_ = (_vala_array_free (_tmp3_, _tmp3__length1, (GDestroyNotify) g_free), NULL);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

static gchar*
ft_gstreamer_backend_get_debug_name (FtGStreamerBackend* self)
{
	gchar* _tmp0_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup_printf ("GStreamerBackend#%u", self->priv->instance_id);
	result = _tmp0_;
	return result;
}

static void
ft_gstreamer_backend_finished (FtGStreamerBackend* self)
{
	gchar* current_uri = NULL;
	gboolean _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_repeat;
	if (_tmp0_) {
		GstElement* _tmp1_;
		gchar* _tmp2_ = NULL;
		const gchar* _tmp3_;
		_tmp1_ = self->priv->pipeline;
		g_object_get ((GObject*) _tmp1_, "current-uri", &_tmp2_, NULL);
		_g_free0 (current_uri);
		current_uri = _tmp2_;
		_tmp3_ = current_uri;
		if (g_strcmp0 (_tmp3_, "") != 0) {
			GstElement* _tmp4_;
			const gchar* _tmp5_;
			_tmp4_ = self->priv->pipeline;
			_tmp5_ = current_uri;
			g_object_set ((GObject*) _tmp4_, "uri", _tmp5_, NULL);
		}
	}
	_g_free0 (current_uri);
}

static void
ft_gstreamer_backend_on_about_to_finish (FtGStreamerBackend* self)
{
	g_return_if_fail (self != NULL);
	self->priv->is_about_to_finish = TRUE;
	ft_gstreamer_backend_finished (self);
}

static gboolean
ft_gstreamer_backend_on_bus_callback (FtGStreamerBackend* self,
                                      GstBus* bus,
                                      GstMessage* message)
{
	GstState state = 0;
	GstState pending_state = 0;
	GError* _error_ = NULL;
	gchar* debug_info = NULL;
	gchar* _tmp0_ = NULL;
	GstObject* _tmp1_;
	gchar* src_name = NULL;
	gchar* _tmp6_;
	GstElement* _tmp7_;
	GstState _tmp8_ = 0;
	GstState _tmp9_ = 0;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (bus != NULL, FALSE);
	g_return_val_if_fail (message != NULL, FALSE);
	_error_ = NULL;
	debug_info = NULL;
	_tmp1_ = message->src;
	if (_tmp1_ != NULL) {
		GstObject* _tmp2_;
		gchar* _tmp3_;
		gchar* _tmp4_;
		_tmp2_ = message->src;
		_tmp3_ = gst_object_get_name (_tmp2_);
		_tmp4_ = _tmp3_;
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp4_;
	} else {
		gchar* _tmp5_;
		_tmp5_ = g_strdup ("<unknown>");
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp5_;
	}
	_tmp6_ = _tmp0_;
	_tmp0_ = NULL;
	src_name = _tmp6_;
	_tmp7_ = self->priv->pipeline;
	gst_element_get_state (_tmp7_, &_tmp8_, &_tmp9_, GST_CLOCK_TIME_NONE);
	state = _tmp8_;
	pending_state = _tmp9_;
	switch (message->type) {
		case GST_MESSAGE_STATE_CHANGED:
		{
			gboolean _tmp10_ = FALSE;
			gboolean _tmp11_ = FALSE;
			if (!self->priv->_is_playing) {
				_tmp10_ = state == GST_STATE_PLAYING;
			} else {
				_tmp10_ = FALSE;
			}
			if (_tmp10_) {
				self->priv->_is_playing = TRUE;
				g_signal_emit ((FtSoundBackend*) self, ft_sound_backend_signals[FT_SOUND_BACKEND_PLAYBACK_STARTED_SIGNAL], 0);
			}
			if (self->priv->_is_playing) {
				_tmp11_ = state != GST_STATE_PLAYING;
			} else {
				_tmp11_ = FALSE;
			}
			if (_tmp11_) {
				self->priv->_is_playing = FALSE;
				g_signal_emit ((FtSoundBackend*) self, ft_sound_backend_signals[FT_SOUND_BACKEND_PLAYBACK_STOPPED_SIGNAL], 0);
			}
			break;
		}
		case GST_MESSAGE_EOS:
		{
			if (self->priv->is_about_to_finish) {
				self->priv->is_about_to_finish = FALSE;
			} else {
				ft_gstreamer_backend_finished (self);
			}
			if (pending_state != GST_STATE_PLAYING) {
				GstElement* _tmp12_;
				_tmp12_ = self->priv->pipeline;
				gst_element_set_state (_tmp12_, GST_STATE_READY);
			}
			break;
		}
		case GST_MESSAGE_ERROR:
		{
			GError* _tmp13_ = NULL;
			gchar* _tmp14_ = NULL;
			gchar* _tmp15_ = NULL;
			gboolean _tmp16_ = FALSE;
			const gchar* _tmp17_;
			gchar* _tmp22_;
			gchar* _tmp23_;
			const gchar* _tmp24_;
			GError* _tmp25_;
			const gchar* _tmp26_;
			GstElement* _tmp27_;
			GError* _tmp28_;
			if (self->priv->is_about_to_finish) {
				self->priv->is_about_to_finish = FALSE;
			}
			gst_message_parse_error (message, &_tmp13_, &_tmp14_);
			_g_error_free0 (_error_);
			_error_ = _tmp13_;
			_g_free0 (debug_info);
			debug_info = _tmp14_;
			_tmp17_ = debug_info;
			if (_tmp17_ != NULL) {
				const gchar* _tmp18_;
				_tmp18_ = debug_info;
				_tmp16_ = g_strcmp0 (_tmp18_, "") != 0;
			} else {
				_tmp16_ = FALSE;
			}
			if (_tmp16_) {
				const gchar* _tmp19_;
				gchar* _tmp20_;
				_tmp19_ = debug_info;
				_tmp20_ = g_strdup_printf (" [debug: %s]", _tmp19_);
				_g_free0 (_tmp15_);
				_tmp15_ = _tmp20_;
			} else {
				gchar* _tmp21_;
				_tmp21_ = g_strdup ("");
				_g_free0 (_tmp15_);
				_tmp15_ = _tmp21_;
			}
			_tmp22_ = ft_gstreamer_backend_get_debug_name (self);
			_tmp23_ = _tmp22_;
			_tmp24_ = src_name;
			_tmp25_ = _error_;
			_tmp26_ = _tmp25_->message;
			g_warning ("sound.vala:476: %s: error from %s: %s%s", _tmp23_, _tmp24_, _tmp26_, _tmp15_);
			_g_free0 (_tmp23_);
			_tmp27_ = self->priv->pipeline;
			gst_element_set_state (_tmp27_, GST_STATE_NULL);
			_tmp28_ = _error_;
			g_signal_emit ((FtSoundBackend*) self, ft_sound_backend_signals[FT_SOUND_BACKEND_PLAYBACK_ERROR_SIGNAL], 0, _tmp28_);
			_g_free0 (_tmp15_);
			break;
		}
		case GST_MESSAGE_WARNING:
		{
			GError* _tmp29_ = NULL;
			gchar* _tmp30_ = NULL;
			gchar* _tmp31_ = NULL;
			gboolean _tmp32_ = FALSE;
			const gchar* _tmp33_;
			gchar* _tmp38_;
			gchar* _tmp39_;
			const gchar* _tmp40_;
			GError* _tmp41_;
			const gchar* _tmp42_;
			gst_message_parse_warning (message, &_tmp29_, &_tmp30_);
			_g_error_free0 (_error_);
			_error_ = _tmp29_;
			_g_free0 (debug_info);
			debug_info = _tmp30_;
			_tmp33_ = debug_info;
			if (_tmp33_ != NULL) {
				const gchar* _tmp34_;
				_tmp34_ = debug_info;
				_tmp32_ = g_strcmp0 (_tmp34_, "") != 0;
			} else {
				_tmp32_ = FALSE;
			}
			if (_tmp32_) {
				const gchar* _tmp35_;
				gchar* _tmp36_;
				_tmp35_ = debug_info;
				_tmp36_ = g_strdup_printf (" [debug: %s]", _tmp35_);
				_g_free0 (_tmp31_);
				_tmp31_ = _tmp36_;
			} else {
				gchar* _tmp37_;
				_tmp37_ = g_strdup ("");
				_g_free0 (_tmp31_);
				_tmp31_ = _tmp37_;
			}
			_tmp38_ = ft_gstreamer_backend_get_debug_name (self);
			_tmp39_ = _tmp38_;
			_tmp40_ = src_name;
			_tmp41_ = _error_;
			_tmp42_ = _tmp41_->message;
			g_warning ("sound.vala:491: %s: warning from %s: %s%s", _tmp39_, _tmp40_, _tmp42_, _tmp31_);
			_g_free0 (_tmp39_);
			_g_free0 (_tmp31_);
			break;
		}
		default:
		{
			break;
		}
	}
	result = G_SOURCE_CONTINUE;
	_g_free0 (src_name);
	_g_free0 (_tmp0_);
	_g_free0 (debug_info);
	_g_error_free0 (_error_);
	return result;
}

static void
ft_gstreamer_backend_real_play (FtSoundBackend* base)
{
	FtGStreamerBackend * self;
	GstElement* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	self = (FtGStreamerBackend*) base;
	_tmp0_ = self->priv->pipeline;
	_vala_return_if_fail (_tmp0_ != NULL, "this.pipeline != null");
	_tmp1_ = ft_gstreamer_backend_get_uri (self);
	_tmp2_ = _tmp1_;
	if (g_strcmp0 (_tmp2_, "") != 0) {
		GstElement* _tmp3_;
		_tmp3_ = self->priv->pipeline;
		gst_element_set_state (_tmp3_, GST_STATE_PLAYING);
	}
}

static void
ft_gstreamer_backend_real_stop (FtSoundBackend* base)
{
	FtGStreamerBackend * self;
	GstState state = 0;
	GstState pending_state = 0;
	GstElement* _tmp0_;
	GstElement* _tmp1_;
	GstState _tmp2_ = 0;
	GstState _tmp3_ = 0;
	gboolean _tmp4_ = FALSE;
	self = (FtGStreamerBackend*) base;
	_tmp0_ = self->priv->pipeline;
	if (_tmp0_ == NULL) {
		return;
	}
	_tmp1_ = self->priv->pipeline;
	gst_element_get_state (_tmp1_, &_tmp2_, &_tmp3_, GST_CLOCK_TIME_NONE);
	state = _tmp2_;
	pending_state = _tmp3_;
	if (pending_state != GST_STATE_VOID_PENDING) {
		state = pending_state;
	}
	if (state != GST_STATE_NULL) {
		_tmp4_ = state != GST_STATE_READY;
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		GstElement* _tmp5_;
		_tmp5_ = self->priv->pipeline;
		gst_element_set_state (_tmp5_, GST_STATE_READY);
	}
}

static gboolean
ft_gstreamer_backend_real_is_playing (FtSoundBackend* base)
{
	FtGStreamerBackend * self;
	gboolean result;
	self = (FtGStreamerBackend*) base;
	result = self->priv->_is_playing;
	return result;
}

static void
ft_gstreamer_backend_real_dispose (GObject* base)
{
	FtGStreamerBackend * self;
	GstElement* _tmp0_;
	self = (FtGStreamerBackend*) base;
	_tmp0_ = self->priv->pipeline;
	if (_tmp0_ != NULL) {
		GstElement* _tmp1_;
		_tmp1_ = self->priv->pipeline;
		gst_element_set_state (_tmp1_, GST_STATE_NULL);
		_g_object_unref0 (self->priv->pipeline);
		self->priv->pipeline = NULL;
	}
	G_OBJECT_CLASS (ft_gstreamer_backend_parent_class)->dispose (G_TYPE_CHECK_INSTANCE_CAST (self, G_TYPE_OBJECT, GObject));
}

const gchar*
ft_gstreamer_backend_get_uri (FtGStreamerBackend* self)
{
	const gchar* result;
	GstElement* _tmp0_;
	gchar* _tmp1_;
	const gchar* _tmp2_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->pipeline;
	g_object_get (_tmp0_, "uri", &_tmp1_, NULL);
	_tmp2_ = _tmp1_;
	result = _tmp2_;
	return result;
}

void
ft_gstreamer_backend_set_uri (FtGStreamerBackend* self,
                              const gchar* value)
{
	GstState state = 0;
	GstState pending_state = 0;
	GstElement* _tmp0_;
	GstState _tmp1_ = 0;
	GstState _tmp2_ = 0;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->pipeline;
	gst_element_get_state (_tmp0_, &_tmp1_, &_tmp2_, GST_CLOCK_TIME_NONE);
	state = _tmp1_;
	pending_state = _tmp2_;
	if (pending_state != GST_STATE_VOID_PENDING) {
		state = pending_state;
	}
	if (state == GST_STATE_PLAYING) {
		GstElement* _tmp3_;
		GstElement* _tmp4_;
		GstElement* _tmp5_;
		_tmp3_ = self->priv->pipeline;
		gst_element_set_state (_tmp3_, GST_STATE_READY);
		_tmp4_ = self->priv->pipeline;
		g_object_set (_tmp4_, "uri", value, NULL);
		_tmp5_ = self->priv->pipeline;
		gst_element_set_state (_tmp5_, GST_STATE_PLAYING);
	} else {
		GstElement* _tmp6_;
		GstElement* _tmp7_;
		_tmp6_ = self->priv->pipeline;
		g_object_set (_tmp6_, "uri", value, NULL);
		_tmp7_ = self->priv->pipeline;
		gst_element_set_state (_tmp7_, GST_STATE_READY);
	}
	g_object_notify_by_pspec ((GObject *) self, ft_gstreamer_backend_properties[FT_GSTREAMER_BACKEND_URI_PROPERTY]);
}

gdouble
ft_gstreamer_backend_get_volume (FtGStreamerBackend* self)
{
	gdouble result;
	GstElement* _tmp0_;
	gdouble _tmp1_;
	gdouble _tmp2_;
	g_return_val_if_fail (self != NULL, -1.0);
	_tmp0_ = self->priv->pipeline;
	g_object_get (_tmp0_, "volume", &_tmp1_, NULL);
	_tmp2_ = _tmp1_;
	result = _tmp2_;
	return result;
}

void
ft_gstreamer_backend_set_volume (FtGStreamerBackend* self,
                                 gdouble value)
{
	GstElement* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->pipeline;
	g_object_set (_tmp0_, "volume", CLAMP (value, 0.0, 1.0), NULL);
	g_object_notify_by_pspec ((GObject *) self, ft_gstreamer_backend_properties[FT_GSTREAMER_BACKEND_VOLUME_PROPERTY]);
}

gdouble
ft_gstreamer_backend_get_volume_fade (FtGStreamerBackend* self)
{
	gdouble result;
	GstElement* _tmp0_;
	gdouble _tmp1_;
	gdouble _tmp2_;
	g_return_val_if_fail (self != NULL, -1.0);
	_tmp0_ = self->priv->volume_filter;
	g_object_get (_tmp0_, "volume", &_tmp1_, NULL);
	_tmp2_ = _tmp1_;
	result = _tmp2_;
	return result;
}

void
ft_gstreamer_backend_set_volume_fade (FtGStreamerBackend* self,
                                      gdouble value)
{
	GstElement* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->volume_filter;
	g_object_set (_tmp0_, "volume", CLAMP (value, 0.0, 1.0), NULL);
	g_object_notify_by_pspec ((GObject *) self, ft_gstreamer_backend_properties[FT_GSTREAMER_BACKEND_VOLUME_FADE_PROPERTY]);
}

gboolean
ft_gstreamer_backend_get_repeat (FtGStreamerBackend* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_repeat;
	return result;
}

void
ft_gstreamer_backend_set_repeat (FtGStreamerBackend* self,
                                 gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = ft_gstreamer_backend_get_repeat (self);
	if (old_value != value) {
		self->priv->_repeat = value;
		g_object_notify_by_pspec ((GObject *) self, ft_gstreamer_backend_properties[FT_GSTREAMER_BACKEND_REPEAT_PROPERTY]);
	}
}

static void
ft_gstreamer_backend_class_init (FtGStreamerBackendClass * klass,
                                 gpointer klass_data)
{
	ft_gstreamer_backend_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &FtGStreamerBackend_private_offset);
	((GObjectClass *) klass)->dispose = (void (*) (GObject*)) ft_gstreamer_backend_real_dispose;
	G_OBJECT_CLASS (klass)->get_property = _vala_ft_gstreamer_backend_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_ft_gstreamer_backend_set_property;
	G_OBJECT_CLASS (klass)->finalize = ft_gstreamer_backend_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_GSTREAMER_BACKEND_URI_PROPERTY, ft_gstreamer_backend_properties[FT_GSTREAMER_BACKEND_URI_PROPERTY] = g_param_spec_string ("uri", "uri", "uri", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_GSTREAMER_BACKEND_VOLUME_PROPERTY, ft_gstreamer_backend_properties[FT_GSTREAMER_BACKEND_VOLUME_PROPERTY] = g_param_spec_double ("volume", "volume", "volume", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_GSTREAMER_BACKEND_VOLUME_FADE_PROPERTY, ft_gstreamer_backend_properties[FT_GSTREAMER_BACKEND_VOLUME_FADE_PROPERTY] = g_param_spec_double ("volume-fade", "volume-fade", "volume-fade", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_GSTREAMER_BACKEND_REPEAT_PROPERTY, ft_gstreamer_backend_properties[FT_GSTREAMER_BACKEND_REPEAT_PROPERTY] = g_param_spec_boolean ("repeat", "repeat", "repeat", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
}

static void
ft_gstreamer_backend_ft_sound_backend_interface_init (FtSoundBackendIface * iface,
                                                      gpointer iface_data)
{
	ft_gstreamer_backend_ft_sound_backend_parent_iface = g_type_interface_peek_parent (iface);
	iface->play = (void (*) (FtSoundBackend*)) ft_gstreamer_backend_real_play;
	iface->stop = (void (*) (FtSoundBackend*)) ft_gstreamer_backend_real_stop;
	iface->is_playing = (gboolean (*) (FtSoundBackend*)) ft_gstreamer_backend_real_is_playing;
}

static void
ft_gstreamer_backend_instance_init (FtGStreamerBackend * self,
                                    gpointer klass)
{
	self->priv = ft_gstreamer_backend_get_instance_private (self);
	self->priv->_repeat = FALSE;
	self->priv->_is_playing = FALSE;
	self->priv->is_about_to_finish = FALSE;
	self->priv->instance_id = (guint) 0;
}

static void
ft_gstreamer_backend_finalize (GObject * obj)
{
	FtGStreamerBackend * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, FT_TYPE_GSTREAMER_BACKEND, FtGStreamerBackend);
	_g_object_unref0 (self->priv->pipeline);
	_g_object_unref0 (self->priv->volume_filter);
	G_OBJECT_CLASS (ft_gstreamer_backend_parent_class)->finalize (obj);
}

static GType
ft_gstreamer_backend_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (FtGStreamerBackendClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ft_gstreamer_backend_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FtGStreamerBackend), 0, (GInstanceInitFunc) ft_gstreamer_backend_instance_init, NULL };
	static const GInterfaceInfo ft_sound_backend_info = { (GInterfaceInitFunc) ft_gstreamer_backend_ft_sound_backend_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	GType ft_gstreamer_backend_type_id;
	ft_gstreamer_backend_type_id = g_type_register_static (G_TYPE_OBJECT, "FtGStreamerBackend", &g_define_type_info, 0);
	g_type_add_interface_static (ft_gstreamer_backend_type_id, FT_TYPE_SOUND_BACKEND, &ft_sound_backend_info);
	FtGStreamerBackend_private_offset = g_type_add_instance_private (ft_gstreamer_backend_type_id, sizeof (FtGStreamerBackendPrivate));
	return ft_gstreamer_backend_type_id;
}

GType
ft_gstreamer_backend_get_type (void)
{
	static volatile gsize ft_gstreamer_backend_type_id__once = 0;
	if (g_once_init_enter (&ft_gstreamer_backend_type_id__once)) {
		GType ft_gstreamer_backend_type_id;
		ft_gstreamer_backend_type_id = ft_gstreamer_backend_get_type_once ();
		g_once_init_leave (&ft_gstreamer_backend_type_id__once, ft_gstreamer_backend_type_id);
	}
	return ft_gstreamer_backend_type_id__once;
}

static void
_vala_ft_gstreamer_backend_get_property (GObject * object,
                                         guint property_id,
                                         GValue * value,
                                         GParamSpec * pspec)
{
	FtGStreamerBackend * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_GSTREAMER_BACKEND, FtGStreamerBackend);
	switch (property_id) {
		case FT_GSTREAMER_BACKEND_URI_PROPERTY:
		g_value_set_string (value, ft_gstreamer_backend_get_uri (self));
		break;
		case FT_GSTREAMER_BACKEND_VOLUME_PROPERTY:
		g_value_set_double (value, ft_gstreamer_backend_get_volume (self));
		break;
		case FT_GSTREAMER_BACKEND_VOLUME_FADE_PROPERTY:
		g_value_set_double (value, ft_gstreamer_backend_get_volume_fade (self));
		break;
		case FT_GSTREAMER_BACKEND_REPEAT_PROPERTY:
		g_value_set_boolean (value, ft_gstreamer_backend_get_repeat (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_ft_gstreamer_backend_set_property (GObject * object,
                                         guint property_id,
                                         const GValue * value,
                                         GParamSpec * pspec)
{
	FtGStreamerBackend * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_GSTREAMER_BACKEND, FtGStreamerBackend);
	switch (property_id) {
		case FT_GSTREAMER_BACKEND_URI_PROPERTY:
		ft_gstreamer_backend_set_uri (self, g_value_get_string (value));
		break;
		case FT_GSTREAMER_BACKEND_VOLUME_PROPERTY:
		ft_gstreamer_backend_set_volume (self, g_value_get_double (value));
		break;
		case FT_GSTREAMER_BACKEND_VOLUME_FADE_PROPERTY:
		ft_gstreamer_backend_set_volume_fade (self, g_value_get_double (value));
		break;
		case FT_GSTREAMER_BACKEND_REPEAT_PROPERTY:
		ft_gstreamer_backend_set_repeat (self, g_value_get_boolean (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

GQuark
ft_sound_error_quark (void)
{
	return g_quark_from_static_string ("ft-sound-error-quark");
}

static GType
ft_sound_error_get_type_once (void)
{
	static const GEnumValue values[] = {{FT_SOUND_ERROR_NOT_FOUND, "FT_SOUND_ERROR_NOT_FOUND", "not-found"}, {FT_SOUND_ERROR_NOT_INITIALIZED, "FT_SOUND_ERROR_NOT_INITIALIZED", "not-initialized"}, {FT_SOUND_ERROR_NOT_SUPPORTED, "FT_SOUND_ERROR_NOT_SUPPORTED", "not-supported"}, {0, NULL, NULL}};
	GType ft_sound_error_type_id;
	ft_sound_error_type_id = g_enum_register_static ("FtSoundError", values);
	return ft_sound_error_type_id;
}

GType
ft_sound_error_get_type (void)
{
	static volatile gsize ft_sound_error_type_id__once = 0;
	if (g_once_init_enter (&ft_sound_error_type_id__once)) {
		GType ft_sound_error_type_id;
		ft_sound_error_type_id = ft_sound_error_get_type_once ();
		g_once_init_leave (&ft_sound_error_type_id__once, ft_sound_error_type_id);
	}
	return ft_sound_error_type_id__once;
}

static inline gpointer
ft_sound_get_instance_private (FtSound* self)
{
	return G_STRUCT_MEMBER_P (self, FtSound_private_offset);
}

static gchar*
ft_sound_real_get_debug_name (FtSound* self)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* result;
	_tmp0_ = g_type_name (G_TYPE_FROM_INSTANCE ((GObject*) self));
	_tmp1_ = g_strdup (_tmp0_);
	result = _tmp1_;
	return result;
}

gchar*
ft_sound_get_debug_name (FtSound* self)
{
	FtSoundClass* _klass_;
	g_return_val_if_fail (self != NULL, NULL);
	_klass_ = FT_SOUND_GET_CLASS (self);
	if (_klass_->get_debug_name) {
		return _klass_->get_debug_name (self);
	}
	return NULL;
}

gchar*
ft_sound_get_absolute_uri (FtSound* self)
{
	const gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_uri;
	_tmp1_ = ft_build_absolute_uri (_tmp0_);
	result = _tmp1_;
	return result;
}

static void
ft_sound_on_playback_error (FtSound* self,
                            GError* _error_)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	const gchar* _tmp4_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (_error_ != NULL);
	_tmp0_ = ft_sound_get_debug_name (self);
	_tmp1_ = _tmp0_;
	_tmp2_ = ft_sound_get_absolute_uri (self);
	_tmp3_ = _tmp2_;
	_tmp4_ = _error_->message;
	g_warning ("sound.vala:615: %s: playback error for uri=%s: %s", _tmp1_, _tmp3_, _tmp4_);
	_g_free0 (_tmp3_);
	_g_free0 (_tmp1_);
	ft_sound_set_error (self, _error_);
}

static void
ft_sound_prepare (FtSound* self)
{
	GFile* _tmp0_ = NULL;
	const gchar* _tmp1_;
	GFile* file = NULL;
	GFile* _tmp5_;
	gchar* _tmp6_ = NULL;
	GFile* _tmp7_;
	gchar* content_type = NULL;
	gchar* _tmp13_;
	FtSoundBackend* backend = NULL;
	FtSoundBackend* _tmp14_;
	FtSoundBackend* _tmp15_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->priv->_uri;
	if (g_strcmp0 (_tmp1_, "") != 0) {
		gchar* _tmp2_;
		gchar* _tmp3_;
		GFile* _tmp4_;
		_tmp2_ = ft_sound_get_absolute_uri (self);
		_tmp3_ = _tmp2_;
		_tmp4_ = g_file_new_for_uri (_tmp3_);
		_g_object_unref0 (_tmp0_);
		_tmp0_ = _tmp4_;
		_g_free0 (_tmp3_);
	} else {
		_g_object_unref0 (_tmp0_);
		_tmp0_ = NULL;
	}
	_tmp5_ = _tmp0_;
	_tmp0_ = NULL;
	file = _tmp5_;
	_tmp7_ = file;
	if (_tmp7_ != NULL) {
		GFile* _tmp8_;
		gchar* _tmp9_;
		gchar* _tmp10_;
		gchar* _tmp11_;
		_tmp8_ = file;
		_tmp9_ = g_file_get_basename (_tmp8_);
		_tmp10_ = _tmp9_;
		_tmp11_ = g_content_type_guess (_tmp10_, NULL, (gsize) 0, NULL);
		_g_free0 (_tmp6_);
		_tmp6_ = _tmp11_;
		_g_free0 (_tmp10_);
	} else {
		gchar* _tmp12_;
		_tmp12_ = g_strdup ("");
		_g_free0 (_tmp6_);
		_tmp6_ = _tmp12_;
	}
	_tmp13_ = _tmp6_;
	_tmp6_ = NULL;
	content_type = _tmp13_;
	_tmp14_ = self->priv->_backend;
	_tmp15_ = _g_object_ref0 (_tmp14_);
	backend = _tmp15_;
	{
		gboolean _tmp16_ = FALSE;
		GFile* _tmp17_;
		GFile* _tmp20_;
		const gchar* _tmp21_;
		FtSoundBackend* _tmp28_;
		FtSoundBackend* _tmp29_;
		FtSoundBackend* _tmp30_;
		FtSoundBackend* _tmp31_;
		_tmp17_ = file;
		if (_tmp17_ != NULL) {
			GFile* _tmp18_;
			_tmp18_ = file;
			_tmp16_ = !g_file_query_exists (_tmp18_, NULL);
		} else {
			_tmp16_ = FALSE;
		}
		if (_tmp16_) {
			GError* _tmp19_;
			_tmp19_ = g_error_new_literal (FT_SOUND_ERROR, FT_SOUND_ERROR_NOT_FOUND, _ ("File not found"));
			_inner_error0_ = _tmp19_;
			goto __catch0_g_error;
		}
		_tmp20_ = file;
		_tmp21_ = content_type;
		if (ft_gstreamer_backend_can_play (self, _tmp20_, _tmp21_)) {
			FtSoundBackend* _tmp22_;
			_tmp22_ = backend;
			if (!FT_IS_GSTREAMER_BACKEND (_tmp22_)) {
				FtGStreamerBackend* _tmp23_ = NULL;
				FtGStreamerBackend* _tmp24_;
				FtGStreamerBackend* _tmp25_;
				_tmp24_ = ft_gstreamer_backend_new (&_inner_error0_);
				_tmp23_ = _tmp24_;
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					goto __catch0_g_error;
				}
				_tmp25_ = _tmp23_;
				_tmp23_ = NULL;
				_g_object_unref0 (backend);
				backend = (FtSoundBackend*) _tmp25_;
				_g_object_unref0 (_tmp23_);
			}
		} else {
			GFile* _tmp26_;
			_tmp26_ = file;
			if (_tmp26_ != NULL) {
				GError* _tmp27_;
				_tmp27_ = g_error_new_literal (FT_SOUND_ERROR, FT_SOUND_ERROR_NOT_SUPPORTED, _ ("File type not supported"));
				_inner_error0_ = _tmp27_;
				goto __catch0_g_error;
			}
			_g_object_unref0 (backend);
			backend = NULL;
		}
		_tmp28_ = self->priv->_backend;
		if (_tmp28_ != NULL) {
			ft_sound_destroy_backend (self);
		}
		_tmp29_ = backend;
		_tmp30_ = _g_object_ref0 (_tmp29_);
		_g_object_unref0 (self->priv->_backend);
		self->priv->_backend = _tmp30_;
		ft_sound_set_error (self, NULL);
		_tmp31_ = backend;
		if (_tmp31_ != NULL) {
			ft_sound_initialize_backend (self);
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* _error_ = NULL;
		gchar* _tmp32_;
		gchar* _tmp33_;
		gchar* _tmp34_;
		gchar* _tmp35_;
		GError* _tmp36_;
		const gchar* _tmp37_;
		FtSoundBackend* _tmp38_;
		GError* _tmp39_;
		_error_ = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp32_ = ft_sound_get_debug_name (self);
		_tmp33_ = _tmp32_;
		_tmp34_ = ft_sound_get_absolute_uri (self);
		_tmp35_ = _tmp34_;
		_tmp36_ = _error_;
		_tmp37_ = _tmp36_->message;
		g_warning ("sound.vala:663: %s: error while initializing sound player for uri=%s: " \
"%s", _tmp33_, _tmp35_, _tmp37_);
		_g_free0 (_tmp35_);
		_g_free0 (_tmp33_);
		_tmp38_ = self->priv->_backend;
		if (_tmp38_ != NULL) {
			ft_sound_destroy_backend (self);
		}
		_g_object_unref0 (self->priv->_backend);
		self->priv->_backend = NULL;
		_tmp39_ = _error_;
		ft_sound_set_error (self, _tmp39_);
		_g_error_free0 (_error_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (backend);
		_g_free0 (content_type);
		_g_free0 (_tmp6_);
		_g_object_unref0 (file);
		_g_object_unref0 (_tmp0_);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
	g_object_notify ((GObject*) self, "backend");
	g_object_notify ((GObject*) self, "error");
	_g_object_unref0 (backend);
	_g_free0 (content_type);
	_g_free0 (_tmp6_);
	_g_object_unref0 (file);
	_g_object_unref0 (_tmp0_);
}

gchar**
ft_sound_get_supported_mime_types (FtSound* self,
                                   gint* result_length1)
{
	gint _tmp0_ = 0;
	gchar** _tmp1_;
	gchar** _tmp2_;
	gint _tmp2__length1;
	gchar** result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp1_ = ft_gstreamer_backend_get_supported_mime_types (&_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp2__length1 = _tmp0_;
	if (result_length1) {
		*result_length1 = _tmp2__length1;
	}
	result = _tmp2_;
	return result;
}

gboolean
ft_sound_can_play (FtSound* self)
{
	FtSoundBackend* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->_backend;
	result = _tmp0_ != NULL;
	return result;
}

gboolean
ft_sound_is_playing (FtSound* self)
{
	gboolean _tmp0_ = FALSE;
	FtSoundBackend* _tmp1_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp1_ = self->priv->_backend;
	if (_tmp1_ != NULL) {
		FtSoundBackend* _tmp2_;
		_tmp2_ = self->priv->_backend;
		_tmp0_ = ft_sound_backend_is_playing (_tmp2_);
	} else {
		_tmp0_ = FALSE;
	}
	result = _tmp0_;
	return result;
}

void
ft_sound_play (FtSound* self)
{
	FtSoundBackend* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_backend;
	if (_tmp0_ != NULL) {
		FtSoundBackend* _tmp1_;
		_tmp1_ = self->priv->_backend;
		ft_sound_backend_play (_tmp1_);
	} else {
		const gchar* _tmp2_;
		_tmp2_ = self->priv->_uri;
		if (g_strcmp0 (_tmp2_, "") != 0) {
			const gchar* _tmp3_ = NULL;
			GError* _tmp4_;
			gchar* _tmp7_;
			gchar* _tmp8_;
			gchar* _tmp9_;
			gchar* _tmp10_;
			_tmp4_ = self->priv->_error;
			if (_tmp4_ != NULL) {
				GError* _tmp5_;
				const gchar* _tmp6_;
				_tmp5_ = self->priv->_error;
				_tmp6_ = _tmp5_->message;
				_tmp3_ = _tmp6_;
			} else {
				_tmp3_ = "<none>";
			}
			_tmp7_ = ft_sound_get_debug_name (self);
			_tmp8_ = _tmp7_;
			_tmp9_ = ft_sound_get_absolute_uri (self);
			_tmp10_ = _tmp9_;
			g_warning ("sound.vala:701: %s: play requested without an initialized backend (uri" \
"=%s error=%s)", _tmp8_, _tmp10_, _tmp3_);
			_g_free0 (_tmp10_);
			_g_free0 (_tmp8_);
		}
	}
}

void
ft_sound_stop (FtSound* self)
{
	FtSoundBackend* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_backend;
	if (_tmp0_ != NULL) {
		FtSoundBackend* _tmp1_;
		_tmp1_ = self->priv->_backend;
		ft_sound_backend_stop (_tmp1_);
	}
}

static void
_ft_sound_on_playback_error_ft_sound_backend_playback_error (FtSoundBackend* _sender,
                                                             GError* _error_,
                                                             gpointer self)
{
	ft_sound_on_playback_error ((FtSound*) self, _error_);
}

static void
ft_sound_real_initialize_backend (FtSound* self)
{
	FtSoundBackend* _tmp0_;
	FtSoundBackend* _tmp1_;
	_tmp0_ = self->priv->_backend;
	_vala_return_if_fail (_tmp0_ != NULL, "this._backend != null");
	_tmp1_ = self->priv->_backend;
	g_signal_connect_object (_tmp1_, "playback-error", (GCallback) _ft_sound_on_playback_error_ft_sound_backend_playback_error, self, 0);
}

void
ft_sound_initialize_backend (FtSound* self)
{
	FtSoundBackend* _tmp0_;
	FtSoundClass* _klass_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_backend;
	_vala_return_if_fail (_tmp0_ != NULL, "this._backend != null");
	_klass_ = FT_SOUND_GET_CLASS (self);
	if (_klass_->initialize_backend) {
		_klass_->initialize_backend (self);
	}
}

static void
ft_sound_real_destroy_backend (FtSound* self)
{
	FtSoundBackend* _tmp0_;
	FtSoundBackend* _tmp1_;
	FtSoundBackend* _tmp2_;
	guint _tmp3_;
	_tmp0_ = self->priv->_backend;
	_vala_return_if_fail (_tmp0_ != NULL, "this._backend != null");
	_tmp1_ = self->priv->_backend;
	ft_sound_backend_stop (_tmp1_);
	_tmp2_ = self->priv->_backend;
	g_signal_parse_name ("playback-error", FT_TYPE_SOUND_BACKEND, &_tmp3_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (_tmp2_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp3_, 0, NULL, (GCallback) _ft_sound_on_playback_error_ft_sound_backend_playback_error, self);
}

void
ft_sound_destroy_backend (FtSound* self)
{
	FtSoundBackend* _tmp0_;
	FtSoundClass* _klass_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_backend;
	_vala_return_if_fail (_tmp0_ != NULL, "this._backend != null");
	_klass_ = FT_SOUND_GET_CLASS (self);
	if (_klass_->destroy_backend) {
		_klass_->destroy_backend (self);
	}
}

static void
ft_sound_real_destroy (FtSound* self)
{
	FtSoundBackend* _tmp0_;
	_tmp0_ = self->priv->_backend;
	if (_tmp0_ != NULL) {
		ft_sound_destroy_backend (self);
		_g_object_unref0 (self->priv->_backend);
		self->priv->_backend = NULL;
	}
}

void
ft_sound_destroy (FtSound* self)
{
	FtSoundClass* _klass_;
	g_return_if_fail (self != NULL);
	_klass_ = FT_SOUND_GET_CLASS (self);
	if (_klass_->destroy) {
		_klass_->destroy (self);
	}
}

FtSound*
ft_sound_construct (GType object_type)
{
	FtSound * self = NULL;
	self = (FtSound*) g_object_new (object_type, NULL);
	return self;
}

const gchar*
ft_sound_get_uri (FtSound* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_uri;
	result = _tmp0_;
	return result;
}

void
ft_sound_set_uri (FtSound* self,
                  const gchar* value)
{
	gboolean _tmp0_ = FALSE;
	const gchar* _tmp1_;
	const gchar* _tmp3_;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->priv->_uri;
	if (g_strcmp0 (_tmp1_, value) == 0) {
		GError* _tmp2_;
		_tmp2_ = self->priv->_error;
		_tmp0_ = _tmp2_ != NULL;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		ft_sound_prepare (self);
		return;
	}
	_tmp3_ = self->priv->_uri;
	if (g_strcmp0 (_tmp3_, value) != 0) {
		gchar* _tmp4_;
		_tmp4_ = g_strdup (value);
		_g_free0 (self->priv->_uri);
		self->priv->_uri = _tmp4_;
		ft_sound_prepare (self);
		g_object_notify ((GObject*) self, "uri");
	}
}

gdouble
ft_sound_get_volume (FtSound* self)
{
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	result = self->priv->_volume;
	return result;
}

void
ft_sound_set_volume (FtSound* self,
                     gdouble value)
{
	gdouble old_value;
	g_return_if_fail (self != NULL);
	old_value = ft_sound_get_volume (self);
	if (old_value != value) {
		self->priv->_volume = value;
		g_object_notify_by_pspec ((GObject *) self, ft_sound_properties[FT_SOUND_VOLUME_PROPERTY]);
	}
}

FtSoundBackend*
ft_sound_get_backend (FtSound* self)
{
	FtSoundBackend* result;
	FtSoundBackend* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_backend;
	result = _tmp0_;
	return result;
}

GError*
ft_sound_get_error (FtSound* self)
{
	GError* result;
	GError* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_error;
	result = _tmp0_;
	return result;
}

static gpointer
_g_error_copy0 (gpointer self)
{
	return self ? g_error_copy (self) : NULL;
}

static void
ft_sound_set_error (FtSound* self,
                    GError* value)
{
	GError* old_value;
	g_return_if_fail (self != NULL);
	old_value = ft_sound_get_error (self);
	if (old_value != value) {
		GError* _tmp0_;
		_tmp0_ = _g_error_copy0 (value);
		_g_error_free0 (self->priv->_error);
		self->priv->_error = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, ft_sound_properties[FT_SOUND_ERROR_PROPERTY]);
	}
}

static void
ft_sound_class_init (FtSoundClass * klass,
                     gpointer klass_data)
{
	ft_sound_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &FtSound_private_offset);
	((FtSoundClass *) klass)->get_debug_name = (gchar* (*) (FtSound*)) ft_sound_real_get_debug_name;
	((FtSoundClass *) klass)->initialize_backend = (void (*) (FtSound*)) ft_sound_real_initialize_backend;
	((FtSoundClass *) klass)->destroy_backend = (void (*) (FtSound*)) ft_sound_real_destroy_backend;
	((FtSoundClass *) klass)->destroy = (void (*) (FtSound*)) ft_sound_real_destroy;
	G_OBJECT_CLASS (klass)->get_property = _vala_ft_sound_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_ft_sound_set_property;
	G_OBJECT_CLASS (klass)->finalize = ft_sound_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_SOUND_URI_PROPERTY, ft_sound_properties[FT_SOUND_URI_PROPERTY] = g_param_spec_string ("uri", "uri", "uri", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_SOUND_VOLUME_PROPERTY, ft_sound_properties[FT_SOUND_VOLUME_PROPERTY] = g_param_spec_double ("volume", "volume", "volume", -G_MAXDOUBLE, G_MAXDOUBLE, 1.0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_SOUND_BACKEND_PROPERTY, ft_sound_properties[FT_SOUND_BACKEND_PROPERTY] = g_param_spec_object ("backend", "backend", "backend", FT_TYPE_SOUND_BACKEND, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_SOUND_ERROR_PROPERTY, ft_sound_properties[FT_SOUND_ERROR_PROPERTY] = g_param_spec_boxed ("error", "error", "error", G_TYPE_ERROR, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
}

static void
ft_sound_instance_init (FtSound * self,
                        gpointer klass)
{
	gchar* _tmp0_;
	self->priv = ft_sound_get_instance_private (self);
	self->priv->_volume = 1.0;
	_tmp0_ = g_strdup ("");
	self->priv->_uri = _tmp0_;
	self->priv->_backend = NULL;
}

static void
ft_sound_finalize (GObject * obj)
{
	FtSound * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, FT_TYPE_SOUND, FtSound);
	_g_error_free0 (self->priv->_error);
	_g_free0 (self->priv->_uri);
	_g_object_unref0 (self->priv->_backend);
	G_OBJECT_CLASS (ft_sound_parent_class)->finalize (obj);
}

/**
     * A sound player instance is intended for playing a single sound multiple times.
     */
static GType
ft_sound_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (FtSoundClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ft_sound_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FtSound), 0, (GInstanceInitFunc) ft_sound_instance_init, NULL };
	GType ft_sound_type_id;
	ft_sound_type_id = g_type_register_static (G_TYPE_OBJECT, "FtSound", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
	FtSound_private_offset = g_type_add_instance_private (ft_sound_type_id, sizeof (FtSoundPrivate));
	return ft_sound_type_id;
}

GType
ft_sound_get_type (void)
{
	static volatile gsize ft_sound_type_id__once = 0;
	if (g_once_init_enter (&ft_sound_type_id__once)) {
		GType ft_sound_type_id;
		ft_sound_type_id = ft_sound_get_type_once ();
		g_once_init_leave (&ft_sound_type_id__once, ft_sound_type_id);
	}
	return ft_sound_type_id__once;
}

static void
_vala_ft_sound_get_property (GObject * object,
                             guint property_id,
                             GValue * value,
                             GParamSpec * pspec)
{
	FtSound * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_SOUND, FtSound);
	switch (property_id) {
		case FT_SOUND_URI_PROPERTY:
		g_value_set_string (value, ft_sound_get_uri (self));
		break;
		case FT_SOUND_VOLUME_PROPERTY:
		g_value_set_double (value, ft_sound_get_volume (self));
		break;
		case FT_SOUND_BACKEND_PROPERTY:
		g_value_set_object (value, ft_sound_get_backend (self));
		break;
		case FT_SOUND_ERROR_PROPERTY:
		g_value_set_boxed (value, ft_sound_get_error (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_ft_sound_set_property (GObject * object,
                             guint property_id,
                             const GValue * value,
                             GParamSpec * pspec)
{
	FtSound * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_SOUND, FtSound);
	switch (property_id) {
		case FT_SOUND_URI_PROPERTY:
		ft_sound_set_uri (self, g_value_get_string (value));
		break;
		case FT_SOUND_VOLUME_PROPERTY:
		ft_sound_set_volume (self, g_value_get_double (value));
		break;
		case FT_SOUND_ERROR_PROPERTY:
		ft_sound_set_error (self, g_value_get_boxed (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
ft_alert_sound_get_instance_private (FtAlertSound* self)
{
	return G_STRUCT_MEMBER_P (self, FtAlertSound_private_offset);
}

FtAlertSound*
ft_alert_sound_construct (GType object_type,
                          const gchar* event_id)
{
	FtAlertSound * self = NULL;
	g_return_val_if_fail (event_id != NULL, NULL);
	self = (FtAlertSound*) g_object_new (object_type, "event-id", event_id, NULL);
	return self;
}

FtAlertSound*
ft_alert_sound_new (const gchar* event_id)
{
	return ft_alert_sound_construct (FT_TYPE_ALERT_SOUND, event_id);
}

static gchar*
ft_alert_sound_real_get_debug_name (FtSound* base)
{
	FtAlertSound * self;
	const gchar* _tmp0_;
	const gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* result;
	self = (FtAlertSound*) base;
	_tmp0_ = g_type_name (G_TYPE_FROM_INSTANCE ((GObject*) self));
	_tmp1_ = self->priv->_event_id;
	_tmp2_ = g_strdup_printf ("%s[event_id=%s]", _tmp0_, _tmp1_);
	result = _tmp2_;
	return result;
}

static gboolean
_ft_transform_uri_to_uri_gbinding_transform_func (GBinding* binding,
                                                  GValue* from_value,
                                                  GValue* to_value,
                                                  gpointer self)
{
	gboolean result;
	result = ft_transform_uri_to_uri (binding, from_value, to_value);
	return result;
}

static void
ft_alert_sound_real_initialize_backend (FtSound* base)
{
	FtAlertSound * self;
	FtSoundBackend* _tmp0_;
	FtSoundBackend* _tmp1_;
	self = (FtAlertSound*) base;
	FT_SOUND_CLASS (ft_alert_sound_parent_class)->initialize_backend (G_TYPE_CHECK_INSTANCE_CAST (self, FT_TYPE_SOUND, FtSound));
	_tmp0_ = ft_sound_get_backend ((FtSound*) self);
	_tmp1_ = _tmp0_;
	if (FT_IS_GSTREAMER_BACKEND (_tmp1_)) {
		FtSoundBackend* _tmp2_;
		FtSoundBackend* _tmp3_;
		FtSoundBackend* _tmp4_;
		FtSoundBackend* _tmp5_;
		_tmp2_ = ft_sound_get_backend ((FtSound*) self);
		_tmp3_ = _tmp2_;
		g_object_bind_property_with_closures ((GObject*) self, "uri", (GObject*) _tmp3_, "uri", G_BINDING_SYNC_CREATE, (GClosure*) g_cclosure_new ((GCallback) _ft_transform_uri_to_uri_gbinding_transform_func, NULL, (GClosureNotify) NULL), (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)));
		_tmp4_ = ft_sound_get_backend ((FtSound*) self);
		_tmp5_ = _tmp4_;
		g_object_bind_property_with_closures ((GObject*) self, "volume", (GObject*) _tmp5_, "volume", G_BINDING_SYNC_CREATE, (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)), (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)));
	}
}

const gchar*
ft_alert_sound_get_event_id (FtAlertSound* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_event_id;
	result = _tmp0_;
	return result;
}

static void
ft_alert_sound_set_event_id (FtAlertSound* self,
                             const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (self != NULL);
	old_value = ft_alert_sound_get_event_id (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_event_id);
		self->priv->_event_id = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, ft_alert_sound_properties[FT_ALERT_SOUND_EVENT_ID_PROPERTY]);
	}
}

static void
ft_alert_sound_class_init (FtAlertSoundClass * klass,
                           gpointer klass_data)
{
	ft_alert_sound_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &FtAlertSound_private_offset);
	((FtSoundClass *) klass)->get_debug_name = (gchar* (*) (FtSound*)) ft_alert_sound_real_get_debug_name;
	((FtSoundClass *) klass)->initialize_backend = (void (*) (FtSound*)) ft_alert_sound_real_initialize_backend;
	G_OBJECT_CLASS (klass)->get_property = _vala_ft_alert_sound_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_ft_alert_sound_set_property;
	G_OBJECT_CLASS (klass)->finalize = ft_alert_sound_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_ALERT_SOUND_EVENT_ID_PROPERTY, ft_alert_sound_properties[FT_ALERT_SOUND_EVENT_ID_PROPERTY] = g_param_spec_string ("event-id", "event-id", "event-id", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
}

static void
ft_alert_sound_instance_init (FtAlertSound * self,
                              gpointer klass)
{
	self->priv = ft_alert_sound_get_instance_private (self);
}

static void
ft_alert_sound_finalize (GObject * obj)
{
	FtAlertSound * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, FT_TYPE_ALERT_SOUND, FtAlertSound);
	_g_free0 (self->priv->_event_id);
	G_OBJECT_CLASS (ft_alert_sound_parent_class)->finalize (obj);
}

static GType
ft_alert_sound_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (FtAlertSoundClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ft_alert_sound_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FtAlertSound), 0, (GInstanceInitFunc) ft_alert_sound_instance_init, NULL };
	GType ft_alert_sound_type_id;
	ft_alert_sound_type_id = g_type_register_static (FT_TYPE_SOUND, "FtAlertSound", &g_define_type_info, 0);
	FtAlertSound_private_offset = g_type_add_instance_private (ft_alert_sound_type_id, sizeof (FtAlertSoundPrivate));
	return ft_alert_sound_type_id;
}

GType
ft_alert_sound_get_type (void)
{
	static volatile gsize ft_alert_sound_type_id__once = 0;
	if (g_once_init_enter (&ft_alert_sound_type_id__once)) {
		GType ft_alert_sound_type_id;
		ft_alert_sound_type_id = ft_alert_sound_get_type_once ();
		g_once_init_leave (&ft_alert_sound_type_id__once, ft_alert_sound_type_id);
	}
	return ft_alert_sound_type_id__once;
}

static void
_vala_ft_alert_sound_get_property (GObject * object,
                                   guint property_id,
                                   GValue * value,
                                   GParamSpec * pspec)
{
	FtAlertSound * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_ALERT_SOUND, FtAlertSound);
	switch (property_id) {
		case FT_ALERT_SOUND_EVENT_ID_PROPERTY:
		g_value_set_string (value, ft_alert_sound_get_event_id (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_ft_alert_sound_set_property (GObject * object,
                                   guint property_id,
                                   const GValue * value,
                                   GParamSpec * pspec)
{
	FtAlertSound * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_ALERT_SOUND, FtAlertSound);
	switch (property_id) {
		case FT_ALERT_SOUND_EVENT_ID_PROPERTY:
		ft_alert_sound_set_event_id (self, g_value_get_string (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
ft_background_sound_get_instance_private (FtBackgroundSound* self)
{
	return G_STRUCT_MEMBER_P (self, FtBackgroundSound_private_offset);
}

static void
ft_background_sound_on_volume_animation_done (FtBackgroundSound* self,
                                              FtVolumeAnimation* volume_animation)
{
	gint64 fade_out_duration = 0LL;
	gint64 fade_out_easing = 0LL;
	GEqualFunc _tmp0_;
	gdouble _tmp1_;
	gdouble _tmp2_;
	gdouble _tmp3_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (volume_animation != NULL);
	fade_out_duration = self->priv->pending_fade_out_duration;
	fade_out_easing = self->priv->pending_fade_out_easing;
	if (fade_out_duration > ((gint64) 0)) {
		ft_background_sound_fade_out (self, fade_out_duration, fade_out_easing);
		return;
	}
	_tmp0_ = g_double_equal;
	_tmp1_ = ft_volume_animation_get_value (volume_animation);
	_tmp2_ = _tmp1_;
	_tmp3_ = 0.0;
	if (_tmp0_ (&_tmp2_, &_tmp3_)) {
		ft_sound_stop ((FtSound*) self);
	}
}

static void
ft_background_sound_real_initialize_backend (FtSound* base)
{
	FtBackgroundSound * self;
	FtSoundBackend* _tmp0_;
	FtSoundBackend* _tmp1_;
	self = (FtBackgroundSound*) base;
	FT_SOUND_CLASS (ft_background_sound_parent_class)->initialize_backend (G_TYPE_CHECK_INSTANCE_CAST (self, FT_TYPE_SOUND, FtSound));
	_tmp0_ = ft_sound_get_backend ((FtSound*) self);
	_tmp1_ = _tmp0_;
	if (FT_IS_GSTREAMER_BACKEND (_tmp1_)) {
		FtSoundBackend* _tmp2_;
		FtSoundBackend* _tmp3_;
		FtSoundBackend* _tmp4_;
		FtSoundBackend* _tmp5_;
		FtSoundBackend* _tmp6_;
		FtSoundBackend* _tmp7_;
		FtVolumeAnimation* _tmp8_;
		FtSoundBackend* _tmp9_;
		FtSoundBackend* _tmp10_;
		_tmp2_ = ft_sound_get_backend ((FtSound*) self);
		_tmp3_ = _tmp2_;
		g_object_bind_property_with_closures ((GObject*) self, "uri", (GObject*) _tmp3_, "uri", G_BINDING_SYNC_CREATE, (GClosure*) g_cclosure_new ((GCallback) _ft_transform_uri_to_uri_gbinding_transform_func, NULL, (GClosureNotify) NULL), (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)));
		_tmp4_ = ft_sound_get_backend ((FtSound*) self);
		_tmp5_ = _tmp4_;
		g_object_bind_property_with_closures ((GObject*) self, "volume", (GObject*) _tmp5_, "volume", G_BINDING_SYNC_CREATE, (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)), (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)));
		_tmp6_ = ft_sound_get_backend ((FtSound*) self);
		_tmp7_ = _tmp6_;
		g_object_bind_property_with_closures ((GObject*) self, "repeat", (GObject*) _tmp7_, "repeat", G_BINDING_SYNC_CREATE, (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)), (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)));
		_tmp8_ = self->priv->volume_animation;
		_tmp9_ = ft_sound_get_backend ((FtSound*) self);
		_tmp10_ = _tmp9_;
		g_object_bind_property_with_closures ((GObject*) _tmp8_, "value", (GObject*) _tmp10_, "volume-fade", G_BINDING_SYNC_CREATE, (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)), (GClosure*) ((NULL == NULL) ? NULL : g_cclosure_new ((GCallback) NULL, NULL, (GClosureNotify) NULL)));
	}
}

static void
_ft_volume_animation_skip_ft_sound_backend_playback_stopped (FtSoundBackend* _sender,
                                                             gpointer self)
{
	ft_volume_animation_skip ((FtVolumeAnimation*) self);
}

static void
ft_background_sound_real_destroy_backend (FtSound* base)
{
	FtBackgroundSound * self;
	FtSoundBackend* _tmp0_;
	FtSoundBackend* _tmp1_;
	FtVolumeAnimation* _tmp2_;
	guint _tmp3_;
	self = (FtBackgroundSound*) base;
	_tmp0_ = ft_sound_get_backend ((FtSound*) self);
	_tmp1_ = _tmp0_;
	_tmp2_ = self->priv->volume_animation;
	g_signal_parse_name ("playback-stopped", FT_TYPE_SOUND_BACKEND, &_tmp3_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (_tmp1_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp3_, 0, NULL, (GCallback) _ft_volume_animation_skip_ft_sound_backend_playback_stopped, _tmp2_);
	FT_SOUND_CLASS (ft_background_sound_parent_class)->destroy_backend (G_TYPE_CHECK_INSTANCE_CAST (self, FT_TYPE_SOUND, FtSound));
}

void
ft_background_sound_fade_in (FtBackgroundSound* self,
                             gint64 duration,
                             FtEasing easing)
{
	FtVolumeAnimation* _tmp0_;
	gdouble _tmp1_;
	gdouble _tmp2_;
	g_return_if_fail (self != NULL);
	if (!ft_sound_is_playing ((FtSound*) self)) {
		ft_sound_play ((FtSound*) self);
	}
	self->priv->pending_fade_out_duration = (gint64) 0;
	_tmp0_ = self->priv->volume_animation;
	_tmp1_ = ft_volume_animation_get_value_to (_tmp0_);
	_tmp2_ = _tmp1_;
	if (_tmp2_ != 1.0) {
		FtVolumeAnimation* _tmp3_;
		_tmp3_ = self->priv->volume_animation;
		ft_volume_animation_animate_to (_tmp3_, 1.0, duration, easing);
	}
}

void
ft_background_sound_fade_out (FtBackgroundSound* self,
                              gint64 duration,
                              FtEasing easing)
{
	FtVolumeAnimation* _tmp0_;
	gdouble _tmp1_;
	gdouble _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->volume_animation;
	_tmp1_ = ft_volume_animation_get_value_to (_tmp0_);
	_tmp2_ = _tmp1_;
	if (_tmp2_ == 0.0) {
		return;
	}
	self->priv->pending_fade_out_duration = (gint64) 0;
	if (ft_sound_is_playing ((FtSound*) self)) {
		FtVolumeAnimation* _tmp3_;
		_tmp3_ = self->priv->volume_animation;
		ft_volume_animation_animate_to (_tmp3_, 0.0, duration, easing);
	} else {
		FtVolumeAnimation* _tmp4_;
		_tmp4_ = self->priv->volume_animation;
		ft_volume_animation_set_value (_tmp4_, 0.0);
	}
}

/**
         * Fade-in to a specified `volume` and fade-out.
         */
void
ft_background_sound_fade_in_out (FtBackgroundSound* self,
                                 gint64 duration,
                                 gdouble volume)
{
	FtVolumeAnimation* _tmp0_;
	gdouble _tmp1_;
	gdouble _tmp2_;
	g_return_if_fail (self != NULL);
	_vala_return_if_fail (duration > ((gint64) 0), "duration > 0");
	if (!ft_sound_is_playing ((FtSound*) self)) {
		ft_sound_play ((FtSound*) self);
	}
	_tmp0_ = self->priv->volume_animation;
	_tmp1_ = ft_volume_animation_get_value_to (_tmp0_);
	_tmp2_ = _tmp1_;
	if (_tmp2_ != volume) {
		FtVolumeAnimation* _tmp3_;
		self->priv->pending_fade_out_duration = 2 * (duration / 3);
		self->priv->pending_fade_out_easing = (gint64) FT_EASING_IN_OUT;
		_tmp3_ = self->priv->volume_animation;
		ft_volume_animation_animate_to (_tmp3_, volume, duration / 3, FT_EASING_OUT);
	} else {
		ft_background_sound_fade_out (self, duration, FT_EASING_IN_OUT);
	}
}

static void
ft_background_sound_real_dispose (GObject* base)
{
	FtBackgroundSound * self;
	FtVolumeAnimation* _tmp0_;
	self = (FtBackgroundSound*) base;
	_tmp0_ = self->priv->volume_animation;
	if (_tmp0_ != NULL) {
		FtVolumeAnimation* _tmp1_;
		_tmp1_ = self->priv->volume_animation;
		ft_volume_animation_stop (_tmp1_);
		_g_object_unref0 (self->priv->volume_animation);
		self->priv->volume_animation = NULL;
	}
	G_OBJECT_CLASS (ft_background_sound_parent_class)->dispose ((GObject*) G_TYPE_CHECK_INSTANCE_CAST (self, FT_TYPE_SOUND, FtSound));
}

FtBackgroundSound*
ft_background_sound_construct (GType object_type)
{
	FtBackgroundSound * self = NULL;
	self = (FtBackgroundSound*) ft_sound_construct (object_type);
	return self;
}

FtBackgroundSound*
ft_background_sound_new (void)
{
	return ft_background_sound_construct (FT_TYPE_BACKGROUND_SOUND);
}

gboolean
ft_background_sound_get_repeat (FtBackgroundSound* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_repeat;
	return result;
}

void
ft_background_sound_set_repeat (FtBackgroundSound* self,
                                gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = ft_background_sound_get_repeat (self);
	if (old_value != value) {
		self->priv->_repeat = value;
		g_object_notify_by_pspec ((GObject *) self, ft_background_sound_properties[FT_BACKGROUND_SOUND_REPEAT_PROPERTY]);
	}
}

static void
_ft_background_sound_on_volume_animation_done_ft_volume_animation_done (FtVolumeAnimation* _sender,
                                                                        gpointer self)
{
	ft_background_sound_on_volume_animation_done ((FtBackgroundSound*) self, _sender);
}

static GObject *
ft_background_sound_constructor (GType type,
                                 guint n_construct_properties,
                                 GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	FtBackgroundSound * self;
	FtVolumeAnimation* _tmp0_;
	FtVolumeAnimation* _tmp1_;
	parent_class = G_OBJECT_CLASS (ft_background_sound_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, FT_TYPE_BACKGROUND_SOUND, FtBackgroundSound);
	_tmp0_ = ft_volume_animation_new ();
	_g_object_unref0 (self->priv->volume_animation);
	self->priv->volume_animation = _tmp0_;
	_tmp1_ = self->priv->volume_animation;
	g_signal_connect_object (_tmp1_, "done", (GCallback) _ft_background_sound_on_volume_animation_done_ft_volume_animation_done, self, 0);
	return obj;
}

static void
ft_background_sound_class_init (FtBackgroundSoundClass * klass,
                                gpointer klass_data)
{
	ft_background_sound_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &FtBackgroundSound_private_offset);
	((FtSoundClass *) klass)->initialize_backend = (void (*) (FtSound*)) ft_background_sound_real_initialize_backend;
	((FtSoundClass *) klass)->destroy_backend = (void (*) (FtSound*)) ft_background_sound_real_destroy_backend;
	((GObjectClass *) klass)->dispose = (void (*) (GObject*)) ft_background_sound_real_dispose;
	G_OBJECT_CLASS (klass)->get_property = _vala_ft_background_sound_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_ft_background_sound_set_property;
	G_OBJECT_CLASS (klass)->constructor = ft_background_sound_constructor;
	G_OBJECT_CLASS (klass)->finalize = ft_background_sound_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_BACKGROUND_SOUND_REPEAT_PROPERTY, ft_background_sound_properties[FT_BACKGROUND_SOUND_REPEAT_PROPERTY] = g_param_spec_boolean ("repeat", "repeat", "repeat", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
}

static void
ft_background_sound_instance_init (FtBackgroundSound * self,
                                   gpointer klass)
{
	self->priv = ft_background_sound_get_instance_private (self);
	self->priv->_repeat = FALSE;
	self->priv->volume_animation = NULL;
	self->priv->pending_fade_out_duration = (gint64) 0;
	self->priv->pending_fade_out_easing = (gint64) FT_EASING_IN_OUT;
}

static void
ft_background_sound_finalize (GObject * obj)
{
	FtBackgroundSound * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, FT_TYPE_BACKGROUND_SOUND, FtBackgroundSound);
	_g_object_unref0 (self->priv->volume_animation);
	G_OBJECT_CLASS (ft_background_sound_parent_class)->finalize (obj);
}

static GType
ft_background_sound_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (FtBackgroundSoundClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ft_background_sound_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FtBackgroundSound), 0, (GInstanceInitFunc) ft_background_sound_instance_init, NULL };
	GType ft_background_sound_type_id;
	ft_background_sound_type_id = g_type_register_static (FT_TYPE_SOUND, "FtBackgroundSound", &g_define_type_info, 0);
	FtBackgroundSound_private_offset = g_type_add_instance_private (ft_background_sound_type_id, sizeof (FtBackgroundSoundPrivate));
	return ft_background_sound_type_id;
}

GType
ft_background_sound_get_type (void)
{
	static volatile gsize ft_background_sound_type_id__once = 0;
	if (g_once_init_enter (&ft_background_sound_type_id__once)) {
		GType ft_background_sound_type_id;
		ft_background_sound_type_id = ft_background_sound_get_type_once ();
		g_once_init_leave (&ft_background_sound_type_id__once, ft_background_sound_type_id);
	}
	return ft_background_sound_type_id__once;
}

static void
_vala_ft_background_sound_get_property (GObject * object,
                                        guint property_id,
                                        GValue * value,
                                        GParamSpec * pspec)
{
	FtBackgroundSound * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_BACKGROUND_SOUND, FtBackgroundSound);
	switch (property_id) {
		case FT_BACKGROUND_SOUND_REPEAT_PROPERTY:
		g_value_set_boolean (value, ft_background_sound_get_repeat (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_ft_background_sound_set_property (GObject * object,
                                        guint property_id,
                                        const GValue * value,
                                        GParamSpec * pspec)
{
	FtBackgroundSound * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_BACKGROUND_SOUND, FtBackgroundSound);
	switch (property_id) {
		case FT_BACKGROUND_SOUND_REPEAT_PROPERTY:
		ft_background_sound_set_repeat (self, g_value_get_boolean (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_array_destroy (gpointer array,
                     gssize array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}

static void
_vala_array_free (gpointer array,
                  gssize array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

