[SCM] gsequencer/master: provide patch of Bug#857910

jkraehemann-guest at users.alioth.debian.org jkraehemann-guest at users.alioth.debian.org
Thu Mar 16 21:05:10 UTC 2017


The following commit has been merged in the master branch:
commit a193c85f64d8ff408617fe417f399ec0666b02d5
Author: Joël Krähemann <jkraehemann-guest at users.alioth.debian.org>
Date:   Thu Mar 16 20:20:19 2017 +0100

    provide patch of Bug#857910

diff --git a/debian/patches/fix-broken-thread-frequency.diff b/debian/patches/fix-broken-thread-frequency.diff
index 9c44ada..13138bb 100644
--- a/debian/patches/fix-broken-thread-frequency.diff
+++ b/debian/patches/fix-broken-thread-frequency.diff
@@ -223,7 +223,7 @@
  
  #include <math.h>
  
-@@ -250,6 +251,9 @@
+@@ -252,6 +253,9 @@
      {
        GObject *soundcard;
  
@@ -233,7 +233,7 @@
        soundcard = (GObject *) g_value_get_object(value);
  
        if(export_thread->soundcard != NULL){
-@@ -259,9 +263,22 @@
+@@ -261,9 +265,22 @@
        if(soundcard != NULL){
  	g_object_ref(G_OBJECT(soundcard));
  
@@ -336,16 +336,7 @@
  #endif /*__AGS_MAIN_LOOP_H__*/
 --- a/ags/audio/thread/ags_audio_loop.c
 +++ b/ags/audio/thread/ags_audio_loop.c
-@@ -68,6 +68,8 @@
- guint ags_audio_loop_get_last_sync(AgsMainLoop *main_loop);
- gboolean ags_audio_loop_monitor(AgsMainLoop *main_loop,
- 				guint time_cycle, guint *time_spent);
-+void ags_audio_loop_change_frequency(AgsMainLoop *main_loop,
-+				     gdouble frequency);
- void ags_audio_loop_finalize(GObject *gobject);
- 
- void ags_audio_loop_start(AgsThread *thread);
-@@ -271,6 +273,7 @@
+@@ -292,6 +292,7 @@
    main_loop->get_last_sync = ags_audio_loop_get_last_sync;
    main_loop->interrupt = NULL;
    main_loop->monitor = ags_audio_loop_monitor;
@@ -353,11 +344,10 @@
  }
  
  void
-@@ -592,6 +595,74 @@
-   }
+@@ -694,6 +695,74 @@
  }
  
-+void
+ void
 +ags_audio_loop_change_frequency(AgsMainLoop *main_loop,
 +				gdouble frequency)
 +{
@@ -425,13 +415,14 @@
 +  }
 +}
 +
