From c30a21deccd3876a313c0edce8fbf4fa03bacaa7 Mon Sep 17 00:00:00 2001
From: Aaron Cuevas Lopez <aacuelo@teleco.upv.es>
Date: Wed, 4 Mar 2015 02:29:02 +0100
Subject: [PATCH] Make FPGA canvas able to work with latest code versions

---
 Source/Processors/DataThreads/DataThread.cpp  |  13 +
 Source/Processors/DataThreads/DataThread.h    |  48 ++-
 .../Processors/DataThreads/RHD2000Editor.cpp  | 198 +++++-----
 Source/Processors/DataThreads/RHD2000Editor.h |  14 +-
 .../Processors/DataThreads/RHD2000Thread.cpp  | 337 +++++++++---------
 Source/Processors/DataThreads/RHD2000Thread.h |  28 +-
 .../GenericProcessor/GenericProcessor.h       |  15 -
 Source/Processors/SourceNode/SourceNode.cpp   |  79 +---
 Source/Processors/SourceNode/SourceNode.h     |   7 +-
 9 files changed, 338 insertions(+), 401 deletions(-)

diff --git a/Source/Processors/DataThreads/DataThread.cpp b/Source/Processors/DataThreads/DataThread.cpp
index 5c6de4151..870c5b84b 100755
--- a/Source/Processors/DataThreads/DataThread.cpp
+++ b/Source/Processors/DataThreads/DataThread.cpp
@@ -70,3 +70,16 @@ DataBuffer* DataThread::getBufferAddress()
 }
 
 
+void DataThread::updateChannels()
+{
+	if (usesCustomNames())
+	{
+		channelInfo.resize(sn->channels.size());
+		setDefaultChannelNames();
+		for (int i = 0; i < channelInfo.size(); i++)
+		{
+			sn->channels[i]->setName(channelInfo[i].name);
+			sn->channels[i]->bitVolts = channelInfo[i].gain;
+		}
+	}
+}
\ No newline at end of file
diff --git a/Source/Processors/DataThreads/DataThread.h b/Source/Processors/DataThreads/DataThread.h
index d6ae6e3fa..9696fe955 100755
--- a/Source/Processors/DataThreads/DataThread.h
+++ b/Source/Processors/DataThreads/DataThread.h
@@ -31,6 +31,13 @@
 
 class SourceNode;
 
+struct ChannelCustomInfo {
+	ChannelCustomInfo() : gain(0), modified(false) {}
+	String name;
+	float gain;
+	bool modified;
+};
+
 /**
 
   Abstract base class for a data input thread owned by the SourceNode.
@@ -99,25 +106,28 @@ public:
     {
         return 0;
     }
-    virtual int modifyChannelName(ChannelType t, int stream, int ch, String newName)
+    virtual int modifyChannelName(int channel, String newName)
     {
         return -1;
     }
-    virtual int modifyChannelGain(ChannelType t, int stream, int ch, float gain)
+    virtual int modifyChannelGain(int channel, float gain)
     {
         return -1;
     }
-    virtual void setDefaultNamingScheme(int scheme)
-    {
-    }
 
-    virtual void getChannelsInfo(StringArray &Names, Array<ChannelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains)
+  /*  virtual void getChannelsInfo(StringArray &Names, Array<ChannelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains)
     {
-    };
+    }*/
+
     virtual void getEventChannelNames(StringArray &names)
     {
     }
 
+	virtual bool usesCustomNames()
+	{
+		return false;
+	}
+
     /** Returns the number of ADC channels of the data source.*/
     virtual int getNumADCchannels()
     {
@@ -125,14 +135,7 @@ public:
     }
 
     /** Changes the names of channels, if the thread needs custom names. */
-    virtual void updateChannelNames() { }
-
-    SourceNode* sn;
-
-    uint64 eventCode;
-    int64 timestamp;
-
-    Time timer;
+	void updateChannels();
 
     /** Returns a pointer to the data input device, in case other processors
     need to communicate with it.*/
@@ -141,8 +144,21 @@ public:
         return 0;
     }
 
-private:
 
+protected:
+	virtual void setDefaultChannelNames()
+	{
+	}
+
+	SourceNode* sn;
+
+	uint64 eventCode;
+	int64 timestamp;
+
+	Array<ChannelCustomInfo> channelInfo;
+
+private:
+	Time timer;
 
 
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DataThread);
diff --git a/Source/Processors/DataThreads/RHD2000Editor.cpp b/Source/Processors/DataThreads/RHD2000Editor.cpp
index a5b932184..e8043fcb2 100644
--- a/Source/Processors/DataThreads/RHD2000Editor.cpp
+++ b/Source/Processors/DataThreads/RHD2000Editor.cpp
@@ -39,8 +39,9 @@ inline double round(double x)
 #endif
 #endif
 
