...
 
Commits (7)
......@@ -398,6 +398,20 @@
<Value>OVTK_StimulationId_VisualStimulationStop</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Cue Image 1</Name>
......@@ -484,7 +498,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x18869d2c, 0x1a544d63)</Value>
<Value>(0x0e529e93, 0xde37b1be)</Value>
</Attribute>
<Attribute>
<Identifier>(0x61d11811, 0x71e65362)</Identifier>
......
......@@ -406,6 +406,20 @@
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -422,7 +436,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x60662001, 0xbee8820f)</Value>
<Value>(0x76b223fd, 0x638b3dcb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......
......@@ -906,6 +906,20 @@
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -922,7 +936,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x60662001, 0xbee8820f)</Value>
<Value>(0x76b223fd, 0x638b3dcb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......
......@@ -1295,6 +1295,20 @@
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -1311,7 +1325,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x60662001, 0xbee8820f)</Value>
<Value>(0x76b223fd, 0x638b3dcb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......
......@@ -406,6 +406,20 @@
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -422,7 +436,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x60662001, 0xbee8820f)</Value>
<Value>(0x76b223fd, 0x638b3dcb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......
......@@ -1847,6 +1847,20 @@
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -1863,7 +1877,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x60662001, 0xbee8820f)</Value>
<Value>(0x76b223fd, 0x638b3dcb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......
......@@ -882,6 +882,20 @@
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -898,7 +912,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x60662001, 0xbee8820f)</Value>
<Value>(0x76b223fd, 0x638b3dcb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......
......@@ -59,6 +59,20 @@
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -75,7 +89,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x60662001, 0xbee8820f)</Value>
<Value>(0x76b223fd, 0x638b3dcb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......
......@@ -13,7 +13,7 @@
# INSTALL(DIRECTORY p300-speller/ DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/openvibe/bci-examples PATTERN ".svn" EXCLUDE)
# INSTALL(DIRECTORY p300-speller-xDAWN/ DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/openvibe/bci-examples PATTERN ".svn" EXCLUDE)
INSTALL(DIRECTORY signals DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/openvibe/scenarios/ PATTERN ".svn" EXCLUDE)
# INSTALL(DIRECTORY signals DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/openvibe/scenarios/ PATTERN ".svn" EXCLUDE)
INSTALL(DIRECTORY bci-examples DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/openvibe/scenarios/ PATTERN ".svn" EXCLUDE)
# FILE(GLOB FILENAMES "*")
......
<OpenViBE-Classifier-Box XMLVersion="3">
<Strategy-Identifier class-id="(0xffffffff, 0xffffffff)">Native</Strategy-Identifier>
<Algorithm-Identifier class-id="(0x2ba17a3c, 0x1bd46d84)">Linear Discrimimant Analysis (LDA)</Algorithm-Identifier>
<Stimulations>
<Class-Stimulation class-id="1">OVTK_StimulationId_Target</Class-Stimulation>
<Class-Stimulation class-id="2">OVTK_StimulationId_NonTarget</Class-Stimulation>
</Stimulations>
<OpenViBE-Classifier>
<LDA>
<Classes>1 2</Classes>
<Weights> -7.122120e+00 1.777545e+01 -1.781346e+01 -3.329611e+00 2.362203e+01 -1.572492e+01 -1.857913e+01 5.847418e+01 -8.563956e+01 8.832628e+01 -7.905228e+01 7.780925e+01 -8.364732e+01 9.759207e+01 -1.179872e+02 1.286545e+02 -1.241806e+02 8.831794e+01 -2.587511e+01 -3.521868e+01 8.543782e+01 -1.118077e+02 9.711441e+01 -6.245437e+01 2.334095e+01 1.967654e+01 -5.167139e+01 5.649979e+01 -4.220202e+01 3.378016e+01 -4.860022e+01 7.126221e+01 -8.544855e+01 8.355727e+01 -5.776034e+01 8.339217e+00 5.205719e+01 -1.031671e+02 1.253024e+02 -1.179639e+02 8.326497e+01 -4.730102e+01 2.565054e+01 -3.170866e+01 6.398977e+01 -1.149526e+02 1.650408e+02 -1.922100e+02 2.000919e+02 -2.092701e+02 2.045770e+02 -1.861620e+02 1.561740e+02 -1.196765e+02 8.973211e+01 -6.411192e+01 4.368705e+01 -3.867175e+01 3.209337e+01 -2.468713e+01 6.344738e+00 2.250683e+01 -3.921717e+01 3.693119e+01 -3.696910e+01 4.548092e+01 -5.187682e+01 3.650097e+01 3.406524e+00 -5.269095e+01 8.947779e+01 -1.032946e+02 8.152717e+01 -3.928739e+01 5.936262e+00 3.519896e+00 -1.329417e+01 3.458413e+01 -5.255438e+01 7.238334e+01 -1.050424e+02 1.339581e+02 -1.370269e+02 1.226060e+02 -9.643596e+01 6.466838e+01 -5.095871e+01 7.402919e+01 -1.127270e+02 1.304361e+02 -1.327929e+02 1.215212e+02 -8.866220e+01 2.535216e+01 4.486416e+01 -8.007328e+01 6.169344e+01 -7.344700e+00 -4.270434e+01 5.254071e+01 -4.121132e+01 4.482422e+01 -7.372178e+01 1.052715e+02 -1.101813e+02 7.074318e+01 -3.479241e+00 -6.210279e+01 1.083678e+02 -1.321705e+02 1.294090e+02 -9.968801e+01 4.750835e+01 1.084392e+01 -5.011680e+01 6.152786e+01 -5.172693e+01 1.322513e+01 3.696735e+01 -7.198078e+01 7.012957e+01 -5.315045e+01 2.909352e+01 -1.046225e+01 4.802064e+00 -1.995977e+01 4.139408e+01 -6.684648e+01 8.761406e+01 -8.690807e+01 5.571024e+01 -1.797395e+01 -3.284783e+00 -3.856386e+00 2.105352e+01 -3.231356e+01 1.677828e+01 2.125954e+01 -5.860028e+01 7.830651e+01 -9.015548e+01 9.728995e+01 -9.893630e+01 9.542621e+01 -9.783217e+01 1.083699e+02 -1.210458e+02 1.206111e+02 -1.071788e+02 7.687832e+01 -3.859535e+01 7.913590e+00 1.356120e+01 -4.051088e+01 7.043170e+01 -1.018706e+02 1.391827e+02 -1.632443e+02 1.609274e+02 -1.373878e+02 1.019344e+02 -6.696022e+01 6.250240e+01 -9.914957e+01 1.525926e+02 -1.905768e+02 2.112993e+02 -2.079184e+02 1.786620e+02 -1.177934e+02 4.202581e+01 7.082889e+00 -4.850787e+00 -4.193205e+01 9.702879e+01 -1.207281e+02 1.136234e+02 -1.068530e+02 1.124635e+02 -1.177883e+02 1.070995e+02 -7.928295e+01 3.244891e+01 2.540448e+01 -6.783156e+01 8.252935e+01 -6.874371e+01 4.088874e+01 5.789947e+00 -4.716482e+01 6.971631e+01 -6.269533e+01 3.411818e+01 1.878494e+01 -7.067014e+01 1.083944e+02 -1.248790e+02 1.211853e+02 -9.780863e+01 7.581420e+01 -8.356914e+01 1.212675e+02 -1.603997e+02 1.881428e+02 -2.005041e+02 1.855934e+02 -1.441734e+02 1.030061e+02 -8.202598e+01 9.333785e+01 -1.122289e+02 1.237476e+02 -1.007398e+02 4.739943e+01 6.899361e+00 -3.125639e+01 4.564319e+01 -5.912309e+01 6.678798e+01 -6.302497e+01 7.019989e+01 -9.116743e+01 1.180301e+02 -1.339850e+02 1.324724e+02 -1.025916e+02 5.063891e+01 -1.257023e+01</Weights>
<Bias-distance>-30.7431</Bias-distance>
<Coefficient-probability>-33.141</Coefficient-probability>
</LDA>
</OpenViBE-Classifier>
</OpenViBE-Classifier-Box>
<OpenViBE-SettingsOverride>
<SettingValue>Epoch block average</SettingValue>
<SettingValue>3</SettingValue>
<SettingValue>1</SettingValue>
</OpenViBE-SettingsOverride>
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
-- For handling target fifo
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
-- this function is called when the box is initialized
function initialize(box)
dofile(box:get_config("${Path_Data}") .. "/plugins/stimulation/lua-stimulator-stim-codes.lua")
row_base = _G[box:get_setting(2)]
segment_start = _G[box:get_setting(3)]
segment_stop = _G[box:get_setting(4)]
-- 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 = {}
do_debug = false
end
-- this function is called when the box is uninitialized
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
row_votes = {}
target_fifo = List.new()
-- fixme fixed 20
for i = 0,20 do
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
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
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
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
-- vote not added in this case
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)
if maxRowValue == 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
for ir, val in pairs(row_votes) do
rowVotes = rowVotes + val
end
box:log("Info", string.format("Vote [%d] wt [%d]", maxRowIdx+row_base, maxRowValue))
box:log("Info", string.format(" Total [%d]", rowVotes))
end
local now = box:get_current_time()
box:send_stimulation(1, maxRowIdx + row_base, now, 0)
segment_status = 0
end
box:sleep()
end
end
-- this function is called when the box is initialized
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
-- this function is called when the box is uninitialized
function uninitialize(box)
end
-- this function is called once by the box
function process(box)
box:send_stimulation(1, stim, launchTime, 0)
end
......@@ -14,4 +14,6 @@
<SettingValue>10,40,10</SettingValue>
<SettingValue>60,100,60</SettingValue>
<SettingValue>40</SettingValue>
<SettingValue>localhost0</SettingValue>
<SettingValue>15361</SettingValue>
</OpenViBE-SettingsOverride>
......@@ -351,6 +351,20 @@
<Value>40</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -367,7 +381,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d30c, 0xa939693a)</Value>
<Value>(0x9b5dd0b3, 0x6d5a95e7)</Value>
</Attribute>
<Attribute>
<Identifier>(0x8d21ff41, 0xdf6afe7e)</Identifier>
......
......@@ -1105,6 +1105,20 @@
<Value>40</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -1121,7 +1135,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d30c, 0xa939693a)</Value>
<Value>(0x9b5dd0b3, 0x6d5a95e7)</Value>
</Attribute>
<Attribute>
<Identifier>(0x8d21ff41, 0xdf6afe7e)</Identifier>
......
......@@ -856,6 +856,20 @@
<Value>40</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -872,7 +886,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d30c, 0xa939693a)</Value>
<Value>(0x9b5dd0b3, 0x6d5a95e7)</Value>
</Attribute>
<Attribute>
<Identifier>(0x8d21ff41, 0xdf6afe7e)</Identifier>
......
......@@ -351,6 +351,20 @@
<Value>40</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -367,7 +381,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d30c, 0xa939693a)</Value>
<Value>(0x9b5dd0b3, 0x6d5a95e7)</Value>
</Attribute>
<Attribute>
<Identifier>(0x8d21ff41, 0xdf6afe7e)</Identifier>
......
......@@ -1199,6 +1199,20 @@
<Value>40</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -1215,7 +1229,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d30c, 0xa939693a)</Value>
<Value>(0x9b5dd0b3, 0x6d5a95e7)</Value>
</Attribute>
<Attribute>
<Identifier>(0x8d21ff41, 0xdf6afe7e)</Identifier>
......
......@@ -1020,6 +1020,20 @@
<Value>40</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -1036,7 +1050,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d30c, 0xa939693a)</Value>
<Value>(0x9b5dd0b3, 0x6d5a95e7)</Value>
</Attribute>
<Attribute>
<Identifier>(0x8d21ff41, 0xdf6afe7e)</Identifier>
......
......@@ -14,4 +14,6 @@
<SettingValue>10,40,10</SettingValue>
<SettingValue>60,100,60</SettingValue>
<SettingValue>40</SettingValue>
<SettingValue>localhost</SettingValue>
<SettingValue>15361</SettingValue>
</OpenViBE-SettingsOverride>
......@@ -1106,6 +1106,20 @@
<Value>false</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -1122,7 +1136,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x60662001, 0xbee8820f)</Value>
<Value>(0x76b223fd, 0x638b3dcb)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......
......@@ -348,6 +348,20 @@
<Value>${Path_Data}/plugins/stimulation/simple-keyboard-to-stimulations.txt</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue></DefaultValue>
<Value></Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -364,7 +378,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d3b7, 0x8339d210)</Value>
<Value>(0x9b5dd008, 0x475a2ecd)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......@@ -604,4 +618,4 @@ the client along with the number of signal bytes received so far.</Text>
<Value>Inria</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>
\ No newline at end of file
</OpenViBE-Scenario>
......@@ -136,6 +136,20 @@
<Value>${Path_Data}/plugins/stimulation/simple-keyboard-to-stimulations.txt</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue></DefaultValue>
<Value></Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -152,7 +166,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d3b7, 0x8339d210)</Value>
<Value>(0x9b5dd008, 0x475a2ecd)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......@@ -627,4 +641,4 @@ Its used together with &lt;b&gt;openvibe-examples-openvibe-to-vrpn&lt;/b&gt; app
<Value>Inria</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>
\ No newline at end of file
</OpenViBE-Scenario>
......@@ -360,6 +360,20 @@
<Value>${Player_ScenarioDirectory}/simple-keyboard-to-stimulations.txt</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue></DefaultValue>
<Value></Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -376,7 +390,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d3b7, 0x8339d210)</Value>
<Value>(0x9b5dd008, 0x475a2ecd)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......@@ -696,4 +710,4 @@
<Value>INRIA</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>
\ No newline at end of file
</OpenViBE-Scenario>
......@@ -264,6 +264,20 @@
<Value>${Player_ScenarioDirectory}/simple-keyboard-to-stimulations.txt</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue></DefaultValue>
<Value></Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -280,7 +294,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d3b7, 0x8339d210)</Value>
<Value>(0x9b5dd008, 0x475a2ecd)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......
......@@ -25,6 +25,7 @@ namespace TCPTagging
virtual ~CStimulusSender();
// Connect to the TCP Tagging plugin of the Acquisition Server
// If sAddress is empty string, the StimulusSender will be inactive and connect() will not print an error but returns false.
virtual TCPTagging::boolean connect(const char* sAddress, const char* sStimulusPort);
// Send a stimulation. Set Timestamp to 0 for immediate tagging (also the default).
......@@ -39,6 +40,63 @@ namespace TCPTagging
TCPTagging::boolean m_bConnectedOnce;
};
// Tentative name
class CStimulusMultiSender : public IStimulusMultiSender {
public :
CStimulusMultiSender(void)
: m_uiGtkExecutionIndex(0)
{
}
virtual ~CStimulusMultiSender() {}
virtual TCPTagging::boolean connect(const char* sAddress, const char* sStimulusPort)
{
return m_sender.connect(sAddress, sStimulusPort);
}
virtual void addStimulationToWaitingList(TCPTagging::uint64 ui64Stimulation, TCPTagging::uint64 ui64Timestamp = 0)
{
m_vStimuliQueue.push_back(ui64Stimulation);
}
virtual TCPTagging::boolean sendStimulations(void)
{
TCPTagging::boolean res = true;
for (const TCPTagging::uint64& stim : m_vStimuliQueue)
{
res &= m_sender.sendStimulation(stim);
}
m_vStimuliQueue.clear();
m_uiGtkExecutionIndex = 0;
return res;
}
virtual TCPTagging::boolean sendStimulationNow(TCPTagging::uint64 ui64Stimulation, TCPTagging::uint64 ui64Timestamp = 0)
{
return m_sender.sendStimulation(ui64Stimulation, ui64Timestamp);
}
virtual bool isCurrentlySending(void)
{
return m_uiGtkExecutionIndex != 0;
}
virtual unsigned int getExecutionIndex(void)
{
return m_uiGtkExecutionIndex;
}
virtual void setExecutionIndex(unsigned int index)
{
m_uiGtkExecutionIndex = index;
}
protected :
std::vector< TCPTagging::uint64 > m_vStimuliQueue;
unsigned int m_uiGtkExecutionIndex;
CStimulusSender m_sender;
};
}
#endif
......@@ -13,7 +13,8 @@ namespace TCPTagging
class OV_API IStimulusSender {
public:
// Connect to the TCP Tagging plugin of the Acquisition Server
// Connect to the TCP Tagging plugin of the Acquisition Server.
// If sAddress is empty string, the StimulusSender will be inactive and connect() will not print an error but returns false.
virtual TCPTagging::boolean connect(const char* sAddress, const char* sStimulusPort) = 0;
// Send a stimulation. Set Timestamp to 0 for immediate tagging (also the default).
......@@ -26,6 +27,33 @@ namespace TCPTagging
// Clients are constructed via this call.
extern OV_API TCPTagging::IStimulusSender* createStimulusSender(void);
/*
* \class IStimulusSender
* \author Thierry Gaugry / Inria
* \brief @todo Describe...
*/
class OV_API IStimulusMultiSender {
public:
virtual TCPTagging::boolean connect(const char* sAddress, const char* sStimulusPort) = 0;
virtual void addStimulationToWaitingList(TCPTagging::uint64 ui64Stimulation, TCPTagging::uint64 ui64Timestamp = 0) = 0;
virtual TCPTagging::boolean sendStimulations(void) = 0;
virtual TCPTagging::boolean sendStimulationNow(TCPTagging::uint64 ui64Stimulation, TCPTagging::uint64 ui64Timestamp = 0) = 0;
virtual bool isCurrentlySending(void) = 0;
virtual unsigned int getExecutionIndex(void) = 0;
virtual void setExecutionIndex(unsigned int index) = 0;
virtual ~IStimulusMultiSender(void) { }
};
extern OV_API TCPTagging::IStimulusMultiSender* createStimulusMultiSender(void);
}
#endif
......@@ -22,7 +22,18 @@ CStimulusSender::~CStimulusSender()
boolean CStimulusSender::connect(const char* sAddress, const char* sStimulusPort)
{
tcp::resolver resolver(m_ioService);
if (!sAddress || !sStimulusPort)
{
std::cout << "Error: Do not pass NULL pointers to CStimulusSender::connect()\n";
return false;
}
if (sAddress[0] == 0)
{
// Empty string is ok, in that case Stimulus Sender is disabled
return false;
}
// Stimulus port
std::cout << "Connecting to Acquisition Server's TCP Tagging [" << sAddress << " , port " << sStimulusPort << "]\n";
try
......
......@@ -6,3 +6,7 @@ OV_API TCPTagging::IStimulusSender* TCPTagging::createStimulusSender(void)
return new TCPTagging::CStimulusSender();
}
OV_API TCPTagging::IStimulusMultiSender* TCPTagging::createStimulusMultiSender(void)
{
return new TCPTagging::CStimulusMultiSender();
}
......@@ -388,6 +388,20 @@
<Value>${Path_Data}/plugins/stimulation/simple-keyboard-to-stimulations.txt</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue></DefaultValue>
<Value></Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -404,7 +418,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d3b7, 0x8339d210)</Value>
<Value>(0x9b5dd008, 0x475a2ecd)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......@@ -715,4 +729,4 @@ that will set all input samples to 0</Text>
<NumChildren>0</NumChildren>
</VisualisationWidget>
</VisualisationTree>
</OpenViBE-Scenario>
\ No newline at end of file
</OpenViBE-Scenario>
......@@ -18,6 +18,20 @@
<Value>${Path_Data}/plugins/stimulation/simple-keyboard-to-stimulations.txt</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue></DefaultValue>
<Value></Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -34,7 +48,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d3b7, 0x8339d210)</Value>
<Value>(0x9b5dd008, 0x475a2ecd)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......@@ -1198,4 +1212,4 @@ used with the 'eog-run.xml' scenario.
<Value>Inria</Value>
</Attribute>
</Attributes>
</OpenViBE-Scenario>
\ No newline at end of file
</OpenViBE-Scenario>
......@@ -57,7 +57,7 @@ INSTALL(TARGETS ${PROJECT_NAME}
INSTALL(DIRECTORY share/ DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/openvibe/plugins/simple-visualisation PATTERN ".svn" EXCLUDE)
INSTALL(DIRECTORY signals DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/openvibe/scenarios/ PATTERN ".svn" EXCLUDE)
#INSTALL(DIRECTORY signals DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/openvibe/scenarios/ PATTERN ".svn" EXCLUDE)
INSTALL(DIRECTORY box-tutorials DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/openvibe/scenarios/ PATTERN ".svn" EXCLUDE)
#INSTALL(DIRECTORY src/ DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h" PATTERN ".svn" EXCLUDE PATTERN "doc" EXCLUDE)
......@@ -40,6 +40,20 @@
<Value>OVTK_StimulationId_Label_03</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue>localhost</DefaultValue>
<Value>localhost</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x330306dd, 0x74a95f98)</TypeIdentifier>
<Name>Cue Image 1</Name>
......@@ -84,7 +98,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x18869d2c, 0x1a544d63)</Value>
<Value>(0x0e529e93, 0xde37b1be)</Value>
</Attribute>
<Attribute>
<Identifier>(0x61d11811, 0x71e65362)</Identifier>
......@@ -384,6 +398,20 @@
<Value>${Path_Data}/plugins/stimulation/simple-keyboard-to-stimulations.txt</Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x79a9edeb, 0x245d83fc)</TypeIdentifier>
<Name>TCP Tagging Host address</Name>
<DefaultValue></DefaultValue>
<Value></Value>
<Modifiability>false</Modifiability>
</Setting>
<Setting>
<TypeIdentifier>(0x007deef9, 0x2f3e95c6)</TypeIdentifier>
<Name>TCP Tagging Host port</Name>
<DefaultValue>15361</DefaultValue>
<Value>15361</Value>
<Modifiability>false</Modifiability>
</Setting>
</Settings>
<Attributes>
<Attribute>
......@@ -400,7 +428,7 @@
</Attribute>
<Attribute>
<Identifier>(0x4e7b798a, 0x183beafb)</Identifier>
<Value>(0x8d89d3b7, 0x8339d210)</Value>
<Value>(0x9b5dd008, 0x475a2ecd)</Value>
</Attribute>
<Attribute>
<Identifier>(0xad100179, 0xa3c984ab)</Identifier>
......@@ -792,4 +820,4 @@ TCP Tagging module.</Text>
<NumChildren>0</NumChildren>
</VisualisationWidget>
</VisualisationTree>
</OpenViBE-Scenario>
\ No newline at end of file
</OpenViBE-Scenario>
......@@ -6,6 +6,7 @@
#include <vector>
#include <string>
#include <algorithm>
#include <tcptagging/IStimulusSender.h>
using namespace OpenViBE;
using namespace OpenViBE::Kernel;
......@@ -49,9 +50,11 @@ boolean CBoxAlgorithmP300MagicCardVisualisation::initialize(void)
m_oTargetBackgroundColor =_AutoCast_(*this->getBoxAlgorithmContext(), 2);
m_oSelectedBackgroundColor=_AutoCast_(*this->getBoxAlgorithmContext(), 3);
m_ui64CardStimulationBase =FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 4);
CString l_sBackgroundImageFilename=FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 5);
OpenViBE::CString l_sTCPTaggingHostAddress = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 5);
OpenViBE::CString l_sTCPTaggingHostPort = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 6);
CString l_sBackgroundImageFilename = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 7);
for(uint32 i=6; i<l_rStaticBoxContext.getSettingCount(); i++)
for(uint32 i=8; i<l_rStaticBoxContext.getSettingCount(); i++)
{
GError *l_pError = NULL;
......@@ -140,11 +143,29 @@ boolean CBoxAlgorithmP300MagicCardVisualisation::initialize(void)
this->_cache_for_each_(&CBoxAlgorithmP300MagicCardVisualisation::_cache_change_image_cb_, &m_vForegroundImage);
this->_cache_for_each_(&CBoxAlgorithmP300MagicCardVisualisation::_cache_change_background_cb_, &m_oBackgroundColor);
//TCP TAGGING
m_pStimulusMultiSender = TCPTagging::createStimulusMultiSender();
if (!m_pStimulusMultiSender->connect(l_sTCPTaggingHostAddress, l_sTCPTaggingHostPort))
{
this->getLogManager() << LogLevel_Warning << "Unable to connect to AS's TCP Tagging plugin, stimuli wont be forwarded.\n";
}
return true;
}
boolean CBoxAlgorithmP300MagicCardVisualisation::uninitialize(void)
{
if (m_pStimulusMultiSender && m_pStimulusMultiSender->isCurrentlySending())
{
g_source_remove(m_pStimulusMultiSender->getExecutionIndex());
m_pStimulusMultiSender->setExecutionIndex(0);
}
if (!m_pStimulusMultiSender)
{
delete m_pStimulusMultiSender;
m_pStimulusMultiSender = nullptr;
}
if(m_pToolbarWidgetInterface)
{
g_object_unref(m_pToolbarWidgetInterface);
......@@ -247,10 +268,12 @@ boolean CBoxAlgorithmP300MagicCardVisualisation::process(void)
int l_iCard=(int)(l_ui64StimulationIdentifier-m_ui64CardStimulationBase);
if(l_iCard==m_iTargetCard)
{
m_pStimulusMultiSender->addStimulationToWaitingList(OVTK_StimulationId_Target);
l_oFlaggingStimulationSet.appendStimulation(OVTK_StimulationId_Target, l_pStimulationSet->getStimulationDate(j), 0);
}
else
{
m_pStimulusMultiSender->addStimulationToWaitingList(OVTK_StimulationId_NonTarget);
l_oFlaggingStimulationSet.appendStimulation(OVTK_StimulationId_NonTarget, l_pStimulationSet->getStimulationDate(j), 0);
}
......@@ -274,7 +297,11 @@ boolean CBoxAlgorithmP300MagicCardVisualisation::process(void)
this->getLogManager() << LogLevel_Debug << "Received OVTK_StimulationId_VisualStimulationStop - resets grid\n";
this->_cache_for_each_(&CBoxAlgorithmP300MagicCardVisualisation::_cache_change_image_cb_, &m_vBackgroundImage);
}
// Pass the stimulation to the server also as-is. If its a flash, it can be differentiated from a 'target' spec because
// its NOT between OVTK_StimulationId_RestStart and OVTK_StimulationId_RestStop stimuli in the generated P300 timeline.
m_pStimulusMultiSender->addStimulationToWaitingList(l_ui64StimulationIdentifier);
}
m_pTargetFlaggingStimulationEncoder->process(OVP_GD_Algorithm_StimulationStreamEncoder_InputTriggerId_EncodeBuffer);
}
......@@ -324,6 +351,15 @@ boolean CBoxAlgorithmP300MagicCardVisualisation::process(void)
&CBoxAlgorithmP300MagicCardVisualisation::_cache_change_null_cb_,
&m_oTargetBackgroundColor,
NULL);
// Merge the current target into the stimulation stream. It can be differentiated
// from a 'flash' spec because it IS between OVTK_StimulationId_RestStart and
// OVTK_StimulationId_RestStop stimulations in the P300 timeline.
{
//or just l_ui64StimulationIdentifier
m_pStimulusMultiSender->addStimulationToWaitingList(m_iTargetCard + m_ui64CardStimulationBase);
}
}
}
}
......@@ -397,6 +433,19 @@ boolean CBoxAlgorithmP300MagicCardVisualisation::process(void)
}
}
// After any possible rendering, we flush the accumulated stimuli. The default idle func is low priority, so it should be run after rendering by gtk.
if (!m_pStimulusMultiSender->isCurrentlySending())
{
m_pStimulusMultiSender->setExecutionIndex(
g_idle_add(
[](gpointer pUserData) -> gboolean
{
((CBoxAlgorithmP300MagicCardVisualisation*)pUserData)->flushQueue();
return false; // Only run once
},
this));
}
return true;
}
......@@ -490,3 +539,8 @@ void CBoxAlgorithmP300MagicCardVisualisation::_cache_change_background_cb_(CBoxA
}
}
// Note that we don't need concurrency control here as gtk callbacks run in the main thread
void CBoxAlgorithmP300MagicCardVisualisation::flushQueue(void)
{
m_pStimulusMultiSender->sendStimulations();
}
\ No newline at end of file
......@@ -15,6 +15,11 @@
#define OVP_ClassId_BoxAlgorithm_P300MagicCardVisualisation OpenViBE::CIdentifier(0x841F46EF, 0x471AA2A4)
#define OVP_ClassId_BoxAlgorithm_P300MagicCardVisualisationDesc OpenViBE::CIdentifier(0x37FAFF20, 0xA74685DB)
namespace TCPTagging
{
class IStimulusMultiSender; // fwd declare
};
namespace OpenViBEPlugins
{
namespace SimpleVisualisation
......@@ -30,6 +35,7 @@ namespace OpenViBEPlugins
virtual OpenViBE::boolean processInput(OpenViBE::uint32 ui32Index);
virtual OpenViBE::boolean process(void);
void flushQueue(void); // Sends all accumulated stimuli to the TCP Tagging
_IsDerivedFromClass_Final_(OpenViBEToolkit::TBoxAlgorithm < OpenViBE::Plugins::IBoxAlgorithm >, OVP_ClassId_BoxAlgorithm_P300MagicCardVisualisation);
private:
......@@ -93,6 +99,9 @@ namespace OpenViBEPlugins
OpenViBE::boolean m_bTableInitialized;
std::map < unsigned long, CBoxAlgorithmP300MagicCardVisualisation::SWidgetStyle > m_vCache;
// TCP Tagging
TCPTagging::IStimulusMultiSender* m_pStimulusMultiSender;
};
class CBoxAlgorithmP300MagicCardVisualisationDesc : public OpenViBE::Plugins::IBoxAlgorithmDesc
......@@ -121,14 +130,16 @@ namespace OpenViBEPlugins
rBoxAlgorithmPrototype.addInput ("Target stimulations", OV_TypeId_Stimulations);
rBoxAlgorithmPrototype.addInput ("Card selection stimulations", OV_TypeId_Stimulations);
rBoxAlgorithmPrototype.addOutput("Target / Non target flagging", OV_TypeId_Stimulations);
rBoxAlgorithmPrototype.addOutput("Target / Non target flagging (deprecated)", OV_TypeId_Stimulations);
rBoxAlgorithmPrototype.addSetting("Interface filename", OV_TypeId_Filename, "${Path_Data}/plugins/simple-visualisation/p300-magic-card.ui");
rBoxAlgorithmPrototype.addSetting("Background color", OV_TypeId_Color, "90,90,90");
rBoxAlgorithmPrototype.addSetting("Target background color", OV_TypeId_Color, "10,40,10");
rBoxAlgorithmPrototype.addSetting("Selected background color", OV_TypeId_Color, "70,20,20");
rBoxAlgorithmPrototype.addSetting("Card stimulation base", OV_TypeId_Stimulation, "OVTK_StimulationId_Label_01");
rBoxAlgorithmPrototype.addSetting("Default background filename", OV_TypeId_Filename, "${Path_Data}/plugins/simple-visualisation/p300-magic-card/openvibe-logo.png-offscreen");
rBoxAlgorithmPrototype.addSetting("TCP Tagging Host address", OV_TypeId_String, "localhost");
rBoxAlgorithmPrototype.addSetting("TCP Tagging Host port", OV_TypeId_Integer, "15361");
rBoxAlgorithmPrototype.addSetting("Background filename", OV_TypeId_Filename, "${Path_Data}/plugins/simple-visualisation/p300-magic-card/openvibe-logo.png-offscreen");
rBoxAlgorithmPrototype.addSetting("Card filename", OV_TypeId_Filename, "${Path_Data}/plugins/simple-visualisation/p300-magic-card/01.png");
rBoxAlgorithmPrototype.addSetting("Card filename", OV_TypeId_Filename, "${Path_Data}/plugins/simple-visualisation/p300-magic-card/02.png");
rBoxAlgorithmPrototype.addSetting("Card filename", OV_TypeId_Filename, "${Path_Data}/plugins/simple-visualisation/p300-magic-card/03.png");
......
......@@ -54,15 +54,6 @@ namespace
}
};
// This callback flushes all accumulated stimulations to the TCP Tagging
// after the rendering has completed.
gboolean flush_callback(gpointer pUserData)
{
((CBoxAlgorithmP300SpellerVisualisation*)pUserData)->flushQueue();
return false; // Only run once
}
boolean CBoxAlgorithmP300SpellerVisualisation::initialize(void)
{
IBox& l_rStaticBoxContext=this->getStaticBoxContext();
......@@ -92,7 +83,8 @@ boolean CBoxAlgorithmP300SpellerVisualisation::initialize(void)
m_oSelectedBackgroundColor =_AutoCast_(l_rStaticBoxContext, this->getConfigurationManager(), 12);
m_oSelectedForegroundColor =_AutoCast_(l_rStaticBoxContext, this->getConfigurationManager(), 13);
m_ui64SelectedFontSize =FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 14);
OpenViBE::CString l_sTCPTaggingHostAddress = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 15);
OpenViBE::CString l_sTCPTaggingHostPort = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 16);
// ----------------------------------------------------------------------------------------------------------------------------------------------------------
m_pSequenceStimulationDecoder=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationStreamDecoder));
......@@ -121,11 +113,6 @@ boolean CBoxAlgorithmP300SpellerVisualisation::initialize(void)
m_ui64LastTime=0;
m_pStimulusSender = NULL;
m_uiIdleFuncTag = 0;
m_vStimuliQueue.clear();
m_pMainWidgetInterface=gtk_builder_new(); // glade_xml_new(m_sInterfaceFilename.toASCIIString(), "p300-speller-main", NULL);
if(!gtk_builder_add_from_file(m_pMainWidgetInterface, m_sInterfaceFilename.toASCIIString(), NULL))
{
......@@ -194,9 +181,9 @@ boolean CBoxAlgorithmP300SpellerVisualisation::initialize(void)
m_iSelectedRow=-1;
m_iSelectedColumn=-1;
m_pStimulusSender = TCPTagging::createStimulusSender();
m_pStimulusMultiSender = TCPTagging::createStimulusMultiSender();
if(!m_pStimulusSender->connect("localhost", "15361"))
if (!m_pStimulusMultiSender->connect(l_sTCPTaggingHostAddress, l_sTCPTaggingHostPort))
{
this->getLogManager() << LogLevel_Warning << "Unable to connect to AS TCP Tagging, stimuli wont be forwarded.\n";
}
......@@ -208,17 +195,15 @@ boolean CBoxAlgorithmP300SpellerVisualisation::initialize(void)
boolean CBoxAlgorithmP300SpellerVisualisation::uninitialize(void)
{
if(m_uiIdleFuncTag)
if (m_pStimulusMultiSender && m_pStimulusMultiSender->isCurrentlySending())
{
m_vStimuliQueue.clear();
g_source_remove(m_uiIdleFuncTag);
m_uiIdleFuncTag = 0;
g_source_remove(m_pStimulusMultiSender->getExecutionIndex());
m_pStimulusMultiSender->setExecutionIndex(0);
}
if(m_pStimulusSender)
if (!m_pStimulusMultiSender)
{
delete m_pStimulusSender;
m_pStimulusSender = NULL;
delete m_pStimulusMultiSender;
m_pStimulusMultiSender = nullptr;
}
if(m_pSelectedFontDescription)
......@@ -408,19 +393,19 @@ boolean CBoxAlgorithmP300SpellerVisualisation::process(void)
// We now know if this flash corresponds to the current target or not, merge this to the outgoing stimulation stream
if(l_bIsTarget)
{
m_vStimuliQueue.push_back(OVTK_StimulationId_Target);
m_pStimulusMultiSender->addStimulationToWaitingList(OVTK_StimulationId_Target);
l_oFlaggingStimulationSet.appendStimulation(OVTK_StimulationId_Target, l_pStimulationSet->getStimulationDate(j), 0);
}
else
{
m_vStimuliQueue.push_back(OVTK_StimulationId_NonTarget);
m_pStimulusMultiSender->addStimulationToWaitingList(OVTK_StimulationId_NonTarget);
l_oFlaggingStimulationSet.appendStimulation(OVTK_StimulationId_NonTarget, l_pStimulationSet->getStimulationDate(j), 0);
}
}
// Pass the stimulation to the server also as-is. If its a flash, it can be differentiated from a 'target' spec because
// its NOT between OVTK_StimulationId_RestStart and OVTK_StimulationId_RestStop stimuli in the generated P300 timeline.
m_vStimuliQueue.push_back(l_ui64StimulationIdentifier);
m_pStimulusMultiSender->addStimulationToWaitingList(l_ui64StimulationIdentifier);
}
m_pTargetFlaggingStimulationEncoder->process(OVP_GD_Algorithm_StimulationStreamEncoder_InputTriggerId_EncodeBuffer);
}
......@@ -505,8 +490,8 @@ boolean CBoxAlgorithmP300SpellerVisualisation::process(void)
// from a 'flash' spec because it IS between OVTK_StimulationId_RestStart and
// OVTK_StimulationId_RestStop stimulations in the P300 timeline.
{
m_vStimuliQueue.push_back(m_iTargetRow + m_ui64RowStimulationBase);
m_vStimuliQueue.push_back(m_iTargetColumn + m_ui64ColumnStimulationBase);
m_pStimulusMultiSender->addStimulationToWaitingList(m_iTargetRow + m_ui64RowStimulationBase);
m_pStimulusMultiSender->addStimulationToWaitingList(m_iTargetColumn + m_ui64ColumnStimulationBase);
}
if(l_vWidgets.size() == 1)
......@@ -688,9 +673,16 @@ boolean CBoxAlgorithmP300SpellerVisualisation::process(void)
}
// After any possible rendering, we flush the accumulated stimuli. The default idle func is low priority, so it should be run after rendering by gtk.
if (m_uiIdleFuncTag == 0)
if (!m_pStimulusMultiSender->isCurrentlySending())
{
m_uiIdleFuncTag = g_idle_add(flush_callback, this);
m_pStimulusMultiSender->setExecutionIndex(
g_idle_add(
[](gpointer pUserData) -> gboolean
{
((CBoxAlgorithmP300SpellerVisualisation*)pUserData)->flushQueue();
return false; // Only run once
},
this));
}
return true;
......@@ -843,12 +835,5 @@ void CBoxAlgorithmP300SpellerVisualisation::_cache_collect_child_widget_cb_(CBox
// Note that we don't need concurrency control here as gtk callbacks run in the main thread
void CBoxAlgorithmP300SpellerVisualisation::flushQueue(void)
{
for(size_t i=0;i<m_vStimuliQueue.size();i++)
{
m_pStimulusSender->sendStimulation(m_vStimuliQueue[i]);
}
m_vStimuliQueue.clear();
// This function will be automatically removed after completion, so set to 0
m_uiIdleFuncTag = 0;
m_pStimulusMultiSender->sendStimulations();
}
\ No newline at end of file
......@@ -18,7 +18,7 @@
namespace TCPTagging
{
class IStimulusSender; // fwd declare
class IStimulusMultiSender; // fwd declare
};
namespace OpenViBEPlugins
......@@ -129,9 +129,7 @@ namespace OpenViBEPlugins
std::list < std::pair < int, int > > m_vTargetHistory;
// TCP Tagging
std::vector< OpenViBE::uint64 > m_vStimuliQueue;
guint m_uiIdleFuncTag;
TCPTagging::IStimulusSender* m_pStimulusSender;
TCPTagging::IStimulusMultiSender* m_pStimulusMultiSender;
};
class CBoxAlgorithmP300SpellerVisualisationDesc : public OpenViBE::Plugins::IBoxAlgorithmDesc
......@@ -183,6 +181,8 @@ namespace OpenViBEPlugins
rBoxAlgorithmPrototype.addSetting("Selected foreground color", OV_TypeId_Color, "30,10,10");
rBoxAlgorithmPrototype.addSetting("Selected font size", OV_TypeId_Integer, "100");
rBoxAlgorithmPrototype.addSetting("TCP Tagging Host address", OV_TypeId_String, "localhost");
rBoxAlgorithmPrototype.addSetting("TCP Tagging Host port", OV_TypeId_Integer, "15361");
return true;
}
......
......@@ -29,15 +29,6 @@ namespace OpenViBEPlugins
{
namespace SimpleVisualisation
{
// This callback flushes all accumulated stimulations to the TCP Tagging
// after the rendering has completed.
gboolean DisplayCueImage_flush_callback(gpointer pUserData)
{
reinterpret_cast<CDisplayCueImage*>(pUserData)->flushQueue();
return false; // Only run once
}
gboolean DisplayCueImage_SizeAllocateCallback(GtkWidget *widget, GtkAllocation *allocation, gpointer data)
{
reinterpret_cast<CDisplayCueImage*>(data)->resize((uint32)allocation->width, (uint32)allocation->height);
......@@ -60,8 +51,7 @@ namespace OpenViBEPlugins
m_int32DrawnImageID(-1),
m_bFullScreen(false),
m_bScaleImages(false),
m_ui64LastOutputChunkDate(-1),
m_pStimulusSender(NULL)
m_ui64LastOutputChunkDate(-1)
{
m_oBackgroundColor.pixel = 0;