EEG .pdf


À propos / Télécharger Visionner le document
Nom original: EEG.pdf

Ce document au format PDF 1.5 a été généré par LaTeX with hyperref package / pdfTeX-1.40.12, et a été envoyé sur fichier-pdf.fr le 25/06/2012 à 19:46, depuis l'adresse IP 188.188.x.x. La présente page de téléchargement du fichier a été vue 3590 fois.
Taille du document: 3.2 Mo (31 pages).
Confidentialité: fichier public


Aperçu du document


ELECTRONIC AND EMOTIVE SOUND PROCESSING
GODEFROID Robin
1st Master Electronic
Robin.Godefroid@Gmail.com
A BSTRACT

2. SYNOPSIS

The project, shown in this document, offers a new perspective for sound processing, in the arts, based on use of a
sensory sensor and a rapid prototyping software.
An electroencephalography headset [9] is used in order to recognize user’s feelings. These information are
retrieved through the open-source workbench Skemmi
[10]. Furthermore, this workbench includes the components needed to communicate with Kyma [11], a powerful
sound processing software.
The work was to implement, inside Skemmi, tools that
allows a simple control, requiring a minimum technical
prerequisites for users, of the sounds settings like the volume, the distorsion, etc.
The application was developed in an open way to allow
use of other sensory inputs interface like, for example, a
Wiimote or a Kinect.
Keywords Signal processing · Sound processing · Emotiv
Epoc · Kyma · OpenInterface · human/machine interface ·
Electroencephalography · C++
1. INTRODUCTION
Nowadays, creating music is mostly based on two approaches :
• A “classical” approach in which music comes from
“ancestral” instruments and is played, directly, by
the artists ;
• An electronic approach where the composition is
done through a computer or a synthesizer.
However, with technological advances which allow
more and more efficient and affordable solutions for sensory sensors (motion detection, sound sensor, . . . ), and
modern computing tools that permit a simple use of these
interfaces, we can imagine a new way for conceiving music.
This one would allow a interaction mainly based on
user’s behavior, his gestures, ... which would give other
artistic possibilities in musical composition.
It’s with this idea that our work has started. We decided
to study the possibility of using an electroencephalographic headset to recognize the user/artist’s feelings in order
to allow sound and sound effects modification according
to these collected information.

The information, about the user’s behavior, are transmited, via a wireless connection, from the electroencephalographic headset to Skemmi. The communication between Skemmin (running on a computer) and Kyma (running on a MAC) is established through Internet using the
OSC protocol 1 . Thereby forwarded to Kyma, the desired
action is finally “materialized” (≡ sonification) through
electronic processing done by the Pacarana, and the audio
interface.
3. SPECIFICATIONS
The application has to allow :
• an interaction as simple as possible with the sound
processing software ;
• an automatic update of the sound settings (dynamic
adaptation) ;
• interfacing the main electroencephalographic headset functions (depending on the API 2 available).

1 . OpenSoundControl, data transmission protocol through Internet
network
2 . ApplicationProgrammingInterface

4. TOOLS

Example with 2 settings :
• Query : “/osc/widget 0”, reply from Kyma :
“/osc/widget 0 JSON0” (first widget) ;

4.1. Kyma

• Query : “/osc/widget 1”, reply from Kyma :
“/osc/widget 1 JSON1” (second widget) ;
• Query : “/osc/widget 2”, reply from Kyma :
“/osc/widget 2” (widget non-existent).
It can be used to detect the end of the enumeration
of the currents settings (we will send the “/osc/widget i” message while the “/osc/widget i” response is
not empty).
4.1.2. JSON structure
The JSON structures, containing the widgets attributes,
are represented as follows :
Figure 1: Kyma

JSON Code
{
" c r e a t i o n C l a s s " : " VCSEventSourceComponent " ,
" layout " : {
" c r e a t i o n C l a s s " : " LayoutFrame " ,
" leftOffset " : 0,
" topOffset " : 0 ,
" rightOffset " : 0,
" bottomOffset " : 0 ,
" l e f t F ra c t i o n " : 0.0 ,
" topFraction " : 0.0 ,
" r i g h t F r a c t i o n " : 0.125 ,
" bottomFraction " : 1.0 ,
}
" l a b e l " : "Amp" ,
" lookOrNil " : null ,
" displayType " : " Fader " ,
" c o n c r e t e E v e n t I d " : 3145730 ,
" minimum " : 0 ,
" maximum " : 0 ,
" grid " : 0 ,
" taper " : " linear " ,
" showNumber " : t r u e ,
" isGenerated " : false ,
" reflectMarker " : null ,
" tickMarksOrNil " : null

Kyma is a powerful graphic software for sound design. In a first step, only a few possibilities, offered by
this software, have been exploited namely the communication with the software in order to determine and modify
the sound settings.
4.1.1. Communication
The communication is established through OSC
messages and proceeds as follows :
Legend :
Messages to Kyma (queries)
Messages from Kyma (replies)
1. /osc/respond_to i
Where “/osc/respond_to” is the OSC pattern and “i”
is an integer corresponding to the port where Kyma
has to send its OSC messages.
2. /osc/response_from i
Where “i” is an integer corresponding to the port
used (by our computer) to send the first message.
3. /osc/widget i
Where “i” is an integer corresponding to the widget
for which we want to know the attributes.
4. /osc/widget i JSON
Where “i” is an integer corresponding to the widget query and “JSON” is a JSON 3 structure which
contains the widget attributes.
5. /osc/widget i
If we send a widget query to kyma with a widget
that doesn’t exist (wrong number), kyma will respond with an “empty JSON”.

3 . JavaScript Object Notation

}

