Browse Source

add visuellen Branch

Visuelles-BCI
Nicole Weber 2 years ago
parent
commit
5e4b38641e
41 changed files with 1 additions and 9665 deletions
  1. 0
    65
      CHANGELOG.txt
  2. 0
    46
      CMakeLists.txt
  3. 1
    24
      README.md
  4. 0
    3
      arduino/README.md
  5. 0
    144
      arduino/TactiloControllerPanda.ino
  6. 0
    124
      scenarios/cfg/OV_TACTILE_PANDA.conf
  7. 0
    4
      scenarios/cfg/p300-epoch-average.cfg
  8. 0
    58
      scenarios/manuals/Commands_TactileBCI.txt
  9. 0
    7
      scenarios/manuals/README.txt
  10. 0
    743
      scenarios/p300-tactile-0-signal-monitoring.xml
  11. 0
    1210
      scenarios/p300-tactile-1-acquisition.xml
  12. 0
    438
      scenarios/p300-tactile-2-train-xDAWN.xml
  13. 0
    898
      scenarios/p300-tactile-3-train-classifier.xml
  14. 0
    1772
      scenarios/p300-tactile-4-online.xml
  15. 0
    199
      scenarios/scripts/p300-tactile-accumulator.lua
  16. 0
    57
      scenarios/scripts/p300-tactile-filter-flash.lua
  17. 0
    57
      scenarios/scripts/p300-tactile-filter-target.lua
  18. 0
    18
      scenarios/scripts/p300-tactile-launch.lua
  19. 0
    131
      scenarios/scripts/p300-tactile-stimulator.lua
  20. 0
    55
      scenarios/scripts/p300-tactile-target.lua
  21. 0
    3
      scenarios/signals/README.txt
  22. 0
    321
      scenarios/ui/p300-tactile-10.ui
  23. 0
    185
      scenarios/ui/p300-tactile-2.ui
  24. 0
    202
      scenarios/ui/p300-tactile-3.ui
  25. 0
    219
      scenarios/ui/p300-tactile-4.ui
  26. 0
    235
      scenarios/ui/p300-tactile-5.ui
  27. 0
    253
      scenarios/ui/p300-tactile-6.ui
  28. 0
    270
      scenarios/ui/p300-tactile-7.ui
  29. 0
    287
      scenarios/ui/p300-tactile-8.ui
  30. 0
    304
      scenarios/ui/p300-tactile-9.ui
  31. 0
    52
      src/TactileVisualization/TactileMenu.cpp
  32. 0
    46
      src/TactileVisualization/TactileMenu.h
  33. 0
    480
      src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.cpp
  34. 0
    162
      src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.h
  35. 0
    140
      src/TactiloController/ovpCBoxAlgorithmTactiloController.cpp
  36. 0
    113
      src/TactiloController/ovpCBoxAlgorithmTactiloController.h
  37. 0
    113
      src/UDPStimCodeSender/ovpCBoxAlgorithmUDPStimcodeSender.cpp
  38. 0
    107
      src/UDPStimCodeSender/ovpCBoxAlgorithmUDPStimcodeSender.h
  39. 0
    36
      src/ovp_defines.h
  40. 0
    34
      src/ovp_main.cpp
  41. 0
    50
      src/utils.h

+ 0
- 65
CHANGELOG.txt View File

-->TODO: -Interface Box erstellen(UDP,Serial,(BT),...)
-Offline Test
-Online Test
06.05.2022:
-->ui files für unterschiedliche Anzahl von Tactilos erstellt (p300-tactile-2.ui, p300-tactile-3.ui, ...)
-->Lua files der szenarios angepasst, um die Variation der Tactiloanzahl zu ermöglichen
-->arduino Firmware auf zehn mögliche Tactilos erweitert
-->arduino Firmware ports angepasst (nutzung der PWM-fähigen ports)

02.05.2022:
-->FindThirdPartyBoost_System aus Cmakelist.txt entfernt (entfaellt mit OpenViBE3.3)
-->Szenarios angepasst (einige Boxen wurden mit OpenViBE3.3 ueberarbeitet)
-->UDPSender, TactileVisualization und TactiloStimulator Boxen erweitert um die Möglichkeit die Anzahl der Tactilos des Systems einzustellen

28.02.2022:
-->Box für die Ansteuerung der Tactilos über die Lattepanda GPIOs hinzugefügt

11.02.2022:
Änderungen am TactileBCI SourceCode:
-->neue Box P300 Tactile Visualization für die Organisation von Menüs/Submenüs des Tactilen BCIs erstellt(Basierend auf der P300 Speller Visualization)

-->Das LogLevel der Nachrichten in der UDPStimCodeSender Box auf Debug gesetzt um nicht standardmäßig die große Menge an Nachrichten anzuzeigen

Änderungen an den Szenarios:
-->In 1-Acquisition und 4-Online P300 Speller Visualization durch die neue Box P300 Tactile Visualization ersetzt

Änderungen in OV_TACTILE.conf:
-->Schriftgröße von Target, Flash und Selected angepasst



05.02.2022:
-->die verschiedenen repositories zu einem zusammengefasst



29.01.2022:
Änderungen an den Szenarios:
1.Szenario Acquisition:
-->Die Filterung des Signals erfolgt jetzt hier, statt in den Szenarien für die filterkonfiguration
-->In der UI des Szenarios gibt es jetzt einen zweiten reiter zur anzeige des EEG-Signals

2.Szenario Train xDAWN:
-->Das aufgezeichnete signal ist jetzt bereits gefiltert, dementsprechend entfällt die filterung hier

3.Szenario Train p300-classifier:
-->Das aufgezeichnete signal ist jetzt bereits gefiltert, dementsprechend entfällt die filterung hier

4.Szenario Online:
-->Analog zu acquisition wird auch hier das gefilterte signal aufgezeichnet und nicht mehr das ungefilterte
-->Auch hier lässt sich jetzt in einem zusätzlichen Reiter das EEG Signal anzeigen

Änderungen an Scripts:
p300-tactile-stimulator.lua:
-->Da die Box derzeit keinen Input hat, wurde eine Zeile entfernt, welche die letzten erhaltenen daten löscht

Änderungen an der UDPSender Box:
-->Die weitergabe der Daten am boxoutput wurde verändert, um ein timingproblem zu beheben

Änderungen im OpenVibe Sourcecode:
\meta\sdk\plugins\processing\signal-processing\src\box-algorithms\ovpCBoxAlgorithmXDAWNTrainer.cpp:
-->Z.338-339 geändert, damit die cfg mit gültigen werten gefüllt wird: fprintf(file, "\t<SettingValue>%u</SettingValue>\n", (unsigned int)m_filterDim);
fprintf(file, "\t<SettingValue>%u</SettingValue>\n", (unsigned int)nChannel);


+ 0
- 46
CMakeLists.txt View File

if(OV_DISABLE_GTK)
message(STATUS "Skipping Plugins: Simple Visualization, no GTK")
return()
endif(OV_DISABLE_GTK)

project(openvibe-plugins-tactile-bci VERSION ${OPENVIBE_MAJOR_VERSION}.${OPENVIBE_MINOR_VERSION}.${OPENVIBE_PATCH_VERSION})

file(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.inl)

add_library(${PROJECT_NAME} SHARED ${SRC_FILES})

target_link_libraries(${PROJECT_NAME}
openvibe
openvibe-common
openvibe-toolkit
openvibe-module-ebml
openvibe-module-system
openvibe-visualization-toolkit
)

set_target_properties(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
FOLDER ${PLUGINS_FOLDER}
COMPILE_FLAGS "-DOVP_Exports -DOVP_Shared")

add_definitions(-DTARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines)
add_definitions(-DBOOST_DATE_TIME_NO_LIB)
if(WIN32)
add_definitions(-D_WIN32_WINNT=0x0501)
endif(WIN32)

include("FindOpenViBEModuleTCPTagging")
include("FindThirdPartyGTK")
# need boost for UDPStimcodeSender and TactileStimulation
include("FindThirdPartyBoost")

# -----------------------------
# Install files
# -----------------------------
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${DIST_BINDIR}
LIBRARY DESTINATION ${DIST_LIBDIR}
ARCHIVE DESTINATION ${DIST_LIBDIR})

install(DIRECTORY scenarios/ DESTINATION ${DIST_DATADIR}/openvibe/thn_bci/scenarios)

+ 1
- 24
README.md View File

# TactileBCI


Enthält alle für das Taktile BCI der THN benötigten Box-Codes und Designer-Szenarien, sowie eine Anleitung zu deren Verwendung (s. TactileBCI/scenarios/manuals/).

Bei diesem taktilen BCI der THN, haben wir ein Hauptmenü mit 6 Elementen wovon 4 in untermenüs führen und die anderen 2 die antwortmöglichkeiten ja/nein darstellen.

Dabei wird jeder Menüpunkt von einem kleinen Vibrationsmotor ("Tactilo") repräsentiert.

Die Tactilos werden, über eine festgelegte Anzahl von Wiederholungen und Trials, in zufälliger Reihenfolge angesteuert um so sensorisch ein P300-Signal zu erzeugen.

Mit dieser vorgehensweise soll es möglich gemacht werden durch die Menüs der UI zu navigieren.

---------------------------------------------------------------------------------------------------------------------------------------------------------------

Verwendung:

**WICHTIG:** Das Plugin ist fuer die Verwendung mit OpenViBE 3.3 gemacht

1) git clone https://git.efi.th-nuernberg.de/gitea/baumannto57992/TactileBCI/

2) das erstellte verzeichniss "TactileBCI" nach /meta/extras/plugins/processing/ kopieren

3) Danach OpenViBE kompilieren
Hier angepassten OpenVIbe Porgrammcode für das visuelle BCI und eine entsprechende Readme einfügen

+ 0
- 3
arduino/README.md View File

# TactiloControllerPanda
Dieses Programm empfaengt Daten von der Korrespondierenden OpenViBE Box ueber eine serielle Schnittstelle. <br />
Auf Basis der erhaltenen Daten, werden die bis zu zehn Tactilos des Taktilen Brain Computer Interface angesteuert. Das Timing wird dabei komplett von OpenViBE uebernommen.

+ 0
- 144
arduino/TactiloControllerPanda.ino View File


///-------------------------------------------------------------------------------------------------
///
/// \file TactiloControllerPanda.ino
/// \brief Controlls the Tactilos on the Leonardos GPIOs, based on the messages from OpenVibes TactiloController Box Algorithm
/// Hochladen mit der Arduino IDE
/// \author Tobias Baumann (TH-Nürnberg).
/// \version 1.0.
/// \date Mon Mar 7 14:02:56 2022.
///
///-------------------------------------------------------------------------------------------------

//define used GPIO pins
#define TAC1 13 //PWM
#define TAC2 11 //PWM
#define TAC3 10 //PWM
#define TAC4 9 //PWM
#define TAC5 6 //PWM
#define TAC6 5 //PWM
//reserve
#define TAC7 3 //PWM
#define TAC8 2
#define TAC9 1
#define TAC10 0



void setup()
{
//init serial
Serial.begin(115200);
//init GPIOs
Serial.println("...init GPIOs");
set_PinMode();
set_AllLow();
}

void loop()
{
char SerialData;

if(Serial.available() > 0)
{
SerialData = Serial.read();
processSerialData(SerialData);
}
}

void set_PinMode()
{
//set all pins to OUTPUT
pinMode(TAC1, OUTPUT);
pinMode(TAC2, OUTPUT);
pinMode(TAC3, OUTPUT);
pinMode(TAC4, OUTPUT);
pinMode(TAC5, OUTPUT);
pinMode(TAC6, OUTPUT);
pinMode(TAC7, OUTPUT);
pinMode(TAC8, OUTPUT);
pinMode(TAC9, OUTPUT);
pinMode(TAC10, OUTPUT);
}

void set_AllLow()
{
//set all pins to LOW
digitalWrite(TAC1, LOW);
digitalWrite(TAC2, LOW);
digitalWrite(TAC3, LOW);
digitalWrite(TAC4, LOW);
digitalWrite(TAC5, LOW);
digitalWrite(TAC6, LOW);
digitalWrite(TAC7, LOW);
digitalWrite(TAC8, LOW);
digitalWrite(TAC9, LOW);
digitalWrite(TAC10, LOW);
}

void processSerialData(char SerialData)
{
switch(SerialData)
{
case '0':
digitalWrite(TAC1, !digitalRead(TAC1));
//Serial.print("Tactilo 1: ");
//Serial.println(digitalRead(TAC1));
break;
case '1':
digitalWrite(TAC2, !digitalRead(TAC2));
//Serial.print("Tactilo 2: ");
//Serial.println(digitalRead(TAC2));
break;
case '2':
digitalWrite(TAC3, !digitalRead(TAC3));
//Serial.print("Tactilo 3: ");
//Serial.println(digitalRead(TAC3));
break;
case '3':
digitalWrite(TAC4, !digitalRead(TAC4));
//Serial.print("Tactilo 4: ");
//Serial.println(digitalRead(TAC4));
break;
case '4':
digitalWrite(TAC5, !digitalRead(TAC5));
//Serial.print("Tactilo 5: ");
//Serial.println(digitalRead(TAC5));
break;
case '5':
digitalWrite(TAC6, !digitalRead(TAC6));
//Serial.print("Tactilo 6: ");
//Serial.println(digitalRead(TAC6));
break;
case '6':
digitalWrite(TAC7, !digitalRead(TAC7));
//Serial.print("Tactilo 7: ");
//Serial.println(digitalRead(TAC7));
break;
case '7':
digitalWrite(TAC8, !digitalRead(TAC8));
//Serial.print("Tactilo 8: ");
//Serial.println(digitalRead(TAC8));
break;
case '8':
digitalWrite(TAC9, !digitalRead(TAC9));
//Serial.print("Tactilo 9: ");
//Serial.println(digitalRead(TAC9));
break;
case '9':
digitalWrite(TAC10, !digitalRead(TAC10));
//Serial.print("Tactilo 10: ");
//Serial.println(digitalRead(TAC10));
break;
case 'b':
Serial.println("...Begin Tactile Session");
break;
case 'e':
set_AllLow();
Serial.println("...End Tactile Session");
break;
default:
break;
}
}

