diff --git a/Source/Plugins/EcubeSource/EcubeEditor.cpp b/Source/Plugins/EcubeSource/EcubeEditor.cpp
index b6f9a918e65982a0a3a7eecdf21701f57ac9e363..92560d4da04e64873766960d7a802abd3f636874 100644
--- a/Source/Plugins/EcubeSource/EcubeEditor.cpp
+++ b/Source/Plugins/EcubeSource/EcubeEditor.cpp
@@ -36,7 +36,7 @@ EcubeEditor::EcubeEditor(GenericProcessor* parentNode, EcubeThread* npThread, bo
 {
     desiredWidth = 180;
 
-    if (pThread->getNumHeadstageOutputs())
+    if (pThread->getNumDataOutputs(DataChannel::HEADSTAGE_CHANNEL, 0))
     {
         volLabel = new Label("Volume text label", "Volume");
         volLabel->setBounds(35, 20, 180, 20);
@@ -71,14 +71,14 @@ EcubeEditor::EcubeEditor(GenericProcessor* parentNode, EcubeThread* npThread, bo
         chanComboBox->addListener(this);
         addAndMakeVisible(chanComboBox);
     }
-    else if (pThread->getNumAdcOutputs())
+    else if (pThread->getNumDataOutputs(DataChannel::ADC_CHANNEL, 0))
     {
         samplerateLabel = new Label("Samplerate label", "Sample Rate (Hz):");
         samplerateLabel->setBounds(10, 20, 180, 20);
         samplerateLabel->setFont(Font("Small Text", 12, Font::plain));
         addAndMakeVisible(samplerateLabel);
 
-        samplerateValueLabel = new Label("Samplerate label", String(pThread->getSampleRate(),3));
+        samplerateValueLabel = new Label("Samplerate label", String(pThread->getSampleRate(0),3));
         samplerateValueLabel->setBounds(20, 40, 180, 20);
         samplerateValueLabel->setFont(Font("Small Text", 12, Font::plain));
         addAndMakeVisible(samplerateValueLabel);
diff --git a/Source/Plugins/EcubeSource/EcubeThread.cpp b/Source/Plugins/EcubeSource/EcubeThread.cpp
index c81e67dce885d33fe2e185c911237ae8e0371f29..ef9be77475c3a3dd8284a9ad602c9427e81f4378 100644
--- a/Source/Plugins/EcubeSource/EcubeThread.cpp
+++ b/Source/Plugins/EcubeSource/EcubeThread.cpp
@@ -227,7 +227,7 @@ EcubeThread::EcubeThread(SourceNode* sn) : DataThread(sn), numberingScheme(1), a
                         }
                     }
                 }
-                dataBuffer = new DataBuffer(pDevInt->n_channel_objects, 10000);
+                sourceBuffers.set(0,new DataBuffer(pDevInt->n_channel_objects, 10000));
                 // Create the interleaving buffer based on the number of channels
                 pDevInt->interleaving_buffer.malloc(sizeof(float)* 1500 * pDevInt->n_channel_objects);
             }
@@ -256,7 +256,7 @@ EcubeThread::EcubeThread(SourceNode* sn) : DataThread(sn), numberingScheme(1), a
                 pDevInt->sampletime_80mhz = pDevInt->pStrmA->GetSampleRateDen();
                 pDevInt->sampletime_80mhz *= 80000000 / pDevInt->pStrmA->GetSampleRateNum();
 
-                dataBuffer = new DataBuffer(32, 10000);
+                sourceBuffers.set(0,new DataBuffer(32, 10000));
                 // The interleaving buffer is there just for short->float conversion
                 pDevInt->interleaving_buffer.malloc(sizeof(float)* 1500);
             }
@@ -283,7 +283,7 @@ EcubeThread::EcubeThread(SourceNode* sn) : DataThread(sn), numberingScheme(1), a
                     pDevInt->n_channel_objects++;
                 }
 
-                dataBuffer = new DataBuffer(64, 10000);
+                sourceBuffers.set(0,new DataBuffer(64, 10000));
                 // Create the interleaving buffer based on the number of digital ports
                 pDevInt->interleaving_buffer.malloc(sizeof(float)* 1500 * 64);
                 // Create the analog of interleaving buffer in packed format (int64)
@@ -313,24 +313,24 @@ void EcubeThread::setDefaultChannelNames()
 {
 
     String prefix;
-    ChannelType common_type;
+    DataChannel::DataChannelTypes common_type;
 
     int numch = getNumChannels();
 
     if (pDevInt->data_format == EcubeDevInt::dfSeparateChannelsAnalog)
     {
         prefix = "HS_CH";
-        common_type = HEADSTAGE_CHANNEL;
+		common_type = DataChannel::HEADSTAGE_CHANNEL;
     }
     else if (pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog)
     {
         prefix = "PAI";
-        common_type = ADC_CHANNEL;
+		common_type = DataChannel::ADC_CHANNEL;
     }
     else //if (pDevInt->data_format == EcubeDevInt::dfDigital)
     {
         prefix = "PDI";
-        common_type = ADC_CHANNEL;
+		common_type = DataChannel::ADC_CHANNEL;
     }
 
     if (numberingScheme != 1)
@@ -346,7 +346,7 @@ void EcubeThread::setDefaultChannelNames()
 
 }
 
-bool EcubeThread::usesCustomNames()
+bool EcubeThread::usesCustomNames() const
 {
     return true;
 }
@@ -369,27 +369,26 @@ EcubeThread::~EcubeThread()
     waitForThreadToExit(-1);
 }
 
-int EcubeThread::getNumHeadstageOutputs()
+int EcubeThread::getNumDataOutputs(DataChannel::DataChannelTypes type, int subIdx) const
 {
-    if (pDevInt->data_format == EcubeDevInt::dfSeparateChannelsAnalog)
-        return pDevInt->n_channel_objects;
-    else
-        return 0;
-}
-
-int EcubeThread::getNumAdcOutputs()
-{
-    if (pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog)
-        return 32;
-    else if (pDevInt->data_format == EcubeDevInt::dfDigital)
-        return 64;
-    else
-        return 0;
-}
-
-int EcubeThread::getNumAuxOutputs()
-{
-    return 0;
+	if (subIdx != 0) return 0;
+	if (type == DataChannel::HEADSTAGE_CHANNEL)
+	{
+		if (pDevInt->data_format == EcubeDevInt::dfSeparateChannelsAnalog)
+			return pDevInt->n_channel_objects;
+		else
+			return 0;
+	}
+	else if (type == DataChannel::ADC_CHANNEL)
+	{
+		if (pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog)
+			return 32;
+		else if (pDevInt->data_format == EcubeDevInt::dfDigital)
+			return 64;
+		else
+			return 0;
+	}
+	else return 0;
 }
 
 int EcubeThread::getNumChannels()
@@ -402,20 +401,21 @@ int EcubeThread::getNumChannels()
         return pDevInt->n_channel_objects;
 }
 
-int EcubeThread::getNumEventChannels()
+int EcubeThread::getNumTTLOutputs(int subIdx) const
 {
+	if (subIdx != 0) return 0;
     if (pDevInt->data_format == EcubeDevInt::dfDigital)
         return 64;
     else
         return 0;
 }
 
-float EcubeThread::getSampleRate()
+float EcubeThread::getSampleRate(int subIdx) const
 {
     return m_samplerate;
 }
 
-float EcubeThread::getBitVolts(int chan)
+float EcubeThread::getBitVolts(int chan) const
 {
     if (pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog || pDevInt->data_format == EcubeDevInt::dfDigital)
         return 10.0/32768; // Volts per bit for front panel analog input and fictive v/bit for the digital input
@@ -423,7 +423,7 @@ float EcubeThread::getBitVolts(int chan)
         return 6.25e3 / 32768; // Microvolts per bit for the headstage channels
 }
 
