Browse Source

„src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.cpp“ ändern

master
Tobias Baumann 1 year ago
parent
commit
2a0ca99d14
1 changed files with 479 additions and 468 deletions
  1. 479
    468
      src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.cpp

+ 479
- 468
src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.cpp View File

@@ -1,469 +1,480 @@
#include "ovpCBoxAlgorithmP300TactileVisualization.h"
using namespace OpenViBE;
using namespace /*OpenViBE::*/Kernel;
using namespace /*OpenViBE::*/Plugins;
using namespace /*OpenViBE::Plugins::*/Tactilebci;
// This callback flushes all accumulated stimulations to the TCP Tagging
// after the rendering has completed.
static gboolean FlushCB(gpointer data)
{
(static_cast<CBoxAlgorithmP300TactileVisualization*>(data))->flushQueue();
return false; // Only run once
}
bool CBoxAlgorithmP300TactileVisualization::initialize()
{
// ------ Init decoder/encoder
m_SequenceInputDecoder.initialize(*this, 0);
m_TargetInputDecoder.initialize(*this, 1);
m_ResultInputDecoder.initialize(*this, 2);
m_ResultOutputEncoder.initialize(*this, 0);
// ------ Get box settings
m_InterfaceFilename = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_RowBase = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_nTactilos = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);
m_FreeSpelling = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3);
//set m_nTactilos minimum number of 2, if lower
if(m_nTactilos < 2)
{
m_nTactilos = 2;
}
//set m_nTactilos maximum number of MAX_TACTILOS(10), if higher
if(m_nTactilos > MAX_TACTILOS)
{
m_nTactilos = MAX_TACTILOS;
}
// ------ Setup acquisition server TCP tagging
m_stimuliQueue.clear();
m_stimulusSender = TCPTagging::CreateStimulusSender();
if(!m_stimulusSender->connect("localhost", "15361"))
{
this->getLogManager() << LogLevel_Warning << "Failed to connect to acquisition server TCP tagging.\n";
}
// ------ Gtk variables
// Build main UI elements
m_MainWidgetInterface = gtk_builder_new();
if(!gtk_builder_add_from_file(m_MainWidgetInterface, m_InterfaceFilename.toASCIIString(), nullptr))//error
{
this->getLogManager() << LogLevel_ImportantWarning << "Failed to load UI file [" << m_InterfaceFilename << "]\n";
this->getLogManager() << LogLevel_ImportantWarning << "Make sure, that the given filename and path are correct\n";
return(false);
}
m_MainWindow = GTK_WIDGET(gtk_builder_get_object(m_MainWidgetInterface, "p300-tactile-main"));
m_Table = GTK_TABLE(gtk_builder_get_object(m_MainWidgetInterface, "p300-tactile-table"));
m_ResultLabel = GTK_LABEL(gtk_builder_get_object(m_MainWidgetInterface, "label-result"));
m_TargetLabel = GTK_LABEL(gtk_builder_get_object(m_MainWidgetInterface, "label-target"));
// Create font description
m_FontDesc = pango_font_description_copy(pango_context_get_font_description(gtk_widget_get_pango_context(m_MainWindow)));
pango_font_description_set_size(m_FontDesc, gint(FontSize*PANGO_SCALE));
// test if the UI-file fits the number of tactilos
guint nRow = 0;
g_object_get(m_Table, "n-rows", &nRow, nullptr);
if(m_nTactilos != nRow)
{
this->getLogManager() << LogLevel_ImportantWarning << "The number of tactilos " << m_nTactilos<<" used and the number of rows "<< nRow << " in the ui file must be the same.\n";
this->getLogManager() << LogLevel_ImportantWarning << "Make sure to choose the right UI-File, e.g. p300-tactile-6.ui for 6 tactilos\n";
return(false);
}
else
{
for(uint64_t i = 0; i < m_nTactilos; i++)
{
std::string eventbox_id = "eventbox-" + std::to_string(i+1);
m_EventBox.push_back(GTK_WIDGET(gtk_builder_get_object(m_MainWidgetInterface, eventbox_id.c_str())));
}
}
// ------ Setup tactile UI
//Create UI for m_nTactilos = 6
if(m_nTactilos == 6)
{
//create free spelling UI for 6 tactilos
if(m_FreeSpelling)
{
m_Menu.push_back(TactileMenu(6));
m_Menu[0].set_LabelText(0, "Ja");
m_Menu[0].set_LabelText(1, "Nein");
m_Menu[0].set_LabelText(2, "Pflege");
m_Menu[0].set_LabelText(3, "Hilfe");
m_Menu[0].set_LabelText(4, "Geräte");
m_Menu[0].set_LabelText(5, "Funktionen");
m_Menu.push_back(TactileMenu(6));
m_Menu[1].set_LabelText(0, "Ja");
m_Menu[1].set_LabelText(1, "Nein");
m_Menu[1].set_LabelText(2, "Hunger");
m_Menu[1].set_LabelText(3, "Lage");
m_Menu[1].set_LabelText(4, "Müdigkeit");
m_Menu[1].set_LabelText(5, "Hauptmenü");
m_Menu.push_back(TactileMenu(6));
m_Menu[2].set_LabelText(0, "Ja");
m_Menu[2].set_LabelText(1, "Nein");
m_Menu[2].set_LabelText(2, "Schmerzen");
m_Menu[2].set_LabelText(3, "Atemnot");
m_Menu[2].set_LabelText(4, "Anderes");
m_Menu[2].set_LabelText(5, "Hauptmenü");
m_Menu.push_back(TactileMenu(6));
m_Menu[3].set_LabelText(0, "Ja");
m_Menu[3].set_LabelText(1, "Nein");
m_Menu[3].set_LabelText(2, "Atemgerät");
m_Menu[3].set_LabelText(3, "Rollstuhl");
m_Menu[3].set_LabelText(4, "Computer");
m_Menu[3].set_LabelText(5, "Hauptmenü");
//set SubMenu ptr
m_Menu[0].set_SubMenu(2, &m_Menu[1]);
m_Menu[0].set_SubMenu(3, &m_Menu[2]);
m_Menu[0].set_SubMenu(4, &m_Menu[3]);
m_Menu[1].set_SubMenu(5, &m_Menu[0]);
m_Menu[2].set_SubMenu(5, &m_Menu[0]);
m_Menu[3].set_SubMenu(5, &m_Menu[0]);
//set curr Menu ptr to main menu
m_CurrMenu = &m_Menu[0];
}
//create copy spelling UI for 6 tactilos
else
{
m_Menu.push_back(TactileMenu(6));
m_Menu[0].set_LabelText(0, "Hand links");
m_Menu[0].set_LabelText(1, "Arm links");
m_Menu[0].set_LabelText(2, "Brust links");
m_Menu[0].set_LabelText(3, "Brust rechts");
m_Menu[0].set_LabelText(4, "Arm rechts");
m_Menu[0].set_LabelText(5, "Hand rechts");
m_CurrMenu = &m_Menu[0];
}
}
//Create default UI for m_nTactilos != 6
else
{
m_Menu.push_back(TactileMenu(m_nTactilos));
m_CurrMenu = &m_Menu[0];
}
// ------ Init UI
m_visualizationCtx = dynamic_cast<VisualizationToolkit::IVisualizationContext*>(this->createPluginObject(OVP_ClassId_Plugin_VisualizationCtx));
m_visualizationCtx->setWidget(*this, m_MainWindow);
for(uint64_t i = 0; i < m_nTactilos; ++i)
{
resetColor();
gtk_widget_modify_font(gtk_bin_get_child(GTK_BIN(m_EventBox[i])), m_FontDesc);
}
toggleLabelText();
return(true);
}
/*******************************************************************************/
bool CBoxAlgorithmP300TactileVisualization::uninitialize()
{
// ------ uninitialize decoder/encoder
m_SequenceInputDecoder.uninitialize();
m_TargetInputDecoder.uninitialize();
m_ResultInputDecoder.uninitialize();
m_ResultOutputEncoder.uninitialize();
// ------ uninitialize GTK UI
if (m_MainWidgetInterface)
{
g_object_unref(m_MainWidgetInterface);
m_MainWidgetInterface = nullptr;
}
if (m_visualizationCtx)
{
this->releasePluginObject(m_visualizationCtx);
}
// ------ uinitialize TCP Tagging
if (m_idleFuncTag != 0)
{
m_stimuliQueue.clear();
g_source_remove(m_idleFuncTag);
m_idleFuncTag = 0;
}
if (m_stimulusSender)
{
delete m_stimulusSender;
m_stimulusSender = nullptr;
}
return(true);
}
/*******************************************************************************/
bool CBoxAlgorithmP300TactileVisualization::processInput(const size_t index)
{
// ------ ready to process
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
return(true);
}
/*******************************************************************************/
bool CBoxAlgorithmP300TactileVisualization::process()
{
const IBox& staticBoxContext=this->getStaticBoxContext();
IBoxIO& boxContext = this->getDynamicBoxContext();
//variables for processing of input chunks
uint64_t SequenceID = 0;
uint64_t TargetID = 0;
uint64_t ResultID = 0;
int Row = -1;
bool IsTarget = false;
bool TargetReceived = false;
bool ResultReceived = false;
//variables for forwarding of target stimulations
uint64_t ChunkStartTime = 0;
uint64_t ChunkEndTime = 0;
uint64_t Size = 0;
const uint8_t* Buffer = nullptr;
// ------ Sequence stimulation
for(uint64_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
m_SequenceInputDecoder.decode(i);
m_LastTime = boxContext.getInputChunkEndTime(0, i);
// if header received
if(m_SequenceInputDecoder.isHeaderReceived())
{}
// if buffer received
if(m_SequenceInputDecoder.isBufferReceived())
{
//check received stimulations on sequence input
CStimulationSet* SequenceStimulationSet = m_SequenceInputDecoder.getOutputStimulationSet();
for(uint64_t j = 0; j < SequenceStimulationSet->size(); ++j)
{
SequenceID = SequenceStimulationSet->getId(j);
if(SequenceID >= m_RowBase && SequenceID < m_RowBase + m_nTactilos)
{
Row = SequenceID - m_RowBase;
IsTarget = (Row == (int)m_LastTarget);
}
if(SequenceID == OVTK_StimulationId_VisualStimulationStart)
{
resetColor();
toggleFlashColor(Row);
if (IsTarget)
{
m_stimuliQueue.push_back(OVTK_StimulationId_Target);
}
else
{
m_stimuliQueue.push_back(OVTK_StimulationId_NonTarget);
}
}
if(SequenceID == OVTK_StimulationId_VisualStimulationStop)
{
resetColor();
}
if(SequenceID == OVTK_StimulationId_SegmentStart)
{
toggleLabelText();
}
m_stimuliQueue.push_back(SequenceID);
}
}
// if end received
if(m_SequenceInputDecoder.isEndReceived())
{}
boxContext.markInputAsDeprecated(0, i);
}
// ------ Target stimulation
for(uint64_t i = 0; i < boxContext.getInputChunkCount(1); ++i)
{
if(m_LastTime >= boxContext.getInputChunkStartTime(1, i))
{
m_TargetInputDecoder.decode(i);
// if header received
if(m_SequenceInputDecoder.isHeaderReceived())
{}
// if buffer received
if(m_SequenceInputDecoder.isBufferReceived())
{
// check received dtimulations on Target input
CStimulationSet* TargetStimulationSet = m_TargetInputDecoder.getOutputStimulationSet();
for(uint64_t j = 0; j < TargetStimulationSet->size(); ++j)
{
TargetID = TargetStimulationSet->getId(j);
if(TargetID >= m_RowBase && TargetID < m_RowBase + m_nTactilos)
{
Row = TargetID - m_RowBase;
TargetReceived = true;
}
if(TargetReceived)
{
toggleTargetColor(Row);
m_stimuliQueue.push_back(TargetID);
std::string TargetLabel = gtk_label_get_text(m_TargetLabel);
TargetLabel += gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(m_EventBox[Row]))));
gtk_label_set_text(m_TargetLabel, TargetLabel.c_str());
m_LastTarget = Row;
}
}
}
// if end received
if(m_SequenceInputDecoder.isEndReceived())
{}
boxContext.markInputAsDeprecated(1, i);
}
}
// ------ Result stimulation
for(uint64_t i = 0; i < boxContext.getInputChunkCount(2); ++i)
{
if(m_LastTime >= boxContext.getInputChunkStartTime(2, i))
{
m_ResultInputDecoder.decode(i);
// if header received
if(m_SequenceInputDecoder.isHeaderReceived())
{}
// if buffer received
if(m_SequenceInputDecoder.isBufferReceived())
{
// check received stimulations on result input
CStimulationSet* ResultStimulationSet = m_ResultInputDecoder.getOutputStimulationSet();
for(uint64_t j = 0; j < ResultStimulationSet->size(); ++j)
{
ResultID = ResultStimulationSet->getId(j);
if(ResultID >= m_RowBase && ResultID < m_RowBase + m_nTactilos)
{
Row = ResultID - m_RowBase;
ResultReceived = true;
}
if(ResultReceived)
{
toggleResultColor(Row);
std::string ResultLabel = gtk_label_get_text(m_ResultLabel);
ResultLabel += gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(m_EventBox[Row]))));
gtk_label_set_text(m_ResultLabel, ResultLabel.c_str());
//switch current menu ptr to submenu
if(m_CurrMenu->get_SubMenu(Row) != nullptr)
{
m_CurrMenu = m_CurrMenu->get_SubMenu(Row);
}
}
}
}
// if end received
if(m_SequenceInputDecoder.isEndReceived())
{}
// forward target stimulations
boxContext.getInputChunk(2, i, ChunkStartTime, ChunkEndTime, Size, Buffer);
boxContext.appendOutputChunkData(0, Buffer, Size);
boxContext.markOutputAsReadyToSend(0, ChunkStartTime, ChunkEndTime);
boxContext.markInputAsDeprecated(2, i);
}
}
// ------ Send accumulated stimuli to the acquisition server
if(m_idleFuncTag == 0)
{
m_idleFuncTag = g_idle_add(FlushCB, this);
}
return(true);
}
// ------ Function Definitions
// Sends all accumulated stimuli to the TCP Tagging
void CBoxAlgorithmP300TactileVisualization::flushQueue()
{
for (const auto& stimulation : m_stimuliQueue)
{
m_stimulusSender->sendStimulation(stimulation);
}
m_stimuliQueue.clear();
// This function will be automatically removed after completion, so set to 0
m_idleFuncTag = 0;
}
// Change labels fore-/background
void CBoxAlgorithmP300TactileVisualization::toggleFlashColor(uint64_t id)
{
gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[id])), GTK_STATE_NORMAL, &m_FlashFG);
gtk_widget_modify_bg(m_EventBox[id], GTK_STATE_NORMAL, &m_FlashBG);
}
void CBoxAlgorithmP300TactileVisualization::toggleTargetColor(uint64_t id)
{
gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[id])), GTK_STATE_NORMAL, &m_TargetFG);
gtk_widget_modify_bg(m_EventBox[id], GTK_STATE_NORMAL, &m_TargetBG);
}
void CBoxAlgorithmP300TactileVisualization::toggleResultColor(uint64_t id)
{
gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[id])), GTK_STATE_NORMAL, &m_ResultFG);
gtk_widget_modify_bg(m_EventBox[id], GTK_STATE_NORMAL, &m_ResultBG);
}
void CBoxAlgorithmP300TactileVisualization::resetColor()
{
for(uint64_t i = 0; i < m_nTactilos; i++)
{
gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[i])), GTK_STATE_NORMAL, &m_NoFlashFG);
gtk_widget_modify_bg(m_EventBox[i], GTK_STATE_NORMAL, &m_NoFlashBG);
}
}
// Change label text
void CBoxAlgorithmP300TactileVisualization::toggleLabelText()
{
for(uint64_t i = 0; i < m_nTactilos; i++)
{
std::string label_text = m_CurrMenu->get_LabelText(i);
gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(m_EventBox[i]))), label_text.c_str());
}
#include "ovpCBoxAlgorithmP300TactileVisualization.h"