+ 0
- 124
scenarios/cfg/OV_TACTILE_PANDA.conf View File

########################################################################################################################
# This configuration file contains declarations of variables used by the scenarios of the tactile BCI System #
# #
# Add --config PATH_TO_THIS_FILE when starting the designer from the command line #
# USE --define TOKEN VALUE to assign a different value to a token without changing the default configuration #
# #
# #
# Scenarios requiring this configuration file: p300-tactile-0-signal-monitoring.xml, p300-tactile-1-acquisition.xml, #
# p300-tactile-2-train-xDAWN.xml, p300-tactile-3-train-classifier.xml, #
# p300-tactile-4-online.xml #
# #
# Author : Tobias Baumann #
# Date : 2021-12-27 #
########################################################################################################################


########################################################################################################################
# General Settings #
########################################################################################################################
PATH_CONFIG = ${Player_ScenarioDirectory}/cfg
PATH_SCRIPTS = ${Player_ScenarioDirectory}/scripts
PATH_SIGNALS = ${Player_ScenarioDirectory}/signals
PATH_UI = ${Player_ScenarioDirectory}/ui

ROW_BASE = OVTK_StimulationId_Label_01
N_TACTILOS = 6
FREE_SPELLING = true


########################################################################################################################
# Acquisition and Signal Processing #
########################################################################################################################
ACQUISITION_SERVER_HOST_NAME = ${AcquisitionServer_HostName}
ACQUISITION_SERVER_PORT = 1024
CHANNEL_SELECTION = 1;2;3;4;5;6;7;8
SIGNAL_DECIMATION_FACTOR = 2
FILTER_TYPE = Band Pass
FILTER_ORDER = 4
LOW_CUT_FREQUENCY = 1.000000
HIGH_CUT_FREQUENCY = 20.000000



########################################################################################################################
# Stimulation #
########################################################################################################################
SCRIPT_TACTILE_STIMULATOR = ${PATH_SCRIPTS}/p300-tactile-stimulator.lua
N_REPETITIONS = 4
N_TRIALS = 4
STIM_DURATION = 0.2
NO_STIM_DURATION = 0.1
INTER_REPETITION_DELAY = 1.0
INTER_TRIAL_DELAY = 4.0
START_STIMULATION = OVTK_StimulationId_Label_00
START_DELAY = 20


########################################################################################################################
# Tactilo Control #
########################################################################################################################
SERIAL_PORT = /dev/ttyACM0


########################################################################################################################
# Target Generation #
########################################################################################################################
SCRIPT_TARGET_GENERATION = ${PATH_SCRIPTS}/p300-tactile-target.lua
SEND_DELAY = 2


########################################################################################################################
# FILE I/O #
########################################################################################################################
OUTPUT_FILE_NAME = ${PATH_SIGNALS}/p300-tactile-session.ov
INPUT_FILE_NAME = ${PATH_SIGNALS}/p300-tactile-session.ov


########################################################################################################################
# xDAWN Spatial Filter #
########################################################################################################################
SPATIAL_TRAIN_TRIGGER = OVTK_StimulationId_ExperimentStop
SPATIAL_FILTER_CONFIG = ${PATH_CONFIG}/p300-spatial-filter.cfg
FILTER_DIMENSION = 2


########################################################################################################################
# P300 Classifier #
########################################################################################################################
CLASSIFIER_TRAIN_TRIGGER = OVTK_StimulationId_ExperimentStop
CLASSIFIER_CONFIG = ${PATH_CONFIG}/p300-classifier.cfg
MULTICLASS_STRATEGY = Native
CLASS_1 = OVTK_StimulationId_Target
CLASS_2 = OVTK_StimulationId_NonTarget
ALGORITHM = Linear Discrimimant Analysis (LDA)
USE_SHRINKAGE = false
SHRINKAGE_COEFFICIENT = -1.000000
SHRINKAGE_FORCE_DIAGONAL_COV = false
N_PARTITIONS = 5
CLASS_BALANCE = false


########################################################################################################################
# P300 ACCUMULATOR #
########################################################################################################################
SCRIPT_P300_ACCUMULATOR = ${PATH_SCRIPTS}/p300-tactile-accumulator.lua


########################################################################################################################
# Tactile Visualization #
########################################################################################################################
TACTILE_UI = ${PATH_UI}/p300-tactile-6.ui
FLASH_BG = 5,5,5
FLASH_FG = 100,100,100
FLASH_FONT_SIZE = 50
NO_FLASH_BG = 0,0,0
NO_FLASH_FG = 25,25,25
NO_FLASH_FONT_SIZE = 50
TARGET_BG = 20,20,70
TARGET_FG = 10,10,30
TARGET_FONT_SIZE = 50
SELECTED_BG = 10,40,10
SELECTED_FG = 60,100,60
SELECTED_FONT_SIZE = 50


+ 0
- 4
scenarios/cfg/p300-epoch-average.cfg View File

<OpenViBE-SettingsOverride>
<SettingValue>Epoch block average</SettingValue>
<SettingValue>1</SettingValue>
</OpenViBE-SettingsOverride>

+ 0
- 58
scenarios/manuals/Commands_TactileBCI.txt View File

#############################################################################################################################################################################################################################################
# OpenViBE Command Lines Tactile-BCI #
# #
# Author : Tobias Baumann #
# Date : 2022-01-18 #
#############################################################################################################################################################################################################################################

#############################################################################################################################################################################################################################################
# Start Acquisition Server #
#############################################################################################################################################################################################################################################

OV_PATH\openvibe-acquisition-server.cmd --define AcquisitionServer_DefaultDriver DRIVER_NAME --define AcquisitionServer_DefaultSampleCountPerBuffer N_SAMPLES_PER_BUFFER --define AcquisitionServer_DefaultConnectionPort PORT_NUMBER

OV_PATH --> Pfad zur openvibe-acquisition-server.sh
DRIVER_NAME --> Bezeichnung des zu verwendenden Treibers z.B.: "g.tec Unicorn Gipsa-lab"
N_SAMPLES_PER_BUFFER --> Anzahl der Samples pro Buffer (4,8,16,32,64,128,256,512) (default: 32)
PORT_NUMBER --> Vom Acquisition Server verwendeter Port (default: 1024)


#############################################################################################################################################################################################################################################
# Wiedergabe der Szenarios ohne Designer GUI und mit der Konfiguration für das Taktile BCI #
#############################################################################################################################################################################################################################################

1. Allgemeiner Aufruf:

OV_PATH\openvibe-designer.cmd --no-gui --config CONFIG_PATH\OV_TACTILE_PANDA.conf --play SCENARIO_PATH\SCENARIO_NAME.xml
OV_PATH --> Pfad zur openvibe-designer.sh
SCENARIO_PATH --> Pfad zu den Szenarios für das Taktile BCI
SCENARIO_NAME --> Name des zu startenden Szenarios
CONFIG_PATH --> Pfad zur Config für das Taktile BCI (=SCENARIO_PATH\cfg)

2. Szenario 0 - Signal Monitoring:

OV_PATH\openvibe-designer.sh --no-gui --config CONFIG_PATH\OV_TACTILE_PANDA.conf --play SCENARIO_PATH\p300-tactile-0-signal-monitoring.xml
3. Szenario 1 - Acquisition:

OV_PATH\openvibe-designer.sh --no-gui --config CONFIG_PATH\OV_TACTILE_PANDA.conf --play SCENARIO_PATH\p300-tactile-1-acquisition.xml
4. Szenario 2 - Train xDAWN Filter:

OV_PATH\openvibe-designer.sh --no-gui --config CONFIG_PATH\OV_TACTILE_PANDA.conf --playfast SCENARIO_PATH\p300-tactile-2-train-xDAWN.xml
4. Szenario 3 - Train P300 Classifier:

OV_PATH\openvibe-designer.sh --no-gui --config CONFIG_PATH\OV_TACTILE_PANDA.conf --playfast SCENARIO_PATH\p300-tactile-3-train-classifier.xml
5. Szenario 4 - Online(Free_Spelling):

OV_PATH\openvibe-designer.sh --no-gui --config CONFIG_PATH\OV_TACTILE_PANDA.conf --define FREE_SPELLING true --play SCENARIO_PATH\p300-tactile-4-online.xml
6. Szenario 4 - Online(Copy_Spelling):

OV_PATH\openvibe-designer.sh --no-gui --config CONFIG_PATH\OV_TACTILE_PANDA.conf --define FREE_SPELLING false --play SCENARIO_PATH\p300-tactile-4-online.xml


+ 0
- 7
scenarios/manuals/README.txt View File

p300-tactile:

- Die Szenarien für das Taktile BCI basieren auf dem OpenVibeSzenrio p300-speller-xDAWN.
- Die Ausführungsreihenfolge ist Acquisition -> train-xDAWN -> train-classifier -> online.

- der Designer muss mit --config CONFIG_PATH\OV_TACTILE_PANDA.conf von der konsole gestartet werden um die im config file festgelegten Tokens verwenden zu können
- weitere Informationen zum ausführen der Szenarios sind in "Commands_TactileBCI.txt" zu finden

+ 0
- 743
scenarios/p300-tactile-0-signal-monitoring.xml View File

