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

#include <glib-object.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include <math.h>
#include <gtk/gtk.h>
#include <gio/gio.h>
#include <sys/types.h>
#include <signal.h>
#include <pango/pango.h>

#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
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define DC_TYPE_AUDIO_PLAYBACK_ITEM (dc_audio_playback_item_get_type ())
#define DC_AUDIO_PLAYBACK_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_AUDIO_PLAYBACK_ITEM, DcAudioPlaybackItem))
#define DC_AUDIO_PLAYBACK_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_AUDIO_PLAYBACK_ITEM, DcAudioPlaybackItemClass))
#define DC_IS_AUDIO_PLAYBACK_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_AUDIO_PLAYBACK_ITEM))
#define DC_IS_AUDIO_PLAYBACK_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_AUDIO_PLAYBACK_ITEM))
#define DC_AUDIO_PLAYBACK_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_AUDIO_PLAYBACK_ITEM, DcAudioPlaybackItemClass))

typedef struct _DcAudioPlaybackItem DcAudioPlaybackItem;
typedef struct _DcAudioPlaybackItemClass DcAudioPlaybackItemClass;
typedef struct _DcAudioPlaybackItemPrivate DcAudioPlaybackItemPrivate;
enum  {
	DC_AUDIO_PLAYBACK_ITEM_0_PROPERTY,
	DC_AUDIO_PLAYBACK_ITEM_ACCOUNT_ID_PROPERTY,
	DC_AUDIO_PLAYBACK_ITEM_CHAT_ID_PROPERTY,
	DC_AUDIO_PLAYBACK_ITEM_MESSAGE_ID_PROPERTY,
	DC_AUDIO_PLAYBACK_ITEM_PATH_PROPERTY,
	DC_AUDIO_PLAYBACK_ITEM_SENDER_NAME_PROPERTY,
	DC_AUDIO_PLAYBACK_ITEM_SENDER_ADDRESS_PROPERTY,
	DC_AUDIO_PLAYBACK_ITEM_AVATAR_PATH_PROPERTY,
	DC_AUDIO_PLAYBACK_ITEM_SENT_TIMESTAMP_PROPERTY,
	DC_AUDIO_PLAYBACK_ITEM_NUM_PROPERTIES
};
static GParamSpec* dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_NUM_PROPERTIES];
#define _g_free0(var) (var = (g_free (var), NULL))

#define DC_TYPE_MESSAGE (dc_message_get_type ())
#define DC_MESSAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_MESSAGE, DcMessage))
#define DC_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_MESSAGE, DcMessageClass))
#define DC_IS_MESSAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_MESSAGE))
#define DC_IS_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_MESSAGE))
#define DC_MESSAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_MESSAGE, DcMessageClass))

typedef struct _DcMessage DcMessage;
typedef struct _DcMessageClass DcMessageClass;

#define DC_TYPE_AUDIO_PLAYBACK (dc_audio_playback_get_type ())
#define DC_AUDIO_PLAYBACK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_AUDIO_PLAYBACK, DcAudioPlayback))
#define DC_AUDIO_PLAYBACK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_AUDIO_PLAYBACK, DcAudioPlaybackClass))
#define DC_IS_AUDIO_PLAYBACK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_AUDIO_PLAYBACK))
#define DC_IS_AUDIO_PLAYBACK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_AUDIO_PLAYBACK))
#define DC_AUDIO_PLAYBACK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_AUDIO_PLAYBACK, DcAudioPlaybackClass))

typedef struct _DcAudioPlayback DcAudioPlayback;
typedef struct _DcAudioPlaybackClass DcAudioPlaybackClass;
typedef struct _DcAudioPlaybackPrivate DcAudioPlaybackPrivate;
enum  {
	DC_AUDIO_PLAYBACK_0_PROPERTY,
	DC_AUDIO_PLAYBACK_CURRENT_ITEM_PROPERTY,
	DC_AUDIO_PLAYBACK_CURRENT_MESSAGE_ID_PROPERTY,
	DC_AUDIO_PLAYBACK_PLAYING_PROPERTY,
	DC_AUDIO_PLAYBACK_CAN_SEEK_PROPERTY,
	DC_AUDIO_PLAYBACK_EXTERNAL_BACKEND_PROPERTY,
	DC_AUDIO_PLAYBACK_HAS_PREVIOUS_PROPERTY,
	DC_AUDIO_PLAYBACK_HAS_NEXT_PROPERTY,
	DC_AUDIO_PLAYBACK_POSITION_US_PROPERTY,
	DC_AUDIO_PLAYBACK_DURATION_US_PROPERTY,
	DC_AUDIO_PLAYBACK_PLAYBACK_RATE_PROPERTY,
	DC_AUDIO_PLAYBACK_CAN_CHANGE_SPEED_PROPERTY,
	DC_AUDIO_PLAYBACK_NUM_PROPERTIES
};
static GParamSpec* dc_audio_playback_properties[DC_AUDIO_PLAYBACK_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
typedef void (*DcPlatformRawAudioFinishedCallback) (gboolean completed, void* user_data);
typedef struct _Block29Data Block29Data;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
enum  {
	DC_AUDIO_PLAYBACK_FINISHED_SIGNAL,
	DC_AUDIO_PLAYBACK_NUM_SIGNALS
};
static guint dc_audio_playback_signals[DC_AUDIO_PLAYBACK_NUM_SIGNALS] = {0};

#define DC_TYPE_AUDIO_PLAYER (dc_audio_player_get_type ())
#define DC_AUDIO_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_AUDIO_PLAYER, DcAudioPlayer))
#define DC_AUDIO_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_AUDIO_PLAYER, DcAudioPlayerClass))
#define DC_IS_AUDIO_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_AUDIO_PLAYER))
#define DC_IS_AUDIO_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_AUDIO_PLAYER))
#define DC_AUDIO_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_AUDIO_PLAYER, DcAudioPlayerClass))

typedef struct _DcAudioPlayer DcAudioPlayer;
typedef struct _DcAudioPlayerClass DcAudioPlayerClass;
typedef struct _DcAudioPlayerPrivate DcAudioPlayerPrivate;

#define DC_TYPE_TRANSCRIBER (dc_transcriber_get_type ())
#define DC_TRANSCRIBER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DC_TYPE_TRANSCRIBER, DcTranscriber))
#define DC_TRANSCRIBER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DC_TYPE_TRANSCRIBER, DcTranscriberClass))
#define DC_IS_TRANSCRIBER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DC_TYPE_TRANSCRIBER))
#define DC_IS_TRANSCRIBER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DC_TYPE_TRANSCRIBER))
#define DC_TRANSCRIBER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DC_TYPE_TRANSCRIBER, DcTranscriberClass))

typedef struct _DcTranscriber DcTranscriber;
typedef struct _DcTranscriberClass DcTranscriberClass;
enum  {
	DC_AUDIO_PLAYER_0_PROPERTY,
	DC_AUDIO_PLAYER_NUM_PROPERTIES
};
static GParamSpec* dc_audio_player_properties[DC_AUDIO_PLAYER_NUM_PROPERTIES];
typedef struct _Block30Data Block30Data;

struct _DcAudioPlaybackItem {
	GObject parent_instance;
	DcAudioPlaybackItemPrivate * priv;
};

struct _DcAudioPlaybackItemClass {
	GObjectClass parent_class;
};

struct _DcAudioPlaybackItemPrivate {
	gint _account_id;
	gint _chat_id;
	gint _message_id;
	gchar* _path;
	gchar* _sender_name;
	gchar* _sender_address;
	gchar* _avatar_path;
	gint64 _sent_timestamp;
};

struct _DcAudioPlayback {
	GObject parent_instance;
	DcAudioPlaybackPrivate * priv;
};

struct _DcAudioPlaybackClass {
	GObjectClass parent_class;
};

struct _DcAudioPlaybackPrivate {
	DcAudioPlaybackItem* _current_item;
	gint _current_message_id;
	gboolean _playing;
	gboolean _can_seek;
	gboolean _external_backend;
	gboolean _has_previous;
	gboolean _has_next;
	gint64 _position_us;
	gint64 _duration_us;
	gdouble _playback_rate;
	gboolean _can_change_speed;
	gchar* path;
	void* native_backend;
	gboolean native_backend_failed;
	GtkMediaFile* media;
	gulong media_handler;
	gboolean media_seek_pending;
	GSubprocess* proc;
	pid_t proc_pid;
	GCancellable* proc_cancel;
	guint progress_timer;
	gint64 external_started_us;
	gint64 external_elapsed_us;
	gboolean external_paused;
};

struct _Block29Data {
	int _ref_count_;
	DcAudioPlayback* self;
	GSubprocess* p;
	gint played_id;
};

struct _DcAudioPlayer {
	GtkBox parent_instance;
	DcAudioPlayerPrivate * priv;
};

struct _DcAudioPlayerClass {
	GtkBoxClass parent_class;
};

struct _DcAudioPlayerPrivate {
	DcMessage* message;
	gint account_id;
	GtkButton* btn;
	GtkButton* transcribe_btn;
	GtkLabel* transcription_label;
	DcAudioPlayback* playback;
	DcTranscriber* transcriber;
	gulong current_handler;
	gulong playing_handler;
	gulong transcriber_handler;
};

struct _Block30Data {
	int _ref_count_;
	DcAudioPlayer* self;
	DcMessage* message;
	gint account_id;
};

static gint DcAudioPlaybackItem_private_offset;
static gpointer dc_audio_playback_item_parent_class = NULL;
VALA_EXTERN gchar* dc_message_row_self_avatar_path;
static gint DcAudioPlayback_private_offset;
static gpointer dc_audio_playback_parent_class = NULL;
static DcAudioPlayback* dc_audio_playback_instance;
static DcAudioPlayback* dc_audio_playback_instance = NULL;
VALA_EXTERN gboolean dc_audio_player_prefer_system;
static gint DcAudioPlayer_private_offset;
static gpointer dc_audio_player_parent_class = NULL;
gboolean dc_audio_player_prefer_system = FALSE;

VALA_EXTERN GType dc_audio_playback_item_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcAudioPlaybackItem, g_object_unref)
VALA_EXTERN GType dc_message_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcMessage, g_object_unref)
VALA_EXTERN DcAudioPlaybackItem* dc_audio_playback_item_new (DcMessage* msg,
                                                 gint account_id);
VALA_EXTERN DcAudioPlaybackItem* dc_audio_playback_item_construct (GType object_type,
                                                       DcMessage* msg,
                                                       gint account_id);
VALA_EXTERN gboolean dc_message_get_is_outgoing (DcMessage* self);
VALA_EXTERN const gchar* dc_message_get_sender_avatar_path (DcMessage* self);
VALA_EXTERN gint dc_message_get_chat_id (DcMessage* self);
VALA_EXTERN gint dc_message_get_id (DcMessage* self);
VALA_EXTERN const gchar* dc_message_get_file_path (DcMessage* self);
VALA_EXTERN gchar* dc_message_row_effective_sender_name (DcMessage* msg);
VALA_EXTERN const gchar* dc_message_get_sender_address (DcMessage* self);
VALA_EXTERN gint64 dc_message_get_timestamp (DcMessage* self);
VALA_EXTERN gint dc_audio_playback_item_get_account_id (DcAudioPlaybackItem* self);
static void dc_audio_playback_item_set_account_id (DcAudioPlaybackItem* self,
                                            gint value);
VALA_EXTERN gint dc_audio_playback_item_get_chat_id (DcAudioPlaybackItem* self);
static void dc_audio_playback_item_set_chat_id (DcAudioPlaybackItem* self,
                                         gint value);
VALA_EXTERN gint dc_audio_playback_item_get_message_id (DcAudioPlaybackItem* self);
static void dc_audio_playback_item_set_message_id (DcAudioPlaybackItem* self,
                                            gint value);
VALA_EXTERN const gchar* dc_audio_playback_item_get_path (DcAudioPlaybackItem* self);
static void dc_audio_playback_item_set_path (DcAudioPlaybackItem* self,
                                      const gchar* value);
VALA_EXTERN const gchar* dc_audio_playback_item_get_sender_name (DcAudioPlaybackItem* self);
static void dc_audio_playback_item_set_sender_name (DcAudioPlaybackItem* self,
                                             const gchar* value);
VALA_EXTERN const gchar* dc_audio_playback_item_get_sender_address (DcAudioPlaybackItem* self);
static void dc_audio_playback_item_set_sender_address (DcAudioPlaybackItem* self,
                                                const gchar* value);
VALA_EXTERN const gchar* dc_audio_playback_item_get_avatar_path (DcAudioPlaybackItem* self);
static void dc_audio_playback_item_set_avatar_path (DcAudioPlaybackItem* self,
                                             const gchar* value);
VALA_EXTERN gint64 dc_audio_playback_item_get_sent_timestamp (DcAudioPlaybackItem* self);
static void dc_audio_playback_item_set_sent_timestamp (DcAudioPlaybackItem* self,
                                                gint64 value);
static void dc_audio_playback_item_finalize (GObject * obj);
static GType dc_audio_playback_item_get_type_once (void);
static void _vala_dc_audio_playback_item_get_property (GObject * object,
                                                guint property_id,
                                                GValue * value,
                                                GParamSpec * pspec);
static void _vala_dc_audio_playback_item_set_property (GObject * object,
                                                guint property_id,
                                                const GValue * value,
                                                GParamSpec * pspec);
VALA_EXTERN GType dc_audio_playback_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcAudioPlayback, g_object_unref)
static DcAudioPlayback* dc_audio_playback_new (void);
static DcAudioPlayback* dc_audio_playback_construct (GType object_type);
VALA_EXTERN gboolean dc_platform_audio_backend_supported (void);
static gboolean dc_audio_playback_rate_player_available (void);
static void dc_audio_playback_set_can_change_speed (DcAudioPlayback* self,
                                             gboolean value);
VALA_EXTERN DcAudioPlayback* dc_audio_playback_shared (void);
VALA_EXTERN gdouble dc_audio_playback_rate_for_index (guint index);
VALA_EXTERN guint dc_audio_playback_index_for_rate (gdouble rate);
VALA_EXTERN void dc_audio_playback_play_message (DcAudioPlayback* self,
                                     DcMessage* msg,
                                     gint account_id);
VALA_EXTERN gboolean dc_message_get_has_local_file (DcMessage* self);
VALA_EXTERN gboolean dc_message_is_audio_file (DcMessage* self);
static void dc_audio_playback_stop_backend (DcAudioPlayback* self);
static void dc_audio_playback_set_position_us (DcAudioPlayback* self,
                                        gint64 value);
static void dc_audio_playback_set_duration_us (DcAudioPlayback* self,
                                        gint64 value);
static void dc_audio_playback_set_can_seek (DcAudioPlayback* self,
                                     gboolean value);
static void dc_audio_playback_set_external_backend (DcAudioPlayback* self,
                                             gboolean value);
static void dc_audio_playback_set_playback_rate (DcAudioPlayback* self,
                                          gdouble value);
static void dc_audio_playback_set_has_previous (DcAudioPlayback* self,
                                         gboolean value);
static void dc_audio_playback_set_has_next (DcAudioPlayback* self,
                                     gboolean value);
static void dc_audio_playback_set_current_item (DcAudioPlayback* self,
                                         DcAudioPlaybackItem* value);
static void dc_audio_playback_set_current_message_id (DcAudioPlayback* self,
                                               gint value);
static void dc_audio_playback_start_backend (DcAudioPlayback* self);
VALA_EXTERN void dc_audio_playback_set_navigation (DcAudioPlayback* self,
                                       gboolean previous,
                                       gboolean next);