using namespace OpenViBE;
using namespace /*OpenViBE::*/Kernel;
using namespace /*OpenViBE::*/Plugins;
using namespace /*OpenViBE::Plugins::*/Tactilebci;

// This callback flushes all accumulated stimulations to the TCP Tagging
// after the rendering has completed.
static gboolean FlushCB(gpointer data)
{
(static_cast<CBoxAlgorithmP300TactileVisualization*>(data))->flushQueue();

return false; // Only run once
}

bool CBoxAlgorithmP300TactileVisualization::initialize()
{
// ------ Init decoder/encoder
m_SequenceInputDecoder.initialize(*this, 0);
m_TargetInputDecoder.initialize(*this, 1);
m_ResultInputDecoder.initialize(*this, 2);
m_ResultOutputEncoder.initialize(*this, 0);
// ------ Get box settings
m_InterfaceFilename = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_RowBase = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_nTactilos = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);
m_FreeSpelling = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3);

//set m_nTactilos minimum number of 2, if lower
if(m_nTactilos < 2)
{
m_nTactilos = 2;
}
//set m_nTactilos maximum number of MAX_TACTILOS(10), if higher
if(m_nTactilos > MAX_TACTILOS)
{
m_nTactilos = MAX_TACTILOS;
}
// ------ Setup acquisition server TCP tagging
m_stimuliQueue.clear();
m_stimulusSender = TCPTagging::CreateStimulusSender();
if(!m_stimulusSender->connect("localhost", "15361"))
{
this->getLogManager() << LogLevel_Warning << "Failed to connect to acquisition server TCP tagging.\n";
}
// ------ Gtk variables
// Build main UI elements
m_MainWidgetInterface = gtk_builder_new();
if(!gtk_builder_add_from_file(m_MainWidgetInterface, m_InterfaceFilename.toASCIIString(), nullptr))//error
{
this->getLogManager() << LogLevel_ImportantWarning << "Failed to load UI file [" << m_InterfaceFilename << "]\n";
this->getLogManager() << LogLevel_ImportantWarning << "Make sure, that the given filename and path are correct\n";
return(false);
}
m_MainWindow = GTK_WIDGET(gtk_builder_get_object(m_MainWidgetInterface, "p300-tactile-main"));
m_Table = GTK_TABLE(gtk_builder_get_object(m_MainWidgetInterface, "p300-tactile-table"));
m_ResultLabel = GTK_LABEL(gtk_builder_get_object(m_MainWidgetInterface, "label-result"));
m_TargetLabel = GTK_LABEL(gtk_builder_get_object(m_MainWidgetInterface, "label-target"));
// Create font description
m_FontDesc = pango_font_description_copy(pango_context_get_font_description(gtk_widget_get_pango_context(m_MainWindow)));
pango_font_description_set_size(m_FontDesc, gint(FontSize*PANGO_SCALE));
// test if the UI-file fits the number of tactilos
guint nRow = 0;
g_object_get(m_Table, "n-rows", &nRow, nullptr);
if(m_nTactilos != nRow)
{
this->getLogManager() << LogLevel_ImportantWarning << "The number of tactilos " << m_nTactilos<<" used and the number of rows "<< nRow << " in the ui file must be the same.\n";
this->getLogManager() << LogLevel_ImportantWarning << "Make sure to choose the right UI-File, e.g. p300-tactile-6.ui for 6 tactilos\n";
return(false);
}
else
{
for(uint64_t i = 0; i < m_nTactilos; i++)
{
std::string eventbox_id = "eventbox-" + std::to_string(i+1);
m_EventBox.push_back(GTK_WIDGET(gtk_builder_get_object(m_MainWidgetInterface, eventbox_id.c_str())));
}
}
// ------ Setup tactile UI
//Create UI for m_nTactilos = 6
if(m_nTactilos == 6)
{
//create free spelling UI for 6 tactilos
if(m_FreeSpelling)
{
//mainmenu
m_Menu.push_back(TactileMenu(6));
m_Menu[0].set_LabelText(0, "Ja");
m_Menu[0].set_LabelText(1, "Nein");
m_Menu[0].set_LabelText(2, "Geräte");
m_Menu[0].set_LabelText(3, "Körper");
m_Menu[0].set_LabelText(4, "Hilfe");
m_Menu[0].set_LabelText(5, "Schmerzen");
//submenu Geräte
m_Menu.push_back(TactileMenu(6));
m_Menu[1].set_LabelText(0, "Ja");
m_Menu[1].set_LabelText(1, "Nein");
m_Menu[1].set_LabelText(2, "Atemgerät");
m_Menu[1].set_LabelText(3, "Computer");
m_Menu[1].set_LabelText(4, "Rollstuhl");
m_Menu[1].set_LabelText(5, "Hauptmenü");
//submenu Körper
m_Menu.push_back(TactileMenu(6));
m_Menu[2].set_LabelText(0, "Ja");
m_Menu[2].set_LabelText(1, "Nein");
m_Menu[2].set_LabelText(2, "Hunger/Durst");
m_Menu[2].set_LabelText(3, "warm/kalt");
m_Menu[2].set_LabelText(4, "Müdigkeit");
m_Menu[2].set_LabelText(5, "Hauptmenü");
//submenu Hilfe
m_Menu.push_back(TactileMenu(6));
m_Menu[3].set_LabelText(0, "Ja");
m_Menu[3].set_LabelText(1, "Nein");
m_Menu[3].set_LabelText(2, "Lage");
m_Menu[3].set_LabelText(3, "Atemnot");
m_Menu[3].set_LabelText(4, "Anderes Problem");
m_Menu[3].set_LabelText(5, "Hauptmenü");
//submenu Schmerzen
m_Menu.push_back(TactileMenu(6));
m_Menu[3].set_LabelText(0, "Ja");
m_Menu[3].set_LabelText(1, "Nein");
m_Menu[3].set_LabelText(2, "Kopf");
m_Menu[3].set_LabelText(3, "Torso");
m_Menu[3].set_LabelText(4, "Glieder");
m_Menu[3].set_LabelText(5, "Hauptmenü");

//set SubMenu ptr
m_Menu[0].set_SubMenu(2, &m_Menu[1]);//main --> Geräte
m_Menu[0].set_SubMenu(3, &m_Menu[2]);//main --> Körper
m_Menu[0].set_SubMenu(4, &m_Menu[3]);//main --> Hilfe
m_Menu[0].set_SubMenu(4, &m_Menu[4]);//main --> Schmerzen
m_Menu[1].set_SubMenu(5, &m_Menu[0]);//Geräte --> main
m_Menu[2].set_SubMenu(5, &m_Menu[0]);//Körper --> main
m_Menu[3].set_SubMenu(5, &m_Menu[0]);//Hilfe --> main
m_Menu[3].set_SubMenu(5, &m_Menu[0]);//Schmerzen --> main
//set curr Menu ptr to main menu
m_CurrMenu = &m_Menu[0];
}
//create copy spelling UI for 6 tactilos
else
{
m_Menu.push_back(TactileMenu(6));
m_Menu[0].set_LabelText(0, "Bein links");
m_Menu[0].set_LabelText(1, "Bein rechts");
m_Menu[0].set_LabelText(2, "Arm links");
m_Menu[0].set_LabelText(3, "Arm rechts");
m_Menu[0].set_LabelText(4, "Brust");
m_Menu[0].set_LabelText(5, "Rücken");

m_CurrMenu = &m_Menu[0];
}
}
//Create default UI for m_nTactilos != 6
else
{
m_Menu.push_back(TactileMenu(m_nTactilos));
m_CurrMenu = &m_Menu[0];
}
// ------ Init UI
m_visualizationCtx = dynamic_cast<VisualizationToolkit::IVisualizationContext*>(this->createPluginObject(OVP_ClassId_Plugin_VisualizationCtx));
m_visualizationCtx->setWidget(*this, m_MainWindow);
for(uint64_t i = 0; i < m_nTactilos; ++i)
{
resetColor();
gtk_widget_modify_font(gtk_bin_get_child(GTK_BIN(m_EventBox[i])), m_FontDesc);
}