<OpenViBE-Scenario>
<FormatVersion>2</FormatVersion>
<Creator>OpenViBE Designer</Creator>
<CreatorVersion>3.3.0</CreatorVersion>
<Settings></Settings>
<Inputs></Inputs>
<Outputs></Outputs>
<Boxes>
<Box>
<Identifier>(0x000014bf, 0x000034db)</Identifier>
<Name>Identity</Name>
<AlgorithmClassIdentifier>(0x5dffe431, 0x35215c50)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input stream 1</Name>
</Input>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input stream 2</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Input stream 3</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output stream 1</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output stream 2</Name>
</Output>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Output stream 3</Name>
</Output>
</Outputs>
<Attributes>
<Attribute>
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>432</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>928</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xa8ffe2a3, 0x27038f03)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xac367a9c, 0x2da95abe)</Identifier>
<Value>6</Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00003f1b, 0x00003c78)</Identifier>
<Name>Signal Decimation</Name>
<AlgorithmClassIdentifier>(0x012f4bea, 0x3be37c66)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Decimation factor</Name>
<DefaultValue>8</DefaultValue>
<Value>${SIGNAL_DECIMATION_FACTOR}</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>816</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x5082af41, 0xd0fbf4cb)</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000046bc, 0x00003f08)</Identifier>
<Name>Temporal Filter</Name>
<AlgorithmClassIdentifier>(0xb4f9d042, 0x9d79f2e5)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0xfa20178e, 0x4cba62e9)</TypeIdentifier>
<Name>Filter Type</Name>
<DefaultValue>Band Pass</DefaultValue>
<Value>${FILTER_TYPE}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Filter Order</Name>
<DefaultValue>4</DefaultValue>
<Value>${FILTER_ORDER}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Low Cut-off Frequency (Hz)</Name>
<DefaultValue>1</DefaultValue>
<Value>${LOW_CUT_FREQUENCY}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>High Cut-off Frequency (Hz)</Name>
<DefaultValue>40</DefaultValue>
<Value>${HIGH_CUT_FREQUENCY}</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>256</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>816</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x6a7c1e9b, 0x6b00b5c5)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>4</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00005c5c, 0x00007610)</Identifier>
<Name>Raw</Name>
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Data</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel Units</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
<Name>Display Mode</Name>
<DefaultValue>Scan</DefaultValue>
<Value>Scan</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
<Name>Auto vertical scale</Name>
<DefaultValue>Per channel</DefaultValue>
<Value>Per channel</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Scale refresh interval (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>0.000000</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Scale</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Offset</Name>
<DefaultValue>0</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Time Scale</Name>
<DefaultValue>10</DefaultValue>
<Value>5.000000</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Horizontal ruler</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Vertical ruler</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Multiview</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>560</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>1024</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>9</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00006b6d, 0x00002690)</Identifier>
<Name>Acquisition client</Name>
<AlgorithmClassIdentifier>(0x35d225cb, 0x3e6e3a5f)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x403488e7, 0x565d70b6)</TypeIdentifier>
<Name>Experiment information</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Signal stream</Name>
</Output>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Output>
<Output>
<TypeIdentifier>(0x013df452, 0xa3a8879a)</TypeIdentifier>
<Name>Channel localisation</Name>
</Output>
<Output>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel units</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Acquisition server hostname</Name>
<DefaultValue>${AcquisitionServer_HostName}</DefaultValue>
<Value>${ACQUISITION_SERVER_HOST_NAME}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Acquisition server port</Name>
<DefaultValue>1024</DefaultValue>
<Value>${ACQUISITION_SERVER_PORT}</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>64</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>944</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x0d4656c0, 0xc95b1fa8)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>5</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00007e4e, 0x00006b7b)</Identifier>
<Name>Filtered</Name>
<AlgorithmClassIdentifier>(0x0055be5f, 0x087bdd12)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Data</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x6ab26b81, 0x0f8c02f3)</TypeIdentifier>
<Name>Channel Units</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x5de046a6, 0x086340aa)</TypeIdentifier>
<Name>Display Mode</Name>
<DefaultValue>Scan</DefaultValue>
<Value>Scan</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x33a30739, 0x00d5299b)</TypeIdentifier>
<Name>Auto vertical scale</Name>
<DefaultValue>Per channel</DefaultValue>
<Value>Per channel</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Scale refresh interval (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>0.000000</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Scale</Name>
<DefaultValue>100</DefaultValue>
<Value>100</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Vertical Offset</Name>
<DefaultValue>0</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Time Scale</Name>
<DefaultValue>10</DefaultValue>
<Value>5.000000</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Horizontal ruler</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Vertical ruler</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Multiview</Name>
<DefaultValue>false</DefaultValue>
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>560</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>832</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>9</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x4ff47ca1, 0x133bd33b)</Identifier>
<Name>EEG Signal Selection</Name>
<AlgorithmClassIdentifier>(0x361722e8, 0x311574e8)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Channel List</Name>
<DefaultValue>:</DefaultValue>
<Value>${CHANNEL_SELECTION}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x3bcf9e67, 0x0c23994d)</TypeIdentifier>
<Name>Action</Name>
<DefaultValue>Select</DefaultValue>
<Value>Select</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x666f25e9, 0x3e5738d6)</TypeIdentifier>
<Name>Channel Matching Method</Name>
<DefaultValue>Smart</DefaultValue>
<Value>Index</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>176</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>864</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x277826e1, 0xa30a3bd0)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x000003a7, 0x000034db)</Identifier>
<Source>
<BoxIdentifier>(0x000014bf, 0x000034db)</BoxIdentifier>
<BoxOutputIndex>2</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00005c5c, 0x00007610)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00000554, 0x0000661a)</Identifier>
<Source>
<BoxIdentifier>(0x000014bf, 0x000034db)</BoxIdentifier>
<BoxOutputIndex>2</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00007e4e, 0x00006b7b)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00001d33, 0x00002bb0)</Identifier>
<Source>
<BoxIdentifier>(0x00006b6d, 0x00002690)</BoxIdentifier>
<BoxOutputIndex>2</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000014bf, 0x000034db)</BoxIdentifier>
<BoxInputIndex>2</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00003f04, 0x000045c3)</Identifier>
<Source>
<BoxIdentifier>(0x000014bf, 0x000034db)</BoxIdentifier>
<BoxOutputIndex>1</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00005c5c, 0x00007610)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00004b11, 0x00006a43)</Identifier>
<Source>
<BoxIdentifier>(0x00003f1b, 0x00003c78)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000014bf, 0x000034db)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x000056fd, 0x00004795)</Identifier>
<Source>
<BoxIdentifier>(0x000014bf, 0x000034db)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00007e4e, 0x00006b7b)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x2336eb7d, 0x44803e51)</Identifier>
<Source>
<BoxIdentifier>(0x4ff47ca1, 0x133bd33b)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000046bc, 0x00003f08)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x384b6f31, 0x639fff7d)</Identifier>
<Source>
<BoxIdentifier>(0x4ff47ca1, 0x133bd33b)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000014bf, 0x000034db)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x771fd1ca, 0x72794515)</Identifier>
<Source>
<BoxIdentifier>(0x000046bc, 0x00003f08)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00003f1b, 0x00003c78)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x7c0285ed, 0x7aaf8bb7)</Identifier>
<Source>
<BoxIdentifier>(0x00006b6d, 0x00002690)</BoxIdentifier>
<BoxOutputIndex>1</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x4ff47ca1, 0x133bd33b)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
</Links>
<Comments>
<Comment>
<Identifier>(0x000028e8, 0x00003dee)</Identifier>
<Text>&lt;u&gt;&lt;b&gt;&lt;big&gt;Scenario Overview&lt;/big&gt;&lt;/b&gt;&lt;/u&gt;

This scenario can be used in order
to check the quality of the signals
before starting an experiment.

One should &lt;u&gt;definitely&lt;/u&gt;
check the quality of the signals
and ensure that :

- &lt;b&gt;eye blinks&lt;/b&gt; are visible
- &lt;b&gt;jaw clenching&lt;/b&gt; are visible
- &lt;b&gt;alpha waves&lt;/b&gt; are visible when closing eyes

Two Signals are displayed, one is the raw EEG-Signal
and the other one is the filtered signal.
The filtered signal is the one, that will actually be used
in other scenarios.</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>576</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>272</Value>
</Attribute>
</Attributes>
</Comment>
</Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"height":635,"identifier":"(0x000077ee, 0x0000254d)","name":"default","parentIdentifier":"(0xffffffff, 0xffffffff)","type":1,"width":783},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":1,"identifier":"(0x00004579, 0x00005fcb)","index":0,"name":"Default tab","parentIdentifier":"(0x000077ee, 0x0000254d)","type":2},{"boxIdentifier":"(0xffffffff, 0xffffffff)","childCount":2,"dividerPosition":293,"identifier":"(0x00005446, 0x000043a1)","index":0,"maxDividerPosition":590,"name":"Vertical split","parentIdentifier":"(0x00004579, 0x00005fcb)","type":4},{"boxIdentifier":"(0x00005c5c, 0x00007610)","childCount":0,"identifier":"(0x00000e42, 0x000074b8)","index":0,"parentIdentifier":"(0x00005446, 0x000043a1)","type":3},{"boxIdentifier":"(0x00007e4e, 0x00006b7b)","childCount":0,"identifier":"(0x00005db7, 0x000032ad)","index":1,"parentIdentifier":"(0x00005446, 0x000043a1)","type":3}]</Data>
</Entry>
</Metadata>
<Attributes>
<Attribute>
<Identifier>(0x790d75b8, 0x3bb90c33)</Identifier>
<Value>Yann Renard</Value>
</Attribute>
<Attribute>
<Identifier>(0x8c1fc55b, 0x7b433dc2)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x9f5c4075, 0x4a0d3666)</Identifier>
<Value>Signal Monitoring</Value>
</Attribute>
<Attribute>
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
<Value>http://openvibe.inria.fr/p300-speller-xdawn/</Value>
</Attribute>
<Attribute>
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
<Value>xDAWN P300 Speller</Value>
</Attribute>
<Attribute>
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
<Value>INRIA</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>

+ 0
- 1210
scenarios/p300-tactile-1-acquisition.xml
File diff suppressed because it is too large
View File


+ 0
- 438
scenarios/p300-tactile-2-train-xDAWN.xml View File

<OpenViBE-Scenario>
<FormatVersion>2</FormatVersion>
<Creator>OpenViBE Designer</Creator>
<CreatorVersion>3.3.0</CreatorVersion>
<Settings></Settings>
<Inputs></Inputs>
<Outputs></Outputs>
<Boxes>
<Box>
<Identifier>(0x00001db8, 0x00001848)</Identifier>
<Name>xDAWN Trainer</Name>
<AlgorithmClassIdentifier>(0x27542f6e, 0x14aa3548)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Session signal</Name>
</Input>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Evoked potential epochs</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Train-completed Flag</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Train stimulation</Name>
<DefaultValue>OVTK_StimulationId_Train</DefaultValue>
<Value>${SPATIAL_TRAIN_TRIGGER}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Spatial filter configuration</Name>
<DefaultValue></DefaultValue>
<Value>${SPATIAL_FILTER_CONFIG}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Filter dimension</Name>
<DefaultValue>4</DefaultValue>
<Value>${FILTER_DIMENSION}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Save as box config</Name>
<DefaultValue>true</DefaultValue>
<Value>true</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>176</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>288</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x4b49a133, 0x42f38d94)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00002514, 0x00001614)</Identifier>
<Name>Generic stream reader</Name>
<AlgorithmClassIdentifier>(0x6468099f, 0x0370095a)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x403488e7, 0x565d70b6)</TypeIdentifier>
<Name>Output stream 1</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output stream 2</Name>
</Output>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Output stream 3</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue></DefaultValue>
<Value>${INPUT_FILE_NAME}</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>-128</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xf37b8e7a, 0x1bc33e4e)</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0000267a, 0x0000427f)</Identifier>
<Name>Time based epoching</Name>
<AlgorithmClassIdentifier>(0x00777fa0, 0x5dc3f560)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Epoched signal 1</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Epoch 1 duration (in sec)</Name>
<DefaultValue>1</DefaultValue>
<Value>0.250000</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Epoch 1 intervals (in sec)</Name>
<DefaultValue>0.5</DefaultValue>
<Value>0.250000</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>-16</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>288</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xc5ff41e9, 0xccc59a01)</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00004aea, 0x00001465)</Identifier>
<Name>Player Controller</Name>
<AlgorithmClassIdentifier>(0x5f426dce, 0x08456e13)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Stimulation name</Name>
<DefaultValue>OVTK_StimulationId_Label_00</DefaultValue>
<Value>OVTK_StimulationId_TrainCompleted</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0xcc14d8d6, 0xf27ecb73)</TypeIdentifier>
<Name>Action to perform</Name>
<DefaultValue>Pause</DefaultValue>
<Value>Stop</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>240</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>288</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x568d148e, 0x650792b3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00006fa4, 0x00003c77)</Identifier>
<Name>Target Selection</Name>
<AlgorithmClassIdentifier>(0x426163d1, 0x324237b0)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Input stimulations</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Epoched signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Epoch duration (in sec)</Name>
<DefaultValue>1</DefaultValue>
<Value>0.6</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Epoch offset (in sec)</Name>
<DefaultValue>0.5</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Stimulation to epoch from</Name>
<DefaultValue>OVTK_GDF_VEP</DefaultValue>
<Value>OVTK_StimulationId_Target</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>64</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>416</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x5de31172, 0xa1304456)</Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x00003920, 0x00007a30)</Identifier>
<Source>
<BoxIdentifier>(0x0000267a, 0x0000427f)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00001db8, 0x00001848)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00004bf5, 0x00007908)</Identifier>
<Source>
<BoxIdentifier>(0x00001db8, 0x00001848)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00004aea, 0x00001465)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x000059e8, 0x00000032)</Identifier>
<Source>
<BoxIdentifier>(0x00002514, 0x00001614)</BoxIdentifier>
<BoxOutputIndex>2</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00001db8, 0x00001848)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00006913, 0x00003182)</Identifier>
<Source>
<BoxIdentifier>(0x00002514, 0x00001614)</BoxIdentifier>
<BoxOutputIndex>1</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0000267a, 0x0000427f)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x074b170c, 0x37e84571)</Identifier>
<Source>
<BoxIdentifier>(0x0000267a, 0x0000427f)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00006fa4, 0x00003c77)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x188f2058, 0x7ac23f09)</Identifier>
<Source>
<BoxIdentifier>(0x00006fa4, 0x00003c77)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00001db8, 0x00001848)</BoxIdentifier>
<BoxInputIndex>2</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x2b245a90, 0x47f6e438)</Identifier>
<Source>
<BoxIdentifier>(0x00002514, 0x00001614)</BoxIdentifier>
<BoxOutputIndex>2</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00006fa4, 0x00003c77)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
</Links>
<Comments>
<Comment>
<Identifier>(0x000049d6, 0x00006e67)</Identifier>
<Text>&lt;u&gt;&lt;b&gt;&lt;big&gt;Scenario Overview&lt;/big&gt;&lt;/b&gt;&lt;/u&gt;

This scenario should be used to train
the spatial filter using the xDAWN algorithm.

At the end of the training, you will have line in
the console about eigen values.
Using a &lt;i&gt;Player Controller&lt;/i&gt; the scenario will
automatically pause at the end of the training.

If you want details on this values, you should read
&lt;u&gt;http://www.icp.inpg.fr/~rivetber/Publications/references/Rivet2009a.pdf&lt;/u&gt;</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>704</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>-32</Value>
</Attribute>
</Attributes>
</Comment>
</Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[]</Data>
</Entry>
</Metadata>
<Attributes>
<Attribute>
<Identifier>(0x790d75b8, 0x3bb90c33)</Identifier>
<Value>Yann Renard</Value>
</Attribute>
<Attribute>
<Identifier>(0x8c1fc55b, 0x7b433dc2)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x9f5c4075, 0x4a0d3666)</Identifier>
<Value>Spatial Filter Training</Value>
</Attribute>
<Attribute>
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
<Value>http://openvibe.inria.fr/p300-speller-xdawn/</Value>
</Attribute>
<Attribute>
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
<Value>xDAWN P300 Speller</Value>
</Attribute>
<Attribute>
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
<Value>INRIA</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>

+ 0
- 898
scenarios/p300-tactile-3-train-classifier.xml View File

