diff --git a/ext/alsa/gstalsamixer.c b/ext/alsa/gstalsamixer.c
index 931d98f..1a6708e 100644
--- a/ext/alsa/gstalsamixer.c
+++ b/ext/alsa/gstalsamixer.c
@@ -42,6 +42,12 @@
 
 #include "gstalsamixer.h"
 
+static void gst_alsa_mixer_update_option (GstAlsaMixer * mixer,
+    GstAlsaMixerOptions * alsa_opts);
+static void gst_alsa_mixer_update_track (GstAlsaMixer * mixer,
+    GstAlsaMixerTrack * alsa_track);
+static int gst_alsa_mixer_handle_callback (snd_mixer_t * handle, unsigned int mask,
+    snd_mixer_elem_t * elem);
 
 /* First some utils, then the mixer implementation */
 static gboolean
@@ -74,6 +80,8 @@ gst_alsa_mixer_open (GstAlsaMixer * mixer)
     goto error;
   }
 
+  snd_mixer_set_callback_private (mixer->handle, mixer);
+  snd_mixer_set_callback (mixer->handle, gst_alsa_mixer_handle_callback);
 
   /* now get the device name, any of this is not fatal */
   g_free (mixer->cardname);
@@ -170,16 +178,79 @@ gst_alsa_mixer_find_master_mixer (GstAlsaMixer * mixer, snd_mixer_t * handle)
 }
 
 static void
+gst_alsa_mixer_update (GstAlsaMixer *mixer, snd_mixer_elem_t * elem)
+{
+  GList *item;
+
+  g_return_if_fail (mixer != NULL);
+
+  g_static_rec_mutex_lock (mixer->rec_mutex);
+
+  for (item = mixer->tracklist; item != NULL; item = item->next) {
+    if (GST_IS_ALSA_MIXER_TRACK (item->data)) {
+      if (elem && (GST_ALSA_MIXER_TRACK (item->data)->element != elem))
+        continue;
+
+      gst_alsa_mixer_update_track (mixer, GST_ALSA_MIXER_TRACK (item->data));
+    } else if (GST_IS_ALSA_MIXER_OPTIONS (item->data)) {
+      if (elem && (GST_ALSA_MIXER_OPTIONS (item->data)->element != elem))
+        continue;
+
+      gst_alsa_mixer_update_option (mixer, GST_ALSA_MIXER_OPTIONS (item->data));
+    }
+  }
+
+  g_static_rec_mutex_unlock (mixer->rec_mutex);
+}
+
+static int
+gst_alsa_mixer_elem_handle_callback (snd_mixer_elem_t * elem, unsigned int mask)
+{
+  GstAlsaMixer *mixer =
+      (GstAlsaMixer *) snd_mixer_elem_get_callback_private (elem);
+
+  GST_LOG ("ALSA elem cb");
+
+  g_return_val_if_fail (mixer != NULL, 1);
+
+  gst_alsa_mixer_update (mixer, elem);
+
+  return 0;
+}
+
+static int
+gst_alsa_mixer_handle_callback (snd_mixer_t * handle, unsigned int mask,
+    snd_mixer_elem_t * elem)
+{
+  GstAlsaMixer *mixer =
+      (GstAlsaMixer *) snd_mixer_get_callback_private (handle);
+
+  GST_LOG ("ALSA cb");
+
+  g_return_val_if_fail (mixer != NULL, 1);
+
+  /* Hopefully won't be call recursively and will handle pending elem events */
+  snd_mixer_handle_events (mixer->handle);
+
+  gst_alsa_mixer_update (mixer, elem);
+
+  return 0;
+}
+
+static void
 gst_alsa_mixer_ensure_track_list (GstAlsaMixer * mixer)
 {
   gint i, count;
   snd_mixer_elem_t *element, *master;
+  GList *item;
 
   g_return_if_fail (mixer->handle != NULL);
 
   if (mixer->tracklist)
     return;
 
+  g_static_rec_mutex_lock (mixer->rec_mutex);
+
   master = gst_alsa_mixer_find_master_mixer (mixer, mixer->handle);
 
   count = snd_mixer_get_count (mixer->handle);
@@ -287,8 +358,61 @@ gst_alsa_mixer_ensure_track_list (GstAlsaMixer * mixer)
 
     element = snd_mixer_elem_next (element);
   }
