Skip to content

Commit

Permalink
Add headphones icon to spike plots
Browse files Browse the repository at this point in the history
  • Loading branch information
jsiegle committed Aug 29, 2024
1 parent 5676a9b commit e747485
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 14 deletions.
20 changes: 15 additions & 5 deletions Plugins/SpikeViewer/SpikeDisplayNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,28 @@ void SpikeDisplayNode::setParameter (int param, float val)
{
if (param == 10)
{
SpikeChannel* chan = spikeChannels[int (val)];

String msg = "AUDIO SELECT ";
msg += String (chan->getStreamId()) + " ";

if (val >= 0 && val < spikeChannels.size())
{
SpikeChannel* chan = spikeChannels[int (val)];

msg += String (chan->getStreamId()) + " ";

for (auto ch : chan->localChannelIndexes)
for (auto ch : chan->localChannelIndexes)
{
msg += String (ch + 1) + " ";
}

}
else
{
msg += String (ch + 1) + " ";
msg += "NONE";
}

//std::cout << "MESSAGE: " << msg << std::endl;
broadcastMessage (msg);

}
}

Expand Down
60 changes: 53 additions & 7 deletions Plugins/SpikeViewer/SpikePlots.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ SpikePlot::SpikePlot (SpikeDisplayCanvas* sdc,
setDisplayThresholdForChannel (i, 0);
}

monitorButton = std::make_unique<UtilityButton> ("MON");
monitorButton = std::make_unique<MonitorButton>();
monitorButton->setTooltip ("Monitor this electrode (requires an Audio Monitor in the signal chain)");
monitorButton->addListener (this);
addAndMakeVisible (monitorButton.get());
Expand All @@ -108,9 +108,6 @@ void SpikePlot::setId (std::string id)

void SpikePlot::paint (Graphics& g)
{
//g.setColour (findColour (ThemeColours::outline));
//g.drawRect (0, 0, getWidth(), getHeight());

g.setFont (font);
g.setColour (findColour (ThemeColours::controlPanelText));
g.drawText (name, 10, 0, 200, 20, Justification::left, false);
Expand Down Expand Up @@ -252,9 +249,17 @@ void SpikePlot::buttonClicked (Button* button)
{
if (button == monitorButton.get())
{
bool shouldMonitor = button->getToggleState();

LOGD ("Button clicked: monitor audio: " + String (int(shouldMonitor)) + " electrode: " + String (electrodeNumber));

canvas->resetAudioMonitorState();
button->setToggleState (true, dontSendNotification);
canvas->processor->setParameter (10, electrodeNumber);
button->setToggleState (shouldMonitor, dontSendNotification);

if(shouldMonitor)
canvas->processor->setParameter (10, electrodeNumber);
else
canvas->processor->setParameter (10, -1);

return;
}
Expand Down Expand Up @@ -858,7 +863,12 @@ void WaveAxes::setDisplayThreshold (float threshold)

// --------------------------------------------------

ProjectionAxes::ProjectionAxes (SpikeDisplayCanvas* canvas, Projection proj_) : GenericAxes (canvas, PROJECTION_AXES), imageDim (500), rangeX (250), rangeY (250), spikesReceivedSinceLastRedraw (0), proj (proj_)
ProjectionAxes::ProjectionAxes (SpikeDisplayCanvas* canvas, Projection proj_) : GenericAxes (canvas, PROJECTION_AXES),
imageDim (500),
rangeX (250),
rangeY (250),
spikesReceivedSinceLastRedraw (0),
proj (proj_)
{
projectionImage = Image (Image::RGB, imageDim, imageDim, true, SoftwareImageType());

Expand Down Expand Up @@ -1002,3 +1012,39 @@ void ProjectionAxes::n2ProjIdx (Projection proj, int* p1, int* p2)
}

// --------------------------------------------------

MonitorButton::MonitorButton() : Button ("Monitor")
{

XmlDocument xmlDoc (R"(
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-headphones-filled" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="#2c3e50" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M21 18a3 3 0 0 1 -2.824 2.995l-.176 .005h-1a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-3a3 3 0 0 1 2.824 -2.995l.176 -.005h1c.351 0 .688 .06 1 .171v-.171a7 7 0 0 0 -13.996 -.24l-.004 .24v.17c.25 -.088 .516 -.144 .791 -.163l.209 -.007h1a3 3 0 0 1 2.995 2.824l.005 .176v3a3 3 0 0 1 -2.824 2.995l-.176 .005h-1a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-6a9 9 0 0 1 17.996 -.265l.004 .265v6z" stroke-width="0" fill="currentColor" />
</svg>
)");

headphoneIcon = Drawable::createFromSVG (*xmlDoc.getDocumentElement().get());

setClickingTogglesState (true);

}

void MonitorButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown)
{
Colour buttonColour;

if (getToggleState())
buttonColour = findColour (ThemeColours::highlightedFill);
else
buttonColour = findColour (ThemeColours::defaultText);

if (isMouseOverButton)
buttonColour = buttonColour.brighter (0.2f);

headphoneIcon->replaceColour (Colours::black, buttonColour);

headphoneIcon->drawWithin (g, getLocalBounds().toFloat(), RectanglePlacement::centred, 1.0f);

headphoneIcon->replaceColour (buttonColour, Colours::black);

}
25 changes: 24 additions & 1 deletion Plugins/SpikeViewer/SpikePlots.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,29 @@ enum SpikePlotType
#define STEREO_PLOT 1002
#define SINGLE_PLOT 1001

/**
Button to trigger audio monitoring for a given electrode
*/

class MonitorButton : public Button
{
public:
/** Constructor */
MonitorButton();

/** Destructor */
~MonitorButton() {}

/** Renders button */
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override;

private:

std::unique_ptr<Drawable> headphoneIcon;
};

/**
Class for drawing the waveforms and projections of incoming spikes
Expand Down Expand Up @@ -170,7 +193,7 @@ class SpikePlot : public Component,
OwnedArray<WaveAxes> waveAxes;
OwnedArray<UtilityButton> rangeButtons;

std::unique_ptr<UtilityButton> monitorButton;
std::unique_ptr<MonitorButton> monitorButton;

Array<float> ranges;

Expand Down
15 changes: 14 additions & 1 deletion Source/Processors/AudioMonitor/AudioMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,20 @@ void AudioMonitor::handleBroadcastMessage (const String& msg, const int64 messag

if (command.equalsIgnoreCase ("SELECT"))
{
if (parts.size() >= 4)
if(parts.size() == 3)
{
String command = parts[2];

if (command.equalsIgnoreCase ("NONE"))
{
Array<var> ch;

for (auto stream : getDataStreams())
stream->getParameter ("channels")->setNextValue (ch);

}
}
else if (parts.size() >= 4)
{
uint16 streamId = parts[2].getIntValue();

Expand Down

0 comments on commit e747485

Please sign in to comment.