VALA_EXTERN void dc_audio_playback_toggle (DcAudioPlayback* self);
VALA_EXTERN gint dc_audio_playback_get_current_message_id (DcAudioPlayback* self);
VALA_EXTERN gboolean dc_audio_playback_get_playing (DcAudioPlayback* self);
static void dc_audio_playback_pause (DcAudioPlayback* self);
static void dc_audio_playback_resume (DcAudioPlayback* self);
VALA_EXTERN void dc_audio_playback_stop (DcAudioPlayback* self);
VALA_EXTERN void dc_audio_playback_seek_fraction (DcAudioPlayback* self,
                                      gdouble fraction);
VALA_EXTERN gboolean dc_audio_playback_get_can_seek (DcAudioPlayback* self);
VALA_EXTERN gint64 dc_audio_playback_get_duration_us (DcAudioPlayback* self);
VALA_EXTERN void dc_platform_audio_backend_seek (void* handle,
                                     gint64 position_us);
VALA_EXTERN void dc_audio_playback_change_playback_rate (DcAudioPlayback* self,
                                             gdouble rate);
VALA_EXTERN gboolean dc_audio_playback_get_can_change_speed (DcAudioPlayback* self);
VALA_EXTERN gdouble dc_audio_playback_get_playback_rate (DcAudioPlayback* self);
VALA_EXTERN void dc_platform_audio_backend_set_rate (void* handle,
                                         gdouble rate);
static void dc_audio_playback_sync_media_state (DcAudioPlayback* self,
                                         GtkMediaFile* m);
static void dc_audio_playback_update_external_position (DcAudioPlayback* self);
VALA_EXTERN void dc_platform_audio_backend_pause (void* handle);
static void dc_audio_playback_sync_native_state (DcAudioPlayback* self);
static void dc_audio_playback_set_playing (DcAudioPlayback* self,
                                    gboolean value);
static void dc_audio_playback_stop_progress_timer (DcAudioPlayback* self);
VALA_EXTERN gint64 dc_audio_playback_get_position_us (DcAudioPlayback* self);
static void dc_audio_playback_stop_external (DcAudioPlayback* self);
VALA_EXTERN gboolean dc_platform_audio_backend_play (void* handle);
static void dc_audio_playback_ensure_progress_timer (DcAudioPlayback* self);
VALA_EXTERN gboolean dc_platform_is_macos (void);
static gboolean dc_audio_playback_play_native (DcAudioPlayback* self,
                                        const gchar* file_path);
static gchar** dc_audio_playback_find_external_command (DcAudioPlayback* self,
                                                 const gchar* file_path,
                                                 gint64 start_us,
                                                 gdouble rate,
                                                 gint* result_length1);
static gboolean dc_audio_playback_play_external (DcAudioPlayback* self,
                                          gchar** argv,
                                          gint argv_length1);
static void dc_audio_playback_play_media (DcAudioPlayback* self,
                                   const gchar* file_path);
VALA_EXTERN void* dc_platform_audio_backend_new (const gchar* path,
                                     DcPlatformRawAudioFinishedCallback callback,
                                     void* user_data);
static void dc_audio_playback_on_native_finished (gboolean completed,
                                           void* user_data);
static void _dc_audio_playback_on_native_finished_dc_platform_raw_audio_finished_callback (gboolean completed,
                                                                                    void* user_data);
VALA_EXTERN void dc_platform_audio_backend_free (void* handle);
VALA_EXTERN gint64 dc_platform_audio_backend_get_position (void* handle);
VALA_EXTERN gint64 dc_platform_audio_backend_get_duration (void* handle);
VALA_EXTERN gboolean dc_platform_audio_backend_can_seek (void* handle);
VALA_EXTERN gboolean dc_platform_audio_backend_is_playing (void* handle);
static Block29Data* block29_data_ref (Block29Data* _data29_);
static void block29_data_unref (void * _userdata_);
VALA_EXTERN GSubprocess* dc_subprocess_util_spawnv (GSubprocessLauncher* launcher,
                                        gchar** argv,
                                        gint argv_length1,
                                        GError** error);
static void ___lambda46_ (Block29Data* _data29_,
                   GObject* obj,
                   GAsyncResult* res);
static void ____lambda46__gasync_ready_callback (GObject* source_object,
                                          GAsyncResult* res,
                                          gpointer self);
static void dc_audio_playback_on_media_notify (GtkMediaFile* m,
                                        GParamSpec* pspec,
                                        DcAudioPlayback* playback);
static gboolean __lambda45_ (DcAudioPlayback* self);
static gboolean ___lambda45__gsource_func (gpointer self);
VALA_EXTERN void dc_platform_audio_backend_stop (void* handle);
VALA_EXTERN DcAudioPlaybackItem* dc_audio_playback_get_current_item (DcAudioPlayback* self);
VALA_EXTERN gboolean dc_audio_playback_get_external_backend (DcAudioPlayback* self);
VALA_EXTERN gboolean dc_audio_playback_get_has_previous (DcAudioPlayback* self);
VALA_EXTERN gboolean dc_audio_playback_get_has_next (DcAudioPlayback* self);
static void dc_audio_playback_finalize (GObject * obj);
static GType dc_audio_playback_get_type_once (void);
static void _vala_dc_audio_playback_get_property (GObject * object,
                                           guint property_id,
                                           GValue * value,
                                           GParamSpec * pspec);
static void _vala_dc_audio_playback_set_property (GObject * object,
                                           guint property_id,
                                           const GValue * value,
                                           GParamSpec * pspec);
VALA_EXTERN GType dc_audio_player_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcAudioPlayer, g_object_unref)
VALA_EXTERN GType dc_transcriber_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (DcTranscriber, g_object_unref)
VALA_EXTERN DcAudioPlayer* dc_audio_player_new (DcMessage* message,
                                    gint account_id);
VALA_EXTERN DcAudioPlayer* dc_audio_player_construct (GType object_type,
                                          DcMessage* message,
                                          gint account_id);
static Block30Data* block30_data_ref (Block30Data* _data30_);
static void block30_data_unref (void * _userdata_);
VALA_EXTERN DcTranscriber* dc_transcriber_shared (void);
static void __lambda437_ (Block30Data* _data30_);
static gboolean dc_audio_player_is_current_message (DcAudioPlayer* self);
static void ___lambda437__gtk_button_clicked (GtkButton* _sender,
                                       gpointer self);
VALA_EXTERN gint dc_message_get_file_bytes (DcMessage* self);
VALA_EXTERN gboolean dc_transcriber_available (void);
static void ___lambda438_ (Block30Data* _data30_);
VALA_EXTERN void dc_transcriber_transcribe (DcTranscriber* self,
                                const gchar* path);
static void ____lambda438__gtk_button_clicked (GtkButton* _sender,
                                        gpointer self);
static void dc_audio_player_update_visuals (DcAudioPlayer* self);
static void _dc_audio_player_update_visuals_g_object_notify (GObject* _sender,
                                                      GParamSpec* pspec,
                                                      gpointer self);
static void __lambda439_ (Block30Data* _data30_,
                   const gchar* path);
static void dc_audio_player_update_transcription (DcAudioPlayer* self);
static void ___lambda439__dc_transcriber_updated (DcTranscriber* _sender,
                                           const gchar* path,
                                           gpointer self);
VALA_EXTERN gboolean dc_transcriber_is_running (DcTranscriber* self,
                                    const gchar* path);
VALA_EXTERN gchar* dc_transcriber_result_for (DcTranscriber* self,
                                  const gchar* path);
static void dc_audio_player_real_dispose (GObject* base);
static void dc_audio_player_finalize (GObject * obj);
static GType dc_audio_player_get_type_once (void);
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 inline gpointer
dc_audio_playback_item_get_instance_private (DcAudioPlaybackItem* self)
{
	return G_STRUCT_MEMBER_P (self, DcAudioPlaybackItem_private_offset);
}

DcAudioPlaybackItem*
dc_audio_playback_item_construct (GType object_type,
                                  DcMessage* msg,
                                  gint account_id)
{
	DcAudioPlaybackItem * self = NULL;
	const gchar* _tmp0_ = NULL;
	gboolean _tmp1_;
	gboolean _tmp2_;
	gint _tmp6_;
	gint _tmp7_;
	gint _tmp8_;
	gint _tmp9_;
	const gchar* _tmp10_;
	const gchar* _tmp11_;
	gchar* _tmp12_;
	gchar* _tmp13_;
	const gchar* _tmp14_;
	const gchar* _tmp15_;
	gint64 _tmp16_;
	gint64 _tmp17_;
	g_return_val_if_fail (msg != NULL, NULL);
	_tmp1_ = dc_message_get_is_outgoing (msg);
	_tmp2_ = _tmp1_;
	if (_tmp2_) {
		const gchar* _tmp3_;
		_tmp3_ = dc_message_row_self_avatar_path;
		_tmp0_ = _tmp3_;
	} else {
		const gchar* _tmp4_;
		const gchar* _tmp5_;
		_tmp4_ = dc_message_get_sender_avatar_path (msg);
		_tmp5_ = _tmp4_;
		_tmp0_ = _tmp5_;
	}
	_tmp6_ = dc_message_get_chat_id (msg);
	_tmp7_ = _tmp6_;
	_tmp8_ = dc_message_get_id (msg);
	_tmp9_ = _tmp8_;
	_tmp10_ = dc_message_get_file_path (msg);
	_tmp11_ = _tmp10_;
	_tmp12_ = dc_message_row_effective_sender_name (msg);
	_tmp13_ = _tmp12_;
	_tmp14_ = dc_message_get_sender_address (msg);
	_tmp15_ = _tmp14_;
	_tmp16_ = dc_message_get_timestamp (msg);
	_tmp17_ = _tmp16_;
	self = (DcAudioPlaybackItem*) g_object_new (object_type, "account-id", account_id, "chat-id", _tmp7_, "message-id", _tmp9_, "path", _tmp11_, "sender-name", _tmp13_, "sender-address", _tmp15_, "avatar-path", _tmp0_, "sent-timestamp", _tmp17_, NULL);
	_g_free0 (_tmp13_);
	return self;
}

DcAudioPlaybackItem*
dc_audio_playback_item_new (DcMessage* msg,
                            gint account_id)
{
	return dc_audio_playback_item_construct (DC_TYPE_AUDIO_PLAYBACK_ITEM, msg, account_id);
}

gint
dc_audio_playback_item_get_account_id (DcAudioPlaybackItem* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_account_id;
	return result;
}

static void
dc_audio_playback_item_set_account_id (DcAudioPlaybackItem* self,
                                       gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_item_get_account_id (self);
	if (old_value != value) {
		self->priv->_account_id = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_ACCOUNT_ID_PROPERTY]);
	}
}

gint
dc_audio_playback_item_get_chat_id (DcAudioPlaybackItem* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_chat_id;
	return result;
}

static void
dc_audio_playback_item_set_chat_id (DcAudioPlaybackItem* self,
                                    gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_item_get_chat_id (self);
	if (old_value != value) {
		self->priv->_chat_id = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_CHAT_ID_PROPERTY]);
	}
}

gint
dc_audio_playback_item_get_message_id (DcAudioPlaybackItem* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_message_id;
	return result;
}

static void
dc_audio_playback_item_set_message_id (DcAudioPlaybackItem* self,
                                       gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_item_get_message_id (self);
	if (old_value != value) {
		self->priv->_message_id = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_MESSAGE_ID_PROPERTY]);
	}
}

const gchar*
dc_audio_playback_item_get_path (DcAudioPlaybackItem* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_path;
	result = _tmp0_;
	return result;
}

static void
dc_audio_playback_item_set_path (DcAudioPlaybackItem* self,
                                 const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_item_get_path (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_path);
		self->priv->_path = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_PATH_PROPERTY]);
	}
}

const gchar*
dc_audio_playback_item_get_sender_name (DcAudioPlaybackItem* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_sender_name;
	result = _tmp0_;
	return result;
}

static void
dc_audio_playback_item_set_sender_name (DcAudioPlaybackItem* self,
                                        const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_item_get_sender_name (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_sender_name);
		self->priv->_sender_name = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_SENDER_NAME_PROPERTY]);
	}
}

const gchar*
dc_audio_playback_item_get_sender_address (DcAudioPlaybackItem* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_sender_address;
	result = _tmp0_;
	return result;
}

static void
dc_audio_playback_item_set_sender_address (DcAudioPlaybackItem* self,
                                           const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_item_get_sender_address (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_sender_address);
		self->priv->_sender_address = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_SENDER_ADDRESS_PROPERTY]);
	}
}

const gchar*
dc_audio_playback_item_get_avatar_path (DcAudioPlaybackItem* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_avatar_path;
	result = _tmp0_;
	return result;
}

static void
dc_audio_playback_item_set_avatar_path (DcAudioPlaybackItem* self,
                                        const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_item_get_avatar_path (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_avatar_path);
		self->priv->_avatar_path = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_AVATAR_PATH_PROPERTY]);
	}
}

gint64
dc_audio_playback_item_get_sent_timestamp (DcAudioPlaybackItem* self)
{
	gint64 result;
	g_return_val_if_fail (self != NULL, -1LL);
	result = self->priv->_sent_timestamp;
	return result;
}

static void
dc_audio_playback_item_set_sent_timestamp (DcAudioPlaybackItem* self,
                                           gint64 value)
{
	gint64 old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_item_get_sent_timestamp (self);
	if (old_value != value) {
		self->priv->_sent_timestamp = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_SENT_TIMESTAMP_PROPERTY]);
	}
}

static void
dc_audio_playback_item_class_init (DcAudioPlaybackItemClass * klass,
                                   gpointer klass_data)
{
	dc_audio_playback_item_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &DcAudioPlaybackItem_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_dc_audio_playback_item_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_dc_audio_playback_item_set_property;
	G_OBJECT_CLASS (klass)->finalize = dc_audio_playback_item_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_ITEM_ACCOUNT_ID_PROPERTY, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_ACCOUNT_ID_PROPERTY] = g_param_spec_int ("account-id", "account-id", "account-id", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_ITEM_CHAT_ID_PROPERTY, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_CHAT_ID_PROPERTY] = g_param_spec_int ("chat-id", "chat-id", "chat-id", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_ITEM_MESSAGE_ID_PROPERTY, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_MESSAGE_ID_PROPERTY] = g_param_spec_int ("message-id", "message-id", "message-id", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_ITEM_PATH_PROPERTY, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_PATH_PROPERTY] = g_param_spec_string ("path", "path", "path", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_ITEM_SENDER_NAME_PROPERTY, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_SENDER_NAME_PROPERTY] = g_param_spec_string ("sender-name", "sender-name", "sender-name", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_ITEM_SENDER_ADDRESS_PROPERTY, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_SENDER_ADDRESS_PROPERTY] = g_param_spec_string ("sender-address", "sender-address", "sender-address", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_ITEM_AVATAR_PATH_PROPERTY, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_AVATAR_PATH_PROPERTY] = g_param_spec_string ("avatar-path", "avatar-path", "avatar-path", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_ITEM_SENT_TIMESTAMP_PROPERTY, dc_audio_playback_item_properties[DC_AUDIO_PLAYBACK_ITEM_SENT_TIMESTAMP_PROPERTY] = g_param_spec_int64 ("sent-timestamp", "sent-timestamp", "sent-timestamp", G_MININT64, G_MAXINT64, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
}

static void
dc_audio_playback_item_instance_init (DcAudioPlaybackItem * self,
                                      gpointer klass)
{
	self->priv = dc_audio_playback_item_get_instance_private (self);
}

static void
dc_audio_playback_item_finalize (GObject * obj)
{
	DcAudioPlaybackItem * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_TYPE_AUDIO_PLAYBACK_ITEM, DcAudioPlaybackItem);
	_g_free0 (self->priv->_path);
	_g_free0 (self->priv->_sender_name);
	_g_free0 (self->priv->_sender_address);
	_g_free0 (self->priv->_avatar_path);
	G_OBJECT_CLASS (dc_audio_playback_item_parent_class)->finalize (obj);
}

