[SCM] gsequencer/master: remove unwanted patches

jkraehemann-guest at users.alioth.debian.org jkraehemann-guest at users.alioth.debian.org
Thu Mar 16 13:53:36 UTC 2017


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

    remove unwanted patches

diff --git a/debian/patches/fix-gsequencer-main.patch b/debian/patches/fix-gsequencer-main.patch
deleted file mode 100644
index f0e0e5d..0000000
--- a/debian/patches/fix-gsequencer-main.patch
+++ /dev/null
@@ -1,227 +0,0 @@
-Description: This patch is considered important since it fixes disappearing
- start animation and excludes timer related code.
- Note the real-time signal involved by the timers is not available to all
- platforms.
-Author: Joël Krähmann <jkraehemann at gmail.com>
-Applied-Upstream: 0.7.122.x, http://git.savannah.gnu.org/cgit/gsequencer.git
-Last-Update: 2017-02-05
---- a/ags/gsequencer_main.c
-+++ b/ags/gsequencer_main.c
-@@ -121,6 +121,7 @@
- 
- extern volatile gboolean ags_show_start_animation;
- 
-+#ifndef AGS_USE_TIMER
- void
- ags_signal_handler(int signr)
- {
-@@ -136,7 +137,9 @@
-     //    }
-   }
- }
-+#endif
- 
-+#ifdef AGS_USE_TIMER
- void
- ags_signal_handler_timer(int sig, siginfo_t *si, void *uc)
- {
-@@ -152,6 +155,7 @@
-     pthread_mutex_unlock(AGS_THREAD(ags_application_context->main_loop)->timer_mutex);
-   //  signal(sig, SIG_IGN);
- }
-+#endif
- 
- static void
- ags_signal_cleanup()
-@@ -164,17 +168,19 @@
- {
-   GtkWidget *window;
-   GdkRectangle rectangle;
--  
--  cairo_t *cr;
-+
-+  cairo_t *gdk_cr, *cr;
-   cairo_surface_t *surface;
--  
-+
-   AgsLog *log;
- 
-   gchar *filename;
-+  unsigned char *bg_data, *image_data;
-   
-   /* create a buffer suitable to image size */
-   GList *list, *start;
- 
-+  guint image_size;
-   gdouble x0, y0;
-   guint i, nth;
-   
-@@ -186,22 +192,30 @@
-   rectangle.y = 0;
-   rectangle.width = 800;
-   rectangle.height = 450;
-+
-+  image_size = 4 * 800 * 450;
-   
--  cr = gdk_cairo_create(window->window);
-+  gdk_cr = gdk_cairo_create(window->window);
-   
-   filename = g_strdup_printf("%s%s\0", DESTDIR, "/gsequencer/images/ags_supermoon-800x450.png\0");
- 
-   surface = cairo_image_surface_create_from_png(filename);
-+  image_data = cairo_image_surface_get_data(surface);
-+  
-+  bg_data = (unsigned char *) malloc(image_size * sizeof(unsigned char));
-+  memcpy(bg_data, image_data, image_size * sizeof(unsigned char));
-+  
-+  cr = cairo_create(surface);
-   
-   cairo_select_font_face(cr, "Georgia\0",
- 			 CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
-   cairo_set_font_size(cr, (gdouble) 11.0);
--
-+  
-   gdk_window_show(window->window);
-   
-   gdk_threads_leave();
- 
--  log = ags_log_get_instance();    
-+  log = ags_log_get_instance();  
-   nth = 0;
-   
-   while(g_atomic_int_get(&(ags_show_start_animation))){
-@@ -211,6 +225,8 @@
-     i = g_list_length(start);
- 
-     if(i > nth){
-+      memcpy(image_data, bg_data, image_size * sizeof(unsigned char));
-+      
-       cairo_set_source_surface(cr, surface, 0, 0);
-       cairo_paint(cr);
-       cairo_surface_flush(surface);
-@@ -226,8 +242,9 @@
- 	
- 	cairo_move_to(cr,
- 		      x0, y0);
-+
- 	cairo_show_text(cr, list->data);
--	
-+
- 	list = list->next;
- 	y0 -= 12.0;
-       }
-@@ -235,12 +252,18 @@
-       cairo_move_to(cr,
- 		    x0, 4.0 + (i + 1) * 12.0);
-       cairo_show_text(cr, "...\0");
--
--      gdk_flush();
-+      
-       nth = g_list_length(start);
--    }    
-+    }
-+
-+    cairo_set_source_surface(gdk_cr, surface, 0, 0);
-+    cairo_paint(gdk_cr);
-+    cairo_surface_flush(surface);
-+    gdk_flush();
-   }
- 
-+  free(bg_data);
-+  
-   gdk_threads_enter();
- 
-   gtk_widget_destroy(window);
-@@ -267,6 +290,7 @@
- 		 ags_start_animation_thread, window);
- }
- 
-+#ifndef AGS_USE_TIMER
- void
- ags_setup(int argc, char **argv)
- {
-@@ -424,6 +448,8 @@
-   ags_application_context->argc = argc;
-   ags_application_context->argv = argv;
- 
-+  ags_application_context_register_types(ags_application_context);
-+
-   /* fix cross-references in managers */
-   lv2_worker_manager->thread_pool = ((AgsXorgApplicationContext *) ags_application_context)->thread_pool;
-   
-@@ -437,7 +463,9 @@
-   g_atomic_int_set(&(ags_show_start_animation),
- 		   FALSE);
- }
-+#endif
- 
-+#ifndef AGS_USE_TIMER
- void
- ags_launch(gboolean single_thread)
- {
-@@ -578,7 +606,9 @@
-     ags_thread_start((AgsThread *) single_thread);
-   }
- }
-+#endif
- 
-+#ifndef AGS_USE_TIMER
- void
- ags_launch_filename(gchar *filename,
- 		    gboolean single_thread)
-@@ -747,7 +777,9 @@
-     		 NULL);
-   }
- }
-+#endif
- 
-+#ifdef AGS_USE_TIMER
- timer_t*
- ags_timer_setup()
- {
-@@ -782,11 +814,13 @@
-   if(timer_create(CLOCK_MONOTONIC, &ags_sev_timer, timer_id) == -1){
-     perror("timer_create\0");
-     exit(EXIT_FAILURE);
--  }
-+  }  
- 
-   return(timer_id);
- }
-+#endif
- 
-+#ifdef AGS_USE_TIMER
- void
- ags_timer_start(timer_t *timer_id)
- {
-@@ -807,9 +841,11 @@
-   if(sigprocmask(SIG_UNBLOCK, &ags_timer_mask, NULL) == -1){
-     perror("sigprocmask\0");
-     exit(EXIT_FAILURE);
--  }
-+  }  
- }
-+#endif
- 
-+#ifdef AGS_USE_TIMER
- void
- ags_timer_launch(timer_t *timer_id,
- 		 gboolean single_thread)
-@@ -954,7 +990,9 @@
-     ags_thread_start((AgsThread *) single_thread);
-   }
- }
-+#endif
- 
-+#ifdef AGS_USE_TIMER
- void
- ags_timer_launch_filename(timer_t *timer_id, gchar *filename,
- 			  gboolean single_thread)
-@@ -1128,6 +1166,7 @@
- 		 NULL);
-   }
- }
-+#endif
- 
- void
- ags_show_file_error(gchar *filename,
diff --git a/debian/patches/improved-disable-output-port-automation.patch b/debian/patches/improved-disable-output-port-automation.patch
deleted file mode 100644
index 172c3af..0000000
--- a/debian/patches/improved-disable-output-port-automation.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-Description: This is a wishlist patch. It disables automation of output ports.
-Author: Joël Krähmann <jkraehemann at gmail.com>
-Applied-Upstream: 0.7.122.x, http://git.savannah.gnu.org/cgit/gsequencer.git
-Last-Update: 2017-02-02
---- a/ags/audio/ags_recall_audio.c
-+++ b/ags/audio/ags_recall_audio.c
-@@ -362,6 +362,12 @@
-   audio = AGS_RECALL_AUDIO(recall)->audio;
- 
-   while(automation_port != NULL){
-+    if((AGS_PORT_IS_OUTPUT & (AGS_PORT(automation_port->data)->flags)) != 0){
-+      automation_port = automation_port->next;
-+
-+      continue;
-+    }
-+
-     if(ags_automation_find_port(audio->automation,
- 				automation_port->data) == NULL){
-       current = ags_automation_new((GObject *) audio,
---- a/ags/audio/ags_recall_channel.c
-+++ b/ags/audio/ags_recall_channel.c
-@@ -425,6 +425,12 @@
-   }
-   
-   while(automation_port != NULL){
-+    if((AGS_PORT_IS_OUTPUT & (AGS_PORT(automation_port->data)->flags)) != 0){
-+      automation_port = automation_port->next;
-+
-+      continue;
-+    }
-+    
-     if((automation = ags_automation_find_port(audio->automation,
- 					      automation_port->data)) == NULL){
-       current = ags_automation_new(channel->audio,
diff --git a/debian/patches/improved-enable-builtin-port-automation.patch b/debian/patches/improved-enable-builtin-port-automation.patch
deleted file mode 100644
index 78a7857..0000000
--- a/debian/patches/improved-enable-builtin-port-automation.patch
+++ /dev/null
@@ -1,400 +0,0 @@
-Description: This is a wishlist patch. It uses the modified AgsPort type of 
- ags-mute recall in order to use the built-in effect by automation.
-Author: Joël Krähmann <jkraehemann at gmail.com>
-Applied-Upstream: 0.7.122.x, http://git.savannah.gnu.org/cgit/gsequencer.git
-Last-Update: 2017-02-02
---- a/ags/audio/recall/ags_mute_audio_signal.c
-+++ b/ags/audio/recall/ags_mute_audio_signal.c
-@@ -245,21 +245,21 @@
-   /* check channel */
-   mute_channel = AGS_MUTE_CHANNEL(AGS_RECALL_CHANNEL_RUN(recall->parent->parent)->recall_channel);
- 
--  g_value_init(&channel_value, G_TYPE_BOOLEAN);
-+  g_value_init(&channel_value, G_TYPE_FLOAT);
-   ags_port_safe_read(mute_channel->muted,
- 		     &channel_value);
- 
--  channel_muted = g_value_get_boolean(&channel_value);
-+  channel_muted = (gboolean) g_value_get_float(&channel_value);
-   g_value_unset(&channel_value);
- 
-   /* check audio */
-   mute_audio = AGS_MUTE_AUDIO(AGS_RECALL_CONTAINER(AGS_RECALL(mute_channel)->container)->recall_audio);
- 
--  g_value_init(&audio_value, G_TYPE_BOOLEAN);
-+  g_value_init(&audio_value, G_TYPE_FLOAT);
-   ags_port_safe_read(mute_audio->muted,
- 		     &audio_value);
- 
--  audio_muted = g_value_get_boolean(&audio_value);
-+  audio_muted = (gboolean) g_value_get_float(&audio_value);
-   g_value_unset(&audio_value);
- 
-   /* if not muted return */
---- a/ags/audio/recall/ags_mute_audio.c
-+++ b/ags/audio/recall/ags_mute_audio.c
-@@ -23,6 +23,8 @@
- #include <ags/object/ags_mutable.h>
- #include <ags/object/ags_plugin.h>
- 
-+#include <ags/plugin/ags_base_plugin.h>
-+
- void ags_mute_audio_class_init(AgsMuteAudioClass *mute_audio);
- void ags_mute_audio_connectable_interface_init(AgsConnectableInterface *connectable);
- void ags_mute_audio_mutable_interface_init(AgsMutableInterface *mutable);
-@@ -43,6 +45,8 @@
- 
- void ags_mute_audio_set_muted(AgsMutable *mutable, gboolean muted);
- 
-+static AgsPortDescriptor* ags_mute_audio_get_muted_port_descriptor();
-+
- /**
-  * SECTION:ags_mute_audio
-  * @short_description: mute audio 
-@@ -181,20 +185,26 @@
- 
-   port = NULL;
- 
-+  /* muted */
-   mute_audio->muted = g_object_new(AGS_TYPE_PORT,
- 				   "plugin-name\0", "ags-mute\0",
- 				   "specifier\0", "./muted[0]\0",
- 				   "control-port\0", "1/1\0",
- 				   "port-value-is-pointer\0", FALSE,
--				   "port-value-type\0", G_TYPE_BOOLEAN,
--				   "port-value-size\0", sizeof(gboolean),
-+				   "port-value-type\0", G_TYPE_FLOAT,
-+				   "port-value-size\0", sizeof(gfloat),
- 				   "port-value-length\0", 1,
- 				   NULL);
--  mute_audio->muted->port_value.ags_port_boolean = FALSE;
-+  
-+  mute_audio->muted->port_value.ags_port_float = (float) FALSE;
- 
-+  /* port descriptor */
-+  mute_audio->muted->port_descriptor = ags_mute_audio_get_muted_port_descriptor();
-+
-+  /* add to port */
-   port = g_list_prepend(port, mute_audio->muted);
- 
--  /*  */
-+  /* set port */
-   AGS_RECALL(mute_audio)->port = port;
- }
- 
-@@ -262,9 +272,20 @@
- void
- ags_mute_audio_connect(AgsConnectable *connectable)
- {
--  ags_mute_audio_parent_connectable_interface->connect(connectable);
-+  AgsRecall *recall;
-+  
-+  recall = AGS_RECALL(connectable);
-+  
-+  if((AGS_RECALL_CONNECTED & (recall->flags)) != 0){
-+    return;
-+  }
- 
--  /* empty */
-+  /* load automation */
-+  ags_recall_load_automation(recall,
-+			     g_list_copy(recall->port));
-+
-+  /* call parent */
-+  ags_mute_audio_parent_connectable_interface->connect(connectable);
- }
- 
- void
-@@ -311,12 +332,45 @@
- {
-   GValue value = {0,};
- 
--  g_value_init(&value, G_TYPE_BOOLEAN);
--  g_value_set_boolean(&value, muted);
-+  g_value_init(&value, G_TYPE_FLOAT);
-+  g_value_set_float(&value, (float) muted);
- 
-   ags_port_safe_write(AGS_MUTE_AUDIO(mutable)->muted, &value);
- }
- 
-+static AgsPortDescriptor*
-+ags_mute_audio_get_muted_port_descriptor()
-+{
-+  static AgsPortDescriptor *port_descriptor = NULL;
-+
-+  if(port_descriptor == NULL){
-+    port_descriptor = ags_port_descriptor_alloc();
-+
-+    port_descriptor->flags |= (AGS_PORT_DESCRIPTOR_INPUT |
-+			       AGS_PORT_DESCRIPTOR_CONTROL |
-+			       AGS_PORT_DESCRIPTOR_TOGGLED);
-+
-+    port_descriptor->port_index = 0;
-+
-+    /* range */
-+    g_value_init(port_descriptor->default_value,
-+		 G_TYPE_FLOAT);
-+    g_value_init(port_descriptor->lower_value,
-+		 G_TYPE_FLOAT);
-+    g_value_init(port_descriptor->upper_value,
-+		 G_TYPE_FLOAT);
-+
-+    g_value_set_float(port_descriptor->default_value,
-+		      0.0);
-+    g_value_set_float(port_descriptor->lower_value,
-+		      0.0);
-+    g_value_set_float(port_descriptor->upper_value,
-+		      1.0);
-+  }
-+  
-+  return(port_descriptor);
-+}
-+
- /**
-  * ags_mute_audio_new:
-  *
---- a/ags/audio/recall/ags_mute_channel.c
-+++ b/ags/audio/recall/ags_mute_channel.c
-@@ -23,6 +23,8 @@
- #include <ags/object/ags_mutable.h>
- #include <ags/object/ags_plugin.h>
- 
-+#include <ags/plugin/ags_base_plugin.h>
-+
- void ags_mute_channel_class_init(AgsMuteChannelClass *mute_channel);
- void ags_mute_channel_connectable_interface_init(AgsConnectableInterface *connectable);
- void ags_mute_channel_mutable_interface_init(AgsMutableInterface *mutable);
-@@ -43,6 +45,8 @@
- 
- void ags_mute_channel_set_muted(AgsMutable *mutable, gboolean muted);
- 
-+static AgsPortDescriptor* ags_mute_channel_get_muted_port_descriptor();
-+
- /**
-  * SECTION:ags_mute_channel
-  * @short_description: mutes channel
-@@ -181,19 +185,26 @@
- 
-   port = NULL;
- 
-+  /* muted */
-   mute_channel->muted = g_object_new(AGS_TYPE_PORT,
- 				     "plugin-name\0", "ags-mute\0",
- 				     "specifier\0", "./muted[0]\0",
- 				     "control-port\0", "1/1\0",
- 				     "port-value-is-pointer\0", FALSE,
--				     "port-value-type\0", G_TYPE_BOOLEAN,
--				     "port-value-size\0", sizeof(gboolean),
-+				     "port-value-type\0", G_TYPE_FLOAT,
-+				     "port-value-size\0", sizeof(gfloat),
- 				     "port-value-length\0", 1,
- 				     NULL);
--  mute_channel->muted->port_value.ags_port_boolean = FALSE;
- 
-+  mute_channel->muted->port_value.ags_port_float = (float) FALSE;
-+
-+  /* port descriptor */
-+  mute_channel->muted->port_descriptor = ags_mute_channel_get_muted_port_descriptor();
-+
-+  /* add to port */
-   port = g_list_prepend(port, mute_channel->muted);
- 
-+  /* set port */
-   AGS_RECALL(mute_channel)->port = port;
- }
- 
-@@ -260,9 +271,20 @@
- void
- ags_mute_channel_connect(AgsConnectable *connectable)
- {
--  ags_mute_channel_parent_connectable_interface->connect(connectable);
-+  AgsRecall *recall;
-+  
-+  recall = AGS_RECALL(connectable);
-+  
-+  if((AGS_RECALL_CONNECTED & (recall->flags)) != 0){
-+    return;
-+  }
- 
--  /* empty */
-+  /* load automation */
-+  ags_recall_load_automation(recall,
-+			     g_list_copy(recall->port));
-+
-+  /* call parent */
-+  ags_mute_channel_parent_connectable_interface->connect(connectable);
- }
- 
- void
-@@ -309,12 +331,45 @@
- {
-   GValue value = {0,};
- 
--  g_value_init(&value, G_TYPE_BOOLEAN);
--  g_value_set_boolean(&value, muted);
-+  g_value_init(&value, G_TYPE_FLOAT);
-+  g_value_set_float(&value, (float) muted);
- 
-   ags_port_safe_write(AGS_MUTE_CHANNEL(mutable)->muted, &value);
- }
- 
-+static AgsPortDescriptor*
-+ags_mute_channel_get_muted_port_descriptor()
-+{
-+  static AgsPortDescriptor *port_descriptor = NULL;
-+
-+  if(port_descriptor == NULL){
-+    port_descriptor = ags_port_descriptor_alloc();
-+
-+    port_descriptor->flags |= (AGS_PORT_DESCRIPTOR_INPUT |
-+			       AGS_PORT_DESCRIPTOR_CONTROL |
-+			       AGS_PORT_DESCRIPTOR_TOGGLED);
-+
-+    port_descriptor->port_index = 0;
-+
-+    /* range */
-+    g_value_init(port_descriptor->default_value,
-+		 G_TYPE_FLOAT);
-+    g_value_init(port_descriptor->lower_value,
-+		 G_TYPE_FLOAT);
-+    g_value_init(port_descriptor->upper_value,
-+		 G_TYPE_FLOAT);
-+
-+    g_value_set_float(port_descriptor->default_value,
-+		      0.0);
-+    g_value_set_float(port_descriptor->lower_value,
-+		      0.0);
-+    g_value_set_float(port_descriptor->upper_value,
-+		      1.0);
-+  }
-+  
-+  return(port_descriptor);
-+}
-+
- /**
-  * ags_mute_channel_new:
-  *
---- a/ags/audio/recall/ags_volume_audio_signal.c
-+++ b/ags/audio/recall/ags_volume_audio_signal.c
-@@ -231,10 +231,10 @@
-     buffer = (signed short *) AGS_RECALL_AUDIO_SIGNAL(recall)->source->stream_current->data;
-     buffer_size = AGS_RECALL_AUDIO_SIGNAL(recall)->source->buffer_size;
- 
--    g_value_init(&value, G_TYPE_DOUBLE);
-+    g_value_init(&value, G_TYPE_FLOAT);
-     ags_port_safe_read(volume_channel->volume, &value);
- 
--    volume = g_value_get_double(&value);
-+    volume = g_value_get_float(&value);
- 
-     for(i = 0; i < buffer_size; i++){
-       switch(AGS_RECALL_AUDIO_SIGNAL(recall)->source->format){
---- a/ags/audio/recall/ags_volume_channel.c
-+++ b/ags/audio/recall/ags_volume_channel.c
-@@ -20,9 +20,10 @@
- #include <ags/audio/recall/ags_volume_channel.h>
- 
- #include <ags/object/ags_connectable.h>
--
- #include <ags/object/ags_plugin.h>
- 
-+#include <ags/plugin/ags_base_plugin.h>
-+
- void ags_volume_channel_class_init(AgsVolumeChannelClass *volume_channel);
- void ags_volume_channel_connectable_interface_init(AgsConnectableInterface *connectable);
- void ags_volume_channel_plugin_interface_init(AgsPluginInterface *plugin);
-@@ -40,6 +41,8 @@
- void ags_volume_channel_set_ports(AgsPlugin *plugin, GList *port);
- void ags_volume_channel_finalize(GObject *gobject);
- 
-+static AgsPortDescriptor* ags_volume_channel_get_volume_port_descriptor();
-+
- /**
-  * SECTION:ags_volume_channel
-  * @short_description: volumes channel
-@@ -174,15 +177,20 @@
- 					"specifier\0", "./volume[0]\0",
- 					"control-port\0", "1/1\0",
- 					"port-value-is-pointer\0", FALSE,
--					"port-value-type\0", G_TYPE_DOUBLE,
--					"port-value-size\0", sizeof(gdouble),
-+					"port-value-type\0", G_TYPE_FLOAT,
-+					"port-value-size\0", sizeof(gfloat),
- 					"port-value-length", 1,
- 					NULL);
- 
--  volume_channel->volume->port_value.ags_port_double = 1.0;
-+  volume_channel->volume->port_value.ags_port_float = 1.0;
-+
-+  /* port descriptor */
-+  volume_channel->volume->port_descriptor = ags_volume_channel_get_volume_port_descriptor();
- 
-+  /* add to port */  
-   port = g_list_prepend(port, volume_channel->volume);
- 
-+  /* set port */
-   AGS_RECALL(volume_channel)->port = port;
- }
- 
-@@ -249,9 +257,20 @@
- void
- ags_volume_channel_connect(AgsConnectable *connectable)
- {
--  ags_volume_channel_parent_connectable_interface->connect(connectable);
-+  AgsRecall *recall;
-+  
-+  recall = AGS_RECALL(connectable);
-+  
-+  if((AGS_RECALL_CONNECTED & (recall->flags)) != 0){
-+    return;
-+  }
- 
--  /* empty */
-+  /* load automation */
-+  ags_recall_load_automation(recall,
-+			     g_list_copy(recall->port));
-+
-+  /* call parent */
-+  ags_volume_channel_parent_connectable_interface->connect(connectable);
- }
- 
- void
-@@ -293,6 +312,38 @@
-   G_OBJECT_CLASS(ags_volume_channel_parent_class)->finalize(gobject);
- }
- 
-+static AgsPortDescriptor*
-+ags_volume_channel_get_volume_port_descriptor()
-+{
-+  static AgsPortDescriptor *port_descriptor = NULL;
-+
-+  if(port_descriptor == NULL){
-+    port_descriptor = ags_port_descriptor_alloc();
-+
-+    port_descriptor->flags |= (AGS_PORT_DESCRIPTOR_INPUT |
-+			       AGS_PORT_DESCRIPTOR_CONTROL);
-+
-+    port_descriptor->port_index = 0;
-+
-+    /* range */
-+    g_value_init(port_descriptor->default_value,
-+		 G_TYPE_FLOAT);
-+    g_value_init(port_descriptor->lower_value,
-+		 G_TYPE_FLOAT);
-+    g_value_init(port_descriptor->upper_value,
-+		 G_TYPE_FLOAT);
-+
-+    g_value_set_float(port_descriptor->default_value,
-+		      1.0);
-+    g_value_set_float(port_descriptor->lower_value,
-+		      0.0);
-+    g_value_set_float(port_descriptor->upper_value,
-+		      2.0);
-+  }
-+  
-+  return(port_descriptor);
-+}
-+
- /**
-  * ags_volume_channel_new:
-  *
diff --git a/debian/patches/improved-generic-output-widget.patch b/debian/patches/improved-generic-output-widget.patch
deleted file mode 100644
index 5d2f465..0000000
--- a/debian/patches/improved-generic-output-widget.patch
+++ /dev/null
@@ -1,2835 +0,0 @@
-Description: This is a wishlist patch. It changes the recall handler to the
- generic callback, introduced in view of plugin output ports. It is responsible
- for redrawing visible feedback.
-Author: Joël Krähmann <jkraehemann at gmail.com>
-Applied-Upstream: 0.7.122.x, http://git.savannah.gnu.org/cgit/gsequencer.git
-Last-Update: 2017-02-02
---- a/ags/X/machine/ags_drum_input_line.c
-+++ b/ags/X/machine/ags_drum_input_line.c
-@@ -101,7 +101,7 @@
- static gpointer ags_drum_input_line_parent_class = NULL;
- static AgsConnectableInterface *ags_drum_input_line_parent_connectable_interface;
- 
--extern GHashTable *ags_indicator_queue_draw;
-+extern GHashTable *ags_line_indicator_queue_draw;
- 
- GType
- ags_drum_input_line_get_type()
-@@ -211,7 +211,7 @@
- 		   1, 1);
-   widget = gtk_bin_get_child(GTK_BIN(line_member));
-   AGS_LINE(drum_input_line)->indicator = widget;
--  g_hash_table_insert(ags_indicator_queue_draw,
-+  g_hash_table_insert(ags_line_indicator_queue_draw,
- 		      widget, ags_line_indicator_queue_draw_timeout);
-   g_timeout_add(1000 / 30, (GSourceFunc) ags_line_indicator_queue_draw_timeout, (gpointer) widget);
- 
-@@ -446,7 +446,7 @@
-     recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
- 
-     recall_handler->signal_name = "run-post\0";
--    recall_handler->callback = G_CALLBACK(ags_line_peak_run_post_callback);
-+    recall_handler->callback = G_CALLBACK(ags_line_output_port_run_post_callback);
-     recall_handler->data = (gpointer) line;
- 
-     ags_recall_add_handler(AGS_RECALL(play_peak_channel_run), recall_handler);
-@@ -462,7 +462,7 @@
-     recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
- 
-     recall_handler->signal_name = "run-post\0";
--    recall_handler->callback = G_CALLBACK(ags_line_peak_run_post_callback);
-+    recall_handler->callback = G_CALLBACK(ags_line_output_port_run_post_callback);
-     recall_handler->data = (gpointer) line;
- 
-     ags_recall_add_handler(AGS_RECALL(recall_peak_channel_run), recall_handler);
---- a/ags/X/ags_effect_bulk.c
-+++ b/ags/X/ags_effect_bulk.c
-@@ -65,6 +65,8 @@
- #include <ags/audio/task/ags_add_recall_container.h>
- #include <ags/audio/task/ags_add_recall.h>
- 
-+#include <ags/widget/ags_led.h>
-+#include <ags/widget/ags_hindicator.h>
- #include <ags/widget/ags_dial.h>
- 
- #include <ags/X/ags_window.h>
-@@ -105,6 +107,7 @@
- void ags_effect_bulk_set_version(AgsPlugin *plugin, gchar *version);
- gchar* ags_effect_bulk_get_build_id(AgsPlugin *plugin);
- void ags_effect_bulk_set_build_id(AgsPlugin *plugin, gchar *build_id);
-+void ags_effect_bulk_finalize(GObject *gobject);
- void ags_effect_bulk_show(GtkWidget *widget);
- 
- GList* ags_effect_bulk_add_ladspa_effect(AgsEffectBulk *effect_bulk,
-@@ -165,6 +168,8 @@
- static gpointer ags_effect_bulk_parent_class = NULL;
- static guint effect_bulk_signals[LAST_SIGNAL];
- 
-+GHashTable *ags_effect_bulk_indicator_queue_draw = NULL;
-+
- GType
- ags_effect_bulk_get_type(void)
- {
-@@ -226,6 +231,7 @@
-   gobject->set_property = ags_effect_bulk_set_property;
-   gobject->get_property = ags_effect_bulk_get_property;
- 
-+  gobject->finalize = ags_effect_bulk_finalize;
-   
-   /* properties */
-   /**
-@@ -413,6 +419,12 @@
- {
-   GtkAlignment *alignment;
-   GtkHBox *hbox;
-+
-+  if(ags_effect_bulk_indicator_queue_draw == NULL){
-+    ags_effect_bulk_indicator_queue_draw = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-+								 NULL,
-+								 NULL);
-+  }
-   
-   effect_bulk->flags = 0;
- 
-@@ -478,6 +490,8 @@
- 		     0);
- 
-   effect_bulk->plugin_browser = (GtkDialog *) ags_plugin_browser_new((GtkWidget *) effect_bulk);
-+
-+  effect_bulk->queued_drawing = NULL;
- }
- 
- void
-@@ -698,6 +712,41 @@
- }
- 
- void
-+ags_effect_bulk_finalize(GObject *gobject)
-+{
-+  AgsEffectBulk *effect_bulk;
-+
-+  GList *list;
-+  
-+  effect_bulk = (AgsEffectBulk *) gobject;
-+
-+  /* unref audio */
-+  if(effect_bulk->audio != NULL){
-+    g_object_unref(effect_bulk->audio);
-+  }
-+
-+  /* free plugin list */
-+  g_list_free_full(effect_bulk->plugin,
-+		   ags_effect_bulk_plugin_free);
-+
-+  /* destroy plugin browser */
-+  gtk_widget_destroy(effect_bulk->plugin_browser);
-+
-+  /* remove of the queued drawing hash */
-+  list = effect_bulk->queued_drawing;
-+
-+  while(list != NULL){
-+    g_hash_table_remove(ags_effect_bulk_indicator_queue_draw,
-+			list->data);
-+
-+    list = list->next;
-+  }
-+  
-+  /* call parent */  
-+  G_OBJECT_CLASS(ags_effect_bulk_parent_class)->finalize(gobject);
-+}
-+
-+void
- ags_effect_bulk_show(GtkWidget *widget)
- {
-   AgsEffectBulk *effect_bulk;
-@@ -715,6 +764,17 @@
-   }
- }
- 
-+/**
-+ * ags_effect_bulk_plugin_alloc:
-+ * @filename: the filename as string
-+ * @effect: the effect as string
-+ * 
-+ * Allocate #AgsEffectBulkPlugin-struct.
-+ * 
-+ * Returns: the newly allocated #AgsEffectBulkPlugin-struct
-+ * 
-+ * Since: 0.7.128
-+ */
- AgsEffectBulkPlugin*
- ags_effect_bulk_plugin_alloc(gchar *filename,
- 			     gchar *effect)
-@@ -731,6 +791,36 @@
-   return(effect_plugin);
- }
- 
-+/**
-+ * ags_effect_bulk_plugin_free:
-+ * @effect_bulk_plugin: the #AgsEffectBulkPlugin-struct
-+ * 
-+ * Free @effect_bulk_plugin.
-+ * 
-+ * Since: 0.7.128
-+ */
-+void
-+ags_effect_bulk_plugin_free(AgsEffectBulkPlugin *effect_bulk_plugin)
-+{
-+  if(effect_bulk_plugin == NULL){
-+    return;
-+  }
-+
-+  if(effect_bulk_plugin->filename != NULL){
-+    free(effect_bulk_plugin->filename);
-+  }
-+
-+  if(effect_bulk_plugin->effect != NULL){
-+    free(effect_bulk_plugin->effect);
-+  }
-+
-+  if(effect_bulk_plugin->control_type_name != NULL){
-+    g_list_free(effect_bulk_plugin->control_type_name);
-+  }
-+  
-+  free(effect_bulk_plugin);
-+}
-+
- GList*
- ags_effect_bulk_add_ladspa_effect(AgsEffectBulk *effect_bulk,
- 				  GList *control_type_name,
-@@ -748,6 +838,7 @@
-   AgsRecallContainer *recall_container;
-   AgsRecallChannelRunDummy *recall_channel_run_dummy;
-   AgsRecallLadspa *recall_ladspa;
-+  AgsRecallHandler *recall_handler;
- 
-   AgsAddRecallContainer *add_recall_container;
-   AgsAddRecall *add_recall;
-@@ -769,6 +860,8 @@
-   guint pads, audio_channels;
-   gdouble step;
-   guint port_count;
-+  gboolean has_output_port;
-+  
-   guint x, y;
-   guint i, j;
-   guint k;
-@@ -838,6 +931,8 @@
- 
-   task = NULL;
-   retport = NULL;
-+
-+  has_output_port = FALSE;
-   
-   for(i = 0; i < pads; i++){
-     for(j = 0; j < audio_channels; j++){
-@@ -858,6 +953,7 @@
- 					    filename,
- 					    effect,
- 					    AGS_BASE_PLUGIN(ladspa_plugin)->effect_index);
-+
-       g_object_set(G_OBJECT(recall_ladspa),
- 		   "soundcard\0", soundcard,
- 		   "recall-container\0", recall_container,
-@@ -872,6 +968,10 @@
- 
-       port = ags_recall_ladspa_load_ports(recall_ladspa);
- 
-+      if((AGS_RECALL_HAS_OUTPUT_PORT & (AGS_RECALL(recall_ladspa)->flags)) != 0){
-+	has_output_port = TRUE;
-+      }
-+      
-       if(retport == NULL){
- 	retport = port;
-       }else{
-@@ -905,6 +1005,17 @@
- 			     FALSE);
-       ags_connectable_connect(AGS_CONNECTABLE(recall_channel_run_dummy));
- 
-+      /* recall handler of output port */
-+      if(has_output_port){
-+	recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+	recall_handler->signal_name = "run-post\0";
-+	recall_handler->callback = G_CALLBACK(ags_effect_bulk_output_port_run_post_callback);
-+	recall_handler->data = (gpointer) effect_bulk;
-+
-+	ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+      }
-+      
-       /* ladspa recall */
-       recall_container = ags_recall_container_new();
-       ags_audio_add_recall_container(effect_bulk->audio,
-@@ -961,6 +1072,17 @@
- 			     FALSE);
-       ags_connectable_connect(AGS_CONNECTABLE(recall_channel_run_dummy));
- 
-+      /* recall handler of output port */
-+      if(has_output_port){
-+	recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+	recall_handler->signal_name = "run-post\0";
-+	recall_handler->callback = G_CALLBACK(ags_effect_bulk_output_port_run_post_callback);
-+	recall_handler->data = (gpointer) effect_bulk;
-+
-+	ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+      }
-+      
-       /* iterate */
-       pthread_mutex_lock(channel_mutex);
-       
-@@ -1010,9 +1132,17 @@
-       }
-       
-       if((AGS_PORT_DESCRIPTOR_TOGGLED & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
--	widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_LED;
-+	}else{
-+	  widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	}
-       }else{
--	widget_type = AGS_TYPE_DIAL;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_HINDICATOR;
-+	}else{
-+	  widget_type = AGS_TYPE_DIAL;
-+	}
-       }
-       
-       step_count = AGS_DIAL_DEFAULT_PRECISION;
-@@ -1129,6 +1259,13 @@
- 	
- 	gtk_adjustment_set_value(adjustment,
- 				 default_value);
-+      }else if(AGS_IS_INDICATOR(child_widget) ||
-+	       AGS_IS_LED(child_widget)){
-+	g_hash_table_insert(ags_effect_bulk_indicator_queue_draw,
-+			    child_widget, ags_effect_bulk_indicator_queue_draw_timeout);
-+	effect_bulk->queued_drawing = g_list_prepend(effect_bulk->queued_drawing,
-+						     child_widget);
-+	g_timeout_add(1000 / 30, (GSourceFunc) ags_effect_bulk_indicator_queue_draw_timeout, (gpointer) child_widget);
-       }
- 
- #ifdef AGS_DEBUG
-@@ -1176,6 +1313,7 @@
-   AgsRecallContainer *recall_container;
-   AgsRecallChannelRunDummy *recall_channel_run_dummy;
-   AgsRecallDssi *recall_dssi;
-+  AgsRecallHandler *recall_handler;
- 
-   AgsAddRecallContainer *add_recall_container;
-   AgsAddRecall *add_recall;
-@@ -1197,6 +1335,8 @@
-   guint pads, audio_channels;
-   gdouble step;
-   guint port_count;
-+  gboolean has_output_port;
-+  
-   guint x, y;
-   guint i, j;
-   guint k;
-@@ -1266,6 +1406,8 @@
- 
-   task = NULL;
-   retport = NULL;
-+
-+  has_output_port = FALSE;
-   
-   for(i = 0; i < pads; i++){
-     for(j = 0; j < audio_channels; j++){
-@@ -1313,6 +1455,10 @@
- 				port);
-       }
- 
-+      if((AGS_RECALL_HAS_OUTPUT_PORT & (AGS_RECALL(recall_dssi)->flags)) != 0){
-+	has_output_port = TRUE;
-+      }
-+
-       ags_channel_add_recall(current,
- 			     (GObject *) recall_dssi,
- 			     TRUE);
-@@ -1338,7 +1484,18 @@
- 			     (GObject *) recall_channel_run_dummy,
- 			     TRUE);
-       ags_connectable_connect(AGS_CONNECTABLE(recall_channel_run_dummy));
-+      
-+      /* recall handler of output port */
-+      if(has_output_port){
-+	recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+	recall_handler->signal_name = "run-post\0";
-+	recall_handler->callback = G_CALLBACK(ags_effect_bulk_output_port_run_post_callback);
-+	recall_handler->data = (gpointer) effect_bulk;
- 
-+	ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+      }
-+      
-       /* dssi recall */
-       recall_container = ags_recall_container_new();
-       ags_audio_add_recall_container(effect_bulk->audio,
-@@ -1401,6 +1558,17 @@
- 			     FALSE);
-       ags_connectable_connect(AGS_CONNECTABLE(recall_channel_run_dummy));
-       
-+      /* recall handler of output port */
-+      if(has_output_port){
-+	recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+	recall_handler->signal_name = "run-post\0";
-+	recall_handler->callback = G_CALLBACK(ags_effect_bulk_output_port_run_post_callback);
-+	recall_handler->data = (gpointer) effect_bulk;
-+
-+	ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+      }
-+
-       /* iterate */
-       pthread_mutex_lock(channel_mutex);
-       
-@@ -1448,9 +1616,17 @@
-       }
- 
-       if((AGS_PORT_DESCRIPTOR_TOGGLED & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
--	widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_LED;
-+	}else{
-+	  widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	}
-       }else{
--	widget_type = AGS_TYPE_DIAL;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_HINDICATOR;
-+	}else{
-+	  widget_type = AGS_TYPE_DIAL;
-+	}
-       }
- 
-       step_count = AGS_DIAL_DEFAULT_PRECISION;
-@@ -1571,6 +1747,13 @@
- #ifdef AGS_DEBUG
- 	g_message("dssi bounds: %f %f\0", lower_bound, upper_bound);
- #endif
-+      }else if(AGS_IS_INDICATOR(child_widget) ||
-+	       AGS_IS_LED(child_widget)){
-+	g_hash_table_insert(ags_effect_bulk_indicator_queue_draw,
-+			    child_widget, ags_effect_bulk_indicator_queue_draw_timeout);
-+	effect_bulk->queued_drawing = g_list_prepend(effect_bulk->queued_drawing,
-+						     child_widget);
-+	g_timeout_add(1000 / 30, (GSourceFunc) ags_effect_bulk_indicator_queue_draw_timeout, (gpointer) child_widget);
-       }
- 
-       gtk_table_attach(effect_bulk->table,
-@@ -1614,6 +1797,7 @@
-   AgsRecallContainer *recall_container;
-   AgsRecallChannelRunDummy *recall_channel_run_dummy;
-   AgsRecallLv2 *recall_lv2;
-+  AgsRecallHandler *recall_handler;
- 
-   AgsAddRecallContainer *add_recall_container;
-   AgsAddRecall *add_recall;
-@@ -1641,6 +1825,8 @@
-   gdouble step;
-   guint pads, audio_channels;
-   guint port_count;
-+  gboolean has_output_port;
-+
-   guint x, y;
-   guint i, j;
-   guint k;
-@@ -1712,6 +1898,8 @@
- 
-   task = NULL;
-   retport = NULL;
-+
-+  has_output_port = FALSE;
-   
-   for(i = 0; i < pads; i++){
-     for(j = 0; j < audio_channels; j++){
-@@ -1761,6 +1949,10 @@
- 				port);
-       }
- 
-+      if((AGS_RECALL_HAS_OUTPUT_PORT & (AGS_RECALL(recall_lv2)->flags)) != 0){
-+	has_output_port = TRUE;
-+      }
-+      
-       ags_channel_add_recall(current,
- 			     (GObject *) recall_lv2,
- 			     TRUE);
-@@ -1787,6 +1979,17 @@
- 			     TRUE);
-       ags_connectable_connect(AGS_CONNECTABLE(recall_channel_run_dummy));
- 
-+      /* recall handler of output port */
-+      if(has_output_port){
-+	recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+	recall_handler->signal_name = "run-post\0";
-+	recall_handler->callback = G_CALLBACK(ags_effect_bulk_output_port_run_post_callback);
-+	recall_handler->data = (gpointer) effect_bulk;
-+
-+	ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+      }
-+
-       /* lv2 recall */
-       recall_container = ags_recall_container_new();
-       ags_audio_add_recall_container(effect_bulk->audio,
-@@ -1850,7 +2053,18 @@
- 			     (GObject *) recall_channel_run_dummy,
- 			     FALSE);
-       ags_connectable_connect(AGS_CONNECTABLE(recall_channel_run_dummy));
--      
-+
-+      /* recall handler of output port */
-+      if(has_output_port){
-+	recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+	recall_handler->signal_name = "run-post\0";
-+	recall_handler->callback = G_CALLBACK(ags_effect_bulk_output_port_run_post_callback);
-+	recall_handler->data = (gpointer) effect_bulk;
-+
-+	ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+      }
-+
-       /* iterate */
-       pthread_mutex_lock(channel_mutex);
-       
-@@ -1898,9 +2112,17 @@
-       }
- 
-       if((AGS_PORT_DESCRIPTOR_TOGGLED & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
--	widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_LED;
-+	}else{
-+	  widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	}
-       }else{
--	widget_type = AGS_TYPE_DIAL;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_HINDICATOR;
-+	}else{
-+	  widget_type = AGS_TYPE_DIAL;
-+	}
-       }
- 
-       step_count = AGS_DIAL_DEFAULT_PRECISION;
-@@ -1980,6 +2202,13 @@
- 				 upper_bound);
- 	gtk_adjustment_set_value(adjustment,
- 				 g_value_get_float(AGS_PORT_DESCRIPTOR(port_descriptor->data)->default_value));
-+      }else if(AGS_IS_INDICATOR(child_widget) ||
-+	       AGS_IS_LED(child_widget)){
-+	g_hash_table_insert(ags_effect_bulk_indicator_queue_draw,
-+			    child_widget, ags_effect_bulk_indicator_queue_draw_timeout);
-+	effect_bulk->queued_drawing = g_list_prepend(effect_bulk->queued_drawing,
-+						     child_widget);
-+	g_timeout_add(1000 / 30, (GSourceFunc) ags_effect_bulk_indicator_queue_draw_timeout, (gpointer) child_widget);
-       }
- 
- #ifdef AGS_DEBUG
-@@ -2212,6 +2441,16 @@
-       }
-       
-       if(i == nth){
-+	GtkWidget *child_widget;
-+	
-+	child_widget = gtk_bin_get_child(list->data);
-+
-+	if(AGS_IS_LED(child_widget) ||
-+	   AGS_IS_INDICATOR(child_widget)){
-+	  g_hash_table_remove(ags_effect_bulk_indicator_queue_draw,
-+			      child_widget);
-+	}
-+
- 	gtk_widget_destroy(list->data);
-       }
-       
-@@ -2652,6 +2881,29 @@
- }
- 
- /**
-+ * ags_effect_bulk_indicator_queue_draw_timeout:
-+ * @widget: the indicator widgt
-+ *
-+ * Queue draw widget
-+ *
-+ * Returns: %TRUE if proceed with redraw, otherwise %FALSE
-+ *
-+ * Since: 0.7.128
-+ */
-+gboolean
-+ags_effect_bulk_indicator_queue_draw_timeout(GtkWidget *widget)
-+{
-+  if(g_hash_table_lookup(ags_effect_bulk_indicator_queue_draw,
-+			 widget) != NULL){
-+    gtk_widget_queue_draw(widget);
-+    
-+    return(TRUE);
-+  }else{
-+    return(FALSE);
-+  }
-+}
-+
-+/**
-  * ags_effect_bulk_new:
-  * @audio: the #AgsAudio to visualize
-  * @channel_type: either %AGS_TYPE_INPUT or %AGS_TYPE_OUTPUT
---- a/ags/X/ags_effect_bulk_callbacks.c
-+++ b/ags/X/ags_effect_bulk_callbacks.c
-@@ -1,5 +1,5 @@
- /* GSequencer - Advanced GTK Sequencer
-- * Copyright (C) 2005-2015 Joël Krähemann
-+ * Copyright (C) 2005-2015,2017 Joël Krähemann
-  *
-  * This file is part of GSequencer.
-  *
-@@ -19,7 +19,18 @@
- 
- #include <ags/X/ags_effect_bulk_callbacks.h>
- 
-+#include <ags/plugin/ags_base_plugin.h>
-+
-+#include <ags/audio/ags_audio.h>
-+#include <ags/audio/ags_channel.h>
-+#include <ags/audio/ags_port.h>
-+
-+#include <ags/widget/ags_led.h>
-+#include <ags/widget/ags_vindicator.h>
-+#include <ags/widget/ags_hindicator.h>
-+
- #include <ags/X/ags_machine.h>
-+#include <ags/X/ags_bulk_member.h>
- #include <ags/X/ags_plugin_browser.h>
- 
- void
-@@ -149,3 +160,147 @@
- 				pads_old);    
-   }
- }
-+
-+void
-+ags_effect_bulk_output_port_run_post_callback(AgsRecall *recall,
-+					      AgsEffectBulk *effect_bulk)
-+{
-+  GtkWidget *child;
-+
-+  GList *list, *list_start;
-+  GList *port, *port_start;
-+
-+  /* lock gdk threads */
-+  gdk_threads_enter();
-+  
-+  list_start = 
-+    list = gtk_container_get_children((GtkContainer *) effect_bulk->table);
-+
-+  /* check members */
-+  while(list != NULL){
-+    if(AGS_IS_BULK_MEMBER(list->data) &&
-+       (AGS_BULK_MEMBER(list->data)->widget_type == AGS_TYPE_VINDICATOR ||
-+	AGS_BULK_MEMBER(list->data)->widget_type == AGS_TYPE_HINDICATOR ||
-+	AGS_BULK_MEMBER(list->data)->widget_type == AGS_TYPE_LED)){
-+      AgsBulkMember *bulk_member;
-+      GtkAdjustment *adjustment;
-+
-+      gdouble average_peak;
-+
-+      bulk_member = AGS_BULK_MEMBER(list->data);
-+      child = GTK_BIN(bulk_member)->child;
-+      
-+      average_peak = 0.0;
-+      
-+      /* copy port list */
-+      port_start = g_list_concat(g_list_copy(bulk_member->bulk_port),
-+				 g_list_copy(bulk_member->recall_bulk_port));
-+
-+      /* get display value */
-+      port = port_start;
-+	
-+      while(port != NULL){
-+	AgsPort *current;
-+	
-+	gdouble lower, upper;
-+	gdouble range;
-+	gdouble peak;
-+	  
-+	GValue value = {0,};
-+
-+	current = AGS_BULK_PORT(port->data)->port;
-+
-+	if(current == NULL){
-+	  port = port->next;
-+	
-+	  continue;
-+	}      
-+	
-+	/* check if output port and specifier matches */
-+	pthread_mutex_lock(current->mutex);
-+
-+	if((AGS_PORT_IS_OUTPUT & (current->flags)) == 0 ||
-+	   current->port_descriptor == NULL ||
-+	   g_ascii_strcasecmp(current->specifier,
-+			      bulk_member->specifier)){
-+	  pthread_mutex_unlock(current->mutex);
-+	    
-+	  port = port->next;
-+
-+	  continue;
-+	}
-+
-+	/* lower and upper */
-+	lower = g_value_get_float(AGS_PORT_DESCRIPTOR(current->port_descriptor)->lower_value);
-+	upper = g_value_get_float(AGS_PORT_DESCRIPTOR(current->port_descriptor)->upper_value);
-+	  
-+	pthread_mutex_unlock(current->mutex);
-+
-+	/* get range */
-+	if(bulk_member->conversion != NULL){
-+	  lower = ags_conversion_convert(bulk_member->conversion,
-+					 lower,
-+					 TRUE);
-+	  
-+	  upper = ags_conversion_convert(bulk_member->conversion,
-+					 upper,
-+					 TRUE);
-+	}
-+
-+	range = upper - lower;
-+
-+	/* port read value */
-+	g_value_init(&value, G_TYPE_FLOAT);
-+	ags_port_safe_read(current,
-+			   &value);
-+	  
-+	peak = g_value_get_float(&value);
-+	g_value_unset(&value);
-+
-+	if(bulk_member->conversion != NULL){
-+	  peak = ags_conversion_convert(bulk_member->conversion,
-+					peak,
-+					TRUE);
-+	}
-+	
-+	/* calculate peak */
-+	if(range == 0.0 ||
-+	   current->port_value_type == G_TYPE_BOOLEAN){
-+	  if(peak != 0.0){
-+	    average_peak = 10.0;
-+	    break;
-+	  }
-+	}else{
-+	  average_peak += ((1.0 / (range / peak)) * 10.0);
-+	}
-+
-+	/* iterate port */
-+	port = port->next;
-+      }
-+
-+      g_list_free(port_start);
-+      
-+      /* apply */
-+      if(AGS_IS_LED(child)){
-+	if(average_peak != 0.0){
-+	  ags_led_set_active(child);
-+	}
-+      }else{
-+	g_object_get(child,
-+		     "adjustment\0", &adjustment,
-+		     NULL);
-+	
-+	gtk_adjustment_set_value(adjustment,
-+				 average_peak);
-+      }
-+    }
-+
-+    /* iterate bulk member */
-+    list = list->next;
-+  }
-+
-+  g_list_free(list_start);
-+
-+  /* unlock gdk threads */
-+  gdk_threads_leave();
-+}
---- a/ags/X/ags_effect_bulk_callbacks.h
-+++ b/ags/X/ags_effect_bulk_callbacks.h
-@@ -1,5 +1,5 @@
- /* GSequencer - Advanced GTK Sequencer
-- * Copyright (C) 2005-2015 Joël Krähemann
-+ * Copyright (C) 2005-2015,2017 Joël Krähemann
-  *
-  * This file is part of GSequencer.
-  *
-@@ -22,10 +22,10 @@
- 
- #include <glib.h>
- #include <glib-object.h>
-+
- #include <gtk/gtk.h>
- 
--#include <lv2.h>
--#include <lv2/lv2plug.in/ns/extensions/ui/ui.h>
-+#include <ags/audio/ags_recall.h>
- 
- #include <ags/X/ags_effect_bulk.h>
- 
-@@ -48,4 +48,7 @@
- 				       guint pads_old,
- 				       AgsEffectBulk *effect_bulk);
- 
-+void ags_effect_bulk_output_port_run_post_callback(AgsRecall *recall,
-+						   AgsEffectBulk *effect_bulk);
-+
- #endif /*__AGS_EFFECT_BULK_CALLBACKS_H__*/
---- a/ags/X/ags_effect_bulk.h
-+++ b/ags/X/ags_effect_bulk.h
-@@ -76,6 +76,8 @@
- 
-   GList *plugin;
-   GtkDialog *plugin_browser;
-+
-+  GList *queued_drawing;
- };
- 
- struct _AgsEffectBulkClass
-@@ -112,6 +114,7 @@
- 
- AgsEffectBulkPlugin* ags_effect_bulk_plugin_alloc(gchar *filename,
- 						  gchar *effect);
-+void ags_effect_bulk_plugin_free(AgsEffectBulkPlugin *effect_bulk_plugin);
- 
- GList* ags_effect_bulk_add_effect(AgsEffectBulk *effect_bulk,
- 				  GList *control_type_name,
-@@ -130,6 +133,8 @@
- void ags_effect_bulk_map_recall(AgsEffectBulk *effect_bulk);
- GList* ags_effect_bulk_find_port(AgsEffectBulk *effect_bulk);
- 
-+gboolean ags_effect_bulk_indicator_queue_draw_timeout(GtkWidget *widget);
-+
- AgsEffectBulk* ags_effect_bulk_new(AgsAudio *audio,
- 				   GType channel_type);
- 
---- a/ags/X/ags_effect_line.c
-+++ b/ags/X/ags_effect_line.c
-@@ -43,9 +43,13 @@
- #include <ags/audio/ags_channel.h>
- #include <ags/audio/ags_output.h>
- #include <ags/audio/ags_input.h>
-+#include <ags/audio/ags_recall_container.h>
- #include <ags/audio/ags_recall_ladspa.h>
- #include <ags/audio/ags_recall_lv2.h>
- 
-+#include <ags/widget/ags_led.h>
-+#include <ags/widget/ags_vindicator.h>
-+#include <ags/widget/ags_hindicator.h>
- #include <ags/widget/ags_dial.h>
- 
- #include <ags/X/ags_window.h>
-@@ -83,6 +87,7 @@
- void ags_effect_line_set_version(AgsPlugin *plugin, gchar *version);
- gchar* ags_effect_line_get_build_id(AgsPlugin *plugin);
- void ags_effect_line_set_build_id(AgsPlugin *plugin, gchar *build_id);
-+void ags_effect_line_finalize(GObject *gobject);
- 
- GList* ags_effect_line_add_ladspa_effect(AgsEffectLine *effect_line,
- 					 GList *control_type_name,
-@@ -129,6 +134,8 @@
- static gpointer ags_effect_line_parent_class = NULL;
- static guint effect_line_signals[LAST_SIGNAL];
- 
-+GHashTable *ags_effect_line_indicator_queue_draw = NULL;
-+
- GType
- ags_effect_line_get_type(void)
- {
-@@ -189,6 +196,8 @@
-   gobject->set_property = ags_effect_line_set_property;
-   gobject->get_property = ags_effect_line_get_property;
- 
-+  gobject->finalize = ags_effect_line_finalize;
-+  
-   /* properties */
-   /**
-    * AgsEffectLine:channel:
-@@ -327,6 +336,12 @@
- void
- ags_effect_line_init(AgsEffectLine *effect_line)
- {
-+  if(ags_effect_line_indicator_queue_draw == NULL){
-+    ags_effect_line_indicator_queue_draw = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-+								 NULL,
-+								 NULL);
-+  }
-+
-   effect_line->flags = 0;
- 
-   effect_line->name = NULL;
-@@ -349,6 +364,8 @@
- 		     GTK_WIDGET(effect_line->table),
- 		     FALSE, FALSE,
- 		     0);
-+
-+  effect_line->queued_drawing = NULL;
- }
- 
- void
-@@ -537,6 +554,25 @@
-   effect_line->build_id = build_id;
- }
- 
-+void
-+ags_effect_line_finalize(GObject *gobject)
-+{
-+  AgsEffectLine *effect_line;
-+  GList *list;
-+
-+  effect_line = AGS_EFFECT_LINE(gobject);
-+  
-+  /* remove of the queued drawing hash */
-+  list = effect_line->queued_drawing;
-+
-+  while(list != NULL){
-+    g_hash_table_remove(ags_effect_line_indicator_queue_draw,
-+			list->data);
-+
-+    list = list->next;
-+  }
-+}
-+
- GList*
- ags_effect_line_add_ladspa_effect(AgsEffectLine *effect_line,
- 				  GList *control_type_name,
-@@ -547,6 +583,8 @@
-   AgsAddLineMember *add_line_member;
-   GtkAdjustment *adjustment;
- 
-+  AgsRecallHandler *recall_handler;
-+
-   AgsLadspaPlugin *ladspa_plugin;
- 
-   AgsMutexManager *mutex_manager;
-@@ -558,11 +596,17 @@
-   
-   gdouble step;
-   guint port_count;
-+  gboolean has_output_port;
-+
-   guint x, y;
-   guint k;
-   
-   pthread_mutex_t *application_mutex;
-   pthread_mutex_t *channel_mutex;
-+
-+  /* get mutex manager and application mutex */
-+  mutex_manager = ags_mutex_manager_get_instance();
-+  application_mutex = ags_mutex_manager_get_application_mutex(mutex_manager);
-   
-   /* load plugin */
-   ladspa_plugin = ags_ladspa_manager_find_ladspa_plugin(ags_ladspa_manager_get_instance(),
-@@ -582,10 +626,6 @@
-     list = list->next;
-   }
- 
--  /* get mutex manager and application mutex */
--  mutex_manager = ags_mutex_manager_get_instance();
--  application_mutex = ags_mutex_manager_get_application_mutex(mutex_manager);
--
-   /* get channel mutex */
-   pthread_mutex_lock(application_mutex);
- 
-@@ -594,13 +634,44 @@
-   
-   pthread_mutex_unlock(application_mutex);
-   
--  /* find ports */
-+  /* play - find ports */
-   pthread_mutex_lock(channel_mutex);
- 
-   recall_start =
-     recall = ags_recall_get_by_effect(effect_line->channel->play,
- 				      filename,
- 				      effect);
-+
-+  if(recall == NULL){
-+    pthread_mutex_unlock(channel_mutex);
-+    
-+    return(NULL);
-+  }
-+
-+  /* check has output port */
-+  if((AGS_RECALL_HAS_OUTPUT_PORT & (AGS_RECALL(recall->data)->flags)) != 0){
-+    has_output_port = TRUE;
-+  }else{
-+    has_output_port = FALSE;
-+  }
-+
-+  /* recall handler of output port */
-+  if(has_output_port){
-+    AgsRecall *recall_channel_run_dummy;
-+
-+    recall_channel_run_dummy = ags_recall_find_template(AGS_RECALL_CONTAINER(AGS_RECALL(recall->data)->container)->recall_channel_run)->data;
-+    
-+    /* alloc handler */
-+    recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+    recall_handler->signal_name = "run-post\0";
-+    recall_handler->callback = G_CALLBACK(ags_effect_line_output_port_run_post_callback);
-+    recall_handler->data = (gpointer) effect_line;
-+
-+    ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+  }
-+  
-+  /* recall - find ports */
-   recall = g_list_last(recall);
-   port = AGS_RECALL(recall->data)->port;
- 
-@@ -613,8 +684,25 @@
-   recall = g_list_last(recall);
- 
-   recall_port = AGS_RECALL(recall->data)->port;
--  g_list_free(recall_start);
- 
-+  /* recall handler of output port */
-+  if(has_output_port){
-+    AgsRecall *recall_channel_run_dummy;
-+
-+    recall_channel_run_dummy = ags_recall_find_template(AGS_RECALL_CONTAINER(AGS_RECALL(recall->data)->container)->recall_channel_run)->data;
-+    
-+    /* alloc handler */
-+    recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+    recall_handler->signal_name = "run-post\0";
-+    recall_handler->callback = G_CALLBACK(ags_effect_line_output_port_run_post_callback);
-+    recall_handler->data = (gpointer) effect_line;
-+
-+    ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+  }
-+
-+  g_list_free(recall_start);
-+  
-   pthread_mutex_unlock(channel_mutex);
- 
-   /* load ports */
-@@ -641,9 +729,17 @@
-       }
-       
-       if((AGS_PORT_DESCRIPTOR_TOGGLED & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
--	widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_LED;
-+	}else{
-+	  widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	}
-       }else{
--	widget_type = AGS_TYPE_DIAL;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_HINDICATOR;
-+	}else{
-+	  widget_type = AGS_TYPE_DIAL;
-+	}
-       }
- 
-       if(control_type_name != NULL){
-@@ -754,6 +850,13 @@
- 				 upper_bound);
- 	gtk_adjustment_set_value(adjustment,
- 				 g_value_get_float(AGS_PORT_DESCRIPTOR(port_descriptor->data)->default_value));
-+      }else if(AGS_IS_INDICATOR(child_widget) ||
-+	       AGS_IS_LED(child_widget)){
-+	g_hash_table_insert(ags_effect_line_indicator_queue_draw,
-+			    child_widget, ags_effect_line_indicator_queue_draw_timeout);
-+	effect_line->queued_drawing = g_list_prepend(effect_line->queued_drawing,
-+						     child_widget);
-+	g_timeout_add(1000 / 30, (GSourceFunc) ags_effect_line_indicator_queue_draw_timeout, (gpointer) child_widget);
-       }
- 
- #ifdef AGS_DEBUG
-@@ -792,6 +895,8 @@
-   AgsAddLineMember *add_line_member;
-   GtkAdjustment *adjustment;
- 
-+  AgsRecallHandler *recall_handler;
-+
-   AgsLv2Plugin *lv2_plugin;
- 
-   AgsMutexManager *mutex_manager;
-@@ -803,12 +908,18 @@
-   
-   gdouble step;
-   guint port_count;
-+  gboolean has_output_port;
-+
-   guint x, y;
-   guint k;
-   
-   pthread_mutex_t *application_mutex;
-   pthread_mutex_t *channel_mutex;
- 
-+  /* get mutex manager and application mutex */
-+  mutex_manager = ags_mutex_manager_get_instance();
-+  application_mutex = ags_mutex_manager_get_application_mutex(mutex_manager);
-+
-   /* load plugin */
-   lv2_plugin = ags_lv2_manager_find_lv2_plugin(ags_lv2_manager_get_instance(),
- 					       filename, effect);
-@@ -827,10 +938,6 @@
-     list = list->next;
-   }
- 
--  /* get mutex manager and application mutex */
--  mutex_manager = ags_mutex_manager_get_instance();
--  application_mutex = ags_mutex_manager_get_application_mutex(mutex_manager);
--
-   /* get channel mutex */
-   pthread_mutex_lock(application_mutex);
- 
-@@ -839,18 +946,49 @@
-   
-   pthread_mutex_unlock(application_mutex);
-   
--  /* find ports */
-+  /* play - find ports */
-   pthread_mutex_lock(channel_mutex);
-   
-   recall_start =
-     recall = ags_recall_get_by_effect(effect_line->channel->play,
- 				      filename,
- 				      effect);
-+
-+  if(recall == NULL){
-+    pthread_mutex_unlock(channel_mutex);
-+    
-+    return(NULL);
-+  }
-+
-   recall = g_list_last(recall);
-   port = AGS_RECALL(recall->data)->port;
- 
-+  /* check has output port */
-+  if((AGS_RECALL_HAS_OUTPUT_PORT & (AGS_RECALL(recall->data)->flags)) != 0){
-+    has_output_port = TRUE;
-+  }else{
-+    has_output_port = FALSE;
-+  }
-+
-+  /* recall handler of output port */
-+  if(has_output_port){
-+    AgsRecall *recall_channel_run_dummy;
-+
-+    recall_channel_run_dummy = ags_recall_find_template(AGS_RECALL_CONTAINER(AGS_RECALL(recall->data)->container)->recall_channel_run)->data;
-+    
-+    /* alloc handler */
-+    recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+    recall_handler->signal_name = "run-post\0";
-+    recall_handler->callback = G_CALLBACK(ags_effect_line_output_port_run_post_callback);
-+    recall_handler->data = (gpointer) effect_line;
-+
-+    ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+  }
-+
-   g_list_free(recall_start);
- 
-+  /* recall - find ports */
-   recall_start = 
-     recall = ags_recall_get_by_effect(effect_line->channel->recall,
- 				      filename,
-@@ -858,10 +996,27 @@
-   recall = g_list_last(recall);
- 
-   recall_port = AGS_RECALL(recall->data)->port;
--  g_list_free(recall_start);
- 
--  pthread_mutex_unlock(channel_mutex);
-+  /* recall handler of output port */
-+  if(has_output_port){
-+    AgsRecall *recall_channel_run_dummy;
-+
-+    recall_channel_run_dummy = ags_recall_find_template(AGS_RECALL_CONTAINER(AGS_RECALL(recall->data)->container)->recall_channel_run)->data;
-+    
-+    /* alloc handler */
-+    recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+    recall_handler->signal_name = "run-post\0";
-+    recall_handler->callback = G_CALLBACK(ags_effect_line_output_port_run_post_callback);
-+    recall_handler->data = (gpointer) effect_line;
-+
-+    ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+  }
-+  
-+  g_list_free(recall_start);
-   
-+  pthread_mutex_unlock(channel_mutex);
-+
-   /* load ports */
-   port_descriptor = AGS_BASE_PLUGIN(lv2_plugin)->port;
- 
-@@ -887,9 +1042,17 @@
-       }
- 
-       if((AGS_PORT_DESCRIPTOR_TOGGLED & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
--	widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_LED;
-+	}else{
-+	  widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	}
-       }else{
--	widget_type = AGS_TYPE_DIAL;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_HINDICATOR;
-+	}else{
-+	  widget_type = AGS_TYPE_DIAL;
-+	}
-       }
- 
-       if(control_type_name != NULL){
-@@ -975,6 +1138,13 @@
- 				 upper_bound);
- 	gtk_adjustment_set_value(adjustment,
- 				 g_value_get_float(AGS_PORT_DESCRIPTOR(port_descriptor->data)->default_value));
-+      }else if(AGS_IS_INDICATOR(child_widget) ||
-+	       AGS_IS_LED(child_widget)){
-+	g_hash_table_insert(ags_effect_line_indicator_queue_draw,
-+			    child_widget, ags_effect_line_indicator_queue_draw_timeout);
-+	effect_line->queued_drawing = g_list_prepend(effect_line->queued_drawing,
-+						     child_widget);
-+	g_timeout_add(1000 / 30, (GSourceFunc) ags_effect_line_indicator_queue_draw_timeout, (gpointer) child_widget);
-       }
- 
- #ifdef AGS_DEBUG
-@@ -1163,6 +1333,10 @@
-     while(control != NULL){
-       if(AGS_IS_LINE_MEMBER(control->data) &&
- 	 AGS_LINE_MEMBER(control->data)->port == port->data){
-+	GtkWidget *child_widget;
-+	
-+	child_widget = gtk_bin_get_child(control->data);
-+	
- 	/* collect specifier */
- 	if(remove_specifier == NULL){
- 	  remove_specifier = (gchar **) malloc(2 * sizeof(gchar *));
-@@ -1175,6 +1349,12 @@
- 	i++;
- 
- 	/* remove widget */
-+	if(AGS_IS_LED(child_widget) ||
-+	   AGS_IS_INDICATOR(child_widget)){
-+	  g_hash_table_remove(ags_effect_line_indicator_queue_draw,
-+			      child_widget);
-+	}
-+
- 	gtk_widget_destroy(control->data);
- 	
- 	break;
-@@ -1327,6 +1507,29 @@
- }
- 
- /**
-+ * ags_effect_line_indicator_queue_draw_timeout:
-+ * @widget: the indicator widgt
-+ *
-+ * Queue draw widget
-+ *
-+ * Returns: %TRUE if proceed with redraw, otherwise %FALSE
-+ *
-+ * Since: 0.7.128
-+ */
-+gboolean
-+ags_effect_line_indicator_queue_draw_timeout(GtkWidget *widget)
-+{
-+  if(g_hash_table_lookup(ags_effect_line_indicator_queue_draw,
-+			 widget) != NULL){
-+    gtk_widget_queue_draw(widget);
-+    
-+    return(TRUE);
-+  }else{
-+    return(FALSE);
-+  }
-+}
-+
-+/**
-  * ags_effect_line_new:
-  * @channel: the #AgsChannel to visualize
-  *
---- a/ags/X/ags_effect_line_callbacks.c
-+++ b/ags/X/ags_effect_line_callbacks.c
-@@ -22,8 +22,7 @@
- #include <ags/object/ags_application_context.h>
- #include <ags/object/ags_soundcard.h>
- 
--#include <ags/thread/ags_mutex_manager.h>
--#include <ags/thread/ags_task_thread.h>
-+#include <ags/plugin/ags_base_plugin.h>
- 
- #include <ags/audio/ags_playback.h>
- #include <ags/audio/ags_recall.h>
-@@ -41,8 +40,10 @@
- #include <ags/audio/recall/ags_copy_pattern_channel.h>
- #include <ags/audio/recall/ags_copy_pattern_channel_run.h>
- 
--#include <ags/widget/ags_indicator.h>
-+#include <ags/widget/ags_led.h>
- #include <ags/widget/ags_vindicator.h>
-+#include <ags/widget/ags_hindicator.h>
-+#include <ags/widget/ags_dial.h>
- 
- #include <ags/X/ags_window.h>
- #include <ags/X/ags_machine.h>
-@@ -58,8 +59,6 @@
- #include <ags/X/ags_dssi_browser.h>
- #include <ags/X/ags_lv2_browser.h>
- 
--#include <ags/X/task/ags_change_indicator.h>
--
- void
- ags_effect_line_remove_recall_callback(AgsRecall *recall, AgsEffectLine *effect_line)
- {
-@@ -162,6 +161,21 @@
- 	      controls = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(port_control->data));
- 
- 	      if(!g_ascii_strncasecmp(controls,
-+				      "led\0",
-+				      4)){
-+		control_type_name = g_list_prepend(control_type_name,
-+						   "AgsLed\0");
-+	      }else if(!g_ascii_strncasecmp(controls,
-+				      "vertical indicator\0",
-+				      19)){
-+		control_type_name = g_list_prepend(control_type_name,
-+						   "AgsVIndicator\0");
-+	      }else if(!g_ascii_strncasecmp(controls,
-+				      "horizontal indicator\0",
-+				      19)){
-+		control_type_name = g_list_prepend(control_type_name,
-+						   "AgsHIndicator\0");
-+	      }else if(!g_ascii_strncasecmp(controls,
- 				      "spin button\0",
- 				      12)){
- 		control_type_name = g_list_prepend(control_type_name,
-@@ -238,4 +252,158 @@
- 
-   /* unlock gdk threads */
-   gdk_threads_leave();
-+}
-+
-+void
-+ags_effect_line_output_port_run_post_callback(AgsRecall *recall,
-+					      AgsEffectLine *effect_line)
-+{
-+  GtkWidget *child;
-+
-+  GList *list, *list_start;
-+  
-+  /* lock gdk threads */
-+  gdk_threads_enter();
-+  
-+  list_start = 
-+    list = gtk_container_get_children((GtkContainer *) AGS_EFFECT_LINE(effect_line)->table);
-+
-+  /* check members */
-+  while(list != NULL){
-+    if(AGS_IS_LINE_MEMBER(list->data) &&
-+       (AGS_LINE_MEMBER(list->data)->widget_type == AGS_TYPE_VINDICATOR ||
-+	AGS_LINE_MEMBER(list->data)->widget_type == AGS_TYPE_HINDICATOR ||
-+	AGS_LINE_MEMBER(list->data)->widget_type == AGS_TYPE_LED)){
-+      AgsLineMember *line_member;
-+      GtkAdjustment *adjustment;
-+
-+      AgsPort *current;
-+	
-+      gdouble average_peak;
-+      gdouble lower, upper;
-+      gdouble range;
-+      gdouble peak;
-+
-+      GValue value = {0,};
-+
-+      line_member = AGS_LINE_MEMBER(list->data);
-+      child = GTK_BIN(line_member)->child;
-+      
-+      average_peak = 0.0;
-+      
-+      /* play port */
-+      current = line_member->port;
-+
-+      if(current == NULL){
-+	list = list->next;
-+	
-+	continue;
-+      }
-+      
-+      /* check if output port and specifier matches */
-+      pthread_mutex_lock(current->mutex);
-+      
-+      if((AGS_PORT_IS_OUTPUT & (current->flags)) == 0 ||
-+	 current->port_descriptor == NULL ||
-+	 g_ascii_strcasecmp(current->specifier,
-+			    line_member->specifier)){
-+	pthread_mutex_unlock(current->mutex);
-+	
-+	list = list->next;
-+	
-+	continue;
-+      }
-+
-+      /* lower and upper */
-+      lower = g_value_get_float(AGS_PORT_DESCRIPTOR(current->port_descriptor)->lower_value);
-+      upper = g_value_get_float(AGS_PORT_DESCRIPTOR(current->port_descriptor)->upper_value);
-+      
-+      pthread_mutex_unlock(current->mutex);
-+
-+      /* get range */
-+      if(line_member->conversion != NULL){
-+	lower = ags_conversion_convert(line_member->conversion,
-+				       lower,
-+				       TRUE);
-+
-+	upper = ags_conversion_convert(line_member->conversion,
-+				       upper,
-+				       TRUE);
-+      }
-+
-+      range = upper - lower;
-+
-+      /* play port - read value */
-+      g_value_init(&value, G_TYPE_FLOAT);
-+      ags_port_safe_read(current,
-+			 &value);
-+      
-+      peak = g_value_get_float(&value);
-+      g_value_unset(&value);
-+
-+      if(line_member->conversion != NULL){
-+	peak = ags_conversion_convert(line_member->conversion,
-+				      peak,
-+				      TRUE);
-+      }
-+
-+      /* calculate peak */
-+      if(range == 0.0 ||
-+	 current->port_value_type == G_TYPE_BOOLEAN){
-+	if(peak != 0.0){
-+	  average_peak = 10.0;
-+	}
-+      }else{
-+	average_peak += ((1.0 / (range / peak)) * 10.0);
-+      }
-+
-+      /* recall port */
-+      current = line_member->recall_port;
-+
-+      /* recall port - read value */
-+      g_value_init(&value, G_TYPE_FLOAT);
-+      ags_port_safe_read(current,
-+			 &value);
-+      
-+      peak = g_value_get_float(&value);
-+      g_value_unset(&value);
-+      
-+      if(line_member->conversion != NULL){
-+	peak = ags_conversion_convert(line_member->conversion,
-+				      peak,
-+				      TRUE);
-+      }
-+
-+      /* calculate peak */
-+      if(range == 0.0 ||
-+	 current->port_value_type == G_TYPE_BOOLEAN){
-+	if(peak != 0.0){
-+	  average_peak = 10.0;
-+	}
-+      }else{
-+	average_peak += ((1.0 / (range / peak)) * 10.0);
-+      }
-+      
-+      /* apply */
-+      if(AGS_IS_LED(child)){
-+	if(average_peak != 0.0){
-+	  ags_led_set_active(child);
-+	}
-+      }else{
-+	g_object_get(child,
-+		     "adjustment\0", &adjustment,
-+		     NULL);
-+	
-+	gtk_adjustment_set_value(adjustment,
-+				 average_peak);
-+      }
-+    }
-+    
-+    list = list->next;
-+  }
-+
-+  g_list_free(list_start);
-+
-+  /* unlock gdk threads */
-+  gdk_threads_leave();
- }
---- a/ags/X/ags_effect_line_callbacks.h
-+++ b/ags/X/ags_effect_line_callbacks.h
-@@ -38,4 +38,7 @@
- 					    guint nth,
- 					    AgsEffectLine *effect_line);
- 
-+void ags_effect_line_output_port_run_post_callback(AgsRecall *recall,
-+						   AgsEffectLine *effect_line);
-+
- #endif /*__AGS_EFFECT_LINE_CALLBACKS_H__*/
---- a/ags/X/ags_effect_line.h
-+++ b/ags/X/ags_effect_line.h
-@@ -63,6 +63,8 @@
-   GtkLabel *label;
-   
-   GtkTable *table;
-+
-+  GList *queued_drawing;
- };
- 
- struct _AgsEffectLineClass
-@@ -98,6 +100,8 @@
- 				guint output_pad_start);
- GList* ags_effect_line_find_port(AgsEffectLine *effect_line);
- 
-+gboolean ags_effect_line_indicator_queue_draw_timeout(GtkWidget *widget);
-+
- AgsEffectLine* ags_effect_line_new(AgsChannel *channel);
- 
- #endif /*__AGS_EFFECT_LINE_H__*/
---- a/ags/X/file/ags_gui_file_xml.c
-+++ b/ags/X/file/ags_gui_file_xml.c
-@@ -2100,7 +2100,7 @@
-       recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
- 
-       recall_handler->signal_name = "run-post\0";
--      recall_handler->callback = G_CALLBACK(ags_line_peak_run_post_callback);
-+      recall_handler->callback = G_CALLBACK(ags_line_output_port_run_post_callback);
-       recall_handler->data = (gpointer) line;
- 
-       ags_recall_add_handler(AGS_RECALL(play_peak_channel_run), recall_handler);
-@@ -2116,7 +2116,7 @@
-       recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
- 
-       recall_handler->signal_name = "run-post\0";
--      recall_handler->callback = G_CALLBACK(ags_line_peak_run_post_callback);
-+      recall_handler->callback = G_CALLBACK(ags_line_output_port_run_post_callback);
-       recall_handler->data = (gpointer) line;
- 
-       ags_recall_add_handler(AGS_RECALL(recall_peak_channel_run), recall_handler);
---- a/ags/X/ags_ladspa_browser.c
-+++ b/ags/X/ags_ladspa_browser.c
-@@ -357,6 +357,58 @@
- }
- 
- /**
-+ * ags_ladspa_browser_combo_box_output_boolean_controls_new:
-+ *
-+ * Creates a #GtkComboBox containing suitable widgets as controls.
-+ *
-+ * Returns: a new #GtkComboBox
-+ *
-+ * Since: 0.7.128
-+ */
-+GtkWidget*
-+ags_ladspa_browser_combo_box_output_boolean_controls_new()
-+{
-+  GtkComboBoxText *combo_box;
-+
-+  combo_box = (GtkComboBoxText *) gtk_combo_box_text_new();
-+
-+  gtk_combo_box_text_append_text(combo_box,
-+				 "led\0");
-+
-+  gtk_combo_box_set_active((GtkComboBox *) combo_box,
-+			   1);
-+
-+  return((GtkWidget *) combo_box);
-+}
-+
-+/**
-+ * ags_ladspa_browser_combo_box_controls_new:
-+ *
-+ * Creates a #GtkComboBox containing suitable widgets as controls.
-+ *
-+ * Returns: a new #GtkComboBox
-+ *
-+ * Since: 0.7.128
-+ */
-+GtkWidget*
-+ags_ladspa_browser_combo_box_output_controls_new()
-+{
-+  GtkComboBoxText *combo_box;
-+
-+  combo_box = (GtkComboBoxText *) gtk_combo_box_text_new();
-+
-+  gtk_combo_box_text_append_text(combo_box,
-+				 "vertical indicator\0");
-+  gtk_combo_box_text_append_text(combo_box,
-+				 "horizontal indicator\0");
-+
-+  gtk_combo_box_set_active((GtkComboBox *) combo_box,
-+			   1);
-+
-+  return((GtkWidget *) combo_box);
-+}
-+
-+/**
-  * ags_ladspa_browser_combo_box_boolean_controls_new:
-  *
-  * Creates a #GtkComboBox containing suitable widgets as controls.
---- a/ags/X/ags_ladspa_browser_callbacks.c
-+++ b/ags/X/ags_ladspa_browser_callbacks.c
-@@ -180,15 +180,29 @@
- 				  y, y + 1);
- 
- 	if(LADSPA_IS_HINT_TOGGLED(plugin_descriptor->PortRangeHints[i].HintDescriptor)){
--	  gtk_table_attach_defaults(table,
--				    GTK_WIDGET(ags_ladspa_browser_combo_box_boolean_controls_new()),
--				    1, 2,
--				    y, y + 1);
-+	  if(LADSPA_IS_PORT_OUTPUT(port_descriptor[i])){
-+	    gtk_table_attach_defaults(table,
-+				      GTK_WIDGET(ags_ladspa_browser_combo_box_output_boolean_controls_new()),
-+				      1, 2,
-+				      y, y + 1);
-+	  }else{
-+	    gtk_table_attach_defaults(table,
-+				      GTK_WIDGET(ags_ladspa_browser_combo_box_boolean_controls_new()),
-+				      1, 2,
-+				      y, y + 1);
-+	  }
- 	}else{
--	  gtk_table_attach_defaults(table,
--				    GTK_WIDGET(ags_ladspa_browser_combo_box_controls_new()),
--				    1, 2,
--				    y, y + 1);
-+	  if(LADSPA_IS_PORT_OUTPUT(port_descriptor[i])){
-+	    gtk_table_attach_defaults(table,
-+				      GTK_WIDGET(ags_ladspa_browser_combo_box_output_controls_new()),
-+				      1, 2,
-+				      y, y + 1);
-+	  }else{
-+	    gtk_table_attach_defaults(table,
-+				      GTK_WIDGET(ags_ladspa_browser_combo_box_controls_new()),
-+				      1, 2,
-+				      y, y + 1);
-+	  }
- 	}
- 	
- 	y++;
---- a/ags/X/ags_ladspa_browser.h
-+++ b/ags/X/ags_ladspa_browser.h
-@@ -56,8 +56,12 @@
- gchar* ags_ladspa_browser_get_plugin_filename(AgsLadspaBrowser *ladspa_browser);
- gchar* ags_ladspa_browser_get_plugin_effect(AgsLadspaBrowser *ladspa_browser);
- 
-+GtkWidget* ags_ladspa_browser_combo_box_output_boolean_controls_new();
-+GtkWidget* ags_ladspa_browser_combo_box_output_controls_new();
-+
- GtkWidget* ags_ladspa_browser_combo_box_boolean_controls_new();
- GtkWidget* ags_ladspa_browser_combo_box_controls_new();
-+
- GtkWidget* ags_ladspa_browser_preview_new();
- 
- AgsLadspaBrowser* ags_ladspa_browser_new();
---- a/ags/X/ags_line.c
-+++ b/ags/X/ags_line.c
-@@ -43,11 +43,15 @@
- #include <ags/audio/ags_channel.h>
- #include <ags/audio/ags_output.h>
- #include <ags/audio/ags_input.h>
-+#include <ags/audio/ags_recall_container.h>
- #include <ags/audio/ags_recall_ladspa.h>
- #include <ags/audio/ags_recall_lv2.h>
- 
- #include <ags/audio/recall/ags_peak_channel_run.h>
- 
-+#include <ags/widget/ags_led.h>
-+#include <ags/widget/ags_vindicator.h>
-+#include <ags/widget/ags_hindicator.h>
- #include <ags/widget/ags_dial.h>
- 
- #include <ags/X/ags_window.h>
-@@ -128,7 +132,7 @@
- static gpointer ags_line_parent_class = NULL;
- static guint line_signals[LAST_SIGNAL];
- 
--GHashTable *ags_indicator_queue_draw = NULL;
-+GHashTable *ags_line_indicator_queue_draw = NULL;
- 
- GType
- ags_line_get_type(void)
-@@ -385,8 +389,8 @@
- void
- ags_line_init(AgsLine *line)
- {
--  if(ags_indicator_queue_draw == NULL){
--    ags_indicator_queue_draw = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-+  if(ags_line_indicator_queue_draw == NULL){
-+    ags_line_indicator_queue_draw = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- 						     NULL,
- 						     NULL);
-   }
-@@ -436,14 +440,27 @@
- ags_line_finalize(GObject *gobject)
- {
-   AgsLine *line;
--
--  line = AGS_LINE(gobject);
-+  GList *list;
-   
-+  line = AGS_LINE(gobject);
-+
-+  /* remove indicator widget */
-   if(line->indicator != NULL){
--    g_hash_table_remove(ags_indicator_queue_draw,
-+    g_hash_table_remove(ags_line_indicator_queue_draw,
- 			line->indicator);
-   }
--  
-+
-+  /* remove of the queued drawing hash */
-+  list = line->queued_drawing;
-+
-+  while(list != NULL){
-+    g_hash_table_remove(ags_line_indicator_queue_draw,
-+			list->data);
-+
-+    list = list->next;
-+  }
-+
-+  /* call parent */
-   G_OBJECT_CLASS(ags_line_parent_class)->finalize(gobject);
- }
- 
-@@ -743,6 +760,8 @@
-   AgsLineMember *line_member;
-   GtkAdjustment *adjustment;
- 
-+  AgsRecallHandler *recall_handler;
-+
-   AgsLadspaPlugin *ladspa_plugin;
- 
-   AgsMutexManager *mutex_manager;
-@@ -754,11 +773,17 @@
- 
-   gdouble step;
-   guint port_count;
-+  gboolean has_output_port;
-+
-   guint x, y;
-   guint k;
- 
-   pthread_mutex_t *application_mutex;
-   pthread_mutex_t *channel_mutex;
-+
-+  /* get mutex manager and application mutex */
-+  mutex_manager = ags_mutex_manager_get_instance();
-+  application_mutex = ags_mutex_manager_get_application_mutex(mutex_manager);
-   
-   /* load plugin */
-   ladspa_plugin = ags_ladspa_manager_find_ladspa_plugin(ags_ladspa_manager_get_instance(),
-@@ -778,10 +803,6 @@
-     list = list->next;
-   }
- 
--  /* get mutex manager and application mutex */
--  mutex_manager = ags_mutex_manager_get_instance();
--  application_mutex = ags_mutex_manager_get_application_mutex(mutex_manager);
--
-   /* get channel mutex */
-   pthread_mutex_lock(application_mutex);
- 
-@@ -790,18 +811,49 @@
-   
-   pthread_mutex_unlock(application_mutex);
-   
--  /* find ports */
-+  /* play - find ports */
-   pthread_mutex_lock(channel_mutex);
-   
-   recall_start =
-     recall = ags_recall_get_by_effect(line->channel->play,
- 				      filename,
- 				      effect);
-+  
-+  if(recall == NULL){
-+    pthread_mutex_unlock(channel_mutex);
-+    
-+    return(NULL);
-+  }
-+
-   recall = g_list_last(recall);
-   port = AGS_RECALL(recall->data)->port;
- 
--  g_list_free(recall_start);
-+  /* check has output port */
-+  if((AGS_RECALL_HAS_OUTPUT_PORT & (AGS_RECALL(recall->data)->flags)) != 0){
-+    has_output_port = TRUE;
-+  }else{
-+    has_output_port = FALSE;
-+  }
-+
-+  /* recall handler of output port */
-+  if(has_output_port){
-+    AgsRecall *recall_channel_run_dummy;
-+
-+    recall_channel_run_dummy = ags_recall_find_template(AGS_RECALL_CONTAINER(AGS_RECALL(recall->data)->container)->recall_channel_run)->data;
-+    
-+    /* alloc handler */
-+    recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
- 
-+    recall_handler->signal_name = "run-post\0";
-+    recall_handler->callback = G_CALLBACK(ags_line_output_port_run_post_callback);
-+    recall_handler->data = (gpointer) line;
-+
-+    ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+  }
-+  
-+  g_list_free(recall_start);
-+  
-+  /* recall - find ports */
-   recall_start = 
-     recall = ags_recall_get_by_effect(line->channel->recall,
- 				      filename,
-@@ -809,8 +861,25 @@
-   recall = g_list_last(recall);
- 
-   recall_port = AGS_RECALL(recall->data)->port;
--  g_list_free(recall_start);
- 
-+  /* recall handler of output port */
-+  if(has_output_port){
-+    AgsRecall *recall_channel_run_dummy;
-+
-+    recall_channel_run_dummy = ags_recall_find_template(AGS_RECALL_CONTAINER(AGS_RECALL(recall->data)->container)->recall_channel_run)->data;
-+    
-+    /* alloc handler */
-+    recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+    recall_handler->signal_name = "run-post\0";
-+    recall_handler->callback = G_CALLBACK(ags_line_output_port_run_post_callback);
-+    recall_handler->data = (gpointer) line;
-+
-+    ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+  }
-+  
-+  g_list_free(recall_start);
-+  
-   pthread_mutex_unlock(channel_mutex);
-   
-   /* load ports */
-@@ -818,7 +887,7 @@
- 
-   port_count = g_list_length(port_descriptor);
-   k = 0;
--
-+  
-   while(port_descriptor != NULL){
-     if((AGS_PORT_DESCRIPTOR_CONTROL & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-       GtkWidget *child_widget;
-@@ -830,9 +899,17 @@
-       guint step_count;
-       
-       if((AGS_PORT_DESCRIPTOR_TOGGLED & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
--	widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_LED;
-+	}else{
-+	  widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	}
-       }else{
--	widget_type = AGS_TYPE_DIAL;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_HINDICATOR;
-+	}else{
-+	  widget_type = AGS_TYPE_DIAL;
-+	}
-       }
- 
-       if(control_type_name != NULL){
-@@ -943,8 +1020,15 @@
- 				 upper_bound);
- 	gtk_adjustment_set_value(adjustment,
- 				 g_value_get_float(AGS_PORT_DESCRIPTOR(port_descriptor->data)->default_value));
-+      }else if(AGS_IS_INDICATOR(child_widget) ||
-+	       AGS_IS_LED(child_widget)){
-+	g_hash_table_insert(ags_line_indicator_queue_draw,
-+			    child_widget, ags_line_indicator_queue_draw_timeout);
-+	line->queued_drawing = g_list_prepend(line->queued_drawing,
-+					      child_widget);
-+	g_timeout_add(1000 / 30, (GSourceFunc) ags_line_indicator_queue_draw_timeout, (gpointer) child_widget);
-       }
--
-+      
- #ifdef AGS_DEBUG
-       g_message("ladspa bounds: %f %f\0", lower_bound, upper_bound);
- #endif
-@@ -977,6 +1061,8 @@
-   AgsLineMember *line_member;
-   GtkAdjustment *adjustment;
- 
-+  AgsRecallHandler *recall_handler;
-+
-   AgsLv2Plugin *lv2_plugin;
- 
-   AgsMutexManager *mutex_manager;
-@@ -991,12 +1077,18 @@
- 
-   gdouble step;
-   guint port_count;
-+  gboolean has_output_port;
-+
-   guint x, y;
-   guint k;
-   
-   pthread_mutex_t *application_mutex;
-   pthread_mutex_t *channel_mutex;
- 
-+  /* get mutex manager and application mutex */
-+  mutex_manager = ags_mutex_manager_get_instance();
-+  application_mutex = ags_mutex_manager_get_application_mutex(mutex_manager);
-+
-   /* load plugin */
-   lv2_plugin = ags_lv2_manager_find_lv2_plugin(ags_lv2_manager_get_instance(),
- 					       filename, effect);
-@@ -1015,10 +1107,6 @@
-     list = list->next;
-   }
- 
--  /* get mutex manager and application mutex */
--  mutex_manager = ags_mutex_manager_get_instance();
--  application_mutex = ags_mutex_manager_get_application_mutex(mutex_manager);
--
-   /* get channel mutex */
-   pthread_mutex_lock(application_mutex);
- 
-@@ -1027,7 +1115,7 @@
-   
-   pthread_mutex_unlock(application_mutex);
-   
--  /* find ports */
-+  /* play - find ports */
-   pthread_mutex_lock(channel_mutex);
-   
-   recall_start =
-@@ -1044,8 +1132,32 @@
-   recall = g_list_last(recall);
-   port = AGS_RECALL(recall->data)->port;
- 
-+  /* check has output port */
-+  if((AGS_RECALL_HAS_OUTPUT_PORT & (AGS_RECALL(recall->data)->flags)) != 0){
-+    has_output_port = TRUE;
-+  }else{
-+    has_output_port = FALSE;
-+  }
-+
-+  /* recall handler of output port */
-+  if(has_output_port){
-+    AgsRecall *recall_channel_run_dummy;
-+
-+    recall_channel_run_dummy = ags_recall_find_template(AGS_RECALL_CONTAINER(AGS_RECALL(recall->data)->container)->recall_channel_run)->data;
-+    
-+    /* alloc handler */
-+    recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+    recall_handler->signal_name = "run-post\0";
-+    recall_handler->callback = G_CALLBACK(ags_line_output_port_run_post_callback);
-+    recall_handler->data = (gpointer) line;
-+
-+    ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+  }
-+  
-   g_list_free(recall_start);
- 
-+  /* recall - find ports */
-   recall_start = 
-     recall = ags_recall_get_by_effect(line->channel->recall,
- 				      filename,
-@@ -1053,10 +1165,27 @@
-   recall = g_list_last(recall);
- 
-   recall_port = AGS_RECALL(recall->data)->port;
--  g_list_free(recall_start);
- 
--  pthread_mutex_unlock(channel_mutex);
-+  /* recall handler of output port */
-+  if(has_output_port){
-+    AgsRecall *recall_channel_run_dummy;
-+
-+    recall_channel_run_dummy = ags_recall_find_template(AGS_RECALL_CONTAINER(AGS_RECALL(recall->data)->container)->recall_channel_run)->data;
-+    
-+    /* alloc handler */
-+    recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
-+
-+    recall_handler->signal_name = "run-post\0";
-+    recall_handler->callback = G_CALLBACK(ags_line_output_port_run_post_callback);
-+    recall_handler->data = (gpointer) line;
-+
-+    ags_recall_add_handler(AGS_RECALL(recall_channel_run_dummy), recall_handler);
-+  }
-   
-+  g_list_free(recall_start);
-+  
-+  pthread_mutex_unlock(channel_mutex);
-+
-   /* load ports */
-   port_descriptor = AGS_BASE_PLUGIN(lv2_plugin)->port;
- 
-@@ -1075,9 +1204,17 @@
-       guint step_count;
-       
-       if((AGS_PORT_DESCRIPTOR_TOGGLED & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
--	widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_LED;
-+	}else{
-+	  widget_type = GTK_TYPE_TOGGLE_BUTTON;
-+	}
-       }else{
--	widget_type = AGS_TYPE_DIAL;
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  widget_type = AGS_TYPE_HINDICATOR;
-+	}else{
-+	  widget_type = AGS_TYPE_DIAL;
-+	}
-       }
- 
-       if(control_type_name != NULL){
-@@ -1163,6 +1300,12 @@
- 				 upper_bound);
- 	gtk_adjustment_set_value(adjustment,
- 				 g_value_get_float(AGS_PORT_DESCRIPTOR(port_descriptor->data)->default_value));
-+      }else if(AGS_IS_INDICATOR(child_widget)){
-+	g_hash_table_insert(ags_line_indicator_queue_draw,
-+			    child_widget, ags_line_indicator_queue_draw_timeout);
-+	line->queued_drawing = g_list_prepend(line->queued_drawing,
-+					      child_widget);
-+	g_timeout_add(1000 / 30, (GSourceFunc) ags_line_indicator_queue_draw_timeout, (gpointer) child_widget);
-       }
- 
- #ifdef AGS_DEBUG
-@@ -1348,6 +1491,10 @@
-     while(control != NULL){
-       if(AGS_IS_LINE_MEMBER(control->data) &&
- 	 AGS_LINE_MEMBER(control->data)->port == port->data){
-+	GtkWidget *child_widget;
-+	
-+	child_widget = gtk_bin_get_child(control->data);
-+
- 	/* collect specifier */
- 	if(remove_specifier == NULL){
- 	  remove_specifier = (gchar **) malloc(2 * sizeof(gchar *));
-@@ -1360,6 +1507,12 @@
- 	i++;
- 
- 	/* remove widget */
-+	if(AGS_IS_LED(child_widget) ||
-+	   AGS_IS_INDICATOR(child_widget)){
-+	  g_hash_table_remove(ags_line_indicator_queue_draw,
-+			      child_widget);
-+	}
-+	
- 	ags_expander_remove(line->expander,
- 			    control->data);
- 
-@@ -1544,7 +1697,7 @@
- gboolean
- ags_line_indicator_queue_draw_timeout(GtkWidget *widget)
- {
--  if(g_hash_table_lookup(ags_indicator_queue_draw,
-+  if(g_hash_table_lookup(ags_line_indicator_queue_draw,
- 			 widget) != NULL){
-     gtk_widget_queue_draw(widget);
-     
---- a/ags/X/ags_line_callbacks.c
-+++ b/ags/X/ags_line_callbacks.c
-@@ -23,7 +23,8 @@
- #include <ags/object/ags_soundcard.h>
- 
- #include <ags/thread/ags_mutex_manager.h>
--#include <ags/thread/ags_task_thread.h>
-+
-+#include <ags/plugin/ags_base_plugin.h>
- 
- #include <ags/audio/ags_playback.h>
- #include <ags/audio/ags_recall.h>
-@@ -41,8 +42,10 @@
- #include <ags/audio/recall/ags_copy_pattern_channel.h>
- #include <ags/audio/recall/ags_copy_pattern_channel_run.h>
- 
-+#include <ags/widget/ags_led.h>
- #include <ags/widget/ags_indicator.h>
- #include <ags/widget/ags_vindicator.h>
-+#include <ags/widget/ags_hindicator.h>
- 
- #include <ags/X/ags_window.h>
- #include <ags/X/ags_machine.h>
-@@ -58,8 +61,6 @@
- #include <ags/X/ags_dssi_browser.h>
- #include <ags/X/ags_lv2_browser.h>
- 
--#include <ags/X/task/ags_change_indicator.h>
--
- int
- ags_line_parent_set_callback(GtkWidget *widget, GtkObject *old_parent, AgsLine *line)
- {
-@@ -231,8 +232,23 @@
- 	      controls = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(port_control->data));
- 
- 	      if(!g_ascii_strncasecmp(controls,
--				      "spin button\0",
--				      12)){
-+				      "led\0",
-+				      4)){
-+		control_type_name = g_list_prepend(control_type_name,
-+						   "AgsLed\0");
-+	      }else if(!g_ascii_strncasecmp(controls,
-+					    "vertical indicator\0",
-+					    19)){
-+		control_type_name = g_list_prepend(control_type_name,
-+						   "AgsVIndicator\0");
-+	      }else if(!g_ascii_strncasecmp(controls,
-+					    "horizontal indicator\0",
-+					    19)){
-+		control_type_name = g_list_prepend(control_type_name,
-+						   "AgsHIndicator\0");
-+	      }else if(!g_ascii_strncasecmp(controls,
-+					    "spin button\0",
-+					    12)){
- 		control_type_name = g_list_prepend(control_type_name,
- 						   "GtkSpinButton\0");
- 	      }else if(!g_ascii_strncasecmp(controls,
-@@ -268,8 +284,8 @@
- 	  }
- 
- 	  /* free lists */
--	g_list_free(description_start);
--	g_list_free(port_control_start);
-+	  g_list_free(description_start);
-+	  g_list_free(port_control_start);
- 	}
-       }
-       
-@@ -339,72 +355,148 @@
- }
- 
- void
--ags_line_peak_run_post_callback(AgsRecall *peak_channel_run,
--				AgsLine *line)
-+ags_line_output_port_run_post_callback(AgsRecall *recall,
-+				       AgsLine *line)
- {
-   GtkWidget *child;
- 
--  AgsPort *port;
--
--  AgsMutexManager *mutex_manager;
--  AgsTaskThread *task_thread;
--
-   GList *list, *list_start;
--
--  gdouble peak;
--
--  GValue value = {0,};
--
--  pthread_mutex_t *application_mutex;
--  pthread_mutex_t *channel_mutex;
--
-+  
-   /* lock gdk threads */
-   gdk_threads_enter();
--
--  mutex_manager = ags_mutex_manager_get_instance();
--  application_mutex = ags_mutex_manager_get_application_mutex(mutex_manager);
-   
-   list_start = 
-     list = gtk_container_get_children((GtkContainer *) AGS_LINE(line)->expander->table);
- 
-+  /* check members */
-   while(list != NULL){
-     if(AGS_IS_LINE_MEMBER(list->data) &&
--       AGS_LINE_MEMBER(list->data)->widget_type == AGS_TYPE_VINDICATOR){
-+       (AGS_LINE_MEMBER(list->data)->widget_type == AGS_TYPE_VINDICATOR ||
-+	AGS_LINE_MEMBER(list->data)->widget_type == AGS_TYPE_HINDICATOR ||
-+	AGS_LINE_MEMBER(list->data)->widget_type == AGS_TYPE_LED)){
-+      AgsLineMember *line_member;
-       GtkAdjustment *adjustment;
- 
--      child = GTK_BIN(list->data)->child;
-+      AgsPort *current;
-+	
-+      gdouble average_peak;
-+      gdouble lower, upper;
-+      gdouble range;
-+      gdouble peak;
- 
--      /* get port */
--      pthread_mutex_lock(application_mutex);
-+      GValue value = {0,};
- 
--      channel_mutex = ags_mutex_manager_lookup(mutex_manager,
--					       (GObject *) line->channel);
-+      line_member = AGS_LINE_MEMBER(list->data);
-+      child = GTK_BIN(line_member)->child;
-+      
-+      average_peak = 0.0;
-       
--      pthread_mutex_unlock(application_mutex);
-+      /* play port */
-+      current = line_member->port;
- 
--      pthread_mutex_lock(channel_mutex);
-+      if(current == NULL){
-+	list = list->next;
-+	
-+	continue;
-+      }
-+	
-+      /* check if output port and specifier matches */
-+      pthread_mutex_lock(current->mutex);
-       
--      port = AGS_PEAK_CHANNEL(AGS_RECALL_CHANNEL_RUN(peak_channel_run)->recall_channel)->peak;
-+      if((AGS_PORT_IS_OUTPUT & (current->flags)) == 0 ||
-+	 current->port_descriptor == NULL ||
-+	 g_ascii_strcasecmp(current->specifier,
-+			    line_member->specifier)){
-+	pthread_mutex_unlock(current->mutex);
-+	
-+	list = list->next;
-+	
-+	continue;
-+      }
- 
--      pthread_mutex_unlock(channel_mutex);
-+      /* lower and upper */
-+      lower = g_value_get_float(AGS_PORT_DESCRIPTOR(current->port_descriptor)->lower_value);
-+      upper = g_value_get_float(AGS_PORT_DESCRIPTOR(current->port_descriptor)->upper_value);
-+      
-+      pthread_mutex_unlock(current->mutex);
- 
--      /* get peak */
--      g_value_init(&value, G_TYPE_DOUBLE);
--      ags_port_safe_read(port,
-+      /* get range */
-+      if(line_member->conversion != NULL){
-+	lower = ags_conversion_convert(line_member->conversion,
-+				       lower,
-+				       TRUE);
-+
-+	upper = ags_conversion_convert(line_member->conversion,
-+				       upper,
-+				       TRUE);
-+      }
-+      
-+      range = upper - lower;
-+      
-+      /* play port - read value */
-+      g_value_init(&value, G_TYPE_FLOAT);
-+      ags_port_safe_read(current,
- 			 &value);
--
--      peak = g_value_get_double(&value);
-+      
-+      peak = g_value_get_float(&value);
-       g_value_unset(&value);
- 
--      /* apply */
--      g_object_get(child,
--		   "adjustment\0", &adjustment,
--		   NULL);
-+      if(line_member->conversion != NULL){
-+	peak = ags_conversion_convert(line_member->conversion,
-+				      peak,
-+				      TRUE);
-+      }
-+      
-+      /* calculate peak */
-+      if(range == 0.0 ||
-+	 current->port_value_type == G_TYPE_BOOLEAN){
-+	if(peak != 0.0){
-+	  average_peak = 10.0;
-+	}
-+      }else{
-+	average_peak += ((1.0 / (range / peak)) * 10.0);
-+      }
- 
--      gtk_adjustment_set_value(adjustment,
--			       peak);
-+      /* recall port */
-+      current = line_member->recall_port;
- 
--      break;
-+      /* recall port - read value */
-+      g_value_init(&value, G_TYPE_FLOAT);
-+      ags_port_safe_read(current,
-+			 &value);
-+      
-+      peak = g_value_get_float(&value);
-+      g_value_unset(&value);
-+
-+      if(line_member->conversion != NULL){
-+	peak = ags_conversion_convert(line_member->conversion,
-+				      peak,
-+				      TRUE);
-+      }
-+
-+      /* calculate peak */
-+      if(range == 0.0 ||
-+	 current->port_value_type == G_TYPE_BOOLEAN){
-+	if(peak != 0.0){
-+	  average_peak = 10.0;
-+	}
-+      }else{
-+	average_peak += ((1.0 / (range / peak)) * 10.0);
-+      }
-+      
-+      /* apply */
-+      if(AGS_IS_LED(child)){
-+	if(average_peak != 0.0){
-+	  ags_led_set_active(child);
-+	}
-+      }else{
-+	g_object_get(child,
-+		     "adjustment\0", &adjustment,
-+		     NULL);
-+	
-+	gtk_adjustment_set_value(adjustment,
-+				 average_peak);
-+      }
-     }
-     
-     list = list->next;
-@@ -423,27 +515,63 @@
-   AgsChannel *channel;
-   AgsPlayback *playback;
-   AgsChannel *next_pad;
-+  AgsRecallID *match_recall_id;
-+
-+  AgsMutexManager *mutex_manager;
- 
-   gboolean all_done;
- 
-+  pthread_mutex_t *application_mutex;
-+  pthread_mutex_t *channel_mutex;
-+
-+  mutex_manager = ags_mutex_manager_get_instance();
-+  application_mutex = ags_mutex_manager_get_application_mutex(mutex_manager);
-+
-   gdk_threads_enter();
-   
-+  /* retrieve channel */
-   channel = AGS_PAD(AGS_LINE(line)->pad)->channel;
-+
-+  /* retrieve channel mutex */
-+  pthread_mutex_lock(application_mutex);
-+
-+  channel_mutex = ags_mutex_manager_lookup(mutex_manager,
-+					   (GObject *) channel);
-+
-+  pthread_mutex_unlock(application_mutex);
-+
-+  /* get next pad */
-+  pthread_mutex_lock(channel_mutex);
-+
-   next_pad = channel->next_pad;
- 
-+  pthread_mutex_unlock(channel_mutex);
-+
-   all_done = TRUE;
- 
-   while(channel != next_pad){
-+    pthread_mutex_lock(channel_mutex);
-+
-     playback = AGS_PLAYBACK(channel->playback);
--    
--    if(playback->recall_id[0] != NULL){
-+    match_recall_id = playback->recall_id[0];
-+		
-+    pthread_mutex_unlock(channel_mutex);
-+
-+    /* check if pending */
-+    if(match_recall_id != NULL){
-       all_done = FALSE;
-       break;
-     }
--    
-+
-+    /* iterate */
-+    pthread_mutex_lock(channel_mutex);
-+
-     channel = channel->next;
-+
-+    pthread_mutex_unlock(channel_mutex);
-   }
- 
-+  /* toggle play button if all playback done */
-   if(all_done){
-     AgsPad *pad;
- 
---- a/ags/X/ags_line_callbacks.h
-+++ b/ags/X/ags_line_callbacks.h
-@@ -45,8 +45,8 @@
- 			      AgsLine *line);
- 
- /* AgsRecall - recall */
--void ags_line_peak_run_post_callback(AgsRecall *peak_channel,
--				     AgsLine *line);
-+void ags_line_output_port_run_post_callback(AgsRecall *recall,
-+					    AgsLine *line);
- 
- void ags_line_copy_pattern_done(AgsRecall *recall,
- 				AgsLine *line);
---- a/ags/X/ags_line.h
-+++ b/ags/X/ags_line.h
-@@ -72,6 +72,8 @@
-   AgsExpander *expander;
- 
-   GtkWidget *indicator;
-+
-+  GList *queued_drawing;
- };
- 
- struct _AgsLineClass
---- a/ags/X/ags_line_member.c
-+++ b/ags/X/ags_line_member.c
-@@ -32,6 +32,8 @@
- 
- #include <ags/audio/thread/ags_audio_loop.h>
- 
-+#include <ags/widget/ags_led.h>
-+#include <ags/widget/ags_hindicator.h>
- #include <ags/widget/ags_dial.h>
- 
- #include <ags/X/ags_window.h>
-@@ -553,7 +555,10 @@
- 	gtk_toggle_button_set_active((GtkToggleButton *) new_child,
- 				     active);
-       }else{
--	g_warning("ags_line_member_set_property() - unknown child type %s\0", g_type_name(widget_type));
-+	if(!(AGS_IS_INDICATOR(new_child) ||
-+	     AGS_IS_LED(new_child))){
-+	  g_warning("ags_line_member_set_property() - unknown child type %s\0", g_type_name(widget_type));
-+	}
-       }
- 
-       /* add */
-@@ -1016,9 +1021,17 @@
- 			   ((guint *) port_data)[0]);
-       }else if(port->port_value_type == G_TYPE_FLOAT){
- 	gfloat val;
--	  
--	val = ((gdouble *) port_data)[0];
--	  
-+	
-+	if(GTK_IS_TOGGLE_BUTTON(gtk_bin_get_child((GtkBin *) line_member))){
-+	  if(((gboolean *) port_data)[0]){
-+	    val = 1.0;
-+	  }else{
-+	    val = 0.0;
-+	  }
-+	}else{
-+	  val = ((gdouble *) port_data)[0];
-+	}
-+
- 	if(line_member->conversion != NULL){
- 	  gfloat upper, lower, range, step;
- 	  gfloat c_upper, c_lower, c_range;
-@@ -1081,14 +1094,21 @@
- 
- 	g_value_init(&value,
- 		     G_TYPE_FLOAT);
--
- 	g_value_set_float(&value,
--			  (gfloat) ((gdouble *) port_data)[0]);
-+			  (gfloat) val);
-       }else if(port->port_value_type == G_TYPE_DOUBLE){
- 	gdouble val;
--	  
--	val = ((gdouble *) port_data)[0];
--	  
-+
-+	if(GTK_IS_TOGGLE_BUTTON(gtk_bin_get_child((GtkBin *) line_member))){
-+	  if(((gboolean *) port_data)[0]){
-+	    val = 1.0;
-+	  }else{
-+	    val = 0.0;
-+	  }
-+	}else{
-+	  val = ((gdouble *) port_data)[0];
-+	}
-+	
- 	if(line_member->conversion != NULL){
- 	  gdouble upper, lower, range, step;
- 	  gdouble c_upper, c_lower, c_range;
-@@ -1154,7 +1174,7 @@
- 		     G_TYPE_DOUBLE);
- 
- 	g_value_set_double(&value,
--			   ((gdouble *) port_data)[0]);
-+			   val);
-       }
-     }else{
-       if(port->port_value_type == G_TYPE_OBJECT){
---- a/ags/X/ags_lv2_browser.c
-+++ b/ags/X/ags_lv2_browser.c
-@@ -355,6 +355,58 @@
- }
- 
- /**
-+ * ags_lv2_browser_combo_box_output_boolean_controls_new:
-+ *
-+ * Creates a #GtkComboBox containing suitable widgets as controls.
-+ *
-+ * Returns: a new #GtkComboBox
-+ *
-+ * Since: 0.7.128
-+ */
-+GtkWidget*
-+ags_lv2_browser_combo_box_output_boolean_controls_new()
-+{
-+  GtkComboBoxText *combo_box;
-+
-+  combo_box = (GtkComboBoxText *) gtk_combo_box_text_new();
-+
-+  gtk_combo_box_text_append_text(combo_box,
-+				 "led\0");
-+
-+  gtk_combo_box_set_active((GtkComboBox *) combo_box,
-+			   1);
-+
-+  return((GtkWidget *) combo_box);
-+}
-+
-+/**
-+ * ags_lv2_browser_combo_box_controls_new:
-+ *
-+ * Creates a #GtkComboBox containing suitable widgets as controls.
-+ *
-+ * Returns: a new #GtkComboBox
-+ *
-+ * Since: 0.7.128
-+ */
-+GtkWidget*
-+ags_lv2_browser_combo_box_output_controls_new()
-+{
-+  GtkComboBoxText *combo_box;
-+
-+  combo_box = (GtkComboBoxText *) gtk_combo_box_text_new();
-+
-+  gtk_combo_box_text_append_text(combo_box,
-+				 "vertical indicator\0");
-+  gtk_combo_box_text_append_text(combo_box,
-+				 "horizontal indicator\0");
-+
-+  gtk_combo_box_set_active((GtkComboBox *) combo_box,
-+			   1);
-+
-+  return((GtkWidget *) combo_box);
-+}
-+
-+/**
-  * ags_lv2_browser_combo_box_boolean_controls_new:
-  *
-  * Creates a #GtkComboBox containing suitable widgets as controls.
---- a/ags/X/ags_lv2_browser_callbacks.c
-+++ b/ags/X/ags_lv2_browser_callbacks.c
-@@ -160,15 +160,29 @@
- 				y, y + 1);
-       
-       if((AGS_PORT_DESCRIPTOR_TOGGLED & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
--	gtk_table_attach_defaults(table,
--				  GTK_WIDGET(ags_lv2_browser_combo_box_boolean_controls_new()),
--				  1, 2,
--				  y, y + 1);
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  gtk_table_attach_defaults(table,
-+				    GTK_WIDGET(ags_lv2_browser_combo_box_output_boolean_controls_new()),
-+				    1, 2,
-+				    y, y + 1);
-+	}else{
-+	  gtk_table_attach_defaults(table,
-+				    GTK_WIDGET(ags_lv2_browser_combo_box_boolean_controls_new()),
-+				    1, 2,
-+				    y, y + 1);
-+	}
-       }else{
--	gtk_table_attach_defaults(table,
--				  GTK_WIDGET(ags_lv2_browser_combo_box_controls_new()),
--				  1, 2,
--				  y, y + 1);
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  gtk_table_attach_defaults(table,
-+				    GTK_WIDGET(ags_lv2_browser_combo_box_output_controls_new()),
-+				    1, 2,
-+				    y, y + 1);
-+	}else{
-+	  gtk_table_attach_defaults(table,
-+				    GTK_WIDGET(ags_lv2_browser_combo_box_controls_new()),
-+				    1, 2,
-+				    y, y + 1);
-+	}
-       }
- 	
-       y++;
---- a/ags/X/ags_lv2_browser.h
-+++ b/ags/X/ags_lv2_browser.h
-@@ -56,8 +56,12 @@
- gchar* ags_lv2_browser_get_plugin_filename(AgsLv2Browser *lv2_browser);
- gchar* ags_lv2_browser_get_plugin_effect(AgsLv2Browser *lv2_browser);
- 
-+GtkWidget* ags_lv2_browser_combo_box_output_boolean_controls_new();
-+GtkWidget* ags_lv2_browser_combo_box_output_controls_new();
-+
- GtkWidget* ags_lv2_browser_combo_box_boolean_controls_new();
- GtkWidget* ags_lv2_browser_combo_box_controls_new();
-+
- GtkWidget* ags_lv2_browser_preview_new();
- 
- AgsLv2Browser* ags_lv2_browser_new();
---- a/ags/X/machine/ags_mixer_input_line.c
-+++ b/ags/X/machine/ags_mixer_input_line.c
-@@ -62,7 +62,7 @@
- static gpointer ags_mixer_input_line_parent_class = NULL;
- static AgsConnectableInterface *ags_mixer_input_line_parent_connectable_interface;
- 
--extern GHashTable *ags_indicator_queue_draw;
-+extern GHashTable *ags_line_indicator_queue_draw;
- 
- GType
- ags_mixer_input_line_get_type()
-@@ -145,7 +145,7 @@
- 		   1, 1);
-   widget = gtk_bin_get_child(GTK_BIN(line_member));
-   AGS_LINE(mixer_input_line)->indicator = widget;
--  g_hash_table_insert(ags_indicator_queue_draw,
-+  g_hash_table_insert(ags_line_indicator_queue_draw,
- 		      widget, ags_line_indicator_queue_draw_timeout);
-   g_timeout_add(1000 / 30, (GSourceFunc) ags_line_indicator_queue_draw_timeout, (gpointer) widget);
- 
-@@ -270,7 +270,7 @@
-     recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
- 
-     recall_handler->signal_name = "run-post\0";
--    recall_handler->callback = G_CALLBACK(ags_line_peak_run_post_callback);
-+    recall_handler->callback = G_CALLBACK(ags_line_output_port_run_post_callback);
-     recall_handler->data = (gpointer) line;
- 
-     ags_recall_add_handler(AGS_RECALL(play_peak_channel_run), recall_handler);
-@@ -286,7 +286,7 @@
-     recall_handler = (AgsRecallHandler *) malloc(sizeof(AgsRecallHandler));
- 
-     recall_handler->signal_name = "run-post\0";
--    recall_handler->callback = G_CALLBACK(ags_line_peak_run_post_callback);
-+    recall_handler->callback = G_CALLBACK(ags_line_output_port_run_post_callback);
-     recall_handler->data = (gpointer) line;
- 
-     ags_recall_add_handler(AGS_RECALL(recall_peak_channel_run), recall_handler);
---- a/ags/audio/ags_recall_dssi.c
-+++ b/ags/audio/ags_recall_dssi.c
-@@ -640,6 +640,12 @@
- 			       "port-value-type\0", G_TYPE_FLOAT,
- 			       NULL);
- 	current->flags |= AGS_PORT_USE_LADSPA_FLOAT;
-+
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  AGS_RECALL(recall_dssi)->flags |= AGS_RECALL_HAS_OUTPUT_PORT;
-+
-+	  current->flags |= AGS_PORT_IS_OUTPUT;
-+	}
- 	
- 	current->port_descriptor = port_descriptor->data;
- 	ags_recall_dssi_load_conversion(recall_dssi,
---- a/ags/audio/ags_recall_lv2.c
-+++ b/ags/audio/ags_recall_lv2.c
-@@ -440,10 +440,11 @@
-     return;
-   }
- 
--  //  g_message("load automation %x\0", recall);
-+  /* load automation */
-   ags_recall_load_automation(recall,
- 			     g_list_copy(recall->port));
- 
-+  /* call parent */
-   ags_recall_lv2_parent_connectable_interface->connect(connectable);
- }
- 
-@@ -767,7 +768,13 @@
- 			       "port-value-is-pointer\0", FALSE,
- 			       "port-value-type\0", G_TYPE_FLOAT,
- 			       NULL);
--
-+	
-+	if((AGS_PORT_DESCRIPTOR_OUTPUT & (AGS_PORT_DESCRIPTOR(port_descriptor->data)->flags)) != 0){
-+	  AGS_RECALL(recall_lv2)->flags |= AGS_RECALL_HAS_OUTPUT_PORT;
-+	  
-+	  current->flags |= AGS_PORT_IS_OUTPUT;
-+	}
-+	
- 	current->port_descriptor = port_descriptor->data;
- 	ags_recall_lv2_load_conversion(recall_lv2,
- 				       (GObject *) current,
---- a/ags/audio/recall/ags_peak_channel.c
-+++ b/ags/audio/recall/ags_peak_channel.c
-@@ -25,6 +25,8 @@
- #include <ags/object/ags_mutable.h>
- #include <ags/object/ags_plugin.h>
- 
-+#include <ags/plugin/ags_base_plugin.h>
-+
- #include <ags/audio/ags_audio.h>
- #include <ags/audio/ags_output.h>
- #include <ags/audio/ags_input.h>
-@@ -49,6 +51,8 @@
- void ags_peak_channel_set_ports(AgsPlugin *plugin, GList *port);
- void ags_peak_channel_finalize(GObject *gobject);
- 
-+static AgsPortDescriptor* ags_peak_channel_get_peak_port_descriptor();
-+
- /**
-  * SECTION:ags_peak_channel
-  * @short_description: peaks channel
-@@ -171,6 +175,8 @@
- ags_peak_channel_init(AgsPeakChannel *peak_channel)
- {
-   GList *port;
-+  
-+  AGS_RECALL(peak_channel)->flags |= AGS_RECALL_HAS_OUTPUT_PORT;
- 
-   AGS_RECALL(peak_channel)->name = "ags-peak\0";
-   AGS_RECALL(peak_channel)->version = AGS_RECALL_DEFAULT_VERSION;
-@@ -179,17 +185,25 @@
- 
-   port = NULL;
- 
-+  /* peak */
-   peak_channel->peak = g_object_new(AGS_TYPE_PORT,
--				     "plugin-name\0", ags_peak_channel_plugin_name,
--				     "specifier\0", ags_peak_channel_plugin_specifier[0],
--				     "control-port\0", ags_peak_channel_plugin_control_port[0],
--				     "port-value-is-pointer\0", FALSE,
--				     "port-value-type\0", G_TYPE_DOUBLE,
--				     "port-value-size\0", sizeof(gdouble),
--				     "port-value-length\0", 1,
--				     NULL);
--  peak_channel->peak->port_value.ags_port_double = FALSE;
-+				    "plugin-name\0", ags_peak_channel_plugin_name,
-+				    "specifier\0", ags_peak_channel_plugin_specifier[0],
-+				    "control-port\0", ags_peak_channel_plugin_control_port[0],
-+				    "port-value-is-pointer\0", FALSE,
-+				    "port-value-type\0", G_TYPE_FLOAT,
-+				    "port-value-size\0", sizeof(gfloat),
-+				    "port-value-length\0", 1,
-+				    NULL);
- 
-+  peak_channel->peak->flags |= AGS_PORT_IS_OUTPUT;
-+  
-+  peak_channel->peak->port_value.ags_port_float = FALSE;
-+  
-+  /* port descriptor */
-+  peak_channel->peak->port_descriptor = ags_peak_channel_get_peak_port_descriptor();
-+
-+  /* add to port */  
-   port = g_list_prepend(port, peak_channel->peak);
- 
-   /* set port */
-@@ -452,14 +466,14 @@
-     current_value = scale_precision * (atan(1.0 / 440.0) / sin(current_value / 22000.0));
-   }
-   
--  g_value_init(&value, G_TYPE_DOUBLE);
-+  g_value_init(&value, G_TYPE_FLOAT);
- 
-   if(current_value < 0.0){
-     current_value *= -1.0;
-   }
- 
--  g_value_set_double(&value,
--		     current_value);
-+  g_value_set_float(&value,
-+		    current_value);
- 
-   ags_port_safe_write(peak_channel->peak,
- 		      &value);
-@@ -469,6 +483,38 @@
-   free(buffer);
- }
- 
-+static AgsPortDescriptor*
-+ags_peak_channel_get_peak_port_descriptor()
-+{
-+  static AgsPortDescriptor *port_descriptor = NULL;
-+
-+  if(port_descriptor == NULL){
-+    port_descriptor = ags_port_descriptor_alloc();
-+
-+    port_descriptor->flags |= (AGS_PORT_DESCRIPTOR_INPUT |
-+			       AGS_PORT_DESCRIPTOR_CONTROL);
-+
-+    port_descriptor->port_index = 0;
-+
-+    /* range */
-+    g_value_init(port_descriptor->default_value,
-+		 G_TYPE_FLOAT);
-+    g_value_init(port_descriptor->lower_value,
-+		 G_TYPE_FLOAT);
-+    g_value_init(port_descriptor->upper_value,
-+		 G_TYPE_FLOAT);
-+
-+    g_value_set_float(port_descriptor->default_value,
-+		      0.0);
-+    g_value_set_float(port_descriptor->lower_value,
-+		      0.0);
-+    g_value_set_float(port_descriptor->upper_value,
-+		      10.0);
-+  }
-+  
-+  return(port_descriptor);
-+}
-+
- /**
-  * ags_peak_channel_new:
-  * @source: the #AgsChannel as source
---- a/ags/X/ags_bulk_member.c
-+++ b/ags/X/ags_bulk_member.c
-@@ -916,7 +916,15 @@
- 	}else if(port->port_value_type == G_TYPE_FLOAT){
- 	  gfloat val;
- 	  
--	  val = ((gdouble *) port_data)[0];
-+	  if(GTK_IS_TOGGLE_BUTTON(gtk_bin_get_child((GtkBin *) bulk_member))){
-+	    if(((gboolean *) port_data)[0]){
-+	      val = 1.0;
-+	    }else{
-+	      val = 0.0;
-+	    }
-+	  }else{
-+	    val = ((gdouble *) port_data)[0];
-+	  }
- 	  
- 	  if(bulk_member->conversion != NULL){
- 	    gfloat upper, lower, range, step;
-@@ -964,11 +972,19 @@
- 		       G_TYPE_FLOAT);
- 
- 	  g_value_set_float(&value,
--			     val);
-+			    val);
- 	}else if(port->port_value_type == G_TYPE_DOUBLE){
- 	  gdouble val;
- 	  
--	  val = ((gdouble *) port_data)[0];
-+	  if(GTK_IS_TOGGLE_BUTTON(gtk_bin_get_child((GtkBin *) bulk_member))){
-+	    if(((gboolean *) port_data)[0]){
-+	      val = 1.0;
-+	    }else{
-+	      val = 0.0;
-+	    }
-+	  }else{
-+	    val = ((gdouble *) port_data)[0];
-+	  }
- 	  
- 	  if(bulk_member->conversion != NULL){
- 	    gdouble upper, lower, range, step;
diff --git a/debian/patches/mangle-output-port.patch b/debian/patches/mangle-output-port.patch
deleted file mode 100644
index cfb1c61..0000000
--- a/debian/patches/mangle-output-port.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-Description: This is a wishlist patch. It introduces flag of recalls with appropriate
- output port availabel in order to get detected by generic callback of output
- widgets.
-Author: Joël Krähmann <jkraehemann at gmail.com>
-Applied-Upstream: 0.7.122.x, http://git.savannah.gnu.org/cgit/gsequencer.git
-Last-Update: 2017-02-02
---- a/ags/audio/ags_recall.h
-+++ b/ags/audio/ags_recall.h
-@@ -67,6 +67,7 @@
-   AGS_RECALL_PERSISTENT_NOTATION   = 1 << 19,
-   AGS_RECALL_SKIP_DEPENDENCIES     = 1 << 20,
-   AGS_RECALL_BULK_MODE             = 1 << 21,
-+  AGS_RECALL_HAS_OUTPUT_PORT       = 1 << 22,
- }AgsRecallFlags;
- 
- typedef enum{
---- a/ags/audio/ags_port.h
-+++ b/ags/audio/ags_port.h
-@@ -43,6 +43,7 @@
- typedef enum{
-   AGS_PORT_CONVERT_ALWAYS   =  1,
-   AGS_PORT_USE_LADSPA_FLOAT =  1 <<  1,
-+  AGS_PORT_IS_OUTPUT        =  1 <<  2,
- }AgsPortFlags;
- 
- struct _AgsPort
diff --git a/debian/patches/series b/debian/patches/series
index 7103ecc..8453e56 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,14 +1,9 @@
 fix-matrix-callbacks.patch
 fix-delay-audio.patch
 fix-matrix.patch
-improved-disable-output-port-automation.patch
-improved-enable-builtin-port-automation.patch
-improved-generic-output-widget.patch
 mangle-indicator-widget.patch
-mangle-output-port.patch
 fix-souncard-editor-callbacks.patch
 fix-export-thread.patch
-fix-gsequencer-main.patch
 fix-set-buffer-size.patch
 fix-set-samplerate.patch
 fix-record-midi-audio-run.patch

-- 
gsequencer packaging



More information about the pkg-multimedia-commits mailing list