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

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

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

#define FT_SOUND_PLAYER_LATENCY ((guint) 200)
#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 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_PLAYER_0_PROPERTY,
	FT_SOUND_PLAYER_URI_PROPERTY,
	FT_SOUND_PLAYER_VOLUME_PROPERTY,
	FT_SOUND_PLAYER_LOOP_PROPERTY,
	FT_SOUND_PLAYER_NUM_PROPERTIES
};
static GParamSpec* ft_sound_player_properties[FT_SOUND_PLAYER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _Block52Data Block52Data;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
enum  {
	FT_SOUND_PLAYER_PLAYBACK_STARTED_SIGNAL,
	FT_SOUND_PLAYER_PLAYBACK_STOPPED_SIGNAL,
	FT_SOUND_PLAYER_PLAYBACK_ERROR_SIGNAL,
	FT_SOUND_PLAYER_NUM_SIGNALS
};
static guint ft_sound_player_signals[FT_SOUND_PLAYER_NUM_SIGNALS] = {0};
#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 _FtSoundPlayerPrivate {
	gboolean _loop;
	GstElement* pipeline;
	GstElement* volume_filter;
	GstElement* audio_sink;
	GstInterpolationControlSource* volume_interpolation;
	gboolean _is_playing;
	gboolean is_about_to_finish;
	gdouble fade_to;
	guint stop_timeout_id;
	guint park_timeout_id;
};

struct _Block52Data {
	int _ref_count_;
	FtSoundPlayer* self;
	GstClockTime running_time;
	GstTimedValue* control_points;
	gint control_points_length1;
	gint _control_points_size_;
};

static gint FtSoundPlayer_private_offset;
static gpointer ft_sound_player_parent_class = NULL;
static gboolean ft_sound_player_is_gstreamer_initialized;
static gboolean ft_sound_player_is_gstreamer_initialized = FALSE;

VALA_EXTERN GType ft_gst_play_flags_get_type (void) G_GNUC_CONST ;
static void ft_sound_player_on_about_to_finish (FtSoundPlayer* self);
static void _ft_sound_player_on_about_to_finish_dynamic_about_to_finish0_ (GstElement* _sender,
                                                                    gpointer self);
static gboolean ft_sound_player_on_bus_callback (FtSoundPlayer* self,
                                          GstBus* bus,
                                          GstMessage* message);
static gboolean _ft_sound_player_on_bus_callback_gst_bus_func (GstBus* bus,
                                                        GstMessage* message,
                                                        gpointer self);
static void ft_sound_player_finished (FtSoundPlayer* self);
static Block52Data* block52_data_ref (Block52Data* _data52_);
static void block52_data_unref (void * _userdata_);
static gdouble ft_sound_player_get_fade_value (FtSoundPlayer* self,
                                        GstClockTime running_time);
static void ___lambda93_ (Block52Data* _data52_,
                   GstTimedValue* control_point);
static void _vala_array_add26 (GstTimedValue* * array,
                        gint* length,
                        gint* size,
                        const GstTimedValue* value);
static void ____lambda93__gfunc (gconstpointer data,
                          gpointer self);
static void ft_sound_player_park_audio_sink (FtSoundPlayer* self);
static void ft_sound_player_ensure_volume_interpolation (FtSoundPlayer* self);
static void ft_sound_player_unschedule_stop (FtSoundPlayer* self);
static gboolean ft_sound_player_on_stop_timeout (FtSoundPlayer* self);
static gboolean ___lambda94_ (FtSoundPlayer* self);
static gboolean ____lambda94__gsource_func (gpointer self);
static gboolean _ft_sound_player_on_stop_timeout_gsource_func (gpointer self);
static void ft_sound_player_real_dispose (GObject* base);
static void ft_sound_player_real_playback_stopped (FtSoundPlayer* self);
static void ft_sound_player_finalize (GObject * obj);
static GType ft_sound_player_get_type_once (void);
static void _vala_ft_sound_player_get_property (GObject * object,
                                         guint property_id,
                                         GValue * value,
                                         GParamSpec * pspec);
static void _vala_ft_sound_player_set_property (GObject * object,
                                         guint property_id,
                                         const GValue * value,
                                         GParamSpec * pspec);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

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;
}

static inline gpointer
ft_sound_player_get_instance_private (FtSoundPlayer* self)
{
	return G_STRUCT_MEMBER_P (self, FtSoundPlayer_private_offset);
}

static void
_ft_sound_player_on_about_to_finish_dynamic_about_to_finish0_ (GstElement* _sender,
                                                               gpointer self)
{
	ft_sound_player_on_about_to_finish ((FtSoundPlayer*) self);
}

static gboolean
_ft_sound_player_on_bus_callback_gst_bus_func (GstBus* bus,
                                               GstMessage* message,
                                               gpointer self)
{
	gboolean result;
	result = ft_sound_player_on_bus_callback ((FtSoundPlayer*) self, bus, message);
	return result;
}

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