/** Immutable metadata needed to render and locate the active voice note. */
static GType
dc_audio_playback_item_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (DcAudioPlaybackItemClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_audio_playback_item_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcAudioPlaybackItem), 0, (GInstanceInitFunc) dc_audio_playback_item_instance_init, NULL };
	GType dc_audio_playback_item_type_id;
	dc_audio_playback_item_type_id = g_type_register_static (G_TYPE_OBJECT, "DcAudioPlaybackItem", &g_define_type_info, 0);
	DcAudioPlaybackItem_private_offset = g_type_add_instance_private (dc_audio_playback_item_type_id, sizeof (DcAudioPlaybackItemPrivate));
	return dc_audio_playback_item_type_id;
}

GType
dc_audio_playback_item_get_type (void)
{
	static volatile gsize dc_audio_playback_item_type_id__once = 0;
	if (g_once_init_enter (&dc_audio_playback_item_type_id__once)) {
		GType dc_audio_playback_item_type_id;
		dc_audio_playback_item_type_id = dc_audio_playback_item_get_type_once ();
		g_once_init_leave (&dc_audio_playback_item_type_id__once, dc_audio_playback_item_type_id);
	}
	return dc_audio_playback_item_type_id__once;
}

static void
_vala_dc_audio_playback_item_get_property (GObject * object,
                                           guint property_id,
                                           GValue * value,
                                           GParamSpec * pspec)
{
	DcAudioPlaybackItem * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, DC_TYPE_AUDIO_PLAYBACK_ITEM, DcAudioPlaybackItem);
	switch (property_id) {
		case DC_AUDIO_PLAYBACK_ITEM_ACCOUNT_ID_PROPERTY:
		g_value_set_int (value, dc_audio_playback_item_get_account_id (self));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_CHAT_ID_PROPERTY:
		g_value_set_int (value, dc_audio_playback_item_get_chat_id (self));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_MESSAGE_ID_PROPERTY:
		g_value_set_int (value, dc_audio_playback_item_get_message_id (self));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_PATH_PROPERTY:
		g_value_set_string (value, dc_audio_playback_item_get_path (self));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_SENDER_NAME_PROPERTY:
		g_value_set_string (value, dc_audio_playback_item_get_sender_name (self));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_SENDER_ADDRESS_PROPERTY:
		g_value_set_string (value, dc_audio_playback_item_get_sender_address (self));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_AVATAR_PATH_PROPERTY:
		g_value_set_string (value, dc_audio_playback_item_get_avatar_path (self));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_SENT_TIMESTAMP_PROPERTY:
		g_value_set_int64 (value, dc_audio_playback_item_get_sent_timestamp (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_dc_audio_playback_item_set_property (GObject * object,
                                           guint property_id,
                                           const GValue * value,
                                           GParamSpec * pspec)
{
	DcAudioPlaybackItem * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, DC_TYPE_AUDIO_PLAYBACK_ITEM, DcAudioPlaybackItem);
	switch (property_id) {
		case DC_AUDIO_PLAYBACK_ITEM_ACCOUNT_ID_PROPERTY:
		dc_audio_playback_item_set_account_id (self, g_value_get_int (value));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_CHAT_ID_PROPERTY:
		dc_audio_playback_item_set_chat_id (self, g_value_get_int (value));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_MESSAGE_ID_PROPERTY:
		dc_audio_playback_item_set_message_id (self, g_value_get_int (value));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_PATH_PROPERTY:
		dc_audio_playback_item_set_path (self, g_value_get_string (value));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_SENDER_NAME_PROPERTY:
		dc_audio_playback_item_set_sender_name (self, g_value_get_string (value));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_SENDER_ADDRESS_PROPERTY:
		dc_audio_playback_item_set_sender_address (self, g_value_get_string (value));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_AVATAR_PATH_PROPERTY:
		dc_audio_playback_item_set_avatar_path (self, g_value_get_string (value));
		break;
		case DC_AUDIO_PLAYBACK_ITEM_SENT_TIMESTAMP_PROPERTY:
		dc_audio_playback_item_set_sent_timestamp (self, g_value_get_int64 (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
dc_audio_playback_get_instance_private (DcAudioPlayback* self)
{
	return G_STRUCT_MEMBER_P (self, DcAudioPlayback_private_offset);
}

static DcAudioPlayback*
dc_audio_playback_construct (GType object_type)
{
	DcAudioPlayback * self = NULL;
	gboolean _tmp0_ = FALSE;
	self = (DcAudioPlayback*) g_object_new (object_type, NULL);
	if (dc_platform_audio_backend_supported ()) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = dc_audio_playback_rate_player_available ();
	}
	dc_audio_playback_set_can_change_speed (self, _tmp0_);
	return self;
}

static DcAudioPlayback*
dc_audio_playback_new (void)
{
	return dc_audio_playback_construct (DC_TYPE_AUDIO_PLAYBACK);
}

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

DcAudioPlayback*
dc_audio_playback_shared (void)
{
	DcAudioPlayback* _tmp0_;
	DcAudioPlayback* _tmp2_;
	DcAudioPlayback* _tmp3_;
	DcAudioPlayback* result;
	_tmp0_ = dc_audio_playback_instance;
	if (_tmp0_ == NULL) {
		DcAudioPlayback* _tmp1_;
		_tmp1_ = dc_audio_playback_new ();
		_g_object_unref0 (dc_audio_playback_instance);
		dc_audio_playback_instance = _tmp1_;
	}
	_tmp2_ = dc_audio_playback_instance;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	result = _tmp3_;
	return result;
}

gdouble
dc_audio_playback_rate_for_index (guint index)
{
	gdouble result;
	switch (index) {
		case 0:
		{
			result = 0.5;
			return result;
		}
		case 1:
		{
			result = 0.75;
			return result;
		}
		case 3:
		{
			result = 1.25;
			return result;
		}
		case 4:
		{
			result = 1.5;
			return result;
		}
		case 5:
		{
			result = 2.0;
			return result;
		}
		case 6:
		{
			result = 3.0;
			return result;
		}
		case 7:
		{
			result = 4.0;
			return result;
		}
		case 8:
		{
			result = 5.0;
			return result;
		}
		default:
		{
			result = 1.0;
			return result;
		}
	}
}

guint
dc_audio_playback_index_for_rate (gdouble rate)
{
	guint result;
	if (fabs (rate - 0.5) < 0.001) {
		result = (guint) 0;
		return result;
	}
	if (fabs (rate - 0.75) < 0.001) {
		result = (guint) 1;
		return result;
	}
	if (fabs (rate - 1.25) < 0.001) {
		result = (guint) 3;
		return result;
	}
	if (fabs (rate - 1.5) < 0.001) {
		result = (guint) 4;
		return result;
	}
	if (fabs (rate - 2.0) < 0.001) {
		result = (guint) 5;
		return result;
	}
	if (fabs (rate - 3.0) < 0.001) {
		result = (guint) 6;
		return result;
	}
	if (fabs (rate - 4.0) < 0.001) {
		result = (guint) 7;
		return result;
	}
	if (fabs (rate - 5.0) < 0.001) {
		result = (guint) 8;
		return result;
	}
	result = (guint) 2;
	return result;
}

void
dc_audio_playback_play_message (DcAudioPlayback* self,
                                DcMessage* msg,
                                gint account_id)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gint _tmp2_;
	gint _tmp3_;
	DcAudioPlaybackItem* item = NULL;
	DcAudioPlaybackItem* _tmp6_;
	DcAudioPlaybackItem* _tmp7_;
	const gchar* _tmp8_;
	const gchar* _tmp9_;
	gchar* _tmp10_;
	DcAudioPlaybackItem* _tmp11_;
	DcAudioPlaybackItem* _tmp12_;
	gint _tmp13_;
	gint _tmp14_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (msg != NULL);
	_tmp2_ = dc_message_get_id (msg);
	_tmp3_ = _tmp2_;
	if (_tmp3_ <= 0) {
		_tmp1_ = TRUE;
	} else {
		gboolean _tmp4_;
		gboolean _tmp5_;
		_tmp4_ = dc_message_get_has_local_file (msg);
		_tmp5_ = _tmp4_;
		_tmp1_ = !_tmp5_;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = !dc_message_is_audio_file (msg);
	}
	if (_tmp0_) {
		return;
	}
	_tmp6_ = dc_audio_playback_item_new (msg, account_id);
	item = _tmp6_;
	dc_audio_playback_stop_backend (self);
	_tmp7_ = item;
	_tmp8_ = dc_audio_playback_item_get_path (_tmp7_);
	_tmp9_ = _tmp8_;
	_tmp10_ = g_strdup (_tmp9_);
	_g_free0 (self->priv->path);
	self->priv->path = _tmp10_;
	dc_audio_playback_set_position_us (self, (gint64) 0);
	dc_audio_playback_set_duration_us (self, (gint64) 0);
	dc_audio_playback_set_can_seek (self, FALSE);
	dc_audio_playback_set_external_backend (self, FALSE);
	dc_audio_playback_set_playback_rate (self, 1.0);
	self->priv->native_backend_failed = FALSE;
	dc_audio_playback_set_has_previous (self, FALSE);
	dc_audio_playback_set_has_next (self, FALSE);
	_tmp11_ = item;
	dc_audio_playback_set_current_item (self, _tmp11_);
	_tmp12_ = item;
	_tmp13_ = dc_audio_playback_item_get_message_id (_tmp12_);
	_tmp14_ = _tmp13_;
	dc_audio_playback_set_current_message_id (self, _tmp14_);
	dc_audio_playback_start_backend (self);
	_g_object_unref0 (item);
}

void
dc_audio_playback_set_navigation (DcAudioPlayback* self,
                                  gboolean previous,
                                  gboolean next)
{
	g_return_if_fail (self != NULL);
	dc_audio_playback_set_has_previous (self, previous);
	dc_audio_playback_set_has_next (self, next);
}

void
dc_audio_playback_toggle (DcAudioPlayback* self)
{
	gboolean _tmp0_ = FALSE;
	gint _tmp1_;
	gboolean _tmp3_;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->priv->_current_message_id;
	if (_tmp1_ <= 0) {
		_tmp0_ = TRUE;
	} else {
		const gchar* _tmp2_;
		_tmp2_ = self->priv->path;
		_tmp0_ = _tmp2_ == NULL;
	}
	if (_tmp0_) {
		return;
	}
	_tmp3_ = self->priv->_playing;
	if (_tmp3_) {
		dc_audio_playback_pause (self);
	} else {
		dc_audio_playback_resume (self);
	}
}

void
dc_audio_playback_stop (DcAudioPlayback* self)
{
	g_return_if_fail (self != NULL);
	dc_audio_playback_stop_backend (self);
	_g_free0 (self->priv->path);
	self->priv->path = NULL;
	dc_audio_playback_set_position_us (self, (gint64) 0);
	dc_audio_playback_set_duration_us (self, (gint64) 0);
	dc_audio_playback_set_has_previous (self, FALSE);
	dc_audio_playback_set_has_next (self, FALSE);
	dc_audio_playback_set_current_item (self, NULL);
	dc_audio_playback_set_current_message_id (self, 0);
	dc_audio_playback_set_playback_rate (self, 1.0);
}

void
dc_audio_playback_seek_fraction (DcAudioPlayback* self,
                                 gdouble fraction)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_;
	gdouble clamped = 0.0;
	gint64 target = 0LL;
	gint64 _tmp3_;
	void* _tmp4_;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->priv->_can_seek;
	if (!_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gint64 _tmp2_;
		_tmp2_ = self->priv->_duration_us;
		_tmp0_ = _tmp2_ <= ((gint64) 0);
	}
	if (_tmp0_) {
		return;
	}
	clamped = MAX (0.0, MIN (1.0, fraction));
	_tmp3_ = self->priv->_duration_us;
	target = (gint64) (clamped * _tmp3_);
	_tmp4_ = self->priv->native_backend;
	if (_tmp4_ != NULL) {
		void* _tmp5_;
		_tmp5_ = self->priv->native_backend;
		dc_platform_audio_backend_seek (_tmp5_, target);
	} else {
		GtkMediaFile* _tmp6_;
		_tmp6_ = self->priv->media;
		if (_tmp6_ != NULL) {
			GtkMediaFile* _tmp7_;
			_tmp7_ = self->priv->media;
			gtk_media_stream_seek ((GtkMediaStream*) _tmp7_, target);
		} else {
			return;
		}
	}
	dc_audio_playback_set_position_us (self, target);
}

void
dc_audio_playback_change_playback_rate (DcAudioPlayback* self,
                                        gdouble rate)
{
	guint index = 0U;
	gdouble normalized = 0.0;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_;
	void* _tmp3_;
	gboolean _tmp5_ = FALSE;
	GtkMediaFile* _tmp6_;
	g_return_if_fail (self != NULL);
	index = dc_audio_playback_index_for_rate (rate);
	normalized = dc_audio_playback_rate_for_index (index);
	_tmp1_ = self->priv->_can_change_speed;
	if (!_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gdouble _tmp2_;
		_tmp2_ = self->priv->_playback_rate;
		_tmp0_ = fabs (normalized - _tmp2_) < 0.001;
	}
	if (_tmp0_) {
		return;
	}
	_tmp3_ = self->priv->native_backend;
	if (_tmp3_ != NULL) {
		void* _tmp4_;
		dc_audio_playback_set_playback_rate (self, normalized);
		_tmp4_ = self->priv->native_backend;
		dc_platform_audio_backend_set_rate (_tmp4_, normalized);
		return;
	}
	_tmp6_ = self->priv->media;
	if (_tmp6_ != NULL) {
		_tmp5_ = TRUE;
	} else {
		GSubprocess* _tmp7_;
		_tmp7_ = self->priv->proc;
		_tmp5_ = _tmp7_ != NULL;
	}
	if (_tmp5_) {
		GtkMediaFile* _tmp8_;
		gboolean was_playing = FALSE;
		gboolean _tmp10_;
		_tmp8_ = self->priv->media;
		if (_tmp8_ != NULL) {
			GtkMediaFile* _tmp9_;
			_tmp9_ = self->priv->media;
			dc_audio_playback_sync_media_state (self, _tmp9_);
		} else {
			dc_audio_playback_update_external_position (self);
		}
		_tmp10_ = self->priv->_playing;
		was_playing = _tmp10_;
		dc_audio_playback_set_playback_rate (self, normalized);
		dc_audio_playback_stop_backend (self);
		if (was_playing) {
			dc_audio_playback_start_backend (self);
		}
	} else {
		dc_audio_playback_set_playback_rate (self, normalized);
	}
}

static void
dc_audio_playback_pause (DcAudioPlayback* self)
{
	void* _tmp0_;
	GtkMediaFile* _tmp2_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->native_backend;
	if (_tmp0_ != NULL) {
		void* _tmp1_;
		_tmp1_ = self->priv->native_backend;
		dc_platform_audio_backend_pause (_tmp1_);
		dc_audio_playback_sync_native_state (self);
		dc_audio_playback_set_playing (self, FALSE);
		dc_audio_playback_stop_progress_timer (self);
		return;
	}
	_tmp2_ = self->priv->media;
	if (_tmp2_ != NULL) {
		GtkMediaFile* _tmp3_;
		GtkMediaFile* _tmp4_;
		_tmp3_ = self->priv->media;
		gtk_media_stream_pause ((GtkMediaStream*) _tmp3_);
		_tmp4_ = self->priv->media;
		dc_audio_playback_sync_media_state (self, _tmp4_);
		dc_audio_playback_set_playing (self, FALSE);
		dc_audio_playback_stop_progress_timer (self);
		return;
	}
	if (self->priv->proc_pid > ((pid_t) 0)) {
		gint64 _tmp5_;
		dc_audio_playback_update_external_position (self);
		kill (self->priv->proc_pid, (gint) SIGSTOP);
		_tmp5_ = self->priv->_position_us;
		self->priv->external_elapsed_us = _tmp5_;
		self->priv->external_started_us = (gint64) 0;
		self->priv->external_paused = TRUE;
	} else {
		dc_audio_playback_stop_external (self);
	}
	dc_audio_playback_set_playing (self, FALSE);
	dc_audio_playback_stop_progress_timer (self);
}

static void
dc_audio_playback_resume (DcAudioPlayback* self)
{
	void* _tmp0_;
	GtkMediaFile* _tmp2_;
	gboolean _tmp4_ = FALSE;
	GSubprocess* _tmp5_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->native_backend;
	if (_tmp0_ != NULL) {
		void* _tmp1_;
		_tmp1_ = self->priv->native_backend;
		if (dc_platform_audio_backend_play (_tmp1_)) {
			dc_audio_playback_set_playing (self, TRUE);
			dc_audio_playback_ensure_progress_timer (self);
		}
		return;
	}
	_tmp2_ = self->priv->media;
	if (_tmp2_ != NULL) {
		GtkMediaFile* _tmp3_;
		_tmp3_ = self->priv->media;
		gtk_media_stream_play ((GtkMediaStream*) _tmp3_);
		dc_audio_playback_set_playing (self, TRUE);
		dc_audio_playback_ensure_progress_timer (self);
		return;
	}
	_tmp5_ = self->priv->proc;
	if (_tmp5_ != NULL) {
		_tmp4_ = self->priv->external_paused;
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		kill (self->priv->proc_pid, (gint) SIGCONT);
		self->priv->external_started_us = g_get_monotonic_time ();
		self->priv->external_paused = FALSE;
		dc_audio_playback_set_playing (self, TRUE);
		dc_audio_playback_ensure_progress_timer (self);
		return;
	}
	dc_audio_playback_start_backend (self);
}

static void
dc_audio_playback_start_backend (DcAudioPlayback* self)
{
	const gchar* _tmp0_;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean try_native = FALSE;
	gboolean _tmp6_ = FALSE;
	gboolean _tmp8_ = FALSE;
	gboolean _tmp9_ = FALSE;
	gboolean try_external = FALSE;
	gdouble _tmp20_;
	const gchar* _tmp21_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->path;
	if (_tmp0_ == NULL) {
		return;
	}
	if (!self->priv->native_backend_failed) {
		_tmp2_ = dc_platform_audio_backend_supported ();
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		gboolean _tmp3_ = FALSE;
		gboolean _tmp4_ = FALSE;
		if (!dc_audio_player_prefer_system) {
			_tmp4_ = TRUE;
		} else {
			_tmp4_ = dc_platform_is_macos ();
		}
		if (_tmp4_) {
			_tmp3_ = TRUE;
		} else {
			gdouble _tmp5_;
			_tmp5_ = self->priv->_playback_rate;
			_tmp3_ = _tmp5_ != 1.0;
		}
		_tmp1_ = _tmp3_;
	} else {
		_tmp1_ = FALSE;
	}
	try_native = _tmp1_;
	if (try_native) {
		const gchar* _tmp7_;
		_tmp7_ = self->priv->path;
		_tmp6_ = dc_audio_playback_play_native (self, _tmp7_);
	} else {
		_tmp6_ = FALSE;
	}
	if (_tmp6_) {
		return;
	}
	if (dc_audio_player_prefer_system) {
		_tmp9_ = TRUE;
	} else {
		_tmp9_ = dc_platform_is_macos ();
	}
	if (_tmp9_) {
		_tmp8_ = TRUE;
	} else {
		gdouble _tmp10_;
		_tmp10_ = self->priv->_playback_rate;
		_tmp8_ = _tmp10_ != 1.0;
	}
	try_external = _tmp8_;
	if (try_external) {
		gchar** argv = NULL;
		const gchar* _tmp11_;
		gint64 _tmp12_;
		gdouble _tmp13_;
		gint _tmp14_ = 0;
		gchar** _tmp15_;
		gint argv_length1;
		gint _argv_size_;
		gboolean _tmp16_ = FALSE;
		gchar** _tmp17_;
		gint _tmp17__length1;
		_tmp11_ = self->priv->path;
		_tmp12_ = self->priv->_position_us;
		_tmp13_ = self->priv->_playback_rate;
		_tmp15_ = dc_audio_playback_find_external_command (self, _tmp11_, _tmp12_, _tmp13_, &_tmp14_);
		argv = _tmp15_;
		argv_length1 = _tmp14_;
		_argv_size_ = argv_length1;
		_tmp17_ = argv;
		_tmp17__length1 = argv_length1;
		if (_tmp17_ != NULL) {
			gchar** _tmp18_;
			gint _tmp18__length1;
			_tmp18_ = argv;
			_tmp18__length1 = argv_length1;
			_tmp16_ = dc_audio_playback_play_external (self, _tmp18_, (gint) _tmp18__length1);
		} else {
			_tmp16_ = FALSE;
		}
		if (_tmp16_) {
			gint64 _tmp19_;
			dc_audio_playback_set_external_backend (self, TRUE);
			dc_audio_playback_set_playing (self, TRUE);
			dc_audio_playback_set_can_seek (self, FALSE);
			_tmp19_ = self->priv->_position_us;
			self->priv->external_elapsed_us = _tmp19_;
			self->priv->external_started_us = g_get_monotonic_time ();
			self->priv->external_paused = FALSE;
			dc_audio_playback_ensure_progress_timer (self);
			argv = (_vala_array_free (argv, argv_length1, (GDestroyNotify) g_free), NULL);
			return;
		}
		argv = (_vala_array_free (argv, argv_length1, (GDestroyNotify) g_free), NULL);
	}
	_tmp20_ = self->priv->_playback_rate;
	if (_tmp20_ != 1.0) {
		dc_audio_playback_set_playback_rate (self, 1.0);
	}
	dc_audio_playback_set_external_backend (self, FALSE);
	_tmp21_ = self->priv->path;
	dc_audio_playback_play_media (self, _tmp21_);
	dc_audio_playback_set_playing (self, TRUE);
	dc_audio_playback_ensure_progress_timer (self);
}

static void
_dc_audio_playback_on_native_finished_dc_platform_raw_audio_finished_callback (gboolean completed,
                                                                               void* user_data)
{
	dc_audio_playback_on_native_finished (completed, user_data);
}

static gboolean
dc_audio_playback_play_native (DcAudioPlayback* self,
                               const gchar* file_path)
{
	void* _tmp0_;
	void* _tmp1_;
	void* _tmp2_;
	gdouble _tmp3_;
	gint64 _tmp4_;
	void* _tmp7_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (file_path != NULL, FALSE);
	_tmp0_ = dc_platform_audio_backend_new (file_path, _dc_audio_playback_on_native_finished_dc_platform_raw_audio_finished_callback, self);
	self->priv->native_backend = _tmp0_;
	_tmp1_ = self->priv->native_backend;
	if (_tmp1_ == NULL) {
		self->priv->native_backend_failed = TRUE;
		result = FALSE;
		return result;
	}
	_tmp2_ = self->priv->native_backend;
	_tmp3_ = self->priv->_playback_rate;
	dc_platform_audio_backend_set_rate (_tmp2_, _tmp3_);
	_tmp4_ = self->priv->_position_us;
	if (_tmp4_ > ((gint64) 0)) {
		void* _tmp5_;
		gint64 _tmp6_;
		_tmp5_ = self->priv->native_backend;
		_tmp6_ = self->priv->_position_us;
		dc_platform_audio_backend_seek (_tmp5_, _tmp6_);
	}
	_tmp7_ = self->priv->native_backend;
	if (!dc_platform_audio_backend_play (_tmp7_)) {
		void* _tmp8_;
		_tmp8_ = self->priv->native_backend;
		dc_platform_audio_backend_free (_tmp8_);
		self->priv->native_backend = NULL;
		self->priv->native_backend_failed = TRUE;
		result = FALSE;
		return result;
	}
	dc_audio_playback_set_external_backend (self, FALSE);
	dc_audio_playback_set_playing (self, TRUE);
	dc_audio_playback_sync_native_state (self);
	dc_audio_playback_ensure_progress_timer (self);
	result = TRUE;
	return result;
}

static void
dc_audio_playback_on_native_finished (gboolean completed,
                                      void* user_data)
{
	DcAudioPlayback* _self_ = NULL;
	DcAudioPlayback* _tmp0_;
	void* _tmp1_;
	DcAudioPlayback* _tmp2_;
	DcAudioPlayback* _tmp3_;
	void* _tmp4_;
	DcAudioPlayback* _tmp5_;
	DcAudioPlayback* _tmp6_;
	DcAudioPlayback* _tmp7_;
	DcAudioPlayback* _tmp8_;
	_self_ = G_TYPE_CHECK_INSTANCE_CAST (user_data, DC_TYPE_AUDIO_PLAYBACK, DcAudioPlayback);
	_tmp0_ = _self_;
	_tmp1_ = _tmp0_->priv->native_backend;
	if (_tmp1_ == NULL) {
		return;
	}
	_tmp2_ = _self_;
	dc_audio_playback_sync_native_state (_tmp2_);
	_tmp3_ = _self_;
	_tmp4_ = _tmp3_->priv->native_backend;
	dc_platform_audio_backend_free (_tmp4_);
	_tmp5_ = _self_;
	_tmp5_->priv->native_backend = NULL;
	_tmp6_ = _self_;
	dc_audio_playback_stop_progress_timer (_tmp6_);
	_tmp7_ = _self_;
	dc_audio_playback_set_playing (_tmp7_, FALSE);
	_tmp8_ = _self_;
	dc_audio_playback_set_can_seek (_tmp8_, FALSE);
	if (completed) {
		DcAudioPlayback* _tmp9_;
		DcAudioPlayback* _tmp10_;
		DcAudioPlayback* _tmp11_;
		gint _tmp12_;
		_tmp9_ = _self_;
		dc_audio_playback_set_position_us (_tmp9_, (gint64) 0);
		_tmp10_ = _self_;
		_tmp11_ = _self_;
		_tmp12_ = _tmp11_->priv->_current_message_id;
		g_signal_emit (_tmp10_, dc_audio_playback_signals[DC_AUDIO_PLAYBACK_FINISHED_SIGNAL], 0, _tmp12_);
	} else {
		DcAudioPlayback* _tmp13_;
		const gchar* _tmp14_;
		_tmp13_ = _self_;
		_tmp14_ = _tmp13_->priv->path;
		if (_tmp14_ != NULL) {
			DcAudioPlayback* _tmp15_;
			DcAudioPlayback* _tmp16_;
			DcAudioPlayback* _tmp17_;
			_tmp15_ = _self_;
			_tmp15_->priv->native_backend_failed = TRUE;
			_tmp16_ = _self_;
			dc_audio_playback_set_playback_rate (_tmp16_, 1.0);
			_tmp17_ = _self_;
			dc_audio_playback_start_backend (_tmp17_);
		}
	}
}

static void
dc_audio_playback_sync_native_state (DcAudioPlayback* self)
{
	void* _tmp0_;
	void* _tmp1_;
	void* _tmp2_;
	gboolean _tmp3_ = FALSE;
	void* _tmp4_;
	void* _tmp6_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->native_backend;
	if (_tmp0_ == NULL) {
		return;
	}
	_tmp1_ = self->priv->native_backend;
	dc_audio_playback_set_position_us (self, MAX ((gint64) 0, dc_platform_audio_backend_get_position (_tmp1_)));
	_tmp2_ = self->priv->native_backend;
	dc_audio_playback_set_duration_us (self, MAX ((gint64) 0, dc_platform_audio_backend_get_duration (_tmp2_)));
	_tmp4_ = self->priv->native_backend;
	if (dc_platform_audio_backend_can_seek (_tmp4_)) {
		gint64 _tmp5_;
		_tmp5_ = self->priv->_duration_us;
		_tmp3_ = _tmp5_ > ((gint64) 0);
	} else {
		_tmp3_ = FALSE;
	}
	dc_audio_playback_set_can_seek (self, _tmp3_);
	_tmp6_ = self->priv->native_backend;
	dc_audio_playback_set_playing (self, dc_platform_audio_backend_is_playing (_tmp6_));
}

static gboolean
dc_audio_playback_rate_player_available (void)
{
	gboolean _tmp0_ = FALSE;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gboolean _tmp3_;
	gboolean result;
	_tmp1_ = g_find_program_in_path ("mpv");
	_tmp2_ = _tmp1_;
	_tmp3_ = _tmp2_ != NULL;
	_g_free0 (_tmp2_);
	if (_tmp3_) {
		_tmp0_ = TRUE;
	} else {
		gchar* _tmp4_;
		gchar* _tmp5_;
		_tmp4_ = g_find_program_in_path ("ffplay");
		_tmp5_ = _tmp4_;
		_tmp0_ = _tmp5_ != NULL;
		_g_free0 (_tmp5_);
	}
	result = _tmp0_;
	return result;
}

static gchar*
double_to_string (gdouble self)
{
	gchar* _tmp0_;
	gchar* _tmp1_;
	gint _tmp1__length1;
	const gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* result;
	_tmp0_ = g_new0 (gchar, G_ASCII_DTOSTR_BUF_SIZE);
	_tmp1_ = _tmp0_;
	_tmp1__length1 = G_ASCII_DTOSTR_BUF_SIZE;
	_tmp2_ = g_ascii_dtostr (_tmp1_, (gint) G_ASCII_DTOSTR_BUF_SIZE, self);
	_tmp3_ = g_strdup (_tmp2_);
	_tmp4_ = _tmp3_;
	_tmp1_ = (g_free (_tmp1_), NULL);
	result = _tmp4_;
	return result;
}

static gchar**
dc_audio_playback_find_external_command (DcAudioPlayback* self,
                                         const gchar* file_path,
                                         gint64 start_us,
                                         gdouble rate,
                                         gint* result_length1)
{
	gchar* speed = NULL;
	gchar* _tmp0_;
	gchar* start = NULL;
	gchar* _tmp1_;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gboolean _tmp4_;
	gchar* _tmp15_;
	gchar* _tmp16_;
	gboolean _tmp17_;
	gboolean _tmp32_ = FALSE;
	gchar* _tmp34_;
	gchar* _tmp35_;
	gboolean _tmp36_;
	gchar* _tmp41_;
	gchar* _tmp42_;
	gboolean _tmp43_;
	gchar** _tmp49_;
	gint _tmp49__length1;
	gchar** result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (file_path != NULL, NULL);
	_tmp0_ = double_to_string (rate);
	speed = _tmp0_;
	_tmp1_ = double_to_string (((gdouble) MAX ((gint64) 0, start_us)) / 1000000.0);
	start = _tmp1_;
	_tmp2_ = g_find_program_in_path ("mpv");
	_tmp3_ = _tmp2_;
	_tmp4_ = _tmp3_ != NULL;
	_g_free0 (_tmp3_);
	if (_tmp4_) {
		gchar* _tmp5_;
		gchar* _tmp6_;
		gchar* _tmp7_;
		const gchar* _tmp8_;
		gchar* _tmp9_;
		const gchar* _tmp10_;
		gchar* _tmp11_;
		gchar* _tmp12_;
		gchar** _tmp13_;
		gchar** _tmp14_;
		gint _tmp14__length1;
		_tmp5_ = g_strdup ("mpv");
		_tmp6_ = g_strdup ("--no-video");
		_tmp7_ = g_strdup ("--really-quiet");
		_tmp8_ = speed;
		_tmp9_ = g_strconcat ("--speed=", _tmp8_, NULL);
		_tmp10_ = start;
		_tmp11_ = g_strconcat ("--start=", _tmp10_, NULL);
		_tmp12_ = g_strdup (file_path);
		_tmp13_ = g_new0 (gchar*, 6 + 1);
		_tmp13_[0] = _tmp5_;
		_tmp13_[1] = _tmp6_;
		_tmp13_[2] = _tmp7_;
		_tmp13_[3] = _tmp9_;
		_tmp13_[4] = _tmp11_;
		_tmp13_[5] = _tmp12_;
		_tmp14_ = _tmp13_;
		_tmp14__length1 = 6;
		if (result_length1) {
			*result_length1 = _tmp14__length1;
		}
		result = _tmp14_;
		_g_free0 (start);
		_g_free0 (speed);
		return result;
	}
	_tmp15_ = g_find_program_in_path ("ffplay");
	_tmp16_ = _tmp15_;
	_tmp17_ = _tmp16_ != NULL;
	_g_free0 (_tmp16_);
	if (_tmp17_) {
		gchar* _tmp18_;
		gchar* _tmp19_;
		gchar* _tmp20_;
		gchar* _tmp21_;
		gchar* _tmp22_;
		gchar* _tmp23_;
		const gchar* _tmp24_;
		gchar* _tmp25_;
		gchar* _tmp26_;
		const gchar* _tmp27_;
		gchar* _tmp28_;
		gchar* _tmp29_;
		gchar** _tmp30_;
		gchar** _tmp31_;
		gint _tmp31__length1;
		_tmp18_ = g_strdup ("ffplay");
		_tmp19_ = g_strdup ("-nodisp");
		_tmp20_ = g_strdup ("-autoexit");
		_tmp21_ = g_strdup ("-loglevel");
		_tmp22_ = g_strdup ("quiet");
		_tmp23_ = g_strdup ("-ss");
		_tmp24_ = start;
		_tmp25_ = g_strdup (_tmp24_);
		_tmp26_ = g_strdup ("-af");
		_tmp27_ = speed;
		_tmp28_ = g_strconcat ("atempo=", _tmp27_, NULL);
		_tmp29_ = g_strdup (file_path);
		_tmp30_ = g_new0 (gchar*, 10 + 1);
		_tmp30_[0] = _tmp18_;
		_tmp30_[1] = _tmp19_;
		_tmp30_[2] = _tmp20_;
		_tmp30_[3] = _tmp21_;
		_tmp30_[4] = _tmp22_;
		_tmp30_[5] = _tmp23_;
		_tmp30_[6] = _tmp25_;
		_tmp30_[7] = _tmp26_;
		_tmp30_[8] = _tmp28_;
		_tmp30_[9] = _tmp29_;
		_tmp31_ = _tmp30_;
		_tmp31__length1 = 10;
		if (result_length1) {
			*result_length1 = _tmp31__length1;
		}
		result = _tmp31_;
		_g_free0 (start);
		_g_free0 (speed);
		return result;
	}
	if (rate != 1.0) {
		_tmp32_ = TRUE;
	} else {
		_tmp32_ = start_us > ((gint64) 0);
	}
	if (_tmp32_) {
		gchar** _tmp33_;
		gint _tmp33__length1;
		_tmp33_ = NULL;
		_tmp33__length1 = 0;
		if (result_length1) {
			*result_length1 = _tmp33__length1;
		}
		result = _tmp33_;
		_g_free0 (start);
		_g_free0 (speed);
		return result;
	}
	_tmp34_ = g_find_program_in_path ("afplay");
	_tmp35_ = _tmp34_;
	_tmp36_ = _tmp35_ != NULL;
	_g_free0 (_tmp35_);
	if (_tmp36_) {
		gchar* _tmp37_;
		gchar* _tmp38_;
		gchar** _tmp39_;
		gchar** _tmp40_;
		gint _tmp40__length1;
		_tmp37_ = g_strdup ("afplay");
		_tmp38_ = g_strdup (file_path);
		_tmp39_ = g_new0 (gchar*, 2 + 1);
		_tmp39_[0] = _tmp37_;
		_tmp39_[1] = _tmp38_;
		_tmp40_ = _tmp39_;
		_tmp40__length1 = 2;
		if (result_length1) {
			*result_length1 = _tmp40__length1;
		}
		result = _tmp40_;
		_g_free0 (start);
		_g_free0 (speed);
		return result;
	}
	_tmp41_ = g_find_program_in_path ("gst-play-1.0");
	_tmp42_ = _tmp41_;
	_tmp43_ = _tmp42_ != NULL;
	_g_free0 (_tmp42_);
	if (_tmp43_) {
		gchar* _tmp44_;
		gchar* _tmp45_;
		gchar* _tmp46_;
		gchar** _tmp47_;
		gchar** _tmp48_;
		gint _tmp48__length1;
		_tmp44_ = g_strdup ("gst-play-1.0");
		_tmp45_ = g_strdup ("--quiet");
		_tmp46_ = g_strdup (file_path);
		_tmp47_ = g_new0 (gchar*, 3 + 1);
		_tmp47_[0] = _tmp44_;
		_tmp47_[1] = _tmp45_;
		_tmp47_[2] = _tmp46_;
		_tmp48_ = _tmp47_;
		_tmp48__length1 = 3;
		if (result_length1) {
			*result_length1 = _tmp48__length1;
		}
		result = _tmp48_;
		_g_free0 (start);
		_g_free0 (speed);
		return result;
	}
	_tmp49_ = NULL;
	_tmp49__length1 = 0;
	if (result_length1) {
		*result_length1 = _tmp49__length1;
	}
	result = _tmp49_;
	_g_free0 (start);
	_g_free0 (speed);
	return result;
}

static Block29Data*
block29_data_ref (Block29Data* _data29_)
{
	g_atomic_int_inc (&_data29_->_ref_count_);
	return _data29_;
}

static void
block29_data_unref (void * _userdata_)
{
	Block29Data* _data29_;
	_data29_ = (Block29Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data29_->_ref_count_)) {
		DcAudioPlayback* self;
		self = _data29_->self;
		_g_object_unref0 (_data29_->p);
		_g_object_unref0 (self);
		g_slice_free (Block29Data, _data29_);
	}
}

static void
___lambda46_ (Block29Data* _data29_,
              GObject* obj,
              GAsyncResult* res)
{
	DcAudioPlayback* self;
	gboolean completed = FALSE;
	GSubprocess* _tmp0_;
	GError* _inner_error0_ = NULL;
	self = _data29_->self;
	g_return_if_fail (res != NULL);
	completed = FALSE;
	{
		g_subprocess_wait_finish (_data29_->p, res, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		completed = g_subprocess_get_successful (_data29_->p);
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		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;
	}
	_tmp0_ = self->priv->proc;
	if (_tmp0_ == _data29_->p) {
		gboolean _tmp1_ = FALSE;
		_g_object_unref0 (self->priv->proc);
		self->priv->proc = NULL;
		self->priv->proc_pid = (pid_t) 0;
		_g_object_unref0 (self->priv->proc_cancel);
		self->priv->proc_cancel = NULL;
		dc_audio_playback_stop_progress_timer (self);
		dc_audio_playback_set_playing (self, FALSE);
		if (completed) {
			dc_audio_playback_set_position_us (self, (gint64) 0);
		}
		if (completed) {
			gint _tmp2_;
			_tmp2_ = self->priv->_current_message_id;
			_tmp1_ = _tmp2_ == _data29_->played_id;
		} else {
			_tmp1_ = FALSE;
		}
		if (_tmp1_) {
			g_signal_emit (self, dc_audio_playback_signals[DC_AUDIO_PLAYBACK_FINISHED_SIGNAL], 0, _data29_->played_id);
		}
	}
}

static void
____lambda46__gasync_ready_callback (GObject* source_object,
                                     GAsyncResult* res,
                                     gpointer self)
{
	___lambda46_ (self, source_object, res);
	block29_data_unref (self);
}

static gboolean
dc_audio_playback_play_external (DcAudioPlayback* self,
                                 gchar** argv,
                                 gint argv_length1)
{
	gboolean _tmp14_ = FALSE;
	GError* _inner_error0_ = NULL;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	{
		Block29Data* _data29_;
		GSubprocessLauncher* launcher = NULL;
		GSubprocessLauncher* _tmp0_;
		GSubprocess* _tmp1_;
		gint _tmp2_;
		GSubprocess* _tmp3_;
		gchar* pid_str = NULL;
		const gchar* _tmp4_;
		gchar* _tmp5_;
		pid_t _tmp6_ = 0;
		const gchar* _tmp7_;
		GCancellable* _tmp9_;
		GCancellable* _tmp10_;
		_data29_ = g_slice_new0 (Block29Data);
		_data29_->_ref_count_ = 1;
		_data29_->self = g_object_ref (self);
		_tmp0_ = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_SILENCE);
		launcher = _tmp0_;
		_tmp1_ = dc_subprocess_util_spawnv (launcher, argv, (gint) argv_length1, &_inner_error0_);
		_data29_->p = _tmp1_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_object_unref0 (launcher);
			block29_data_unref (_data29_);
			_data29_ = NULL;
			goto __catch0_g_error;
		}
		_tmp2_ = self->priv->_current_message_id;
		_data29_->played_id = _tmp2_;
		_tmp3_ = _g_object_ref0 (_data29_->p);
		_g_object_unref0 (self->priv->proc);
		self->priv->proc = _tmp3_;
		_tmp4_ = g_subprocess_get_identifier (_data29_->p);
		_tmp5_ = g_strdup (_tmp4_);
		pid_str = _tmp5_;
		_tmp7_ = pid_str;
		if (_tmp7_ != NULL) {
			const gchar* _tmp8_;
			_tmp8_ = pid_str;
			_tmp6_ = (pid_t) atoi (_tmp8_);
		} else {
			_tmp6_ = (pid_t) 0;
		}
		self->priv->proc_pid = _tmp6_;
		_tmp9_ = g_cancellable_new ();
		_g_object_unref0 (self->priv->proc_cancel);
		self->priv->proc_cancel = _tmp9_;
		_tmp10_ = self->priv->proc_cancel;
		g_subprocess_wait_async (_data29_->p, _tmp10_, ____lambda46__gasync_ready_callback, block29_data_ref (_data29_));
		result = TRUE;
		_g_free0 (pid_str);
		_g_object_unref0 (launcher);
		block29_data_unref (_data29_);
		_data29_ = NULL;
		return result;
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		const gchar* _tmp11_;
		GError* _tmp12_;
		const gchar* _tmp13_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp11_ = argv[0];
		_tmp12_ = e;
		_tmp13_ = _tmp12_->message;
		g_warning ("audio_player.vala:393: audio: failed to spawn %s: %s", _tmp11_, _tmp13_);
		result = FALSE;
		_g_error_free0 (e);
		return result;
	}
	__finally0:
	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 _tmp14_;
}

static void
dc_audio_playback_play_media (DcAudioPlayback* self,
                              const gchar* file_path)
{
	GtkMediaFile* m = NULL;
	GtkMediaFile* _tmp0_;
	GtkMediaFile* _tmp1_;
	gint64 _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (file_path != NULL);
	_tmp0_ = (GtkMediaFile*) gtk_media_file_new_for_filename (file_path);
	m = _tmp0_;
	_tmp1_ = _g_object_ref0 (m);
	_g_object_unref0 (self->priv->media);
	self->priv->media = _tmp1_;
	_tmp2_ = self->priv->_position_us;
	self->priv->media_seek_pending = _tmp2_ > ((gint64) 0);
	self->priv->media_handler = g_signal_connect_object (m, "notify", (GCallback) dc_audio_playback_on_media_notify, (GObject*) self, (GConnectFlags) 0);
	gtk_media_stream_play ((GtkMediaStream*) m);
	dc_audio_playback_sync_media_state (self, m);
	_g_object_unref0 (m);
}

static void
dc_audio_playback_on_media_notify (GtkMediaFile* m,
                                   GParamSpec* pspec,
                                   DcAudioPlayback* playback)
{
	GtkMediaFile* _tmp0_;
	gboolean _tmp1_ = FALSE;
	const gchar* _tmp2_;
	g_return_if_fail (m != NULL);
	g_return_if_fail (pspec != NULL);
	g_return_if_fail (playback != NULL);
	_tmp0_ = playback->priv->media;
	if (_tmp0_ != m) {
		return;
	}
	dc_audio_playback_sync_media_state (playback, m);
	_tmp2_ = pspec->name;
	if (g_strcmp0 (_tmp2_, "ended") == 0) {
		gboolean _tmp3_;
		gboolean _tmp4_;
		_tmp3_ = gtk_media_stream_get_ended ((GtkMediaStream*) m);
		_tmp4_ = _tmp3_;
		_tmp1_ = _tmp4_;
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		gint _tmp5_;
		dc_audio_playback_set_playing (playback, FALSE);
		dc_audio_playback_set_position_us (playback, (gint64) 0);
		dc_audio_playback_stop_progress_timer (playback);
		_tmp5_ = playback->priv->_current_message_id;
		g_signal_emit (playback, dc_audio_playback_signals[DC_AUDIO_PLAYBACK_FINISHED_SIGNAL], 0, _tmp5_);
	} else {
		gboolean _tmp6_ = FALSE;
		const gchar* _tmp7_;
		_tmp7_ = pspec->name;
		if (g_strcmp0 (_tmp7_, "error") == 0) {
			GError* _tmp8_;
			GError* _tmp9_;
			_tmp8_ = gtk_media_stream_get_error ((GtkMediaStream*) m);
			_tmp9_ = _tmp8_;
			_tmp6_ = _tmp9_ != NULL;
		} else {
			_tmp6_ = FALSE;
		}
		if (_tmp6_) {
			dc_audio_playback_stop_backend (playback);
		}
	}
}

static void
dc_audio_playback_sync_media_state (DcAudioPlayback* self,
                                    GtkMediaFile* m)
{
	gboolean _tmp0_ = FALSE;
	gint64 _tmp4_;
	gint64 _tmp5_;
	gint64 _tmp6_;
	gint64 _tmp7_;
	gboolean _tmp8_ = FALSE;
	gboolean _tmp9_;
	gboolean _tmp10_;
	gboolean _tmp12_ = FALSE;
	gboolean _tmp13_;
	gboolean _tmp14_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (m != NULL);
	if (self->priv->media_seek_pending) {
		gboolean _tmp1_;
		gboolean _tmp2_;
		g_object_get ((GtkMediaStream*) m, "prepared", &_tmp1_, NULL);
		_tmp2_ = _tmp1_;
		_tmp0_ = _tmp2_;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gint64 _tmp3_;
		self->priv->media_seek_pending = FALSE;
		_tmp3_ = self->priv->_position_us;
		gtk_media_stream_seek ((GtkMediaStream*) m, _tmp3_);
	}
	_tmp4_ = gtk_media_stream_get_timestamp ((GtkMediaStream*) m);
	_tmp5_ = _tmp4_;
	dc_audio_playback_set_position_us (self, MAX ((gint64) 0, _tmp5_));
	_tmp6_ = gtk_media_stream_get_duration ((GtkMediaStream*) m);
	_tmp7_ = _tmp6_;
	dc_audio_playback_set_duration_us (self, MAX ((gint64) 0, _tmp7_));
	g_object_get ((GtkMediaStream*) m, "seekable", &_tmp9_, NULL);
	_tmp10_ = _tmp9_;
	if (_tmp10_) {
		gint64 _tmp11_;
		_tmp11_ = self->priv->_duration_us;
		_tmp8_ = _tmp11_ > ((gint64) 0);
	} else {
		_tmp8_ = FALSE;
	}
	dc_audio_playback_set_can_seek (self, _tmp8_);
	_tmp13_ = gtk_media_stream_get_playing ((GtkMediaStream*) m);
	_tmp14_ = _tmp13_;
	if (_tmp14_) {
		gboolean _tmp15_;
		gboolean _tmp16_;
		_tmp15_ = gtk_media_stream_get_ended ((GtkMediaStream*) m);
		_tmp16_ = _tmp15_;
		_tmp12_ = !_tmp16_;
	} else {
		_tmp12_ = FALSE;
	}
	dc_audio_playback_set_playing (self, _tmp12_);
}

static gboolean
__lambda45_ (DcAudioPlayback* self)
{
	gboolean _tmp0_;
	void* _tmp1_;
	gboolean result;
	_tmp0_ = self->priv->_playing;
	if (!_tmp0_) {
		self->priv->progress_timer = (guint) 0;
		result = G_SOURCE_REMOVE;
		return result;
	}
	_tmp1_ = self->priv->native_backend;
	if (_tmp1_ != NULL) {
		dc_audio_playback_sync_native_state (self);
	} else {
		GtkMediaFile* _tmp2_;
		_tmp2_ = self->priv->media;
		if (_tmp2_ != NULL) {
			GtkMediaFile* _tmp3_;
			_tmp3_ = self->priv->media;
			dc_audio_playback_sync_media_state (self, _tmp3_);
		} else {
			gboolean _tmp4_ = FALSE;
			GSubprocess* _tmp5_;
			_tmp5_ = self->priv->proc;
			if (_tmp5_ != NULL) {
				_tmp4_ = self->priv->external_started_us > ((gint64) 0);
			} else {
				_tmp4_ = FALSE;
			}
			if (_tmp4_) {
				dc_audio_playback_update_external_position (self);
			}
		}
	}
	result = G_SOURCE_CONTINUE;
	return result;
}

static gboolean
___lambda45__gsource_func (gpointer self)
{
	gboolean result;
	result = __lambda45_ ((DcAudioPlayback*) self);
	return result;
}

static void
dc_audio_playback_ensure_progress_timer (DcAudioPlayback* self)
{
	g_return_if_fail (self != NULL);
	if (self->priv->progress_timer != ((guint) 0)) {
		return;
	}
	self->priv->progress_timer = g_timeout_add_full (G_PRIORITY_DEFAULT, (guint) 250, ___lambda45__gsource_func, g_object_ref (self), g_object_unref);
}

static void
dc_audio_playback_stop_progress_timer (DcAudioPlayback* self)
{
	g_return_if_fail (self != NULL);
	if (self->priv->progress_timer == ((guint) 0)) {
		return;
	}
	g_source_remove (self->priv->progress_timer);
	self->priv->progress_timer = (guint) 0;
}

static void
dc_audio_playback_stop_backend (DcAudioPlayback* self)
{
	void* _tmp0_;
	GtkMediaFile* _tmp3_;
	g_return_if_fail (self != NULL);
	dc_audio_playback_stop_progress_timer (self);
	dc_audio_playback_stop_external (self);
	_tmp0_ = self->priv->native_backend;
	if (_tmp0_ != NULL) {
		void* _tmp1_;
		void* _tmp2_;
		_tmp1_ = self->priv->native_backend;
		dc_platform_audio_backend_stop (_tmp1_);
		_tmp2_ = self->priv->native_backend;
		dc_platform_audio_backend_free (_tmp2_);
		self->priv->native_backend = NULL;
	}
	_tmp3_ = self->priv->media;
	if (_tmp3_ != NULL) {
		GtkMediaFile* _tmp5_;
		if (self->priv->media_handler != ((gulong) 0)) {
			GtkMediaFile* _tmp4_;
			_tmp4_ = self->priv->media;
			g_signal_handler_disconnect ((GObject*) _tmp4_, self->priv->media_handler);
		}
		self->priv->media_handler = (gulong) 0;
		_tmp5_ = self->priv->media;
		gtk_media_stream_pause ((GtkMediaStream*) _tmp5_);
		_g_object_unref0 (self->priv->media);
		self->priv->media = NULL;
	}
	self->priv->media_seek_pending = FALSE;
	dc_audio_playback_set_playing (self, FALSE);
	dc_audio_playback_set_can_seek (self, FALSE);
	dc_audio_playback_set_external_backend (self, FALSE);
}

static void
dc_audio_playback_update_external_position (DcAudioPlayback* self)
{
	gdouble _tmp0_;
	g_return_if_fail (self != NULL);
	if (self->priv->external_started_us <= ((gint64) 0)) {
		return;
	}
	_tmp0_ = self->priv->_playback_rate;
	dc_audio_playback_set_position_us (self, self->priv->external_elapsed_us + ((gint64) ((g_get_monotonic_time () - self->priv->external_started_us) * _tmp0_)));
}

static void
dc_audio_playback_stop_external (DcAudioPlayback* self)
{
	GCancellable* _tmp0_;
	g_return_if_fail (self != NULL);
	_g_object_unref0 (self->priv->proc);
	self->priv->proc = NULL;
	if (self->priv->proc_pid > ((pid_t) 0)) {
		kill (self->priv->proc_pid, (gint) SIGTERM);
		kill (self->priv->proc_pid, (gint) SIGKILL);
		self->priv->proc_pid = (pid_t) 0;
	}
	_tmp0_ = self->priv->proc_cancel;
	if (_tmp0_ != NULL) {
		GCancellable* _tmp1_;
		_tmp1_ = self->priv->proc_cancel;
		g_cancellable_cancel (_tmp1_);
		_g_object_unref0 (self->priv->proc_cancel);
		self->priv->proc_cancel = NULL;
	}
	self->priv->external_started_us = (gint64) 0;
	self->priv->external_elapsed_us = (gint64) 0;
	self->priv->external_paused = FALSE;
}

DcAudioPlaybackItem*
dc_audio_playback_get_current_item (DcAudioPlayback* self)
{
	DcAudioPlaybackItem* result;
	DcAudioPlaybackItem* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_current_item;
	result = _tmp0_;
	return result;
}

static void
dc_audio_playback_set_current_item (DcAudioPlayback* self,
                                    DcAudioPlaybackItem* value)
{
	DcAudioPlaybackItem* old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_get_current_item (self);
	if (old_value != value) {
		DcAudioPlaybackItem* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_current_item);
		self->priv->_current_item = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_CURRENT_ITEM_PROPERTY]);
	}
}