-FPGAchannelList::FPGAchannelList(GenericProcessor* proc_, Viewport* p, FPGAcanvas* c) : proc(proc_), viewport(p), canvas(c)
+FPGAchannelList::FPGAchannelList(GenericProcessor* proc_, Viewport* p, FPGAcanvas* c) : viewport(p), canvas(c), chainUpdate(false)
 {
+	proc = (SourceNode*)proc_;
     channelComponents.clear();
 
     numberingSchemeLabel = new Label("Numbering scheme:","Numbering scheme:");
@@ -121,39 +122,53 @@ void FPGAchannelList::buttonClicked(Button* btn)
 
 void FPGAchannelList::update()
 {
+	const int columnWidth = 330;
     // Query processor for number of channels, types, gains, etc... and update the UI
     channelComponents.clear();
     staticLabels.clear();
-    StringArray names;
-    Array<float> oldgains;
-    proc->getChannelsInfo(names,types,stream,orig_number,oldgains);
-    int numChannels = names.size();
+
+	RHD2000Thread* thread = (RHD2000Thread*)proc->getThread();
+	ChannelType type;
 
     // find out which streams are active.
-    bool streamActive[MAX_NUM_DATA_STREAMS+1];
+    bool hsActive[MAX_NUM_HEADSTAGES+1];
     bool adcActive = false;
-    int numActiveStreams = 0;
-    int streamColumn[MAX_NUM_DATA_STREAMS+1];
-    int numChannelsPerStream[MAX_NUM_DATA_STREAMS+1];
-
-    for (int k=0; k<MAX_NUM_DATA_STREAMS+1; k++)
-    {
-        numChannelsPerStream[k] = 0;
-        streamActive[k] = false;
-        streamColumn[k] = 0;
-    }
-    int columnWidth = 330;
+    int numActiveHeadstages = 0;
+	int hsColumn[MAX_NUM_HEADSTAGES + 1];
+	int numChannelsPerHeadstage[MAX_NUM_HEADSTAGES + 1];
+	chainUpdate = false;
 
-    for (int k=0; k<numChannels; k++)
+	for (int k = 0; k<MAX_NUM_HEADSTAGES; k++)
     {
-        if (streamActive[stream[k]] == false)
-        {
-            streamColumn[stream[k]] = numActiveStreams*columnWidth;
-            numActiveStreams++;
-            streamActive[stream[k]] = true;
-        }
+		if (thread->isHeadstageEnabled(k))
+		{
+			numChannelsPerHeadstage[k] = thread->getActiveChannelsInHeadstage(k);
+			hsActive[k] = true;
+			hsColumn[k] = numActiveHeadstages*columnWidth;
+			numActiveHeadstages++;
+		}
+		else
+		{
+			numChannelsPerHeadstage[k] = 0;
+			hsActive[k] = false;
+			hsColumn[k] = 0;
+		}
     }
-
+    
+	if (thread->getNumAdcOutputs() > 0)
+	{
+		numChannelsPerHeadstage[MAX_NUM_HEADSTAGES] = thread->getNumAdcOutputs();
+		hsActive[MAX_NUM_HEADSTAGES] = true;
+		hsColumn[MAX_NUM_HEADSTAGES] = numActiveHeadstages*columnWidth;
+		numActiveHeadstages++;
+	}
+	else
+	{
+		numChannelsPerHeadstage[MAX_NUM_HEADSTAGES] = 0;
+		hsActive[MAX_NUM_HEADSTAGES] = false;
+		hsColumn[MAX_NUM_HEADSTAGES] = 0;
+	}
+   
     StringArray streamNames;
     streamNames.add("Port A1");
     streamNames.add("Port A2");
@@ -167,11 +182,11 @@ void FPGAchannelList::update()
 
     for (int k = 0; k < MAX_NUM_DATA_STREAMS + 1; k++)
     {
-        if (streamActive[k])
+        if (hsActive[k])
         {
             Label* lbl = new Label(streamNames[k],streamNames[k]);
             lbl->setEditable(false);
-            lbl->setBounds(10+streamColumn[k],40,columnWidth, 25);
+            lbl->setBounds(10+hsColumn[k],40,columnWidth, 25);
             lbl->setJustificationType(juce::Justification::centred);
             lbl->setColour(Label::textColourId,juce::Colours::white);
             staticLabels.add(lbl);
@@ -181,36 +196,45 @@ void FPGAchannelList::update()
 
     }
 
-    // add buttons for all DATA, AUX, channels
-    for (int k = 0; k < numChannels; k++)
-    {
-        int channelGainIndex = 1;
-		float ch_gain = 1.0f; ///%oldgains[k]/static_cast<SourceNode*>(proc)->getBitVolts(k);
-        for (int j = 0; j < gains.size(); j++)
-        {
-            if (fabs(gains[j]-ch_gain) < 1e-3)
-            {
-                channelGainIndex = j;
-                break;
-            }
-        }
-
-        FPGAchannelComponent* comp = new FPGAchannelComponent(this, stream[k],orig_number[k],types[k],channelGainIndex+1, names[k],gains);
-        comp->setBounds(10+streamColumn[stream[k]],70+numChannelsPerStream[stream[k]]*22,columnWidth,22);
-        numChannelsPerStream[stream[k]]++;
-
-        comp->setUserDefinedData(k);
-        addAndMakeVisible(comp);
-        channelComponents.add(comp);
-    }
+	for (int k = 0; k < MAX_NUM_HEADSTAGES + 1; k++)
+	{
+		if (hsActive[k])
+		{
+			for (int ch = 0; ch < numChannelsPerHeadstage[k]+ (k < MAX_NUM_HEADSTAGES ? 3 : 0); ch++)
+			{
+				int channelGainIndex = 1;
+				int realChan = thread->getChannelFromHeadstage(k, ch);
+				float ch_gain = proc->channels[realChan]->getBitVolts() / proc->getBitVolts(proc->channels[realChan]);
+				for (int j = 0; j < gains.size(); j++)
+				{
+					if (fabs(gains[j] - ch_gain) < 1e-3)
+					{
+						channelGainIndex = j;
+						break;
+					}
+				}
+				if (k < MAX_NUM_HEADSTAGES)
+					type = ch < numChannelsPerHeadstage[k] ? HEADSTAGE_CHANNEL : AUX_CHANNEL;
+				else
+					type = ADC_CHANNEL;
+
+				FPGAchannelComponent* comp = new FPGAchannelComponent(this, realChan, channelGainIndex + 1, thread->getChannelName(realChan), gains,type);
+				comp->setBounds(10 + hsColumn[k], 70 + ch * 22, columnWidth, 22);
+				comp->setUserDefinedData(k);
+				addAndMakeVisible(comp);
+				channelComponents.add(comp);
+			}
+		}
+	}
 
+    
     StringArray ttlNames;
     proc->getEventChannelNames(ttlNames);
     // add buttons for TTL channels
     for (int k=0; k<ttlNames.size(); k++)
     {
-        FPGAchannelComponent* comp = new FPGAchannelComponent(this,-1,k, EVENT_CHANNEL,-1, ttlNames[k],gains);
-        comp->setBounds(10+numActiveStreams*columnWidth,70+k*22,columnWidth,22);
+        FPGAchannelComponent* comp = new FPGAchannelComponent(this,k, -1, ttlNames[k],gains,EVENT_CHANNEL);
+        comp->setBounds(10+numActiveHeadstages*columnWidth,70+k*22,columnWidth,22);
         comp->setUserDefinedData(k);
         addAndMakeVisible(comp);
         channelComponents.add(comp);
@@ -218,13 +242,13 @@ void FPGAchannelList::update()
 
     Label* lbl = new Label("TTL Events","TTL Events");
     lbl->setEditable(false);
-    lbl->setBounds(numActiveStreams*columnWidth,40,columnWidth, 25);
+    lbl->setBounds(numActiveHeadstages*columnWidth,40,columnWidth, 25);
     lbl->setJustificationType(juce::Justification::centred);
     lbl->setColour(Label::textColourId,juce::Colours::white);
     staticLabels.add(lbl);
     addAndMakeVisible(lbl);
 
-
+	chainUpdate = true;
 }
 
 void FPGAchannelList::disableAll()
@@ -244,27 +268,20 @@ void FPGAchannelList::enableAll()
 
 }
 
-void FPGAchannelList::setNewGain(int stream, int channel, ChannelType type, float gain)
+void FPGAchannelList::setNewGain(int channel, float gain)
 {
-    float newGain;
-	int realChan;
-	SourceNode* p = (SourceNode*) proc;
-
-	if (type==ADC_CHANNEL)
-	{
-		realChan = p->getNumOutputs()-p->getThread()->getNumADCchannels()+channel;
-	}
-	else
-	{
-		realChan = channel;
-	}
-	//newGain = p->getBitVolts(realChan)*gain;
-    p->modifyChannelGain(stream, channel, type, newGain, true);
+	RHD2000Thread* thread = (RHD2000Thread*)proc->getThread();
+	thread->modifyChannelGain(channel, gain);
+	if (chainUpdate)
+		proc->requestChainUpdate();
 }
 
-void FPGAchannelList::setNewName(int stream, int channelIndex, ChannelType t, String newName)
+void FPGAchannelList::setNewName(int channel, String newName)
 {
-    proc->modifyChannelName(t, stream, channelIndex, newName, true);
+	RHD2000Thread* thread = (RHD2000Thread*)proc->getThread();
+	thread->modifyChannelName(channel, newName);
+	if (chainUpdate)
+		proc->requestChainUpdate();    
 }
 
 void FPGAchannelList::updateButtons()
@@ -281,17 +298,11 @@ void FPGAchannelList::comboBoxChanged(ComboBox* b)
     if (b == numberingScheme)
     {
         SourceNode* p = (SourceNode*)proc;
+		RHD2000Thread* thread = (RHD2000Thread*)p->getThread();
         int scheme = numberingScheme->getSelectedId();
-        if (scheme == 1)
-        {
-            p->setDefaultNamingScheme(scheme);
-        }
-        else if (scheme == 2)
-        {
-            p->setDefaultNamingScheme(scheme);
-        }
+		thread->setDefaultNamingScheme(scheme);
         update();
-		canvas->processor->getEditorViewport()->makeEditorVisible(canvas->processor->getEditor(),false,true);
+		p->requestChainUpdate();
     }
 }
 
@@ -314,7 +325,8 @@ void FPGAchannelList::updateImpedance(Array<int> streams, Array<int> channels, A
 
 
 /****************************************************/
-FPGAchannelComponent::FPGAchannelComponent(FPGAchannelList* cl, int stream_, int ch, ChannelType t, int gainIndex_, String N, Array<float> gains_) :   gains(gains_), channelList(cl), channel(ch), name(N), stream(stream_), type(t), gainIndex(gainIndex_)
+FPGAchannelComponent::FPGAchannelComponent(FPGAchannelList* cl, int ch, int gainIndex_, String N, Array<float> gains_, ChannelType type) :  
+	gains(gains_), channelList(cl), channel(ch), name(N), gainIndex(gainIndex_)
 {
     Font f = Font("Small Text", 13, Font::plain);
 
@@ -344,7 +356,7 @@ FPGAchannelComponent::FPGAchannelComponent(FPGAchannelList* cl, int stream_, int
                 gainComboBox->addItem("x"+String((int)gains[k]),k+1);
             }
         }
-        gainComboBox->setSelectedId(gainIndex, sendNotification);
+        gainComboBox->setSelectedId(gainIndex, sendNotificationSync);
         gainComboBox->addListener(this);
         addAndMakeVisible(gainComboBox);
     }
@@ -393,15 +405,15 @@ void FPGAchannelComponent::comboBoxChanged(ComboBox* comboBox)
     {
         int newGainIndex = gainComboBox->getSelectedId();
         float mult = gains[newGainIndex-1];
-        float bitvolts = channelList->proc->getDefaultBitVolts();
-        channelList->setNewGain(stream,channel,type, mult*bitvolts);
+		float bitvolts = channelList->proc->getBitVolts(channelList->proc->channels[channel]);
+        channelList->setNewGain(channel, mult*bitvolts);
     }
 }
 void FPGAchannelComponent::labelTextChanged(Label* lbl)
 {
     // channel name change
     String newName = lbl->getText();
-    channelList->setNewName(stream,channel, type, newName);
+    channelList->setNewName(channel, newName);
 }
 
 void FPGAchannelComponent::disableEdit()