FtSoundPlayer*
ft_sound_player_construct (GType object_type,
                           GError** error)
{
	FtSoundPlayer * self = NULL;
	GstElement* pipeline = NULL;
	GstElement* _tmp0_;
	GstElement* volume_filter = NULL;
	GstElement* _tmp1_;
	GstElement* audio_sink = NULL;
	GstElement* _tmp2_;
	gboolean _tmp3_ = FALSE;
	gboolean _tmp4_ = FALSE;
	GstElement* _tmp5_;
	GstElement* _tmp9_;
	GstElement* _tmp10_;
	GstElement* _tmp11_;
	GstElement* _tmp12_;
	GstElement* _tmp13_;
	GstElement* _tmp14_;
	GstElement* _tmp15_;
	GstElement* _tmp16_;
	GstBus* _tmp17_;
	GstBus* _tmp18_;
	GstElement* _tmp19_;
	GstElement* _tmp20_;
	GstElement* _tmp21_;
	GstElement* _tmp22_;
	GstElement* _tmp23_;
	GstElement* _tmp24_;
	GError* _inner_error0_ = NULL;
	self = (FtSoundPlayer*) g_object_new (object_type, NULL);
	if (!ft_sound_player_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_sound_player_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_;
	_tmp2_ = gst_element_factory_make ("autoaudiosink", "audio-output");
	if (_tmp2_ != NULL) {
		g_object_ref_sink (_tmp2_);
	}
	audio_sink = _tmp2_;
	_tmp5_ = pipeline;
	if (_tmp5_ == NULL) {
		_tmp4_ = TRUE;
	} else {
		GstElement* _tmp6_;
		_tmp6_ = volume_filter;
		_tmp4_ = _tmp6_ == NULL;
	}
	if (_tmp4_) {
		_tmp3_ = TRUE;
	} else {
		GstElement* _tmp7_;
		_tmp7_ = audio_sink;
		_tmp3_ = _tmp7_ == NULL;
	}
	if (_tmp3_) {
		GError* _tmp8_;
		_tmp8_ = g_error_new_literal (FT_SOUND_ERROR, FT_SOUND_ERROR_NOT_INITIALIZED, _ ("Failed to initialize playback"));
		_inner_error0_ = _tmp8_;
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (audio_sink);
		_g_object_unref0 (volume_filter);
		_g_object_unref0 (pipeline);
		_g_object_unref0 (self);
		return NULL;
	}
	_tmp9_ = pipeline;
	((GstObject*) _tmp9_)->flags = (guint32) FT_GST_PLAY_FLAGS_AUDIO;
	_tmp10_ = pipeline;
	_tmp11_ = volume_filter;
	g_object_set (_tmp10_, "audio-filter", _tmp11_, NULL);
	_tmp12_ = pipeline;
	_tmp13_ = audio_sink;
	g_object_set (_tmp12_, "audio-sink", _tmp13_, NULL);
	_tmp14_ = audio_sink;
	gst_element_set_locked_state (_tmp14_, TRUE);
	_tmp15_ = pipeline;
	g_signal_connect_object (_tmp15_, "about-to-finish", (GCallback) _ft_sound_player_on_about_to_finish_dynamic_about_to_finish0_, self, 0);
	_tmp16_ = pipeline;
	_tmp17_ = gst_element_get_bus (_tmp16_);
	_tmp18_ = _tmp17_;
	gst_bus_add_watch_full (_tmp18_, G_PRIORITY_DEFAULT, _ft_sound_player_on_bus_callback_gst_bus_func, g_object_ref (self), g_object_unref);
	_g_object_unref0 (_tmp18_);
	_tmp19_ = pipeline;
	_tmp20_ = _g_object_ref0 (_tmp19_);
	_g_object_unref0 (self->priv->pipeline);
	self->priv->pipeline = _tmp20_;
	_tmp21_ = volume_filter;
	_tmp22_ = _g_object_ref0 (_tmp21_);
	_g_object_unref0 (self->priv->volume_filter);
	self->priv->volume_filter = _tmp22_;
	_tmp23_ = audio_sink;
	_tmp24_ = _g_object_ref0 (_tmp23_);
	_g_object_unref0 (self->priv->audio_sink);
	self->priv->audio_sink = _tmp24_;
	_g_object_unref0 (audio_sink);
	_g_object_unref0 (volume_filter);
	_g_object_unref0 (pipeline);
	return self;
}

FtSoundPlayer*
ft_sound_player_new (GError** error)
{
	return ft_sound_player_construct (FT_TYPE_SOUND_PLAYER, error);
}

gchar**
ft_sound_player_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;
}

static void
ft_sound_player_finished (FtSoundPlayer* self)
{
	gchar* current_uri = NULL;
	gboolean _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_loop;
	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 Block52Data*
block52_data_ref (Block52Data* _data52_)
{
	g_atomic_int_inc (&_data52_->_ref_count_);
	return _data52_;
}

static void
block52_data_unref (void * _userdata_)
{
	Block52Data* _data52_;
	_data52_ = (Block52Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data52_->_ref_count_)) {
		FtSoundPlayer* self;
		self = _data52_->self;
		_data52_->control_points = (g_free (_data52_->control_points), NULL);
		_g_object_unref0 (self);
		g_slice_free (Block52Data, _data52_);
	}
}