For this application, only a few of these attributes are
relevant :
• creationClass : informs about the type of the widget. For this application, only the “VCSEventSourceComponent” is used ;
• label : widget name (“Amplitude”, “Distorsion”,
...);
• concreteEventID : widget identification (ID). It’s
probably the most important information needed. It’s
with that ID that it’s possible to modify the settings
value ;
• minimum : minimum value for the widget ;
• maximum : maximum value for the widget.
To get back these information, the structure needs to be
parsed. To do this, the SimpleJSON library 4 , written in
4 . https ://github.com/MJPA/SimpleJSON (accessed February 2012)

C++, is used.

4.1.3. Notifications
The notifications are used to warn when new settings
are used (new song in Kyma). Nevertheless, they have to
be activated first :
/osc/notify/vcs/. . . i
Where “. . . ” is an arbitrary word (we can choose
what we want but we have to know that Kyma will
respond with the same OSC pattern) and “i” is an integer
corresponding to the notifications status (1 = enabled, 0 =
disabled).
When the played song is changed, Kyma will send the
following message :
/osc/notify/vcs/. . . i
Where “. . . ” is the same word used in the query and
“i” is an integer corresponding to the number of widgets
used in the new sound.
Once the notification received, it only remains to get
back the new settings (“/osc/widget i”).

Figure 3: Emotiv Epoc
4.3. Emotiv EPOC
“The Emotiv EPOC is a high resolution, neuro-signal
acquisition and processing wireless neuroheadset. It uses
a set of sensors to tune into electric signals produced by
the brain to detect user thoughts, feelings and expressions
and connects wirelessly to most PCs”.
It’s used, in this project, as sensory sensor in order to
modify sound settings according to the user’s behavior.
There are 2 main ways to use the sensor :
• Use the functions implemented in the Emotiv API ;
• Perform a signal processing on the raw signals.
4.3.1. Emotiv API

4.1.4. Settings modification
Changing the widgets value is done with the following
OSC message :
/vcs id value
Where “id” is an integer corresponding to the widget
ID (parsed in the JSON structure) and “value” is a float
corresponding to the desired value.

4.2. Paccarana

Emotiv offers an API to use the EEPOC. This one can
be used with several programming languages (C++, Java,
.NET, . . . ) and allows to exploit the headset without any
“medical” knowledge (it’s ideal for rapid prototyping).
It has 3 main suites :
• Affectiv suite : informs about some user’s feelings
(peaceful, nervous, . . . ) ;
• Cognitiv suite : allows recording brain activity
states in order to reuse them afterward (≡ learning) ;
• Expressiv suite : informs about face expressions
(smile, blink, eyebrow motion, . . . ).
Only this last one had time to be explored. The API
is fairly simple to use and the results (with the expressiv
suite) are “amazing”.
4.3.2. Raw signals

Figure 2: Pacarana
The Pacarana is a set of 4 DSP 5 that allows a powerfull electronic processing. It’s specially designed for
sound processing and it permits to use all the Kyma capacities.

The API also allows to get back the raw signals from
the electrodes. Once got back, it’s possible to perform
many kind of processing (filtering, FFT 6 , learning, . . . )
on these signals according to the desired result (brain activity analysis, motion detection, . . . ). However, this method is difficult to implment and requires time. Furthermore requires some brain activity knowledges. Neverthe5 . Digital Signal Processor
6 . FastFourierTransform

less it’s the one which offers the most long-term possibilities. This method has not been more explored, so it will
not be described further.

5. COMPONENTS IMPLEMENTATION
5.1. Kyma

4.4. OpenInterface Workbench (Skemmi)

Figure 5: Kyma component

Figure 4: Skemmi
OpenInterface Workbench (called Skemmi) is an
Eclipse plugin which allows rapid integration of heterogeneous components. Specially designed for rapid prototyping, the workbench allows interaction between components written in several languages (C++, Java, . . . ).
The interaction between the sensor (EEPOC) and the
sound processing software (Kyma) is done through this
platform.
Skemmi is shown as graphical diagrams. These diagrams are composed with differents blocks (representing
sensors, softwares, . . . ) and the interaction between blocks
is done with connection between their inputs and block
outputs (cf. figure 4)
The peculiarity of this platform is that the block drivers (block operation) may be coded in the any desired
programming language and will be executed by the kernel
of Skemmi in a specific thread.
So, graphically it’s like a data flow programming language but each bloc executes a specific code (which can
be structured, object-oriented, multi-task, . . . ).

Inputs :
• Start : initializes the communication between
Skemmi and Kyma ;
• Respond_from : receives the first reply from Kyma
(≡ ACK) ;
• JSON_input : receives the JSON structures ;
• Notify_I : called when a song is changed and notifications are enabled.
Outputs :
• Remove_settings : deletes all the Virtual Interface
inputs/outputs (cf. §5.3.2) ;
• Add_setting : adds an input/output to the Virtual Interface ;
• Respond_to : sends the first message to Kyma ;
• Widget : sends a query for the corresponding widget ;
• Notify_O : enables/disables the notifications.
5.2. EEPOC

Figure 6: EEPOC component