+
+  for (item = mixer->tracklist; item != NULL; item = item->next) {
+    snd_mixer_elem_t *temp;
+
+    if (GST_IS_ALSA_MIXER_OPTIONS (item->data))
+      temp = GST_ALSA_MIXER_OPTIONS (item->data)->element;
+    else
+      temp = GST_ALSA_MIXER_TRACK (item->data)->element;
+
+    snd_mixer_elem_set_callback (temp, gst_alsa_mixer_elem_handle_callback);
+    snd_mixer_elem_set_callback_private (temp, mixer);
+  }
+
+  g_static_rec_mutex_unlock (mixer->rec_mutex);
 }
 
+static void
+task_monitor_alsa (gpointer data) 
+{
+  struct pollfd *pfds;
+  unsigned int nfds, rnfds;
+  unsigned short revents;
+  GstAlsaMixer *mixer = (GstAlsaMixer *)data;
+  
+  g_static_rec_mutex_lock (mixer->rec_mutex);
+
+  nfds = snd_mixer_poll_descriptors_count (mixer->handle);
+  if (nfds <= 0) {
+    GST_ERROR ("snd_mixer_poll_descriptors_count <= 0: %d", nfds);
+    /* FIXME: sleep ? stop monitoring ? */
+    return;
+  }
+
+  pfds = g_newa (struct pollfd, nfds + 1);
+  rnfds = snd_mixer_poll_descriptors (mixer->handle, pfds, nfds);
+  g_assert (rnfds <= nfds);
+
+  pfds[rnfds].fd = mixer->pfd[0];
+  pfds[rnfds].events = POLLIN | POLLPRI | POLLHUP | POLLERR;
+  pfds[rnfds].revents = 0;
+
+  g_static_rec_mutex_unlock (mixer->rec_mutex);
+
+  GST_LOG ("task loop");
+  poll (pfds, rnfds + 1, -1);
+
+  g_static_rec_mutex_lock (mixer->rec_mutex);
+
+  snd_mixer_poll_descriptors_revents (mixer->handle, pfds, nfds, &revents);
+  if (revents & POLLIN || revents & POLLPRI) {
+    snd_mixer_handle_events (mixer->handle);
+  }
+
+  g_static_rec_mutex_unlock (mixer->rec_mutex);
+}
 
 /* API */
 
@@ -301,12 +425,28 @@ gst_alsa_mixer_new (const char *device, GstAlsaMixerDirection dir)
 
   ret = g_new0 (GstAlsaMixer, 1);
 
+  if (pipe (ret->pfd) == -1)
+    goto error;
+
+  ret->rec_mutex = g_new (GStaticRecMutex, 1);
+  g_static_rec_mutex_init (ret->rec_mutex);
+
+  ret->task_mutex = g_new (GStaticRecMutex, 1);
+  g_static_rec_mutex_init (ret->task_mutex);
+
+  ret->task = gst_task_create (task_monitor_alsa, ret);
+  gst_task_set_lock (ret->task, ret->task_mutex);
+
   ret->device = g_strdup (device);
   ret->dir = dir;
 
   if (!gst_alsa_mixer_open (ret))
     goto error;
 
+  if (gst_task_start (ret->task) == FALSE) {
+    GST_WARNING ("Could not start alsamixer task");
+  }
+
   return ret;
 
   /* ERRORS */