<OpenViBE-Scenario>
<FormatVersion>2</FormatVersion>
<Creator>OpenViBE Designer</Creator>
<CreatorVersion>3.3.0</CreatorVersion>
<Settings></Settings>
<Inputs></Inputs>
<Outputs></Outputs>
<Boxes>
<Box>
<Identifier>(0x00000b2d, 0x00006d61)</Identifier>
<Name>Feature aggregator</Name>
<AlgorithmClassIdentifier>(0x00682417, 0x453635f9)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
<Name>Input stream 1</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x17341935, 0x152ff448)</TypeIdentifier>
<Name>Feature vector stream</Name>
</Output>
</Outputs>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>240</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xb5d15cc9, 0x6c8c28fb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x002bb807)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00000d41, 0x000013b7)</Identifier>
<Name>Feature aggregator</Name>
<AlgorithmClassIdentifier>(0x00682417, 0x453635f9)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x544a003e, 0x6dcba5f6)</TypeIdentifier>
<Name>Input stream 1</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x17341935, 0x152ff448)</TypeIdentifier>
<Name>Feature vector stream</Name>
</Output>
</Outputs>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>240</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>528</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xb5d15cc9, 0x6c8c28fb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x002b7d6e)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00001f83, 0x00004e32)</Identifier>
<Name>Generic stream reader</Name>
<AlgorithmClassIdentifier>(0x6468099f, 0x0370095a)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x403488e7, 0x565d70b6)</TypeIdentifier>
<Name>Output stream 1</Name>
</Output>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output stream 2</Name>
</Output>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Output stream 3</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename</Name>
<DefaultValue></DefaultValue>
<Value>${INPUT_FILE_NAME}</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>-160</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>400</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xf37b8e7a, 0x1bc33e4e)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x008e34c7)</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00002c8b, 0x000001d5)</Identifier>
<Name>Player Controller</Name>
<AlgorithmClassIdentifier>(0x5f426dce, 0x08456e13)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
</Inputs>
<Settings>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Stimulation name</Name>
<DefaultValue>OVTK_StimulationId_Label_00</DefaultValue>
<Value>OVTK_StimulationId_TrainCompleted</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0xcc14d8d6, 0xf27ecb73)</TypeIdentifier>
<Name>Action to perform</Name>
<DefaultValue>Pause</DefaultValue>
<Value>Stop</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>416</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>448</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x568d148e, 0x650792b3)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x00301c7f)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00002f94, 0x00000342)</Identifier>
<Name>Non Target Selection</Name>
<AlgorithmClassIdentifier>(0x426163d1, 0x324237b0)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Input stimulations</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Epoched signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Epoch duration (in sec)</Name>
<DefaultValue>1</DefaultValue>
<Value>0.6</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Epoch offset (in sec)</Name>
<DefaultValue>0.5</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Stimulation to epoch from</Name>
<DefaultValue>OVTK_GDF_VEP</DefaultValue>
<Value>OVTK_StimulationId_NonTarget</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>112</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>528</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x5de31172, 0xa1304456)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x002bbddf)</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000063a5, 0x0000197d)</Identifier>
<Name>Target Selection</Name>
<AlgorithmClassIdentifier>(0x426163d1, 0x324237b0)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input signal</Name>
</Input>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Input stimulations</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Epoched signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Epoch duration (in sec)</Name>
<DefaultValue>1</DefaultValue>
<Value>0.6</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Epoch offset (in sec)</Name>
<DefaultValue>0.5</DefaultValue>
<Value>0</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Stimulation to epoch from</Name>
<DefaultValue>OVTK_GDF_VEP</DefaultValue>
<Value>OVTK_StimulationId_Target</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>112</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x5de31172, 0xa1304456)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x002b4e91)</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000078d0, 0x000029bc)</Identifier>
<Name>Epoch average</Name>
<AlgorithmClassIdentifier>(0x21283d9f, 0xe76ff640)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input epochs</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Averaged epochs</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x6530bdb1, 0xd057bbfe)</TypeIdentifier>
<Name>Averaging type</Name>
<DefaultValue>Epoch block average</DefaultValue>
<Value>Epoch block average</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Epoch count</Name>
<DefaultValue>4</DefaultValue>
<Value>1</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>176</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xb73cee83, 0xf7215d60)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x8d21ff41, 0xdf6afe7e)</Identifier>
<Value>${Player_ScenarioDirectory}/cfg/p300-epoch-average.cfg</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x002b5470)</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x000078f9, 0x000063eb)</Identifier>
<Name>xDAWN Spatial Filter</Name>
<AlgorithmClassIdentifier>(0xdd332c6c, 0x195b4fd4)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input Signal</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Output Signal</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Spatial Filter Coefficients</Name>
<DefaultValue>1;0;0;0;0;1;0;0;0;0;1;0;0;0;0;1</DefaultValue>
<Value>9.970221e-001 -3.729500e-002 -1.177390e-002 2.814447e-002 -3.772446e-003 3.371324e-002 -5.480030e-003 8.893039e-003 -1.565213e-002 -9.956694e-003 -2.347757e-002 -2.312669e-003 -1.847227e-002 -7.550644e-004 -8.423513e-003 3.243223e-002 2.079848e-002 5.079737e-001 -2.835127e-002 8.259231e-002 -3.621803e-001 -2.004259e-001 -2.432480e-001 -1.861558e-001 -3.798139e-001 9.614762e-002 3.407766e-001 -2.158597e-001 3.720552e-001 7.500469e-002 -8.628774e-002 -3.182367e-002 5.923482e-002 4.124707e-001 2.083913e-001 -2.629501e-001 2.023081e-001 -2.658446e-001 4.022738e-001 -1.785569e-001 4.450742e-001 3.549239e-001 1.550204e-002 3.750389e-002 3.114249e-002 9.273764e-002 -7.093797e-002 -2.610929e-001</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Number of Output Channels</Name>
<DefaultValue>4</DefaultValue>
<Value>3</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Number of Input Channels</Name>
<DefaultValue>4</DefaultValue>
<Value>16</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filter matrix file</Name>
<DefaultValue></DefaultValue>
<Value></Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>-32</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>304</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x81db9bf9, 0xf1cf4ed7)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x8d21ff41, 0xdf6afe7e)</Identifier>
<Value>${SPATIAL_FILTER_CONFIG}</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x002b601f)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>1</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00007b56, 0x000033f9)</Identifier>
<Name>Epoch average</Name>
<AlgorithmClassIdentifier>(0x21283d9f, 0xe76ff640)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Input epochs</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x5ba36127, 0x195feae1)</TypeIdentifier>
<Name>Averaged epochs</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x6530bdb1, 0xd057bbfe)</TypeIdentifier>
<Name>Averaging type</Name>
<DefaultValue>Epoch block average</DefaultValue>
<Value>Epoch block average</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Epoch count</Name>
<DefaultValue>4</DefaultValue>
<Value>1</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>176</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>528</Value>
</Attribute>
<Attribute>
<Identifier>(0x30a4e5c9, 0x83502953)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xb73cee83, 0xf7215d60)</Value>
</Attribute>
<Attribute>
<Identifier>(0x527ad68d, 0x16d746a0)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x8d21ff41, 0xdf6afe7e)</Identifier>
<Value>${Player_ScenarioDirectory}/cfg/p300-epoch-average.cfg</Value>
</Attribute>
<Attribute>
<Identifier>(0xc46b3d00, 0x3e0454e1)</Identifier>
<Value>(0x00000000, 0x002c2168)</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x0a5a6a4a, 0x1d92a778)</Identifier>
<Name>Classifier trainer</Name>
<AlgorithmClassIdentifier>(0xf3dae8a8, 0x3b444154)</AlgorithmClassIdentifier>
<Inputs>
<Input>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Input>
<Input>
<TypeIdentifier>(0x17341935, 0x152ff448)</TypeIdentifier>
<Name>Features for class 1</Name>
</Input>
<Input>
<TypeIdentifier>(0x17341935, 0x152ff448)</TypeIdentifier>
<Name>Features for class 2</Name>
</Input>
</Inputs>
<Outputs>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Train-completed Flag</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Train trigger</Name>
<DefaultValue>OVTK_StimulationId_Train</DefaultValue>
<Value>${CLASSIFIER_TRAIN_TRIGGER}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Filename to save configuration to</Name>
<DefaultValue>${Path_UserData}/my-classifier.xml</DefaultValue>
<Value>${CLASSIFIER_CONFIG}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0xbe9eba5c, 0xa8415d37)</TypeIdentifier>
<Name>Multiclass strategy to apply</Name>
<DefaultValue>Native</DefaultValue>
<Value>${MULTICLASS_STRATEGY}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Class 1 label</Name>
<DefaultValue>OVTK_StimulationId_Label_01</DefaultValue>
<Value>${CLASS_1}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Class 2 label</Name>
<DefaultValue>OVTK_StimulationId_Label_02</DefaultValue>
<Value>${CLASS_2}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0xd765a736, 0xed708c65)</TypeIdentifier>
<Name>Algorithm to use</Name>
<DefaultValue>Linear Discrimimant Analysis (LDA)</DefaultValue>
<Value>${ALGORITHM}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Use shrinkage</Name>
<DefaultValue>false</DefaultValue>
<Value>${USE_SHRINKAGE}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Shrinkage coefficient (-1 == auto)</Name>
<DefaultValue>-1.000000</DefaultValue>
<Value>${SHRINKAGE_COEFFICIENT}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Shrinkage: Force diagonal cov (DDA)</Name>
<DefaultValue>false</DefaultValue>
<Value>${SHRINKAGE_FORCE_DIAGONAL_COV}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Number of partitions for k-fold cross-validation test</Name>
<DefaultValue>10</DefaultValue>
<Value>${N_PARTITIONS}</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2cdb2f0b, 0x12f231ea)</TypeIdentifier>
<Name>Balance classes</Name>
<DefaultValue>false</DefaultValue>
<Value>${CLASS_BALANCE}</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>336</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>448</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x9de21779, 0x37776c89)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc73e83ec, 0xf855c5bc)</Identifier>
<Value>false</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>6</Value>
</Attribute>
<Attribute>
<Identifier>(0xcfad85b0, 0x7c6d841c)</Identifier>
<Value>3</Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
</Boxes>
<Links>
<Link>
<Identifier>(0x00000192, 0x0000714e)</Identifier>
<Source>
<BoxIdentifier>(0x00001f83, 0x00004e32)</BoxIdentifier>
<BoxOutputIndex>1</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000078f9, 0x000063eb)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00001717, 0x00003cf9)</Identifier>
<Source>
<BoxIdentifier>(0x000078d0, 0x000029bc)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00000b2d, 0x00006d61)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00004674, 0x000061af)</Identifier>
<Source>
<BoxIdentifier>(0x00007b56, 0x000033f9)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00000d41, 0x000013b7)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x0ac1c4d1, 0x0a9429d6)</Identifier>
<Source>
<BoxIdentifier>(0x000063a5, 0x0000197d)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000078d0, 0x000029bc)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x0f719dbe, 0x6b9207ad)</Identifier>
<Source>
<BoxIdentifier>(0x000078f9, 0x000063eb)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00002f94, 0x00000342)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x175e412c, 0x0692f4ee)</Identifier>
<Source>
<BoxIdentifier>(0x00000d41, 0x000013b7)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0a5a6a4a, 0x1d92a778)</BoxIdentifier>
<BoxInputIndex>2</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x26545f2f, 0x4e793786)</Identifier>
<Source>
<BoxIdentifier>(0x000078f9, 0x000063eb)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000063a5, 0x0000197d)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x26dbc15a, 0x2ae965d4)</Identifier>
<Source>
<BoxIdentifier>(0x00001f83, 0x00004e32)</BoxIdentifier>
<BoxOutputIndex>2</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x000063a5, 0x0000197d)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x33c4df2d, 0x7548b76f)</Identifier>
<Source>
<BoxIdentifier>(0x00001f83, 0x00004e32)</BoxIdentifier>
<BoxOutputIndex>2</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00002f94, 0x00000342)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x431fd3b9, 0x43484889)</Identifier>
<Source>
<BoxIdentifier>(0x00002f94, 0x00000342)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00007b56, 0x000033f9)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x5a67b7d8, 0x1cf07f9a)</Identifier>
<Source>
<BoxIdentifier>(0x00001f83, 0x00004e32)</BoxIdentifier>
<BoxOutputIndex>2</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0a5a6a4a, 0x1d92a778)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x616495af, 0x5c020b32)</Identifier>
<Source>
<BoxIdentifier>(0x0a5a6a4a, 0x1d92a778)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00002c8b, 0x000001d5)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x63fa63da, 0x0e447c5b)</Identifier>
<Source>
<BoxIdentifier>(0x00000b2d, 0x00006d61)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x0a5a6a4a, 0x1d92a778)</BoxIdentifier>
<BoxInputIndex>1</BoxInputIndex>
</Target>
</Link>
</Links>
<Comments>
<Comment>
<Identifier>(0x00005277, 0x00007fbe)</Identifier>
<Text>&lt;u&gt;&lt;b&gt;&lt;big&gt;Scenario Overview&lt;/big&gt;&lt;/b&gt;&lt;/u&gt;

This scenario should be used to train
the LDA classifier.

At the end of the training, you will have an estimation
of the classifier performance printed in the console.
If this performance is lower than 70%, just run a new
&lt;i&gt;4-online&lt;/i&gt; session to have better results.

