Commit 2435b201 authored by Jussi Lindgren's avatar Jussi Lindgren

Demos: Work on the unsupervised P300 speller

- The spelling session will no longer restart after ending
- Changed the bandpass filter to [0.5, 12] hz
- Past letters will be remembered even after the
  max trial count of the Matlab script has been exceeded
- Changed the visualizer to use monospace font for
  the target and result texts for clarity
- Made the letters flash in bold
- Made the default target text longer
parent c5aac8ed
......@@ -16,18 +16,17 @@ function box_out = p300_Initialize(box_in)
% We carry settings in this structure instead of using global variables
box_in.user_data.flashes_per_trial = box_in.settings(1).value;
box_in.user_data.debug = box_in.settings(2).value;
box_in.user_data.max_trials = 15;
box_in.user_data.keyboard_cols = 7; % @FIXME bad hardcoding
box_in.user_data.max_trials = 15; % max number of trials retained for building the classifier
% and how many past letters can be affected
box_in.user_data.keyboard_cols = 7; % @FIXME bad hardcoding
box_in.user_data.previous_time = 0;
box_in.user_data.gfeatures = [];
box_in.user_data.oldSelections = []; % set of letter predictions from before max_trials was reached
box_in.user_data.total_flashes = 0;
box_in.user_data.total_trials = 0;
box_in.user_data.C = []; % classifier
% fprintf(1,'%d\n', box_in.settings(1).value);
% declare some identifiers
% OV_stimulations();
box_out = box_in;
......
......@@ -117,16 +117,19 @@ function box_out = p300_Process(box_in)
box_in.user_data.gsequence, ...
[],box_in.user_data.flashes_per_trial,A,gamma,1:numTrials,false);
% predict
% output prediction (2 stim pair?), print letter
% predict which letter was selected
[~,select]=max(box_in.user_data.C.classifier.probs,[],2);
% Include predictions from before maxFeatures was reached
box_in.user_data.selection = select;
select = [box_in.user_data.oldSelections;select];
if(box_in.user_data.debug)
fprintf(1,'Trial %03d end (at %f s, %d flashes total, %d trls used, fd %d): Spelled so far: %s\n', ...
box_in.user_data.total_trials, end_time, ...
box_in.user_data.total_flashes, numTrials, size(features,2), convert_position_to_letter(select));
end
% Convert select to stimulations
select = select - 1;
rowidx = floor(select / box_in.user_data.keyboard_cols);
......@@ -140,6 +143,11 @@ function box_out = p300_Process(box_in)
stim_set = [stim_set, [double(OVTK_StimulationId_SegmentStop); time_now; 0]];
box_in = OV_addOutputBuffer(box_in,1,box_in.user_data.previous_time,time_now,stim_set);
if(box_in.user_data.total_flashes >= maxFeatures)
box_in.user_data.oldSelections = [box_in.user_data.oldSelections;box_in.user_data.selection(1)];
end
else
box_in = OV_addOutputBuffer(box_in,1,box_in.user_data.previous_time,time_now,[]);
end
......
delay = 1
function initialize(box)
s_delay = box:get_setting(2);
io.write(string.format("Delay : [%s]\n", s_delay))
if (s_delay:find("^%d+$") ~= nil) then
delay = tonumber(s_delay)
else
io.write("[ERROR] The parameter should be a numeric value\n")
end
end
function uninitialize(box)
end
function process(box)
box:send_stimulation(1, 0x00008001, delay, 0)
end
<OpenViBE-Scenario>
<FormatVersion>1</FormatVersion>
<Creator>OpenViBE Designer</Creator>
<CreatorVersion>2.0.0</CreatorVersion>
<CreatorVersion>2.0.1</CreatorVersion>
<Settings></Settings>
<Inputs></Inputs>
<Outputs></Outputs>
......@@ -136,6 +136,71 @@
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00002684, 0x00005b3b)</Identifier>
<Name>Lua Stimulator</Name>
<AlgorithmClassIdentifier>(0x0b5a2787, 0x02750621)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Stimulations</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0xb0d0db45, 0x49cbc34a)</TypeIdentifier>
<Name>Lua Script</Name>
<DefaultValue></DefaultValue>
<Value>${Player_ScenarioDirectory}/start-stimulator.lua</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Start delay (secs)</Name>
<DefaultValue>5</DefaultValue>
<Value>5</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x17ee7c08, 0x94c14893)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>-144</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>896</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0xd6e3f48b, 0xbee3523a)</Value>
</Attribute>
<Attribute>
<Identifier>(0x61d11811, 0x71e65362)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xf191c1c8, 0xa0123976)</Identifier>
<Value></Value>
</Attribute>
<Attribute>
<Identifier>(0xfba64161, 0x65304e21)</Identifier>
<Value></Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00002bb3, 0x0000133c)</Identifier>
<Name>Acquisition client</Name>
......@@ -301,6 +366,10 @@
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>560</Value>
</Attribute>
<Attribute>
<Identifier>(0x341d3912, 0x1478de86)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x92c056a7, 0x2dc71aff)</Value>
......@@ -319,55 +388,6 @@
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00003a0e, 0x0000636c)</Identifier>
<Name>Clock stimulator</Name>
<AlgorithmClassIdentifier>(0x4f756d3f, 0x29ff0b96)</AlgorithmClassIdentifier>
<Outputs>
<Output>
<TypeIdentifier>(0x6f752dd0, 0x082a321e)</TypeIdentifier>
<Name>Generated stimulations</Name>
</Output>
</Outputs>
<Settings>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Interstimulation interval (in sec)</Name>
<DefaultValue>1.0</DefaultValue>
<Value>5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Stimulation</Name>
<DefaultValue>OVTK_StimulationId_Label_00</DefaultValue>
<Value>OVTK_StimulationId_Label_00</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
<Identifier>(0x1fa7a38f, 0x54edbe0b)</Identifier>
<Value>-128</Value>
</Attribute>
<Attribute>
<Identifier>(0x207c9054, 0x3c841b63)</Identifier>
<Value>896</Value>
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x27b3ee3c, 0xc50527e6)</Value>
</Attribute>
<Attribute>
<Identifier>(0xc80ce8af, 0xf699f813)</Identifier>
<Value>1</Value>
</Attribute>
<Attribute>
<Identifier>(0xce18836a, 0x9c0eb403)</Identifier>
<Value>2</Value>
</Attribute>
</Attributes>
</Box>
<Box>
<Identifier>(0x00003d0e, 0x000025ef)</Identifier>
<Name>Player Controller</Name>
......@@ -836,7 +856,7 @@
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Flash font size</Name>
<DefaultValue>100</DefaultValue>
<Value>95</Value>
<Value>60</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
......@@ -857,7 +877,7 @@
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>No flash font size</Name>
<DefaultValue>75</DefaultValue>
<Value>75</Value>
<Value>60</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
......@@ -878,7 +898,7 @@
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Target font size</Name>
<DefaultValue>100</DefaultValue>
<Value>75</Value>
<Value>60</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
......@@ -899,7 +919,7 @@
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>Selected font size</Name>
<DefaultValue>100</DefaultValue>
<Value>75</Value>
<Value>60</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
......@@ -968,14 +988,14 @@
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>Low Cut-off Frequency (Hz)</Name>
<DefaultValue>1</DefaultValue>
<Value>1</Value>
<Value>0.5</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x512a166f, 0x5c3ef83f)</TypeIdentifier>
<Name>High Cut-off Frequency (Hz)</Name>
<DefaultValue>40</DefaultValue>
<Value>40</Value>
<Value>12</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
......@@ -1042,7 +1062,7 @@
<TypeIdentifier>(0x2c132d6e, 0x44ab0d97)</TypeIdentifier>
<Name>Start stimulation</Name>
<DefaultValue>OVTK_StimulationId_Label_00</DefaultValue>
<Value>OVTK_StimulationId_Label_00</Value>
<Value>OVTK_StimulationId_ExperimentStart</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
......@@ -1140,7 +1160,7 @@
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>Text to spell</Name>
<DefaultValue>quick_brown_fox</DefaultValue>
<Value>quick_brown_fox</Value>
<Value>quick_brown_fox_jumps_over_the_lazy_dog</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
......@@ -1559,17 +1579,6 @@
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00003417, 0x00005898)</Identifier>
<Source>
<BoxIdentifier>(0x00003a0e, 0x0000636c)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00007262, 0x00006c13)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00003659, 0x000038f5)</Identifier>
<Source>
......@@ -1669,6 +1678,17 @@
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00005fd4, 0x00005832)</Identifier>
<Source>
<BoxIdentifier>(0x00002684, 0x00005b3b)</BoxIdentifier>
<BoxOutputIndex>0</BoxOutputIndex>
</Source>
<Target>
<BoxIdentifier>(0x00007262, 0x00006c13)</BoxIdentifier>
<BoxInputIndex>0</BoxInputIndex>
</Target>
</Link>
<Link>
<Identifier>(0x00006a33, 0x00004bb6)</Identifier>
<Source>
......
......@@ -159,16 +159,28 @@ bool CBoxAlgorithmP300SpellerVisualisation2::initialize(void)
l_ui64MaxSize=std::max(l_ui64MaxSize, m_ui64TargetFontSize);
l_ui64MaxSize=std::max(l_ui64MaxSize, m_ui64SelectedFontSize);
::PangoFontDescription *l_pTmp = pango_context_get_font_description(gtk_widget_get_pango_context(GTK_WIDGET(m_pTarget)));
pango_font_description_set_family(l_pTmp, "mono");
l_pTmp = pango_context_get_font_description(gtk_widget_get_pango_context(GTK_WIDGET(m_pResult)));
pango_font_description_set_family(l_pTmp, "mono");
l_pTmp = pango_context_get_font_description(gtk_widget_get_pango_context(GTK_WIDGET(gtk_builder_get_object(m_pMainWidgetInterface, "label-target-title"))));
pango_font_description_set_family(l_pTmp, "mono");
l_pTmp = pango_context_get_font_description(gtk_widget_get_pango_context(GTK_WIDGET(gtk_builder_get_object(m_pMainWidgetInterface, "label-result-title"))));
pango_font_description_set_family(l_pTmp, "mono");
pango_font_description_set_size(l_pMaxFontDescription, (gint)(l_ui64MaxSize * PANGO_SCALE));
pango_font_description_set_size(m_pFlashFontDescription, (gint)(m_ui64FlashFontSize * PANGO_SCALE));
pango_font_description_set_size(m_pNoFlashFontDescription, (gint)(m_ui64NoFlashFontSize * PANGO_SCALE));
pango_font_description_set_size(m_pTargetFontDescription, (gint)(m_ui64TargetFontSize * PANGO_SCALE));
pango_font_description_set_size(m_pSelectedFontDescription, (gint)(m_ui64SelectedFontSize * PANGO_SCALE));
pango_font_description_set_weight(m_pFlashFontDescription, PANGO_WEIGHT_SEMIBOLD);
pango_font_description_set_weight(m_pNoFlashFontDescription, PANGO_WEIGHT_LIGHT);
this->_cache_build_from_table_(m_pTable);
this->_cache_for_each_(&CBoxAlgorithmP300SpellerVisualisation2::_cache_change_background_cb_, &m_oNoFlashBackgroundColor);
this->_cache_for_each_(&CBoxAlgorithmP300SpellerVisualisation2::_cache_change_foreground_cb_, &m_oNoFlashForegroundColor);
this->_cache_for_each_(&CBoxAlgorithmP300SpellerVisualisation2::_cache_change_font_cb_, l_pMaxFontDescription);
this->_cache_for_each_(&CBoxAlgorithmP300SpellerVisualisation2::_cache_change_font_cb_, m_pFlashFontDescription);
pango_font_description_free(l_pMaxFontDescription);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment