From c4c5df8fa52d43a439442f8d4540aaa2f1eb574e Mon Sep 17 00:00:00 2001 From: jsiegle <jsiegle@mit.edu> Date: Wed, 29 May 2013 23:39:54 -0400 Subject: [PATCH] Enable audio monitoring from RHD2000Thread --- .../Processors/DataThreads/RHD2000Thread.cpp | 46 +++++++++++++++-- Source/Processors/DataThreads/RHD2000Thread.h | 6 +++ Source/Processors/Editors/ChannelSelector.cpp | 36 +++++++++---- Source/Processors/Editors/GenericEditor.cpp | 6 +-- Source/Processors/Editors/RHD2000Editor.cpp | 51 ++++++++++++++++++- Source/Processors/Editors/RHD2000Editor.h | 6 +++ .../Editors/SpikeDetectorEditor.cpp | 3 +- Source/Processors/SourceNode.cpp | 3 ++ 8 files changed, 137 insertions(+), 20 deletions(-) diff --git a/Source/Processors/DataThreads/RHD2000Thread.cpp b/Source/Processors/DataThreads/RHD2000Thread.cpp index bee46419e..ebe2204fb 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 e49f50ec1..c5f164e08 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 2cc01b7c5..6e3b4bb3e 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 7ac6df358..6c41a3a48 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 53027bc04..6935f09cc 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 645e45687..588315553 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 19b31041c..940ad01bb 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 c04d71b03..67fa66afc 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")) // { -- GitLab