What’s new in 2.3.1#
2.3.1 stamps every LSL sample with the time the headset took it. It builds on 2.3.0, which added
support for firmware 3.8 (digital input, time-synchronised markers), higher sample rates, charging
settings, and an LSL stream that follows the BrainAccess Board LSL contract. The complete list is
in CHANGELOG.md in the distribution ZIP.
New in 2.3.1#
LSL timestamps from the headset’s clock (firmware 3.8.0+):
streamToLslstamps every sample with the moment the headset took it, to within about 1 ms, instead of the moment its packet reached the phone. The first seconds of a stream are held until the clock is fitted. Without time sync (older firmware, impedance mode) chunks are stamped on arrival after a 5 s hold at the stream’s start.BrainAccessLslOutlettakes an optionalsampleTimesfunction for the same.session.sampleHostTimeNs(sample)(the hostSystem.nanoTime()time of a device sample) andsession.sampleNearest(hostTimeNs)(the sample nearest a host time); both returnnullwithout a valid device-clock fit.
Upgrading from 2.2.0#
LSL outlet. The stream follows the BrainAccess Board LSL contract v1: new column order (
contact_*directly after the EEG columns, then IMU,Sample,Streaming,Battery), canonical types and units (ACCEL,GYRO,CONTACT;microvolts,m/s2),double64samples,source_id= the advertised BLE name and stream name<BLE name>_<MODEL>_BrainAccess.streamToLsl(scope, outputMode, software, digitalInput)replacesstreamToLsl(scope, streamName);BrainAccessLslOutletnow takes aStreamMetadata. LSL apps declare the JNA dependency (see Installation).New errors.
BrainAccessErrorgainsStreamStartFailedandDigitalInputNotSupported; an exhaustivewhenneeds branches for both.Stricter configs.
DeviceConfigaccepts only gains 1, 2, 4, 6, 8, 12, 24 (0 on an inactive channel), andconfigure()/stream()refuse a config with no active channel.Impedance sample numbers. Each impedance value carries the sample number it was measured at; nothing is gap-filled between values (see Impedance).
Custom transports and fakes.
GattConnectiongains an abstractlinkand areadTimedwith a default, and must finish an attribute operation once issued even if its caller is cancelled.EegChunk’s constructor takeswireLastSampleIndexandpacketBytes.
New in 2.3.0#
Digital input (firmware 3.8.1+):
stream(digitalInput = true),EegChunk.digitalInput, and theDigitalLSL column.Markers on the right sample:
session.sampleIndexAt(hostTimeNs), backed by the headset’s time-sync service on firmware 3.8.0+;session.timeSyncInfo().Higher sample rates per board: 2000 Hz in
DeviceConfig.SUPPORTED_SRATES;hardware.supportedSratesadds 1 kHz on HALO V3 and 1 and 2 kHz on EXG8.Charging settings:
readChargingSettings()/writeChargingSettings()(stay on while charging, idle power-off), pluschargerConnectedandbatteryLow.Diagnostics:
link(BLE link parameters),readBatteryGauge(), theundecodablePackets/sampleCounterJumps/stalePacketscounters, andEegChunk.wireLastSampleIndex/packetBytes.Recording metadata:
session.streamMetadata(...)andStreamMetadata.toJson()(Board’s StreamMetadata schema v1);session.name(advertised BLE name).
Improvements in 2.3.0#
Sample numbers are exact for recordings of any length.
Cancelling a stream’s collector stops the headset’s stream; repeated stop/start on one connection is reliable.
stream()reportsStreamStartFailedwhen the headset cannot start its converter.Packet handling follows firmware 3.8.x, including variable-length packets and counter restarts at each stream start.
Impedance at high configured rates streams at a rate where the measurement is valid (
DeviceConfig.deviceSrate).
Tested with every headset model (HALO, MINI, MIDI, MAXI, EXG8) on firmware 3.8.8, and with MINI, MIDI, MAXI and EXG8 on firmware 3.8.9.