static void
_vala_array_add26 (GstTimedValue* * array,
                   gint* length,
                   gint* size,
                   const GstTimedValue* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (GstTimedValue, *array, *size);
	}
	(*array)[(*length)++] = *value;
}

static void
___lambda93_ (Block52Data* _data52_,
              GstTimedValue* control_point)
{
	FtSoundPlayer* self;
	self = _data52_->self;
	if ((*control_point).timestamp > _data52_->running_time) {
		GstTimedValue _tmp0_ = {0};
		memset (&_tmp0_, 0, sizeof (GstTimedValue));
		_tmp0_.timestamp = (*control_point).timestamp - _data52_->running_time;
		_tmp0_.value = (*control_point).value;
		_vala_array_add26 (&_data52_->control_points, &_data52_->control_points_length1, &_data52_->_control_points_size_, &_tmp0_);
	}
}

static void
____lambda93__gfunc (gconstpointer data,
                     gpointer self)
{
	___lambda93_ (self, (GstTimedValue*) data);
}

static void
ft_sound_player_on_about_to_finish (FtSoundPlayer* self)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_;
	g_return_if_fail (self != NULL);
	self->priv->is_about_to_finish = TRUE;
	ft_sound_player_finished (self);
	_tmp1_ = self->priv->_loop;
	if (_tmp1_) {
		GstInterpolationControlSource* _tmp2_;
		_tmp2_ = self->priv->volume_interpolation;
		_tmp0_ = _tmp2_ != NULL;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		Block52Data* _data52_;
		gdouble current_fade_value = 0.0;
		GstTimedValue* _tmp3_;
		GstInterpolationControlSource* _tmp4_;
		GList* _tmp5_;
		GList* _tmp6_;
		GstTimedValue* _tmp7_;
		gint _tmp7__length1;
		_data52_ = g_slice_new0 (Block52Data);
		_data52_->_ref_count_ = 1;
		_data52_->self = g_object_ref (self);
		_data52_->running_time = ft_sound_player_get_running_time (self);
		current_fade_value = ft_sound_player_get_fade_value (self, _data52_->running_time);
		_tmp3_ = g_new0 (GstTimedValue, 0);
		_data52_->control_points = _tmp3_;
		_data52_->control_points_length1 = 0;
		_data52_->_control_points_size_ = _data52_->control_points_length1;
		_tmp4_ = self->priv->volume_interpolation;
		_tmp5_ = gst_timed_value_control_source_get_all ((GstTimedValueControlSource*) _tmp4_);
		_tmp6_ = _tmp5_;
		g_list_foreach (_tmp6_, ____lambda93__gfunc, _data52_);
		(_tmp6_ == NULL) ? NULL : (_tmp6_ = (g_list_free (_tmp6_), NULL));
		_tmp7_ = _data52_->control_points;
		_tmp7__length1 = _data52_->control_points_length1;
		if (_tmp7__length1 > 0) {
			GstInterpolationControlSource* _tmp8_;
			GstInterpolationControlSource* _tmp9_;
			GstTimedValue* _tmp10_;
			gint _tmp10__length1;
			_tmp8_ = self->priv->volume_interpolation;
			gst_timed_value_control_source_unset_all ((GstTimedValueControlSource*) _tmp8_);
			_tmp9_ = self->priv->volume_interpolation;
			gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp9_, (GstClockTime) 0, current_fade_value);
			_tmp10_ = _data52_->control_points;
			_tmp10__length1 = _data52_->control_points_length1;
			{
				GstTimedValue* control_point_collection = NULL;
				gint control_point_collection_length1 = 0;
				gint _control_point_collection_size_ = 0;
				gint control_point_it = 0;
				control_point_collection = _tmp10_;
				control_point_collection_length1 = _tmp10__length1;
				for (control_point_it = 0; control_point_it < control_point_collection_length1; control_point_it = control_point_it + 1) {
					GstTimedValue control_point = {0};
					control_point = control_point_collection[control_point_it];
					{
						GstInterpolationControlSource* _tmp11_;
						GstTimedValue _tmp12_;
						GstTimedValue _tmp13_;
						_tmp11_ = self->priv->volume_interpolation;
						_tmp12_ = control_point;
						_tmp13_ = control_point;
						gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp11_, _tmp12_.timestamp, _tmp13_.value);
					}
				}
			}
		} else {
			GstInterpolationControlSource* _tmp14_;
			GstInterpolationControlSource* _tmp15_;
			_tmp14_ = self->priv->volume_interpolation;
			gst_timed_value_control_source_unset_all ((GstTimedValueControlSource*) _tmp14_);
			_tmp15_ = self->priv->volume_interpolation;
			gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp15_, (GstClockTime) 0, self->priv->fade_to);
		}
		block52_data_unref (_data52_);
		_data52_ = NULL;
	}
}