gint
dc_audio_playback_get_current_message_id (DcAudioPlayback* self)
{
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	result = self->priv->_current_message_id;
	return result;
}

static void
dc_audio_playback_set_current_message_id (DcAudioPlayback* self,
                                          gint value)
{
	gint old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_get_current_message_id (self);
	if (old_value != value) {
		self->priv->_current_message_id = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_CURRENT_MESSAGE_ID_PROPERTY]);
	}
}

gboolean
dc_audio_playback_get_playing (DcAudioPlayback* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_playing;
	return result;
}

static void
dc_audio_playback_set_playing (DcAudioPlayback* self,
                               gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_get_playing (self);
	if (old_value != value) {
		self->priv->_playing = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_PLAYING_PROPERTY]);
	}
}

gboolean
dc_audio_playback_get_can_seek (DcAudioPlayback* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_can_seek;
	return result;
}

static void
dc_audio_playback_set_can_seek (DcAudioPlayback* self,
                                gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_get_can_seek (self);
	if (old_value != value) {
		self->priv->_can_seek = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_CAN_SEEK_PROPERTY]);
	}
}

gboolean
dc_audio_playback_get_external_backend (DcAudioPlayback* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_external_backend;
	return result;
}

static void
dc_audio_playback_set_external_backend (DcAudioPlayback* self,
                                        gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_get_external_backend (self);
	if (old_value != value) {
		self->priv->_external_backend = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_EXTERNAL_BACKEND_PROPERTY]);
	}
}