@@ -445,9 +457,9 @@ void FPGAchannelComponent::resized()
 
 /**********************************************/
 
-FPGAcanvas::FPGAcanvas(GenericProcessor* n) : processor(n)
+FPGAcanvas::FPGAcanvas(GenericProcessor* n) 
 {
-
+	processor = (SourceNode*)n;
     channelsViewport = new Viewport();
     channelList = new FPGAchannelList(processor, channelsViewport, this);
     channelsViewport->setViewedComponent(channelList, false);
@@ -710,7 +722,7 @@ void RHD2000Editor::measureImpedance()
 		for (int i = 0; i < channel.size(); i++)
 		{
 			XmlElement* chan = new XmlElement("CHANNEL");
-			chan->setAttribute("name",board->getChannelName(HEADSTAGE_CHANNEL,stream[i],channel[i]));
+			chan->setAttribute("name",board->getChannelName(i));
 			chan->setAttribute("stream",stream[i]);
 			chan->setAttribute("channel_number",channel[i]);
 			chan->setAttribute("magnitude",magnitude[i]);
@@ -1199,7 +1211,7 @@ void HeadstageOptionsInterface::checkEnabledState()
 
     if (board->isHeadstageEnabled(hsNumber1))
     {
-		channelsOnHs1 = board->getChannelsInHeadstage(hsNumber1);
+		channelsOnHs1 = board->getActiveChannelsInHeadstage(hsNumber1);
         hsButton1->setLabel(String(channelsOnHs1));
         hsButton1->setEnabledState(true);
     }
@@ -1212,7 +1224,7 @@ void HeadstageOptionsInterface::checkEnabledState()
 
     if (board->isHeadstageEnabled(hsNumber2))
     {
-        channelsOnHs2 = board->getChannelsInHeadstage(hsNumber2);
+        channelsOnHs2 = board->getActiveChannelsInHeadstage(hsNumber2);
         hsButton2->setLabel(String(channelsOnHs2));
         hsButton2->setEnabledState(true);
     }
@@ -1234,7 +1246,7 @@ void HeadstageOptionsInterface::buttonClicked(Button* button)
     {
 
         //std::cout << "Acquisition is not active" << std::endl;
-		if ((button == hsButton1) && (board->getChannelsInHeadstage(hsNumber1)))
+		if ((button == hsButton1) && (board->getChannelsInHeadstage(hsNumber1) == 32))
         {
             if (channelsOnHs1 == 32)
                 channelsOnHs1 = 16;
@@ -1246,11 +1258,11 @@ void HeadstageOptionsInterface::buttonClicked(Button* button)
             hsButton1->setLabel(String(channelsOnHs1));
             board->setNumChannels(hsNumber1, channelsOnHs1);
 
-            board->updateChannelNames();
+            //board->updateChannels();
             editor->updateSettings();
 
         }
-		else if ((button == hsButton2) && (board->getChannelsInHeadstage(hsNumber2)))
+		else if ((button == hsButton2) && (board->getChannelsInHeadstage(hsNumber2) == 32))
         {
             if (channelsOnHs2 == 32)
                 channelsOnHs2 = 16;
@@ -1259,7 +1271,7 @@ void HeadstageOptionsInterface::buttonClicked(Button* button)
 
             hsButton2->setLabel(String(channelsOnHs2));
             board->setNumChannels(hsNumber2, channelsOnHs2);
-            board->updateChannelNames();
+            //board->updateChannels();
             editor->updateSettings();
         }
 
diff --git a/Source/Processors/DataThreads/RHD2000Editor.h b/Source/Processors/DataThreads/RHD2000Editor.h
index 6a997b6c5..ef8bea165 100644
--- a/Source/Processors/DataThreads/RHD2000Editor.h
+++ b/Source/Processors/DataThreads/RHD2000Editor.h
@@ -59,8 +59,8 @@ public:
     
     FPGAchannelList(GenericProcessor* proc, Viewport *p, FPGAcanvas*c);
     ~FPGAchannelList();
-    void setNewName(int stream, int channelIndex, ChannelType t, String newName);
-    void setNewGain(int stream, int channel, ChannelType t, float gain);
+    void setNewName(int channelIndex, String newName);
+	void setNewGain(int channel, float gain);
     void disableAll();
     void enableAll();
     void paint(Graphics& g);
@@ -70,7 +70,7 @@ public:
     int getNumChannels();
     void comboBoxChanged(ComboBox *b);
     void updateImpedance(Array<int> streams, Array<int> channels, Array<float> magnitude, Array<float> phase);
-    GenericProcessor* proc;
+    SourceNode* proc;
     
 private:
     Array<float> gains;
@@ -78,6 +78,8 @@ private:
     Array<int> stream;
     Array<int> orig_number;
 
+	bool chainUpdate;
+
     Viewport *viewport;
     FPGAcanvas *canvas;
     ScopedPointer<UtilityButton> impedanceButton;
@@ -94,7 +96,7 @@ private:
 class FPGAchannelComponent : public Component, public AccessClass, Button::Listener, public ComboBox::Listener, public Label::Listener
 {
 public:
-    FPGAchannelComponent(FPGAchannelList* cl,int stream, int ch, ChannelType t,  int gainIndex_, String name_, Array<float> gains_);
+    FPGAchannelComponent(FPGAchannelList* cl, int ch, int gainIndex_, String name_, Array<float> gains_, ChannelType type);
     ~FPGAchannelComponent();
     Colour getDefaultColor(int ID);
     void setImpedanceValues(float mag, float phase);
@@ -121,8 +123,6 @@ private:
     ScopedPointer<ComboBox> gainComboBox;
     int channel;
     String name;
-    int stream;
-    ChannelType type;
     int gainIndex;
     int userDefinedData;
     Font font;
@@ -155,7 +155,7 @@ public:
     void resized();
     void buttonClicked(Button* button);
     ScopedPointer<Viewport> channelsViewport;
-    GenericProcessor* processor;
+    SourceNode* processor;
     ScopedPointer<FPGAchannelList> channelList;
 };
 
diff --git a/Source/Processors/DataThreads/RHD2000Thread.cpp b/Source/Processors/DataThreads/RHD2000Thread.cpp
index bbc9ecaae..581efe267 100644
--- a/Source/Processors/DataThreads/RHD2000Thread.cpp
+++ b/Source/Processors/DataThreads/RHD2000Thread.cpp
@@ -79,7 +79,8 @@ RHD2000Thread::RHD2000Thread(SourceNode* sn) : DataThread(sn),
     boardSampleRate(30000.0f),
     savedSampleRateIndex(16),
     cableLengthPortA(0.914f), cableLengthPortB(0.914f), cableLengthPortC(0.914f), cableLengthPortD(0.914f), // default is 3 feet (0.914 m),
-    audioOutputL(-1), audioOutputR(-1) ,numberingScheme(1)
+    audioOutputL(-1), audioOutputR(-1) ,numberingScheme(1),
+	newScan(true)
 {
 
 	for (int i=0; i < MAX_NUM_HEADSTAGES; i++)
@@ -145,7 +146,7 @@ RHD2000Thread::RHD2000Thread(SourceNode* sn) : DataThread(sn),
 
        // evalBoard->getDacInformation(dacChannels,dacThresholds);
 
-		//sn->setDefaultNamingScheme(numberingScheme);
+	//	setDefaultNamingScheme(numberingScheme);
         //setDefaultChannelNamesAndType();
     }
 }
@@ -180,6 +181,11 @@ RHD2000Thread::~RHD2000Thread()
 
 }
 
+bool RHD2000Thread::usesCustomNames()
+{
+	return true;
+}
+
 void RHD2000Thread::setDACthreshold(int dacOutput, float threshold)
 {
     dacThresholds[dacOutput]= threshold;
@@ -648,6 +654,7 @@ void RHD2000Thread::scanPorts()
 
     setSampleRate(savedSampleRateIndex); // restore saved sample rate
     //updateRegisters();
+	newScan = true;
 }
 
 int RHD2000Thread::deviceId(Rhd2000DataBlock* dataBlock, int stream, int &register59Value)
@@ -712,142 +719,45 @@ void RHD2000Thread::getEventChannelNames(StringArray& Names)
     }
 }
 
