/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ /*-------------------- Global structure --------------------*/ struct Emotiv = [ EMOTIV_inst : PInstance, EMOTIV_object : ObjEmotiv, EMOTIV_iExpressionType : I, EMOTIV_iActionType : I, EMOTIV_sProfile : S, EMOTIV_sListOfProfiles : [S r1], EMOTIV_sSensorPads : S, EMOTIV_dlgstr : VUIDlg, EMOTIV_trainingTime : I, EMOTIV_nextTick : I ] mkEmotiv;; /*-------------------- Global variables --------------------*/ var profilePath = "./configEmotiv/";; var currentProfile = "";; var fUpperFacePower = 0.0;; var fLowerFacePower = 0.0;; var fActionPower = 0.0;; var fEyePower = 0.0;; fun deleteOb(inst, obstr)= _DSEmotiv obstr.EMOTIV_object; if obstr.EMOTIV_dlgstr == nil then nil else VUIdestroyDialogBox obstr.EMOTIV_dlgstr; set obstr.EMOTIV_object = nil; 0;; fun cbConnected(mEmotiv, obstr)= SendPluginEvent obstr.EMOTIV_inst "Headset connected" nil nil; 0;; fun cbDisconnected(mEmotiv, obstr)= SendPluginEvent obstr.EMOTIV_inst "Headset disconnected" nil nil; 0;; fun cbPoorSignal(mEmotiv, obstr)= SendPluginEvent obstr.EMOTIV_inst "Headset poor signal" nil nil; 0;; fun cbLowBattery(mEmotiv, obstr)= SendPluginEvent obstr.EMOTIV_inst "Headset low battery" nil nil; 0;; fun cbNewHeadsetData(mEmotiv, obstr, referencePads, lHemisphere, rHemisphere, gyro, systemUpTime)= let referencePads -> [cms drl] in let lHemisphere -> [af3 f7 f3 fc5 t7 p7 o1] in let rHemisphere -> [af4 f8 f4 fc6 t8 p8 o2] in let gyro -> [x y] in ( if (cms >= 1 && drl >= 1) then ( // Update the values for all sensor pads set obstr.EMOTIV_sSensorPads = strbuild ((itoa cms)::(itoa drl)::(itoa af3)::(itoa f7)::(itoa f3)::(itoa fc5)::(itoa t7)::(itoa p7)::(itoa o1)::(itoa af4)::(itoa f8)::(itoa f4)::(itoa fc6)::(itoa t8)::(itoa p8)::(itoa o2)::nil)::nil; // Send the list of sensor pads status //SendPluginEvent inst "Headset sensor pads" strbuild ((itoa cms)::(itoa drl)::(itoa af3)::(itoa f7)::(itoa f3)::(itoa fc5)::(itoa t7)::(itoa p7)::(itoa o1)::(itoa af4)::(itoa f8)::(itoa f4)::(itoa fc6)::(itoa t8)::(itoa p8)::(itoa o2)::nil)::nil nil; ) else nil; if (systemUpTime <=. 0.0) then nil else SendPluginEvent obstr.EMOTIV_inst "Headset system up time" ftoa systemUpTime nil; if (x == 0.0 && y == 0.0) then nil else SendPluginEvent obstr.EMOTIV_inst "Headset gyro" strbuild ((ftoa x)::(ftoa y)::nil)::nil nil; ); 0;; fun cbNewAffectivData(mEmotiv, obstr, engagement, stress, relaxation, shortExcitement, longExcitement, interest, focus)= //if engagement <=. 0.0 then nil else SendPluginEvent obstr.EMOTIV_inst "Engagement" ftoa engagement nil; //if stress <=. 0.0 then nil else SendPluginEvent obstr.EMOTIV_inst "Stress" ftoa stress nil; //if relaxation <=. 0.0 then nil else SendPluginEvent obstr.EMOTIV_inst "Relaxation" ftoa relaxation nil; //if shortExcitement <=. 0.0 then nil else SendPluginEvent obstr.EMOTIV_inst "Short excitement" ftoa shortExcitement nil; //if longExcitement <=. 0.0 then nil else SendPluginEvent obstr.EMOTIV_inst "Long excitement" ftoa longExcitement nil; //if interest <=. 0.0 then nil else SendPluginEvent obstr.EMOTIV_inst "Interest" ftoa interest nil; //if focus <=. 0.0 then nil else SendPluginEvent obstr.EMOTIV_inst "Focus" ftoa focus nil; 0;; fun cbNewExpressivData(mEmotiv, obstr, eyeExpressionType, upperFaceType, upperFacePower, lowerFaceType, lowerFacePower)= // New eye related action ? if eyeExpressionType != 0 then ( // Switch type of eye related action if eyeExpressionType == 1 then SendPluginEvent obstr.EMOTIV_inst "Blink" "100.0" nil else if eyeExpressionType == 2 then SendPluginEvent obstr.EMOTIV_inst "Left Wink" "100.0" nil else if eyeExpressionType == 4 then SendPluginEvent obstr.EMOTIV_inst "Right Wink" "100.0" nil else if eyeExpressionType == 8 then SendPluginEvent obstr.EMOTIV_inst "Left Look" "100.0" nil else if eyeExpressionType == 16 then SendPluginEvent obstr.EMOTIV_inst "Right Look" "100.0" nil else if eyeExpressionType == 32 then SendPluginEvent obstr.EMOTIV_inst "Up Look" "100.0" nil else if eyeExpressionType == 64 then SendPluginEvent obstr.EMOTIV_inst "Down Look" "100.0" nil else nil; set fEyePower = 100.0; ) // Else reset all parameters else if (fEyePower >. 0.0) then ( SendPluginEvent obstr.EMOTIV_inst "Blink" "0.0" nil; SendPluginEvent obstr.EMOTIV_inst "Left Wink" "0.0" nil; SendPluginEvent obstr.EMOTIV_inst "Right Wink" "0.0" nil; SendPluginEvent obstr.EMOTIV_inst "Left Look" "0.0" nil; SendPluginEvent obstr.EMOTIV_inst "Right Look" "0.0" nil; SendPluginEvent obstr.EMOTIV_inst "Up Look" "0.0" nil; SendPluginEvent obstr.EMOTIV_inst "Down Look" "0.0" nil; set fEyePower = 0.0; ) else nil; // New upper face action ? if upperFaceType != 0 && upperFacePower >. 0.0 then ( // Switch type of upper face action if upperFaceType == 1 then SendPluginEvent obstr.EMOTIV_inst "Surprise" ftoa upperFacePower nil else if upperFaceType == 2 then SendPluginEvent obstr.EMOTIV_inst "Frown" ftoa upperFacePower nil else nil; set fUpperFacePower = upperFacePower; ) // Else reset all parameters else if (fUpperFacePower >. 0.0) then ( SendPluginEvent obstr.EMOTIV_inst "Surprise" ftoa upperFacePower nil; SendPluginEvent obstr.EMOTIV_inst "Frown" ftoa upperFacePower nil; set fUpperFacePower = 0.0; ) else nil; // New lower face action ? if lowerFaceType != 0 && lowerFacePower >. 0.0 then ( // Switch type of lower face action if lowerFaceType == 1 then SendPluginEvent obstr.EMOTIV_inst "Clench" ftoa lowerFacePower nil else if lowerFaceType == 2 then SendPluginEvent obstr.EMOTIV_inst "Smile" ftoa lowerFacePower nil else if lowerFaceType == 4 then SendPluginEvent obstr.EMOTIV_inst "Laugh" ftoa lowerFacePower nil else if lowerFaceType == 8 then SendPluginEvent obstr.EMOTIV_inst "Left Smirk" ftoa lowerFacePower nil else if lowerFaceType == 16 then SendPluginEvent obstr.EMOTIV_inst "Right Smirk" ftoa lowerFacePower nil else nil; set fLowerFacePower = lowerFacePower; ) // Else reset all parameters else if (fLowerFacePower >. 0.0) then ( SendPluginEvent obstr.EMOTIV_inst "Clench" ftoa lowerFacePower nil; SendPluginEvent obstr.EMOTIV_inst "Smile" ftoa lowerFacePower nil; SendPluginEvent obstr.EMOTIV_inst "Laugh" ftoa lowerFacePower nil; SendPluginEvent obstr.EMOTIV_inst "Left Smirk" ftoa lowerFacePower nil; SendPluginEvent obstr.EMOTIV_inst "Right Smirk" ftoa lowerFacePower nil; set fLowerFacePower = 0.0; ) else nil; if lowerFaceType != 0 || upperFaceType != 0 then nil else SendPluginEvent obstr.EMOTIV_inst "Neutral" ftoa /*temporary*/(maxf lowerFacePower upperFacePower) nil; 0;; fun cbNewCognitivData(mEmotiv, obstr, actionType, actionPower)= if actionType > 0 && actionPower >. 0.0 then ( if actionType == 2 then SendPluginEvent obstr.EMOTIV_inst "Push" ftoa actionPower nil else if actionType == 4 then SendPluginEvent obstr.EMOTIV_inst "Pull" ftoa actionPower nil else if actionType == 8 then SendPluginEvent obstr.EMOTIV_inst "Lift" ftoa actionPower nil else if actionType == 16 then SendPluginEvent obstr.EMOTIV_inst "Drop" ftoa actionPower nil else if actionType == 32 then SendPluginEvent obstr.EMOTIV_inst "Left" ftoa actionPower nil else if actionType == 64 then SendPluginEvent obstr.EMOTIV_inst "Right" ftoa actionPower nil else if actionType == 128 then SendPluginEvent obstr.EMOTIV_inst "Rotate Left" ftoa actionPower nil else if actionType == 256 then SendPluginEvent obstr.EMOTIV_inst "Rotate Right" ftoa actionPower nil else if actionType == 512 then SendPluginEvent obstr.EMOTIV_inst "Rotate Clockwise" ftoa actionPower nil else if actionType == 1024 then SendPluginEvent obstr.EMOTIV_inst "Rotate Anti-Clockwise" ftoa actionPower nil else if actionType == 2048 then SendPluginEvent obstr.EMOTIV_inst "Rotate Forwards" ftoa actionPower nil else if actionType == 4096 then SendPluginEvent obstr.EMOTIV_inst "Rotate Reverse" ftoa actionPower nil else if actionType == 8192 then SendPluginEvent obstr.EMOTIV_inst "Disappear" ftoa actionPower nil else nil; set fActionPower = actionPower; ) // Else reset all parameters else if (fActionPower >. 0.0) then ( SendPluginEvent obstr.EMOTIV_inst "Push" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Pull" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Lift" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Drop" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Left" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Right" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Rotate Left" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Rotate Right" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Rotate Clockwise" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Rotate Anti-Clockwise" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Rotate Forwards" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Rotate Reverse" ftoa actionPower nil; SendPluginEvent obstr.EMOTIV_inst "Disappear" ftoa actionPower nil; set fActionPower = 0.0; ) else nil; 0;; fun cbPreRenderCountdown(inst, viewstr, obstr)= let V3DgetSessionView c3dXsession -> viewstr in let _tickcount -> tick in if (obstr.EMOTIV_nextTick > tick) || (obstr.EMOTIV_trainingTime <= 0) then nil else ( let VUIgetDialogFrame obstr.EMOTIV_dlgstr -> framestr in VUIsetElementTextContent framestr (strcat (itoa obstr.EMOTIV_trainingTime) " seconds remaining"); VUIupdateDialogBoxSize (V3DgetSessionView c3dXsession) obstr.EMOTIV_dlgstr; set obstr.EMOTIV_nextTick = tick + 1000; set obstr.EMOTIV_trainingTime = obstr.EMOTIV_trainingTime - 1; ); 0;; fun cbExpressivTrainingStarted(mEmotiv, obstr)= set obstr.EMOTIV_trainingTime = 8; set obstr.EMOTIV_nextTick = 0; setPluginInstanceCbPreRender obstr.EMOTIV_inst mkfun3 @cbPreRenderCountdown obstr; SendPluginEvent obstr.EMOTIV_inst "Facial expression training started" nil nil; 0;; fun cbCognitivTrainingStarted(mEmotiv, obstr)= set obstr.EMOTIV_trainingTime = 8; set obstr.EMOTIV_nextTick = 0; setPluginInstanceCbPreRender obstr.EMOTIV_inst mkfun3 @cbPreRenderCountdown obstr; SendPluginEvent obstr.EMOTIV_inst "Mental command training started" nil nil; 0;; fun cbExpressivTrainingCompleted(mEmotiv, obstr)= //SendPluginEvent obstr.EMOTIV_inst "Facial expression training completed" nil nil; SendPluginEvent obstr.EMOTIV_inst "Facial expression training completed" strbuild ((itoa obstr.EMOTIV_iExpressionType)::"Completed"::nil)::nil nil; 0;; fun cbCognitivTrainingCompleted(mEmotiv, obstr)= //SendPluginEvent obstr.EMOTIV_inst "Mental command training completed" nil nil; SendPluginEvent obstr.EMOTIV_inst "Mental command training completed" strbuild ((itoa obstr.EMOTIV_iActionType)::"Completed"::nil)::nil nil; 0;; fun getExpressionType(expression, obstr) = // Check if the parameter is from the list if (!strcmp (strtrim expression) "Neutral") then set obstr.EMOTIV_iExpressionType = 1 else if (!strcmp (strtrim expression) "Raise Brow") then set obstr.EMOTIV_iExpressionType = 32 else if (!strcmp (strtrim expression) "Furrow Brow") then set obstr.EMOTIV_iExpressionType = 64 else if (!strcmp (strtrim expression) "Smile") then set obstr.EMOTIV_iExpressionType = 128 else if (!strcmp (strtrim expression) "Clench") then set obstr.EMOTIV_iExpressionType = 256 else if (!strcmp (strtrim expression) "Laugh") then set obstr.EMOTIV_iExpressionType = 512 else if (!strcmp (strtrim expression) "Left Smirk") then set obstr.EMOTIV_iExpressionType = 1024 else if (!strcmp (strtrim expression) "Right Smirk") then set obstr.EMOTIV_iExpressionType = 2048 // Otherwise, it's a user defined parameter else set obstr.EMOTIV_iExpressionType = atoi expression; 0;; fun getActionType(action, obstr) = // Check if the parameter is from the list if (!strcmp (strtrim action) "Neutral") then set obstr.EMOTIV_iActionType = 1 else if (!strcmp (strtrim action) "Push") then set obstr.EMOTIV_iActionType = 2 else if (!strcmp (strtrim action) "Pull") then set obstr.EMOTIV_iActionType = 4 else if (!strcmp (strtrim action) "Lift") then set obstr.EMOTIV_iActionType = 8 else if (!strcmp (strtrim action) "Drop") then set obstr.EMOTIV_iActionType = 16 else if (!strcmp (strtrim action) "Left") then set obstr.EMOTIV_iActionType = 32 else if (!strcmp (strtrim action) "Right") then set obstr.EMOTIV_iActionType = 64 else if (!strcmp (strtrim action) "Rotate Left") then set obstr.EMOTIV_iActionType = 128 else if (!strcmp (strtrim action) "Rotate Right") then set obstr.EMOTIV_iActionType = 256 else if (!strcmp (strtrim action) "Rotate Clockwise") then set obstr.EMOTIV_iActionType = 512 else if (!strcmp (strtrim action) "Rotate Counter-Clockwise") then set obstr.EMOTIV_iActionType = 1024 else if (!strcmp (strtrim action) "Rotate Forwards") then set obstr.EMOTIV_iActionType = 2048 else if (!strcmp (strtrim action) "Rotate Reverse") then set obstr.EMOTIV_iActionType = 4096 else if (!strcmp (strtrim action) "Disappear") then set obstr.EMOTIV_iActionType = 8192 // Otherwise, it's a user defined parameter else set obstr.EMOTIV_iActionType = atoi action; 0;; // DEBUG: Display all the elements from a list fun displayElemsFromList(l)= let sizelist l -> size in let "" -> str in let 0 -> i in ( while i < size do ( let nth_list l i -> elem in if (i == 0) then set str = strcat str elem else set str = strcat strcat str ":" elem; set i = i + 1; ); _fooS strcatn "Profiles = "::str::"\n"::nil; );; fun cbStartExpressivTraining(inst, from, action, param, reply, obstr)= if param == nil then nil else ( getExpressionType param obstr; if (_StartExpressivTraining obstr.EMOTIV_object obstr.EMOTIV_iExpressionType) != 1 then nil else let V3DgetSessionView c3dXsession -> viewstr in ( let (loc "OS3DEMOTIV_C0006") -> title in set obstr.EMOTIV_dlgstr = VUIcreateDialogBoxExt viewstr (getVUIgroupFromInstance inst) title (loc "OS3DEMOTIV_C0003") nil nil 95 (V3DgetVrMode viewstr) nil "dialogBox"; VUIshowDialog obstr.EMOTIV_dlgstr 1; VUIsetContainerPos obstr.EMOTIV_dlgstr.VUIDLG_container [0.0 0.0] [1 1] nil; ); ); 0;; fun cbEraseExpressivTraining(inst, from, action, param, reply, obstr)= if param == nil then nil else ( getExpressionType param obstr; _EraseExpressivTraining obstr.EMOTIV_object obstr.EMOTIV_iExpressionType; ); 0;; fun cbStartCognitivTraining(inst, from, action, param, reply, obstr)= if param == nil then nil else ( getActionType param obstr; if (_StartCognitivTraining obstr.EMOTIV_object obstr.EMOTIV_iActionType) != 1 then nil else let V3DgetSessionView c3dXsession -> viewstr in ( let (loc "OS3DEMOTIV_C0007") -> title in set obstr.EMOTIV_dlgstr = VUIcreateDialogBoxExt viewstr (getVUIgroupFromInstance inst) title (loc "OS3DEMOTIV_C0003") nil nil 95 (V3DgetVrMode viewstr) nil "dialogBox"; VUIshowDialog obstr.EMOTIV_dlgstr 1; VUIsetContainerPos obstr.EMOTIV_dlgstr.VUIDLG_container [0.0 0.0] [1 1] nil; ); ); 0;; fun cbEraseCognitivTraining(inst, from, action, param, reply, obstr)= if param == nil then nil else ( getActionType param obstr; _EraseCognitivTraining obstr.EMOTIV_object obstr.EMOTIV_iActionType; ); 0;; fun cbLoadProfile(inst, from, action, param, reply, obstr)= if param == nil then nil else ( // Update list of available profiles let _listoffiles profilePath -> files in ( if (files == nil) then nil else ( // DEBUG : Display the list of user profiles that can be loaded displayElemsFromList files; // Update list of available profiles set obstr.EMOTIV_sListOfProfiles = files; set currentProfile = strcatn profilePath::(strtrim param)::".emu"::nil; // Load profile set obstr.EMOTIV_sProfile = currentProfile; _fooS strcat "Load profile : " obstr.EMOTIV_sProfile; _EmotivLoadProfile obstr.EMOTIV_object obstr.EMOTIV_sProfile; ); ); ); 0;; fun cbSaveProfile(inst, from, action, param, reply, obstr)= // If param nil, save to current loaded profile if param == nil then ( _fooS strcat "Save profile : " obstr.EMOTIV_sProfile; _EmotivSaveProfile obstr.EMOTIV_object obstr.EMOTIV_sProfile; ) // Save to a new profile else ( set currentProfile = strcatn profilePath::(strtrim param)::".emu"::nil; _fooS strcat "New user profile : " currentProfile; // Update current profile set obstr.EMOTIV_sProfile = currentProfile; // Update list of profiles set obstr.EMOTIV_sListOfProfiles = lcat obstr.EMOTIV_sListOfProfiles obstr.EMOTIV_sProfile::nil; _fooS strcat "Save profile : " obstr.EMOTIV_sProfile; _EmotivSaveProfile obstr.EMOTIV_object obstr.EMOTIV_sProfile; ); 0;; fun cbUpdateSensors(inst, from, action, param, reply, obstr)= SendPluginEvent inst "Headset sensor contact quality" obstr.EMOTIV_sSensorPads nil; 0;; fun cbExpressivTrainingErased(mEmotiv, obstr)= //SendPluginEvent obstr.EMOTIV_inst "Facial expression training erased" nil nil; SendPluginEvent obstr.EMOTIV_inst "Facial expression training erased" strbuild ((itoa obstr.EMOTIV_iExpressionType)::"Erased"::nil)::nil nil; 0;; fun cbCognitivTrainingErased(mEmotiv, obstr)= SendPluginEvent obstr.EMOTIV_inst "Mental command training erased" nil nil; 0;; fun cbExpressivTrainingRejected(mEmotiv, obstr)= SendPluginEvent obstr.EMOTIV_inst "Facial expression training rejected" nil nil; 0;; fun cbCognitivTrainingRejected(mEmotiv, obstr)= SendPluginEvent obstr.EMOTIV_inst "Mental command training rejected" nil nil; 0;; fun cbDlgClickExpressivSucceeded(dlgstr, state, obstr)= if state == 1 then _AcceptExpressivTraining(obstr.EMOTIV_object) else _RejectExpressivTraining(obstr.EMOTIV_object); 0;; fun cbExpressivTrainingSucceeded(mEmotiv, obstr)= setPluginInstanceCbPreRender obstr.EMOTIV_inst nil; VUIdestroyDialogBox(obstr.EMOTIV_dlgstr); let V3DgetSessionView c3dXsession -> viewstr in let (loc "OS3DEMOTIV_C0006") -> title in set obstr.EMOTIV_dlgstr = VUIcreateDialogBoxExt viewstr (getVUIgroupFromInstance obstr.EMOTIV_inst) title (loc "OS3DEMOTIV_C0004") (loc "OS3DEMOTIV_C0001") (loc "OS3DEMOTIV_C0002") 95 (V3DgetVrMode viewstr) (mkfun3 @cbDlgClickExpressivSucceeded obstr) "dialogBox"; VUIshowDialog obstr.EMOTIV_dlgstr 1; SendPluginEvent obstr.EMOTIV_inst "Facial expression training succeeded" nil nil; 0;; fun cbDlgClickCognitivSucceeded(dlgstr, state, obstr)= if state == 1 then _AcceptCognitivTraining(obstr.EMOTIV_object) else _RejectCognitivTraining(obstr.EMOTIV_object); 0;; fun cbCognitivTrainingSucceeded(mEmotiv, obstr)= setPluginInstanceCbPreRender obstr.EMOTIV_inst nil; VUIdestroyDialogBox(obstr.EMOTIV_dlgstr); let V3DgetSessionView c3dXsession -> viewstr in let (loc "OS3DEMOTIV_C0007") -> title in set obstr.EMOTIV_dlgstr = VUIcreateDialogBoxExt viewstr (getVUIgroupFromInstance obstr.EMOTIV_inst) title (loc "OS3DEMOTIV_C0004") (loc "OS3DEMOTIV_C0001") (loc "OS3DEMOTIV_C0002") 95 (V3DgetVrMode viewstr) (mkfun3 @cbDlgClickCognitivSucceeded obstr) "dialogBox"; VUIshowDialog obstr.EMOTIV_dlgstr 1; SendPluginEvent obstr.EMOTIV_inst "Mental command training succeeded" nil nil; 0;; fun cbDlgClickExpressivFailed(dlgstr, state, obstr)= if state != 1 then nil else _StartExpressivTraining obstr.EMOTIV_object obstr.EMOTIV_iExpressionType; 0;; fun cbExpressivTrainingFailed(mEmotiv, obstr)= setPluginInstanceCbPreRender obstr.EMOTIV_inst nil; VUIdestroyDialogBox(obstr.EMOTIV_dlgstr); let V3DgetSessionView c3dXsession -> viewstr in let (loc "OS3DEMOTIV_C0006") -> title in set obstr.EMOTIV_dlgstr = VUIcreateDialogBoxExt viewstr (getVUIgroupFromInstance obstr.EMOTIV_inst) title (loc "OS3DEMOTIV_C0005") (loc "OS3DEMOTIV_C0001") (loc "OS3DEMOTIV_C0002") 95 (V3DgetVrMode viewstr) (mkfun3 @cbDlgClickExpressivFailed obstr) "dialogBox"; VUIshowDialog obstr.EMOTIV_dlgstr 1; SendPluginEvent obstr.EMOTIV_inst "Facial expression training failed" nil nil; 0;; fun cbDlgClickCognitivFailed(dlgstr, state, obstr)= if state != 1 then nil else _StartCognitivTraining obstr.EMOTIV_object obstr.EMOTIV_iActionType; 0;; fun cbCognitivTrainingFailed(mEmotiv, obstr)= setPluginInstanceCbPreRender obstr.EMOTIV_inst nil; VUIdestroyDialogBox(obstr.EMOTIV_dlgstr); let V3DgetSessionView c3dXsession -> viewstr in let (loc "OS3DEMOTIV_C0007") -> title in set obstr.EMOTIV_dlgstr = VUIcreateDialogBoxExt viewstr (getVUIgroupFromInstance obstr.EMOTIV_inst) title (loc "OS3DEMOTIV_C0005") (loc "OS3DEMOTIV_C0001") (loc "OS3DEMOTIV_C0002") 95 (V3DgetVrMode viewstr) (mkfun3 @cbDlgClickCognitivFailed obstr) "dialogBox"; VUIshowDialog obstr.EMOTIV_dlgstr 1; SendPluginEvent obstr.EMOTIV_inst "Mental command training failed" nil nil; 0;; fun cbNewRawEEGData(mEmotiv, obstr, eegData)= let sizelist eegData -> size in let "" -> eegDataStr in let 0 -> i in ( while i < size do ( let nth_list eegData i -> eeg in if (i == 0) then set eegDataStr = strcat eegDataStr (ftoa eeg) else set eegDataStr = strcat strcat eegDataStr ";" (ftoa eeg); set i = i + 1; ); SendPluginEvent obstr.EMOTIV_inst "Raw EEG" eegDataStr nil; ); 0;; fun cbEnable(inst, from, action, param, rep, obstr)= if (obstr.EMOTIV_object != nil) then nil else ( // Create the object set obstr.EMOTIV_object = _CREmotiv _channel; // Associate callbacks to the current EMOTIV object _CBEmotivConnected obstr.EMOTIV_object @cbConnected obstr; _CBEmotivDisconnected obstr.EMOTIV_object @cbDisconnected obstr; _CBEmotivBadSignal obstr.EMOTIV_object @cbPoorSignal obstr; _CBEmotivLowBattery obstr.EMOTIV_object @cbLowBattery obstr; _CBEmotivHeadsetData obstr.EMOTIV_object @cbNewHeadsetData obstr; _CBEmotivAffectivData obstr.EMOTIV_object @cbNewAffectivData obstr; _CBEmotivExpressivData obstr.EMOTIV_object @cbNewExpressivData obstr; _CBEmotivCognitivData obstr.EMOTIV_object @cbNewCognitivData obstr; _CBEmotivExpressivTrainingStarted obstr.EMOTIV_object @cbExpressivTrainingStarted obstr; _CBEmotivCognitivTrainingStarted obstr.EMOTIV_object @cbCognitivTrainingStarted obstr; _CBEmotivExpressivTrainingCompleted obstr.EMOTIV_object @cbExpressivTrainingCompleted obstr; _CBEmotivCognitivTrainingCompleted obstr.EMOTIV_object @cbCognitivTrainingCompleted obstr; _CBEmotivExpressivTrainingErased obstr.EMOTIV_object @cbExpressivTrainingErased obstr; _CBEmotivCognitivTrainingErased obstr.EMOTIV_object @cbCognitivTrainingErased obstr; _CBEmotivExpressivTrainingRejected obstr.EMOTIV_object @cbExpressivTrainingRejected obstr; _CBEmotivCognitivTrainingRejected obstr.EMOTIV_object @cbCognitivTrainingRejected obstr; _CBEmotivExpressivTrainingSucceeded obstr.EMOTIV_object @cbExpressivTrainingSucceeded obstr; _CBEmotivCognitivTrainingSucceeded obstr.EMOTIV_object @cbCognitivTrainingSucceeded obstr; _CBEmotivExpressivTrainingFailed obstr.EMOTIV_object @cbExpressivTrainingFailed obstr; _CBEmotivCognitivTrainingFailed obstr.EMOTIV_object @cbCognitivTrainingFailed obstr; _CBEmotivRawEEGData obstr.EMOTIV_object @cbNewRawEEGData obstr; // Associate callbacks to actions PluginRegisterAction inst "Start Expressiv training" mkfun6 @cbStartExpressivTraining obstr; PluginRegisterAction inst "Start Cognitiv training" mkfun6 @cbStartCognitivTraining obstr; PluginRegisterAction inst "Erase Expressiv training" mkfun6 @cbEraseExpressivTraining obstr; PluginRegisterAction inst "Erase Cognitiv training" mkfun6 @cbEraseCognitivTraining obstr; PluginRegisterAction inst "Load profile" mkfun6 @cbLoadProfile obstr; PluginRegisterAction inst "Save profile" mkfun6 @cbSaveProfile obstr; PluginRegisterAction inst "Get sensors contact quality" mkfun6 @cbUpdateSensors obstr; ); 0;; fun cbDisable(inst, from, action, param, rep, p)= SendPluginEvent inst "Headset disconnected" nil nil; deleteOb inst p; 0;; fun newOb(inst)= let atoi (getPluginInstanceParam inst "oninit") -> oninit in let mkEmotiv [inst nil 0 0 nil nil nil nil 0 0] -> obstr in ( if !oninit then nil else cbEnable inst nil nil nil nil obstr; PluginRegisterAction inst "Enable" mkfun6 @cbEnable obstr; PluginRegisterAction inst "Disable" mkfun6 @cbDisable obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;