gboolean
dc_audio_playback_get_has_previous (DcAudioPlayback* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_has_previous;
	return result;
}

static void
dc_audio_playback_set_has_previous (DcAudioPlayback* self,
                                    gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_get_has_previous (self);
	if (old_value != value) {
		self->priv->_has_previous = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_HAS_PREVIOUS_PROPERTY]);
	}
}

gboolean
dc_audio_playback_get_has_next (DcAudioPlayback* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_has_next;
	return result;
}

static void
dc_audio_playback_set_has_next (DcAudioPlayback* self,
                                gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_get_has_next (self);
	if (old_value != value) {
		self->priv->_has_next = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_HAS_NEXT_PROPERTY]);
	}
}

gint64
dc_audio_playback_get_position_us (DcAudioPlayback* self)
{
	gint64 result;
	g_return_val_if_fail (self != NULL, -1LL);
	result = self->priv->_position_us;
	return result;
}

static void
dc_audio_playback_set_position_us (DcAudioPlayback* self,
                                   gint64 value)
{
	gint64 old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_get_position_us (self);
	if (old_value != value) {
		self->priv->_position_us = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_POSITION_US_PROPERTY]);
	}
}

gint64
dc_audio_playback_get_duration_us (DcAudioPlayback* self)
{
	gint64 result;
	g_return_val_if_fail (self != NULL, -1LL);
	result = self->priv->_duration_us;
	return result;
}

