ESP OpenBCI - An EEG Signal Processing Library for OpenBCI Hardware

ESP OpenBCI - An EEG Signal Processing Library for OpenBCI Hardware

ESP OpenBCI - An EEG Signal Processing Library for OpenBCI Hardware

See:
          Description

Packages
com.github.mrstampy.esp.dsp  
com.github.mrstampy.esp.dsp.lab  
com.github.mrstampy.esp.multiconnectionsocket  
com.github.mrstampy.esp.multiconnectionsocket.event  
com.github.mrstampy.esp.multiconnectionsocket.subscription  
com.github.mrstampy.esp.openbci  
com.github.mrstampy.esp.openbci.dsp  
com.github.mrstampy.esp.openbci.rxtx  
com.github.mrstampy.esp.openbci.subscription  

 

ESP OpenBCI - An EEG Signal Processing Library for OpenBCI Hardware

Release 2.1, 25-05-14 (Initial Release)

This Java library provides the implementation of ESP library classes to acquire the raw EEG signal from OpenBCI hardware. ESP-OpenBCI was compiled for Java version 1.6 compatibility.

Design Goals

ESP is designed to provide Java programs access to EEG device signals and provide the ability to process the signals for the purposes of the program. The ESP library itself is not an implementation, however there are several implementations for specific EEG devices:

ESP provides a common structure for device specific implementations. This allows programs using the ESP libraries to cater for multiple devices from a single codebase.

The core classes have been designed with speed and concurrency in mind using high performance Java libraries:

Primary Design Specifics

The MultiConnectSocket Interface

This interface defines the methods that must be implemented for a class which provides access to EEG hardware. An abstract superclass exists for ease of implementation.

The RawEspConnection Interface

RawEspConnection extends the MultiConnectSocket interface. Implementations are intended to encapsulate and control a MultiConnectSocket instance through the implementation of the common methods, as well as provide the current seconds' worth of samples on demand for direct use or further processing. Signal processing methods exist to provide ease of processing the signal. An abstract superclass exists for ease of implementation.

The Lab Interface

While the ESP library provides DSP processing classes, how the signal is processed is left to programs using the library. Lab implementations provide the ability to obtain the current seconds' worth of samples from the encapsulated RawEspConnection, process the signal and notify the program when a sample is ready for use. A default implementation exists and an abstract superclass provides ease of custom lab implementation.

Usage

Direct MultiConnectSocket Usage

This is the lowest level use case. Programs using ESP library implementations in this manner will receive device-specific signals as they occur. Each implementation of the ESP library's MultiConnectSocket has a device-specific listener mechanism to obtain the signal. Pseudo code for usage appears as so:

                        MultiConnectOpenBCISocket socket = new MultiConnectOpenBCISocket();
                        
                        // optional, common to all MultiConnectSocket implementations:
                        // add a listener to receive connect/disconnect events
                        socket.addConnectionEventListener(new ConnectionEventListener() {
                                public void connectionEventPerformed(ConnectionEvent e) {
                                        doSomethingWith(e);
                                }
                        });
                        
                        socket.addListener(new OpenBCIEventListener() {
                                public void dataEventPerformed(OpenBCIEvent event) {
                                        doSomethingWith(e);
                                }
                        });
                        
                        socket.start();
                        

Direct MultiConnectSocket Usage - Remote Connection

This functionality is from where the MultiConnectSocket derives its name. Device specific implementations provide the ability to open a socket on a configurable port. Such sockets facilitate a subscribe and publish of device signals. This allows separate processes and machines to receive the device signals for their own purposes - signal recording, secondary processing, display etc.

                        // on the host machine or process:
                        // port is set via the system property 'socket.broadcaster.port', default '12345'
                        MultiConnectOpenBCISocket socket = new MultiConnectOpenBCISocket(true);
                        
                        // on the remote process/machine:
                        // port is set via the system property 'socket.broadcaster.port', default '12345'
                        OpenBCISocketConnector connector = new OpenBCISocketConnector("host machine name or IP address");
                        
                        connector.addListener(new OpenBCIEventListener() {
                                public void dataEventPerformed(OpenBCIEvent event) {
                                        doSomethingWith(e);
                                }
                        });
                        
                        connector.connect();
                        connector.subscribe(....);
                        
                        // and back on the host machine or process:
                        socket.start();
                        