Inputs :
• Start : starts the communication with the EEPOC ;
• Stop : stops the communication and frees up the memory.
Sorties :
• LookRight : sends 1 if the user is looking on the
right, 0 otherwise ;
• LookLeft : sends 1 if the user is looking on the left,
0 otherwise ;
• Clench : sends a value between 0 and 1 corresponding to the clench intensity of the user’s teeth ;
• Eyebrow : sends a value between 0 and 1 corresponding to the motion intensity of the user’s eyebrow ;
• Smile : sends a value between 0 and 1 corresponding
to the user’s smile intensity ;
• LookRight : sends 1 if the user is blinking, 0 otherwise ;
• LeftWink : sends 1 if the user closes the left eye, 0
otherwise ;
• RightWink : sends 1 if the user closes the right eye,
0 otherwise ;
• EyesOpen : sends 1 if the user closes the eyes, 0
otherwise ;
• Gyro : sends the headset gyroscope coordinates
(x,y) ;
• EEG : sends the raw signals value (14 channels).
5.3. Operation
Although the community is not very wide yet Skemmi
has a number of components already implemented or available on the Web 7 , including all the components needed
for the OSC communication with Kyma.

These blocks can be interfaced directly with the Kyma
component.

Figure 7: connection between the OSC blocks and the
Kyma component

5.3.2. The Virtual Interface
The Virtual Interface is a component designed specially for this application. Unlike the other static components, this one has the possibility to adapt dynamically its
inputs/outputs via control signals. This interface is driven
by the Kyma component in order to get a number of inputs/outputs equivalent to the number of sound settings.
Each signal from the sensor can be connected to the input
corresponding to the desired setting and, the ouput corresponding to this input, can be connected to the OSC client.

5.3.1. OSC components
Skemmi has 2 OSC blocks :
• OSC client : used to send a specific pattern ;
• OSC server : used to receive a specific pattern ;

Figure 8: Virtual Interface
The Virtual Interface is relatively recent in Skemmi,
so the “Forward” component is temporally used to ensure
the compatibility with the OSC blocks.

7 . https ://forge.openinterface.org/ (accessed first semester 2012)

This interface can be driven by any component and can
receive signals from any block (sensor).

6. CONCLUSION
The developed application is still at the prototype stage
and still requires the correction of some bugs (especially
for the new components implemented in Skemmi). However, after this first year of study, and through the various
tools used (including the Emotiv API, easy to handle, and
the rapid prototyping software Skemmi), the application
is able to :
• Determine the number of settings present in a song ;
• Adapt itself, in real time, to the sound settings when
they are modified (song changed) ;
• Drive these settings according to signals from many
sensor ;
• Change sensor/settings assignments in real time ;
• Use the main EEPOC Expressiv suite functions ;
• Use any other input sensor.
It can therefore be used to develop artistic applications
wishing to use sensory sensors in order to modify sounds,
images, . . .
The work also provides the use of raw signals from the
sensor to allow a development-oriented to learning, motion and feelings recognition, . . . (signal processing blocks
required are almost all included in Skemmi), or the use of
any other interface which permit a maximum possibilities
and flexibility to the user.
7. BIBLIOGRAPHY
[1] Nebra M., et Schaller M. Programmer avec le langage C++. le Livre du Zéro, France, 2011, 673p.
[2] Lawson L., OpenInterface Platform Component Developer Guide, fichier PDF, 32p.
[3] Lawson L., OpenInterface Platform Description
Languages Specification, fichier PDF, 79p.
[4] Lawson L., OpenInterface Platform Plugins Specification, fichier PDF, 30p.
[5] Lawson L., OpenInterface Platform User Guide, fichier PDF, 17p.
[6] Lawson L., SKEMMI OpenInterface Platform Workbench Quick Start, fichier PDF, 11p.
[7] Scaletti C., Kyma Open Sound Control
Protocol [ en ligne ]. Disponible sur :
<http ://www.symbolicsound.com/cgi-bin/bin/view
/Learn/OpenSoundControlImplementation/> (accessed first semester 2012)
[8] Stroustrup B. Le langage C++. Édition spéciale, revue et corrigée. Pearson Education, France, 2004,
1100p.
[9] Emotiv | EEG System | Electroencephalography [ en
ligne ]. Disponible sur <http ://www.emotiv.com/>
(accessed first semester 2012)
[10] OpenInterface Platform [ en ligne ]. Disponible
sur <http ://www.openinterface.org/platform/> (accessed first semester 2012)

[11] Symbolic Sound Kyma : Company WebHome [ en ligne ]. Disponible sur
<http ://www.symbolicsound.com/> (accessed
first semester 2012)

Figure 9: Final application

Appendix

//Generated by OpenInterface ComponentBuilder
#ifndef _EPOC_Facet_H
#define _EPOC_Facet_H
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef WIN32
#ifdef DLLEXPORT
#define OPENINTERFACE_API __declspec(dllexport)
#else
#define OPENINTERFACE_API __declspec(dllimport)
#endif
#else
#define OPENINTERFACE_API
#endif
OPENINTERFACE_API void Start();
OPENINTERFACE_API void Stop();
OPENINTERFACE_API void setCb_LookRightCallback(void (*cb)(bool LookRight));
OPENINTERFACE_API void setCb_LookLeftCallback(void (*cb)(bool LookLeft));
OPENINTERFACE_API void setCb_ClenchCallback(void (*cb)(double Clench));
OPENINTERFACE_API void setCb_EyeBrowCallback(void (*cb)(double EyeBrow));
OPENINTERFACE_API void setCb_SmileCallback(void (*cb)(double Smile));
OPENINTERFACE_API void setCb_BlinkCallback(void (*cb)(bool Blink));
OPENINTERFACE_API void setCb_LeftWinkCallback(void (*cb)(bool LeftWink));
OPENINTERFACE_API void setCb_RightWinkCallback(void (*cb)(bool RightWink));
OPENINTERFACE_API void setCb_GyroCallback(void (*cb)(int GyroX, int GyroY));
OPENINTERFACE_API void setCb_EEGCallback(void (*cb)(double AF3, double F7, double
F3, double FC5,\
double T7, double P7, double O1, double O2, double P8, double T8, double
FC6, double F4,\
double F8, double AF4));
OPENINTERFACE_API void setCb_EyesOpenCallback(void (*cb)(bool EyesOpen));
#ifdef __cplusplus
}
#endif
#endif