@@ -322,6 +462,40 @@ gst_alsa_mixer_free (GstAlsaMixer * mixer)
 {
   g_return_if_fail (mixer != NULL);
 
+  if (mixer->task) {
+    if (write (mixer->pfd[1], "stop", 5) <= 0) {
+      GST_ERROR ("Cannot send ""stop"" to alsamixer task");
+      close (mixer->pfd[1]);
+      mixer->pfd[1] = -1;
+    } 
+
+    if (gst_task_join (mixer->task) == FALSE) {
+      GST_ERROR ("Cannot join alsamixer task");
+    } 
+
+    gst_object_unref (mixer->task);
+    mixer->task = NULL;
+  }
+
+  g_static_rec_mutex_free (mixer->task_mutex);
+  g_free (mixer->task_mutex);
+  mixer->task_mutex = NULL;
+
+  if (mixer->pfd[0] > 0) {
+    close (mixer->pfd[0]);
+    mixer->pfd[0] = -1;
+  }
+
+  if (mixer->pfd[1] > 0) {
+    close (mixer->pfd[1]);
+    mixer->pfd[1] = -1;
+  }
+
+  if (mixer->interface) {
+    g_object_unref (G_OBJECT (mixer->interface));
+    mixer->interface = NULL;
+  }
+
   if (mixer->device) {
     g_free (mixer->device);
     mixer->device = NULL;
@@ -343,6 +517,10 @@ gst_alsa_mixer_free (GstAlsaMixer * mixer)
     mixer->handle = NULL;
   }
 
+  g_static_rec_mutex_free (mixer->rec_mutex);
+  g_free (mixer->rec_mutex);
+  mixer->rec_mutex = NULL;
+
   g_free (mixer);
 }
 
@@ -356,16 +534,6 @@ gst_alsa_mixer_list_tracks (GstAlsaMixer * mixer)
   return (const GList *) mixer->tracklist;
 }
 
-static void
-gst_alsa_mixer_update (GstAlsaMixer * mixer, GstAlsaMixerTrack * alsa_track)
-{
-  snd_mixer_handle_events (mixer->handle);
-
-  if (alsa_track)
-    gst_alsa_mixer_track_update (alsa_track);
-}
-
-
 void
 gst_alsa_mixer_get_volume (GstAlsaMixer * mixer, GstMixerTrack * track,
     gint * volumes)