toggleLabelText();
return(true);
}
/*******************************************************************************/

bool CBoxAlgorithmP300TactileVisualization::uninitialize()
{
// ------ uninitialize decoder/encoder
m_SequenceInputDecoder.uninitialize();
m_TargetInputDecoder.uninitialize();
m_ResultInputDecoder.uninitialize();
m_ResultOutputEncoder.uninitialize();
// ------ uninitialize GTK UI
if (m_MainWidgetInterface)
{
g_object_unref(m_MainWidgetInterface);
m_MainWidgetInterface = nullptr;
}
if (m_visualizationCtx)
{
this->releasePluginObject(m_visualizationCtx);
}
// ------ uinitialize TCP Tagging
if (m_idleFuncTag != 0)
{
m_stimuliQueue.clear();
g_source_remove(m_idleFuncTag);
m_idleFuncTag = 0;
}
if (m_stimulusSender)
{
delete m_stimulusSender;
m_stimulusSender = nullptr;
}

return(true);
}
/*******************************************************************************/


bool CBoxAlgorithmP300TactileVisualization::processInput(const size_t index)
{
// ------ ready to process
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();

return(true);
}

/*******************************************************************************/


bool CBoxAlgorithmP300TactileVisualization::process()
{
const IBox& staticBoxContext=this->getStaticBoxContext();
IBoxIO& boxContext = this->getDynamicBoxContext();
//variables for processing of input chunks
uint64_t SequenceID = 0;
uint64_t TargetID = 0;
uint64_t ResultID = 0;
int Row = -1;
bool IsTarget = false;
bool TargetReceived = false;
bool ResultReceived = false;
//variables for forwarding of target stimulations
uint64_t ChunkStartTime = 0;
uint64_t ChunkEndTime = 0;
uint64_t Size = 0;
const uint8_t* Buffer = nullptr;

// ------ Sequence stimulation
for(uint64_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
m_SequenceInputDecoder.decode(i);
m_LastTime = boxContext.getInputChunkEndTime(0, i);
// if header received
if(m_SequenceInputDecoder.isHeaderReceived())
{}
// if buffer received
if(m_SequenceInputDecoder.isBufferReceived())
{
//check received stimulations on sequence input
CStimulationSet* SequenceStimulationSet = m_SequenceInputDecoder.getOutputStimulationSet();
for(uint64_t j = 0; j < SequenceStimulationSet->size(); ++j)
{
SequenceID = SequenceStimulationSet->getId(j);
if(SequenceID >= m_RowBase && SequenceID < m_RowBase + m_nTactilos)
{
Row = SequenceID - m_RowBase;
IsTarget = (Row == (int)m_LastTarget);
}
if(SequenceID == OVTK_StimulationId_VisualStimulationStart)
{
resetColor();
toggleFlashColor(Row);
if (IsTarget)
{
m_stimuliQueue.push_back(OVTK_StimulationId_Target);
}
else
{
m_stimuliQueue.push_back(OVTK_StimulationId_NonTarget);
}
}
if(SequenceID == OVTK_StimulationId_VisualStimulationStop)
{
resetColor();
}
if(SequenceID == OVTK_StimulationId_SegmentStart)
{
toggleLabelText();
}
m_stimuliQueue.push_back(SequenceID);
}
}
// if end received
if(m_SequenceInputDecoder.isEndReceived())
{}
boxContext.markInputAsDeprecated(0, i);
}
// ------ Target stimulation
for(uint64_t i = 0; i < boxContext.getInputChunkCount(1); ++i)
{
if(m_LastTime >= boxContext.getInputChunkStartTime(1, i))
{
m_TargetInputDecoder.decode(i);
// if header received
if(m_SequenceInputDecoder.isHeaderReceived())
{}

// if buffer received
if(m_SequenceInputDecoder.isBufferReceived())
{
// check received dtimulations on Target input
CStimulationSet* TargetStimulationSet = m_TargetInputDecoder.getOutputStimulationSet();
for(uint64_t j = 0; j < TargetStimulationSet->size(); ++j)
{
TargetID = TargetStimulationSet->getId(j);
if(TargetID >= m_RowBase && TargetID < m_RowBase + m_nTactilos)
{
Row = TargetID - m_RowBase;
TargetReceived = true;
}
if(TargetReceived)
{
toggleTargetColor(Row);
m_stimuliQueue.push_back(TargetID);
std::string TargetLabel = gtk_label_get_text(m_TargetLabel);
TargetLabel += gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(m_EventBox[Row]))));
gtk_label_set_text(m_TargetLabel, TargetLabel.c_str());
m_LastTarget = Row;
}
}
}
// if end received
if(m_SequenceInputDecoder.isEndReceived())
{}
boxContext.markInputAsDeprecated(1, i);
}
}
// ------ Result stimulation
for(uint64_t i = 0; i < boxContext.getInputChunkCount(2); ++i)
{
if(m_LastTime >= boxContext.getInputChunkStartTime(2, i))
{
m_ResultInputDecoder.decode(i);
// if header received
if(m_SequenceInputDecoder.isHeaderReceived())
{}

// if buffer received
if(m_SequenceInputDecoder.isBufferReceived())
{
// check received stimulations on result input
CStimulationSet* ResultStimulationSet = m_ResultInputDecoder.getOutputStimulationSet();
for(uint64_t j = 0; j < ResultStimulationSet->size(); ++j)
{
ResultID = ResultStimulationSet->getId(j);
if(ResultID >= m_RowBase && ResultID < m_RowBase + m_nTactilos)
{
Row = ResultID - m_RowBase;
ResultReceived = true;
}
if(ResultReceived)
{
toggleResultColor(Row);
std::string ResultLabel = gtk_label_get_text(m_ResultLabel);
ResultLabel += gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(m_EventBox[Row]))));
gtk_label_set_text(m_ResultLabel, ResultLabel.c_str());
//switch current menu ptr to submenu
if(m_CurrMenu->get_SubMenu(Row) != nullptr)
{
m_CurrMenu = m_CurrMenu->get_SubMenu(Row);
}
}
}
}
// if end received
if(m_SequenceInputDecoder.isEndReceived())
{}
// forward target stimulations
boxContext.getInputChunk(2, i, ChunkStartTime, ChunkEndTime, Size, Buffer);
boxContext.appendOutputChunkData(0, Buffer, Size);
boxContext.markOutputAsReadyToSend(0, ChunkStartTime, ChunkEndTime);
boxContext.markInputAsDeprecated(2, i);

}
}