static gboolean
ft_sound_player_on_bus_callback (FtSoundPlayer* 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 (self, ft_sound_player_signals[FT_SOUND_PLAYER_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 (self, ft_sound_player_signals[FT_SOUND_PLAYER_PLAYBACK_STOPPED_SIGNAL], 0);
			}
			break;
		}
		case GST_MESSAGE_EOS:
		{
			gboolean _tmp12_ = FALSE;
			gboolean _tmp13_;
			if (self->priv->is_about_to_finish) {
				self->priv->is_about_to_finish = FALSE;
			} else {
				ft_sound_player_finished (self);
			}
			_tmp13_ = self->priv->_loop;
			if (!_tmp13_) {
				_tmp12_ = pending_state != GST_STATE_PLAYING;
			} else {
				_tmp12_ = FALSE;
			}
			if (_tmp12_) {
				GstElement* _tmp14_;
				_tmp14_ = self->priv->pipeline;
				gst_element_set_state (_tmp14_, GST_STATE_READY);
				ft_sound_player_park_audio_sink (self);
			}
			break;
		}
		case GST_MESSAGE_ERROR:
		{
			GError* _tmp15_ = NULL;
			gchar* _tmp16_ = NULL;
			const gchar* _tmp17_ = NULL;
			const gchar* _tmp18_;
			const gchar* _tmp19_;
			GError* _tmp20_;
			const gchar* _tmp21_;
			GstElement* _tmp22_;
			GError* _tmp23_;
			if (self->priv->is_about_to_finish) {
				self->priv->is_about_to_finish = FALSE;
			}
			gst_message_parse_error (message, &_tmp15_, &_tmp16_);
			_g_error_free0 (_error_);
			_error_ = _tmp15_;
			_g_free0 (debug_info);
			debug_info = _tmp16_;
			_tmp18_ = debug_info;
			_tmp17_ = _tmp18_;
			if (_tmp17_ == NULL) {
				_tmp17_ = "";
			}
			_tmp19_ = src_name;
			_tmp20_ = _error_;
			_tmp21_ = _tmp20_->message;
			g_warning ("sound-player.vala:232: SoundPlayer error from %s: %s [debug: %s]", _tmp19_, _tmp21_, _tmp17_);
			_tmp22_ = self->priv->pipeline;
			gst_element_set_state (_tmp22_, GST_STATE_NULL);
			_tmp23_ = _error_;
			g_signal_emit (self, ft_sound_player_signals[FT_SOUND_PLAYER_PLAYBACK_ERROR_SIGNAL], 0, _tmp23_);
			break;
		}
		case GST_MESSAGE_WARNING:
		{
			GError* _tmp24_ = NULL;
			gchar* _tmp25_ = NULL;
			const gchar* _tmp26_ = NULL;
			const gchar* _tmp27_;
			const gchar* _tmp28_;
			GError* _tmp29_;
			const gchar* _tmp30_;
			gst_message_parse_warning (message, &_tmp24_, &_tmp25_);
			_g_error_free0 (_error_);
			_error_ = _tmp24_;
			_g_free0 (debug_info);
			debug_info = _tmp25_;
			_tmp27_ = debug_info;
			_tmp26_ = _tmp27_;
			if (_tmp26_ == NULL) {
				_tmp26_ = "";
			}
			_tmp28_ = src_name;
			_tmp29_ = _error_;
			_tmp30_ = _tmp29_->message;
			g_warning ("sound-player.vala:243: SoundPlayer warning from %s: %s [debug: %s]", _tmp28_, _tmp30_, _tmp26_);
			break;
		}
		default:
		{
			break;
		}
	}
	result = G_SOURCE_CONTINUE;
	_g_free0 (src_name);
	_g_free0 (_tmp0_);
	_g_free0 (debug_info);
	_g_error_free0 (_error_);
	return result;
}

GstClockTime
ft_sound_player_get_running_time (FtSoundPlayer* self)
{
	GstClockTime running_time = 0ULL;
	GstElement* _tmp0_;
	gint64 _tmp1_ = 0LL;
	GstClockTime result;
	g_return_val_if_fail (self != NULL, 0ULL);
	running_time = (GstClockTime) 0;
	_tmp0_ = self->priv->pipeline;
	gst_element_query_position (_tmp0_, GST_FORMAT_TIME, &_tmp1_);
	running_time = (GstClockTime) _tmp1_;
	result = running_time;
	return result;
}

static void
ft_sound_player_park_audio_sink (FtSoundPlayer* self)
{
	GstElement* _tmp0_;
	GstElement* _tmp1_;
	g_return_if_fail (self != NULL);
	if (self->priv->park_timeout_id != ((guint) 0)) {
		g_source_remove (self->priv->park_timeout_id);
		self->priv->park_timeout_id = (guint) 0;
	}
	_tmp0_ = self->priv->audio_sink;
	gst_element_set_locked_state (_tmp0_, TRUE);
	_tmp1_ = self->priv->audio_sink;
	gst_element_set_state (_tmp1_, GST_STATE_NULL);
}