//Generated by OpenInterface ComponentBuilder
#include "EPOC_Facet.h"
#include <stdio.h>
#include <Windows.h>
#include "EmoStateDLL.h"
#include "edk.h"
#include "edkErrorCode.h"
#include <iostream>
#pragma comment(lib, "D:/Program Files/Emotiv Research Edition SDK_v1.0.0.5PREMIUM/doc/examples/lib/edk.lib")
/* OI Callbacks */
static void (*LookRight)(bool LookRight) = NULL;
static void (*LookLeft)(bool LookLeft) = NULL;
static void (*Clench)(double Clench) = NULL;
static void (*EyeBrow)(double EyeBrow) = NULL;
static void (*Smile)(double Smile) = NULL;
static void (*Blink)(bool Blink) = NULL;
static void (*LeftWink)(bool LeftWink) = NULL;
static void (*RightWink)(bool RightWink) = NULL;
static void (*Gyro)(int GyroX, int GyroY) = NULL;
static void (*EEG)(double AF3, double F7, double F3, double FC5,\
double T7, double P7, double O1, double O2, double P8, double T8, double
FC6, double F4,\
double F8, double AF4) = NULL;
static void (*EyesOpen)(bool EyesOpen) = NULL;
/* Prototype */
void logEmoState(unsigned int userID, EmoStateHandle eState);
/* Global var. */
static bool run(false);
EE_DataChannel_t targetChannelList[] = {
ED_COUNTER,
ED_AF3, ED_F7, ED_F3, ED_FC5, ED_T7,
ED_P7, ED_O1, ED_O2, ED_P8, ED_T8,
ED_FC6, ED_F4, ED_F8, ED_AF4, ED_GYROX, ED_GYROY, ED_TIMESTAMP,
ED_FUNC_ID, ED_FUNC_VALUE, ED_MARKER, ED_SYNC_SIGNAL
};