- void
++void
  ags_audio_loop_finalize(GObject *gobject)
  {
+   AgsAudioLoop *audio_loop;
 --- a/ags/audio/recall/ags_delay_audio.c
 +++ b/ags/audio/recall/ags_delay_audio.c
-@@ -42,10 +42,20 @@
- void ags_delay_audio_set_ports(AgsPlugin *plugin, GList *port);
+@@ -43,10 +43,20 @@
+ void ags_delay_audio_dispose(GObject *gobject);
  void ags_delay_audio_finalize(GObject *gobject);
  
 +void ags_delay_audio_notify_audio_callback(GObject *gobject,
@@ -451,7 +442,7 @@
  gdouble ags_delay_audio_get_bpm(AgsTactable *tactable);
  gdouble ags_delay_audio_get_tact(AgsTactable *tactable);
  gdouble ags_delay_audio_get_sequencer_duration(AgsTactable *tactable);
-@@ -55,6 +65,8 @@
+@@ -56,6 +66,8 @@
  void ags_delay_audio_change_sequencer_duration(AgsTactable *tactable, gdouble duration);
  void ags_delay_audio_change_notation_duration(AgsTactable *tactable, gdouble duration);
  
@@ -460,7 +451,7 @@
  /**
   * SECTION:ags_delay_audio
   * @short_description: delay audio 
-@@ -326,7 +338,11 @@
+@@ -328,7 +340,11 @@
    AGS_RECALL(delay_audio)->build_id = AGS_RECALL_DEFAULT_BUILD_ID;
    AGS_RECALL(delay_audio)->xml_type = "ags-delay-audio\0";
  
@@ -473,7 +464,7 @@
  			 G_CALLBACK(ags_delay_audio_notify_soundcard_callback), NULL);
  }
  
-@@ -590,6 +606,30 @@
+@@ -642,6 +658,30 @@
  }
  
  void
@@ -504,7 +495,7 @@
  ags_delay_audio_notify_soundcard_callback(GObject *gobject,
  					  GParamSpec *pspec,
  					  gpointer user_data)
-@@ -606,6 +646,11 @@
+@@ -658,6 +698,11 @@
    delay_audio = AGS_DELAY_AUDIO(gobject);
  
    soundcard = AGS_RECALL(delay_audio)->soundcard;
@@ -516,7 +507,7 @@
    port = NULL;
  
    /*  */
-@@ -706,6 +751,30 @@
+@@ -776,6 +821,30 @@
    AGS_RECALL(delay_audio)->port = port;
  }
  
@@ -547,7 +538,7 @@
  gdouble
  ags_delay_audio_get_bpm(AgsTactable *tactable)
  {
-@@ -884,6 +953,59 @@
+@@ -954,6 +1023,59 @@
  
    /* notation-duration */
    g_value_reset(&value);
diff --git a/debian/patches/fix-missing-dispose.diff b/debian/patches/fix-missing-dispose.diff
new file mode 100644
index 0000000..bb4c78e
--- /dev/null
+++ b/debian/patches/fix-missing-dispose.diff
@@ -0,0 +1,9399 @@
+--- a/ags/X/ags_effect_bulk.c
++++ b/ags/X/ags_effect_bulk.c
+@@ -723,8 +723,8 @@
+ 
+   effect_plugin = (AgsEffectBulkPlugin *) malloc(sizeof(AgsEffectBulkPlugin));
+ 
+-  effect_plugin->filename = filename;
+-  effect_plugin->effect = effect;
++  effect_plugin->filename = g_strdup(filename);
++  effect_plugin->effect = g_strdup(effect);
+ 
+   effect_plugin->control_type_name = NULL;
+   
+--- a/ags/audio/ags_acceleration.c
++++ b/ags/audio/ags_acceleration.c
+@@ -28,7 +28,7 @@
+ void ags_acceleration_init(AgsAcceleration *acceleration);
+ void ags_acceleration_connect(AgsConnectable *connectable);
+ void ags_acceleration_disconnect(AgsConnectable *connectable);
+-void ags_acceleration_finalize(GObject *object);
++void ags_acceleration_finalize(GObject *gobject);
+ 
+ /**
+  * SECTION:ags_acceleration
+@@ -112,20 +112,43 @@
+ void
+ ags_acceleration_connect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsAcceleration *acceleration;
++
++  acceleration = AGS_ACCELERATION(connectable);
++
++  if((AGS_ACCELERATION_CONNECTED & (acceleration->flags)) != 0){
++    return;
++  }
++
++  acceleration->flags |= AGS_ACCELERATION_CONNECTED;
+ }
+ 
+ void
+ ags_acceleration_disconnect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsAcceleration *acceleration;
++
++  acceleration = AGS_ACCELERATION(connectable);
++
++  if((AGS_ACCELERATION_CONNECTED & (acceleration->flags)) == 0){
++    return;
++  }
++
++  acceleration->flags &= (~AGS_ACCELERATION_CONNECTED);
+ }
+ 
+ void
+ ags_acceleration_finalize(GObject *gobject)
+ {
+-  /* empty */
++  AgsAcceleration *acceleration;
+ 
++  acceleration = AGS_ACCELERATION(gobject);
++  
++  if(acceleration->name != NULL){
++    free(acceleration->name);
++  }
++  
++  /* call parent */
+   G_OBJECT_CLASS(ags_acceleration_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/ags_acceleration.h
++++ b/ags/audio/ags_acceleration.h
+@@ -35,6 +35,7 @@
+ 
+ /**
+  * AgsAccelerationFlags:
++ * @AGS_ACCELERATION_CONNECTED: if this object is already connected
+  * @AGS_ACCELERATION_DEFAULT_START: if start is default start point
+  * @AGS_ACCELERATION_DEFAULT_END: if end is default end point
+  * @AGS_ACCELERATION_GUI: interpret x and y as GUI format
+@@ -44,13 +45,14 @@
+  * @AGS_ACCELERATION_IS_SELECTED: if the acceleration is selected
+  */
+ typedef enum{
+-  AGS_ACCELERATION_DEFAULT_START   = 1,
+-  AGS_ACCELERATION_DEFAULT_END     = 1 <<  1,
+-  AGS_ACCELERATION_GUI             = 1 <<  2,
+-  AGS_ACCELERATION_RUNTIME         = 1 <<  3,
+-  AGS_ACCELERATION_HUMAN_READABLE  = 1 <<  4,
+-  AGS_ACCELERATION_DEFAULT_LENGTH  = 1 <<  5,
+-  AGS_ACCELERATION_IS_SELECTED     = 1 <<  6,
++  AGS_ACCELERATION_CONNECTED       = 1,
++  AGS_ACCELERATION_DEFAULT_START   = 1 <<  1,
++  AGS_ACCELERATION_DEFAULT_END     = 1 <<  2,
++  AGS_ACCELERATION_GUI             = 1 <<  3,
++  AGS_ACCELERATION_RUNTIME         = 1 <<  4,
++  AGS_ACCELERATION_HUMAN_READABLE  = 1 <<  5,
++  AGS_ACCELERATION_DEFAULT_LENGTH  = 1 <<  6,
++  AGS_ACCELERATION_IS_SELECTED     = 1 <<  7,
+ }AgsAccelerationFlags;
+ 
+ struct _AgsAcceleration
+--- a/ags/audio/ags_audio.h
++++ b/ags/audio/ags_audio.h
+@@ -23,6 +23,7 @@
+ #include <glib-object.h>
+ 
+ #include <ags/audio/ags_channel.h>
++#include <ags/audio/ags_recall_id.h>
+ 
+ #define AGS_TYPE_AUDIO                (ags_audio_get_type ())
+ #define AGS_AUDIO(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_AUDIO, AgsAudio))
+--- a/ags/audio/ags_audio_application_context.c
++++ b/ags/audio/ags_audio_application_context.c
+@@ -128,6 +128,7 @@
+ void ags_audio_application_context_set_sequencer(AgsSoundProvider *sound_provider,
+ 						 GList *sequencer);
+ GList* ags_audio_application_context_get_distributed_manager(AgsSoundProvider *sound_provider);
++void ags_audio_application_context_dispose(GObject *gobject);
+ void ags_audio_application_context_finalize(GObject *gobject);
+ 
+ void ags_audio_application_context_register_types(AgsApplicationContext *application_context);
+@@ -228,6 +229,7 @@
+   gobject->set_property = ags_audio_application_context_set_property;
+   gobject->get_property = ags_audio_application_context_get_property;
+ 
++  gobject->dispose = ags_audio_application_context_dispose;
+   gobject->finalize = ags_audio_application_context_finalize;
+   
+   /**
+@@ -315,6 +317,7 @@
+   /**/
+   config = ags_config_get_instance();
+   AGS_APPLICATION_CONTEXT(audio_application_context)->config = config;
++  g_object_ref(config);
+   g_object_set(config,
+ 	       "application-context\0", audio_application_context,
+ 	       NULL);
+@@ -865,6 +868,103 @@
+ }
+ 
+ void
++ags_audio_application_context_dispose(GObject *gobject)
++{
++  AgsAudioApplicationContext *audio_application_context;
++
++  GList *list;
++  
++  audio_application_context = AGS_AUDIO_APPLICATION_CONTEXT(gobject);
++
++  /* thread pool */
++  if(audio_application_context->thread_pool != NULL){
++    g_object_unref(audio_application_context->thread_pool);
++    
++    audio_application_context->thread_pool = NULL;
++  }
++
++  /* soundcard and export thread */
++  if(audio_application_context->soundcard_thread != NULL){
++    g_object_unref(audio_application_context->soundcard_thread);
++
++    audio_application_context->soundcard_thread = NULL;
++  }
++
++  if(audio_application_context->export_thread != NULL){
++    g_object_unref(audio_application_context->export_thread);
++
++    audio_application_context->export_thread = NULL;
++  }
++
++  /* server */
++  if(audio_application_context->server != NULL){
++    g_object_set(audio_application_context->server,
++		 "application-context\0", NULL,
++		 NULL);
++    
++    g_object_unref(audio_application_context->server);
++
++    audio_application_context->server = NULL;
++  }
++
++  /* soundcard and sequencer */
++  if(audio_application_context->soundcard != NULL){
++    list = audio_application_context->soundcard;
++
++    while(list != NULL){
++      g_object_set(list->data,
++		   "application-context\0", NULL,
++		   NULL);
++
++      list = list->next;
++    }
++    
++    g_list_free_full(audio_application_context->soundcard,
++		     g_object_unref);
++
++    audio_application_context->soundcard = NULL;
++  }
++
++  if(audio_application_context->sequencer != NULL){
++    list = audio_application_context->sequencer;
++
++    while(list != NULL){
++      g_object_set(list->data,
++		   "application-context\0", NULL,
++		   NULL);
++
++      list = list->next;
++    }
++
++    g_list_free_full(audio_application_context->sequencer,
++		     g_object_unref);
++
++    audio_application_context->sequencer = NULL;
++  }
++
++  /* distributed manager */
++  if(audio_application_context->distributed_manager != NULL){
++    list = audio_application_context->distributed_manager;
++
++    while(list != NULL){
++      g_object_set(list->data,
++		   "application-context\0", NULL,
++		   NULL);
++
++      list = list->next;
++    }
++
++    g_list_free_full(audio_application_context->distributed_manager,
++		     g_object_unref);
++
++    audio_application_context->distributed_manager = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_audio_application_context_parent_class)->dispose(gobject);
++}
++
++void
+ ags_audio_application_context_finalize(GObject *gobject)
+ {
+   AgsAudioApplicationContext *audio_application_context;
+--- a/ags/audio/ags_audio_signal.c
++++ b/ags/audio/ags_audio_signal.c
+@@ -57,9 +57,10 @@
+ 				   guint prop_id,
+ 				   GValue *value,
+ 				   GParamSpec *param_spec);
+-void ags_audio_signal_finalize(GObject *gobject);
+ void ags_audio_signal_connect(AgsConnectable *connectable);
+ void ags_audio_signal_disconnect(AgsConnectable *connectable);
++void ags_audio_signal_dispose(GObject *gobject);
++void ags_audio_signal_finalize(GObject *gobject);
+ 
+ void ags_audio_signal_real_realloc_buffer_size(AgsAudioSignal *audio_signal, guint buffer_size);
+ 
+@@ -145,6 +146,7 @@
+   gobject->set_property = ags_audio_signal_set_property;
+   gobject->get_property = ags_audio_signal_get_property;
+ 
++  gobject->dispose = ags_audio_signal_dispose;
+   gobject->finalize = ags_audio_signal_finalize;
+ 
+   /* properties */
+@@ -946,6 +948,70 @@
+ }
+ 
+ void
++ags_audio_signal_connect(AgsConnectable *connectable)
++{
++  AgsAudioSignal *audio_signal;
++
++  audio_signal = AGS_AUDIO_SIGNAL(connectable);
++
++  if((AGS_AUDIO_SIGNAL_CONNECTED & (audio_signal->flags)) != 0){
++    return;
++  }
++
++  audio_signal->flags |= AGS_AUDIO_SIGNAL_CONNECTED;
++}
++
++void
++ags_audio_signal_disconnect(AgsConnectable *connectable)
++{
++  AgsAudioSignal *audio_signal;
++
++  audio_signal = AGS_AUDIO_SIGNAL(connectable);
++
++  if((AGS_AUDIO_SIGNAL_CONNECTED & (audio_signal->flags)) == 0){
++    return;
++  }
++
++  audio_signal->flags &= (~AGS_AUDIO_SIGNAL_CONNECTED);
++}
++
++void
++ags_audio_signal_dispose(GObject *gobject)
++{
++  AgsAudioSignal *audio_signal;
++
++  audio_signal = AGS_AUDIO_SIGNAL(gobject);
++
++  /* soundcard */
++  if(audio_signal->soundcard != NULL){
++    g_object_unref(audio_signal->soundcard);
++
++    audio_signal->soundcard = NULL;
++  }
++
++  /* recycling */
++  if(audio_signal->recycling != NULL){
++    g_object_unref(audio_signal->recycling);
++    
++    audio_signal->recycling = NULL;  
++  }
++
++  /* recall id */
++  if(audio_signal->recall_id != NULL){
++    g_object_unref(audio_signal->recall_id);
++
++    audio_signal->recall_id = NULL;
++  }
++
++  /* note */
++  if(audio_signal->note != NULL){
++    g_object_unref(audio_signal->note);
++
++    audio_signal->note = NULL;
++  }
++}
++
++void
+ ags_audio_signal_finalize(GObject *gobject)
+ {
+   AgsAudioSignal *audio_signal;
+@@ -962,7 +1028,8 @@
+   if((AGS_AUDIO_SIGNAL_TEMPLATE & (audio_signal->flags)) != 0){
+     g_warning("AGS_AUDIO_SIGNAL_TEMPLATE: destroying\n\0");
+   }
+-  
++
++  /* disconnect */
+   ids = g_signal_list_ids(AGS_TYPE_AUDIO_SIGNAL,
+ 			  &n_ids);
+   
+@@ -977,24 +1044,29 @@
+   }
+ 
+   g_free(ids);
+-  
++
++  /* soundcard */
+   if(audio_signal->soundcard != NULL){
+     g_object_unref(audio_signal->soundcard);
+   }
+-  
++
++  /* recycling */
+   if(audio_signal->recycling != NULL){
+     g_object_unref(audio_signal->recycling);
+   }
+-  
++
++  /* recall id */
+   if(audio_signal->recall_id != NULL){
+     g_object_unref(audio_signal->recall_id);
+   }
+-  
++
++  /* audio data */
+   if(audio_signal->stream_beginning != NULL){
+     g_list_free_full(audio_signal->stream_beginning,
+ 		     (GDestroyNotify) ags_stream_free);
+   }
+ 
++  /* note */
+   if(audio_signal->note != NULL){
+     g_object_unref(audio_signal->note);
+   }
+@@ -1003,18 +1075,6 @@
+   G_OBJECT_CLASS(ags_audio_signal_parent_class)->finalize(gobject);
+ }
+ 
+-void
+-ags_audio_signal_connect(AgsConnectable *connectable)
+-{
+-  // empty
+-}
+-
+-void
+-ags_audio_signal_disconnect(AgsConnectable *connectable)
+-{
+-  // empty
+-}
+-
+ /**
+  * ags_stream_alloc:
+  * @buffer_size: the buffer size
+--- a/ags/audio/ags_audio_signal.h
++++ b/ags/audio/ags_audio_signal.h
+@@ -34,9 +34,10 @@
+ typedef struct _AgsAudioSignalClass AgsAudioSignalClass;
+ 
+ typedef enum{
+-  AGS_AUDIO_SIGNAL_TEMPLATE             = 1,
+-  AGS_AUDIO_SIGNAL_PLAY_DONE            = 1 << 1,
+-  AGS_AUDIO_SIGNAL_STANDALONE           = 1 << 2,
++  AGS_AUDIO_SIGNAL_CONNECTED            = 1,
++  AGS_AUDIO_SIGNAL_TEMPLATE             = 1 <<  1,
++  AGS_AUDIO_SIGNAL_PLAY_DONE            = 1 <<  2,
++  AGS_AUDIO_SIGNAL_STANDALONE           = 1 <<  3,
+ }AgsAudioSignalFlags;
+ 
+ struct _AgsAudioSignal
+--- a/ags/audio/ags_automation.c
++++ b/ags/audio/ags_automation.c
+@@ -54,7 +54,8 @@
+ 				 GParamSpec *param_spec);
+ void ags_automation_connect(AgsConnectable *connectable);
+ void ags_automation_disconnect(AgsConnectable *connectable);
+-void ags_automation_finalize(GObject *object);
++void ags_automation_dispose(GObject *gobject);
++void ags_automation_finalize(GObject *gobject);
+ 
+ void ags_automation_set_port(AgsPortlet *portlet, GObject *port);
+ GObject* ags_automation_get_port(AgsPortlet *portlet);
+@@ -155,6 +156,7 @@
+   gobject->set_property = ags_automation_set_property;
+   gobject->get_property = ags_automation_get_property;
+ 
++  gobject->dispose = ags_automation_dispose;
+   gobject->finalize = ags_automation_finalize;
+ 
+   /* properties */
+@@ -432,13 +434,51 @@
+ void
+ ags_automation_connect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsAutomation *automation;
++
++  GList *list;
++  
++  automation = AGS_AUTOMATION(connectable);
++
++  if((AGS_AUTOMATION_CONNECTED & (automation->flags)) != 0){
++    return;
++  }
++
++  automation->flags |= AGS_AUTOMATION_CONNECTED;
++
++  /* acceleration */
++  list = automation->acceleration;
++
++  while(list != NULL){
++    ags_connectable_connect(AGS_CONNECTABLE(list->data));
++
++    list = list->next;
++  }
+ }
+ 
+ void
+ ags_automation_disconnect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsAutomation *automation;
++
++  GList *list;
++
++  automation = AGS_AUTOMATION(connectable);
++
++  if((AGS_AUTOMATION_CONNECTED & (automation->flags)) == 0){
++    return;
++  }
++
++  automation->flags &= (~AGS_AUTOMATION_CONNECTED);
++
++  /* acceleration */
++  list = automation->acceleration;
++
++  while(list != NULL){
++    ags_connectable_disconnect(AGS_CONNECTABLE(list->data));
++
++    list = list->next;
++  }
+ }
+ 
+ void
+@@ -723,19 +763,103 @@
+ }
+ 
+ void
++ags_automation_dispose(GObject *gobject)
++{
++  AgsAutomation *automation;
++
++  GList *list;
++  
++  automation = AGS_AUTOMATION(gobject);
++
++  /* timestamp */
++  if(automation->timestamp != NULL){
++    g_object_unref(automation->timestamp);
++
++    automation->timestamp = NULL;
++  }
++
++  /* audio */
++  if(automation->audio != NULL){
++    g_object_unref(automation->audio);
++
++    automation->audio = NULL;
++  }
++
++  /* source function */
++  if(automation->source_function != NULL){
++    g_object_run_dispose(automation->source_function);
++    
++    g_object_unref(automation->source_function);
++
++    automation->source_function = NULL;
++  }
++
++  /* acceleration */
++  list = automation->acceleration;
++
++  while(list != NULL){
++    g_object_run_dispose(G_OBJECT(list->data));
++
++    list = list->next;
++  }
++  
++  g_list_free_full(automation->acceleration,
++		   g_object_unref);
++  g_list_free(automation->selection);
++
++  automation->acceleration = NULL;
++  automation->selection = NULL;
++
++  /* port */
++  if(automation->port != NULL){
++    g_object_unref(automation->port);
++
++    automation->port = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_automation_parent_class)->dispose(gobject);
++}
++
++void
+ ags_automation_finalize(GObject *gobject)
+ {
+   AgsAutomation *automation;
+ 
+   automation = AGS_AUTOMATION(gobject);
++
++  /* timestamp */
++  if(automation->timestamp != NULL){
++    g_object_unref(automation->timestamp);
++  }
+   
++  /* audio */
+   if(automation->audio != NULL){
+     g_object_unref(automation->audio);
+   }
++
++  /* control name */
++  if(automation->control_name != NULL){
++    free(automation->control_name);
++  }
++
++  /* source function */
++  if(automation->source_function != NULL){
++    g_object_unref(automation->source_function);
++  }
+   
++  /* acceleration */
+   g_list_free_full(automation->acceleration,
+ 		   g_object_unref);
+ 
++  g_list_free(automation->selection);
++
++  /* port */
++  if(automation->port != NULL){
++    g_object_unref(automation->port);
++  }
++  
++  /* call parent */
+   G_OBJECT_CLASS(ags_automation_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/ags_input.c
++++ b/ags/audio/ags_input.c
+@@ -26,6 +26,7 @@
+ #include <ags/audio/ags_playable.h>
+ #include <ags/audio/ags_recycling.h>
+ #include <ags/audio/ags_audio_signal.h>
++#include <ags/audio/ags_synth_generator.h>
+ 
+ #include <ags/audio/file/ags_audio_file_link.h>
+ #include <ags/audio/file/ags_audio_file.h>
+@@ -42,7 +43,8 @@
+ 			    GValue *value,
+ 			    GParamSpec *param_spec);
+ void ags_input_init (AgsInput *input);
+-void ags_input_finalize (GObject *gobject);
++void ags_input_dispose(GObject *gobject);
++void ags_input_finalize(GObject *gobject);
+ void ags_input_connect(AgsConnectable *connectable);
+ void ags_input_disconnect(AgsConnectable *connectable);
+ 
+@@ -62,6 +64,7 @@
+ enum{
+   PROP_0,
+   PROP_FILE_LINK,
++  PROP_SYNTH_GENERATOR,
+ };
+ 
+ GType
+@@ -114,6 +117,7 @@
+   gobject->set_property = ags_input_set_property;
+   gobject->get_property = ags_input_get_property;
+ 
++  gobject->dispose = ags_input_dispose;
+   gobject->finalize = ags_input_finalize;
+   
+   /* properties */
+@@ -132,6 +136,22 @@
+   g_object_class_install_property(gobject,
+ 				  PROP_FILE_LINK,
+ 				  param_spec);
++
++  /**
++   * AgsInput:synth-generator:
++   *
++   * An optional synth generator that might be used.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_object("synth-generator\0",
++				   "the synth generator\0",
++				   "The synth generator to be used\0",
++				   AGS_TYPE_SYNTH_GENERATOR,
++				   G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_SYNTH_GENERATOR,
++				  param_spec);
+ }
+ 
+ void
+@@ -165,7 +185,6 @@
+   switch(prop_id){
+   case PROP_FILE_LINK:
+     {
+-      AgsAudioFile *audio_file;
+       AgsFileLink *file_link;
+ 
+       file_link = (AgsFileLink *) g_value_get_object(value);
+@@ -185,6 +204,27 @@
+       input->file_link = (GObject *) file_link;
+     }
+     break;
++  case PROP_SYNTH_GENERATOR:
++    {
++      AgsFileLink *synth_generator;
++
++      synth_generator = (AgsFileLink *) g_value_get_object(value);
++
++      if(input->synth_generator == (GObject *) synth_generator){
++	return;
++      }
++      
++      if(input->synth_generator != NULL){
++	g_object_unref(G_OBJECT(input->synth_generator));
++      }
++
++      if(synth_generator != NULL){
++	g_object_ref(G_OBJECT(synth_generator));
++      }
++
++      input->synth_generator = (GObject *) synth_generator;
++    }
++    break;
+   default:
+     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+     break;
+@@ -203,7 +243,14 @@
+ 
+   switch(prop_id){
+   case PROP_FILE_LINK:
+-    g_value_set_object(value, input->file_link);
++    {
++      g_value_set_object(value, input->file_link);
++    }
++    break;
++  case PROP_SYNTH_GENERATOR:
++    {
++      g_value_set_object(value, input->synth_generator);
++    }
+     break;
+   default:
+     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+@@ -212,16 +259,52 @@
+ }
+ 
+ void
++ags_input_dispose(GObject *gobject)
++{
++  AgsInput *input;
++
++  input = AGS_INPUT(gobject);
++
++  /* file link */
++  if(input->file_link != NULL){
++    g_object_run_dispose(G_OBJECT(input->file_link));
++
++    g_object_unref(G_OBJECT(input->file_link));
++    
++    input->file_link = NULL;
++  }
++
++  /* synth generator */
++  if(input->synth_generator != NULL){
++    g_object_run_dispose(G_OBJECT(input->synth_generator));
++
++    g_object_unref(G_OBJECT(input->synth_generator));
++    
++    input->synth_generator = NULL;
++  }
++
++  /* finalize */
++  G_OBJECT_CLASS(ags_input_parent_class)->dispose(gobject);
++}
++
++void
+ ags_input_finalize(GObject *gobject)
+ {
+   AgsInput *input;
+ 
+   input = AGS_INPUT(gobject);
+ 
++  /* file link */
+   if(input->file_link != NULL){
+     g_object_unref(G_OBJECT(input->file_link));
+   }
+ 
++  /* synth generator */
++  if(input->synth_generator != NULL){
++    g_object_unref(G_OBJECT(input->synth_generator));
++  }
++
++  /* finalize */
+   G_OBJECT_CLASS(ags_input_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/ags_midiin.c
++++ b/ags/audio/ags_midiin.c
+@@ -72,6 +72,7 @@
+ 			     GParamSpec *param_spec);
+ void ags_midiin_disconnect(AgsConnectable *connectable);
+ void ags_midiin_connect(AgsConnectable *connectable);
++void ags_midiin_dispose(GObject *gobject);
+ void ags_midiin_finalize(GObject *gobject);
+ 
+ void ags_midiin_switch_buffer_flag(AgsMidiin *midiin);
+@@ -219,6 +220,7 @@
+   gobject->set_property = ags_midiin_set_property;
+   gobject->get_property = ags_midiin_get_property;
+ 
++  gobject->dispose = ags_midiin_dispose;
+   gobject->finalize = ags_midiin_finalize;
+ 
+   /* properties */
+@@ -702,13 +704,44 @@
+ }
+ 
+ void
++ags_midiin_dispose(GObject *gobject)
++{
++  AgsMidiin *midiin;
++
++  GList *list;
++
++  midiin = AGS_MIDIIN(gobject);
++
++  /* audio */  
++  if(midiin->audio != NULL){
++    list = midiin->audio;
++
++    while(list != NULL){
++      g_object_set(list->data,
++		   "sequencer\0", NULL,
++		   NULL);
++
++      list = list->next;
++    }
++    
++    g_list_free_full(midiin->audio,
++		     g_object_unref);
++
++    midiin->audio = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_midiin_parent_class)->dispose(gobject);
++}
++
++void
+ ags_midiin_finalize(GObject *gobject)
+ {
+   AgsMidiin *midiin;
+ 
+   AgsMutexManager *mutex_manager;
+   
+-  GList *list, *list_next;
++  GList *list;
+ 
+   midiin = AGS_MIDIIN(gobject);
+ 
+@@ -742,7 +775,18 @@
+   /* free buffer array */
+   free(midiin->buffer);
+ 
++  /* audio */
+   if(midiin->audio != NULL){
++    list = midiin->audio;
++
++    while(list != NULL){
++      g_object_set(list->data,
++		   "sequencer\0", NULL,
++		   NULL);
++
++      list = list->next;
++    }
++    
+     g_list_free_full(midiin->audio,
+ 		     g_object_unref);
+   }
+--- a/ags/audio/ags_notation.c
++++ b/ags/audio/ags_notation.c
+@@ -46,7 +46,8 @@
+ 			       GParamSpec *param_spec);
+ void ags_notation_connect(AgsConnectable *connectable);
+ void ags_notation_disconnect(AgsConnectable *connectable);
+-void ags_notation_finalize(GObject *object);
++void ags_notation_dispose(GObject *gobject);
++void ags_notation_finalize(GObject *gobject);
+ 
+ void ags_notation_change_bpm(AgsTactable *tactable, gdouble new_bpm, gdouble old_bpm);
+ 
+@@ -156,6 +157,7 @@
+   gobject->set_property = ags_notation_set_property;
+   gobject->get_property = ags_notation_get_property;
+ 
++  gobject->dispose = ags_notation_dispose;
+   gobject->finalize = ags_notation_finalize;
+ 
+   /* properties */
+@@ -335,13 +337,51 @@
+ void
+ ags_notation_connect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsNotation *notation;
++
++  GList *list;
++  
++  notation = AGS_NOTATION(connectable);
++
++  if((AGS_NOTATION_CONNECTED & (notation->flags)) != 0){
++    return;
++  }
++
++  notation->flags |= AGS_NOTATION_CONNECTED;
++
++  /* note */
++  list = notation->notes;
++
++  while(list != NULL){
++    ags_connectable_connect(AGS_CONNECTABLE(list->data));
++
++    list = list->next;
++  }
+ }
+ 
+ void
+ ags_notation_disconnect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsNotation *notation;
++
++  GList *list;
++
++  notation = AGS_NOTATION(connectable);
++
++  if((AGS_NOTATION_CONNECTED & (notation->flags)) == 0){
++    return;
++  }
++
++  notation->flags &= (~AGS_NOTATION_CONNECTED);
++
++  /* note */
++  list = notation->notes;
++
++  while(list != NULL){
++    ags_connectable_disconnect(AGS_CONNECTABLE(list->data));
++
++    list = list->next;
++  }
+ }
+ 
+ void
+@@ -608,16 +648,107 @@
+ }
+ 
+ void
++ags_notation_dispose(GObject *gobject)
++{
++  AgsNotation *notation;
++
++  GList *list;
++  
++  notation = AGS_NOTATION(gobject);
++
++  /* timestamp */
++  if(notation->timestamp != NULL){
++    g_object_unref(notation->timestamp);
++
++    notation->timestamp = NULL;
++  }
++
++  /* audio */
++  if(notation->audio != NULL){
++    g_object_unref(notation->audio);
++
++    notation->audio = NULL;
++  }
++
++  /* key and base note */
++  if(notation->key != NULL){
++    free(notation->key);
++
++    notation->key = NULL;
++  }
++
++  if(notation->base_note != NULL){
++    free(notation->base_note);
++
++    notation->base_note = NULL;
++  }
++    
++  /* note and selection */
++  list = notation->notes;
++
++  while(list != NULL){
++    g_object_run_dispose(G_OBJECT(list->data));
++    
++    list = list->next;
++  }
++  
++  g_list_free_full(notation->notes,
++		   g_object_unref);
++
++  g_list_free(notation->selection);
++
++  notation->notes = NULL;
++  notation->selection = NULL;
++  
++  /* port */
++  if(notation->port != NULL){
++    g_object_unref(notation->port);
++
++    notation->port = NULL;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_notation_parent_class)->dispose(gobject);
++}
++
++void
+ ags_notation_finalize(GObject *gobject)
+ {
+   AgsNotation *notation;
+-  GList *list, *list_next;
+ 
+   notation = AGS_NOTATION(gobject);
+ 
++  /* timestamp */
++  if(notation->timestamp != NULL){
++    g_object_unref(notation->timestamp);
++  }
++
++  /* audio */
++  if(notation->audio != NULL){
++    g_object_unref(notation->audio);
++  }
++
++  /* key and base note */
++  if(notation->key != NULL){
++    free(notation->key);
++  }
++
++  if(notation->base_note != NULL){
++    free(notation->base_note);
++  }
++    
++  /* note and selection */
+   g_list_free_full(notation->notes,
+ 		   g_object_unref);
+ 
++  g_list_free(notation->selection);
++
++  /* port */
++  if(notation->port != NULL){
++    g_object_unref(notation->port);
++  }
++  
++  /* call parent */
+   G_OBJECT_CLASS(ags_notation_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/ags_notation.h
++++ b/ags/audio/ags_notation.h
+@@ -53,8 +53,9 @@
+ typedef struct _AgsNotationClass AgsNotationClass;
+ 
+ typedef enum{
+-  AGS_NOTATION_STICKY              =  1,
+-  AGS_NOTATION_PATTERN_MODE        =  1 <<  1,
++  AGS_NOTATION_CONNECTED           = 1,
++  AGS_NOTATION_STICKY              = 1 <<  1,
++  AGS_NOTATION_PATTERN_MODE        = 1 <<  2,
+ }AgsNotationFlags;
+ 
+ struct _AgsNotation
+--- a/ags/audio/ags_note.c
++++ b/ags/audio/ags_note.c
+@@ -38,7 +38,7 @@
+ 			   GParamSpec *param_spec);
+ void ags_note_connect(AgsConnectable *connectable);
+ void ags_note_disconnect(AgsConnectable *connectable);
+-void ags_note_finalize(GObject *object);
++void ags_note_finalize(GObject *gobject);
+ 
+ /**
+  * SECTION:ags_note
+@@ -327,13 +327,29 @@
+ void
+ ags_note_connect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsNote *note;
++
++  note = AGS_NOTE(connectable);
++
++  if((AGS_NOTE_CONNECTED & (note->flags)) != 0){
++    return;
++  }
++
++  note->flags |= AGS_NOTE_CONNECTED;
+ }
+ 
+ void
+ ags_note_disconnect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsNote *note;
++
++  note = AGS_NOTE(connectable);
++
++  if((AGS_NOTE_CONNECTED & (note->flags)) == 0){
++    return;
++  }
++
++  note->flags &= (~AGS_NOTE_CONNECTED);
+ }
+ 
+ void
+@@ -478,8 +494,16 @@
+ void
+ ags_note_finalize(GObject *gobject)
+ {
+-  /* empty */
++  AgsNote *note;
+ 
++  note = AGS_NOTE(gobject);
++
++  /* name */
++  if(note->name != NULL){
++    free(note->name);
++  }
++  
++  /* call parent */
+   G_OBJECT_CLASS(ags_note_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/ags_note.h
++++ b/ags/audio/ags_note.h
+@@ -41,12 +41,13 @@
+ typedef struct _AgsNoteClass AgsNoteClass;
+ 
+ typedef enum{
+-  AGS_NOTE_GUI             =  1,
+-  AGS_NOTE_RUNTIME         =  1 <<  1,
+-  AGS_NOTE_HUMAN_READABLE  =  1 <<  2,
+-  AGS_NOTE_DEFAULT_LENGTH  =  1 <<  3,
+-  AGS_NOTE_IS_SELECTED     =  1 <<  4,
+-  AGS_NOTE_FEED            =  1 <<  5,
++  AGS_NOTE_CONNECTED       = 1,
++  AGS_NOTE_GUI             = 1 <<  1,
++  AGS_NOTE_RUNTIME         = 1 <<  2,
++  AGS_NOTE_HUMAN_READABLE  = 1 <<  3,
++  AGS_NOTE_DEFAULT_LENGTH  = 1 <<  4,
++  AGS_NOTE_IS_SELECTED     = 1 <<  5,
++  AGS_NOTE_FEED            = 1 <<  6,
+ }AgsNoteFlags;
+ 
+ struct _AgsNote
+--- a/ags/audio/ags_pattern.c
++++ b/ags/audio/ags_pattern.c
+@@ -46,6 +46,7 @@
+ 			      GParamSpec *param_spec);
+ void ags_pattern_connect(AgsConnectable *connectable);
+ void ags_pattern_disconnect(AgsConnectable *connectable);
++void ags_pattern_dispose(GObject *gobject);
+ void ags_pattern_finalize(GObject *gobject);
+ 
+ void ags_pattern_change_bpm(AgsTactable *tactable, gdouble new_bpm, gdouble old_bpm);
+@@ -148,6 +149,7 @@
+   gobject->set_property = ags_pattern_set_property;
+   gobject->get_property = ags_pattern_get_property;
+ 
++  gobject->dispose = ags_pattern_dispose;
+   gobject->finalize = ags_pattern_finalize;
+ 
+   /* properties */
+@@ -307,35 +309,29 @@
+   
+   pthread_mutex_unlock(application_mutex);
+ 
+-  /*  */
++  /* base initialization */
++  pattern->flags = 0;
++
++  /* timestamp */
+   pattern->timestamp = NULL;
+ 
++  /* dimension and pattern */
+   pattern->dim[0] = 0;
+   pattern->dim[1] = 0;
+   pattern->dim[2] = 0;
+ 
+   pattern->pattern = NULL;
+ 
++  /* port */
+   pattern->port = NULL;
+ 
++  /* indices */
+   pattern->i = 0;
+   pattern->j = 0;
+   pattern->bit = 0;
+ }
+ 
+ void
+-ags_pattern_connect(AgsConnectable *connectable)
+-{
+-  /* empty */
+-}
+-
+-void
+-ags_pattern_disconnect(AgsConnectable *connectable)
+-{
+-  /* empty */
+-}
+-
+-void
+ ags_pattern_set_property(GObject *gobject,
+ 			 guint prop_id,
+ 			 const GValue *value,
+@@ -521,23 +517,95 @@
+ }
+ 
+ void
++ags_pattern_connect(AgsConnectable *connectable)
++{
++  AgsPattern *pattern;
++
++  pattern = AGS_PATTERN(connectable);
++
++  if((AGS_PATTERN_CONNECTED & (pattern->flags)) != 0){
++    return;
++  }
++
++  pattern->flags |= AGS_PATTERN_CONNECTED;
++}
++
++void
++ags_pattern_disconnect(AgsConnectable *connectable)
++{
++  AgsPattern *pattern;
++
++  pattern = AGS_PATTERN(connectable);
++
++  if((AGS_PATTERN_CONNECTED & (pattern->flags)) == 0){
++    return;
++  }
++
++  pattern->flags &= (~AGS_PATTERN_CONNECTED);
++}
++
++void
++ags_pattern_dispose(GObject *gobject)
++{
++  AgsPattern *pattern;
++
++  pattern = AGS_PATTERN(gobject);
++
++  /* timestamp */
++  if(pattern->timestamp != NULL){
++    g_object_run_dispose(G_OBJECT(pattern->timestamp));
++    
++    g_object_unref(G_OBJECT(pattern->timestamp));
++  }
++
++  /* port */
++  if(pattern->port != NULL){
++    g_object_unref(G_OBJECT(pattern->port));
++
++    pattern->port = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_pattern_parent_class)->dispose(gobject);
++}
++
++void
+ ags_pattern_finalize(GObject *gobject)
+ {
+   AgsPattern *pattern;
++  
+   guint i, j;
+ 
+   pattern = AGS_PATTERN(gobject);
+ 
+-  for(i = 0; i < pattern->dim[0]; i++){
+-    for(j = 0; i < pattern->dim[1]; i++){
+-      free(pattern->pattern[i][j]);
+-    }
+-
+-    free(pattern->pattern[i]);
++  /* timestamp */
++  if(pattern->timestamp != NULL){
++    g_object_unref(G_OBJECT(pattern->timestamp));
+   }
+ 
+-  free(pattern->pattern);
++  /* pattern */
++  if(pattern->pattern != NULL){
++    for(i = 0; i < pattern->dim[0]; i++){
++      if(pattern->pattern[i] != NULL){
++	for(j = 0; j < pattern->dim[1]; j++){
++	  if(pattern->pattern[i][j] != NULL){
++	    free(pattern->pattern[i][j]);
++	  }
++	}
++
++	free(pattern->pattern[i]);
++      }
++    }
+ 
++    free(pattern->pattern);
++  }
++ 
++  /* port */
++  if(pattern->port != NULL){
++    g_object_unref(G_OBJECT(pattern->port));
++  }
++  
++  /* call parent */
+   G_OBJECT_CLASS(ags_pattern_parent_class)->finalize(gobject);
+ }
+ 
+@@ -570,9 +638,10 @@
+ GList*
+ ags_pattern_list_safe_properties(AgsPortlet *portlet)
+ {
+-  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+   static GList *list = NULL;
+ 
++  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
++  
+   pthread_mutex_lock(&mutex);
+ 
+   if(list == NULL){
+@@ -668,24 +737,23 @@
+   // shrink
+   if(pattern->dim[0] > dim0){
+     for(i = dim0; i < pattern->dim[0]; i++){
+-      for(j = 0; j < pattern->dim[1]; j++)
++      for(j = 0; j < pattern->dim[1]; j++){
+ 	free(pattern->pattern[i][j]);
++      }
+ 
+       free(pattern->pattern[i]);
+     }
+ 
+     if(dim0 == 0){
+       free(pattern->pattern);
+-      ags_pattern_init(pattern);
++      
++      pattern->pattern = NULL;
++      pattern->dim[0] = 0;
++
+       return;
+     }else{
+-      index0 = (guint ***) malloc((int) dim0 * sizeof(guint**));
+-
+-      for(i = 0; i < dim0; i++)
+-	index0[i] = pattern->pattern[i];
+-
+-      free(pattern->pattern);
+-      pattern->pattern = index0;
++      pattern->pattern = (guint ***) realloc(pattern->pattern,
++					     (int) dim0 * sizeof(guint **));
+ 
+       pattern->dim[0] = dim0;
+     }
+@@ -697,9 +765,13 @@
+ 	for(j = dim1; j < pattern->dim[1]; j++){
+ 	  free(pattern->pattern[i][j]);
+ 	}
++
+ 	pattern->pattern[i] = NULL;
+       }
+ 
++      pattern->dim[1] = 0;
++      
++      return;
+     }else{
+       for(i = 0; i < pattern->dim[0]; i++){
+ 	for(j = dim1; j < pattern->dim[1]; j++){
+@@ -708,87 +780,103 @@
+       }
+ 
+       for(i = 0; pattern->dim[0]; i++){
+-	index1 = (guint **) malloc(dim1 * sizeof(guint*));
++	pattern->pattern[i] = (guint **) realloc(pattern->pattern[i],
++						 dim1 * sizeof(guint *));
++      }
++
++      pattern->dim[1] = dim1;
++    }
++  }
+ 
+-	for(j = 0; j < dim1; j++){
+-	  index1[j] = pattern->pattern[i][j];
++  if(pattern->dim[2] > length){
++    if(length == 0){
++      for(i = 0; i < pattern->dim[0]; i++){
++	for(j = 0; j < pattern->dim[1]; j++){
++      	  free(pattern->pattern[i][j]);
++	  
++	  pattern->pattern[i][j] = NULL;
+ 	}
++      }
+ 
+-	free(pattern->pattern[i]);
+-	pattern->pattern[i] = index1;
++      pattern->dim[2] = 0;
++    }else{
++      for(i = 0; i < pattern->dim[0]; i++){
++	for(j = 0; j < pattern->dim[1]; j++){
++	  pattern->pattern[i][j] = (guint *) realloc(pattern->pattern[i][j],
++						     (int) ceil((double) length / (double) (sizeof(guint) * 8)) * sizeof(guint));
++	}
+       }
+-    }
+ 
+-    pattern->dim[1] = dim1;
++      pattern->dim[2] = length;
++    }
+   }
+ 
+-  if(pattern->dim[2] > length){
+-    for(i = 0; i < pattern->dim[0]; i++)
+-      for(j = 0; j < pattern->dim[1]; j++){
+-	bitmap = (guint *) malloc((int) ceil((double) length / (double) (sizeof(guint) * 8)) * sizeof(guint));
++  // grow
++  bitmap_size = (int) ceil((double) pattern->dim[2] / (double) (sizeof(guint) * 8)) * sizeof(guint);
++    
++  if(pattern->dim[0] < dim0){
++    if(pattern->pattern == NULL){
++      pattern->pattern = (guint ***) malloc(dim0 * sizeof(guint **));
++    }else{
++      pattern->pattern = (guint ***) realloc(pattern->pattern,
++					     dim0 * sizeof(guint **));
++    }
+ 
+-	for(k = 0; k < (guint) ceil((double) length / (double) (sizeof(guint) * 8)); k++)
+-	  bitmap[k] = pattern->pattern[i][j][k];
++    for(i = pattern->dim[0]; i < dim0; i++){
++      pattern->pattern[i] = (guint **) malloc(pattern->dim[1] * sizeof(guint *));
+ 
+-	free(pattern->pattern[i][j]);
+-	pattern->pattern[i][j] = bitmap;
+-      }
+-  }else if(pattern->dim[2] < length){ // grow
+-    for(i = 0; i < pattern->dim[0]; i++)
+       for(j = 0; j < pattern->dim[1]; j++){
+-	bitmap = (guint *) malloc((int) ceil((double) length / (double) (sizeof(guint) * 8)) * sizeof(guint));
+-
+-	for(k = 0; k < (guint) ceil((double) pattern->dim[2] / (double) (sizeof(guint) * 8)); k++)
+-	  bitmap[k] = pattern->pattern[i][j][k];
+-
+-	free(pattern->pattern[i][j]);
+-	pattern->pattern[i][j] = bitmap;
++	if(bitmap_size == 0){
++	  pattern->pattern[i][j] = NULL;
++	}else{
++	  pattern->pattern[i][j] = (guint *) malloc(bitmap_size);
++	  memset(pattern->pattern[i][j], 0, bitmap_size);
++	}
+       }
+-  }
++    }
+ 
+-  pattern->dim[2] = length;
+-  bitmap_size = (guint) ceil((double) pattern->dim[2] / (double) (sizeof(guint) * 8)) * sizeof(guint);
++    pattern->dim[0] = dim0;
++  }
+ 
+-  if(pattern->dim[1] < dim1){
++  if(pattern->dim[1] < dim1){  
+     for(i = 0; i < pattern->dim[0]; i++){
+-      index1 = (guint**) malloc(dim1 * sizeof(guint*));
+-
+-      for(j = 0; j < pattern->dim[1]; j++)
+-	index1[j] = pattern->pattern[i][j];
+-
+-      free(pattern->pattern[i]);
+-      pattern->pattern[i] = index1;
++      if(pattern->pattern[i] == NULL){
++	pattern->pattern[i] = (guint **) malloc(dim1 * sizeof(guint *));
++      }else{
++	pattern->pattern[i] = (guint **) realloc(pattern->pattern[i],
++						 dim1 * sizeof(guint *));
++      }
+ 
+       for(j = pattern->dim[1]; j < dim1; j++){
+-	pattern->pattern[i][j] = (guint*) malloc(bitmap_size);
+-	memset(pattern->pattern[i][j], 0, bitmap_size);
++	if(bitmap_size == 0){
++	  pattern->pattern[i][j] = NULL;
++	}else{
++	  pattern->pattern[i][j] = (guint *) malloc(bitmap_size);
++	  memset(pattern->pattern[i][j], 0, bitmap_size);
++	}
+       }
+     }
+ 
+     pattern->dim[1] = dim1;
+   }
+ 
+-  if(pattern->dim[0] < dim0){
+-    index0 = (guint***) malloc(dim0 * sizeof(guint**));
+-
+-    for(i = 0; i < pattern->dim[0]; i++)
+-      index0[i] = pattern->pattern[i];
+-
+-    if(pattern->pattern != NULL)
+-      free(pattern->pattern);
+-
+-    pattern->pattern = index0;
+-
+-    for(i = pattern->dim[0]; i < dim0; i++){
+-      pattern->pattern[i] = (guint**) malloc(pattern->dim[1] * sizeof(guint*));
+-
++  if(pattern->dim[2] < length){
++    guint new_bitmap_size;
++    
++    new_bitmap_size = (int) ceil((double) length / (double) (sizeof(guint) * 8)) * sizeof(guint);
++    
++    for(i = 0; i < pattern->dim[0]; i++){
+       for(j = 0; j < pattern->dim[1]; j++){
+-	pattern->pattern[i][j] = (guint*) malloc(bitmap_size);
+-	memset(pattern->pattern[i][j], 0, bitmap_size);
++	if(pattern->pattern[i][j] == NULL){
++	  pattern->pattern[i][j] = (guint *) malloc(new_bitmap_size);
++	  memset(pattern->pattern[i][j], 0, new_bitmap_size);
++	}else{
++	  pattern->pattern[i][j] =(guint *) realloc(pattern->pattern[i][j],
++						    new_bitmap_size);
++	  memset(pattern->pattern[i][j] + bitmap_size, 0, new_bitmap_size - bitmap_size);
++	}
+       }
+     }
+-
+-    pattern->dim[0] = dim0;
+   }
+ }
+ 
+--- a/ags/audio/ags_pattern.h
++++ b/ags/audio/ags_pattern.h
+@@ -46,10 +46,16 @@
+ typedef struct _AgsPattern AgsPattern;
+ typedef struct _AgsPatternClass AgsPatternClass;
+ 
++typedef enum{
++  AGS_PATTERN_CONNECTED   = 1,
++}AgsPatternFlags;
++
+ struct _AgsPattern
+ {
+-  GObject object;
++  GObject gobject;
+ 
++  guint flags;
++  
+   GObject *timestamp;
+ 
+   guint dim[3];
+@@ -64,7 +70,7 @@
+ 
+ struct _AgsPatternClass
+ {
+-  GObjectClass object;
++  GObjectClass gobject;
+ };
+ 
+ GType ags_pattern_get_type();
+--- a/ags/audio/ags_playback.c
++++ b/ags/audio/ags_playback.c
+@@ -39,12 +39,28 @@
+ void ags_playback_class_init(AgsPlaybackClass *playback);
+ void ags_playback_connectable_interface_init(AgsConnectableInterface *connectable);
+ void ags_playback_init(AgsPlayback *playback);
++void ags_playback_set_property(GObject *gobject,
++				      guint prop_id,
++				      const GValue *value,
++				      GParamSpec *param_spec);
++void ags_playback_get_property(GObject *gobject,
++				      guint prop_id,
++				      GValue *value,
++				      GParamSpec *param_spec);
+ void ags_playback_disconnect(AgsConnectable *connectable);
+ void ags_playback_connect(AgsConnectable *connectable);
++void ags_playback_dispose(GObject *gobject);
+ void ags_playback_finalize(GObject *gobject);
+ 
+ static gpointer ags_playback_parent_class = NULL;
+ 
++enum{
++  PROP_0,
++  PROP_PLAYBACK_DOMAIN,
++  PROP_SOURCE,
++  PROP_AUDIO_CHANNEL,
++};
++
+ GType
+ ags_playback_get_type (void)
+ {
+@@ -93,7 +109,62 @@
+   /* GObjectClass */
+   gobject = (GObjectClass *) playback;
+ 
++  gobject->set_property = ags_playback_set_property;
++  gobject->get_property = ags_playback_get_property;
++
++  gobject->dispose = ags_playback_dispose;
+   gobject->finalize = ags_playback_finalize;
++
++  /* properties */
++  /**
++   * AgsPlayback:playback-domain:
++   *
++   * The parent playback domain.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_object("playback-domain\0",
++				   "parent playback domain\0",
++				   "The playback domain it is child of\0",
++				   G_TYPE_OBJECT,
++				   G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_PLAYBACK_DOMAIN,
++				  param_spec);
++
++  /**
++   * AgsPlayback:source:
++   *
++   * The assigned source.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_object("source\0",
++				   "assigned source\0",
++				   "The source it is assigned with\0",
++				   G_TYPE_OBJECT,
++				   G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_SOURCE,
++				  param_spec);
++
++  /**
++   * AgsPlayback:audio-channel:
++   *
++   * The assigned audio channel.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_uint("audio-channel\0",
++				 "assigned audio channel\0",
++				 "The audio channel it is assigned with\0",
++				 0,
++				 G_MAXUINT,
++				 0,
++				 G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_AUDIO_CHANNEL,
++				  param_spec);
+ }
+ 
+ void
+@@ -146,17 +217,295 @@
+ }
+ 
+ void
++ags_playback_set_property(GObject *gobject,
++				 guint prop_id,
++				 const GValue *value,
++				 GParamSpec *param_spec)
++{
++  AgsPlayback *playback;
++  
++  playback = AGS_PLAYBACK(gobject);
++
++  switch(prop_id){
++  case PROP_PLAYBACK_DOMAIN:
++    {
++      GObject *playback_domain;
++
++      playback_domain = (GObject *) g_value_get_object(value);
++
++      if((GObject *) playback->playback_domain == playback_domain){
++	return;
++      }
++
++      if(playback->playback_domain != NULL){
++	g_object_unref(G_OBJECT(playback->playback_domain));
++      }
++
++      if(playback_domain != NULL){
++	g_object_ref(G_OBJECT(playback_domain));
++      }
++
++      playback->playback_domain = (GObject *) playback_domain;
++    }
++    break;
++  case PROP_SOURCE:
++    {
++      GObject *source;
++
++      source = (GObject *) g_value_get_object(value);
++
++      if(source == playback->source){
++	return;
++      }
++
++      if(playback->source != NULL){
++	g_object_unref(G_OBJECT(playback->source));
++      }
++
++      if(source != NULL){
++	g_object_ref(G_OBJECT(source));
++
++	if(AGS_IS_CHANNEL(source) &&
++	   ((AGS_PLAYBACK_SUPER_THREADED_CHANNEL & (g_atomic_int_get(&(playback->flags)))) != 0 ||
++	    (AGS_PLAYBACK_SUPER_THREADED_RECYCLING & (g_atomic_int_get(&(playback->flags)))) != 0)){
++	  gdouble freq;
++	  
++	  /* thread frequency */
++	  freq = ceil((gdouble) AGS_CHANNEL(source)->samplerate / (gdouble) AGS_CHANNEL(source)->buffer_size) + AGS_SOUNDCARD_DEFAULT_OVERCLOCK;
++
++	  /* channel thread */
++	  g_object_set(playback->channel_thread[0],
++		       "frequency\0", freq,
++		       "channel\0", source,
++		       NULL);
++
++	  g_object_set(playback->channel_thread[1],
++		       "frequency\0", freq,
++		       "channel\0", source,
++		       NULL);
++
++	  g_object_set(playback->channel_thread[2],
++		       "frequency\0", freq,
++		       "channel\0", source,
++		       NULL);
++
++	  if((AGS_PLAYBACK_SUPER_THREADED_RECYCLING & (g_atomic_int_get(&(playback->flags)))) != 0){
++	    /* recycling thread */
++	    g_object_set(playback->recycling_thread[0],
++			 "frequency\0", freq,
++			 NULL);
++
++	    g_object_set(playback->recycling_thread[1],
++			 "frequency\0", freq,
++			 NULL);
++
++	    g_object_set(playback->recycling_thread[2],
++			 "frequency\0", freq,
++			 NULL);
++
++	    /* iterator thread */
++	    g_object_set(playback->iterator_thread[0],
++			 "frequency\0", freq,
++			 NULL);
++
++	    g_object_set(playback->iterator_thread[1],
++			 "frequency\0", freq,
++			 NULL);
++
++	    g_object_set(playback->iterator_thread[2],
++			 "frequency\0", freq,
++			 NULL);
++	  }
++	}
++      }
++
++      playback->source = (GObject *) source;
++    }
++    break;
++  case PROP_AUDIO_CHANNEL:
++    {
++      playback->audio_channel = g_value_get_uint(value);
++    }
++    break;
++  default:
++    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
++    break;
++  }
++}
++
++void
++ags_playback_get_property(GObject *gobject,
++				 guint prop_id,
++				 GValue *value,
++				 GParamSpec *param_spec)
++{
++  AgsPlayback *playback;
++
++  playback = AGS_PLAYBACK(gobject);
++
++  switch(prop_id){
++  case PROP_PLAYBACK_DOMAIN:
++    {
++      g_value_set_object(value,
++			 playback->playback_domain);
++    }
++    break;
++  case PROP_SOURCE:
++    {
++      g_value_set_object(value,
++			  playback->source);
++    }
++    break;
++  case PROP_AUDIO_CHANNEL:
++    {
++      g_value_set_uint(value,
++		       playback->audio_channel);      
++    }
++    break;
++  default:
++    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
++    break;
++  }
++}
++
++void
++ags_playback_dispose(GObject *gobject)
++{
++  AgsPlayback *playback;
++
++  guint i;
++  
++  playback = AGS_PLAYBACK(gobject);
++
++  /* playback domain */
++  if(playback->playback_domain != NULL){
++    g_object_unref(playback->playback_domain);
++
++    playback->playback_domain = NULL;
++  }
++
++  /* source */
++  if(playback->source != NULL){
++    g_object_unref(playback->source);
++
++    playback->source = NULL;
++  }
++  
++  /* channel thread */
++  if(playback->channel_thread != NULL){
++    for(i = 0; i < 3; i++){
++      if(playback->channel_thread[i] != NULL){
++	g_object_run_dispose(playback->channel_thread[i]);
++	g_object_unref(playback->channel_thread[i]);
++
++	playback->channel_thread[i] = NULL;
++      }
++    }
++  }
++  
++  /* recycling thread */
++  if(playback->recycling_thread != NULL){
++    for(i = 0; i < 3; i++){
++      if(playback->recycling_thread[i] != NULL){
++	g_object_run_dispose(playback->recycling_thread[i]);
++	g_object_unref(playback->recycling_thread[i]);
++
++	playback->recycling_thread[i] = NULL;
++      }
++    }
++    
++  }
++  
++  /* iterator thread */
++  if(playback->iterator_thread != NULL){
++    for(i = 0; i < 3; i++){
++      if(playback->iterator_thread[i] != NULL){
++	g_object_run_dispose(playback->iterator_thread[i]);
++	g_object_unref(playback->iterator_thread[i]);
++
++	playback->iterator_thread[i] = NULL;
++      }
++    }
++    
++  }
++  
++  /* recall id */
++  if(playback->recall_id != NULL){
++    for(i = 0; i < 3; i++){
++      if(playback->recall_id[i] != NULL){
++	g_object_unref(playback->recall_id[i]);
++
++	playback->recall_id[i] = NULL;
++      }
++    }
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_playback_parent_class)->dispose(gobject);
++}
++
++void
+ ags_playback_finalize(GObject *gobject)
+ {
+   AgsPlayback *playback;
+ 
++  guint i;
++  
+   playback = AGS_PLAYBACK(gobject);
+ 
+-  g_object_unref(G_OBJECT(playback->iterator_thread[0]));
+-  g_object_unref(G_OBJECT(playback->iterator_thread[1]));
+-  g_object_unref(G_OBJECT(playback->iterator_thread[2]));
++  /* playback domain */
++  if(playback->playback_domain != NULL){
++    g_object_unref(playback->playback_domain);
++  }
+ 
+-  free(playback->iterator_thread);
++  /* source */
++  if(playback->source != NULL){
++    g_object_unref(playback->source);
++  }
++  
++  /* channel thread */
++  if(playback->channel_thread != NULL){
++    for(i = 0; i < 3; i++){
++      if(playback->channel_thread[i] != NULL){
++	g_object_unref(playback->channel_thread[i]);
++      }
++    }
++    
++    free(playback->channel_thread);
++  }
++  
++  /* recycling thread */
++  if(playback->recycling_thread != NULL){
++    for(i = 0; i < 3; i++){
++      if(playback->recycling_thread[i] != NULL){
++	g_object_unref(playback->recycling_thread[i]);
++      }
++    }
++    
++    free(playback->recycling_thread);
++  }
++  
++  /* iterator thread */
++  if(playback->iterator_thread != NULL){
++    for(i = 0; i < 3; i++){
++      if(playback->iterator_thread[i] != NULL){
++	g_object_unref(playback->iterator_thread[i]);
++      }
++    }
++    
++    free(playback->iterator_thread);
++  }
++  
++  /* recall id */
++  if(playback->recall_id != NULL){
++    for(i = 0; i < 3; i++){
++      if(playback->recall_id[i] != NULL){
++	g_object_unref(playback->recall_id[i]);
++      }
++    }
++    
++    free(playback->recall_id);
++  }
+ 
+   /* call parent */
+   G_OBJECT_CLASS(ags_playback_parent_class)->finalize(gobject);
+@@ -165,13 +514,250 @@
+ void
+ ags_playback_connect(AgsConnectable *connectable)
+ {
+-  //TODO:JK: implement me
++  AgsPlayback *playback;
++
++  playback = AGS_PLAYBACK(connectable);
++
++  if((AGS_PLAYBACK_CONNECTED & (playback->flags)) != 0){
++    return;
++  }
++
++  playback->flags |= AGS_PLAYBACK_CONNECTED;
+ }
+ 
+ void
+ ags_playback_disconnect(AgsConnectable *connectable)
+ {
+-  //TODO:JK: implement me
++  AgsPlayback *playback;
++
++  playback = AGS_PLAYBACK(connectable);
++
++
++  if((AGS_PLAYBACK_CONNECTED & (playback->flags)) == 0){
++    return;
++  }
++
++  playback->flags &= (~AGS_PLAYBACK_CONNECTED);
++}
++
++/**
++ * ags_playback_set_channel_thread:
++ * @playback: the #AgsPlayback
++ * @thread: the #AgsChannelThread
++ * @scope: the scope of the thread to set
++ * 
++ * Set channel thread of appropriate scope.
++ * 
++ * Since: 0.7.122.7
++ */
++void
++ags_playback_set_channel_thread(AgsPlayback *playback,
++				AgsThread *thread,
++				guint scope)
++{
++  if(playback == NULL ||
++     scope > 2){
++    return;
++  }
++
++  if(playback->channel_thread[scope] != NULL){
++    g_object_unref(playback->channel_thread[scope]);
++  }
++
++  if(thread != NULL){
++    g_object_ref(thread);
++  }
++  
++  playback->channel_thread[scope] = thread;
++}
++
++/**
++ * ags_playback_get_channel_thread:
++ * @playback: the #AgsPlayback
++ * @scope: the scope of the thread to get
++ * 
++ * Get channel thread of appropriate scope.
++ * 
++ * Returns: the matching #AgsThread or %NULL
++ * 
++ * Since: 0.7.122.7
++ */
++AgsThread*
++ags_playback_get_channel_thread(AgsPlayback *playback,
++				guint scope)
++{
++  if(playback == NULL ||
++     playback->channel_thread == NULL ||
++     scope > 2){
++    return(NULL);
++  }
++
++  return(playback->channel_thread[scope]);
++}
++
++/**
++ * ags_playback_set_iterator_thread:
++ * @playback: the #AgsPlayback
++ * @thread: the #AgsIteratorThread
++ * @scope: the scope of the thread to set
++ * 
++ * Set iterator thread of appropriate scope.
++ * 
++ * Since: 0.7.122.7
++ */
++void
++ags_playback_set_iterator_thread(AgsPlayback *playback,
++				 AgsThread *thread,
++				 guint scope)
++{
++  if(playback == NULL ||
++     scope > 2){
++    return;
++  }
++
++  if(playback->iterator_thread[scope] != NULL){
++    g_object_unref(playback->iterator_thread[scope]);
++  }
++
++  if(thread != NULL){
++    g_object_ref(thread);
++  }
++  
++  playback->iterator_thread[scope] = thread;
++}
++
++/**
++ * ags_playback_get_iterator_thread:
++ * @playback: the #AgsPlayback
++ * @scope: the scope of the thread to get
++ * 
++ * Get iterator thread of appropriate scope.
++ * 
++ * Returns: the matching #AgsThread or %NULL
++ * 
++ * Since: 0.7.122.7
++ */
++AgsThread*
++ags_playback_get_iterator_thread(AgsPlayback *playback,
++				 guint scope)
++{
++  if(playback == NULL ||
++     playback->iterator_thread == NULL ||
++     scope > 2){
++    return(NULL);
++  }
++
++  return(playback->iterator_thread[scope]);
++}
++
++/**
++ * ags_playback_set_recycling_thread:
++ * @playback: the #AgsPlayback
++ * @thread: the #AgsRecyclingThread
++ * @scope: the scope of the thread to set
++ * 
++ * Set recycling thread of appropriate scope.
++ * 
++ * Since: 0.7.122.7
++ */
++void
++ags_playback_set_recycling_thread(AgsPlayback *playback,
++				  AgsThread *thread,
++				  guint scope)
++{
++  if(playback == NULL ||
++     scope > 2){
++    return;
++  }
++
++  if(playback->recycling_thread[scope] != NULL){
++    g_object_unref(playback->recycling_thread[scope]);
++  }
++
++  if(thread != NULL){
++    g_object_ref(thread);
++  }
++  
++  playback->recycling_thread[scope] = thread;
++}
++
++/**
++ * ags_playback_get_recycling_thread:
++ * @playback: the #AgsPlayback
++ * @scope: the scope of the thread to get
++ * 
++ * Get recycling thread of appropriate scope.
++ * 
++ * Returns: the matching #AgsThread or %NULL
++ * 
++ * Since: 0.7.122.7
++ */
++AgsThread*
++ags_playback_get_recycling_thread(AgsPlayback *playback,
++				  guint scope)
++{
++  if(playback == NULL ||
++     playback->recycling_thread == NULL ||
++     scope > 2){
++    return(NULL);
++  }
++
++  return(playback->recycling_thread[scope]);
++}
++
++/**
++ * ags_playback_set_recall_id:
++ * @playback: the #AgsPlayback
++ * @recall_id: the #AgsRecallID
++ * @scope: the scope of the recall id to set
++ * 
++ * Set recall id of appropriate scope.
++ * 
++ * Since: 0.7.122.7
++ */
++void
++ags_playback_set_recall_id(AgsPlayback *playback,
++			   AgsRecallID *recall_id,
++			   guint scope)
++{
++  if(playback == NULL ||
++     scope > 2){
++    return;
++  }
++
++  if(playback->recall_id[scope] != NULL){
++    g_object_unref(playback->recall_id[scope]);
++  }
++
++  if(recall_id != NULL){
++    g_object_ref(recall_id);
++  }
++  
++  playback->recall_id[scope] = recall_id;
++}
++
++/**
++ * ags_playback_get_recall_id:
++ * @playback: the #AgsPlayback
++ * @scope: the scope of the recall id to get
++ * 
++ * Get recall id of appropriate scope.
++ * 
++ * Returns: the matching #AgsRecallID or %NULL
++ * 
++ * Since: 0.7.122.7
++ */
++AgsRecallID*
++ags_playback_get_recall_id(AgsPlayback *playback,
++			   guint scope)
++{
++  if(playback == NULL ||
++     playback->recall_id == NULL ||
++     scope > 2){
++    return(NULL);
++  }
++
++  return(playback->recall_id[scope]);
+ }
+ 
+ /**
+--- a/ags/audio/ags_playback.h
++++ b/ags/audio/ags_playback.h
+@@ -31,8 +31,6 @@
+ 
+ #include <ags/audio/ags_recall_id.h>
+ 
+-#include <ags/audio/thread/ags_iterator_thread.h>
+-
+ #define AGS_TYPE_PLAYBACK                (ags_playback_get_type())
+ #define AGS_PLAYBACK(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_PLAYBACK, AgsPlayback))
+ #define AGS_PLAYBACK_CLASS(class)        (G_TYPE_CHECK_CLASS_CAST(class, AGS_TYPE_PLAYBACK, AgsPlayback))
+@@ -43,35 +41,43 @@
+ typedef struct _AgsPlayback AgsPlayback;
+ typedef struct _AgsPlaybackClass AgsPlaybackClass;
+ 
+-typedef enum
+-{
+-  AGS_PLAYBACK_DONE                         = 1,
+-  AGS_PLAYBACK_REMOVE                       = 1 <<  1,
+-  AGS_PLAYBACK_CHANNEL                      = 1 <<  2,
+-  AGS_PLAYBACK_PAD                          = 1 <<  3,
+-  AGS_PLAYBACK_AUDIO                        = 1 <<  4,
+-  AGS_PLAYBACK_PLAYBACK                     = 1 <<  5,
+-  AGS_PLAYBACK_SEQUENCER                    = 1 <<  6,
+-  AGS_PLAYBACK_NOTATION                     = 1 <<  7,
+-  AGS_PLAYBACK_SINGLE_THREADED              = 1 <<  8,
+-  AGS_PLAYBACK_SUPER_THREADED_CHANNEL       = 1 <<  9,
+-  AGS_PLAYBACK_SUPER_THREADED_RECYCLING     = 1 << 10,
++typedef enum{
++  AGS_PLAYBACK_CONNECTED                    = 1,
++  AGS_PLAYBACK_DONE                         = 1 <<  1,
++  AGS_PLAYBACK_REMOVE                       = 1 <<  2,
++  AGS_PLAYBACK_CHANNEL                      = 1 <<  3,
++  AGS_PLAYBACK_PAD                          = 1 <<  4,
++  AGS_PLAYBACK_AUDIO                        = 1 <<  5,
++  AGS_PLAYBACK_PLAYBACK                     = 1 <<  6,
++  AGS_PLAYBACK_SEQUENCER                    = 1 <<  7,
++  AGS_PLAYBACK_NOTATION                     = 1 <<  8,
++  AGS_PLAYBACK_SINGLE_THREADED              = 1 <<  9,
++  AGS_PLAYBACK_SUPER_THREADED_CHANNEL       = 1 << 10,
++  AGS_PLAYBACK_SUPER_THREADED_RECYCLING     = 1 << 11,
+ }AgsPlaybackFlags;
+ 
++typedef enum{
++  AGS_PLAYBACK_SCOPE_PLAYBACK,
++  AGS_PLAYBACK_SCOPE_SEQUENCER,
++  AGS_PLAYBACK_SCOPE_NOTATION,  
++}AgsPlaybackScope;
++
+ struct _AgsPlayback
+ {
+   GObject gobject;
+   
+   volatile guint flags;
+ 
+-  AgsThread **channel_thread;
+-  AgsIteratorThread **iterator_thread;
+-
+-  AgsThread **recycling_thread;
++  GObject *playback_domain;
+   
+   GObject *source;
+   guint audio_channel;
+ 
++  AgsThread **channel_thread;
++  AgsThread **iterator_thread;
++
++  AgsThread **recycling_thread;
++  
+   AgsRecallID **recall_id;
+ };
+ 
+@@ -82,9 +88,36 @@
+ 
+ GType ags_playback_get_type();
+ 
++/* get and set */
++void ags_playback_set_channel_thread(AgsPlayback *playback,
++				     AgsThread *thread,
++				     guint scope);
++AgsThread* ags_playback_get_channel_thread(AgsPlayback *playback,
++					   guint scope);
++
++void ags_playback_set_iterator_thread(AgsPlayback *playback,
++				      AgsThread *thread,
++				      guint scope);
++AgsThread* ags_playback_get_iterator_thread(AgsPlayback *playback,
++					    guint scope);
++
++void ags_playback_set_recycling_thread(AgsPlayback *playback,
++				       AgsThread *thread,
++				       guint scope);
++AgsThread* ags_playback_get_recycling_thread(AgsPlayback *playback,
++					     guint scope);
++
++void ags_playback_set_recall_id(AgsPlayback *playback,
++				AgsRecallID *recall_id,
++				guint scope);
++AgsRecallID* ags_playback_get_recall_id(AgsPlayback *playback,
++					guint scope);
++
++/* find */
+ AgsPlayback* ags_playback_find_source(GList *playback,
+ 				      GObject *source);
+ 
++/* instance */
+ AgsPlayback* ags_playback_new();
+ 
+ #endif /*__AGS_PLAYBACK_H__*/
+--- a/ags/audio/ags_playback_domain.c
++++ b/ags/audio/ags_playback_domain.c
+@@ -19,7 +19,12 @@
+ 
+ #include <ags/audio/ags_playback_domain.h>
+ 
++#include <ags/object/ags_config.h>
+ #include <ags/object/ags_connectable.h>
++#include <ags/object/ags_soundcard.h>
++
++#include <ags/audio/ags_audio.h>
++#include <ags/audio/ags_playback.h>
+ 
+ #include <ags/audio/thread/ags_audio_thread.h>
+ 
+@@ -36,12 +41,27 @@
+ void ags_playback_domain_class_init(AgsPlaybackDomainClass *playback_domain);
+ void ags_playback_domain_connectable_interface_init(AgsConnectableInterface *connectable);
+ void ags_playback_domain_init(AgsPlaybackDomain *playback_domain);
++void ags_playback_domain_set_property(GObject *gobject,
++				      guint prop_id,
++				      const GValue *value,
++				      GParamSpec *param_spec);
++void ags_playback_domain_get_property(GObject *gobject,
++				      guint prop_id,
++				      GValue *value,
++				      GParamSpec *param_spec);
+ void ags_playback_domain_disconnect(AgsConnectable *connectable);
+ void ags_playback_domain_connect(AgsConnectable *connectable);
++void ags_playback_domain_dispose(GObject *gobject);
+ void ags_playback_domain_finalize(GObject *gobject);
+ 
+ static gpointer ags_playback_domain_parent_class = NULL;
+ 
++enum{
++  PROP_0,
++  PROP_DOMAIN,
++  PROP_PLAYBACK,
++};
++
+ GType
+ ags_playback_domain_get_type (void)
+ {
+@@ -90,7 +110,44 @@
+   /* GObjectClass */
+   gobject = (GObjectClass *) playback_domain;
+ 
++  gobject->set_property = ags_playback_domain_set_property;
++  gobject->get_property = ags_playback_domain_get_property;
++
++  gobject->dispose = ags_playback_domain_dispose;
+   gobject->finalize = ags_playback_domain_finalize;
++
++  /* properties */
++  /**
++   * AgsPlaybackDomain:domain:
++   *
++   * The assigned domain.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_object("domain\0",
++				   "assigned domain\0",
++				   "The domain it is assigned with\0",
++				   G_TYPE_OBJECT,
++				   G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_DOMAIN,
++				  param_spec);
++
++  /**
++   * AgsPlaybackDomain:playback:
++   *
++   * The assigned playback.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_object("playback\0",
++				   "assigned playback\0",
++				   "The playback it is assigned with\0",
++				   G_TYPE_OBJECT,
++				   G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_PLAYBACK,
++				  param_spec);
+ }
+ 
+ void
+@@ -105,9 +162,60 @@
+ void
+ ags_playback_domain_init(AgsPlaybackDomain *playback_domain)
+ {
++  AgsConfig *config;
++
++  gchar *str, *str0, *str1;
++
++  gboolean super_threaded_audio;
++  
++  /* config */
++  config = ags_config_get_instance();
++
++  /* thread model */
++  str0 = ags_config_get_value(config,
++			      AGS_CONFIG_THREAD,
++			      "model\0");
++  str1 = ags_config_get_value(config,
++			      AGS_CONFIG_THREAD,
++			      "super-threaded-scope\0");
++
++  if(str0 != NULL && str1 != NULL){
++    if(!g_ascii_strncasecmp(str0,
++			    "super-threaded\0",
++			    15)){
++      if(!g_ascii_strncasecmp(str1,
++			      "audio\0",
++			      6) ||
++	 !g_ascii_strncasecmp(str1,
++			      "channel\0",
++			      8) ||
++	 !g_ascii_strncasecmp(str1,
++			      "recycling\0",
++			      10)){
++	super_threaded_audio = TRUE;
++      }
++    }
++  }
++  
++  if(str0 != NULL){
++    free(str0);
++  }
++
++  if(str1 != NULL){
++    free(str1);
++  }
++  
+   /* default flags */
+-  g_atomic_int_set(&(playback_domain->flags),
+-		   AGS_PLAYBACK_DOMAIN_SUPER_THREADED_AUDIO);
++  if(super_threaded_audio){
++    g_atomic_int_set(&(playback_domain->flags),
++		     AGS_PLAYBACK_DOMAIN_SUPER_THREADED_AUDIO);
++  }else{
++    g_atomic_int_set(&(playback_domain->flags),
++		     0);
++  }
++
++  /* domain */
++  playback_domain->domain = NULL;
+ 
+   /* super threaded audio */
+   playback_domain->audio_thread = (AgsThread **) malloc(3 * sizeof(AgsThread *));
+@@ -115,20 +223,248 @@
+   playback_domain->audio_thread[0] = NULL;
+   playback_domain->audio_thread[1] = NULL;
+   playback_domain->audio_thread[2] = NULL;
++  
++  if(super_threaded_audio){
++    guint samplerate, buffer_size;
++    gdouble freq;
++    
++    samplerate = AGS_SOUNDCARD_DEFAULT_SAMPLERATE;
++    buffer_size = AGS_SOUNDCARD_DEFAULT_BUFFER_SIZE;
++
++    /* samplerate */
++    str = ags_config_get_value(config,
++			       AGS_CONFIG_SOUNDCARD,
++			       "samplerate\0");
++
++    if(str == NULL){
++      str = ags_config_get_value(config,
++				 AGS_CONFIG_SOUNDCARD_0,
++				 "samplerate\0");
++    }
++  
++    if(str != NULL){
++      samplerate = g_ascii_strtoull(str,
++				    NULL,
++				    10);
++
++      free(str);
++    }
++
++    /* buffer size */
++    str = ags_config_get_value(config,
++			       AGS_CONFIG_SOUNDCARD,
++			       "buffer-size\0");
++
++    if(str == NULL){
++      str = ags_config_get_value(config,
++				 AGS_CONFIG_SOUNDCARD_0,
++				 "buffer-size\0");
++    }
++  
++    if(str != NULL){
++      buffer_size = g_ascii_strtoull(str,
++				     NULL,
++				     10);
++
++      free(str);
++    }
++
++    /* thread frequency */
++    freq = ceil((gdouble) samplerate / (gdouble) buffer_size) + AGS_SOUNDCARD_DEFAULT_OVERCLOCK;
++
++    /* playback audio thread */
++    playback_domain->audio_thread[0] = (AgsThread *) ags_audio_thread_new(NULL,
++									  NULL);
++    g_object_ref(playback_domain->audio_thread[0]);
++    playback_domain->audio_thread[0]->freq = freq;
++
++    /* sequencer audio thread */
++    playback_domain->audio_thread[1] = (AgsThread *) ags_audio_thread_new(NULL,
++									  NULL);
++    g_object_ref(playback_domain->audio_thread[1]);
++    playback_domain->audio_thread[1]->freq = freq;
++
++    /* notation audio thread */
++    playback_domain->audio_thread[2] = (AgsThread *) ags_audio_thread_new(NULL,
++									  NULL);
++    g_object_ref(playback_domain->audio_thread[2]);
++    playback_domain->audio_thread[2]->freq = freq;
++  }
+ 
+-  playback_domain->domain = NULL;
++  /* playback */
+   playback_domain->playback = NULL;
+ }
+ 
+ void
++ags_playback_domain_set_property(GObject *gobject,
++				 guint prop_id,
++				 const GValue *value,
++				 GParamSpec *param_spec)
++{
++  AgsPlaybackDomain *playback_domain;
++  
++  playback_domain = AGS_PLAYBACK_DOMAIN(gobject);
++
++  switch(prop_id){
++  case PROP_DOMAIN:
++    {
++      GObject *domain;
++
++      domain = (GObject *) g_value_get_object(value);
++
++      if((GObject *) playback_domain->domain == domain){
++	return;
++      }
++
++      if(playback_domain->domain != NULL){
++	g_object_unref(G_OBJECT(playback_domain->domain));
++      }
++
++      if(domain != NULL){
++	g_object_ref(G_OBJECT(domain));
++
++	if(AGS_IS_AUDIO(domain) &&
++	   (AGS_PLAYBACK_DOMAIN_SUPER_THREADED_AUDIO & (g_atomic_int_get(&(playback_domain->flags)))) != 0){
++	  gdouble freq;
++	  
++	  /* thread frequency */
++	  freq = ceil((gdouble) AGS_AUDIO(domain)->samplerate / (gdouble) AGS_AUDIO(domain)->buffer_size) + AGS_SOUNDCARD_DEFAULT_OVERCLOCK;
++
++	  g_object_set(playback_domain->audio_thread[0],
++		       "frequency\0", freq,
++		       "audio\0", domain,
++		       NULL);
++
++	  g_object_set(playback_domain->audio_thread[1],
++		       "frequency\0", freq,
++		       "audio\0", domain,
++		       NULL);
++
++	  g_object_set(playback_domain->audio_thread[2],
++		       "frequency\0", freq,
++		       "audio\0", domain,
++		       NULL);
++	}
++      }
++
++      playback_domain->domain = (GObject *) domain;
++    }
++    break;
++  case PROP_PLAYBACK:
++    {
++      AgsPlayback *playback;
++
++      playback = (AgsPlayback *) g_value_get_object(value);
++
++      if(playback == NULL ||
++	 g_list_find(playback_domain->playback, playback) != NULL){
++	return;
++      }
++
++      ags_playback_domain_add_playback(playback_domain,
++				       (GObject *) playback);
++    }
++    break;
++  default:
++    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
++    break;
++  }
++}
++
++void
++ags_playback_domain_get_property(GObject *gobject,
++				 guint prop_id,
++				 GValue *value,
++				 GParamSpec *param_spec)
++{
++  AgsPlaybackDomain *playback_domain;
++
++  playback_domain = AGS_PLAYBACK_DOMAIN(gobject);
++
++  switch(prop_id){
++  case PROP_DOMAIN:
++    {
++      g_value_set_object(value,
++			 playback_domain->domain);
++    }
++    break;
++  case PROP_PLAYBACK:
++    {
++      g_value_set_pointer(value,
++			  g_list_copy(playback_domain->playback));
++    }
++    break;
++  default:
++    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
++    break;
++  }
++}
++
++void
++ags_playback_domain_dispose(GObject *gobject)
++{
++  AgsPlaybackDomain *playback_domain;
++
++  guint i;
++  
++  playback_domain = AGS_PLAYBACK_DOMAIN(gobject);
++  
++  if(playback_domain->audio_thread != NULL){
++    for(i = 0; i < 3; i++){
++      if(playback_domain->audio_thread[i] != NULL){
++	g_object_run_dispose(playback_domain->audio_thread[i]);
++	g_object_unref(playback_domain->audio_thread[i]);
++
++	playback_domain->audio_thread[i] = NULL;
++      }
++    }
++  }
++
++  /* domain */
++  if(playback_domain->domain != NULL){
++    g_object_unref(playback_domain->domain);
++
++    playback_domain->domain = NULL;
++  }
++
++  /* playback */
++  if(playback_domain->playback != NULL){
++    g_list_free_full(playback_domain->playback,
++		     g_object_unref);
++    
++    playback_domain->playback = NULL;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_playback_domain_parent_class)->dispose(gobject);
++}
++
++void
+ ags_playback_domain_finalize(GObject *gobject)
+ {
+   AgsPlaybackDomain *playback_domain;
+ 
++  guint i;
++  
+   playback_domain = AGS_PLAYBACK_DOMAIN(gobject);
+ 
+-  free(playback_domain->audio_thread);
++  /* audio thread */
++  if(playback_domain->audio_thread != NULL){
++    for(i = 0; i < 3; i++){
++      if(playback_domain->audio_thread[i] != NULL){
++	g_object_unref(playback_domain->audio_thread[i]);
++      }
++    }
++    
++    free(playback_domain->audio_thread);
++  }
++
++  /* domain */
++  if(playback_domain->domain != NULL){
++    g_object_unref(playback_domain->domain);
++  }
+   
++  /* playback */
+   g_list_free_full(playback_domain->playback,
+ 		   g_object_unref);
+ 
+@@ -139,13 +475,133 @@
+ void
+ ags_playback_domain_connect(AgsConnectable *connectable)
+ {
+-  //TODO:JK: implement me
++  AgsPlaybackDomain *playback_domain;
++
++  playback_domain = AGS_PLAYBACK_DOMAIN(connectable);
++
++  if((AGS_PLAYBACK_DOMAIN_CONNECTED & (playback_domain->flags)) != 0){
++    return;
++  }
++
++  playback_domain->flags |= AGS_PLAYBACK_DOMAIN_CONNECTED;
+ }
+ 
+ void
+ ags_playback_domain_disconnect(AgsConnectable *connectable)
+ {
+-  //TODO:JK: implement me
++  AgsPlaybackDomain *playback_domain;
++
++  playback_domain = AGS_PLAYBACK_DOMAIN(connectable);
++
++
++  if((AGS_PLAYBACK_DOMAIN_CONNECTED & (playback_domain->flags)) == 0){
++    return;
++  }
++
++  playback_domain->flags &= (~AGS_PLAYBACK_DOMAIN_CONNECTED);
++}
++
++/**
++ * ags_playback_domain_set_audio_thread:
++ * @playback_domain: the #AgsPlaybackDomain
++ * @thread: the #AgsThread
++ * @scope: the thread's scope
++ * 
++ * Set audio thread to specified scope.
++ * 
++ * Since: 0.7.122.7
++ */
++void
++ags_playback_domain_set_audio_thread(AgsPlaybackDomain *playback_domain,
++				     AgsThread *thread,
++				     guint scope)
++{
++  if(playback_domain == NULL ||
++     scope > 2){
++    return;
++  }
++
++  if(playback_domain->audio_thread[scope] != NULL){
++    g_object_unref(playback_domain->audio_thread[scope]);
++  }
++
++  if(thread != NULL){
++    g_object_ref(thread);
++  }
++  
++  playback_domain->audio_thread[scope] = thread;
++}
++
++/**
++ * ags_playback_domain_set_audio_thread:
++ * @playback_domain: the #AgsPlaybackDomain
++ * @scope: the thread's scope
++ * 
++ * Get audio thread of specified scope.
++ * 
++ * Returns: the matching #AgsThread or %NULL
++ * 
++ * Since: 0.7.122.7
++ */
++AgsThread*
++ags_playback_domain_get_audio_thread(AgsPlaybackDomain *playback_domain,
++				     guint scope)
++{
++  if(playback_domain == NULL ||
++     playback_domain->audio_thread == NULL ||
++     scope > 2){
++    return(NULL);
++  }
++
++  return(playback_domain->audio_thread[scope]);
++}
++
++
++/**
++ * ags_playback_domain_add_playback:
++ * @playback_domain: the #AgsPlaybackDomain
++ * @playback: the #AgsPlayback
++ * 
++ * Add @playback to @playback_domain.
++ * 
++ * Since: 0.7.122.7
++ */
++void
++ags_playback_domain_add_playback(AgsPlaybackDomain *playback_domain,
++				 GObject *playback)
++{
++  if(playback_domain == NULL ||
++     playback == NULL){
++    return;
++  }
++
++  //TODO:JK: rather use prepend but needs refactoring
++  g_object_ref(playback);
++  playback_domain->playback = g_list_append(playback_domain->playback,
++					    playback);
++}
++
++/**
++ * ags_playback_domain_remove_playback:
++ * @playback_domain: the #AgsPlaybackDomain
++ * @playback: the #AgsPlayback
++ * 
++ * Remove @playback of @playback_domain.
++ * 
++ * Since: 0.7.122.7
++ */
++void
++ags_playback_domain_remove_playback(AgsPlaybackDomain *playback_domain,
++				    GObject *playback)
++{
++  if(playback_domain == NULL ||
++     playback == NULL){
++    return;
++  }
++
++  playback_domain->playback = g_list_remove(playback_domain->playback,
++					    playback);
++  g_object_unref(playback);
+ }
+ 
+ /**
+--- a/ags/audio/ags_playback_domain.h
++++ b/ags/audio/ags_playback_domain.h
+@@ -40,22 +40,30 @@
+ typedef struct _AgsPlaybackDomainClass AgsPlaybackDomainClass;
+ 
+ typedef enum{
+-  AGS_PLAYBACK_DOMAIN_PLAYBACK                   = 1,
+-  AGS_PLAYBACK_DOMAIN_SEQUENCER                  = 1 <<  1,
+-  AGS_PLAYBACK_DOMAIN_NOTATION                   = 1 <<  2,
+-  AGS_PLAYBACK_DOMAIN_SINGLE_THREADED            = 1 <<  3,
+-  AGS_PLAYBACK_DOMAIN_SUPER_THREADED_AUDIO       = 1 <<  4,
++  AGS_PLAYBACK_DOMAIN_CONNECTED                  = 1,
++  AGS_PLAYBACK_DOMAIN_PLAYBACK                   = 1 <<  1,
++  AGS_PLAYBACK_DOMAIN_SEQUENCER                  = 1 <<  2,
++  AGS_PLAYBACK_DOMAIN_NOTATION                   = 1 <<  3,
++  AGS_PLAYBACK_DOMAIN_SINGLE_THREADED            = 1 <<  4,
++  AGS_PLAYBACK_DOMAIN_SUPER_THREADED_AUDIO       = 1 <<  5,
+ }AgsPlaybackDomainFlags;
+ 
++typedef enum{
++  AGS_PLAYBACK_DOMAIN_SCOPE_PLAYBACK,
++  AGS_PLAYBACK_DOMAIN_SCOPE_SEQUENCER,
++  AGS_PLAYBACK_DOMAIN_SCOPE_NOTATION,  
++}AgsPlaybackDomainScope;
++
+ struct _AgsPlaybackDomain
+ {
+   GObject gobject;
+ 
+   volatile guint flags;
++  
++  GObject *domain;
+ 
+   AgsThread **audio_thread;
+ 
+-  GObject *domain;
+   GList *playback;
+ };
+ 
+@@ -66,6 +74,20 @@
+ 
+ GType ags_playback_domain_get_type();
+ 
++/* get and set */
++void ags_playback_domain_set_audio_thread(AgsPlaybackDomain *playback_domain,
++					  AgsThread *thread,
++					  guint scope);
++AgsThread* ags_playback_domain_get_audio_thread(AgsPlaybackDomain *playback_domain,
++						guint scope);
++
++/* add and remove */
++void ags_playback_domain_add_playback(AgsPlaybackDomain *playback_domain,
++				      GObject *playback);
++void ags_playback_domain_remove_playback(AgsPlaybackDomain *playback_domain,
++					 GObject *playback);
++
++/* instance */
+ AgsPlaybackDomain* ags_playback_domain_new();
+ 
+ #endif /*__AGS_PLAYBACK_DOMAIN_H__*/
+--- a/ags/audio/ags_recall.c
++++ b/ags/audio/ags_recall.c
+@@ -96,7 +96,8 @@
+ GList* ags_recall_get_ports(AgsPlugin *plugin);
+ void ags_recall_read(AgsFile *file, xmlNode *node, AgsPlugin *plugin);
+ xmlNode* ags_recall_write(AgsFile *file, xmlNode *parent, AgsPlugin *plugin);
+-void ags_recall_finalize(GObject *recall);
++void ags_recall_dispose(GObject *gobject);
++void ags_recall_finalize(GObject *gobject);
+ 
+ void ags_recall_real_load_automation(AgsRecall *recall,
+ 				     GList *automation_port);
+@@ -250,6 +251,7 @@
+   gobject->set_property = ags_recall_set_property;
+   gobject->get_property = ags_recall_get_property;
+ 
++  gobject->dispose = ags_recall_dispose;
+   gobject->finalize = ags_recall_finalize;
+ 
+   /* properties */
+@@ -902,18 +904,39 @@
+   case PROP_PARENT:
+     {
+       AgsRecall *parent;
+-
++      
+       parent = (AgsRecall *) g_value_get_object(value);
+ 
+-      ags_recall_add_child(parent, recall);
++      if(recall->parent == parent){
++	return;
++      }
++
++      if(recall->parent != NULL){
++	g_object_unref(recall->parent);
++      }
++
++      if(parent != NULL){
++	g_object_ref(parent);
++      }
++      
++      recall->parent = parent;
+     }
+     break;
+   case PROP_CHILD:
+     {
+       AgsRecall *child;
+ 
++      gboolean child_added;
++      
+       child = (AgsRecall *) g_value_get_object(value);
+ 
++      child_added = (g_list_find(recall->children, child) != NULL) ? TRUE: FALSE;
++
++      if(child == NULL ||
++	 child_added){
++	return;
++      }
++      
+       ags_recall_add_child(recall, child);
+     }
+     break;
+@@ -1297,6 +1320,81 @@
+ }
+ 
+ void
++ags_recall_dispose(GObject *gobject)
++{
++  AgsRecall *recall;
++
++  GList *list, *list_next;
++
++  recall = AGS_RECALL(gobject);
++
++  /* soundcard */
++  if(recall->soundcard != NULL){
++    g_object_unref(recall->soundcard);
++
++    recall->soundcard = NULL;
++  }
++
++  /* dependency */
++  if(recall->dependencies != NULL){
++    g_list_free_full(recall->dependencies,
++		     g_object_unref);
++
++    recall->dependencies = NULL;
++  }
++  
++  /* recall id */
++  if(recall->recall_id != NULL){
++    g_object_unref(recall->recall_id);
++
++    recall->recall_id = NULL;
++  }
++  
++  /* children */
++  if(recall->children != NULL){
++    list = recall->children;
++
++    while(list != NULL){
++      list_next = list->next;
++      
++      g_object_run_dispose(G_OBJECT(list->data));
++
++      list = list_next;
++    }
++    
++    g_list_free_full(recall->children,
++		     g_object_unref);
++
++    recall->children = NULL;
++  }
++  
++  if(recall->container != NULL){
++    ags_packable_unpack(AGS_PACKABLE(recall));
++
++    recall->container = NULL;
++  }
++
++  /* port */
++  if(recall->port != NULL){
++    g_list_free_full(recall->port,
++		     g_object_unref);
++
++    recall->port = NULL;
++  }
++  
++  /* parent */
++  if(recall->parent != NULL){
++    ags_recall_remove_child(recall->parent,
++			    recall);
++
++    recall->parent = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_recall_parent_class)->dispose(gobject);
++}
++
++void
+ ags_recall_finalize(GObject *gobject)
+ {
+   AgsRecall *recall;
+@@ -1324,7 +1422,8 @@
+   }
+ 
+   g_free(ids);
+-  
++
++  /* soundcard */
+   if(recall->soundcard != NULL){
+     g_object_unref(recall->soundcard);
+   }
+@@ -1333,9 +1432,16 @@
+     //    g_free(recall->name);
+   //  }
+ 
++  /* dependency */
+   g_list_free_full(recall->dependencies,
+ 		   g_object_unref);
+ 
++  /* recall id */
++  if(recall->recall_id != NULL){
++    g_object_unref(recall->recall_id);
++  }
++  
++  /* children */
+   g_list_free_full(recall->children,
+ 		   g_object_unref);
+   
+@@ -1348,9 +1454,11 @@
+     g_free(recall->child_parameters);
+   }
+ 
++  /* port */
+   g_list_free_full(recall->port,
+ 		   g_object_unref);
+ 
++  /* parent */
+   if(recall->parent != NULL){
+     ags_recall_remove_child(recall->parent,
+ 			    recall);
+@@ -1890,22 +1998,22 @@
+ ags_recall_real_remove(AgsRecall *recall)
+ {
+   AgsRecall *parent;
+-
+-  if(recall == NULL){
+-    return;
+-  }
+   
+   g_object_ref(recall);
+ 
+   if(recall->parent == NULL){
+-    parent = NULL;
++    g_object_run_dispose(recall);
+     g_object_unref(recall);
++    
+     return;
+   }else{
+     parent = AGS_RECALL(recall->parent);
+ 
+     ags_recall_remove_child(parent,
+ 			    recall);
++
++    g_object_run_dispose(recall);
++    g_object_unref(recall);
+   }
+ 
+   /* propagate done */
+@@ -2227,10 +2335,12 @@
+ ags_recall_add_child(AgsRecall *parent, AgsRecall *child)
+ {
+   guint inheritated_flags_mask;
+-
++  
+   if(child == NULL ||
+-     child->parent == parent)
++     parent == NULL ||
++     child->parent == parent){
+     return;
++  }
+ 
+   inheritated_flags_mask = (AGS_RECALL_PLAYBACK |
+ 			    AGS_RECALL_SEQUENCER |
+@@ -2274,6 +2384,10 @@
+     g_signal_connect(G_OBJECT(child), "done\0",
+     		     G_CALLBACK(ags_recall_child_done), parent);
+   }
++
++  if(child->parent != NULL){
++    g_object_unref(child);
++  }
+   
+   child->parent = parent;
+ 
+--- a/ags/audio/ags_recall_audio.c
++++ b/ags/audio/ags_recall_audio.c
+@@ -44,6 +44,7 @@
+ void ags_recall_audio_disconnect(AgsConnectable *connectable);
+ gboolean ags_recall_audio_pack(AgsPackable *packable, GObject *container);
+ gboolean ags_recall_audio_unpack(AgsPackable *packable);
++void ags_recall_audio_dispose(GObject *gobject);
+ void ags_recall_audio_finalize(GObject *gobject);
+ 
+ void ags_recall_audio_load_automation(AgsRecall *recall,
+@@ -132,6 +133,7 @@
+   /* GObjectClass */
+   gobject = (GObjectClass *) recall_audio;
+ 
++  gobject->dispose = ags_recall_audio_dispose;
+   gobject->finalize = ags_recall_audio_finalize;
+ 
+   gobject->set_property = ags_recall_audio_set_property;
+@@ -337,15 +339,39 @@
+ }
+ 
+ void
++ags_recall_audio_dispose(GObject *gobject)
++{
++  AgsRecallAudio *recall_audio;
++
++  recall_audio = AGS_RECALL_AUDIO(gobject);
++
++  /* unpack */
++  ags_packable_unpack(AGS_PACKABLE(recall_audio));
++  
++  /* audio */
++  if(recall_audio->audio != NULL){
++    g_object_unref(G_OBJECT(recall_audio->audio));
++
++    recall_audio->audio = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_recall_audio_parent_class)->dispose(gobject);
++}
++
++void
+ ags_recall_audio_finalize(GObject *gobject)
+ {
+   AgsRecallAudio *recall_audio;
+ 
+   recall_audio = AGS_RECALL_AUDIO(gobject);
+ 
+-  if(recall_audio->audio != NULL)
++  /* audio */
++  if(recall_audio->audio != NULL){
+     g_object_unref(G_OBJECT(recall_audio->audio));
++  }
+ 
++  /* call parent */
+   G_OBJECT_CLASS(ags_recall_audio_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/ags_recall_audio_run.c
++++ b/ags/audio/ags_recall_audio_run.c
+@@ -51,6 +51,7 @@
+ gboolean ags_recall_audio_run_unpack(AgsPackable *packable);
+ void ags_recall_audio_run_connect_dynamic(AgsDynamicConnectable *dynamic_connectable);
+ void ags_recall_audio_run_disconnect_dynamic(AgsDynamicConnectable *dynamic_connectable);
++void ags_recall_audio_run_dispose(GObject *gobject);
+ void ags_recall_audio_run_finalize(GObject *gobject);
+ 
+ void ags_recall_audio_run_remove(AgsRecall *recall);
+@@ -71,6 +72,7 @@
+ 
+ enum{
+   PROP_0,
++  PROP_AUDIO,
+   PROP_RECALL_AUDIO,
+ };
+ 
+@@ -152,10 +154,27 @@
+   gobject->set_property = ags_recall_audio_run_set_property;
+   gobject->get_property = ags_recall_audio_run_get_property;
+ 
++  gobject->dispose = ags_recall_audio_run_dispose;
+   gobject->finalize = ags_recall_audio_run_finalize;
+ 
+   /* properties */
+   /**
++   * AgsRecallAudioRun:audio:
++   *
++   * The assigned audio.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_object("audio\0",
++				   "assigned audio\0",
++				   "The audio object it is assigned to\0",
++				   AGS_TYPE_AUDIO,
++				   G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_AUDIO,
++				  param_spec);
++
++  /**
+    * AgsRecallAudioRun:recall-audio:
+    *
+    * The recall audio belonging to.
+@@ -210,10 +229,10 @@
+ void
+ ags_recall_audio_run_init(AgsRecallAudioRun *recall_audio_run)
+ {
++  recall_audio_run->audio = NULL;
+   recall_audio_run->recall_audio = NULL;
+ }
+ 
+-
+ void
+ ags_recall_audio_run_set_property(GObject *gobject,
+ 				  guint prop_id,
+@@ -225,14 +244,36 @@
+   recall_audio_run = AGS_RECALL_AUDIO_RUN(gobject);
+ 
+   switch(prop_id){
++  case PROP_AUDIO:
++    {
++      AgsRecallAudio *audio;
++
++      audio = (AgsRecallAudio *) g_value_get_object(value);
++
++      if(recall_audio_run->audio == audio){
++	return;
++      }
++
++      if(recall_audio_run->audio != NULL){
++	g_object_unref(G_OBJECT(recall_audio_run->audio));
++      }
++
++      if(audio != NULL){
++	g_object_ref(G_OBJECT(audio));
++      }
++
++      recall_audio_run->audio = audio;
++    }
++    break;
+   case PROP_RECALL_AUDIO:
+     {
+       AgsRecallAudio *recall_audio;
+ 
+       recall_audio = (AgsRecallAudio *) g_value_get_object(value);
+ 
+-      if(recall_audio_run->recall_audio == recall_audio)
++      if(recall_audio_run->recall_audio == recall_audio){
+ 	return;
++      }
+ 
+       if(recall_audio_run->recall_audio != NULL){
+ 	g_object_unref(G_OBJECT(recall_audio_run->recall_audio));
+@@ -262,6 +303,11 @@
+   recall_audio_run = AGS_RECALL_AUDIO_RUN(gobject);
+ 
+   switch(prop_id){
++  case PROP_AUDIO:
++    {
++      g_value_set_object(value, recall_audio_run->audio);
++    }
++    break;
+   case PROP_RECALL_AUDIO:
+     {
+       g_value_set_object(value, recall_audio_run->recall_audio);
+@@ -274,15 +320,74 @@
+ }
+ 
+ void
++ags_recall_audio_run_dispose(GObject *gobject)
++{
++  AgsRecallAudioRun *recall_audio_run;
++
++  recall_audio_run = AGS_RECALL_AUDIO_RUN(gobject);
++
++  /* unpack */
++  ags_packable_unpack(AGS_PACKABLE(recall_audio_run));
++
++  if(AGS_RECALL(gobject)->container != NULL){
++    AgsRecallContainer *recall_container;
++
++    recall_container = AGS_RECALL(gobject)->container;
++
++    recall_container->recall_audio_run = g_list_remove(recall_container->recall_audio_run,
++						       gobject);
++    g_object_unref(gobject);
++    g_object_unref(AGS_RECALL(gobject)->container);
++
++    AGS_RECALL(gobject)->container = NULL;
++  }
++
++  /* audio */
++  if(recall_audio_run->audio != NULL){
++    g_object_unref(G_OBJECT(recall_audio_run->audio));
++
++    recall_audio_run->audio = NULL;
++  }
++
++  /* recall audio */
++  if(recall_audio_run->recall_audio != NULL){
++    g_object_unref(G_OBJECT(recall_audio_run->recall_audio));
++
++    recall_audio_run->recall_audio = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_recall_audio_run_parent_class)->dispose(gobject);
++}
++
++void
+ ags_recall_audio_run_finalize(GObject *gobject)
+ {
+   AgsRecallAudioRun *recall_audio_run;
+ 
+   recall_audio_run = AGS_RECALL_AUDIO_RUN(gobject);
+ 
+-  if(recall_audio_run->recall_audio != NULL)
++  if(AGS_RECALL(gobject)->container != NULL){
++    AgsRecallContainer *recall_container;
++
++    recall_container = AGS_RECALL(gobject)->container;
++
++    recall_container->recall_audio_run = g_list_remove(recall_container->recall_audio_run,
++						       gobject);
++    g_object_unref(AGS_RECALL(gobject)->container);
++  }
++  
++  /* audio */
++  if(recall_audio_run->audio != NULL){
++    g_object_unref(G_OBJECT(recall_audio_run->audio));
++  }
++
++  /* recall audio */
++  if(recall_audio_run->recall_audio != NULL){
+     g_object_unref(G_OBJECT(recall_audio_run->recall_audio));
++  }
+ 
++  /* call parent */
+   G_OBJECT_CLASS(ags_recall_audio_run_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/ags_recall_audio_signal.c
++++ b/ags/audio/ags_recall_audio_signal.c
+@@ -49,6 +49,7 @@
+ void ags_recall_audio_signal_disconnect(AgsConnectable *connectable);
+ void ags_recall_audio_signal_connect_dynamic(AgsDynamicConnectable *dynamic_connectable);
+ void ags_recall_audio_signal_disconnect_dynamic(AgsDynamicConnectable *dynamic_connectable);
++void ags_recall_audio_signal_dispose(GObject *gobject);
+ void ags_recall_audio_signal_finalize(GObject *gobject);
+ 
+ void ags_recall_audio_signal_run_init_pre(AgsRecall *recall);
+@@ -150,6 +151,7 @@
+   gobject->set_property = ags_recall_audio_signal_set_property;
+   gobject->get_property = ags_recall_audio_signal_get_property;
+ 
++  gobject->dispose = ags_recall_audio_signal_dispose;
+   gobject->finalize = ags_recall_audio_signal_finalize;
+ 
+   /* for debugging purpose */
+@@ -385,23 +387,48 @@
+ }
+ 
+ void
+-ags_recall_audio_signal_finalize(GObject *gobject)
++ags_recall_audio_signal_dispose(GObject *gobject)
+ {
+   AgsRecallAudioSignal *recall_audio_signal;
+ 
+   recall_audio_signal = AGS_RECALL_AUDIO_SIGNAL(gobject);
+-  
++
++  /* destination */
+   if(recall_audio_signal->destination != NULL){
+     g_object_unref(recall_audio_signal->destination);
++
+     recall_audio_signal->destination = NULL;
+   }
+ 
++  /* source */
+   if(recall_audio_signal->source != NULL){
+     g_object_unref(recall_audio_signal->source);
++
+     recall_audio_signal->source = NULL;
+   }
+ 
+   /* call parent */
++  G_OBJECT_CLASS(ags_recall_audio_signal_parent_class)->dispose(gobject);
++}
++
++void
++ags_recall_audio_signal_finalize(GObject *gobject)
++{
++  AgsRecallAudioSignal *recall_audio_signal;
++
++  recall_audio_signal = AGS_RECALL_AUDIO_SIGNAL(gobject);
++
++  /* destination */
++  if(recall_audio_signal->destination != NULL){
++    g_object_unref(recall_audio_signal->destination);
++  }
++
++  /* source */
++  if(recall_audio_signal->source != NULL){
++    g_object_unref(recall_audio_signal->source);
++  }
++
++  /* call parent */
+   G_OBJECT_CLASS(ags_recall_audio_signal_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/ags_recall_channel.c
++++ b/ags/audio/ags_recall_channel.c
+@@ -49,6 +49,7 @@
+ void ags_recall_channel_disconnect(AgsConnectable *connectable);
+ gboolean ags_recall_channel_pack(AgsPackable *packable, GObject *container);
+ gboolean ags_recall_channel_unpack(AgsPackable *packable);
++void ags_recall_channel_dispose(GObject *gobject);
+ void ags_recall_channel_finalize(GObject *gobject);
+ 
+ void ags_recall_channel_load_automation(AgsRecall *recall,
+@@ -141,6 +142,7 @@
+   gobject->set_property = ags_recall_channel_set_property;
+   gobject->get_property = ags_recall_channel_get_property;
+ 
++  gobject->dispose = ags_recall_channel_dispose;
+   gobject->finalize = ags_recall_channel_finalize;
+ 
+   /* properties */
+@@ -277,10 +279,14 @@
+ 
+   switch(prop_id){
+   case PROP_DESTINATION:
+-    g_value_set_object(value, recall_channel->destination);
++    {
++      g_value_set_object(value, recall_channel->destination);
++    }
+     break;
+   case PROP_SOURCE:
+-    g_value_set_object(value, recall_channel->source);
++    {
++      g_value_set_object(value, recall_channel->source);
++    }
+     break;
+   default:
+     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+@@ -289,18 +295,51 @@
+ }
+ 
+ void
++ags_recall_channel_dispose(GObject *gobject)
++{
++  AgsRecallChannel *recall_channel;
++
++  recall_channel = AGS_RECALL_CHANNEL(gobject);
++
++  /* unpack */
++  ags_packable_unpack(AGS_PACKABLE(recall_channel));
++  
++  /* source */
++  if(recall_channel->source != NULL){
++    g_object_unref(recall_channel->source);
++
++    recall_channel->source = NULL;
++  }
++
++  /* destination */
++  if(recall_channel->destination != NULL){
++    g_object_unref(G_OBJECT(recall_channel->destination));
++
++    recall_channel->destination = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_recall_channel_parent_class)->dispose(gobject);
++}
++
++void
+ ags_recall_channel_finalize(GObject *gobject)
+ {
+   AgsRecallChannel *recall_channel;
+ 
+   recall_channel = AGS_RECALL_CHANNEL(gobject);
+ 
+-  if(recall_channel->source != NULL)
++  /* source */
++  if(recall_channel->source != NULL){
+     g_object_unref(recall_channel->source);
++  }
+ 
+-  if(recall_channel->destination != NULL)
++  /* destination */
++  if(recall_channel->destination != NULL){
+     g_object_unref(G_OBJECT(recall_channel->destination));
++  }
+ 
++  /* call parent */
+   G_OBJECT_CLASS(ags_recall_channel_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/ags_recall_channel_run.c
++++ b/ags/audio/ags_recall_channel_run.c
+@@ -63,6 +63,7 @@
+ gboolean ags_recall_channel_run_unpack(AgsPackable *packable);
+ void ags_recall_channel_run_connect_dynamic(AgsDynamicConnectable *dynamic_connectable);
+ void ags_recall_channel_run_disconnect_dynamic(AgsDynamicConnectable *dynamic_connectable);
++void ags_recall_channel_run_dispose(GObject *gobject);
+ void ags_recall_channel_run_finalize(GObject *gobject);
+ 
+ void ags_recall_channel_run_remove(AgsRecall *recall);
+@@ -198,6 +199,7 @@
+   gobject->set_property = ags_recall_channel_run_set_property;
+   gobject->get_property = ags_recall_channel_run_get_property;
+ 
++  gobject->dispose = ags_recall_channel_run_dispose;
+   gobject->finalize = ags_recall_channel_run_finalize;
+ 
+   /* properties */
+@@ -516,28 +518,98 @@
+ }
+ 
+ void
+-ags_recall_channel_run_finalize(GObject *gobject)
++ags_recall_channel_run_dispose(GObject *gobject)
+ {
+   AgsRecallChannelRun *recall_channel_run;
+ 
+   recall_channel_run = AGS_RECALL_CHANNEL_RUN(gobject);
+ 
++  /* unpack */
++  ags_packable_unpack(AGS_PACKABLE(recall_channel_run));
++
++  if(AGS_RECALL(gobject)->container != NULL){
++    AgsRecallContainer *recall_container;
++
++    recall_container = AGS_RECALL(gobject)->container;
++
++    recall_container->recall_channel_run = g_list_remove(recall_container->recall_channel_run,
++							 gobject);
++    g_object_unref(gobject);
++    g_object_unref(AGS_RECALL(gobject)->container);
++
++    AGS_RECALL(gobject)->container = NULL;
++  }
++  
++  /* recall audio run */
+   if(recall_channel_run->recall_audio_run != NULL){
+     g_object_unref(G_OBJECT(recall_channel_run->recall_audio_run));
++
++    recall_channel_run->recall_audio_run = NULL;
+   }
+   
++  /* recall channel */
+   if(recall_channel_run->recall_channel != NULL){
+     g_object_unref(G_OBJECT(recall_channel_run->recall_channel));
++
++    recall_channel_run->recall_channel = NULL;
+   }
+-  
++
++  /* destination */
+   if(recall_channel_run->destination != NULL){
+     g_object_unref(recall_channel_run->destination);
++
++    recall_channel_run->destination = NULL;
+   }
+-  
++
++  /* source */
+   if(recall_channel_run->source != NULL){
+     g_object_unref(recall_channel_run->source);
++
++    recall_channel_run->source = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_recall_channel_run_parent_class)->dispose(gobject);
++}
++
++void
++ags_recall_channel_run_finalize(GObject *gobject)
++{
++  AgsRecallChannelRun *recall_channel_run;
++
++  recall_channel_run = AGS_RECALL_CHANNEL_RUN(gobject);
++
++  if(AGS_RECALL(gobject)->container != NULL){
++    AgsRecallContainer *recall_container;
++
++    recall_container = AGS_RECALL(gobject)->container;
++
++    recall_container->recall_channel_run = g_list_remove(recall_container->recall_channel_run,
++							 gobject);
++    g_object_unref(AGS_RECALL(gobject)->container);
++  }
++
++  /* recall audio run */
++  if(recall_channel_run->recall_audio_run != NULL){
++    g_object_unref(G_OBJECT(recall_channel_run->recall_audio_run));
+   }
+   
++  /* recall channel */
++  if(recall_channel_run->recall_channel != NULL){
++    g_object_unref(G_OBJECT(recall_channel_run->recall_channel));
++  }
++
++  /* destination */
++  if(recall_channel_run->destination != NULL){
++    g_object_unref(recall_channel_run->destination);
++  }
++
++  /* source */
++  if(recall_channel_run->source != NULL){
++    g_object_unref(recall_channel_run->source);
++  }
++
++  /* call parent */
+   G_OBJECT_CLASS(ags_recall_channel_run_parent_class)->finalize(gobject);
+ }
+ 
+@@ -685,13 +757,15 @@
+ 
+   recall = AGS_RECALL(packable);
+ 
+-  if(recall == NULL)
++  if(recall == NULL){
+     return(TRUE);
++  }
+ 
+   recall_container = AGS_RECALL_CONTAINER(recall->container);
+ 
+-  if(recall_container == NULL)
++  if(recall_container == NULL){
+     return(TRUE);
++  }
+ 
+   /* ref */
+   g_object_ref(recall);
+--- a/ags/audio/ags_recall_container.c
++++ b/ags/audio/ags_recall_container.c
+@@ -324,14 +324,16 @@
+       recall_audio_run = (AgsRecallAudioRun *) g_value_get_object(value);
+ 
+       if(recall_audio_run == NULL ||
+-	 g_list_find(recall_container->recall_audio_run, recall_audio_run) != NULL)
++	 g_list_find(recall_container->recall_audio_run, recall_audio_run) != NULL){
+ 	return;
++      }
+ 
+       if(recall_audio_run != NULL){
+ 	g_object_ref(G_OBJECT(recall_audio_run));
+       }
+ 
+-      recall_container->recall_audio_run = g_list_prepend(recall_container->recall_audio_run, recall_audio_run);
++      recall_container->recall_audio_run = g_list_prepend(recall_container->recall_audio_run,
++							  recall_audio_run);
+     }
+     break;
+   case PROP_RECALL_CHANNEL_TYPE:
+@@ -350,12 +352,14 @@
+       recall_channel = (AgsRecallChannel *) g_value_get_object(value);
+ 
+       if(recall_channel == NULL ||
+-	 g_list_find(recall_container->recall_channel, recall_channel) != NULL)
++	 g_list_find(recall_container->recall_channel, recall_channel) != NULL){
+ 	return;
++      }
+ 
+-	g_object_ref(G_OBJECT(recall_channel));
+-
+-	recall_container->recall_channel = g_list_prepend(recall_container->recall_channel, recall_channel);
++      g_object_ref(G_OBJECT(recall_channel));
++      
++      recall_container->recall_channel = g_list_prepend(recall_container->recall_channel,
++							recall_channel);
+     }
+     break;
+   case PROP_RECALL_CHANNEL_RUN_TYPE:
+@@ -374,12 +378,14 @@
+       recall_channel_run = (AgsRecallChannelRun *) g_value_get_object(value);
+ 
+       if(recall_channel_run == NULL ||
+-	 g_list_find(recall_container->recall_channel_run, recall_channel_run) != NULL)
++	 g_list_find(recall_container->recall_channel_run, recall_channel_run) != NULL){
+ 	return;
++      }
+ 
+       g_object_ref(G_OBJECT(recall_channel_run));
+ 
+-      recall_container->recall_channel_run = g_list_prepend(recall_container->recall_channel_run, recall_channel_run);
++      recall_container->recall_channel_run = g_list_prepend(recall_container->recall_channel_run,
++							    recall_channel_run);
+     }
+     break;
+   default:
+--- a/ags/audio/ags_recall_dependency.c
++++ b/ags/audio/ags_recall_dependency.c
+@@ -32,8 +32,17 @@
+ void ags_recall_dependency_class_init(AgsRecallDependencyClass *recall_dependency);
+ void ags_recall_dependency_connectable_interface_init(AgsConnectableInterface *connectable);
+ void ags_recall_dependency_init(AgsRecallDependency *recall_dependency);
++void ags_recall_dependency_set_property(GObject *gobject,
++					guint prop_id,
++					const GValue *value,
++					GParamSpec *param_spec);
++void ags_recall_dependency_get_property(GObject *gobject,
++					guint prop_id,
++					GValue *value,
++					GParamSpec *param_spec);
+ void ags_recall_dependency_connect(AgsConnectable *connectable);
+ void ags_recall_dependency_disconnect(AgsConnectable *connectable);
++void ags_recall_dependency_dispose(GObject *gobject);
+ void ags_recall_dependency_finalize(GObject *gobject);
+ 
+ /**
+@@ -49,6 +58,11 @@
+ 
+ static gpointer ags_recall_dependency_parent_class = NULL;
+ 
++enum{
++  PROP_0,
++  PROP_DEPENDENCY,
++};
++
+ GType
+ ags_recall_dependency_get_type(void)
+ {
+@@ -90,11 +104,34 @@
+ ags_recall_dependency_class_init(AgsRecallDependencyClass *recall_dependency)
+ {
+   GObjectClass *gobject;
+-
++  GParamSpec *param_spec;
++  
+   ags_recall_dependency_parent_class = g_type_class_peek_parent(recall_dependency);
+ 
+   gobject = (GObjectClass *) recall_dependency;
++
++  gobject->set_property = ags_recall_dependency_set_property;
++  gobject->get_property = ags_recall_dependency_get_property;
++  
++  gobject->dispose = ags_recall_dependency_dispose;
+   gobject->finalize = ags_recall_dependency_finalize;
++
++  /* properties */
++  /**
++   * AgsRecallDependency:dependency:
++   *
++   * The dependency.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_object("dependency\0",
++				   "dependency of recall\0",
++				   "A dependency of the recall\0",
++				   AGS_TYPE_RECALL,
++				   G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_DEPENDENCY,
++				  param_spec);
+ }
+ 
+ void
+@@ -107,24 +144,130 @@
+ void
+ ags_recall_dependency_init(AgsRecallDependency *recall_dependency)
+ {
++  recall_dependency->flags = 0;
++  
+   recall_dependency->dependency = NULL;
+ }
+ 
+ void
++ags_recall_dependency_set_property(GObject *gobject,
++				   guint prop_id,
++				   const GValue *value,
++				   GParamSpec *param_spec)
++{
++  AgsRecallDependency *recall_dependency;
++
++  recall_dependency = AGS_RECALL_DEPENDENCY(gobject);
++  
++  switch(prop_id){
++  case PROP_DEPENDENCY:
++    {
++      AgsRecall *dependency;
++      
++      dependency = (AgsRecall *) g_value_get_object(value);
++      
++      if(recall_dependency->dependency == dependency){
++	return;
++      }
++	
++      if(recall_dependency->dependency != NULL){
++	g_object_unref(G_OBJECT(recall_dependency->dependency));
++      }
++
++      if(dependency != NULL){
++	g_object_ref(G_OBJECT(dependency));
++      }
++
++      recall_dependency->dependency = dependency;
++    }
++    break;
++  default:
++    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
++    break;
++  };
++}
++
++void
++ags_recall_dependency_get_property(GObject *gobject,
++				   guint prop_id,
++				   GValue *value,
++				   GParamSpec *param_spec)
++{
++  AgsRecallDependency *recall_dependency;
++
++  recall_dependency = AGS_RECALL_DEPENDENCY(gobject);
++
++  switch(prop_id){
++  case PROP_DEPENDENCY:
++    {
++      g_value_set_object(value, recall_dependency->dependency);
++    }
++    break;
++  default:
++    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
++    break;
++  };
++}
++
++void
+ ags_recall_dependency_connect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsRecallDependency *recall_dependency;
++
++  recall_dependency = AGS_RECALL_DEPENDENCY(connectable);
++
++  if((AGS_RECALL_DEPENDENCY_CONNECTED & (recall_dependency->flags)) != 0){
++    return;
++  }
++
++  recall_dependency->flags |= AGS_RECALL_DEPENDENCY_CONNECTED;
+ }
+ 
+ void
+ ags_recall_dependency_disconnect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsRecallDependency *recall_dependency;
++
++  recall_dependency = AGS_RECALL_DEPENDENCY(connectable);
++
++  if((AGS_RECALL_DEPENDENCY_CONNECTED & (recall_dependency->flags)) == 0){
++    return;
++  }
++
++  recall_dependency->flags &= (~AGS_RECALL_DEPENDENCY_CONNECTED);
++}
++
++void
++ags_recall_dependency_dispose(GObject *gobject)
++{
++  AgsRecallDependency *recall_dependency;
++
++  recall_dependency = AGS_RECALL_DEPENDENCY(gobject);
++
++  /* dependency */
++  if(recall_dependency->dependency != NULL){
++    g_object_unref(recall_dependency->dependency);
++
++    recall_dependency->dependency = NULL;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_recall_dependency_parent_class)->dispose(gobject);
+ }
+ 
+ void
+ ags_recall_dependency_finalize(GObject *gobject)
+ {
++  AgsRecallDependency *recall_dependency;
++
++  recall_dependency = AGS_RECALL_DEPENDENCY(gobject);
++
++  /* dependency */
++  if(recall_dependency->dependency != NULL){
++    g_object_unref(recall_dependency->dependency);
++  }
++
++  /* call parent */
+   G_OBJECT_CLASS(ags_recall_dependency_parent_class)->finalize(gobject);
+ }
+ 
+@@ -296,9 +439,8 @@
+   AgsRecallDependency *recall_dependency;
+ 
+   recall_dependency = (AgsRecallDependency *) g_object_new(AGS_TYPE_RECALL_DEPENDENCY,
++							   "dependency\0", dependency,
+ 							   NULL);
+ 
+-  recall_dependency->dependency = dependency;
+-
+   return(recall_dependency);
+ }
+--- a/ags/audio/ags_recall_dependency.h
++++ b/ags/audio/ags_recall_dependency.h
+@@ -35,10 +35,16 @@
+ typedef struct _AgsRecallDependency AgsRecallDependency;
+ typedef struct _AgsRecallDependencyClass AgsRecallDependencyClass;
+ 
++typedef enum{
++  AGS_RECALL_DEPENDENCY_CONNECTED      = 1,
++}AgsRecallDependencyFlags;
++
+ struct _AgsRecallDependency
+ {
+   GObject object;
+ 
++  guint flags;
++  
+   GObject *dependency;
+ };
+ 
+--- a/ags/audio/ags_recall_dssi.c
++++ b/ags/audio/ags_recall_dssi.c
+@@ -639,6 +639,7 @@
+ 			       "port-value-is-pointer\0", FALSE,
+ 			       "port-value-type\0", G_TYPE_FLOAT,
+ 			       NULL);
++	g_object_ref(current);
+ 	current->flags |= AGS_PORT_USE_LADSPA_FLOAT;
+ 	
+ 	current->port_descriptor = port_descriptor->data;
+--- a/ags/audio/ags_recall_id.c
++++ b/ags/audio/ags_recall_id.c
+@@ -37,6 +37,7 @@
+ 				GParamSpec *param_spec);
+ void ags_recall_id_connect(AgsConnectable *connectable);
+ void ags_recall_id_disconnect(AgsConnectable *connectable);
++void ags_recall_id_dispose(GObject *gobject);
+ void ags_recall_id_finalize(GObject *gobject);
+ 
+ /**
+@@ -108,6 +109,7 @@
+   gobject->set_property = ags_recall_id_set_property;
+   gobject->get_property = ags_recall_id_get_property;
+ 
++  gobject->dispose = ags_recall_id_dispose;
+   gobject->finalize = ags_recall_id_finalize;
+ 
+   /* properties */
+@@ -177,8 +179,9 @@
+ 
+       recycling = g_value_get_object(value);
+ 
+-      if(recall_id->recycling == (GObject *) recycling)
++      if(recall_id->recycling == (GObject *) recycling){
+ 	return;
++      }
+ 
+       if(recall_id->recycling != NULL){
+ 	g_object_unref(recycling);
+@@ -230,10 +233,14 @@
+ 
+   switch(prop_id){
+   case PROP_RECYCLING:
+-    g_value_set_object(value, recall_id->recycling);
++    {
++      g_value_set_object(value, recall_id->recycling);
++    }
+     break;
+   case PROP_RECYCLING_CONTEXT:
+-    g_value_set_object(value, recall_id->recycling_context);
++    {
++      g_value_set_object(value, recall_id->recycling_context);
++    }
+     break;
+   default:
+     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+@@ -244,18 +251,71 @@
+ void
+ ags_recall_id_connect(AgsConnectable *connectable)
+ {
++  AgsRecallID *recall_id;
++
++  recall_id = AGS_RECALL_ID(connectable);
++
++  if((AGS_RECALL_ID_CONNECTED & (recall_id->flags)) != 0){
++    return;
++  }
++
++  recall_id->flags |= AGS_RECALL_ID_CONNECTED;
+ }
+ 
+ void
+ ags_recall_id_disconnect(AgsConnectable *connectable)
+ {
++  AgsRecallID *recall_id;
++
++  recall_id = AGS_RECALL_ID(connectable);
++
++
++  if((AGS_RECALL_ID_CONNECTED & (recall_id->flags)) == 0){
++    return;
++  }
++
++  recall_id->flags &= (~AGS_RECALL_ID_CONNECTED);
++}
++
++void
++ags_recall_id_dispose(GObject *gobject)
++{
++  AgsRecallID *recall_id;
++
++  recall_id = AGS_RECALL_ID(gobject);
++
++  if(recall_id->recycling != NULL){
++    g_object_unref(recall_id->recycling);
++
++    recall_id->recycling = NULL;
++  }
++  
++  if(recall_id->recycling_context != NULL){
++    g_object_unref(recall_id->recycling_context);
++
++    recall_id->recycling_context = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_recall_id_parent_class)->dispose(gobject);
+ }
+ 
+ void
+ ags_recall_id_finalize(GObject *gobject)
+ {
+-  g_warning("ags_recall_id_finalize\0");
++  AgsRecallID *recall_id;
++
++  recall_id = AGS_RECALL_ID(gobject);
++
++  if(recall_id->recycling != NULL){
++    g_object_unref(recall_id->recycling);
++  }
++  
++  if(recall_id->recycling_context != NULL){
++    g_object_unref(recall_id->recycling_context);
++  }
+ 
++  /* call parent */
+   G_OBJECT_CLASS(ags_recall_id_parent_class)->finalize(gobject);
+ }
+ 
+@@ -276,18 +336,25 @@
+ {
+   switch(stage){
+   case 0:
+-    if((AGS_RECALL_ID_PRE & (id->flags)) == 0)
+-      return(TRUE);
+-
++    {
++      if((AGS_RECALL_ID_PRE & (id->flags)) == 0){
++	return(TRUE);
++      }
++    }
+     break;
+   case 1:
+-    if((AGS_RECALL_ID_INTER & (id->flags)) == 0)
+-      return(TRUE);
+-
++    {
++      if((AGS_RECALL_ID_INTER & (id->flags)) == 0){
++	return(TRUE);
++      }
++    }
+     break;
+   case 2:
+-    if((AGS_RECALL_ID_POST & (id->flags)) == 0)
+-      return(TRUE);
++    {
++      if((AGS_RECALL_ID_POST & (id->flags)) == 0){
++	return(TRUE);
++      }
++    }
+     break;
+   }
+ 
+--- a/ags/audio/ags_recall_id.h
++++ b/ags/audio/ags_recall_id.h
+@@ -37,18 +37,19 @@
+ typedef struct _AgsRecallIDClass AgsRecallIDClass;
+ 
+ typedef enum{
+-  AGS_RECALL_ID_PLAYBACK          = 1,
+-  AGS_RECALL_ID_SEQUENCER         = 1 << 1,
+-  AGS_RECALL_ID_NOTATION          = 1 << 2,
+-  AGS_RECALL_ID_DUPLICATE         = 1 << 3,
+-  AGS_RECALL_ID_RESOLVE           = 1 << 4,
+-  AGS_RECALL_ID_INIT_PRE          = 1 << 5,
+-  AGS_RECALL_ID_INIT_INTER        = 1 << 6,
+-  AGS_RECALL_ID_INIT_POST         = 1 << 7,
+-  AGS_RECALL_ID_PRE               = 1 << 8,
+-  AGS_RECALL_ID_INTER             = 1 << 9,
+-  AGS_RECALL_ID_POST              = 1 << 10,
+-  AGS_RECALL_ID_CANCEL            = 1 << 11,
++  AGS_RECALL_ID_CONNECTED         = 1,
++  AGS_RECALL_ID_PLAYBACK          = 1 <<  1,
++  AGS_RECALL_ID_SEQUENCER         = 1 <<  2,
++  AGS_RECALL_ID_NOTATION          = 1 <<  3,
++  AGS_RECALL_ID_DUPLICATE         = 1 <<  4,
++  AGS_RECALL_ID_RESOLVE           = 1 <<  5,
++  AGS_RECALL_ID_INIT_PRE          = 1 <<  6,
++  AGS_RECALL_ID_INIT_INTER        = 1 <<  7,
++  AGS_RECALL_ID_INIT_POST         = 1 <<  8,
++  AGS_RECALL_ID_PRE               = 1 <<  9,
++  AGS_RECALL_ID_INTER             = 1 << 10,
++  AGS_RECALL_ID_POST              = 1 << 11,
++  AGS_RECALL_ID_CANCEL            = 1 << 12,
+ }AgsRecallIDFlags;
+ 
+ struct _AgsRecallID
+--- a/ags/audio/ags_recall_ladspa.c
++++ b/ags/audio/ags_recall_ladspa.c
+@@ -639,6 +639,7 @@
+ 			       "port-value-is-pointer\0", FALSE,
+ 			       "port-value-type\0", G_TYPE_FLOAT,
+ 			       NULL);
++	g_object_ref(current);
+ 	current->flags |= AGS_PORT_USE_LADSPA_FLOAT;
+ 	
+ 	current->port_descriptor = port_descriptor->data;	
+--- a/ags/audio/ags_recall_lv2.c
++++ b/ags/audio/ags_recall_lv2.c
+@@ -60,6 +60,7 @@
+ void ags_recall_lv2_connect(AgsConnectable *connectable);
+ void ags_recall_lv2_disconnect(AgsConnectable *connectable);
+ void ags_recall_lv2_set_ports(AgsPlugin *plugin, GList *port);
++void ags_recall_lv2_dispose(GObject *gobject);
+ void ags_recall_lv2_finalize(GObject *gobject);
+ 
+ void ags_recall_lv2_read(AgsFile *file, xmlNode *node, AgsPlugin *plugin);
+@@ -149,6 +150,7 @@
+   gobject->set_property = ags_recall_lv2_set_property;
+   gobject->get_property = ags_recall_lv2_get_property;
+ 
++  gobject->dispose = ags_recall_lv2_dispose;
+   gobject->finalize = ags_recall_lv2_finalize;
+ 
+   /* properties */
+@@ -550,16 +552,36 @@
+ }
+ 
+ void
++ags_recall_lv2_dispose(GObject *gobject)
++{
++  AgsRecallLv2 *recall_lv2;
++  
++  recall_lv2 = AGS_RECALL_LV2(gobject);
++
++  /* turtle */
++  if(recall_lv2->turtle != NULL){
++    g_object_unref(recall_lv2->turtle);
++
++    recall_lv2->turtle = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_recall_lv2_parent_class)->dispose(gobject);
++}
++
++void
+ ags_recall_lv2_finalize(GObject *gobject)
+ {
+   AgsRecallLv2 *recall_lv2;
+   
+   recall_lv2 = AGS_RECALL_LV2(gobject);
+ 
++  /* turtle */
+   if(recall_lv2->turtle != NULL){
+     g_object_unref(recall_lv2->turtle);
+   }
+ 
++  /* filename, effect and uri */
+   g_free(recall_lv2->filename);
+   g_free(recall_lv2->effect);
+   g_free(recall_lv2->uri);
+@@ -767,6 +789,7 @@
+ 			       "port-value-is-pointer\0", FALSE,
+ 			       "port-value-type\0", G_TYPE_FLOAT,
+ 			       NULL);
++	g_object_ref(current);
+ 
+ 	current->port_descriptor = port_descriptor->data;
+ 	ags_recall_lv2_load_conversion(recall_lv2,
+--- a/ags/audio/ags_recall_recycling.c
++++ b/ags/audio/ags_recall_recycling.c
+@@ -60,6 +60,7 @@
+ void ags_recall_recycling_disconnect(AgsConnectable *connectable);
+ void ags_recall_recycling_connect_dynamic(AgsDynamicConnectable *dynamic_connectable);
+ void ags_recall_recycling_disconnect_dynamic(AgsDynamicConnectable *dynamic_connectable);
++void ags_recall_recycling_dispose(GObject *gobject);
+ void ags_recall_recycling_finalize(GObject *gobject);
+ 
+ AgsRecall* ags_recall_recycling_duplicate(AgsRecall *recall,
+@@ -164,6 +165,7 @@
+   gobject->set_property = ags_recall_recycling_set_property;
+   gobject->get_property = ags_recall_recycling_get_property;
+ 
++  gobject->dispose = ags_recall_recycling_dispose;
+   gobject->finalize = ags_recall_recycling_finalize;
+ 
+   /* properties */
+@@ -280,7 +282,6 @@
+ void
+ ags_recall_recycling_init(AgsRecallRecycling *recall_recycling)
+ {
+-  recall_recycling->flags = 0;
+   recall_recycling->flags = (AGS_RECALL_RECYCLING_MAP_CHILD_DESTINATION  |
+ 			     AGS_RECALL_RECYCLING_MAP_CHILD_SOURCE);
+ 
+@@ -477,24 +478,68 @@
+ }
+ 
+ void
++ags_recall_recycling_dispose(GObject *gobject)
++{
++  AgsRecallRecycling *recall_recycling;
++
++  recall_recycling = AGS_RECALL_RECYCLING(gobject);
++
++  /* destination */
++  if(recall_recycling->destination != NULL){
++    g_object_unref(G_OBJECT(recall_recycling->destination));
++
++    recall_recycling->destination = NULL;
++  }
++
++  /* source */
++  if(recall_recycling->source != NULL){
++    g_object_unref(G_OBJECT(recall_recycling->source));
++
++    recall_recycling->source = NULL;
++  }
++
++  /* child destination */
++  if(recall_recycling->child_destination != NULL){
++    g_object_unref(G_OBJECT(recall_recycling->child_destination));
++
++    recall_recycling->child_destination = NULL;
++  }
++
++  /* child source */
++  if(recall_recycling->child_source != NULL){
++    g_list_free_full(recall_recycling->child_source,
++		     g_object_unref);
++
++    recall_recycling->child_source = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_recall_recycling_parent_class)->dispose(gobject);
++}
++
++void
+ ags_recall_recycling_finalize(GObject *gobject)
+ {
+   AgsRecallRecycling *recall_recycling;
+ 
+   recall_recycling = AGS_RECALL_RECYCLING(gobject);
+ 
++  /* destination */
+   if(recall_recycling->destination != NULL){
+     g_object_unref(G_OBJECT(recall_recycling->destination));
+   }
+-  
++
++  /* source */
+   if(recall_recycling->source != NULL){
+     g_object_unref(G_OBJECT(recall_recycling->source));
+   }
+-  
++
++  /* child destination */
+   if(recall_recycling->child_destination != NULL){
+     g_object_unref(G_OBJECT(recall_recycling->child_destination));
+   }
+-  
++
++  /* child source */
+   if(recall_recycling->child_source != NULL){
+     g_list_free_full(recall_recycling->child_source,
+ 		     g_object_unref);
+--- a/ags/audio/ags_recall_recycling.h
++++ b/ags/audio/ags_recall_recycling.h
+@@ -41,9 +41,9 @@
+ 
+ typedef enum{
+   AGS_RECALL_RECYCLING_GARBAGE_COLLECTOR                = 1,
+-  AGS_RECALL_RECYCLING_MAP_CHILD_DESTINATION            = 1 << 1,
+-  AGS_RECALL_RECYCLING_MAP_CHILD_SOURCE                 = 1 << 2,
+-  AGS_RECALL_RECYCLING_CREATE_DESTINATION_ON_MAP_SOURCE = 1 << 3,
++  AGS_RECALL_RECYCLING_MAP_CHILD_DESTINATION            = 1 <<  1,
++  AGS_RECALL_RECYCLING_MAP_CHILD_SOURCE                 = 1 <<  2,
++  AGS_RECALL_RECYCLING_CREATE_DESTINATION_ON_MAP_SOURCE = 1 <<  3,
+ }AgsRecallRecyclingFlags;
+ 
+ struct _AgsRecallRecycling
+--- a/ags/audio/ags_recycling.c
++++ b/ags/audio/ags_recycling.c
+@@ -49,6 +49,7 @@
+ void ags_recycling_disconnect(AgsConnectable *connectable);
+ pthread_mutex_t* ags_recycling_get_lock(AgsConcurrentTree *concurrent_tree);
+ pthread_mutex_t* ags_recycling_get_parent_lock(AgsConcurrentTree *concurrent_tree);
++void ags_recycling_dispose(GObject *gobject);
+ void ags_recycling_finalize(GObject *gobject);
+ 
+ void ags_recycling_real_add_audio_signal(AgsRecycling *recycling,
+@@ -147,6 +148,7 @@
+   gobject->set_property = ags_recycling_set_property;
+   gobject->get_property = ags_recycling_get_property;
+ 
++  gobject->dispose = ags_recycling_dispose;
+   gobject->finalize = ags_recycling_finalize;
+ 
+   /* properties */
+@@ -481,10 +483,14 @@
+   
+   switch(prop_id){
+   case PROP_SOUNDCARD:
+-    g_value_set_object(value, recycling->soundcard);
++    {
++      g_value_set_object(value, recycling->soundcard);
++    }
+     break;
+   case PROP_CHANNEL:
+-    g_value_set_object(value, recycling->channel);
++    {
++      g_value_set_object(value, recycling->channel);
++    }
+     break;
+   case PROP_PARENT:
+     {
+@@ -515,13 +521,51 @@
+ void
+ ags_recycling_connect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsRecycling *recycling;
++
++  GList *list;
++  
++  recycling = AGS_RECYCLING(connectable);
++
++  if((AGS_RECYCLING_CONNECTED & (recycling->flags)) != 0){
++    return;
++  }
++
++  recycling->flags |= AGS_RECYCLING_CONNECTED;
++
++  /* audio signal */
++  list = recycling->audio_signal;
++
++  while(list != NULL){
++    ags_connectable_connect(AGS_CONNECTABLE(list->data));
++    
++    list = list->next;
++  }
+ }
+ 
+ void
+ ags_recycling_disconnect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsRecycling *recycling;
++
++  GList *list;
++  
++  recycling = AGS_RECYCLING(connectable);
++
++  if((AGS_RECYCLING_CONNECTED & (recycling->flags)) == 0){
++    return;
++  }
++
++  recycling->flags &= (~AGS_RECYCLING_CONNECTED);
++
++  /* audio signal */
++  list = recycling->audio_signal;
++
++  while(list != NULL){
++    ags_connectable_disconnect(AGS_CONNECTABLE(list->data));
++    
++    list = list->next;
++  }
+ }
+ 
+ pthread_mutex_t*
+@@ -574,14 +618,70 @@
+ }
+ 
+ void
++ags_recycling_dispose(GObject *gobject)
++{
++  AgsRecycling *recycling;  
++
++  GList *list;
++
++  recycling = AGS_RECYCLING(gobject);
++
++  /* channel */
++  if(recycling->channel != NULL){
++    g_object_unref(recycling->channel);
++
++    recycling->channel = NULL;
++  }
++
++  /* soundcard */
++  if(recycling->soundcard != NULL){
++    g_object_unref(recycling->soundcard);
++
++    recycling->soundcard = NULL;
++  }
++
++  /* parent */
++  if(recycling->parent != NULL){
++    g_object_unref(recycling->parent);
++
++    recycling->parent = NULL;
++  }
++
++  /* next and prev */
++  if(recycling->next != NULL){
++    //    g_object_unref(recycling->next);
++
++    recycling->next = NULL;
++  }
++
++  if(recycling->prev != NULL){
++    //    g_object_unref(recycling->prev);
++
++    recycling->prev = NULL;
++  }
++
++  /* AgsAudioSignal */
++  list = recycling->audio_signal;
++
++  while(list != NULL){
++    g_object_run_dispose(list->data);
++    
++    list = list->next;
++  }
++  
++  g_list_free_full(recycling->audio_signal,
++		   g_object_unref);
++
++  recycling->audio_signal = NULL;
++}
++
++void
+ ags_recycling_finalize(GObject *gobject)
+ {
+   AgsRecycling *recycling;  
+ 
+   AgsMutexManager *mutex_manager;
+   
+-  GList *list, *list_next;
+-
+   pthread_mutex_t *application_mutex;
+   
+   //  g_warning("ags_recycling_finalize\0");
+@@ -598,6 +698,30 @@
+ 
+   recycling = AGS_RECYCLING(gobject);
+ 
++  /* channel */
++  if(recycling->channel != NULL){
++    g_object_unref(recycling->channel);
++  }
++
++  /* soundcard */
++  if(recycling->soundcard != NULL){
++    g_object_unref(recycling->soundcard);
++  }
++
++  /* parent */
++  if(recycling->parent != NULL){
++    g_object_unref(recycling->parent);
++  }
++
++  /* next and prev */
++  if(recycling->next != NULL){
++    g_object_unref(recycling->next);
++  }
++
++  if(recycling->prev != NULL){
++    g_object_unref(recycling->prev);
++  }
++
+   /* AgsAudioSignal */
+   g_list_free_full(recycling->audio_signal,
+ 		   g_object_unref);
+@@ -619,15 +743,18 @@
+ ags_recycling_set_soundcard(AgsRecycling *recycling, GObject *soundcard)
+ {
+   /* recycling */
+-  if(recycling->soundcard == soundcard)
++  if(recycling->soundcard == soundcard){
+     return;
++  }
+ 
+-  if(recycling->soundcard != NULL)
++  if(recycling->soundcard != NULL){
+     g_object_unref(recycling->soundcard);
+-
+-  if(soundcard != NULL)
++  }
++  
++  if(soundcard != NULL){
+     g_object_ref(soundcard);
+-
++  }
++  
+   recycling->soundcard = (GObject *) soundcard;
+ }
+ 
+@@ -693,21 +820,27 @@
+ ags_recycling_real_add_audio_signal(AgsRecycling *recycling,
+ 				    AgsAudioSignal *audio_signal)
+ {
+-  if((AGS_AUDIO_SIGNAL_TEMPLATE & (audio_signal->flags)) != 0){
+-    AgsAudioSignal *old_template;
++  if(g_list_find(recycling->audio_signal,
++		 audio_signal) == NULL){
++    if((AGS_AUDIO_SIGNAL_TEMPLATE & (audio_signal->flags)) != 0){
++      AgsAudioSignal *old_template;
+ 
+-    /* old template */
+-    old_template = ags_audio_signal_get_template(recycling->audio_signal);
++      /* old template */
++      old_template = ags_audio_signal_get_template(recycling->audio_signal);
+     
+-    /* remove old template */
+-    ags_recycling_remove_audio_signal(recycling,
+-				      old_template);
++      /* remove old template */
++      ags_recycling_remove_audio_signal(recycling,
++					old_template);
++    }
++
++    recycling->audio_signal = g_list_prepend(recycling->audio_signal, (gpointer) audio_signal);
++    g_object_ref(audio_signal);
+   }
+   
+-  recycling->audio_signal = g_list_prepend(recycling->audio_signal, (gpointer) audio_signal);
+-  audio_signal->recycling = (GObject *) recycling;
+-  g_object_ref(recycling);
+-  g_object_ref(audio_signal);
++  if(audio_signal->recycling != recycling){
++    audio_signal->recycling = (GObject *) recycling;
++    g_object_ref(recycling);
++  }
+ }
+ 
+ /**
+--- a/ags/audio/ags_recycling.h
++++ b/ags/audio/ags_recycling.h
+@@ -35,7 +35,8 @@
+ typedef struct _AgsRecyclingClass AgsRecyclingClass;
+ 
+ typedef enum{
+-  AGS_RECYCLING_MUTED           =  1,
++  AGS_RECYCLING_CONNECTED       = 1,
++  AGS_RECYCLING_MUTED           = 1 <<  1,
+ }AgsRecyclingFlags;
+ 
+ struct _AgsRecycling
+--- a/ags/audio/ags_recycling_context.c
++++ b/ags/audio/ags_recycling_context.c
+@@ -34,6 +34,7 @@
+ 					guint prop_id,
+ 					GValue *value,
+ 					GParamSpec *param_spec);
++void ags_recycling_context_dispose(GObject *gobject);
+ void ags_recycling_context_finalize(GObject *gobject);
+ 
+ /**
+@@ -96,6 +97,7 @@
+   gobject->set_property = ags_recycling_context_set_property;
+   gobject->get_property = ags_recycling_context_get_property;
+ 
++  gobject->dispose = ags_recycling_context_dispose;
+   gobject->finalize = ags_recycling_context_finalize;
+ 
+   /* properties */
+@@ -270,8 +272,88 @@
+ }
+ 
+ void
++ags_recycling_context_dispose(GObject *gobject)
++{
++  AgsRecyclingContext *recycling_context;
++
++  GList *list, *list_next;
++
++  guint i;
++  
++  recycling_context = AGS_RECYCLING_CONTEXT(gobject);
++
++  /* parent */
++  if(recycling_context->parent != NULL){
++    g_object_unref(recycling_context->parent);
++  }
++  
++  /* recall id */
++  if(recycling_context->recall_id != NULL){
++    g_object_unref(recycling_context->recall_id);
++  }
++
++  /* recycling */
++  if(recycling_context->recycling != NULL){
++    for(i = 0; i < recycling_context->length; i++){
++      g_object_unref(recycling_context->recycling[i]);
++    }
++
++    free(recycling_context->recycling);
++    
++    recycling_context->recycling = NULL;
++    recycling_context->length = 0;
++  }
++  
++  /* children */
++  list = recycling_context->children;
++
++  while(list != NULL){
++    list_next = list->next;
++    
++    ags_recycling_context_remove_child(recycling_context,
++				       list->data);
++    
++    list = list_next;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_recycling_context_parent_class)->dispose(gobject);
++}
++
++void
+ ags_recycling_context_finalize(GObject *gobject)
+ {
++  AgsRecyclingContext *recycling_context;
++
++  GList *list;
++
++  guint i;
++    
++  recycling_context = AGS_RECYCLING_CONTEXT(gobject);
++
++  /* parent */
++  if(recycling_context->parent != NULL){
++    g_object_unref(recycling_context->parent);
++  }
++  
++  /* recall id */
++  if(recycling_context->recall_id != NULL){
++    g_object_unref(recycling_context->recall_id);
++  }
++
++  /* recycling */
++  if(recycling_context->recycling != NULL){
++    for(i = 0; i < recycling_context->length; i++){
++      g_object_unref(recycling_context->recycling[i]);
++    }
++  
++    free(recycling_context->recycling);
++  }
++  
++  /* children */
++  g_list_free(recycling_context->children);
++
++  /* call parent */
+   G_OBJECT_CLASS(ags_recycling_context_parent_class)->finalize(gobject);
+ }
+ 
+@@ -314,8 +396,10 @@
+ 			  AgsRecycling *recycling)
+ {
+   AgsRecyclingContext *new_recycling_context;
+-  gint new_length;
+ 
++  gint new_length;
++  guint i;
++  
+   if(recycling_context == NULL){
+     return(NULL);
+   }
+@@ -328,6 +412,11 @@
+   memcpy(new_recycling_context->recycling, recycling_context->recycling, new_length * sizeof(AgsRecycling *));
+   new_recycling_context->recycling[new_length] = recycling;
+ 
++  /* ref count */
++  for(i = 0; i < new_recycling_context->length; i++){
++    g_object_ref(new_recycling_context->recycling[i]);
++  }
++
+   return(new_recycling_context);
+ }
+ 
+@@ -347,9 +436,11 @@
+ 			     AgsRecycling *recycling)
+ {
+   AgsRecyclingContext *new_recycling_context;
++
+   gint new_length;
+   gint position;
+-
++  guint i;
++  
+   new_recycling_context = (AgsRecyclingContext *) g_object_new(AGS_TYPE_RECYCLING_CONTEXT,
+ 							       NULL);
+ 
+@@ -362,6 +453,11 @@
+   memcpy(new_recycling_context->recycling, recycling_context->recycling, (new_length - position) * sizeof(AgsRecycling *));
+   memcpy(&(new_recycling_context->recycling[position + 1]), recycling_context->recycling, (-1 * (position - new_length)) * sizeof(AgsRecycling *));
+ 
++  /* ref count */
++  for(i = 0; i < new_recycling_context->length; i++){
++    g_object_ref(new_recycling_context->recycling[i]);
++  }
++
+   return(new_recycling_context);
+ }
+ 
+@@ -383,7 +479,9 @@
+ 			     gint position)
+ {
+   AgsRecyclingContext *new_recycling_context;
++
+   gint new_length;
++  guint i;
+ 
+   new_recycling_context = (AgsRecyclingContext *) g_object_new(AGS_TYPE_RECYCLING_CONTEXT,
+ 							       NULL);
+@@ -395,6 +493,11 @@
+   memcpy(new_recycling_context->recycling, recycling_context->recycling, (new_length - position) * sizeof(AgsRecycling *));
+   new_recycling_context->recycling[position] = recycling;
+   memcpy(&(new_recycling_context->recycling[position + 1]), recycling_context->recycling, (-1 * (position - new_length)) * sizeof(AgsRecycling *));
++  
++  /* ref count */
++  for(i = 0; i < new_recycling_context->length; i++){
++    g_object_ref(new_recycling_context->recycling[i]);
++  }
+ 
+   return(new_recycling_context);
+ }
+@@ -613,6 +716,7 @@
+ {
+   AgsRecyclingContext *new_recycling_context;
+   AgsRecycling *recycling;
++
+   gint new_length;
+   gint first_index, last_index;
+   guint i;
+@@ -726,6 +830,11 @@
+     }
+   }
+ 
++  /* ref count */
++  for(i = 0; i < new_recycling_context->length; i++){
++    g_object_ref(new_recycling_context->recycling[i]);
++  }
++
+   return(new_recycling_context);
+ }
+ 
+--- a/ags/audio/ags_recycling_context.h
++++ b/ags/audio/ags_recycling_context.h
+@@ -37,12 +37,13 @@
+ {
+   GObject object;
+ 
++  AgsRecyclingContext *parent;
++
+   GObject *recall_id;
+ 
+   AgsRecycling **recycling;
+   guint64 length;
+ 
+-  AgsRecyclingContext *parent;
+   GList *children;
+ };
+ 
+@@ -53,6 +54,7 @@
+ 
+ GType ags_recycling_context_get_type();
+ 
++/* replace, add, remove and insert */
+ void ags_recycling_context_replace(AgsRecyclingContext *recycling_context,
+ 				   AgsRecycling *recycling,
+ 				   gint position);
+@@ -65,6 +67,7 @@
+ 						  AgsRecycling *recycling,
+ 						  gint position);
+ 
++/* tolevel, find, find child and find parent */
+ AgsRecyclingContext* ags_recycling_context_get_toplevel(AgsRecyclingContext *recycling_context);
+ 
+ gint ags_recycling_context_find(AgsRecyclingContext *recycling_context,
+@@ -74,17 +77,21 @@
+ gint ags_recycling_context_find_parent(AgsRecyclingContext *recycling_context,
+ 				       AgsRecycling *recycling);
+ 
++/* add and remove child */
+ void ags_recycling_context_add_child(AgsRecyclingContext *parent,
+ 				     AgsRecyclingContext *child);
+ void ags_recycling_context_remove_child(AgsRecyclingContext *parent,
+ 					AgsRecyclingContext *child);
+ 
++/* child recall id */
+ GList* ags_recycling_context_get_child_recall_id(AgsRecyclingContext *recycling_context);
+ 
++/* instantiate - reset recycling */
+ AgsRecyclingContext* ags_recycling_context_reset_recycling(AgsRecyclingContext *recycling_context,
+ 							   AgsRecycling *old_first_recycling, AgsRecycling *old_last_recycling,
+ 							   AgsRecycling *new_first_recycling, AgsRecycling *new_last_recycling);
+ 
++/* instantiate */
+ AgsRecyclingContext* ags_recycling_context_new(guint64 length);
+ 
+ #endif /*__AGS_RECYCLING_CONTEXT_H__*/
+--- a/ags/audio/ags_synth_generator.c
++++ b/ags/audio/ags_synth_generator.c
+@@ -21,7 +21,9 @@
+ 
+ #include <ags/util/ags_id_generator.h>
+ 
++#include <ags/object/ags_config.h>
+ #include <ags/object/ags_plugin.h>
++#include <ags/object/ags_soundcard.h>
+ 
+ #include <ags/thread/ags_timestamp.h>
+ 
+@@ -310,6 +312,87 @@
+ void
+ ags_synth_generator_init(AgsSynthGenerator *synth_generator)
+ {
++  AgsConfig *config;
++  
++  gchar *str;
++  
++  /* config */
++  config = ags_config_get_instance();
++
++  /* base init */
++  synth_generator->flags = 0;
++
++  synth_generator->samplerate = AGS_SOUNDCARD_DEFAULT_SAMPLERATE;
++  synth_generator->buffer_size = AGS_SOUNDCARD_DEFAULT_BUFFER_SIZE;
++  synth_generator->format = AGS_SOUNDCARD_DEFAULT_FORMAT;
++
++  /* samplerate */
++  str = ags_config_get_value(config,
++			     AGS_CONFIG_SOUNDCARD,
++			     "samplerate\0");
++
++  if(str == NULL){
++    str = ags_config_get_value(config,
++			       AGS_CONFIG_SOUNDCARD_0,
++			       "samplerate\0");
++  }
++  
++  if(str != NULL){
++    synth_generator->samplerate = g_ascii_strtoull(str,
++						   NULL,
++						   10);
++
++    free(str);
++  }
++
++  /* buffer size */
++  str = ags_config_get_value(config,
++			     AGS_CONFIG_SOUNDCARD,
++			     "buffer-size\0");
++
++  if(str == NULL){
++    str = ags_config_get_value(config,
++			       AGS_CONFIG_SOUNDCARD_0,
++			       "buffer-size\0");
++  }
++  
++  if(str != NULL){
++    synth_generator->buffer_size = g_ascii_strtoull(str,
++						    NULL,
++						    10);
++
++    free(str);
++  }
++
++  /* format */
++  str = ags_config_get_value(config,
++			     AGS_CONFIG_SOUNDCARD,
++			     "format\0");
++
++  if(str == NULL){
++    str = ags_config_get_value(config,
++			       AGS_CONFIG_SOUNDCARD_0,
++			       "format\0");
++  }
++  
++  if(str != NULL){
++    synth_generator->format = g_ascii_strtoull(str,
++					       NULL,
++					       10);
++
++    free(str);
++  }
++
++  /* more base init */
++  synth_generator->n_frames = 0;
++
++  synth_generator->oscillator = 0;
++  
++  synth_generator->frequency = 0.0;
++  synth_generator->phase = 0.0;
++  synth_generator->volume = 1.0;
++  
++  /* timestamp */
+   synth_generator->timestamp = NULL;
+ }
+ 
+--- a/ags/audio/ags_synth_generator.h
++++ b/ags/audio/ags_synth_generator.h
+@@ -45,6 +45,8 @@
+ struct _AgsSynthGenerator
+ {
+   AgsFunction function;
++
++  guint flags;
+   
+   guint samplerate;
+   guint buffer_size;
+--- a/ags/audio/jack/ags_jack_port.c
++++ b/ags/audio/jack/ags_jack_port.c
+@@ -49,6 +49,7 @@
+ 				GParamSpec *param_spec);
+ void ags_jack_port_connect(AgsConnectable *connectable);
+ void ags_jack_port_disconnect(AgsConnectable *connectable);
++void ags_jack_port_dispose(GObject *gobject);
+ void ags_jack_port_finalize(GObject *gobject);
+ 
+ /**
+@@ -121,6 +122,7 @@
+   gobject->set_property = ags_jack_port_set_property;
+   gobject->get_property = ags_jack_port_get_property;
+ 
++  gobject->dispose = ags_jack_port_dispose;
+   gobject->finalize = ags_jack_port_finalize;
+ 
+   /* properties */
+@@ -269,13 +271,50 @@
+ void
+ ags_jack_port_connect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsJackPort *jack_port;
++
++  jack_port = AGS_JACK_PORT(connectable);
++
++  if((AGS_JACK_PORT_CONNECTED & (jack_port->flags)) != 0){
++    return;
++  }
++
++  jack_port->flags |= AGS_JACK_PORT_CONNECTED;
+ }
+ 
+ void
+ ags_jack_port_disconnect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsJackPort *jack_port;
++
++  jack_port = AGS_JACK_PORT(connectable);
++
++  if((AGS_JACK_PORT_CONNECTED & (jack_port->flags)) == 0){
++    return;
++  }
++
++  jack_port->flags &= (~AGS_JACK_PORT_CONNECTED);
++}
++
++void
++ags_jack_port_dispose(GObject *gobject)
++{
++  AgsJackPort *jack_port;
++
++  jack_port = AGS_JACK_PORT(gobject);
++
++  /* jack client */
++  if(jack_port->jack_client != NULL){
++    g_object_unref(jack_port->jack_client);
++
++    jack_port->jack_client = NULL;
++  }
++
++  /* name */
++  g_free(jack_port->name);
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_jack_port_parent_class)->dispose(gobject);
+ }
+ 
+ void
+@@ -285,12 +324,15 @@
+ 
+   jack_port = AGS_JACK_PORT(gobject);
+ 
++  /* jack client */
+   if(jack_port->jack_client != NULL){
+     g_object_unref(jack_port->jack_client);
+   }
+-  
++
++  /* name */
+   g_free(jack_port->name);
+-  
++
++  /* call parent */
+   G_OBJECT_CLASS(ags_jack_port_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/jack/ags_jack_server.c
++++ b/ags/audio/jack/ags_jack_server.c
+@@ -48,6 +48,7 @@
+ 				  GParamSpec *param_spec);
+ void ags_jack_server_connect(AgsConnectable *connectable);
+ void ags_jack_server_disconnect(AgsConnectable *connectable);
++void ags_jack_server_dispose(GObject *gobject);
+ void ags_jack_server_finalize(GObject *gobject);
+ 
+ void ags_jack_server_set_url(AgsDistributedManager *distributed_manager,
+@@ -90,6 +91,9 @@
+   PROP_0,
+   PROP_APPLICATION_CONTEXT,
+   PROP_URL,
++  PROP_DEFAULT_SOUNDCARD,
++  PROP_DEFAULT_JACK_CLIENT,
++  PROP_JACK_CLIENT,
+ };
+ 
+ static gpointer ags_jack_server_parent_class = NULL;
+@@ -155,6 +159,7 @@
+   gobject->set_property = ags_jack_server_set_property;
+   gobject->get_property = ags_jack_server_get_property;
+ 
++  gobject->dispose = ags_jack_server_dispose;
+   gobject->finalize = ags_jack_server_finalize;
+ 
+   /* properties */
+@@ -189,6 +194,54 @@
+   g_object_class_install_property(gobject,
+ 				  PROP_URL,
+ 				  param_spec);
++
++  /**
++   * AgsJackServer:default-soundcard:
++   *
++   * The default soundcard.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_object("default-soundcard\0",
++				   "default soundcard\0",
++				   "The default soundcard\0",
++				   G_TYPE_OBJECT,
++				   G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_DEFAULT_SOUNDCARD,
++				  param_spec);
++
++  /**
++   * AgsJackServer:default-jack-client:
++   *
++   * The default jack client.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_object("default-jack-client\0",
++				   "default jack client\0",
++				   "The default jack client\0",
++				   AGS_TYPE_JACK_CLIENT,
++				   G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_DEFAULT_JACK_CLIENT,
++				  param_spec);
++
++  /**
++   * AgsJackServer:jack-client:
++   *
++   * The jack client list.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_object("jack-client\0",
++				   "jack client list\0",
++				   "The jack client list\0",
++				   AGS_TYPE_JACK_CLIENT,
++				   G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_JACK_CLIENT,
++				  param_spec);
+ }
+ 
+ void
+@@ -290,6 +343,66 @@
+       jack_server->url = g_strdup(url);
+     }
+     break;
++  case PROP_DEFAULT_SOUNDCARD:
++    {
++      GObject *default_soundcard;
++
++      default_soundcard = (GObject *) g_value_get_object(value);
++
++      if(jack_server->default_soundcard == (GObject *) default_soundcard){
++	return;
++      }
++
++      if(jack_server->default_soundcard != NULL){
++	g_object_unref(G_OBJECT(jack_server->default_soundcard));
++      }
++
++      if(default_soundcard != NULL){
++	g_object_ref(G_OBJECT(default_soundcard));
++      }
++
++      jack_server->default_soundcard = (GObject *) default_soundcard;
++    }
++    break;
++  case PROP_DEFAULT_JACK_CLIENT:
++    {
++      AgsJackClient *default_client;
++
++      default_client = (AgsJackClient *) g_value_get_object(value);
++
++      if(jack_server->default_client == (GObject *) default_client){
++	return;
++      }
++
++      if(jack_server->default_client != NULL){
++	g_object_unref(G_OBJECT(jack_server->default_client));
++      }
++
++      if(default_client != NULL){
++	g_object_ref(G_OBJECT(default_client));
++      }
++
++      jack_server->default_client = (GObject *) default_client;
++    }
++    break;
++  case PROP_JACK_CLIENT:
++    {
++      GObject *client;
++
++      client = (GObject *) g_value_get_object(value);
++
++      if(g_list_find(jack_server->client, client) != NULL){
++	return;
++      }
++
++      if(client != NULL){
++	g_object_ref(G_OBJECT(client));
++
++	jack_server->client = g_list_prepend(jack_server->client,
++					     client);
++      }
++    }
++    break;
+   default:
+     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+     break;
+@@ -317,6 +430,22 @@
+       g_value_set_string(value, jack_server->url);
+     }
+     break;
++  case PROP_DEFAULT_SOUNDCARD:
++    {
++      g_value_set_object(value, jack_server->default_soundcard);
++    }
++    break;
++  case PROP_DEFAULT_JACK_CLIENT:
++    {
++      g_value_set_object(value, jack_server->default_soundcard);
++    }
++    break;
++  case PROP_JACK_CLIENT:
++    {
++      g_value_set_pointer(value,
++			  g_list_copy(jack_server->client));
++    }
++    break;
+   default:
+     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+     break;
+@@ -326,28 +455,133 @@
+ void
+ ags_jack_server_connect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsJackServer *jack_server;
++
++  GList *list;
++  
++  jack_server = AGS_JACK_SERVER(connectable);
++
++  if((AGS_JACK_SERVER_CONNECTED & (jack_server->flags)) != 0){
++    return;
++  }
++
++  jack_server->flags |= AGS_JACK_SERVER_CONNECTED;
++
++  list = jack_server->client;
++
++  while(list != NULL){
++    ags_connectable_connect(AGS_CONNECTABLE(list->data));
++
++    list = list->next;
++  }
+ }
+ 
+ void
+ ags_jack_server_disconnect(AgsConnectable *connectable)
+ {
+-  /* empty */
++  AgsJackServer *jack_server;
++
++  GList *list;
++  
++  jack_server = AGS_JACK_SERVER(connectable);
++
++  if((AGS_JACK_SERVER_CONNECTED & (jack_server->flags)) != 0){
++    return;
++  }
++
++  jack_server->flags |= AGS_JACK_SERVER_CONNECTED;
++
++  list = jack_server->client;
++
++  while(list != NULL){
++    ags_connectable_disconnect(AGS_CONNECTABLE(list->data));
++
++    list = list->next;
++  }
+ }
+ 
+ void
+-ags_jack_server_finalize(GObject *gobject)
++ags_jack_server_dispose(GObject *gobject)
+ {
+   AgsJackServer *jack_server;
+ 
++  GList *list;
++  
+   jack_server = AGS_JACK_SERVER(gobject);
+ 
++  /* application context */
+   if(jack_server->application_context != NULL){
++    g_object_unref(G_OBJECT(jack_server->application_context));
++    
+     jack_server->application_context = NULL;
+   }
+ 
++  /* default soundcard */
++  if(jack_server->default_soundcard != NULL){
++    g_object_unref(G_OBJECT(jack_server->default_soundcard));
++
++    jack_server->default_soundcard = NULL;
++  }
++  
++  /* default client */
++  if(jack_server->default_client != NULL){
++    g_object_unref(G_OBJECT(jack_server->default_client));
++
++    jack_server->default_client = NULL;
++  }
++  
++  /* client */
++  if(jack_server->client != NULL){
++    list = jack_server->client;
++
++    while(list != NULL){
++      g_object_run_dispose(G_OBJECT(list->data));
++
++      list = list->next;
++    }
++    
++    g_list_free_full(jack_server->client,
++		     g_object_unref);
++
++    jack_server->client = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_jack_server_parent_class)->finalize(gobject);
++}
++
++void
++ags_jack_server_finalize(GObject *gobject)
++{
++  AgsJackServer *jack_server;
++
++  jack_server = AGS_JACK_SERVER(gobject);
++
++  /* application context */
++  if(jack_server->application_context != NULL){
++    g_object_unref(G_OBJECT(jack_server->application_context));
++  }
++
++  /* url */
+   g_free(jack_server->url);
++
++  /* default soundcard */
++  if(jack_server->default_soundcard != NULL){
++    g_object_unref(G_OBJECT(jack_server->default_soundcard));
++  }
++  
++  /* default client */
++  if(jack_server->default_client != NULL){
++    g_object_unref(G_OBJECT(jack_server->default_client));
++  }
++  
++  /* client */
++  if(jack_server->client != NULL){
++    g_list_free_full(jack_server->client,
++		     g_object_unref);
++  }
+   
++  /* call parent */
+   G_OBJECT_CLASS(ags_jack_server_parent_class)->finalize(gobject);
+ }
+ 
+@@ -518,7 +752,9 @@
+   
+   /* the default client */
+   if(jack_server->default_client == NULL){
+-    jack_server->default_client = ags_jack_client_new((GObject *) jack_server);
++    g_object_set(jack_server,
++		 "default-jack-client\0", ags_jack_client_new((GObject *) jack_server),
++		 NULL);
+     ags_jack_server_add_client(jack_server,
+ 			       jack_server->default_client);
+     
+@@ -543,10 +779,10 @@
+ 		 "device\0", str,
+ 		 NULL);
+     g_free(str);
+-    g_object_ref(jack_devout);
+-    default_client->device = g_list_prepend(default_client->device,
+-					    jack_devout);
+-
++    g_object_set(default_client,
++		 "device\0", jack_devout,
++		 NULL);
++    
+     if(initial_set &&
+        default_client->client != NULL){
+       rc = jack_set_buffer_size(default_client->client,
+@@ -562,7 +798,7 @@
+       str = g_strdup_printf("ags-soundcard%d-%04d\0",
+ 			    jack_server->n_soundcards,
+ 			    i);
+-
++      
+ #ifdef AGS_DEBUG
+       g_message("%s\0", str);
+ #endif
+@@ -571,8 +807,9 @@
+       ags_jack_client_add_port(default_client,
+ 			       (GObject *) jack_port);
+ 
+-      jack_devout->jack_port = g_list_append(jack_devout->jack_port,
+-					     jack_port);
++      g_object_set(jack_devout,
++		   "jack-port\0", jack_port,
++		   NULL);
+       
+       if(jack_devout->port_name == NULL){
+ 	jack_devout->port_name = (gchar **) malloc(2 * sizeof(gchar *));
+@@ -654,7 +891,9 @@
+   
+   /* the default client */
+   if(jack_server->default_client == NULL){
+-    jack_server->default_client = (GObject *) ags_jack_client_new((GObject *) jack_server);
++    g_object_set(jack_server,
++		 "default-jack-client\0", (GObject *) ags_jack_client_new((GObject *) jack_server),
++		 NULL);
+     ags_jack_server_add_client(jack_server,
+ 			       jack_server->default_client);
+     
+@@ -675,9 +914,9 @@
+ 	       "jack-client\0", default_client,
+ 	       "device\0", str,
+ 	       NULL);
+-  g_object_ref(jack_midiin);
+-  default_client->device = g_list_prepend(default_client->device,
+-					  jack_midiin);
++  g_object_set(default_client,
++	       "device\0", jack_midiin,
++	       NULL);
+ 
+   /* register sequencer */
+   str = g_strdup_printf("ags-sequencer%d\0",
+@@ -691,8 +930,9 @@
+   ags_jack_client_add_port(default_client,
+ 			   (GObject *) jack_port);
+ 
+-  jack_midiin->jack_port = g_list_append(jack_midiin->jack_port,
+-					 jack_port);
++  g_object_set(jack_midiin,
++	       "jack-port\0", jack_port,
++	       NULL);
+   
+   ags_jack_port_register(jack_port,
+ 			 str,
+@@ -754,7 +994,9 @@
+   
+   /* the default client */
+   if(jack_server->default_client == NULL){
+-    jack_server->default_client = (GObject *) ags_jack_client_new((GObject *) jack_server);
++    g_object_set(jack_server,
++		 "default-jack-client\0", (GObject *) ags_jack_client_new((GObject *) jack_server),
++		 NULL);
+     ags_jack_server_add_client(jack_server,
+ 			       jack_server->default_client);
+     
+@@ -776,8 +1018,9 @@
+ 	       "jack-client\0", default_client,
+ 	       "device\0", "ags-default-devout\0",
+ 	       NULL);
+-  default_client->device = g_list_prepend(default_client->device,
+-					  jack_devout);
++  g_object_set(default_client,
++	       "device\0", jack_devout,
++	       NULL);
+ 
+   if(default_client->client != NULL){
+     rc = jack_set_buffer_size(default_client->client,
+@@ -801,8 +1044,9 @@
+     ags_jack_client_add_port(default_client,
+ 			     (GObject *) jack_port);
+ 
+-    jack_devout->jack_port = g_list_prepend(jack_devout->jack_port,
+-					    jack_port);
++    g_object_set(jack_devout,
++		 "jack-port\0", jack_port,
++		 NULL);
+ 
+     if(jack_devout->port_name == NULL){
+       jack_devout->port_name = (gchar **) malloc(2 * sizeof(gchar *));
+--- a/ags/audio/recall/ags_buffer_audio_signal.c
++++ b/ags/audio/recall/ags_buffer_audio_signal.c
+@@ -164,10 +164,6 @@
+ void
+ ags_buffer_audio_signal_finalize(GObject *gobject)
+ {
+-  if(AGS_RECALL_AUDIO_SIGNAL(gobject)->destination != NULL){
+-    g_object_unref(AGS_RECALL_AUDIO_SIGNAL(gobject)->destination);
+-  }
+-  
+   /* call parent */
+   G_OBJECT_CLASS(ags_buffer_audio_signal_parent_class)->finalize(gobject); 
+ }
+--- a/ags/audio/recall/ags_buffer_channel.c
++++ b/ags/audio/recall/ags_buffer_channel.c
+@@ -39,6 +39,7 @@
+ void ags_buffer_channel_connect(AgsConnectable *connectable);
+ void ags_buffer_channel_disconnect(AgsConnectable *connectable);
+ void ags_buffer_channel_set_ports(AgsPlugin *plugin, GList *port);
++void ags_buffer_channel_dispose(GObject *gobject);
+ void ags_buffer_channel_finalize(GObject *gobject);
+ 
+ void ags_buffer_channel_set_muted(AgsMutable *mutable, gboolean muted);
+@@ -168,9 +169,17 @@
+   gobject->set_property = ags_buffer_channel_set_property;
+   gobject->get_property = ags_buffer_channel_get_property;
+ 
++  gobject->dispose = ags_buffer_channel_dispose;
+   gobject->finalize = ags_buffer_channel_finalize;
+ 
+   /* properties */
++  /**
++   * AgsBufferChannel:muted:
++   *
++   * The mute port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("muted\0",
+ 				   "mute channel\0",
+ 				   "Mute the channel\0",
+@@ -202,9 +211,11 @@
+ 				     "port-value-size\0", sizeof(gboolean),
+ 				     "port-value-length\0", 1,
+ 				     NULL);
++  g_object_ref(buffer_channel->muted);
+   buffer_channel->muted->port_value.ags_port_boolean = FALSE;
+ 
+   port = g_list_prepend(port, buffer_channel->muted);
++  g_object_ref(buffer_channel->muted);
+ 
+   /* set port */
+   AGS_RECALL(buffer_channel)->port = port;
+@@ -273,6 +284,23 @@
+ }
+ 
+ void
++ags_buffer_channel_dispose(GObject *gobject)
++{
++  AgsBufferChannel *buffer_channel;
++
++  buffer_channel = AGS_BUFFER_CHANNEL(gobject);
++
++  if(buffer_channel->muted != NULL){
++    g_object_unref(G_OBJECT(buffer_channel->muted));
++
++    buffer_channel->muted = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_buffer_channel_parent_class)->dispose(gobject);
++}
++
++void
+ ags_buffer_channel_finalize(GObject *gobject)
+ {
+   AgsBufferChannel *buffer_channel;
+--- a/ags/audio/recall/ags_copy_channel.c
++++ b/ags/audio/recall/ags_copy_channel.c
+@@ -39,6 +39,7 @@
+ void ags_copy_channel_connect(AgsConnectable *connectable);
+ void ags_copy_channel_disconnect(AgsConnectable *connectable);
+ void ags_copy_channel_set_ports(AgsPlugin *plugin, GList *port);
++void ags_copy_channel_dispose(GObject *gobject);
+ void ags_copy_channel_finalize(GObject *gobject);
+ 
+ void ags_copy_channel_set_muted(AgsMutable *mutable, gboolean muted);
+@@ -167,9 +168,17 @@
+   gobject->set_property = ags_copy_channel_set_property;
+   gobject->get_property = ags_copy_channel_get_property;
+ 
++  gobject->dispose = ags_copy_channel_dispose;
+   gobject->finalize = ags_copy_channel_finalize;
+ 
+   /* properties */
++  /**
++   * AgsCopyChannel:muted:
++   *
++   * The mute port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("muted\0",
+ 				   "mute channel\0",
+ 				   "Mute the channel\0",
+@@ -201,9 +210,12 @@
+ 				     "port-value-size\0", sizeof(gboolean),
+ 				     "port-value-length\0", 1,
+ 				     NULL);
++  g_object_ref(copy_channel->muted);
+   copy_channel->muted->port_value.ags_port_boolean = FALSE;
+ 
++  /* add to port */
+   port = g_list_prepend(port, copy_channel->muted);
++  g_object_ref(copy_channel->muted);
+ 
+   /* set port */
+   AGS_RECALL(copy_channel)->port = port;
+@@ -270,6 +282,23 @@
+ }
+ 
+ void
++ags_copy_channel_dispose(GObject *gobject)
++{
++  AgsCopyChannel *copy_channel;
++
++  copy_channel = AGS_COPY_CHANNEL(gobject);
++
++  if(copy_channel->muted != NULL){
++    g_object_unref(G_OBJECT(copy_channel->muted));
++
++    copy_channel->muted = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_copy_channel_parent_class)->dispose(gobject);
++}
++
++void
+ ags_copy_channel_finalize(GObject *gobject)
+ {
+   AgsCopyChannel *copy_channel;
+--- a/ags/audio/recall/ags_copy_notation_audio.c
++++ b/ags/audio/recall/ags_copy_notation_audio.c
+@@ -29,6 +29,7 @@
+ 					  guint prop_id,
+ 					  GValue *value,
+ 					  GParamSpec *param_spec);
++void ags_copy_notation_audio_dispose(GObject *gobject);
+ void ags_copy_notation_audio_finalize(GObject *gobject);
+ 
+ /**
+@@ -43,7 +44,6 @@
+ 
+ enum{
+   PROP_0,
+-  PROP_DEVOUT,
+   PROP_NOTATION,
+   PROP_AUDIO_CHANNEL,
+ };
+@@ -94,6 +94,13 @@
+   gobject->finalize = ags_copy_notation_audio_finalize;
+ 
+   /* properties */
++  /**
++   * AgsCopyNotationAudio:notation:
++   *
++   * The notation.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("notation\0",
+ 				   "the assigned notation\0",
+ 				   "The AgsNotation it is assigned to\0",
+@@ -103,6 +110,13 @@
+ 				  PROP_NOTATION,
+ 				  param_spec);
+ 
++  /**
++   * AgsCopyNotationAudio:audio-channel:
++   *
++   * The audio channel.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_uint("audio_channel\0",
+ 				 "the audio channel to play\0",
+ 				 "The audio channel to play of audio object\0",
+@@ -136,24 +150,6 @@
+   copy_notation_audio = AGS_COPY_NOTATION_AUDIO(gobject);
+ 
+   switch(prop_id){
+-  case PROP_DEVOUT:
+-    {
+-      GObject *soundcard;
+-
+-      soundcard = (GObject *) g_value_get_object(value);
+-
+-      if(copy_notation_audio->soundcard != soundcard)
+-	return;
+-
+-      if(copy_notation_audio->soundcard != NULL)
+-	g_object_unref(copy_notation_audio->soundcard);
+-
+-      if(soundcard != NULL)
+-	g_object_ref(soundcard);
+-
+-      copy_notation_audio->soundcard = soundcard;
+-    }
+-    break;
+   case PROP_NOTATION:
+     {
+       AgsNotation *notation;
+@@ -197,11 +193,6 @@
+   copy_notation_audio = AGS_COPY_NOTATION_AUDIO(gobject);
+ 
+   switch(prop_id){
+-  case PROP_DEVOUT:
+-    {
+-      g_value_set_object(value, copy_notation_audio->soundcard);
+-    }
+-    break;
+   case PROP_NOTATION:
+     {
+       g_value_set_object(value, copy_notation_audio->notation);
+@@ -218,8 +209,35 @@
+ }
+ 
+ void
++ags_copy_notation_audio_dispose(GObject *gobject)
++{
++  AgsCopyNotationAudio *copy_notation_audio;
++
++  copy_notation_audio = AGS_COPY_NOTATION_AUDIO(gobject);
++  
++  /* notation */
++  if(copy_notation_audio->notation != NULL){
++    g_object_unref(copy_notation_audio->notation);
++
++    copy_notation_audio->notation = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_copy_notation_audio_parent_class)->dispose(gobject);
++}
++
++void
+ ags_copy_notation_audio_finalize(GObject *gobject)
+ {
++  AgsCopyNotationAudio *copy_notation_audio;
++
++  copy_notation_audio = AGS_COPY_NOTATION_AUDIO(gobject);
++  
++  /* notation */
++  if(copy_notation_audio->notation != NULL){
++    g_object_unref(copy_notation_audio->notation);
++  }
++
+   /* call parent */
+   G_OBJECT_CLASS(ags_copy_notation_audio_parent_class)->finalize(gobject);
+ }
+--- a/ags/audio/recall/ags_copy_notation_audio.h
++++ b/ags/audio/recall/ags_copy_notation_audio.h
+@@ -46,8 +46,6 @@
+ 
+   guint flags;
+ 
+-  GObject *soundcard;
+-
+   AgsNotation *notation;
+   guint audio_channel;
+ };
+--- a/ags/audio/recall/ags_copy_notation_audio_run.c
++++ b/ags/audio/recall/ags_copy_notation_audio_run.c
+@@ -42,6 +42,7 @@
+ void ags_copy_notation_audio_run_disconnect(AgsConnectable *connectable);
+ void ags_copy_notation_audio_run_connect_dynamic(AgsDynamicConnectable *dynamic_connectable);
+ void ags_copy_notation_audio_run_disconnect_dynamic(AgsDynamicConnectable *dynamic_connectable);
++void ags_copy_notation_audio_run_dispose(GObject *gobject);
+ void ags_copy_notation_audio_run_finalize(GObject *gobject);
+ 
+ void ags_copy_notation_audio_run_resolve_dependencies(AgsRecall *recall);
+@@ -135,6 +136,7 @@
+   gobject->set_property = ags_copy_notation_audio_run_set_property;
+   gobject->get_property = ags_copy_notation_audio_run_get_property;
+ 
++  gobject->dispose = ags_copy_notation_audio_run_dispose;
+   gobject->finalize = ags_copy_notation_audio_run_finalize;
+ 
+   /* properties */
+@@ -259,15 +261,35 @@
+ }
+ 
+ void
+-ags_copy_notation_audio_run_finalize(GObject *gobject)
++ags_copy_notation_audio_run_dispose(GObject *gobject)
+ {
+   AgsCopyNotationAudioRun *copy_notation_audio_run;
+ 
+   copy_notation_audio_run = AGS_COPY_NOTATION_AUDIO_RUN(gobject);
+ 
+-  if(copy_notation_audio_run->count_beats_audio_run != NULL)
++  /* count beats audio run */
++  if(copy_notation_audio_run->count_beats_audio_run != NULL){
+     g_object_unref(copy_notation_audio_run->count_beats_audio_run);
+ 
++    copy_notation_audio_run->count_beats_audio_run = NULL;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_copy_notation_audio_run_parent_class)->dispose(gobject);
++}
++
++void
++ags_copy_notation_audio_run_finalize(GObject *gobject)
++{
++  AgsCopyNotationAudioRun *copy_notation_audio_run;
++
++  copy_notation_audio_run = AGS_COPY_NOTATION_AUDIO_RUN(gobject);
++
++  /* count beats audio run */
++  if(copy_notation_audio_run->count_beats_audio_run != NULL){
++    g_object_unref(copy_notation_audio_run->count_beats_audio_run);
++  }
++  
+   /* call parent */
+   G_OBJECT_CLASS(ags_copy_notation_audio_run_parent_class)->finalize(gobject);
+ }
+@@ -434,12 +456,12 @@
+ 
+ 	while(recycling != last_recycling->next){
+ 	  if((AGS_COPY_NOTATION_AUDIO_FIT_AUDIO_SIGNAL & (copy_notation_audio->flags)) != 0){
+-	    audio_signal = ags_audio_signal_new_with_length((GObject *) copy_notation_audio->soundcard,
++	    audio_signal = ags_audio_signal_new_with_length((GObject *) AGS_RECALL(copy_notation_audio)->soundcard,
+ 							    (GObject *) recycling,
+ 							    (GObject *) AGS_RECALL(copy_notation_audio_run)->recall_id,
+ 							    length);
+ 	  }else{
+-	    audio_signal = ags_audio_signal_new((GObject *) copy_notation_audio->soundcard,
++	    audio_signal = ags_audio_signal_new((GObject *) AGS_RECALL(copy_notation_audio)->soundcard,
+ 						(GObject *) recycling,
+ 						(GObject *) AGS_RECALL(copy_notation_audio_run)->recall_id);
+ 	  }
+--- a/ags/audio/recall/ags_copy_pattern_audio.c
++++ b/ags/audio/recall/ags_copy_pattern_audio.c
+@@ -36,6 +36,7 @@
+ 					 GValue *value,
+ 					 GParamSpec *param_spec);
+ void ags_copy_pattern_audio_set_ports(AgsPlugin *plugin, GList *port);
++void ags_copy_pattern_audio_dispose(GObject *gobject);
+ void ags_copy_pattern_audio_finalize(GObject *gobject);
+ 
+ /**
+@@ -123,9 +124,17 @@
+   gobject->set_property = ags_copy_pattern_audio_set_property;
+   gobject->get_property = ags_copy_pattern_audio_get_property;
+ 
++  gobject->dispose = ags_copy_pattern_audio_dispose;
+   gobject->finalize = ags_copy_pattern_audio_finalize;
+ 
+   /* properties */
++  /**
++   * AgsCopyPatternAudio:bank-index-0:
++   *
++   * The bank index 0 port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("bank-index-0\0",
+ 				   "current bank index 0\0",
+ 				   "The current bank index 0 of the AgsPattern\0",
+@@ -135,6 +144,13 @@
+ 				  PROP_BANK_INDEX_0,
+ 				  param_spec);
+ 
++  /**
++   * AgsCopyPatternAudio:bank-index-1:
++   *
++   * The bank index 1 port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("bank-index-1\0",
+ 				   "current bank index 1\0",
+ 				   "The current bank index 1 of the AgsPattern\0",
+@@ -157,6 +173,7 @@
+ 
+   port = NULL;
+ 
++  /* bank index 0 */
+   copy_pattern_audio->bank_index_0 = g_object_new(AGS_TYPE_PORT,
+ 						  "plugin-name\0", ags_copy_pattern_audio_plugin_name,
+ 						  "specifier\0", ags_copy_pattern_audio_specifier[0],
+@@ -166,10 +183,15 @@
+ 						  "port-value-size\0", sizeof(guint),
+ 						  "port-value-length\0", 1,
+ 						  NULL);
++  g_object_ref(copy_pattern_audio->bank_index_0);
++
+   copy_pattern_audio->bank_index_0->port_value.ags_port_uint = 0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, copy_pattern_audio->bank_index_0);
++  g_object_ref(copy_pattern_audio->bank_index_0);
+ 
++  /* bank index 1 */
+   copy_pattern_audio->bank_index_1 = g_object_new(AGS_TYPE_PORT,
+ 						  "plugin-name\0", ags_copy_pattern_audio_plugin_name,
+ 						  "specifier\0", ags_copy_pattern_audio_specifier[1],
+@@ -179,10 +201,15 @@
+ 						  "port-value-size\0", sizeof(guint),
+ 						  "port-value-length\0", 1,
+ 						  NULL);
++  g_object_ref(copy_pattern_audio->bank_index_1);
++
+   copy_pattern_audio->bank_index_1->port_value.ags_port_uint = 0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, copy_pattern_audio->bank_index_1);
++  g_object_ref(copy_pattern_audio->bank_index_1);
+ 
++  /* set port */
+   AGS_RECALL(copy_pattern_audio)->port = port;
+ }
+ 
+@@ -295,6 +322,31 @@
+ }
+ 
+ void
++ags_copy_pattern_audio_dispose(GObject *gobject)
++{
++  AgsCopyPatternAudio *copy_pattern_audio;
++  
++  copy_pattern_audio = AGS_COPY_PATTERN_AUDIO(gobject);
++
++  /* bank index 0 */
++  if(copy_pattern_audio->bank_index_0 != NULL){
++    g_object_unref(copy_pattern_audio->bank_index_0);
++
++    copy_pattern_audio->bank_index_0 = NULL;
++  }
++
++  /* bank index 1 */
++  if(copy_pattern_audio->bank_index_1 != NULL){
++    g_object_unref(copy_pattern_audio->bank_index_1);
++
++    copy_pattern_audio->bank_index_1 = NULL;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_copy_pattern_audio_parent_class)->dispose(gobject);
++}
++
++void
+ ags_copy_pattern_audio_finalize(GObject *gobject)
+ {
+   AgsCopyPatternAudio *copy_pattern_audio;
+--- a/ags/audio/recall/ags_copy_pattern_audio_run.c
++++ b/ags/audio/recall/ags_copy_pattern_audio_run.c
+@@ -45,6 +45,7 @@
+ 					     guint prop_id,
+ 					     GValue *value,
+ 					     GParamSpec *param_spec);
++void ags_copy_pattern_audio_run_dispose(GObject *gobject);
+ void ags_copy_pattern_audio_run_finalize(GObject *gobject);
+ void ags_copy_pattern_audio_run_connect(AgsConnectable *connectable);
+ void ags_copy_pattern_audio_run_disconnect(AgsConnectable *connectable);
+@@ -157,9 +158,17 @@
+   gobject->set_property = ags_copy_pattern_audio_run_set_property;
+   gobject->get_property = ags_copy_pattern_audio_run_get_property;
+ 
++  gobject->dispose = ags_copy_pattern_audio_run_dispose;
+   gobject->finalize = ags_copy_pattern_audio_run_finalize;
+ 
+   /* properties */
++  /**
++   * AgsCopyPatternAudioRun:delay-audio-run:
++   *
++   * The delay audio run dependency.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("delay-audio-run\0",
+ 				   "assigned AgsDelayAudioRun\0",
+ 				   "the AgsDelayAudioRun which emits alloc signal\0",
+@@ -169,6 +178,13 @@
+ 				  PROP_DELAY_AUDIO_RUN,
+ 				  param_spec);
+ 
++  /**
++   * AgsCopyPatternAudioRun:count-beats-audio-run:
++   *
++   * The count beats audio run dependency.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("count-beats-audio-run\0",
+ 				   "assigned AgsCountBeatsAudioRun\0",
+ 				   "the AgsCountBeatsAudioRun which emits beat signal\0",
+@@ -285,8 +301,9 @@
+ 
+       count_beats_audio_run = (AgsCountBeatsAudioRun *) g_value_get_object(value);
+ 
+-      if(copy_pattern_audio_run->count_beats_audio_run == count_beats_audio_run)
++      if(copy_pattern_audio_run->count_beats_audio_run == count_beats_audio_run){
+ 	return;
++      }
+ 
+       if(count_beats_audio_run != NULL &&
+ 	 (AGS_RECALL_TEMPLATE & (AGS_RECALL(count_beats_audio_run)->flags)) != 0){
+@@ -350,16 +367,43 @@
+ }
+ 
+ void
++ags_copy_pattern_audio_run_dispose(GObject *gobject)
++{
++  AgsCopyPatternAudioRun *copy_pattern_audio_run;
++
++  copy_pattern_audio_run = AGS_COPY_PATTERN_AUDIO_RUN(gobject);
++
++  /* delay audio run */
++  if(copy_pattern_audio_run->delay_audio_run != NULL){
++    g_object_unref(copy_pattern_audio_run->delay_audio_run);
++
++    copy_pattern_audio_run->delay_audio_run = NULL;
++  }
++  
++  /* count beats audio run */
++  if(copy_pattern_audio_run->count_beats_audio_run != NULL){
++    g_object_unref(copy_pattern_audio_run->count_beats_audio_run);
++
++    copy_pattern_audio_run->count_beats_audio_run = NULL;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_copy_pattern_audio_run_parent_class)->dispose(gobject);
++}
++
++void
+ ags_copy_pattern_audio_run_finalize(GObject *gobject)
+ {
+   AgsCopyPatternAudioRun *copy_pattern_audio_run;
+ 
+   copy_pattern_audio_run = AGS_COPY_PATTERN_AUDIO_RUN(gobject);
+ 
++  /* delay audio run */
+   if(copy_pattern_audio_run->delay_audio_run != NULL){
+     g_object_unref(copy_pattern_audio_run->delay_audio_run);
+   }
+   
++  /* count beats audio run */
+   if(copy_pattern_audio_run->count_beats_audio_run != NULL){
+     g_object_unref(copy_pattern_audio_run->count_beats_audio_run);
+   }
+--- a/ags/audio/recall/ags_copy_pattern_channel.c
++++ b/ags/audio/recall/ags_copy_pattern_channel.c
+@@ -36,6 +36,7 @@
+ 					   GValue *value,
+ 					   GParamSpec *param_spec);
+ void ags_copy_pattern_channel_set_ports(AgsPlugin *plugin, GList *port);
++void ags_copy_pattern_channel_dispose(GObject *gobject);
+ void ags_copy_pattern_channel_finalize(GObject *gobject);
+ 
+ /**
+@@ -120,9 +121,17 @@
+   gobject->set_property = ags_copy_pattern_channel_set_property;
+   gobject->get_property = ags_copy_pattern_channel_get_property;
+ 
++  gobject->dispose = ags_copy_pattern_channel_dispose;
+   gobject->finalize = ags_copy_pattern_channel_finalize;
+ 
+   /* properties */
++  /**
++   * AgsCopyPatternChannel:pattern:
++   *
++   * The pattern port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("pattern\0",
+ 				   "pattern to play\0",
+ 				   "The pattern which has to be played\0",
+@@ -145,6 +154,7 @@
+   
+   port = NULL;
+ 
++  /* pattern */
+   copy_pattern_channel->pattern = g_object_new(AGS_TYPE_PORT,
+ 					       "plugin-name\0", ags_copy_pattern_channel_plugin_name,
+ 					       "specifier\0", ags_copy_pattern_channel_specifier[0],
+@@ -152,11 +162,15 @@
+ 					       "port-value-is-pointer\0", FALSE,
+ 					       "port-value-type\0", G_TYPE_OBJECT,
+ 					       NULL);
+-
++  g_object_ref(copy_pattern_channel->pattern);
++  
+   copy_pattern_channel->pattern->port_value.ags_port_object = NULL;
+ 
++  /* add to port */
+   port = g_list_prepend(port, copy_pattern_channel->pattern);
++  g_object_ref(copy_pattern_channel->pattern);
+ 
++  /* set port */
+   AGS_RECALL(copy_pattern_channel)->port = port;
+ }
+ 
+@@ -237,16 +251,36 @@
+ }
+ 
+ void
++ags_copy_pattern_channel_dispose(GObject *gobject)
++{
++  AgsCopyPatternChannel *copy_pattern_channel;
++
++  copy_pattern_channel = AGS_COPY_PATTERN_CHANNEL(gobject);
++
++  /* pattern */
++  if(copy_pattern_channel->pattern != NULL){
++    g_object_unref(copy_pattern_channel->pattern);
++
++    copy_pattern_channel->pattern = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_copy_pattern_channel_parent_class)->dispose(gobject);
++}
++
++void
+ ags_copy_pattern_channel_finalize(GObject *gobject)
+ {
+   AgsCopyPatternChannel *copy_pattern_channel;
+ 
+   copy_pattern_channel = AGS_COPY_PATTERN_CHANNEL(gobject);
+ 
++  /* pattern */
+   if(copy_pattern_channel->pattern != NULL){
+     g_object_unref(copy_pattern_channel->pattern);
+   }
+ 
++  /* call parent */
+   G_OBJECT_CLASS(ags_copy_pattern_channel_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/recall/ags_count_beats_audio.c
++++ b/ags/audio/recall/ags_count_beats_audio.c
+@@ -39,6 +39,7 @@
+ 					GValue *value,
+ 					GParamSpec *param_spec);
+ void ags_count_beats_audio_set_ports(AgsPlugin *plugin, GList *port);
++void ags_count_beats_audio_dispose(GObject *gobject);
+ void ags_count_beats_audio_finalize(GObject *gobject);
+ void ags_count_beats_audio_connect(AgsConnectable *connectable);
+ void ags_count_beats_audio_disconnect(AgsConnectable *connectable);
+@@ -184,6 +185,7 @@
+   gobject->set_property = ags_count_beats_audio_set_property;
+   gobject->get_property = ags_count_beats_audio_get_property;
+ 
++  gobject->dispose = ags_count_beats_audio_dispose;
+   gobject->finalize = ags_count_beats_audio_finalize;
+ 
+   /* properties */
+@@ -306,10 +308,13 @@
+ 						   "port-value-size\0", sizeof(gboolean),
+ 						   "port-value-length", 1,
+ 						   NULL);
+-
++  g_object_ref(count_beats_audio->sequencer_loop);
++  
+   count_beats_audio->sequencer_loop->port_value.ags_port_boolean = FALSE;
+ 
++  /* add to port */
+   port = g_list_prepend(port, count_beats_audio->sequencer_loop);
++  g_object_ref(count_beats_audio->sequencer_loop);
+ 
+   /* notation loop */
+   count_beats_audio->notation_loop = g_object_new(AGS_TYPE_PORT,
+@@ -321,10 +326,13 @@
+ 						   "port-value-size\0", sizeof(gboolean),
+ 						   "port-value-length", 1,
+ 						   NULL);
+-
++  g_object_ref(count_beats_audio->notation_loop);
++  
+   count_beats_audio->notation_loop->port_value.ags_port_boolean = FALSE;
+ 
++  /* add to port */
+   port = g_list_prepend(port, count_beats_audio->notation_loop);
++  g_object_ref(count_beats_audio->notation_loop);
+   
+   /* sequencer-loop-start  */
+   count_beats_audio->sequencer_loop_start = g_object_new(AGS_TYPE_PORT,
+@@ -336,10 +344,13 @@
+ 							 "port-value-size\0", sizeof(gdouble),
+ 							 "port-value-length", 1,
+ 							 NULL);
+-
++  g_object_ref(count_beats_audio->sequencer_loop_start);
++  
+   count_beats_audio->sequencer_loop_start->port_value.ags_port_double = 0.0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, count_beats_audio->sequencer_loop_start);
++  g_object_ref(count_beats_audio->sequencer_loop_start);
+ 
+   /* notation-loop-start */
+   count_beats_audio->notation_loop_start = g_object_new(AGS_TYPE_PORT,
+@@ -351,11 +362,14 @@
+ 							"port-value-size\0", sizeof(gdouble),
+ 							"port-value-length", 1,
+ 							NULL);
+-
++  g_object_ref(count_beats_audio->notation_loop_start);
++  
+   count_beats_audio->notation_loop_start->port_value.ags_port_double = 0.0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, count_beats_audio->notation_loop_start);
+-
++  g_object_ref(count_beats_audio->notation_loop_start);
++  
+   /* sequencer-loop-end */
+   count_beats_audio->sequencer_loop_end = g_object_new(AGS_TYPE_PORT,
+ 						       "plugin-name\0", ags_count_beats_audio_plugin_name,
+@@ -366,11 +380,14 @@
+ 						       "port-value-size\0", sizeof(gdouble),
+ 						       "port-value-length", 1,
+ 						       NULL);
+-
++  g_object_ref(count_beats_audio->sequencer_loop_end);
++  
+   count_beats_audio->sequencer_loop_end->port_value.ags_port_double = 16.0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, count_beats_audio->sequencer_loop_end);
+-
++  g_object_ref(count_beats_audio->sequencer_loop_end);
++  
+   /* notation-loop-end */
+   count_beats_audio->notation_loop_end = g_object_new(AGS_TYPE_PORT,
+ 						      "plugin-name\0", ags_count_beats_audio_plugin_name,
+@@ -381,10 +398,13 @@
+ 						      "port-value-size\0", sizeof(gdouble),
+ 						      "port-value-length", 1,
+ 						      NULL);
+-
++  g_object_ref(count_beats_audio->notation_loop_end);
++  
+   count_beats_audio->notation_loop_end->port_value.ags_port_double = 64.0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, count_beats_audio->notation_loop_end);
++  g_object_ref(count_beats_audio->notation_loop_end);
+ 
+   /* port */
+   AGS_RECALL(count_beats_audio)->port = port;
+@@ -626,7 +646,54 @@
+   }
+ }
+ 
+-  void
++void
++ags_count_beats_audio_dispose(GObject *gobject)
++{
++  AgsCountBeatsAudio *count_beats_audio;
++
++  count_beats_audio = AGS_COUNT_BEATS_AUDIO(gobject);
++
++  if(count_beats_audio->notation_loop != NULL){
++    g_object_unref(G_OBJECT(count_beats_audio->notation_loop));
++
++    count_beats_audio->notation_loop = NULL;
++  }
++
++  if(count_beats_audio->notation_loop_start != NULL){
++    g_object_unref(G_OBJECT(count_beats_audio->notation_loop_start));
++
++    count_beats_audio->notation_loop_start = NULL;
++  }
++
++  if(count_beats_audio->notation_loop_end != NULL){
++    g_object_unref(G_OBJECT(count_beats_audio->notation_loop_end));
++
++    count_beats_audio->notation_loop_end = NULL;
++  }
++
++  if(count_beats_audio->sequencer_loop != NULL){
++    g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop));
++
++    count_beats_audio->sequencer_loop = NULL;
++  }
++
++  if(count_beats_audio->sequencer_loop_start != NULL){
++    g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop_start));
++
++    count_beats_audio->sequencer_loop_start = NULL;
++  }
++
++  if(count_beats_audio->sequencer_loop_end != NULL){
++    g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop_end));
++
++    count_beats_audio->sequencer_loop_end = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_count_beats_audio_parent_class)->dispose(gobject);
++}
++
++void
+ ags_count_beats_audio_finalize(GObject *gobject)
+ {
+   AgsCountBeatsAudio *count_beats_audio;
+--- a/ags/audio/recall/ags_envelope_channel.c
++++ b/ags/audio/recall/ags_envelope_channel.c
+@@ -37,6 +37,7 @@
+ void ags_envelope_channel_connect(AgsConnectable *connectable);
+ void ags_envelope_channel_disconnect(AgsConnectable *connectable);
+ void ags_envelope_channel_set_ports(AgsPlugin *plugin, GList *port);
++void ags_envelope_channel_dispose(GObject *gobject);
+ void ags_envelope_channel_finalize(GObject *gobject);
+ 
+ /**
+@@ -137,9 +138,17 @@
+   gobject->set_property = ags_envelope_channel_set_property;
+   gobject->get_property = ags_envelope_channel_get_property;
+ 
++  gobject->dispose = ags_envelope_channel_dispose;
+   gobject->finalize = ags_envelope_channel_finalize;
+ 
+   /* properties */
++  /**
++   * AgsEnvelopeChannel:attack:
++   *
++   * The attack of envelope.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("attack\0",
+ 				   "attack channel\0",
+ 				   "Attack of the channel\0",
+@@ -149,6 +158,13 @@
+ 				  PROP_ATTACK,
+ 				  param_spec);
+ 
++  /**
++   * AgsEnvelopeChannel:decay:
++   *
++   * The decay of envelope.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("decay\0",
+ 				   "decay channel\0",
+ 				   "Decay of the channel\0",
+@@ -158,6 +174,13 @@
+ 				  PROP_DECAY,
+ 				  param_spec);
+ 
++  /**
++   * AgsEnvelopeChannel:sustain:
++   *
++   * The sustain of envelope.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("sustain\0",
+ 				   "sustain channel\0",
+ 				   "Sustain of the channel\0",
+@@ -167,6 +190,13 @@
+ 				  PROP_SUSTAIN,
+ 				  param_spec);
+ 
++  /**
++   * AgsEnvelopeChannel:release:
++   *
++   * The release of envelope.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("release\0",
+ 				   "release channel\0",
+ 				   "Release of the channel\0",
+@@ -176,6 +206,13 @@
+ 				  PROP_RELEASE,
+ 				  param_spec);
+ 
++  /**
++   * AgsEnvelopeChannel:ratio:
++   *
++   * The ratio of envelope.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("ratio\0",
+ 				   "envelope ratio\0",
+ 				   "The ratio of the envelope\0",
+@@ -199,6 +236,7 @@
+   /* ports */
+   port = NULL;
+ 
++  /* attack */
+   envelope_channel->attack = g_object_new(AGS_TYPE_PORT,
+ 					  "plugin-name\0", g_strdup("ags-envelope\0"),
+ 					  "specifier\0", "./attack[0]\0",
+@@ -208,10 +246,15 @@
+ 					  "port-value-size\0", sizeof(gdouble),
+ 					  "port-value-length\0", 1,
+ 					  NULL);
++  g_object_ref(envelope_channel->attack);
++  
+   envelope_channel->attack->port_value.ags_port_double = 1.0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, envelope_channel->attack);
++  g_object_ref(envelope_channel->attack);
+ 
++  /* decay */
+   envelope_channel->decay = g_object_new(AGS_TYPE_PORT,
+ 					 "plugin-name\0", g_strdup("ags-envelope\0"),
+ 					 "specifier\0", "./decay[0]\0",
+@@ -221,10 +264,15 @@
+ 					 "port-value-size\0", sizeof(gdouble),
+ 					 "port-value-length\0", 1,
+ 					 NULL);
++  g_object_ref(envelope_channel->decay);
++
+   envelope_channel->decay->port_value.ags_port_double = 1.0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, envelope_channel->decay);
++  g_object_ref(envelope_channel->decay);
+ 
++  /* sustain */
+   envelope_channel->sustain = g_object_new(AGS_TYPE_PORT,
+ 					   "plugin-name\0", g_strdup("ags-envelope\0"),
+ 					   "specifier\0", "./sustain[0]\0",
+@@ -234,10 +282,15 @@
+ 					   "port-value-size\0", sizeof(gdouble),
+ 					   "port-value-length\0", 1,
+ 					   NULL);
+-  envelope_channel->sustain->port_value.ags_port_double = 1.0;
++  g_object_ref(envelope_channel->sustain);
+ 
++  envelope_channel->sustain->port_value.ags_port_double = 1.0;
++  
++  /* add to port */
+   port = g_list_prepend(port, envelope_channel->sustain);
++  g_object_ref(envelope_channel->sustain);
+ 
++  /* release */
+   envelope_channel->release = g_object_new(AGS_TYPE_PORT,
+ 					   "plugin-name\0", g_strdup("ags-envelope\0"),
+ 					   "specifier\0", "./release[0]\0",
+@@ -247,10 +300,15 @@
+ 					   "port-value-size\0", sizeof(gdouble),
+ 					   "port-value-length\0", 1,
+ 					   NULL);
++  g_object_ref(envelope_channel->release);
++  
+   envelope_channel->release->port_value.ags_port_boolean = 1.0;
+-
++  
++  /* add to port */
+   port = g_list_prepend(port, envelope_channel->release);
++  g_object_ref(envelope_channel->release);
+ 
++  /* ratio */  
+   envelope_channel->ratio = g_object_new(AGS_TYPE_PORT,
+ 					 "plugin-name\0", g_strdup("ags-envelope\0"),
+ 					 "specifier\0", "./ratio[0]\0",
+@@ -260,9 +318,13 @@
+ 					 "port-value-size\0", sizeof(gdouble),
+ 					 "port-value-length\0", 1,
+ 					 NULL);
++  g_object_ref(envelope_channel->ratio);
++  
+   envelope_channel->ratio->port_value.ags_port_boolean = 1.0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, envelope_channel->ratio);
++  g_object_ref(envelope_channel->ratio);
+ 
+   /* set ports */
+   AGS_RECALL(envelope_channel)->port = port;
+@@ -490,6 +552,47 @@
+ }
+ 
+ void
++ags_envelope_channel_dispose(GObject *gobject)
++{
++  AgsEnvelopeChannel *envelope_channel;
++
++  envelope_channel = AGS_ENVELOPE_CHANNEL(gobject);
++
++  if(envelope_channel->attack != NULL){
++    g_object_unref(G_OBJECT(envelope_channel->attack));
++
++    envelope_channel->attack = NULL;
++  }
++
++  if(envelope_channel->decay != NULL){
++    g_object_unref(G_OBJECT(envelope_channel->decay));
++
++    envelope_channel->decay = NULL;
++  }
++
++  if(envelope_channel->sustain != NULL){
++    g_object_unref(G_OBJECT(envelope_channel->sustain));
++
++    envelope_channel->sustain = NULL;
++  }
++
++  if(envelope_channel->release != NULL){
++    g_object_unref(G_OBJECT(envelope_channel->release));
++
++    envelope_channel->release = NULL;
++  }
++
++  if(envelope_channel->ratio != NULL){
++    g_object_unref(G_OBJECT(envelope_channel->ratio));
++
++    envelope_channel->ratio = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_envelope_channel_parent_class)->dispose(gobject);
++}
++
++void
+ ags_envelope_channel_finalize(GObject *gobject)
+ {
+   AgsEnvelopeChannel *envelope_channel;
+--- a/ags/audio/recall/ags_loop_channel.c
++++ b/ags/audio/recall/ags_loop_channel.c
+@@ -44,6 +44,7 @@
+ 				   GParamSpec *param_spec);
+ void ags_loop_channel_connect(AgsConnectable *connectable);
+ void ags_loop_channel_disconnect(AgsConnectable *connectable);
++void ags_loop_channel_dispose(GObject *gobject);
+ void ags_loop_channel_finalize(GObject *gobject);
+ 
+ void ags_loop_channel_sequencer_duration_changed_callback(AgsDelayAudio *delay_audio,
+@@ -130,12 +131,20 @@
+   gobject->set_property = ags_loop_channel_set_property;
+   gobject->get_property = ags_loop_channel_get_property;
+ 
++  gobject->dispose = ags_loop_channel_dispose;
+   gobject->finalize = ags_loop_channel_finalize;
+ 
+   /* properties */
++  /**
++   * AgsLoopChannel:delay-audio:
++   *
++   * The assigned #AgsDelayAudio.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("delay-audio\0",
+-				   "assigned delay-audio\0",
+-				   "The delay-audio it is assigned with\0",
++				   "assigned delay audio\0",
++				   "The delay audio it is assigned with\0",
+ 				   AGS_TYPE_DELAY_AUDIO,
+ 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
+   g_object_class_install_property(gobject,
+@@ -187,8 +196,9 @@
+ 
+       delay_audio = (AgsDelayAudio *) g_value_get_object(value);
+ 
+-      if(loop_channel->delay_audio == delay_audio)
++      if(loop_channel->delay_audio == delay_audio){
+ 	return;
++      }
+ 
+       if(loop_channel->delay_audio != NULL){
+ 	g_object_disconnect(G_OBJECT(loop_channel->delay_audio),
+@@ -225,10 +235,12 @@
+   AgsLoopChannel *loop_channel;
+ 
+   loop_channel = AGS_LOOP_CHANNEL(gobject);
+-
++  
+   switch(prop_id){
+   case PROP_DELAY_AUDIO:
+-    g_value_set_object(value, loop_channel->delay_audio);
++    {
++      g_value_set_object(value, loop_channel->delay_audio);
++    }
+     break;
+   default:
+     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+@@ -237,12 +249,31 @@
+ }
+ 
+ void
++ags_loop_channel_dispose(GObject *gobject)
++{
++  AgsLoopChannel *loop_channel;
++
++  loop_channel = AGS_LOOP_CHANNEL(gobject);
++
++  /* delay audio */
++  if(loop_channel->delay_audio != NULL){
++    g_object_unref(G_OBJECT(loop_channel->delay_audio));
++
++    loop_channel->delay_audio = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_loop_channel_parent_class)->dispose(gobject);
++}
++
++void
+ ags_loop_channel_finalize(GObject *gobject)
+ {
+   AgsLoopChannel *loop_channel;
+ 
+   loop_channel = AGS_LOOP_CHANNEL(gobject);
+ 
++  /* delay audio */
+   if(loop_channel->delay_audio != NULL){
+     g_object_unref(G_OBJECT(loop_channel->delay_audio));
+   }
+--- a/ags/audio/recall/ags_loop_channel_run.c
++++ b/ags/audio/recall/ags_loop_channel_run.c
+@@ -52,6 +52,7 @@
+ 				       guint prop_id,
+ 				       GValue *value,
+ 				       GParamSpec *param_spec);
++void ags_loop_channel_run_dispose(GObject *gobject);
+ void ags_loop_channel_run_finalize(GObject *gobject);
+ void ags_loop_channel_run_connect(AgsConnectable *connectable);
+ void ags_loop_channel_run_disconnect(AgsConnectable *connectable);
+@@ -171,9 +172,17 @@
+   gobject->set_property = ags_loop_channel_run_set_property;
+   gobject->get_property = ags_loop_channel_run_get_property;
+ 
++  gobject->dispose = ags_loop_channel_run_dispose;
+   gobject->finalize = ags_loop_channel_run_finalize;
+ 
+   /* properties */
++  /**
++   * AgsLoopChannelRun:count-beats-audio-run:
++   *
++   * The count beats audio run dependency.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("count-beats-audio-run\0",
+ 				   "assigned AgsCountBeatsAudioRun\0",
+ 				   "The pointer to a counter object which indicates when looping should happen\0",
+@@ -335,12 +344,31 @@
+ }
+ 
+ void
++ags_loop_channel_run_dispose(GObject *gobject)
++{
++  AgsLoopChannelRun *loop_channel_run;
++
++  loop_channel_run = AGS_LOOP_CHANNEL_RUN(gobject);
++
++  /* count beats audio run */
++  if(loop_channel_run->count_beats_audio_run != NULL){
++    g_object_unref(G_OBJECT(loop_channel_run->count_beats_audio_run));
++
++    loop_channel_run->count_beats_audio_run = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_loop_channel_run_parent_class)->dispose(gobject);
++}
++
++void
+ ags_loop_channel_run_finalize(GObject *gobject)
+ {
+   AgsLoopChannelRun *loop_channel_run;
+ 
+   loop_channel_run = AGS_LOOP_CHANNEL_RUN(gobject);
+ 
++  /* count beats audio run */
+   if(loop_channel_run->count_beats_audio_run != NULL){
+     g_object_unref(G_OBJECT(loop_channel_run->count_beats_audio_run));
+   }
+--- a/ags/audio/recall/ags_mute_audio.c
++++ b/ags/audio/recall/ags_mute_audio.c
+@@ -39,6 +39,7 @@
+ void ags_mute_audio_connect(AgsConnectable *connectable);
+ void ags_mute_audio_disconnect(AgsConnectable *connectable);
+ void ags_mute_audio_set_ports(AgsPlugin *plugin, GList *port);
++void ags_mute_audio_dispose(GObject *gobject);
+ void ags_mute_audio_finalize(GObject *gobject);
+ 
+ void ags_mute_audio_set_muted(AgsMutable *mutable, gboolean muted);
+@@ -133,9 +134,17 @@
+   gobject->set_property = ags_mute_audio_set_property;
+   gobject->get_property = ags_mute_audio_get_property;
+ 
++  gobject->dispose = ags_mute_audio_dispose;
+   gobject->finalize = ags_mute_audio_finalize;
+ 
+   /* properties */
++  /**
++   * AgsMuteAudio:muted:
++   *
++   * The mute port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("muted\0",
+ 				   "mute audio\0",
+ 				   "Mute the audio\0",
+@@ -190,9 +199,11 @@
+ 				   "port-value-size\0", sizeof(gboolean),
+ 				   "port-value-length\0", 1,
+ 				   NULL);
++  g_object_ref(mute_audio->muted);
+   mute_audio->muted->port_value.ags_port_boolean = FALSE;
+ 
+   port = g_list_prepend(port, mute_audio->muted);
++  g_object_ref(mute_audio->muted);
+ 
+   /*  */
+   AGS_RECALL(mute_audio)->port = port;
+@@ -292,12 +303,31 @@
+ }
+ 
+ void
++ags_mute_audio_dispose(GObject *gobject)
++{
++  AgsMuteAudio *mute_audio;
++
++  mute_audio = AGS_MUTE_AUDIO(gobject);
++
++  /* muted */
++  if(mute_audio->muted != NULL){
++    g_object_unref(G_OBJECT(mute_audio->muted));
++
++    mute_audio->muted = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_mute_audio_parent_class)->dispose(gobject);
++}
++
++void
+ ags_mute_audio_finalize(GObject *gobject)
+ {
+   AgsMuteAudio *mute_audio;
+ 
+   mute_audio = AGS_MUTE_AUDIO(gobject);
+ 
++  /* muted */
+   if(mute_audio->muted != NULL){
+     g_object_unref(G_OBJECT(mute_audio->muted));
+   }
+--- a/ags/audio/recall/ags_mute_channel.c
++++ b/ags/audio/recall/ags_mute_channel.c
+@@ -39,6 +39,7 @@
+ void ags_mute_channel_connect(AgsConnectable *connectable);
+ void ags_mute_channel_disconnect(AgsConnectable *connectable);
+ void ags_mute_channel_set_ports(AgsPlugin *plugin, GList *port);
++void ags_mute_channel_dispose(GObject *gobject);
+ void ags_mute_channel_finalize(GObject *gobject);
+ 
+ void ags_mute_channel_set_muted(AgsMutable *mutable, gboolean muted);
+@@ -156,9 +157,17 @@
+   gobject->set_property = ags_mute_channel_set_property;
+   gobject->get_property = ags_mute_channel_get_property;
+ 
++  gobject->dispose = ags_mute_channel_dispose;
+   gobject->finalize = ags_mute_channel_finalize;
+ 
+   /* properties */
++  /**
++   * AgsMuteChannel:muted:
++   *
++   * The mute port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("muted\0",
+ 				   "mute channel\0",
+ 				   "Mute the channel\0",
+@@ -190,9 +199,11 @@
+ 				     "port-value-size\0", sizeof(gboolean),
+ 				     "port-value-length\0", 1,
+ 				     NULL);
++  g_object_ref(mute_channel->muted);
+   mute_channel->muted->port_value.ags_port_boolean = FALSE;
+ 
+   port = g_list_prepend(port, mute_channel->muted);
++  g_object_ref(mute_channel->muted);
+ 
+   AGS_RECALL(mute_channel)->port = port;
+ }
+@@ -290,12 +301,31 @@
+ }
+ 
+ void
++ags_mute_channel_dispose(GObject *gobject)
++{
++  AgsMuteChannel *mute_channel;
++
++  mute_channel = AGS_MUTE_CHANNEL(gobject);
++
++  /* muted */
++  if(mute_channel->muted != NULL){
++    g_object_unref(G_OBJECT(mute_channel->muted));
++
++    mute_channel->muted = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_mute_channel_parent_class)->dispose(gobject);
++}
++
++void
+ ags_mute_channel_finalize(GObject *gobject)
+ {
+   AgsMuteChannel *mute_channel;
+ 
+   mute_channel = AGS_MUTE_CHANNEL(gobject);
+ 
++  /* muted */
+   if(mute_channel->muted != NULL){
+     g_object_unref(G_OBJECT(mute_channel->muted));
+   }
+--- a/ags/audio/recall/ags_peak_channel.c
++++ b/ags/audio/recall/ags_peak_channel.c
+@@ -47,6 +47,7 @@
+ void ags_peak_channel_connect(AgsConnectable *connectable);
+ void ags_peak_channel_disconnect(AgsConnectable *connectable);
+ void ags_peak_channel_set_ports(AgsPlugin *plugin, GList *port);
++void ags_peak_channel_dispose(GObject *gobject);
+ void ags_peak_channel_finalize(GObject *gobject);
+ 
+ /**
+@@ -154,9 +155,17 @@
+   gobject->set_property = ags_peak_channel_set_property;
+   gobject->get_property = ags_peak_channel_get_property;
+ 
++  gobject->dispose = ags_peak_channel_dispose;
+   gobject->finalize = ags_peak_channel_finalize;
+ 
+   /* properties */
++  /**
++   * AgsPeakChannel:peak:
++   * 
++   * The peak of the channel.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("peak\0",
+ 				   "peak of channel\0",
+ 				   "The peak of channel\0",
+@@ -191,6 +200,7 @@
+   peak_channel->peak->port_value.ags_port_double = FALSE;
+ 
+   port = g_list_prepend(port, peak_channel->peak);
++  g_object_ref(peak_channel->peak);
+ 
+   /* set port */
+   AGS_RECALL(peak_channel)->port = port;
+@@ -257,12 +267,31 @@
+ }
+ 
+ void
++ags_peak_channel_dispose(GObject *gobject)
++{
++  AgsPeakChannel *peak_channel;
++
++  peak_channel = AGS_PEAK_CHANNEL(gobject);
++
++  /* peak */
++  if(peak_channel->peak != NULL){
++    g_object_unref(G_OBJECT(peak_channel->peak));
++
++    peak_channel->peak = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_peak_channel_parent_class)->dispose(gobject);
++}
++
++void
+ ags_peak_channel_finalize(GObject *gobject)
+ {
+   AgsPeakChannel *peak_channel;
+ 
+   peak_channel = AGS_PEAK_CHANNEL(gobject);
+ 
++  /* peak */
+   if(peak_channel->peak != NULL){
+     g_object_unref(G_OBJECT(peak_channel->peak));
+   }
+@@ -329,7 +358,7 @@
+   guint i;
+   guint copy_mode;
+   
+-  GValue value = {0,};
++  GValue *value;
+ 
+   if(peak_channel == NULL){
+     return;
+--- a/ags/audio/recall/ags_play_channel.c
++++ b/ags/audio/recall/ags_play_channel.c
+@@ -45,6 +45,7 @@
+ void ags_play_channel_connect(AgsConnectable *connectable);
+ void ags_play_channel_disconnect(AgsConnectable *connectable);
+ void ags_play_channel_set_ports(AgsPlugin *plugin, GList *port);
++void ags_play_channel_dispose(GObject *gobject);
+ void ags_play_channel_finalize(GObject *gobject);
+ 
+ void ags_play_channel_set_muted(AgsMutable *mutable, gboolean muted);
+@@ -152,9 +153,17 @@
+   gobject->set_property = ags_play_channel_set_property;
+   gobject->get_property = ags_play_channel_get_property;
+ 
++  gobject->dispose = ags_play_channel_dispose;
+   gobject->finalize = ags_play_channel_finalize;
+ 
+   /* properties */
++  /**
++   * AgsPlayChannel:audio-channel:
++   * 
++   * The audio channel port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("audio-channel\0",
+ 				   "assigned audio channel\0",
+ 				   "The audio channel this recall does output to\0",
+@@ -164,6 +173,13 @@
+ 				  PROP_AUDIO_CHANNEL,
+ 				  param_spec);
+ 
++  /**
++   * AgsPlayChannel:muted:
++   * 
++   * The muted port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("muted\0",
+ 				   "mute channel\0",
+ 				   "Mute the channel\0",
+@@ -211,6 +227,7 @@
+ 
+   port = NULL;
+ 
++  /* audio channel */
+   play_channel->audio_channel = g_object_new(AGS_TYPE_PORT,
+ 					     "plugin-name\0", ags_play_channel_plugin_name,
+ 					     "specifier\0", ags_play_channel_specifier[0],
+@@ -220,10 +237,15 @@
+ 					     "port-value-size\0", sizeof(guint64),
+ 					     "port-value-length\0", 1,
+ 					     NULL);
++  g_object_ref(play_channel->audio_channel);
++
+   play_channel->audio_channel->port_value.ags_port_uint = 0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, play_channel->audio_channel);
++  g_object_ref(play_channel->audio_channel);
+ 
++  /* muted */
+   play_channel->muted = g_object_new(AGS_TYPE_PORT,
+ 				     "plugin-name\0", ags_play_channel_plugin_name,
+ 				     "specifier\0", ags_play_channel_specifier[1],
+@@ -233,9 +255,13 @@
+ 				     "port-value-size\0", sizeof(gboolean),
+ 				     "port-value-length\0", 1,
+ 				     NULL);
++  g_object_ref(play_channel->muted);
++
+   play_channel->muted->port_value.ags_port_boolean = FALSE;
+ 
++  /* add to port */
+   port = g_list_prepend(port, play_channel->muted);
++  g_object_ref(play_channel->muted);
+ 
+   /* set port */
+   AGS_RECALL(play_channel)->port = port;
+@@ -328,16 +354,43 @@
+ }
+ 
+ void
++ags_play_channel_dispose(GObject *gobject)
++{
++  AgsPlayChannel *play_channel;
++
++  play_channel = AGS_PLAY_CHANNEL(gobject);
++
++  /* audio channel */
++  if(play_channel->audio_channel != NULL){
++    g_object_unref(G_OBJECT(play_channel->audio_channel));
++
++    play_channel->audio_channel = NULL;
++  }
++
++  /* muted */
++  if(play_channel->muted != NULL){
++    g_object_unref(G_OBJECT(play_channel->muted));
++
++    play_channel->muted = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_play_channel_parent_class)->dispose(gobject);
++}
++
++void
+ ags_play_channel_finalize(GObject *gobject)
+ {
+   AgsPlayChannel *play_channel;
+ 
+   play_channel = AGS_PLAY_CHANNEL(gobject);
+ 
++  /* audio channel */
+   if(play_channel->audio_channel != NULL){
+     g_object_unref(G_OBJECT(play_channel->audio_channel));
+   }
+ 
++  /* muted */
+   if(play_channel->muted != NULL){
+     g_object_unref(G_OBJECT(play_channel->muted));
+   }
+--- a/ags/audio/recall/ags_play_channel_run.c
++++ b/ags/audio/recall/ags_play_channel_run.c
+@@ -65,6 +65,7 @@
+ void ags_play_channel_run_disconnect(AgsConnectable *connectable);
+ void ags_play_channel_run_connect_dynamic(AgsDynamicConnectable *dynamic_connectable);
+ void ags_play_channel_run_disconnect_dynamic(AgsDynamicConnectable *dynamic_connectable);
++void ags_play_channel_run_dispose(GObject *gobject);
+ void ags_play_channel_run_finalize(GObject *gobject);
+ 
+ void ags_play_channel_run_run_init_inter(AgsRecall *recall);
+@@ -176,9 +177,17 @@
+   gobject->set_property = ags_play_channel_run_set_property;
+   gobject->get_property = ags_play_channel_run_get_property;
+ 
++  gobject->dispose = ags_play_channel_run_dispose;
+   gobject->finalize = ags_play_channel_run_finalize;
+ 
+   /* properties */
++  /**
++   * AgsPlayChannelRun:stream-channel-run:
++   * 
++   * The stream channel run dependency.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("stream-channel-run\0",
+ 				   "assigned AgsStreamChannelRun\0",
+ 				   "the assigned AgsStreamChannelRun\0",
+@@ -319,12 +328,31 @@
+ }
+ 
+ void
++ags_play_channel_run_dispose(GObject *gobject)
++{
++  AgsPlayChannelRun *play_channel_run;
++
++  play_channel_run = AGS_PLAY_CHANNEL_RUN(gobject);
++
++  /* stream channel run */
++  if(play_channel_run->stream_channel_run != NULL){
++    g_object_unref(G_OBJECT(play_channel_run->stream_channel_run));
++
++    play_channel_run->stream_channel_run = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_play_channel_run_parent_class)->dispose(gobject);
++}
++
++void
+ ags_play_channel_run_finalize(GObject *gobject)
+ {
+   AgsPlayChannelRun *play_channel_run;
+ 
+   play_channel_run = AGS_PLAY_CHANNEL_RUN(gobject);
+ 
++  /* stream channel run */
+   if(play_channel_run->stream_channel_run != NULL){
+     g_object_unref(G_OBJECT(play_channel_run->stream_channel_run));
+   }
+--- a/ags/audio/recall/ags_play_channel_run_master.c
++++ b/ags/audio/recall/ags_play_channel_run_master.c
+@@ -54,6 +54,7 @@
+ void ags_play_channel_run_master_disconnect(AgsConnectable *connectable);
+ void ags_play_channel_run_master_connect_dynamic(AgsDynamicConnectable *dynamic_connectable);
+ void ags_play_channel_run_master_disconnect_dynamic(AgsDynamicConnectable *dynamic_connectable);
++void ags_play_channel_run_master_dispose(GObject *gobject);
+ void ags_play_channel_run_master_finalize(GObject *gobject);
+ 
+ void ags_play_channel_run_master_run_init_pre(AgsRecall *recall);
+@@ -173,9 +174,17 @@
+   gobject->set_property = ags_play_channel_run_master_set_property;
+   gobject->get_property = ags_play_channel_run_master_get_property;
+ 
++  gobject->dispose = ags_play_channel_run_master_dispose;
+   gobject->finalize = ags_play_channel_run_master_finalize;
+ 
+   /* properties */
++  /**
++   * AgsPlayChannelRunMaster:stream-channel-run:
++   * 
++   * The assigned stream channel run.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("stream-channel-run\0",
+ 				   "assigned AgsStreamChannelRun\0",
+ 				   "an assigned AgsStreamChannelRun\0",
+@@ -324,10 +333,37 @@
+ }
+ 
+ void
++ags_play_channel_run_master_dispose(GObject *gobject)
++{
++  AgsPlayChannelRunMaster *play_channel_run_master;
++
++  play_channel_run_master = AGS_PLAY_CHANNEL_RUN_MASTER(gobject);
++
++  /* streamer */
++  if(play_channel_run_master->streamer != NULL){
++    g_list_free_full(play_channel_run_master->streamer,
++		     ags_play_channel_run_master_streamer_free);
++
++    play_channel_run_master->streamer = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_play_channel_run_master_parent_class)->dispose(gobject);
++}
++
++void
+ ags_play_channel_run_master_finalize(GObject *gobject)
+ {
+-  /* empty */
++  AgsPlayChannelRunMaster *play_channel_run_master;
+ 
++  play_channel_run_master = AGS_PLAY_CHANNEL_RUN_MASTER(gobject);
++  
++  /* streamer */
++  if(play_channel_run_master->streamer != NULL){
++    g_list_free_full(play_channel_run_master->streamer,
++		     ags_play_channel_run_master_streamer_free);
++  }
++  
+   /* call parent */
+   G_OBJECT_CLASS(ags_play_channel_run_master_parent_class)->finalize(gobject);
+ }
+@@ -657,6 +693,13 @@
+ void
+ ags_play_channel_run_master_streamer_free(AgsPlayChannelRunMasterStreamer *streamer)
+ {
++  if(streamer == NULL){
++    return;
++  }
++  
++  g_object_unref(streamer->play_channel_run_master);
++  g_object_unref(streamer->stream_channel_run);
++  
+   free(streamer);
+ }
+ 
+@@ -666,11 +709,19 @@
+ {
+   AgsPlayChannelRunMasterStreamer *streamer;
+ 
++  if(play_channel_run_master == NULL ||
++     stream_channel_run == NULL){
++    return;
++  }
++  
+   streamer = (AgsPlayChannelRunMasterStreamer *) malloc(sizeof(AgsPlayChannelRunMasterStreamer));
+ 
+   streamer->play_channel_run_master = play_channel_run_master;
++  g_object_ref(play_channel_run_master);
++  
+   streamer->stream_channel_run = stream_channel_run;
+-
++  g_object_ref(stream_channel_run);
++  
+   return(streamer);
+ }
+ 
+--- a/ags/audio/recall/ags_play_notation_audio_run.c
++++ b/ags/audio/recall/ags_play_notation_audio_run.c
+@@ -57,6 +57,7 @@
+ 					      guint prop_id,
+ 					      GValue *value,
+ 					      GParamSpec *param_spec);
++void ags_play_notation_audio_run_dispose(GObject *gobject);
+ void ags_play_notation_audio_run_finalize(GObject *gobject);
+ void ags_play_notation_audio_run_connect(AgsConnectable *connectable);
+ void ags_play_notation_audio_run_disconnect(AgsConnectable *connectable);
+@@ -94,6 +95,7 @@
+   PROP_0,
+   PROP_DELAY_AUDIO_RUN,
+   PROP_COUNT_BEATS_AUDIO_RUN,
++  PROP_NOTATION,
+ };
+ 
+ static gpointer ags_play_notation_audio_run_parent_class = NULL;
+@@ -173,9 +175,17 @@
+   gobject->set_property = ags_play_notation_audio_run_set_property;
+   gobject->get_property = ags_play_notation_audio_run_get_property;
+ 
++  gobject->dispose = ags_play_notation_audio_run_dispose;
+   gobject->finalize = ags_play_notation_audio_run_finalize;
+ 
+   /* properties */
++  /**
++   * AgsPlayNotationAudioRun:delay-audio-run:
++   *
++   * The delay audio run dependency.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("delay-audio-run\0",
+ 				   "assigned AgsDelayAudioRun\0",
+ 				   "the AgsDelayAudioRun which emits notation_alloc_input signal\0",
+@@ -185,6 +195,13 @@
+ 				  PROP_DELAY_AUDIO_RUN,
+ 				  param_spec);
+ 
++  /**
++   * AgsPlayNotationAudioRun:count-beats-audio-run:
++   *
++   * The count beats audio run dependency.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("count-beats-audio-run\0",
+ 				   "assigned AgsCountBeatsAudioRun\0",
+ 				   "the AgsCountBeatsAudioRun which just counts\0",
+@@ -194,6 +211,22 @@
+ 				  PROP_COUNT_BEATS_AUDIO_RUN,
+ 				  param_spec);
+ 
++  /**
++   * AgsPlayNotationAudioRun:notation:
++   *
++   * The notation containing the notes.
++   * 
++   * Since: 0.7.122.7
++   */
++  param_spec = g_param_spec_object("notation\0",
++				   "assigned AgsNotation\0",
++				   "The AgsNotation containing notes\0",
++				   AGS_TYPE_NOTATION,
++				   G_PARAM_READABLE | G_PARAM_WRITABLE);
++  g_object_class_install_property(gobject,
++				  PROP_NOTATION,
++				  param_spec);
++
+   /* AgsRecallClass */
+   recall = (AgsRecallClass *) play_notation_audio_run;
+ 
+@@ -346,6 +379,27 @@
+       play_notation_audio_run->count_beats_audio_run = count_beats_audio_run;
+     }
+     break;
++  case PROP_NOTATION:
++    {
++      AgsNotation *notation;
++
++      notation = (AgsNotation *) g_value_get_object(value);
++
++      if(play_notation_audio_run->notation == notation){
++	return;
++      }
++
++      if(play_notation_audio_run->notation != NULL){
++	g_object_unref(play_notation_audio_run->notation);
++      }
++
++      if(notation != NULL){
++	g_object_ref(notation);
++      }
++
++      play_notation_audio_run->notation = notation;
++    }
++    break;
+   default:
+     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+     break;
+@@ -373,6 +427,11 @@
+       g_value_set_object(value, G_OBJECT(play_notation_audio_run->count_beats_audio_run));
+     }
+     break;
++  case PROP_NOTATION:
++    {
++      g_value_set_object(value, play_notation_audio_run->notation);
++    }
++    break;
+   default:
+     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+     break;
+@@ -380,20 +439,60 @@
+ }
+ 
+ void
++ags_play_notation_audio_run_dispose(GObject *gobject)
++{
++  AgsPlayNotationAudioRun *play_notation_audio_run;
++
++  play_notation_audio_run = AGS_PLAY_NOTATION_AUDIO_RUN(gobject);
++
++  /* delay audio run */
++  if(play_notation_audio_run->delay_audio_run != NULL){
++    g_object_unref(G_OBJECT(play_notation_audio_run->delay_audio_run));
++
++    play_notation_audio_run->delay_audio_run = NULL;
++  }
++
++  /* count beats audio run */
++  if(play_notation_audio_run->count_beats_audio_run != NULL){
++    g_object_unref(G_OBJECT(play_notation_audio_run->count_beats_audio_run));
++
++    play_notation_audio_run->count_beats_audio_run = NULL;
++  }
++
++  /* notation */
++  if(play_notation_audio_run->notation != NULL){
++    g_object_unref(G_OBJECT(play_notation_audio_run->notation));
++
++    play_notation_audio_run->notation = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_play_notation_audio_run_parent_class)->dispose(gobject);
++}
++
++void
+ ags_play_notation_audio_run_finalize(GObject *gobject)
+ {
+   AgsPlayNotationAudioRun *play_notation_audio_run;
+ 
+   play_notation_audio_run = AGS_PLAY_NOTATION_AUDIO_RUN(gobject);
+ 
++  /* delay audio run */
+   if(play_notation_audio_run->delay_audio_run != NULL){
+     g_object_unref(G_OBJECT(play_notation_audio_run->delay_audio_run));
+   }
+ 
++  /* count beats audio run */
+   if(play_notation_audio_run->count_beats_audio_run != NULL){
+     g_object_unref(G_OBJECT(play_notation_audio_run->count_beats_audio_run));
+   }
+ 
++  /* notation */
++  if(play_notation_audio_run->notation != NULL){
++    g_object_unref(G_OBJECT(play_notation_audio_run->notation));
++  }
++
++  /* call parent */
+   G_OBJECT_CLASS(ags_play_notation_audio_run_parent_class)->finalize(gobject);
+ }
+ 
+@@ -911,7 +1010,7 @@
+ 
+ 	ags_recycling_add_audio_signal(recycling,
+ 				       audio_signal);
+-	g_object_unref(audio_signal);
++	//	g_object_unref(audio_signal);
+ 
+ 	/* iterate */
+ 	recycling = recycling->next;
+--- a/ags/audio/recall/ags_record_midi_audio.c
++++ b/ags/audio/recall/ags_record_midi_audio.c
+@@ -32,6 +32,7 @@
+ 					guint prop_id,
+ 					GValue *value,
+ 					GParamSpec *param_spec);
++void ags_record_midi_audio_dispose(GObject *gobject);
+ void ags_record_midi_audio_finalize(GObject *gobject);
+ void ags_record_midi_audio_set_ports(AgsPlugin *plugin, GList *port);
+ 
+@@ -127,9 +128,17 @@
+   gobject->set_property = ags_record_midi_audio_set_property;
+   gobject->get_property = ags_record_midi_audio_get_property;
+ 
++  gobject->dispose = ags_record_midi_audio_dispose;
+   gobject->finalize = ags_record_midi_audio_finalize;
+ 
+   /* properties */
++  /**
++   * AgsRecordMidiAudio:playback:
++   * 
++   * The playback port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("playback\0",
+ 				   "if do playback\0",
+ 				   "If playback should be performed\0",
+@@ -139,6 +148,13 @@
+ 				  PROP_PLAYBACK,
+ 				  param_spec);
+ 
++  /**
++   * AgsRecordMidiAudio:record:
++   * 
++   * The record port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("record\0",
+ 				   "if do record\0",
+ 				   "If record data for later use should be done\0",
+@@ -148,6 +164,13 @@
+ 				  PROP_RECORD,
+ 				  param_spec);
+ 
++  /**
++   * AgsRecordMidiAudio:filename:
++   * 
++   * The filename port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("filename\0",
+ 				   "filename of record\0",
+ 				   "The filename of record\0",
+@@ -157,6 +180,13 @@
+ 				  PROP_FILENAME,
+ 				  param_spec);
+ 
++  /**
++   * AgsRecordMidiAudio:division:
++   * 
++   * The division port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("division\0",
+ 				   "division of record\0",
+ 				   "The division of record\0",
+@@ -166,6 +196,13 @@
+ 				  PROP_DIVISION,
+ 				  param_spec);
+ 
++  /**
++   * AgsRecordMidiAudio:tempo:
++   * 
++   * The tempo port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("tempo\0",
+ 				   "tempo of record\0",
+ 				   "The tempo of record\0",
+@@ -175,6 +212,13 @@
+ 				  PROP_TEMPO,
+ 				  param_spec);
+ 
++  /**
++   * AgsRecordMidiAudio:bpm:
++   * 
++   * The bpm port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("bpm\0",
+ 				   "bpm of record\0",
+ 				   "The bpm of record\0",
+@@ -213,11 +257,14 @@
+ 					     "port-value-is-pointer\0", FALSE,
+ 					     "port-value-type\0", G_TYPE_BOOLEAN,
+ 					     NULL);
+-
++  g_object_ref(record_midi_audio->playback);
++  
+   record_midi_audio->playback->port_value.ags_port_boolean = TRUE;
+ 
++  /* add to port */
+   port = g_list_prepend(port, record_midi_audio->playback);
+-
++  g_object_ref(record_midi_audio->playback);
++  
+   /* record */
+   record_midi_audio->record = g_object_new(AGS_TYPE_PORT,
+ 					   "plugin-name\0", ags_record_midi_audio_plugin_name,
+@@ -226,10 +273,13 @@
+ 					   "port-value-is-pointer\0", FALSE,
+ 					   "port-value-type\0", G_TYPE_BOOLEAN,
+ 					   NULL);
+-
++  g_object_ref(record_midi_audio->record);
++  
+   record_midi_audio->record->port_value.ags_port_boolean = FALSE;
+ 
++  /* add to port */
+   port = g_list_prepend(port, record_midi_audio->record);
++  g_object_ref(record_midi_audio->record);
+ 
+   /* filename */
+   record_midi_audio->filename = g_object_new(AGS_TYPE_PORT,
+@@ -239,10 +289,13 @@
+ 					     "port-value-is-pointer\0", FALSE,
+ 					     "port-value-type\0", G_TYPE_BOOLEAN,
+ 					     NULL);
++  g_object_ref(record_midi_audio->filename);
+ 
+   record_midi_audio->filename->port_value.ags_port_boolean = TRUE;
+ 
++  /* add to port */
+   port = g_list_prepend(port, record_midi_audio->filename);
++  g_object_ref(record_midi_audio->filename);
+ 
+   /* division */
+   record_midi_audio->division = g_object_new(AGS_TYPE_PORT,
+@@ -252,10 +305,13 @@
+ 					     "port-value-is-pointer\0", FALSE,
+ 					     "port-value-type\0", G_TYPE_INT64,
+ 					     NULL);
++  g_object_ref(record_midi_audio->division);
+ 
+   record_midi_audio->division->port_value.ags_port_int = 0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, record_midi_audio->division);
++  g_object_ref(record_midi_audio->division);
+ 
+   /* tempo */
+   record_midi_audio->tempo = g_object_new(AGS_TYPE_PORT,
+@@ -265,10 +321,13 @@
+ 					  "port-value-is-pointer\0", FALSE,
+ 					  "port-value-type\0", G_TYPE_INT64,
+ 					  NULL);
++  g_object_ref(record_midi_audio->tempo);
+ 
+   record_midi_audio->tempo->port_value.ags_port_int = 0;
+ 
++  /* add to port */
+   port = g_list_prepend(port, record_midi_audio->tempo);
++  g_object_ref(record_midi_audio->tempo);
+ 
+   /* bpm */
+   record_midi_audio->bpm = g_object_new(AGS_TYPE_PORT,
+@@ -278,10 +337,13 @@
+ 					"port-value-is-pointer\0", FALSE,
+ 					"port-value-type\0", G_TYPE_INT64,
+ 					NULL);
++  g_object_ref(record_midi_audio->bpm);
+ 
+   record_midi_audio->bpm->port_value.ags_port_int = 120;
+ 
++  /* add to port */
+   port = g_list_prepend(port, record_midi_audio->bpm);
++  g_object_ref(record_midi_audio->bpm);
+ 
+   /* set port */
+   AGS_RECALL(record_midi_audio)->port = port;
+@@ -478,12 +540,95 @@
+ }
+ 
+ void
++ags_record_midi_audio_dispose(GObject *gobject)
++{
++  AgsRecordMidiAudio *record_midi_audio;
++
++  record_midi_audio = AGS_RECORD_MIDI_AUDIO(gobject);
++
++  /* playback */
++  if(record_midi_audio->playback != NULL){
++    g_object_unref(record_midi_audio->playback);
++
++    record_midi_audio->playback = NULL;
++  }
++
++  /* record */
++  if(record_midi_audio->record != NULL){
++    g_object_unref(record_midi_audio->record);
++
++    record_midi_audio->record = NULL;
++  }
++
++  /* filename */
++  if(record_midi_audio->filename != NULL){
++    g_object_unref(record_midi_audio->filename);
++
++    record_midi_audio->filename = NULL;
++  }
++
++  /* division */
++  if(record_midi_audio->division != NULL){
++    g_object_unref(record_midi_audio->division);
++
++    record_midi_audio->division = NULL;
++  }
++
++  /* tempo */
++  if(record_midi_audio->tempo != NULL){
++    g_object_unref(record_midi_audio->tempo);
++
++    record_midi_audio->tempo = NULL;
++  }
++
++  /* bpm */
++  if(record_midi_audio->bpm != NULL){
++    g_object_unref(record_midi_audio->bpm);
++
++    record_midi_audio->bpm = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_record_midi_audio_parent_class)->dispose(gobject);
++}
++
++void
+ ags_record_midi_audio_finalize(GObject *gobject)
+ {
+   AgsRecordMidiAudio *record_midi_audio;
+ 
+   record_midi_audio = AGS_RECORD_MIDI_AUDIO(gobject);
+ 
++  /* playback */
++  if(record_midi_audio->playback != NULL){
++    g_object_unref(record_midi_audio->playback);
++  }
++
++  /* record */
++  if(record_midi_audio->record != NULL){
++    g_object_unref(record_midi_audio->record);
++  }
++
++  /* filename */
++  if(record_midi_audio->filename != NULL){
++    g_object_unref(record_midi_audio->filename);
++  }
++
++  /* division */
++  if(record_midi_audio->division != NULL){
++    g_object_unref(record_midi_audio->division);
++  }
++
++  /* tempo */
++  if(record_midi_audio->tempo != NULL){
++    g_object_unref(record_midi_audio->tempo);
++  }
++
++  /* bpm */
++  if(record_midi_audio->bpm != NULL){
++    g_object_unref(record_midi_audio->bpm);
++  }
++
+   /* call parent */
+   G_OBJECT_CLASS(ags_record_midi_audio_parent_class)->finalize(gobject);
+ }
+--- a/ags/audio/recall/ags_route_dssi_audio.c
++++ b/ags/audio/recall/ags_route_dssi_audio.c
+@@ -34,6 +34,7 @@
+ 				       GValue *value,
+ 				       GParamSpec *param_spec);
+ void ags_route_dssi_audio_set_ports(AgsPlugin *plugin, GList *port);
++void ags_route_dssi_audio_dispose(GObject *gobject);
+ void ags_route_dssi_audio_finalize(GObject *gobject);
+ 
+ /**
+@@ -120,6 +121,7 @@
+   gobject->set_property = ags_route_dssi_audio_set_property;
+   gobject->get_property = ags_route_dssi_audio_get_property;
+ 
++  gobject->dispose = ags_route_dssi_audio_dispose;
+   gobject->finalize = ags_route_dssi_audio_finalize;
+ 
+   /* properties */
+@@ -178,10 +180,13 @@
+ 						  "port-value-size\0", sizeof(gboolean),
+ 						  "port-value-length", 1,
+ 						  NULL);
+-
++  g_object_ref(route_dssi_audio->notation_input);
++  
+   route_dssi_audio->notation_input->port_value.ags_port_boolean = FALSE;
+ 
++  /* add to port */
+   port = g_list_prepend(port, route_dssi_audio->notation_input);
++  g_object_ref(route_dssi_audio->notation_input);
+ 
+   /* sequencer input */
+   route_dssi_audio->sequencer_input = g_object_new(AGS_TYPE_PORT,
+@@ -193,10 +198,13 @@
+ 						  "port-value-size\0", sizeof(gboolean),
+ 						  "port-value-length", 1,
+ 						  NULL);
++  g_object_ref(route_dssi_audio->sequencer_input);
+ 
+   route_dssi_audio->sequencer_input->port_value.ags_port_boolean = FALSE;
+ 
++  /* add to port */
+   port = g_list_prepend(port, route_dssi_audio->sequencer_input);
++  g_object_ref(route_dssi_audio->sequencer_input);
+ 
+   /* port */
+   AGS_RECALL(route_dssi_audio)->port = port;
+@@ -311,6 +319,31 @@
+ }
+ 
+ void
++ags_route_dssi_audio_dispose(GObject *gobject)
++{
++  AgsRouteDssiAudio *route_dssi_audio;
++
++  route_dssi_audio = AGS_ROUTE_DSSI_AUDIO(gobject);
++
++  /* notation input */
++  if(route_dssi_audio->notation_input != NULL){
++    g_object_unref(G_OBJECT(route_dssi_audio->notation_input));
++
++    route_dssi_audio->notation_input = NULL;
++  }
++
++  /* sequencer input */
++  if(route_dssi_audio->sequencer_input != NULL){
++    g_object_unref(G_OBJECT(route_dssi_audio->sequencer_input));
++
++    route_dssi_audio->sequencer_input = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_route_dssi_audio_parent_class)->dispose(gobject);
++}
++
++void
+ ags_route_dssi_audio_finalize(GObject *gobject)
+ {
+   AgsRouteDssiAudio *route_dssi_audio;
+--- a/ags/audio/recall/ags_route_dssi_audio_run.c
++++ b/ags/audio/recall/ags_route_dssi_audio_run.c
+@@ -63,6 +63,7 @@
+ 					   guint prop_id,
+ 					   GValue *value,
+ 					   GParamSpec *param_spec);
++void ags_route_dssi_audio_run_dispose(GObject *gobject);
+ void ags_route_dssi_audio_run_finalize(GObject *gobject);
+ void ags_route_dssi_audio_run_connect(AgsConnectable *connectable);
+ void ags_route_dssi_audio_run_disconnect(AgsConnectable *connectable);
+@@ -211,9 +212,17 @@
+   gobject->set_property = ags_route_dssi_audio_run_set_property;
+   gobject->get_property = ags_route_dssi_audio_run_get_property;
+ 
++  gobject->dispose = ags_route_dssi_audio_run_dispose;
+   gobject->finalize = ags_route_dssi_audio_run_finalize;
+ 
+   /* properties */
++  /**
++   * AgsRouteDssiAudioRun:delay-audio-run:
++   * 
++   * The delay audio run dependency.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("delay-audio-run\0",
+ 				   "assigned AgsDelayAudioRun\0",
+ 				   "the AgsDelayAudioRun which emits notation_alloc_input signal\0",
+@@ -223,6 +232,13 @@
+ 				  PROP_DELAY_AUDIO_RUN,
+ 				  param_spec);
+ 
++  /**
++   * AgsRouteDssiAudioRun:count-beats-audio-run:
++   * 
++   * The count beats audio run dependency.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("count-beats-audio-run\0",
+ 				   "assigned AgsCountBeatsAudioRun\0",
+ 				   "the AgsCountBeatsAudioRun which just counts\0",
+@@ -392,20 +408,48 @@
+ }
+ 
+ void
++ags_route_dssi_audio_run_dispose(GObject *gobject)
++{
++  AgsRouteDssiAudioRun *route_dssi_audio_run;
++
++  route_dssi_audio_run = AGS_ROUTE_DSSI_AUDIO_RUN(gobject);
++
++  /* delay audio run */
++  if(route_dssi_audio_run->delay_audio_run != NULL){
++    g_object_unref(G_OBJECT(route_dssi_audio_run->delay_audio_run));
++
++    route_dssi_audio_run->delay_audio_run = NULL;
++  }
++
++  /* count beats audio run */
++  if(route_dssi_audio_run->count_beats_audio_run != NULL){
++    g_object_unref(G_OBJECT(route_dssi_audio_run->count_beats_audio_run));
++
++    route_dssi_audio_run->count_beats_audio_run = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_route_dssi_audio_run_parent_class)->finalize(gobject);
++}
++
++void
+ ags_route_dssi_audio_run_finalize(GObject *gobject)
+ {
+   AgsRouteDssiAudioRun *route_dssi_audio_run;
+ 
+   route_dssi_audio_run = AGS_ROUTE_DSSI_AUDIO_RUN(gobject);
+ 
++  /* delay audio run */
+   if(route_dssi_audio_run->delay_audio_run != NULL){
+     g_object_unref(G_OBJECT(route_dssi_audio_run->delay_audio_run));
+   }
+ 
++  /* count beats audio run */
+   if(route_dssi_audio_run->count_beats_audio_run != NULL){
+     g_object_unref(G_OBJECT(route_dssi_audio_run->count_beats_audio_run));
+   }
+ 
++  /* call parent */
+   G_OBJECT_CLASS(ags_route_dssi_audio_run_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/audio/recall/ags_route_lv2_audio.c
++++ b/ags/audio/recall/ags_route_lv2_audio.c
+@@ -34,6 +34,7 @@
+ 				      GValue *value,
+ 				      GParamSpec *param_spec);
+ void ags_route_lv2_audio_set_ports(AgsPlugin *plugin, GList *port);
++void ags_route_lv2_audio_dispose(GObject *gobject);
+ void ags_route_lv2_audio_finalize(GObject *gobject);
+ 
+ /**
+@@ -120,6 +121,7 @@
+   gobject->set_property = ags_route_lv2_audio_set_property;
+   gobject->get_property = ags_route_lv2_audio_get_property;
+ 
++  gobject->dispose = ags_route_lv2_audio_dispose;
+   gobject->finalize = ags_route_lv2_audio_finalize;
+ 
+   /* properties */
+@@ -178,10 +180,13 @@
+ 						 "port-value-size\0", sizeof(gboolean),
+ 						 "port-value-length", 1,
+ 						 NULL);
+-
++  g_object_ref(route_lv2_audio->notation_input);
++  
+   route_lv2_audio->notation_input->port_value.ags_port_boolean = FALSE;
+ 
++  /* add to port */
+   port = g_list_prepend(port, route_lv2_audio->notation_input);
++  g_object_ref(route_lv2_audio->notation_input);
+ 
+   /* sequencer input */
+   route_lv2_audio->sequencer_input = g_object_new(AGS_TYPE_PORT,
+@@ -193,12 +198,15 @@
+ 						  "port-value-size\0", sizeof(gboolean),
+ 						  "port-value-length", 1,
+ 						  NULL);
++  g_object_ref(route_lv2_audio->sequencer_input);
+ 
+   route_lv2_audio->sequencer_input->port_value.ags_port_boolean = FALSE;
+ 
++  /* add to port */
+   port = g_list_prepend(port, route_lv2_audio->sequencer_input);
++  g_object_ref(route_lv2_audio->sequencer_input);
+ 
+-  /* port */
++  /* set port */
+   AGS_RECALL(route_lv2_audio)->port = port;
+ }
+ 
+@@ -311,16 +319,43 @@
+ }
+ 
+ void
++ags_route_lv2_audio_dispose(GObject *gobject)
++{
++  AgsRouteLv2Audio *route_lv2_audio;
++
++  route_lv2_audio = AGS_ROUTE_LV2_AUDIO(gobject);
++
++  /* notation input */
++  if(route_lv2_audio->notation_input != NULL){
++    g_object_unref(G_OBJECT(route_lv2_audio->notation_input));
++
++    route_lv2_audio->notation_input = NULL;
++  }
++
++  /* sequencer input */
++  if(route_lv2_audio->sequencer_input != NULL){
++    g_object_unref(G_OBJECT(route_lv2_audio->sequencer_input));
++
++    route_lv2_audio->sequencer_input = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_route_lv2_audio_parent_class)->dispose(gobject);
++}
++
++void
+ ags_route_lv2_audio_finalize(GObject *gobject)
+ {
+   AgsRouteLv2Audio *route_lv2_audio;
+ 
+   route_lv2_audio = AGS_ROUTE_LV2_AUDIO(gobject);
+ 
++  /* notation input */
+   if(route_lv2_audio->notation_input != NULL){
+     g_object_unref(G_OBJECT(route_lv2_audio->notation_input));
+   }
+ 
++  /* sequencer input */
+   if(route_lv2_audio->sequencer_input != NULL){
+     g_object_unref(G_OBJECT(route_lv2_audio->sequencer_input));
+   }
+--- a/ags/audio/recall/ags_stream_audio_signal.c
++++ b/ags/audio/recall/ags_stream_audio_signal.c
+@@ -37,6 +37,7 @@
+ void ags_stream_audio_signal_disconnect(AgsConnectable *connectable);
+ void ags_stream_audio_signal_connect_dynamic(AgsDynamicConnectable *dynamic_connectable);
+ void ags_stream_audio_signal_disconnect_dynamic(AgsDynamicConnectable *dynamic_connectable);
++void ags_stream_audio_signal_dispose(GObject *gobject);
+ void ags_stream_audio_signal_finalize(GObject *gobject);
+ 
+ void ags_stream_audio_signal_run_init_pre(AgsRecall *recall);
+@@ -118,6 +119,7 @@
+   /* GObjectClass */
+   gobject = (GObjectClass *) stream_audio_signal;
+ 
++  gobject->dispose = ags_stream_audio_signal_dispose;
+   gobject->finalize = ags_stream_audio_signal_finalize;
+ 
+   /* AgsRecallClass */
+@@ -156,15 +158,33 @@
+   AGS_RECALL(stream_audio_signal)->port = NULL;
+ 
+   AGS_RECALL(stream_audio_signal)->child_type = G_TYPE_NONE;
++
++  stream_audio_signal->dispose_source = NULL;
++}
++
++void
++ags_stream_audio_signal_dispose(GObject *gobject)
++{
++  AGS_STREAM_AUDIO_SIGNAL(gobject)->dispose_source = AGS_RECALL_AUDIO_SIGNAL(gobject)->source;
++  /* call parent */
++  G_OBJECT_CLASS(ags_stream_audio_signal_parent_class)->dispose(gobject); 
+ }
+ 
+ void
+ ags_stream_audio_signal_finalize(GObject *gobject)
+ {
+-  if(AGS_RECALL_AUDIO_SIGNAL(gobject)->source != NULL &&
+-     AGS_RECALL_AUDIO_SIGNAL(gobject)->source->recycling != NULL){
+-    ags_recycling_remove_audio_signal((AgsRecycling *) AGS_RECALL_AUDIO_SIGNAL(gobject)->source->recycling,
+-				      AGS_RECALL_AUDIO_SIGNAL(gobject)->source);
++  if(AGS_STREAM_AUDIO_SIGNAL(gobject)->dispose_source != NULL &&
++     AGS_AUDIO_SIGNAL(AGS_STREAM_AUDIO_SIGNAL(gobject)->dispose_source)->recycling != NULL){
++    AgsRecycling *recycling;
++    AgsAudioSignal *audio_signal;
++
++    recycling = AGS_AUDIO_SIGNAL(AGS_STREAM_AUDIO_SIGNAL(gobject)->dispose_source)->recycling;
++    audio_signal = AGS_STREAM_AUDIO_SIGNAL(gobject)->dispose_source;
++    
++    ags_recycling_remove_audio_signal(recycling,
++				      audio_signal);
++    g_object_run_dispose(audio_signal);
++    g_object_unref(audio_signal);
+   }
+ 
+   /* call parent */
+--- a/ags/audio/recall/ags_stream_audio_signal.h
++++ b/ags/audio/recall/ags_stream_audio_signal.h
+@@ -38,6 +38,8 @@
+ struct _AgsStreamAudioSignal
+ {
+   AgsRecallAudioSignal recall_audio_signal;
++
++  GObject *dispose_source;
+ };
+ 
+ struct _AgsStreamAudioSignalClass
+--- a/ags/audio/recall/ags_stream_channel.c
++++ b/ags/audio/recall/ags_stream_channel.c
+@@ -38,6 +38,7 @@
+ void ags_stream_channel_connect(AgsConnectable *connectable);
+ void ags_stream_channel_disconnect(AgsConnectable *connectable);
+ void ags_stream_channel_set_ports(AgsPlugin *plugin, GList *port);
++void ags_stream_channel_dispose(GObject *gobject);
+ void ags_stream_channel_finalize(GObject *gobject);
+ 
+ /**
+@@ -129,9 +130,17 @@
+   gobject->set_property = ags_stream_channel_set_property;
+   gobject->get_property = ags_stream_channel_get_property;
+ 
++  gobject->dispose = ags_stream_channel_dispose;
+   gobject->finalize = ags_stream_channel_finalize;
+ 
+   /* properties */
++  /**
++   * AgsStreamChannel:auto-sense:
++   * 
++   * The auto-sense port.
++   * 
++   * Since: 0.7.122.7
++   */
+   param_spec = g_param_spec_object("auto-sense\0",
+ 				   "mute channel\0",
+ 				   "Mute the channel\0",
+@@ -174,8 +183,10 @@
+   AGS_RECALL(stream_channel)->build_id = AGS_RECALL_DEFAULT_BUILD_ID;
+   AGS_RECALL(stream_channel)->xml_type = "ags-stream-channel\0";
+ 
++  /* initialize port */
+   port = NULL;
+ 
++  /* auto-sense */
+   stream_channel->auto_sense = g_object_new(AGS_TYPE_PORT,
+ 				     "plugin-name\0", ags_stream_channel_plugin_name,
+ 				     "specifier\0", ags_stream_channel_plugin_specifier[0],
+@@ -185,7 +196,8 @@
+ 				     "port-value-size\0", sizeof(gboolean),
+ 				     "port-value-length\0", 1,
+ 				     NULL);
+-
++  g_object_ref(stream_channel->auto_sense);
++  
+   config = ags_config_get_instance();
+   
+   str = ags_config_get_value(config,
+@@ -194,9 +206,11 @@
+   stream_channel->auto_sense->port_value.ags_port_boolean = ((!g_strcmp0(str, "true\0")
+ 							      ) ? TRUE: FALSE);
+   free(str);
+-  
+-  port = g_list_prepend(port, stream_channel->auto_sense);
+ 
++  /* add to port */
++  port = g_list_prepend(port, stream_channel->auto_sense);
++  g_object_ref(stream_channel->auto_sense);
++  
+   /* set port */
+   AGS_RECALL(stream_channel)->port = port;
+ 
+@@ -264,12 +278,31 @@
+ }
+ 
+ void
++ags_stream_channel_dispose(GObject *gobject)
++{
++  AgsStreamChannel *stream_channel;
++
++  stream_channel = AGS_STREAM_CHANNEL(gobject);
++
++  /* auto-sense */
++  if(stream_channel->auto_sense != NULL){
++    g_object_unref(G_OBJECT(stream_channel->auto_sense));
++
++    stream_channel->auto_sense = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_stream_channel_parent_class)->dispose(gobject);
++}
++
++void
+ ags_stream_channel_finalize(GObject *gobject)
+ {
+   AgsStreamChannel *stream_channel;
+ 
+   stream_channel = AGS_STREAM_CHANNEL(gobject);
+ 
++  /* auto-sense */
+   if(stream_channel->auto_sense != NULL){
+     g_object_unref(G_OBJECT(stream_channel->auto_sense));
+   }
+--- a/ags/audio/recall/ags_volume_channel.c
++++ b/ags/audio/recall/ags_volume_channel.c
+@@ -38,6 +38,7 @@
+ void ags_volume_channel_connect(AgsConnectable *connectable);
+ void ags_volume_channel_disconnect(AgsConnectable *connectable);
+ void ags_volume_channel_set_ports(AgsPlugin *plugin, GList *port);
++void ags_volume_channel_dispose(GObject *gobject);
+ void ags_volume_channel_finalize(GObject *gobject);
+ 
+ /**
+@@ -143,9 +144,17 @@
+   gobject->set_property = ags_volume_channel_set_property;
+   gobject->get_property = ags_volume_channel_get_property;
+ 
++  gobject->dispose = ags_volume_channel_dispose;
+   gobject->finalize = ags_volume_channel_finalize;
+ 
+   /* properties */
++  /**
++   * AgsVolumeChannel:volume:
++   * 
++   * The volume port.
++   * 
++   * Since: 0.7.122.7 
++   */
+   param_spec = g_param_spec_object("volume\0",
+ 				   "volume to apply\0",
+ 				   "The volume to apply on the channel\0",
+@@ -166,6 +175,7 @@
+   AGS_RECALL(volume_channel)->build_id = AGS_RECALL_DEFAULT_BUILD_ID;
+   AGS_RECALL(volume_channel)->xml_type = "ags-volume-channel\0";
+ 
++  /* initialize the port */
+   port = NULL;
+ 
+   /* volume */
+@@ -179,9 +189,11 @@
+ 					"port-value-length", 1,
+ 					NULL);
+ 
++  g_object_ref(volume_channel->volume);
+   volume_channel->volume->port_value.ags_port_double = 1.0;
+ 
+   port = g_list_prepend(port, volume_channel->volume);
++  g_object_ref(volume_channel->volume);
+ 
+   AGS_RECALL(volume_channel)->port = port;
+ }
+@@ -279,12 +291,29 @@
+ }
+ 
+ void
++ags_volume_channel_dispose(GObject *gobject)
++{
++  AgsVolumeChannel *volume_channel;
++
++  volume_channel = AGS_VOLUME_CHANNEL(gobject);
++
++  /* volume */
++  if(volume_channel->volume != NULL){
++    g_object_unref(G_OBJECT(volume_channel->volume));
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_volume_channel_parent_class)->dispose(gobject);
++}
++
++void
+ ags_volume_channel_finalize(GObject *gobject)
+ {
+   AgsVolumeChannel *volume_channel;
+ 
+   volume_channel = AGS_VOLUME_CHANNEL(gobject);
+ 
++  /* volume */
+   if(volume_channel->volume != NULL){
+     g_object_unref(G_OBJECT(volume_channel->volume));
+   }
+--- a/ags/audio/task/ags_remove_audio.c
++++ b/ags/audio/task/ags_remove_audio.c
+@@ -314,6 +314,7 @@
+   ags_soundcard_set_audio(AGS_SOUNDCARD(remove_audio->soundcard),
+ 			  list);
+ 
++  g_object_run_dispose(remove_audio->audio);
+   g_object_unref(remove_audio->audio);
+ }
+ 
+--- a/ags/audio/thread/ags_audio_thread.c
++++ b/ags/audio/thread/ags_audio_thread.c
+@@ -47,6 +47,7 @@
+ 				   GParamSpec *param_spec);
+ void ags_audio_thread_connect(AgsConnectable *connectable);
+ void ags_audio_thread_disconnect(AgsConnectable *connectable);
++void ags_audio_thread_dispose(GObject *gobject);
+ void ags_audio_thread_finalize(GObject *gobject);
+ 
+ void ags_audio_thread_start(AgsThread *thread);
+@@ -127,6 +128,7 @@
+   gobject->set_property = ags_audio_thread_set_property;
+   gobject->get_property = ags_audio_thread_get_property;
+ 
++  gobject->dispose = ags_audio_thread_dispose;
+   gobject->finalize = ags_audio_thread_finalize;
+ 
+   /* properties */
+@@ -367,11 +369,63 @@
+ }
+ 
+ void
++ags_audio_thread_dispose(GObject *gobject)
++{
++  AgsAudioThread *audio_thread;
++
++  audio_thread = AGS_AUDIO_THREAD(gobject);
++
++  /* soundcard */
++  if(audio_thread->soundcard != NULL){
++    g_object_unref(audio_thread->soundcard);
++
++    audio_thread->soundcard = NULL;
++  }
++
++  /* audio */
++  if(audio_thread->audio != NULL){
++    g_object_unref(audio_thread->audio);
++
++    audio_thread->audio = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_audio_thread_parent_class)->dispose(gobject);
++}
++
++void
+ ags_audio_thread_finalize(GObject *gobject)
+ {
+-  G_OBJECT_CLASS(ags_audio_thread_parent_class)->finalize(gobject);
++  AgsAudioThread *audio_thread;
+ 
+-  /* empty */
++  audio_thread = AGS_AUDIO_THREAD(gobject);
++
++  /* soundcard */
++  if(audio_thread->soundcard != NULL){
++    g_object_unref(audio_thread->soundcard);
++  }
++
++  /* wakeup mutex and cond */
++  pthread_mutex_destroy(audio_thread->wakeup_mutex);
++  free(audio_thread->wakeup_mutex);
++  
++  pthread_mutex_destroy(audio_thread->wakeup_cond);
++  free(audio_thread->wakeup_cond);
++
++  /* sync mutex and cond */
++  pthread_mutex_destroy(audio_thread->done_mutex);
++  free(audio_thread->done_mutex);
++  
++  pthread_mutex_destroy(audio_thread->done_cond);
++  free(audio_thread->done_cond);
++
++  /* audio */
++  if(audio_thread->audio != NULL){
++    g_object_unref(audio_thread->audio);
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_audio_thread_parent_class)->finalize(gobject);
+ }
+ 
+ void
+--- a/ags/audio/thread/ags_channel_thread.c
++++ b/ags/audio/thread/ags_channel_thread.c
+@@ -43,6 +43,7 @@
+ 				     GParamSpec *param_spec);
+ void ags_channel_thread_connect(AgsConnectable *connectable);
+ void ags_channel_thread_disconnect(AgsConnectable *connectable);
++void ags_channel_thread_dispose(GObject *gobject);
+ void ags_channel_thread_finalize(GObject *gobject);
+ 
+ void ags_channel_thread_start(AgsThread *thread);
+@@ -120,6 +121,7 @@
+   gobject->set_property = ags_channel_thread_set_property;
+   gobject->get_property = ags_channel_thread_get_property;
+ 
++  gobject->dispose = ags_channel_thread_dispose;
+   gobject->finalize = ags_channel_thread_finalize;
+ 
+   /* properties */
+@@ -360,11 +362,63 @@
+ }
+ 
+ void
++ags_channel_thread_dispose(GObject *gobject)
++{
++  AgsChannelThread *channel_thread;
++
++  channel_thread = AGS_CHANNEL_THREAD(gobject);
++
++  /* soundcard */
++  if(channel_thread->soundcard != NULL){
++    g_object_unref(channel_thread->soundcard);
++
++    channel_thread->soundcard = NULL;
++  }
++
++  /* channel */
++  if(channel_thread->channel != NULL){
++    g_object_unref(channel_thread->channel);
++
++    channel_thread->channel = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_channel_thread_parent_class)->dispose(gobject);
++}
++
++void
+ ags_channel_thread_finalize(GObject *gobject)
+ {
+-  G_OBJECT_CLASS(ags_channel_thread_parent_class)->finalize(gobject);
++  AgsChannelThread *channel_thread;
+ 
+-  /* empty */
++  channel_thread = AGS_CHANNEL_THREAD(gobject);
++
++  /* soundcard */
++  if(channel_thread->soundcard != NULL){
++    g_object_unref(channel_thread->soundcard);
++  }
++
++  /* wakeup mutex and cond */
++  pthread_mutex_destroy(channel_thread->wakeup_mutex);
++  free(channel_thread->wakeup_mutex);
++  
++  pthread_mutex_destroy(channel_thread->wakeup_cond);
++  free(channel_thread->wakeup_cond);
++
++  /* sync mutex and cond */
++  pthread_mutex_destroy(channel_thread->done_mutex);
++  free(channel_thread->done_mutex);
++  
++  pthread_mutex_destroy(channel_thread->done_cond);
++  free(channel_thread->done_cond);
++
++  /* channel */
++  if(channel_thread->channel != NULL){
++    g_object_unref(channel_thread->channel);
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_channel_thread_parent_class)->finalize(gobject);
+ }
+ 
+ void
+--- a/ags/audio/thread/ags_sequencer_thread.c
++++ b/ags/audio/thread/ags_sequencer_thread.c
+@@ -47,6 +47,7 @@
+ 				       GParamSpec *param_spec);
+ void ags_sequencer_thread_connect(AgsConnectable *connectable);
+ void ags_sequencer_thread_disconnect(AgsConnectable *connectable);
++void ags_sequencer_thread_dispose(GObject *gobject);
+ void ags_sequencer_thread_finalize(GObject *gobject);
+ 
+ void ags_sequencer_thread_start(AgsThread *thread);
+@@ -133,6 +134,7 @@
+   gobject->set_property = ags_sequencer_thread_set_property;
+   gobject->get_property = ags_sequencer_thread_get_property;
+ 
++  gobject->dispose = ags_sequencer_thread_dispose;
+   gobject->finalize = ags_sequencer_thread_finalize;
+ 
+   /**
+@@ -238,6 +240,7 @@
+ 
+   sequencer_thread->sequencer = NULL;
+ 
++  sequencer_thread->timestamp_thread = NULL;
+   //  sequencer_thread->timestamp_thread = (AgsThread *) ags_timestamp_thread_new();
+   //  ags_thread_add_child(thread, sequencer_thread->timestamp_thread);
+ 
+@@ -329,11 +332,37 @@
+ }
+ 
+ void
++ags_sequencer_thread_dispose(GObject *gobject)
++{
++  AgsSequencerThread *sequencer_thread;
++
++  sequencer_thread = AGS_SEQUENCER_THREAD(gobject);
++
++  /* sequencer */
++  if(sequencer_thread->sequencer != NULL){
++    g_object_unref(sequencer_thread->sequencer);
++
++    sequencer_thread->sequencer = NULL;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_sequencer_thread_parent_class)->dispose(gobject);
++}
++
++void
+ ags_sequencer_thread_finalize(GObject *gobject)
+ {
+-  G_OBJECT_CLASS(ags_sequencer_thread_parent_class)->finalize(gobject);
++  AgsSequencerThread *sequencer_thread;
+ 
+-  /* empty */
++  sequencer_thread = AGS_SEQUENCER_THREAD(gobject);
++
++  /* sequencer */
++  if(sequencer_thread->sequencer != NULL){
++    g_object_unref(sequencer_thread->sequencer);
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_sequencer_thread_parent_class)->finalize(gobject);
+ }
+ 
+ void
+--- a/ags/audio/thread/ags_soundcard_thread.c
++++ b/ags/audio/thread/ags_soundcard_thread.c
+@@ -48,6 +48,7 @@
+ 				       GParamSpec *param_spec);
+ void ags_soundcard_thread_connect(AgsConnectable *connectable);
+ void ags_soundcard_thread_disconnect(AgsConnectable *connectable);
++void ags_soundcard_thread_dispose(GObject *gobject);
+ void ags_soundcard_thread_finalize(GObject *gobject);
+ 
+ void ags_soundcard_thread_start(AgsThread *thread);
+@@ -129,6 +130,7 @@
+   gobject->set_property = ags_soundcard_thread_set_property;
+   gobject->get_property = ags_soundcard_thread_get_property;
+ 
++  gobject->dispose = ags_soundcard_thread_dispose;
+   gobject->finalize = ags_soundcard_thread_finalize;
+ 
+   /**
+@@ -223,7 +225,8 @@
+   /*  */
+   soundcard_thread->soundcard = NULL;
+ 
+-  soundcard_thread->timestamp_thread = (AgsThread *) ags_timestamp_thread_new();
++  soundcard_thread->timestamp_thread = NULL;
++  //  soundcard_thread->timestamp_thread = (AgsThread *) ags_timestamp_thread_new();
+   //  ags_thread_add_child(thread, soundcard_thread->timestamp_thread);
+ 
+   soundcard_thread->error = NULL;
+@@ -330,11 +333,37 @@
+ }
+ 
+ void
++ags_soundcard_thread_dispose(GObject *gobject)
++{
++  AgsSoundcardThread *soundcard_thread;
++
++  soundcard_thread = AGS_SOUNDCARD_THREAD(gobject);
++
++  /* soundcard */
++  if(soundcard_thread->soundcard != NULL){
++    g_object_unref(soundcard_thread->soundcard);
++
++    soundcard_thread->soundcard = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_soundcard_thread_parent_class)->dispose(gobject);
++}
++
++void
+ ags_soundcard_thread_finalize(GObject *gobject)
+ {
+-  G_OBJECT_CLASS(ags_soundcard_thread_parent_class)->finalize(gobject);
++  AgsSoundcardThread *soundcard_thread;
+ 
+-  /* empty */
++  soundcard_thread = AGS_SOUNDCARD_THREAD(gobject);
++
++  /* soundcard */
++  if(soundcard_thread->soundcard != NULL){
++    g_object_unref(soundcard_thread->soundcard);
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_soundcard_thread_parent_class)->finalize(gobject);
+ }
+ 
+ void
+--- a/ags/gsequencer_main.c
++++ b/ags/gsequencer_main.c
+@@ -1271,8 +1271,8 @@
+   //  g_thread_init(NULL);
+   gtk_init(&argc, &argv);
+   ipatch_init();
+-  //  g_log_set_fatal_mask("GLib-GObject\0", //G_LOG_DOMAIN,
+-  //		       G_LOG_LEVEL_CRITICAL);
++  //  g_log_set_fatal_mask("GLib-GObject\0", // "Gtk\0" G_LOG_DOMAIN, // 
++  //		       G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
+ 
+   /* animate */
+   animation_thread = (pthread_t *) malloc(sizeof(pthread_t));
+--- a/ags/lib/ags_conversion.c
++++ b/ags/lib/ags_conversion.c
+@@ -261,6 +261,9 @@
+   if(conversion->description != NULL){
+     g_free(conversion->description);
+   }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_conversion_parent_class)->finalize(gobject);
+ }
+ 
+ gdouble
+--- a/ags/lib/ags_function.c
++++ b/ags/lib/ags_function.c
+@@ -342,6 +342,9 @@
+ 
+     free(function->pivot_table);
+   }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_function_parent_class)->finalize(gobject);
+ }
+ 
+ /**
+--- a/ags/lib/ags_log.c
++++ b/ags/lib/ags_log.c
+@@ -97,6 +97,7 @@
+   g_list_free_full(g_atomic_pointer_get(&(log->messages)),
+ 		   g_free);
+ 
++  /* call parent */
+   G_OBJECT_CLASS(ags_log_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/lib/ags_turtle.c
++++ b/ags/lib/ags_turtle.c
+@@ -207,10 +207,14 @@
+ 
+   switch(prop_id){
+   case PROP_FILENAME:
+-    g_value_set_string(value, turtle->filename);
++    {
++      g_value_set_string(value, turtle->filename);
++    }
+     break;
+   case PROP_XML_DOC:
+-    g_value_set_pointer(value, turtle->doc);
++    {
++      g_value_set_pointer(value, turtle->doc);
++    }
+     break;
+   default:
+     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+@@ -225,6 +229,17 @@
+   gchar **str;
+   
+   turtle = AGS_TURTLE(gobject);
++
++  if(turtle->filename != NULL){
++    g_free(turtle->filename);
++  }
++
++  if(turtle->doc != NULL){
++    xmlFreeDoc(turtle->doc);
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_turtle_parent_class)->finalize(gobject);
+ }
+ 
+ /**
+--- a/ags/lib/ags_turtle_manager.c
++++ b/ags/lib/ags_turtle_manager.c
+@@ -22,6 +22,7 @@
+ 
+ void ags_turtle_manager_class_init(AgsTurtleManagerClass *turtle_manager);
+ void ags_turtle_manager_init (AgsTurtleManager *turtle_manager);
++void ags_turtle_manager_dispose(GObject *gobject);
+ void ags_turtle_manager_finalize(GObject *gobject);
+ 
+ /**
+@@ -76,6 +77,7 @@
+   /* GObjectClass */
+   gobject = (GObjectClass *) turtle_manager;
+ 
++  gobject->dispose = ags_turtle_manager_dispose;
+   gobject->finalize = ags_turtle_manager_finalize;
+ }
+ 
+@@ -86,17 +88,42 @@
+ }
+ 
+ void
+-ags_turtle_manager_finalize(GObject *gobject)
++ags_turtle_manager_dispose(GObject *gobject)
+ {
+   AgsTurtleManager *turtle_manager;
++
+   GList *turtle;
+ 
+   turtle_manager = AGS_TURTLE_MANAGER(gobject);
+ 
+   turtle = turtle_manager->turtle;
+-
++  turtle_manager->turtle = NULL;
++  
+   g_list_free_full(turtle,
+ 		   g_object_unref);
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_turtle_manager_parent_class)->dispose(gobject);
++}
++
++void
++ags_turtle_manager_finalize(GObject *gobject)
++{
++  AgsTurtleManager *turtle_manager;
++
++  GList *turtle;
++
++  turtle_manager = AGS_TURTLE_MANAGER(gobject);
++
++  turtle = turtle_manager->turtle;
++
++  if(turtle != NULL){
++    g_list_free_full(turtle,
++		     g_object_unref);
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_turtle_manager_parent_class)->finalize(gobject);
+ }
+ 
+ /**
+--- a/ags/object/ags_application_context.c
++++ b/ags/object/ags_application_context.c
+@@ -43,6 +43,7 @@
+ 					  GParamSpec *param_spec);
+ void ags_application_context_connect(AgsConnectable *connectable);
+ void ags_application_context_disconnect(AgsConnectable *connectable);
++void ags_application_context_dispose(GObject *gobject);
+ void ags_application_context_finalize(GObject *gobject);
+ 
+ void ags_application_context_real_load_config(AgsApplicationContext *application_context);
+@@ -133,6 +134,7 @@
+   gobject->set_property = ags_application_context_set_property;
+   gobject->get_property = ags_application_context_get_property;
+ 
++  gobject->dispose = ags_application_context_dispose;
+   gobject->finalize = ags_application_context_finalize;
+ 
+   /* properties */
+@@ -436,6 +438,75 @@
+ }
+ 
+ void
++ags_application_context_dispose(GObject *gobject)
++{
++  AgsApplicationContext *application_context;
++
++  application_context = AGS_APPLICATION_CONTEXT(gobject);
++  
++  /* log */
++  if(application_context->log != NULL){
++    g_object_unref(application_context->log);
++
++    application_context->log = NULL;
++  }
++
++  /* config */
++  if(application_context->config != NULL){
++    g_object_set(application_context->config,
++		 "application-context\0", NULL,
++		 NULL);
++    
++    g_object_unref(application_context->config);
++
++    application_context->config = NULL;
++  }
++  
++  /* main loop */
++  if(application_context->main_loop != NULL){
++    g_object_set(application_context->main_loop,
++		 "application-context\0", NULL,
++		 NULL);
++
++    g_object_unref(application_context->main_loop);
++
++    application_context->main_loop = NULL;
++  }
++
++  /* autosave thread */
++  if(application_context->autosave_thread != NULL){
++    g_object_set(application_context->autosave_thread,
++		 "application-context\0", NULL,
++		 NULL);
++
++    g_object_unref(application_context->autosave_thread);
++
++    application_context->autosave_thread = NULL;
++  }
++
++  /* task thread */
++  if(application_context->task_thread != NULL){
++    g_object_unref(application_context->task_thread);
++
++    application_context->task_thread = NULL;
++  }
++
++  /* file */
++  if(application_context->file != NULL){
++    g_object_set(application_context->file,
++		 "application-context\0", NULL,
++		 NULL);
++
++    g_object_unref(application_context->file);
++
++    application_context->file = NULL;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_application_context_parent_class)->dispose(gobject);
++}
++
++void
+ ags_application_context_finalize(GObject *gobject)
+ {
+   AgsApplicationContext *application_context;
+@@ -449,16 +520,43 @@
+   pthread_mutex_destroy(application_context->mutex);
+   free(application_context->mutex);
+ 
++  /* log */
++  if(application_context->log != NULL){
++    g_object_unref(application_context->log);
++  }
++
+   /* config */
+   if(application_context->config != NULL){
++    g_object_set(application_context->config,
++		 "application-context\0", NULL,
++		 NULL);
++
+     g_object_unref(application_context->config);
+   }
+   
+   /* main loop */
+   if(application_context->main_loop != NULL){
++    g_object_set(application_context->main_loop,
++		 "application-context\0", NULL,
++		 NULL);
++
+     g_object_unref(application_context->main_loop);
+   }
+-  
++
++  /* autosave thread */
++  if(application_context->autosave_thread != NULL){
++    g_object_set(application_context->autosave_thread,
++		 "application-context\0", NULL,
++		 NULL);
++
++    g_object_unref(application_context->autosave_thread);
++  }
++
++  /* task thread */
++  if(application_context->task_thread != NULL){
++    g_object_unref(application_context->task_thread);
++  }
++
+   /* file */
+   if(application_context->file != NULL){
+     g_object_unref(application_context->file);
+--- a/ags/object/ags_config.c
++++ b/ags/object/ags_config.c
+@@ -52,6 +52,7 @@
+ gboolean ags_config_is_connected(AgsConnectable *connectable);
+ void ags_config_connect(AgsConnectable *connectable);
+ void ags_config_disconnect(AgsConnectable *connectable);
++void ags_config_dispose(GObject *gobject);
+ void ags_config_finalize(GObject *gobject);
+ gchar* ags_config_get_version(AgsConfig *config);
+ void ags_config_set_version(AgsConfig *config, gchar *version);
+@@ -141,6 +142,7 @@
+   gobject->set_property = ags_config_set_property;
+   gobject->get_property = ags_config_get_property;
+ 
++  gobject->dispose = ags_config_dispose;
+   gobject->finalize = ags_config_finalize;
+ 
+   /* properties */
+@@ -267,15 +269,18 @@
+       
+       application_context = (AgsApplicationContext *) g_value_get_object(value);
+ 
+-      if(application_context == ((AgsApplicationContext *) config->application_context))
++      if(application_context == ((AgsApplicationContext *) config->application_context)){
+ 	return;
++      }
+ 
+-      if(config->application_context != NULL)
++      if(config->application_context != NULL){
+ 	g_object_unref(config->application_context);
+-
+-      if(application_context != NULL)
++      }
++      
++      if(application_context != NULL){
+ 	g_object_ref(G_OBJECT(application_context));
+-
++      }
++      
+       config->application_context = (GObject *) application_context;
+     }
+     break;
+@@ -338,11 +343,38 @@
+ }
+ 
+ void
++ags_config_dispose(GObject *gobject)
++{
++  AgsConfig *config;
++
++  config = (AgsConfig *) gobject;
++
++  if(config->application_context != NULL){
++    g_object_unref(config->application_context);
++
++    config->application_context = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_config_parent_class)->dispose(gobject);
++}
++
++void
+ ags_config_finalize(GObject *gobject)
+ {
++  AgsConfig *config;
+ 
+-  //TODO:JK: implement me
++  config = (AgsConfig *) gobject;
++
++  if(config->application_context != NULL){
++    g_object_unref(config->application_context);
++  }
++
++  if(config->key_file != NULL){
++    g_key_file_unref(config->key_file);
++  }
+ 
++  /* call parent */
+   G_OBJECT_CLASS(ags_config_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/object/ags_connection.c
++++ b/ags/object/ags_connection.c
+@@ -29,6 +29,7 @@
+ 				 guint prop_id,
+ 				 GValue *value,
+ 				 GParamSpec *param_spec);
++void ags_connection_dispose(GObject *gobject);
+ void ags_connection_finalize(GObject *gobject);
+ 
+ /**
+@@ -91,6 +92,7 @@
+   gobject->set_property = ags_connection_set_property;
+   gobject->get_property = ags_connection_get_property;
+ 
++  gobject->dispose = ags_connection_dispose;
+   gobject->finalize = ags_connection_finalize;
+ 
+   /* properties */
+@@ -177,6 +179,23 @@
+ }
+ 
+ void
++ags_connection_dispose(GObject *gobject)
++{
++  AgsConnection *connection;
++
++  connection = AGS_CONNECTION(gobject);
++
++  if(connection->data_object != NULL){
++    g_object_unref(connection->data_object);
++
++    connection->data_object = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_connection_parent_class)->dispose(gobject);
++}
++
++void
+ ags_connection_finalize(GObject *gobject)
+ {
+   AgsConnection *connection;
+@@ -186,6 +205,9 @@
+   if(connection->data_object != NULL){
+     g_object_unref(connection->data_object);
+   }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_connection_parent_class)->finalize(gobject);
+ }
+ 
+ /**
+--- a/ags/object/ags_connection_manager.c
++++ b/ags/object/ags_connection_manager.c
+@@ -21,6 +21,7 @@
+ 
+ void ags_connection_manager_class_init(AgsConnectionManagerClass *connection_manager);
+ void ags_connection_manager_init (AgsConnectionManager *connection_manager);
++void ags_connection_manager_dispose(GObject *gobject);
+ void ags_connection_manager_finalize(GObject *gobject);
+ 
+ /**
+@@ -75,6 +76,7 @@
+   /* GObjectClass */
+   gobject = (GObjectClass *) connection_manager;
+ 
++  gobject->dispose = ags_connection_manager_dispose;
+   gobject->finalize = ags_connection_manager_finalize;
+ }
+ 
+@@ -85,6 +87,24 @@
+ }
+ 
+ void
++ags_connection_manager_dispose(GObject *gobject)
++{
++  AgsConnectionManager *connection_manager;
++
++  connection_manager = AGS_CONNECTION_MANAGER(gobject);
++
++  if(connection_manager->connection != NULL){
++    g_list_free_full(connection_manager->connection,
++		     g_object_unref);
++
++    connection_manager->connection = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_connection_manager_parent_class)->dispose(gobject);
++}
++
++void
+ ags_connection_manager_finalize(GObject *gobject)
+ {
+   AgsConnectionManager *connection_manager;
+@@ -96,6 +116,7 @@
+ 		     g_object_unref);
+   }
+ 
++  /* call parent */
+   G_OBJECT_CLASS(ags_connection_manager_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/plugin/ags_base_plugin.c
++++ b/ags/plugin/ags_base_plugin.c
+@@ -33,6 +33,7 @@
+ 				  guint prop_id,
+ 				  GValue *value,
+ 				  GParamSpec *param_spec);
++void ags_base_plugin_dispose(GObject *gobject);
+ void ags_base_plugin_finalize(GObject *gobject);
+ 
+ /**
+@@ -107,6 +108,7 @@
+   gobject->set_property = ags_base_plugin_set_property;
+   gobject->get_property = ags_base_plugin_get_property;
+ 
++  gobject->dispose = ags_base_plugin_dispose;
+   gobject->finalize = ags_base_plugin_finalize;
+ 
+   /* properties */
+@@ -432,6 +434,23 @@
+ }
+ 
+ void
++ags_base_plugin_dispose(GObject *gobject)
++{
++  AgsBasePlugin *base_plugin;
++
++  base_plugin = AGS_BASE_PLUGIN(gobject);
++
++  if(base_plugin->ui_plugin != NULL){
++    g_object_unref(base_plugin->ui_plugin);
++
++    base_plugin->ui_plugin = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_base_plugin_parent_class)->dispose(gobject);
++}
++
++void
+ ags_base_plugin_finalize(GObject *gobject)
+ {
+   AgsBasePlugin *base_plugin;
+--- a/ags/plugin/ags_dssi_manager.c
++++ b/ags/plugin/ags_dssi_manager.c
+@@ -39,6 +39,7 @@
+ 
+ void ags_dssi_manager_class_init(AgsDssiManagerClass *dssi_manager);
+ void ags_dssi_manager_init (AgsDssiManager *dssi_manager);
++void ags_dssi_manager_dispose(GObject *gobject);
+ void ags_dssi_manager_finalize(GObject *gobject);
+ 
+ /**
+@@ -99,6 +100,7 @@
+   /* GObjectClass */
+   gobject = (GObjectClass *) dssi_manager;
+ 
++  gobject->dispose = ags_dssi_manager_dispose;
+   gobject->finalize = ags_dssi_manager_finalize;
+ }
+ 
+@@ -117,6 +119,24 @@
+ }
+ 
+ void
++ags_dssi_manager_dispose(GObject *gobject)
++{
++  AgsDssiManager *dssi_manager;
++
++  dssi_manager = AGS_DSSI_MANAGER(gobject);
++
++  if(dssi_manager->dssi_plugin != NULL){
++    g_list_free_full(dssi_manager->dssi_plugin,
++		     (GDestroyNotify) g_object_unref);
++
++    dssi_manager->dssi_plugin = NULL;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_dssi_manager_parent_class)->dispose(gobject);
++}
++
++void
+ ags_dssi_manager_finalize(GObject *gobject)
+ {
+   AgsDssiManager *dssi_manager;
+@@ -129,6 +149,9 @@
+ 
+   g_list_free_full(dssi_plugin,
+ 		   (GDestroyNotify) g_object_unref);
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_dssi_manager_parent_class)->finalize(gobject);
+ }
+ 
+ /**
+--- a/ags/plugin/ags_ladspa_manager.c
++++ b/ags/plugin/ags_ladspa_manager.c
+@@ -39,6 +39,7 @@
+ 
+ void ags_ladspa_manager_class_init(AgsLadspaManagerClass *ladspa_manager);
+ void ags_ladspa_manager_init (AgsLadspaManager *ladspa_manager);
++void ags_ladspa_manager_dispose(GObject *gobject);
+ void ags_ladspa_manager_finalize(GObject *gobject);
+ 
+ /**
+@@ -99,6 +100,7 @@
+   /* GObjectClass */
+   gobject = (GObjectClass *) ladspa_manager;
+ 
++  gobject->dispose = ags_ladspa_manager_dispose;
+   gobject->finalize = ags_ladspa_manager_finalize;
+ }
+ 
+@@ -117,9 +119,28 @@
+ }
+ 
+ void
++ags_ladspa_manager_dispose(GObject *gobject)
++{
++  AgsLadspaManager *ladspa_manager;
++
++  ladspa_manager = AGS_LADSPA_MANAGER(gobject);
++
++  if(ladspa_manager->ladspa_plugin != NULL){
++    g_list_free_full(ladspa_manager->ladspa_plugin,
++		     (GDestroyNotify) g_object_unref);
++
++    ladspa_manager->ladspa_plugin = NULL;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_ladspa_manager_parent_class)->dispose(gobject);
++}
++
++void
+ ags_ladspa_manager_finalize(GObject *gobject)
+ {
+   AgsLadspaManager *ladspa_manager;
++  
+   GList *ladspa_plugin;
+ 
+   ladspa_manager = AGS_LADSPA_MANAGER(gobject);
+@@ -128,6 +149,9 @@
+ 
+   g_list_free_full(ladspa_plugin,
+ 		   (GDestroyNotify) g_object_unref);
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_ladspa_manager_parent_class)->finalize(gobject);
+ }
+ 
+ /**
+--- a/ags/plugin/ags_lv2_event_manager.c
++++ b/ags/plugin/ags_lv2_event_manager.c
+@@ -124,6 +124,9 @@
+ ags_lv2_event_manager_finalize(GObject *gobject)
+ {
+   /* empty */
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2_event_manager_parent_class)->finalize(gobject);
+ }
+ 
+ uint32_t
+--- a/ags/plugin/ags_lv2_log_manager.c
++++ b/ags/plugin/ags_lv2_log_manager.c
+@@ -122,6 +122,9 @@
+ ags_lv2_log_manager_finalize(GObject *gobject)
+ {
+   /* empty */
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2_log_manager_parent_class)->finalize(gobject);
+ }
+ 
+ /**
+--- a/ags/plugin/ags_lv2_manager.c
++++ b/ags/plugin/ags_lv2_manager.c
+@@ -48,6 +48,7 @@
+ 				  guint prop_id,
+ 				  GValue *value,
+ 				  GParamSpec *param_spec);
++void ags_lv2_manager_dispose(GObject *gobject);
+ void ags_lv2_manager_finalize(GObject *gobject);
+ 
+ /**
+@@ -111,6 +112,7 @@
+   gobject->set_property = ags_lv2_manager_set_property;
+   gobject->get_property = ags_lv2_manager_get_property;
+ 
++  gobject->dispose = ags_lv2_manager_dispose;
+   gobject->finalize = ags_lv2_manager_finalize;
+ 
+   /* properties */
+@@ -207,9 +209,28 @@
+ }
+ 
+ void
++ags_lv2_manager_dispose(GObject *gobject)
++{
++  AgsLv2Manager *lv2_manager;
++
++  lv2_manager = AGS_LV2_MANAGER(gobject);
++
++  if(lv2_manager->lv2_plugin != NULL){
++    g_list_free_full(lv2_manager->lv2_plugin,
++		     g_object_unref);
++
++    lv2_manager->lv2_plugin = NULL;
++  }
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2_manager_parent_class)->dispose(gobject);
++}
++
++void
+ ags_lv2_manager_finalize(GObject *gobject)
+ {
+   AgsLv2Manager *lv2_manager;
++
+   GList *lv2_plugin;
+ 
+   lv2_manager = AGS_LV2_MANAGER(gobject);
+@@ -218,6 +239,9 @@
+ 
+   g_list_free_full(lv2_plugin,
+ 		   g_object_unref);
++  
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2_manager_parent_class)->finalize(gobject);
+ }
+ 
+ /**
+--- a/ags/plugin/ags_lv2_plugin.c
++++ b/ags/plugin/ags_lv2_plugin.c
+@@ -45,6 +45,7 @@
+ 				 guint prop_id,
+ 				 GValue *value,
+ 				 GParamSpec *param_spec);
++void ags_lv2_plugin_dispose(GObject *gobject);
+ void ags_lv2_plugin_finalize(GObject *gobject);
+ 
+ gpointer ags_lv2_plugin_instantiate(AgsBasePlugin *base_plugin,
+@@ -125,6 +126,7 @@
+   gobject->set_property = ags_lv2_plugin_set_property;
+   gobject->get_property = ags_lv2_plugin_get_property;
+ 
++  gobject->dispose = ags_lv2_plugin_dispose;
+   gobject->finalize = ags_lv2_plugin_finalize;
+ 
+   /* properties */
+@@ -311,6 +313,29 @@
+ }
+ 
+ void
++ags_lv2_plugin_dispose(GObject *gobject)
++{
++  AgsLv2Plugin *lv2_plugin;
++
++  lv2_plugin = AGS_LV2_PLUGIN(gobject);
++
++  if(lv2_plugin->manifest != NULL){
++    g_object_unref(lv2_plugin->manifest);
++
++    lv2_plugin->manifest = NULL;
++  }
++  
++  if(lv2_plugin->turtle != NULL){
++    g_object_unref(lv2_plugin->turtle);
++
++    lv2_plugin->turtle = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2_plugin_parent_class)->dispose(gobject);
++}
++
++void
+ ags_lv2_plugin_finalize(GObject *gobject)
+ {
+   AgsLv2Plugin *lv2_plugin;
+@@ -326,6 +351,9 @@
+   if(lv2_plugin->turtle != NULL){
+     g_object_unref(lv2_plugin->turtle);
+   }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2_plugin_parent_class)->finalize(gobject);
+ }
+ 
+ gpointer
+--- a/ags/plugin/ags_lv2_uri_map_manager.c
++++ b/ags/plugin/ags_lv2_uri_map_manager.c
+@@ -133,6 +133,9 @@
+   lv2_uri_map_manager = AGS_LV2_URI_MAP_MANAGER(gobject);
+ 
+   g_hash_table_destroy(lv2_uri_map_manager->uri_map);
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2_uri_map_manager_parent_class)->finalize(gobject);
+ }
+ 
+ void
+--- a/ags/plugin/ags_lv2_urid_manager.c
++++ b/ags/plugin/ags_lv2_urid_manager.c
+@@ -134,6 +134,9 @@
+   lv2_urid_manager = AGS_LV2_URID_MANAGER(gobject);
+ 
+   g_hash_table_destroy(lv2_urid_manager->urid);
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2_urid_manager_parent_class)->finalize(gobject);
+ }
+ 
+ void
+--- a/ags/plugin/ags_lv2_worker.c
++++ b/ags/plugin/ags_lv2_worker.c
+@@ -121,21 +121,20 @@
+ ags_lv2_worker_connect(AgsConnectable *connectable)
+ {
+   /* empty */
+-
+-  ags_lv2_worker_parent_connectable_interface->connect(connectable);
+ }
+ 
+ void
+ ags_lv2_worker_disconnect(AgsConnectable *connectable)
+ {
+   /* empty */
+-
+-  ags_lv2_worker_parent_connectable_interface->disconnect(connectable);
+ }
+ 
+ void
+ ags_lv2_worker_finalize(GObject *gobject)
+ {
++  /* empty */
++
++  /* call parent */
+   G_OBJECT_CLASS(ags_lv2_worker_parent_class)->finalize(gobject);
+ }
+ 
+--- a/ags/plugin/ags_lv2_worker_manager.c
++++ b/ags/plugin/ags_lv2_worker_manager.c
+@@ -130,6 +130,9 @@
+ ags_lv2_worker_manager_finalize(GObject *gobject)
+ {
+   /* empty */
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2_worker_manager_parent_class)->finalize(gobject);
+ }
+ 
+ GObject*
+--- a/ags/plugin/ags_lv2ui_manager.c
++++ b/ags/plugin/ags_lv2ui_manager.c
+@@ -38,6 +38,7 @@
+ 
+ void ags_lv2ui_manager_class_init(AgsLv2uiManagerClass *lv2ui_manager);
+ void ags_lv2ui_manager_init (AgsLv2uiManager *lv2ui_manager);
++void ags_lv2ui_manager_dispose(GObject *gobject);
+ void ags_lv2ui_manager_finalize(GObject *gobject);
+ 
+ /**
+@@ -92,6 +93,7 @@
+   /* GObjectClass */
+   gobject = (GObjectClass *) lv2ui_manager;
+ 
++  gobject->dispose = ags_lv2ui_manager_dispose;
+   gobject->finalize = ags_lv2ui_manager_finalize;
+ }
+ 
+@@ -110,9 +112,28 @@
+ }
+ 
+ void
++ags_lv2ui_manager_dispose(GObject *gobject)
++{
++  AgsLv2uiManager *lv2ui_manager;
++
++  lv2ui_manager = AGS_LV2UI_MANAGER(gobject);
++
++  if(lv2ui_manager->lv2ui_plugin != NULL){
++    g_list_free_full(lv2ui_manager->lv2ui_plugin,
++		     g_object_unref);
++
++    lv2ui_manager->lv2ui_plugin = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2ui_manager_parent_class)->dispose(gobject);
++}
++
++void
+ ags_lv2ui_manager_finalize(GObject *gobject)
+ {
+   AgsLv2uiManager *lv2ui_manager;
++
+   GList *lv2ui_plugin;
+ 
+   lv2ui_manager = AGS_LV2UI_MANAGER(gobject);
+@@ -121,6 +142,9 @@
+ 
+   g_list_free_full(lv2ui_plugin,
+ 		   g_object_unref);
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2ui_manager_parent_class)->finalize(gobject);
+ }
+ 
+ /**
+--- a/ags/plugin/ags_lv2ui_plugin.c
++++ b/ags/plugin/ags_lv2ui_plugin.c
+@@ -42,6 +42,7 @@
+ 				   guint prop_id,
+ 				   GValue *value,
+ 				   GParamSpec *param_spec);
++void ags_lv2ui_plugin_dispose(GObject *gobject);
+ void ags_lv2ui_plugin_finalize(GObject *gobject);
+ 
+ gpointer ags_lv2ui_plugin_instantiate(AgsBasePlugin *base_plugin,
+@@ -124,6 +125,7 @@
+   gobject->set_property = ags_lv2ui_plugin_set_property;
+   gobject->get_property = ags_lv2ui_plugin_get_property;
+ 
++  gobject->dispose = ags_lv2ui_plugin_dispose;
+   gobject->finalize = ags_lv2ui_plugin_finalize;
+ 
+   /* properties */
+@@ -385,6 +387,35 @@
+ }
+ 
+ void
++ags_lv2ui_plugin_dispose(GObject *gobject)
++{
++  AgsLv2uiPlugin *lv2ui_plugin;
++
++  lv2ui_plugin = AGS_LV2UI_PLUGIN(gobject);
++
++  if(lv2ui_plugin->manifest != NULL){
++    g_object_unref(lv2ui_plugin->manifest);
++
++    lv2ui_plugin->manifest = NULL;
++  }
++
++  if(lv2ui_plugin->gui_turtle != NULL){
++    g_object_unref(lv2ui_plugin->gui_turtle);
++
++    lv2ui_plugin->gui_turtle = NULL;
++  }
++
++  if(lv2ui_plugin->lv2_plugin != NULL){
++    g_object_unref(lv2ui_plugin->lv2_plugin);
++
++    lv2ui_plugin->lv2_plugin = NULL;
++  }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2ui_plugin_parent_class)->dispose(gobject);
++}
++
++void
+ ags_lv2ui_plugin_finalize(GObject *gobject)
+ {
+   AgsLv2uiPlugin *lv2ui_plugin;
+@@ -404,6 +435,9 @@
+   if(lv2ui_plugin->lv2_plugin != NULL){
+     g_object_unref(lv2ui_plugin->lv2_plugin);
+   }
++
++  /* call parent */
++  G_OBJECT_CLASS(ags_lv2ui_plugin_parent_class)->finalize(gobject);
+ }
+ 
+ void
diff --git a/debian/patches/series b/debian/patches/series
index 15aca26..8267fa1 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,4 @@
+fix-missing-dispose.diff
 fix-possible-division-by-zero.diff
 fix-matrix-callbacks.patch
 fix-matrix.patch
@@ -13,7 +14,6 @@ fix-export-soundcard-callbacks.patch
 fix-missing-mutices.diff
 fix-soundcard-data-race.diff
 fix-thread-posix.patch
-fix-duplicated-flag-definition.diff
 fix-null-pointer-dereference.diff
 fix-missing-midi-connection-dialog.diff
 fix-leak-while-g-timeout-function.diff

-- 
gsequencer packaging



More information about the pkg-multimedia-commits mailing list