Index: configure.in
===================================================================
--- configure.in	(revision 2086)
+++ configure.in	(working copy)
@@ -119,6 +119,17 @@
 AC_SUBST(DBUS_LIBS)
 
 #
+# Voice Notes require Gstreamer
+#
+PKG_CHECK_MODULES(GST, [gstreamer-0.10 glib-2.0 gstreamer-plugins-base-0.10], ENABLE_GST="yes", ENABLE_GST="no")
+AC_ARG_ENABLE(gstreamer, 
+	      [  --enable-gstreamer[[=no/yes]]  compile with Voice Notes addin [[default: yes]]],
+	      ENABLE_GST="$enableval")
+AM_CONDITIONAL(ENABLE_GST, test "$ENABLE_GST" = "yes")
+AC_SUBST(GST_CFLAGS)
+AC_SUBST(GST_LIBS)
+
+#
 # Check for external Mono.Addins
 #
 PKG_CHECK_MODULES(MONO_ADDINS, mono-addins >= 0.3 \
@@ -291,6 +302,7 @@
 Tomboy/Addins/SshSyncService/Makefile
 Tomboy/Addins/StickyNoteImport/Makefile
 Tomboy/Addins/Tasque/Makefile
+Tomboy/Addins/VoiceNotes/Makefile
 Tomboy/Addins/WebDavSyncService/Makefile
 test/Makefile
 po/Makefile.in
Index: Tomboy.mdp
===================================================================
--- Tomboy.mdp	(revision 2086)
+++ Tomboy.mdp	(working copy)
@@ -206,6 +206,8 @@
     <File name="Tomboy/Addins/GalagoPresence/GalagoPresenceNoteAddin.cs" subtype="Code" buildaction="Compile" />
     <File name="Tomboy/RecentTreeView.cs" subtype="Code" buildaction="Compile" />
     <File name="Mono.Addins/Mono.Addins/Mono.Addins/InstanceExtensionNode.cs" subtype="Code" buildaction="Compile" />
+    <File name="Tomboy/Addins/VoiceNotes" subtype="Directory" buildaction="Compile" />
+    <File name="Tomboy/Addins/VoiceNotes/VoiceNote.cs" subtype="Code" buildaction="Compile" />
   </Contents>
   <References>
     <ProjectReference type="Gac" localcopy="True" refto="gdk-sharp, Version=2.8.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
Index: Tomboy/NoteWindow.cs
===================================================================
--- Tomboy/NoteWindow.cs	(revision 2086)
+++ Tomboy/NoteWindow.cs	(working copy)
@@ -15,6 +15,7 @@
 
 		Gtk.AccelGroup accel_group;
 		Gtk.Toolbar toolbar;
+		Gtk.HBox extra_space;
 		Gtk.Tooltips toolbar_tips;
 		Gtk.ToolButton link_button;
 		NoteTextMenu text_menu;
@@ -98,10 +99,12 @@
 			find_bar.Hidden += FindBarHidden;
 
 			Gtk.VBox box = new Gtk.VBox (false, 2);
+			extra_space = new Gtk.HBox (false, 0);
+			extra_space.Show ();
 			box.PackStart (toolbar, false, false, 0);
 			box.PackStart (editor_window, true, true, 0);
 			box.PackStart (find_bar, false, false, 0);
-
+			box.PackStart (extra_space, false, false, 0);
 			box.Show ();
 
 			// Don't set up Ctrl-W or Ctrl-N if Emacs is in use
@@ -284,6 +287,12 @@
 				return toolbar;
 			}
 		}
+		
+		public Gtk.HBox ExtraSpace {
+			get {
+				return extra_space;
+			}
+		}
 
 		/// <summary>
 		/// The Delete Toolbar Button
Index: Tomboy/Addins/Makefile.am
===================================================================
--- Tomboy/Addins/Makefile.am	(revision 2086)
+++ Tomboy/Addins/Makefile.am	(working copy)
@@ -13,5 +13,7 @@
 	SshSyncService		\
 	StickyNoteImport	\
 	Tasque			\
+	VoiceNotes			\
 	WebDavSyncService
 
+
Index: Tomboy/Addins/VoiceNotes/VoiceNote.cs
===================================================================
--- Tomboy/Addins/VoiceNotes/VoiceNote.cs	(revision 2086)
+++ Tomboy/Addins/VoiceNotes/VoiceNote.cs	(working copy)
@@ -3,20 +3,27 @@
 using System;
 using System.IO;
 using System.Runtime.InteropServices;
