diff --git a/Source/Processors/SpikeSorter/SpikeSorter.cpp b/Source/Processors/SpikeSorter/SpikeSorter.cpp
index 813bdc28c0b3810015c6231ae03673be5f90a80a..3fab6eb2a9f4d49beac900f6bb22827f85c102ed 100644
--- a/Source/Processors/SpikeSorter/SpikeSorter.cpp
+++ b/Source/Processors/SpikeSorter/SpikeSorter.cpp
@@ -221,6 +221,8 @@ Electrode::~Electrode()
 	delete voltageScale;
     delete channels;
 	delete spikeSort;
+	delete runningStats;
+
 }
 
 Electrode::Electrode(int ID, UniqueIDgenerator *uniqueIDgenerator_, PCAcomputingThread *pth, String _name, int _numChannels, int *_channels, float default_threshold, int pre, int post, float samplingRate , int sourceNodeId)
@@ -238,6 +240,7 @@ Electrode::Electrode(int ID, UniqueIDgenerator *uniqueIDgenerator_, PCAcomputing
     isActive = new bool[numChannels];
     channels = new int[numChannels];
 	voltageScale = new double[numChannels];
+	runningStats = new RunningStat[numChannels];
 	depthOffsetMM = 0.0;
 
 	advancerID = -1;
@@ -860,6 +863,25 @@ void SpikeSorter::handleEvent(int eventType, MidiMessage& event, int sampleNum)
 // 	}
 // }
 
+
+float SpikeSorter::getSelectedElectrodeNoise()
+{
+	if (electrodes.size() == 0)
+		return 0.0;
+
+	// TODO, change "0" to active channel to support tetrodes.
+	return electrodes[currentElectrode]->runningStats[0].StandardDeviation();
+}
+
+
+void SpikeSorter::clearRunningStatForSelectedElectrode()
+{
+	if (electrodes.size() == 0)
+		return;
+	// TODO, change "0" to active channel to support tetrodes.
+	electrodes[currentElectrode]->runningStats[0].Clear();
+}
+
 void SpikeSorter::process(AudioSampleBuffer& buffer,
                             MidiBuffer& events)
 {
@@ -893,23 +915,25 @@ void SpikeSorter::process(AudioSampleBuffer& buffer,
         {
 
             sampleIndex++;
-
+			
             // cycle through channels
             for (int chan = 0; chan < electrode->numChannels; chan++)
             {
 
                 // std::cout << "  channel " << chan << std::endl;
-
+				
                 if (*(electrode->isActive+chan))
                 {
 					//float v = getNextSample(currentChannel);
 
                     int currentChannel = electrode->channels[chan];
+					float currentValue = getNextSample(currentChannel);
+					electrode->runningStats[chan].Push(currentValue);
 
 					bool bSpikeDetectedPositive  = electrode->thresholds[chan] > 0 &&
-						(getNextSample(currentChannel) > electrode->thresholds[chan]); // rising edge
+						(currentValue > electrode->thresholds[chan]); // rising edge
 					bool bSpikeDetectedNegative = electrode->thresholds[chan] < 0 &&
-						(getNextSample(currentChannel) < electrode->thresholds[chan]); // falling edge
+						(currentValue < electrode->thresholds[chan]); // falling edge
 
                     if  (bSpikeDetectedPositive || bSpikeDetectedNegative)
                     { 
diff --git a/Source/Processors/SpikeSorter/SpikeSorter.h b/Source/Processors/SpikeSorter/SpikeSorter.h
index bb520b868bc464251a657df3025aa9c8c03f8af9..8650b05d3bf386b6218f21a9690cd2f600993827 100644
--- a/Source/Processors/SpikeSorter/SpikeSorter.h
+++ b/Source/Processors/SpikeSorter/SpikeSorter.h
@@ -81,6 +81,63 @@ private:
 	int globalUniqueID;
 };
 
+/* snatched from http://www.johndcook.com/blog/standard_deviation/ */
+class RunningStat
+{
+public:
+	RunningStat() : m_n(0) {}
+
+	void Clear()
+	{
+		m_n = 0;
+	}
+
+	void Push(double x)
+	{
+		m_n++;
+
+		// See Knuth TAOCP vol 2, 3rd edition, page 232
+		if (m_n == 1)
+		{
+			m_oldM = m_newM = x;
+			m_oldS = 0.0;
+		}
+		else
+		{
+			m_newM = m_oldM + (x - m_oldM) / m_n;
+			m_newS = m_oldS + (x - m_oldM)*(x - m_newM);
+
+			// set up for next iteration
+			m_oldM = m_newM;
+			m_oldS = m_newS;
+		}
+	}
+
+	int NumDataValues() const
+	{
+		return m_n;
+	}
+
+	double Mean() const
+	{
+		return (m_n > 0) ? m_newM : 0.0;
+	}
+
+	double Variance() const
+	{
+		return ((m_n > 1) ? m_newS / (m_n - 1) : 0.0);
+	}
+
+	double StandardDeviation() const
+	{
+		return sqrt(Variance());
+	}
+
+private:
+	int m_n;
+	double m_oldM, m_newM, m_oldS, m_newS;
+};
+
 class Electrode
 {
 	public:
@@ -106,6 +163,7 @@ class Electrode
 		double *voltageScale;
 		//float PCArange[4];
 
+		RunningStat *runningStats;
 		SpikeHistogramPlot* spikePlot;
 		SpikeSortBoxes* spikeSort;
 		PCAcomputingThread *computingThread;
@@ -181,8 +239,9 @@ public:
     /** Creates the SpikeSorterEditor. */
     AudioProcessorEditor* createEditor();
 
+	float getSelectedElectrodeNoise();
+	void clearRunningStatForSelectedElectrode();
 
-	
 	//void addNetworkEventToQueue(StringTS S);
 
 	void postEventsInQueue(MidiBuffer& events);
diff --git a/Source/Processors/SpikeSorter/SpikeSorterCanvas.cpp b/Source/Processors/SpikeSorter/SpikeSorterCanvas.cpp
index abfc13528109520887efa69b8d9299b0269feda4..4379d7ab93fcb8bd8063bb418b4a04cb3d28c0d0 100644
--- a/Source/Processors/SpikeSorter/SpikeSorterCanvas.cpp
+++ b/Source/Processors/SpikeSorter/SpikeSorterCanvas.cpp
@@ -1203,7 +1203,7 @@ bool WaveformAxes::checkThreshold(const SpikeObject& s)
 
 void WaveformAxes::clear()
 {
-
+	processor->clearRunningStatForSelectedElectrode();
     spikeBuffer.clear();
     spikeIndex = 0;
     int numSamples=40;
@@ -1668,16 +1668,13 @@ void WaveformAxes::paint(Graphics& g)
 
     if (drawGrid)
         drawWaveformGrid(g);
+	 
+	double noise = processor->getSelectedElectrodeNoise();
+	String d = "STD: " + String(noise, 2) + "uV";
+	g.setFont(Font("Small Text", 13, Font::plain));
+	g.setColour(Colours::white);
 
-    if (channel == 0)
-    {
-        //double depth = processor->getSelectedElectrodeDepth();
-        //String d = "Depth: "+String(depth,4) +" mm";
-        //g.setFont(Font("Small Text", 13, Font::plain));
-        // g.setColour(Colours::white);
-
-        //g.drawText(d,10,10,150,20,Justification::left,false);
-    }
+	g.drawText(d, 10, 10, 150, 20, Justification::left, false);
     // draw the grid lines for the waveforms
 
     // draw the threshold line and labels