RawEspConnection Usage

RawEspConnection implementations aggregate the current second's worth of data, insulating the program from device specific listeners. The samples are intended to be queried periodically in a separate scheduled task or thread. The period of querying is left to the program and is independent of sample rate.

                        OpenBCIConnection connection = new OpenBCIConnection();
                        
                        // optional, common to all RawEspConnection implementations:
                        // add a listener to receive connect/disconnect events
                        connection.addConnectionEventListener(new ConnectionEventListener() {
                                public void connectionEventPerformed(ConnectionEvent e) {
                                        doSomethingWith(e);
                                }
                        });
                        
                        connection.start();
                        
                        // in a separate scheduled periodic task..
                        int channel = 1; // channel of interest 
                        dealWithCurrentSecondOfSamples(connection.getCurrentFor(channel));
                        

Lab Usage

Lab implementations provide the ability to process the current seconds' worth of data from the RawEspConnection and notify any interested parties of its completion. Triggering of signal processing is intended to be executed periodically in a separate scheduled task or thread. The period of triggering is left to the program and is independent of sample rate.

                        OpenBCIConnection connection = new OpenBCIConnection();
                        
                        // optional, common to all RawEspConnection implementations:
                        // add a listener to receive connect/disconnect events
                        connection.addConnectionEventListener(new ConnectionEventListener() {
                                public void connectionEventPerformed(ConnectionEvent e) {
                                        doSomethingWith(e);
                                }
                        });
                        
                        Lab lab = connection.getDefaultLab();
                        
                        int numBands = 40; // first 40 bands
                        lab.setNumBands(numBands); // must be set
                        
                        int channel = 1; // channel of interest for multichannels
                        lab.setChannel(channel); // required if > 1 channel
                        
                        lab.addSignalProcessedListener(new SignalProcessedListener() {
                                public void signalProcessed(double[] processed) {
                                        doSomethingWith(processed);
                                }
                        });
                        
                        // other lab values set as appropriate for processing the signal
                        
                        connection.start();
                        
                        // in a separate scheduled periodic task..
                        lab.triggerProcessing();
                        

Example classes

OpenBCITester

Architecture

Properties

This library expects a file named 'esp.openbci.properties' to exist and be on the classpath. An example file can be found in the repository.

Local use of the Multi Connection OpenBCI Socket

The MultiConnectOpenBCISocket is the core class of this library. Listeners can register themselves with the socket implementation and will receive the generated events as they occur, allowing near-realtime signal acquisition from the device.

But this doesn't explain the 'multi connection' name...

Remote Connection to the Multi Connection OpenBCI Socket

Remote use of the Multi Connection OpenBCI Socket

The Multi Connection OpenBCI Socket allows connections from the OpenBCISocketConnector. Multi connection sockets can accept many such remote connections (theoretically thousands). The connections can be running in the same JVM or in different Java programs, even on different computers. Due to the introduced latency resulting from the remote connection the signal received cannot be considered near-realtime, however the socket connector is quite useful for highly buffered signals and for applications such as data recorders.

Applications using the socket connector create the connection to the multi connection socket and subscribe to receive device-specific events. Listeners register themselves with the socket connector and receive the event notifications as they are received by the socket connector.

Raw Signal Processing

Raw data processing

In the development of the ESP-OpenBCI implementation the base classes for raw signal processing were developed. Multi connection socket implementations contain a raw data buffer which contains the current second's worth of data.

Raw data event listeners can make use of OpenBCISignalAggregator which keeps the current second's worth of snapshots in memory (number of snapshots = sample rate). The OpenBCIDSP class provides the ability to apply signal processing algorithms to the current group of snapshots and notifies any RawProcessedListeners upon completion of each cycle. A utility class is provided which contains methods which may be useful in processing the raw signal and the ESP library contains classes liberated from Minim and MaryTTS projects which can be used to process the signal.

The goal of the ESP raw signal processing is to line the ducks up in a row for processing. How the signal is processed is up to the application using the library.

Additional functionality is described in these JavaDocs. This work is released under the GPL 3.0 license. No warranty of any kind is offered. ESP-OpenBCI Copyright (C) 2014 Burton Alexander. OpenBCI Copyright (C) ...


brought to you by Mr. Stampy