-->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); | |||||
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) |
# 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 |
# 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. |
///------------------------------------------------------------------------------------------------- | |||||
/// | |||||
/// \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; | |||||
} | |||||
} |
######################################################################################################################## | |||||
# 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 | |||||
<OpenViBE-SettingsOverride> | |||||
<SettingValue>Epoch block average</SettingValue> | |||||
<SettingValue>1</SettingValue> | |||||
</OpenViBE-SettingsOverride> |
############################################################################################################################################################################################################################################# | |||||
# 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 | |||||
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 |
<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><u><b><big>Scenario Overview</big></b></u> | |||||
This scenario can be used in order | |||||
to check the quality of the signals | |||||
before starting an experiment. | |||||
One should <u>definitely</u> | |||||
check the quality of the signals | |||||
and ensure that : | |||||
- <b>eye blinks</b> are visible | |||||
- <b>jaw clenching</b> are visible | |||||
- <b>alpha waves</b> 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> |
<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><u><b><big>Scenario Overview</big></b></u> | |||||
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 <i>Player Controller</i> the scenario will | |||||
automatically pause at the end of the training. | |||||
If you want details on this values, you should read | |||||
<u>http://www.icp.inpg.fr/~rivetber/Publications/references/Rivet2009a.pdf</u></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> |
<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><u><b><big>Scenario Overview</big></b></u> | |||||
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 | |||||
<i>4-online</i> session to have better results. | |||||
<u><b>Note:</b></u> in order to run this scenario, | |||||
the spatial filter should have been trained using | |||||
<i>2-train-xDAWN</i> !</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> |
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 | |||||
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 |
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 |
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 |
-- | |||||
--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 |
-- | |||||
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 |
The scenario will record its signals here. | |||||
<?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> |
<?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> |
<?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> |
<?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> |
<?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> |
<?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> |
<?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> |
<?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> |
<?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> |
///------------------------------------------------------------------------------------------------- | |||||
/// | |||||
/// \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 |
///------------------------------------------------------------------------------------------------- | |||||
/// | |||||
/// \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 |
#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()); | |||||
} | |||||
} |
///------------------------------------------------------------------------------------------------- | |||||
/// | |||||
/// \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 |
///------------------------------------------------------------------------------------------------- | |||||
/// | |||||
/// \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"; | |||||
} | |||||
} |
///------------------------------------------------------------------------------------------------- | |||||
/// | |||||
/// \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 |
///------------------------------------------------------------------------------------------------- | |||||
/// | |||||
/// \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; | |||||
} |
///------------------------------------------------------------------------------------------------- | |||||
/// | |||||
/// \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 |
///------------------------------------------------------------------------------------------------- | |||||
/// | |||||
/// \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) | |||||
///------------------------------------------------------------------------------------------------- | |||||
/// | |||||
/// \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 |
#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; | |||||
}; | |||||
//--------------------------------------------------------------------------------------------------- |