diff --git a/Builds/MacOSX/Info.plist b/Builds/MacOSX/Info.plist index 4a774cb476806c772b0307ca047e157914451433..cb42e529e1f7c85afdb1d9f9635c288b204180cc 100644 --- a/Builds/MacOSX/Info.plist +++ b/Builds/MacOSX/Info.plist @@ -16,9 +16,9 @@ <key>CFBundleSignature</key> <string>????</string> <key>CFBundleShortVersionString</key> - <string>0.2.3</string> + <string>0.2.4</string> <key>CFBundleVersion</key> - <string>0.2.3</string> + <string>0.2.4</string> <key>NSHumanReadableCopyright</key> <string>Open Ephys</string> <key>NSHighResolutionCapable</key> diff --git a/Builds/VisualStudio2012/resources.rc b/Builds/VisualStudio2012/resources.rc index 5cba7fd111efb2a43b23ba1931b1bdeb1f6b4fd8..53bffa9f316be65686aa078bcfea977d23be12b0 100644 --- a/Builds/VisualStudio2012/resources.rc +++ b/Builds/VisualStudio2012/resources.rc @@ -7,7 +7,7 @@ #include <windows.h> VS_VERSION_INFO VERSIONINFO -FILEVERSION 0,2,3,0 +FILEVERSION 0,2,4,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -15,9 +15,9 @@ BEGIN BEGIN VALUE "CompanyName", "Open Ephys\0" VALUE "FileDescription", "open-ephys\0" - VALUE "FileVersion", "0.2.3\0" + VALUE "FileVersion", "0.2.4\0" VALUE "ProductName", "open-ephys\0" - VALUE "ProductVersion", "0.2.3\0" + VALUE "ProductVersion", "0.2.4\0" END END diff --git a/JuceLibraryCode/JuceHeader.h b/JuceLibraryCode/JuceHeader.h index f72eb30499b32ce3f16fd1fd39115181b3226f14..9d7c9f06ddcd8aaf28a936ea2c04f71bf98e7d69 100644 --- a/JuceLibraryCode/JuceHeader.h +++ b/JuceLibraryCode/JuceHeader.h @@ -39,8 +39,8 @@ namespace ProjectInfo { const char* const projectName = "open-ephys"; - const char* const versionString = "0.2.3"; - const int versionNumber = 0x203; + const char* const versionString = "0.2.4"; + const int versionNumber = 0x204; } #endif // __APPHEADERFILE_YNSYIRR__ diff --git a/Source/MainWindow.cpp b/Source/MainWindow.cpp index 306597fc2ee861ba952453b72e3304111bb71042..fb6729bd38325f7a39dec2a529cfa14143c9a6b5 100644 --- a/Source/MainWindow.cpp +++ b/Source/MainWindow.cpp @@ -92,9 +92,10 @@ void MainWindow::closeButtonPressed() if (audioComponent->callbacksAreActive()) { audioComponent->endCallbacks(); - processorGraph->disableProcessors(); } + processorGraph->disableProcessors(); + JUCEApplication::getInstance()->systemRequestedQuit(); } @@ -112,6 +113,10 @@ void MainWindow::saveWindowBounds() XmlElement* xml = new XmlElement("MAINWINDOW"); + xml->setAttribute("version", JUCEApplication::getInstance()->getApplicationVersion()); + + JUCEApplication::getInstance()->systemRequestedQuit(); + XmlElement* bounds = new XmlElement("BOUNDS"); bounds->setAttribute("x",getScreenX()); bounds->setAttribute("y",getScreenY()); @@ -121,6 +126,21 @@ void MainWindow::saveWindowBounds() xml->addChildElement(bounds); + XmlElement* recentDirectories = new XmlElement("RECENTDIRECTORYNAMES"); + + UIComponent* ui = (UIComponent*) getContentComponent(); + + StringArray dirs = ui->getRecentlyUsedFilenames(); + + for (int i = 0; i < dirs.size(); i++) + { + XmlElement* directory = new XmlElement("DIRECTORY"); + directory->setAttribute("name", dirs[i]); + recentDirectories->addChildElement(directory); + } + + xml->addChildElement(recentDirectories); + String error; if (! xml->writeToFile(file, String::empty)) @@ -177,6 +197,23 @@ void MainWindow::loadWindowBounds() #endif getContentComponent()->setBounds(0,0,w-10,h-33); //setFullScreen(fs); + } else if (e->hasTagName("RECENTDIRECTORYNAMES")) + { + + StringArray filenames; + + forEachXmlChildElement(*e, directory) + { + + if (directory->hasTagName("DIRECTORY")) + { + filenames.add(directory->getStringAttribute("name")); + } + } + + UIComponent* ui = (UIComponent*) getContentComponent(); + ui->setRecentlyUsedFilenames(filenames); + } } diff --git a/Source/Processors/Editors/FilterEditor.cpp b/Source/Processors/Editors/FilterEditor.cpp index 6f405d7fbc04154f001530140d3624da3f90d12b..9beedcc4edda560cea9e4a070473cf07b2709f3a 100755 --- a/Source/Processors/Editors/FilterEditor.cpp +++ b/Source/Processors/Editors/FilterEditor.cpp @@ -36,35 +36,52 @@ FilterEditor::FilterEditor(GenericProcessor* parentNode, bool useDefaultParamete lastHighCutString = " "; highCutLabel = new Label("high cut label", "High cut:"); - highCutLabel->setBounds(35,80,80,20); + highCutLabel->setBounds(10,65,80,20); highCutLabel->setFont(Font("Small Text", 12, Font::plain)); highCutLabel->setColour(Label::textColourId, Colours::darkgrey); addAndMakeVisible(highCutLabel); lowCutLabel = new Label("low cut label", "Low cut:"); - lowCutLabel->setBounds(35,30,80,20); + lowCutLabel->setBounds(10,25,80,20); lowCutLabel->setFont(Font("Small Text", 12, Font::plain)); lowCutLabel->setColour(Label::textColourId, Colours::darkgrey); addAndMakeVisible(lowCutLabel); lowCutValue = new Label("low cut value", lastLowCutString); - lowCutValue->setBounds(40,50,60,20); + lowCutValue->setBounds(15,42,60,18); lowCutValue->setFont(Font("Default", 15, Font::plain)); lowCutValue->setColour(Label::textColourId, Colours::white); lowCutValue->setColour(Label::backgroundColourId, Colours::grey); lowCutValue->setEditable(true); lowCutValue->addListener(this); + lowCutValue->setTooltip("Set the low cut for the selected channels"); addAndMakeVisible(lowCutValue); highCutValue = new Label("high cut label", lastHighCutString); - highCutValue->setBounds(40,100,60,20); + highCutValue->setBounds(15,82,60,18); highCutValue->setFont(Font("Default", 15, Font::plain)); highCutValue->setColour(Label::textColourId, Colours::white); highCutValue->setColour(Label::backgroundColourId, Colours::grey); highCutValue->setEditable(true); highCutValue->addListener(this); + highCutValue->setTooltip("Set the high cut for the selected channels"); addAndMakeVisible(highCutValue); + applyFilterOnADC = new UtilityButton("+ADCs",Font("Default", 10, Font::plain)); + applyFilterOnADC->addListener(this); + applyFilterOnADC->setBounds(90,70,40,18); + applyFilterOnADC->setClickingTogglesState(true); + applyFilterOnADC->setTooltip("When this button is off, ADC channels will not be filtered"); + addAndMakeVisible(applyFilterOnADC); + + applyFilterOnChan = new UtilityButton("+CH",Font("Default", 10, Font::plain)); + applyFilterOnChan->addListener(this); + applyFilterOnChan->setBounds(95,95,30,18); + applyFilterOnChan->setClickingTogglesState(true); + applyFilterOnChan->setToggleState(true, false); + applyFilterOnChan->setTooltip("When this button is off, selected channels will not be filtered"); + addAndMakeVisible(applyFilterOnChan); + } FilterEditor::~FilterEditor() @@ -117,11 +134,11 @@ void FilterEditor::labelTextChanged(Label* label) if (label == highCutValue) { - double minVal = fn->getLowCutValueForChannel(n); + double minVal = fn->getLowCutValueForChannel(chans[n]); if (requestedValue > minVal) { - fn->setCurrentChannel(n); + fn->setCurrentChannel(chans[n]); fn->setParameter(1, requestedValue); } @@ -130,11 +147,11 @@ void FilterEditor::labelTextChanged(Label* label) } else { - double maxVal = fn->getHighCutValueForChannel(n); + double maxVal = fn->getHighCutValueForChannel(chans[n]); if (requestedValue < maxVal) { - fn->setCurrentChannel(n); + fn->setCurrentChannel(chans[n]); fn->setParameter(0, requestedValue); } @@ -145,39 +162,42 @@ void FilterEditor::labelTextChanged(Label* label) } -void FilterEditor::buttonEvent(Button* button) +void FilterEditor::channelChanged(int chan) { - //std::cout << button->getRadioGroupId() << " " << button->getName() << std::endl; - - //if (!checkDrawerButton(button) && !checkChannelSelectors(button)) { - - // String value = button->getName(); - // float val; + FilterNode* fn = (FilterNode*) getProcessor(); - // val = value.getFloatValue(); + highCutValue->setText(String(fn->getHighCutValueForChannel(chan)), dontSendNotification); + lowCutValue->setText(String(fn->getLowCutValueForChannel(chan)), dontSendNotification); + applyFilterOnChan->setToggleState(fn->getBypassStatusForChannel(chan), false); - // Array<int> chans = getActiveChannels(); +} - // GenericProcessor* p = (GenericProcessor*) getAudioProcessor(); +void FilterEditor::buttonEvent(Button* button) +{ - // for (int n = 0; n < chans.size(); n++) - // { + if (button == applyFilterOnADC) + { + FilterNode* fn = (FilterNode*) getProcessor(); + fn->setApplyOnADC(applyFilterOnADC->getToggleState()); - // p->setCurrentChannel(chans[n]); + } else if (button == applyFilterOnChan) + { + FilterNode* fn = (FilterNode*) getProcessor(); - // if (button->getRadioGroupId() == 1) - // getAudioProcessor()->setParameter(0,val); - // else - // getAudioProcessor()->setParameter(1,val*1000.0f); + Array<int> chans = getActiveChannels(); - // } - //std::cout << button->getRadioGroupId() << " " << val << std::endl; - // } + for (int n = 0; n < chans.size(); n++) + { + float newValue = button->getToggleState() ? 1.0 : 0.0; + fn->setCurrentChannel(chans[n]); + fn->setParameter(2, newValue); + } + } } -void FilterEditor::saveEditorParameters(XmlElement* xml) +void FilterEditor::saveCustomParameters(XmlElement* xml) { xml->setAttribute("Type", "FilterEditor"); @@ -185,9 +205,10 @@ void FilterEditor::saveEditorParameters(XmlElement* xml) XmlElement* textLabelValues = xml->createNewChildElement("VALUES"); textLabelValues->setAttribute("HighCut",lastHighCutString); textLabelValues->setAttribute("LowCut",lastLowCutString); + textLabelValues->setAttribute("ApplyToADC", applyFilterOnADC->getToggleState()); } -void FilterEditor::loadEditorParameters(XmlElement* xml) +void FilterEditor::loadCustomParameters(XmlElement* xml) { forEachXmlChildElement(*xml, xmlNode) @@ -196,6 +217,7 @@ void FilterEditor::loadEditorParameters(XmlElement* xml) { highCutValue->setText(xmlNode->getStringAttribute("HighCut"),dontSendNotification); lowCutValue->setText(xmlNode->getStringAttribute("LowCut"),dontSendNotification); + applyFilterOnADC->setToggleState(xmlNode->getBoolAttribute("ApplyToADC",false),true); } } } diff --git a/Source/Processors/Editors/FilterEditor.h b/Source/Processors/Editors/FilterEditor.h index 907c20d1444fbbbc3592922fc25ef37e98b3adc0..58945523e182ceaf3ac40c6270526b85a7f3e7e1 100755 --- a/Source/Processors/Editors/FilterEditor.h +++ b/Source/Processors/Editors/FilterEditor.h @@ -39,20 +39,22 @@ class FilterViewport; */ class FilterEditor : public GenericEditor, - public Label::Listener + public Label::Listener { public: FilterEditor(GenericProcessor* parentNode, bool useDefaultParameterEditors); virtual ~FilterEditor(); - void buttonEvent(Button* button); + void buttonEvent(Button* button); void labelTextChanged(Label* label); - void saveEditorParameters(XmlElement* xml); - void loadEditorParameters(XmlElement* xml); + void saveCustomParameters(XmlElement* xml); + void loadCustomParameters(XmlElement* xml); void setDefaults(double lowCut, double highCut); + void channelChanged(int chan); + private: String lastHighCutString; @@ -63,6 +65,8 @@ private: ScopedPointer<Label> highCutValue; ScopedPointer<Label> lowCutValue; + ScopedPointer<UtilityButton> applyFilterOnADC; + ScopedPointer<UtilityButton> applyFilterOnChan; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FilterEditor); diff --git a/Source/Processors/Editors/PhaseDetectorEditor.cpp b/Source/Processors/Editors/PhaseDetectorEditor.cpp index 0d580806e8b1c62668f62a429b942f7339b77f4c..f26a1b6d288b09a0dd72a789b9b27cdd51b6d9e1 100644 --- a/Source/Processors/Editors/PhaseDetectorEditor.cpp +++ b/Source/Processors/Editors/PhaseDetectorEditor.cpp @@ -161,7 +161,7 @@ void PhaseDetectorEditor::addDetector() } -void PhaseDetectorEditor::saveEditorParameters(XmlElement* xml) +void PhaseDetectorEditor::saveCustomParameters(XmlElement* xml) { xml->setAttribute("Type", "PhaseDetectorEditor"); @@ -176,7 +176,7 @@ void PhaseDetectorEditor::saveEditorParameters(XmlElement* xml) } } -void PhaseDetectorEditor::loadEditorParameters(XmlElement* xml) +void PhaseDetectorEditor::loadCustomParameters(XmlElement* xml) { int i = 0; diff --git a/Source/Processors/Editors/PhaseDetectorEditor.h b/Source/Processors/Editors/PhaseDetectorEditor.h index a42e02ea503e2e41c086e2ffdfbd3cf89882c9ad..6c0d82c66743fce1158b3d91dc889164c49b57da 100644 --- a/Source/Processors/Editors/PhaseDetectorEditor.h +++ b/Source/Processors/Editors/PhaseDetectorEditor.h @@ -56,8 +56,8 @@ public: void updateSettings(); - void saveEditorParameters(XmlElement* xml); - void loadEditorParameters(XmlElement* xml); + void saveCustomParameters(XmlElement* xml); + void loadCustomParameters(XmlElement* xml); private: diff --git a/Source/Processors/Editors/PulsePalOutputEditor.cpp b/Source/Processors/Editors/PulsePalOutputEditor.cpp index 1ba458f1e094007f056c22cafdacd7cd38bd6a09..91390a80a5f205b9e81035389e6a13352407453f 100644 --- a/Source/Processors/Editors/PulsePalOutputEditor.cpp +++ b/Source/Processors/Editors/PulsePalOutputEditor.cpp @@ -55,7 +55,7 @@ PulsePalOutputEditor::~PulsePalOutputEditor() } -void PulsePalOutputEditor::saveEditorParameters(XmlElement* xml) +void PulsePalOutputEditor::saveCustomParameters(XmlElement* xml) { xml->setAttribute("Type", "PulsePalOutputEditor"); @@ -71,7 +71,7 @@ void PulsePalOutputEditor::saveEditorParameters(XmlElement* xml) } -void PulsePalOutputEditor::loadEditorParameters(XmlElement* xml) +void PulsePalOutputEditor::loadCustomParameters(XmlElement* xml) { forEachXmlChildElement(*xml, xmlNode) diff --git a/Source/Processors/Editors/PulsePalOutputEditor.h b/Source/Processors/Editors/PulsePalOutputEditor.h index 95d8e96f1141994c7aa5baee838c0d7ff1e645a3..a7036704d38740a221c44e3525f753daa8c966ef 100644 --- a/Source/Processors/Editors/PulsePalOutputEditor.h +++ b/Source/Processors/Editors/PulsePalOutputEditor.h @@ -54,8 +54,8 @@ private: PulsePal* pulsePal; - void saveEditorParameters(XmlElement* xml); - void loadEditorParameters(XmlElement* xml); + void saveCustomParameters(XmlElement* xml); + void loadCustomParameters(XmlElement* xml); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PulsePalOutputEditor); diff --git a/Source/Processors/Editors/SpikeDetectorEditor.cpp b/Source/Processors/Editors/SpikeDetectorEditor.cpp index acf7d24ec5336780fcfac432ffa95953cbcca33d..ea12234f41201cd5fa2d485c2185db3c64241e25 100755 --- a/Source/Processors/Editors/SpikeDetectorEditor.cpp +++ b/Source/Processors/Editors/SpikeDetectorEditor.cpp @@ -489,9 +489,12 @@ void SpikeDetectorEditor::comboBoxChanged(ComboBox* comboBox) void SpikeDetectorEditor::checkSettings() { electrodeList->setSelectedItemIndex(0); + drawElectrodeButtons(0); getEditorViewport()->makeEditorVisible(this, true, true); + + } void SpikeDetectorEditor::drawElectrodeButtons(int ID) diff --git a/Source/Processors/Editors/VisualizerEditor.cpp b/Source/Processors/Editors/VisualizerEditor.cpp index 18aa344ebfb1e6776677ee46d075cddd2805e47f..3d6c24caae21811709edb3e68f33753aef16e361 100755 --- a/Source/Processors/Editors/VisualizerEditor.cpp +++ b/Source/Processors/Editors/VisualizerEditor.cpp @@ -190,7 +190,7 @@ void VisualizerEditor::buttonEvent(Button* button) tabIndex = -1; } - if (dataWindow == nullptr) + if (dataWindow == nullptr) // have we created a window already? { dataWindow = new DataWindow(windowSelector, tabText); @@ -256,7 +256,7 @@ void VisualizerEditor::buttonEvent(Button* button) } -void VisualizerEditor::saveEditorParameters(XmlElement* xml) +void VisualizerEditor::saveCustomParameters(XmlElement* xml) { xml->setAttribute("Type", "Visualizer"); @@ -282,7 +282,7 @@ void VisualizerEditor::saveEditorParameters(XmlElement* xml) } -void VisualizerEditor::loadEditorParameters(XmlElement* xml) +void VisualizerEditor::loadCustomParameters(XmlElement* xml) { forEachXmlChildElement(*xml, xmlNode) @@ -305,10 +305,13 @@ void VisualizerEditor::loadEditorParameters(XmlElement* xml) if (windowState) { windowSelector->setToggleState(true,true); - dataWindow->setBounds(xmlNode->getIntAttribute("x"), - xmlNode->getIntAttribute("y"), - xmlNode->getIntAttribute("width"), - xmlNode->getIntAttribute("height")); + if (dataWindow != nullptr) + { + dataWindow->setBounds(xmlNode->getIntAttribute("x"), + xmlNode->getIntAttribute("y"), + xmlNode->getIntAttribute("width"), + xmlNode->getIntAttribute("height")); + } } diff --git a/Source/Processors/Editors/VisualizerEditor.h b/Source/Processors/Editors/VisualizerEditor.h index f64530e8f388e30863cc200733fff30482ca9e7e..b15139d80d205fd12defe9f05cf8b7cdd66f2886 100755 --- a/Source/Processors/Editors/VisualizerEditor.h +++ b/Source/Processors/Editors/VisualizerEditor.h @@ -80,8 +80,8 @@ public: void updateVisualizer(); - void saveEditorParameters(XmlElement* xml); - void loadEditorParameters(XmlElement* xml); + void saveCustomParameters(XmlElement* xml); + void loadCustomParameters(XmlElement* xml); virtual void saveVisualizerParameters(XmlElement* xml); virtual void loadVisualizerParameters(XmlElement* xml); diff --git a/Source/Processors/FilterNode.cpp b/Source/Processors/FilterNode.cpp index 6a97cb9d7266bcd5f122fc9de43807c6f29d7e48..44c7346cd4f3586228828bf4b7cc1c03e0a3a9d4 100755 --- a/Source/Processors/FilterNode.cpp +++ b/Source/Processors/FilterNode.cpp @@ -46,7 +46,7 @@ FilterNode::FilterNode() // highCutValues.add(9000.0f); // parameters.add(Parameter("high cut",highCutValues, 2, 1)); - + applyOnADC = false; } FilterNode::~FilterNode() @@ -126,13 +126,20 @@ AudioProcessorEditor* FilterNode::createEditor() void FilterNode::updateSettings() { - - if (getNumInputs() < 1024 && getNumInputs() != filters.size()) + int id = nodeId; + int numInputs = getNumInputs(); + int numfilt = filters.size(); + if (numInputs < 1024 && numInputs != numfilt) { + // SO fixed this. I think values were never restored correctly because you cleared lowCuts. + Array<double> oldlowCuts, oldhighCuts; + oldlowCuts = lowCuts; + oldhighCuts = highCuts; filters.clear(); lowCuts.clear(); highCuts.clear(); + shouldFilterChannel.clear(); for (int n = 0; n < getNumInputs(); n++) { @@ -154,12 +161,14 @@ void FilterNode::updateSettings() // restore defaults + shouldFilterChannel.add(true); + float lc, hc; - if (lowCuts.size() > n) + if (oldlowCuts.size() > n) { - lc = lowCuts[n]; - hc = highCuts[n]; + lc = oldlowCuts[n]; + hc = oldhighCuts[n]; } else { lc = defaultLowCut; hc = defaultHighCut; @@ -173,6 +182,8 @@ void FilterNode::updateSettings() } + setApplyOnADC(applyOnADC); + } double FilterNode::getLowCutValueForChannel(int chan) @@ -185,6 +196,11 @@ double FilterNode::getHighCutValueForChannel(int chan) return highCuts[chan]; } +bool FilterNode::getBypassStatusForChannel(int chan) +{ + return shouldFilterChannel[chan]; +} + void FilterNode::setFilterParameters(double lowCut, double highCut, int chan) { @@ -202,52 +218,41 @@ void FilterNode::setFilterParameters(double lowCut, double highCut, int chan) void FilterNode::setParameter(int parameterIndex, float newValue) { - if (newValue <= 0.01 || newValue >= 10000.0f) - return; + if (parameterIndex < 2) // change filter settings + { - //std::cout << "Setting channel " << currentChannel;// << std::endl; + if (newValue <= 0.01 || newValue >= 10000.0f) + return; - if (parameterIndex == 0) - { - // std::cout << " low cut to " << newValue << std::endl; - lowCuts.set(currentChannel,newValue); - } - else - { - //std::cout << " high cut to " << newValue << std::endl; - highCuts.set(currentChannel,newValue); - } + //std::cout << "Setting channel " << currentChannel;// << std::endl; - //std::cout << newValue << std::endl; + if (parameterIndex == 0) + { + // std::cout << " low cut to " << newValue << std::endl; + lowCuts.set(currentChannel,newValue); + } + else if (parameterIndex == 1) + { + //std::cout << " high cut to " << newValue << std::endl; + highCuts.set(currentChannel,newValue); + } - setFilterParameters(lowCuts[currentChannel], + setFilterParameters(lowCuts[currentChannel], highCuts[currentChannel], currentChannel); + editor->updateParameterButtons(parameterIndex); - // Deprecated code: - //if (parameterIndex) - // - // Parameter& p = parameters.getReference(parameterIndex); - - // p.setValue(newValue, currentChannel); - - // Parameter& p1 = parameters.getReference(0); - // Parameter& p2 = parameters.getReference(1); - - // std::cout << float(p1[currentChannel]) << " "; - // std::cout << float(p2[currentChannel]) << std::endl; - - // if (parameterIndex == 0) { - // parameters[0].setValue(newValue, currentChannel); - // setFilterParameters(newValue, parameters[0][currentChannel], currentChannel); - // } else { - // parameters[1].setValue(newValue, currentChannel); - // setFilterParameters(lowCuts[currentChannel], newValue, currentChannel); - // } - - editor->updateParameterButtons(parameterIndex); - + } else // change channel bypass state + { + if (newValue == 0) + { + shouldFilterChannel.set(currentChannel, false); + } else { + shouldFilterChannel.set(currentChannel, true); + } + + } } void FilterNode::process(AudioSampleBuffer& buffer, @@ -257,12 +262,32 @@ void FilterNode::process(AudioSampleBuffer& buffer, for (int n = 0; n < getNumOutputs(); n++) { - float* ptr = buffer.getSampleData(n); - filters[n]->process(nSamples, &ptr); + if (shouldFilterChannel[n]) + { + float* ptr = buffer.getSampleData(n); + filters[n]->process(nSamples, &ptr); + } } } +void FilterNode::setApplyOnADC(bool state) +{ + + for (int n = 0; n < channels.size(); n++) + { + if (channels[n]->isADCchannel) + { + setCurrentChannel(n); + + if (state) + setParameter(2,1.0); + else + setParameter(2,0.0); + } + } +} + void FilterNode::saveCustomChannelParametersToXml(XmlElement* channelInfo, int channelNumber, bool isEventChannel) { @@ -275,6 +300,7 @@ void FilterNode::saveCustomChannelParametersToXml(XmlElement* channelInfo, int c XmlElement* channelParams = channelInfo->createNewChildElement("PARAMETERS"); channelParams->setAttribute("highcut",highCuts[channelNumber]); channelParams->setAttribute("lowcut",lowCuts[channelNumber]); + channelParams->setAttribute("shouldFilter",shouldFilterChannel[channelNumber]); } } @@ -292,6 +318,7 @@ void FilterNode::loadCustomChannelParametersFromXml(XmlElement* channelInfo, boo { highCuts.set(channelNum, subNode->getDoubleAttribute("highcut",defaultHighCut)); lowCuts.set(channelNum, subNode->getDoubleAttribute("lowcut",defaultLowCut)); + shouldFilterChannel.set(channelNum, subNode->getBoolAttribute("shouldFilter",true)); setFilterParameters(lowCuts[channelNum], highCuts[channelNum], diff --git a/Source/Processors/FilterNode.h b/Source/Processors/FilterNode.h index 82857b32fd64b7653aab26e7a1781697fb740cd0..b5ea5f337df644410b623258331f74b1c7dc47cb 100755 --- a/Source/Processors/FilterNode.h +++ b/Source/Processors/FilterNode.h @@ -58,18 +58,22 @@ public: double getLowCutValueForChannel(int chan); double getHighCutValueForChannel(int chan); + bool getBypassStatusForChannel(int chan); void updateSettings(); void saveCustomChannelParametersToXml(XmlElement* channelInfo, int channelNumber, bool isEventChannel); void loadCustomChannelParametersFromXml(XmlElement* channelInfo, bool isEventChannel); - + + void setApplyOnADC(bool state); private: Array<double> lowCuts, highCuts; OwnedArray<Dsp::Filter> filters; + Array<bool> shouldFilterChannel; + bool applyOnADC; double defaultLowCut; double defaultHighCut; diff --git a/Source/Processors/GenericProcessor.cpp b/Source/Processors/GenericProcessor.cpp index 16ca2df00f350c5f894fe1e163042bd1fffdb305..462624f08fa07d0b6d1b6d935509b0ac58ae32e4 100755 --- a/Source/Processors/GenericProcessor.cpp +++ b/Source/Processors/GenericProcessor.cpp @@ -589,7 +589,8 @@ void GenericProcessor::saveToXml(XmlElement* parentElement) for (int i = 0; i < channels.size(); i++) { - saveChannelParametersToXml(parentElement, i); + if (!isSplitter() && !isMerger()) + saveChannelParametersToXml(parentElement, i); // channelName = String(i); // channelChildNode = parentElement->createNewChildElement("CHANNEL"); @@ -599,7 +600,8 @@ void GenericProcessor::saveToXml(XmlElement* parentElement) for (int i = 0; i < eventChannels.size(); i++) { - saveChannelParametersToXml(parentElement, i, true); + if (!isSplitter() && !isMerger()) + saveChannelParametersToXml(parentElement, i, true); // channelName=/**String("EventCh:")+*/String(i); // channelChildNode = parentElement->createNewChildElement("EVENTCHANNEL"); diff --git a/Source/UI/EditorViewport.cpp b/Source/UI/EditorViewport.cpp index e572998174c7097e710d7e3617a02e727c291d3e..4430d1132c243cbd342ec45983b4a5d6e6bd7b22 100755 --- a/Source/UI/EditorViewport.cpp +++ b/Source/UI/EditorViewport.cpp @@ -1178,7 +1178,7 @@ const String EditorViewport::saveState(File fileToUse) XmlElement* info = xml->createNewChildElement("INFO"); XmlElement* version = info->createNewChildElement("VERSION"); - version->addTextElement("0.1"); + version->addTextElement(JUCEApplication::getInstance()->getApplicationVersion()); Time currentTime = Time::getCurrentTime(); @@ -1355,7 +1355,9 @@ const String EditorViewport::loadState(File fileToLoad) return "Not a valid file."; } - bool olderVersionFound = true; + bool sameVersion = false; + String versionString; + forEachXmlChildElement(*xml, element) { if (element->hasTagName("INFO")) @@ -1364,20 +1366,35 @@ const String EditorViewport::loadState(File fileToLoad) { if (element2->hasTagName("VERSION")) { - String S= element2->getAllSubText(); - double version =S.getDoubleValue(); - if (version >= 0.1) - olderVersionFound = false; + versionString = element2->getAllSubText(); + // float majorVersion = versionString.upToFirstOccurrenceOf(".", false, true).getIntValue(); + // float minorVersion = versionString.fromFirstOccurrenceOf(".", false, true).getFloatValue(); + + if (versionString.equalsIgnoreCase(JUCEApplication::getInstance()->getApplicationVersion())) + sameVersion = true; } } break; } } - if (olderVersionFound) + if (!sameVersion) { - bool response = AlertWindow::showOkCancelBox (AlertWindow::NoIcon, - "Old configuration file.", - "File may not load properly since it could lack some fields. Continute?", + String responseString = "Your configuration file was saved from a different version of the GUI than the one you're using. \n"; + responseString += "The current software is version "; + responseString += JUCEApplication::getInstance()->getApplicationVersion(); + responseString += ", but the file you selected "; + if (versionString.length() > 0) + { + responseString += " is version "; + responseString += versionString; + } else { + responseString += "does not have a version number"; + } + + responseString += ".\n This file may not load properly. Continue?"; + + bool response = AlertWindow::showOkCancelBox (AlertWindow::NoIcon, + "Version mismatch", responseString, "Yes", "No", 0, 0); if (!response) return "Failed To Open " + fileToLoad.getFileName(); diff --git a/Source/UI/GraphViewer.cpp b/Source/UI/GraphViewer.cpp index fc3da28cd64776e3134a254e2f4f9fef5b65f447..a9df2cd69e96b11e2c4388eb69824a42ca90985c 100644 --- a/Source/UI/GraphViewer.cpp +++ b/Source/UI/GraphViewer.cpp @@ -235,8 +235,12 @@ void GraphViewer::paint(Graphics& g) g.setFont(labelFont); g.setColour(Colours::grey); + + JUCEApplication* app = JUCEApplication::getInstance(); + String text = "open ephys "; + text += app->getApplicationVersion(); - g.drawFittedText("open ephys", 40, 40, getWidth()-50, getHeight()-50, Justification::bottomRight, 100); + g.drawFittedText(text, 40, 40, getWidth()-50, getHeight()-50, Justification::bottomRight, 100); // draw connections diff --git a/open-ephys.jucer b/open-ephys.jucer index e22bc68924185b720fb4be26e9e4b7c9a1d080e2..928c55fe36af944bf27427f69daa0829bd064f67 100644 --- a/open-ephys.jucer +++ b/open-ephys.jucer @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<JUCERPROJECT id="ynSYIrr" name="open-ephys" projectType="guiapp" version="0.2.3" +<JUCERPROJECT id="ynSYIrr" name="open-ephys" projectType="guiapp" version="0.2.4" juceLinkage="amalg_multi" buildVST="1" buildRTAS="0" buildAU="1" pluginName="Juce Project" pluginDesc="Juce Project" pluginManufacturer="yourcompany" pluginManufacturerCode="Manu" pluginCode="Plug" pluginChannelConfigs="{1, 1}, {2, 2}"