void Start(){
EmoEngineEventHandle eEvent = EE_EmoEngineEventCreate();
EmoStateHandle eState = EE_EmoStateCreate();
unsigned int userID = 0;
const unsigned short composerPort = 1726;
float secs = 1;
unsigned int datarate = 0;
bool readytocollect = false;
int option = 0;
int state = 0;
std::cout<<"connecting.."<<std::endl;
while(EE_EngineConnect() != EDK_OK);
std::cout<<"DATA"<<std::endl;
//EEG signals
DataHandle hData = EE_DataCreate();
EE_DataSetBufferSizeInSec(secs);

run = true;
while (run) {
state = EE_EngineGetNextEvent(eEvent);
// New event needs to be handled
if (state == EDK_OK) {
std::cout<<"STATE OK"<<std::endl;
EE_Event_t eventType = EE_EmoEngineEventGetType(eEvent);
EE_EmoEngineEventGetUserId(eEvent, &userID);
if (eventType == EE_UserAdded) {
std::cout << "User added";
EE_DataAcquisitionEnable(userID,true);
readytocollect = true;
}
// Log the EmoState if it has been updated
if (eventType == EE_EmoStateUpdated) {
EE_EmoEngineEventGetEmoState(eEvent, eState);
const float timestamp = ES_GetTimeFromStart(eState);
logEmoState(userID, eState);
}
}
else if (state != EDK_NO_EVENT) {
break;
}
//sample signal
if (readytocollect) {
EE_DataUpdateHandle(0, hData);
unsigned int nSamplesTaken=0;
EE_DataGetNumberOfSample(hData,&nSamplesTaken);
if (nSamplesTaken != 0) {
double* data = new double[nSamplesTaken];
double value[14] = {0};
for (int sampleIdx=0 ; sampleIdx<(int)nSamplesTaken ; ++
sampleIdx) {
for (int i = 1 ; i < 15 ; i++) {
EE_DataGet(hData, targetChannelList[i],
data, nSamplesTaken);
//send sample to OI
value[i-1] += data[sampleIdx]; //get
sample n°sampleIdx for each channel
}
}
//send value[0],value[1],value[2],value[3]
for(int i =0; i < 14 ; i++){
value[i] /= nSamplesTaken; //average
}
if(EEG != NULL){
EEG(value[0],value[1],value[2],value[3],value[4],value[5],value[6],value[7],value[8
],value[9],\
value[10],value[11],value[12],value[13]);
}
delete[] data;
}
}

Sleep(1);
}
std::cout<<"STOP"<<std::endl;
EE_DataFree(hData);
EE_EngineDisconnect();
EE_EmoStateFree(eState);
EE_EmoEngineEventFree(eEvent);
}
void Stop(void){
run = false;
}
void logEmoState(unsigned int userID, EmoStateHandle eState) {
float eyeLoc[2];
bool ll(0),lr(0),bl(0),lw(0),rw(0),eo(0);
double cl(0.0), eb(0.0), sm(0.0);
int error;
ES_ExpressivGetEyeLocation(eState,&eyeLoc[0],&eyeLoc[1]);
if(eyeLoc[0]>0)
ll=true;
if(eyeLoc[0]<0)
lr=true;
cl = ES_ExpressivGetClenchExtent(eState);
eb = ES_ExpressivGetEyebrowExtent(eState);
sm = ES_ExpressivGetSmileExtent(eState);
if(ES_ExpressivIsBlink(eState))
bl=true;
if(ES_ExpressivIsLeftWink(eState))
lw=true;
if(ES_ExpressivIsRightWink(eState))
lr=true;
if(ES_ExpressivIsEyesOpen(eState))
eo=true;
int gyro[2];
do{
error = EE_HeadsetGetGyroDelta(userID,&gyro[0],&gyro[1]);
std::cout<<error<<std::endl;
if(error == EDK_GYRO_NOT_CALIBRATED)
Sleep(500);
}
while(error != EDK_OK);
if(LookLeft!=NULL)
LookLeft(ll);
if(LookRight!=NULL)
LookRight(lr);
if(Clench!=NULL)
Clench(cl);
if(EyeBrow!=NULL)
EyeBrow(eb);
if(Smile!=NULL)
Smile(sm);
if(Blink!=NULL)
Blink(bl);

if(LeftWink!=NULL)
LeftWink(lw);
if(RightWink!=NULL)
RightWink(rw);
if(EyesOpen!=NULL)
EyesOpen(eo);
if(Gyro!=NULL)
Gyro(gyro[0],gyro[1]);
}
void setCb_LookRightCallback(void (*cb)(bool LookRight)){
::LookRight = cb;
}
void setCb_LookLeftCallback(void (*cb)(bool LookLeft)){
::LookLeft = cb;
}
void setCb_ClenchCallback(void (*cb)(double Clench)){
::Clench = cb;
}
void setCb_EyeBrowCallback(void (*cb)(double EyeBrow)){
::EyeBrow = cb;
}
void setCb_SmileCallback(void (*cb)(double Smile)){
::Smile = cb;
}
void setCb_BlinkCallback(void (*cb)(bool Blink)){
::Blink = cb;
}
void setCb_LeftWinkCallback(void (*cb)(bool LeftWink)){
::LeftWink = cb;
}
void setCb_RightWinkCallback(void (*cb)(bool RightWink)){
::RightWink = cb;
}
void setCb_GyroCallback(void (*cb)(int GyroX, int GyroY)){
::Gyro = cb;
}
void setCb_EEGCallback(void (*cb)(double AF3, double F7, double F3, double FC5,\
double T7, double P7, double O1, double O2, double P8, double T8, double
FC6, double F4,\
double F8, double AF4)){
::EEG = cb;
}
void setCb_EyesOpenCallback(void (*cb)(bool EyesOpen)){
::EyesOpen = cb;
}

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!--Exported by OpenInterface Component Builder-->
<!DOCTYPE Component PUBLIC "-//OpenInterface//DTD Component XML V0.1//EN" "component.dtd">
<Component id="org.openinterface.component.cpp.custom.EPOC">
<Name value="EPOC"/>
<Properties>
<Descr> Implementation of the Emotiv EPOC Headset (brain-computer interface)
</Descr>
<Author firstname="Robin" lastname="Godefroid" email="Robin.Godefroid@gmail.com"/>
<License type="BSD-2">
<Descr>Copyright (C) 2012 Jean-Yves Lionel Lawson
This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you
are welcome to redistribute it under certain conditions.
http://www.opensource.org/licenses/bsd-license.php.</Descr>
</License>
</Properties>
<Language value="c++"/>
<Container>
<Name value="EPOC_Facet"/>
<Format value="so"/>
<Location><![CDATA[EPOC]]></Location>
</Container>
<IO>
<Facet id="EPOC_Facet">
<Bin>
<CustomType def="EPOC_Facet.h" name="" type="cppclass"/>
</Bin>
<Sink id="Start" hint_threaded="yes" hint_startup="yes">
<Interface type="static_function">
<Name value="Start"/>
</Interface>
</Sink>
<Sink id="Stop" hint_shutdownhook="yes" hint_startup="yes">
<Interface type="static_function">
<Name value="Stop"/>
</Interface>
</Sink>
<Source id="LookRight">
<Callback>
<Interface type="static_function">
<Name value="LookRight"/>
<Argument>
<Param direction="in" name="LookRight">
<Descr/>
<PrimitiveType name="bool"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_LookRightCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="EPOC_Facet.h"
name="LookRightCallback" type="cCallback"/>
</Param>

</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="LookLeft">
<Callback>
<Interface type="static_function">
<Name value="LookLeft"/>
<Argument>
<Param direction="in" name="LookLeft">
<Descr/>
<PrimitiveType name="bool"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_LookLeftCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="EPOC_Facet.h" name="LookLeftCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="Clench">
<Callback>
<Interface type="static_function">
<Name value="Clench"/>
<Argument>
<Param direction="in" name="Clench">
<Descr/>
<PrimitiveType name="double"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_ClenchCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="EPOC_Facet.h" name="ClenchCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="EyeBrow">
<Callback>
<Interface type="static_function">
<Name value="EyeBrow"/>
<Argument>

<Param direction="in" name="EyeBrow">
<Descr/>
<PrimitiveType name="double"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_EyeBrowCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="EPOC_Facet.h" name="EyeBrowCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="Smile">
<Callback>
<Interface type="static_function">
<Name value="Smile"/>
<Argument>
<Param direction="in" name="Smile">
<Descr/>
<PrimitiveType name="double"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_SmileCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="EPOC_Facet.h" name="SmileCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="Blink">
<Callback>
<Interface type="static_function">
<Name value="Blink"/>
<Argument>
<Param direction="in" name="Blink">
<Descr/>
<PrimitiveType name="bool"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_BlinkCallback"/>
<Argument>