-void RHD2000Thread::getChannelsInfo(StringArray& Names_, Array<ChannelType>& type_, Array<int>& stream_, Array<int>& originalChannelNumber_,Array<float>& gains_)
-{
-    Names_ = Names;
-    type_ = type;
-    stream_ = stream;
-    originalChannelNumber_ = originalChannelNumber;
-    gains_ = gains;
-}
-
-void RHD2000Thread::updateChannelNames()
-{
-    setDefaultChannelNamesAndType();
-
-	for (int i = 0; i < sn->channels.size(); i++)
-	{
-		sn->channels[i]->setName(Names[i]);
-		sn->channels[i]->bitVolts = gains[i];
-		sn->channels[i]->setType(type[i]);
-	}
-}
 
 /* go over the old names and tests whether this particular channel name was changed.
 if so, return the old name */
-bool RHD2000Thread::channelModified(ChannelType t, int str, int ch, String& oldName, float& oldGain, int& index)
-{
-    for (int k = 0; k < oldNames.size(); k++)
-    {
-        if (oldType[k] == t && oldStream[k] == str && oldChannelNumber[k] == ch)
-        {
-            oldName = oldNames[k];
-            oldGain = oldGains[k];
-            index = k;
-            return true;
-        }
-    }
-    return false;
-}
 
 
-int RHD2000Thread::modifyChannelName(ChannelType t, int str, int ch, String newName)
+int RHD2000Thread::modifyChannelName(int channel, String newName)
 {
-    String dummy;
-    float dummyFloat = 0;
-    int index;
-    if (channelModified(t, str, ch, dummy, dummyFloat, index))
-    {
-        oldNames.set(index, newName);
-    }
-    else
-    {
-  //       oldNames.add(newName);
-  //       oldType.add(t);
-  //       oldStream.add(str);
-  //       oldChannelNumber.add(ch);
-		// if (t == ADC_CHANNEL)
-		// 	oldGains.add(gains[getNumChannels()-getNumADCchannels()+ch]);
-		// else
-		// 	oldGains.add(gains[ch]);
-    }
-
-    for (int k = 0; k < Names.size(); k++)
-    {
-        if (type[k] == t && stream[k] == str && originalChannelNumber[k] == ch)
-        {
-            Names.set(k,newName);
-            return k;
-        }
-    }
-    return -1;
+	ChannelCustomInfo i = channelInfo[channel];
+	i.name = newName;
+	i.modified = true;
+	channelInfo.set(channel, i);
+    return 0;
 }
 
