diff --git a/Source/Processors/DataThreads/RHD2000Thread.cpp b/Source/Processors/DataThreads/RHD2000Thread.cpp index bee46419e698558d6c6aa0904ecf93644098aed3..ebe2204fb13f1dc5595185ee6b3c6a52d6b412e1 100644 --- a/Source/Processors/DataThreads/RHD2000Thread.cpp +++ b/Source/Processors/DataThreads/RHD2000Thread.cpp @@ -27,7 +27,7 @@ RHD2000Thread::RHD2000Thread(SourceNode* sn) : DataThread(sn), isTransmitting(false), fastSettleEnabled(false), chipRegisters(30000.0f), dspEnabled(true), boardSampleRate(30000.0f), desiredDspCutoffFreq(0.5f), desiredUpperBandwidth(7500.0f), desiredLowerBandwidth(1.0f), - savedSampleRateIndex(16), + savedSampleRateIndex(16), audioOutputL(-1), audioOutputR(-1), dacOutputShouldChange(false), cableLengthPortA(0.914f), cableLengthPortB(0.914f), cableLengthPortC(0.914f), cableLengthPortD(0.914f) // default is 3 feet (0.914 m) { evalBoard = new Rhd2000EvalBoard; @@ -53,7 +53,7 @@ RHD2000Thread::RHD2000Thread(SourceNode* sn) : DataThread(sn), isTransmitting(fa initializeBoard(); // automatically find connected headstages - scanPorts(); + scanPorts(); // do this after the editor has been created? } } @@ -143,8 +143,6 @@ void RHD2000Thread::initializeBoard() int ledArray[8] = {1, 0, 0, 0, 0, 0, 0, 0}; evalBoard->setLedDisplay(ledArray); - - } void RHD2000Thread::scanPorts() @@ -357,6 +355,7 @@ int RHD2000Thread::deviceId(Rhd2000DataBlock* dataBlock, int stream) } + bool RHD2000Thread::isAcquisitionActive() { return isTransmitting; @@ -484,6 +483,26 @@ bool RHD2000Thread::isHeadstageEnabled(int hsNum) } +void RHD2000Thread::assignAudioOut(int dacChannel, int dataChannel) +{ + + if (dacChannel == 0) + { + audioOutputR = dataChannel; + + + } else if (dacChannel == 1) + { + audioOutputL = dataChannel; + + } + + dacOutputShouldChange = true; // set a flag and take care of setting wires + // during the updateBuffer() method + // to avoid problems + +} + void RHD2000Thread::setSampleRate(int sampleRateIndex, bool isTemporary) { @@ -855,7 +874,26 @@ bool RHD2000Thread::updateBuffer() } } + if (dacOutputShouldChange) + { + if (audioOutputR >= 0) + { + evalBoard->enableDac(0, true); + evalBoard->selectDacDataChannel(0, audioOutputR); + } else { + evalBoard->enableDac(0, false); + } + + if (audioOutputL >= 0) + { + evalBoard->enableDac(1, true); + evalBoard->selectDacDataChannel(1, audioOutputR); + } else { + evalBoard->enableDac(1, false); + } + dacOutputShouldChange = false; + } return true; diff --git a/Source/Processors/DataThreads/RHD2000Thread.h b/Source/Processors/DataThreads/RHD2000Thread.h index e49f50ec1f7ac1e0945624774f474c8a68ac1606..c5f164e082e45636b0a7c0c5bbbf853caab44537 100644 --- a/Source/Processors/DataThreads/RHD2000Thread.h +++ b/Source/Processors/DataThreads/RHD2000Thread.h @@ -77,6 +77,8 @@ public: int getNumEventChannels(); + void assignAudioOut(int dacChannel, int dataChannel); + bool isAcquisitionActive(); private: @@ -85,6 +87,8 @@ private: Rhd2000Registers chipRegisters; Rhd2000DataBlock* dataBlock; + int audioOutputL, audioOutputR; + Array<int> numChannelsPerDataStream; int numChannels; @@ -97,6 +101,8 @@ private: bool isTransmitting; + bool dacOutputShouldChange; + bool fastSettleEnabled; bool dspEnabled; diff --git a/Source/Processors/Editors/ChannelSelector.cpp b/Source/Processors/Editors/ChannelSelector.cpp index 2cc01b7c55827310e74a5b2565d075e1b0a9747d..6e3b4bb3e3514414cdba77b1a0410d9b53b5f6e2 100755 --- a/Source/Processors/Editors/ChannelSelector.cpp +++ b/Source/Processors/Editors/ChannelSelector.cpp @@ -352,22 +352,29 @@ void ChannelSelector::stopAcquisition() void ChannelSelector::setRadioStatus(bool radioOn) { - radioStatus = radioOn; - - for (int i = 0; i < parameterButtons.size(); i++) + if (radioStatus != radioOn) { - if (radioOn) - { - parameterButtons[i]->setToggleState(false, false); - parameterButtons[i]->setRadioGroupId(999); - } - else + + radioStatus = radioOn; + + for (int i = 0; i < parameterButtons.size(); i++) { - parameterButtons[i]->setToggleState(false, false); - parameterButtons[i]->setRadioGroupId(0); + if (radioOn) + { + parameterButtons[i]->setToggleState(false, false); + parameterButtons[i]->setRadioGroupId(999); + } + else + { + parameterButtons[i]->setToggleState(false, false); + parameterButtons[i]->setRadioGroupId(0); + } } + } + + } bool ChannelSelector::getParamStatus(int chan) @@ -525,6 +532,13 @@ void ChannelSelector::buttonClicked(Button* button) audioButtons[i]->setToggleState(false, true); } } + + if (radioStatus) // if radio buttons are active + { + // send a message to parent + GenericEditor* editor = (GenericEditor*) getParentComponent(); + editor->channelChanged(-1); + } } else { diff --git a/Source/Processors/Editors/GenericEditor.cpp b/Source/Processors/Editors/GenericEditor.cpp index 7ac6df358d154582490145e26d68215a10a92410..6c41a3a48733dca79f49c9c72b521e4af3e6758f 100755 --- a/Source/Processors/Editors/GenericEditor.cpp +++ b/Source/Processors/Editors/GenericEditor.cpp @@ -809,10 +809,10 @@ void TriangleButton::paintButton(Graphics& g, bool isMouseOver, bool isButtonDow void GenericEditor::updateParameterButtons(int parameterIndex) { - if (parameterEditors.size()==0) + if (parameterEditors.size() == 0) { //Checks if there is a parameter editor, and stops a bug if there isn't. - std::cout << "No parameterEditors" << std::endl; + //std::cout << "No parameterEditors" << std::endl; } else { @@ -827,6 +827,6 @@ void GenericEditor::updateParameterButtons(int parameterIndex) { parameterEditors[parameterIndex]->channelSelectionUI(); } - std::cout << "updateParameterButtons" << std::endl; + //std::cout << "updateParameterButtons" << std::endl; } } diff --git a/Source/Processors/Editors/RHD2000Editor.cpp b/Source/Processors/Editors/RHD2000Editor.cpp index 53027bc040b55643a1aeb9c058a831a3ba3270d2..6935f09cc21ea483ba292ea41d84cbd699dea9cb 100644 --- a/Source/Processors/Editors/RHD2000Editor.cpp +++ b/Source/Processors/Editors/RHD2000Editor.cpp @@ -24,6 +24,8 @@ #include "RHD2000Editor.h" #include "../../UI/EditorViewport.h" +#include "ChannelSelector.h" + #include "../DataThreads/RHD2000Thread.h" RHD2000Editor::RHD2000Editor(GenericProcessor* parentNode, @@ -32,7 +34,7 @@ RHD2000Editor::RHD2000Editor(GenericProcessor* parentNode, ) : GenericEditor(parentNode, useDefaultParameterEditors), board(board_) { - desiredWidth = 200; + desiredWidth = 260; // add headstage-specific controls (currently just an enable/disable button) for (int i = 0; i < 4; i++) @@ -60,6 +62,28 @@ RHD2000Editor::RHD2000Editor(GenericProcessor* parentNode, rescanButton->addListener(this); addAndMakeVisible(rescanButton); + for (int i = 0; i < 2; i++) + { + ElectrodeButton* button = new ElectrodeButton(-1); + electrodeButtons.add(button); + + button->setBounds(190+i*25, 40, 25, 15); + button->setChannelNum(-1); + button->setToggleState(false,false); + button->setRadioGroupId(999); + + addAndMakeVisible(button); + button->addListener(this); + } + + audioLabel = new Label("audio label", "Audio out"); + audioLabel->setBounds(180,25,180,15); + audioLabel->setFont(Font("Small Text", 10, Font::plain)); + audioLabel->setColour(Label::textColourId, Colours::darkgrey); + addAndMakeVisible(audioLabel); + + + } RHD2000Editor::~RHD2000Editor() @@ -67,6 +91,11 @@ RHD2000Editor::~RHD2000Editor() } +void RHD2000Editor::scanPorts() +{ + rescanButton->triggerClick(); +} + void RHD2000Editor::buttonEvent(Button* button) { @@ -79,10 +108,30 @@ void RHD2000Editor::buttonEvent(Button* button) headstageOptionsInterfaces[i]->checkEnabledState(); } + } else if (button == electrodeButtons[0]) + { + channelSelector->setRadioStatus(true); + } else if (button == electrodeButtons[1]) + { + channelSelector->setRadioStatus(true); } } +void RHD2000Editor::channelChanged(int chan) +{ + for (int i = 0; i < 2; i++) + { + if (electrodeButtons[i]->getToggleState()) + { + electrodeButtons[i]->setChannelNum(chan); + electrodeButtons[i]->repaint(); + + board->assignAudioOut(i, chan); + } + } +} + // Bandwidth Options -------------------------------------------------------------------- BandwidthInterface::BandwidthInterface(RHD2000Thread* board_, diff --git a/Source/Processors/Editors/RHD2000Editor.h b/Source/Processors/Editors/RHD2000Editor.h index 645e45687021ec30150d3c7a0d032f2d5f36691a..5883155530160566e2f28d40ffb4a22b22bef5cd 100644 --- a/Source/Processors/Editors/RHD2000Editor.h +++ b/Source/Processors/Editors/RHD2000Editor.h @@ -54,6 +54,10 @@ public: void buttonEvent(Button* button); + void scanPorts(); + + void channelChanged(int chan); + private: OwnedArray<HeadstageOptionsInterface> headstageOptionsInterfaces; @@ -64,6 +68,8 @@ private: ScopedPointer<UtilityButton> rescanButton; + ScopedPointer<Label> audioLabel; + RHD2000Thread* board; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RHD2000Editor); diff --git a/Source/Processors/Editors/SpikeDetectorEditor.cpp b/Source/Processors/Editors/SpikeDetectorEditor.cpp index 19b31041c723bebad9550da6d171d1cb43f0c377..940ad01bbd0f4979dd3a2656ec08192b435a68af 100755 --- a/Source/Processors/Editors/SpikeDetectorEditor.cpp +++ b/Source/Processors/Editors/SpikeDetectorEditor.cpp @@ -530,7 +530,8 @@ void ElectrodeButton::paintButton(Graphics& g, bool isMouseOver, bool isButtonDo g.drawRect(0,0,getWidth(),getHeight(),1.0); - g.drawText(String(chan),0,0,getWidth(),getHeight(),Justification::centred,true); + if (chan >= 0) + g.drawText(String(chan),0,0,getWidth(),getHeight(),Justification::centred,true); } diff --git a/Source/Processors/SourceNode.cpp b/Source/Processors/SourceNode.cpp index c04d71b034df54e1db588595056161abf709345f..67fa66afcf3f4cb1adb8115d1525d3a0d7cb5e73 100755 --- a/Source/Processors/SourceNode.cpp +++ b/Source/Processors/SourceNode.cpp @@ -209,6 +209,9 @@ AudioProcessorEditor* SourceNode::createEditor() if (getName().equalsIgnoreCase("Rhythm FPGA")) { editor = new RHD2000Editor(this, (RHD2000Thread*) dataThread.get(), true); + + // RHD2000Editor* r2e = (RHD2000Editor*) editor.get(); + // r2e->scanPorts(); } // else if (getName().equalsIgnoreCase("File Reader")) // {