@neurodevs/node-lsl 18.1.0 → 20.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/__tests__/AbstractPackageTest.d.ts +19 -17
- package/build/__tests__/AbstractPackageTest.js +54 -39
- package/build/__tests__/AbstractPackageTest.js.map +1 -1
- package/build/__tests__/impl/BleDeviceController.test.d.ts +6 -1
- package/build/__tests__/impl/BleDeviceController.test.js +44 -15
- package/build/__tests__/impl/BleDeviceController.test.js.map +1 -1
- package/build/__tests__/impl/LslEventMarkerEmitter.test.js +13 -13
- package/build/__tests__/impl/LslEventMarkerEmitter.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamInfo.test.js +2 -2
- package/build/__tests__/impl/LslStreamInfo.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamInlet.test.d.ts +3 -5
- package/build/__tests__/impl/LslStreamInlet.test.js +13 -46
- package/build/__tests__/impl/LslStreamInlet.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamOutlet.test.js +9 -16
- package/build/__tests__/impl/LslStreamOutlet.test.js.map +1 -1
- package/build/__tests__/impl/LslWebSocketBridge.test.js +9 -10
- package/build/__tests__/impl/LslWebSocketBridge.test.js.map +1 -1
- package/build/__tests__/impl/UsbDeviceController.test.d.ts +17 -0
- package/build/__tests__/impl/UsbDeviceController.test.js +81 -0
- package/build/__tests__/impl/UsbDeviceController.test.js.map +1 -0
- package/build/__tests__/impl/WindowedClockRegressor.test.d.ts +19 -0
- package/build/__tests__/impl/WindowedClockRegressor.test.js +172 -0
- package/build/__tests__/impl/WindowedClockRegressor.test.js.map +1 -0
- package/build/assertions.js +1 -1
- package/build/assertions.js.map +1 -1
- package/build/impl/LslEventMarkerEmitter.d.ts +12 -12
- package/build/impl/LslEventMarkerEmitter.js.map +1 -1
- package/build/impl/LslStreamInfo.d.ts +7 -7
- package/build/impl/LslStreamInfo.js.map +1 -1
- package/build/impl/LslStreamInlet.d.ts +63 -20
- package/build/impl/LslStreamInlet.js +221 -64
- package/build/impl/LslStreamInlet.js.map +1 -1
- package/build/impl/LslStreamOutlet.d.ts +16 -14
- package/build/impl/LslStreamOutlet.js +34 -37
- package/build/impl/LslStreamOutlet.js.map +1 -1
- package/build/impl/LslWebSocketBridge.d.ts +10 -10
- package/build/impl/LslWebSocketBridge.js.map +1 -1
- package/build/impl/clocks/WindowedClockRegressor.d.ts +24 -0
- package/build/impl/clocks/WindowedClockRegressor.js +73 -0
- package/build/impl/clocks/WindowedClockRegressor.js.map +1 -0
- package/build/impl/controllers/BleDeviceController.d.ts +3 -1
- package/build/impl/controllers/BleDeviceController.js +9 -1
- package/build/impl/controllers/BleDeviceController.js.map +1 -1
- package/build/impl/controllers/UsbDeviceController.d.ts +23 -0
- package/build/impl/controllers/UsbDeviceController.js +40 -0
- package/build/impl/controllers/UsbDeviceController.js.map +1 -0
- package/build/index.d.ts +32 -20
- package/build/index.js +39 -26
- package/build/index.js.map +1 -1
- package/build/scripts/{runLslEventMarkerEmitter.js → runLslEmitter.js} +5 -4
- package/build/scripts/runLslEmitter.js.map +1 -0
- package/build/scripts/{runLslStreamOutlet.js → runLslOutlet.js} +1 -1
- package/build/scripts/runLslOutlet.js.map +1 -0
- package/build/scripts/runMuse.js +1 -1
- package/build/scripts/runMuse.js.map +1 -1
- package/build/scripts/runUsb.js +14 -0
- package/build/scripts/runUsb.js.map +1 -0
- package/build/testDoubles/BleController/FakeBleController.d.ts +3 -1
- package/build/testDoubles/BleController/FakeBleController.js +5 -0
- package/build/testDoubles/BleController/FakeBleController.js.map +1 -1
- package/build/testDoubles/ClockRegressor/FakeClockRegressor.d.ts +17 -0
- package/build/testDoubles/ClockRegressor/FakeClockRegressor.js +23 -0
- package/build/testDoubles/ClockRegressor/FakeClockRegressor.js.map +1 -0
- package/build/testDoubles/{EventMarkerEmitter/FakeEventMarkerEmitter.d.ts → LslEmitter/FakeLslEmitter.d.ts} +4 -4
- package/build/testDoubles/{EventMarkerEmitter/FakeEventMarkerEmitter.js → LslEmitter/FakeLslEmitter.js} +7 -7
- package/build/testDoubles/LslEmitter/FakeLslEmitter.js.map +1 -0
- package/build/testDoubles/{EventMarkerEmitter/SpyEventMarkerEmitter.d.ts → LslEmitter/SpyLslEmitter.d.ts} +4 -4
- package/build/testDoubles/{EventMarkerEmitter/SpyEventMarkerEmitter.js → LslEmitter/SpyLslEmitter.js} +3 -3
- package/build/testDoubles/LslEmitter/SpyLslEmitter.js.map +1 -0
- package/build/testDoubles/LslEmitter/ThrowingLslEmitter.d.ts +9 -0
- package/build/testDoubles/{EventMarkerEmitter/ThrowingEventMarkerEmitter.js → LslEmitter/ThrowingLslEmitter.js} +2 -2
- package/build/testDoubles/LslEmitter/ThrowingLslEmitter.js.map +1 -0
- package/build/testDoubles/{StreamInfo/FakeStreamInfo.d.ts → LslInfo/FakeLslInfo.d.ts} +4 -4
- package/build/testDoubles/{StreamInfo/FakeStreamInfo.js → LslInfo/FakeLslInfo.js} +7 -7
- package/build/testDoubles/LslInfo/FakeLslInfo.js.map +1 -0
- package/build/testDoubles/LslInfo/SpyLslInfo.d.ts +10 -0
- package/build/testDoubles/{StreamInfo/SpyStreamInfo.js → LslInfo/SpyLslInfo.js} +4 -4
- package/build/testDoubles/LslInfo/SpyLslInfo.js.map +1 -0
- package/build/testDoubles/{StreamInlet/FakeStreamInlet.d.ts → LslInlet/FakeLslInlet.d.ts} +4 -4
- package/build/testDoubles/{StreamInlet/FakeStreamInlet.js → LslInlet/FakeLslInlet.js} +12 -11
- package/build/testDoubles/LslInlet/FakeLslInlet.js.map +1 -0
- package/build/testDoubles/LslInlet/SpyLslInlet.d.ts +4 -0
- package/build/testDoubles/{StreamInlet/SpyStreamInlet.js → LslInlet/SpyLslInlet.js} +2 -2
- package/build/testDoubles/LslInlet/SpyLslInlet.js.map +1 -0
- package/build/testDoubles/{StreamOutlet/FakeStreamOutlet.d.ts → LslOutlet/FakeLslOutlet.d.ts} +5 -5
- package/build/testDoubles/{StreamOutlet/FakeStreamOutlet.js → LslOutlet/FakeLslOutlet.js} +8 -8
- package/build/testDoubles/LslOutlet/FakeLslOutlet.js.map +1 -0
- package/build/testDoubles/LslWsBridge/FakeLslWsBridge.d.ts +14 -0
- package/build/testDoubles/{WebSocketBridge/FakeWebSocketBridge.js → LslWsBridge/FakeLslWsBridge.js} +14 -14
- package/build/testDoubles/LslWsBridge/FakeLslWsBridge.js.map +1 -0
- package/build/testDoubles/LslWsBridge/SpyLslWsBridge.d.ts +4 -0
- package/build/testDoubles/{WebSocketBridge/SpyLslWebSocketBridge.js → LslWsBridge/SpyLslWsBridge.js} +2 -2
- package/build/testDoubles/LslWsBridge/SpyLslWsBridge.js.map +1 -0
- package/build/testDoubles/UsbController/FakeUsbController.d.ts +12 -0
- package/build/testDoubles/UsbController/FakeUsbController.js +25 -0
- package/build/testDoubles/UsbController/FakeUsbController.js.map +1 -0
- package/build/testDoubles/consts.d.ts +2 -12
- package/build/testDoubles/consts.js +0 -20
- package/build/testDoubles/consts.js.map +1 -1
- package/build/testDoubles/generateRandomOutletOptions.d.ts +2 -2
- package/build/testDoubles/generateRandomOutletOptions.js.map +1 -1
- package/package.json +6 -5
- package/src/__tests__/AbstractPackageTest.ts +78 -49
- package/src/__tests__/impl/BleDeviceController.test.ts +59 -18
- package/src/__tests__/impl/LslEventMarkerEmitter.test.ts +19 -24
- package/src/__tests__/impl/LslStreamInfo.test.ts +8 -8
- package/src/__tests__/impl/LslStreamInlet.test.ts +21 -78
- package/src/__tests__/impl/LslStreamOutlet.test.ts +22 -28
- package/src/__tests__/impl/LslWebSocketBridge.test.ts +15 -18
- package/src/__tests__/impl/UsbDeviceController.test.ts +109 -0
- package/src/__tests__/impl/WindowedClockRegressor.test.ts +262 -0
- package/src/assertions.ts +1 -2
- package/src/impl/LslEventMarkerEmitter.ts +15 -17
- package/src/impl/LslStreamInfo.ts +7 -9
- package/src/impl/LslStreamInlet.ts +304 -77
- package/src/impl/LslStreamOutlet.ts +59 -57
- package/src/impl/LslWebSocketBridge.ts +15 -18
- package/src/impl/clocks/WindowedClockRegressor.ts +136 -0
- package/src/impl/controllers/BleDeviceController.ts +18 -1
- package/src/impl/controllers/UsbDeviceController.ts +65 -0
- package/src/index.ts +48 -28
- package/src/scripts/{runLslEventMarkerEmitter.ts → runLslEmitter.ts} +4 -3
- package/src/scripts/runMuse.ts +1 -1
- package/src/scripts/runUsb.ts +20 -0
- package/src/testDoubles/BleController/FakeBleController.ts +11 -0
- package/src/testDoubles/ClockRegressor/FakeClockRegressor.ts +46 -0
- package/src/testDoubles/{EventMarkerEmitter/FakeEventMarkerEmitter.ts → LslEmitter/FakeLslEmitter.ts} +10 -10
- package/src/testDoubles/{EventMarkerEmitter/SpyEventMarkerEmitter.ts → LslEmitter/SpyLslEmitter.ts} +4 -4
- package/src/testDoubles/{EventMarkerEmitter/ThrowingEventMarkerEmitter.ts → LslEmitter/ThrowingLslEmitter.ts} +4 -4
- package/src/testDoubles/{StreamInfo/FakeStreamInfo.ts → LslInfo/FakeLslInfo.ts} +9 -9
- package/src/testDoubles/{StreamInfo/SpyStreamInfo.ts → LslInfo/SpyLslInfo.ts} +5 -5
- package/src/testDoubles/{StreamInlet/FakeStreamInlet.ts → LslInlet/FakeLslInlet.ts} +15 -14
- package/src/testDoubles/LslInlet/SpyLslInlet.ts +10 -0
- package/src/testDoubles/{StreamOutlet/FakeStreamOutlet.ts → LslOutlet/FakeLslOutlet.ts} +11 -14
- package/src/testDoubles/{WebSocketBridge/FakeWebSocketBridge.ts → LslWsBridge/FakeLslWsBridge.ts} +19 -20
- package/src/testDoubles/LslWsBridge/SpyLslWsBridge.ts +9 -0
- package/src/testDoubles/UsbController/FakeUsbController.ts +34 -0
- package/src/testDoubles/consts.ts +3 -23
- package/src/testDoubles/generateRandomOutletOptions.ts +2 -2
- package/build/consts.d.ts +0 -11
- package/build/consts.js +0 -21
- package/build/consts.js.map +0 -1
- package/build/impl/workers/inlet/LslStreamInlet.worker.d.ts +0 -22
- package/build/impl/workers/inlet/LslStreamInlet.worker.js +0 -42
- package/build/impl/workers/inlet/LslStreamInlet.worker.js.map +0 -1
- package/build/impl/workers/inlet/StreamInletWorker.d.ts +0 -73
- package/build/impl/workers/inlet/StreamInletWorker.js +0 -253
- package/build/impl/workers/inlet/StreamInletWorker.js.map +0 -1
- package/build/impl/workers/outlet/LslStreamOutlet.worker.d.ts +0 -32
- package/build/impl/workers/outlet/LslStreamOutlet.worker.js +0 -82
- package/build/impl/workers/outlet/LslStreamOutlet.worker.js.map +0 -1
- package/build/scripts/discoverMuse.js +0 -40
- package/build/scripts/discoverMuse.js.map +0 -1
- package/build/scripts/runLslEventMarkerEmitter.js.map +0 -1
- package/build/scripts/runLslStreamOutlet.js.map +0 -1
- package/build/scripts/testDestroyOutlet.d.ts +0 -1
- package/build/scripts/testDestroyOutlet.js +0 -4
- package/build/scripts/testDestroyOutlet.js.map +0 -1
- package/build/testDoubles/EventMarkerEmitter/FakeEventMarkerEmitter.js.map +0 -1
- package/build/testDoubles/EventMarkerEmitter/SpyEventMarkerEmitter.js.map +0 -1
- package/build/testDoubles/EventMarkerEmitter/ThrowingEventMarkerEmitter.d.ts +0 -9
- package/build/testDoubles/EventMarkerEmitter/ThrowingEventMarkerEmitter.js.map +0 -1
- package/build/testDoubles/StreamInfo/FakeStreamInfo.js.map +0 -1
- package/build/testDoubles/StreamInfo/SpyStreamInfo.d.ts +0 -10
- package/build/testDoubles/StreamInfo/SpyStreamInfo.js.map +0 -1
- package/build/testDoubles/StreamInlet/FakeStreamInlet.js.map +0 -1
- package/build/testDoubles/StreamInlet/SpyStreamInlet.d.ts +0 -4
- package/build/testDoubles/StreamInlet/SpyStreamInlet.js.map +0 -1
- package/build/testDoubles/StreamOutlet/FakeStreamOutlet.js.map +0 -1
- package/build/testDoubles/WebSocketBridge/FakeWebSocketBridge.d.ts +0 -14
- package/build/testDoubles/WebSocketBridge/FakeWebSocketBridge.js.map +0 -1
- package/build/testDoubles/WebSocketBridge/SpyLslWebSocketBridge.d.ts +0 -4
- package/build/testDoubles/WebSocketBridge/SpyLslWebSocketBridge.js.map +0 -1
- package/build/testDoubles/WorkerThreads/FakeWorker.d.ts +0 -27
- package/build/testDoubles/WorkerThreads/FakeWorker.js +0 -67
- package/build/testDoubles/WorkerThreads/FakeWorker.js.map +0 -1
- package/src/consts.ts +0 -21
- package/src/impl/workers/inlet/LslStreamInlet.worker.ts +0 -74
- package/src/impl/workers/inlet/StreamInletWorker.ts +0 -348
- package/src/impl/workers/outlet/LslStreamOutlet.worker.ts +0 -144
- package/src/scripts/discoverMuse.ts +0 -50
- package/src/scripts/testDestroyOutlet.ts +0 -5
- package/src/testDoubles/StreamInlet/SpyStreamInlet.ts +0 -10
- package/src/testDoubles/WebSocketBridge/SpyLslWebSocketBridge.ts +0 -9
- package/src/testDoubles/WorkerThreads/FakeWorker.ts +0 -99
- /package/build/scripts/{discoverMuse.d.ts → runLslEmitter.d.ts} +0 -0
- /package/build/scripts/{runLslEventMarkerEmitter.d.ts → runLslOutlet.d.ts} +0 -0
- /package/build/scripts/{runLslStreamOutlet.d.ts → runUsb.d.ts} +0 -0
- /package/src/scripts/{runLslStreamOutlet.ts → runLslOutlet.ts} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FakeWorker.js","sourceRoot":"","sources":["../../../src/testDoubles/WorkerThreads/FakeWorker.ts"],"names":[],"mappings":"AAGA,OAAO,iBAAiB,MAAM,+CAA+C,CAAA;AAC7E,OAAO,EACH,YAAY,EACZ,aAAa,EACb,UAAU,GACb,MAAM,qDAAqD,CAAA;AAE5D,MAAM,CAAC,OAAO,OAAO,UAAU;IACpB,MAAM,CAAC,kBAAkB,GAG1B,EAAE,CAAA;IAED,MAAM,CAAC,kBAAkB,GAAoB,EAAE,CAAA;IAE/C,MAAM,CAAC,SAAS,GAGjB,EAAE,CAAA;IAED,MAAM,CAAC,WAAW,GAAG,IAAI,iBAAiB,EAAE,CAAA;IAC5C,MAAM,CAAC,UAAU,CAAgB;IAEjC,kBAAkB,CAAgB;IAEzC,YAAmB,QAAsB,EAAE,OAAuB;QAC9D,UAAU,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;IAC7D,CAAC;IAEM,WAAW,CAAC,GAAkB;QACjC,UAAU,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAEvC,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAA;QAEpB,QAAQ,IAAI,EAAE,CAAC;YACX,KAAK,cAAc,CAAC,CAAC,CAAC;gBAClB,YAAY,CAAC,GAAU,CAAC,CAAA;gBACxB,MAAK;YACT,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBAChB,UAAU,CAAC,GAAU,CAAC,CAAA;gBACtB,MAAK;YACT,CAAC;YACD,KAAK,eAAe,CAAC,CAAC,CAAC;gBACnB,aAAa,EAAE,CAAA;gBACf,MAAK;YACT,CAAC;YACD,KAAK,aAAa,CAAC,CAAC,CAAC;gBACjB,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAA;gBACvB,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,CAClD,OAAc,CACjB,CAAA;gBACD,MAAK;YACT,CAAC;YACD,KAAK,cAAc,CAAC,CAAC,CAAC;gBAClB,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;gBAC9C,MAAK;YACT,CAAC;YACD,KAAK,YAAY,CAAC,CAAC,CAAC;gBAChB,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAA;gBAC7B,MAAK;YACT,CAAC;YACD,KAAK,aAAa,CAAC,CAAC,CAAC;gBACjB,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAA;gBAC9B,MAAK;YACT,CAAC;YACD,KAAK,cAAc,CAAC,CAAC,CAAC;gBAClB,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,CAAA;gBAC/B,MAAK;YACT,CAAC;QACL,CAAC;IACL,CAAC;IAEM,EAAE,CAAC,IAAY,EAAE,QAAsC;QAC1D,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAA;IACjD,CAAC;IAED,IAAY,WAAW;QACnB,OAAO,UAAU,CAAC,WAAW,CAAA;IACjC,CAAC;IAED,IAAY,UAAU;QAClB,OAAO,UAAU,CAAC,UAAU,CAAA;IAChC,CAAC;IAEM,MAAM,CAAC,gBAAgB;QAC1B,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAA;QAC5B,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAA;QAC5B,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;IACvB,CAAC"}
|
package/src/consts.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export const CHANNEL_FORMATS = [
|
|
2
|
-
'undefined',
|
|
3
|
-
'float32',
|
|
4
|
-
'double64',
|
|
5
|
-
'string',
|
|
6
|
-
'int32',
|
|
7
|
-
'int16',
|
|
8
|
-
'int8',
|
|
9
|
-
'int64',
|
|
10
|
-
] as const
|
|
11
|
-
|
|
12
|
-
export const CHANNEL_FORMATS_MAP = {
|
|
13
|
-
undefined: 0,
|
|
14
|
-
float32: 1,
|
|
15
|
-
double64: 2,
|
|
16
|
-
string: 3,
|
|
17
|
-
int32: 4,
|
|
18
|
-
int16: 5,
|
|
19
|
-
int8: 6,
|
|
20
|
-
int64: 7,
|
|
21
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { parentPort } from 'node:worker_threads'
|
|
2
|
-
import StreamInletWorker from './StreamInletWorker.js'
|
|
3
|
-
|
|
4
|
-
const worker = new StreamInletWorker()
|
|
5
|
-
|
|
6
|
-
parentPort?.on('message', async (msg: InletMessage) => {
|
|
7
|
-
try {
|
|
8
|
-
switch (msg.type) {
|
|
9
|
-
case 'createInlet':
|
|
10
|
-
const { payload } = msg
|
|
11
|
-
await worker.createInlet(payload)
|
|
12
|
-
parentPort?.postMessage({ type: 'ready' })
|
|
13
|
-
break
|
|
14
|
-
|
|
15
|
-
case 'startPulling':
|
|
16
|
-
worker.startPulling((samples, timestamps) => {
|
|
17
|
-
parentPort?.postMessage({
|
|
18
|
-
type: 'data',
|
|
19
|
-
payload: {
|
|
20
|
-
samples,
|
|
21
|
-
timestamps,
|
|
22
|
-
},
|
|
23
|
-
})
|
|
24
|
-
})
|
|
25
|
-
break
|
|
26
|
-
|
|
27
|
-
case 'stopPulling':
|
|
28
|
-
worker.stopPulling()
|
|
29
|
-
break
|
|
30
|
-
case 'flushInlet':
|
|
31
|
-
worker.flushInlet()
|
|
32
|
-
break
|
|
33
|
-
|
|
34
|
-
case 'destroyInlet':
|
|
35
|
-
worker.destroyInlet()
|
|
36
|
-
parentPort?.close()
|
|
37
|
-
break
|
|
38
|
-
}
|
|
39
|
-
} catch (err) {
|
|
40
|
-
parentPort?.postMessage({
|
|
41
|
-
type: 'error',
|
|
42
|
-
error: err instanceof Error ? err.message : String(err),
|
|
43
|
-
})
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
export type InletMessage =
|
|
48
|
-
| {
|
|
49
|
-
type: 'createInlet'
|
|
50
|
-
payload: CreateInletPayload
|
|
51
|
-
}
|
|
52
|
-
| {
|
|
53
|
-
type: 'startPulling'
|
|
54
|
-
}
|
|
55
|
-
| {
|
|
56
|
-
type: 'flushInlet'
|
|
57
|
-
}
|
|
58
|
-
| {
|
|
59
|
-
type: 'stopPulling'
|
|
60
|
-
}
|
|
61
|
-
| {
|
|
62
|
-
type: 'destroyInlet'
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface CreateInletPayload {
|
|
66
|
-
sourceId: string
|
|
67
|
-
chunkSize: number
|
|
68
|
-
maxBufferedMs: number
|
|
69
|
-
openStreamTimeoutMs: number
|
|
70
|
-
waitAfterOpenStreamMs: number
|
|
71
|
-
pullTimeoutMs: number
|
|
72
|
-
waitBetweenPullsMs: number
|
|
73
|
-
flushInletOnStop: boolean
|
|
74
|
-
}
|
|
@@ -1,348 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
handleLslError,
|
|
3
|
-
InfoHandle,
|
|
4
|
-
InletHandle,
|
|
5
|
-
LiblslAdapter,
|
|
6
|
-
} from '@neurodevs/ndx-native'
|
|
7
|
-
import {
|
|
8
|
-
JsExternal,
|
|
9
|
-
unwrapPointer,
|
|
10
|
-
createPointer,
|
|
11
|
-
DataType,
|
|
12
|
-
freePointer,
|
|
13
|
-
PointerType,
|
|
14
|
-
} from 'ffi-rs'
|
|
15
|
-
|
|
16
|
-
import { OnDataCallback } from '../../LslStreamInlet.js'
|
|
17
|
-
import { CreateInletPayload } from './LslStreamInlet.worker.js'
|
|
18
|
-
|
|
19
|
-
export default class StreamInletWorker {
|
|
20
|
-
public static lsl = LiblslAdapter.getInstance()
|
|
21
|
-
public static handleLslError = handleLslError
|
|
22
|
-
public static freePointer = freePointer
|
|
23
|
-
|
|
24
|
-
private sourceId!: string
|
|
25
|
-
private chunkSize!: number
|
|
26
|
-
private maxBufferedMs!: number
|
|
27
|
-
private openStreamTimeoutMs!: number
|
|
28
|
-
private waitAfterOpenStreamMs!: number
|
|
29
|
-
private waitBetweenPullsMs!: number
|
|
30
|
-
private pullTimeoutMs!: number
|
|
31
|
-
private flushInletOnStop!: boolean
|
|
32
|
-
|
|
33
|
-
private pullMethod!: () => {
|
|
34
|
-
samples: number[] | undefined
|
|
35
|
-
timestamps: number[] | undefined
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
protected infoHandle!: InfoHandle
|
|
39
|
-
protected inletHandle!: InletHandle
|
|
40
|
-
private channelCount!: number
|
|
41
|
-
|
|
42
|
-
private sampleBuffer!: Buffer<ArrayBuffer>
|
|
43
|
-
private sampleBufferRef!: JsExternal[]
|
|
44
|
-
private sampleBufferPtr!: JsExternal
|
|
45
|
-
|
|
46
|
-
private timestampBuffer!: Buffer<ArrayBuffer>
|
|
47
|
-
private timestampBufferRef!: JsExternal[]
|
|
48
|
-
private timestampBufferPtr!: JsExternal
|
|
49
|
-
|
|
50
|
-
private pullErrorBuffer!: Buffer<ArrayBuffer>
|
|
51
|
-
private pullErrorBufferRef!: JsExternal[]
|
|
52
|
-
private pullErrorBufferPtr!: JsExternal
|
|
53
|
-
|
|
54
|
-
private openStreamErrorBuffer!: Buffer<ArrayBuffer>
|
|
55
|
-
private openStreamErrorBufferRef!: JsExternal[]
|
|
56
|
-
private openStreamErrorBufferPtr!: JsExternal
|
|
57
|
-
|
|
58
|
-
private onData!: OnDataCallback
|
|
59
|
-
|
|
60
|
-
private readonly bytesPerFloat = 4
|
|
61
|
-
private readonly bytesPerDouble = 8
|
|
62
|
-
private readonly bytesPerI32 = 4
|
|
63
|
-
|
|
64
|
-
private isRunning = false
|
|
65
|
-
|
|
66
|
-
public async createInlet(payload: CreateInletPayload) {
|
|
67
|
-
Object.assign(this, payload)
|
|
68
|
-
|
|
69
|
-
this.infoHandle = this.resolveInfoHandle()
|
|
70
|
-
this.inletHandle = this.doCreateInlet()
|
|
71
|
-
this.channelCount = this.getChannelCount()
|
|
72
|
-
|
|
73
|
-
this.allocateWritableBuffers()
|
|
74
|
-
this.setPullMethod()
|
|
75
|
-
|
|
76
|
-
this.openStream()
|
|
77
|
-
await this.waitForSetup()
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
private resolveInfoHandle() {
|
|
81
|
-
const handles = this.resolveByProp()
|
|
82
|
-
|
|
83
|
-
if (handles.length === 0) {
|
|
84
|
-
this.throwNoStreamFound()
|
|
85
|
-
} else if (handles.length > 1) {
|
|
86
|
-
this.warnMultipleStreamsFound()
|
|
87
|
-
}
|
|
88
|
-
return handles[0]
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
private resolveByProp() {
|
|
92
|
-
return this.lsl.resolveByProp({
|
|
93
|
-
prop: 'source_id',
|
|
94
|
-
value: this.sourceId,
|
|
95
|
-
})
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
private throwNoStreamFound() {
|
|
99
|
-
throw new Error(`No stream info for sourceId "${this.sourceId}"`)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
private warnMultipleStreamsFound() {
|
|
103
|
-
console.warn(
|
|
104
|
-
`Multiple stream infos for sourceId "${this.sourceId}", using the first one.`
|
|
105
|
-
)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
private doCreateInlet() {
|
|
109
|
-
return this.lsl.createInlet({
|
|
110
|
-
infoHandle: this.infoHandle,
|
|
111
|
-
maxBufferedMs: this.maxBufferedMs,
|
|
112
|
-
})
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
private getChannelCount() {
|
|
116
|
-
return this.lsl.getChannelCount({ infoHandle: this.infoHandle })
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private allocateWritableBuffers() {
|
|
120
|
-
this.allocateDataBuffer()
|
|
121
|
-
this.allocateTimestampBuffer()
|
|
122
|
-
this.allocatePullErrorBuffer()
|
|
123
|
-
this.allocateOpenStreamErrorBuffer()
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
private allocateDataBuffer() {
|
|
127
|
-
this.sampleBuffer = Buffer.alloc(
|
|
128
|
-
this.channelCount * this.chunkSize * this.bytesPerFloat
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
this.sampleBufferRef = createPointer({
|
|
132
|
-
paramsType: [DataType.U8Array],
|
|
133
|
-
paramsValue: [this.sampleBuffer],
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
this.sampleBufferPtr = unwrapPointer(this.sampleBufferRef)[0]
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
private allocateTimestampBuffer() {
|
|
140
|
-
this.timestampBuffer = Buffer.alloc(
|
|
141
|
-
this.chunkSize * this.bytesPerDouble
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
this.timestampBufferRef = createPointer({
|
|
145
|
-
paramsType: [DataType.U8Array],
|
|
146
|
-
paramsValue: [this.timestampBuffer],
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
this.timestampBufferPtr = unwrapPointer(this.timestampBufferRef)[0]
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
private allocatePullErrorBuffer() {
|
|
153
|
-
this.pullErrorBuffer = Buffer.alloc(this.bytesPerI32)
|
|
154
|
-
|
|
155
|
-
this.pullErrorBufferRef = createPointer({
|
|
156
|
-
paramsType: [DataType.U8Array],
|
|
157
|
-
paramsValue: [this.pullErrorBuffer],
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
this.pullErrorBufferPtr = unwrapPointer(this.pullErrorBufferRef)[0]
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
private allocateOpenStreamErrorBuffer() {
|
|
164
|
-
this.openStreamErrorBuffer = Buffer.alloc(this.bytesPerI32)
|
|
165
|
-
|
|
166
|
-
this.openStreamErrorBufferRef = createPointer({
|
|
167
|
-
paramsType: [DataType.U8Array],
|
|
168
|
-
paramsValue: [this.openStreamErrorBuffer],
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
this.openStreamErrorBufferPtr = unwrapPointer(
|
|
172
|
-
this.openStreamErrorBufferRef
|
|
173
|
-
)[0]
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
private setPullMethod() {
|
|
177
|
-
this.pullMethod =
|
|
178
|
-
this.chunkSize === 1 ? this.pullSample : this.pullChunk
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
private pullSample = () => {
|
|
182
|
-
const timestampSec = this.doPullsample()
|
|
183
|
-
|
|
184
|
-
if (timestampSec > 0) {
|
|
185
|
-
return {
|
|
186
|
-
samples: this.readSamplesFromBuffer(),
|
|
187
|
-
timestamps: [timestampSec],
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return { samples: undefined, timestamps: undefined }
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
private doPullsample() {
|
|
194
|
-
return this.lsl.pullSample({
|
|
195
|
-
inletHandle: this.inletHandle,
|
|
196
|
-
sampleBufferPtr: this.sampleBufferPtr,
|
|
197
|
-
sampleBufferElements: this.channelCount,
|
|
198
|
-
timeoutMs: this.pullTimeoutMs,
|
|
199
|
-
errorCodePtr: this.pullErrorBufferPtr,
|
|
200
|
-
})
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
private readSamplesFromBuffer() {
|
|
204
|
-
const floats = new Float32Array(
|
|
205
|
-
this.sampleBuffer.buffer,
|
|
206
|
-
this.sampleBuffer.byteOffset,
|
|
207
|
-
this.chunkSize * this.channelCount
|
|
208
|
-
)
|
|
209
|
-
return Array.from(floats)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
private pullChunk = () => {
|
|
213
|
-
const firstTimestampSec = this.doPullChunk()
|
|
214
|
-
|
|
215
|
-
if (firstTimestampSec > 0) {
|
|
216
|
-
return {
|
|
217
|
-
samples: this.readSamplesFromBuffer(),
|
|
218
|
-
timestamps: this.readTimestampsFromBuffer(),
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
return { samples: undefined, timestamps: undefined }
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
private doPullChunk() {
|
|
225
|
-
return this.lsl.pullChunk({
|
|
226
|
-
inletHandle: this.inletHandle,
|
|
227
|
-
sampleBufferPtr: this.sampleBufferPtr,
|
|
228
|
-
sampleBufferElements: this.chunkSize * this.channelCount,
|
|
229
|
-
timestampBufferPtr: this.timestampBufferPtr,
|
|
230
|
-
timestampBufferElements: this.chunkSize,
|
|
231
|
-
timeoutMs: this.pullTimeoutMs,
|
|
232
|
-
errorCodePtr: this.pullErrorBufferPtr,
|
|
233
|
-
})
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
private readTimestampsFromBuffer() {
|
|
237
|
-
const doubles = new Float64Array(
|
|
238
|
-
this.timestampBuffer.buffer,
|
|
239
|
-
this.timestampBuffer.byteOffset,
|
|
240
|
-
this.chunkSize
|
|
241
|
-
)
|
|
242
|
-
return Array.from(doubles)
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
private openStream() {
|
|
246
|
-
this.lsl.openStream({
|
|
247
|
-
inletHandle: this.inletHandle,
|
|
248
|
-
timeoutMs: this.openStreamTimeoutMs,
|
|
249
|
-
errorCodePtr: this.openStreamErrorBufferPtr,
|
|
250
|
-
})
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
private async waitForSetup() {
|
|
254
|
-
return new Promise((r) => setTimeout(r, this.waitAfterOpenStreamMs))
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
public startPulling(onData: OnDataCallback) {
|
|
258
|
-
if (this.isRunning) {
|
|
259
|
-
console.warn('StreamInletWorker is already running.')
|
|
260
|
-
return
|
|
261
|
-
}
|
|
262
|
-
this.isRunning = true
|
|
263
|
-
this.onData = onData
|
|
264
|
-
|
|
265
|
-
void this.pullLoop()
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
private async pullLoop() {
|
|
269
|
-
while (this.isRunning) {
|
|
270
|
-
await this.pullDataOnce()
|
|
271
|
-
await this.waitBetweenPulls()
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
private async pullDataOnce() {
|
|
276
|
-
const { samples, timestamps } = this.pullMethod()
|
|
277
|
-
this.handleLslErrorIfPresent()
|
|
278
|
-
|
|
279
|
-
if (samples && timestamps) {
|
|
280
|
-
this.onData(samples, timestamps)
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
private handleLslErrorIfPresent() {
|
|
285
|
-
const errorCode = this.pullErrorBuffer.readInt32LE()
|
|
286
|
-
this.handleLslError(errorCode)
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
private async waitBetweenPulls() {
|
|
290
|
-
await new Promise((r) => setTimeout(r, this.waitBetweenPullsMs))
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
public flushInlet() {
|
|
294
|
-
this.lsl.flushInlet({ inletHandle: this.inletHandle })
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
public stopPulling() {
|
|
298
|
-
this.isRunning = false
|
|
299
|
-
this.closeStream()
|
|
300
|
-
|
|
301
|
-
if (this.flushInletOnStop) {
|
|
302
|
-
this.flushInlet()
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
private closeStream() {
|
|
307
|
-
this.lsl.closeStream({ inletHandle: this.inletHandle })
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
public destroyInlet() {
|
|
311
|
-
this.doDestroyInlet()
|
|
312
|
-
this.freeNativePointers()
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
private doDestroyInlet() {
|
|
316
|
-
this.lsl.destroyInlet({ inletHandle: this.inletHandle })
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
private freeNativePointers() {
|
|
320
|
-
this.freePointer({
|
|
321
|
-
paramsType: [
|
|
322
|
-
DataType.U8Array,
|
|
323
|
-
DataType.U8Array,
|
|
324
|
-
DataType.U8Array,
|
|
325
|
-
DataType.U8Array,
|
|
326
|
-
],
|
|
327
|
-
paramsValue: [
|
|
328
|
-
this.openStreamErrorBufferPtr,
|
|
329
|
-
this.sampleBufferPtr,
|
|
330
|
-
this.timestampBufferPtr,
|
|
331
|
-
this.pullErrorBufferPtr,
|
|
332
|
-
],
|
|
333
|
-
pointerType: PointerType.CPointer,
|
|
334
|
-
})
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
private get lsl() {
|
|
338
|
-
return StreamInletWorker.lsl
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
private get handleLslError() {
|
|
342
|
-
return StreamInletWorker.handleLslError
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
private get freePointer() {
|
|
346
|
-
return StreamInletWorker.freePointer
|
|
347
|
-
}
|
|
348
|
-
}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { parentPort } from 'node:worker_threads'
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
LiblslAdapter,
|
|
5
|
-
Liblsl,
|
|
6
|
-
OutletHandle,
|
|
7
|
-
handleLslError,
|
|
8
|
-
LslErrorCode,
|
|
9
|
-
} from '@neurodevs/ndx-native'
|
|
10
|
-
|
|
11
|
-
import LslStreamInfo, {
|
|
12
|
-
StreamInfo,
|
|
13
|
-
StreamInfoOptions,
|
|
14
|
-
} from '../../LslStreamInfo.js'
|
|
15
|
-
|
|
16
|
-
let lsl = LiblslAdapter.getInstance()
|
|
17
|
-
|
|
18
|
-
export function setOutletLiblslAdapter(adapter: Liblsl) {
|
|
19
|
-
LiblslAdapter.setInstance(adapter)
|
|
20
|
-
lsl = LiblslAdapter.getInstance()
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
let handleLslErrorFn = handleLslError
|
|
24
|
-
|
|
25
|
-
export function setOutletHandleLslError(fn: typeof handleLslError) {
|
|
26
|
-
handleLslErrorFn = fn
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
let info: StreamInfo
|
|
30
|
-
let handle: OutletHandle
|
|
31
|
-
let pushMethod: (opts: unknown) => LslErrorCode
|
|
32
|
-
|
|
33
|
-
parentPort?.on('message', (msg: OutletMessage) => {
|
|
34
|
-
const { type } = msg
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
switch (type) {
|
|
38
|
-
case 'createOutlet': {
|
|
39
|
-
createOutlet(msg)
|
|
40
|
-
break
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
case 'pushSample': {
|
|
44
|
-
pushSample(msg)
|
|
45
|
-
break
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
case 'destroyOutlet': {
|
|
49
|
-
destroyOutlet()
|
|
50
|
-
break
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
} catch (err) {
|
|
54
|
-
parentPort?.postMessage({
|
|
55
|
-
type: 'error',
|
|
56
|
-
error: err instanceof Error ? err.message : String(err),
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
export function createOutlet(msg: {
|
|
62
|
-
type: 'createOutlet'
|
|
63
|
-
payload: CreateOutletPayload
|
|
64
|
-
}) {
|
|
65
|
-
const { payload } = msg
|
|
66
|
-
|
|
67
|
-
info = LslStreamInfo.Create(payload.infoOptions)
|
|
68
|
-
|
|
69
|
-
handle = lsl.createOutlet({
|
|
70
|
-
infoHandle: info.infoHandle,
|
|
71
|
-
chunkSize: payload.chunkSize,
|
|
72
|
-
maxBufferedMs: payload.maxBufferedMs,
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
pushMethod = (
|
|
76
|
-
lsl[payload.pushMethod] as (opts: unknown) => LslErrorCode
|
|
77
|
-
).bind(lsl)
|
|
78
|
-
|
|
79
|
-
parentPort?.postMessage({ type: 'ready' })
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export function pushSample(msg: {
|
|
83
|
-
type: 'pushSample'
|
|
84
|
-
payload: PushSamplePayload
|
|
85
|
-
}) {
|
|
86
|
-
const { payload } = msg
|
|
87
|
-
const { sample, timestampSec = lsl.localClock() } = payload
|
|
88
|
-
|
|
89
|
-
if (!handle || !pushMethod) {
|
|
90
|
-
throw new Error('Outlet not initialized')
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const errorCode = pushMethod({
|
|
94
|
-
outletHandle: handle,
|
|
95
|
-
sample,
|
|
96
|
-
timestampSec,
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
try {
|
|
100
|
-
handleLslErrorFn(errorCode)
|
|
101
|
-
} catch {
|
|
102
|
-
parentPort?.postMessage({
|
|
103
|
-
type: 'error',
|
|
104
|
-
error: `Error pushing sample: ${LslErrorCode[errorCode]}`,
|
|
105
|
-
})
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export function destroyOutlet() {
|
|
110
|
-
if (handle) {
|
|
111
|
-
lsl.destroyOutlet({ outletHandle: handle })
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (info) {
|
|
115
|
-
lsl.destroyStreamInfo({ infoHandle: info.infoHandle })
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
parentPort?.close()
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export type OutletMessage =
|
|
122
|
-
| {
|
|
123
|
-
type: 'createOutlet'
|
|
124
|
-
payload: CreateOutletPayload
|
|
125
|
-
}
|
|
126
|
-
| {
|
|
127
|
-
type: 'pushSample'
|
|
128
|
-
payload: PushSamplePayload
|
|
129
|
-
}
|
|
130
|
-
| {
|
|
131
|
-
type: 'destroyOutlet'
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export interface CreateOutletPayload {
|
|
135
|
-
infoOptions: StreamInfoOptions
|
|
136
|
-
chunkSize: number
|
|
137
|
-
maxBufferedMs: number
|
|
138
|
-
pushMethod: 'pushSampleFloatTimestamp' | 'pushSampleStringTimestamp'
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export interface PushSamplePayload {
|
|
142
|
-
sample: unknown
|
|
143
|
-
timestampSec?: number
|
|
144
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import koffi from 'koffi'
|
|
2
|
-
|
|
3
|
-
import BleDeviceController from '../impl/controllers/BleDeviceController.js'
|
|
4
|
-
|
|
5
|
-
const MUSE_CHARACTERISTIC_UUIDS: Record<string, string> = {
|
|
6
|
-
CONTROL: '273E0001-4C4D-454D-96BE-F03BAC821358',
|
|
7
|
-
TELEMETRY: '273E000B-4C4D-454D-96BE-F03BAC821358',
|
|
8
|
-
GYROSCOPE: '273E0009-4C4D-454D-96BE-F03BAC821358',
|
|
9
|
-
ACCELEROMETER: '273E000A-4C4D-454D-96BE-F03BAC821358',
|
|
10
|
-
PPG_AMBIENT: '273E000F-4C4D-454D-96BE-F03BAC821358',
|
|
11
|
-
PPG_INFRARED: '273E0010-4C4D-454D-96BE-F03BAC821358',
|
|
12
|
-
PPG_RED: '273E0011-4C4D-454D-96BE-F03BAC821358',
|
|
13
|
-
EEG_TP9: '273E0003-4C4D-454D-96BE-F03BAC821358',
|
|
14
|
-
EEG_AF7: '273E0004-4C4D-454D-96BE-F03BAC821358',
|
|
15
|
-
EEG_AF8: '273E0005-4C4D-454D-96BE-F03BAC821358',
|
|
16
|
-
EEG_TP10: '273E0006-4C4D-454D-96BE-F03BAC821358',
|
|
17
|
-
EEG_AUX: '273E0007-4C4D-454D-96BE-F03BAC821358',
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const CONTROL_UUID = MUSE_CHARACTERISTIC_UUIDS['CONTROL']
|
|
21
|
-
|
|
22
|
-
const charCallbacks = Object.entries(MUSE_CHARACTERISTIC_UUIDS).map(
|
|
23
|
-
([name, uuid]) => {
|
|
24
|
-
return {
|
|
25
|
-
charUuid: uuid,
|
|
26
|
-
charName: name,
|
|
27
|
-
onData: (data: Buffer, length: number, timestampSec: number) => {
|
|
28
|
-
const bytes = koffi.decode(data, 'uint8', length) as number[]
|
|
29
|
-
console.info(`[${timestampSec}] length=${length}`, bytes)
|
|
30
|
-
},
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
const muse = await BleDeviceController.Create({
|
|
36
|
-
deviceNamePrefix: 'Muse',
|
|
37
|
-
charCallbacks,
|
|
38
|
-
rssiIntervalMs: 1000,
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
await muse.connect()
|
|
42
|
-
|
|
43
|
-
for (const cmd of ['h', 'p50', 's', 'd']) {
|
|
44
|
-
await muse.writeCharacteristic(CONTROL_UUID, cmd)
|
|
45
|
-
await new Promise((resolve) => setTimeout(resolve, 100))
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
await new Promise((resolve) => setTimeout(resolve, 5 * 1000))
|
|
49
|
-
|
|
50
|
-
await muse.disconnect()
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import LslStreamInlet, {
|
|
2
|
-
OnDataCallback,
|
|
3
|
-
StreamInletOptions,
|
|
4
|
-
} from '../../impl/LslStreamInlet.js'
|
|
5
|
-
|
|
6
|
-
export class SpyStreamInlet extends LslStreamInlet {
|
|
7
|
-
public constructor(options: StreamInletOptions, onData: OnDataCallback) {
|
|
8
|
-
super(options, onData)
|
|
9
|
-
}
|
|
10
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import LslWebSocketBridge, {
|
|
2
|
-
WebSocketBridgeConstructorOptions,
|
|
3
|
-
} from '../../impl/LslWebSocketBridge.js'
|
|
4
|
-
|
|
5
|
-
export default class SpyLslWebSocketBridge extends LslWebSocketBridge {
|
|
6
|
-
public constructor(options: WebSocketBridgeConstructorOptions) {
|
|
7
|
-
super(options)
|
|
8
|
-
}
|
|
9
|
-
}
|