static void
ft_sound_player_ensure_volume_interpolation (FtSoundPlayer* self)
{
	GstInterpolationControlSource* _tmp0_;
	GstInterpolationControlSource* volume_interpolation = NULL;
	GstInterpolationControlSource* _tmp1_;
	GstInterpolationControlSource* _tmp2_;
	GstInterpolationControlSource* _tmp3_;
	GstDirectControlBinding* binding = NULL;
	GstElement* _tmp4_;
	GstInterpolationControlSource* _tmp5_;
	GstDirectControlBinding* _tmp6_;
	GstElement* _tmp7_;
	GstDirectControlBinding* _tmp8_;
	GstInterpolationControlSource* _tmp9_;
	GstInterpolationControlSource* _tmp10_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->volume_interpolation;
	if (_tmp0_ != NULL) {
		return;
	}
	_tmp1_ = (GstInterpolationControlSource*) gst_interpolation_control_source_new ();
	g_object_ref_sink (_tmp1_);
	volume_interpolation = _tmp1_;
	_tmp2_ = volume_interpolation;
	g_object_set (_tmp2_, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
	_tmp3_ = volume_interpolation;
	gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp3_, (GstClockTime) 0, 1.0);
	_tmp4_ = self->priv->volume_filter;
	_tmp5_ = volume_interpolation;
	_tmp6_ = (GstDirectControlBinding*) gst_direct_control_binding_new_absolute ((GstObject*) _tmp4_, "volume", (GstControlSource*) _tmp5_);
	g_object_ref_sink (_tmp6_);
	binding = _tmp6_;
	_tmp7_ = self->priv->volume_filter;
	_tmp8_ = binding;
	gst_object_add_control_binding ((GstObject*) _tmp7_, (GstControlBinding*) _tmp8_);
	_tmp9_ = volume_interpolation;
	_tmp10_ = _g_object_ref0 (_tmp9_);
	_g_object_unref0 (self->priv->volume_interpolation);
	self->priv->volume_interpolation = _tmp10_;
	_g_object_unref0 (binding);
	_g_object_unref0 (volume_interpolation);
}

static gdouble
ft_sound_player_get_fade_value (FtSoundPlayer* self,
                                GstClockTime running_time)
{
	gdouble fade_value = 0.0;
	gboolean _tmp0_ = FALSE;
	GstInterpolationControlSource* _tmp1_;
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	fade_value = ((double) NAN);
	if (running_time == GST_CLOCK_TIME_NONE) {
		result = self->priv->fade_to;
		return result;
	}
	_tmp1_ = self->priv->volume_interpolation;
	if (_tmp1_ != NULL) {
		GstInterpolationControlSource* _tmp2_;
		gdouble _tmp3_ = 0.0;
		gboolean _tmp4_;
		_tmp2_ = self->priv->volume_interpolation;
		_tmp4_ = gst_control_source_get_value ((GstControlSource*) _tmp2_, running_time, &_tmp3_);
		fade_value = _tmp3_;
		_tmp0_ = _tmp4_;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		result = fade_value;
		return result;
	}
	result = self->priv->fade_to;
	return result;
}

static void
ft_sound_player_unschedule_stop (FtSoundPlayer* self)
{
	g_return_if_fail (self != NULL);
	if (self->priv->stop_timeout_id != ((guint) 0)) {
		g_source_remove (self->priv->stop_timeout_id);
		self->priv->stop_timeout_id = (guint) 0;
	}
}

static gboolean
ft_sound_player_on_stop_timeout (FtSoundPlayer* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	self->priv->stop_timeout_id = (guint) 0;
	ft_sound_player_stop (self);
	result = G_SOURCE_REMOVE;
	return result;
}

void
ft_sound_player_play (FtSoundPlayer* self)
{
	GstElement* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->pipeline;
	_vala_return_if_fail (_tmp0_ != NULL, "this.pipeline != null");
	if (self->priv->park_timeout_id != ((guint) 0)) {
		g_source_remove (self->priv->park_timeout_id);
		self->priv->park_timeout_id = (guint) 0;
	}
	_tmp1_ = ft_sound_player_get_uri (self);
	_tmp2_ = _tmp1_;
	if (g_strcmp0 (_tmp2_, "") != 0) {
		GstElement* _tmp3_;
		GstElement* _tmp4_;
		_tmp3_ = self->priv->audio_sink;
		gst_element_set_locked_state (_tmp3_, FALSE);
		_tmp4_ = self->priv->pipeline;
		gst_element_set_state (_tmp4_, GST_STATE_PLAYING);
	}
}

static gboolean
___lambda94_ (FtSoundPlayer* self)
{
	gboolean result;
	self->priv->park_timeout_id = (guint) 0;
	ft_sound_player_park_audio_sink (self);
	result = G_SOURCE_REMOVE;
	return result;
}

static gboolean
____lambda94__gsource_func (gpointer self)
{
	gboolean result;
	result = ___lambda94_ ((FtSoundPlayer*) self);
	return result;
}