// ------ Send accumulated stimuli to the acquisition server
if(m_idleFuncTag == 0)
{
m_idleFuncTag = g_idle_add(FlushCB, this);
}
return(true);
}



// ------ Function Definitions


// Sends all accumulated stimuli to the TCP Tagging
void CBoxAlgorithmP300TactileVisualization::flushQueue()
{
for (const auto& stimulation : m_stimuliQueue)
{
m_stimulusSender->sendStimulation(stimulation);
}
m_stimuliQueue.clear();

// This function will be automatically removed after completion, so set to 0
m_idleFuncTag = 0;
}


// Change labels fore-/background
void CBoxAlgorithmP300TactileVisualization::toggleFlashColor(uint64_t id)
{
gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[id])), GTK_STATE_NORMAL, &m_FlashFG);
gtk_widget_modify_bg(m_EventBox[id], GTK_STATE_NORMAL, &m_FlashBG);
}

void CBoxAlgorithmP300TactileVisualization::toggleTargetColor(uint64_t id)
{
gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[id])), GTK_STATE_NORMAL, &m_TargetFG);
gtk_widget_modify_bg(m_EventBox[id], GTK_STATE_NORMAL, &m_TargetBG);
}

void CBoxAlgorithmP300TactileVisualization::toggleResultColor(uint64_t id)
{
gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[id])), GTK_STATE_NORMAL, &m_ResultFG);
gtk_widget_modify_bg(m_EventBox[id], GTK_STATE_NORMAL, &m_ResultBG);
}

void CBoxAlgorithmP300TactileVisualization::resetColor()
{
for(uint64_t i = 0; i < m_nTactilos; i++)
{
gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[i])), GTK_STATE_NORMAL, &m_NoFlashFG);
gtk_widget_modify_bg(m_EventBox[i], GTK_STATE_NORMAL, &m_NoFlashBG);
}
}


// Change label text
void CBoxAlgorithmP300TactileVisualization::toggleLabelText()
{
for(uint64_t i = 0; i < m_nTactilos; i++)
{
std::string label_text = m_CurrMenu->get_LabelText(i);
gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(m_EventBox[i]))), label_text.c_str());
}
}

Loading…
Cancel
Save