+using System.Media;
 using Gtk;
 
 namespace Tomboy.VoiceNote
 {
+	/// <summary>
+	/// This is the NoteAddin for VoiceNotes, started as a Summer of Code
+	/// project in 2008.
+	/// </summary>
 	public class VoiceNote : NoteAddin
 	{
 		Gtk.ToolButton record_button;
 		Gtk.ToolButton play_button;
 		Gtk.ToolButton stop_button;
+		Gtk.VolumeButton volume_button;
 		Gtk.SeparatorToolItem separator;
 		InterruptableTimeout button_manager;
 		Gtk.MenuItem delete_item;
 		String voice_note_path;
 		bool has_voice_note;
+		static double max_volume;
 		static Gdk.Pixbuf icon = null;
 
 		
@@ -40,8 +47,17 @@
 		
 		[DllImport("libvoicenote")]
 		static extern int get_state ();
+		
+		[DllImport("libvoicenote")]
+		static extern void set_volume (int volume);
+		
+		[DllImport("libvoicenote")]
+		static extern int get_volume ();
+		
+		[DllImport("libvoicenote")]
+		static extern int get_max_volume ();
+		
 
-
 		public override void Initialize ()
 		{
 			separator = new Gtk.SeparatorToolItem ();
@@ -58,12 +74,17 @@
 			stop_button = new Gtk.ToolButton (Gtk.Stock.MediaStop);
 			stop_button.Clicked += OnStopButtonClicked;
 			stop_button.Show ();
-
+			
+			volume_button = new Gtk.VolumeButton ();
+			volume_button.ValueChanged += OnVolumeChanged;
+			volume_button.Show ();
+			
 			delete_item = new Gtk.MenuItem ("Delete Voice Note");
 			delete_item.Activated += OnDeleteItemActivated;
 			delete_item.Show ();
 		
 			initialize ();
+			max_volume = get_max_volume ();
 		}
 
 		
@@ -86,10 +107,14 @@
 			if (has_voice_note)
 				Window.Icon = icon;
 			
-			AddToolItem (separator, -1);
-			AddToolItem (record_button, -1);
-			AddToolItem (play_button, -1);
-			AddToolItem (stop_button, -1);
+			/*
+			 * This 'ExtraSpace' is a HBox added to NoteWindow
+			 */ 
+			Window.ExtraSpace.PackStart (record_button, false, false, 0);
+			Window.ExtraSpace.PackStart (play_button, false, false, 0);
+			Window.ExtraSpace.PackStart (stop_button, false, false, 0);
+			Window.ExtraSpace.PackEnd (volume_button, false, false, 0);
+			volume_button.Value = (double) get_volume() / max_volume;
 			AddPluginMenuItem (delete_item);			
 			
 			play_button.Sensitive = has_voice_note; 
@@ -99,6 +124,9 @@
 			button_manager.Timeout += UpdateButtons;
 		}
 		
+		/* 
+		 * Here come the callbacks for the buttons 
+		 */
 
 		void OnRecordButtonClicked (object sender, EventArgs args)
 		{
@@ -124,6 +152,10 @@
 			play_button.Sensitive = false;
 			stop_button.Sensitive = true;
 			button_manager.Reset (500);
+			
+			// The volume could have been changed outside tomboy
+			double current_volume = (double) get_volume () / max_volume;
+			UpdateVolume (current_volume);
 		}
 
 		
@@ -141,7 +173,24 @@
 			stop_button.Sensitive = false;
 		}
 		
+		void OnVolumeChanged (object sender, EventArgs args)
+		{
+			double note_volume = volume_button.Value;
+			int new_volume = (int) (note_volume * max_volume);
+			set_volume (new_volume);
+		}
 		