static void
dc_audio_playback_set_duration_us (DcAudioPlayback* self,
                                   gint64 value)
{
	gint64 old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_get_duration_us (self);
	if (old_value != value) {
		self->priv->_duration_us = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_DURATION_US_PROPERTY]);
	}
}

gdouble
dc_audio_playback_get_playback_rate (DcAudioPlayback* self)
{
	gdouble result;
	g_return_val_if_fail (self != NULL, -1.0);
	result = self->priv->_playback_rate;
	return result;
}

static void
dc_audio_playback_set_playback_rate (DcAudioPlayback* self,
                                     gdouble value)
{
	gdouble old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_get_playback_rate (self);
	if (old_value != value) {
		self->priv->_playback_rate = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_PLAYBACK_RATE_PROPERTY]);
	}
}

gboolean
dc_audio_playback_get_can_change_speed (DcAudioPlayback* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_can_change_speed;
	return result;
}

static void
dc_audio_playback_set_can_change_speed (DcAudioPlayback* self,
                                        gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = dc_audio_playback_get_can_change_speed (self);
	if (old_value != value) {
		self->priv->_can_change_speed = value;
		g_object_notify_by_pspec ((GObject *) self, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_CAN_CHANGE_SPEED_PROPERTY]);
	}
}

static void
dc_audio_playback_class_init (DcAudioPlaybackClass * klass,
                              gpointer klass_data)
{
	dc_audio_playback_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &DcAudioPlayback_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_dc_audio_playback_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_dc_audio_playback_set_property;
	G_OBJECT_CLASS (klass)->finalize = dc_audio_playback_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_CURRENT_ITEM_PROPERTY, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_CURRENT_ITEM_PROPERTY] = g_param_spec_object ("current-item", "current-item", "current-item", DC_TYPE_AUDIO_PLAYBACK_ITEM, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_CURRENT_MESSAGE_ID_PROPERTY, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_CURRENT_MESSAGE_ID_PROPERTY] = g_param_spec_int ("current-message-id", "current-message-id", "current-message-id", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_PLAYING_PROPERTY, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_PLAYING_PROPERTY] = g_param_spec_boolean ("playing", "playing", "playing", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_CAN_SEEK_PROPERTY, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_CAN_SEEK_PROPERTY] = g_param_spec_boolean ("can-seek", "can-seek", "can-seek", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_EXTERNAL_BACKEND_PROPERTY, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_EXTERNAL_BACKEND_PROPERTY] = g_param_spec_boolean ("external-backend", "external-backend", "external-backend", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_HAS_PREVIOUS_PROPERTY, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_HAS_PREVIOUS_PROPERTY] = g_param_spec_boolean ("has-previous", "has-previous", "has-previous", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_HAS_NEXT_PROPERTY, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_HAS_NEXT_PROPERTY] = g_param_spec_boolean ("has-next", "has-next", "has-next", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_POSITION_US_PROPERTY, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_POSITION_US_PROPERTY] = g_param_spec_int64 ("position-us", "position-us", "position-us", G_MININT64, G_MAXINT64, (gint64) 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_DURATION_US_PROPERTY, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_DURATION_US_PROPERTY] = g_param_spec_int64 ("duration-us", "duration-us", "duration-us", G_MININT64, G_MAXINT64, (gint64) 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_PLAYBACK_RATE_PROPERTY, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_PLAYBACK_RATE_PROPERTY] = g_param_spec_double ("playback-rate", "playback-rate", "playback-rate", -G_MAXDOUBLE, G_MAXDOUBLE, 1.0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), DC_AUDIO_PLAYBACK_CAN_CHANGE_SPEED_PROPERTY, dc_audio_playback_properties[DC_AUDIO_PLAYBACK_CAN_CHANGE_SPEED_PROPERTY] = g_param_spec_boolean ("can-change-speed", "can-change-speed", "can-change-speed", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	dc_audio_playback_signals[DC_AUDIO_PLAYBACK_FINISHED_SIGNAL] = g_signal_new ("finished", DC_TYPE_AUDIO_PLAYBACK, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
}

static void
dc_audio_playback_instance_init (DcAudioPlayback * self,
                                 gpointer klass)
{
	self->priv = dc_audio_playback_get_instance_private (self);
	self->priv->_current_item = NULL;
	self->priv->_current_message_id = 0;
	self->priv->_playing = FALSE;
	self->priv->_can_seek = FALSE;
	self->priv->_external_backend = FALSE;
	self->priv->_has_previous = FALSE;
	self->priv->_has_next = FALSE;
	self->priv->_position_us = (gint64) 0;
	self->priv->_duration_us = (gint64) 0;
	self->priv->_playback_rate = 1.0;
	self->priv->_can_change_speed = FALSE;
	self->priv->path = NULL;
	self->priv->native_backend = NULL;
	self->priv->native_backend_failed = FALSE;
	self->priv->media = NULL;
	self->priv->media_handler = (gulong) 0;
	self->priv->media_seek_pending = FALSE;
	self->priv->proc = NULL;
	self->priv->proc_pid = (pid_t) 0;
	self->priv->proc_cancel = NULL;
	self->priv->progress_timer = (guint) 0;
	self->priv->external_started_us = (gint64) 0;
	self->priv->external_elapsed_us = (gint64) 0;
	self->priv->external_paused = FALSE;
}

static void
dc_audio_playback_finalize (GObject * obj)
{
	DcAudioPlayback * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_TYPE_AUDIO_PLAYBACK, DcAudioPlayback);
	_g_object_unref0 (self->priv->_current_item);
	_g_free0 (self->priv->path);
	_g_object_unref0 (self->priv->media);
	_g_object_unref0 (self->priv->proc);
	_g_object_unref0 (self->priv->proc_cancel);
	G_OBJECT_CLASS (dc_audio_playback_parent_class)->finalize (obj);
}

/**
     * Application-wide voice-message playback session. Inline players and the
     * conversation media bar both control this object, so row recycling does
     * not interrupt playback or lose the current position.
     */