-String RHD2000Thread::getChannelName(ChannelType t, int str, int ch)
+String RHD2000Thread::getChannelName(int ch)
 {
-	for (int k=0; k<Names.size(); k++)
-    {
-        if (type[k] == t && stream[k] == str && originalChannelNumber[k] == ch)
-        {
-            return Names[k];
-        }
-    }
+	return channelInfo[ch].name;
 }
 
-int RHD2000Thread::modifyChannelGain(ChannelType t, int str, int ch, float gain)
+int RHD2000Thread::modifyChannelGain(int channel, float gain)
 {
-    String dummy;
-    float dummyFloat = 0;
-    int index;
-    if (channelModified(t, str, ch, dummy, dummyFloat, index))
-    {
-        oldGains.set(index, gain);
-    }
-    else
-    {
-
-		if (t == ADC_CHANNEL)
-			oldNames.add(Names[getNumChannels()-getNumADCchannels()+ch]);
-		else
-			oldNames.add(getChannelName(t,str,ch));
-        oldType.add(t);
-        oldStream.add(str);
-        oldChannelNumber.add(ch);
-        oldGains.add(gain);
-
-    }
-
-    for (int k=0; k<Names.size(); k++)
-    {
-        if (type[k] == t && stream[k] == str && originalChannelNumber[k] == ch)
-        {
-            gains.set(k,gain);
-            return k;
-        }
-    }
-    return -1;
+	ChannelCustomInfo i = channelInfo[channel];
+	i.gain = gain;
+	i.modified = true;
+	channelInfo.set(channel, i);
+	return 0;
 }
 
 void RHD2000Thread::setDefaultNamingScheme(int scheme)
 {
-    oldNames.clear();
-    oldType.clear();
-    oldStream.clear();
-    oldGains.clear();
-    oldChannelNumber.clear();
     numberingScheme = scheme;
-    setDefaultChannelNamesAndType();
+	newScan = true; //if the scheme is changed, reset all names
+    setDefaultChannelNames();
 }
 
 /* This will give default names & gains to channels, unless they were manually modified by the user
  In that case, the query channelModified, will return the values that need to be put */