&lt;u&gt;&lt;b&gt;Note:&lt;/b&gt;&lt;/u&gt; in order to run this scenario,
the spatial filter should have been trained using
&lt;i&gt;2-train-xDAWN&lt;/i&gt; !</Text>
<Attributes>
<Attribute>
<Identifier>(0x473d9a43, 0x97fc0a97)</Identifier>
<Value>688</Value>
</Attribute>
<Attribute>
<Identifier>(0x7234b86b, 0x2b8651a5)</Identifier>
<Value>-64</Value>
</Attribute>
</Attributes>
</Comment>
</Comments>
<Metadata>
<Entry>
<Identifier>(0x0000775c, 0x000078ff)</Identifier>
<Type>(0x3bcce5d2, 0x43f2d968)</Type>
<Data>[]</Data>
</Entry>
</Metadata>
<Attributes>
<Attribute>
<Identifier>(0x790d75b8, 0x3bb90c33)</Identifier>
<Value>Yann Renard</Value>
</Attribute>
<Attribute>
<Identifier>(0x8c1fc55b, 0x7b433dc2)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x9f5c4075, 0x4a0d3666)</Identifier>
<Value>LDA Classifier Trainer</Value>
</Attribute>
<Attribute>
<Identifier>(0xf36a1567, 0xd13c53da)</Identifier>
<Value>http://openvibe.inria.fr/p300-speller-xdawn/</Value>
</Attribute>
<Attribute>
<Identifier>(0xf6b2e3fa, 0x7bd43926)</Identifier>
<Value>xDAWN P300 Speller</Value>
</Attribute>
<Attribute>
<Identifier>(0xf8034a49, 0x8b3f37cc)</Identifier>
<Value>INRIA</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>

+ 0
- 1772
scenarios/p300-tactile-4-online.xml
File diff suppressed because it is too large
View File


+ 0
- 199
scenarios/scripts/p300-tactile-accumulator.lua View File


