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

Acquisition automatically stops if data source is lost

Changes to the DataThread, SourceNode, and UIComponent classes allow data
threads to disable callbacks if they are no longer receiving input. So
far this has only been tested with the Intan Board, but it works really well.
Unplugging the board in the middle of acquisition allows the thread to exit,
and callbacks to be disabled, without any seg faults.
parent 8d0136c5
No related branches found
No related tags found
No related merge requests found
Showing
with 103 additions and 21 deletions
<?xml version="1.0" encoding="UTF-8"?>
<MAINWINDOW>
<BOUNDS x="1729" y="52" w="1161" h="968" fullscreen="0"/>
<BOUNDS x="1739" y="52" w="1181" h="831" fullscreen="0"/>
</MAINWINDOW>
......@@ -9,8 +9,13 @@
*/
#include "DataThread.h"
#include "../SourceNode.h"
DataThread::DataThread() : Thread ("Data Thread"), dataBuffer(0) {}
DataThread::DataThread(SourceNode* s) : Thread ("Data Thread"), dataBuffer(0)
{
sn = s;
}
DataThread::~DataThread() {}
......@@ -21,8 +26,15 @@ void DataThread::run() {
const MessageManagerLock mml (Thread::getCurrentThread());
if (! mml.lockWasGained())
return;
if (!updateBuffer())
if (!updateBuffer()) {
std::cout << "Aquisition error...stopping thread." << std::endl;
signalThreadShouldExit();
//stopAcquisition();
std::cout << "Notifying source node to stop acqusition." << std::endl;
sn->acquisitionStopped();
}
//
}
}
......
......@@ -15,12 +15,14 @@
#include <stdio.h>
#include "DataBuffer.h"
class SourceNode;
class DataThread : public Thread
{
public:
DataThread();
DataThread(SourceNode* sn);
~DataThread();
void run();
......@@ -37,6 +39,8 @@ public:
virtual int getNumChannels() = 0;
virtual float getSampleRate() = 0;
SourceNode* sn;
};
......
......@@ -10,7 +10,7 @@
#include "FPGAThread.h"
FPGAThread::FPGAThread() : DataThread(),
FPGAThread::FPGAThread(SourceNode* sn) : DataThread(sn),
isRunning(false),
numchannels(32),
m_u32SegmentSize(1048576)
......
......@@ -22,11 +22,14 @@
#include "okFrontPanelDLL.h"
#include "DataThread.h"
class SourceNode;
class FPGAThread : public DataThread
{
public:
FPGAThread();
FPGAThread(SourceNode* sn);
~FPGAThread();
bool foundInputSource() {return true;}
......
......@@ -11,7 +11,7 @@
#include "FileReaderThread.h"
FileReaderThread::FileReaderThread() : DataThread(),
FileReaderThread::FileReaderThread(SourceNode* sn) : DataThread(sn),
sampleRate(40000.0),
numChannels(16),
samplesPerBlock(1024)
......
......@@ -17,11 +17,14 @@
#include <stdio.h>
#include "DataThread.h"
class SourceNode;
class FileReaderThread : public DataThread
{
public:
FileReaderThread();
FileReaderThread(SourceNode* sn);
~FileReaderThread();
bool foundInputSource() {return true;}
......
......@@ -10,7 +10,7 @@
#include "IntanThread.h"
IntanThread::IntanThread() : DataThread(),
IntanThread::IntanThread(SourceNode* sn) : DataThread(sn),
vendorID(0x0403),
productID(0x6010),
baudrate(115200),
......@@ -29,7 +29,7 @@ IntanThread::IntanThread() : DataThread(),
IntanThread::~IntanThread()
{
closeUSB();
//closeUSB();
deleteAndZero(dataBuffer);
}
......@@ -70,17 +70,33 @@ bool IntanThread::foundInputSource()
bool IntanThread::startAcquisition()
{
closeUSB();
initializeUSB(false);
ftdi_write_data(&ftdic, &startCode, 1);
startThread();
return true;
}
bool IntanThread::stopAcquisition()
{
stopThread(500);
std::cout << "Received signal to terminate thread." << std::endl;
if (isThreadRunning()) {
signalThreadShouldExit();
}
std::cout << "Thread stopped successfully, stopping Intan Board." << std::endl;
ftdi_write_data(&ftdic, &stopCode, 1);
unsigned char buf[4097]; // has to be bigger than the on-chip buffer
ftdi_read_data(&ftdic, buf, sizeof(buf));
int return_value;
if ((return_value = ftdi_write_data(&ftdic, &stopCode, 1)) > 0) {
unsigned char buf[4097]; // has to be bigger than the on-chip buffer
ftdi_read_data(&ftdic, buf, sizeof(buf));
closeUSB();
}
return true;
}
......@@ -150,6 +166,7 @@ bool IntanThread::updateBuffer()
// >0 : number of bytes read
if ((bytes_read = ftdi_read_data(&ftdic, buffer, sizeof(buffer))) < 0)
{
std::cout << "NO DATA FOUND!" << std::endl;
return false;
}
......
......@@ -16,11 +16,13 @@
#include <stdio.h>
#include "DataThread.h"
class SourceNode;
class IntanThread : public DataThread
{
public:
IntanThread();
IntanThread(SourceNode* sn);
~IntanThread();
bool foundInputSource();
......
......@@ -10,7 +10,7 @@
#include "NetworkThread.h"
NetworkThread::NetworkThread() : DataThread()
NetworkThread::NetworkThread(SourceNode* sn) : DataThread(sn)
{
char host[] = "10.121.43.47";
char port[] = "5227";
......
......@@ -25,7 +25,7 @@ class NetworkThread : public DataThread
{
public:
NetworkThread();
NetworkThread(SourceNode* sn);
~NetworkThread();
bool foundInputSource() {return true;}
......
......@@ -113,6 +113,7 @@ void* ProcessorGraph::createNewProcessor(String& description)//,
processor->setFilterViewport(filterViewport);
processor->setConfiguration(config);
processor->addActionListener(messageCenter);
processor->setUIComponent(UI);
addNode(processor,id); // have to add it so it can be deleted by the graph
......
......@@ -19,11 +19,11 @@ SourceNode::SourceNode(const String& name_)
sourceCheckInterval(1500)
{
if (getName().equalsIgnoreCase("Intan Demo Board")) {
dataThread = new IntanThread();
dataThread = new IntanThread(this);
} else if (getName().equalsIgnoreCase("Custom FPGA")) {
dataThread = new FPGAThread();
dataThread = new FPGAThread(this);
} else if (getName().equalsIgnoreCase("File Reader")) {
dataThread = new FileReaderThread();
dataThread = new FileReaderThread(this);
}
setNumInputs(0);
......@@ -211,6 +211,15 @@ bool SourceNode::disable() {
return true;
}
void SourceNode::acquisitionStopped()
{
std::cout << "Source node sending signal to UI." << std::endl;
UI->disableCallbacks();
enabledState(false);
GenericEditor* ed = (GenericEditor*) getEditor();
viewport->updateVisibleEditors(ed, 4);
}
void SourceNode::process(AudioSampleBuffer &outputBuffer,
MidiBuffer &midiMessages,
......
......@@ -19,6 +19,7 @@
#include "DataThreads/FPGAThread.h"
#include "DataThreads/FileReaderThread.h"
#include "GenericProcessor.h"
#include "../UI/UIComponent.h"
class SourceNode : public GenericProcessor,
public Timer
......@@ -54,6 +55,8 @@ public:
bool disable();
bool isSource() {return true;}
void acquisitionStopped();
private:
......
......@@ -268,6 +268,24 @@ void ControlPanel::buttonClicked(Button* button)
}
void ControlPanel::disableCallbacks()
{
std::cout << "Control panel received signal to disable callbacks." << std::endl;
if (audio->callbacksAreActive())
{
std::cout << "Stopping audio." << std::endl;
audio->endCallbacks();
std::cout << "Disabling processors." << std::endl;
graph->disableProcessors();
std::cout << "Updating control panel." << std::endl;
cpuMeter->updateCPU(0.0f);
playButton->setToggleState(false,false);
recordButton->setToggleState(false,false);
}
}
void ControlPanel::actionListenerCallback(const String & msg)
{
//std::cout << "Message Received." << std::endl;
......
......@@ -86,6 +86,8 @@ public:
ControlPanel(ProcessorGraph* graph, AudioComponent* audio);
~ControlPanel();
void disableCallbacks();
private:
PlayButton* playButton;
RecordButton* recordButton;
......
......@@ -45,6 +45,7 @@ UIComponent::UIComponent (ProcessorGraph* pgraph, AudioComponent* audio_)
messageCenter = new MessageCenter();
processorGraph->addActionListener(messageCenter);
addActionListener(messageCenter);
addAndMakeVisible(messageCenter);
std::cout << "Created message center." << std::endl;
......@@ -100,4 +101,10 @@ void UIComponent::resized()
if (messageCenter != 0)
messageCenter->setBounds(40,h-40,w-160,30);
}
void UIComponent::disableCallbacks()
{
//sendActionMessage("Data acquisition terminated.");
controlPanel->disableCallbacks();
}
\ No newline at end of file
......@@ -25,7 +25,7 @@
class UIComponent : public Component,
//public ActionBroadcaster,
public ActionBroadcaster,
public DragAndDropContainer // required for
// drag-and-drop
// internal components
......@@ -40,6 +40,7 @@ public:
Configuration* getConfiguration() {return config;}
//void transmitMessage(const String& message);
void disableCallbacks();
private:
......
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