-float EcubeThread::getBitVolts(Channel* chan)
+float EcubeThread::getBitVolts(const DataChannel* chan) const
 {
     if (pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog || pDevInt->data_format == EcubeDevInt::dfDigital)
         return 10.0 / 32768; // Volts per bit for front panel analog input and fictive v/bit for the digital input
@@ -439,7 +439,7 @@ bool EcubeThread::foundInputSource()
 bool EcubeThread::updateBuffer()
 {
     unsigned long ba;
-    eventCode = 0;
+    ttlEventWords.set(0,0);
     int nchan = pDevInt->n_channel_objects;
 
     if (pDevInt->data_format == EcubeDevInt::dfSeparateChannelsAnalog || pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog)
@@ -477,7 +477,7 @@ bool EcubeThread::updateBuffer()
                             int64 cts = pDevInt->buf_timestamp64 / pDevInt->sampletime_80mhz; // Convert eCube 80MHz timestamp into a 25kHz timestamp
                             for (unsigned long j = 0; j < pDevInt->int_buf_size; j++)
                             {
-                                dataBuffer->addToBuffer(pDevInt->interleaving_buffer + j*nchan, &cts, &eventCode, 1);
+								sourceBuffers[0]->addToBuffer(pDevInt->interleaving_buffer + j*nchan, &cts, &ttlEventWords.getReference(0), 1);
                                 cts++;
                             }
                             // Update the 64-bit timestamp, take account of its wrap-around
@@ -527,7 +527,7 @@ bool EcubeThread::updateBuffer()
                     int64 cts = pDevInt->buf_timestamp64 / pDevInt->sampletime_80mhz; // Convert eCube's 80MHz timestamps into number of samples on the Panel Analog input (orig sample rate 1144)
                     for (unsigned long j = 0; j < datasam; j++)
                     {
-                        dataBuffer->addToBuffer(pDevInt->interleaving_buffer+j*32, &cts, &eventCode, 1);
+						sourceBuffers[0]->addToBuffer(pDevInt->interleaving_buffer + j * 32, &cts, &ttlEventWords.getReference(0), 1);
                         cts++;
                     }
                 }
@@ -545,7 +545,7 @@ bool EcubeThread::updateBuffer()
                             int64 cts = pDevInt->buf_timestamp64 / pDevInt->sampletime_80mhz; // Convert eCube 80MHz timestamp into a 25kHz timestamp
                             for (unsigned long j = 0; j < pDevInt->int_buf_size; j++)
                             {
-                                dataBuffer->addToBuffer(pDevInt->interleaving_buffer + j*64, &cts, pDevInt->event_buffer+j, 1);
+                                sourceBuffers[0]->addToBuffer(pDevInt->interleaving_buffer + j*64, &cts, pDevInt->event_buffer+j, 1);
                                 cts++;
                             }
                             // Update the 64-bit timestamp, take account of its wrap-around
diff --git a/Source/Plugins/EcubeSource/EcubeThread.h b/Source/Plugins/EcubeSource/EcubeThread.h
index b35fd282864095314676249d9152e0e2d019e3af..28d5b03fc2ed3614fbf933d9995aa6a4d2de2601 100644
--- a/Source/Plugins/EcubeSource/EcubeThread.h
+++ b/Source/Plugins/EcubeSource/EcubeThread.h
@@ -55,40 +55,36 @@ public:
 
     /** Fills the DataBuffer with incoming data. This is the most important
     method for each DataThread.*/
-    virtual bool updateBuffer();
+    bool updateBuffer() override;
 
     /** Returns true if the data source is connected, false otherwise.*/
-    virtual bool foundInputSource();
+    bool foundInputSource() override;
 
     /** Initializes data transfer.*/
-    virtual bool startAcquisition();
+    bool startAcquisition() override;
 
     /** Stops data transfer.*/
-    virtual bool stopAcquisition();
+    bool stopAcquisition() override;
 
-    /** Returns the number of continuous channels the data source can provide.*/
-    virtual int getNumChannels();
-
-    virtual int getNumHeadstageOutputs();
+	int getNumChannels();
 
-    virtual int getNumAdcOutputs();
-
-    virtual int getNumAuxOutputs();
+    /** Returns the number of continuous channels the data source can provide.*/
+    int getNumDataOutputs(DataChannel::DataChannelTypes type, int subIdx) const override;
 
-    /** Returns the number of event channels of the data source.*/
-    virtual int getNumEventChannels();
+	int getNumTTLOutputs(int subIdx) const override;
 
+    
     /** Returns the sample rate of the data source.*/
-    virtual float getSampleRate();
+    float getSampleRate(int subIdx) const override;
 
     /** Returns the volts per bit of a given data channel.*/
-    virtual float getBitVolts(int chan);
+    float getBitVolts(int chan) const;
 
-    virtual float getBitVolts(Channel* chan);
+    float getBitVolts(const DataChannel* chan) const override;
 
     void setDefaultNamingScheme(int scheme);
 
-    bool usesCustomNames();
+    bool usesCustomNames() const override;
 
     // Custom thread control functions
     void setSpeakerVolume(double volume);
@@ -96,7 +92,7 @@ public:
 
 private:
     int numberingScheme;
-    void setDefaultChannelNames();
+    void setDefaultChannelNames() override;
 
     ScopedPointer<EcubeDevInt> pDevInt;
 
diff --git a/Source/Plugins/EcubeSource/OpenEphysLib.cpp b/Source/Plugins/EcubeSource/OpenEphysLib.cpp
index e446f3c253bea18c7e9c999c04f563c26d27dab2..7804bf16c44c44a2887ab97b2e3a8cf067030f98 100644
--- a/Source/Plugins/EcubeSource/OpenEphysLib.cpp
+++ b/Source/Plugins/EcubeSource/OpenEphysLib.cpp
@@ -47,7 +47,7 @@ extern "C" EXPORT int getPluginInfo(int index, Plugin::PluginInfo* info)
 	switch (index)
 	{
 	case 0:
-		info->type = Plugin::DatathreadPlugin;
+		info->type = Plugin::PLUGIN_TYPE_DATA_THREAD;
 		info->dataThread.name = "eCube";
 		info->dataThread.creator = &createDataThread<EcubeThread>;
 		break;