function arrayMax(a)
if #a == 0 then return nil, nil end
local maxIdx, maxValue = 0, a[0]
for i = 1, (#a -1 ) do
if maxValue < a[i] then
maxIdx, maxValue = i, a[i]
end
end
return maxIdx, maxValue
end


List = {}
function List.new ()
return {first = 0, last = -1}
end

function List.pushright (list, value)
local last = list.last + 1
list.last = last
list[last] = value
end

function List.popleft (list)
local first = list.first
if first > list.last then
error("list is empty")
end
local value = list[first]
list[first] = nil -- to allow garbage collection
list.first = first + 1
return value
end

function List.isempty (list)
if list.first > list.last then
return true
else
return false
end
end

function initialize(box)

dofile(box:get_config("${Path_Data}") .. "/plugins/stimulation/lua-stimulator-stim-codes.lua")

row_base = _G[box:get_setting(2)]
n_tactilos = box:get_setting(3)
segment_start = _G[box:get_setting(4)]
segment_stop = _G[box:get_setting(5)]
col_base = row_base + n_tactilos

-- 0 inactive, 1 segment started, 2 segment stopped (can vote)
segment_status = 0

-- the idea is to push the flash states to the fifo, and when predictions arrive (with some delay), they are matched in oldest-first fashion.
target_fifo = List.new()
-- box:log("Info", string.format("pop %d %d", id[1], id[2]))
row_votes = {}
col_votes = {}
do_debug = false
end

function uninitialize(box)
end
function process(box)
-- loops until box is stopped
while box:keep_processing() do
-- first, parse the timeline stream
for stimulation = 1, box:get_stimulation_count(2) do
-- gets the received stimulation
local identifier, date, duration = box:get_stimulation(2, 1)
-- discards it
box:remove_stimulation(2, 1)

if identifier == segment_start then
if do_debug then
box:log("Info", string.format("Trial start"))
box:log("Info", string.format("Clear votes"))
end
-- zero the votes
col_votes = {}
row_votes = {}
target_fifo = List.new()
-- fixme fixed 20
for i = 0,20 do
col_votes[i] = 0
row_votes[i] = 0
end
segment_status = 1
end

-- Does the identifier code a flash? if so, put into fifo
if segment_status == 1 and identifier >= row_base and identifier <= OVTK_StimulationId_LabelEnd then
-- assume rows before cols
if identifier < col_base then
local t = {"row", identifier - row_base}
List.pushright(target_fifo,t)
if do_debug then
box:log("Info", string.format("Push row target %d", identifier - row_base ))
end
else
local t = {"col", identifier - col_base}
List.pushright(target_fifo,t)
if do_debug then
box:log("Info", string.format("Push col target %d", identifier - col_base ))
end
end
end

if identifier == segment_stop then
if do_debug then
box:log("Info", string.format("Trial stop"))
end
segment_status = 2
end

end
-- then parse the classifications
for stimulation = 1, box:get_stimulation_count(1) do

-- gets the received stimulation
local identifier, date, duration = box:get_stimulation(1, 1)
-- discards it
box:remove_stimulation(1, 1)

-- Is it an in-class prediction?
if identifier == OVTK_StimulationId_Target then
local t = List.popleft(target_fifo)
if do_debug then
box:log("Info", string.format("Pred fifo %s %d is target", t[1], t[2]))
end
if t[1]=="row" then
row_votes[t[2]] = row_votes[t[2]] + 1
else
col_votes[t[2]] = col_votes[t[2]] + 1
end
end
if identifier == OVTK_StimulationId_NonTarget then
local t = List.popleft(target_fifo)
if do_debug then
box:log("Info", string.format("Pred fifo %s %d is nontarget", t[1], t[2]))
end
end
end
if segment_status == 2 and List.isempty(target_fifo) then
-- output the vote after the segment end when we've matched all predictions
local maxRowIdx, maxRowValue = arrayMax(row_votes)
local maxColIdx, maxColValue = arrayMax(col_votes)

if maxRowValue == 0 and maxColValue == 0 then
box:log("Warning", string.format("Classifier predicted 'no p300' for all flashes of the trial"));
end
if do_debug then
local rowVotes = 0
local colVotes = 0
for ir, val in pairs(row_votes) do
rowVotes = rowVotes + val
end
for ir, val in pairs(col_votes) do
colVotes = colVotes + val
end
box:log("Info", string.format("Vote [%d %d] wt [%d,%d]", maxRowIdx+row_base, maxColIdx+col_base, maxRowValue, maxColValue))
box:log("Info", string.format(" Total [%d %d]", rowVotes, colVotes))
end

local now = box:get_current_time()
box:send_stimulation(1, maxRowIdx + row_base, now, 0)
-- box:send_stimulation(2, maxColIdx + col_base, now, 0)
segment_status = 0
end

box:sleep()
end
end


+ 0
- 57
scenarios/scripts/p300-tactile-filter-flash.lua View File



function initialize(box)

dofile(box:get_config("${Path_Data}") .. "/plugins/stimulation/lua-stimulator-stim-codes.lua")
box:set_filter_mode(1);
state = 0
do_debug = false
end

function uninitialize(box)
end

function process(box)

-- loop until box:keep_processing() returns zero
-- cpu will be released with a call to sleep
-- at the end of the loop
while box:keep_processing() do

-- gets current simulated time
t = box:get_current_time()

-- loops on every received stimulation for a given input
for stimulation = 1, box:get_stimulation_count(1) do

-- gets stimulation
stimulation_id, stimulation_time, stimulation_duration = box:get_stimulation(1, 1)

if stimulation_id == OVTK_StimulationId_SegmentStart then
state = 1
elseif stimulation_id == OVTK_StimulationId_SegmentStop then
state = 0
end

-- If we're between 'rest start' and 'rest_stop', this specifies a target
if state == 1 and stimulation_id >= OVTK_StimulationId_LabelStart and stimulation_id <= OVTK_StimulationId_LabelEnd then
box:send_stimulation(1, stimulation_id, stimulation_time, 0)

if do_debug then
box:log("Info", string.format("Push a target %d at %f (now %f)", stimulation_id, stimulation_time, t))
end
end
-- discards it
box:remove_stimulation(1, 1)

end

-- releases cpu
box:sleep()
end
end

+ 0
- 57
scenarios/scripts/p300-tactile-filter-target.lua View File



function initialize(box)

dofile(box:get_config("${Path_Data}") .. "/plugins/stimulation/lua-stimulator-stim-codes.lua")
state = 0
box:set_filter_mode(1);
do_debug = false
end

function uninitialize(box)
end

function process(box)

-- loop until box:keep_processing() returns zero
-- cpu will be released with a call to sleep
-- at the end of the loop
while box:keep_processing() do

-- gets current simulated time
t = box:get_current_time()

-- loops on every received stimulation for a given input
for stimulation = 1, box:get_stimulation_count(1) do

-- gets stimulation
stimulation_id, stimulation_time, stimulation_duration = box:get_stimulation(1, 1)

if stimulation_id == OVTK_StimulationId_RestStart then
state = 1
elseif stimulation_id == OVTK_StimulationId_RestStop then
state = 0
end

-- If we're between 'rest start' and 'rest_stop', this specifies a target
if state == 1 and stimulation_id >= OVTK_StimulationId_LabelStart and stimulation_id <= OVTK_StimulationId_LabelEnd then
box:send_stimulation(1, stimulation_id, stimulation_time, 0)

if do_debug then
box:log("Info", string.format("Push a target %d at %f (now = %f)", stimulation_id, stimulation_time, t))
end
end
-- discards it
box:remove_stimulation(1, 1)

end

-- releases cpu
box:sleep()
end
end

+ 0
- 18
scenarios/scripts/p300-tactile-launch.lua View File


function initialize(box)

dofile(box:get_config("${Path_Data}") .. "/plugins/stimulation/lua-stimulator-stim-codes.lua")

stim = _G[box:get_setting(2)]
launchTime = box:get_setting(3)
end

function uninitialize(box)
end

function process(box)

box:send_stimulation(1, stim, launchTime, 0)

end

+ 0
- 131
scenarios/scripts/p300-tactile-stimulator.lua View File

--

--This function lets the box sleep until a fixed moment
function wait_until(box, time)
while box:get_current_time() < time do
box:sleep()
end
end

--This function lets the box wait for a fixed duration
function wait_for(box, duration)
wait_until(box, box:get_current_time() + duration)
end

--this function checks, wether value already is an element of the given stim_matrix
function is_element(matrix, value)
for i = 1, #matrix do
if #matrix == 0 then
return(false)
elseif value == matrix[i] then
return(true)
end
end
return(false)
end
--this function creates a sequence of stimulations by shuffeling the values of the given stim_matrix
function create_sequence(matrix)
local stim_matrix = {}
local stim_code = 0
local i = 1
while i <= #matrix do
stim_code = matrix[math.random(1,#matrix)]
if is_element(stim_matrix, stim_code) == false then
stim_matrix[i] = stim_code
i = i + 1
end
end
return(stim_matrix)
end

function initialize(box)
--randomseed
math.randomseed(os.time())
--load stimulation codes
dofile(box:get_config("${Path_Data}") .. "/plugins/stimulation/lua-stimulator-stim-codes.lua")
--load box settings
row_base = _G[box:get_setting(2)]
n_tactilos = box:get_setting(3)
n_repetitions = box:get_setting(4)
n_trials = box:get_setting(5)
flash_duration = box:get_setting(6)
noflash_duration = box:get_setting(7)
inter_repetition_delay = box:get_setting(8)
inter_trial_delay = box:get_setting(9)
send_toggle = _G[box:get_setting(10)]
free_spelling = box:get_setting(11)
time_to_send = box:get_setting(12)
--Set number of trials to 1 in free spelling mode
if free_spelling == 'true' then
n_trials = 1
end
--Lua variables
send = false
experiment_end = false
tactilo_stimcodes = {}
for x = 1, n_tactilos do
tactilo_stimcodes[x] = row_base + x - 1
end
end

function uninitialize(box)

end

function process(box)
while box:keep_processing() do
if send and not experiment_end then
-- iterate over the number of trials
for trial = 1, n_trials do
box:send_stimulation(1, OVTK_StimulationId_RestStart, box:get_current_time() , 0)
wait_for(box, inter_trial_delay)
box:send_stimulation(1, OVTK_StimulationId_RestStop, box:get_current_time() , 0)
box:send_stimulation(1, OVTK_StimulationId_TrialStart ,box:get_current_time() , 0)
-- iterate over the number of repetitions
for segment = 1, n_repetitions do
tactilo_stimcodes = create_sequence(tactilo_stimcodes)
box:send_stimulation(1, OVTK_StimulationId_SegmentStart ,box:get_current_time() , 0)
-- iterate over the number of tactilos
for i = 1, #tactilo_stimcodes do
box:send_stimulation(1, tactilo_stimcodes[i] ,box:get_current_time() , 0)
box:send_stimulation(1, OVTK_StimulationId_VisualStimulationStart ,box:get_current_time() , 0)
wait_for(box, flash_duration)
box:send_stimulation(1, OVTK_StimulationId_VisualStimulationStop ,box:get_current_time() , 0)
wait_for(box, noflash_duration)
end
box:send_stimulation(1, OVTK_StimulationId_SegmentStop ,box:get_current_time() , 0)
wait_for(box, inter_repetition_delay)
end
box:send_stimulation(1, OVTK_StimulationId_TrialStop ,box:get_current_time() , 0)
end
if free_spelling == 'false' then
-- end experiment if set to copy spelling
box:send_stimulation(1, OVTK_StimulationId_ExperimentStop ,box:get_current_time() , 0)
send = false
experiment_end = true
end
else if not send and not experiment_end then
-- delay the start of the experiment by t = time_to_send
wait_for(box, time_to_send)
send = true
box:send_stimulation(1, OVTK_StimulationId_ExperimentStart ,box:get_current_time() , 0)
end
end
-- releases cpu
box:sleep()
end
end

+ 0
- 55
scenarios/scripts/p300-tactile-target.lua View File

--

function initialize(box)

dofile(box:get_config("${Path_Data}") .. "/plugins/stimulation/lua-stimulator-stim-codes.lua")

math.randomseed(os.time())
row_base = _G[box:get_setting(2)]
n_tactilos = box:get_setting(3)
delay = box:get_setting(4)
free_spelling = box:get_setting(5)

end

function uninitialize(box)
end

function process(box)

-- loop until box:keep_processing() returns zero
-- cpu will be released with a call to sleep
-- at the end of the loop
while box:keep_processing() do

-- gets current simulated time
t = box:get_current_time()
-- loops on every received stimulation for a given input
for stimulation = 1, box:get_stimulation_count(1) do

-- gets stimulation
stimulation_id, stimulation_time, stimulation_duration = box:get_stimulation(1, 1)
if free_spelling == 'false' then
if stimulation_id == OVTK_StimulationId_RestStart then

-- triggers the target
box:send_stimulation(1, row_base+math.random(1,n_tactilos)-1, t+delay, 0)

elseif stimulation_id == OVTK_StimulationId_ExperimentStop then

-- triggers train stimulation
box:send_stimulation(1, OVTK_StimulationId_Train, t+delay+1, 0)

end
end
-- discards it
box:remove_stimulation(1, 1)

end

-- releases cpu
box:sleep()
end
end

+ 0
- 3
scenarios/signals/README.txt View File


The scenario will record its signals here.


+ 0
- 321
scenarios/ui/p300-tactile-10.ui View File

<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="p300-tactile">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkTable" id="p300-tactile-main">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkTable" id="p300-tactile-table">
<property name="visible">True</property>
<property name="n_rows">10</property>
<property name="n_columns">1</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkEventBox" id="eventbox-1">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-1">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo1</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-2">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-2">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo2</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-3">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-3">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo3</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-4">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-4">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo4</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-5">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-5">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo5</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-6">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-6">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo6</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-7">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-7">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo7</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-8">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-8">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo8</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">7</property>
<property name="bottom_attach">8</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-9">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-9">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo9</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">8</property>
<property name="bottom_attach">9</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-10">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-10">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo10</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">9</property>
<property name="bottom_attach">10</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkTable" id="p300-tactile-table-target-result">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="column_spacing">4</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkLabel" id="label-result">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-result-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Result :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Target :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image">
<property name="visible">True</property>
<property name="stock">gtk-select-font</property>
</object>
<packing>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator">
<property name="visible">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="p300-tactile-toolbar">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes">P300 tactile</property>
<property name="type_hint">dialog</property>
<child>
<object class="GtkToolbar" id="toolbar">
<property name="width_request">640</property>
<property name="visible">True</property>
<property name="toolbar_style">both</property>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_target_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Target Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_result_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Result Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

+ 0
- 185
scenarios/ui/p300-tactile-2.ui View File

<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="p300-tactile">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkTable" id="p300-tactile-main">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkTable" id="p300-tactile-table">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">1</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkEventBox" id="eventbox-1">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-1">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo1</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-2">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-2">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo2</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkTable" id="p300-tactile-table-target-result">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="column_spacing">4</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkLabel" id="label-result">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-result-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Result :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Target :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image">
<property name="visible">True</property>
<property name="stock">gtk-select-font</property>
</object>
<packing>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator">
<property name="visible">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="p300-tactile-toolbar">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes">P300 tactile</property>
<property name="type_hint">dialog</property>
<child>
<object class="GtkToolbar" id="toolbar">
<property name="width_request">640</property>
<property name="visible">True</property>
<property name="toolbar_style">both</property>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_target_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Target Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_result_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Result Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

+ 0
- 202
scenarios/ui/p300-tactile-3.ui View File

<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="p300-tactile">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkTable" id="p300-tactile-main">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkTable" id="p300-tactile-table">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_columns">1</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkEventBox" id="eventbox-1">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-1">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo1</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-2">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-2">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo2</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-3">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-3">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo3</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkTable" id="p300-tactile-table-target-result">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="column_spacing">4</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkLabel" id="label-result">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-result-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Result :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Target :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image">
<property name="visible">True</property>
<property name="stock">gtk-select-font</property>
</object>
<packing>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator">
<property name="visible">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="p300-tactile-toolbar">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes">P300 tactile</property>
<property name="type_hint">dialog</property>
<child>
<object class="GtkToolbar" id="toolbar">
<property name="width_request">640</property>
<property name="visible">True</property>
<property name="toolbar_style">both</property>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_target_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Target Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_result_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Result Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

+ 0
- 219
scenarios/ui/p300-tactile-4.ui View File

<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="p300-tactile">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkTable" id="p300-tactile-main">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkTable" id="p300-tactile-table">
<property name="visible">True</property>
<property name="n_rows">4</property>
<property name="n_columns">1</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkEventBox" id="eventbox-1">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-1">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo1</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-2">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-2">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo2</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-3">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-3">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo3</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-4">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-4">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo4</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkTable" id="p300-tactile-table-target-result">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="column_spacing">4</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkLabel" id="label-result">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-result-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Result :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Target :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image">
<property name="visible">True</property>
<property name="stock">gtk-select-font</property>
</object>
<packing>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator">
<property name="visible">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="p300-tactile-toolbar">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes">P300 tactile</property>
<property name="type_hint">dialog</property>
<child>
<object class="GtkToolbar" id="toolbar">
<property name="width_request">640</property>
<property name="visible">True</property>
<property name="toolbar_style">both</property>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_target_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Target Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_result_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Result Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

+ 0
- 235
scenarios/ui/p300-tactile-5.ui View File

<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="p300-tactile">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkTable" id="p300-tactile-main">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkTable" id="p300-tactile-table">
<property name="visible">True</property>
<property name="n_rows">5</property>
<property name="n_columns">1</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkEventBox" id="eventbox-1">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-1">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo1</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-2">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-2">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo2</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-3">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-3">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo3</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-4">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-4">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo4</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-5">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-5">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo5</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
</child>
<child>
<object class="GtkTable" id="p300-tactile-table-target-result">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="column_spacing">4</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkLabel" id="label-result">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-result-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Result :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Target :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image">
<property name="visible">True</property>
<property name="stock">gtk-select-font</property>
</object>
<packing>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator">
<property name="visible">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="p300-tactile-toolbar">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes">P300 tactile</property>
<property name="type_hint">dialog</property>
<child>
<object class="GtkToolbar" id="toolbar">
<property name="width_request">640</property>
<property name="visible">True</property>
<property name="toolbar_style">both</property>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_target_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Target Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_result_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Result Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

+ 0
- 253
scenarios/ui/p300-tactile-6.ui View File

<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="p300-tactile">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkTable" id="p300-tactile-main">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkTable" id="p300-tactile-table">
<property name="visible">True</property>
<property name="n_rows">6</property>
<property name="n_columns">1</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkEventBox" id="eventbox-1">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-1">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo1</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-2">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-2">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo2</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-3">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-3">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo3</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-4">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-4">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo4</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-5">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-5">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo5</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-6">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-6">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo6</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkTable" id="p300-tactile-table-target-result">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="column_spacing">4</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkLabel" id="label-result">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-result-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Result :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Target :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image">
<property name="visible">True</property>
<property name="stock">gtk-select-font</property>
</object>
<packing>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator">
<property name="visible">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="p300-tactile-toolbar">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes">P300 tactile</property>
<property name="type_hint">dialog</property>
<child>
<object class="GtkToolbar" id="toolbar">
<property name="width_request">640</property>
<property name="visible">True</property>
<property name="toolbar_style">both</property>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_target_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Target Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_result_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Result Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

+ 0
- 270
scenarios/ui/p300-tactile-7.ui View File

<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="p300-tactile">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkTable" id="p300-tactile-main">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkTable" id="p300-tactile-table">
<property name="visible">True</property>
<property name="n_rows">7</property>
<property name="n_columns">1</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkEventBox" id="eventbox-1">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-1">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo1</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-2">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-2">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo2</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-3">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-3">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo3</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-4">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-4">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo4</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-5">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-5">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo5</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-6">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-6">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo6</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-7">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-7">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo7</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkTable" id="p300-tactile-table-target-result">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="column_spacing">4</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkLabel" id="label-result">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-result-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Result :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Target :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image">
<property name="visible">True</property>
<property name="stock">gtk-select-font</property>
</object>
<packing>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator">
<property name="visible">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="p300-tactile-toolbar">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes">P300 tactile</property>
<property name="type_hint">dialog</property>
<child>
<object class="GtkToolbar" id="toolbar">
<property name="width_request">640</property>
<property name="visible">True</property>
<property name="toolbar_style">both</property>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_target_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Target Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_result_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Result Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

+ 0
- 287
scenarios/ui/p300-tactile-8.ui View File

<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="p300-tactile">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkTable" id="p300-tactile-main">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkTable" id="p300-tactile-table">
<property name="visible">True</property>
<property name="n_rows">8</property>
<property name="n_columns">1</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkEventBox" id="eventbox-1">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-1">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo1</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-2">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-2">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo2</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-3">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-3">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo3</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-4">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-4">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo4</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-5">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-5">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo5</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-6">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-6">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo6</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-7">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-7">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo7</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-8">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-8">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo8</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">7</property>
<property name="bottom_attach">8</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkTable" id="p300-tactile-table-target-result">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="column_spacing">4</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkLabel" id="label-result">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-result-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Result :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Target :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image">
<property name="visible">True</property>
<property name="stock">gtk-select-font</property>
</object>
<packing>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator">
<property name="visible">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="p300-tactile-toolbar">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes">P300 tactile</property>
<property name="type_hint">dialog</property>
<child>
<object class="GtkToolbar" id="toolbar">
<property name="width_request">640</property>
<property name="visible">True</property>
<property name="toolbar_style">both</property>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_target_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Target Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_result_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Result Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

+ 0
- 304
scenarios/ui/p300-tactile-9.ui View File

<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkWindow" id="p300-tactile">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkTable" id="p300-tactile-main">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkTable" id="p300-tactile-table">
<property name="visible">True</property>
<property name="n_rows">9</property>
<property name="n_columns">1</property>
<property name="homogeneous">True</property>
<child>
<object class="GtkEventBox" id="eventbox-1">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-1">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo1</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">1</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-2">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-2">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo2</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-3">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-3">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo3</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-4">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-4">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo4</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-5">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-5">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo5</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-6">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-6">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo6</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-7">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-7">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo7</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-8">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-8">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo8</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">7</property>
<property name="bottom_attach">8</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventbox-9">
<property name="visible">True</property>
<child>
<object class="GtkLabel" id="label-9">
<property name="visible">True</property>
<property name="label" translatable="yes">Tactilo9</property>
<property name="use_markup">True</property>
<property name="justify">center</property>
</object>
</child>
</object>
<packing>
<property name="top_attach">8</property>
<property name="bottom_attach">9</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkTable" id="p300-tactile-table-target-result">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="column_spacing">4</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkLabel" id="label-result">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-result-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Result :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label-target-title">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Target :</property>
<property name="single_line_mode">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkImage" id="image">
<property name="visible">True</property>
<property name="stock">gtk-select-font</property>
</object>
<packing>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="hseparator">
<property name="visible">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkWindow" id="p300-tactile-toolbar">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="title" translatable="yes">P300 tactile</property>
<property name="type_hint">dialog</property>
<child>
<object class="GtkToolbar" id="toolbar">
<property name="width_request">640</property>
<property name="visible">True</property>
<property name="toolbar_style">both</property>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_target_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Target Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToggleToolButton" id="toolbutton-show_result_text">
<property name="visible">True</property>
<property name="label" translatable="yes">Show Result Text</property>
<property name="stock_id">gtk-info</property>
<property name="active">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

+ 0
- 52
src/TactileVisualization/TactileMenu.cpp View File

///-------------------------------------------------------------------------------------------------
///
/// \file TactileMenu.cpp
/// \brief Definitions for class TactileMenu
/// \author Tobias Baumann (TH Nuernberg).
/// \version 1.0.
/// \date Mon Feb 10 17:11:34 2022.
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
///
///-------------------------------------------------------------------------------------------------

//includes
#include "TactileMenu.h"


namespace OpenViBE {
namespace Plugins {
namespace Tactilebci {

//TactileMenu Memberfunctions
TactileMenu::TactileMenu(int n_Tactilos)
{
for(int i = 1; i <= n_Tactilos; i++)
{
m_LabelText.push_back("Tactilo" + std::to_string(i));
m_SubMenu.push_back(nullptr);
}
}

void TactileMenu::set_LabelText(int i, std::string Text)
{
m_LabelText[i] = Text;
}

void TactileMenu::set_SubMenu(int i, TactileMenu* Menu)
{
m_SubMenu[i] = Menu;
}

std::string TactileMenu::get_LabelText(int i)
{
return(m_LabelText[i]);
}

TactileMenu* TactileMenu::get_SubMenu(int i)
{
return(m_SubMenu[i]);
}

} // namespace Tactilebci
} // namespace Plugins
} // namespace OpenViBE

+ 0
- 46
src/TactileVisualization/TactileMenu.h View File

///-------------------------------------------------------------------------------------------------
///
/// \file TactileMenu.h
/// \brief Class for the Menues of the Tactile P300 System
/// \author Tobias Baumann (TH Nuernberg).
/// \version 1.0.
/// \date Mon Feb 10 17:10:32 2022.
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
///
///-------------------------------------------------------------------------------------------------
//includes
#pragma once

#include "../ovp_defines.h"

#include <gtk/gtk.h>
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>

#include <vector>
#include <string>

namespace OpenViBE {
namespace Plugins {
namespace Tactilebci {
//Class TactileMenu
class TactileMenu
{
private:
std::vector<std::string> m_LabelText;
std::vector<TactileMenu*> m_SubMenu;
public:
TactileMenu(int n_Tactilos);
std::string get_LabelText(int i);
TactileMenu* get_SubMenu(int i);
void set_LabelText(int i, std::string Text);
void set_SubMenu(int i, TactileMenu* Menu);
};

} // namespace Tactilebci
} // namespace Plugins
} // namespace OpenViBE

+ 0
- 480
src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.cpp View File

#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(5, &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());
}
}

+ 0
- 162
src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.h View File

///-------------------------------------------------------------------------------------------------
///
/// \file CBoxAlgorithmP300TactileVisualization.h
/// \brief Classes of the Box P300TactileVisualization.
/// \author Tobias Baumann (TH Nuernberg).
/// \version 1.0.
/// \date Sat May 07 14:20:29 2022.
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
///
///-------------------------------------------------------------------------------------------------
#pragma once

//You may have to change this path to match your folder organisation
#include "../ovp_defines.h"
#include "TactileMenu.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <tcptagging/IStimulusSender.h>
#include <visualization-toolkit/ovviz_all.h>

#include <gtk/gtk.h>
#include <list>
#include <map>
#include <vector>
#include <algorithm>
#include <string>
#include "../utils.h"


namespace TCPTagging {
class IStimulusSender; // fwd declare
}

namespace OpenViBE
{
namespace Plugins
{
namespace Tactilebci
{
/// <summary> The class CBoxAlgorithmP300TactileVisualization describes the box P300TactileVisualization. </summary>
class CBoxAlgorithmP300TactileVisualization final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
// ------ OV base functions
void release() override { delete this; }

bool initialize() override;
bool uninitialize() override;

//Process Callback on new input received (the most common behaviour for signal processing) :
bool processInput(const size_t index) override;

bool process() override;

// As we do with any class in openvibe, we use the macro below to associate this box to an unique identifier.
// The inheritance information is also made available, as we provide the superclass Toolkit::TBoxAlgorithm < IBoxAlgorithm >
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_P300TactileVisualization)
// ------ TCP Tagging
void flushQueue();
// ------ UI Functions
void toggleFlashColor(uint64_t id);
void toggleTargetColor(uint64_t id);
void toggleResultColor(uint64_t id);
void resetColor();
void toggleLabelText();
protected:
// ------ Input decoder:
Toolkit::TStimulationDecoder<CBoxAlgorithmP300TactileVisualization> m_SequenceInputDecoder;
Toolkit::TStimulationDecoder<CBoxAlgorithmP300TactileVisualization> m_TargetInputDecoder;
Toolkit::TStimulationDecoder<CBoxAlgorithmP300TactileVisualization> m_ResultInputDecoder;
// ------ Output decoder:
Toolkit::TStimulationEncoder<CBoxAlgorithmP300TactileVisualization> m_ResultOutputEncoder;
private:
uint64_t m_LastTarget = 0;
uint64_t m_LastTime = 0;
// ------ Box setting variables
CString m_InterfaceFilename;
uint64_t m_RowBase = 0;
uint64_t m_nTactilos = 6;
bool m_FreeSpelling = false;
// ------TactileMenu variables
std::vector<TactileMenu> m_Menu;
TactileMenu* m_CurrMenu = nullptr;
// ------ GTK variables
GtkBuilder* m_MainWidgetInterface = nullptr;
GtkWidget* m_MainWindow = nullptr;
GtkTable* m_Table = nullptr;
std::vector<GtkWidget*> m_EventBox;
GtkLabel* m_ResultLabel = nullptr;
GtkLabel* m_TargetLabel = nullptr;
GdkColor m_FlashBG = InitGDKColor(0, 3276, 3276, 3276);
GdkColor m_FlashFG = InitGDKColor(0, 65535, 65535, 65535);
GdkColor m_NoFlashBG = InitGDKColor(0, 0, 0, 0);
GdkColor m_NoFlashFG = InitGDKColor(0, 16383, 16383, 16383);
GdkColor m_TargetBG = InitGDKColor(0, 13107, 13107, 45874);
GdkColor m_TargetFG = InitGDKColor(0, 6553, 6553, 19660);
GdkColor m_ResultBG = InitGDKColor(0, 6553, 26214, 6553);
GdkColor m_ResultFG = InitGDKColor(0, 39321, 65535, 39321);
uint64_t FontSize = 50;
PangoFontDescription* m_FontDesc = nullptr;
// ------ TCP Tagging
std::vector<uint64_t> m_stimuliQueue;
guint m_idleFuncTag = 0;
TCPTagging::IStimulusSender* m_stimulusSender = nullptr;
// ------ Box visualization
VisualizationToolkit::IVisualizationContext* m_visualizationCtx = nullptr;
};

/// <summary> Descriptor of the box P300TactileVisualization. </summary>
class CBoxAlgorithmP300TactileVisualizationDesc final : virtual public IBoxAlgorithmDesc
{
public:

void release() override { }

CString getName() const override { return CString("P300TactileVisualization"); }
CString getAuthorName() const override { return CString("Tobias Baumann"); }
CString getAuthorCompanyName() const override { return CString("TH Nuernberg"); }
CString getShortDescription() const override { return CString(""); }
CString getDetailedDescription() const override { return CString(""); }
CString getCategory() const override { return CString("TactileBCI"); }
CString getVersion() const override { return CString("1.0"); }
CString getStockItemName() const override { return CString("gtk-underline"); }

CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_P300TactileVisualization; }
IPluginObject* create() override { return new CBoxAlgorithmP300TactileVisualization; }

bool hasFunctionality(const EPluginFunctionality functionality) const override { return functionality == EPluginFunctionality::Visualization; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Sequence",OV_TypeId_Stimulations);
prototype.addInput("Target",OV_TypeId_Stimulations);
prototype.addInput("Result",OV_TypeId_Stimulations);

prototype.addOutput("Result",OV_TypeId_Stimulations);

prototype.addSetting("Interface Filename",OV_TypeId_Filename,"${Player_ScenarioDirectory}/ui/p300-tactile-6.ui");
prototype.addSetting("Row Stimulation Base",OV_TypeId_Stimulation,"OVTK_StimulationId_Label_01");
prototype.addSetting("Number of Tactilos",OV_TypeId_Integer,"6");
prototype.addSetting("Free Spelling",OV_TypeId_Boolean,"false");

prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);

return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_P300TactileVisualizationDesc)
};
} // namespace Tactilebci
} // namespace Plugins
} // namespace OpenViBE

