diff --git a/envy24control/levelmeters.c b/envy24control/levelmeters.c
index fa44979..a07913d 100644
--- a/envy24control/levelmeters.c
+++ b/envy24control/levelmeters.c
@@ -1,6 +1,8 @@
 /*****************************************************************************
    levelmeters.c - Stereo level meters
    Copyright (C) 2000 by Jaroslav Kysela <perex@perex.cz>
+   Missing peak-level meter feature implented by NPM:
+   Copyright (C) 2010 by Niels Mayer <NielsMayer@gmail.com>
    
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
@@ -19,6 +21,7 @@
 
 #include "envy24control.h"
 
+static GdkGC *penWhiteLight[21] = { NULL, }; /* NPM */
 static GdkGC *penGreenShadow[21] = { NULL, };
 static GdkGC *penGreenLight[21] = { NULL, };
 static GdkGC *penOrangeShadow[21] = { NULL, };
@@ -38,15 +41,40 @@ static void update_peak_switch(void)
 		g_print("Unable to read peaks: %s\n", snd_strerror(err));
 }
 
+/*
+ * Niels Mayer (NPM) Jul-11-10: Fixing https://bugzilla.redhat.com/show_bug.cgi?id=602903
+ * by implementing peak-level meters. The http://alsa.cybermirror.org/manuals/icensemble/envy24.pdf
+ * soundchip provides hardware level meters and these are returned via ALSA as such:
+ * >> amixer -c M66 cget iface=PCM,name='Multi Track Peak',numid=45
+ *  ; type=INTEGER,access=r-------,values=22,min=0,max=255,step=0
+ *  : values=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,198,255,198 
+ * These globals store the peak levels of the meters across callbacks.
+ */
+#define MULTI_TRACK_PEAK_CHANNELS 22
+static int peak_levels[MULTI_TRACK_PEAK_CHANNELS] = {0,};
+// special case for stereo mix track at "index 0" which is actually "(peaks, 20)" and "(peaks, 21)" cases below
+static int peak_lmix = 0;
+static int peak_rmix = 0;
+
+/* NPM: changed for https://bugzilla.redhat.com/show_bug.cgi?id=602903 */
 static void get_levels(int idx, int *l1, int *l2)
 {
 	*l1 = *l2 = 0;
 	
 	if (idx == 0) {
-		*l1 = snd_ctl_elem_value_get_integer(peaks, 20);
-		*l2 = snd_ctl_elem_value_get_integer(peaks, 21);
+	  if ((*l1 = snd_ctl_elem_value_get_integer(peaks, 20)) > peak_lmix) {
+	    peak_lmix = (*l1);
+//	    g_print("set peak_lmix: %d\n", peak_lmix);
+	  }
+	  if ((*l2 = snd_ctl_elem_value_get_integer(peaks, 21)) > peak_rmix) {
+	    peak_rmix = (*l2);
+//	    g_print("set peak_rmix: %d\n", peak_rmix);      
+	  }
 	} else {
-		*l1 = *l2 = snd_ctl_elem_value_get_integer(peaks, idx - 1);
+	  if ((*l1 = *l2 = snd_ctl_elem_value_get_integer(peaks, idx - 1)) > peak_levels[idx - 1]) {
+	    peak_levels[idx - 1] = (*l1);
+//	    g_print("set peak_levels[%d]: %d\n", idx - 1, peak_levels[idx - 1]);      
+	  }
 	}
 }
 
@@ -146,6 +174,58 @@ static void redraw_meters(int idx, int width, int height, int level1, int level2
 		segs_on1--;
 		segs_on2--;
 	}
+
+	/*
+	 * NPM: Fixing https://bugzilla.redhat.com/show_bug.cgi?id=602903
+	 * The code below was "transformed" from the above (which isn't how
+	 * I'd do things in the first place) and could be further
+	 * simplified to eliminate the for loop. The purpose was to
+	 * reuse the "geometries" implicit in the algorithm above, by
+	 * drawing a line directly above the highest lit segment;
+	 * to represent the "waterline" for the peak audio level.
+	 */
+	 
+	int pklevel1, pklevel2;
+	int drawn1, drawn2;
+	
+	if (idx== 0) {
+	  pklevel1 = peak_lmix;
+	  pklevel2 = peak_rmix;
+	}
+	else {
+	  pklevel1 = pklevel2 = peak_levels[idx - 1];
+	}
+	segs_on1 = ((segments * pklevel1) + 128) / 255;
+	segs_on2 = ((segments * pklevel2) + 128) / 255;
+	drawn1 = drawn2 = FALSE;
+	for (seg = 0; seg < segments; seg++) {
+	  if ((segs_on1 > 0) ^ (segs_on1 > 1)) {
+	    gdk_draw_line(pixmap[idx],                                            
+			    penWhiteLight[idx],
+			    6,
+			    3 + ((segments - seg - 1) * 4),
+			    segment_width + 5,
+			    3 + ((segments - seg - 1) * 4));
+	    drawn1 = TRUE;
+	    if ((idx != 0) || drawn2)
+		break;
+	  }
+	  if (idx == 0)
+	    if ((segs_on2 > 0) ^ (segs_on2 > 1)) {
+		gdk_draw_line(pixmap[idx],
+			      penWhiteLight[idx],
+			      2 + (width / 2),
+			      3 + ((segments - seg - 1) * 4),
+			      segment_width + 1 + (width / 2),
+			      3 + ((segments - seg - 1) * 4));
+		drawn2 = TRUE;
+		if (drawn1)
+		  break;
+	    }
+	
+	  segs_on1--;
+	  segs_on2--;
+	}
 }
 
 gint level_meters_configure_event(GtkWidget *widget, GdkEventConfigure *event)
@@ -158,6 +238,7 @@ gint level_meters_configure_event(GtkWidget *widget, GdkEventConfigure *event)
 				     widget->allocation.width,
 				     widget->allocation.height,
 				     -1);
+	penWhiteLight[idx] = get_pen(idx, 0xffff, 0xffff, 0xffff);
 	penGreenShadow[idx] = get_pen(idx, 0, 0x77ff, 0);
 	penGreenLight[idx] = get_pen(idx, 0, 0xffff, 0);
 	penOrangeShadow[idx] = get_pen(idx, 0xddff, 0x55ff, 0);
@@ -255,8 +336,15 @@ gint level_meters_timeout_callback(gpointer data)
 	return TRUE;
 }
 
+/* NPM fixed lack of implementation ( https://bugzilla.redhat.com/show_bug.cgi?id=602903 )*/
 void level_meters_reset_peaks(GtkButton *button, gpointer data)
 {
+  int i;
+  for (i = 0; i < MULTI_TRACK_PEAK_CHANNELS ; i++) {
+    peak_levels[i] = 0;
+  }
+  peak_lmix = 0;
+  peak_rmix = 0;
 }
 
 void level_meters_init(void)
