Skip to content
Snippets Groups Projects
Commit ddb0bfbf authored by jsiegle's avatar jsiegle
Browse files

Update ChannelMappingNode from spikesorting version

parent 810680f7
No related branches found
No related tags found
No related merge requests found
......@@ -64,17 +64,34 @@ AudioProcessorEditor* ChannelMappingNode::createEditor()
void ChannelMappingNode::updateSettings()
{
int j;
if (getNumInputs() > 0)
channelBuffer.setSize(getNumInputs(), 10000);
if (getNumInputs() != previousChannelCount)
{
previousChannelCount = getNumInputs();
if (editorIsConfigured)
{
j = 0;
for (int i = 0; i < getNumInputs(); i++)
{
if (enabledChannelArray[i])
{
j++;
}
else
{
channels.remove(j);
}
}
settings.numOutputs = j;
}
}
else
{
int j=0;
for (int i=0; i < getNumInputs(); i++)
j = 0;
for (int i = 0; i < getNumInputs(); i++)
{
if (enabledChannelArray[i])
{
......@@ -106,6 +123,10 @@ void ChannelMappingNode::setParameter(int parameterIndex, float newValue)
{
enabledChannelArray.set(currentChannel, (newValue != 0) ? true : false);
}
else if (parameterIndex == 4)
{
editorIsConfigured = (newValue != 0) ? true : false;
}
else
{
channelArray.set(currentChannel, (int) newValue);
......@@ -118,40 +139,33 @@ void ChannelMappingNode::process(AudioSampleBuffer& buffer,
int& nSamples)
{
int j=0;
int i=0;
int realChan;
// use copy constructor to set the data to refer to
channelBuffer = buffer;
// copy it back into the buffer according to the channel mapping
buffer.clear();
for (int i = 0; i < buffer.getNumChannels(); i++)
while (j < settings.numOutputs)
{
if (enabledChannelArray[channelArray[i]])
realChan = channelArray[i];
if ((realChan < channelBuffer.getNumChannels()) && (enabledChannelArray[realChan]))
{
// copy it back into the buffer according to the channel mapping
buffer.addFrom(j, // destChannel
0, // destStartSample
channelBuffer, // source
channelArray[i], // sourceChannel
realChan, // sourceChannel
0, // sourceStartSample
nSamples, // numSamples
1.0f // gain to apply to source (positive for original signal)
);
j++;
}
}
j=0;
// now do the referencing
for (int i = 0; i < buffer.getNumChannels(); i++)
{
int realChan = channelArray[i];
if (enabledChannelArray[realChan])
{
if ((referenceArray[realChan] > -1) && referenceChannels[referenceArray[realChan]] > -1)
// now do the referencing
if ((referenceArray[realChan] > -1) && (referenceChannels[referenceArray[realChan]] > -1)
&& (referenceChannels[referenceArray[realChan]] < channelBuffer.getNumChannels()))
{
buffer.addFrom(j, // destChannel
0, // destStartSample
channelBuffer, // source
......@@ -163,6 +177,8 @@ void ChannelMappingNode::process(AudioSampleBuffer& buffer,
}
j++;
}
i++;
}
}
......
......@@ -70,6 +70,7 @@ private:
Array<bool> enabledChannelArray;
int previousChannelCount;
bool editorIsConfigured;
AudioSampleBuffer channelBuffer;
......
......@@ -30,24 +30,34 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
ChannelMappingEditor::ChannelMappingEditor(GenericProcessor* parentNode, bool useDefaultParameterEditors=true)
: GenericEditor(parentNode, useDefaultParameterEditors), previousChannelCount(0)
: GenericEditor(parentNode, useDefaultParameterEditors), previousChannelCount(0), isConfigured(false)
{
desiredWidth = 340;
scrollDistance = 0;
selectAllButton = new ElectrodeEditorButton("Select All",Font("Small Text",14,Font::plain));
selectAllButton->addListener(this);
addAndMakeVisible(selectAllButton);
selectAllButton->setBounds(140,110,110,10);
selectAllButton->setBounds(125,110,110,10);
selectAllButton->setToggleState(false, false);
modifyButton = new ElectrodeEditorButton("Remap",Font("Small Text",14,Font::plain));
modifyButton->addListener(this);
addAndMakeVisible(modifyButton);
modifyButton->setBounds(250,110,60,10);
modifyButton->setBounds(220,110,60,10);
modifyButton->setToggleState(false, false);
modifyButton->setClickingTogglesState(true);
resetButton = new ElectrodeEditorButton("Reset", Font("Small Text",14,Font::plain));
resetButton->addListener(this);
addAndMakeVisible(resetButton);
resetButton->setBounds(285,110,60,10);
resetButton->setToggleState(true,false);
resetButton->setClickingTogglesState(false);
resetButton->setEnabled(false);
// channelSelector->setRadioStatus(true);
for (int i = 0 ; i < NUM_REFERENCES; i++)
......@@ -77,46 +87,80 @@ ChannelMappingEditor::~ChannelMappingEditor()
void ChannelMappingEditor::updateSettings()
{
if (isConfigured)
{
if (getProcessor()->getNumInputs() > previousChannelCount)
{
createElectrodeButtons(getProcessor()->getNumInputs(),false);
previousChannelCount = getProcessor()->getNumInputs();
}
else if (!reorderActive)
{
checkUnusedChannels();
}
if (getProcessor()->getNumInputs() != previousChannelCount)
} else if (getProcessor()->getNumInputs() != previousChannelCount)
{
createElectrodeButtons(getProcessor()->getNumInputs());
previousChannelCount = getProcessor()->getNumInputs();
}
}
void ChannelMappingEditor::createElectrodeButtons(int numNeeded)
void ChannelMappingEditor::createElectrodeButtons(int numNeeded, bool clearPrevious)
{
int startButton;
electrodeButtons.clear();
referenceArray.clear();
channelArray.clear();
referenceChannels.clear();
enabledChannelArray.clear();
if (clearPrevious)
{
electrodeButtons.clear();
int width = 20;
int height = 15;
referenceArray.clear();
channelArray.clear();
referenceChannels.clear();
enabledChannelArray.clear();
startButton=0;
previousClickedChan = -1;
previousShiftClickedChan = -1;
referenceButtons[0]->setToggleState(true,false);
selectedReference = 0;
modifyButton->setToggleState(false,false);
reorderActive = false;
channelSelector->activateButtons();
int row = 0;
int column = 0;
}
else
{
startButton = previousChannelCount;
if (startButton > numNeeded) return;
//row = startButton/16;
//column = startButton % 16;
}
for (int i = 0; i < numNeeded; i++)
for (int i = startButton; i < numNeeded; i++)
{
ElectrodeButton* button = new ElectrodeButton(i+1);
electrodeButtons.add(button);
button->setBounds(10+(column++)*(width), 30+row*(height), width, 15);
button->setToggleState(false,false);
button->setRadioGroupId(0);
// if (!getCollapsedState())
// addAndMakeVisible(button);
// else
addChildComponent(button); // determine visibility in refreshButtonLocations()
addAndMakeVisible(button);
button->addListener(this);
if (reorderActive)
{
button->setToggleState(true,false);
electrodeButtons[i]->setClickingTogglesState(false);
electrodeButtons[i]->addMouseListener(this,false);
}
else
{
button->setToggleState(false,false);
electrodeButtons[i]->setClickingTogglesState(true);
}
referenceArray.add(-1);
getProcessor()->setCurrentChannel(i);
......@@ -127,33 +171,55 @@ void ChannelMappingEditor::createElectrodeButtons(int numNeeded)
channelArray.add(i+1);
enabledChannelArray.add(true);
if (column % 16 == 0)
{
column = 0;
row++;
}
}
getProcessor()->setCurrentChannel(-1);
for (int i = 0; i < NUM_REFERENCES; i++)
if (clearPrevious)
{
getProcessor()->setCurrentChannel(-1);
for (int i = 0; i < NUM_REFERENCES; i++)
{
getProcessor()->setParameter(2,i); //Clear reference
referenceChannels.add(-1);
getProcessor()->setParameter(2,i); //Clear reference
referenceChannels.add(-1);
referenceButtons[i]->setEnabled(true);
}
}
channelSelector->setRadioStatus(true);
referenceButtons[0]->setToggleState(true,false);
selectedReference = 0;
refreshButtonLocations();
}
modifyButton->setToggleState(false,false);
reorderActive = false;
previousClickedChan = -1;
previousShiftClickedChan = -1;
void ChannelMappingEditor::refreshButtonLocations()
{
int width = 19;
int height = 15;
int row = (int) -scrollDistance;
int column = 0;
for (int i = 0; i < electrodeButtons.size(); i++)
{
channelSelector->setRadioStatus(true);
ElectrodeButton* button = electrodeButtons[i];
button->setBounds(10+(column++)*(width), 30+row*(height), width, 15);
if (row <= 4 && row >= 0 && !getCollapsedState())
button->setVisible(true);
else
button->setVisible(false);
if (column % 16 == 0)
{
column = 0;
row++;
}
}
}
void ChannelMappingEditor::collapsedStateChanged()
{
refreshButtonLocations();
}
void ChannelMappingEditor::buttonEvent(Button* button)
{
......@@ -166,6 +232,14 @@ void ChannelMappingEditor::buttonEvent(Button* button)
setChannelReference(electrodeButtons[i]);
}
previousClickedChan = -1;
setConfigured(true);
}
else if (button == resetButton)
{
createElectrodeButtons(getProcessor()->getNumInputs());
previousChannelCount = getProcessor()->getNumInputs();
setConfigured(false);
getEditorViewport()->makeEditorVisible(this, false, true);
}
else if (button == modifyButton)
{
......@@ -174,7 +248,7 @@ void ChannelMappingEditor::buttonEvent(Button* button)
channelSelector->activateButtons();
reorderActive = false;
selectedReference = 0;
for (int i=0; i < referenceButtons.size(); i++)
for (int i = 0; i < referenceButtons.size(); i++)
{
referenceButtons[i]->setEnabled(true);
}
......@@ -199,7 +273,7 @@ void ChannelMappingEditor::buttonEvent(Button* button)
{
electrodeButtons[i]->setToggleState(false,false);
}
if (enabledChannelArray[electrodeButtons[i]->getChannelNum()-1])
if ((enabledChannelArray[electrodeButtons[i]->getChannelNum()-1]) && (electrodeButtons[i]->getChannelNum() <= getProcessor()->getNumInputs()))
{
electrodeButtons[i]->setEnabled(true);
}
......@@ -234,7 +308,7 @@ void ChannelMappingEditor::buttonEvent(Button* button)
electrodeButtons[i]->setToggleState(false,false);
}
electrodeButtons[i]->addMouseListener(this,false);
}
selectAllButton->setEnabled(false);
}
......@@ -245,7 +319,8 @@ void ChannelMappingEditor::buttonEvent(Button* button)
Array<int> a;
if (referenceChannels[selectedReference] >= 0 )
if ((referenceChannels[selectedReference] >= 0 )
&& (referenceChannels[selectedReference] < channelSelector->getNumChannels() ))
{
a.add(referenceChannels[selectedReference]);
}
......@@ -269,6 +344,7 @@ void ChannelMappingEditor::buttonEvent(Button* button)
{
if (!reorderActive)
{
setConfigured(true);
int clickedChan = electrodeButtons.indexOf((ElectrodeButton*)button);
if (ModifierKeys::getCurrentModifiers().isShiftDown() && (previousClickedChan >= 0))
......@@ -419,16 +495,21 @@ void ChannelMappingEditor::channelChanged(int chan)
{
if (!reorderActive)
{
setConfigured(true);
getProcessor()->setCurrentChannel(chan-1);
getProcessor()->setParameter(2,selectedReference);
referenceChannels.set(selectedReference,chan-1);
}
}
void ChannelMappingEditor::saveEditorParameters(XmlElement* xml)
void ChannelMappingEditor::saveCustomParameters(XmlElement* xml)
{
xml->setAttribute("Type", "ChannelMappingEditor");
//Made a bit generic in case future expansions need more settings
XmlElement* settingsXml = xml->createNewChildElement("SETTING");
settingsXml->setAttribute("Type","visibleChannels");
settingsXml->setAttribute("Value",previousChannelCount);
for (int i = 0; i < channelArray.size(); i++)
{
XmlElement* channelXml = xml->createNewChildElement("CHANNEL");
......@@ -446,9 +527,20 @@ void ChannelMappingEditor::saveEditorParameters(XmlElement* xml)
}
void ChannelMappingEditor::loadEditorParameters(XmlElement* xml)
void ChannelMappingEditor::loadCustomParameters(XmlElement* xml)
{
setConfigured(true);
forEachXmlChildElementWithTagName(*xml, settingXml, "SETTING")
{
if (settingXml->getStringAttribute("Type").equalsIgnoreCase("visibleChannels"))
{
int nChans = settingXml->getIntAttribute("Value");
if (nChans > getProcessor()->getNumInputs())
{
createElectrodeButtons(nChans,false);
}
}
}
forEachXmlChildElementWithTagName(*xml, channelXml, "CHANNEL")
{
int i = channelXml->getIntAttribute("Number");
......@@ -467,7 +559,7 @@ void ChannelMappingEditor::loadEditorParameters(XmlElement* xml)
electrodeButtons[i]->setChannelNum(mapping);
electrodeButtons[i]->setEnabled(enabled);
electrodeButtons[i]->repaint();
getProcessor()->setCurrentChannel(i);
......@@ -499,16 +591,18 @@ void ChannelMappingEditor::loadEditorParameters(XmlElement* xml)
}
for (int i = 0; i < electrodeButtons.size(); i++)
{
if (referenceArray[electrodeButtons[i]->getChannelNum()-1] == selectedReference)
{
if (referenceArray[electrodeButtons[i]->getChannelNum()-1] == selectedReference)
{
electrodeButtons[i]->setToggleState(true,false);
}
else
{
electrodeButtons[i]->setToggleState(false,false);
}
electrodeButtons[i]->setToggleState(true,false);
}
else
{
electrodeButtons[i]->setToggleState(false,false);
}
}
refreshButtonLocations();
}
......@@ -569,7 +663,7 @@ void ChannelMappingEditor::mouseDrag(const MouseEvent &e)
if (hoverButton != lastHoverButton)
{
electrodeButtons[lastHoverButton]->setVisible(true);
electrodeButtons[hoverButton]->setVisible(false);
......@@ -605,7 +699,7 @@ void ChannelMappingEditor::mouseDrag(const MouseEvent &e)
}
electrodeButtons[hoverButton]->setChannelNum(draggingChannel);
electrodeButtons[hoverButton]->setToggleState(enabledChannelArray[draggingChannel-1],false);
lastHoverButton = hoverButton;
repaint();
}
......@@ -622,7 +716,11 @@ void ChannelMappingEditor::mouseUp(const MouseEvent &e)
isDragging = false;
electrodeButtons[lastHoverButton]->setVisible(true);
int from, to;
if (lastHoverButton < initialDraggedButton)
if (lastHoverButton == initialDraggedButton)
{
return;
}
else if (lastHoverButton < initialDraggedButton)
{
from = lastHoverButton;
to = initialDraggedButton;
......@@ -637,6 +735,7 @@ void ChannelMappingEditor::mouseUp(const MouseEvent &e)
{
setChannelPosition(i,electrodeButtons[i]->getChannelNum());
}
setConfigured(true);
}
}
......@@ -651,6 +750,7 @@ void ChannelMappingEditor::mouseDoubleClick(const MouseEvent &e)
{
if ((reorderActive) && electrodeButtons.contains((ElectrodeButton*)e.originalComponent))
{
setConfigured(true);
ElectrodeButton *button = (ElectrodeButton*)e.originalComponent;
if (button->getToggleState())
......@@ -669,4 +769,53 @@ void ChannelMappingEditor::mouseDoubleClick(const MouseEvent &e)
}
getEditorViewport()->makeEditorVisible(this, false, true);
}
}
\ No newline at end of file
}
void ChannelMappingEditor::mouseWheelMove(const MouseEvent& event,
const MouseWheelDetails& wheel)
{
float maxScrollDistance = ceil(float(electrodeButtons.size() - 80) / 16.0f);
// std::cout << "Got wheel move: " << wheel.deltaY << std::endl;
// channelSelector->shiftChannelsVertical(-wheel.deltaY);
scrollDistance -= wheel.deltaY*2;
if (scrollDistance > maxScrollDistance)
scrollDistance = maxScrollDistance;
if (scrollDistance < 0)
scrollDistance = 0;
refreshButtonLocations();
}
void ChannelMappingEditor::checkUnusedChannels()
{
for (int i = 0; i < electrodeButtons.size(); i++)
{
if (electrodeButtons[i]->getChannelNum() > getProcessor()->getNumInputs())
{
electrodeButtons[i]->setEnabled(false);
}
else
{
if (enabledChannelArray[electrodeButtons[i]->getChannelNum()-1])
{
electrodeButtons[i]->setEnabled(true);
}
else
{
electrodeButtons[i]->setEnabled(false);
}
}
}
}
void ChannelMappingEditor::setConfigured(bool state)
{
isConfigured = state;
resetButton->setEnabled(state);
resetButton->setToggleState(!state,false);
getProcessor()->setParameter(4,state?1:0);
}
......@@ -52,10 +52,10 @@ public:
void updateSettings();
void createElectrodeButtons(int numNeeded);
void createElectrodeButtons(int numNeeded, bool clearPrevious = true);
void saveEditorParameters(XmlElement* xml);
void loadEditorParameters(XmlElement* xml);
void saveCustomParameters(XmlElement* xml);
void loadCustomParameters(XmlElement* xml);
void channelChanged(int chan);
......@@ -65,16 +65,24 @@ public:
void mouseDoubleClick(const MouseEvent &e);
void mouseWheelMove(const MouseEvent& event, const MouseWheelDetails& wheel);
void collapsedStateChanged();
private:
void setChannelReference(ElectrodeButton *button);
void setChannelPosition(int position, int channel);
void checkUnusedChannels();
void setConfigured(bool state);
void refreshButtonLocations();
OwnedArray<ElectrodeButton> electrodeButtons;
OwnedArray<ElectrodeButton> referenceButtons;
ScopedPointer<ElectrodeEditorButton> selectAllButton;
ScopedPointer<ElectrodeEditorButton> modifyButton;
ScopedPointer<ElectrodeEditorButton> resetButton;
Array<int> channelArray;
Array<int> referenceArray;
......@@ -92,6 +100,9 @@ private:
int initialDraggedButton;
int draggingChannel;
int lastHoverButton;
bool isConfigured;
float scrollDistance;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ChannelMappingEditor);
......
......@@ -143,7 +143,7 @@ void ChannelSelector::shiftChannelsVertical(float amount)
offsetUD = jmax(offsetUD, float(parameterButtons.size())/8*-10.68f);
}
std::cout << "offsetUD = " << offsetUD << std::endl;
//std::cout << "offsetUD = " << offsetUD << std::endl;
refreshButtonBoundaries();
......@@ -432,7 +432,11 @@ void ChannelSelector::setAudioStatus(int chan, bool b)
}
void ChannelSelector::clearAudio()
{
for (int chan = 0; chan < audioButtons.size(); chan++)
audioButtons[chan]->setToggleState(false, true);
}
int ChannelSelector::getDesiredWidth()
{
......@@ -555,11 +559,12 @@ void ChannelSelector::buttonClicked(Button* button)
//int channelNum = editor->getStartChannel() + b->getChannel() - 1;
bool status = b->getToggleState();
std::cout << "Requesting audio monitor for channel " << ch->num << std::endl;
if (acquisitionIsActive) // use setParameter to change parameter safely
{
editor->getProcessorGraph()->
getAudioNode()->
setChannelStatus(ch, status);
getAudioNode()->setChannelStatus(ch, status);
}
else // change parameter directly
{
......@@ -590,8 +595,12 @@ void ChannelSelector::buttonClicked(Button* button)
}
}
else
else // parameter type
{
GenericEditor* editor = (GenericEditor*) getParentComponent();
editor->channelChanged(b->getChannel()-1);
// do nothing
if (radioStatus) // if radio buttons are active
{
......@@ -832,8 +841,8 @@ void ChannelSelectorRegion::mouseWheelMove(const MouseEvent& event,
const MouseWheelDetails& wheel)
{
std::cout << "Got wheel move: " << wheel.deltaY << std::endl;
channelSelector->shiftChannelsVertical(wheel.deltaY);
// std::cout << "Got wheel move: " << wheel.deltaY << std::endl;
channelSelector->shiftChannelsVertical(-wheel.deltaY);
}
void ChannelSelectorRegion::paint(Graphics& g)
......
......@@ -94,6 +94,9 @@ public:
/** Set whether a particular channel should be monitored. */
void setAudioStatus(int, bool);
/** Sets all audio monitors to 'false' */
void clearAudio();
/** Set whether a particular channel is selected for editing parameters. */
void setParamStatus(int, bool);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment