From b6d9276ac32432704e9ade3a800aad91f57ec1c6 Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez <aacuelo@teleco.upv.es> Date: Wed, 4 Mar 2015 05:25:13 +0100 Subject: [PATCH] AStyle pass --- Source/Processors/DataThreads/DataThread.cpp | 24 +- Source/Processors/DataThreads/DataThread.h | 57 +- Source/Processors/DataThreads/EcubeThread.cpp | 62 +- Source/Processors/DataThreads/EcubeThread.h | 51 +- .../Processors/DataThreads/RHD2000Editor.cpp | 314 +-- Source/Processors/DataThreads/RHD2000Editor.h | 82 +- .../Processors/DataThreads/RHD2000Thread.cpp | 705 +++---- Source/Processors/DataThreads/RHD2000Thread.h | 108 +- .../GenericProcessor/GenericProcessor.cpp | 76 +- .../GenericProcessor/GenericProcessor.h | 16 +- Source/Processors/SourceNode/SourceNode.cpp | 68 +- Source/Processors/SourceNode/SourceNode.h | 12 +- Source/Processors/SpikeSorter/SpikeSorter.cpp | 1683 +++++++++-------- 13 files changed, 1651 insertions(+), 1607 deletions(-) diff --git a/Source/Processors/DataThreads/DataThread.cpp b/Source/Processors/DataThreads/DataThread.cpp index b1e0aa4a1..adf8a9aca 100755 --- a/Source/Processors/DataThreads/DataThread.cpp +++ b/Source/Processors/DataThreads/DataThread.cpp @@ -71,21 +71,21 @@ DataBuffer* DataThread::getBufferAddress() void DataThread::getChannelInfo(Array<ChannelCustomInfo>& infoArray) { - infoArray.clear(); - infoArray.addArray(channelInfo); + infoArray.clear(); + infoArray.addArray(channelInfo); } 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; - } - } + 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 5e016c875..8a29f8160 100755 --- a/Source/Processors/DataThreads/DataThread.h +++ b/Source/Processors/DataThreads/DataThread.h @@ -31,11 +31,12 @@ class SourceNode; -struct ChannelCustomInfo { - ChannelCustomInfo() : gain(0), modified(false) {} - String name; - float gain; - bool modified; +struct ChannelCustomInfo +{ + ChannelCustomInfo() : gain(0), modified(false) {} + String name; + float gain; + bool modified; }; /** @@ -90,10 +91,16 @@ public: virtual int getNumHeadstageOutputs() = 0; /** Returns the number of continuous aux channels the data source can provide.*/ - virtual int getNumAuxOutputs() {return 0;} + virtual int getNumAuxOutputs() + { + return 0; + } /** Returns the number of continuous ADC channels the data source can provide.*/ - virtual int getNumAdcOutputs() {return 0;} + virtual int getNumAdcOutputs() + { + return 0; + } /** Returns the sample rate of the data source.*/ virtual float getSampleRate() = 0; @@ -115,21 +122,21 @@ public: return -1; } - /* 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 void getEventChannelNames(StringArray& names) { } - virtual bool usesCustomNames() - { - return false; - } + virtual bool usesCustomNames() + { + return false; + } /** Changes the names of channels, if the thread needs custom names. */ - void updateChannels(); + void updateChannels(); /** Returns a pointer to the data input device, in case other processors need to communicate with it.*/ @@ -138,22 +145,22 @@ public: return 0; } - void getChannelInfo(Array<ChannelCustomInfo>& infoArray); + void getChannelInfo(Array<ChannelCustomInfo>& infoArray); protected: - virtual void setDefaultChannelNames() - { - } + virtual void setDefaultChannelNames() + { + } - SourceNode* sn; + SourceNode* sn; - uint64 eventCode; - int64 timestamp; + uint64 eventCode; + int64 timestamp; - Array<ChannelCustomInfo> channelInfo; + Array<ChannelCustomInfo> channelInfo; private: - Time timer; + Time timer; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DataThread); diff --git a/Source/Processors/DataThreads/EcubeThread.cpp b/Source/Processors/DataThreads/EcubeThread.cpp index 2dc25c20e..f44e255b9 100644 --- a/Source/Processors/DataThreads/EcubeThread.cpp +++ b/Source/Processors/DataThreads/EcubeThread.cpp @@ -104,7 +104,7 @@ static std::vector<std::wstring> SafeArrayToVecStr(SAFEARRAY* sa) if (SafeArrayGetElemsize(sa) != sizeof(BSTR*)) _com_raise_error(E_FAIL); - if(SafeArrayGetDim(sa)!=1) + if (SafeArrayGetDim(sa)!=1) _com_raise_error(E_FAIL); if (FAILED(hr = SafeArrayGetLBound(sa, 1, &lbound))) _com_raise_error(hr); @@ -159,7 +159,7 @@ std::vector<std::wstring> GetEcubeModuleChannels(IEcubeModulePtr& mp) { std::vector<std::wstring> chnames; { - SAFEARRAY *sa = mp->GetChannels(); + SAFEARRAY* sa = mp->GetChannels(); chnames = SafeArrayToVecStr(sa); SafeArrayDestroy(sa); // ARTEM - Leaks a safearray if an exception is thrown here } @@ -179,7 +179,7 @@ EcubeThread::EcubeThread(SourceNode* sn) : DataThread(sn), numberingScheme(1), a pDevInt = new EcubeDevInt; pDevInt->pEcube.CreateInstance(__uuidof(Ecube)); { - SAFEARRAY *sa = pDevInt->pEcube->DetectNetworkDevices(); + SAFEARRAY* sa = pDevInt->pEcube->DetectNetworkDevices(); StringArray a(SafeArrayToStringArray(sa)); // ARTEM - Leaks a safearray if an exception is thrown here SafeArrayDestroy(sa); component.SetDeviceNames(a); @@ -312,7 +312,7 @@ EcubeThread::EcubeThread(SourceNode* sn) : DataThread(sn), numberingScheme(1), a In that case, the query channelModified, will return the values that need to be put */ void EcubeThread::setDefaultChannelNames() { - + String prefix; ChannelType common_type; @@ -339,17 +339,17 @@ void EcubeThread::setDefaultChannelNames() for (int i = 0; i < numch; i++) { - ChannelCustomInfo ci; - ci.name = prefix + String(i); - ci.gain = getBitVolts(i); - channelInfo.set(i, ci); + ChannelCustomInfo ci; + ci.name = prefix + String(i); + ci.gain = getBitVolts(i); + channelInfo.set(i, ci); } } bool EcubeThread::usesCustomNames() { - return true; + return true; } void EcubeThread::setDefaultNamingScheme(int scheme) @@ -390,7 +390,7 @@ int EcubeThread::getNumAdcOutputs() int EcubeThread::getNumAuxOutputs() { - return 0; + return 0; } int EcubeThread::getNumChannels() @@ -418,10 +418,10 @@ float EcubeThread::getSampleRate() float EcubeThread::getBitVolts(int chan) { - 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 - else - return 6.25e3 / 32768; // Microvolts per bit for the headstage channels + 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 + else + return 6.25e3 / 32768; // Microvolts per bit for the headstage channels } float EcubeThread::getBitVolts(Channel* chan) @@ -455,7 +455,7 @@ bool EcubeThread::updateBuffer() if (pDevInt->data_format == EcubeDevInt::dfSeparateChannelsAnalog || pDevInt->data_format == EcubeDevInt::dfInterleavedChannelsAnalog) ab = pDevInt->pStrmA->FetchNextBuffer(); else - ab = pDevInt->pStrmD->FetchNextBuffer(); + ab = pDevInt->pStrmD->FetchNextBuffer(); unsigned long chid = ab->GetStreamID(); std::map<int, int>::const_iterator chit = pDevInt->chid_map.find(chid); if (chit != pDevInt->chid_map.end()) @@ -573,22 +573,22 @@ bool EcubeThread::updateBuffer() const uint32_t* pconvtbl; switch (chid) { - case 0: - case 3: - pbits = bits_port0; - pconvtbl = pDevInt->bit_conversion_tables; - break; - case 1: - case 4: - pbits = bits_port1; - pconvtbl = pDevInt->bit_conversion_tables+0x200; - break; - case 2: - case 5: - default: - pbits = bits_port2; - pconvtbl = pDevInt->bit_conversion_tables + 0x400; - break; + case 0: + case 3: + pbits = bits_port0; + pconvtbl = pDevInt->bit_conversion_tables; + break; + case 1: + case 4: + pbits = bits_port1; + pconvtbl = pDevInt->bit_conversion_tables+0x200; + break; + case 2: + case 5: + default: + pbits = bits_port2; + pconvtbl = pDevInt->bit_conversion_tables + 0x400; + break; } int bitchn_offset = chid >= 3 ? 32 : 0; uint8_t dword_shift = chid>=3 ? 32 : 0; diff --git a/Source/Processors/DataThreads/EcubeThread.h b/Source/Processors/DataThreads/EcubeThread.h index d6afc1821..481cff3da 100644 --- a/Source/Processors/DataThreads/EcubeThread.h +++ b/Source/Processors/DataThreads/EcubeThread.h @@ -76,11 +76,11 @@ public: /** Returns the number of continuous channels the data source can provide.*/ virtual int getNumChannels(); - virtual int getNumHeadstageOutputs(); + virtual int getNumHeadstageOutputs(); - virtual int getNumAdcOutputs(); + virtual int getNumAdcOutputs(); - virtual int getNumAuxOutputs(); + virtual int getNumAuxOutputs(); /** Returns the number of event channels of the data source.*/ virtual int getNumEventChannels(); @@ -91,18 +91,18 @@ public: /** Returns the volts per bit of a given data channel.*/ virtual float getBitVolts(int chan); - virtual float getBitVolts(Channel* chan); + virtual float getBitVolts(Channel* chan); void setDefaultNamingScheme(int scheme); - - bool usesCustomNames(); + + bool usesCustomNames(); // Custom thread control functions void setSpeakerVolume(double volume); void setSpeakerChannel(unsigned short channel); private: - int numberingScheme; + int numberingScheme; void setDefaultChannelNames(); ScopedPointer<EcubeDevInt> pDevInt; @@ -111,14 +111,35 @@ private: bool acquisition_running; #else -/** Empty methods for non-Windows platforms **/ - bool updateBuffer() {return false;} - bool foundInputSource() {return false;} - bool startAcquisition() {return false;} - bool stopAcquisition() {return false;} - int getNumChannels() {return 0;} - float getSampleRate() {return 0.0f;} - float getBitVolts() {return 0.0f;} + /** Empty methods for non-Windows platforms **/ + bool updateBuffer() + { + return false; + } + bool foundInputSource() + { + return false; + } + bool startAcquisition() + { + return false; + } + bool stopAcquisition() + { + return false; + } + int getNumChannels() + { + return 0; + } + float getSampleRate() + { + return 0.0f; + } + float getBitVolts() + { + return 0.0f; + } #endif diff --git a/Source/Processors/DataThreads/RHD2000Editor.cpp b/Source/Processors/DataThreads/RHD2000Editor.cpp index dc5a9d727..081e47007 100644 --- a/Source/Processors/DataThreads/RHD2000Editor.cpp +++ b/Source/Processors/DataThreads/RHD2000Editor.cpp @@ -41,7 +41,7 @@ inline double round(double x) FPGAchannelList::FPGAchannelList(GenericProcessor* proc_, Viewport* p, FPGAcanvas* c) : viewport(p), canvas(c), chainUpdate(false) { - proc = (SourceNode*)proc_; + proc = (SourceNode*)proc_; channelComponents.clear(); numberingSchemeLabel = new Label("Numbering scheme:","Numbering scheme:"); @@ -64,18 +64,18 @@ FPGAchannelList::FPGAchannelList(GenericProcessor* proc_, Viewport* p, FPGAcanva impedanceButton->addListener(this); addAndMakeVisible(impedanceButton); - RHD2000Editor *e = static_cast<RHD2000Editor*>(proc->getEditor()); - saveImpedanceButton = new ToggleButton("Save impedance measurements"); - saveImpedanceButton->setBounds(430,10,110,25); - saveImpedanceButton->setToggleState(e->getSaveImpedance(),dontSendNotification); - saveImpedanceButton->addListener(this); - addAndMakeVisible(saveImpedanceButton); - - autoMeasureButton = new ToggleButton("Measure impedance at acquisition start"); - autoMeasureButton->setBounds(550,10,150,25); - autoMeasureButton->setToggleState(e->getAutoMeasureImpedance(),dontSendNotification); - autoMeasureButton->addListener(this); - addAndMakeVisible(autoMeasureButton); + RHD2000Editor* e = static_cast<RHD2000Editor*>(proc->getEditor()); + saveImpedanceButton = new ToggleButton("Save impedance measurements"); + saveImpedanceButton->setBounds(430,10,110,25); + saveImpedanceButton->setToggleState(e->getSaveImpedance(),dontSendNotification); + saveImpedanceButton->addListener(this); + addAndMakeVisible(saveImpedanceButton); + + autoMeasureButton = new ToggleButton("Measure impedance at acquisition start"); + autoMeasureButton->setBounds(550,10,150,25); + autoMeasureButton->setToggleState(e->getAutoMeasureImpedance(),dontSendNotification); + autoMeasureButton->addListener(this); + addAndMakeVisible(autoMeasureButton); gains.clear(); gains.add(0.01); @@ -105,70 +105,70 @@ void FPGAchannelList::paint(Graphics& g) void FPGAchannelList::buttonClicked(Button* btn) { - RHD2000Editor* p = (RHD2000Editor*)proc->getEditor(); + RHD2000Editor* p = (RHD2000Editor*)proc->getEditor(); if (btn == impedanceButton) { p->measureImpedance(); } - else if (btn == saveImpedanceButton) - { - p->setSaveImpedance(btn->getToggleState()); - } - else if (btn == autoMeasureButton) - { - p->setAutoMeasureImpedance(btn->getToggleState()); - } + else if (btn == saveImpedanceButton) + { + p->setSaveImpedance(btn->getToggleState()); + } + else if (btn == autoMeasureButton) + { + p->setAutoMeasureImpedance(btn->getToggleState()); + } } void FPGAchannelList::update() { - const int columnWidth = 330; + const int columnWidth = 330; // Query processor for number of channels, types, gains, etc... and update the UI channelComponents.clear(); staticLabels.clear(); - RHD2000Thread* thread = (RHD2000Thread*)proc->getThread(); - ChannelType type; + RHD2000Thread* thread = (RHD2000Thread*)proc->getThread(); + ChannelType type; // find out which streams are active. bool hsActive[MAX_NUM_HEADSTAGES+1]; bool adcActive = false; int numActiveHeadstages = 0; - int hsColumn[MAX_NUM_HEADSTAGES + 1]; - int numChannelsPerHeadstage[MAX_NUM_HEADSTAGES + 1]; - chainUpdate = false; + int hsColumn[MAX_NUM_HEADSTAGES + 1]; + int numChannelsPerHeadstage[MAX_NUM_HEADSTAGES + 1]; + chainUpdate = false; - for (int k = 0; k<MAX_NUM_HEADSTAGES; k++) + for (int k = 0; k<MAX_NUM_HEADSTAGES; k++) { - 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->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; - } - + + 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"); @@ -196,38 +196,38 @@ void FPGAchannelList::update() } - 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); - } - } - } - - + 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 @@ -248,7 +248,7 @@ void FPGAchannelList::update() staticLabels.add(lbl); addAndMakeVisible(lbl); - chainUpdate = true; + chainUpdate = true; } void FPGAchannelList::disableAll() @@ -270,18 +270,18 @@ void FPGAchannelList::enableAll() void FPGAchannelList::setNewGain(int channel, float gain) { - RHD2000Thread* thread = (RHD2000Thread*)proc->getThread(); - thread->modifyChannelGain(channel, gain); - if (chainUpdate) - proc->requestChainUpdate(); + RHD2000Thread* thread = (RHD2000Thread*)proc->getThread(); + thread->modifyChannelGain(channel, gain); + if (chainUpdate) + proc->requestChainUpdate(); } void FPGAchannelList::setNewName(int channel, String newName) { - RHD2000Thread* thread = (RHD2000Thread*)proc->getThread(); - thread->modifyChannelName(channel, newName); - if (chainUpdate) - proc->requestChainUpdate(); + RHD2000Thread* thread = (RHD2000Thread*)proc->getThread(); + thread->modifyChannelName(channel, newName); + if (chainUpdate) + proc->requestChainUpdate(); } void FPGAchannelList::updateButtons() @@ -298,27 +298,27 @@ void FPGAchannelList::comboBoxChanged(ComboBox* b) if (b == numberingScheme) { SourceNode* p = (SourceNode*)proc; - RHD2000Thread* thread = (RHD2000Thread*)p->getThread(); + RHD2000Thread* thread = (RHD2000Thread*)p->getThread(); int scheme = numberingScheme->getSelectedId(); - thread->setDefaultNamingScheme(scheme); + thread->setDefaultNamingScheme(scheme); update(); - p->requestChainUpdate(); + p->requestChainUpdate(); } } void FPGAchannelList::updateImpedance(Array<int> streams, Array<int> channels, Array<float> magnitude, Array<float> phase) { - for (int k = 0; k < streams.size(); k++) - { - channelComponents[k]->setImpedanceValues(magnitude[k], phase[k]); - } + for (int k = 0; k < streams.size(); k++) + { + channelComponents[k]->setImpedanceValues(magnitude[k], phase[k]); + } } /****************************************************/ -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_) +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); @@ -397,7 +397,7 @@ void FPGAchannelComponent::comboBoxChanged(ComboBox* comboBox) { int newGainIndex = gainComboBox->getSelectedId(); float mult = gains[newGainIndex-1]; - float bitvolts = channelList->proc->getBitVolts(channelList->proc->channels[channel]); + float bitvolts = channelList->proc->getBitVolts(channelList->proc->channels[channel]); channelList->setNewGain(channel, mult*bitvolts); } } @@ -449,9 +449,9 @@ void FPGAchannelComponent::resized() /**********************************************/ -FPGAcanvas::FPGAcanvas(GenericProcessor* n) +FPGAcanvas::FPGAcanvas(GenericProcessor* n) { - processor = (SourceNode*)n; + processor = (SourceNode*)n; channelsViewport = new Viewport(); channelList = new FPGAchannelList(processor, channelsViewport, this); channelsViewport->setViewedComponent(channelList, false); @@ -538,8 +538,8 @@ RHD2000Editor::RHD2000Editor(GenericProcessor* parentNode, canvas = nullptr; desiredWidth = 330; tabText = "FPGA"; - measureWhenRecording = false; - saveImpedances = false; + measureWhenRecording = false; + saveImpedances = false; // add headstage-specific controls (currently just an enable/disable button) for (int i = 0; i < 4; i++) @@ -693,57 +693,57 @@ void RHD2000Editor::measureImpedance() Array<float> magnitude, phase; board->runImpedanceTest(stream,channel,magnitude,phase); - if (canvas == nullptr) - VisualizerEditor::canvas = createNewCanvas(); + if (canvas == nullptr) + VisualizerEditor::canvas = createNewCanvas(); // update components... canvas->updateImpedance(stream,channel,magnitude,phase); - if (saveImpedances) - { - getProcessorGraph()->getRecordNode()->createNewDirectory(); - - String path(getProcessorGraph()->getRecordNode()->getDataDirectory().getFullPathName() - + File::separatorString + "impedance_measurement.xml"); - std::cout << "Saving impedance measurements in " << path << std::endl; - File file(path); - - if (!file.getParentDirectory().exists()) - file.getParentDirectory().createDirectory(); - - XmlDocument doc(file); - ScopedPointer<XmlElement> xml = new XmlElement("CHANNEL_IMPEDANCES"); - for (int i = 0; i < channel.size(); i++) - { - XmlElement* chan = new XmlElement("CHANNEL"); - chan->setAttribute("name",board->getChannelName(i)); - chan->setAttribute("stream",stream[i]); - chan->setAttribute("channel_number",channel[i]); - chan->setAttribute("magnitude",magnitude[i]); - chan->setAttribute("phase",phase[i]); - xml->addChildElement(chan); - } - xml->writeToFile(file,String::empty); - } + if (saveImpedances) + { + getProcessorGraph()->getRecordNode()->createNewDirectory(); + + String path(getProcessorGraph()->getRecordNode()->getDataDirectory().getFullPathName() + + File::separatorString + "impedance_measurement.xml"); + std::cout << "Saving impedance measurements in " << path << std::endl; + File file(path); + + if (!file.getParentDirectory().exists()) + file.getParentDirectory().createDirectory(); + + XmlDocument doc(file); + ScopedPointer<XmlElement> xml = new XmlElement("CHANNEL_IMPEDANCES"); + for (int i = 0; i < channel.size(); i++) + { + XmlElement* chan = new XmlElement("CHANNEL"); + chan->setAttribute("name",board->getChannelName(i)); + chan->setAttribute("stream",stream[i]); + chan->setAttribute("channel_number",channel[i]); + chan->setAttribute("magnitude",magnitude[i]); + chan->setAttribute("phase",phase[i]); + xml->addChildElement(chan); + } + xml->writeToFile(file,String::empty); + } } void RHD2000Editor::setSaveImpedance(bool en) { - saveImpedances = en; + saveImpedances = en; } void RHD2000Editor::setAutoMeasureImpedance(bool en) { - measureWhenRecording = en; + measureWhenRecording = en; } bool RHD2000Editor::getSaveImpedance() { - return saveImpedances; + return saveImpedances; } bool RHD2000Editor::getAutoMeasureImpedance() { - return measureWhenRecording; + return measureWhenRecording; } void RHD2000Editor::comboBoxChanged(ComboBox* comboBox) @@ -787,8 +787,8 @@ void RHD2000Editor::buttonEvent(Button* button) { headstageOptionsInterfaces[i]->checkEnabledState(); } - // board->updateChannelNames(); - getEditorViewport()->makeEditorVisible(this, false, true); + // board->updateChannelNames(); + getEditorViewport()->makeEditorVisible(this, false, true); } else if (button == electrodeButtons[0]) { @@ -801,7 +801,7 @@ void RHD2000Editor::buttonEvent(Button* button) else if (button == adcButton && !acquisitionIsActive) { board->enableAdcs(button->getToggleState()); -// board->updateChannelNames(); + // board->updateChannelNames(); std::cout << "ADC Button toggled" << std::endl; getEditorViewport()->makeEditorVisible(this, false, true); std::cout << "Editor visible." << std::endl; @@ -834,8 +834,8 @@ void RHD2000Editor::channelChanged(int chan) void RHD2000Editor::startAcquisition() { - if (measureWhenRecording) - measureImpedance(); + if (measureWhenRecording) + measureImpedance(); channelSelector->startAcquisition(); @@ -880,8 +880,8 @@ void RHD2000Editor::saveCustomParameters(XmlElement* xml) xml->setAttribute("DAC_HPF", dacHPFcombo->getSelectedId()); xml->setAttribute("DSPOffset", dspoffsetButton->getToggleState()); xml->setAttribute("DSPCutoffFreq", dspInterface->getDspCutoffFreq()); - xml->setAttribute("save_impedance_measurements",saveImpedances); - xml->setAttribute("auto_measure_impedances",measureWhenRecording); + xml->setAttribute("save_impedance_measurements",saveImpedances); + xml->setAttribute("auto_measure_impedances",measureWhenRecording); } void RHD2000Editor::loadCustomParameters(XmlElement* xml) @@ -901,8 +901,8 @@ void RHD2000Editor::loadCustomParameters(XmlElement* xml) dacHPFcombo->setSelectedId(xml->getIntAttribute("DAC_HPF")); dspoffsetButton->setToggleState(xml->getBoolAttribute("DSPOffset"), sendNotification); dspInterface->setDspCutoffFreq(xml->getDoubleAttribute("DSPCutoffFreq")); - saveImpedances = xml->getBoolAttribute("save_impedance_measurements"); - measureWhenRecording = xml->getBoolAttribute("auto_measure_impedances"); + saveImpedances = xml->getBoolAttribute("save_impedance_measurements"); + measureWhenRecording = xml->getBoolAttribute("auto_measure_impedances"); } @@ -1203,7 +1203,7 @@ void HeadstageOptionsInterface::checkEnabledState() if (board->isHeadstageEnabled(hsNumber1)) { - channelsOnHs1 = board->getActiveChannelsInHeadstage(hsNumber1); + channelsOnHs1 = board->getActiveChannelsInHeadstage(hsNumber1); hsButton1->setLabel(String(channelsOnHs1)); hsButton1->setEnabledState(true); } @@ -1234,11 +1234,11 @@ void HeadstageOptionsInterface::checkEnabledState() void HeadstageOptionsInterface::buttonClicked(Button* button) { - if (!(editor->acquisitionIsActive) && board->foundInputSource()) + if (!(editor->acquisitionIsActive) && board->foundInputSource()) { //std::cout << "Acquisition is not active" << std::endl; - if ((button == hsButton1) && (board->getChannelsInHeadstage(hsNumber1) == 32)) + if ((button == hsButton1) && (board->getChannelsInHeadstage(hsNumber1) == 32)) { if (channelsOnHs1 == 32) channelsOnHs1 = 16; @@ -1254,7 +1254,7 @@ void HeadstageOptionsInterface::buttonClicked(Button* button) editor->updateSettings(); } - else if ((button == hsButton2) && (board->getChannelsInHeadstage(hsNumber2) == 32)) + else if ((button == hsButton2) && (board->getChannelsInHeadstage(hsNumber2) == 32)) { if (channelsOnHs2 == 32) channelsOnHs2 = 16; diff --git a/Source/Processors/DataThreads/RHD2000Editor.h b/Source/Processors/DataThreads/RHD2000Editor.h index c3d1559f8..66da62c90 100644 --- a/Source/Processors/DataThreads/RHD2000Editor.h +++ b/Source/Processors/DataThreads/RHD2000Editor.h @@ -56,38 +56,38 @@ class FPGAchannelList : public Component, public AccessClass, Button::Listener, ComboBox::Listener { public: - - FPGAchannelList(GenericProcessor* proc, Viewport *p, FPGAcanvas*c); + + FPGAchannelList(GenericProcessor* proc, Viewport* p, FPGAcanvas* c); ~FPGAchannelList(); void setNewName(int channelIndex, String newName); - void setNewGain(int channel, float gain); + void setNewGain(int channel, float gain); void disableAll(); void enableAll(); void paint(Graphics& g); - void buttonClicked(Button *btn); + void buttonClicked(Button* btn); void update(); void updateButtons(); int getNumChannels(); - void comboBoxChanged(ComboBox *b); + void comboBoxChanged(ComboBox* b); void updateImpedance(Array<int> streams, Array<int> channels, Array<float> magnitude, Array<float> phase); SourceNode* proc; - + private: Array<float> gains; Array<ChannelType> types; - bool chainUpdate; + bool chainUpdate; - Viewport *viewport; - FPGAcanvas *canvas; + Viewport* viewport; + FPGAcanvas* canvas; ScopedPointer<UtilityButton> impedanceButton; - ScopedPointer<ToggleButton> saveImpedanceButton; - ScopedPointer<ToggleButton> autoMeasureButton; + ScopedPointer<ToggleButton> saveImpedanceButton; + ScopedPointer<ToggleButton> autoMeasureButton; ScopedPointer<ComboBox> numberingScheme; ScopedPointer<Label> numberingSchemeLabel; OwnedArray<Label> staticLabels; OwnedArray<FPGAchannelComponent> channelComponents; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FPGAchannelList); + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FPGAchannelList); }; @@ -107,7 +107,7 @@ public: { return isEnabled; } - void buttonClicked(Button *btn); + void buttonClicked(Button* btn); void setUserDefinedData(int d); int getUserDefinedData(); void comboBoxChanged(ComboBox* comboBox); @@ -132,7 +132,7 @@ private: class FPGAcanvas : public Visualizer, public Button::Listener { public: - FPGAcanvas(GenericProcessor* n); + FPGAcanvas(GenericProcessor* n); ~FPGAcanvas(); void paint(Graphics& g); @@ -168,7 +168,7 @@ public: void scanPorts(); void comboBoxChanged(ComboBox* comboBox); - + void startAcquisition(); void stopAcquisition(); @@ -179,10 +179,10 @@ public: Visualizer* createNewCanvas(void); void measureImpedance(); - void setSaveImpedance(bool en); - void setAutoMeasureImpedance(bool en); - bool getSaveImpedance(); - bool getAutoMeasureImpedance(); + void setSaveImpedance(bool en); + void setAutoMeasureImpedance(bool en); + bool getSaveImpedance(); + bool getAutoMeasureImpedance(); private: @@ -197,17 +197,17 @@ private: ScopedPointer<UtilityButton> rescanButton,dacTTLButton; ScopedPointer<UtilityButton> adcButton; - + ScopedPointer<UtilityButton> dspoffsetButton; ScopedPointer<ComboBox> ttlSettleCombo,dacHPFcombo; ScopedPointer<Label> audioLabel,ttlSettleLabel,dacHPFlabel ; - bool saveImpedances, measureWhenRecording; + bool saveImpedances, measureWhenRecording; RHD2000Thread* board; - FPGAcanvas *canvas; + FPGAcanvas* canvas; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RHD2000Editor); }; @@ -276,29 +276,29 @@ private: }; class DSPInterface : public Component, -public Label::Listener + public Label::Listener { public: DSPInterface(RHD2000Thread*, RHD2000Editor*); ~DSPInterface(); - + void paint(Graphics& g); void labelTextChanged(Label* te); - + void setDspCutoffFreq(double value); double getDspCutoffFreq(); - + private: - + String name; - + RHD2000Thread* board; RHD2000Editor* editor; - + ScopedPointer<Label> dspOffsetSelection; - + double actualDspCutoffFreq; - + }; @@ -330,36 +330,36 @@ private: }; class AudioInterface : public Component, -public Label::Listener + public Label::Listener { public: AudioInterface(RHD2000Thread*, RHD2000Editor*); ~AudioInterface(); - + void paint(Graphics& g); void labelTextChanged(Label* te); - + void setNoiseSlicerLevel(int value); int getNoiseSlicerLevel(); //void setGain(double value); //double getGain(); - + private: - + String name; - + String lastNoiseSlicerString; String lastGainString; - + RHD2000Thread* board; RHD2000Editor* editor; - + ScopedPointer<Label> noiseSlicerLevelSelection; //ScopedPointer<Label> gainSelection; - + int actualNoiseSlicerLevel; //double actualGain; - + }; diff --git a/Source/Processors/DataThreads/RHD2000Thread.cpp b/Source/Processors/DataThreads/RHD2000Thread.cpp index 7e682e533..c7564316b 100644 --- a/Source/Processors/DataThreads/RHD2000Thread.cpp +++ b/Source/Processors/DataThreads/RHD2000Thread.cpp @@ -80,11 +80,11 @@ RHD2000Thread::RHD2000Thread(SourceNode* sn) : DataThread(sn), 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), - newScan(true) + newScan(true) { - for (int i=0; i < MAX_NUM_HEADSTAGES; i++) - headstagesArray.add(new RHDHeadstage(static_cast<Rhd2000EvalBoard::BoardDataSource>(i))); + for (int i=0; i < MAX_NUM_HEADSTAGES; i++) + headstagesArray.add(new RHDHeadstage(static_cast<Rhd2000EvalBoard::BoardDataSource>(i))); evalBoard = new Rhd2000EvalBoard; dataBlock = new Rhd2000DataBlock(1); @@ -140,13 +140,13 @@ RHD2000Thread::RHD2000Thread(SourceNode* sn) : DataThread(sn), dacChannelsToUpdate[k] = true; dacStream[k] = 0; setDACthreshold(k, 65534); - dacChannels[k] = -1; - dacThresholds[k] = 0; + dacChannels[k] = -1; + dacThresholds[k] = 0; } - // evalBoard->getDacInformation(dacChannels,dacThresholds); + // evalBoard->getDacInformation(dacChannels,dacThresholds); - // setDefaultNamingScheme(numberingScheme); + // setDefaultNamingScheme(numberingScheme); //setDefaultChannelNamesAndType(); } } @@ -183,7 +183,7 @@ RHD2000Thread::~RHD2000Thread() bool RHD2000Thread::usesCustomNames() { - return true; + return true; } void RHD2000Thread::setDACthreshold(int dacOutput, float threshold) @@ -197,32 +197,32 @@ void RHD2000Thread::setDACthreshold(int dacOutput, float threshold) void RHD2000Thread::setDACchannel(int dacOutput, int channel) { - if (channel < getNumHeadstageOutputs()) - { - int channelCount = 0; - for (int i = 0; i < enabledStreams.size(); i++) - { - if (channel < channelCount + numChannelsPerDataStream[i]) - { - dacChannels[dacOutput] = channel - channelCount; - dacStream[dacOutput] = i; - } - else - { - channelCount += numChannelsPerDataStream[i]; - } - } - dacChannelsToUpdate[dacOutput] = true; - dacOutputShouldChange = true; - } + if (channel < getNumHeadstageOutputs()) + { + int channelCount = 0; + for (int i = 0; i < enabledStreams.size(); i++) + { + if (channel < channelCount + numChannelsPerDataStream[i]) + { + dacChannels[dacOutput] = channel - channelCount; + dacStream[dacOutput] = i; + } + else + { + channelCount += numChannelsPerDataStream[i]; + } + } + dacChannelsToUpdate[dacOutput] = true; + dacOutputShouldChange = true; + } } Array<int> RHD2000Thread::getDACchannels() { Array<int> dacChannelsArray; - //dacChannelsArray.addArray(dacChannels,8); + //dacChannelsArray.addArray(dacChannels,8); for (int k=0; k<8; k++) - { + { dacChannelsArray.add(dacChannels[k]); } return dacChannelsArray; @@ -372,8 +372,8 @@ void RHD2000Thread::initializeBoard() // - clears the ttlOut // - disables all DACs and sets gain to 0 - setSampleRate(Rhd2000EvalBoard::SampleRate30000Hz); - evalBoard->setCableLengthMeters(Rhd2000EvalBoard::PortA, cableLengthPortA); + setSampleRate(Rhd2000EvalBoard::SampleRate30000Hz); + evalBoard->setCableLengthMeters(Rhd2000EvalBoard::PortA, cableLengthPortA); evalBoard->setCableLengthMeters(Rhd2000EvalBoard::PortB, cableLengthPortB); evalBoard->setCableLengthMeters(Rhd2000EvalBoard::PortC, cableLengthPortC); evalBoard->setCableLengthMeters(Rhd2000EvalBoard::PortD, cableLengthPortD); @@ -403,7 +403,7 @@ void RHD2000Thread::initializeBoard() ScopedPointer<Rhd2000DataBlock> dataBlock = new Rhd2000DataBlock(evalBoard->getNumEnabledDataStreams()); - evalBoard->readDataBlock(dataBlock); + evalBoard->readDataBlock(dataBlock); // Now that ADC calibration has been performed, we switch to the command sequence // that does not execute ADC calibration. @@ -419,7 +419,7 @@ void RHD2000Thread::initializeBoard() //updateRegisters(); - // Let's turn one LED on to indicate that the board is now connected + // Let's turn one LED on to indicate that the board is now connected int ledArray[8] = {1, 0, 0, 0, 0, 0, 0, 0}; evalBoard->setLedDisplay(ledArray); @@ -432,13 +432,13 @@ void RHD2000Thread::scanPorts() return; } - //Clear previous known streams - enabledStreams.clear(); + //Clear previous known streams + enabledStreams.clear(); // Scan SPI ports int delay, hs, id; - int register59Value; + int register59Value; //int numChannelsOnPort[4] = {0, 0, 0, 0}; Rhd2000EvalBoard::BoardDataSource initStreamPorts[8] = { @@ -465,9 +465,9 @@ void RHD2000Thread::scanPorts() }; chipId.insertMultiple(0,-1,8); - Array<int> tmpChipId(chipId); + Array<int> tmpChipId(chipId); - setSampleRate(Rhd2000EvalBoard::SampleRate30000Hz, true); // set to 30 kHz temporarily + setSampleRate(Rhd2000EvalBoard::SampleRate30000Hz, true); // set to 30 kHz temporarily // Enable all data streams, and set sources to cover one or two chips // on Ports A-D. @@ -549,9 +549,9 @@ void RHD2000Thread::scanPorts() { // std::cout << "Stream number " << stream << ", delay = " << delay << std::endl; - id = deviceId(dataBlock, hs, register59Value); + id = deviceId(dataBlock, hs, register59Value); - if (id == CHIP_ID_RHD2132 || id == CHIP_ID_RHD2216 || + if (id == CHIP_ID_RHD2132 || id == CHIP_ID_RHD2216 || (id == CHIP_ID_RHD2164 && register59Value == REGISTER_59_MISO_A)) { // std::cout << "Device ID found: " << id << std::endl; @@ -580,50 +580,50 @@ void RHD2000Thread::scanPorts() //std::cout << std::endl; #if DEBUG_EMULATE_HEADSTAGES > 0 - for (int nd = 0; nd < MAX_NUM_DATA_STREAMS; ++nd) - { - if ((nd < DEBUG_EMULATE_HEADSTAGES) &&(tmpChipId[0] > 0)) - { - evalBoard->setDataSource(nd,initStreamPorts[0]); - enableHeadstage(nd,true); - } - else - { - enableHeadstage(stream,false); - } - } + for (int nd = 0; nd < MAX_NUM_DATA_STREAMS; ++nd) + { + if ((nd < DEBUG_EMULATE_HEADSTAGES) &&(tmpChipId[0] > 0)) + { + evalBoard->setDataSource(nd,initStreamPorts[0]); + enableHeadstage(nd,true); + } + else + { + enableHeadstage(stream,false); + } + } #else - // Now, disable data streams where we did not find chips present. - int chipIdx = 0; - for (hs = 0; hs < MAX_NUM_HEADSTAGES; ++hs) + // Now, disable data streams where we did not find chips present. + int chipIdx = 0; + for (hs = 0; hs < MAX_NUM_HEADSTAGES; ++hs) { - if ((tmpChipId[hs] > 0) && (enabledStreams.size() < MAX_NUM_DATA_STREAMS)) + if ((tmpChipId[hs] > 0) && (enabledStreams.size() < MAX_NUM_DATA_STREAMS)) { - chipId.set(chipIdx++,tmpChipId[hs]); + chipId.set(chipIdx++,tmpChipId[hs]); //std::cout << "Enabling headstage on stream " << stream << std::endl; if (tmpChipId[hs] == CHIP_ID_RHD2164) //RHD2164 { - if (enabledStreams.size() < MAX_NUM_DATA_STREAMS - 1) - { - enableHeadstage(hs,true,2,32); - chipId.set(chipIdx++,CHIP_ID_RHD2164_B); - } - else //just one stream left - { - enableHeadstage(hs,true,1,32); - } + if (enabledStreams.size() < MAX_NUM_DATA_STREAMS - 1) + { + enableHeadstage(hs,true,2,32); + chipId.set(chipIdx++,CHIP_ID_RHD2164_B); + } + else //just one stream left + { + enableHeadstage(hs,true,1,32); + } } else - { + { enableHeadstage(hs, true,1,tmpChipId[hs] == 1 ? 32:16); - } + } } else { enableHeadstage(hs, false); } } - updateBoardStreams(); + updateBoardStreams(); #endif @@ -635,7 +635,7 @@ void RHD2000Thread::scanPorts() Array<int> optimumDelay; optimumDelay.insertMultiple(0,0,8); - for (hs = 0; hs < MAX_NUM_HEADSTAGES; ++hs) + for (hs = 0; hs < MAX_NUM_HEADSTAGES; ++hs) { if (sumGoodDelays[hs] == 1 || sumGoodDelays[hs] == 2) { @@ -667,10 +667,10 @@ void RHD2000Thread::scanPorts() setSampleRate(savedSampleRateIndex); // restore saved sample rate //updateRegisters(); - newScan = true; + newScan = true; } -int RHD2000Thread::deviceId(Rhd2000DataBlock* dataBlock, int stream, int ®ister59Value) +int RHD2000Thread::deviceId(Rhd2000DataBlock* dataBlock, int stream, int& register59Value) { bool intanChipPresent; @@ -687,12 +687,15 @@ int RHD2000Thread::deviceId(Rhd2000DataBlock* dataBlock, int stream, int ®ist (char) dataBlock->auxiliaryData[stream][2][25] == 'H' && (char) dataBlock->auxiliaryData[stream][2][26] == 'D'); - // If the SPI communication is bad, return -1. Otherwise, return the Intan + // If the SPI communication is bad, return -1. Otherwise, return the Intan // chip ID number stored in ROM regstier 63. - if (!intanChipPresent) { + if (!intanChipPresent) + { register59Value = -1; return -1; - } else { + } + else + { register59Value = dataBlock->auxiliaryData[stream][2][23]; // Register 59 return dataBlock->auxiliaryData[stream][2][19]; // chip ID (Register 63) } @@ -707,19 +710,19 @@ bool RHD2000Thread::isAcquisitionActive() void RHD2000Thread::setNumChannels(int hsNum, int numChannels) { - if (headstagesArray[hsNum]->getNumChannels() == 32) - { - if (numChannels < headstagesArray[hsNum]->getNumChannels()) - headstagesArray[hsNum]->setHalfChannels(true); - else - headstagesArray[hsNum]->setHalfChannels(false); - numChannelsPerDataStream.set(hsNum, numChannels); - } + if (headstagesArray[hsNum]->getNumChannels() == 32) + { + if (numChannels < headstagesArray[hsNum]->getNumChannels()) + headstagesArray[hsNum]->setHalfChannels(true); + else + headstagesArray[hsNum]->setHalfChannels(false); + numChannelsPerDataStream.set(hsNum, numChannels); + } } int RHD2000Thread::getHeadstageChannels(int hsNum) { - return headstagesArray[hsNum]->getNumChannels(); + return headstagesArray[hsNum]->getNumChannels(); } @@ -739,31 +742,31 @@ if so, return the old name */ int RHD2000Thread::modifyChannelName(int channel, String newName) { - ChannelCustomInfo i = channelInfo[channel]; - i.name = newName; - i.modified = true; - channelInfo.set(channel, i); + ChannelCustomInfo i = channelInfo[channel]; + i.name = newName; + i.modified = true; + channelInfo.set(channel, i); return 0; } String RHD2000Thread::getChannelName(int ch) { - return channelInfo[ch].name; + return channelInfo[ch].name; } int RHD2000Thread::modifyChannelGain(int channel, float gain) { - ChannelCustomInfo i = channelInfo[channel]; - i.gain = gain; - i.modified = true; - channelInfo.set(channel, i); - return 0; + ChannelCustomInfo i = channelInfo[channel]; + i.gain = gain; + i.modified = true; + channelInfo.set(channel, i); + return 0; } void RHD2000Thread::setDefaultNamingScheme(int scheme) { numberingScheme = scheme; - newScan = true; //if the scheme is changed, reset all names + newScan = true; //if the scheme is changed, reset all names setDefaultChannelNames(); } @@ -788,67 +791,67 @@ void RHD2000Thread::setDefaultChannelNames() for (int i = 0; i < MAX_NUM_HEADSTAGES; i++) { - if (headstagesArray[i]->isPlugged()) + if (headstagesArray[i]->isPlugged()) { - for (int k = 0; k < headstagesArray[i]->getNumActiveChannels(); k++) + for (int k = 0; k < headstagesArray[i]->getNumActiveChannels(); 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++; + 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++; } } } - //Aux channels - for (int i = 0; i < MAX_NUM_HEADSTAGES; i++) - { - if (headstagesArray[i]->isPlugged()) + //Aux channels + for (int i = 0; i < MAX_NUM_HEADSTAGES; i++) + { + if (headstagesArray[i]->isPlugged()) { - for (int k = 0; k < 3; k++) - { - int chn = channelNumber - 1; - - 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); - - } - channelNumber++; - aux_counter++; - } - } - } - //ADC channels + for (int k = 0; k < 3; k++) + { + int chn = channelNumber - 1; + + 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); + + } + channelNumber++; + aux_counter++; + } + } + } + //ADC channels if (acquireAdcChannels) { for (int k = 0; k < 8; 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++; + 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; + newScan = false; } int RHD2000Thread::getNumChannels() @@ -859,12 +862,12 @@ int RHD2000Thread::getNumChannels() int RHD2000Thread::getNumHeadstageOutputs() { numChannels = 0; - for (int i = 0; i < MAX_NUM_HEADSTAGES; i++) + for (int i = 0; i < MAX_NUM_HEADSTAGES; i++) { - if (headstagesArray[i]->isPlugged()) + if (headstagesArray[i]->isPlugged()) { - numChannels += headstagesArray[i]->getNumActiveChannels(); + numChannels += headstagesArray[i]->getNumActiveChannels(); } } @@ -878,7 +881,7 @@ int RHD2000Thread::getNumAuxOutputs() { int numAuxOutputs = 0; - for (int i = 0; i < MAX_NUM_HEADSTAGES; i++) + for (int i = 0; i < MAX_NUM_HEADSTAGES; i++) { if (headstagesArray[i]->isPlugged() > 0) { @@ -895,7 +898,9 @@ int RHD2000Thread::getNumAdcOutputs() if (acquireAdcChannels) { return 8; - } else { + } + else + { return 0; } } @@ -913,7 +918,7 @@ float RHD2000Thread::getSampleRate() float RHD2000Thread::getBitVolts(Channel* ch) { if (ch->type == ADC_CHANNEL) - return getAdcBitVolts(ch->index); + return getAdcBitVolts(ch->index); else if (ch->type == AUX_CHANNEL) return 0.0000374; else @@ -1016,84 +1021,84 @@ bool RHD2000Thread::foundInputSource() bool RHD2000Thread::enableHeadstage(int hsNum, bool enabled, int nStr, int strChans) { - /* evalBoard->enableDataStream(hsNum, enabled);*/ - - if (enabled) - { - headstagesArray[hsNum]->setNumStreams(nStr); - headstagesArray[hsNum]->setChannelsPerStream(strChans); - enabledStreams.add(headstagesArray[hsNum]->getDataStream(0)); - numChannelsPerDataStream.add(strChans); - if (nStr > 1) - { - enabledStreams.add(headstagesArray[hsNum]->getDataStream(1)); - numChannelsPerDataStream.add(strChans); - } - } - else - { - int idx = enabledStreams.indexOf(headstagesArray[hsNum]->getDataStream(0)); - if (idx >= 0) - { - enabledStreams.remove(idx); - numChannelsPerDataStream.remove(idx); - } - if (headstagesArray[hsNum]->getNumStreams() > 1) - { - idx = enabledStreams.indexOf(headstagesArray[hsNum]->getDataStream(1)); - if (idx >= 0) - { - enabledStreams.remove(idx); - numChannelsPerDataStream.remove(idx); - } - } - headstagesArray[hsNum]->setNumStreams(0); - } - - /* - std::cout << "Enabled channels: "; + /* evalBoard->enableDataStream(hsNum, enabled);*/ + + if (enabled) + { + headstagesArray[hsNum]->setNumStreams(nStr); + headstagesArray[hsNum]->setChannelsPerStream(strChans); + enabledStreams.add(headstagesArray[hsNum]->getDataStream(0)); + numChannelsPerDataStream.add(strChans); + if (nStr > 1) + { + enabledStreams.add(headstagesArray[hsNum]->getDataStream(1)); + numChannelsPerDataStream.add(strChans); + } + } + else + { + int idx = enabledStreams.indexOf(headstagesArray[hsNum]->getDataStream(0)); + if (idx >= 0) + { + enabledStreams.remove(idx); + numChannelsPerDataStream.remove(idx); + } + if (headstagesArray[hsNum]->getNumStreams() > 1) + { + idx = enabledStreams.indexOf(headstagesArray[hsNum]->getDataStream(1)); + if (idx >= 0) + { + enabledStreams.remove(idx); + numChannelsPerDataStream.remove(idx); + } + } + headstagesArray[hsNum]->setNumStreams(0); + } + + /* + std::cout << "Enabled channels: "; for (int i = 0; i < MAX_NUM_DATA_STREAMS; i++) { std::cout << numChannelsPerDataStream[i] << " "; }*/ - dataBuffer->resize(getNumChannels(), 10000); + dataBuffer->resize(getNumChannels(), 10000); - return true; + return true; } void RHD2000Thread::updateBoardStreams() { - for (int i=0; i < MAX_NUM_DATA_STREAMS; i++) - { - if (i < enabledStreams.size()) - { - evalBoard->enableDataStream(i,true); - evalBoard->setDataSource(i,enabledStreams[i]); - } - else - { - evalBoard->enableDataStream(i,false); - } - } + for (int i=0; i < MAX_NUM_DATA_STREAMS; i++) + { + if (i < enabledStreams.size()) + { + evalBoard->enableDataStream(i,true); + evalBoard->setDataSource(i,enabledStreams[i]); + } + else + { + evalBoard->enableDataStream(i,false); + } + } } bool RHD2000Thread::isHeadstageEnabled(int hsNum) { - return headstagesArray[hsNum]->isPlugged(); + return headstagesArray[hsNum]->isPlugged(); } int RHD2000Thread::getActiveChannelsInHeadstage(int hsNum) { - return headstagesArray[hsNum]->getNumActiveChannels(); + return headstagesArray[hsNum]->getNumActiveChannels(); } int RHD2000Thread::getChannelsInHeadstage(int hsNum) { - return headstagesArray[hsNum]->getNumChannels(); + return headstagesArray[hsNum]->getNumChannels(); } /*void RHD2000Thread::assignAudioOut(int dacChannel, int dataChannel) @@ -1246,7 +1251,7 @@ void RHD2000Thread::setSampleRate(int sampleRateIndex, bool isTemporary) evalBoard->setCableLengthMeters(Rhd2000EvalBoard::PortC, cableLengthPortC); evalBoard->setCableLengthMeters(Rhd2000EvalBoard::PortD, cableLengthPortD); - updateRegisters(); + updateRegisters(); } @@ -1466,71 +1471,71 @@ bool RHD2000Thread::updateBuffer() int channel = -1; // do the neural data channels first - for (int dataStream = 0; dataStream < enabledStreams.size(); dataStream++) - { + for (int dataStream = 0; dataStream < enabledStreams.size(); dataStream++) + { - for (int chan = 0; chan < numChannelsPerDataStream[dataStream]; chan++) - { + for (int chan = 0; chan < numChannelsPerDataStream[dataStream]; chan++) + { - // std::cout << "reading sample stream " << streamNumber << " chan " << chan << " sample "<< samp << std::endl; + // std::cout << "reading sample stream " << streamNumber << " chan " << chan << " sample "<< samp << std::endl; - channel++; + channel++; - int value = dataBlock->amplifierData[dataStream][chan][samp]; + int value = dataBlock->amplifierData[dataStream][chan][samp]; - thisSample[channel] = float(value-32768)*0.195f; - } + thisSample[channel] = float(value-32768)*0.195f; + } - } + } // then do the Intan AUX channels - for (int dataStream = 0; dataStream < enabledStreams.size(); dataStream++) + for (int dataStream = 0; dataStream < enabledStreams.size(); dataStream++) { - if (chipId[dataStream] != CHIP_ID_RHD2164_B) //Channel B of 2164 shouldn't be copied - { - if (samp % 4 == 1) // every 4th sample should have auxiliary input data - { + if (chipId[dataStream] != CHIP_ID_RHD2164_B) //Channel B of 2164 shouldn't be copied + { + if (samp % 4 == 1) // every 4th sample should have auxiliary input data + { - // std::cout << "reading sample stream " << streamNumber << " aux ADCs " << std::endl; + // std::cout << "reading sample stream " << streamNumber << " aux ADCs " << std::endl; - channel++; - thisSample[channel] = 0.0374 * - float(dataBlock->auxiliaryData[dataStream][1][samp + 0] - 45000.0f); - // constant offset keeps the values visible in the LFP Viewer + channel++; + thisSample[channel] = 0.0374 * + float(dataBlock->auxiliaryData[dataStream][1][samp + 0] - 45000.0f); + // constant offset keeps the values visible in the LFP Viewer - auxBuffer[channel] = thisSample[channel]; + auxBuffer[channel] = thisSample[channel]; - channel++; - thisSample[channel] = 0.0374 * - float(dataBlock->auxiliaryData[dataStream][1][samp + 1] - 45000.0f); - // constant offset keeps the values visible in the LFP Viewer + channel++; + thisSample[channel] = 0.0374 * + float(dataBlock->auxiliaryData[dataStream][1][samp + 1] - 45000.0f); + // constant offset keeps the values visible in the LFP Viewer - auxBuffer[channel] = thisSample[channel]; + auxBuffer[channel] = thisSample[channel]; - channel++; - thisSample[channel] = 0.0374 * - float(dataBlock->auxiliaryData[dataStream][1][samp + 2] - 45000.0f); - // constant offset keeps the values visible in the LFP Viewer + channel++; + thisSample[channel] = 0.0374 * + float(dataBlock->auxiliaryData[dataStream][1][samp + 2] - 45000.0f); + // constant offset keeps the values visible in the LFP Viewer - auxBuffer[channel] = thisSample[channel]; + auxBuffer[channel] = thisSample[channel]; - } - else // repeat last values from buffer - { + } + else // repeat last values from buffer + { - //std::cout << "reading sample stream " << streamNumber << " aux ADCs " << std::endl; + //std::cout << "reading sample stream " << streamNumber << " aux ADCs " << std::endl; - channel++; - thisSample[channel] = auxBuffer[channel]; - channel++; - thisSample[channel] = auxBuffer[channel]; - channel++; - thisSample[channel] = auxBuffer[channel]; - } - } + channel++; + thisSample[channel] = auxBuffer[channel]; + channel++; + thisSample[channel] = auxBuffer[channel]; + channel++; + thisSample[channel] = auxBuffer[channel]; + } + } } @@ -1572,8 +1577,8 @@ bool RHD2000Thread::updateBuffer() evalBoard->enableDac(k, true); evalBoard->selectDacDataStream(k, dacStream[k]); evalBoard->selectDacDataChannel(k, dacChannels[k]); - evalBoard->setDacThreshold(k, (int)abs((dacThresholds[k]/0.195) + 32768),dacThresholds[k] >= 0); - // evalBoard->setDacThresholdVoltage(k, (int) dacThresholds[k]); + evalBoard->setDacThreshold(k, (int)abs((dacThresholds[k]/0.195) + 32768),dacThresholds[k] >= 0); + // evalBoard->setDacThresholdVoltage(k, (int) dacThresholds[k]); } else { @@ -1583,8 +1588,8 @@ bool RHD2000Thread::updateBuffer() } evalBoard->setTtlMode(ttlMode); - evalBoard->enableExternalFastSettle(fastTTLSettleEnabled); - evalBoard->setExternalFastSettleChannel(fastSettleTTLChannel); + evalBoard->enableExternalFastSettle(fastTTLSettleEnabled); + evalBoard->setExternalFastSettleChannel(fastSettleTTLChannel); evalBoard->setDacHighpassFilter(desiredDAChpf); evalBoard->enableDacHighpassFilter(desiredDAChpfState); @@ -2091,101 +2096,101 @@ 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 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) + 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) { } @@ -2195,41 +2200,41 @@ RHDHeadstage::~RHDHeadstage() void RHDHeadstage::setNumStreams(int num) { - numStreams = num; + numStreams = num; } void RHDHeadstage::setChannelsPerStream(int nchan) { - channelsPerStream = nchan; + channelsPerStream = nchan; } int RHDHeadstage::getNumChannels() { - return channelsPerStream*numStreams; + return channelsPerStream*numStreams; } int RHDHeadstage::getNumStreams() { - return numStreams; + return numStreams; } void RHDHeadstage::setHalfChannels(bool half) { - halfChannels = half; + halfChannels = half; } int RHDHeadstage::getNumActiveChannels() { - return (int)(getNumChannels() / (halfChannels ? 2 : 1)); + return (int)(getNumChannels() / (halfChannels ? 2 : 1)); } Rhd2000EvalBoard::BoardDataSource RHDHeadstage::getDataStream(int index) { - if (index < 0 || index > 1) index = 0; - return static_cast<Rhd2000EvalBoard::BoardDataSource>(dataStream+MAX_NUM_HEADSTAGES*index); + if (index < 0 || index > 1) index = 0; + return static_cast<Rhd2000EvalBoard::BoardDataSource>(dataStream+MAX_NUM_HEADSTAGES*index); } bool RHDHeadstage::isPlugged() { - return (numStreams > 0); + return (numStreams > 0); } \ No newline at end of file diff --git a/Source/Processors/DataThreads/RHD2000Thread.h b/Source/Processors/DataThreads/RHD2000Thread.h index 01801e116..8ca1a68b5 100644 --- a/Source/Processors/DataThreads/RHD2000Thread.h +++ b/Source/Processors/DataThreads/RHD2000Thread.h @@ -69,8 +69,8 @@ public: float getBitVolts(Channel* chan); float getAdcBitVolts(int channelNum); - bool isHeadstageEnabled(int hsNum); - int getChannelsInHeadstage(int hsNum); + bool isHeadstageEnabled(int hsNum); + int getChannelsInHeadstage(int hsNum); void setSampleRate(int index, bool temporary = false); @@ -79,55 +79,55 @@ public: double setDspCutoffFreq(double freq); double getDspCutoffFreq(); - + void setDSPOffset(bool state); int setNoiseSlicerLevel(int level); - void runImpedanceTest(Array<int> &stream, Array<int> &channel, Array<float> &magnitude, Array<float> &phase); + void runImpedanceTest(Array<int>& stream, Array<int>& channel, Array<float>& magnitude, Array<float>& phase); void setFastTTLSettle(bool state, int channel); void setTTLoutputMode(bool state); void setDAChpf(float cutoff, bool enabled); void scanPorts(); - float updateImpedanceFrequency(float desiredImpedanceFreq, bool &impedanceFreqValid); - int loadAmplifierData(queue<Rhd2000DataBlock> &dataQueue, - int numBlocks, int numDataStreams); - void measureComplexAmplitude(std::vector<std::vector<std::vector<double>>> &measuredMagnitude, - std::vector<std::vector<std::vector<double>>> &measuredPhase, - int capIndex, int stream, int chipChannel, int numBlocks, - double sampleRate, double frequency, int numPeriods); - void amplitudeOfFreqComponent(double &realComponent, double &imagComponent, - const std::vector<double> &data, int startIndex, - int endIndex, double sampleRate, double frequency); + float updateImpedanceFrequency(float desiredImpedanceFreq, bool& impedanceFreqValid); + int loadAmplifierData(queue<Rhd2000DataBlock>& dataQueue, + int numBlocks, int numDataStreams); + void measureComplexAmplitude(std::vector<std::vector<std::vector<double>>>& measuredMagnitude, + std::vector<std::vector<std::vector<double>>>& measuredPhase, + int capIndex, int stream, int chipChannel, int numBlocks, + double sampleRate, double frequency, int numPeriods); + void amplitudeOfFreqComponent(double& realComponent, double& imagComponent, + const std::vector<double>& data, int startIndex, + int endIndex, double sampleRate, double frequency); int getNumEventChannels(); void enableAdcs(bool); bool isAcquisitionActive(); - + int modifyChannelGain(int channel, float gain); int modifyChannelName(int channel, String newName); - void getEventChannelNames(StringArray &Names); + void getEventChannelNames(StringArray& Names); Array<int> getDACchannels(); void setDACchannel(int dacOutput, int channel); void setDACthreshold(int dacOutput, float threshold); void setDefaultNamingScheme(int scheme); - 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); + 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: bool enableHeadstage(int hsNum, bool enabled, int nStr = 1, int strChans = 32); - void updateBoardStreams(); + void updateBoardStreams(); void setCableLength(int hsNum, float length); void setDefaultChannelNames(); @@ -137,10 +137,10 @@ private: Rhd2000DataBlock* dataBlock; std::vector<std::vector<std::vector<double>>> amplifierPreFilter; - void factorOutParallelCapacitance(double &impedanceMagnitude, double &impedancePhase, - double frequency, double parasiticCapacitance); - void empiricalResistanceCorrection(double &impedanceMagnitude, double &impedancePhase, - double boardSampleRate); + void factorOutParallelCapacitance(double& impedanceMagnitude, double& impedancePhase, + double frequency, double parasiticCapacitance); + void empiricalResistanceCorrection(double& impedanceMagnitude, double& impedancePhase, + double boardSampleRate); int numChannels; bool deviceFound; @@ -183,25 +183,25 @@ private: void updateRegisters(); - int deviceId(Rhd2000DataBlock* dataBlock, int stream, int ®ister59Value); + int deviceId(Rhd2000DataBlock* dataBlock, int stream, int& register59Value); bool updateBuffer(); double cableLengthPortA, cableLengthPortB, cableLengthPortC, cableLengthPortD; int audioOutputL, audioOutputR; - int *dacChannels, *dacStream; - float *dacThresholds; - bool *dacChannelsToUpdate; + int* dacChannels, *dacStream; + float* dacThresholds; + bool* dacChannelsToUpdate; Array<int> chipId; - OwnedArray<RHDHeadstage> headstagesArray; - Array<Rhd2000EvalBoard::BoardDataSource> enabledStreams; - Array<int> numChannelsPerDataStream; + OwnedArray<RHDHeadstage> headstagesArray; + Array<Rhd2000EvalBoard::BoardDataSource> enabledStreams; + Array<int> numChannelsPerDataStream; // used for data stream names... int numberingScheme ; Array<float> adcBitVolts; - bool newScan; + bool newScan; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RHD2000Thread); }; @@ -209,22 +209,22 @@ private: class RHDHeadstage { public: - RHDHeadstage(Rhd2000EvalBoard::BoardDataSource stream); - ~RHDHeadstage(); - void setNumStreams(int num); - void setChannelsPerStream(int nchan); - int getNumChannels(); - int getNumStreams(); - void setHalfChannels(bool half); //mainly used for de 16ch rhd2132 board - int getNumActiveChannels(); - Rhd2000EvalBoard::BoardDataSource getDataStream(int index); - bool isPlugged(); + RHDHeadstage(Rhd2000EvalBoard::BoardDataSource stream); + ~RHDHeadstage(); + void setNumStreams(int num); + void setChannelsPerStream(int nchan); + int getNumChannels(); + int getNumStreams(); + void setHalfChannels(bool half); //mainly used for de 16ch rhd2132 board + int getNumActiveChannels(); + Rhd2000EvalBoard::BoardDataSource getDataStream(int index); + bool isPlugged(); private: - Rhd2000EvalBoard::BoardDataSource dataStream; - int numStreams; - int channelsPerStream; - bool halfChannels; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RHDHeadstage); + Rhd2000EvalBoard::BoardDataSource dataStream; + int numStreams; + int channelsPerStream; + bool halfChannels; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RHDHeadstage); }; #endif // __RHD2000THREAD_H_2C4CBD67__ diff --git a/Source/Processors/GenericProcessor/GenericProcessor.cpp b/Source/Processors/GenericProcessor/GenericProcessor.cpp index 618d475b8..3dfbba6b7 100755 --- a/Source/Processors/GenericProcessor/GenericProcessor.cpp +++ b/Source/Processors/GenericProcessor/GenericProcessor.cpp @@ -29,8 +29,8 @@ GenericProcessor::GenericProcessor(const String& name_) : AccessClass(), sourceNode(0), destNode(0), isEnabled(true), wasConnected(false), nextAvailableChannel(0), saveOrder(-1), loadOrder(-1), currentChannel(-1), - editor(0), parametersAsXml(nullptr), sendSampleCount(true), name(name_), - paramsWereLoaded(false), needsToSendTimestampMessage(false) + editor(0), parametersAsXml(nullptr), sendSampleCount(true), name(name_), + paramsWereLoaded(false), needsToSendTimestampMessage(false) { settings.numInputs = settings.numOutputs = settings.sampleRate = 0; @@ -285,14 +285,14 @@ void GenericProcessor::clearSettings() if (recordStatus.size() < channels.size()) recordStatus.resize(channels.size()); - if(monitorStatus.size() < channels.size()) - monitorStatus.resize(channels.size()); + if (monitorStatus.size() < channels.size()) + monitorStatus.resize(channels.size()); for (int i = 0; i < channels.size(); i++) { // std::cout << channels[i]->getRecordState() << std::endl; recordStatus.set(i,channels[i]->getRecordState()); - monitorStatus.set(i,channels[i]->isMonitored); + monitorStatus.set(i,channels[i]->isMonitored); } channels.clear(); @@ -333,12 +333,12 @@ void GenericProcessor::update() Channel* ch = new Channel(*sourceChan); ch->setProcessor(this); ch->nodeIndex = i; - ch->mappedIndex = i; + ch->mappedIndex = i; if (i < recordStatus.size()) { ch->setRecordState(recordStatus[i]); - ch->isMonitored = monitorStatus[i]; + ch->isMonitored = monitorStatus[i]; } channels.add(ch); @@ -369,7 +369,7 @@ void GenericProcessor::update() ch->bitVolts = getBitVolts(ch); ch->sourceNodeId = nodeId; ch->nodeIndex = nidx; - ch->mappedIndex = nidx; + ch->mappedIndex = nidx; if (i < recordStatus.size()) { @@ -393,7 +393,7 @@ void GenericProcessor::update() ch->bitVolts = getBitVolts(ch); ch->sourceNodeId = nodeId; ch->nodeIndex = nidx; - ch->mappedIndex = nidx; + ch->mappedIndex = nidx; if (j < recordStatus.size()) { @@ -417,7 +417,7 @@ void GenericProcessor::update() ch->bitVolts = getBitVolts(ch); ch->sourceNodeId = nodeId; ch->nodeIndex = nidx; - ch->mappedIndex = nidx; + ch->mappedIndex = nidx; if (k < recordStatus.size()) { @@ -485,17 +485,17 @@ void GenericProcessor::setRecording(bool state) if (ed != 0) ed->startRecording(); startRecording(); - if (generatesTimestamps()) - { - needsToSendTimestampMessage = true; - } + if (generatesTimestamps()) + { + needsToSendTimestampMessage = true; + } } else { if (ed != 0) ed->stopRecording(); stopRecording(); - needsToSendTimestampMessage = false; + needsToSendTimestampMessage = false; } } @@ -613,29 +613,29 @@ void GenericProcessor::setTimestamp(MidiBuffer& events, int64 timestamp) 0, // eventChannel 8, // numBytes data, // data - true // isTimestampEvent + true // isTimestampEvent ); - //since the processor generating the timestamp won't get the event, add it to the map - timestamps[nodeId] = timestamp; + //since the processor generating the timestamp won't get the event, add it to the map + timestamps[nodeId] = timestamp; - if (needsToSendTimestampMessage) - { - String eventString = "Processor: " + String(getNodeId()) + " start time: " + String(timestamp); + if (needsToSendTimestampMessage) + { + String eventString = "Processor: " + String(getNodeId()) + " start time: " + String(timestamp); - CharPointer_UTF8 data = eventString.toUTF8(); + CharPointer_UTF8 data = eventString.toUTF8(); - addEvent(events, - MESSAGE, - 0, - 0, - 0, - data.length() + 1, //It doesn't hurt to send the end-string null and can help avoid issues - (uint8*)data.getAddress(), - true); + addEvent(events, + MESSAGE, + 0, + 0, + 0, + data.length() + 1, //It doesn't hurt to send the end-string null and can help avoid issues + (uint8*)data.getAddress(), + true); - needsToSendTimestampMessage = false; - } + needsToSendTimestampMessage = false; + } } int GenericProcessor::processEventBuffer(MidiBuffer& events) @@ -711,7 +711,7 @@ int GenericProcessor::processEventBuffer(MidiBuffer& events) // changing the const cast is dangerous, but probably necessary: uint8* ptr = const_cast<uint8*>(dataptr); *(ptr + 4) = 0; // set fifth byte of raw data to 0, so the event - // won't be saved twice + // won't be saved twice } } } @@ -758,7 +758,7 @@ void GenericProcessor::addEvent(MidiBuffer& eventBuffer, uint8 eventChannel, uint8 numBytes, uint8* eventData, - bool isTimestamp) + bool isTimestamp) { uint8* data = new uint8[6+numBytes]; @@ -767,10 +767,10 @@ void GenericProcessor::addEvent(MidiBuffer& eventBuffer, data[2] = eventId; // event ID (1 = on, 0 = off, usually) data[3] = eventChannel; // event channel data[4] = 1; // saving flag - if (!isTimestamp) - data[5] = (uint8)eventChannels[eventChannel]->sourceNodeId; // source node ID (for nSamples) - else - data[5] = nodeId; + if (!isTimestamp) + data[5] = (uint8)eventChannels[eventChannel]->sourceNodeId; // source node ID (for nSamples) + else + data[5] = nodeId; memcpy(data + 6, eventData, numBytes); //std::cout << "Node id: " << data[1] << std::endl; diff --git a/Source/Processors/GenericProcessor/GenericProcessor.h b/Source/Processors/GenericProcessor/GenericProcessor.h index 16d0dae42..32059caf8 100755 --- a/Source/Processors/GenericProcessor/GenericProcessor.h +++ b/Source/Processors/GenericProcessor/GenericProcessor.h @@ -369,11 +369,11 @@ public: /** Sets one of two possible source nodes for a splitter.*/ virtual void setSplitterDestNode(GenericProcessor* dn) { } - /** Returns trus if a processor generates its own timestamps, false otherwise.*/ - virtual bool generatesTimestamps() - { - return false; - } + /** Returns trus if a processor generates its own timestamps, false otherwise.*/ + virtual bool generatesTimestamps() + { + return false; + } /** Returns true if a processor is a source, false otherwise.*/ virtual bool isSource() @@ -496,7 +496,7 @@ public: uint8 eventChannel = 0, uint8 numBytes = 0, uint8* data = 0, - bool isTimestamp = false); + bool isTimestamp = false); /** Makes it easier for processors to respond to incoming events, such as TTLs and spikes. @@ -651,7 +651,7 @@ private: /** Saves the record status of individual channels, even when other parameters are updated. */ Array<bool> recordStatus; - Array<bool> monitorStatus; + Array<bool> monitorStatus; /** Extracts sample counts and timestamps from the MidiBuffer. */ int processEventBuffer(MidiBuffer&); @@ -660,7 +660,7 @@ private: static const String unusedNameString; bool paramsWereLoaded; - bool needsToSendTimestampMessage; + bool needsToSendTimestampMessage; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(GenericProcessor); diff --git a/Source/Processors/SourceNode/SourceNode.cpp b/Source/Processors/SourceNode/SourceNode.cpp index a3b034d82..60367057b 100755 --- a/Source/Processors/SourceNode/SourceNode.cpp +++ b/Source/Processors/SourceNode/SourceNode.cpp @@ -43,10 +43,10 @@ SourceNode::SourceNode(const String& name_) { // dataThread = new IntanThread(this); // this thread has not been updated recently } - // else if (getName().equalsIgnoreCase("Custom FPGA")) - // { - // dataThread = new FPGAThread(this); - // } + // else if (getName().equalsIgnoreCase("Custom FPGA")) + // { + // dataThread = new FPGAThread(this); + // } else if (getName().equalsIgnoreCase("Rhythm FPGA")) { dataThread = new RHD2000Thread(this); @@ -110,10 +110,10 @@ DataThread* SourceNode::getThread() void SourceNode::requestChainUpdate() { - getEditorViewport()->makeEditorVisible(getEditor(), false, true); + getEditorViewport()->makeEditorVisible(getEditor(), false, true); } -void SourceNode::getEventChannelNames(StringArray &names) +void SourceNode::getEventChannelNames(StringArray& names) { if (dataThread != 0) dataThread->getEventChannelNames(names); @@ -129,7 +129,7 @@ void SourceNode::updateSettings() std::cout << "Input buffer address is " << inputBuffer << std::endl; } - dataThread->updateChannels(); + dataThread->updateChannels(); } @@ -208,10 +208,10 @@ int SourceNode::getNumEventChannels() float SourceNode::getBitVolts(Channel* chan) { - if (dataThread != 0) - return dataThread->getBitVolts(chan); - else - return 1.0f; + if (dataThread != 0) + return dataThread->getBitVolts(chan); + else + return 1.0f; } @@ -375,7 +375,7 @@ void SourceNode::process(AudioSampleBuffer& buffer, //std::cout << "Samples per buffer: " << nSamples << std::endl; - + // std::cout << (int) *(data + 7) << " " << // (int) *(data + 6) << " " << @@ -438,19 +438,19 @@ void SourceNode::process(AudioSampleBuffer& buffer, void SourceNode::saveCustomParametersToXml(XmlElement* parentElement) { - XmlElement *channelXml = parentElement->createNewChildElement("CHANNEL_INFO"); - if (dataThread->usesCustomNames()) - { - Array<ChannelCustomInfo> channelInfo; - dataThread->getChannelInfo(channelInfo); - for (int i = 0; i < channelInfo.size(); i++) - { - XmlElement* chan = channelXml->createNewChildElement("CHANNEL"); - chan->setAttribute("name", channelInfo[i].name); - chan->setAttribute("number", i); - chan->setAttribute("gain", channelInfo[i].gain); - } - } + XmlElement* channelXml = parentElement->createNewChildElement("CHANNEL_INFO"); + if (dataThread->usesCustomNames()) + { + Array<ChannelCustomInfo> channelInfo; + dataThread->getChannelInfo(channelInfo); + for (int i = 0; i < channelInfo.size(); i++) + { + XmlElement* chan = channelXml->createNewChildElement("CHANNEL"); + chan->setAttribute("name", channelInfo[i].name); + chan->setAttribute("number", i); + chan->setAttribute("gain", channelInfo[i].gain); + } + } } @@ -463,16 +463,16 @@ void SourceNode::loadCustomParametersFromXml() forEachXmlChildElement(*parametersAsXml, xmlNode) { - if (xmlNode->hasTagName("CHANNEL_INFO")) + if (xmlNode->hasTagName("CHANNEL_INFO")) { - forEachXmlChildElementWithTagName(*xmlNode,chan,"CHANNEL") - { - String name = chan->getStringAttribute("name"); - int number = chan->getIntAttribute("number"); - float gain = chan->getDoubleAttribute("gain"); - dataThread->modifyChannelGain(number, gain); - dataThread->modifyChannelName(number, name); - } + forEachXmlChildElementWithTagName(*xmlNode,chan,"CHANNEL") + { + String name = chan->getStringAttribute("name"); + int number = chan->getIntAttribute("number"); + float gain = chan->getDoubleAttribute("gain"); + dataThread->modifyChannelGain(number, gain); + dataThread->modifyChannelName(number, name); + } } } } diff --git a/Source/Processors/SourceNode/SourceNode.h b/Source/Processors/SourceNode/SourceNode.h index b96734dd9..4bfdd8d56 100755 --- a/Source/Processors/SourceNode/SourceNode.h +++ b/Source/Processors/SourceNode/SourceNode.h @@ -65,9 +65,9 @@ public: int getNumEventChannels(); float getBitVolts(Channel* chan); - void requestChainUpdate(); + void requestChainUpdate(); - void getEventChannelNames(StringArray &names); + void getEventChannelNames(StringArray& names); AudioProcessorEditor* createEditor(); bool hasEditor() const @@ -85,10 +85,10 @@ public: return true; } - bool generatesTimestamps() - { - return true; - } + bool generatesTimestamps() + { + return true; + } void acquisitionStopped(); diff --git a/Source/Processors/SpikeSorter/SpikeSorter.cpp b/Source/Processors/SpikeSorter/SpikeSorter.cpp index e29b2db7c..0eab93df0 100644 --- a/Source/Processors/SpikeSorter/SpikeSorter.cpp +++ b/Source/Processors/SpikeSorter/SpikeSorter.cpp @@ -33,95 +33,95 @@ class spikeSorter; SpikeSorter::SpikeSorter() : GenericProcessor("Spike Sorter"), - overflowBuffer(2,100), dataBuffer(nullptr), + overflowBuffer(2,100), dataBuffer(nullptr), overflowBufferSize(100), currentElectrode(-1), - numPreSamples(8),numPostSamples(32) -{ - uniqueID = 0; // for electrode count - uniqueSpikeID = 0; - juce::Time timer; - ticksPerSec = (float) timer.getHighResolutionTicksPerSecond(); - electrodeTypes.clear(); - electrodeCounter.clear(); + numPreSamples(8),numPostSamples(32) +{ + uniqueID = 0; // for electrode count + uniqueSpikeID = 0; + juce::Time timer; + ticksPerSec = (float) timer.getHighResolutionTicksPerSecond(); + electrodeTypes.clear(); + electrodeCounter.clear(); spikeBuffer = new uint8_t[MAX_SPIKE_BUFFER_LEN]; // MAX_SPIKE_BUFFER_LEN defined in SpikeObject.h - channelBuffers=nullptr; - PCAbeforeBoxes = true; - autoDACassignment = false; - syncThresholds = false; - flipSignal = false; + channelBuffers=nullptr; + PCAbeforeBoxes = true; + autoDACassignment = false; + syncThresholds = false; + flipSignal = false; } bool SpikeSorter::getFlipSignalState() { - return flipSignal; + return flipSignal; } void SpikeSorter::setFlipSignalState(bool state) { - flipSignal = state; + flipSignal = state; - mut.enter(); - if (currentElectrode >= 0) - { - if (electrodes[currentElectrode]->spikePlot != nullptr) - electrodes[currentElectrode]->spikePlot->setFlipSignal(state); + mut.enter(); + if (currentElectrode >= 0) + { + if (electrodes[currentElectrode]->spikePlot != nullptr) + electrodes[currentElectrode]->spikePlot->setFlipSignal(state); - } - mut.exit(); + } + mut.exit(); } int SpikeSorter::getNumPreSamples() { - return numPreSamples; + return numPreSamples; } int SpikeSorter::getNumPostSamples() { - return numPostSamples; + return numPostSamples; } bool SpikeSorter::getAutoDacAssignmentStatus() { - return autoDACassignment; + return autoDACassignment; } bool SpikeSorter::getThresholdSyncStatus() { - return syncThresholds; + return syncThresholds; } void SpikeSorter::setThresholdSyncStatus(bool status) { - syncThresholds= status; + syncThresholds= status; } void SpikeSorter::seteAutoDacAssignment(bool status) { - autoDACassignment = status; + autoDACassignment = status; } void SpikeSorter::setNumPreSamples(int numSamples) { - // we need to update all electrodes, and also inform other modules that this has happened.... - numPreSamples = numSamples; + // we need to update all electrodes, and also inform other modules that this has happened.... + numPreSamples = numSamples; + + for (int k = 0; k < electrodes.size(); k++) + { + electrodes[k]->resizeWaveform(numPreSamples,numPostSamples); + } - for (int k = 0; k < electrodes.size(); k++) - { - electrodes[k]->resizeWaveform(numPreSamples,numPostSamples); - } - } void SpikeSorter::setNumPostSamples(int numSamples) { - numPostSamples = numSamples; - for (int k = 0; k < electrodes.size(); k++) - { - electrodes[k]->resizeWaveform(numPreSamples,numPostSamples); - } + numPostSamples = numSamples; + for (int k = 0; k < electrodes.size(); k++) + { + electrodes[k]->resizeWaveform(numPreSamples,numPostSamples); + } } @@ -130,14 +130,14 @@ int SpikeSorter::getUniqueProbeID(String type) for (int i = 0; i < electrodeTypes.size(); i++) { if (electrodeTypes[i] == type) - { - return electrodeCounter[i]; - } + { + return electrodeCounter[i]; + } } - // if we reached here, we didn't find the type. Add it. - electrodeTypes.push_back(type); - electrodeCounter.push_back(1); - return 1; + // if we reached here, we didn't find the type. Add it. + electrodeTypes.push_back(type); + electrodeCounter.push_back(1); + return 1; } @@ -146,9 +146,9 @@ void SpikeSorter::increaseUniqueProbeID(String type) for (int i = 0; i < electrodeTypes.size(); i++) { if (electrodeTypes[i] == type) - { - electrodeCounter[i]++; - } + { + electrodeCounter[i]++; + } } } @@ -156,11 +156,11 @@ void SpikeSorter::increaseUniqueProbeID(String type) SpikeSorter::~SpikeSorter() { - delete spikeBuffer; - spikeBuffer = nullptr; + delete spikeBuffer; + spikeBuffer = nullptr; - if (channelBuffers != nullptr) - delete channelBuffers; + if (channelBuffers != nullptr) + delete channelBuffers; } @@ -169,26 +169,26 @@ SpikeSorter::~SpikeSorter() AudioProcessorEditor* SpikeSorter::createEditor() { editor = new SpikeSorterEditor(this, true); - + return editor; } void SpikeSorter::updateSettings() { - - mut.enter(); - int numChannels = getNumInputs(); + + mut.enter(); + int numChannels = getNumInputs(); if (numChannels > 0) overflowBuffer.setSize(getNumInputs(), overflowBufferSize); - if (channelBuffers != nullptr) - delete channelBuffers; + if (channelBuffers != nullptr) + delete channelBuffers; + + double SamplingRate = getSampleRate();; + double ContinuousBufferLengthSec = 5; + channelBuffers = new ContinuousCircularBuffer(numChannels,SamplingRate,1, ContinuousBufferLengthSec); + - double SamplingRate = getSampleRate();; - double ContinuousBufferLengthSec = 5; - channelBuffers = new ContinuousCircularBuffer(numChannels,SamplingRate,1, ContinuousBufferLengthSec); - - for (int i = 0; i < electrodes.size(); i++) { @@ -209,28 +209,28 @@ void SpikeSorter::updateSettings() eventChannels.add(ch); } - - mut.exit(); + + mut.exit(); } Electrode::~Electrode() { - delete thresholds; + delete thresholds; delete isActive; - delete voltageScale; + delete voltageScale; delete channels; - delete spikeSort; - delete runningStats; + delete spikeSort; + delete runningStats; } -Electrode::Electrode(int ID, UniqueIDgenerator *uniqueIDgenerator_, PCAcomputingThread *pth, String _name, int _numChannels, int *_channels, float default_threshold, int pre, int post, float samplingRate , int sourceNodeId) +Electrode::Electrode(int ID, UniqueIDgenerator* uniqueIDgenerator_, PCAcomputingThread* pth, String _name, int _numChannels, int* _channels, float default_threshold, int pre, int post, float samplingRate , int sourceNodeId) { - electrodeID = ID; - computingThread = pth; - uniqueIDgenerator = uniqueIDgenerator_; - name = _name; + electrodeID = ID; + computingThread = pth; + uniqueIDgenerator = uniqueIDgenerator_; + name = _name; numChannels = _numChannels; prePeakSamples = pre; @@ -239,82 +239,82 @@ Electrode::Electrode(int ID, UniqueIDgenerator *uniqueIDgenerator_, PCAcomputing thresholds = new double[numChannels]; isActive = new bool[numChannels]; channels = new int[numChannels]; - voltageScale = new double[numChannels]; - runningStats = new RunningStat[numChannels]; - depthOffsetMM = 0.0; + voltageScale = new double[numChannels]; + runningStats = new RunningStat[numChannels]; + depthOffsetMM = 0.0; - advancerID = -1; + advancerID = -1; for (int i = 0; i < numChannels; i++) { channels[i] = _channels[i]; - thresholds[i] = default_threshold; - isActive[i] = true; - voltageScale[i] = 500; + thresholds[i] = default_threshold; + isActive[i] = true; + voltageScale[i] = 500; } - spikePlot = nullptr; + spikePlot = nullptr; + + if (computingThread != nullptr) + spikeSort = new SpikeSortBoxes(uniqueIDgenerator, computingThread, numChannels, samplingRate, pre+post); + else + spikeSort = nullptr; - if (computingThread != nullptr) - spikeSort = new SpikeSortBoxes(uniqueIDgenerator, computingThread, numChannels, samplingRate, pre+post); - else - spikeSort = nullptr; - isMonitored = false; } void Electrode::resizeWaveform(int numPre, int numPost) { - // update electrode and all sorted units.... - // we can't keep pca space anymore, so we discard of all pca units (?) + // update electrode and all sorted units.... + // we can't keep pca space anymore, so we discard of all pca units (?) prePeakSamples = numPre; postPeakSamples = numPost; - //spikePlot = nullptr; - spikeSort->resizeWaveform(prePeakSamples+postPeakSamples); + //spikePlot = nullptr; + spikeSort->resizeWaveform(prePeakSamples+postPeakSamples); } void SpikeSorter::setElectrodeVoltageScale(int electrodeID, int index, float newvalue) { - std::vector<float> values; - mut.enter(); - for (int k = 0; k < electrodes.size(); k++) - { - if (electrodes[k]->electrodeID == electrodeID) - { - electrodes[k]->voltageScale[index] = newvalue; - mut.exit(); - return; - } - } - mut.exit(); + std::vector<float> values; + mut.enter(); + for (int k = 0; k < electrodes.size(); k++) + { + if (electrodes[k]->electrodeID == electrodeID) + { + electrodes[k]->voltageScale[index] = newvalue; + mut.exit(); + return; + } + } + mut.exit(); } std::vector<float> SpikeSorter::getElectrodeVoltageScales(int electrodeID) { - std::vector<float> values; - mut.enter(); - for (int k=0;k<electrodes.size();k++) - { - if (electrodes[k]->electrodeID == electrodeID) - { - values.resize(electrodes[k]->numChannels); - for (int i=0;i<electrodes[k]->numChannels;i++) - { - values[i] = electrodes[k]->voltageScale[i]; - } - mut.exit(); - return values; - } - } - mut.exit(); - return values; + std::vector<float> values; + mut.enter(); + for (int k=0; k<electrodes.size(); k++) + { + if (electrodes[k]->electrodeID == electrodeID) + { + values.resize(electrodes[k]->numChannels); + for (int i=0; i<electrodes[k]->numChannels; i++) + { + values[i] = electrodes[k]->voltageScale[i]; + } + mut.exit(); + return values; + } + } + mut.exit(); + return values; } // void SpikeSorter::setElectrodeAdvancerOffset(int i, double v) // { // mut.enter(); -// if (i >= 0) +// if (i >= 0) // { // electrodes[i]->depthOffsetMM = v; // addNetworkEventToQueue(StringTS("NewElectrodeDepthOffset "+String(electrodes[i]->electrodeID)+" "+String(v,4))); @@ -325,7 +325,7 @@ std::vector<float> SpikeSorter::getElectrodeVoltageScales(int electrodeID) // void SpikeSorter::setElectrodeAdvancer(int i, int ID) // { // mut.enter(); -// if (i >= 0) +// if (i >= 0) // { // electrodes[i]->advancerID = ID; // } @@ -334,100 +334,100 @@ std::vector<float> SpikeSorter::getElectrodeVoltageScales(int electrodeID) void SpikeSorter::addNewUnit(int electrodeID, int newUnitID, uint8 r, uint8 g, uint8 b) { - String eventlog = "NewUnit "+String(electrodeID) + " "+String(newUnitID)+" "+String(r)+" "+String(g)+" "+String(b); - //addNetworkEventToQueue(StringTS(eventlog)); - updateSinks( electrodeID, newUnitID, r,g,b,true); + String eventlog = "NewUnit "+String(electrodeID) + " "+String(newUnitID)+" "+String(r)+" "+String(g)+" "+String(b); + //addNetworkEventToQueue(StringTS(eventlog)); + updateSinks(electrodeID, newUnitID, r,g,b,true); } void SpikeSorter::removeUnit(int electrodeID, int unitID) { - String eventlog = "RemoveUnit "+String(electrodeID) + " "+String(unitID); - //addNetworkEventToQueue(StringTS(eventlog)); - updateSinks( electrodeID, unitID, 0,0,0,false); - + String eventlog = "RemoveUnit "+String(electrodeID) + " "+String(unitID); + //addNetworkEventToQueue(StringTS(eventlog)); + updateSinks(electrodeID, unitID, 0,0,0,false); + } void SpikeSorter::removeAllUnits(int electrodeID) { - String eventlog = "RemoveAllUnits "+String(electrodeID); - //addNetworkEventToQueue(StringTS(eventlog)); - updateSinks( electrodeID,true); + String eventlog = "RemoveAllUnits "+String(electrodeID); + //addNetworkEventToQueue(StringTS(eventlog)); + updateSinks(electrodeID,true); } RHD2000Thread* SpikeSorter::getRhythmAccess() { - ProcessorGraph *gr = getProcessorGraph(); - Array<GenericProcessor*> p = gr->getListOfProcessors(); - for (int k=0;k<p.size();k++) - { - if (p[k]->getName() == "Rhythm FPGA") - { - SourceNode* src = (SourceNode* )p[k]; - return (RHD2000Thread*)src->getThread(); - } - } - return nullptr; + ProcessorGraph* gr = getProcessorGraph(); + Array<GenericProcessor*> p = gr->getListOfProcessors(); + for (int k=0; k<p.size(); k++) + { + if (p[k]->getName() == "Rhythm FPGA") + { + SourceNode* src = (SourceNode*)p[k]; + return (RHD2000Thread*)src->getThread(); + } + } + return nullptr; } void SpikeSorter::updateDACthreshold(int dacChannel, float threshold) { - RHD2000Thread* th = getRhythmAccess(); - if (th != nullptr) - { - th->setDACthreshold(dacChannel,threshold); - } + RHD2000Thread* th = getRhythmAccess(); + if (th != nullptr) + { + th->setDACthreshold(dacChannel,threshold); + } } Array<int> SpikeSorter::getDACassignments() { - Array<int> dacChannels ; - RHD2000Thread* th = getRhythmAccess(); - if (th != nullptr) - { - dacChannels = th->getDACchannels(); - } - return dacChannels; + Array<int> dacChannels ; + RHD2000Thread* th = getRhythmAccess(); + if (th != nullptr) + { + dacChannels = th->getDACchannels(); + } + return dacChannels; } int SpikeSorter::getDACassignment(int dacchannel) { - RHD2000Thread* th = getRhythmAccess(); - if (th != nullptr) - { - Array<int> dacChannels = th->getDACchannels(); - return dacChannels[dacchannel]; - } - - return -1; // not assigned + RHD2000Thread* th = getRhythmAccess(); + if (th != nullptr) + { + Array<int> dacChannels = th->getDACchannels(); + return dacChannels[dacchannel]; + } + + return -1; // not assigned } void SpikeSorter::assignDACtoChannel(int dacOutput, int channel) { - // inform sinks about a new unit - //getSourceNode() - RHD2000Thread* th = getRhythmAccess(); - if (th != nullptr) - { - th->setDACchannel(dacOutput, channel); // this is probably wrong (JHS) - } + // inform sinks about a new unit + //getSourceNode() + RHD2000Thread* th = getRhythmAccess(); + if (th != nullptr) + { + th->setDACchannel(dacOutput, channel); // this is probably wrong (JHS) + } } void SpikeSorter::addElectrode(Electrode* newElectrode) { - mut.enter(); + mut.enter(); resetElectrode(newElectrode); electrodes.add(newElectrode); - // inform PSTH sink, if it exists, about this new electrode. - updateSinks(newElectrode); - mut.exit(); + // inform PSTH sink, if it exists, about this new electrode. + updateSinks(newElectrode); + mut.exit(); } bool SpikeSorter::addElectrode(int nChans, String name, double Depth) { - mut.enter(); + mut.enter(); int firstChan; if (electrodes.size() == 0) @@ -442,35 +442,35 @@ bool SpikeSorter::addElectrode(int nChans, String name, double Depth) if (firstChan + nChans > getNumInputs()) { - mut.exit(); + mut.exit(); return false; } - - int *chans = new int[nChans]; - for (int k = 0; k < nChans; k++) - chans[k] = firstChan + k; - Electrode* newElectrode = new Electrode(++uniqueID, &uniqueIDgenerator, &computingThread, name, nChans, chans, getDefaultThreshold(), - numPreSamples, numPostSamples, getSampleRate(), channels[chans[0]]->sourceNodeId); + int* chans = new int[nChans]; + for (int k = 0; k < nChans; k++) + chans[k] = firstChan + k; + + Electrode* newElectrode = new Electrode(++uniqueID, &uniqueIDgenerator, &computingThread, name, nChans, chans, getDefaultThreshold(), + numPreSamples, numPostSamples, getSampleRate(), channels[chans[0]]->sourceNodeId); - newElectrode->depthOffsetMM = Depth; - String log = "Added electrode (ID "+ String(uniqueID)+") with " + String(nChans) + " channels." ; + newElectrode->depthOffsetMM = Depth; + String log = "Added electrode (ID "+ String(uniqueID)+") with " + String(nChans) + " channels." ; std::cout << log << std::endl; for (int i = 0; i < nChans; i++) { - std::cout << " Channel " << i << " = " << newElectrode->channels[i] << std::endl; + std::cout << " Channel " << i << " = " << newElectrode->channels[i] << std::endl; } - String eventlog = "NewElectrode "+ String(uniqueID) + " " + String(nChans) + " "; - for (int k = 0; k < nChans; k++) - eventlog += String(chans[k])+ " " + name; + String eventlog = "NewElectrode "+ String(uniqueID) + " " + String(nChans) + " "; + for (int k = 0; k < nChans; k++) + eventlog += String(chans[k])+ " " + name; - //addNetworkEventToQueue(StringTS(eventlog)); + //addNetworkEventToQueue(StringTS(eventlog)); resetElectrode(newElectrode); electrodes.add(newElectrode); - updateSinks(newElectrode); - setCurrentElectrodeIndex(electrodes.size()-1); - mut.exit(); + updateSinks(newElectrode); + setCurrentElectrodeIndex(electrodes.size()-1); + mut.exit(); return true; } @@ -483,12 +483,12 @@ float SpikeSorter::getDefaultThreshold() StringArray SpikeSorter::getElectrodeNames() { StringArray names; - mut.enter(); + mut.enter(); for (int i = 0; i < electrodes.size(); i++) { names.add(electrodes[i]->name); } - mut.exit(); + mut.exit(); return names; } @@ -499,76 +499,77 @@ void SpikeSorter::resetElectrode(Electrode* e) bool SpikeSorter::removeElectrode(int index) { - mut.enter(); + mut.enter(); // std::cout << "Spike detector removing electrode" << std::endl; - if (index > electrodes.size() || index < 0) { + if (index > electrodes.size() || index < 0) + { mut.exit(); - return false; - } + return false; + } + - - String log = "Removing electrode (ID " + String(electrodes[index]->electrodeID)+")"; - std::cout << log <<std::endl; + String log = "Removing electrode (ID " + String(electrodes[index]->electrodeID)+")"; + std::cout << log <<std::endl; - String eventlog = "RemoveElectrode " + String(electrodes[index]->electrodeID); - //addNetworkEventToQueue(StringTS(eventlog)); - - int idToRemove = electrodes[index]->electrodeID; + String eventlog = "RemoveElectrode " + String(electrodes[index]->electrodeID); + //addNetworkEventToQueue(StringTS(eventlog)); + + int idToRemove = electrodes[index]->electrodeID; electrodes.remove(index); - //(idToRemove); + //(idToRemove); - if (electrodes.size() > 0) - currentElectrode = electrodes.size()-1; - else - currentElectrode = -1; - - mut.exit(); + if (electrodes.size() > 0) + currentElectrode = electrodes.size()-1; + else + currentElectrode = -1; + + mut.exit(); return true; } void SpikeSorter::setElectrodeName(int index, String newName) { - mut.enter(); - if ((electrodes.size() > 0) && (index > 0)) - electrodes[index-1]->name = newName; - updateSinks(electrodes[index-1]->electrodeID, newName); - mut.exit(); + mut.enter(); + if ((electrodes.size() > 0) && (index > 0)) + electrodes[index-1]->name = newName; + updateSinks(electrodes[index-1]->electrodeID, newName); + mut.exit(); } void SpikeSorter::setChannel(int electrodeIndex, int channelNum, int newChannel) { - mut.enter(); - String log = "Setting electrode " + String(electrodeIndex) + " channel " + String( channelNum )+ - " to " + String( newChannel ); + mut.enter(); + String log = "Setting electrode " + String(electrodeIndex) + " channel " + String(channelNum)+ + " to " + String(newChannel); std::cout << log<< std::endl; - - String eventlog = "ChanelElectrodeChannel " + String(electrodes[electrodeIndex]->electrodeID) + " " + String(channelNum) + " " + String(newChannel); - //addNetworkEventToQueue(StringTS(eventlog)); - - updateSinks(electrodes[electrodeIndex]->electrodeID, channelNum,newChannel); + + String eventlog = "ChanelElectrodeChannel " + String(electrodes[electrodeIndex]->electrodeID) + " " + String(channelNum) + " " + String(newChannel); + //addNetworkEventToQueue(StringTS(eventlog)); + + updateSinks(electrodes[electrodeIndex]->electrodeID, channelNum,newChannel); *(electrodes[electrodeIndex]->channels+channelNum) = newChannel; - mut.exit(); + mut.exit(); } int SpikeSorter::getNumChannels(int index) { - mut.enter(); + mut.enter(); int i=electrodes[index]->numChannels; - mut.exit(); - return i; + mut.exit(); + return i; } int SpikeSorter::getChannel(int index, int i) { - mut.enter(); + mut.enter(); int ii=*(electrodes[index]->channels+i); - mut.exit(); - return ii; + mut.exit(); + return ii; } @@ -582,55 +583,55 @@ void SpikeSorter::setChannelActive(int electrodeIndex, int subChannel, bool acti setParameter(98, 1); else setParameter(98, 0); - - //getEditorViewport()->makeEditorVisible(this, true, true); + + //getEditorViewport()->makeEditorVisible(this, true, true); } bool SpikeSorter::isChannelActive(int electrodeIndex, int i) { - mut.enter(); - bool b= *(electrodes[electrodeIndex]->isActive+i); - mut.exit(); - return b; + mut.enter(); + bool b= *(electrodes[electrodeIndex]->isActive+i); + mut.exit(); + return b; } void SpikeSorter::setChannelThreshold(int electrodeNum, int channelNum, float thresh) { - mut.enter(); + mut.enter(); currentElectrode = electrodeNum; currentChannelIndex = channelNum; - electrodes[electrodeNum]->thresholds[channelNum] = thresh; - if (electrodes[electrodeNum]->spikePlot != nullptr) - electrodes[electrodeNum]->spikePlot->setDisplayThresholdForChannel(channelNum,thresh); + electrodes[electrodeNum]->thresholds[channelNum] = thresh; + if (electrodes[electrodeNum]->spikePlot != nullptr) + electrodes[electrodeNum]->spikePlot->setDisplayThresholdForChannel(channelNum,thresh); - if (syncThresholds) - { - for (int k=0;k<electrodes.size();k++) - { - for (int i=0;i<electrodes[k]->numChannels;i++) - { - electrodes[k]->thresholds[i] = thresh; - } - } - } + if (syncThresholds) + { + for (int k=0; k<electrodes.size(); k++) + { + for (int i=0; i<electrodes[k]->numChannels; i++) + { + electrodes[k]->thresholds[i] = thresh; + } + } + } - mut.exit(); + mut.exit(); setParameter(99, thresh); } double SpikeSorter::getChannelThreshold(int electrodeNum, int channelNum) { mut.enter(); - double f= *(electrodes[electrodeNum]->thresholds+channelNum); - mut.exit(); - return f; + double f= *(electrodes[electrodeNum]->thresholds+channelNum); + mut.exit(); + return f; } void SpikeSorter::setParameter(int parameterIndex, float newValue) { //editor->updateParameterButtons(parameterIndex); - mut.enter(); + mut.enter(); if (parameterIndex == 99 && currentElectrode > -1) { *(electrodes[currentElectrode]->thresholds+currentChannelIndex) = newValue; @@ -642,7 +643,7 @@ void SpikeSorter::setParameter(int parameterIndex, float newValue) else *(electrodes[currentElectrode]->isActive+currentChannelIndex) = true; } - mut.exit(); + mut.exit(); } @@ -655,9 +656,9 @@ bool SpikeSorter::enable() useOverflowBuffer.add(false); - SpikeSorterEditor* editor = (SpikeSorterEditor*) getEditor(); - editor->enable(); - + SpikeSorterEditor* editor = (SpikeSorterEditor*) getEditor(); + editor->enable(); + return true; } @@ -670,20 +671,20 @@ bool SpikeSorter::isReady() bool SpikeSorter::disable() { - mut.enter(); + mut.enter(); for (int n = 0; n < electrodes.size(); n++) { resetElectrode(electrodes[n]); } - //editor->disable(); - mut.exit(); + //editor->disable(); + mut.exit(); return true; } Electrode* SpikeSorter::getActiveElectrode() { if (electrodes.size() == 0) - return nullptr; + return nullptr; return electrodes[currentElectrode]; } @@ -693,7 +694,7 @@ void SpikeSorter::addSpikeEvent(SpikeObject* s, MidiBuffer& eventBuffer, int pea { // std::cout << "Adding spike event for index " << peakIndex << std::endl; - + s->eventType = SPIKE_EVENT_CODE; int numBytes = packSpike(s, // SpikeObject @@ -702,30 +703,30 @@ void SpikeSorter::addSpikeEvent(SpikeObject* s, MidiBuffer& eventBuffer, int pea if (numBytes > 0) eventBuffer.addEvent(spikeBuffer, numBytes, peakIndex); - + //std::cout << "Adding spike" << std::endl; } void SpikeSorter::addWaveformToSpikeObject(SpikeObject* s, - int& peakIndex, - int& electrodeNumber, - int& currentChannel) + int& peakIndex, + int& electrodeNumber, + int& currentChannel) { - mut.enter(); + mut.enter(); int spikeLength = electrodes[electrodeNumber]->prePeakSamples + + electrodes[electrodeNumber]->postPeakSamples; - + s->timestamp = getTimestamp(currentChannel) + peakIndex; - // convert sample offset to software ticks - float samplesPerSec = getSampleRate(); - s->timestamp_software = software_timestamp + int64( ticksPerSec*float(peakIndex)/samplesPerSec); + // convert sample offset to software ticks + float samplesPerSec = getSampleRate(); + s->timestamp_software = software_timestamp + int64(ticksPerSec*float(peakIndex)/samplesPerSec); s->nSamples = spikeLength; int chan = *(electrodes[electrodeNumber]->channels+currentChannel); - s->gain[currentChannel] = (1.0f / channels[chan]->bitVolts)*1000; - s->threshold[currentChannel] = (int) electrodes[electrodeNumber]->thresholds[currentChannel]; + s->gain[currentChannel] = (1.0f / channels[chan]->bitVolts)*1000; + s->threshold[currentChannel] = (int) electrodes[electrodeNumber]->thresholds[currentChannel]; // cycle through buffer @@ -733,14 +734,14 @@ void SpikeSorter::addWaveformToSpikeObject(SpikeObject* s, { for (int sample = 0; sample < spikeLength; sample++) - { + { // warning -- be careful of bitvolts conversion - // do not flip signal (!). - float value = getNextSample(electrodes[electrodeNumber]->channels[currentChannel]); - s->data[currentIndex] = uint16(jmin(65535,jmax(0, int(value / channels[chan]->bitVolts) + 32768))); - // recovered data - //float value2 = (s->data[currentIndex]-32768) /float(s->gain[currentChannel])*1000.0f; + // do not flip signal (!). + float value = getNextSample(electrodes[electrodeNumber]->channels[currentChannel]); + s->data[currentIndex] = uint16(jmin(65535,jmax(0, int(value / channels[chan]->bitVolts) + 32768))); + // recovered data + //float value2 = (s->data[currentIndex]-32768) /float(s->gain[currentChannel])*1000.0f; currentIndex++; sampleIndex++; @@ -766,46 +767,46 @@ void SpikeSorter::addWaveformToSpikeObject(SpikeObject* s, sampleIndex -= spikeLength; // reset sample index - mut.exit(); + mut.exit(); } void SpikeSorter::startRecording() { - // send status messages about which electrodes and units are available. - mut.enter(); - for (int k=0;k<electrodes.size();k++) - { - String eventlog = "CurrentElectrodes "+String(electrodes[k]->electrodeID) + " "+ String(electrodes[k]->advancerID) + " "+String(electrodes[k]->depthOffsetMM) + " "+ - String(electrodes[k]->numChannels) + " "; - for (int i=0;i<electrodes[k]->numChannels;i++) - { - eventlog += String(electrodes[k]->channels[i])+ " " + electrodes[k]->name; - } - //addNetworkEventToQueue(StringTS(eventlog)); + // send status messages about which electrodes and units are available. + mut.enter(); + for (int k=0; k<electrodes.size(); k++) + { + String eventlog = "CurrentElectrodes "+String(electrodes[k]->electrodeID) + " "+ String(electrodes[k]->advancerID) + " "+String(electrodes[k]->depthOffsetMM) + " "+ + String(electrodes[k]->numChannels) + " "; + for (int i=0; i<electrodes[k]->numChannels; i++) + { + eventlog += String(electrodes[k]->channels[i])+ " " + electrodes[k]->name; + } + //addNetworkEventToQueue(StringTS(eventlog)); - std::vector<BoxUnit> boxUnits = electrodes[k]->spikeSort->getBoxUnits(); - for (int i=0;i<boxUnits.size();i++) - { - String eventlog = "CurrentElectrodeUnits "+String(electrodes[k]->electrodeID) + " " + String(boxUnits[i].UnitID); - } + std::vector<BoxUnit> boxUnits = electrodes[k]->spikeSort->getBoxUnits(); + for (int i=0; i<boxUnits.size(); i++) + { + String eventlog = "CurrentElectrodeUnits "+String(electrodes[k]->electrodeID) + " " + String(boxUnits[i].UnitID); + } - std::vector<PCAUnit> pcaUnits = electrodes[k]->spikeSort->getPCAUnits(); - for (int i=0;i<pcaUnits.size();i++) - { - String eventlog = "CurrentElectrodeUnits "+String(electrodes[k]->electrodeID) + " " + String(pcaUnits[i].UnitID); - } + std::vector<PCAUnit> pcaUnits = electrodes[k]->spikeSort->getPCAUnits(); + for (int i=0; i<pcaUnits.size(); i++) + { + String eventlog = "CurrentElectrodeUnits "+String(electrodes[k]->electrodeID) + " " + String(pcaUnits[i].UnitID); + } - } - - mut.exit(); + } + + mut.exit(); } // int64 SpikeSorter::getExtrapolatedHardwareTimestamp(int64 softwareTS) // { // Time timer; // // this is the case in which messages arrived before the data stream started.... -// if (hardware_timestamp == 0) +// if (hardware_timestamp == 0) // return 0; // // compute how many ticks passed since the last known software-hardware pair @@ -821,7 +822,7 @@ void SpikeSorter::startRecording() // void SpikeSorter::postTimestamppedStringToMidiBuffer(StringTS s, MidiBuffer& events) // { // uint8* msg_with_ts = new uint8[s.len+8]; // for the two timestamps -// memcpy(msg_with_ts, s.str, s.len); +// memcpy(msg_with_ts, s.str, s.len); // memcpy(msg_with_ts+s.len, &s.timestamp, 8); // addEvent(events, // eventBuffer @@ -838,10 +839,10 @@ void SpikeSorter::startRecording() void SpikeSorter::handleEvent(int eventType, MidiMessage& event, int sampleNum) { if (eventType == TIMESTAMP) - { + { const uint8* dataptr = event.getRawData(); - memcpy(&hardware_timestamp, dataptr + 4, 8); // remember to skip first four bytes - memcpy(&software_timestamp, dataptr + 12, 8); // remember to skip first four bytes + memcpy(&hardware_timestamp, dataptr + 4, 8); // remember to skip first four bytes + memcpy(&software_timestamp, dataptr + 12, 8); // remember to skip first four bytes } } @@ -866,36 +867,36 @@ void SpikeSorter::handleEvent(int eventType, MidiMessage& event, int sampleNum) float SpikeSorter::getSelectedElectrodeNoise() { - if (electrodes.size() == 0) - return 0.0; + if (electrodes.size() == 0) + return 0.0; - // TODO, change "0" to active channel to support tetrodes. - return electrodes[currentElectrode]->runningStats[0].StandardDeviation(); + // TODO, change "0" to active channel to support tetrodes. + return electrodes[currentElectrode]->runningStats[0].StandardDeviation(); } void SpikeSorter::clearRunningStatForSelectedElectrode() { - if (electrodes.size() == 0) - return; - // TODO, change "0" to active channel to support tetrodes. - electrodes[currentElectrode]->runningStats[0].Clear(); + if (electrodes.size() == 0) + return; + // TODO, change "0" to active channel to support tetrodes. + electrodes[currentElectrode]->runningStats[0].Clear(); } void SpikeSorter::process(AudioSampleBuffer& buffer, - MidiBuffer& events) + MidiBuffer& events) { - - //printf("Entering Spike Detector::process\n"); - mut.enter(); - uint16_t samplingFrequencyHz = getSampleRate();//buffer.getSamplingFrequency(); + + //printf("Entering Spike Detector::process\n"); + mut.enter(); + uint16_t samplingFrequencyHz = getSampleRate();//buffer.getSamplingFrequency(); // cycle through electrodes Electrode* electrode; dataBuffer = &buffer; - + checkForEvents(events); // find latest's packet timestamps - - //channelBuffers->update(buffer, hardware_timestamp,software_timestamp, nSamples); + + //channelBuffers->update(buffer, hardware_timestamp,software_timestamp, nSamples); for (int i = 0; i < electrodes.size(); i++) { @@ -915,28 +916,28 @@ void SpikeSorter::process(AudioSampleBuffer& buffer, { sampleIndex++; - + // cycle through channels for (int chan = 0; chan < electrode->numChannels; chan++) { // std::cout << " channel " << chan << std::endl; - + if (*(electrode->isActive+chan)) { - //float v = getNextSample(currentChannel); + //float v = getNextSample(currentChannel); int currentChannel = electrode->channels[chan]; - float currentValue = getNextSample(currentChannel); - electrode->runningStats[chan].Push(currentValue); + float currentValue = getNextSample(currentChannel); + electrode->runningStats[chan].Push(currentValue); - bool bSpikeDetectedPositive = electrode->thresholds[chan] > 0 && - (currentValue > electrode->thresholds[chan]); // rising edge - bool bSpikeDetectedNegative = electrode->thresholds[chan] < 0 && - (currentValue < electrode->thresholds[chan]); // falling edge + bool bSpikeDetectedPositive = electrode->thresholds[chan] > 0 && + (currentValue > electrode->thresholds[chan]); // rising edge + bool bSpikeDetectedNegative = electrode->thresholds[chan] < 0 && + (currentValue < electrode->thresholds[chan]); // falling edge - if (bSpikeDetectedPositive || bSpikeDetectedNegative) - { + if (bSpikeDetectedPositive || bSpikeDetectedNegative) + { //std::cout << "Spike detected on electrode " << i << std::endl; // find the peak @@ -945,36 +946,38 @@ void SpikeSorter::process(AudioSampleBuffer& buffer, //if (sampleIndex == 0 && i == 0) // std::cout << getCurrentSample(currentChannel) << std::endl; - if (bSpikeDetectedPositive) - { - // find localmaxima - while (getCurrentSample(currentChannel) < getNextSample(currentChannel) && - sampleIndex < peakIndex + electrode->postPeakSamples) - { - sampleIndex++; - } - } else { - // find local minimum - - while (getCurrentSample(currentChannel) > getNextSample(currentChannel) && - sampleIndex < peakIndex + electrode->postPeakSamples) - { - sampleIndex++; - } - } + if (bSpikeDetectedPositive) + { + // find localmaxima + while (getCurrentSample(currentChannel) < getNextSample(currentChannel) && + sampleIndex < peakIndex + electrode->postPeakSamples) + { + sampleIndex++; + } + } + else + { + // find local minimum + + while (getCurrentSample(currentChannel) > getNextSample(currentChannel) && + sampleIndex < peakIndex + electrode->postPeakSamples) + { + sampleIndex++; + } + } peakIndex = sampleIndex; sampleIndex -= (electrode->prePeakSamples+1); SpikeObject newSpike; - newSpike.sortedId = 0; // unsorted. + newSpike.sortedId = 0; // unsorted. newSpike.timestamp = getTimestamp(currentChannel) + peakIndex; - newSpike.electrodeID = electrode->electrodeID; - newSpike.channel = chan; + newSpike.electrodeID = electrode->electrodeID; + newSpike.channel = chan; newSpike.source = i; newSpike.nChannels = electrode->numChannels; - newSpike.samplingFrequencyHz = samplingFrequencyHz; - newSpike.color[0] = newSpike.color[1] = newSpike.color[2] = 127; + newSpike.samplingFrequencyHz = samplingFrequencyHz; + newSpike.color[0] = newSpike.color[1] = newSpike.color[2] = 127; currentIndex = 0; // package spikes; @@ -989,42 +992,43 @@ void SpikeSorter::process(AudioSampleBuffer& buffer, //std::cout << "adding waveform" << std::endl; } - /* - bool perfectMatch = true; - for (int k=0;k<40;k++) { - perfectMatch = perfectMatch & (prevSpike.data[k] == newSpike.data[k]); - } - if (perfectMatch) - { - int x; - x++; - } - */ - - //for (int xxx = 0; xxx < 1000; xxx++) // overload with spikes for testing purposes - electrode->spikeSort->projectOnPrincipalComponents(&newSpike); - - // Add spike to drawing buffer.... - electrode->spikeSort->sortSpike(&newSpike, PCAbeforeBoxes); - - - // transfer buffered spikes to spike plot - if (electrode->spikePlot != nullptr) { - if (electrode->spikeSort->isPCAfinished()) - { - electrode->spikeSort->resetJobStatus(); - float p1min,p2min, p1max, p2max; - electrode->spikeSort->getPCArange(p1min,p2min, p1max, p2max); - electrode->spikePlot->setPCARange(p1min,p2min, p1max, p2max); - } - - - electrode->spikePlot->processSpikeObject(newSpike); - } - - - addSpikeEvent(&newSpike, events, peakIndex); - //prevSpike = newSpike; + /* + bool perfectMatch = true; + for (int k=0;k<40;k++) { + perfectMatch = perfectMatch & (prevSpike.data[k] == newSpike.data[k]); + } + if (perfectMatch) + { + int x; + x++; + } + */ + + //for (int xxx = 0; xxx < 1000; xxx++) // overload with spikes for testing purposes + electrode->spikeSort->projectOnPrincipalComponents(&newSpike); + + // Add spike to drawing buffer.... + electrode->spikeSort->sortSpike(&newSpike, PCAbeforeBoxes); + + + // transfer buffered spikes to spike plot + if (electrode->spikePlot != nullptr) + { + if (electrode->spikeSort->isPCAfinished()) + { + electrode->spikeSort->resetJobStatus(); + float p1min,p2min, p1max, p2max; + electrode->spikeSort->getPCArange(p1min,p2min, p1max, p2max); + electrode->spikePlot->setPCARange(p1min,p2min, p1max, p2max); + } + + + electrode->spikePlot->processSpikeObject(newSpike); + } + + + addSpikeEvent(&newSpike, events, peakIndex); + //prevSpike = newSpike; // advance the sample index sampleIndex = peakIndex + electrode->postPeakSamples; @@ -1037,7 +1041,7 @@ void SpikeSorter::process(AudioSampleBuffer& buffer, } // end cycle through samples - //float vv = getNextSample(currentChannel); + //float vv = getNextSample(currentChannel); electrode->lastBufferIndex = sampleIndex - nSamples; // should be negative //jassert(electrode->lastBufferIndex < 0); @@ -1047,13 +1051,13 @@ void SpikeSorter::process(AudioSampleBuffer& buffer, for (int j = 0; j < electrode->numChannels; j++) { - //std::cout << "Processing " << *electrode->channels+i << std::endl; + //std::cout << "Processing " << *electrode->channels+i << std::endl; overflowBuffer.copyFrom(*(electrode->channels+j), 0, buffer, *(electrode->channels+j), nSamples-overflowBufferSize, overflowBufferSize); - + } useOverflowBuffer.set(i, true); @@ -1067,8 +1071,8 @@ void SpikeSorter::process(AudioSampleBuffer& buffer, } // end cycle through electrodes - mut.exit(); - //printf("Exitting Spike Detector::process\n"); + mut.exit(); + //printf("Exitting Spike Detector::process\n"); } float SpikeSorter::getNextSample(int& chan) @@ -1148,30 +1152,31 @@ bool SpikeSorter::samplesAvailable(int nSamples) void SpikeSorter::addProbes(String probeType,int numProbes, int nElectrodesPerProbe, int nChansPerElectrode, double firstContactOffset, double interelectrodeDistance) { - for (int probeIter=0;probeIter<numProbes;probeIter++) - { - int probeCounter = getUniqueProbeID(probeType); - for (int electrodeIter = 0; electrodeIter < nElectrodesPerProbe; electrodeIter++) - { - double depth = firstContactOffset - electrodeIter*interelectrodeDistance; - String name; - if (nElectrodesPerProbe > 1) - name = probeType + " " + String(probeCounter) + " ["+String(electrodeIter+1)+"/"+String(nElectrodesPerProbe)+"]"; - else - name = probeType + " " + String(probeCounter); - - bool successful = addElectrode(nChansPerElectrode, name, depth); - if (!successful) { + for (int probeIter=0; probeIter<numProbes; probeIter++) + { + int probeCounter = getUniqueProbeID(probeType); + for (int electrodeIter = 0; electrodeIter < nElectrodesPerProbe; electrodeIter++) + { + double depth = firstContactOffset - electrodeIter*interelectrodeDistance; + String name; + if (nElectrodesPerProbe > 1) + name = probeType + " " + String(probeCounter) + " ["+String(electrodeIter+1)+"/"+String(nElectrodesPerProbe)+"]"; + else + name = probeType + " " + String(probeCounter); + + bool successful = addElectrode(nChansPerElectrode, name, depth); + if (!successful) + { sendActionMessage("Not enough channels to add electrode."); - return; - } - } - increaseUniqueProbeID(probeType); - } + return; + } + } + increaseUniqueProbeID(probeType); + } } Array<Electrode*> SpikeSorter::getElectrodes() { - return electrodes; + return electrodes; } // double SpikeSorter::getAdvancerPosition(int advancerID) @@ -1217,19 +1222,19 @@ Array<Electrode*> SpikeSorter::getElectrodes() bool SpikeSorter::isSelectedElectrodeRecorded(int channel_index) { - if (electrodes.size() == 0) - return false; - int channel = electrodes[currentElectrode]->channels[channel_index]; - RecordNode* recordNode = getProcessorGraph()->getRecordNode(); - - StringArray names; - Array<bool> recording; - recordNode->getChannelNamesAndRecordingStatus(names, recording); - if (channel >= 0 && channel < recording.size()) - return recording[channel]; + if (electrodes.size() == 0) + return false; + int channel = electrodes[currentElectrode]->channels[channel_index]; + RecordNode* recordNode = getProcessorGraph()->getRecordNode(); + + StringArray names; + Array<bool> recording; + recordNode->getChannelNamesAndRecordingStatus(names, recording); + if (channel >= 0 && channel < recording.size()) + return recording[channel]; - return false; - //return electrodes[currentElectrode]->depthOffsetMM + currentAdvancerPos; + return false; + //return electrodes[currentElectrode]->depthOffsetMM + currentAdvancerPos; } void SpikeSorter::saveCustomParametersToXml(XmlElement* parentElement) @@ -1237,25 +1242,25 @@ void SpikeSorter::saveCustomParametersToXml(XmlElement* parentElement) XmlElement* mainNode = parentElement->createNewChildElement("SpikeSorter"); mainNode->setAttribute("numElectrodes", electrodes.size()); - SpikeSorterEditor* ed = (SpikeSorterEditor*) getEditor(); - - mainNode->setAttribute("activeElectrode", ed->getSelectedElectrode()-1); - mainNode->setAttribute("numPreSamples", numPreSamples); - mainNode->setAttribute("numPostSamples", numPostSamples); - mainNode->setAttribute("autoDACassignment", autoDACassignment); - mainNode->setAttribute("syncThresholds",syncThresholds); - mainNode->setAttribute("uniqueID",uniqueID); - mainNode->setAttribute("flipSignal",flipSignal); + SpikeSorterEditor* ed = (SpikeSorterEditor*) getEditor(); + + mainNode->setAttribute("activeElectrode", ed->getSelectedElectrode()-1); + mainNode->setAttribute("numPreSamples", numPreSamples); + mainNode->setAttribute("numPostSamples", numPostSamples); + mainNode->setAttribute("autoDACassignment", autoDACassignment); + mainNode->setAttribute("syncThresholds",syncThresholds); + mainNode->setAttribute("uniqueID",uniqueID); + mainNode->setAttribute("flipSignal",flipSignal); XmlElement* countNode = mainNode->createNewChildElement("ELECTRODE_COUNTER"); - countNode->setAttribute("numElectrodeTypes", (int)electrodeTypes.size()); - for (int k=0;k<electrodeTypes.size();k++) - { - XmlElement* countNode2 = countNode->createNewChildElement("ELECTRODE_TYPE"); - countNode2->setAttribute("type", electrodeTypes[k]); - countNode2->setAttribute("count", electrodeCounter[k]); - } + countNode->setAttribute("numElectrodeTypes", (int)electrodeTypes.size()); + for (int k=0; k<electrodeTypes.size(); k++) + { + XmlElement* countNode2 = countNode->createNewChildElement("ELECTRODE_TYPE"); + countNode2->setAttribute("type", electrodeTypes[k]); + countNode2->setAttribute("count", electrodeCounter[k]); + } for (int i = 0; i < electrodes.size(); i++) { @@ -1264,9 +1269,9 @@ void SpikeSorter::saveCustomParametersToXml(XmlElement* parentElement) electrodeNode->setAttribute("numChannels", electrodes[i]->numChannels); electrodeNode->setAttribute("prePeakSamples", electrodes[i]->prePeakSamples); electrodeNode->setAttribute("postPeakSamples", electrodes[i]->postPeakSamples); - electrodeNode->setAttribute("advancerID", electrodes[i]->advancerID); - electrodeNode->setAttribute("depthOffsetMM", electrodes[i]->depthOffsetMM); - electrodeNode->setAttribute("electrodeID", electrodes[i]->electrodeID); + electrodeNode->setAttribute("advancerID", electrodes[i]->advancerID); + electrodeNode->setAttribute("depthOffsetMM", electrodes[i]->depthOffsetMM); + electrodeNode->setAttribute("electrodeID", electrodes[i]->electrodeID); for (int j = 0; j < electrodes[i]->numChannels; j++) { @@ -1277,8 +1282,8 @@ void SpikeSorter::saveCustomParametersToXml(XmlElement* parentElement) } - // save spike sorting data. - electrodes[i]->spikeSort->saveCustomParametersToXml(electrodeNode); + // save spike sorting data. + electrodes[i]->spikeSort->saveCustomParametersToXml(electrodeNode); } @@ -1288,144 +1293,148 @@ void SpikeSorter::saveCustomParametersToXml(XmlElement* parentElement) void SpikeSorter::loadCustomParametersFromXml() { - if (parametersAsXml != nullptr) - { + if (parametersAsXml != nullptr) + { - int electrodeIndex = -1; + int electrodeIndex = -1; - forEachXmlChildElement(*parametersAsXml, mainNode) - { + forEachXmlChildElement(*parametersAsXml, mainNode) + { - // use parametersAsXml to restore state - - if (mainNode->hasTagName("SpikeSorter")) - { - int numElectrodes = mainNode->getIntAttribute("numElectrodes"); - currentElectrode = mainNode->getIntAttribute("activeElectrode"); - numPreSamples = mainNode->getIntAttribute("numPreSamples"); - numPostSamples = mainNode->getIntAttribute("numPostSamples"); - autoDACassignment = mainNode->getBoolAttribute("autoDACassignment"); - syncThresholds = mainNode->getBoolAttribute("syncThresholds"); - uniqueID = mainNode->getIntAttribute("uniqueID"); - flipSignal = mainNode->getBoolAttribute("flipSignal"); - - forEachXmlChildElement(*mainNode, xmlNode) - { - - if (xmlNode->hasTagName("ELECTRODE_COUNTER")) - { - int numElectrodeTypes = xmlNode->getIntAttribute("numElectrodeTypes"); - electrodeCounter.resize(numElectrodeTypes); - electrodeTypes.resize(numElectrodeTypes); - int counter = 0; - forEachXmlChildElement(*xmlNode, xmltype) - { - if (xmltype->hasTagName("ELECTRODE_TYPE")) - { - electrodeTypes[counter] = xmltype->getStringAttribute("type"); - electrodeCounter[counter] = xmltype->getIntAttribute("count"); - counter++; - } - } - } else - if (xmlNode->hasTagName("ELECTRODE")) - { - - electrodeIndex++; - - int channelsPerElectrode = xmlNode->getIntAttribute("numChannels"); - - int advancerID = xmlNode->getIntAttribute("advancerID"); - float depthOffsetMM = xmlNode->getDoubleAttribute("depthOffsetMM"); - int electrodeID = xmlNode->getIntAttribute("electrodeID"); - String electrodeName=xmlNode->getStringAttribute("name"); - - - int channelIndex = -1; - - int *channels = new int[channelsPerElectrode]; - float *thres = new float[channelsPerElectrode]; - bool *isActive = new bool[channelsPerElectrode]; - - forEachXmlChildElement(*xmlNode, channelNode) - { - if (channelNode->hasTagName("SUBCHANNEL")) - { - channelIndex++; - channels[channelIndex] = channelNode->getIntAttribute("ch"); - thres[channelIndex] = channelNode->getDoubleAttribute("thresh"); - isActive[channelIndex] = channelNode->getBoolAttribute("isActive"); - } - } - - int sourceNodeId = 102010; // some number - - Electrode* newElectrode = new Electrode(electrodeID, &uniqueIDgenerator,&computingThread, electrodeName, channelsPerElectrode, channels,getDefaultThreshold(), - numPreSamples,numPostSamples, getSampleRate(), sourceNodeId); - for (int k=0;k<channelsPerElectrode;k++) - { - newElectrode->thresholds[k] = thres[k]; - newElectrode->isActive[k] = isActive[k]; - } - - newElectrode->advancerID = advancerID; - newElectrode->depthOffsetMM = depthOffsetMM; - // now read sorted units information - newElectrode->spikeSort->loadCustomParametersFromXml(xmlNode); - addElectrode(newElectrode); - - } - } - } - } - } + // use parametersAsXml to restore state + + if (mainNode->hasTagName("SpikeSorter")) + { + int numElectrodes = mainNode->getIntAttribute("numElectrodes"); + currentElectrode = mainNode->getIntAttribute("activeElectrode"); + numPreSamples = mainNode->getIntAttribute("numPreSamples"); + numPostSamples = mainNode->getIntAttribute("numPostSamples"); + autoDACassignment = mainNode->getBoolAttribute("autoDACassignment"); + syncThresholds = mainNode->getBoolAttribute("syncThresholds"); + uniqueID = mainNode->getIntAttribute("uniqueID"); + flipSignal = mainNode->getBoolAttribute("flipSignal"); + + forEachXmlChildElement(*mainNode, xmlNode) + { + + if (xmlNode->hasTagName("ELECTRODE_COUNTER")) + { + int numElectrodeTypes = xmlNode->getIntAttribute("numElectrodeTypes"); + electrodeCounter.resize(numElectrodeTypes); + electrodeTypes.resize(numElectrodeTypes); + int counter = 0; + forEachXmlChildElement(*xmlNode, xmltype) + { + if (xmltype->hasTagName("ELECTRODE_TYPE")) + { + electrodeTypes[counter] = xmltype->getStringAttribute("type"); + electrodeCounter[counter] = xmltype->getIntAttribute("count"); + counter++; + } + } + } + else if (xmlNode->hasTagName("ELECTRODE")) + { + + electrodeIndex++; + + int channelsPerElectrode = xmlNode->getIntAttribute("numChannels"); + + int advancerID = xmlNode->getIntAttribute("advancerID"); + float depthOffsetMM = xmlNode->getDoubleAttribute("depthOffsetMM"); + int electrodeID = xmlNode->getIntAttribute("electrodeID"); + String electrodeName=xmlNode->getStringAttribute("name"); + + + int channelIndex = -1; + + int* channels = new int[channelsPerElectrode]; + float* thres = new float[channelsPerElectrode]; + bool* isActive = new bool[channelsPerElectrode]; + + forEachXmlChildElement(*xmlNode, channelNode) + { + if (channelNode->hasTagName("SUBCHANNEL")) + { + channelIndex++; + channels[channelIndex] = channelNode->getIntAttribute("ch"); + thres[channelIndex] = channelNode->getDoubleAttribute("thresh"); + isActive[channelIndex] = channelNode->getBoolAttribute("isActive"); + } + } + + int sourceNodeId = 102010; // some number + + Electrode* newElectrode = new Electrode(electrodeID, &uniqueIDgenerator,&computingThread, electrodeName, channelsPerElectrode, channels,getDefaultThreshold(), + numPreSamples,numPostSamples, getSampleRate(), sourceNodeId); + for (int k=0; k<channelsPerElectrode; k++) + { + newElectrode->thresholds[k] = thres[k]; + newElectrode->isActive[k] = isActive[k]; + } + + newElectrode->advancerID = advancerID; + newElectrode->depthOffsetMM = depthOffsetMM; + // now read sorted units information + newElectrode->spikeSort->loadCustomParametersFromXml(xmlNode); + addElectrode(newElectrode); + + } + } + } + } + } SpikeSorterEditor* ed = (SpikeSorterEditor*) getEditor(); - // ed->updateAdvancerList(); + // ed->updateAdvancerList(); + + if (currentElectrode >= 0) + { + ed->refreshElectrodeList(currentElectrode); + ed->setSelectedElectrode(1+currentElectrode); + } + else + { + ed->refreshElectrodeList(); + } - if (currentElectrode >= 0) { - ed->refreshElectrodeList(currentElectrode); - ed->setSelectedElectrode(1+currentElectrode); - } else - { - ed->refreshElectrodeList(); - } - } void SpikeSorter::removeSpikePlots() { - mut.enter(); + mut.enter(); for (int i = 0; i < getNumElectrodes(); i++) { - Electrode *ee = electrodes[i]; - ee->spikePlot = nullptr; + Electrode* ee = electrodes[i]; + ee->spikePlot = nullptr; } - mut.exit(); + mut.exit(); } int SpikeSorter::getNumElectrodes() { - mut.enter(); + mut.enter(); int i= electrodes.size(); - mut.exit(); - return i; + mut.exit(); + return i; } int SpikeSorter::getNumberOfChannelsForElectrode(int i) { - mut.enter(); + mut.enter(); if (i > -1 && i < electrodes.size()) { - Electrode *ee = electrodes[i]; - int ii=ee->numChannels; - mut.exit(); - return ii; - } else { - mut.exit(); + Electrode* ee = electrodes[i]; + int ii=ee->numChannels; + mut.exit(); + return ii; + } + else + { + mut.exit(); return 0; } } @@ -1434,15 +1443,17 @@ int SpikeSorter::getNumberOfChannelsForElectrode(int i) String SpikeSorter::getNameForElectrode(int i) { - mut.enter(); + mut.enter(); if (i > -1 && i < electrodes.size()) { - Electrode *ee = electrodes[i]; + Electrode* ee = electrodes[i]; String s= ee->name; - mut.exit(); - return s; - } else { - mut.exit(); + mut.exit(); + return s; + } + else + { + mut.exit(); return " "; } } @@ -1450,224 +1461,224 @@ String SpikeSorter::getNameForElectrode(int i) void SpikeSorter::addSpikePlotForElectrode(SpikeHistogramPlot* sp, int i) { - mut.enter(); - Electrode *ee = electrodes[i]; + mut.enter(); + Electrode* ee = electrodes[i]; ee->spikePlot = sp; - mut.exit(); + mut.exit(); } int SpikeSorter::getCurrentElectrodeIndex() { - return currentElectrode; + return currentElectrode; } Electrode* SpikeSorter::getElectrode(int i) { - return electrodes[i]; + return electrodes[i]; } std::vector<int> SpikeSorter::getElectrodeChannels(int ID) { - std::vector<int> ch; - mut.enter(); - for (int k=0;k<electrodes.size();k++) - { - if (electrodes[k]->electrodeID == ID) - { + std::vector<int> ch; + mut.enter(); + for (int k=0; k<electrodes.size(); k++) + { + if (electrodes[k]->electrodeID == ID) + { - ch.resize(electrodes[k]->numChannels); - for (int j=0;j<electrodes[k]->numChannels;j++) - { - ch[j] = electrodes[k]->channels[j]; - } + ch.resize(electrodes[k]->numChannels); + for (int j=0; j<electrodes[k]->numChannels; j++) + { + ch[j] = electrodes[k]->channels[j]; + } - return ch; - mut.exit(); - } + return ch; + mut.exit(); + } - - } - mut.exit(); - return ch; + + } + mut.exit(); + return ch; } Electrode* SpikeSorter::setCurrentElectrodeIndex(int i) { - jassert(i >= 0 & i < electrodes.size()); - currentElectrode = i; - return electrodes[i]; + jassert(i >= 0 & i < electrodes.size()); + currentElectrode = i; + return electrodes[i]; } void SpikeSorter::updateSinks(int electrodeID, int unitID, uint8 r, uint8 g, uint8 b, bool addRemove) { - // inform sinks about a new unit - ProcessorGraph *gr = getProcessorGraph(); - Array<GenericProcessor*> p = gr->getListOfProcessors(); - for (int k = 0; k<p.size(); k++) - { - if (p[k]->getName() == "PSTH") - { - PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k]; - if (node->trialCircularBuffer != nullptr) - { - if (addRemove) - { - // add electrode - node->trialCircularBuffer->addNewUnit(electrodeID, unitID, r, g, b); - } - else - { - // remove electrode - node->trialCircularBuffer->removeUnit(electrodeID, unitID); - } - ((PeriStimulusTimeHistogramEditor *)node->getEditor())->updateCanvas(); - } - } - } + // inform sinks about a new unit + ProcessorGraph* gr = getProcessorGraph(); + Array<GenericProcessor*> p = gr->getListOfProcessors(); + for (int k = 0; k<p.size(); k++) + { + if (p[k]->getName() == "PSTH") + { + PeriStimulusTimeHistogramNode* node = (PeriStimulusTimeHistogramNode*)p[k]; + if (node->trialCircularBuffer != nullptr) + { + if (addRemove) + { + // add electrode + node->trialCircularBuffer->addNewUnit(electrodeID, unitID, r, g, b); + } + else + { + // remove electrode + node->trialCircularBuffer->removeUnit(electrodeID, unitID); + } + ((PeriStimulusTimeHistogramEditor*)node->getEditor())->updateCanvas(); + } + } + } } void SpikeSorter::updateSinks(int electrodeID, bool rem) { - // inform sinks about a removal of all units - ProcessorGraph *g = getProcessorGraph(); - Array<GenericProcessor*> p = g->getListOfProcessors(); - for (int k = 0; k<p.size(); k++) - { - if (p[k]->getName() == "PSTH") - { - PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k]; - if (node->trialCircularBuffer != nullptr) - { - if (rem) - { - node->trialCircularBuffer->removeAllUnits(electrodeID); - } - (((PeriStimulusTimeHistogramEditor *)node->getEditor()))->updateCanvas(); - } - } - /* - if (p[k]->getName() == "Spike Viewer") - { - SpikeSorter* node = (SpikeSorter*)p[k]; - node->syncWithSpikeSorter(); - } - */ - } + // inform sinks about a removal of all units + ProcessorGraph* g = getProcessorGraph(); + Array<GenericProcessor*> p = g->getListOfProcessors(); + for (int k = 0; k<p.size(); k++) + { + if (p[k]->getName() == "PSTH") + { + PeriStimulusTimeHistogramNode* node = (PeriStimulusTimeHistogramNode*)p[k]; + if (node->trialCircularBuffer != nullptr) + { + if (rem) + { + node->trialCircularBuffer->removeAllUnits(electrodeID); + } + (((PeriStimulusTimeHistogramEditor*)node->getEditor()))->updateCanvas(); + } + } + /* + if (p[k]->getName() == "Spike Viewer") + { + SpikeSorter* node = (SpikeSorter*)p[k]; + node->syncWithSpikeSorter(); + } + */ + } } void SpikeSorter::updateSinks(int electrodeID, int channelindex, int newchannel) { - // inform sinks about a channel change - ProcessorGraph *g = getProcessorGraph(); - Array<GenericProcessor*> p = g->getListOfProcessors(); - for (int k = 0; k<p.size(); k++) - { - if (p[k]->getName() == "PSTH") - { - PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k]; - if (node->trialCircularBuffer != nullptr) - { - node->trialCircularBuffer->channelChange(electrodeID, channelindex, newchannel); - } - } + // inform sinks about a channel change + ProcessorGraph* g = getProcessorGraph(); + Array<GenericProcessor*> p = g->getListOfProcessors(); + for (int k = 0; k<p.size(); k++) + { + if (p[k]->getName() == "PSTH") + { + PeriStimulusTimeHistogramNode* node = (PeriStimulusTimeHistogramNode*)p[k]; + if (node->trialCircularBuffer != nullptr) + { + node->trialCircularBuffer->channelChange(electrodeID, channelindex, newchannel); + } + } - } + } } void SpikeSorter::updateSinks(Electrode* electrode) { - // inform sinks about an electrode add - ProcessorGraph *g = getProcessorGraph(); - Array<GenericProcessor*> p = g->getListOfProcessors(); - for (int k = 0; k<p.size(); k++) - { - String s = p[k]->getName(); - if (p[k]->getName() == "PSTH") - { - PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k]; - if (node->trialCircularBuffer != nullptr) - { - // add electrode - node->trialCircularBuffer->addNewElectrode(electrode); - (((PeriStimulusTimeHistogramEditor *)node->getEditor()))->updateCanvas(); - } - } + // inform sinks about an electrode add + ProcessorGraph* g = getProcessorGraph(); + Array<GenericProcessor*> p = g->getListOfProcessors(); + for (int k = 0; k<p.size(); k++) + { + String s = p[k]->getName(); + if (p[k]->getName() == "PSTH") + { + PeriStimulusTimeHistogramNode* node = (PeriStimulusTimeHistogramNode*)p[k]; + if (node->trialCircularBuffer != nullptr) + { + // add electrode + node->trialCircularBuffer->addNewElectrode(electrode); + (((PeriStimulusTimeHistogramEditor*)node->getEditor()))->updateCanvas(); + } + } - } + } } void SpikeSorter::updateSinks(int electrodeID, String NewName) { - // inform sinks about an electrode name change - ProcessorGraph *g = getProcessorGraph(); - Array<GenericProcessor*> p = g->getListOfProcessors(); - for (int k = 0; k < p.size(); k++) - { - String s = p[k]->getName(); - if (p[k]->getName() == "PSTH") - { - PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k]; - if (node->trialCircularBuffer != nullptr) - { - // add electrode - node->trialCircularBuffer->updateElectrodeName(electrodeID, NewName); - (((PeriStimulusTimeHistogramEditor *)node->getEditor()))->updateCanvas(); - } - } + // inform sinks about an electrode name change + ProcessorGraph* g = getProcessorGraph(); + Array<GenericProcessor*> p = g->getListOfProcessors(); + for (int k = 0; k < p.size(); k++) + { + String s = p[k]->getName(); + if (p[k]->getName() == "PSTH") + { + PeriStimulusTimeHistogramNode* node = (PeriStimulusTimeHistogramNode*)p[k]; + if (node->trialCircularBuffer != nullptr) + { + // add electrode + node->trialCircularBuffer->updateElectrodeName(electrodeID, NewName); + (((PeriStimulusTimeHistogramEditor*)node->getEditor()))->updateCanvas(); + } + } - } + } } void SpikeSorter::updateSinks(int electrodeID) { - // inform sinks about an electrode removal - ProcessorGraph *g = getProcessorGraph(); - Array<GenericProcessor*> p = g->getListOfProcessors(); - for (int k = 0; k<p.size(); k++) - { - String s = p[k]->getName(); - if (p[k]->getName() == "PSTH") - { - PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k]; - if (node->trialCircularBuffer != nullptr) - { - // remove electrode - node->trialCircularBuffer->removeElectrode(electrodeID); - ((PeriStimulusTimeHistogramEditor *)node->getEditor())->updateCanvas(); - } - } + // inform sinks about an electrode removal + ProcessorGraph* g = getProcessorGraph(); + Array<GenericProcessor*> p = g->getListOfProcessors(); + for (int k = 0; k<p.size(); k++) + { + String s = p[k]->getName(); + if (p[k]->getName() == "PSTH") + { + PeriStimulusTimeHistogramNode* node = (PeriStimulusTimeHistogramNode*)p[k]; + if (node->trialCircularBuffer != nullptr) + { + // remove electrode + node->trialCircularBuffer->removeElectrode(electrodeID); + ((PeriStimulusTimeHistogramEditor*)node->getEditor())->updateCanvas(); + } + } - } + } } /* -Histogram::Histogram(float _minValue, float _maxValue, float _resolution, bool _throwOutsideSamples) : +Histogram::Histogram(float _minValue, float _maxValue, float _resolution, bool _throwOutsideSamples) : minValue(_minValue), maxValue(_maxValue), resolution(_resolution), throwOutsideSamples(_throwOutsideSamples) { numBins = 1+ abs(maxValue-minValue) / resolution; binCounts = new unsigned long[numBins]; binCenters = new float[numBins]; float deno = (numBins-1)/abs(maxValue-minValue); - for (int k=0;k<numBins;k++) + for (int k=0;k<numBins;k++) { binCounts[k] = 0; binCenters[k] = minValue + k/deno; } } // -//Histogram::Histogram(float _minValue, float _maxValue, int _numBins, bool _throwOutsideSamples) : +//Histogram::Histogram(float _minValue, float _maxValue, int _numBins, bool _throwOutsideSamples) : // minValue(_minValue), maxValue(_maxValue), numBins(_numBins), throwOutsideSamples(_throwOutsideSamples) //{ // resolution = abs(maxValue-minValue) / numBins ; // binCounts = new int[numBins]; // binCenters = new float[numBins]; -// for (int k=0;k<numBins;k++) +// for (int k=0;k<numBins;k++) // { // binCounts[k] = 0; // binCenters[k] = minValue + k/(numBins-1)*resolution; @@ -1677,15 +1688,15 @@ Histogram::Histogram(float _minValue, float _maxValue, float _resolution, bool _ void Histogram::clear() { -for (int k=0;k<numBins;k++) +for (int k=0;k<numBins;k++) { binCounts[k] = 0; - } + } } void Histogram::addSamples(float *Samples, int numSamples) { - for (int k=0;k<numSamples;k++) + for (int k=0;k<numSamples;k++) { int indx = ceil( (Samples[k] - minValue) / (maxValue-minValue) * (numBins-1)); if (indx >= 0 && indx < numBins) @@ -1693,7 +1704,7 @@ void Histogram::addSamples(float *Samples, int numSamples) { } } -Histogram::~Histogram() +Histogram::~Histogram() { delete [] binCounts; delete [] binCenters; @@ -1741,7 +1752,7 @@ Histogram::~Histogram() // std::vector<double> LongArray; // LongArray.resize(N); // mut.enter(); -// +// // int p = ptr - 1; // for (int k = 0; k < N; k++) // { @@ -1787,7 +1798,7 @@ Histogram::~Histogram() // // Run median on analog input // double numSamplesPerSecond = 30000; // std::vector<double> LongArray = getDataArray(channel, numSamplesPerSecond*5); -// +// // for (int k = 0; k < LongArray.size(); k++) // LongArray[k] = fabs(LongArray[k]); // @@ -1802,146 +1813,146 @@ Histogram::~Histogram() //} -// =================================================== +// =================================================== void ContinuousCircularBuffer::reallocate(int NumCh) { - numCh =NumCh; - Buf.resize(numCh); - for (int k=0;k< numCh;k++) - { - Buf[k].resize(bufLen); - } - numSamplesInBuf = 0; - ptr = 0; // points to a valid position in the buffer. + numCh =NumCh; + Buf.resize(numCh); + for (int k=0; k< numCh; k++) + { + Buf[k].resize(bufLen); + } + numSamplesInBuf = 0; + ptr = 0; // points to a valid position in the buffer. } ContinuousCircularBuffer::ContinuousCircularBuffer(int NumCh, float SamplingRate, int SubSampling, float NumSecInBuffer) { - Time t; - - numTicksPerSecond = (double) t.getHighResolutionTicksPerSecond(); + Time t; - int numSamplesToHoldPerChannel = (int)(SamplingRate * NumSecInBuffer / SubSampling); - buffer_dx = 1.0 / (SamplingRate / SubSampling); - subSampling = SubSampling; - samplingRate = SamplingRate; - numCh =NumCh; - leftover_k = 0; - Buf.resize(numCh); + numTicksPerSecond = (double) t.getHighResolutionTicksPerSecond(); + int numSamplesToHoldPerChannel = (int)(SamplingRate * NumSecInBuffer / SubSampling); + buffer_dx = 1.0 / (SamplingRate / SubSampling); + subSampling = SubSampling; + samplingRate = SamplingRate; + numCh =NumCh; + leftover_k = 0; + Buf.resize(numCh); - for (int k=0;k< numCh;k++) - { - Buf[k].resize(numSamplesToHoldPerChannel); - } - hardwareTS.resize(numSamplesToHoldPerChannel); - softwareTS.resize(numSamplesToHoldPerChannel); - valid.resize(numSamplesToHoldPerChannel); - bufLen = numSamplesToHoldPerChannel; - numSamplesInBuf = 0; - ptr = 0; // points to a valid position in the buffer. + for (int k=0; k< numCh; k++) + { + Buf[k].resize(numSamplesToHoldPerChannel); + } + + hardwareTS.resize(numSamplesToHoldPerChannel); + softwareTS.resize(numSamplesToHoldPerChannel); + valid.resize(numSamplesToHoldPerChannel); + bufLen = numSamplesToHoldPerChannel; + numSamplesInBuf = 0; + ptr = 0; // points to a valid position in the buffer. } void ContinuousCircularBuffer::update(int channel, int64 hardware_ts, int64 software_ts, bool rise) { - // used to record ttl pulses as continuous data... - mut.enter(); - valid[ptr] = true; - hardwareTS[ptr] = hardware_ts; - softwareTS[ptr] = software_ts; + // used to record ttl pulses as continuous data... + mut.enter(); + valid[ptr] = true; + hardwareTS[ptr] = hardware_ts; + softwareTS[ptr] = software_ts; - Buf[channel][ptr] = (rise) ? 1.0 : 0.0; + Buf[channel][ptr] = (rise) ? 1.0 : 0.0; - ptr++; - if (ptr == bufLen) - { - ptr = 0; - } - numSamplesInBuf++; - if (numSamplesInBuf >= bufLen) - { - numSamplesInBuf = bufLen; - } - mut.exit(); + ptr++; + if (ptr == bufLen) + { + ptr = 0; + } + numSamplesInBuf++; + if (numSamplesInBuf >= bufLen) + { + numSamplesInBuf = bufLen; + } + mut.exit(); } void ContinuousCircularBuffer::update(AudioSampleBuffer& buffer, int64 hardware_ts, int64 software_ts, int numpts) { - mut.enter(); - - // we don't start from zero because of subsampling issues. - // previous packet may not have ended exactly at the last given sample. - int k = leftover_k; - int lastUsedSample; - for (; k < numpts; k+=subSampling) - { - lastUsedSample = k; - valid[ptr] = true; - hardwareTS[ptr] = hardware_ts + k; - softwareTS[ptr] = software_ts + int64(float(k) / samplingRate * numTicksPerSecond); + mut.enter(); - for (int ch = 0; ch < numCh; ch++) - { - Buf[ch][ptr] = *(buffer.getReadPointer(ch,k)); - } - ptr++; - if (ptr == bufLen) - { - ptr = 0; - } - numSamplesInBuf++; - if (numSamplesInBuf >= bufLen) - { - numSamplesInBuf = bufLen; - } - } - - int numMissedSamples = (numpts-1)-lastUsedSample; - leftover_k = (subSampling-numMissedSamples-1) % subSampling; - mut.exit(); + // we don't start from zero because of subsampling issues. + // previous packet may not have ended exactly at the last given sample. + int k = leftover_k; + int lastUsedSample; + for (; k < numpts; k+=subSampling) + { + lastUsedSample = k; + valid[ptr] = true; + hardwareTS[ptr] = hardware_ts + k; + softwareTS[ptr] = software_ts + int64(float(k) / samplingRate * numTicksPerSecond); + + for (int ch = 0; ch < numCh; ch++) + { + Buf[ch][ptr] = *(buffer.getReadPointer(ch,k)); + } + ptr++; + if (ptr == bufLen) + { + ptr = 0; + } + numSamplesInBuf++; + if (numSamplesInBuf >= bufLen) + { + numSamplesInBuf = bufLen; + } + } + + int numMissedSamples = (numpts-1)-lastUsedSample; + leftover_k = (subSampling-numMissedSamples-1) % subSampling; + mut.exit(); } void ContinuousCircularBuffer::update(std::vector<std::vector<bool>> contdata, int64 hardware_ts, int64 software_ts, int numpts) { - mut.enter(); - - // we don't start from zero because of subsampling issues. - // previous packet may not have ended exactly at the last given sample. - int k = leftover_k; - int lastUsedSample; - for (; k < numpts; k+=subSampling) - { - lastUsedSample = k; - valid[ptr] = true; - hardwareTS[ptr] = hardware_ts + k; - softwareTS[ptr] = software_ts + int64(float(k) / samplingRate * numTicksPerSecond); + mut.enter(); - for (int ch = 0; ch < numCh; ch++) - { - Buf[ch][ptr] = contdata[ch][k]; - } - ptr++; - if (ptr == bufLen) - { - ptr = 0; - } - numSamplesInBuf++; - if (numSamplesInBuf >= bufLen) - { - numSamplesInBuf = bufLen; - } - } - - int numMissedSamples = (numpts-1)-lastUsedSample; - leftover_k =subSampling-numMissedSamples-1; - mut.exit(); + // we don't start from zero because of subsampling issues. + // previous packet may not have ended exactly at the last given sample. + int k = leftover_k; + int lastUsedSample; + for (; k < numpts; k+=subSampling) + { + lastUsedSample = k; + valid[ptr] = true; + hardwareTS[ptr] = hardware_ts + k; + softwareTS[ptr] = software_ts + int64(float(k) / samplingRate * numTicksPerSecond); + + for (int ch = 0; ch < numCh; ch++) + { + Buf[ch][ptr] = contdata[ch][k]; + } + ptr++; + if (ptr == bufLen) + { + ptr = 0; + } + numSamplesInBuf++; + if (numSamplesInBuf >= bufLen) + { + numSamplesInBuf = bufLen; + } + } + + int numMissedSamples = (numpts-1)-lastUsedSample; + leftover_k =subSampling-numMissedSamples-1; + mut.exit(); } /* @@ -1971,10 +1982,10 @@ void ContinuousCircularBuffer::AddDataToBuffer(std::vector<std::vector<double>> mut.exit(); } */ - + int ContinuousCircularBuffer::GetPtr() { - return ptr; + return ptr; } /************************************************************/ -- GitLab