Skip to content

Commit 6af9210

Browse files
committed
Add subprocessor channel filtering by sample rate to LfpDisplayEditor
1 parent c4c9cd1 commit 6af9210

5 files changed

Lines changed: 183 additions & 73 deletions

File tree

Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.cpp

Lines changed: 38 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,9 @@ void LfpDisplayCanvas::update()
222222
}
223223
}
224224
else
225+
{
225226
sampleRate.add(30000);
227+
}
226228

227229
// std::cout << "Sample rate for ch " << i << " = " << sampleRate[i] << std::endl;
228230
displayBufferIndex.add(0);
@@ -264,6 +266,8 @@ void LfpDisplayCanvas::update()
264266
}
265267

266268
}
269+
270+
lfpDisplay->rebuildDrawableChannelsList();
267271

268272
}
269273

@@ -564,10 +568,15 @@ bool LfpDisplayCanvas::getDrawMethodState()
564568

565569
int LfpDisplayCanvas::getChannelSampleRate(int channel)
566570
{
567-
// TODO: (kelly) should this do a range check?
568571
return sampleRate[channel];
569572
}
570573

574+
void LfpDisplayCanvas::setDrawableSampleRate(float samplerate)
575+
{
576+
std::cout << "setting the drawable sample rate in the canvas" << std::endl;
577+
lfpDisplay->setDisplayedSampleRate(samplerate);
578+
}
579+
571580
void LfpDisplayCanvas::redraw()
572581
{
573582
fullredraw=true;
@@ -1947,9 +1956,6 @@ void LfpDisplay::setNumChannels(int numChannels)
19471956
//lfpInfo->setColour(channelColours[i % channelColours.size()]);
19481957
lfpInfo->setRange(range[options->getChannelType(i)]);
19491958
lfpInfo->setChannelHeight(canvas->getChannelHeight());
1950-
1951-
// TODO: (kelly) this won't work... samplerate gets set AFTER this method is called
1952-
lfpInfo->setChannelSampleRate(canvas->getChannelSampleRate(i));
19531959

19541960
addAndMakeVisible(lfpInfo);
19551961

@@ -1992,35 +1998,7 @@ int LfpDisplay::getTotalHeight()
19921998

19931999
void LfpDisplay::resized()
19942000
{
1995-
1996-
//canvas->channelOverlapFactor
1997-
19982001
int totalHeight = 0;
1999-
2000-
// for (int i = 0; i < channels.size(); i++)
2001-
// {
2002-
//
2003-
// LfpChannelDisplay* disp = channels[i];
2004-
//
2005-
// if (disp->getHidden()) continue;
2006-
//
2007-
// disp->setBounds(canvas->leftmargin,
2008-
// totalHeight-(disp->getChannelOverlap()*canvas->channelOverlapFactor)/2,
2009-
// getWidth(),
2010-
// disp->getChannelHeight()+(disp->getChannelOverlap()*canvas->channelOverlapFactor));
2011-
//
2012-
// disp-> resized();
2013-
//
2014-
// LfpChannelDisplayInfo* info = channelInfo[i];
2015-
//
2016-
// info->setBounds(0,
2017-
// totalHeight-disp->getChannelHeight()/4,
2018-
// canvas->leftmargin + 50,
2019-
// disp->getChannelHeight());
2020-
//
2021-
// totalHeight += disp->getChannelHeight();
2022-
//
2023-
// }
20242002

20252003
for (int i = 0; i < drawableChannels.size(); i++)
20262004
{
@@ -2189,6 +2167,7 @@ int LfpDisplay::getRange(DataChannel::DataChannelTypes type)
21892167

21902168
void LfpDisplay::setChannelHeight(int r, bool resetSingle)
21912169
{
2170+
std::cout << "setting channel height in LfpDisplay" << std::endl;
21922171
if (!getSingleChannelState()) cachedDisplayChannelHeight = r;
21932172

21942173
for (int i = 0; i < numChans; i++)
@@ -2258,6 +2237,18 @@ void LfpDisplay::cacheNewChannelHeight(int r)
22582237
cachedDisplayChannelHeight = r;
22592238
}
22602239

2240+
float LfpDisplay::getDisplayedSampleRate()
2241+
{
2242+
return drawableSampleRate;
2243+
}
2244+
2245+
// Must manually call rebuildDrawableChannelsList after this is set, typically will happen
2246+
// already as a result of some other procedure
2247+
void LfpDisplay::setDisplayedSampleRate(float samplerate)
2248+
{
2249+
std::cout << "Setting the displayed samplerate for LfpDisplayCanvas to " << samplerate << std::endl;
2250+
drawableSampleRate = samplerate;
2251+
}
22612252

22622253
bool LfpDisplay::getChannelsReversed()
22632254
{
@@ -2266,8 +2257,6 @@ bool LfpDisplay::getChannelsReversed()
22662257

22672258
void LfpDisplay::setChannelsReversed(bool state)
22682259
{
2269-
// TODO: (kelly) clean up this method
2270-
22712260
if (state == channelsReversed) return; // bail early, in case bookkeeping error
22722261

22732262
channelsReversed = state;
@@ -2288,7 +2277,6 @@ void LfpDisplay::setChannelsReversed(bool state)
22882277

22892278
// swap front and back, moving towards middle
22902279
drawableChannels.swap(i, j);
2291-
// channelInfo.swap(i, j);
22922280

22932281
// also swap coords
22942282
{
@@ -2448,45 +2436,21 @@ void LfpDisplay::mouseWheelMove(const MouseEvent& e, const MouseWheelDetails&
24482436

24492437
void LfpDisplay::toggleSingleChannel(int chan)
24502438
{
2451-
//std::cout << "Toggle channel " << chan << std::endl;
2452-
2453-
2454-
//if (chan != singleChan)
24552439
if (!getSingleChannelState())
24562440
{
2457-
// std::cout << "Single channel on" << std::endl;
2458-
// singleChan = chan;
2459-
//
2460-
// int newHeight = viewport->getHeight();
2461-
// channelInfo[chan]->setEnabledState(true);
2462-
// channelInfo[chan]->setSingleChannelState(true);
2463-
// setChannelHeight(newHeight, false);
2464-
// setSize(getWidth(), numChans*getChannelHeight());
2465-
//
2466-
// viewport->setScrollBarsShown(false,false);
2467-
// viewport->setViewPosition(Point<int>(0,chan*newHeight));
2468-
//
2469-
// for (int i = 0; i < channels.size(); i++)
2470-
// {
2471-
// if (i != chan)
2472-
// channels[i]->setEnabledState(false);
2473-
// }
24742441

24752442
std::cout << "Single channel on (" << chan << ")" << std::endl;
24762443
singleChan = chan;
24772444

24782445
int newHeight = viewport->getHeight();
24792446
LfpChannelTrack lfpChannelTrack{drawableChannels[chan].channel, drawableChannels[chan].channelInfo};
2480-
// drawableChannels[chan].channelInfo->setEnabledState(true);
2481-
// drawableChannels[chan].channelInfo->setSingleChannelState(true);
24822447
lfpChannelTrack.channelInfo->setEnabledState(true);
24832448
lfpChannelTrack.channelInfo->setSingleChannelState(true);
24842449
setChannelHeight(newHeight, false);
24852450
setSize(getWidth(), numChans*getChannelHeight());
24862451

24872452
viewport->setScrollBarsShown(false, false);
24882453
viewport->setViewPosition(Point<int>(0, chan*newHeight));
2489-
// viewport->setViewPosition(Point<int>(0, 0));
24902454

24912455
// disable unused channels
24922456
for (int i = 0; i < drawableChannels.size(); i++)
@@ -2512,7 +2476,7 @@ void LfpDisplay::toggleSingleChannel(int chan)
25122476
{
25132477
channelInfo[n]->setSingleChannelState(false);
25142478
}
2515-
//drawableChannels[0].channelInfo->setSingleChannelState(false);
2479+
25162480
setChannelHeight(cachedDisplayChannelHeight);
25172481

25182482
reactivateChannels();
@@ -2536,10 +2500,17 @@ void LfpDisplay::rebuildDrawableChannelsList()
25362500
Array<LfpChannelTrack> channelsToDraw;
25372501
drawableChannels = Array<LfpDisplay::LfpChannelTrack>();
25382502

2539-
25402503
// iterate over all channels and select drawable ones
25412504
for (size_t i = 0; i < channels.size(); i++)
25422505
{
2506+
// if channel[i] is not the right samplerate, hide it and continue
2507+
if (canvas->getChannelSampleRate(i) != getDisplayedSampleRate())
2508+
{
2509+
channels[i]->setHidden(true);
2510+
channelInfo[i]->setHidden(true);
2511+
continue;
2512+
}
2513+
25432514
if (displaySkipAmt == 0) // no skips, add all channels
25442515
{
25452516
channels[i]->setHidden(false);
@@ -2595,7 +2566,12 @@ void LfpDisplay::rebuildDrawableChannelsList()
25952566
}
25962567
}
25972568

2598-
canvas->resizeToChannels();
2569+
// this guards against an exception where the editor sets the drawable samplerate
2570+
// before the lfpDisplay is fully initialized
2571+
if (getHeight() > 0 && getWidth() > 0)
2572+
{
2573+
canvas->resizeToChannels();
2574+
}
25992575
}
26002576

26012577
LfpBitmapPlotter * const LfpDisplay::getPlotterPtr() const

Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayCanvas.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,17 @@ class LfpDisplayCanvas : public Visualizer,
9696
float histogramParameterA;
9797
float histogramParameterB;
9898

99+
/** Returns the number of both continuous and event channels tracked by the canvas */
99100
int getNumChannels();
100101
/** Returns the number of channels NOT hidden for display */
101102
int getNumChannelsVisible();
102103
bool getInputInvertedState();
103104
bool getDrawMethodState();
104105

105106
int getChannelSampleRate(int channel);
107+
108+
/** Delegates a samplerate for drawing to the LfpDisplay referenced by this canvas */
109+
void setDrawableSampleRate(float samplerate);
106110

107111
const float getXCoord(int chan, int samp);
108112
const float getYCoord(int chan, int samp);
@@ -137,7 +141,7 @@ class LfpDisplayCanvas : public Visualizer,
137141
bool drawSaturationWarning; // optionally raise hell if the actual data is saturating
138142

139143
int nChans;
140-
int nChansVisible; // the number of channels NOT hidden for display
144+
//int nChansVisible; // the number of channels NOT hidden for display
141145

142146
float timebase;
143147

@@ -450,6 +454,19 @@ class LfpDisplay : public Component
450454
void setChannelHeight(int r, bool resetSingle = true);
451455
int getChannelHeight();
452456

457+
/** Returns the sample rate that is currently filtering the drawable channels */
458+
float getDisplayedSampleRate();
459+
460+
/** Sets the samplerate that displayed channels must be set to. No channels with
461+
differing samplerates will be drawn to screen.
462+
463+
This function does not automatically repopulate the drawableChannels list, so
464+
rebuildDrawableChannelsList must be called before the screen is updated.
465+
466+
@see LfpDisplayCanvas::setDrawableSampleRate, LfpDisplayNode::updateSettings
467+
*/
468+
void setDisplayedSampleRate(float samplerate);
469+
453470
/** Caches a new channel height without updating the channels */
454471
void cacheNewChannelHeight(int r);
455472

@@ -556,6 +573,7 @@ class LfpDisplay : public Component
556573
int numChans;
557574
int displaySkipAmt;
558575
int cachedDisplayChannelHeight; // holds a channel height if reset during single channel focus
576+
float drawableSampleRate;
559577

560578
int totalHeight;
561579

Source/Plugins/LfpDisplayNodeAlpha/LfpDisplayEditor.cpp

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,53 @@ LfpDisplayEditor::LfpDisplayEditor(GenericProcessor* parentNode, bool useDefault
3030
: VisualizerEditor(parentNode, useDefaultParameterEditors)
3131

3232
{
33-
33+
lfpProcessor = (LfpDisplayNode*) parentNode;
3434
tabText = "LFP";
3535

3636
desiredWidth = 180;
37-
37+
38+
subprocessorSelectionLabel = new Label("Display subprocessor sample rate", "Display Subproc. Sample Rate");
39+
subprocessorSelectionLabel->setBounds(10, 25, 140, 20);
40+
addAndMakeVisible(subprocessorSelectionLabel);
41+
42+
subprocessorSelection = new ComboBox("Subprocessor sample rate");
43+
subprocessorSelection->setBounds(subprocessorSelectionLabel->getX()+5, subprocessorSelectionLabel->getBottom(), 60, 22);
44+
subprocessorSelection->addListener(this);
45+
addAndMakeVisible(subprocessorSelection);
3846
}
3947

4048
LfpDisplayEditor::~LfpDisplayEditor()
4149
{
4250
}
4351

44-
4552
Visualizer* LfpDisplayEditor::createNewCanvas()
4653
{
54+
canvas = new LfpDisplayCanvas(lfpProcessor);
55+
updateSubprocessorSelectorOptions();
56+
return canvas;
57+
}
4758

48-
LfpDisplayNode* processor = (LfpDisplayNode*) getProcessor();
49-
return new LfpDisplayCanvas(processor);
50-
59+
void LfpDisplayEditor::buttonClicked(Button *button)
60+
{
61+
// duplicate default VisualizerEditor behavior, except...
62+
if (canvas == nullptr)
63+
{
64+
canvas = createNewCanvas();
65+
66+
// initialize the subprocessor sample rate filtering before canvas updates
67+
// (else) initialization errors. lots of time-critical cross dependencies here,
68+
// should be cleaned up
69+
updateSubprocessorSelectorOptions();
70+
((LfpDisplayCanvas*)canvas.get())->setDrawableSampleRate(*(inputSampleRates.begin() + (subprocessorSelection->getSelectedId() - 1)));
71+
72+
canvas->update();
73+
74+
if (isPlaying)
75+
canvas->beginAnimation();
76+
}
77+
78+
// resume default behavior
79+
VisualizerEditor::buttonClicked(button);
5180
}
5281

5382
// not really being used (yet)...
@@ -57,3 +86,54 @@ void LfpDisplayEditor::buttonEvent(Button* button)
5786

5887
}
5988

89+
void LfpDisplayEditor::comboBoxChanged(juce::ComboBox *cb)
90+
{
91+
if (cb == subprocessorSelection)
92+
{
93+
setCanvasDrawableSampleRate(cb->getSelectedId() - 1);
94+
}
95+
}
96+
97+
void LfpDisplayEditor::updateSubprocessorSelectorOptions()
98+
{
99+
// clear out the old data
100+
inputSampleRates.clear();
101+
subprocessorSelection->clear(dontSendNotification);
102+
103+
// get a list of all the sample rates
104+
for (int i = 0, len = lfpProcessor->getNumInputs(); i < len; ++i)
105+
{
106+
float samplerate = lfpProcessor->getDataChannel(i)->getSampleRate();
107+
bool success = inputSampleRates.add(samplerate);
108+
109+
// if (success) std::cout << "\t\tadding sample rate " << samplerate << " ... size = " << inputSampleRates.size() << std::endl;
110+
}
111+
112+
// if the source changes, default to first samplerate given
113+
int sampleRateToSet = -1;
114+
if (inputSampleRates.size() > 0)
115+
{
116+
sampleRateToSet = 0;
117+
}
118+
119+
// add the samplerate options to the combobox
120+
for (int i = 0; i < inputSampleRates.size(); ++i)
121+
{
122+
subprocessorSelection->addItem(String(*(inputSampleRates.begin()+i)), i+1);
123+
}
124+
125+
if (sampleRateToSet >= 0)
126+
{
127+
setCanvasDrawableSampleRate(sampleRateToSet);
128+
}
129+
}
130+
131+
void LfpDisplayEditor::setCanvasDrawableSampleRate(int index)
132+
{
133+
if (canvas)
134+
{
135+
std::cout << "selected index = " << index << std::endl;
136+
((LfpDisplayCanvas*)canvas.get())->setDrawableSampleRate(*(inputSampleRates.begin() + (index)));
137+
}
138+
}
139+

0 commit comments

Comments
 (0)