bc-ecap-sdk 0.3.0__cp38-abi3-manylinux_2_31_x86_64.whl

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.
@@ -0,0 +1,486 @@
1
+ # This file is automatically generated by pyo3_stub_gen
2
+ # ruff: noqa: E501, F401
3
+
4
+ import builtins
5
+ import typing
6
+ from . import ble
7
+ from enum import Enum
8
+
9
+ class BLEDeviceInfo:
10
+ manufacturer: builtins.str
11
+ model: builtins.str
12
+ serial: builtins.str
13
+ hardware: builtins.str
14
+ firmware: builtins.str
15
+
16
+ class BandPassFilter:
17
+ a: builtins.float
18
+ d1: builtins.float
19
+ d2: builtins.float
20
+ d3: builtins.float
21
+ d4: builtins.float
22
+ w0: builtins.float
23
+ w1: builtins.float
24
+ w2: builtins.float
25
+ w3: builtins.float
26
+ w4: builtins.float
27
+ def __new__(cls, fs:builtins.float, fl:builtins.float, fu:builtins.float) -> BandPassFilter: ...
28
+ def filter(self, iter:typing.Sequence[builtins.float]) -> builtins.list[builtins.float]: ...
29
+ def apply(self, input:builtins.float) -> builtins.float: ...
30
+
31
+ class BandStopFilter:
32
+ a: builtins.float
33
+ d1: builtins.float
34
+ d2: builtins.float
35
+ d3: builtins.float
36
+ d4: builtins.float
37
+ w0: builtins.float
38
+ w1: builtins.float
39
+ w2: builtins.float
40
+ w3: builtins.float
41
+ w4: builtins.float
42
+ r: builtins.float
43
+ s: builtins.float
44
+ def __new__(cls, fs:builtins.float, fl:builtins.float, fu:builtins.float) -> BandStopFilter: ...
45
+ def filter(self, iter:typing.Sequence[builtins.float]) -> builtins.list[builtins.float]: ...
46
+ def apply(self, input:builtins.float) -> builtins.float: ...
47
+
48
+ class ECapClient:
49
+ def __new__(cls, addr:builtins.str, port:builtins.int) -> ECapClient: ...
50
+ def start_data_stream(self, py_parser:MessageParser) -> typing.Any: ...
51
+ def send_command(self, msg_id:builtins.int, data:typing.Sequence[builtins.int]) -> typing.Any: ...
52
+ def get_battery_level(self) -> typing.Any: ...
53
+ def get_device_info(self) -> typing.Any: ...
54
+ def start_leadoff_check(self, loop_check:builtins.bool, freq:LeadOffFreq, current:LeadOffCurrent) -> typing.Any: ...
55
+ def stop_leadoff_check(self) -> typing.Any: ...
56
+ def start_eeg_stream(self) -> typing.Any: ...
57
+ def stop_eeg_stream(self) -> typing.Any: ...
58
+ def start_imu_stream(self) -> typing.Any: ...
59
+ def stop_imu_stream(self) -> typing.Any: ...
60
+ def get_eeg_config(self) -> typing.Any: ...
61
+ def get_imu_config(self) -> typing.Any: ...
62
+ def set_eeg_config(self, fs:EegSampleRate, gain:EegSignalGain, signal:EegSignalSource) -> typing.Any: ...
63
+ def set_imu_config(self, fs:ImuSampleRate) -> typing.Any: ...
64
+
65
+ class HighPassFilter:
66
+ a: builtins.float
67
+ d1: builtins.float
68
+ d2: builtins.float
69
+ w0: builtins.float
70
+ w1: builtins.float
71
+ w2: builtins.float
72
+ def __new__(cls, fs:builtins.float, fu:builtins.float) -> HighPassFilter: ...
73
+ def filter(self, iter:typing.Sequence[builtins.float]) -> builtins.list[builtins.float]: ...
74
+ def apply(self, input:builtins.float) -> builtins.float: ...
75
+
76
+ class LowPassFilter:
77
+ a: builtins.float
78
+ d1: builtins.float
79
+ d2: builtins.float
80
+ w0: builtins.float
81
+ w1: builtins.float
82
+ w2: builtins.float
83
+ def __new__(cls, fs:builtins.float, fl:builtins.float) -> LowPassFilter: ...
84
+ def filter(self, iter:typing.Sequence[builtins.float]) -> builtins.list[builtins.float]: ...
85
+ def apply(self, input:builtins.float) -> builtins.float: ...
86
+
87
+ class LslConfig:
88
+ r"""
89
+ LSL流配置
90
+ """
91
+ stream_name: builtins.str
92
+ r"""
93
+ 流名称
94
+ """
95
+ stream_type: builtins.str
96
+ r"""
97
+ 流类型(通常为"EEG")
98
+ """
99
+ channel_count: builtins.int
100
+ r"""
101
+ 通道数
102
+ """
103
+ sample_rate: builtins.float
104
+ r"""
105
+ 采样率
106
+ """
107
+ source_id: builtins.str
108
+ r"""
109
+ 源ID(唯一标识符)
110
+ """
111
+ def __new__(cls, stream_name:builtins.str='BrainCo-EEG-32Ch', stream_type:builtins.str='EEG', channel_count:builtins.int=32, sample_rate:builtins.float=250.0, source_id:builtins.str='brainco-eeg-32ch-001') -> LslConfig:
112
+ r"""
113
+ 创建新的 LSL 配置
114
+
115
+ # Arguments
116
+ * `stream_name` - LSL流名称 (默认: "BrainCo-EEG-32Ch")
117
+ * `stream_type` - 流类型 (默认: "EEG")
118
+ * `channel_count` - 通道数 (默认: 32)
119
+ * `sample_rate` - 采样率 (默认: 250.0)
120
+ * `source_id` - 源标识符 (默认: "brainco-eeg-32ch-001")
121
+ """
122
+
123
+ class MdnsScanResult:
124
+ fullname: builtins.str
125
+ hostname: builtins.str
126
+ addr: builtins.str
127
+ port: builtins.int
128
+ sn: builtins.str
129
+ model: builtins.str
130
+
131
+ class MessageParser:
132
+ def __new__(cls, device_id:builtins.str, msg_type:MsgType) -> MessageParser: ...
133
+ def receive_data(self, data:typing.Sequence[builtins.int]) -> None: ...
134
+
135
+ class NotchFilter:
136
+ def __new__(cls, f0:builtins.float, fs:builtins.float, quality:builtins.float) -> NotchFilter: ...
137
+ def apply(self, signal:typing.Sequence[builtins.float]) -> builtins.list[builtins.float]: ...
138
+
139
+ class PyTcpClient:
140
+ def __new__(cls, addr:builtins.str, port:builtins.int) -> PyTcpClient: ...
141
+ def start_data_stream(self, py_parser:MessageParser) -> typing.Any: ...
142
+ def send_command(self, msg_id:builtins.int, data:typing.Sequence[builtins.int]) -> typing.Any: ...
143
+
144
+ class PyTcpStream:
145
+ def __aiter__(self) -> PyTcpStream: ...
146
+ def __anext__(self) -> typing.Any: ...
147
+
148
+ class PyTcpStream:
149
+ def __aiter__(self) -> PyTcpStream: ...
150
+ def __anext__(self) -> typing.Any: ...
151
+
152
+ class ScanResult:
153
+ id: builtins.str
154
+ name: builtins.str
155
+ rssi: builtins.int
156
+ is_in_pairing_mode: builtins.bool
157
+ battery_level: builtins.int
158
+
159
+ class SosFilter:
160
+ @staticmethod
161
+ def create_low_pass(order:builtins.int, fs:builtins.float, lowcut:builtins.float) -> SosFilter: ...
162
+ @staticmethod
163
+ def create_high_pass(order:builtins.int, fs:builtins.float, highcut:builtins.float) -> SosFilter: ...
164
+ @staticmethod
165
+ def create_band_pass(order:builtins.int, fs:builtins.float, lowcut:builtins.float, highcut:builtins.float) -> SosFilter: ...
166
+ @staticmethod
167
+ def create_band_stop(order:builtins.int, fs:builtins.float, lowcut:builtins.float, highcut:builtins.float) -> SosFilter: ...
168
+ def apply(self, signal:typing.Sequence[builtins.float]) -> builtins.list[builtins.float]: ...
169
+
170
+ class AggOperations(Enum):
171
+ Mean = ...
172
+ Median = ...
173
+
174
+ int_value: builtins.int
175
+
176
+ def __new__(cls, value:builtins.int) -> AggOperations: ...
177
+
178
+ class CentralAdapterState(Enum):
179
+ Unknown = ...
180
+ PoweredOn = ...
181
+ PoweredOff = ...
182
+
183
+ int_value: builtins.int
184
+
185
+ def __new__(cls, value:builtins.int) -> CentralAdapterState: ...
186
+
187
+ class ConnectionState(Enum):
188
+ Connecting = ...
189
+ Connected = ...
190
+ Disconnecting = ...
191
+ Disconnected = ...
192
+
193
+ int_value: builtins.int
194
+
195
+ def __new__(cls, value:builtins.int) -> ConnectionState: ...
196
+
197
+ class DfuState(Enum):
198
+ Idle = ...
199
+ Starting = ...
200
+ Transferring = ...
201
+ TransferFinished = ...
202
+ Rebooting = ...
203
+ Success = ...
204
+ Error = ...
205
+
206
+ int_value: builtins.int
207
+
208
+ def __new__(cls, value:builtins.int) -> DfuState: ...
209
+
210
+ class DownsamplingOperations(Enum):
211
+ Mean = ...
212
+ Median = ...
213
+ Max = ...
214
+ Min = ...
215
+ Sum = ...
216
+ First = ...
217
+ Last = ...
218
+ Extremes = ...
219
+
220
+ int_value: builtins.int
221
+
222
+ def __new__(cls, value:builtins.int) -> DownsamplingOperations: ...
223
+
224
+ class EEGCapModuleId(Enum):
225
+ MCU = ...
226
+ BLE = ...
227
+ APP = ...
228
+
229
+ int_value: builtins.int
230
+
231
+ def __new__(cls, value:builtins.int) -> EEGCapModuleId: ...
232
+
233
+ class EegSampleRate(Enum):
234
+ SR_None = ...
235
+ SR_250Hz = ...
236
+ SR_500Hz = ...
237
+ SR_1000Hz = ...
238
+ SR_2000Hz = ...
239
+
240
+ int_value: builtins.int
241
+
242
+ def __new__(cls, value:builtins.int) -> EegSampleRate: ...
243
+
244
+ class EegSignalGain(Enum):
245
+ GAIN_NONE = ...
246
+ GAIN_1 = ...
247
+ GAIN_2 = ...
248
+ GAIN_4 = ...
249
+ GAIN_6 = ...
250
+ GAIN_8 = ...
251
+ GAIN_12 = ...
252
+ GAIN_24 = ...
253
+
254
+ int_value: builtins.int
255
+
256
+ def __new__(cls, value:builtins.int) -> EegSignalGain: ...
257
+
258
+ class EegSignalSource(Enum):
259
+ SIGNAL_NONE = ...
260
+ NORMAL = ...
261
+ SHORTED = ...
262
+ MVDD = ...
263
+ TEST_SIGNAL = ...
264
+
265
+ int_value: builtins.int
266
+
267
+ def __new__(cls, value:builtins.int) -> EegSignalSource: ...
268
+
269
+ class ImuSampleRate(Enum):
270
+ SR_NONE = ...
271
+ SR_50Hz = ...
272
+ SR_100Hz = ...
273
+
274
+ int_value: builtins.int
275
+
276
+ def __new__(cls, value:builtins.int) -> ImuSampleRate: ...
277
+
278
+ class LeadOffChip(Enum):
279
+ None = ...
280
+ Chip1 = ...
281
+ Chip2 = ...
282
+ Chip3 = ...
283
+ Chip4 = ...
284
+
285
+ int_value: builtins.int
286
+
287
+ def __new__(cls, value:builtins.int) -> LeadOffChip: ...
288
+
289
+ class LeadOffCurrent(Enum):
290
+ None = ...
291
+ Cur6nA = ...
292
+ Cur24nA = ...
293
+ Cur6uA = ...
294
+ Cur24uA = ...
295
+
296
+ int_value: builtins.int
297
+
298
+ def __new__(cls, value:builtins.int) -> LeadOffCurrent: ...
299
+
300
+ class LeadOffFreq(Enum):
301
+ None = ...
302
+ Dc = ...
303
+ Ac7p8hz = ...
304
+ Ac31p2hz = ...
305
+ AcFdr4 = ...
306
+
307
+ int_value: builtins.int
308
+
309
+ def __new__(cls, value:builtins.int) -> LeadOffFreq: ...
310
+
311
+ class LogLevel(Enum):
312
+ Error = ...
313
+ Warn = ...
314
+ Info = ...
315
+ Debug = ...
316
+ Trace = ...
317
+
318
+ class MsgType(Enum):
319
+ Crimson = ...
320
+ OxyZen = ...
321
+ Mobius = ...
322
+ MobiusV1_5 = ...
323
+ Almond = ...
324
+ AlmondV2 = ...
325
+ Morpheus = ...
326
+ Luna = ...
327
+ REN = ...
328
+ Breeze = ...
329
+ Stark = ...
330
+ EEGCap = ...
331
+ Edu = ...
332
+ Clear = ...
333
+ Melody = ...
334
+ Aura = ...
335
+
336
+ int_value: builtins.int
337
+
338
+ def __new__(cls, value:builtins.int) -> MsgType: ...
339
+
340
+ class NoiseTypes(Enum):
341
+ FIFTY = ...
342
+ SIXTY = ...
343
+ FIFTY_AND_SIXTY = ...
344
+
345
+ int_value: builtins.int
346
+
347
+ def __new__(cls, value:builtins.int) -> NoiseTypes: ...
348
+
349
+ class TcpExitReason(Enum):
350
+ Normal = ...
351
+ Disconnected = ...
352
+ Timeout = ...
353
+ ConnectionError = ...
354
+
355
+ int_value: builtins.int
356
+
357
+ def __new__(cls, value:builtins.int) -> TcpExitReason: ...
358
+
359
+ class WiFiSecurity(Enum):
360
+ SECURITY_NONE = ...
361
+ SECURITY_OPEN = ...
362
+ SECURITY_WPA2_MIXED_PSK = ...
363
+
364
+ int_value: builtins.int
365
+
366
+ def __new__(cls, value:builtins.int) -> WiFiSecurity: ...
367
+
368
+ def apply_bandpass_filter(data:typing.Sequence[builtins.float], channel:builtins.int) -> builtins.list[builtins.float]: ...
369
+
370
+ def apply_bandstop_filter(data:typing.Sequence[builtins.float], channel:builtins.int) -> builtins.list[builtins.float]: ...
371
+
372
+ def apply_downsampling(data:typing.Sequence[builtins.float], window_size:builtins.int, operation:DownsamplingOperations) -> builtins.list[builtins.float]: ...
373
+
374
+ def apply_eeg_filter(data:typing.Sequence[builtins.float], channel:builtins.int) -> builtins.list[builtins.float]: ...
375
+
376
+ def apply_eeg_sosfiltfilt(data:typing.Sequence[builtins.float], channel:builtins.int) -> builtins.list[builtins.float]: ...
377
+
378
+ def apply_highpass_filter(data:typing.Sequence[builtins.float], channel:builtins.int) -> builtins.list[builtins.float]: ...
379
+
380
+ def apply_impendance_filter(data:typing.Sequence[builtins.float], channel:builtins.int) -> builtins.list[builtins.float]: ...
381
+
382
+ def apply_impendance_sosfiltfilt(data:typing.Sequence[builtins.float], channel:builtins.int) -> builtins.list[builtins.float]: ...
383
+
384
+ def apply_lowpass_filter(data:typing.Sequence[builtins.float], channel:builtins.int) -> builtins.list[builtins.float]: ...
385
+
386
+ def calculate_fft_data(data:typing.Sequence[builtins.float], fs:builtins.float) -> tuple[builtins.list[builtins.float], builtins.list[builtins.float]]: ...
387
+
388
+ def get_ble_device_info(id:builtins.str) -> typing.Any: ...
389
+
390
+ def get_wifi_config(id:builtins.str) -> typing.Any: ...
391
+
392
+ def get_wifi_status(id:builtins.str) -> typing.Any: ...
393
+
394
+ def parse_eeg_data(data:typing.Sequence[builtins.int], gain:EegSignalGain) -> builtins.list[builtins.float]: ...
395
+
396
+ def py_is_lsl_bridge_enabled() -> builtins.bool:
397
+ r"""
398
+ 检查LSL桥接器是否已启动
399
+
400
+ # Returns
401
+ * `bool` - 如果LSL桥接器已启动则返回True,否则返回False
402
+
403
+ # Example
404
+ ```python
405
+ from bc_ecap_sdk.main_mod import is_lsl_bridge_enabled
406
+
407
+ if is_lsl_bridge_enabled():
408
+ print("LSL bridge is running")
409
+ ```
410
+ """
411
+
412
+ def py_set_lsl_sample_rate(sample_rate:builtins.float) -> None:
413
+ r"""
414
+ 更新LSL桥接器的采样率
415
+
416
+ # Arguments
417
+ * `sample_rate` - 新的采样率(Hz)
418
+
419
+ # Example
420
+ ```python
421
+ from bc_ecap_sdk.main_mod import set_lsl_sample_rate
422
+
423
+ set_lsl_sample_rate(500.0) # 设置为500Hz
424
+ ```
425
+ """
426
+
427
+ def py_start_lsl_bridge(config:typing.Optional[LslConfig]=None) -> None:
428
+ r"""
429
+ 启动LSL桥接器
430
+
431
+ # Arguments
432
+ * `config` - LSL配置对象,如果为None则使用默认配置
433
+
434
+ # Example
435
+ ```python
436
+ from bc_ecap_sdk.main_mod import LslConfig, start_lsl_bridge
437
+
438
+ config = LslConfig(
439
+ stream_name="BrainCo-EEG-32Ch",
440
+ stream_type="EEG",
441
+ channel_count=32,
442
+ sample_rate=250.0,
443
+ source_id="brainco-eeg-32ch-001"
444
+ )
445
+ start_lsl_bridge(config)
446
+ ```
447
+ """
448
+
449
+ def py_stop_lsl_bridge() -> None:
450
+ r"""
451
+ 停止LSL桥接器
452
+
453
+ # Example
454
+ ```python
455
+ from bc_ecap_sdk.main_mod import stop_lsl_bridge
456
+
457
+ stop_lsl_bridge()
458
+ ```
459
+ """
460
+
461
+ def remove_env_noise(data:typing.Sequence[builtins.float], channel:builtins.int) -> builtins.list[builtins.float]: ...
462
+
463
+ def remove_env_noise_notch(data:typing.Sequence[builtins.float], channel:builtins.int) -> builtins.list[builtins.float]: ...
464
+
465
+ def remove_env_noise_sosfiltfilt(data:typing.Sequence[builtins.float], channel:builtins.int) -> builtins.list[builtins.float]: ...
466
+
467
+ def set_ble_device_info(id:builtins.str, model:builtins.str, sn:builtins.str) -> typing.Any: ...
468
+
469
+ def set_eeg_data_callback(func:typing.Any) -> None: ...
470
+
471
+ def set_eeg_data_callback_v2(func:typing.Any) -> None: ...
472
+
473
+ def set_env_noise_cfg(noise_type:NoiseTypes, fs:builtins.float) -> None: ...
474
+
475
+ def set_imp_data_callback(func:typing.Any) -> None: ...
476
+
477
+ def set_imu_data_callback(func:typing.Any) -> None: ...
478
+
479
+ def set_msg_resp_callback(func:typing.Any) -> None: ...
480
+
481
+ def set_wifi_config(id:builtins.str, enable:builtins.bool, security:WiFiSecurity, ssid:builtins.str, password:builtins.str) -> typing.Any: ...
482
+
483
+ def start_scan(with_sn:typing.Optional[builtins.str]=None) -> typing.Any: ...
484
+
485
+ def stop_scan() -> typing.Any: ...
486
+
@@ -0,0 +1,30 @@
1
+ # This file is automatically generated by pyo3_stub_gen
2
+ # ruff: noqa: E501, F401
3
+
4
+ import builtins
5
+ import typing
6
+
7
+ def connect(id:builtins.str) -> typing.Any: ...
8
+
9
+ def disconnect(id:builtins.str) -> typing.Any: ...
10
+
11
+ def init_adapter() -> typing.Any: ...
12
+
13
+ def set_adapter_state_callback(func:typing.Any) -> None: ...
14
+
15
+ def set_battery_level_callback(func:typing.Any) -> None: ...
16
+
17
+ def set_connection_state_callback(func:typing.Any) -> None: ...
18
+
19
+ def set_device_discovered_callback(func:typing.Any) -> None: ...
20
+
21
+ def set_device_info_callback(func:typing.Any) -> None: ...
22
+
23
+ def set_received_data_callback(func:typing.Any) -> None: ...
24
+
25
+ def set_scan_result_callback(func:typing.Any) -> None: ...
26
+
27
+ def start_scan(with_uuids:typing.Optional[typing.Sequence[builtins.str]]=None) -> None: ...
28
+
29
+ def stop_scan() -> None: ...
30
+
Binary file
@@ -0,0 +1,16 @@
1
+ Metadata-Version: 2.4
2
+ Name: bc_ecap_sdk
3
+ Version: 0.3.0
4
+ Classifier: Programming Language :: Rust
5
+ Classifier: Programming Language :: Python :: Implementation :: CPython
6
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
7
+ License-File: LICENSE
8
+ Summary: BrainCo FW proto message SDK
9
+ Author: BrainCo
10
+ License:
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
13
+ Project-URL: Source Code, https://github.com/BrainCoTech/bc_ecap_sdk
14
+
15
+ # BrainCo ECAP SDK
16
+
@@ -0,0 +1,13 @@
1
+ bc_ecap_sdk-0.3.0.dist-info/METADATA,sha256=UKWMU2wnQJgpWYzw5KmYUnEXHzCl0z1nu4ohWlbEOu8,505
2
+ bc_ecap_sdk-0.3.0.dist-info/WHEEL,sha256=CKTrMmDidU39xt7Iw8pJMYDtNkRVK1O6xYkpH-Havww,106
3
+ bc_ecap_sdk-0.3.0.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ bc_ecap_sdk.libs/libdbus-1-c5c41a4c.so.3,sha256=NvR2pWYleDUDpuoZ6kdxIOJVtxnuamCMVbqiy1J_Qf4,363697
5
+ bc_ecap_sdk.libs/libgcrypt-f648d4ed.so.20,sha256=yNfs9AmC7S2BOTNWZtM0EGsg1MtHEQ9tIfwBugA-xkU,1184321
6
+ bc_ecap_sdk.libs/libgpg-error-df95914e.so.0,sha256=yf9Ah8rgp7nX0p54ZkBwh_oGBcPHzzFj3YTYlGsw5qs,144049
7
+ bc_ecap_sdk.libs/liblz4-d6574e34.so.1,sha256=hkTqySc6HSeA5y0yUwIGAQK5ARJI00SInyW6SCnO1eo,134345
8
+ bc_ecap_sdk.libs/liblzma-79a1dbc7.so.5,sha256=PksHx-puyo0mL1lqf1d338OPRD07uM-rq8sYI3fRC1A,167617
9
+ bc_ecap_sdk.libs/libsystemd-4d12bf8d.so.0,sha256=EDluOVbQV0XcWDZznzpQWFfQ5bvezVY-F0tBM807uvg,753929
10
+ bc_ecap_sdk/main_mod/__init__.pyi,sha256=YnKiHC3EvRXdWAgrpoYYtHXFPoMhOmFJEY1JXntkP48,14007
11
+ bc_ecap_sdk/main_mod/ble.pyi,sha256=32Cq_k8gpPpvTy_dRa4xVQSJ3YPyXbt7RzM6T4KhLDY,813
12
+ bc_ecap_sdk/main_mod.abi3.so,sha256=vaf2VruijZnG86T1bUYPvvUbJENNwItIeg68mBGdyn8,5571801
13
+ bc_ecap_sdk-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.8.3)
3
+ Root-Is-Purelib: false
4
+ Tag: cp38-abi3-manylinux_2_31_x86_64
File without changes
Binary file
Binary file
Binary file