+ 0
- 140
src/TactiloController/ovpCBoxAlgorithmTactiloController.cpp View File

///-------------------------------------------------------------------------------------------------
///
/// \file ovpCBoxAlgorithmTactiloController.cpp
/// \brief Functions of the Box Tactilo Controller.
/// \author Tobias Baumann (TH-Nürnberg).
/// \version 1.0.
/// \date Mon Feb 21 14:59:56 2022.
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
///
///-------------------------------------------------------------------------------------------------

//includes
#include "ovpCBoxAlgorithmTactiloController.h"

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

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

bool CBoxAlgorithmTactiloController::initialize()
{
m_StimDecoder.initialize(*this, 0);
m_StimEncoder.initialize(*this, 0);
//get Box Settings
m_PortName = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_RowBase = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_nTactilos = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);
//set m_nTactilos to 2 if lower than 2
if(m_nTactilos < 2)
{
m_nTactilos = 2;
}
//set m_nTactilos to MAX if greater than MAX_TACTILOS
if(m_nTactilos > MAX_TACTILOS)
{
m_nTactilos = MAX_TACTILOS;
}
//open serial port and set baudrate to 115200
m_Port.open(m_PortName.toASCIIString());
m_Port.set_option(boost::asio::serial_port::baud_rate(115200));
if(m_Port.is_open())
{
this->getLogManager() << LogLevel_Info << "Connected to Serial Port: " << m_PortName << "\n";
m_Port.write_some(boost::asio::buffer("b"));
}
return true;
}

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

bool CBoxAlgorithmTactiloController::uninitialize()
{
this->getLogManager() << LogLevel_Info << "Disconnect from Serial Port: " << m_PortName << "\n";
m_Port.write_some(boost::asio::buffer("e"));
m_Port.close();

m_StimDecoder.uninitialize();
m_StimEncoder.uninitialize();
return true;
}

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

bool CBoxAlgorithmTactiloController::processInput(const size_t index)
{
// some pre-processing code if needed...

// ready to process !
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();

return true;
}

/*******************************************************************************/
bool CBoxAlgorithmTactiloController::process()
{
// the static box context describes the box inputs, outputs, settings structures
const IBox& staticBoxContext = this->getStaticBoxContext();
// the dynamic box context describes the current state of the box inputs and outputs (i.e. the chunks)
IBoxIO& boxContext = this->getDynamicBoxContext();

uint64_t ChunkStartTime = 0;
uint64_t ChunkEndTime = 0;
uint64_t Size = 0;
const uint8_t* Buffer = nullptr;

//iterate over all chunk on input 0
for (uint64_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
// decode the chunk i
m_StimDecoder.decode(i);
if(m_StimDecoder.isBufferReceived())
{
//check received stimulations
CStimulationSet* StimSet = m_StimDecoder.getOutputStimulationSet();
for(uint64_t j=0; j<StimSet->size(); j++)
{
uint64_t StimulationID = StimSet->getId(j);
if(StimulationID >= m_RowBase && StimulationID < (m_RowBase + m_nTactilos))
{
m_currTactiloID = StimulationID-m_RowBase;
}
if(StimulationID == OVTK_StimulationId_VisualStimulationStart || StimulationID == OVTK_StimulationId_VisualStimulationStop)
{
boost::asio::async_write(m_Port, boost::asio::buffer(std::to_string(m_currTactiloID), 1), boost::bind(&CBoxAlgorithmTactiloController::handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
}
}

// forward input chunks
boxContext.getInputChunk(0, i, ChunkStartTime, ChunkEndTime, Size, Buffer);
boxContext.appendOutputChunkData(0, Buffer, Size);
boxContext.markOutputAsReadyToSend(0, ChunkStartTime, ChunkEndTime);
boxContext.markInputAsDeprecated(0, i);

}

return true;
}

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

void CBoxAlgorithmTactiloController::handler(const boost::system::error_code& error, std::size_t bytes_transferred)
{
if(error)
{
this->getLogManager() << LogLevel_Warning << error.message() << "\n";
}
}

+ 0
- 113
src/TactiloController/ovpCBoxAlgorithmTactiloController.h View File

///-------------------------------------------------------------------------------------------------
///
/// \file ovpCBoxAlgorithmTactiloController.h
/// \brief Classes of the Box Tactilo Controller.
/// \author Tobias Baumann (TH-Nürnberg).
/// \version 1.0.
/// \date Mon Feb 21 14:59:56 2022.
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
///
///-------------------------------------------------------------------------------------------------

//includes
#pragma once

#include "../ovp_defines.h"

#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <string>

namespace OpenViBE
{
namespace Plugins
{
namespace Tactilebci
{
/// <summary> The class CBoxAlgorithmTactiloController describes the box Tactilo Controller. </summary>
class CBoxAlgorithmTactiloController final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
void release() override { delete this; }

bool initialize() override;
bool uninitialize() override;
bool processInput(const size_t index) override;
bool process() override;
// write handler
void handler(const boost::system::error_code& error, std::size_t bytes_transferred);
// As we do with any class in openvibe, we use the macro below to associate this box to an unique identifier.
// The inheritance information is also made available, as we provide the superclass Toolkit::TBoxAlgorithm < IBoxAlgorithm >
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_TactiloController)

protected:
// Input decoder:
Toolkit::TStimulationDecoder<CBoxAlgorithmTactiloController> m_StimDecoder;
// Output decoder:
Toolkit::TStimulationEncoder<CBoxAlgorithmTactiloController> m_StimEncoder;
private:
//variable to store the current TactiloNr
uint64_t m_currTactiloID = 0;
//Box Settings
CString m_PortName = "";
uint64_t m_RowBase = 0;
uint64_t m_nTactilos = 0;
//Serial Port
boost::asio::io_service m_IOService;
boost::asio::serial_port m_Port{m_IOService};
};

/// <summary> Descriptor of the box Tactilo Controller. </summary>
class CBoxAlgorithmTactiloControllerDesc final : virtual public IBoxAlgorithmDesc
{
public:

void release() override { }

CString getName() const override { return CString("Tactilo Controller"); }
CString getAuthorName() const override { return CString("Tobias Baumann"); }
CString getAuthorCompanyName() const override { return CString("TH-Nürnberg"); }
CString getShortDescription() const override { return CString("Controls the Tactilos on the Lattepandas GPIOs"); }
CString getDetailedDescription() const override { return CString("Communicates with the Arduino Coprocessor of the Lattepanda over a Serial Inteface, to control the Tactilos connected to the Arduinos GPIOs"); }
CString getCategory() const override { return CString("TactileBCI"); }
CString getVersion() const override { return CString("1.0"); }
CString getStockItemName() const override { return CString("gtk-network"); }

CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_TactiloController; }
IPluginObject* create() override { return new CBoxAlgorithmTactiloController; }

bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("StimInput",OV_TypeId_Stimulations);

//prototype.addFlag(Kernel::BoxFlag_CanModifyInput);
//prototype.addFlag(Kernel::BoxFlag_CanAddInput);

prototype.addOutput("StimOutput",OV_TypeId_Stimulations);

//prototype.addFlag(Kernel::BoxFlag_CanModifyOutput);
//prototype.addFlag(Kernel::BoxFlag_CanAddOutput);

//Box Settings
prototype.addSetting("Serial Port Name",OV_TypeId_String,"/dev/ttyACM0");
prototype.addSetting("Row Stimulation Base",OV_TypeId_Stimulation,"OVTK_StimulationId_Label_01");
prototype.addSetting("Number of Tactilos",OV_TypeId_Integer,"6");
//prototype.addFlag(Kernel::BoxFlag_CanModifySetting);
//prototype.addFlag(Kernel::BoxFlag_CanAddSetting);

prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);

return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_TactiloControllerDesc)
};
} // namespace Tactilebci
} // namespace Plugins
} // namespace OpenViBE