@@ -375,7 +543,7 @@ gst_alsa_mixer_get_volume (GstAlsaMixer * mixer, GstMixerTrack * track,
 
   g_return_if_fail (mixer->handle != NULL);
 
-  gst_alsa_mixer_update (mixer, alsa_track);
+  gst_alsa_mixer_track_update (alsa_track);
 
   if (track->flags & GST_MIXER_TRACK_OUTPUT) {  /* return playback volume */
 
@@ -420,7 +588,7 @@ gst_alsa_mixer_set_volume (GstAlsaMixer * mixer, GstMixerTrack * track,
 
   g_return_if_fail (mixer->handle != NULL);
 
-  gst_alsa_mixer_update (mixer, alsa_track);
+  gst_alsa_mixer_track_update (alsa_track);
 
   if (track->flags & GST_MIXER_TRACK_OUTPUT) {
 
@@ -461,7 +629,7 @@ gst_alsa_mixer_set_mute (GstAlsaMixer * mixer, GstMixerTrack * track,
 
   g_return_if_fail (mixer->handle != NULL);
 
-  gst_alsa_mixer_update (mixer, alsa_track);
+  gst_alsa_mixer_track_update (alsa_track);
 
   if (!!(mute) == !!(track->flags & GST_MIXER_TRACK_MUTE))
     return;
@@ -509,7 +677,7 @@ gst_alsa_mixer_set_record (GstAlsaMixer * mixer,
 
   g_return_if_fail (mixer->handle != NULL);
 
-  gst_alsa_mixer_update (mixer, alsa_track);
+  gst_alsa_mixer_track_update (alsa_track);
 
   if (!!(record) == !!(track->flags & GST_MIXER_TRACK_RECORD))
     return;
@@ -536,7 +704,7 @@ gst_alsa_mixer_set_record (GstAlsaMixer * mixer,
 
           if (item_alsa_track->alsa_flags & GST_ALSA_MIXER_TRACK_CSWITCH_EXCL &&
               item_alsa_track->capture_group == alsa_track->capture_group) {
-            gst_alsa_mixer_update (mixer, item_alsa_track);
+            gst_alsa_mixer_track_update (item_alsa_track);
           }
         }
       }
@@ -562,8 +730,6 @@ gst_alsa_mixer_set_option (GstAlsaMixer * mixer,
 
   g_return_if_fail (mixer->handle != NULL);
 
-  gst_alsa_mixer_update (mixer, NULL);
-
   for (item = opts->values; item != NULL; item = item->next, n++) {
     if (!strcmp (item->data, value)) {
       idx = n;
@@ -585,11 +751,60 @@ gst_alsa_mixer_get_option (GstAlsaMixer * mixer, GstMixerOptions * opts)
 
   g_return_val_if_fail (mixer->handle != NULL, NULL);
 
-  gst_alsa_mixer_update (mixer, NULL);
-
   ret = snd_mixer_selem_get_enum_item (alsa_opts->element, 0, &idx);
   if (ret == 0)
     return g_list_nth_data (opts->values, idx);
   else
     return snd_strerror (ret);  /* feeble attempt at error handling */
 }
+
+static void
+gst_alsa_mixer_update_option (GstAlsaMixer * mixer,
+    GstAlsaMixerOptions * alsa_opts)
+{
+  gint ret;
+  guint idx;
+  /* const */ gchar *option;
+
+  if (mixer->interface == NULL) {
+    GST_WARNING ("Cannot send update notifications, no GstMixer * given");
+    return;
+  }
+
+  ret = snd_mixer_selem_get_enum_item (alsa_opts->element, 0, &idx);
+  if (ret == 0) {
+    option = g_list_nth_data (GST_MIXER_OPTIONS (alsa_opts)->values, idx);
+    gst_mixer_option_changed (mixer->interface, GST_MIXER_OPTIONS (alsa_opts),
+			      option);
+  }
+}
+
+static void
+gst_alsa_mixer_update_track (GstAlsaMixer * mixer,
+    GstAlsaMixerTrack * alsa_track)
+{
+  GstMixerTrack *track = (GstMixerTrack *) alsa_track;
+
+  if (mixer->interface == NULL) {
+    GST_WARNING ("Cannot send update notifications, no GstMixer * given");
+    return;
+  }
+
+  gst_alsa_mixer_track_update (alsa_track);
+
+  gst_mixer_record_toggled (mixer->interface, track,
+      GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_RECORD));
+  gst_mixer_mute_toggled (mixer->interface, track,
+      GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MUTE));
+  gst_mixer_volume_changed (mixer->interface, track, alsa_track->volumes);
+}
+
+/* utility function for gstalsamixerelement to set the interface */
+void		
+_gst_alsa_mixer_set_interface (GstAlsaMixer * mixer, GstMixer * interface)
+{
+  g_return_if_fail (mixer != NULL && mixer->interface == NULL);
+  g_return_if_fail (interface != NULL);
+
+  mixer->interface = g_object_ref (G_OBJECT (interface));
+}
diff --git a/ext/alsa/gstalsamixer.h b/ext/alsa/gstalsamixer.h
index 6c9eb1e..e29b2ef 100644
--- a/ext/alsa/gstalsamixer.h
+++ b/ext/alsa/gstalsamixer.h
@@ -52,6 +52,13 @@ struct _GstAlsaMixer
 
   snd_mixer_t *         handle;
 
+  GstTask *		task;
+  GStaticRecMutex *	task_mutex;
+  GStaticRecMutex *	rec_mutex;
+
+  int			pfd[2];
+
+  GstMixer *		interface;
   gchar *               device;
   gchar *               cardname;
 
@@ -81,7 +88,8 @@ void            gst_alsa_mixer_set_option       (GstAlsaMixer * mixer,
                                                  gchar * value);
 const gchar*    gst_alsa_mixer_get_option       (GstAlsaMixer * mixer,
                                                  GstMixerOptions * opts);
-
+void		_gst_alsa_mixer_set_interface   (GstAlsaMixer * mixer,
+						 GstMixer * interface);
 
 #define GST_IMPLEMENT_ALSA_MIXER_METHODS(Type, interface_as_function)           \
 static gboolean                                                                 \
diff --git a/ext/alsa/gstalsamixerelement.c b/ext/alsa/gstalsamixerelement.c
index 75d5b4a..be8040e 100644
--- a/ext/alsa/gstalsamixerelement.c
+++ b/ext/alsa/gstalsamixerelement.c
@@ -214,6 +214,7 @@ gst_alsa_mixer_element_change_state (GstElement * element,
         this->mixer = gst_alsa_mixer_new (this->device, GST_ALSA_MIXER_ALL);
         if (!this->mixer)
           goto open_failed;
+	_gst_alsa_mixer_set_interface (this->mixer, GST_MIXER (element));
       }
       break;
     default:
diff --git a/ext/alsa/gstalsamixertrack.c b/ext/alsa/gstalsamixertrack.c
index d7b8a93..146c7bc 100644
--- a/ext/alsa/gstalsamixertrack.c
+++ b/ext/alsa/gstalsamixertrack.c
@@ -239,7 +239,27 @@ gst_alsa_mixer_track_update (GstAlsaMixerTrack * alsa_track)
   gint i;
   gint audible = !(track->flags & GST_MIXER_TRACK_MUTE);
 
-  /* Any updates in flags? */
+  if (alsa_track_has_cap (alsa_track, GST_ALSA_MIXER_TRACK_PVOLUME)) {
+    /* update playback volume */
+    for (i = 0; i < track->num_channels; i++) {
+      long vol = 0;
+
+      snd_mixer_selem_get_playback_volume (alsa_track->element, i, &vol);
+      alsa_track->volumes[i] = (gint) vol;
+    }
+  }
+
+  if (alsa_track_has_cap (alsa_track, GST_ALSA_MIXER_TRACK_CVOLUME)) {
+    /* update capture volume */
+    for (i = 0; i < track->num_channels; i++) {
+      long vol = 0;
+      
+      snd_mixer_selem_get_capture_volume (alsa_track->element, i, &vol);
+      alsa_track->volumes[i] = (gint) vol;
+    }
+  }
+  
+ /* Any updates in flags? */
   if (alsa_track_has_cap (alsa_track, GST_ALSA_MIXER_TRACK_PSWITCH)) {
     int v = 0;
 
diff --git a/gst-libs/gst/interfaces/mixer.c b/gst-libs/gst/interfaces/mixer.c
index 116bab2..ec66b53 100644
--- a/gst-libs/gst/interfaces/mixer.c
+++ b/gst-libs/gst/interfaces/mixer.c
@@ -31,19 +31,8 @@
  * @short_description: Interface for elements that provide mixer operations
  */
 
-enum
-{
-  SIGNAL_MUTE_TOGGLED,
-  SIGNAL_RECORD_TOGGLED,
-  SIGNAL_VOLUME_CHANGED,
-  SIGNAL_OPTION_CHANGED,
-  LAST_SIGNAL
-};
-
 static void gst_mixer_class_init (GstMixerClass * klass);
 
-static guint gst_mixer_signals[LAST_SIGNAL] = { 0 };
-
 GType
 gst_mixer_get_type (void)
 {
@@ -74,41 +63,6 @@ gst_mixer_get_type (void)
 static void
 gst_mixer_class_init (GstMixerClass * klass)
 {
-  static gboolean initialized = FALSE;
-
-  if (!initialized) {
-    gst_mixer_signals[SIGNAL_RECORD_TOGGLED] =
-        g_signal_new ("record-toggled",
-        GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
-        G_STRUCT_OFFSET (GstMixerClass, record_toggled),
-        NULL, NULL,
-        gst_interfaces_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
-        GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
-    gst_mixer_signals[SIGNAL_MUTE_TOGGLED] =
-        g_signal_new ("mute-toggled",
-        GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
-        G_STRUCT_OFFSET (GstMixerClass, mute_toggled),
-        NULL, NULL,
-        gst_interfaces_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2,
-        GST_TYPE_MIXER_TRACK, G_TYPE_BOOLEAN);
-    gst_mixer_signals[SIGNAL_VOLUME_CHANGED] =
-        g_signal_new ("volume-changed",
-        GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
-        G_STRUCT_OFFSET (GstMixerClass, volume_changed),
-        NULL, NULL,
-        gst_interfaces_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
-        GST_TYPE_MIXER_TRACK, G_TYPE_POINTER);
-    gst_mixer_signals[SIGNAL_OPTION_CHANGED] =
-        g_signal_new ("option-changed",
-        GST_TYPE_MIXER, G_SIGNAL_RUN_LAST,
-        G_STRUCT_OFFSET (GstMixerClass, option_changed),
-        NULL, NULL,
-        gst_interfaces_marshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2,
-        GST_TYPE_MIXER_OPTIONS, G_TYPE_STRING);
-
-    initialized = TRUE;
-  }
-
   klass->mixer_type = GST_MIXER_SOFTWARE;
 
   /* default virtual functions */
@@ -316,50 +270,100 @@ gst_mixer_get_option (GstMixer * mixer, GstMixerOptions * opts)
 void
 gst_mixer_mute_toggled (GstMixer * mixer, GstMixerTrack * track, gboolean mute)
 {
+  GstStructure *s;
+  GstMessage *m;
+
   g_return_if_fail (mixer != NULL);
   g_return_if_fail (track != NULL);
 
-  g_signal_emit (G_OBJECT (mixer),
-      gst_mixer_signals[SIGNAL_MUTE_TOGGLED], 0, track, mute);
+  s = gst_structure_new ("mute-toggled", 
+			 "mute", G_TYPE_BOOLEAN, mute, 
+			 "track", GST_TYPE_MIXER_TRACK, track,
+			 NULL);
 
-  g_signal_emit_by_name (G_OBJECT (track), "mute_toggled", mute);
+  m = gst_message_new_element (GST_OBJECT (mixer), s);
+  if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) {
+    GST_WARNING ("This element has no bus, therefore no message sent!");
+  }
 }
 
 void
 gst_mixer_record_toggled (GstMixer * mixer,
     GstMixerTrack * track, gboolean record)
 {
+  GstStructure *s;
+  GstMessage *m;
+
   g_return_if_fail (mixer != NULL);
   g_return_if_fail (track != NULL);
 
-  g_signal_emit (G_OBJECT (mixer),
-      gst_mixer_signals[SIGNAL_RECORD_TOGGLED], 0, track, record);
+  s = gst_structure_new ("record-toggled", 
+			 "record", G_TYPE_BOOLEAN, record, 
+			 "track", GST_TYPE_MIXER_TRACK, track,
+			 NULL);
 
-  g_signal_emit_by_name (G_OBJECT (track), "record_toggled", record);
+  m = gst_message_new_element (GST_OBJECT (mixer), s);
+  if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) {
+    GST_WARNING ("This element has no bus, therefore no message sent!");
+  }
 }
 
 void
 gst_mixer_volume_changed (GstMixer * mixer,
     GstMixerTrack * track, gint * volumes)
 {
+  GstStructure *s;
+  GstMessage *m;
+  GValue l = { 0, };
+  GValue v = { 0, };
+  gint i;
+  GArray *array;
+
   g_return_if_fail (mixer != NULL);
   g_return_if_fail (track != NULL);
 
-  g_signal_emit (G_OBJECT (mixer),
-      gst_mixer_signals[SIGNAL_VOLUME_CHANGED], 0, track, volumes);
+  g_value_init (&l, GST_TYPE_LIST);
+  array = g_value_peek_pointer (&l);
+  g_return_if_fail (array != NULL);
+
+  g_value_init (&v, G_TYPE_INT);
+
+  /* FIXME 0.11: pass track->num_channels to the function */
+  for (i = 0; i < track->num_channels; ++i) {
+    g_value_set_int (&v, volumes[i]);
+    g_array_append_val (array, v);
+  }
+  
+  s = gst_structure_new ("volume-changed", 
+			 "track", GST_TYPE_MIXER_TRACK, track,
+			 "volumes", GST_TYPE_LIST, array,
+			 NULL);
+
+  g_value_unset (&l);
 
-  g_signal_emit_by_name (G_OBJECT (track), "volume_changed", volumes);
+  m = gst_message_new_element (GST_OBJECT (mixer), s);
+  if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) {
+    GST_WARNING ("This element has no bus, therefore no message sent!");
+  }
 }
 
 void
 gst_mixer_option_changed (GstMixer * mixer,
     GstMixerOptions * opts, gchar * value)
 {
+  GstStructure *s;
+  GstMessage *m;
+
   g_return_if_fail (mixer != NULL);
   g_return_if_fail (opts != NULL);
 
-  g_signal_emit (G_OBJECT (mixer),
-      gst_mixer_signals[SIGNAL_OPTION_CHANGED], 0, opts, value);
+  s = gst_structure_new ("option-changed", 
+			 "value", G_TYPE_STRING, value,
+			 "options", GST_TYPE_MIXER_OPTIONS, opts,
+			 NULL);
 
-  g_signal_emit_by_name (G_OBJECT (opts), "value_changed", value);
+  m = gst_message_new_element (GST_OBJECT (mixer), s);
+  if (gst_element_post_message (GST_ELEMENT (mixer), m) == FALSE) {
+    GST_WARNING ("This element has no bus, therefore no message sent!");
+  }
 }
diff --git a/gst-libs/gst/interfaces/mixer.h b/gst-libs/gst/interfaces/mixer.h
index dde73ab..23f91c7 100644
--- a/gst-libs/gst/interfaces/mixer.h
+++ b/gst-libs/gst/interfaces/mixer.h
@@ -74,8 +74,8 @@ struct _GstMixerClass {
   void           (* set_record)    (GstMixer      *mixer,
                                     GstMixerTrack *track,
                                     gboolean       record);
-
-  /* signals */
+#ifndef GST_DISABLE_DEPRECATED
+  /* signals (deprecated) */
   void (* mute_toggled)   (GstMixer      *mixer,
                            GstMixerTrack *channel,
                            gboolean       mute);
@@ -85,6 +85,7 @@ struct _GstMixerClass {
   void (* volume_changed) (GstMixer      *mixer,
                            GstMixerTrack *channel,
                            gint          *volumes);
+#endif /* not GST_DISABLE_DEPRECATED */
 
   void          (* set_option)     (GstMixer      *mixer,
                                     GstMixerOptions *opts,
@@ -92,9 +93,11 @@ struct _GstMixerClass {
   const gchar * (* get_option)     (GstMixer      *mixer,
                                     GstMixerOptions *opts);
 
+#ifndef GST_DISABLE_DEPRECATED
   void (* option_changed) (GstMixer      *mixer,
                            GstMixerOptions *opts,
-                           gchar         *option);
+                           const gchar   *option);
+#endif /* not GST_DISABLE_DEPRECATED */
 
   /*< private >*/
   gpointer _gst_reserved[GST_PADDING];
@@ -122,7 +125,7 @@ void            gst_mixer_set_option     (GstMixer      *mixer,
 const gchar *   gst_mixer_get_option     (GstMixer      *mixer,
                                           GstMixerOptions *opts);
 
-/* trigger signals */
+/* trigger bus messages */
 void            gst_mixer_mute_toggled   (GstMixer      *mixer,
                                           GstMixerTrack *track,
                                           gboolean       mute);
diff --git a/gst-libs/gst/interfaces/mixeroptions.c b/gst-libs/gst/interfaces/mixeroptions.c
index 7c5c836..6c2fef4 100644
--- a/gst-libs/gst/interfaces/mixeroptions.c
+++ b/gst-libs/gst/interfaces/mixeroptions.c
@@ -25,19 +25,11 @@
 
 #include "mixeroptions.h"
 
-enum
-{
-  /* FILL ME */
-  SIGNAL_OPTION_CHANGED,
-  LAST_SIGNAL
-};
-
 static void gst_mixer_options_class_init (GstMixerOptionsClass * klass);
 static void gst_mixer_options_init (GstMixerOptions * mixer);
 static void gst_mixer_options_dispose (GObject * object);
 
 static GObjectClass *parent_class = NULL;
-static guint signals[LAST_SIGNAL] = { 0 };
 
 GType
 gst_mixer_options_get_type (void)
@@ -73,13 +65,6 @@ gst_mixer_options_class_init (GstMixerOptionsClass * klass)
 
   parent_class = g_type_class_peek_parent (klass);
 
-  signals[SIGNAL_OPTION_CHANGED] =
-      g_signal_new ("option_changed", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST,
-      G_STRUCT_OFFSET (GstMixerOptionsClass, option_changed),
-      NULL, NULL, g_cclosure_marshal_VOID__STRING,
-      G_TYPE_NONE, 1, G_TYPE_STRING);
-
   object_klass->dispose = gst_mixer_options_dispose;
 }
 
diff --git a/gst-libs/gst/interfaces/mixeroptions.h b/gst-libs/gst/interfaces/mixeroptions.h
index 1b85b05..e59a7e5 100644
--- a/gst-libs/gst/interfaces/mixeroptions.h
+++ b/gst-libs/gst/interfaces/mixeroptions.h
@@ -57,9 +57,11 @@ struct _GstMixerOptions {
 struct _GstMixerOptionsClass {
   GstMixerTrackClass parent;
 
+#ifndef GST_DISABLE_DEPRECATED
   /* signals */
   void (* option_changed) (GstMixerOptions *opts,
                            gchar           *value);
+#endif /* not GST_DISABLE_DEPRECATED */
 
   gpointer _gst_reserved[GST_PADDING];
 };
diff --git a/gst-libs/gst/interfaces/mixertrack.c b/gst-libs/gst/interfaces/mixertrack.c
index d5c2487..b2ae93b 100644
--- a/gst-libs/gst/interfaces/mixertrack.c
+++ b/gst-libs/gst/interfaces/mixertrack.c
@@ -27,15 +27,6 @@
 
 enum
 {
-  /* FILL ME */
-  SIGNAL_VOLUME_CHANGED,
-  SIGNAL_RECORD_TOGGLED,
-  SIGNAL_MUTE_TOGGLED,
-  LAST_SIGNAL
-};
-
-enum
-{
   ARG_0,
   ARG_LABEL,
   ARG_UNTRANSLATED_LABEL,
@@ -55,7 +46,6 @@ static void gst_mixer_track_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
 
 static GObjectClass *parent_class = NULL;
-static guint signals[LAST_SIGNAL] = { 0 };
 
 GType
 gst_mixer_track_get_type (void)
@@ -135,28 +125,6 @@ gst_mixer_track_class_init (GstMixerTrackClass * klass)
           "The number of channels contained within the track",
           0, G_MAXINT, 0, G_PARAM_READABLE));
 
-  signals[SIGNAL_RECORD_TOGGLED] =
-      g_signal_new ("record_toggled", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST,
-      G_STRUCT_OFFSET (GstMixerTrackClass,
-          record_toggled),
-      NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
-      G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
-  signals[SIGNAL_MUTE_TOGGLED] =
-      g_signal_new ("mute_toggled", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST,
-      G_STRUCT_OFFSET (GstMixerTrackClass,
-          mute_toggled),
-      NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
-      G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
-  signals[SIGNAL_VOLUME_CHANGED] =
-      g_signal_new ("volume_changed", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST,
-      G_STRUCT_OFFSET (GstMixerTrackClass,
-          volume_changed),
-      NULL, NULL, g_cclosure_marshal_VOID__POINTER,
-      G_TYPE_NONE, 1, G_TYPE_POINTER);
-
   object_klass->dispose = gst_mixer_track_dispose;
 }
 
diff --git a/gst-libs/gst/interfaces/mixertrack.h b/gst-libs/gst/interfaces/mixertrack.h
index 7c87e00..655e8d0 100644
--- a/gst-libs/gst/interfaces/mixertrack.h
+++ b/gst-libs/gst/interfaces/mixertrack.h
@@ -88,13 +88,15 @@ struct _GstMixerTrack {
 struct _GstMixerTrackClass {
   GObjectClass parent;
 
-  /* signals */
+#ifndef GST_DISABLE_DEPRECATED
+  /* signals (deprecated) */
   void (* mute_toggled)   (GstMixerTrack *channel,
                            gboolean       mute);
   void (* record_toggled) (GstMixerTrack *channel,
                            gboolean       record);
   void (* volume_changed) (GstMixerTrack *channel,
                            gint          *volumes);
+#endif /* not GST_DISABLE_DEPRECATED */
 
   gpointer _gst_reserved[GST_PADDING];
 };