-void RHD2000Thread::setDefaultChannelNamesAndType()
+void RHD2000Thread::setDefaultChannelNames()
 {
-    Names.clear();
-    type.clear();
-    stream.clear();
-    gains.clear();
-    originalChannelNumber.clear();
     int aux_counter = 1;
     int channelNumber = 1;
     String oldName;
@@ -867,29 +777,20 @@ void RHD2000Thread::setDefaultChannelNamesAndType()
     {
 		if (headstagesArray[i]->isPlugged())
         {
-			for (int k = 0; k < headstagesArray[i]->getNumChannels(); k++)
+			for (int k = 0; k < headstagesArray[i]->getNumActiveChannels(); k++)
             {
-                type.add(HEADSTAGE_CHANNEL);
-
-                if (channelModified(HEADSTAGE_CHANNEL,i,k, oldName,oldGain,dummy))
-                {
-                    Names.add(oldName);
-                    gains.add(oldGain);
-                    channelNumber++;
-                }
-                else
-                {
-                    if (numberingScheme == 1)
-                        Names.add("CH"+String(channelNumber++));
-                    else
-                        Names.add("CH_"+stream_prefix[i]+"_"+String(1+k));
-
-                   // gains.add(getBitVolts(channelNumber));
-                }
-                
-                stream.add(i);
-                originalChannelNumber.add(k);
+				if (newScan || !channelInfo[k].modified)
+				{
+					ChannelCustomInfo in;
+					if (numberingScheme == 1)
+						in.name = "CH" + String(channelNumber);
+					else
+						in.name = "CH_" + stream_prefix[i] + "_" + String(1 + k);
+					in.gain = getBitVolts(sn->channels[k]);
+					channelInfo.set(k, in);
 
+				}
+				channelNumber++;
             }
         }
     }
@@ -900,29 +801,21 @@ void RHD2000Thread::setDefaultChannelNamesAndType()
         {
 			for (int k = 0; k < 3; k++)
 		        {
+					int chn = channelNumber - 1;
 
-		            type.add(AUX_CHANNEL);
-
-		            if (channelModified(AUX_CHANNEL,i,headstagesArray[i]->getNumChannels()+k, oldName,oldGain, dummy))
-		            {
-		                Names.add(oldName);
-		                gains.add(oldGain);
-
-		                aux_counter++;
-		            }
-		            else
-		            {
-		                if (numberingScheme == 1)
-		                    Names.add("AUX"+String(aux_counter++));
-		                else
-		                    Names.add("AUX_"+stream_prefix[i]+"_"+String(1+k));
-
-		                gains.add(0.0000374);
-
-		            }
+					if (newScan || !channelInfo[chn].modified)
+					{
+						ChannelCustomInfo in;
+						if (numberingScheme == 1)
+							in.name = "AUX" + String(aux_counter);
+						else
+							in.name = "AUX_" + stream_prefix[i] + "_" + String(1 + k);
+						in.gain = getBitVolts(sn->channels[chn]);
+						channelInfo.set(chn, in);
 
-		            stream.add(i);
-		            originalChannelNumber.add(headstagesArray[i]->getNumChannels()+k);
+					}
+					channelNumber++;
+					aux_counter++;
 		        }
 		 }
 	}
@@ -931,27 +824,18 @@ void RHD2000Thread::setDefaultChannelNamesAndType()
     {
         for (int k = 0; k < 8; k++)
         {
-
-            channelNumber++;
-            type.add(ADC_CHANNEL);
-
-			if (channelModified(ADC_CHANNEL,MAX_NUM_HEADSTAGES,k, oldName,oldGain,dummy))
-            {
-                Names.add(oldName);
-                gains.add(oldGain);
-            }
-            else
-            {
-                Names.add("ADC" + String(k+1));
-                gains.add(getAdcBitVolts(k));
-            }
-            
-            stream.add(MAX_NUM_HEADSTAGES);
-            originalChannelNumber.add(k);
-
+			int chn = channelNumber - 1;
+			if (newScan || !channelInfo[chn].modified)
+			{
+				ChannelCustomInfo in;
+				in.name = "ADC" + String(k + 1);
+				in.gain = getAdcBitVolts(k);
+				channelInfo.set(chn, in);
+			}
+			channelNumber++;
         }
     }
-
+	newScan = false;
 }
 
 int RHD2000Thread::getNumChannels()
@@ -1189,6 +1073,11 @@ bool RHD2000Thread::isHeadstageEnabled(int hsNum)
 
 }
 
+int RHD2000Thread::getActiveChannelsInHeadstage(int hsNum)
+{
+	return headstagesArray[hsNum]->getNumActiveChannels();
+}
+
 int RHD2000Thread::getChannelsInHeadstage(int hsNum)
 {
 	return headstagesArray[hsNum]->getNumChannels();
@@ -2187,6 +2076,100 @@ void RHD2000Thread::runImpedanceTest(Array<int>& streams, Array<int>& channels,
     }
 }
 
