Skip to content
Snippets Groups Projects
Commit 0d10f898 authored by Josh Siegle's avatar Josh Siegle
Browse files

Merge branch 'master' of https://github.com/open-ephys/GUI

parents 23985030 cdab7635
No related branches found
No related tags found
No related merge requests found
......@@ -129,7 +129,7 @@ void AudioNode::setParameter (int parameterIndex, float newValue)
if (parameterIndex == 1)
{
// volume level
volume = newValue*0.00001f;
volume = newValue*0.1f;
} else if (parameterIndex == 100)
{
......@@ -160,7 +160,7 @@ void AudioNode::process(AudioSampleBuffer &buffer,
MidiBuffer &midiMessages,
int& nSamples)
{
float gain;
//std::cout << "Audio node sample count: " << nSamples << std::endl; ///buffer.getNumSamples() << std::endl;
// clear the left and right channels
......@@ -174,13 +174,14 @@ void AudioNode::process(AudioSampleBuffer &buffer,
if (channelPointers[i-2]->isMonitored)
{
gain=volume/( float(0x7fff) * channelPointers[i-2]->bitVolts );
buffer.addFrom(0, // destination channel
0, // destination start sample
buffer, // source
i, // source channel
0, // source start sample
buffer.getNumSamples(), // number of samples
volume // gain to apply
gain // gain to apply
);
buffer.addFrom(1, // destination channel
......@@ -189,7 +190,7 @@ void AudioNode::process(AudioSampleBuffer &buffer,
i, // source channel
0, // source start sample
buffer.getNumSamples(), // number of samples
volume // gain to apply
gain // gain to apply
);
}
......
......@@ -24,13 +24,9 @@
#include "FileReaderThread.h"
FileReaderThread::FileReaderThread(SourceNode* sn) : DataThread(sn)
FileReaderThread::FileReaderThread(SourceNode* sn) :
DataThread(sn), lengthOfInputFile(0), bufferSize(0)
{
//File file = File("./data_stream_16ch");
//input = file.createInputStream();
bufferSize = 1600;
// FileChooser chooseFileReaderFile ("Please select the file you want to load...",
// File::getSpecialLocation (File::userHomeDirectory),
// "*");
......@@ -42,33 +38,48 @@ FileReaderThread::FileReaderThread(SourceNode* sn) : DataThread(sn)
// input = fopen(fileName.String::toCString(), "r");
// }
// FIXME stop hard-coding `path' once DataThread gives us a proper
// mechanism for accepting arguments (the above commented-out code
// is a layering violation that's best avoided).
#if JUCE_MAC
input = fopen("/Users/Josh/Programming/open-ephys/GUI/Builds/Linux/build/data_stream_16ch_2", "r");
const char *path = "/Users/Josh/Programming/open-ephys/GUI/Builds/Linux/build/data_stream_16ch_2";
#else
input = fopen("./data_stream_16ch_2","r");
const char *path = "./data_stream_16ch_2";
#endif
input = fopen(path, "r");
// Avoid a segfault if crock above fails.
if (!input) {
std::cout << "Can't find data file "
<< '"' << path << "\", "
<< "either make sure you're Josh on OS X, "
<< "or run open-ephys from the build directory on Linux."
<< std::endl;
return;
}
fseek(input, 0, SEEK_END);
lengthOfInputFile = ftell(input);
rewind(input);
bufferSize = 1600;
dataBuffer = new DataBuffer(16, bufferSize*3);
eventCode = 0;
eventCode = 0;
std::cout << "File Reader Thread initialized." << std::endl;
}
FileReaderThread::~FileReaderThread() {
//deleteAndZero(input);
if (input)
fclose(input);
}
bool FileReaderThread::foundInputSource()
{
return true;
return input != 0;
}
int FileReaderThread::getNumChannels()
......@@ -88,10 +99,11 @@ float FileReaderThread::getBitVolts()
bool FileReaderThread::startAcquisition()
{
startThread();
if (!input)
return false;
startThread();
return true;
}
bool FileReaderThread::stopAcquisition()
......@@ -100,7 +112,7 @@ bool FileReaderThread::stopAcquisition()
if (isThreadRunning()) {
signalThreadShouldExit();
}
return true;
......@@ -108,7 +120,8 @@ bool FileReaderThread::stopAcquisition()
bool FileReaderThread::updateBuffer()
{
if (!input)
return false;
if (dataBuffer->getNumSamples() < bufferSize)
{
// // std::cout << dataBuffer->getNumSamples() << std::endl;
......@@ -137,7 +150,7 @@ bool FileReaderThread::updateBuffer()
}
} else {
wait(50); // pause for 50 ms to decrease sample rate
......
......@@ -41,7 +41,7 @@ class SourceNode;
Has issues with setting the correct sampling rate.
@see DataThread, FileReader
@see DataThread
*/
......@@ -60,13 +60,7 @@ public:
float getBitVolts();
private:
int samplesPerBlock;
int lengthOfInputFile;
int playHead;
FILE* input;
float thisSample[16];
......
......@@ -39,7 +39,7 @@ FilterNode::FilterNode()
parameters.add(Parameter("low cut",lowCutValues, 1, 0));
Array<var> highCutValues;
highCutValues.add(12.0f);
highCutValues.add(1000.0f);
highCutValues.add(3000.0f);
highCutValues.add(6000.0f);
highCutValues.add(9000.0f);
......@@ -140,9 +140,9 @@ void FilterNode::updateSettings()
p1.setValue(4.0f, n);
Parameter& p2 = parameters.getReference(1);
p2.setValue(12.0f, n);
p2.setValue(1000.0f, n);
setFilterParameters(4.0f, 12.0f, n);
setFilterParameters(4.0f, 1000.0f, n);
}
}
......
......@@ -49,7 +49,7 @@
#include "../UI/UIComponent.h"
#include "../UI/EditorViewport.h"
ProcessorGraph::ProcessorGraph() : currentNodeId(100)
ProcessorGraph::ProcessorGraph() : currentNodeId(100)
{
// The ProcessorGraph will always have 0 inputs (all content is generated within graph)
......@@ -70,7 +70,7 @@ void ProcessorGraph::createDefaultNodes()
{
// add output node -- sends output to the audio card
AudioProcessorGraph::AudioGraphIOProcessor* on =
AudioProcessorGraph::AudioGraphIOProcessor* on =
new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode);
// add record node -- sends output to disk
......@@ -92,10 +92,10 @@ void ProcessorGraph::createDefaultNodes()
// connect audio subnetwork
for (int n = 0; n < 2; n++) {
addConnection(AUDIO_NODE_ID, n,
RESAMPLING_NODE_ID, n);
addConnection(RESAMPLING_NODE_ID, n,
OUTPUT_NODE_ID, n);
......@@ -105,12 +105,12 @@ void ProcessorGraph::createDefaultNodes()
RESAMPLING_NODE_ID, midiChannelIndex);
std::cout << "Default nodes created." << std::endl;
}
void* ProcessorGraph::createNewProcessor(String& description)//,
// GenericProcessor* source,
// GenericProcessor* dest)
// GenericProcessor* dest)
{
GenericProcessor* processor = createProcessorFromDescription(description);
......@@ -121,7 +121,7 @@ void* ProcessorGraph::createNewProcessor(String& description)//,
processor->setNodeId(id); // identifier within processor graph
std::cout << " Adding node to graph with ID number " << id << std::endl;
processor->setUIComponent(getUIComponent()); // give access to important pointers
addNode(processor,id); // have to add it so it can be deleted by the graph
......@@ -142,12 +142,12 @@ void ProcessorGraph::clearSignalChain()
int n = 0;
while (getNumNodes() > 4)
while (getNumNodes() > 4)
{
Node* node = getNode(n);
int nodeId = node->nodeId;
if (nodeId != OUTPUT_NODE_ID &&
if (nodeId != OUTPUT_NODE_ID &&
nodeId != AUDIO_NODE_ID &&
nodeId != RECORD_NODE_ID &&
nodeId != RESAMPLING_NODE_ID)
......@@ -172,7 +172,7 @@ void ProcessorGraph::changeListenerCallback(ChangeBroadcaster* source)
int nodeId = node->nodeId;
if (nodeId != OUTPUT_NODE_ID &&
if (nodeId != OUTPUT_NODE_ID &&
nodeId != AUDIO_NODE_ID &&
nodeId != RECORD_NODE_ID &&
nodeId != RESAMPLING_NODE_ID)
......@@ -180,7 +180,7 @@ void ProcessorGraph::changeListenerCallback(ChangeBroadcaster* source)
GenericProcessor* p =(GenericProcessor*) node->getProcessor();
GenericEditor* e = (GenericEditor*) p->getEditor();
e->refreshColors();
}
}
}
}
......@@ -196,7 +196,7 @@ void ProcessorGraph::clearConnections()
if (connection->destNodeId == RESAMPLING_NODE_ID ||
connection->destNodeId == OUTPUT_NODE_ID)
{
; // leave it
; // leave it
} else {
removeConnection(i);
}
......@@ -268,23 +268,23 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
getAudioNode()->addInputChannel(source, chan);
// std::cout << "Connecting to audio channel: " <<
// std::cout << "Connecting to audio channel: " <<
// getAudioNode()->getNextChannel(false) << std::endl;
//getAudioNode()->enableCurrentChannel(source->audioStatus(chan));
addConnection(source->getNodeId(), // sourceNodeID
chan, // sourceNodeChannelIndex
AUDIO_NODE_ID, // destNodeID
getAudioNode()->getNextChannel(true)); // destNodeChannelIndex
// add 2 to account for 2 output channels
//std::cout << getAudioNode()->getNextChannel(false) << " ";
getRecordNode()->addInputChannel(source, chan);
// std::cout << "Connecting to record channel: " <<
// std::cout << "Connecting to record channel: " <<
// getRecordNode()->getNextChannel(false) << std::endl;
......@@ -292,7 +292,7 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
chan, // sourceNodeChannelIndex
RECORD_NODE_ID, // destNodeID
getRecordNode()->getNextChannel(true)); // destNodeChannelIndex
}
// connect event channel
......@@ -318,7 +318,7 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
if (dest->enabledState())
std::cout << " OK." << std::endl;
else
else
std::cout << " Not OK." << std::endl;
if (dest->enabledState())
......@@ -326,10 +326,10 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
std::cout << " Connecting " << source->getName() << " channel ";
for (int chan = 0; chan < source->getNumOutputs(); chan++)
for (int chan = 0; chan < source->getNumOutputs(); chan++)
{
std::cout << chan << " ";
addConnection(source->getNodeId(), // sourceNodeID
chan, // sourceNodeChannelIndex
dest->getNodeId(), // destNodeID
......@@ -337,7 +337,7 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
}
std::cout << " to " << dest->getName() << std::endl;
std::cout << " Connecting " << source->getName() <<
" event channel to " <<
dest->getName() << std::endl;
......@@ -351,15 +351,15 @@ void ProcessorGraph::updateConnections(Array<SignalChainTabButton*, CriticalSect
}
}
}
}
source->wasConnected = true;
source = dest; // switch source and dest
if (source == 0 && splitters.size() > 0)
{
dest = splitters.getFirst(); // dest is now the splitter
splitters.remove(0); // take it out of the
splitters.remove(0); // take it out of the
dest->switchIO(); // switch to the other destination
dest->wasConnected = true; // don't want to re-add splitter
source = dest->getSourceNode(); // splitter is now source
......@@ -382,17 +382,19 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
if (processorType.equalsIgnoreCase("Sources")) {
if (subProcessorType.equalsIgnoreCase("Intan Demo Board") ||
subProcessorType.equalsIgnoreCase("File Reader") ||
if (subProcessorType.equalsIgnoreCase("Intan Demo Board") ||
subProcessorType.equalsIgnoreCase("File Reader") ||
subProcessorType.equalsIgnoreCase("Custom FPGA")) {
// only one Intan Demo Board at a time, please
if (!processorWithSameNameExists(subProcessorType)) {
if (subProcessorType.equalsIgnoreCase("Intan Demo Board") &&
!processorWithSameNameExists(subProcessorType)) {
std::cout << "Only one Intan Demo Board is allowed at a time."
<< std::endl;
} else {
processor = new SourceNode(subProcessorType);
std::cout << "Creating a new data source." << std::endl;
}
std::cout << "Creating a new data source." << std::endl;
} else if (subProcessorType.equalsIgnoreCase("Signal Generator"))
{
processor = new SignalGenerator();
......@@ -403,9 +405,9 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
std::cout << "Creating a new event node." << std::endl;
}
//sendActionMessage("New source node created.");
} else if (processorType.equalsIgnoreCase("Filters")) {
......@@ -417,7 +419,7 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
} else if (subProcessorType.equalsIgnoreCase("Resampler")) {
std::cout << "Creating a new resampler." << std::endl;
processor = new ResamplingNode();
} else if (subProcessorType.equalsIgnoreCase("Spike Detector")) {
std::cout << "Creating a new spike detector." << std::endl;
processor = new SpikeDetector();
......@@ -440,14 +442,14 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
} else if (processorType.equalsIgnoreCase("Utilities")) {
if (subProcessorType.equalsIgnoreCase("Splitter")) {
std::cout << "Creating a new splitter." << std::endl;
processor = new Splitter();
//sendActionMessage("New splitter created.");
} else if (subProcessorType.equalsIgnoreCase("Merger")) {
std::cout << "Creating a new merger." << std::endl;
processor = new Merger();
......@@ -465,14 +467,14 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
if (subProcessorType.equalsIgnoreCase("LFP Viewer")) {
std::cout << "Creating an LfpDisplayNode." << std::endl;
processor = new LfpDisplayNode();
// std::cout << "Graph data viewport: " << UI->getDataViewport() << std::endl;
// processor->setDataViewport(getDataViewport());
//processor->setUIComponent(UI);
}
}
else if (subProcessorType.equalsIgnoreCase("Spike Viewer")) {
std::cout << "Creating an SpikeDisplayNode." << std::endl;
processor = new SpikeDisplayNode();
processor = new SpikeDisplayNode();
}
else if (subProcessorType.equalsIgnoreCase("WiFi Output")) {
std::cout << "Creating a WiFi node." << std::endl;
......@@ -486,7 +488,7 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
std::cout << "Creating an FPGA output node." << std::endl;
processor = new FPGAOutput();
}
//sendActionMessage("New sink created.");
}
......@@ -502,7 +504,7 @@ bool ProcessorGraph::processorWithSameNameExists(const String& name)
if (name.equalsIgnoreCase(node->getProcessor()->getName()))
return true;
}
return false;
......@@ -511,7 +513,7 @@ bool ProcessorGraph::processorWithSameNameExists(const String& name)
void ProcessorGraph::removeProcessor(GenericProcessor* processor) {
std::cout << "Removing processor with ID " << processor->getNodeId() << std::endl;
removeNode(processor->getNodeId());
......@@ -564,7 +566,7 @@ bool ProcessorGraph::enableProcessors() {
p->enable();
}
}
getEditorViewport()->signalChainCanBeEdited(false);
// sendActionMessage("Acquisition started.");
......@@ -604,14 +606,14 @@ bool ProcessorGraph::disableProcessors() {
AudioNode* ProcessorGraph::getAudioNode() {
Node* node = getNodeForId(AUDIO_NODE_ID);
return (AudioNode*) node->getProcessor();
}
RecordNode* ProcessorGraph::getRecordNode() {
Node* node = getNodeForId(RECORD_NODE_ID);
return (RecordNode*) node->getProcessor();
......@@ -628,4 +630,3 @@ RecordNode* ProcessorGraph::getRecordNode() {
// File file = File("./savedState.xml");
// getEditorViewport()->loadState(file);
// }
......@@ -22,6 +22,10 @@
*/
#include "SourceNode.h"
#include "DataThreads/DataBuffer.h"
#include "DataThreads/IntanThread.h"
#include "DataThreads/FPGAThread.h"
#include "DataThreads/FileReaderThread.h"
#include "Editors/SourceNodeEditor.h"
#include "Channel.h"
#include <stdio.h>
......@@ -58,20 +62,23 @@ SourceNode::SourceNode(const String& name_)
} else {
enabledState(false);
eventChannelState = 0;
numEventChannels = 0;
}
// check for input source every few seconds
startTimer(sourceCheckInterval);
startTimer(sourceCheckInterval);
timestamp = 0;
timestamp = 0;
eventCodeBuffer = new int16[10000]; //10000 samples per buffer max?
}
SourceNode::~SourceNode()
SourceNode::~SourceNode()
{
if (eventChannelState)
delete[] eventChannelState;
}
DataThread* SourceNode::getThread()
......@@ -100,9 +107,9 @@ void SourceNode::updateSettings()
void SourceNode::actionListenerCallback(const String& msg)
{
//std::cout << msg << std::endl;
if (msg.equalsIgnoreCase("HI"))
{
// std::cout << "HI." << std::endl;
......@@ -176,38 +183,41 @@ AudioProcessorEditor* SourceNode::createEditor()
return editor;
}
bool SourceNode::tryEnablingEditor()
{
if (!isReady()) {
std::cout << "No input source found." << std::endl;
return false;
} else if (isEnabled) {
// If we're already enabled (e.g. if we're being called again
// due to timerCallback()), then there's no need to go through
// the editor again.
return true;
}
std::cout << "Input source found." << std::endl;
enabledState(true);
GenericEditor* ed = getEditor();
getEditorViewport()->makeEditorVisible(ed);
return true;
}
void SourceNode::timerCallback()
{
if (dataThread->foundInputSource())
{
if (!isEnabled) {
std::cout << "Input source found." << std::endl;
//stopTimer(); // check for input source every two seconds
enabledState(true);
GenericEditor* ed = getEditor();
getEditorViewport()->makeEditorVisible(ed);
}
} else {
if (isEnabled) {
std::cout << "No input source found." << std::endl;
enabledState(false);
GenericEditor* ed = getEditor();
getEditorViewport()->makeEditorVisible(ed);
}
if (!tryEnablingEditor() && isEnabled) {
std::cout << "Input source lost." << std::endl;
enabledState(false);
GenericEditor* ed = getEditor();
getEditorViewport()->makeEditorVisible(ed);
}
}
bool SourceNode::isReady() {
if (dataThread != 0) {
return dataThread->foundInputSource();
} else {
return false;
}
return dataThread && dataThread->foundInputSource();
}
bool SourceNode::enable() {
std::cout << "Source node received enable signal" << std::endl;
wasDisabled = false;
......@@ -230,7 +240,7 @@ bool SourceNode::disable() {
if (dataThread != 0)
dataThread->stopAcquisition();
startTimer(2000);
wasDisabled = true;
......@@ -243,7 +253,7 @@ bool SourceNode::disable() {
void SourceNode::acquisitionStopped()
{
//if (!dataThread->foundInputSource()) {
if (!wasDisabled) {
std::cout << "Source node sending signal to UI." << std::endl;
getUIComponent()->disableCallbacks();
......@@ -255,11 +265,11 @@ void SourceNode::acquisitionStopped()
}
void SourceNode::process(AudioSampleBuffer &buffer,
void SourceNode::process(AudioSampleBuffer &buffer,
MidiBuffer &events,
int& nSamples)
{
//std::cout << "SOURCE NODE" << std::endl;
// clear the input buffers
......@@ -267,9 +277,9 @@ void SourceNode::process(AudioSampleBuffer &buffer,
buffer.clear();
nSamples = inputBuffer->readAllFromBuffer(buffer, &timestamp, eventCodeBuffer, buffer.getNumSamples());
//std::cout << "TIMESTAMP: " << timestamp << std::endl;
//std::cout << "Samples per buffer: " << nSamples << std::endl;
uint8 data[4];
......@@ -309,7 +319,7 @@ void SourceNode::process(AudioSampleBuffer &buffer,
// std::cout << "ON" << std::endl;
// std::cout << c << std::endl;
// signal channel state is ON
addEvent(events, // MidiBuffer
TTL, // eventType
......@@ -317,7 +327,7 @@ void SourceNode::process(AudioSampleBuffer &buffer,
1, // eventID
c // eventChannel
);
}
......@@ -327,6 +337,3 @@ void SourceNode::process(AudioSampleBuffer &buffer,
}
}
......@@ -30,10 +30,7 @@
#include "../../JuceLibraryCode/JuceHeader.h"
#include <ftdi.h>
#include <stdio.h>
#include "DataThreads/DataBuffer.h"
#include "DataThreads/IntanThread.h"
#include "DataThreads/FPGAThread.h"
#include "DataThreads/FileReaderThread.h"
#include "DataThreads/DataThread.h"
#include "GenericProcessor.h"
#include "../UI/UIComponent.h"
......@@ -51,13 +48,13 @@ class SourceNode : public GenericProcessor,
{
public:
// real member functions:
SourceNode(const String& name);
~SourceNode();
void enabledState(bool t);
void process(AudioSampleBuffer &buffer, MidiBuffer &midiMessages, int& nSamples);
void setParameter (int parameterIndex, float newValue);
......@@ -78,13 +75,13 @@ public:
bool isSource() {return true;}
void acquisitionStopped();
DataThread* getThread();
void actionListenerCallback(const String& message);
int getTTLState();
private:
int numEventChannels;
......@@ -101,13 +98,12 @@ private:
uint64 timestamp;
int16* eventCodeBuffer;
int* eventChannelState;
int ttlState;
void updateSettings();
int* numSamplesInThisBuffer;
bool tryEnablingEditor();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SourceNode);
......@@ -115,4 +111,3 @@ private:
#endif // __SOURCENODE_H_DCE798F1__
......@@ -27,6 +27,13 @@
#include "UIComponent.h"
enum colorIds {
PROCESSOR_COLOR = 801,
FILTER_COLOR = 802,
SINK_COLOR = 803,
SOURCE_COLOR = 804,
UTILITY_COLOR = 805,
};
ProcessorList::ProcessorList() : isDragging(false),
itemHeight(32),
......@@ -573,14 +580,6 @@ void ProcessorListItem::setParentName(const String& name)
{
parentName = name;
enum {
PROCESSOR_COLOR = 801,
FILTER_COLOR = 802,
SINK_COLOR = 803,
SOURCE_COLOR = 804,
UTILITY_COLOR = 805,
};
if (parentName.equalsIgnoreCase("Processors"))
{
colorId = PROCESSOR_COLOR;
......@@ -614,4 +613,4 @@ void ProcessorListItem::setParentName(const String& name)
// } else {
// color = Colour(20, 37, 92);
// }
\ No newline at end of file
// }
......@@ -97,15 +97,6 @@ private:
/** Sets the appropriate OpenGL viewport for drawing.*/
void setViewport(bool);
enum colorIds {
PROCESSOR_COLOR = 801,
FILTER_COLOR = 802,
SINK_COLOR = 803,
SOURCE_COLOR = 804,
UTILITY_COLOR = 805,
};
int currentColor;
/** Returns the height requested by the ProcessorList. Determines whether or not
......
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