<Param direction="in" name="cb">
<CustomType def="EPOC_Facet.h" name="BlinkCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="LeftWink">
<Callback>
<Interface type="static_function">
<Name value="LeftWink"/>
<Argument>
<Param direction="in" name="LeftWink">
<Descr/>
<PrimitiveType name="bool"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_LeftWinkCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="EPOC_Facet.h" name="LeftWinkCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="RightWink">
<Callback>
<Interface type="static_function">
<Name value="RightWink"/>
<Argument>
<Param direction="in" name="RightWink">
<Descr/>
<PrimitiveType name="bool"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_RightWinkCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="EPOC_Facet.h"
name="RightWinkCallback" type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="Gyro">

<Callback>
<Interface type="static_function">
<Name value="Gyro"/>
<Argument>
<Param direction="in" name="GyroX">
<Descr/>
<PrimitiveType name="int"/>
</Param>
<Param direction="in" name="GyroY">
<Descr/>
<PrimitiveType name="int"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_GyroCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="EPOC_Facet.h" name="GyroCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="EEG">
<Callback>
<Interface type="static_function">
<Name value="EEG"/>
<Argument>
<Param direction="in" name="AF3">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="F7">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="F3">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="FC5">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="T7">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="P7">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="O1">

<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="O2">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="P8">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="T8">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="FC6">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="F4">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="F8">
<Descr/>
<PrimitiveType name="double"/>
</Param>
<Param direction="in" name="AF4">
<Descr/>
<PrimitiveType name="double"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_EEGCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="EPOC_Facet.h" name="EEGCallback" type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="EyesOpen">
<Callback>
<Interface type="static_function">
<Name value="EyesOpen"/>
<Argument>
<Param direction="in" name="EyesOpen">
<Descr/>
<PrimitiveType name="bool"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">

<Interface type="static_function">
<Name value="setCb_EyesOpenCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="EPOC_Facet.h" name="EyesOpenCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
</Facet>
</IO>
</Component>

//Generated by OpenInterface ComponentBuilder
#ifndef _Kyma_Facet_H
#define _Kyma_Facet_H
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef WIN32
#ifdef DLLEXPORT
#define OPENINTERFACE_API __declspec(dllexport)
#else
#define OPENINTERFACE_API __declspec(dllimport)
#endif
#else
#define OPENINTERFACE_API
#endif
OPENINTERFACE_API void JSON_input(int Argument,char* str);
OPENINTERFACE_API void Start(int port, bool notifyOnOff);
OPENINTERFACE_API void Respond_from(int port);
OPENINTERFACE_API void Notify_I(int count);
OPENINTERFACE_API void Preset_I(int *array, unsigned int dim);
OPENINTERFACE_API void setCb_Respond_toCallback(void (*cb)(int port));
OPENINTERFACE_API void setCb_WidgetCallback(void (*cb)(int widget));
OPENINTERFACE_API void setCb_AddSettingCallback(void (*cb)(char* label, long ID));
OPENINTERFACE_API void setCb_RemoveSettingsCallback(void (*cb)(void));
OPENINTERFACE_API void setCb_VCSCallback(void (*cb)(int id,float value));
OPENINTERFACE_API void setCb_Notify_OCallback(void (*cb)(int onOff));
OPENINTERFACE_API void setCb_Preset_OCallback(void (*cb)(int value));
#ifdef __cplusplus
}
#endif
#endif

//Generated by OpenInterface ComponentBuilder
#include "Kyma_Facet.h"
#include <iostream>
#include <string>
#include <algorithm> //transform
#include "D:\Users\Robs32\Desktop\json\MJPA-SimpleJSON-8fb7fd0/src/JSON.h"
#include <vector>
#include <Windows.h>
using namespace std;
/* OI Callbacks */
static void (*Respond_to)(int port) = NULL;
static void (*Widget)(int widget) = NULL;
static void (*AddSetting)(char* label, long ID) = NULL;
static void (*RemoveSettings)(void) = NULL;
static void (*VCS)(int id,float value) = NULL;
static void (*Notify_O)(int onOff) = NULL;
static void (*Preset_O)(int value) = NULL;
static int _i(0), _port(8000);
static bool _notifyOnOff(false), _queryPreset(false);
/* Personal prototypes */
void setSettings(vector<int>& id);
void displayNoCallback(string callbackName);
/* Global var. */
static vector<int> _id;
static vector<int> _maximum;
static vector<int> _minimum;
static vector<float> _value;
static vector<string> _label;
inline unsigned short bswap_16(unsigned short x) {
return (x>>8) | (x<<8);
}
inline unsigned int bswap_32(unsigned int x) {
return (bswap_16(x&0xffff)<<16) | (bswap_16(x>>16));
}
union intToFloat {
int integer;
float flottant;
};
void queryPreset(){
if(_queryPreset){
cout<<"query already sended"<<endl;
}
else{
cout<<"Query for value"<<endl;
//enable notification
if(!_notifyOnOff && Notify_O!=NULL){
Notify_O(1);
}
if(Preset_O != NULL)
Preset_O(129);
}
}