void
ft_sound_player_stop (FtSoundPlayer* self)
{
	GstState state = 0;
	GstState pending_state = 0;
	GstElement* _tmp0_;
	GstElement* _tmp1_;
	GstState _tmp2_ = 0;
	GstState _tmp3_ = 0;
	gboolean _tmp4_ = FALSE;
	g_return_if_fail (self != NULL);
	_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_;
		GstElement* _tmp6_;
		GstState _tmp7_ = 0;
		GstState _tmp8_ = 0;
		_tmp5_ = self->priv->pipeline;
		gst_element_set_state (_tmp5_, GST_STATE_READY);
		_tmp6_ = self->priv->pipeline;
		gst_element_get_state (_tmp6_, &_tmp7_, &_tmp8_, GST_CLOCK_TIME_NONE);
		state = _tmp7_;
		pending_state = _tmp8_;
	}
	if (self->priv->park_timeout_id == ((guint) 0)) {
		self->priv->park_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, FT_SOUND_PLAYER_LATENCY, ____lambda94__gsource_func, g_object_ref (self), g_object_unref);
	}
}

gboolean
ft_sound_player_is_playing (FtSoundPlayer* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_is_playing;
	return result;
}

void
ft_sound_player_fade_in (FtSoundPlayer* self,
                         gint64 duration)
{
	GstClockTime running_time = 0ULL;
	gdouble current_fade_value = 0.0;
	g_return_if_fail (self != NULL);
	running_time = ft_sound_player_get_running_time (self);
	current_fade_value = ft_sound_player_get_fade_value (self, running_time);
	ft_sound_player_unschedule_stop (self);
	self->priv->fade_to = 1.0;
	ft_sound_player_ensure_volume_interpolation (self);
	if (current_fade_value == 1.0) {
		return;
	}
	if (duration <= ((gint64) 0)) {
		GstInterpolationControlSource* _tmp0_;
		GstInterpolationControlSource* _tmp1_;
		_tmp0_ = self->priv->volume_interpolation;
		gst_timed_value_control_source_unset_all ((GstTimedValueControlSource*) _tmp0_);
		_tmp1_ = self->priv->volume_interpolation;
		gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp1_, (GstClockTime) 0, self->priv->fade_to);
	} else {
		gboolean _tmp2_ = FALSE;
		if (running_time == ((GstClockTime) 0)) {
			_tmp2_ = TRUE;
		} else {
			_tmp2_ = running_time == GST_CLOCK_TIME_NONE;
		}
		if (_tmp2_) {
			GstInterpolationControlSource* _tmp3_;
			GstInterpolationControlSource* _tmp4_;
			GstInterpolationControlSource* _tmp5_;
			_tmp3_ = self->priv->volume_interpolation;
			gst_timed_value_control_source_unset_all ((GstTimedValueControlSource*) _tmp3_);
			_tmp4_ = self->priv->volume_interpolation;
			gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp4_, (GstClockTime) 0, current_fade_value);
			_tmp5_ = self->priv->volume_interpolation;
			gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp5_, 0 + (((GstClockTime) duration) * 1000), self->priv->fade_to);
		} else {
			GstClockTimeDiff latency = 0LL;
			gdouble latency_fade_value = 0.0;
			GstInterpolationControlSource* _tmp6_;
			GstInterpolationControlSource* _tmp7_;
			GstInterpolationControlSource* _tmp8_;
			GstInterpolationControlSource* _tmp9_;
			latency = FT_SOUND_PLAYER_LATENCY * GST_MSECOND;
			latency_fade_value = ft_sound_player_get_fade_value (self, running_time + latency);
			_tmp6_ = self->priv->volume_interpolation;
			gst_timed_value_control_source_unset_all ((GstTimedValueControlSource*) _tmp6_);
			_tmp7_ = self->priv->volume_interpolation;
			gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp7_, running_time, current_fade_value);
			_tmp8_ = self->priv->volume_interpolation;
			gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp8_, running_time + latency, latency_fade_value);
			_tmp9_ = self->priv->volume_interpolation;
			gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp9_, (running_time + latency) + (((GstClockTime) duration) * 1000), self->priv->fade_to);
		}
	}
	if (!self->priv->_is_playing) {
		ft_sound_player_play (self);
	}
}

static gboolean
_ft_sound_player_on_stop_timeout_gsource_func (gpointer self)
{
	gboolean result;
	result = ft_sound_player_on_stop_timeout ((FtSoundPlayer*) self);
	return result;
}