+ 0
- 113
src/UDPStimCodeSender/ovpCBoxAlgorithmUDPStimcodeSender.cpp View File

///-------------------------------------------------------------------------------------------------
///
/// \file CBoxAlgorithmUDPStimcodeSender.cpp
/// \brief Functions of Class UDP-StimCode-Sender
/// \author Tobias Baumann (TH Nuernberg).
/// \version 1.2.
/// \date Mon Oct 04 12:43:53 2021.
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
///
///-------------------------------------------------------------------------------------------------

//includes
#include "ovpCBoxAlgorithmUDPStimcodeSender.h"

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

bool CBoxAlgorithmUDPStimcodeSender::initialize()
{
m_StimDecoder.initialize(*this, 0);
m_StimEncoder.initialize(*this, 0);
// retrieve box settings
m_IP = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
m_Port = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
m_RowBase = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);
m_nTactilos = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3);
//set m_nTactilos to 2 if lower than 2
if(m_nTactilos < 2)
{
m_nTactilos = 2;
}
//set m_nTactilos to MAX if greater than MAX_TACTILOS
if(m_nTactilos > MAX_TACTILOS)
{
m_nTactilos = MAX_TACTILOS;
}
// connect UDP socket
boost::asio::ip::udp::endpoint m_Endpoint(boost::asio::ip::address::from_string(m_IP), m_Port);
m_Socket.connect(m_Endpoint);

return true;
}
/*******************************************************************************/

bool CBoxAlgorithmUDPStimcodeSender::uninitialize()
{
m_StimDecoder.uninitialize();
m_StimEncoder.uninitialize();

return true;
}
/*******************************************************************************/

bool CBoxAlgorithmUDPStimcodeSender::processInput(const size_t index)
{
// some pre-processing code if needed...

// ready to process !
getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();

return true;
}

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


bool CBoxAlgorithmUDPStimcodeSender::process()
{
// the static box context describes the box inputs, outputs, settings structures
const IBox& staticBoxContext = this->getStaticBoxContext();
// the dynamic box context describes the current state of the box inputs and outputs (i.e. the chunks)
IBoxIO& boxContext = this->getDynamicBoxContext();
uint64_t StimulationID = 0;
uint64_t ChunkStartTime = 0;
uint64_t ChunkEndTime = 0;
uint64_t Size = 0;
const uint8_t* Buffer = nullptr;

//iterate over all chunk on input 0
for (uint64_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
// decode the chunk i
m_StimDecoder.decode(i);
if(m_StimDecoder.isBufferReceived())
{
//check received stimulations
IStimulationSet* StimSet = m_StimDecoder.getOutputStimulationSet();
for(uint64_t j=0; j<StimSet->getStimulationCount(); j++)
{
StimulationID = StimSet->getStimulationIdentifier(j);
if(StimulationID >= m_RowBase && StimulationID < (m_RowBase + m_nTactilos))
{
this->getLogManager() << LogLevel_Debug << "send udp : [StimulusCode " << (StimulationID-m_RowBase+1) << "]\n";
m_Socket.send(boost::asio::buffer(std::to_string(StimulationID-m_RowBase+1)));
}
}
}
// forward input chunks
boxContext.getInputChunk(0, i, ChunkStartTime, ChunkEndTime, Size, Buffer);
boxContext.appendOutputChunkData(0, Buffer, Size);
boxContext.markOutputAsReadyToSend(0, ChunkStartTime, ChunkEndTime);
boxContext.markInputAsDeprecated(0, i);
}
return true;
}

+ 0
- 107
src/UDPStimCodeSender/ovpCBoxAlgorithmUDPStimcodeSender.h View File

///-------------------------------------------------------------------------------------------------
///
/// \file CBoxAlgorithmUDPStimcodeSender.h
/// \brief Classes of the Box UDPStimcodeSender.
/// \author Tobias Baumann (TH Nuernberg).
/// \version 1.1.
/// \date Mon Oct 04 12:43:53 2021.
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
///
///-------------------------------------------------------------------------------------------------

//includes
#pragma once
//You may have to change this path to match your folder organisation
#include "../ovp_defines.h"

#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <boost/asio.hpp>


namespace OpenViBE
{
namespace Plugins
{
namespace Tactilebci
{
/// <summary> The class CBoxAlgorithmUDPStimcodeSender describes the box UDPStimcodeSender. </summary>
class CBoxAlgorithmUDPStimcodeSender final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
void release() override { delete this; }

bool initialize() override;
bool uninitialize() override;
bool processInput(const size_t index) override;
bool process() override;

// As we do with any class in openvibe, we use the macro below to associate this box to an unique identifier.
// The inheritance information is also made available, as we provide the superclass Toolkit::TBoxAlgorithm < IBoxAlgorithm >
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_UDPStimcodeSender)

protected:
// Input decoder:
Toolkit::TStimulationDecoder<CBoxAlgorithmUDPStimcodeSender> m_StimDecoder;
// Output decoder:
Toolkit::TStimulationEncoder<CBoxAlgorithmUDPStimcodeSender> m_StimEncoder;
private:
// Box setting variables
CString m_IP = "";
uint64_t m_Port = 0;
uint64_t m_RowBase = 0;
uint64_t m_nTactilos = 0;
// Socket
boost::asio::io_service m_IOService;
boost::asio::ip::udp::socket m_Socket{m_IOService};
};


/// <summary> Descriptor of the box UDPStimcodeSender. </summary>
class CBoxAlgorithmUDPStimcodeSenderDesc final : virtual public IBoxAlgorithmDesc
{
public:

void release() override { }

CString getName() const override { return CString("UDPStimcodeSender"); }
CString getAuthorName() const override { return CString("Tobias Baumann"); }
CString getAuthorCompanyName() const override { return CString("TH Nuernberg"); }
CString getShortDescription() const override { return CString("Sends Stimulationcodes via UDP"); }
CString getDetailedDescription() const override { return CString("Sends the received Stimulationcodes the Adafruit Feather, using UDP. The Input Stimulation will be passed to the Output unchanged."); }
CString getCategory() const override { return CString("TactileBCI"); }
CString getVersion() const override { return CString("1.1"); }
CString getStockItemName() const override { return CString("gtk-network"); }

CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_UDPStimcodeSender; }
IPluginObject* create() override { return new CBoxAlgorithmUDPStimcodeSender; }

bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("StimcodeIn",OV_TypeId_Stimulations);

//prototype.addFlag(Kernel::BoxFlag_CanModifyInput);
//prototype.addFlag(Kernel::BoxFlag_CanAddInput);

prototype.addOutput("StimcodeOut",OV_TypeId_Stimulations);

//prototype.addFlag(Kernel::BoxFlag_CanModifyOutput);
//prototype.addFlag(Kernel::BoxFlag_CanAddOutput);

prototype.addSetting("FeatherIP",OV_TypeId_String,"192.168.4.1");
prototype.addSetting("FeatherPort",OV_TypeId_Integer,"8888");
prototype.addSetting("RowStimulationBase",OV_TypeId_Stimulation,"OVTK_StimulationId_Label_01");
prototype.addSetting("Number of Tactilos",OV_TypeId_Integer,"6");

prototype.addFlag(Kernel::BoxFlag_CanModifySetting);
//prototype.addFlag(Kernel::BoxFlag_CanAddSetting);

prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);

return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_UDPStimcodeSenderDesc)
};
} // namespace Tactilebci
} // namespace Plugins
} // namespace OpenViBE

+ 0
- 36
src/ovp_defines.h View File

///-------------------------------------------------------------------------------------------------
///
/// \file ovp_defines.h
/// \brief defines for the TactileBCI Plugin
/// \author Tobias Baumann (TH-Nürnberg).
/// \date Mon Feb 04 14:59:56 2022.
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
///
///-------------------------------------------------------------------------------------------------

#pragma once

// Boxes
// The unique identifiers for the boxes and their descriptors.
// Identifier are randomly chosen by the skeleton-generator.
//---------------------------------------------------------------------------------------------------
#define OVP_ClassId_BoxAlgorithm_P300TactileVisualization OpenViBE::CIdentifier(0xd463df86, 0x7fbfdd81)
#define OVP_ClassId_BoxAlgorithm_P300TactileVisualizationDesc OpenViBE::CIdentifier(0x3e7f0ef5, 0x5ca2a1fc)

#define OVP_ClassId_BoxAlgorithm_UDPStimcodeSender OpenViBE::CIdentifier(0xc326e786, 0xcd512965)
#define OVP_ClassId_BoxAlgorithm_UDPStimcodeSenderDesc OpenViBE::CIdentifier(0x82aeb3c9, 0x37303d0e)

#define OVP_ClassId_BoxAlgorithm_TactiloController OpenViBE::CIdentifier(0x823bbe28, 0x0daf2111)
#define OVP_ClassId_BoxAlgorithm_TactiloControllerDesc OpenViBE::CIdentifier(0xdb6e9c60, 0x4ce98ac3)

// Global defines
//---------------------------------------------------------------------------------------------------
#define MAX_TACTILOS 10

#ifdef TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines
#include "ovp_global_defines.h"
#endif // TARGET_HAS_ThirdPartyOpenViBEPluginsGlobalDefines

#define OV_AttributeId_Box_FlagIsUnstable OpenViBE::CIdentifier(0x666FFFFF, 0x666FFFFF)



+ 0
- 34
src/ovp_main.cpp View File

///-------------------------------------------------------------------------------------------------
///
/// \file ovp_main.cpp
/// \brief Declarations/Includes for the TactileBCI Plugin
/// \author Tobias Baumann (TH-Nürnberg).
/// \date Mon Feb 07 14:59:56 2022.
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
///
///-------------------------------------------------------------------------------------------------

//Tactile BCI Includes
#include <vector>
#include <openvibe/ov_all.h>
#include "ovp_defines.h"

#include "TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.h"
#include "UDPStimCodeSender/ovpCBoxAlgorithmUDPStimcodeSender.h"
#include "TactiloController/ovpCBoxAlgorithmTactiloController.h"

namespace OpenViBE {
namespace Plugins {
namespace Tactilebci {

OVP_Declare_Begin()

OVP_Declare_New(CBoxAlgorithmP300TactileVisualizationDesc);
OVP_Declare_New(CBoxAlgorithmUDPStimcodeSenderDesc);
OVP_Declare_New(CBoxAlgorithmTactiloControllerDesc);

OVP_Declare_End()

} // namespace Tactilebci
} // namespace Plugins
} // namespace OpenViBE

+ 0
- 50
src/utils.h View File

#pragma once

#include <openvibe/ov_all.h>
#include <gtk/gtk.h>
#include <sstream>

//---------------------------------------------------------------------------------------------------
/// <summary> Initializes the color of the GDK. with old compiler as vs2013 we can't initialize structure easily.....</summary>
/// <param name="pixel"> For allocated colors, the pixel value used to draw this color on the screen.Not used anymore.</param>
/// <param name="r"> The red component of the color. This is a value between 0 and 65535, with 65535 indicating full intensity.</param>
/// <param name="g"> The green component of the color.</param>
/// <param name="b"> The blue component of the color.</param>
/// <returns> The initialized color (</returns>
inline GdkColor InitGDKColor(const guint32 pixel = 0, const guint16 r = 0, const guint16 g = 0, const guint16 b = 0)
{
GdkColor c;
c.pixel = pixel;
c.red = r;
c.green = g;
c.blue = b;
return c;
}
//---------------------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------------------
class CGdkcolorAutoCast
{
public:
CGdkcolorAutoCast(const OpenViBE::Kernel::IBox& box, OpenViBE::Kernel::IConfigurationManager& configManager, const size_t index)
: m_configManager(configManager)
{
box.getSettingValue(index, m_settingValue);
m_settingValue = m_configManager.expand(m_settingValue);
}

operator GdkColor() const
{
std::stringstream ss(m_settingValue.toASCIIString());
int r = 0, g = 0, b = 0;
char c;
ss >> r >> c >> g >> c >> b;
return InitGDKColor(0, guint16(r * 655.35), guint16(g * 655.35), guint16(b * 655.35));
}

protected:
OpenViBE::Kernel::IConfigurationManager& m_configManager;
OpenViBE::CString m_settingValue;
};

//---------------------------------------------------------------------------------------------------

Loading…
Cancel
Save