//Start the communication between Kyma & Skemmi
void Start(int port, bool notifyOnOff){
_notifyOnOff = notifyOnOff;
if(_notifyOnOff){
if(Notify_O != NULL){
Notify_O(1); //enable notification
}
else
displayNoCallback("Notify_O");
}
if(Respond_to!=NULL){
//clear current settings
_i = 0;
_port = port;
_id.clear();
_maximum.clear();
_minimum.clear();
_value.clear();
_label.clear();
if(RemoveSettings != NULL){
RemoveSettings(); //remove all active setting
}
cout<<"Communication started."<<endl;
Respond_to(_port);
}
else
displayNoCallback("Respond_to");
}

void Respond_from(int port){
cout<<"Response from Kyma."<<endl;
if(Widget != NULL){
cout<<"Sending a query for widget "<<_i<<"."<<endl;
Widget(_i);
_i++;
}
else
displayNoCallback("Widget");
}
//not used yet
void Preset_I(int *array, unsigned int dim){
dim /= 4; //=widget number * 2 (ID + Vale)
Sleep(200); //w8 for chgt or new song
if(!_queryPreset){
intToFloat iTf;
if(_value.size() != _id.size())
_value.resize(_id.size());//precaution
for(unsigned int i = 1 ; i < dim ; i += 2){ //0=ID 1=VALUE
array[i-1] = bswap_32(array[i-1]); //ID
array[i] = bswap_32(array[i]); //value
iTf.integer = array[i];
for(unsigned int j = 0 ; j < _id.size() ; j++){
if(array[i-1] == _id.at(j)){
_value.insert(_value.begin() + j , iTf.flottant);
}

}
}
//disable notif
if(!_notifyOnOff && Notify_O != NULL){
Notify_O(0);
}
}
}
void JSON_input(int Argument,char* str){
wstring response(L"");
if(!strcmp(str,"") || str==NULL || str=="") {
cout<<"Received an empty JSON, end of transmission."<<endl;
_value.resize(_id.size());
if(_queryPreset)
_queryPreset = false; //enable query !!
queryPreset();
return;
}
cout<<"JSON received"<<endl;
JSONValue *value = JSON::Parse(str);
// Did it go wrong?
if (value == NULL)
return;
else{
// Retrieve the main object
JSONObject root;
if (value->IsObject() == false)
return;
else{
root = value->AsObject();
if (root.find(L"creationClass") != root.end() &&
root[L"creationClass"]->IsString())
{
wstring response=root[L"creationClass"]->AsString();
transform(response.begin(), response.end(), response.begin(),
toupper);
if(!response.compare(L"VCSEVENTSOURCECOMPONENT")) //0 = ok
{
cout<<"VCSEventSourceComponent received"<<endl;
if (root.find(L"label") != root.end() && root[L"label"]>IsString())
{
response=root[L"label"]->AsString();
string sTemp;
sTemp.assign(response.begin(),response.end());
cout<<"Label : "<<sTemp.c_str()<<endl;
_label.push_back(sTemp.c_str());
}
if (root.find(L"concreteEventID") != root.end() &&
root[L"concreteEventID"]->IsNumber())
{
_id.push_back(root[L"concreteEventID"]>AsNumber());
}
if (root.find(L"maximum") != root.end() &&
root[L"maximum"]->IsNumber())
{

_maximum.push_back(root[L"maximum"]->AsNumber());
}
if (root.find(L"minimum") != root.end() &&
root[L"minimum"]->IsNumber())
{
_minimum.push_back(root[L"minimum"]->AsNumber());
}
if(AddSetting != NULL){
cout<<"New Input:"<<_id.back()<<" +
"<<_label.back().c_str()<<endl;
AddSetting(const_cast<char*>(_label.back().c_str()),_id.back());
}
else{
displayNoCallback("Response");
}
}
}
delete value;
cout<<"Other widget?"<<endl;
if(Respond_to != NULL){
Respond_to(_port);
}
else{
displayNoCallback("Respond_to");
}
}
}
}
void Notify_I(int count){
_queryPreset = true; //disable query -> conflict
cout<<"Notification received, number of widgets : "<<count<<endl;
if(RemoveSettings != NULL){
RemoveSettings(); //remove all active setting
}
if(Respond_to != NULL){
cout<<"Query for new settings."<<endl;
_i = 0;
_id.clear();
_maximum.clear();
_minimum.clear();
_value.clear();
_label.clear();
Respond_to(_port);
}
else{
displayNoCallback("Response_to");
}
}
//not used yet
void setSettings(vector<int>& id){
if(VCS != NULL){
cout<<"Set new settings"<<endl;

for(vector<int>::iterator it = id.begin() ; it != id.end() ; ++it){
VCS(*it,0.5); // use variable instead
}
}
else{
displayNoCallback("VCS");
}
id.clear();
}
void displayNoCallback(string callbackName){
cout<<"No callback set : "<<callbackName.c_str()<<endl;
}
void setCb_Respond_toCallback(void (*cb)(int port)){
::Respond_to = cb;
}
void setCb_WidgetCallback(void (*cb)(int widget)){
::Widget = cb;
}
void setCb_AddSettingCallback(void (*cb)(char* label, long ID)){
::AddSetting = cb;
}
void setCb_RemoveSettingsCallback(void (*cb)(void)){
::RemoveSettings = cb;
}
void setCb_VCSCallback(void (*cb)(int id,float value)){
::VCS = cb;
}
void setCb_Notify_OCallback(void (*cb)(int onOff)){
::Notify_O = cb;
}
void setCb_Preset_OCallback(void (*cb)(int value)){
::Preset_O = cb;
}

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!--Exported by OpenInterface Component Builder-->
<!DOCTYPE Component PUBLIC "-//OpenInterface//DTD Component XML V0.1//EN" "component.dtd">
<Component id="org.openinterface.component.cpp.custom.Kyma">
<Name value="Kyma"/>
<Properties>
<Descr/>
</Properties>
<Language value="c++"/>
<Container>
<Name value="Kyma"/>
<Format value="so"/>
<Location><![CDATA[Kyma]]></Location>
</Container>
<IO>
<Facet id="Kyma_Facet">
<Bin>
<CustomType def="Kyma_Facet.h" name="" type="cppclass"/>
</Bin>
<Sink id="JSON_input">
<Interface type="static_function">
<Name value="JSON_input"/>
<Argument>
<Param direction="in" name="Argument">
<Descr/>
<PrimitiveType name="int"/>
</Param>
<Param direction="in" name="str">
<Descr/>
<PrimitiveType name="string"/>
</Param>
</Argument>
</Interface>
</Sink>
<Sink id="Start">
<Interface type="static_function">
<Name value="Start"/>
<Argument>
<Param direction="in" name="port">
<Descr/>
<PrimitiveType name="int"/>
</Param>
<Param direction="in" name="notifyOnOff">
<Descr/>
<PrimitiveType name="bool"/>
</Param>
</Argument>
</Interface>
</Sink>
<Sink id="Respond_from">
<Interface type="static_function">
<Name value="Respond_from"/>
<Argument>
<Param direction="in" name="port">
<Descr/>
<PrimitiveType name="int"/>
</Param>