+int RHD2000Thread::getChannelFromHeadstage(int hs, int ch)
+{
+	int channelCount = 0;
+	int hsCount = 0;
+	if (hs < 0 || hs >= MAX_NUM_HEADSTAGES+1)
+		return -1;
+	if (hs == MAX_NUM_HEADSTAGES) //let's consider this the ADC channels
+	{
+		if (getNumAdcOutputs() > 0)
+		{
+			return getNumHeadstageOutputs() + getNumAuxOutputs() + ch;
+		}
+		else
+			return -1;
+	}
+	if (headstagesArray[hs]->isPlugged())
+	{
+		if (ch < 0)
+			return -1;
+		 if (ch < headstagesArray[hs]->getNumActiveChannels())
+		{
+			for (int i = 0; i < hs; i++)
+			{
+				channelCount += headstagesArray[i]->getNumActiveChannels();
+			}
+			return channelCount + ch;
+		}
+		 else if (ch < headstagesArray[hs]->getNumActiveChannels() + 3)
+		 {
+			 for (int i = 0; i < MAX_NUM_HEADSTAGES; i++)
+			 {
+				 if (headstagesArray[i]->isPlugged())
+				 {
+					 channelCount += headstagesArray[i]->getNumActiveChannels();
+					 if (i < hs)
+						 hsCount++;
+				 }
+				 return channelCount + hsCount * 3 + ch;
+			 }
+		 }
+		 else
+		 {
+			 return -1;
+		 }
+
+	}
+	else
+	{
+		return -1;
+	}
+}
+
+int RHD2000Thread::getHeadstageChannel(int& hs, int ch)
+{
+	int channelCount = 0;
+	int hsCount = 0;
+
+	if (ch < 0)
+		return -1;
+	
+	for (int i = 0; i < MAX_NUM_HEADSTAGES; i++)
+	{
+		if (headstagesArray[i]->isPlugged())
+		{
+			int chans = headstagesArray[hs]->getNumActiveChannels();
+			if (ch >= channelCount && ch < channelCount + chans)
+			{
+				hs = i;
+				return ch - channelCount;
+			}
+			channelCount += chans;
+			hsCount++;
+		}
+	}
+	if (ch < (channelCount + hsCount * 3)) //AUX
+	{
+		hsCount = (ch - channelCount) / 3;
+		for (int i = 0; i < MAX_NUM_HEADSTAGES; i++)
+		{
+			if (headstagesArray[i]->isPlugged())
+			{
+				if (hsCount == 0)
+				{
+					hs = i;
+					return ch - channelCount;
+				}
+				hsCount--;
+				channelCount++;
+			}
+		}
+	}
+	return -1;
+}
+
 
 RHDHeadstage::RHDHeadstage(Rhd2000EvalBoard::BoardDataSource stream) : 
 numStreams(0), channelsPerStream(32), dataStream(stream), halfChannels(false)
diff --git a/Source/Processors/DataThreads/RHD2000Thread.h b/Source/Processors/DataThreads/RHD2000Thread.h
index 9a5bd3cf6..cd05cc707 100644
--- a/Source/Processors/DataThreads/RHD2000Thread.h
+++ b/Source/Processors/DataThreads/RHD2000Thread.h
@@ -106,19 +106,24 @@ public:
 
     bool isAcquisitionActive();
     
-    virtual int modifyChannelGain(ChannelType t, int str, int ch, float gain);
-    virtual int modifyChannelName(ChannelType t, int str, int k, String newName);
-    virtual void getChannelsInfo(StringArray &Names, Array<ChannelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains);
-    virtual void getEventChannelNames(StringArray &Names);
-    void updateChannelNames();
+    int modifyChannelGain(int channel, float gain);
+    int modifyChannelName(int channel, String newName);
+    void getEventChannelNames(StringArray &Names);
     Array<int> getDACchannels();
     void setDACchannel(int dacOutput, int stream, int channel);
     void setDACthreshold(int dacOutput, float threshold);
     void setDefaultNamingScheme(int scheme);
 
-	String getChannelName(ChannelType t, int str, int ch);
+	String getChannelName(int ch);
 	void setNumChannels(int hsNum, int nChannels);
 	int getHeadstageChannels(int hsNum);
+	int getActiveChannelsInHeadstage(int hsNum);
+	bool usesCustomNames();
+	
+	/* Gets the absolute channel index from the headstage channel index*/
+	int getChannelFromHeadstage(int hs, int ch);
+	/*Gets the headstage relative channel index from the absolute channel index*/
+	int getHeadstageChannel(int& hs, int ch);
 
 private:
 
@@ -126,8 +131,7 @@ private:
 	void updateBoardStreams();
     void setCableLength(int hsNum, float length);
 
-    void setDefaultChannelNamesAndType();
-    bool channelModified(ChannelType t, int str, int k, String &oldName, float &oldGain, int &index);
+    void setDefaultChannelNames();
 
     ScopedPointer<Rhd2000EvalBoard> evalBoard;
     Rhd2000Registers chipRegisters;
@@ -197,14 +201,8 @@ private:
 
     // used for data stream names...
     int numberingScheme ;
-    StringArray Names, oldNames;
-    Array<ChannelType> type, oldType;
-    Array<float> gains, oldGains;
     Array<float> adcBitVolts;
-    Array<int> stream, oldStream;
-    Array<bool> modifiedName, oldModifiedName;
-    Array<int> originalChannelNumber, oldChannelNumber;
-
+	bool newScan;
 
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RHD2000Thread);
 };
diff --git a/Source/Processors/GenericProcessor/GenericProcessor.h b/Source/Processors/GenericProcessor/GenericProcessor.h
index 9da3ee596..16d0dae42 100755
--- a/Source/Processors/GenericProcessor/GenericProcessor.h
+++ b/Source/Processors/GenericProcessor/GenericProcessor.h
@@ -139,21 +139,6 @@ public:
         return GenericProcessor::unusedNameString;
     }
 