+		/// <summary>
+		///  In case the volume was changed outside tomboy
+		/// </summary>
+		void UpdateVolume (double new_volume)
+		{
+			volume_button.Value = new_volume;
+		}
+		
+		/// <summary>
+		///  Manage buttons' sensitivity 
+		/// </summary>
 		void UpdateButtons (object sender, EventArgs args)
 		{
 			int media_state = get_state ();
Index: Tomboy/Addins/VoiceNotes/Makefile.am
===================================================================
--- Tomboy/Addins/VoiceNotes/Makefile.am	(revision 2086)
+++ Tomboy/Addins/VoiceNotes/Makefile.am	(working copy)
@@ -20,16 +20,13 @@
 	-resource:$(srcdir)/$(ADDIN_NAME).addin.xml \
 	-resource:$(srcdir)/voicenote-22.png,voicenote.png
 
-$(TARGET).mdb: $(TARGET)
-
 $(TARGET): $(CSFILES) $(top_builddir)/Tomboy/Tomboy.exe
 	$(CSC) -out:$@ $(CSFLAGS) $(ASSEMBLIES) $(CSFILES) $(RESOURCES)
 
 
 addinsdir = $(pkglibdir)/addins
 addins_DATA = \
-	$(TARGET) \
-	$(TARGET).mdb
+	$(TARGET)
 
 EXTRA_DIST = \
 	$(CSFILES) \
@@ -64,7 +61,7 @@
 libvoicenote_la_LDFLAGS = \
 	-export-dynamic -module -avoid-version \
 	$(LIBTOMBOY_LIBS) \
-	$(GST_LIBS)
+	$(GST_LIBS) -lgstinterfaces-0.10 -lgstaudio-0.10 
 
 maintainer-clean-local:
 	rm -f Makefile.in
Index: Tomboy/Addins/VoiceNotes/voicenotemedia.c
===================================================================
--- Tomboy/Addins/VoiceNotes/voicenotemedia.c	(revision 2086)
+++ Tomboy/Addins/VoiceNotes/voicenotemedia.c	(working copy)
@@ -1,19 +1,34 @@
 #include <gst/gst.h>
+#include <gst/interfaces/mixer.h>
+#include <glib.h>
 #include <string.h>
 
 #define PLAY_CMD_START "filesrc location="
 #define PLAY_CMD_END " !oggdemux!vorbisdec!audioconvert!audioresample!gconfaudiosink "
 #define RECORD_CMD "gconfaudiosrc !audioconvert !vorbisenc !oggmux !filesink location="
+#define MIXER_NAME "alsamixerelement0"
+#define TRACK_NAME "Master"
 
 static GstElement *pipeline = NULL;
 static GstBus *bus;
+static GstMixer *mixer;
+static GstMixerTrack *track;
+static gboolean track_found;
 
+void find_track (gpointer, gpointer);
+void find_mixer (gpointer, gpointer);
+
+
 void
 initialize ()
 {
   gst_init (NULL, NULL);
+  track_found = FALSE;
+  GList* all_mixers = gst_audio_default_registry_mixer_filter (NULL, FALSE, NULL);
+  g_list_foreach (all_mixers, find_mixer, NULL);
 }
 
+
 static gboolean
 bus_callback (GstBus *bus, GstMessage *message, gpointer data)
 {
@@ -29,7 +44,66 @@
   return TRUE;
 }
 
+
 void
+find_track (gpointer data, gpointer extra_data)
+{
+  GstMixer *this_mixer = GST_MIXER(extra_data);
+  GstMixerTrack *this_track = GST_MIXER_TRACK (data);
+
+  if (!track_found && 
+      GST_IS_MIXER_TRACK (this_track) &&
+      GST_IS_MIXER (this_mixer) &&  
+      g_ascii_strncasecmp (this_track->label, TRACK_NAME, 6) == 0 ) {
+    mixer = this_mixer;
+    track = this_track;
+    track_found = TRUE;
+  }
+}
+
+
+void
+find_mixer (gpointer data, gpointer extra_data){
+  GstElement *this_mixer = GST_ELEMENT (data);
+  GList *tracks;
+
+  if (!track_found && GST_IS_ELEMENT (this_mixer))
+  {
+    gst_element_set_state (this_mixer,GST_STATE_READY);
+    if (g_ascii_strncasecmp (gst_element_get_name (this_mixer), MIXER_NAME, 17) == 0){
+      tracks = gst_mixer_list_tracks (GST_MIXER (this_mixer));
+      g_list_foreach (tracks, find_track, this_mixer);
+    }
+  }
+}
+
+
+void
+set_volume (int new_volume)
+{
+  if (new_volume <= 31)
+  {
+    gint volumes[2] = {new_volume, new_volume};
+    gst_mixer_set_volume(mixer, track, volumes);
+  }
+}
+
+gint
+get_volume ()
+{
+  gint volumes[2];
+  gst_mixer_get_volume(mixer, track, volumes);
+  return volumes[0];
+}
+
+gint
+get_max_volume ()
+{
+  return track->max_volume;
+}
+
+
+void
 set_bus ()
 {
   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
Index: Tomboy/Tomboy.exe.config.in
===================================================================
--- Tomboy/Tomboy.exe.config.in	(revision 2086)
+++ Tomboy/Tomboy.exe.config.in	(working copy)
@@ -2,6 +2,7 @@
   <dllmap dll="libglib-2.0-0.dll" target="libglib-2.0.so.0"/>
   <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0"/>	
   <dllmap dll="libgtkspell" target="libgtkspell.so.0"/>
+  <dllmap dll="libgstreamer" target="libgstreamer-0.10.so" />
   <dllmap dll="libtomboy" target="libtomboy.so"/>
   <dllmap dll="panel-applet-2" target="libpanel-applet-2.so.0"/>
 </configuration>