void
ft_sound_player_fade_out (FtSoundPlayer* self,
                          gint64 duration)
{
	GstClockTime running_time = 0ULL;
	gdouble current_fade_value = 0.0;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	g_return_if_fail (self != NULL);
	running_time = ft_sound_player_get_running_time (self);
	current_fade_value = ft_sound_player_get_fade_value (self, running_time);
	ft_sound_player_ensure_volume_interpolation (self);
	ft_sound_player_unschedule_stop (self);
	self->priv->fade_to = 0.0;
	if (!self->priv->_is_playing) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = running_time == GST_CLOCK_TIME_NONE;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = current_fade_value == 0.0;
	}
	if (_tmp0_) {
		return;
	}
	if (duration <= ((gint64) 0)) {
		GstInterpolationControlSource* _tmp2_;
		GstInterpolationControlSource* _tmp3_;
		_tmp2_ = self->priv->volume_interpolation;
		gst_timed_value_control_source_unset_all ((GstTimedValueControlSource*) _tmp2_);
		_tmp3_ = self->priv->volume_interpolation;
		gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp3_, (GstClockTime) 0, self->priv->fade_to);
		ft_sound_player_stop (self);
	} else {
		GstClockTimeDiff latency = 0LL;
		gdouble latency_fade_value = 0.0;
		GstInterpolationControlSource* _tmp4_;
		GstInterpolationControlSource* _tmp5_;
		GstInterpolationControlSource* _tmp6_;
		GstInterpolationControlSource* _tmp7_;
		latency = FT_SOUND_PLAYER_LATENCY * GST_MSECOND;
		latency_fade_value = ft_sound_player_get_fade_value (self, running_time + latency);
		_tmp4_ = self->priv->volume_interpolation;
		gst_timed_value_control_source_unset_all ((GstTimedValueControlSource*) _tmp4_);
		_tmp5_ = self->priv->volume_interpolation;
		gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp5_, running_time, current_fade_value);
		_tmp6_ = self->priv->volume_interpolation;
		gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp6_, running_time + latency, latency_fade_value);
		_tmp7_ = self->priv->volume_interpolation;
		gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp7_, (running_time + latency) + (((GstClockTime) duration) * 1000), self->priv->fade_to);
		self->priv->stop_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, ft_timestamp_to_milliseconds_uint (duration) + FT_SOUND_PLAYER_LATENCY, _ft_sound_player_on_stop_timeout_gsource_func, g_object_ref (self), g_object_unref);
	}
}

static void
ft_sound_player_real_dispose (GObject* base)
{
	FtSoundPlayer * self;
	GstElement* _tmp0_;
	self = (FtSoundPlayer*) base;
	ft_sound_player_unschedule_stop (self);
	if (self->priv->park_timeout_id != ((guint) 0)) {
		g_source_remove (self->priv->park_timeout_id);
		self->priv->park_timeout_id = (guint) 0;
	}
	_tmp0_ = self->priv->pipeline;
	if (_tmp0_ != NULL) {
		GstElement* _tmp1_;
		GstElement* _tmp2_;
		_tmp1_ = self->priv->audio_sink;
		gst_element_set_locked_state (_tmp1_, FALSE);
		_tmp2_ = self->priv->pipeline;
		gst_element_set_state (_tmp2_, GST_STATE_NULL);
	}
	_g_object_unref0 (self->priv->audio_sink);
	self->priv->audio_sink = NULL;
	_g_object_unref0 (self->priv->volume_filter);
	self->priv->volume_filter = NULL;
	_g_object_unref0 (self->priv->pipeline);
	self->priv->pipeline = NULL;
	G_OBJECT_CLASS (ft_sound_player_parent_class)->dispose (G_TYPE_CHECK_INSTANCE_CAST (self, G_TYPE_OBJECT, GObject));
}

const gchar*
ft_sound_player_get_uri (FtSoundPlayer* 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_sound_player_set_uri (FtSoundPlayer* 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_sound_player_properties[FT_SOUND_PLAYER_URI_PROPERTY]);
}

gdouble
ft_sound_player_get_volume (FtSoundPlayer* 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_sound_player_set_volume (FtSoundPlayer* 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_sound_player_properties[FT_SOUND_PLAYER_VOLUME_PROPERTY]);
}

gboolean
ft_sound_player_get_loop (FtSoundPlayer* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_loop;
	return result;
}

void
ft_sound_player_set_loop (FtSoundPlayer* self,
                          gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = ft_sound_player_get_loop (self);
	if (old_value != value) {
		self->priv->_loop = value;
		g_object_notify_by_pspec ((GObject *) self, ft_sound_player_properties[FT_SOUND_PLAYER_LOOP_PROPERTY]);
	}
}

static void
ft_sound_player_real_playback_stopped (FtSoundPlayer* self)
{
	GstInterpolationControlSource* _tmp0_;
	ft_sound_player_unschedule_stop (self);
	_tmp0_ = self->priv->volume_interpolation;
	if (_tmp0_ != NULL) {
		GstInterpolationControlSource* _tmp1_;
		GstInterpolationControlSource* _tmp2_;
		_tmp1_ = self->priv->volume_interpolation;
		gst_timed_value_control_source_unset_all ((GstTimedValueControlSource*) _tmp1_);
		_tmp2_ = self->priv->volume_interpolation;
		gst_timed_value_control_source_set ((GstTimedValueControlSource*) _tmp2_, (GstClockTime) 0, 0.0);
	}
}

