diff --git a/Builds/Linux/build/data_stream_16ch b/Builds/Linux/build/data_stream_16ch
new file mode 100644
index 0000000000000000000000000000000000000000..de0196c18569705d7b26fdfa2d22b14ef5f92436
Binary files /dev/null and b/Builds/Linux/build/data_stream_16ch differ
diff --git a/Source/Processors/DataThreads/FileReaderThread.cpp b/Source/Processors/DataThreads/FileReaderThread.cpp
index ba6c1574082c28294d475db273136dcdc9de4c63..03c7aa100ea2e87f1cb57909218d36e05a265d1e 100644
--- a/Source/Processors/DataThreads/FileReaderThread.cpp
+++ b/Source/Processors/DataThreads/FileReaderThread.cpp
@@ -70,7 +70,7 @@ bool FileReaderThread::updateBuffer()
     		if (input->isExhausted())
     			input->setPosition(0);   			
     	
-    		thisSample[ch%numChannels] = float(input->readShort());
+    		thisSample[ch%numChannels] = float(input->readShort())/80000.0f;
 
     	}
 
diff --git a/Source/Processors/ProcessorGraph.cpp b/Source/Processors/ProcessorGraph.cpp
index 219387137afe9f5a71a1f98ec14bf5f146a1f20e..a7d37ff6a3b1a8a13468e22d7159023caab118dd 100644
--- a/Source/Processors/ProcessorGraph.cpp
+++ b/Source/Processors/ProcessorGraph.cpp
@@ -315,7 +315,8 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
 
 	if (processorType.equalsIgnoreCase("Sources")) {
 
-		if (subProcessorType.equalsIgnoreCase("Intan Demo Board")) {
+		if (subProcessorType.equalsIgnoreCase("Intan Demo Board") || 
+			subProcessorType.equalsIgnoreCase("File Reader")) {
 			
 			// only one Intan Demo Board at a time, please
 			if (!processorWithSameNameExists(subProcessorType)) {
diff --git a/Source/Processors/SpikeDetector.cpp b/Source/Processors/SpikeDetector.cpp
index 3eb899e2e963a685d328c5d294fa5d93a07861b4..83c98027460d5a30f61f4d8aaae58803fd775ed3 100644
--- a/Source/Processors/SpikeDetector.cpp
+++ b/Source/Processors/SpikeDetector.cpp
@@ -26,18 +26,16 @@
 
 SpikeDetector::SpikeDetector()
     : GenericProcessor("Spike Detector"), 
-	  sampleRate (40000.0), threshold(5000.0), prePeakMs(0.2), postPeakMs(0.6),
-	  accumulator(0)
+	  threshold(5000.0), prePeakMs(0.2), postPeakMs(0.6),
+	  accumulator(0), overflowBuffer(2,100)
 	
 {
 
-	spikeBuffer = new MidiBuffer();
-
 }
 
 SpikeDetector::~SpikeDetector()
 {
-	deleteAndZero(spikeBuffer);
+
 }
 
 
@@ -53,14 +51,26 @@ AudioProcessorEditor* SpikeDetector::createEditor()
 	return editor;
 }
 
+void SpikeDetector::updateSettings()
+{
+
+    overflowBuffer.setSize(getNumInputs(),100);
+
+    thresh.clear();
+
+    for (int i = 0; i < getNumInputs(); i++)
+    {
+        thresh.add(threshold);
+    }
+
+}
+
 void SpikeDetector::setParameter (int parameterIndex, float newValue)
 {
 	//std::cout << "Message received." << std::endl;
-	if (parameterIndex == 0) {
-		for (int n = 0; n < getNumOutputs(); n++)
-        {
-            thresh.set(n,newValue);
-        }
+	if (parameterIndex == 0) 
+    {
+        thresh.set(currentChannel,newValue);
 	}
 
 }
@@ -85,22 +95,6 @@ bool SpikeDetector::enable()
     }
 
     // check configuration
-    for (int ds = 0; ds < getConfiguration()->numDataSources(); ds++)
-    {
-        for (int tt = 0; tt < getConfiguration()->getSource(ds)->numTetrodes(); tt++)
-        {
-
-            Trode* t = getConfiguration()->getSource(ds)->getTetrode(tt);
-
-            for (int ch = 0; ch < t->numChannels(); ch++)
-            {
-                thresh.set(t->getChannel(ch),t->getThreshold(ch));
-                channels.set(t->getChannel(ch),t->getRawDataPointer());
-                nChans.set(t->getChannel(ch),t->numChannels());
-                isActive.set(t->getChannel(ch),t->getState(ch));
-            }
-        }
-    }
 
     return true;
 
@@ -118,15 +112,13 @@ bool SpikeDetector::disable()
 }
 
 void SpikeDetector::process(AudioSampleBuffer &buffer, 
-                            MidiBuffer &midiMessages,
+                            MidiBuffer &events,
                             int& nSamples)
 {
 
 	int maxSamples = nSamples;//getNumSamples(midiMessages);
 	int spikeSize = 2 + prePeakSamples*2 + postPeakSamples*2; 
 
-    spikeBuffer->clear();
-
     for (int sample = prePeakSamples + 1; sample < maxSamples - postPeakSamples - 1; sample++)
     {
         for (int chan = 0; chan < getNumOutputs(); chan++) 
@@ -164,7 +156,7 @@ void SpikeDetector::process(AudioSampleBuffer &buffer,
                         }
 
                         // broadcast spike
-                        spikeBuffer->addEvent(data, // spike data
+                        events.addEvent(data, // spike data
                               sizeof(data), // total bytes
                               sample);           // sample index
                         
diff --git a/Source/Processors/SpikeDetector.h b/Source/Processors/SpikeDetector.h
index 770ed5800acc4749afc7ea94f1cab679d5b510ca..2adc96a7366bb5e3b7d8eb40c90c1984ce1c6b0a 100644
--- a/Source/Processors/SpikeDetector.h
+++ b/Source/Processors/SpikeDetector.h
@@ -25,12 +25,14 @@
 #define __SPIKEDETECTOR_H_3F920F95__
 
 #include "../../JuceLibraryCode/JuceHeader.h"
+
 #include "GenericProcessor.h"
 #include "Editors/SpikeDetectorEditor.h"
-#include "../UI/Configuration.h"
 
 /**
 
+  == UNDER CONSTRUCTION ==
+
   Detects spikes in a continuous signal and outputs events containing the spike data.
 
   @see GenericProcessor, SpikeDetectorEditor
@@ -38,7 +40,6 @@
 */
 
 class SpikeDetectorEditor;
-class FilterViewport;
 
 class SpikeDetector : public GenericProcessor
 
@@ -48,20 +49,20 @@ public:
 	SpikeDetector();
 	~SpikeDetector();
 	
-	void process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples);
+	void process(AudioSampleBuffer &buffer, MidiBuffer &events, int& nSamples);
 	void setParameter (int parameterIndex, float newValue);
 
+	void updateSettings();
+
 	bool enable();
 	bool disable();
 
-	MidiBuffer* getEventBuffer() {return spikeBuffer;}
-
 	AudioProcessorEditor* createEditor();
 
-	bool hasEditor() const {return true;}
+	AudioSampleBuffer overflowBuffer;
 	
 private:
-	double sampleRate, threshold;
+	double threshold;
 	double prePeakMs, postPeakMs;
 	int prePeakSamples, postPeakSamples;
 	int accumulator;
@@ -72,10 +73,6 @@ private:
 	Array<bool> isActive;
 	Array<int> lastSpike;
 
-	MidiBuffer* spikeBuffer;
-
-	//AudioData::ConverterInstance<AudioData::Float32, AudioData::Int16> converter;
-
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SpikeDetector);
 
 };
diff --git a/Source/UI/ProcessorList.cpp b/Source/UI/ProcessorList.cpp
index a7d3a5dd1845bc99fc99cb3939b0b7b9d1469b76..d7faaf96315bcd0aae9085b6a9ea276debad3c3e 100644
--- a/Source/UI/ProcessorList.cpp
+++ b/Source/UI/ProcessorList.cpp
@@ -40,7 +40,7 @@ ProcessorList::ProcessorList() : isDragging(false),
 	sources->addSubItem(new ProcessorListItem("Intan Demo Board"));
 	sources->addSubItem(new ProcessorListItem("Signal Generator"));
 	//sources->addSubItem(new ProcessorListItem("Custom FPGA"));
-	//sources->addSubItem(new ProcessorListItem("File Reader"));
+	sources->addSubItem(new ProcessorListItem("File Reader"));
 	sources->addSubItem(new ProcessorListItem("Event Generator"));
 
 	ProcessorListItem* filters = new ProcessorListItem("Filters");