-    /** returns the names and types of all data, aux and adc channels */
-    virtual void getChannelsInfo(StringArray& Names, Array<ChannelType>& type, Array<int>& stream, Array<int>& originalChannelNumber, Array<float>& gains)
-    {
-
-    }
-
-    virtual int modifyChannelName(ChannelType t, int stream, int ch, String newName, bool updateSignalChain)
-    {
-        return -1;
-    }
-
-    virtual int modifyChannelGain(ChannelType t, int stream, int ch, float newGain, bool updateSignalChain)
-    {
-        return -1;
-    }
     virtual void getEventChannelNames(StringArray& Names)
     {
     }
diff --git a/Source/Processors/SourceNode/SourceNode.cpp b/Source/Processors/SourceNode/SourceNode.cpp
index 59860e098..d8c568fc9 100755
--- a/Source/Processors/SourceNode/SourceNode.cpp
+++ b/Source/Processors/SourceNode/SourceNode.cpp
@@ -108,76 +108,9 @@ DataThread* SourceNode::getThread()
     return dataThread;
 }
 
-int SourceNode::modifyChannelName(ChannelType t, int str, int ch, String newName, bool updateSignalChain)
+void SourceNode::requestChainUpdate()
 {
-    if (dataThread != 0) {
-        int channel_index = dataThread->modifyChannelName(t, str, ch, newName);
-        if (channel_index >= 0 && channel_index < channels.size())
-        {
-            if (channels[channel_index]->getName() != newName)
-            {
-                channels[channel_index]->setName(newName);
-                // propagate this information...
-                
-                if (updateSignalChain)
-                    getEditorViewport()->makeEditorVisible(getEditor(), false, true);
-                    
-            }
-        }
-        return channel_index;
-    }
-    return -1;
-}
-
-int SourceNode::modifyChannelGain(int stream, int channel, ChannelType type, float gain, bool updateSignalChain)
-{
-    if (dataThread != 0) 
-    {
-        
-        int channel_index = dataThread->modifyChannelGain(type, stream, channel, gain);
-        
-        if (channel_index >= 0 && channel_index < channels.size())
-        {
-            // we now need to update the signal chain to propagate this change.....
-            if (channels[channel_index]->bitVolts != gain) 
-            {
-                channels[channel_index]->bitVolts = gain;
-                
-                if (updateSignalChain)
-                    getEditorViewport()->makeEditorVisible(getEditor(), false, true);
-                
-                return channel_index;
-            }
-        }
-    }
-
-    return -1;
-}
-
-void SourceNode::getChannelsInfo(StringArray &names, Array<ChannelType> &types, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains)
-{
-    if (dataThread != 0)
-        dataThread->getChannelsInfo(names, types,stream,originalChannelNumber,gains);
-}
-
-void SourceNode::setDefaultNamingScheme(int scheme)
-{
-    if (dataThread != 0) 
-    {
-        dataThread->setDefaultNamingScheme(scheme);
-
-        StringArray names;
-        Array<ChannelType> types;
-        Array<int> stream;
-        Array<int> originalChannelNumber;
-        Array<float> gains;
-        getChannelsInfo(names, types, stream, originalChannelNumber, gains);
-        for (int k = 0; k < names.size(); k++)
-        {
-            modifyChannelName(types[k],stream[k],originalChannelNumber[k], names[k],false);
-        }
-    }
-
+	getEditorViewport()->makeEditorVisible(getEditor(), false, true);
 }
 
 void SourceNode::getEventChannelNames(StringArray &names)
@@ -196,7 +129,7 @@ void SourceNode::updateSettings()
         std::cout << "Input buffer address is " << inputBuffer << std::endl;
     }
 
-	//dataThread->updateChannelNames();
+	dataThread->updateChannels();
 
 }
 
@@ -510,7 +443,7 @@ void SourceNode::saveCustomParametersToXml(XmlElement* parentElement)
     Array<int> stream;
     Array<int> originalChannelNumber;
     Array<float> gains;
-    getChannelsInfo(names, types, stream, originalChannelNumber, gains);
+ //   getChannelsInfo(names, types, stream, originalChannelNumber, gains);
 	XmlElement *channelInfo = parentElement->createNewChildElement("CHANNEL_INFO");
 	for (int i = 0; i < names.size(); i++)
 	{
@@ -542,8 +475,8 @@ void SourceNode::loadCustomParametersFromXml()
 					int number = chan->getIntAttribute("number");
 					ChannelType type = static_cast<ChannelType>(chan->getIntAttribute("type"));
 					float gain = chan->getDoubleAttribute("gain");
-					modifyChannelName(type,stream,number,name,false);
-					modifyChannelGain(stream,number,type,gain,false);					
+//					modifyChannelName(type,stream,number,name,false);
+//					modifyChannelGain(stream,number,type,gain,false);					
 				}
             }
         }
diff --git a/Source/Processors/SourceNode/SourceNode.h b/Source/Processors/SourceNode/SourceNode.h
index 0f1aa105f..b96734dd9 100755
--- a/Source/Processors/SourceNode/SourceNode.h
+++ b/Source/Processors/SourceNode/SourceNode.h
@@ -65,12 +65,9 @@ public:
     int getNumEventChannels();
     float getBitVolts(Channel* chan);
 
-    int modifyChannelGain(int stream, int channel,ChannelType type, float gain, bool updateSignalChain);
-    int modifyChannelName(ChannelType t, int str, int ch, String newName, bool updateSignalChain);
+	void requestChainUpdate();
 
-    void getChannelsInfo(StringArray &Names, Array<ChannelType> &type, Array<int> &stream, Array<int> &originalChannelNumber, Array<float> &gains);
-    void setDefaultNamingScheme(int scheme);
-    void getEventChannelNames(StringArray &names);
+   void getEventChannelNames(StringArray &names);
 
     AudioProcessorEditor* createEditor();
     bool hasEditor() const
-- 
GitLab