An easy-to-use platform for EEG experimentation in the classroom
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Added explicit session id to inject markers

jdpigeon 5f4a945c 5d144464

+24 -15
+24 -15
app/utils/eeg/emotiv.js
··· 3 3 * an RxJS Observable of raw EEG data 4 4 * 5 5 */ 6 - import { fromEvent } from "rxjs"; 7 - import { map, withLatestFrom, share } from "rxjs/operators"; 8 - import { addInfo, epoch, bandpassFilter } from "@neurosity/pipes"; 9 - import { toast } from "react-toastify"; 10 - import { parseEmotivSignalQuality } from "./pipes"; 6 + import { fromEvent } from 'rxjs'; 7 + import { map, withLatestFrom, share } from 'rxjs/operators'; 8 + import { addInfo, epoch, bandpassFilter } from '@neurosity/pipes'; 9 + import { toast } from 'react-toastify'; 10 + import { parseEmotivSignalQuality } from './pipes'; 11 11 import { 12 12 USERNAME, 13 13 PASSWORD, 14 14 CLIENT_ID, 15 15 CLIENT_SECRET, 16 16 LICENSE_ID 17 - } from "../../../keys"; 18 - import { EMOTIV_CHANNELS, PLOTTING_INTERVAL } from "../../constants/constants"; 19 - import Cortex from "./cortex"; 17 + } from '../../../keys'; 18 + import { EMOTIV_CHANNELS, PLOTTING_INTERVAL } from '../../constants/constants'; 19 + import Cortex from './cortex'; 20 20 21 21 // Creates the Cortex object from SDK 22 22 const verbose = process.env.LOG_LEVEL || 1; 23 23 const options = { verbose }; 24 24 const client = new Cortex(options); 25 + // Used to explictly link event markers to session 26 + let sessionID = null; 25 27 26 28 // Gets a list of available Emotiv devices 27 29 export const getEmotiv = async () => { 28 30 const devices = await client.queryHeadsets(); 31 + devices.push([{ id: 'Emotiv-debug' }]); 29 32 return devices; 30 33 }; 31 34 ··· 46 49 toast.error(`Authentication failed. ${err}`); 47 50 return err; 48 51 }) 52 + .then(() => client.getLicenseInfo()) 49 53 .then(() => 50 54 client.createSession({ 51 - status: "active", 55 + status: 'active', 52 56 headset: device.id 53 57 }) 54 58 ) ··· 58 62 }) 59 63 .then(session => { 60 64 if (session.headset === undefined) { 61 - return new Error("Session does not exist"); 65 + return new Error('Session does not exist'); 62 66 } 67 + sessionID = session.id; 68 + 63 69 return { 64 70 name: session.headset.id, 65 71 samplingRate: session.headset.settings.eegRate, ··· 72 78 }); 73 79 74 80 export const disconnectFromEmotiv = async () => { 75 - const sessionStatus = await client.updateSession({ status: "close" }); 81 + const sessionStatus = await client.updateSession({ status: 'close' }); 76 82 return sessionStatus; 77 83 }; 78 84 79 85 // Returns an observable that will handle both connecting to Client and providing a source of EEG data 80 86 export const createRawEmotivObservable = async () => { 81 - const subs = await client.subscribe({ streams: ["eeg", "dev"] }); 87 + const subs = await client.subscribe({ streams: ['eeg', 'dev'] }); 82 88 if (!subs[0].eeg) { 83 89 toast.error(`Subscription to Session data failed`); 84 90 } 85 - return fromEvent(client, "eeg").pipe(map(createEEGSample)); 91 + return fromEvent(client, 'eeg').pipe(map(createEEGSample)); 86 92 }; 87 93 88 94 // Creates an observable that will epoch, filter, and add signal quality to EEG stream 89 95 export const createEmotivSignalQualityObservable = rawObservable => { 90 - const signalQualityObservable = fromEvent(client, "dev"); 96 + const signalQualityObservable = fromEvent(client, 'dev'); 91 97 const samplingRate = 128; 92 98 const channels = EMOTIV_CHANNELS; 93 99 const intervalSamples = (PLOTTING_INTERVAL * samplingRate) / 1000; ··· 112 118 }; 113 119 114 120 export const injectEmotivMarker = (value, time) => { 115 - client.injectMarker({ label: "event", value, time }); 121 + if (sessionID !== null) { 122 + client.injectMarker({ label: 'event', id: sessionID, value, time }); 123 + } 124 + client.injectMarker({ label: 'event', value, time }); 116 125 }; 117 126 118 127 // ---------------------------------------------------------------------