@neurodevs/ndx-native 0.0.1
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/.nvmrc +1 -0
- package/.vscode/launch.json +58 -0
- package/.vscode/settings.json +67 -0
- package/.vscode/tasks.json +130 -0
- package/LICENSE +21 -0
- package/README.md +2 -0
- package/build/.spruce/settings.json +11 -0
- package/build/__tests__/AbstractPackageTest.d.ts +7 -0
- package/build/__tests__/AbstractPackageTest.js +14 -0
- package/build/__tests__/AbstractPackageTest.js.map +1 -0
- package/build/__tests__/impl/LabrecorderAdapter.test.d.ts +30 -0
- package/build/__tests__/impl/LabrecorderAdapter.test.js +164 -0
- package/build/__tests__/impl/LabrecorderAdapter.test.js.map +1 -0
- package/build/__tests__/impl/LiblslAdapter.test.d.ts +84 -0
- package/build/__tests__/impl/LiblslAdapter.test.js +750 -0
- package/build/__tests__/impl/LiblslAdapter.test.js.map +1 -0
- package/build/__tests__/impl/LibxdfAdapter.test.d.ts +45 -0
- package/build/__tests__/impl/LibxdfAdapter.test.js +243 -0
- package/build/__tests__/impl/LibxdfAdapter.test.js.map +1 -0
- package/build/consts.d.ts +11 -0
- package/build/consts.js +21 -0
- package/build/consts.js.map +1 -0
- package/build/impl/LabrecorderAdapter.d.ts +30 -0
- package/build/impl/LabrecorderAdapter.js +69 -0
- package/build/impl/LabrecorderAdapter.js.map +1 -0
- package/build/impl/LiblslAdapter.d.ts +172 -0
- package/build/impl/LiblslAdapter.js +360 -0
- package/build/impl/LiblslAdapter.js.map +1 -0
- package/build/impl/LibxdfAdapter.d.ts +92 -0
- package/build/impl/LibxdfAdapter.js +130 -0
- package/build/impl/LibxdfAdapter.js.map +1 -0
- package/build/index.d.ts +14 -0
- package/build/index.js +18 -0
- package/build/index.js.map +1 -0
- package/build/lib/handleError.d.ts +8 -0
- package/build/lib/handleError.js +25 -0
- package/build/lib/handleError.js.map +1 -0
- package/build/testDoubles/Labrecorder/FakeLabrecorder.d.ts +15 -0
- package/build/testDoubles/Labrecorder/FakeLabrecorder.js +26 -0
- package/build/testDoubles/Labrecorder/FakeLabrecorder.js.map +1 -0
- package/build/testDoubles/Liblsl/FakeLiblsl.d.ts +57 -0
- package/build/testDoubles/Liblsl/FakeLiblsl.js +140 -0
- package/build/testDoubles/Liblsl/FakeLiblsl.js.map +1 -0
- package/build/testDoubles/Libxdf/FakeLibxdf.d.ts +13 -0
- package/build/testDoubles/Libxdf/FakeLibxdf.js +25 -0
- package/build/testDoubles/Libxdf/FakeLibxdf.js.map +1 -0
- package/build/testDoubles/Libxdf/SpyLibxdf.d.ts +6 -0
- package/build/testDoubles/Libxdf/SpyLibxdf.js +10 -0
- package/build/testDoubles/Libxdf/SpyLibxdf.js.map +1 -0
- package/eslint.config.mjs +3 -0
- package/package.json +84 -0
- package/src/.spruce/settings.json +11 -0
- package/src/__tests__/AbstractPackageTest.ts +16 -0
- package/src/__tests__/impl/LabrecorderAdapter.test.ts +197 -0
- package/src/__tests__/impl/LiblslAdapter.test.ts +907 -0
- package/src/__tests__/impl/LibxdfAdapter.test.ts +290 -0
- package/src/consts.ts +21 -0
- package/src/impl/LabrecorderAdapter.ts +100 -0
- package/src/impl/LiblslAdapter.ts +616 -0
- package/src/impl/LibxdfAdapter.ts +227 -0
- package/src/index.ts +26 -0
- package/src/lib/handleError.ts +24 -0
- package/src/testDoubles/Labrecorder/FakeLabrecorder.ts +37 -0
- package/src/testDoubles/Liblsl/FakeLiblsl.ts +204 -0
- package/src/testDoubles/Libxdf/FakeLibxdf.ts +33 -0
- package/src/testDoubles/Libxdf/SpyLibxdf.ts +13 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createPointer,
|
|
3
|
+
DataType,
|
|
4
|
+
define,
|
|
5
|
+
JsExternal,
|
|
6
|
+
load,
|
|
7
|
+
open,
|
|
8
|
+
unwrapPointer,
|
|
9
|
+
} from 'ffi-rs'
|
|
10
|
+
|
|
11
|
+
import { CHANNEL_FORMATS } from '../consts.js'
|
|
12
|
+
import { LslErrorCode } from '../lib/handleError.js'
|
|
13
|
+
|
|
14
|
+
export default class LiblslAdapter implements Liblsl {
|
|
15
|
+
public static open = open
|
|
16
|
+
public static define = define
|
|
17
|
+
public static load = load
|
|
18
|
+
public static alloc = Buffer.alloc
|
|
19
|
+
|
|
20
|
+
private static instance?: Liblsl
|
|
21
|
+
|
|
22
|
+
public liblslPath: string
|
|
23
|
+
private bindings!: LiblslBindings
|
|
24
|
+
|
|
25
|
+
private readonly defaultMacOsPath = `/opt/homebrew/Cellar/lsl/1.16.2/lib/liblsl.1.16.2.dylib`
|
|
26
|
+
|
|
27
|
+
protected constructor() {
|
|
28
|
+
this.liblslPath = process.env.LIBLSL_PATH ?? this.defaultMacOsPath
|
|
29
|
+
this.tryToLoadBindings()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private tryToLoadBindings() {
|
|
33
|
+
try {
|
|
34
|
+
this.loadBindings()
|
|
35
|
+
} catch (error) {
|
|
36
|
+
this.throwFailedToLoadLiblsl(error as Error)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private throwFailedToLoadLiblsl(error: Error) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Loading the liblsl dylib failed! I tried to load it from ${this.liblslPath}.\n\n${error.message}\n\n`
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public static getInstance() {
|
|
47
|
+
if (!this.instance) {
|
|
48
|
+
this.setInstance(new this())
|
|
49
|
+
}
|
|
50
|
+
return this.instance!
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public static setInstance(instance: Liblsl) {
|
|
54
|
+
this.instance = instance
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public static resetInstance() {
|
|
58
|
+
delete this.instance
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private loadBindings() {
|
|
62
|
+
this.openLiblsl()
|
|
63
|
+
this.bindings = this.defineLiblslBindings()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private openLiblsl() {
|
|
67
|
+
this.open({
|
|
68
|
+
library: 'lsl',
|
|
69
|
+
path: this.liblslPath,
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private defineLiblslBindings() {
|
|
74
|
+
return this.define(this.liblslFuncs) as LiblslBindings
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public createStreamInfo(options: CreateStreamInfoOptions) {
|
|
78
|
+
const {
|
|
79
|
+
name,
|
|
80
|
+
type,
|
|
81
|
+
sourceId,
|
|
82
|
+
channelCount,
|
|
83
|
+
channelFormat,
|
|
84
|
+
sampleRateHz,
|
|
85
|
+
} = options
|
|
86
|
+
|
|
87
|
+
return this.bindings.lsl_create_streaminfo([
|
|
88
|
+
name,
|
|
89
|
+
type,
|
|
90
|
+
channelCount,
|
|
91
|
+
sampleRateHz,
|
|
92
|
+
channelFormat,
|
|
93
|
+
sourceId,
|
|
94
|
+
])
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public appendChannelsToStreamInfo(
|
|
98
|
+
options: AppendChannelsToStreamInfoOptions
|
|
99
|
+
) {
|
|
100
|
+
const { infoHandle, channels } = options
|
|
101
|
+
|
|
102
|
+
const description = this.bindings.lsl_get_desc([infoHandle])
|
|
103
|
+
const parent = this.bindings.lsl_append_child([description, 'channels'])
|
|
104
|
+
|
|
105
|
+
for (const channel of channels) {
|
|
106
|
+
const child = this.bindings.lsl_append_child([parent, 'channel'])
|
|
107
|
+
this.bindings.lsl_append_child_value([
|
|
108
|
+
child,
|
|
109
|
+
'label',
|
|
110
|
+
channel.label,
|
|
111
|
+
])
|
|
112
|
+
this.bindings.lsl_append_child_value([child, 'unit', channel.units])
|
|
113
|
+
this.bindings.lsl_append_child_value([child, 'type', channel.type])
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public destroyStreamInfo(options: DestroyStreamInfoOptions) {
|
|
118
|
+
const { infoHandle } = options
|
|
119
|
+
this.bindings.lsl_destroy_streaminfo([infoHandle])
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public async resolveByProp(options: ResolveByPropOptions) {
|
|
123
|
+
const { prop, value, minResults = 1, timeoutMs = 1000 } = options
|
|
124
|
+
|
|
125
|
+
const maxResults = 1024
|
|
126
|
+
const bytesPerPointer = 8
|
|
127
|
+
|
|
128
|
+
const resultsBuffer = this.alloc(maxResults * bytesPerPointer)
|
|
129
|
+
|
|
130
|
+
const resultsBufferPtr = unwrapPointer(
|
|
131
|
+
createPointer({
|
|
132
|
+
paramsType: [DataType.U8Array],
|
|
133
|
+
paramsValue: [resultsBuffer],
|
|
134
|
+
})
|
|
135
|
+
)[0]
|
|
136
|
+
|
|
137
|
+
const numResults = await this.load({
|
|
138
|
+
library: 'lsl',
|
|
139
|
+
funcName: 'lsl_resolve_byprop',
|
|
140
|
+
retType: DataType.I32,
|
|
141
|
+
paramsType: [
|
|
142
|
+
DataType.External,
|
|
143
|
+
DataType.I32,
|
|
144
|
+
DataType.String,
|
|
145
|
+
DataType.String,
|
|
146
|
+
DataType.I32,
|
|
147
|
+
DataType.Double,
|
|
148
|
+
],
|
|
149
|
+
paramsValue: [
|
|
150
|
+
resultsBufferPtr,
|
|
151
|
+
maxResults,
|
|
152
|
+
prop,
|
|
153
|
+
value,
|
|
154
|
+
minResults,
|
|
155
|
+
timeoutMs / 1000,
|
|
156
|
+
],
|
|
157
|
+
runInNewThread: true,
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
const handles: InfoHandle[] = []
|
|
161
|
+
|
|
162
|
+
for (let i = 0; i < numResults; i++) {
|
|
163
|
+
const handle = resultsBuffer.readBigUInt64LE(i * bytesPerPointer)
|
|
164
|
+
|
|
165
|
+
if (handle !== 0n) {
|
|
166
|
+
const handleRef = createPointer({
|
|
167
|
+
paramsType: [DataType.BigInt],
|
|
168
|
+
paramsValue: [handle],
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
const handlePtr = unwrapPointer(handleRef)[0]
|
|
172
|
+
|
|
173
|
+
handles.push(handlePtr)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return handles
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
public createOutlet(options: CreateOutletOptions) {
|
|
181
|
+
const { infoHandle, chunkSize, maxBufferedMs } = options
|
|
182
|
+
|
|
183
|
+
return this.bindings.lsl_create_outlet([
|
|
184
|
+
infoHandle,
|
|
185
|
+
chunkSize,
|
|
186
|
+
maxBufferedMs / 1000,
|
|
187
|
+
])
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public pushSampleFloatTimestamp(options: PushSampleFloatTimestampOptions) {
|
|
191
|
+
const { outletHandle, sample, timestamp } = options
|
|
192
|
+
|
|
193
|
+
return this.bindings.lsl_push_sample_ft([
|
|
194
|
+
outletHandle,
|
|
195
|
+
sample,
|
|
196
|
+
timestamp,
|
|
197
|
+
])
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public pushSampleStringTimestamp(
|
|
201
|
+
options: PushSampleStringTimestampOptions
|
|
202
|
+
) {
|
|
203
|
+
const { outletHandle, sample, timestamp } = options
|
|
204
|
+
|
|
205
|
+
return this.bindings.lsl_push_sample_strt([
|
|
206
|
+
outletHandle,
|
|
207
|
+
sample,
|
|
208
|
+
timestamp,
|
|
209
|
+
])
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
public destroyOutlet(options: DestroyOutletOptions) {
|
|
213
|
+
const { outletHandle } = options
|
|
214
|
+
this.bindings.lsl_destroy_outlet([outletHandle])
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
public createInlet(options: CreateInletOptions) {
|
|
218
|
+
const { infoHandle, maxBufferedMs } = options
|
|
219
|
+
|
|
220
|
+
return this.bindings.lsl_create_inlet([
|
|
221
|
+
infoHandle,
|
|
222
|
+
maxBufferedMs / 1000,
|
|
223
|
+
this.maxChunkSize,
|
|
224
|
+
this.shouldRecover,
|
|
225
|
+
])
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private readonly maxChunkSize = 0
|
|
229
|
+
private readonly shouldRecover = 1
|
|
230
|
+
|
|
231
|
+
public getChannelCount(options: GetChannelCountOptions) {
|
|
232
|
+
const { infoHandle } = options
|
|
233
|
+
return this.bindings.lsl_get_channel_count([infoHandle])
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
public async openStream(options: OpenStreamOptions) {
|
|
237
|
+
const { inletHandle, timeoutMs, errorCodePtr } = options
|
|
238
|
+
|
|
239
|
+
await this.load({
|
|
240
|
+
library: 'lsl',
|
|
241
|
+
funcName: 'lsl_open_stream',
|
|
242
|
+
retType: DataType.Void,
|
|
243
|
+
paramsType: [DataType.External, DataType.Double, DataType.External],
|
|
244
|
+
paramsValue: [inletHandle, timeoutMs / 1000, errorCodePtr],
|
|
245
|
+
runInNewThread: true,
|
|
246
|
+
})
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
public closeStream(options: CloseStreamOptions) {
|
|
250
|
+
const { inletHandle } = options
|
|
251
|
+
|
|
252
|
+
this.load({
|
|
253
|
+
library: 'lsl',
|
|
254
|
+
funcName: 'lsl_close_stream',
|
|
255
|
+
retType: DataType.Void,
|
|
256
|
+
paramsType: [DataType.External],
|
|
257
|
+
paramsValue: [inletHandle],
|
|
258
|
+
})
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
public pullSample(options: PullSampleOptions) {
|
|
262
|
+
const {
|
|
263
|
+
inletHandle,
|
|
264
|
+
sampleBufferPtr,
|
|
265
|
+
sampleBufferElements,
|
|
266
|
+
timeoutMs,
|
|
267
|
+
errorCodePtr: errorCodePtr,
|
|
268
|
+
} = options
|
|
269
|
+
|
|
270
|
+
return this.load({
|
|
271
|
+
library: 'lsl',
|
|
272
|
+
funcName: 'lsl_pull_sample_f',
|
|
273
|
+
retType: DataType.Double,
|
|
274
|
+
paramsType: [
|
|
275
|
+
DataType.External,
|
|
276
|
+
DataType.External,
|
|
277
|
+
DataType.I32,
|
|
278
|
+
DataType.Double,
|
|
279
|
+
DataType.External,
|
|
280
|
+
],
|
|
281
|
+
paramsValue: [
|
|
282
|
+
inletHandle,
|
|
283
|
+
sampleBufferPtr,
|
|
284
|
+
sampleBufferElements,
|
|
285
|
+
timeoutMs / 1000,
|
|
286
|
+
errorCodePtr,
|
|
287
|
+
],
|
|
288
|
+
})
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
public pullChunk(options: PullChunkOptions) {
|
|
292
|
+
const {
|
|
293
|
+
inletHandle,
|
|
294
|
+
sampleBufferPtr,
|
|
295
|
+
timestampBufferPtr,
|
|
296
|
+
sampleBufferElements,
|
|
297
|
+
timestampBufferElements,
|
|
298
|
+
timeoutMs,
|
|
299
|
+
errorCodePtr: errorCodePtr,
|
|
300
|
+
} = options
|
|
301
|
+
|
|
302
|
+
return this.load({
|
|
303
|
+
library: 'lsl',
|
|
304
|
+
funcName: 'lsl_pull_chunk_f',
|
|
305
|
+
retType: DataType.Double,
|
|
306
|
+
paramsType: [
|
|
307
|
+
DataType.External,
|
|
308
|
+
DataType.External,
|
|
309
|
+
DataType.External,
|
|
310
|
+
DataType.I32,
|
|
311
|
+
DataType.I32,
|
|
312
|
+
DataType.Double,
|
|
313
|
+
DataType.External,
|
|
314
|
+
],
|
|
315
|
+
paramsValue: [
|
|
316
|
+
inletHandle,
|
|
317
|
+
sampleBufferPtr,
|
|
318
|
+
timestampBufferPtr,
|
|
319
|
+
sampleBufferElements,
|
|
320
|
+
timestampBufferElements,
|
|
321
|
+
timeoutMs / 1000,
|
|
322
|
+
errorCodePtr,
|
|
323
|
+
],
|
|
324
|
+
})
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
public flushInlet(options: FlushInletOptions) {
|
|
328
|
+
const { inletHandle } = options
|
|
329
|
+
this.bindings.lsl_inlet_flush([inletHandle])
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
public destroyInlet(options: DestroyInletOptions) {
|
|
333
|
+
const { inletHandle } = options
|
|
334
|
+
this.bindings.lsl_destroy_inlet([inletHandle])
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
public localClock() {
|
|
338
|
+
return this.bindings.lsl_local_clock([])
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
private get open() {
|
|
342
|
+
return LiblslAdapter.open
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
private get define() {
|
|
346
|
+
return LiblslAdapter.define
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
private get load() {
|
|
350
|
+
return LiblslAdapter.load
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
private get alloc() {
|
|
354
|
+
return LiblslAdapter.alloc
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
private get liblslFuncs() {
|
|
358
|
+
return {
|
|
359
|
+
lsl_create_streaminfo: {
|
|
360
|
+
library: 'lsl',
|
|
361
|
+
retType: DataType.External,
|
|
362
|
+
paramsType: [
|
|
363
|
+
DataType.String,
|
|
364
|
+
DataType.String,
|
|
365
|
+
DataType.I32,
|
|
366
|
+
DataType.Double,
|
|
367
|
+
DataType.I32,
|
|
368
|
+
DataType.String,
|
|
369
|
+
],
|
|
370
|
+
},
|
|
371
|
+
lsl_destroy_streaminfo: {
|
|
372
|
+
library: 'lsl',
|
|
373
|
+
retType: DataType.Void,
|
|
374
|
+
paramsType: [DataType.External],
|
|
375
|
+
},
|
|
376
|
+
lsl_create_outlet: {
|
|
377
|
+
library: 'lsl',
|
|
378
|
+
retType: DataType.External,
|
|
379
|
+
paramsType: [DataType.External, DataType.I32, DataType.I32],
|
|
380
|
+
},
|
|
381
|
+
lsl_push_sample_ft: {
|
|
382
|
+
library: 'lsl',
|
|
383
|
+
retType: DataType.I32,
|
|
384
|
+
paramsType: [
|
|
385
|
+
DataType.External,
|
|
386
|
+
DataType.FloatArray,
|
|
387
|
+
DataType.Double,
|
|
388
|
+
],
|
|
389
|
+
},
|
|
390
|
+
lsl_push_sample_strt: {
|
|
391
|
+
library: 'lsl',
|
|
392
|
+
retType: DataType.I32,
|
|
393
|
+
paramsType: [
|
|
394
|
+
DataType.External,
|
|
395
|
+
DataType.StringArray,
|
|
396
|
+
DataType.Double,
|
|
397
|
+
],
|
|
398
|
+
},
|
|
399
|
+
lsl_destroy_outlet: {
|
|
400
|
+
library: 'lsl',
|
|
401
|
+
retType: DataType.Void,
|
|
402
|
+
paramsType: [DataType.External],
|
|
403
|
+
},
|
|
404
|
+
lsl_create_inlet: {
|
|
405
|
+
library: 'lsl',
|
|
406
|
+
retType: DataType.External,
|
|
407
|
+
paramsType: [
|
|
408
|
+
DataType.External,
|
|
409
|
+
DataType.I32,
|
|
410
|
+
DataType.I32,
|
|
411
|
+
DataType.I32,
|
|
412
|
+
],
|
|
413
|
+
},
|
|
414
|
+
lsl_inlet_flush: {
|
|
415
|
+
library: 'lsl',
|
|
416
|
+
retType: DataType.I32,
|
|
417
|
+
paramsType: [DataType.External],
|
|
418
|
+
},
|
|
419
|
+
lsl_destroy_inlet: {
|
|
420
|
+
library: 'lsl',
|
|
421
|
+
retType: DataType.Void,
|
|
422
|
+
paramsType: [DataType.External],
|
|
423
|
+
},
|
|
424
|
+
lsl_get_desc: {
|
|
425
|
+
library: 'lsl',
|
|
426
|
+
retType: DataType.External,
|
|
427
|
+
paramsType: [DataType.External],
|
|
428
|
+
},
|
|
429
|
+
lsl_get_channel_count: {
|
|
430
|
+
library: 'lsl',
|
|
431
|
+
retType: DataType.I32,
|
|
432
|
+
paramsType: [DataType.External],
|
|
433
|
+
},
|
|
434
|
+
lsl_append_child: {
|
|
435
|
+
library: 'lsl',
|
|
436
|
+
retType: DataType.External,
|
|
437
|
+
paramsType: [DataType.External, DataType.String],
|
|
438
|
+
},
|
|
439
|
+
lsl_append_child_value: {
|
|
440
|
+
library: 'lsl',
|
|
441
|
+
retType: DataType.External,
|
|
442
|
+
paramsType: [
|
|
443
|
+
DataType.External,
|
|
444
|
+
DataType.String,
|
|
445
|
+
DataType.String,
|
|
446
|
+
],
|
|
447
|
+
},
|
|
448
|
+
lsl_local_clock: {
|
|
449
|
+
library: 'lsl',
|
|
450
|
+
retType: DataType.Double,
|
|
451
|
+
paramsType: [],
|
|
452
|
+
},
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export interface Liblsl {
|
|
458
|
+
liblslPath: string
|
|
459
|
+
|
|
460
|
+
createStreamInfo(options: CreateStreamInfoOptions): InfoHandle
|
|
461
|
+
destroyStreamInfo(options: DestroyStreamInfoOptions): void
|
|
462
|
+
appendChannelsToStreamInfo(options: AppendChannelsToStreamInfoOptions): void
|
|
463
|
+
getChannelCount(options: GetChannelCountOptions): number
|
|
464
|
+
|
|
465
|
+
resolveByProp(options: ResolveByPropOptions): Promise<InfoHandle[]>
|
|
466
|
+
|
|
467
|
+
createOutlet(options: CreateOutletOptions): OutletHandle
|
|
468
|
+
|
|
469
|
+
pushSampleFloatTimestamp(
|
|
470
|
+
options: PushSampleFloatTimestampOptions
|
|
471
|
+
): LslErrorCode
|
|
472
|
+
|
|
473
|
+
pushSampleStringTimestamp(
|
|
474
|
+
options: PushSampleStringTimestampOptions
|
|
475
|
+
): LslErrorCode
|
|
476
|
+
|
|
477
|
+
destroyOutlet(options: DestroyOutletOptions): void
|
|
478
|
+
|
|
479
|
+
createInlet(options: CreateInletOptions): InletHandle
|
|
480
|
+
openStream(options: OpenStreamOptions): Promise<void>
|
|
481
|
+
closeStream(options: CloseStreamOptions): void
|
|
482
|
+
pullSample(options: PullSampleOptions): number
|
|
483
|
+
pullChunk(options: PullChunkOptions): number
|
|
484
|
+
flushInlet(options: FlushInletOptions): void
|
|
485
|
+
destroyInlet(options: DestroyInletOptions): void
|
|
486
|
+
|
|
487
|
+
localClock(): number
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
export interface CreateStreamInfoOptions {
|
|
491
|
+
name: string
|
|
492
|
+
type: string
|
|
493
|
+
sourceId: string
|
|
494
|
+
channelCount: number
|
|
495
|
+
channelFormat: number
|
|
496
|
+
sampleRateHz: number
|
|
497
|
+
manufacturer?: string
|
|
498
|
+
units?: string
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
export interface AppendChannelsToStreamInfoOptions {
|
|
502
|
+
infoHandle: InfoHandle
|
|
503
|
+
channels: LslChannel[]
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
export interface GetChannelCountOptions {
|
|
507
|
+
infoHandle: InfoHandle
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
export interface DestroyStreamInfoOptions {
|
|
511
|
+
infoHandle: InfoHandle
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
export interface ResolveByPropOptions {
|
|
515
|
+
prop: string
|
|
516
|
+
value: string
|
|
517
|
+
minResults?: number
|
|
518
|
+
timeoutMs?: number
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
export interface CreateOutletOptions {
|
|
522
|
+
infoHandle: InfoHandle
|
|
523
|
+
chunkSize: number
|
|
524
|
+
maxBufferedMs: number
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export interface PushSampleFloatTimestampOptions {
|
|
528
|
+
outletHandle: OutletHandle
|
|
529
|
+
sample: number[]
|
|
530
|
+
timestamp: number
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
export interface PushSampleStringTimestampOptions {
|
|
534
|
+
outletHandle: OutletHandle
|
|
535
|
+
sample: string[]
|
|
536
|
+
timestamp: number
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
export interface DestroyOutletOptions {
|
|
540
|
+
outletHandle: OutletHandle
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
export interface CreateInletOptions {
|
|
544
|
+
infoHandle: InfoHandle
|
|
545
|
+
maxBufferedMs: number
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
export interface OpenStreamOptions {
|
|
549
|
+
inletHandle: InletHandle
|
|
550
|
+
timeoutMs: number
|
|
551
|
+
errorCodePtr: JsExternal
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
export interface CloseStreamOptions {
|
|
555
|
+
inletHandle: InletHandle
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
export interface PullSampleOptions {
|
|
559
|
+
inletHandle: InletHandle
|
|
560
|
+
sampleBufferPtr: JsExternal
|
|
561
|
+
sampleBufferElements: number
|
|
562
|
+
timeoutMs: number
|
|
563
|
+
errorCodePtr: JsExternal
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
export interface PullChunkOptions extends PullSampleOptions {
|
|
567
|
+
timestampBufferPtr: JsExternal
|
|
568
|
+
timestampBufferElements: number
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
export interface FlushInletOptions {
|
|
572
|
+
inletHandle: InletHandle
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
export interface DestroyInletOptions {
|
|
576
|
+
inletHandle: InletHandle
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
export interface LiblslBindings {
|
|
580
|
+
lsl_create_streaminfo(
|
|
581
|
+
args: [string, string, number, number, number, string]
|
|
582
|
+
): InfoHandle
|
|
583
|
+
|
|
584
|
+
lsl_get_desc(args: [InfoHandle]): DescriptionHandle
|
|
585
|
+
lsl_get_channel_count(args: [InfoHandle]): number
|
|
586
|
+
lsl_append_child(args: [DescriptionHandle, string]): ChildHandle
|
|
587
|
+
lsl_append_child_value(args: [ChildHandle, string, string]): void
|
|
588
|
+
lsl_destroy_streaminfo(args: [InfoHandle]): void
|
|
589
|
+
|
|
590
|
+
lsl_create_outlet(args: [InfoHandle, number, number]): OutletHandle
|
|
591
|
+
lsl_push_sample_ft(args: [OutletHandle, LslSample, number]): LslErrorCode
|
|
592
|
+
lsl_push_sample_strt(args: [OutletHandle, LslSample, number]): LslErrorCode
|
|
593
|
+
lsl_destroy_outlet(args: [OutletHandle]): void
|
|
594
|
+
|
|
595
|
+
lsl_create_inlet(args: any): InletHandle
|
|
596
|
+
lsl_inlet_flush(args: [InletHandle]): void
|
|
597
|
+
lsl_destroy_inlet(args: any): void
|
|
598
|
+
|
|
599
|
+
lsl_local_clock(args: []): number
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
export type ChannelFormat = (typeof CHANNEL_FORMATS)[number]
|
|
603
|
+
|
|
604
|
+
export interface LslChannel {
|
|
605
|
+
label: string
|
|
606
|
+
units: string
|
|
607
|
+
type: string
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export type LslSample = (number | string | undefined)[]
|
|
611
|
+
|
|
612
|
+
export interface InfoHandle {}
|
|
613
|
+
export interface OutletHandle {}
|
|
614
|
+
export interface InletHandle {}
|
|
615
|
+
export interface DescriptionHandle {}
|
|
616
|
+
export interface ChildHandle {}
|