static GType
dc_audio_playback_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (DcAudioPlaybackClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_audio_playback_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcAudioPlayback), 0, (GInstanceInitFunc) dc_audio_playback_instance_init, NULL };
	GType dc_audio_playback_type_id;
	dc_audio_playback_type_id = g_type_register_static (G_TYPE_OBJECT, "DcAudioPlayback", &g_define_type_info, 0);
	DcAudioPlayback_private_offset = g_type_add_instance_private (dc_audio_playback_type_id, sizeof (DcAudioPlaybackPrivate));
	return dc_audio_playback_type_id;
}

GType
dc_audio_playback_get_type (void)
{
	static volatile gsize dc_audio_playback_type_id__once = 0;
	if (g_once_init_enter (&dc_audio_playback_type_id__once)) {
		GType dc_audio_playback_type_id;
		dc_audio_playback_type_id = dc_audio_playback_get_type_once ();
		g_once_init_leave (&dc_audio_playback_type_id__once, dc_audio_playback_type_id);
	}
	return dc_audio_playback_type_id__once;
}

static void
_vala_dc_audio_playback_get_property (GObject * object,
                                      guint property_id,
                                      GValue * value,
                                      GParamSpec * pspec)
{
	DcAudioPlayback * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, DC_TYPE_AUDIO_PLAYBACK, DcAudioPlayback);
	switch (property_id) {
		case DC_AUDIO_PLAYBACK_CURRENT_ITEM_PROPERTY:
		g_value_set_object (value, dc_audio_playback_get_current_item (self));
		break;
		case DC_AUDIO_PLAYBACK_CURRENT_MESSAGE_ID_PROPERTY:
		g_value_set_int (value, dc_audio_playback_get_current_message_id (self));
		break;
		case DC_AUDIO_PLAYBACK_PLAYING_PROPERTY:
		g_value_set_boolean (value, dc_audio_playback_get_playing (self));
		break;
		case DC_AUDIO_PLAYBACK_CAN_SEEK_PROPERTY:
		g_value_set_boolean (value, dc_audio_playback_get_can_seek (self));
		break;
		case DC_AUDIO_PLAYBACK_EXTERNAL_BACKEND_PROPERTY:
		g_value_set_boolean (value, dc_audio_playback_get_external_backend (self));
		break;
		case DC_AUDIO_PLAYBACK_HAS_PREVIOUS_PROPERTY:
		g_value_set_boolean (value, dc_audio_playback_get_has_previous (self));
		break;
		case DC_AUDIO_PLAYBACK_HAS_NEXT_PROPERTY:
		g_value_set_boolean (value, dc_audio_playback_get_has_next (self));
		break;
		case DC_AUDIO_PLAYBACK_POSITION_US_PROPERTY:
		g_value_set_int64 (value, dc_audio_playback_get_position_us (self));
		break;
		case DC_AUDIO_PLAYBACK_DURATION_US_PROPERTY:
		g_value_set_int64 (value, dc_audio_playback_get_duration_us (self));
		break;
		case DC_AUDIO_PLAYBACK_PLAYBACK_RATE_PROPERTY:
		g_value_set_double (value, dc_audio_playback_get_playback_rate (self));
		break;
		case DC_AUDIO_PLAYBACK_CAN_CHANGE_SPEED_PROPERTY:
		g_value_set_boolean (value, dc_audio_playback_get_can_change_speed (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_dc_audio_playback_set_property (GObject * object,
                                      guint property_id,
                                      const GValue * value,
                                      GParamSpec * pspec)
{
	DcAudioPlayback * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, DC_TYPE_AUDIO_PLAYBACK, DcAudioPlayback);
	switch (property_id) {
		case DC_AUDIO_PLAYBACK_CURRENT_ITEM_PROPERTY:
		dc_audio_playback_set_current_item (self, g_value_get_object (value));
		break;
		case DC_AUDIO_PLAYBACK_CURRENT_MESSAGE_ID_PROPERTY:
		dc_audio_playback_set_current_message_id (self, g_value_get_int (value));
		break;
		case DC_AUDIO_PLAYBACK_PLAYING_PROPERTY:
		dc_audio_playback_set_playing (self, g_value_get_boolean (value));
		break;
		case DC_AUDIO_PLAYBACK_CAN_SEEK_PROPERTY:
		dc_audio_playback_set_can_seek (self, g_value_get_boolean (value));
		break;
		case DC_AUDIO_PLAYBACK_EXTERNAL_BACKEND_PROPERTY:
		dc_audio_playback_set_external_backend (self, g_value_get_boolean (value));
		break;
		case DC_AUDIO_PLAYBACK_HAS_PREVIOUS_PROPERTY:
		dc_audio_playback_set_has_previous (self, g_value_get_boolean (value));
		break;
		case DC_AUDIO_PLAYBACK_HAS_NEXT_PROPERTY:
		dc_audio_playback_set_has_next (self, g_value_get_boolean (value));
		break;
		case DC_AUDIO_PLAYBACK_POSITION_US_PROPERTY:
		dc_audio_playback_set_position_us (self, g_value_get_int64 (value));
		break;
		case DC_AUDIO_PLAYBACK_DURATION_US_PROPERTY:
		dc_audio_playback_set_duration_us (self, g_value_get_int64 (value));
		break;
		case DC_AUDIO_PLAYBACK_PLAYBACK_RATE_PROPERTY:
		dc_audio_playback_set_playback_rate (self, g_value_get_double (value));
		break;
		case DC_AUDIO_PLAYBACK_CAN_CHANGE_SPEED_PROPERTY:
		dc_audio_playback_set_can_change_speed (self, g_value_get_boolean (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
dc_audio_player_get_instance_private (DcAudioPlayer* self)
{
	return G_STRUCT_MEMBER_P (self, DcAudioPlayer_private_offset);
}

static Block30Data*
block30_data_ref (Block30Data* _data30_)
{
	g_atomic_int_inc (&_data30_->_ref_count_);
	return _data30_;
}

static void
block30_data_unref (void * _userdata_)
{
	Block30Data* _data30_;
	_data30_ = (Block30Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data30_->_ref_count_)) {
		DcAudioPlayer* self;
		self = _data30_->self;
		_g_object_unref0 (_data30_->message);
		_g_object_unref0 (self);
		g_slice_free (Block30Data, _data30_);
	}
}

static void
__lambda437_ (Block30Data* _data30_)
{
	DcAudioPlayer* self;
	self = _data30_->self;
	if (dc_audio_player_is_current_message (self)) {
		DcAudioPlayback* _tmp0_;
		_tmp0_ = self->priv->playback;
		dc_audio_playback_toggle (_tmp0_);
	} else {
		DcAudioPlayback* _tmp1_;
		_tmp1_ = self->priv->playback;
		dc_audio_playback_play_message (_tmp1_, _data30_->message, _data30_->account_id);
	}
}

static void
___lambda437__gtk_button_clicked (GtkButton* _sender,
                                  gpointer self)
{
	__lambda437_ (self);
}

static void
___lambda438_ (Block30Data* _data30_)
{
	DcAudioPlayer* self;
	DcTranscriber* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	self = _data30_->self;
	_tmp0_ = self->priv->transcriber;
	_tmp1_ = dc_message_get_file_path (_data30_->message);
	_tmp2_ = _tmp1_;
	dc_transcriber_transcribe (_tmp0_, _tmp2_);
}

static void
____lambda438__gtk_button_clicked (GtkButton* _sender,
                                   gpointer self)
{
	___lambda438_ (self);
}

static void
_dc_audio_player_update_visuals_g_object_notify (GObject* _sender,
                                                 GParamSpec* pspec,
                                                 gpointer self)
{
	dc_audio_player_update_visuals ((DcAudioPlayer*) self);
}

static void
__lambda439_ (Block30Data* _data30_,
              const gchar* path)
{
	DcAudioPlayer* self;
	const gchar* _tmp0_;
	const gchar* _tmp1_;
	self = _data30_->self;
	g_return_if_fail (path != NULL);
	_tmp0_ = dc_message_get_file_path (_data30_->message);
	_tmp1_ = _tmp0_;
	if (g_strcmp0 (path, _tmp1_) == 0) {
		dc_audio_player_update_transcription (self);
	}
}

static void
___lambda439__dc_transcriber_updated (DcTranscriber* _sender,
                                      const gchar* path,
                                      gpointer self)
{
	__lambda439_ (self, path);
}

DcAudioPlayer*
dc_audio_player_construct (GType object_type,
                           DcMessage* message,
                           gint account_id)
{
	DcAudioPlayer * self = NULL;
	Block30Data* _data30_;
	DcMessage* _tmp0_;
	DcMessage* _tmp1_;
	DcAudioPlayback* _tmp2_;
	DcTranscriber* _tmp3_;
	GtkBox* row = NULL;
	GtkBox* _tmp4_;
	GtkButton* _tmp5_;
	GtkButton* _tmp6_;
	GtkButton* _tmp7_;
	GtkButton* _tmp8_;
	GtkBox* _tmp9_;
	GtkButton* _tmp10_;
	gchar* _tmp11_ = NULL;
	gint _tmp12_;
	gint _tmp13_;
	gchar* size = NULL;
	gchar* _tmp20_;
	GtkLabel* label = NULL;
	const gchar* _tmp21_;
	gchar* _tmp22_;
	gchar* _tmp23_;
	GtkLabel* _tmp24_;
	GtkLabel* _tmp25_;
	GtkLabel* _tmp26_;
	GtkLabel* _tmp27_;
	GtkLabel* _tmp28_;
	GtkBox* _tmp29_;
	GtkLabel* _tmp30_;
	gboolean _tmp31_ = FALSE;
	GtkBox* _tmp42_;
	GtkLabel* _tmp43_;
	GtkLabel* _tmp44_;
	GtkLabel* _tmp45_;
	GtkLabel* _tmp46_;
	GtkLabel* _tmp47_;
	GtkLabel* _tmp48_;
	GtkLabel* _tmp49_;
	GtkLabel* _tmp50_;
	GtkLabel* _tmp51_;
	GtkLabel* _tmp52_;
	DcAudioPlayback* _tmp53_;
	gulong _tmp54_;
	DcAudioPlayback* _tmp55_;
	gulong _tmp56_;
	DcTranscriber* _tmp57_;
	gulong _tmp58_;
	g_return_val_if_fail (message != NULL, NULL);
	_data30_ = g_slice_new0 (Block30Data);
	_data30_->_ref_count_ = 1;
	_tmp0_ = _g_object_ref0 (message);
	_g_object_unref0 (_data30_->message);
	_data30_->message = _tmp0_;
	_data30_->account_id = account_id;
	self = (DcAudioPlayer*) g_object_new (object_type, "orientation", GTK_ORIENTATION_VERTICAL, "spacing", 2, NULL);
	_data30_->self = g_object_ref (self);
	_tmp1_ = _g_object_ref0 (_data30_->message);
	_g_object_unref0 (self->priv->message);
	self->priv->message = _tmp1_;
	self->priv->account_id = _data30_->account_id;
	_tmp2_ = dc_audio_playback_shared ();
	_g_object_unref0 (self->priv->playback);
	self->priv->playback = _tmp2_;
	_tmp3_ = dc_transcriber_shared ();
	_g_object_unref0 (self->priv->transcriber);
	self->priv->transcriber = _tmp3_;
	gtk_widget_add_css_class ((GtkWidget*) self, "message-audio");
	gtk_widget_set_halign ((GtkWidget*) self, GTK_ALIGN_START);
	_tmp4_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
	g_object_ref_sink (_tmp4_);
	row = _tmp4_;
	_tmp5_ = (GtkButton*) gtk_button_new_from_icon_name ("media-playback-start-symbolic");
	g_object_ref_sink (_tmp5_);
	_g_object_unref0 (self->priv->btn);
	self->priv->btn = _tmp5_;
	_tmp6_ = self->priv->btn;
	gtk_widget_add_css_class ((GtkWidget*) _tmp6_, "circular");
	_tmp7_ = self->priv->btn;
	gtk_widget_set_valign ((GtkWidget*) _tmp7_, GTK_ALIGN_CENTER);
	_tmp8_ = self->priv->btn;
	g_signal_connect_data (_tmp8_, "clicked", (GCallback) ___lambda437__gtk_button_clicked, block30_data_ref (_data30_), (GClosureNotify) block30_data_unref, 0);
	_tmp9_ = row;
	_tmp10_ = self->priv->btn;
	gtk_box_append (_tmp9_, (GtkWidget*) _tmp10_);
	_tmp12_ = dc_message_get_file_bytes (_data30_->message);
	_tmp13_ = _tmp12_;
	if (_tmp13_ > 0) {
		gint _tmp14_;
		gint _tmp15_;
		gchar* _tmp16_;
		gchar* _tmp17_;
		gchar* _tmp18_;
		_tmp14_ = dc_message_get_file_bytes (_data30_->message);
		_tmp15_ = _tmp14_;
		_tmp16_ = g_format_size_full ((guint64) _tmp15_, G_FORMAT_SIZE_DEFAULT);
		_tmp17_ = _tmp16_;
		_tmp18_ = g_strdup_printf (" (%s)", _tmp17_);
		_g_free0 (_tmp11_);
		_tmp11_ = _tmp18_;
		_g_free0 (_tmp17_);
	} else {
		gchar* _tmp19_;
		_tmp19_ = g_strdup ("");
		_g_free0 (_tmp11_);
		_tmp11_ = _tmp19_;
	}
	_tmp20_ = _tmp11_;
	_tmp11_ = NULL;
	size = _tmp20_;
	_tmp21_ = size;
	_tmp22_ = g_strconcat ("Voice Message", _tmp21_, NULL);
	_tmp23_ = _tmp22_;
	_tmp24_ = (GtkLabel*) gtk_label_new (_tmp23_);
	g_object_ref_sink (_tmp24_);
	_tmp25_ = _tmp24_;
	_g_free0 (_tmp23_);
	label = _tmp25_;
	_tmp26_ = label;
	gtk_widget_add_css_class ((GtkWidget*) _tmp26_, "message-audio-name");
	_tmp27_ = label;
	gtk_label_set_xalign (_tmp27_, (gfloat) 0);
	_tmp28_ = label;
	gtk_widget_set_valign ((GtkWidget*) _tmp28_, GTK_ALIGN_CENTER);
	_tmp29_ = row;
	_tmp30_ = label;
	gtk_box_append (_tmp29_, (GtkWidget*) _tmp30_);
	if (dc_transcriber_available ()) {
		gboolean _tmp32_;
		gboolean _tmp33_;
		_tmp32_ = dc_message_get_has_local_file (_data30_->message);
		_tmp33_ = _tmp32_;
		_tmp31_ = _tmp33_;
	} else {
		_tmp31_ = FALSE;
	}
	if (_tmp31_) {
		GtkButton* _tmp34_;
		GtkButton* _tmp35_;
		GtkButton* _tmp36_;
		GtkButton* _tmp37_;
		GtkButton* _tmp38_;
		GtkButton* _tmp39_;
		GtkBox* _tmp40_;
		GtkButton* _tmp41_;
		_tmp34_ = (GtkButton*) gtk_button_new_with_label ("A");
		g_object_ref_sink (_tmp34_);
		_g_object_unref0 (self->priv->transcribe_btn);
		self->priv->transcribe_btn = _tmp34_;
		_tmp35_ = self->priv->transcribe_btn;
		gtk_widget_add_css_class ((GtkWidget*) _tmp35_, "flat");
		_tmp36_ = self->priv->transcribe_btn;
		gtk_widget_add_css_class ((GtkWidget*) _tmp36_, "message-transcribe-button");
		_tmp37_ = self->priv->transcribe_btn;
		gtk_widget_set_valign ((GtkWidget*) _tmp37_, GTK_ALIGN_CENTER);
		_tmp38_ = self->priv->transcribe_btn;
		gtk_widget_set_tooltip_text ((GtkWidget*) _tmp38_, "Transcribe voice message");
		_tmp39_ = self->priv->transcribe_btn;
		g_signal_connect_data (_tmp39_, "clicked", (GCallback) ____lambda438__gtk_button_clicked, block30_data_ref (_data30_), (GClosureNotify) block30_data_unref, 0);
		_tmp40_ = row;
		_tmp41_ = self->priv->transcribe_btn;
		gtk_box_append (_tmp40_, (GtkWidget*) _tmp41_);
	}
	_tmp42_ = row;
	gtk_box_append ((GtkBox*) self, (GtkWidget*) _tmp42_);
	_tmp43_ = (GtkLabel*) gtk_label_new ("");
	g_object_ref_sink (_tmp43_);
	_g_object_unref0 (self->priv->transcription_label);
	self->priv->transcription_label = _tmp43_;
	_tmp44_ = self->priv->transcription_label;
	gtk_widget_add_css_class ((GtkWidget*) _tmp44_, "message-transcription");
	_tmp45_ = self->priv->transcription_label;
	gtk_widget_set_visible ((GtkWidget*) _tmp45_, FALSE);
	_tmp46_ = self->priv->transcription_label;
	gtk_label_set_wrap (_tmp46_, TRUE);
	_tmp47_ = self->priv->transcription_label;
	gtk_label_set_wrap_mode (_tmp47_, PANGO_WRAP_WORD_CHAR);
	_tmp48_ = self->priv->transcription_label;
	gtk_label_set_max_width_chars (_tmp48_, 42);
	_tmp49_ = self->priv->transcription_label;
	gtk_label_set_xalign (_tmp49_, (gfloat) 0);
	_tmp50_ = self->priv->transcription_label;
	gtk_widget_set_halign ((GtkWidget*) _tmp50_, GTK_ALIGN_START);
	_tmp51_ = self->priv->transcription_label;
	gtk_label_set_selectable (_tmp51_, TRUE);
	_tmp52_ = self->priv->transcription_label;
	gtk_box_append ((GtkBox*) self, (GtkWidget*) _tmp52_);
	_tmp53_ = self->priv->playback;
	_tmp54_ = g_signal_connect_object ((GObject*) _tmp53_, "notify::current-item", (GCallback) _dc_audio_player_update_visuals_g_object_notify, self, 0);
	self->priv->current_handler = _tmp54_;
	_tmp55_ = self->priv->playback;
	_tmp56_ = g_signal_connect_object ((GObject*) _tmp55_, "notify::playing", (GCallback) _dc_audio_player_update_visuals_g_object_notify, self, 0);
	self->priv->playing_handler = _tmp56_;
	_tmp57_ = self->priv->transcriber;
	_tmp58_ = g_signal_connect_data (_tmp57_, "updated", (GCallback) ___lambda439__dc_transcriber_updated, block30_data_ref (_data30_), (GClosureNotify) block30_data_unref, 0);
	self->priv->transcriber_handler = _tmp58_;
	dc_audio_player_update_visuals (self);
	dc_audio_player_update_transcription (self);
	_g_object_unref0 (label);
	_g_free0 (size);
	_g_free0 (_tmp11_);
	_g_object_unref0 (row);
	block30_data_unref (_data30_);
	_data30_ = NULL;
	return self;
}

DcAudioPlayer*
dc_audio_player_new (DcMessage* message,
                     gint account_id)
{
	return dc_audio_player_construct (DC_TYPE_AUDIO_PLAYER, message, account_id);
}

/** Reflect the in-memory transcription state: a progress note while
            whisper runs, then the quoted text. Never persisted anywhere. */
static void
dc_audio_player_update_transcription (DcAudioPlayer* self)
{
	gchar* path = NULL;
	DcMessage* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	gchar* _tmp3_;
	const gchar* _tmp4_;
	gboolean in_progress = FALSE;
	DcTranscriber* _tmp5_;
	const gchar* _tmp6_;
	gchar* text = NULL;
	DcTranscriber* _tmp7_;
	const gchar* _tmp8_;
	gchar* _tmp9_;
	GtkButton* _tmp10_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->message;
	_tmp1_ = dc_message_get_file_path (_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = g_strdup (_tmp2_);
	path = _tmp3_;
	_tmp4_ = path;
	if (_tmp4_ == NULL) {
		_g_free0 (path);
		return;
	}
	_tmp5_ = self->priv->transcriber;
	_tmp6_ = path;
	in_progress = dc_transcriber_is_running (_tmp5_, _tmp6_);
	_tmp7_ = self->priv->transcriber;
	_tmp8_ = path;
	_tmp9_ = dc_transcriber_result_for (_tmp7_, _tmp8_);
	text = _tmp9_;
	_tmp10_ = self->priv->transcribe_btn;
	if (_tmp10_ != NULL) {
		gboolean _tmp11_ = FALSE;
		GtkButton* _tmp13_;
		if (!in_progress) {
			const gchar* _tmp12_;
			_tmp12_ = text;
			_tmp11_ = _tmp12_ == NULL;
		} else {
			_tmp11_ = FALSE;
		}
		_tmp13_ = self->priv->transcribe_btn;
		gtk_widget_set_sensitive ((GtkWidget*) _tmp13_, _tmp11_);
	}
	if (in_progress) {
		GtkLabel* _tmp14_;
		GtkLabel* _tmp15_;
		_tmp14_ = self->priv->transcription_label;
		gtk_label_set_markup (_tmp14_, "<i>Transcribing…</i>");
		_tmp15_ = self->priv->transcription_label;
		gtk_widget_set_visible ((GtkWidget*) _tmp15_, TRUE);
	} else {
		const gchar* _tmp16_;
		_tmp16_ = text;
		if (_tmp16_ != NULL) {
			gchar* _tmp17_ = NULL;
			const gchar* _tmp18_;
			gint _tmp19_;
			gint _tmp20_;
			gchar* quoted = NULL;
			gchar* _tmp28_;
			GtkLabel* _tmp29_;
			const gchar* _tmp30_;
			gchar* _tmp31_;
			gchar* _tmp32_;
			gchar* _tmp33_;
			gchar* _tmp34_;
			GtkLabel* _tmp35_;
			_tmp18_ = text;
			_tmp19_ = strlen (_tmp18_);
			_tmp20_ = _tmp19_;
			if (_tmp20_ > 0) {
				const gchar* _tmp21_;
				gchar* _tmp22_;
				gchar* _tmp23_;
				gchar* _tmp24_;
				gchar* _tmp25_;
				gchar* _tmp26_;
				_tmp21_ = text;
				_tmp22_ = g_markup_escape_text (_tmp21_, (gssize) -1);
				_tmp23_ = _tmp22_;
				_tmp24_ = g_strconcat ("“", _tmp23_, NULL);
				_tmp25_ = _tmp24_;
				_tmp26_ = g_strconcat (_tmp25_, "”", NULL);
				_g_free0 (_tmp17_);
				_tmp17_ = _tmp26_;
				_g_free0 (_tmp25_);
				_g_free0 (_tmp23_);
			} else {
				gchar* _tmp27_;
				_tmp27_ = g_strdup ("(no speech detected)");
				_g_free0 (_tmp17_);
				_tmp17_ = _tmp27_;
			}
			_tmp28_ = _tmp17_;
			_tmp17_ = NULL;
			quoted = _tmp28_;
			_tmp29_ = self->priv->transcription_label;
			_tmp30_ = quoted;
			_tmp31_ = g_strconcat ("Transcription: <i>", _tmp30_, NULL);
			_tmp32_ = _tmp31_;
			_tmp33_ = g_strconcat (_tmp32_, "</i>", NULL);
			_tmp34_ = _tmp33_;
			gtk_label_set_markup (_tmp29_, _tmp34_);
			_g_free0 (_tmp34_);
			_g_free0 (_tmp32_);
			_tmp35_ = self->priv->transcription_label;
			gtk_widget_set_visible ((GtkWidget*) _tmp35_, TRUE);
			_g_free0 (quoted);
			_g_free0 (_tmp17_);
		} else {
			GtkLabel* _tmp36_;
			_tmp36_ = self->priv->transcription_label;
			gtk_widget_set_visible ((GtkWidget*) _tmp36_, FALSE);
		}
	}
	_g_free0 (text);
	_g_free0 (path);
}

static void
dc_audio_player_update_visuals (DcAudioPlayer* self)
{
	gboolean _tmp0_ = FALSE;
	gboolean is_playing = FALSE;
	const gchar* _tmp4_ = NULL;
	GtkButton* _tmp5_;
	const gchar* _tmp6_ = NULL;
	GtkButton* _tmp7_;
	g_return_if_fail (self != NULL);
	if (dc_audio_player_is_current_message (self)) {
		DcAudioPlayback* _tmp1_;
		gboolean _tmp2_;
		gboolean _tmp3_;
		_tmp1_ = self->priv->playback;
		_tmp2_ = dc_audio_playback_get_playing (_tmp1_);
		_tmp3_ = _tmp2_;
		_tmp0_ = _tmp3_;
	} else {
		_tmp0_ = FALSE;
	}
	is_playing = _tmp0_;
	if (is_playing) {
		_tmp4_ = "media-playback-pause-symbolic";
	} else {
		_tmp4_ = "media-playback-start-symbolic";
	}
	_tmp5_ = self->priv->btn;
	gtk_button_set_icon_name (_tmp5_, _tmp4_);
	if (is_playing) {
		_tmp6_ = "Pause";
	} else {
		_tmp6_ = "Play";
	}
	_tmp7_ = self->priv->btn;
	gtk_widget_set_tooltip_text ((GtkWidget*) _tmp7_, _tmp6_);
}

static gboolean
dc_audio_player_is_current_message (DcAudioPlayer* self)
{
	DcAudioPlaybackItem* item = NULL;
	DcAudioPlayback* _tmp0_;
	DcAudioPlaybackItem* _tmp1_;
	DcAudioPlaybackItem* _tmp2_;
	DcAudioPlaybackItem* _tmp3_;
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	gboolean _tmp6_ = FALSE;
	DcAudioPlaybackItem* _tmp7_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->playback;
	_tmp1_ = dc_audio_playback_get_current_item (_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	item = _tmp3_;
	_tmp7_ = item;
	if (_tmp7_ != NULL) {
		DcAudioPlaybackItem* _tmp8_;
		gint _tmp9_;
		gint _tmp10_;
		_tmp8_ = item;
		_tmp9_ = dc_audio_playback_item_get_account_id (_tmp8_);
		_tmp10_ = _tmp9_;
		_tmp6_ = _tmp10_ == self->priv->account_id;
	} else {
		_tmp6_ = FALSE;
	}
	if (_tmp6_) {
		DcAudioPlaybackItem* _tmp11_;
		gint _tmp12_;
		gint _tmp13_;
		DcMessage* _tmp14_;
		gint _tmp15_;
		gint _tmp16_;
		_tmp11_ = item;
		_tmp12_ = dc_audio_playback_item_get_chat_id (_tmp11_);
		_tmp13_ = _tmp12_;
		_tmp14_ = self->priv->message;
		_tmp15_ = dc_message_get_chat_id (_tmp14_);
		_tmp16_ = _tmp15_;
		_tmp5_ = _tmp13_ == _tmp16_;
	} else {
		_tmp5_ = FALSE;
	}
	if (_tmp5_) {
		DcAudioPlaybackItem* _tmp17_;
		gint _tmp18_;
		gint _tmp19_;
		DcMessage* _tmp20_;
		gint _tmp21_;
		gint _tmp22_;
		_tmp17_ = item;
		_tmp18_ = dc_audio_playback_item_get_message_id (_tmp17_);
		_tmp19_ = _tmp18_;
		_tmp20_ = self->priv->message;
		_tmp21_ = dc_message_get_id (_tmp20_);
		_tmp22_ = _tmp21_;
		_tmp4_ = _tmp19_ == _tmp22_;
	} else {
		_tmp4_ = FALSE;
	}
	result = _tmp4_;
	_g_object_unref0 (item);
	return result;
}

static void
dc_audio_player_real_dispose (GObject* base)
{
	DcAudioPlayer * self;
	self = (DcAudioPlayer*) base;
	if (self->priv->current_handler != ((gulong) 0)) {
		DcAudioPlayback* _tmp0_;
		_tmp0_ = self->priv->playback;
		g_signal_handler_disconnect ((GObject*) _tmp0_, self->priv->current_handler);
		self->priv->current_handler = (gulong) 0;
	}
	if (self->priv->playing_handler != ((gulong) 0)) {
		DcAudioPlayback* _tmp1_;
		_tmp1_ = self->priv->playback;
		g_signal_handler_disconnect ((GObject*) _tmp1_, self->priv->playing_handler);
		self->priv->playing_handler = (gulong) 0;
	}
	if (self->priv->transcriber_handler != ((gulong) 0)) {
		DcTranscriber* _tmp2_;
		_tmp2_ = self->priv->transcriber;
		g_signal_handler_disconnect ((GObject*) _tmp2_, self->priv->transcriber_handler);
		self->priv->transcriber_handler = (gulong) 0;
	}
	G_OBJECT_CLASS (dc_audio_player_parent_class)->dispose ((GObject*) G_TYPE_CHECK_INSTANCE_CAST (self, gtk_box_get_type (), GtkBox));
}

static void
dc_audio_player_class_init (DcAudioPlayerClass * klass,
                            gpointer klass_data)
{
	dc_audio_player_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &DcAudioPlayer_private_offset);
	((GObjectClass *) klass)->dispose = (void (*) (GObject*)) dc_audio_player_real_dispose;
	G_OBJECT_CLASS (klass)->finalize = dc_audio_player_finalize;
}

static void
dc_audio_player_instance_init (DcAudioPlayer * self,
                               gpointer klass)
{
	self->priv = dc_audio_player_get_instance_private (self);
	self->priv->transcribe_btn = NULL;
	self->priv->current_handler = (gulong) 0;
	self->priv->playing_handler = (gulong) 0;
	self->priv->transcriber_handler = (gulong) 0;
}

static void
dc_audio_player_finalize (GObject * obj)
{
	DcAudioPlayer * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, DC_TYPE_AUDIO_PLAYER, DcAudioPlayer);
	_g_object_unref0 (self->priv->message);
	_g_object_unref0 (self->priv->btn);
	_g_object_unref0 (self->priv->transcribe_btn);
	_g_object_unref0 (self->priv->transcription_label);
	_g_object_unref0 (self->priv->playback);
	_g_object_unref0 (self->priv->transcriber);
	G_OBJECT_CLASS (dc_audio_player_parent_class)->finalize (obj);
}

/** Compact inline control for an audio attachment. */
static GType
dc_audio_player_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (DcAudioPlayerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) dc_audio_player_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (DcAudioPlayer), 0, (GInstanceInitFunc) dc_audio_player_instance_init, NULL };
	GType dc_audio_player_type_id;
	dc_audio_player_type_id = g_type_register_static (gtk_box_get_type (), "DcAudioPlayer", &g_define_type_info, 0);
	DcAudioPlayer_private_offset = g_type_add_instance_private (dc_audio_player_type_id, sizeof (DcAudioPlayerPrivate));
	return dc_audio_player_type_id;
}

GType
dc_audio_player_get_type (void)
{
	static volatile gsize dc_audio_player_type_id__once = 0;
	if (g_once_init_enter (&dc_audio_player_type_id__once)) {
		GType dc_audio_player_type_id;
		dc_audio_player_type_id = dc_audio_player_get_type_once ();
		g_once_init_leave (&dc_audio_player_type_id__once, dc_audio_player_type_id);
	}
	return dc_audio_player_type_id__once;
}

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