</Argument>
</Interface>
</Sink>
<Sink id="Notify_I">
<Interface type="static_function">
<Name value="Notify_I"/>
<Argument>
<Param direction="in" name="count">
<Descr/>
<PrimitiveType name="int"/>
</Param>
</Argument>
</Interface>
</Sink>
<Sink id="Preset_I">
<Interface type="static_function">
<Name value="Preset_I"/>
<Argument>
<Param direction="in" name="array">
<Descr/>
<ArrayType>
<PrimitiveType name="int"/>
<DimSpec>
<NDims type="custom" value="1"/>
<DimList>
<NDims ref="dim" type="custom"/>
</DimList>
</DimSpec>
</ArrayType>
</Param>
<Param direction="in" name="dim">
<Descr/>
<PrimitiveType name="uint"/>
</Param>
</Argument>
</Interface>
</Sink>

<Source id="Respond_to">
<Callback>
<Interface type="static_function">
<Name value="Respond_to"/>
<Argument>
<Param direction="in" name="port">
<Descr/>
<PrimitiveType name="int"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_Respond_toCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="Kyma_Facet.h" name="Respond_toCallback"
type="cCallback"/>

</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="Widget">
<Callback>
<Interface type="static_function">
<Name value="Widget"/>
<Argument>
<Param direction="in" name="widget">
<Descr/>
<PrimitiveType name="int"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_WidgetCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="Kyma_Facet.h" name="WidgetCallback" type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="Add_setting">
<Callback>
<Interface type="static_function">
<Name value="AddSetting"/>
<Argument>
<Param direction="in" name="label">
<Descr/>
<PrimitiveType name="string"/>
</Param>
<Param direction="in" name="ID">
<Descr/>
<PrimitiveType name="long"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_AddSettingCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="Kyma_Facet.h" name="AddSettingCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>

</Source>
<Source id="Remove_settings">
<Callback>
<Interface type="static_function">
<Name value="RemoveSettings"/>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_RemoveSettingsCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="Kyma_Facet.h" name="RemoveSettingsCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="VCS">
<Callback>
<Interface type="static_function">
<Name value="VCS"/>
<Argument>
<Param direction="in" name="id">
<Descr/>
<PrimitiveType name="int"/>
</Param>
<Param direction="in" name="value">
<Descr/>
<PrimitiveType name="float"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_VCSCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="Kyma_Facet.h" name="VCSCallback" type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="Notify_O">
<Callback>
<Interface type="static_function">
<Name value="Notify_O"/>
<Argument>
<Param direction="in" name="onOff">
<Descr/>
<PrimitiveType name="int"/>
</Param>

</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_Notify_OCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="Kyma_Facet.h" name="Notify_OCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
<Source id="Preset_O">
<Callback>
<Interface type="static_function">
<Name value="Preset_O"/>
<Argument>
<Param direction="in" name="value">
<Descr/>
<PrimitiveType name="int"/>
</Param>
</Argument>
</Interface>
<Setter type="builtin">
<Interface type="static_function">
<Name value="setCb_Preset_OCallback"/>
<Argument>
<Param direction="in" name="cb">
<CustomType def="Kyma_Facet.h" name="Preset_OCallback"
type="cCallback"/>
</Param>
</Argument>
</Interface>
</Setter>
</Callback>
</Source>
</Facet>
</IO>
</Component>


Aperçu du document EEG.pdf - page 1/31

 
EEG.pdf - page 2/31
EEG.pdf - page 3/31
EEG.pdf - page 4/31
EEG.pdf - page 5/31
EEG.pdf - page 6/31
 







Télécharger le fichier (PDF)


EEG.pdf (PDF, 3.2 Mo)



Sur le même sujet..





Ce fichier a été mis en ligne par un utilisateur du site Fichier PDF. Identifiant unique du document: 00120738.
⚠️  Signaler un contenu illicite
Pour plus d'informations sur notre politique de lutte contre la diffusion illicite de contenus protégés par droit d'auteur, consultez notre page dédiée.


adplus-dvertising