diff --git a/Source/Processors/DataThreads/DataThread.cpp b/Source/Processors/DataThreads/DataThread.cpp index 5c6de4151ad9308bc3c61b7a99f3ac3a749cd5e0..870c5b84bac8337cad53a6b7ad173f1358517324 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 d6ae6e3faf006baa2662a3f8a86c662047a9092e..9696fe9550f5db72cdf2466887436af98ca6e085 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 a5b9321846b374749050a672f87fe34f7f0402a3..e8043fcb2a1f318e59194611c90d52249d143abe 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 6a997b6c5c3a469ff9a9bcc24e4c8eca09dca1e4..ef8bea16558f425b4f31025aef31ca97903181d8 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 bbc9ecaae67fe82c7bd185aba427f0341c0f7050..581efe2671269410a37255851c5c4f971c2fce73 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 ®ister59Value) @@ -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 9a5bd3cf6109c122c74bb1664d5167c81423f2c9..cd05cc70780280a3e78f81c22475e1b11c6e8743 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 9da3ee59692635cd9b74bd295ad4614b991325ae..16d0dae42c6af27b745ebf479a12eea7dfb7abf8 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 59860e09867be3703488757ca220c08e7c23eebe..d8c568fc957d14c5953a0f5a81d4d1ab304ec4c7 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 0f1aa105fe63b3954f845ad892691418f5a2f0cd..b96734dd9d0634c8b1360c724325636035939ae6 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