static void
ft_sound_player_class_init (FtSoundPlayerClass * klass,
                            gpointer klass_data)
{
	ft_sound_player_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &FtSoundPlayer_private_offset);
	((GObjectClass *) klass)->dispose = (void (*) (GObject*)) ft_sound_player_real_dispose;
	((FtSoundPlayerClass *) klass)->playback_stopped = ft_sound_player_real_playback_stopped;
	G_OBJECT_CLASS (klass)->get_property = _vala_ft_sound_player_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_ft_sound_player_set_property;
	G_OBJECT_CLASS (klass)->finalize = ft_sound_player_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), FT_SOUND_PLAYER_URI_PROPERTY, ft_sound_player_properties[FT_SOUND_PLAYER_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_SOUND_PLAYER_VOLUME_PROPERTY, ft_sound_player_properties[FT_SOUND_PLAYER_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_SOUND_PLAYER_LOOP_PROPERTY, ft_sound_player_properties[FT_SOUND_PLAYER_LOOP_PROPERTY] = g_param_spec_boolean ("loop", "loop", "loop", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	ft_sound_player_signals[FT_SOUND_PLAYER_PLAYBACK_STARTED_SIGNAL] = g_signal_new ("playback-started", FT_TYPE_SOUND_PLAYER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	ft_sound_player_signals[FT_SOUND_PLAYER_PLAYBACK_STOPPED_SIGNAL] = g_signal_new ("playback-stopped", FT_TYPE_SOUND_PLAYER, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (FtSoundPlayerClass, playback_stopped), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	ft_sound_player_signals[FT_SOUND_PLAYER_PLAYBACK_ERROR_SIGNAL] = g_signal_new ("playback-error", FT_TYPE_SOUND_PLAYER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, G_TYPE_ERROR);
}

static void
ft_sound_player_instance_init (FtSoundPlayer * self,
                               gpointer klass)
{
	self->priv = ft_sound_player_get_instance_private (self);
	self->priv->_loop = FALSE;
	self->priv->_is_playing = FALSE;
	self->priv->is_about_to_finish = FALSE;
	self->priv->fade_to = 0.0;
	self->priv->stop_timeout_id = (guint) 0;
	self->priv->park_timeout_id = (guint) 0;
}

static void
ft_sound_player_finalize (GObject * obj)
{
	FtSoundPlayer * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, FT_TYPE_SOUND_PLAYER, FtSoundPlayer);
	_g_object_unref0 (self->priv->pipeline);
	_g_object_unref0 (self->priv->volume_filter);
	_g_object_unref0 (self->priv->audio_sink);
	_g_object_unref0 (self->priv->volume_interpolation);
	G_OBJECT_CLASS (ft_sound_player_parent_class)->finalize (obj);
}

static GType
ft_sound_player_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (FtSoundPlayerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) ft_sound_player_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (FtSoundPlayer), 0, (GInstanceInitFunc) ft_sound_player_instance_init, NULL };
	GType ft_sound_player_type_id;
	ft_sound_player_type_id = g_type_register_static (G_TYPE_OBJECT, "FtSoundPlayer", &g_define_type_info, 0);
	FtSoundPlayer_private_offset = g_type_add_instance_private (ft_sound_player_type_id, sizeof (FtSoundPlayerPrivate));
	return ft_sound_player_type_id;
}

GType
ft_sound_player_get_type (void)
{
	static volatile gsize ft_sound_player_type_id__once = 0;
	if (g_once_init_enter (&ft_sound_player_type_id__once)) {
		GType ft_sound_player_type_id;
		ft_sound_player_type_id = ft_sound_player_get_type_once ();
		g_once_init_leave (&ft_sound_player_type_id__once, ft_sound_player_type_id);
	}
	return ft_sound_player_type_id__once;
}

static void
_vala_ft_sound_player_get_property (GObject * object,
                                    guint property_id,
                                    GValue * value,
                                    GParamSpec * pspec)
{
	FtSoundPlayer * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_SOUND_PLAYER, FtSoundPlayer);
	switch (property_id) {
		case FT_SOUND_PLAYER_URI_PROPERTY:
		g_value_set_string (value, ft_sound_player_get_uri (self));
		break;
		case FT_SOUND_PLAYER_VOLUME_PROPERTY:
		g_value_set_double (value, ft_sound_player_get_volume (self));
		break;
		case FT_SOUND_PLAYER_LOOP_PROPERTY:
		g_value_set_boolean (value, ft_sound_player_get_loop (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_ft_sound_player_set_property (GObject * object,
                                    guint property_id,
                                    const GValue * value,
                                    GParamSpec * pspec)
{
	FtSoundPlayer * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, FT_TYPE_SOUND_PLAYER, FtSoundPlayer);
	switch (property_id) {
		case FT_SOUND_PLAYER_URI_PROPERTY:
		ft_sound_player_set_uri (self, g_value_get_string (value));
		break;
		case FT_SOUND_PLAYER_VOLUME_PROPERTY:
		ft_sound_player_set_volume (self, g_value_get_double (value));
		break;
		case FT_SOUND_PLAYER_LOOP_PROPERTY:
		ft_sound_player_set_loop (self, g_value_get_boolean (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

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;
}

