Skip to content
Snippets Groups Projects
Commit 167a58d7 authored by Stuart Layton's avatar Stuart Layton
Browse files

The spikeviewer shows up without segfaults! That was more painful than it should have been.

The SpikeDisplayNode object isn't working properly. Queueing of spikes there appeared to be what was causing the problem.

I need to consider an alternative way of handling the SpikeObjects. In the past I've used a circular buffer but that has
problems with having a set size. I can use an stl::queue but queues are not thread safe, which is something that we
definitely need.

Anyway the plots show up and dance when the viewer is turned on.  I still need to implement a Stereotrode plot and then the
tetrode plot. I'll probably derive them from the ElectrodePlot base class instead of creating a base classs from which all
three plot types are derived from.

Finally I need to get a better handle on the setup of the OpenGLCanvas and how its sized.  How the "Magical" scroll bars work
and how to auto place the plots.

Do we force all the plots to be of the same type? Or do we mix in Electrode Plots with Tetrode Plots?  If so how do we orient them all?
parent 41c0c6bd
No related branches found
No related tags found
No related merge requests found
Showing
with 299 additions and 497 deletions
...@@ -10,18 +10,18 @@ SpikeDisplayEditor::SpikeDisplayEditor (GenericProcessor* parentNode) ...@@ -10,18 +10,18 @@ SpikeDisplayEditor::SpikeDisplayEditor (GenericProcessor* parentNode)
desiredWidth = 250; desiredWidth = 250;
StringArray timeBaseValues; StringArray timeBaseValues;
timeBaseValues.add("1"); timeBaseValues.add("100");
timeBaseValues.add("2"); timeBaseValues.add("200");
timeBaseValues.add("5"); timeBaseValues.add("500");
timeBaseValues.add("10"); timeBaseValues.add("1000");
createRadioButtons(35, 50, 160, timeBaseValues, "Display width (s)"); createRadioButtons(35, 50, 160, timeBaseValues, "Thresholds (s)");
StringArray displayGainValues; StringArray displayGainValues;
displayGainValues.add("1"); displayGainValues.add("100");
displayGainValues.add("2"); displayGainValues.add("200");
displayGainValues.add("4"); displayGainValues.add("400");
displayGainValues.add("8"); displayGainValues.add("800");
createRadioButtons(35, 90, 160, displayGainValues, "Display Gain"); createRadioButtons(35, 90, 160, displayGainValues, "Display Gain");
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "AudioNode.h" #include "AudioNode.h"
#include "LfpDisplayNode.h" #include "LfpDisplayNode.h"
#include "SpikeDisplayNode.h"
#include "EventNode.h" #include "EventNode.h"
#include "FilterNode.h" #include "FilterNode.h"
#include "GenericProcessor.h" #include "GenericProcessor.h"
...@@ -381,7 +382,13 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip ...@@ -381,7 +382,13 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
// std::cout << "Graph data viewport: " << UI->getDataViewport() << std::endl; // std::cout << "Graph data viewport: " << UI->getDataViewport() << std::endl;
// processor->setDataViewport(getDataViewport()); // processor->setDataViewport(getDataViewport());
//processor->setUIComponent(UI); //processor->setUIComponent(UI);
} else if (subProcessorType.equalsIgnoreCase("WiFi Output")) { }
else if (subProcessorType.equalsIgnoreCase("Spike Viewer")) {
std::cout << "Creating an SpikeDisplayNode." << std::endl;
processor = new SpikeDisplayNode();
}
else if (subProcessorType.equalsIgnoreCase("WiFi Output")) {
std::cout << "Creating a WiFi node." << std::endl; std::cout << "Creating a WiFi node." << std::endl;
processor = new WiFiOutput(); processor = new WiFiOutput();
} }
...@@ -408,6 +415,7 @@ bool ProcessorGraph::processorWithSameNameExists(const String& name) ...@@ -408,6 +415,7 @@ bool ProcessorGraph::processorWithSameNameExists(const String& name)
} }
void ProcessorGraph::removeProcessor(GenericProcessor* processor) { void ProcessorGraph::removeProcessor(GenericProcessor* processor) {
std::cout << "Removing processor with ID " << processor->getNodeId() << std::endl; std::cout << "Removing processor with ID " << processor->getNodeId() << std::endl;
......
...@@ -26,11 +26,10 @@ ...@@ -26,11 +26,10 @@
SpikeDisplayNode::SpikeDisplayNode() SpikeDisplayNode::SpikeDisplayNode()
: GenericProcessor("SpikeDisplay Viewer"), : GenericProcessor("SpikeDisplay Viewer"),
bufferLength(200), displayGain(1), bufferSize(0), abstractFifo(100)
displayBufferIndex(0), abstractFifo(100)
{ {
displayBuffer = new AudioSampleBuffer(8, 100); // displayBuffer = new AudioSampleBuffer(8, 100);
eventBuffer = new MidiBuffer(); eventBuffer = new MidiBuffer();
} }
...@@ -54,37 +53,14 @@ void SpikeDisplayNode::updateSettings() ...@@ -54,37 +53,14 @@ void SpikeDisplayNode::updateSettings()
std::cout << "Setting num inputs on SpikeDisplayNode to " << getNumInputs() << std::endl; std::cout << "Setting num inputs on SpikeDisplayNode to " << getNumInputs() << std::endl;
} }
bool SpikeDisplayNode::resizeBuffer()
{
int nSamples = (int) getSampleRate()*bufferLength;
int nInputs = getNumInputs();
std::cout << "Resizing buffer. Samples: " << nSamples << ", Inputs: " << nInputs << std::endl;
if (nSamples > 0 && nInputs > 0)
{
abstractFifo.setTotalSize(nSamples);
displayBuffer->setSize(nInputs, nSamples);
return true;
} else {
return false;
}
}
bool SpikeDisplayNode::enable() bool SpikeDisplayNode::enable()
{ {
std::cout<<"SpikeDisplayNode enabled!"<<std::endl; std::cout<<"SpikeDisplayNode::enable()"<<std::endl;
if (resizeBuffer()) SpikeDisplayEditor* editor = (SpikeDisplayEditor*) getEditor();
{ editor->enable();
SpikeDisplayEditor* editor = (SpikeDisplayEditor*) getEditor(); return true;
editor->enable();
return true;
} else {
return false;
}
} }
bool SpikeDisplayNode::disable() bool SpikeDisplayNode::disable()
...@@ -95,58 +71,44 @@ bool SpikeDisplayNode::disable() ...@@ -95,58 +71,44 @@ bool SpikeDisplayNode::disable()
return true; return true;
} }
int SpikeDisplayNode::getNumberOfChannelsForInput(int i){
std::cout<<"SpikeDisplayNode::getNumberOfChannelsForInput()"<<std::endl;
return 1;
}
void SpikeDisplayNode::setParameter (int parameterIndex, float newValue) void SpikeDisplayNode::setParameter (int parameterIndex, float newValue)
{ {
std::cout<<"SpikeDisplayNode setParameter!"<<std::endl; std::cout<<"SpikeDisplayNode setParameter!"<<std::endl;
} }
void SpikeDisplayNode::process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples) void SpikeDisplayNode::process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples)
{ {
std::cout<<"SpikeDisplayNode process!"<<std::endl; std::cout<<"SpikeDisplayNode::process"<<std::endl;
// 1. place any new samples into the displayBuffer uint64_t ts = 00000;
int noise = 10;
int samplesLeft = displayBuffer->getNumSamples() - displayBufferIndex; SpikeObject newSpike;
if (nSamples < samplesLeft)
{
for (int chan = 0; chan < buffer.getNumChannels(); chan++)
{
displayBuffer->copyFrom(chan, // destChannel
displayBufferIndex, // destStartSample
buffer, // source
chan, // source channel
0, // source start sample
nSamples); // numSamples
}
displayBufferIndex += (nSamples);
} else {
int extraSamples = nSamples - samplesLeft;
for (int chan = 0; chan < buffer.getNumChannels(); chan++)
{
displayBuffer->copyFrom(chan, // destChannel
displayBufferIndex, // destStartSample
buffer, // source
chan, // source channel
0, // source start sample
samplesLeft); // numSamples
displayBuffer->copyFrom(chan,
0,
buffer,
chan,
samplesLeft,
extraSamples);
}
displayBufferIndex = extraSamples;
}
generateSimulatedSpike(&newSpike, ts, noise);
spikebuffer.push(newSpike);
bufferSize++;
} }
bool SpikeDisplayNode::getNextSpike(SpikeObject *spike){
std::cout<<"SpikeDisplayNode::getNextSpike()"<<std::endl;
if (bufferSize<1 || spikebuffer.empty())
return false;
else{
SpikeObject s = spikebuffer.front();
spikebuffer.pop();
bufferSize--;
*spike = s;
return true;
}
return false;
}
\ No newline at end of file
...@@ -29,18 +29,18 @@ ...@@ -29,18 +29,18 @@
#include "Editors/VisualizerEditor.h" #include "Editors/VisualizerEditor.h"
#include "GenericProcessor.h" #include "GenericProcessor.h"
#include "Visualization/SpikeObject.h" #include "Visualization/SpikeObject.h"
#include <queue>
/** /**
Holds data in a displayBuffer to be used by the SpikeDisplayCanvas Takes in MidiEvents and extracts SpikeObjects from the MidiEvent buffers. Those Events are then held in a queue until they are pulled by the spikeviewer
for rendering individual spike events
@see GenericProcessor, SpikeDisplayEditor, SpikeDisplayCanvas @see GenericProcessor, SpikeDisplayEditor, SpikeDisplayCanvas
*/ */
class DataViewport; class DataViewport;
class SpikeDisplayNode : public GenericProcessor class SpikeDisplayNode : public GenericProcessor
...@@ -63,22 +63,22 @@ public: ...@@ -63,22 +63,22 @@ public:
bool enable(); bool enable();
bool disable(); bool disable();
AudioSampleBuffer* getDisplayBufferAddress() {return displayBuffer;} int getNumberOfChannelsForInput(int i);
int getDisplayBufferIndex() {return displayBufferIndex;}
bool getNextSpike(SpikeObject *spike);
private: private:
ScopedPointer<AudioSampleBuffer> displayBuffer; int numberOfSources;
ScopedPointer<MidiBuffer> eventBuffer; AbstractFifo abstractFifo;
int displayBufferIndex;
float displayGain; // //ScopedPointer<AudioSampleBuffer> displayBuffer;
int bufferLength; // s ScopedPointer<MidiBuffer> eventBuffer;
AbstractFifo abstractFifo; std::queue<SpikeObject> spikebuffer;
bool resizeBuffer(); int bufferSize;
//bool resizeBuffer();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SpikeDisplayNode); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SpikeDisplayNode);
......
...@@ -24,23 +24,36 @@ ...@@ -24,23 +24,36 @@
#include "SpikeDisplayCanvas.h" #include "SpikeDisplayCanvas.h"
SpikeDisplayCanvas::SpikeDisplayCanvas(SpikeDisplayNode* n) : processor(n), SpikeDisplayCanvas::SpikeDisplayCanvas(SpikeDisplayNode* n) : processor(n),
xBuffer(0), yBuffer(0), xBuffer(0), yBuffer(0), newSpike(false)
plotHeight(40), selectedChan(-1), screenBufferIndex(0),
timebase(1.0f), displayGain(5.0f), displayBufferIndex(0)
{ {
nChans = processor->getNumInputs();
sampleRate = processor->getSampleRate();
std::cout << "Setting num inputs on SpikeDisplayCanvas to " << nChans << std::endl; nSources = 0; //processor->getNumInputs();
std::cout<<"SpikeDisplayNode has :"<<nSources<<" outputs!"<<std::endl;
//memset(nChannels, 0, sizeof(nChannels[0]) * MAX_NUMBER_OF_SPIKE_SOURCES);
for (int i=0; i<nSources; i++)
nChannels[i] = processor->getNumberOfChannelsForInput(i);
displayBuffer = processor->getDisplayBufferAddress(); // sampleRate = processor->getSampleRate();
displayBufferSize = displayBuffer->getNumSamples(); std::cout << "Setting num inputs on SpikeDisplayCanvas to " << nSources << std::endl;
std::cout << "Setting displayBufferSize on SpikeDisplayCanvas to " << displayBufferSize << std::endl;
//generateEmptySpike(&spike, 1);
for (int i=0; i<8; i++)
{
ElectrodePlot ep = ElectrodePlot(10 +i * 80, 10, 75, 75, "");
plots.push_back(ep);
}
// displayBuffer = processor->getDisplayBufferAddress();
// displayBufferSize = displayBuffer->getNumSamples();
// std::cout << "Setting displayBufferSize on SpikeDisplayCanvas to " << displayBufferSize << std::endl;
totalHeight = (plotHeight+yBuffer)*nChans + yBuffer; // totalHeight = (plotHeight+yBuffer)*nChans + yBuffer;
screenBuffer = new AudioSampleBuffer(nChans, 10000); // screenBuffer = new AudioSampleBuffer(nChans, 10000);
} }
...@@ -52,13 +65,13 @@ SpikeDisplayCanvas::~SpikeDisplayCanvas() ...@@ -52,13 +65,13 @@ SpikeDisplayCanvas::~SpikeDisplayCanvas()
void SpikeDisplayCanvas::newOpenGLContextCreated() void SpikeDisplayCanvas::newOpenGLContextCreated()
{ {
std::cout<<"SpikeDisplayCanvas::newOpenGLContextCreated()"<<std::endl;
setUp2DCanvas(); setUp2DCanvas();
activateAntiAliasing(); //activateAntiAliasing();
glClearColor (0.667, 0.698, 0.718, 1.0); glClearColor (0.667, 0.698, 0.718, 1.0);
resized(); resized();
endAnimation();
//startTimer(50); //startTimer(50);
} }
...@@ -67,12 +80,12 @@ void SpikeDisplayCanvas::beginAnimation() ...@@ -67,12 +80,12 @@ void SpikeDisplayCanvas::beginAnimation()
{ {
std::cout << "Beginning animation." << std::endl; std::cout << "Beginning animation." << std::endl;
displayBufferSize = displayBuffer->getNumSamples(); // displayBufferSize = displayBuffer->getNumSamples();
screenBuffer->clear(); // screenBuffer->clear();
//displayBufferIndex = 0; //displayBufferIndex = 0;
screenBufferIndex = 0; // screenBufferIndex = 0;
startCallbacks(); startCallbacks();
} }
...@@ -85,124 +98,41 @@ void SpikeDisplayCanvas::endAnimation() ...@@ -85,124 +98,41 @@ void SpikeDisplayCanvas::endAnimation()
void SpikeDisplayCanvas::update() void SpikeDisplayCanvas::update()
{ {
nChans = processor->getNumInputs(); // nChans = processor->getNumInputs();
sampleRate = processor->getSampleRate(); // sampleRate = processor->getSampleRate();
std::cout << "Setting num inputs on SpikeDisplayCanvas to " << nChans << std::endl; // std::cout << "Setting num inputs on SpikeDisplayCanvas to " << nChans << std::endl;
if (nChans < 200 && nChans > 0) // if (nChans < 200 && nChans > 0)
screenBuffer->setSize(nChans, 10000); // screenBuffer->setSize(nChans, 10000);
//sampleRate = processor->getSampleRate(); // //sampleRate = processor->getSampleRate();
screenBuffer->clear(); // screenBuffer->clear();
repaint(); repaint();
totalHeight = (plotHeight+yBuffer)*nChans + yBuffer; // totalHeight = (plotHeight+yBuffer)*nChans + yBuffer;
} }
void SpikeDisplayCanvas::setParameter(int param, float val) void SpikeDisplayCanvas::setParameter(int param, float val)
{ {
if (param == 0) // if (param == 0)
timebase = val; // timebase = val;
else // else
displayGain = val; // displayGain = val;
} }
void SpikeDisplayCanvas::refreshState() void SpikeDisplayCanvas::refreshState()
{ {
// called when the component's tab becomes visible again // called when the component's tab becomes visible again
displayBufferIndex = processor->getDisplayBufferIndex(); // displayBufferIndex = processor->getDisplayBufferIndex();
screenBufferIndex = 0; // screenBufferIndex = 0;
//resized(); //resized();
} }
void SpikeDisplayCanvas::updateScreenBuffer()
{
// copy new samples from the displayBuffer into the screenBuffer
int maxSamples = getWidth();
int index = processor->getDisplayBufferIndex();
//std::cout << index << screenBufferIndex << std::endl;
int nSamples = index - displayBufferIndex;
if (nSamples < 0)
{
nSamples = (displayBufferSize - displayBufferIndex) + index;
}
float ratio = sampleRate * timebase / float(getWidth());
// this number is crucial:
int valuesNeeded = (int) float(nSamples) / ratio;
//lock->enterRead();
float subSampleOffset = 0.0;
int nextPos = (displayBufferIndex + 1) % displayBufferSize;
//int screenBufferPos;
if (valuesNeeded > 0 && valuesNeeded < 1000) {
int maxVal = screenBufferIndex + valuesNeeded;
int overflow = maxVal - maxSamples;
screenBuffer->clear(screenBufferIndex, valuesNeeded);
if (overflow > 0)
screenBuffer->clear(0, overflow);
for (int i = 0; i < valuesNeeded; i++)
{
float gain = 1.0;
float alpha = (float) subSampleOffset;
float invAlpha = 1.0f - alpha;
for (int channel = 0; channel < displayBuffer->getNumChannels(); channel++) {
screenBuffer->addFrom(channel,
screenBufferIndex,
*displayBuffer,
channel,
displayBufferIndex,
1,
invAlpha*gain*displayGain);
screenBuffer->addFrom(channel,
screenBufferIndex,
*displayBuffer,
channel,
nextPos,
1,
alpha*gain*displayGain);
}
subSampleOffset += ratio;
while (subSampleOffset >= 1.0)
{
if (++displayBufferIndex >= displayBufferSize)
displayBufferIndex = 0;
nextPos = (displayBufferIndex + 1) % displayBufferSize;
subSampleOffset -= 1.0;
}
screenBufferIndex++;
screenBufferIndex %= maxSamples;
}
} else {
//std::cout << "Skip." << std::endl;
}
}
void SpikeDisplayCanvas::canvasWasResized() void SpikeDisplayCanvas::canvasWasResized()
{ {
//std::cout << "Resized!" << std::endl; //std::cout << "Resized!" << std::endl;
...@@ -210,136 +140,35 @@ void SpikeDisplayCanvas::canvasWasResized() ...@@ -210,136 +140,35 @@ void SpikeDisplayCanvas::canvasWasResized()
void SpikeDisplayCanvas::renderOpenGL() void SpikeDisplayCanvas::renderOpenGL()
{ {
glClear(GL_COLOR_BUFFER_BIT); // clear buffers to preset values glClear(GL_COLOR_BUFFER_BIT); // clear buffers to preset values
std::cout<<"SpikeDisplayCanvas::renderOpenGL"<<std::endl;
//drawTicks();
updateScreenBuffer();
for (int i = 0; i < nChans; i++)
{
bool isSelected = false;
if (selectedChan == i)
isSelected = true;
if (checkBounds(i)) { // Get Spikes from the processor
setViewport(i); // Iterate through each spike, passing them individually to the appropriate plots and calling redraw before moving on to the next spike
//drawBorder(isSelected);
drawChannelInfo(i,isSelected);
drawWaveform(i,isSelected);
}
}
drawScrollBars();
//std::cout << "Render." << std::endl;
}
void SpikeDisplayCanvas::drawWaveform(int chan, bool isSelected)
{
// draw the screen buffer for a given channel
float w = float(getWidth());
glBegin(GL_LINE_STRIP);
for (float i = 0; i < float(getWidth()); i++)
{
glVertex2f(i/w,*screenBuffer->getSampleData(chan, int(i))+0.5);
}
glEnd();
glColor4f(1.0, 1.0, 0.1, 1.0);
glBegin(GL_LINE_STRIP);
glVertex2f(float(screenBufferIndex)/w,0);
glVertex2f(float(screenBufferIndex)/w,1);
glEnd();
}
void SpikeDisplayCanvas::drawTicks()
{
glViewport(0,0,getWidth(),getHeight()); //while(processor->getNextSpike(&spike))
//{
glColor4f(1.0f, 1.0f, 1.0f, 0.25f);
// Identify which plot the spike should go to
for (int i = 0; i < 10; i++)
{ // Distribute those spike to the appropriate plot object
if (i == 5)
glLineWidth(3.0); SpikeObject tmpSpike;
else if (i == 1 || i == 3 || i == 7 || i == 9) for (int i=0; i<plots.size(); i++){
glLineWidth(2.0); generateSimulatedSpike(&tmpSpike, 0, 100);
else plots[i].processSpikeObject(tmpSpike);
glLineWidth(1.0); plots[i].redraw();
glBegin(GL_LINE_STRIP);
glVertex2f(0.1*i,0);
glVertex2f(0.1*i,1);
glEnd();
} }
}
bool SpikeDisplayCanvas::checkBounds(int chan)
{
bool isVisible;
int lowerBound = (chan+1)*(plotHeight+yBuffer);
int upperBound = chan*(plotHeight+yBuffer);
if (getScrollAmount() < lowerBound && getScrollAmount() + getHeight() > upperBound)
isVisible = true;
else
isVisible = false;
return isVisible; //}
} drawScrollBars();
void SpikeDisplayCanvas::setViewport(int chan)
{
glViewport(xBuffer,
getHeight()-(chan+1)*(plotHeight+yBuffer)+getScrollAmount(),
getWidth()-2*xBuffer,
plotHeight);
}
void SpikeDisplayCanvas::drawBorder(bool isSelected)
{
float alpha = 0.5f;
if (isSelected)
alpha = 1.0f;
glColor4f(0.0f, 0.0f, 0.0f, alpha);
glBegin(GL_LINE_STRIP);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glVertex2f(0.0f, 0.0f);
glEnd();
} }
void SpikeDisplayCanvas::drawChannelInfo(int chan, bool isSelected) void SpikeDisplayCanvas::drawTicks()
{ {
float alpha = 0.5f;
if (isSelected)
alpha = 1.0f;
glColor4f(0.0f,0.0f,0.0f,alpha);
glRasterPos2f(5.0f/getWidth(),0.9);
String s = "";//String("Channel ");
s += (chan+1);
getFont(String("cpmono-bold"))->FaceSize(35);
getFont(String("cpmono-bold"))->Render(s);
} }
int SpikeDisplayCanvas::getTotalHeight() int SpikeDisplayCanvas::getTotalHeight()
...@@ -351,17 +180,17 @@ int SpikeDisplayCanvas::getTotalHeight() ...@@ -351,17 +180,17 @@ int SpikeDisplayCanvas::getTotalHeight()
void SpikeDisplayCanvas::mouseDownInCanvas(const MouseEvent& e) void SpikeDisplayCanvas::mouseDownInCanvas(const MouseEvent& e)
{ {
Point<int> pos = e.getPosition(); // Point<int> pos = e.getPosition();
int xcoord = pos.getX(); // int xcoord = pos.getX();
if (xcoord < getWidth()-getScrollBarWidth()) // if (xcoord < getWidth()-getScrollBarWidth())
{ // {
int chan = (e.getMouseDownY() + getScrollAmount())/(yBuffer+plotHeight); // int chan = (e.getMouseDownY() + getScrollAmount())/(yBuffer+plotHeight);
selectedChan = chan; // selectedChan = chan;
repaint(); // repaint();
} // }
} }
......
...@@ -24,8 +24,15 @@ ...@@ -24,8 +24,15 @@
#define SPIKEDISPLAYCANVAS_H_ #define SPIKEDISPLAYCANVAS_H_
#include "../../../JuceLibraryCode/JuceHeader.h" #include "../../../JuceLibraryCode/JuceHeader.h"
#include "../SpikeDisplayNode.h" #include "../SpikeDisplayNode.h"
#include "SpikePlotting/ElectrodePlot.h"
#include "SpikeObject.h"
#include "Visualizer.h" #include "Visualizer.h"
#include <vector>
#define MAX_NUMBER_OF_SPIKE_SOURCES = 128;
class SpikeDisplayNode; class SpikeDisplayNode;
...@@ -51,36 +58,42 @@ private: ...@@ -51,36 +58,42 @@ private:
int xBuffer, yBuffer; int xBuffer, yBuffer;
float sampleRate; bool plotsInitialized;
float timebase;
float displayGain;
bool newSpike;
SpikeObject spike;
SpikeDisplayNode* processor; SpikeDisplayNode* processor;
AudioSampleBuffer* displayBuffer; std::vector<ElectrodePlot> plots;
ScopedPointer<AudioSampleBuffer> screenBuffer; // AudioSampleBuffer* displayBuffer;
MidiBuffer* eventBuffer; // ScopedPointer<AudioSampleBuffer> screenBuffer;
// MidiBuffer* eventBuffer;
void setViewport(int chan); // void setViewport(int chan);
void drawBorder(bool isSelected); // void drawBorder(bool isSelected);
void drawChannelInfo(int chan, bool isSelected); // void drawChannelInfo(int chan, bool isSelected);
void drawWaveform(int chan, bool isSelected); // void drawWaveform(int chan, bool isSelected);
void drawTicks(); void drawTicks();
bool checkBounds(int chan); // bool checkBounds(int chan);
void updateScreenBuffer(); // void updateScreenBuffer();
int screenBufferIndex; // int screenBufferIndex;
int displayBufferIndex; // int displayBufferIndex;
int displayBufferSize; // int displayBufferSize;
int nChans, plotHeight, totalHeight; int totalHeight;
int selectedChan; // int selectedChan;
int getTotalHeight(); int getTotalHeight();
void canvasWasResized(); int nSources;
void mouseDownInCanvas(const MouseEvent& e); int nChannels[MAX_NUMBER_OF_SPIKE_CHANNELS];
void initializeSpikePlots();
void canvasWasResized();
void mouseDownInCanvas(const MouseEvent& e);
// void mouseDrag(const MouseEvent& e); // void mouseDrag(const MouseEvent& e);
// void mouseMove(const MouseEvent& e); // void mouseMove(const MouseEvent& e);
// void mouseUp(const MouseEvent& e); // void mouseUp(const MouseEvent& e);
......
...@@ -25,9 +25,8 @@ ...@@ -25,9 +25,8 @@
#include <iostream> #include <iostream>
#include "memory.h" #include "memory.h"
#include <stdlib.h> #include <stdlib.h>
#include "time.h"
// Simple method for serializing a SpikeObject into a string of bytes // Simple method for serializing a SpikeObject into a string of bytes
bool packSpike(SpikeObject *s, char* buffer, int bufferSize){ bool packSpike(SpikeObject *s, char* buffer, int bufferSize){
...@@ -135,11 +134,21 @@ void makeBufferValid(char *buffer, int bufferSize){ ...@@ -135,11 +134,21 @@ void makeBufferValid(char *buffer, int bufferSize){
void generateSimulatedSpike(SpikeObject *s, uint64_t timestamp, int noise) void generateSimulatedSpike(SpikeObject *s, uint64_t timestamp, int noise)
{ {
uint16_t trace[32] = std::cout<<"generateSimulatedSpike()"<<std::endl;
{ 1880, 1900, 1940, 2040, 2290, 2790, 3475, 3995, 4110, 3890,
3505, 3090, 2720, 2410, 2155, 1945, 1775, 1635, 1520, 1420, uint16_t trace[][32] =
1340, 1265, 1205, 1155, 1115, 1080, 1050, 1034, 1010, 1001, {
1000, 1000}; { 880, 900, 940, 1040, 1290, 1790, 2475, 2995, 3110, 2890,
2505, 2090, 1720, 1410, 1155, 945, 775, 635, 520, 420,
340, 265, 205, 155, 115, 80, 50, 34, 10, 34, 50, 80},
{ 1040, 1090, 1190, 1350, 1600, 1960, 2380, 2790, 3080, 3140,
2910, 2430, 1810, 1180, 680, 380, 270, 320, 460, 630,
770, 870, 940, 970, 990, 1000, 1000, 1000, 1000, 1000, 1000, 1000},
{ 1000, 1000, 1000, 1000, 1000, 1040, 1140, 1440, 2040, 2940,
3800, 4140, 3880, 3680, 1640, 920, 520, 300, 140, 040,
20, 20, 40, 100, 260, 500, 740, 900, 960, 1000, 1000, 1000}
};
// uint16_t sineSpikeWave[32] = // uint16_t sineSpikeWave[32] =
// { 78, 90, 101, 111, 120, 126, 129, 130, // { 78, 90, 101, 111, 120, 126, 129, 130,
...@@ -151,26 +160,20 @@ void generateSimulatedSpike(SpikeObject *s, uint64_t timestamp, int noise) ...@@ -151,26 +160,20 @@ void generateSimulatedSpike(SpikeObject *s, uint64_t timestamp, int noise)
uint16_t gain = 5; uint16_t gain = 5;
// if(sineWave){
// memcpy(trace, sineSpikeWave, 64);
// gain = 100;
// }
// else{
// memcpy(trace, realSpikeWave, 64);
// gain = 5;
// }
s->timestamp = timestamp; s->timestamp = timestamp;
s->source = 0; s->source = 0;
s->nChannels = 4; s->nChannels = 4;
s->nSamples = 32; s->nSamples = 32;
int idx=0; int idx=0;
int waveType = rand()%3; // Pick one of the three predefined waveshapes to generate
double waveScaling = (double)(rand()%5 + 5) / 10.00; // Scale the wave between 50% and 150%
int shift = 1000;
for (int i=0; i<4; i++) for (int i=0; i<4; i++)
{ {
s->gain[i] = gain; s->gain[i] = gain;
s->threshold[i] = 12000; s->threshold[i] = 8000;
for (int j=0; j<32; j++){ for (int j=0; j<32; j++){
...@@ -179,10 +182,24 @@ void generateSimulatedSpike(SpikeObject *s, uint64_t timestamp, int noise) ...@@ -179,10 +182,24 @@ void generateSimulatedSpike(SpikeObject *s, uint64_t timestamp, int noise)
n = rand() % noise - noise/2; n = rand() % noise - noise/2;
} }
s->data[idx] = (trace[j] + n) * gain; s->data[idx] = (trace[waveType][j] + n) * gain * waveScaling + shift;
idx = idx+1; idx = idx+1;
} }
} }
}
void generateEmptySpike(SpikeObject *s, int nChannels){
/*
std::cout<<"generateEmptySpike()"<<std::endl;
s->timestamp = 0;
s->source = 0;
s->nChannels = nChannels;
s->nSamples = 32;
memset(&(s->gain), 0, 2*nChannels);
memset(&(s->threshold), 0, 2*nChannels);
memset(&(s->data), 0, 2*nChannels*32);
*/
} }
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
*/ */
#ifndef SPIKEOBJECT_H_OPENEPHYS #ifndef SPIKEOBJECT_H_
#define SPIKEOBJECT_H_OPENEPHYS #define SPIKEOBJECT_H_
#include <stdint.h> #include <stdint.h>
...@@ -38,7 +38,8 @@ struct SpikeObject{ ...@@ -38,7 +38,8 @@ struct SpikeObject{
uint16_t nSamples; uint16_t nSamples;
uint16_t data[MAX_NUMBER_OF_SPIKE_CHANNELS * MAX_NUMBER_OF_SPIKE_CHANNEL_SAMPLES]; uint16_t data[MAX_NUMBER_OF_SPIKE_CHANNELS * MAX_NUMBER_OF_SPIKE_CHANNEL_SAMPLES];
uint16_t gain[MAX_NUMBER_OF_SPIKE_CHANNELS]; uint16_t gain[MAX_NUMBER_OF_SPIKE_CHANNELS];
uint16_t threshold[MAX_NUMBER_OF_SPIKE_CHANNELS]; uint16_t threshold[MAX_NUMBER_OF_SPIKE_CHANNELS];
}; };
/* /*
...@@ -76,5 +77,8 @@ void generateSimulatedSpike(SpikeObject *s, uint64_t timestamp, int noise); ...@@ -76,5 +77,8 @@ void generateSimulatedSpike(SpikeObject *s, uint64_t timestamp, int noise);
// Define the << operator for the SpikeObject // Define the << operator for the SpikeObject
// std::ostream& operator<<(std::ostream &strm, const SpikeObject s); // std::ostream& operator<<(std::ostream &strm, const SpikeObject s);
// Helper function for zeroing out a spike object with a specified number of channels
void generateEmptySpike(SpikeObject *s, int nChannels);
#endif //SPIKEOBJECT_H_OPENEPHYS #endif //SPIKEOBJECT_H_
\ No newline at end of file \ No newline at end of file
#include "BaseUIElement.h" #include "BaseUIElement.h"
BaseUIElement::BaseUIElement(): BaseUIElement::BaseUIElement():
xpos(0), ypos(0), width(100), height(100), enabled(true), padding(0) xpos(0), ypos(0), width(100), height(100), enabled(true), padding(0)
{ {
elementName = (char*) "BaseUIElement"; elementName = (char*) "BaseUIElement";
clearNextDraw = false; clearNextDraw = false;
} }
BaseUIElement::BaseUIElement(int x, int y, double w, double h): BaseUIElement::BaseUIElement(int x, int y, double w, double h):
enabled(true), padding(0) enabled(true), padding(0)
{ {
xpos = x+padding; xpos = x+padding;
ypos = y+padding; ypos = y+padding;
...@@ -18,7 +18,7 @@ enabled(true), padding(0) ...@@ -18,7 +18,7 @@ enabled(true), padding(0)
clearNextDraw = false; clearNextDraw = false;
} }
BaseUIElement::BaseUIElement(int x, int y, double w, double h, int p): BaseUIElement::BaseUIElement(int x, int y, double w, double h, int p):
enabled(true), padding(0) enabled(true), padding(0)
{ {
xpos = x+padding; xpos = x+padding;
ypos = y+padding; ypos = y+padding;
...@@ -32,13 +32,12 @@ void BaseUIElement::redraw(){ ...@@ -32,13 +32,12 @@ void BaseUIElement::redraw(){
// std::cout<<"BaseUIElement::redraw(), Position:"<<xpos<<","<<ypos<<" : "<<width<<","<<height<<std::endl; // std::cout<<"BaseUIElement::redraw(), Position:"<<xpos<<","<<ypos<<" : "<<width<<","<<height<<std::endl;
setGlViewport(); setGlViewport();
if (clearNextDraw){ if (clearNextDraw || !clearNextDraw){
clearNextDraw = false; clearNextDraw = false;
glColor3f(0.0, 0.0, 0.0); glColor3f(0.0, 0.0, 0.0);
glRecti(-1,-1,1,1); glRecti(-1,-1,1,1);
// glutSwapBuffers();
glRecti(-1,-1,1,1);
//glutSwapBuffers();
} }
} }
void BaseUIElement::drawElementEdges(){ void BaseUIElement::drawElementEdges(){
......
#ifndef BaseUIElement_H_ #ifndef BASEUIELEMENT_H_
#define BaseUIElement_H_ #define BASEUIELEMENT_H_
#include "PlotUtils.h" #include "PlotUtils.h"
......
#include "ElectrodePlot.h" #include "ElectrodePlot.h"
#include "../SpikeObject.h"
ElectrodePlot::ElectrodePlot(): ElectrodePlot::ElectrodePlot():
BaseUIElement(), titleHeight(15), enableTitle(true), limitsChanged(true) BaseUIElement(), titleHeight(0), enableTitle(true), limitsChanged(true)
{ {
plotTitle = (char*) "Electrode Plot"; plotTitle = (char*) "Electrode Plot";
} }
ElectrodePlot::ElectrodePlot(int x, int y, int w, int h, char *n): ElectrodePlot::ElectrodePlot(int x, int y, int w, int h, char *n):
BaseUIElement(x,y,w,h,1), titleHeight(15), enableTitle(true), limitsChanged(true) BaseUIElement(x,y,w,h,1), titleHeight(0), enableTitle(true), limitsChanged(true)
{ {
plotTitle = n; plotTitle = n;
titleBox = TitleBox(x, y+h-titleHeight-3, w, titleHeight+3, plotTitle); titleBox = TitleBox(x, y+h-titleHeight-3, w, titleHeight+3, plotTitle);
initAxes();
} }
ElectrodePlot::~ElectrodePlot(){
}
// Each plot needs to update its children axes when its redraw gets called. // Each plot needs to update its children axes when its redraw gets called.
// it also needs to call the parent plot when children axes get added it // it also needs to call the parent plot when children axes get added it
...@@ -22,47 +27,18 @@ ElectrodePlot::ElectrodePlot(int x, int y, int w, int h, char *n): ...@@ -22,47 +27,18 @@ ElectrodePlot::ElectrodePlot(int x, int y, int w, int h, char *n):
// the right direction // the right direction
void ElectrodePlot::redraw(){ void ElectrodePlot::redraw(){
// std::cout<<"ElectrodePlot() starting drawing"<<std::endl; std::cout<<"ElectrodePlot() starting drawing"<<std::endl;\
BaseUIElement::clearNextDraw = true;
BaseUIElement::redraw(); BaseUIElement::redraw();
// SpikeObject tempSpike; axes.redraw();
// std::list<GenericAxes>::iterator i;
// bool axesDrawnOnce = false;
// while(tetSource.getNextSpike(&tempSpike)){
// axesDrawnOnce = true;
// for (i=axesList.begin(); i!= axesList.end(); ++i){
// i->updateSpikeData(tempSpike);
// if (limitsChanged){
// int n = i->getType();
// if (n>=WAVE1 && n<=WAVE4)
// i->setYLims(limits[n][0], limits[n][1]);
// else if( n>=PROJ1x2 && n<=PROJ3x4){
// int d1, d2;
// n2ProjIdx(i->getType(), &d1, &d2);
// i->setXLims(limits[d1][0], limits[d1][1]);
// i->setYLims(limits[d2][0], limits[d2][1]);
// }
// }
// i->redraw();
// }
// if (limitsChanged)
// limitsChanged = false;
// }
// if (!axesDrawnOnce)
// for (i= axesList.begin(); i!=axesList.end(); ++i)
// i->redraw();
// titleBox.redraw();
// BaseUIElement::drawElementEdges();
// // std::cout<<"ElectrodePlot() Done drawing"<<std::endl;
} }
// This would normally happen for collection of axes but an electrode plot doesn't have a collection instead its a single axes
void ElectrodePlot::processSpikeObject(SpikeObject s){
std::cout<<"ElectrdePlot::processSpikeObject()"<<std::endl;
axes.updateSpikeData(s);
}
void ElectrodePlot::setTitle(char *n){ void ElectrodePlot::setTitle(char *n){
plotTitle = n; plotTitle = n;
} }
...@@ -70,7 +46,7 @@ void ElectrodePlot::setTitle(char *n){ ...@@ -70,7 +46,7 @@ void ElectrodePlot::setTitle(char *n){
void ElectrodePlot::setEnabled(bool e){ void ElectrodePlot::setEnabled(bool e){
BaseUIElement::enabled = e; BaseUIElement::enabled = e;
axes->setEnabled(e); axes.setEnabled(e);
} }
bool ElectrodePlot::getEnabled(){ bool ElectrodePlot::getEnabled(){
...@@ -88,13 +64,11 @@ void ElectrodePlot::initAxes(){ ...@@ -88,13 +64,11 @@ void ElectrodePlot::initAxes(){
double axesHeight = (BaseUIElement::height - titleHeight); double axesHeight = (BaseUIElement::height - titleHeight);
WaveAxes tempAx = WaveAxes(minX, minY, axesWidth, axesHeight, 0); axes = WaveAxes(minX, minY, axesWidth, axesHeight, 0);
tempAx.setEnabled(false); //axes.setEnabled(false);
tempAx.setYLims(-1*pow(2,11), pow(2,14)); axes.setYLims(-1*pow(2,11), pow(2,14)*1.6);
tempAx.setWaveformColor(1.0, 1.0, 1.0); axes.setWaveformColor(1.0, 1.0, 1.0);
axes = &tempAx;
} }
...@@ -106,7 +80,7 @@ void ElectrodePlot::setPosition(int x, int y, double w, double h){ ...@@ -106,7 +80,7 @@ void ElectrodePlot::setPosition(int x, int y, double w, double h){
double axesWidth = BaseUIElement::width; double axesWidth = BaseUIElement::width;
double axesHeight = BaseUIElement::height - titleHeight; double axesHeight = BaseUIElement::height - titleHeight;
axes->setPosition(minX, minY, axesWidth, axesHeight); axes.setPosition(minX, minY, axesWidth, axesHeight);
titleBox.setPosition(x, y+h-titleHeight-3, w, titleHeight+3); titleBox.setPosition(x, y+h-titleHeight-3, w, titleHeight+3);
} }
...@@ -142,6 +116,10 @@ void ElectrodePlot::initLimits(){ ...@@ -142,6 +116,10 @@ void ElectrodePlot::initLimits(){
} }
void ElectrodePlot::getPreferredDimensions(double *w, double *h){
*w = 75;
*h = 75;
}
// void ElectrodePlot::mouseDown(int x, int y){ // void ElectrodePlot::mouseDown(int x, int y){
// // selectedAxesN = -1; // // selectedAxesN = -1;
...@@ -164,7 +142,7 @@ void ElectrodePlot::initLimits(){ ...@@ -164,7 +142,7 @@ void ElectrodePlot::initLimits(){
// // if (!hit) // // if (!hit)
// // selectedAxes = NULL; // // selectedAxes = NULL;
// // if (selectedAxes != NULL) // // if (selectedAxes != NULL)
// // std::cout<<"ElectrodePlot::mouseDown() hit:"<<selectedAxes<<" AxesType:"<<selectedAxes->getType()<<std::endl; // // std::cout<<"ElectrodePlot::mouseDown() hit:"<<selectedAxes<<" AxesType:"<<selectedaxes.getType()<<std::endl;
// // else // // else
// // std::cout<<"ElectrodePlot::mouseDown() NO HIT!"<<std::endl; // // std::cout<<"ElectrodePlot::mouseDown() NO HIT!"<<std::endl;
...@@ -173,7 +151,7 @@ void ElectrodePlot::initLimits(){ ...@@ -173,7 +151,7 @@ void ElectrodePlot::initLimits(){
// // if (selectedAxes == NULL || dx==0) // // if (selectedAxes == NULL || dx==0)
// // return; // // return;
// // // zoomAxes(selectedAxes->getType(), true, dx>0); // // // zoomAxes(selectedaxes.getType(), true, dx>0);
// // if (shift) // // if (shift)
// // zoomAxes(selectedAxesN, true, dx); // // zoomAxes(selectedAxesN, true, dx);
// // if (ctrl) // // if (ctrl)
......
...@@ -32,8 +32,8 @@ class ElectrodePlot : public BaseUIElement{ ...@@ -32,8 +32,8 @@ class ElectrodePlot : public BaseUIElement{
bool limitsChanged; bool limitsChanged;
double limits[1][2]; double limits[1][2];
WaveAxes *axes; WaveAxes axes;
// void zoomAxes(int n, bool xdim, int zoomval); // void zoomAxes(int n, bool xdim, int zoomval);
// void zoomProjection (int n, bool xdim, int zoomval); // void zoomProjection (int n, bool xdim, int zoomval);
...@@ -48,6 +48,7 @@ class ElectrodePlot : public BaseUIElement{ ...@@ -48,6 +48,7 @@ class ElectrodePlot : public BaseUIElement{
public: public:
ElectrodePlot(); ElectrodePlot();
ElectrodePlot(int x, int y,int w,int h, char *n); ElectrodePlot(int x, int y,int w,int h, char *n);
~ElectrodePlot();
void initAxes(); void initAxes();
void redraw(); void redraw();
...@@ -56,6 +57,8 @@ public: ...@@ -56,6 +57,8 @@ public:
bool getEnabled(); bool getEnabled();
void setPosition(int,int,double,double); void setPosition(int,int,double,double);
void getPreferredDimensions(double*, double*);
int getNumberOfAxes(); int getNumberOfAxes();
void clearOnNextDraw(bool c); void clearOnNextDraw(bool c);
void setTitleEnabled(bool e); void setTitleEnabled(bool e);
...@@ -66,6 +69,8 @@ public: ...@@ -66,6 +69,8 @@ public:
void mouseDragY(int dy, bool shift, bool ctr); void mouseDragY(int dy, bool shift, bool ctr);
bool processKeyEvent(SimpleKeyEvent k); bool processKeyEvent(SimpleKeyEvent k);
void processSpikeObject(SpikeObject s);
}; };
......
...@@ -9,7 +9,7 @@ GenericAxes::GenericAxes(): ...@@ -9,7 +9,7 @@ GenericAxes::GenericAxes():
ylims[0] = 0; ylims[0] = 0;
ylims[1] = 1; ylims[1] = 1;
BaseUIElement::elementName = (char*) "GenericAxes"; //BaseUIElement::elementName = (char*) "GenericAxes";
} }
GenericAxes::GenericAxes(int x, int y, double w, double h, int t): GenericAxes::GenericAxes(int x, int y, double w, double h, int t):
...@@ -17,19 +17,24 @@ GenericAxes::GenericAxes(int x, int y, double w, double h, int t): ...@@ -17,19 +17,24 @@ GenericAxes::GenericAxes(int x, int y, double w, double h, int t):
gotFirstSpike(false), gotFirstSpike(false),
resizedFlag(false) resizedFlag(false)
{ {
std::cout<<"Generic Axes!!!!!"<<std::endl;
std::cout<<"gotFirstSpike:"<<gotFirstSpike<<std::endl;
// if (t<WAVE1 || t>PROJ3x4) // if (t<WAVE1 || t>PROJ3x4)
//("Invalid Axes type specified"); //("Invalid Axes type specified");
type = t; type = t;
BaseUIElement::elementName = (char*) "GenericAxes"; // BaseUIElement::elementName = (char*) "GenericAxes";
} }
void GenericAxes::updateSpikeData(SpikeObject newSpike){ void GenericAxes::updateSpikeData(SpikeObject newSpike){
std::cout<<"GenericAxes::updateSpikeData() ";
if (!gotFirstSpike){ if (!gotFirstSpike){
gotFirstSpike = true; gotFirstSpike = true;
//std::cout<<"GenericAxes::updateSpikeData() got first spike"<<std::endl;
} }
s = newSpike; s = newSpike;
std::cout<<"got spike with nSamples:"<<s.nSamples<<std::endl;
} }
// void GenericAxes::redraw(){ // void GenericAxes::redraw(){
......
...@@ -26,6 +26,8 @@ protected: ...@@ -26,6 +26,8 @@ protected:
bool resizedFlag; bool resizedFlag;
int type; int type;
virtual void plot(){}
public: public:
GenericAxes(); GenericAxes();
...@@ -33,7 +35,6 @@ public: ...@@ -33,7 +35,6 @@ public:
void updateSpikeData(SpikeObject s); void updateSpikeData(SpikeObject s);
virtual void plot(){}
virtual void redraw(){} virtual void redraw(){}
......
...@@ -37,14 +37,19 @@ WaveAxes::WaveAxes(int x, int y, double w, double h, int t): ...@@ -37,14 +37,19 @@ WaveAxes::WaveAxes(int x, int y, double w, double h, int t):
BaseUIElement::elementName = (char*) "WaveAxes"; BaseUIElement::elementName = (char*) "WaveAxes";
} }
void WaveAxes::updateSpikeData(SpikeObject newSpike){ void WaveAxes::updateSpikeData(SpikeObject newSpike){
std::cout<<"WaveAxes::updateSpikeData()"<<std::endl;
GenericAxes::updateSpikeData(newSpike); GenericAxes::updateSpikeData(newSpike);
} }
void WaveAxes::redraw(){ void WaveAxes::redraw(){
BaseUIElement::redraw(); BaseUIElement::redraw();
if (BaseUIElement::enabled)
plot(); plot();
BaseUIElement::drawElementEdges(); BaseUIElement::drawElementEdges();
} }
...@@ -52,28 +57,18 @@ void WaveAxes::redraw(){ ...@@ -52,28 +57,18 @@ void WaveAxes::redraw(){
void WaveAxes::plot(){ void WaveAxes::plot(){
int chan = 0; int chan = 0;
// If no spikes have been received then don't plot anything
if (!gotFirstSpike) if (!gotFirstSpike)
{ {
std::cout<<"\tWaiting for the first spike"<<std::endl; std::cout<<"\tWaiting for the first spike"<<std::endl;
return; return;
} }
if (s.nSamples>1024) // Set the plotting range for the current axes the xlims member is ignored as the xdims are 0->number of samples per waveform minus one
return;
// Set the plotting range for the current axes
// the xlims member is ignored as the xdims are 0->number of samples per waveform minus one
// so the line goes all the way to the edges ydims are specified by the ylims vector // so the line goes all the way to the edges ydims are specified by the ylims vector
setViewportRange(0, ylims[0], s.nSamples-1, ylims[1]); setViewportRange(0, ylims[0], s.nSamples-1, ylims[1]);
// Are new waves getting overlayed on top of old waves? If not clear the display // draw the grid lines for the waveforms?
if(!overlay){
glColor3f(0.0,0.0,0.0);
glRectd(0, ylims[0], s.nSamples, ylims[1]);
}
// Are we drawing the grid lines for the waveforms?
if(drawGrid) if(drawGrid)
drawWaveformGrid(s.threshold[chan], s.gain[chan]); drawWaveformGrid(s.threshold[chan], s.gain[chan]);
...@@ -86,37 +81,21 @@ void WaveAxes::plot(){ ...@@ -86,37 +81,21 @@ void WaveAxes::plot(){
// if drawWaveformPoints is set to false then force the drawing of the line, _SOMETHING_ must be drawn // if drawWaveformPoints is set to false then force the drawing of the line, _SOMETHING_ must be drawn
glColor3fv(waveColor); glColor3fv(waveColor);
//if drawWaveformLine and drawWaveformPoints are both set glLineWidth(1);
if(drawWaveformLine){ glBegin( GL_LINE_STRIP );
glLineWidth(1);
glBegin( GL_LINE_STRIP ); int dSamples = 1;
for (int i=0; i<s.nSamples; i++) for (int i=0; i<s.nSamples; i++)
{ {
glVertex2f(x, s.data[sampIdx]); //std::cout<<"\t"<<s.data[sampIdx];
sampIdx +=4; glVertex2f(x, s.data[sampIdx]);
x +=dx; sampIdx += dSamples;
} x +=dx;
glEnd();
} }
glEnd();
/* // std::cout<<std::endl;
//if drawWaveformLine and drawWaveformPoints are both set false then draw the points
//this ensures that something is always drawn
if(drawWaveformPoints || !drawWaveformLine){
x = 0;
sampIdx = chan;
glColor3fv(pointColor);
glPointSize(1);
glBegin( GL_POINTS );
for (int i=0; i<s.nSamples; i++)
{
glVertex2f(x, s.data[sampIdx]);
sampIdx +=4;
x +=dx;
}
glEnd();
} */
// Draw the threshold line and label // Draw the threshold line and label
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
class WaveAxes: public GenericAxes{ class WaveAxes: public GenericAxes{
SpikeObject s;
GLfloat waveColor[3]; GLfloat waveColor[3];
GLfloat thresholdColor[3]; GLfloat thresholdColor[3];
GLfloat gridColor[3]; GLfloat gridColor[3];
...@@ -23,6 +22,10 @@ class WaveAxes: public GenericAxes{ ...@@ -23,6 +22,10 @@ class WaveAxes: public GenericAxes{
void drawWaveformGrid(int thold, int gain); void drawWaveformGrid(int thold, int gain);
protected:
void plot();
public: public:
WaveAxes(); WaveAxes();
WaveAxes(int x, int y, double w, double h, int t); WaveAxes(int x, int y, double w, double h, int t);
...@@ -34,7 +37,6 @@ public: ...@@ -34,7 +37,6 @@ public:
void setGridColor(GLfloat, GLfloat, GLfloat); void setGridColor(GLfloat, GLfloat, GLfloat);
void redraw(); void redraw();
void plot();
bool drawWaveformLine; bool drawWaveformLine;
bool drawWaveformPoints; bool drawWaveformPoints;
......
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