Code Samples
Make sure that you’ve installed MindRove package before running the code samples below.
See Installation Instructions for details.
Python
To run some signal processing samples, you may need to install:
matplotlib
pandas
mne
pyqtgraph
MindRove doesn’t use these packages and doesn’t install them, but the packages will be used in demos below.
Python Real Time Plot
Extra requirements for this code sample:
PyQt5==5.15.7
PyQt5-Qt5==5.15.2
PyQt5-sip==12.11.0
pyqtgraph==0.12.4
mindrove
import argparse
import logging
import pyqtgraph as pg
from mindrove.board_shim import BoardShim, MindRoveInputParams, BoardIds
from mindrove.data_filter import DataFilter, FilterTypes, DetrendOperations
from pyqtgraph.Qt import QtGui, QtCore
class Graph:
def __init__(self, board_shim):
self.board_id = board_shim.get_board_id()
self.board_shim = board_shim
self.exg_channels = BoardShim.get_exg_channels(self.board_id)
self.sampling_rate = BoardShim.get_sampling_rate(self.board_id)
self.update_speed_ms = 50
self.window_size = 4
self.num_points = self.window_size * self.sampling_rate
self.app = QtGui.QApplication([])
self.win = pg.GraphicsWindow(title='MindRove Plot', size=(800, 600))
self._init_timeseries()
timer = QtCore.QTimer()
timer.timeout.connect(self.update)
timer.start(self.update_speed_ms)
QtGui.QApplication.instance().exec_()
def _init_timeseries(self):
self.plots = list()
self.curves = list()
for i in range(len(self.exg_channels)):
p = self.win.addPlot(row=i, col=0)
p.showAxis('left', False)
p.setMenuEnabled('left', False)
p.showAxis('bottom', False)
p.setMenuEnabled('bottom', False)
if i == 0:
p.setTitle('TimeSeries Plot')
self.plots.append(p)
curve = p.plot()
self.curves.append(curve)
def update(self):
data = self.board_shim.get_current_board_data(self.num_points)
for count, channel in enumerate(self.exg_channels):
# plot timeseries
DataFilter.detrend(data[channel], DetrendOperations.CONSTANT.value)
DataFilter.perform_bandpass(data[channel], self.sampling_rate, 3.0, self.sampling_rate/2, 2,
FilterTypes.BUTTERWORTH_ZERO_PHASE, 0)
DataFilter.perform_bandstop(data[channel], self.sampling_rate, 48.0, 52.0, 2,
FilterTypes.BUTTERWORTH_ZERO_PHASE, 0)
DataFilter.perform_bandstop(data[channel], self.sampling_rate, 58.0, 62.0, 2,
FilterTypes.BUTTERWORTH_ZERO_PHASE, 0)
self.curves[count].setData(data[channel].tolist())
self.app.processEvents()
def main():
BoardShim.enable_dev_board_logger()
logging.basicConfig(level=logging.DEBUG)
parser = argparse.ArgumentParser()
# use docs to check which parameters are required for specific board, e.g. for Cyton - set serial port
parser.add_argument('--timeout', type=int, help='timeout for device discovery or connection', required=False,
default=0)
parser.add_argument('--ip-port', type=int, help='ip port', required=False, default=0)
parser.add_argument('--ip-protocol', type=int, help='ip protocol, check IpProtocolType enum', required=False,
default=0)
parser.add_argument('--ip-address', type=str, help='ip address', required=False, default='')
parser.add_argument('--serial-port', type=str, help='serial port', required=False, default='')
parser.add_argument('--mac-address', type=str, help='mac address', required=False, default='')
parser.add_argument('--other-info', type=str, help='other info', required=False, default='')
parser.add_argument('--streamer-params', type=str, help='streamer params', required=False, default='')
parser.add_argument('--serial-number', type=str, help='serial number', required=False, default='')
parser.add_argument('--board-id', type=int, help='board id, check docs to get a list of supported boards',
required=False, default=BoardIds.MINDROVE_SYNCBOX_BOARD)
parser.add_argument('--file', type=str, help='file', required=False, default='')
parser.add_argument('--master-board', type=int, help='master board id for streaming and playback boards',
required=False, default=BoardIds.NO_BOARD)
args = parser.parse_args()
params = MindRoveInputParams()
params.ip_port = args.ip_port
params.serial_port = args.serial_port
params.mac_address = args.mac_address
params.other_info = args.other_info
params.serial_number = args.serial_number
params.ip_address = args.ip_address
params.ip_protocol = args.ip_protocol
params.timeout = args.timeout
params.file = args.file
params.master_board = args.master_board
board_shim = BoardShim(args.board_id, params)
try:
board_shim.prepare_session()
board_shim.start_stream(450000, args.streamer_params)
Graph(board_shim)
except BaseException:
logging.warning('Exception', exc_info=True)
finally:
logging.info('End')
if board_shim.is_prepared():
logging.info('Releasing session')
board_shim.release_session()
if __name__ == '__main__':
main()
C#
C# Read Data from a Board
using System;
using mindrove;
using mindrove.math;
namespace examples
{
class GetBoardData
{
static void Main (string[] args)
{
BoardShim.enable_dev_board_logger ();
MindRoveInputParams input_params = new MindRoveInputParams ();
int board_id = parse_args (args, input_params);
BoardShim board_shim = new BoardShim (board_id, input_params);
board_shim.prepare_session ();
board_shim.start_stream ();
System.Threading.Thread.Sleep (5000);
board_shim.stop_stream ();
double[,] unprocessed_data = board_shim.get_current_board_data (20);
int[] eeg_channels = BoardShim.get_eeg_channels (board_id);
foreach (var index in eeg_channels)
Console.WriteLine ("[{0}]", string.Join (", ", unprocessed_data.GetRow (index)));
board_shim.release_session ();
}
static int parse_args (string[] args, MindRoveInputParams input_params)
{
int board_id = (int)BoardIds.SYNTHETIC_BOARD; //assume synthetic board by default
// use docs to get params for your specific board, e.g. set serial_port for Cyton
for (int i = 0; i < args.Length; i++)
{
if (args[i].Equals ("--ip-address"))
{
input_params.ip_address = args[i + 1];
}
if (args[i].Equals ("--mac-address"))
{
input_params.mac_address = args[i + 1];
}
if (args[i].Equals ("--serial-port"))
{
input_params.serial_port = args[i + 1];
}
if (args[i].Equals ("--other-info"))
{
input_params.other_info = args[i + 1];
}
if (args[i].Equals ("--ip-port"))
{
input_params.ip_port = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--ip-protocol"))
{
input_params.ip_protocol = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--board-id"))
{
board_id = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--timeout"))
{
input_params.timeout = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--serial-number"))
{
input_params.serial_number = args[i + 1];
}
if (args[i].Equals ("--file"))
{
input_params.file = args[i + 1];
}
}
return board_id;
}
}
}
C# Markers
using System;
using mindrove;
using mindrove.math;
namespace examples
{
class Markers
{
static void Main (string[] args)
{
BoardShim.enable_dev_board_logger ();
MindRoveInputParams input_params = new MindRoveInputParams ();
int board_id = parse_args (args, input_params);
BoardShim board_shim = new BoardShim (board_id, input_params);
board_shim.prepare_session ();
board_shim.start_stream ();
board_shim.add_streamer ("file://data.csv:w");
for (int i = 1; i < 5; i++)
{
System.Threading.Thread.Sleep (1000);
board_shim.insert_marker (i);
}
board_shim.stop_stream ();
board_shim.release_session ();
}
static int parse_args (string[] args, MindRoveInputParams input_params)
{
int board_id = (int)BoardIds.SYNTHETIC_BOARD; //assume synthetic board by default
// use docs to get params for your specific board, e.g. set serial_port for Cyton
for (int i = 0; i < args.Length; i++)
{
if (args[i].Equals ("--ip-address"))
{
input_params.ip_address = args[i + 1];
}
if (args[i].Equals ("--mac-address"))
{
input_params.mac_address = args[i + 1];
}
if (args[i].Equals ("--serial-port"))
{
input_params.serial_port = args[i + 1];
}
if (args[i].Equals ("--other-info"))
{
input_params.other_info = args[i + 1];
}
if (args[i].Equals ("--ip-port"))
{
input_params.ip_port = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--ip-protocol"))
{
input_params.ip_protocol = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--board-id"))
{
board_id = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--timeout"))
{
input_params.timeout = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--serial-number"))
{
input_params.serial_number = args[i + 1];
}
if (args[i].Equals ("--file"))
{
input_params.file = args[i + 1];
}
}
return board_id;
}
}
}
C# Read Write File
using System;
using mindrove;
using mindrove.math;
namespace examples
{
class Serialization
{
static void Main (string[] args)
{
// use synthetic board for demo
BoardShim.enable_dev_board_logger ();
MindRoveInputParams input_params = new MindRoveInputParams ();
int board_id = (int)BoardIds.SYNTHETIC_BOARD;
BoardShim board_shim = new BoardShim (board_id, input_params);
board_shim.prepare_session ();
board_shim.start_stream (3600);
System.Threading.Thread.Sleep (5000);
board_shim.stop_stream ();
double[,] unprocessed_data = board_shim.get_current_board_data (20);
int[] eeg_channels = BoardShim.get_eeg_channels (board_id);
Console.WriteLine ("Before serialization:");
foreach (var index in eeg_channels)
Console.WriteLine ("[{0}]", string.Join (", ", unprocessed_data.GetRow (index)));
board_shim.release_session ();
// demo for data serialization
DataFilter.write_file (unprocessed_data, "test.csv", "w");
double[,] restored_data = DataFilter.read_file ("test.csv");
Console.WriteLine ("After Serialization:");
foreach (var index in eeg_channels)
Console.WriteLine ("[{0}]", string.Join (", ", restored_data.GetRow (index)));
}
}
}
C# Downsample Data
using System;
using mindrove;
using mindrove.math;
namespace examples
{
class Downsampling
{
static void Main (string[] args)
{
// use synthetic board for demo
BoardShim.enable_dev_board_logger ();
MindRoveInputParams input_params = new MindRoveInputParams ();
int board_id = (int)BoardIds.SYNTHETIC_BOARD;
BoardShim board_shim = new BoardShim (board_id, input_params);
board_shim.prepare_session ();
board_shim.start_stream (3600);
System.Threading.Thread.Sleep (5000);
board_shim.stop_stream ();
double[,] unprocessed_data = board_shim.get_board_data ();
int[] eeg_channels = BoardShim.get_eeg_channels (board_id);
board_shim.release_session ();
for (int i = 0; i < eeg_channels.Length; i++)
{
Console.WriteLine ("Before processing:");
Console.WriteLine ("[{0}]", string.Join (", ", unprocessed_data.GetRow (eeg_channels[i])));
// you can use MEAN, MEDIAN or EACH for downsampling
double[] filtered = DataFilter.perform_downsampling (unprocessed_data.GetRow (eeg_channels[i]), 3, (int)AggOperations.MEDIAN);
Console.WriteLine ("Before processing:");
Console.WriteLine ("[{0}]", string.Join (", ", filtered));
}
}
}
}
C# Transforms
using System;
using System.Numerics;
using mindrove;
using mindrove.math;
namespace examples
{
class Transforms
{
static void Main (string[] args)
{
// use synthetic board for demo
BoardShim.enable_dev_board_logger ();
MindRoveInputParams input_params = new MindRoveInputParams ();
int board_id = (int)BoardIds.SYNTHETIC_BOARD;
BoardShim board_shim = new BoardShim (board_id, input_params);
board_shim.prepare_session ();
board_shim.start_stream (3600);
System.Threading.Thread.Sleep (5000);
board_shim.stop_stream ();
double[,] unprocessed_data = board_shim.get_current_board_data (64);
int[] eeg_channels = BoardShim.get_eeg_channels (board_id);
board_shim.release_session ();
for (int i = 0; i < eeg_channels.Length; i++)
{
Console.WriteLine ("Original data:");
Console.WriteLine ("[{0}]", string.Join (", ", unprocessed_data.GetRow (eeg_channels[i])));
// demo for wavelet transform
// tuple of coeffs array in format[A(J) D(J) D(J-1) ..... D(1)] where J is a
// decomposition level, A - app coeffs, D - detailed coeffs, and array which stores
// length for each block, len of this array is decomposition_length + 1
Tuple<double[], int[]> wavelet_data = DataFilter.perform_wavelet_transform (unprocessed_data.GetRow (eeg_channels[i]), (int)WaveletTypes.DB4, 1, (int)WaveletExtensionTypes.SYMMETRIC);
// print app coeffs
for (int j = 0; j < wavelet_data.Item2[0]; j++)
{
Console.Write (wavelet_data.Item1[j] + " ");
}
Console.WriteLine ();
// you can do smth with wavelet coeffs here, for example denoising works via thresholds for wavelets coeffs
double[] restored_data = DataFilter.perform_inverse_wavelet_transform (wavelet_data, unprocessed_data.GetRow (eeg_channels[i]).Length, (int)WaveletTypes.DB4, 1, (int)WaveletExtensionTypes.SYMMETRIC);
Console.WriteLine ("Restored wavelet data:");
Console.WriteLine ("[{0}]", string.Join (", ", restored_data));
// demo for fft
// end_pos - start_pos must be a power of 2
Complex[] fft_data = DataFilter.perform_fft (unprocessed_data.GetRow (eeg_channels[i]), 0, 64, (int)WindowOperations.HAMMING);
// len of fft_data is N / 2 + 1
double[] restored_fft_data = DataFilter.perform_ifft (fft_data);
Console.WriteLine ("Restored fft data:");
Console.WriteLine ("[{0}]", string.Join (", ", restored_fft_data));
}
}
}
}
C# Signal Filtering
using System;
using mindrove;
using mindrove.math;
namespace examples
{
class SignalFiltering
{
static void Main (string[] args)
{
// use synthetic board for demo
BoardShim.enable_dev_board_logger ();
MindRoveInputParams input_params = new MindRoveInputParams ();
int board_id = (int)BoardIds.SYNTHETIC_BOARD;
BoardShim board_shim = new BoardShim (board_id, input_params);
board_shim.prepare_session ();
board_shim.start_stream (3600);
System.Threading.Thread.Sleep (5000);
board_shim.stop_stream ();
double[,] unprocessed_data = board_shim.get_current_board_data (20);
int[] eeg_channels = BoardShim.get_eeg_channels (board_id);
board_shim.release_session ();
for (int i = 0; i < eeg_channels.Length; i++)
{
DataFilter.detrend (unprocessed_data, eeg_channels[i], (int)DetrendOperations.CONSTANT);
DataFilter.perform_bandstop (unprocessed_data, eeg_channels[i], BoardShim.get_sampling_rate (board_id), 48.0, 52.0, 4, (int)FilterTypes.BUTTERWORTH, 0.0);
DataFilter.perform_bandpass (unprocessed_data, eeg_channels[i], BoardShim.get_sampling_rate (board_id), 4.0, 30.0, 4, (int)FilterTypes.BUTTERWORTH, 0.0);
}
}
}
}
C# Denoising
using System;
using mindrove;
using mindrove.math;
namespace examples
{
class Denoising
{
static void Main (string[] args)
{
// use synthetic board for demo
BoardShim.enable_dev_board_logger ();
MindRoveInputParams input_params = new MindRoveInputParams ();
int board_id = (int)BoardIds.SYNTHETIC_BOARD;
BoardShim board_shim = new BoardShim (board_id, input_params);
board_shim.prepare_session ();
board_shim.start_stream (3600);
System.Threading.Thread.Sleep (5000);
board_shim.stop_stream ();
double[,] unprocessed_data = board_shim.get_current_board_data (64);
int[] eeg_channels = BoardShim.get_eeg_channels (board_id);
foreach (var index in eeg_channels)
Console.WriteLine ("[{0}]", string.Join (", ", unprocessed_data.GetRow (index)));
board_shim.release_session ();
// for demo apply different methods to different channels
double[] filtered;
for (int i = 0; i < eeg_channels.Length; i++)
{
switch (i)
{
// first of all you can try simple moving average or moving median
case 0:
filtered = DataFilter.perform_rolling_filter (unprocessed_data.GetRow (eeg_channels[i]), 3, (int)AggOperations.MEAN);
Console.WriteLine ("Filtered channel " + eeg_channels[i]);
Console.WriteLine ("[{0}]", string.Join (", ", filtered));
break;
case 1:
filtered = DataFilter.perform_rolling_filter (unprocessed_data.GetRow (eeg_channels[i]), 3, (int)AggOperations.MEDIAN);
Console.WriteLine ("Filtered channel " + eeg_channels[i]);
Console.WriteLine ("[{0}]", string.Join (", ", filtered));
break;
// if for your signal these methods dont work good you can try wavelet based denoising
default:
// feel free to try different functions and different decomposition levels
filtered = DataFilter.perform_wavelet_denoising (unprocessed_data.GetRow (eeg_channels[i]), (int)WaveletTypes.BIOR3_9, 3);
Console.WriteLine ("Filtered channel " + eeg_channels[i]);
Console.WriteLine ("[{0}]", string.Join (", ", filtered));
break;
}
}
}
}
}
C# Band Power
using System;
using System.Runtime.Serialization;
using mindrove;
using mindrove.math;
namespace examples
{
class BandPower
{
static void Main (string[] args)
{
// use synthetic board for demo
BoardShim.enable_dev_board_logger ();
MindRoveInputParams input_params = new MindRoveInputParams ();
int board_id = (int)BoardIds.SYNTHETIC_BOARD;
BoardDescr board_descr = BoardShim.get_board_descr<BoardDescr> (board_id);
int sampling_rate = board_descr.sampling_rate;
int nfft = DataFilter.get_nearest_power_of_two (sampling_rate);
BoardShim board_shim = new BoardShim (board_id, input_params);
board_shim.prepare_session ();
board_shim.start_stream (3600);
System.Threading.Thread.Sleep (10000);
board_shim.stop_stream ();
double[,] data = board_shim.get_board_data ();
int[] eeg_channels = board_descr.eeg_channels;
// use second channel of synthetic board to see 'alpha'
int channel = eeg_channels[1];
board_shim.release_session ();
double[] detrend = DataFilter.detrend (data.GetRow (channel), (int)DetrendOperations.LINEAR);
Tuple<double[], double[]> psd = DataFilter.get_psd_welch (detrend, nfft, nfft / 2, sampling_rate, (int)WindowOperations.HANNING);
double band_power_alpha = DataFilter.get_band_power (psd, 7.0, 13.0);
double band_power_beta = DataFilter.get_band_power (psd, 14.0, 30.0);
Console.WriteLine ("Alpha/Beta Ratio:" + (band_power_alpha / band_power_beta));
}
}
}
C# EEG Metrics
using System;
using mindrove;
using mindrove.math;
namespace examples
{
class EEGMetrics
{
static void Main (string[] args)
{
// use synthetic board for demo
BoardShim.enable_dev_board_logger ();
MindRoveInputParams input_params = new MindRoveInputParams ();
int board_id = parse_args (args, input_params);
BoardShim board_shim = new BoardShim (board_id, input_params);
int sampling_rate = BoardShim.get_sampling_rate (board_shim.get_board_id ());
int[] eeg_channels = BoardShim.get_eeg_channels (board_shim.get_board_id ());
board_shim.prepare_session ();
board_shim.start_stream (3600);
System.Threading.Thread.Sleep (10000);
board_shim.stop_stream ();
double[,] data = board_shim.get_board_data ();
board_shim.release_session ();
Tuple<double[], double[]> bands = DataFilter.get_avg_band_powers (data, eeg_channels, sampling_rate, true);
double[] feature_vector = bands.Item1;
MindRoveModelParams model_params = new MindRoveModelParams ((int)MindRoveMetrics.MINDFULNESS, (int)MindRoveClassifiers.DEFAULT_CLASSIFIER);
MLModel model = new MLModel (model_params);
model.prepare ();
Console.WriteLine ("Score: " + model.predict (feature_vector)[0]);
model.release ();
}
static int parse_args (string[] args, MindRoveInputParams input_params)
{
int board_id = (int)BoardIds.SYNTHETIC_BOARD; //assume synthetic board by default
// use docs to get params for your specific board, e.g. set serial_port for Cyton
for (int i = 0; i < args.Length; i++)
{
if (args[i].Equals ("--ip-address"))
{
input_params.ip_address = args[i + 1];
}
if (args[i].Equals ("--mac-address"))
{
input_params.mac_address = args[i + 1];
}
if (args[i].Equals ("--serial-port"))
{
input_params.serial_port = args[i + 1];
}
if (args[i].Equals ("--other-info"))
{
input_params.other_info = args[i + 1];
}
if (args[i].Equals ("--ip-port"))
{
input_params.ip_port = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--ip-protocol"))
{
input_params.ip_protocol = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--board-id"))
{
board_id = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--timeout"))
{
input_params.timeout = Convert.ToInt32 (args[i + 1]);
}
if (args[i].Equals ("--serial-number"))
{
input_params.serial_number = args[i + 1];
}
if (args[i].Equals ("--file"))
{
input_params.file = args[i + 1];
}
}
return board_id;
}
}
}
C# ICA
using System;
using System.Runtime.Serialization;
using mindrove;
using mindrove.math;
namespace examples
{
class ICA
{
static void Main (string[] args)
{
BoardShim.enable_dev_board_logger ();
int board_id = (int)BoardIds.SYNTHETIC_BOARD;
BoardDescr board_descr = BoardShim.get_board_descr<BoardDescr> (board_id);
int[] eeg_channels = board_descr.eeg_channels;
int channel = eeg_channels[1];
MindRoveInputParams input_params = new MindRoveInputParams ();
BoardShim board_shim = new BoardShim (board_id, input_params);
board_shim.prepare_session ();
board_shim.start_stream (3600);
System.Threading.Thread.Sleep (10000);
board_shim.stop_stream ();
double[,] data = board_shim.get_board_data (500);
board_shim.release_session ();
double[,] ica_data = data.GetRow (channel).Reshape(5, 100);
Tuple<double[,], double[,], double[,], double[,]> ica = DataFilter.perform_ica (ica_data, 2);
}
}
}
C++
To compile examples below for Linux or MacOS run:
cd cpp_package/examples/get_data
mkdir build
cd build
cmake -DCMAKE_PREFIX_PATH=TYPE_FULL_PATH_TO_MINDROVE_INSTALLED_FOLDER ..
# e.g. cmake -DCMAKE_PREFIX_PATH=/home/andrey/mindrove/installed ..
make
For Windows it’s almost the same.
Make sure that compiled dynamic libraries exist in search path before running an executable by doing one of the following:
for Linux and MacOS add them to LD_LIBRARY_PATH env variable
for Windows add them to PATH env variable
or just copypaste them to the folder where your executable is located
CMake File Example
cmake_minimum_required (VERSION 3.10)
project (MINDROVE_GET_DATA)
set (CMAKE_CXX_STANDARD 11)
set (CMAKE_VERBOSE_MAKEFILE ON)
macro (configure_msvc_runtime)
if (MSVC)
# Default to statically-linked runtime.
if ("${MSVC_RUNTIME}" STREQUAL "")
set (MSVC_RUNTIME "static")
endif ()
# Set compiler options.
set (variables
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
)
if (${MSVC_RUNTIME} STREQUAL "static")
message(STATUS
"MSVC -> forcing use of statically-linked runtime."
)
foreach (variable ${variables})
if (${variable} MATCHES "/MD")
string (REGEX REPLACE "/MD" "/MT" ${variable} "${${variable}}")
endif ()
endforeach ()
else ()
message (STATUS
"MSVC -> forcing use of dynamically-linked runtime."
)
foreach (variable ${variables})
if (${variable} MATCHES "/MT")
string (REGEX REPLACE "/MT" "/MD" ${variable} "${${variable}}")
endif ()
endforeach ()
endif ()
endif ()
endmacro ()
# link msvc runtime statically
configure_msvc_runtime()
find_package (
mindrove CONFIG REQUIRED
)
add_executable (
mindrove_get_data
src/mindrove_get_data.cpp
)
target_include_directories (
mindrove_get_data PUBLIC
${mindrove_INCLUDE_DIRS}
)
target_link_libraries (
mindrove_get_data PUBLIC
# for some systems(ubuntu for example) order matters
${MindrovePath}
${MLModulePath}
${DataHandlerPath}
${BoardControllerPath}
)
add_executable (
markers
src/markers.cpp
)
target_include_directories (
markers PUBLIC
${mindrove_INCLUDE_DIRS}
)
target_link_libraries (
markers PUBLIC
# for some systems(ubuntu for example) order matters
${MindrovePath}
${MLModulePath}
${DataHandlerPath}
${BoardControllerPath}
)
add_executable (
get_data_twice
src/get_data_twice.cpp
)
target_include_directories (
get_data_twice PUBLIC
${mindrove_INCLUDE_DIRS}
)
target_link_libraries (
get_data_twice PUBLIC
# for some systems(ubuntu for example) order matters
${MindrovePath}
${MLModulePath}
${DataHandlerPath}
${BoardControllerPath}
)
add_executable (
multiple_streamers
src/multiple_streamers.cpp
)
target_include_directories (
multiple_streamers PUBLIC
${mindrove_INCLUDE_DIRS}
)
target_link_libraries (
multiple_streamers PUBLIC
# for some systems(ubuntu for example) order matters
${MindrovePath}
${MLModulePath}
${DataHandlerPath}
${BoardControllerPath}
)
C++ Read Data from a Board
#include <iostream>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "board_shim.h"
using namespace std;
bool parse_args (int argc, char *argv[], struct MindRoveInputParams *params, int *board_id);
int main (int argc, char *argv[])
{
BoardShim::enable_dev_board_logger ();
//BoardShim::get_board_presets (-1);
struct MindRoveInputParams params;
int board_id = 1;
/*
if (!parse_args (argc, argv, ¶ms, &board_id))
{
return -1;
}
*/
int res = 0;
std::string ipa = "::1";
params.ip_address = ipa;
params.ip_port = 5005;
params.mac_address = "abcdef";
BoardShim *board_1 = new BoardShim (board_id, params);
params.mac_address = "ghijkl";
BoardShim *board_2 = new BoardShim (board_id, params);
params.mac_address = "mnopqr";
BoardShim *board_3 = new BoardShim (board_id, params);
try
{
board_1->prepare_session ();
board_1->start_stream ();
board_2->prepare_session ();
board_2->start_stream ();
board_3->prepare_session ();
board_3->start_stream ();
#ifdef _WIN32
Sleep (5000);
#else
sleep (5);
#endif
board_1->stop_stream ();
board_2->stop_stream ();
board_3->stop_stream ();
MindRoveArray<double, 2> data = board_1->get_current_board_data (10);
board_1->release_session ();
std::cout << data << std::endl;
MindRoveArray<double, 2> data2 = board_2->get_current_board_data (10);
board_2->release_session ();
std::cout << data2 << std::endl;
MindRoveArray<double, 2> data3 = board_3->get_current_board_data (10);
board_3->release_session ();
std::cout << data3 << std::endl;
}
catch (const MindRoveException &err)
{
BoardShim::log_message ((int)LogLevels::LEVEL_ERROR, err.what ());
res = err.exit_code;
if (board_1->is_prepared ())
{
board_1->release_session ();
}
if (board_2->is_prepared ())
{
board_2->release_session ();
}
if (board_3->is_prepared ())
{
board_3->release_session ();
}
}
delete board_1;
delete board_2;
delete board_3;
return res;
}
bool parse_args (int argc, char *argv[], struct MindRoveInputParams *params, int *board_id)
{
bool board_id_found = false;
for (int i = 1; i < argc; i++)
{
if (std::string (argv[i]) == std::string ("--board-id"))
{
if (i + 1 < argc)
{
i++;
board_id_found = true;
*board_id = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-address"))
{
if (i + 1 < argc)
{
i++;
params->ip_address = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-address-aux"))
{
if (i + 1 < argc)
{
i++;
params->ip_address_aux = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-address-anc"))
{
if (i + 1 < argc)
{
i++;
params->ip_address_anc = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-port"))
{
if (i + 1 < argc)
{
i++;
params->ip_port = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-port-aux"))
{
if (i + 1 < argc)
{
i++;
params->ip_port_aux = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-port-anc"))
{
if (i + 1 < argc)
{
i++;
params->ip_port_anc = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--serial-port"))
{
if (i + 1 < argc)
{
i++;
params->serial_port = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-protocol"))
{
if (i + 1 < argc)
{
i++;
params->ip_protocol = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--timeout"))
{
if (i + 1 < argc)
{
i++;
params->timeout = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--other-info"))
{
if (i + 1 < argc)
{
i++;
params->other_info = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--mac-address"))
{
if (i + 1 < argc)
{
i++;
params->mac_address = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--serial-number"))
{
if (i + 1 < argc)
{
i++;
params->serial_number = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--file"))
{
if (i + 1 < argc)
{
i++;
params->file = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--file-aux"))
{
if (i + 1 < argc)
{
i++;
params->file_aux = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--file-anc"))
{
if (i + 1 < argc)
{
i++;
params->file_anc = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--master-board"))
{
if (i + 1 < argc)
{
i++;
params->master_board = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
}
if (!board_id_found)
{
std::cerr << "board id is not provided" << std::endl;
return false;
}
return true;
}
C++ Markers
#include <iostream>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "board_shim.h"
using namespace std;
bool parse_args (int argc, char *argv[], struct MindRoveInputParams *params, int *board_id);
int main (int argc, char *argv[])
{
BoardShim::enable_dev_board_logger ();
struct MindRoveInputParams params;
int board_id = 0;
if (!parse_args (argc, argv, ¶ms, &board_id))
{
return -1;
}
int res = 0;
BoardShim *board = new BoardShim (board_id, params);
try
{
board->prepare_session ();
board->start_stream ();
for (int i = 1; i < 5; i++)
{
board->insert_marker (i);
#ifdef _WIN32
Sleep (2000);
#else
sleep (2);
#endif
}
board->stop_stream ();
MindRoveArray<double, 2> data = board->get_board_data ();
board->release_session ();
std::cout << data << std::endl;
}
catch (const MindRoveException &err)
{
BoardShim::log_message ((int)LogLevels::LEVEL_ERROR, err.what ());
res = err.exit_code;
if (board->is_prepared ())
{
board->release_session ();
}
}
delete board;
return res;
}
bool parse_args (int argc, char *argv[], struct MindRoveInputParams *params, int *board_id)
{
bool board_id_found = false;
for (int i = 1; i < argc; i++)
{
if (std::string (argv[i]) == std::string ("--board-id"))
{
if (i + 1 < argc)
{
i++;
board_id_found = true;
*board_id = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-address"))
{
if (i + 1 < argc)
{
i++;
params->ip_address = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-port"))
{
if (i + 1 < argc)
{
i++;
params->ip_port = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--serial-port"))
{
if (i + 1 < argc)
{
i++;
params->serial_port = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-protocol"))
{
if (i + 1 < argc)
{
i++;
params->ip_protocol = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--timeout"))
{
if (i + 1 < argc)
{
i++;
params->timeout = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--other-info"))
{
if (i + 1 < argc)
{
i++;
params->other_info = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--mac-address"))
{
if (i + 1 < argc)
{
i++;
params->mac_address = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--serial-number"))
{
if (i + 1 < argc)
{
i++;
params->serial_number = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--file"))
{
if (i + 1 < argc)
{
i++;
params->file = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--master-board"))
{
if (i + 1 < argc)
{
i++;
params->master_board = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
}
if (!board_id_found)
{
std::cerr << "board id is not provided" << std::endl;
return false;
}
return true;
}
C++ Read Write File
#include <iostream>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "board_shim.h"
#include "data_filter.h"
using namespace std;
int main (int argc, char *argv[])
{
BoardShim::enable_dev_board_logger ();
struct MindRoveInputParams params;
int res = 0;
int board_id = (int)BoardIds::SYNTHETIC_BOARD;
// use synthetic board for demo
BoardShim *board = new BoardShim (board_id, params);
try
{
board->prepare_session ();
board->start_stream ();
#ifdef _WIN32
Sleep (5000);
#else
sleep (5);
#endif
board->stop_stream ();
MindRoveArray<double, 2> data = board->get_current_board_data (10);
board->release_session ();
std::cout << "Original data:" << std::endl << data << std::endl;
DataFilter::write_file (data, "test.csv", "w");
MindRoveArray<double, 2> restored_data = DataFilter::read_file ("test.csv");
std::cout << "Restored data:" << std::endl << restored_data << std::endl;
}
catch (const MindRoveException &err)
{
BoardShim::log_message ((int)LogLevels::LEVEL_ERROR, err.what ());
res = err.exit_code;
if (board->is_prepared ())
{
board->release_session ();
}
}
delete board;
return res;
}
C++ Downsample Data
#include <iostream>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "board_shim.h"
#include "data_filter.h"
using namespace std;
void print_one_row (double *data, int num_data_points);
int main (int argc, char *argv[])
{
BoardShim::enable_dev_board_logger ();
struct MindRoveInputParams params;
int res = 0;
int board_id = (int)BoardIds::SYNTHETIC_BOARD;
// use synthetic board for demo
BoardShim *board = new BoardShim (board_id, params);
try
{
board->prepare_session ();
board->start_stream ();
#ifdef _WIN32
Sleep (5000);
#else
sleep (5);
#endif
board->stop_stream ();
MindRoveArray<double, 2> data = board->get_board_data ();
board->release_session ();
double *downsampled_data = NULL;
int filtered_size = 0;
std::vector<int> eeg_channels = BoardShim::get_eeg_channels (board_id);
for (int i = 0; i < eeg_channels.size (); i++)
{
std::cout << "Data from :" << eeg_channels[i] << " before downsampling " << std::endl;
print_one_row (data.get_address (eeg_channels[i]), data.get_size (1));
// just for demo apply different downsampling algorithms to different channels
// downsampling here just aggregates data points
switch (i)
{
case 0:
downsampled_data =
DataFilter::perform_downsampling (data.get_address (eeg_channels[i]),
data.get_size (1), 2, (int)AggOperations::MEAN, &filtered_size);
break;
case 1:
downsampled_data =
DataFilter::perform_downsampling (data.get_address (eeg_channels[i]),
data.get_size (1), 3, (int)AggOperations::MEDIAN, &filtered_size);
break;
default:
downsampled_data =
DataFilter::perform_downsampling (data.get_address (eeg_channels[i]),
data.get_size (1), 2, (int)AggOperations::EACH, &filtered_size);
break;
}
std::cout << "Data from :" << eeg_channels[i] << " after downsampling " << std::endl;
print_one_row (downsampled_data, filtered_size);
delete[] downsampled_data;
}
}
catch (const MindRoveException &err)
{
BoardShim::log_message ((int)LogLevels::LEVEL_ERROR, err.what ());
res = err.exit_code;
if (board->is_prepared ())
{
board->release_session ();
}
}
delete board;
return res;
}
void print_one_row (double *data, int num_data_points)
{
// print only first 10 data points
int num_points = (num_data_points < 10) ? num_data_points : 10;
for (int i = 0; i < num_points; i++)
{
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
C++ Transforms
#include <iostream>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "board_shim.h"
#include "data_filter.h"
using namespace std;
void print_one_row (double *data, int num_data_points);
int main (int argc, char *argv[])
{
BoardShim::enable_dev_board_logger ();
struct MindRoveInputParams params;
int res = 0;
// use synthetic board for demo
BoardShim *board = new BoardShim ((int)BoardIds::SYNTHETIC_BOARD, params);
try
{
board->prepare_session ();
board->start_stream ();
#ifdef _WIN32
Sleep (10000);
#else
sleep (10);
#endif
board->stop_stream ();
MindRoveArray<double, 2> data = board->get_current_board_data (128);
board->release_session ();
std::cout << "Original data:" << std::endl << data << std::endl;
// apply filters
int sampling_rate = BoardShim::get_sampling_rate ((int)BoardIds::SYNTHETIC_BOARD);
std::vector<int> eeg_channels =
BoardShim::get_eeg_channels ((int)BoardIds::SYNTHETIC_BOARD);
int data_count = data.get_size (1);
for (int i = 0; i < eeg_channels.size (); i++)
{
// demo for wavelet transform
// std::pair of coeffs array in format[A(J) D(J) D(J-1) ..... D(1)] where J is a
// decomposition level, A - app coeffs, D - detailed coeffs, and array which stores
// length for each block, len of this array is decomposition_length + 1
std::pair<double *, int *> wavelet_output = DataFilter::perform_wavelet_transform (
data.get_address (eeg_channels[i]), data_count, (int)WaveletTypes::DB3, 3);
// you can do smth with wavelet coeffs here, for example denoising works via thresholds
// for wavelet coefficients
std::cout << "approximation coefficients:" << std::endl;
for (int i = 0; i < wavelet_output.second[0]; i++)
{
std::cout << wavelet_output.first[i] << " ";
}
std::cout << std::endl;
std::cout << "first block of detailed coefficients:" << std::endl;
for (int i = wavelet_output.second[0];
i < wavelet_output.second[0] + wavelet_output.second[1]; i++)
{
std::cout << wavelet_output.first[i] << " ";
}
std::cout << std::endl;
double *restored_data = DataFilter::perform_inverse_wavelet_transform (
wavelet_output, data_count, (int)WaveletTypes::DB3, 3);
std::cout << "Original data:" << std::endl;
print_one_row (data.get_address (eeg_channels[i]), data_count);
std::cout << "Restored after inverse wavelet transform data:" << std::endl;
print_one_row (restored_data, data_count);
delete[] wavelet_output.first;
delete[] restored_data;
delete[] wavelet_output.second;
// demo for fft
// data count must be power of 2 for fft!
int fft_len = 0;
std::complex<double> *fft_data =
DataFilter::perform_fft (data.get_address (eeg_channels[i]), data_count,
(int)WindowOperations::NO_WINDOW, &fft_len);
std::cout << "FFT coeffs:" << std::endl;
for (int i = 0; i < fft_len; i++)
{
std::cout << fft_data[i] << " ";
}
std::cout << std::endl;
int restored_len = 0;
double *restored_from_fft_data =
DataFilter::perform_ifft (fft_data, fft_len, &restored_len);
std::cout << "Restored after inverse fft transform data:" << std::endl;
print_one_row (restored_from_fft_data, data_count);
delete[] fft_data;
delete[] restored_from_fft_data;
}
}
catch (const MindRoveException &err)
{
BoardShim::log_message ((int)LogLevels::LEVEL_ERROR, err.what ());
res = err.exit_code;
if (board->is_prepared ())
{
board->release_session ();
}
}
delete board;
return res;
}
void print_one_row (double *data, int num_data_points)
{
for (int i = 0; i < num_data_points; i++)
{
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
C++ Signal Filtering
#include <iostream>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "board_shim.h"
#include "data_filter.h"
using namespace std;
int main (int argc, char *argv[])
{
BoardShim::enable_dev_board_logger ();
struct MindRoveInputParams params;
int res = 0;
int board_id = (int)BoardIds::SYNTHETIC_BOARD;
// use synthetic board for demo
BoardShim *board = new BoardShim (board_id, params);
try
{
board->prepare_session ();
board->start_stream ();
#ifdef _WIN32
Sleep (5000);
#else
sleep (5);
#endif
board->stop_stream ();
MindRoveArray<double, 2> data = board->get_board_data ();
board->release_session ();
std::cout << "Original data:" << std::endl << data << std::endl;
// apply filters
int sampling_rate = BoardShim::get_sampling_rate ((int)BoardIds::SYNTHETIC_BOARD);
std::vector<int> eeg_channels = BoardShim::get_eeg_channels (board_id);
for (int i = 0; i < eeg_channels.size (); i++)
{
switch (i)
{
// just for test and demo - apply different filters to different eeg channels
// signal filtering methods work in-place
case 0:
DataFilter::perform_lowpass (data.get_address (eeg_channels[i]),
data.get_size (1), BoardShim::get_sampling_rate (board_id), 50.0, 3,
(int)FilterTypes::BUTTERWORTH_ZERO_PHASE, 0);
break;
case 1:
DataFilter::perform_highpass (data.get_address (eeg_channels[i]),
data.get_size (1), BoardShim::get_sampling_rate (board_id), 3.0, 5,
(int)FilterTypes::CHEBYSHEV_TYPE_1_ZERO_PHASE, 1);
break;
case 2:
DataFilter::perform_bandpass (data.get_address (eeg_channels[i]),
data.get_size (1), BoardShim::get_sampling_rate (board_id), 3.0, 45.0, 3,
(int)FilterTypes::BESSEL_ZERO_PHASE, 0);
break;
case 3:
DataFilter::perform_bandstop (data.get_address (eeg_channels[i]),
data.get_size (1), BoardShim::get_sampling_rate (board_id), 48.0, 62.0, 4,
(int)FilterTypes::BUTTERWORTH, 0);
break;
default:
DataFilter::remove_environmental_noise (data.get_address (eeg_channels[i]),
data.get_size (1), BoardShim::get_sampling_rate (board_id),
(int)NoiseTypes::FIFTY);
break;
}
}
std::cout << "Filtered data:" << std::endl << data << std::endl;
}
catch (const MindRoveException &err)
{
BoardShim::log_message ((int)LogLevels::LEVEL_ERROR, err.what ());
res = err.exit_code;
if (board->is_prepared ())
{
board->release_session ();
}
}
delete board;
return res;
}
C++ Denoising
#include <iostream>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "board_shim.h"
#include "data_filter.h"
using namespace std;
int main (int argc, char *argv[])
{
BoardShim::enable_dev_board_logger ();
struct MindRoveInputParams params;
int res = 0;
int board_id = (int)BoardIds::SYNTHETIC_BOARD;
// use synthetic board for demo
BoardShim *board = new BoardShim (board_id, params);
try
{
board->prepare_session ();
board->start_stream ();
#ifdef _WIN32
Sleep (5000);
#else
sleep (5);
#endif
board->stop_stream ();
MindRoveArray<double, 2> data = board->get_board_data ();
board->release_session ();
std::cout << "Original data:" << std::endl << data << std::endl;
// apply filters
std::vector<int> eeg_channels = BoardShim::get_eeg_channels (board_id);
for (int i = 0; i < eeg_channels.size (); i++)
{
switch (i)
{
// for demo apply different methods to different channels
case 0:
DataFilter::perform_rolling_filter (data.get_address (eeg_channels[i]),
data.get_size (1), 3, (int)AggOperations::MEDIAN);
break;
case 1:
DataFilter::perform_rolling_filter (data.get_address (eeg_channels[i]),
data.get_size (1), 3, (int)AggOperations::MEAN);
break;
default:
// if moving average and moving median dont work well for your signal you can
// try wavelet based denoising, feel free to try different wavelet functions and
// decomposition levels
DataFilter::perform_wavelet_denoising (data.get_address (eeg_channels[i]),
data.get_size (1), (int)WaveletTypes::BIOR3_9, 3,
(int)WaveletDenoisingTypes::SURESHRINK, (int)ThresholdTypes::HARD,
(int)WaveletExtensionTypes::SYMMETRIC,
(int)NoiseEstimationLevelTypes::FIRST_LEVEL);
break;
}
}
std::cout << "Data after denoising:" << std::endl << data << std::endl;
}
catch (const MindRoveException &err)
{
BoardShim::log_message ((int)LogLevels::LEVEL_ERROR, err.what ());
res = err.exit_code;
if (board->is_prepared ())
{
board->release_session ();
}
}
delete board;
return res;
}
C++ Band Power
#include <iostream>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "board_shim.h"
#include "data_filter.h"
using namespace std;
int main (int argc, char *argv[])
{
BoardShim::enable_dev_board_logger ();
struct MindRoveInputParams params;
int res = 0;
int board_id = (int)BoardIds::SYNTHETIC_BOARD;
// use synthetic board for demo
BoardShim *board = new BoardShim (board_id, params);
try
{
board->prepare_session ();
board->start_stream ();
#ifdef _WIN32
Sleep (10000);
#else
sleep (10);
#endif
board->stop_stream ();
MindRoveArray<double, 2> data = board->get_board_data ();
board->release_session ();
std::cout << "Original data:" << std::endl << data << std::endl;
// calc band powers
json board_descr = BoardShim::get_board_descr (board_id);
int sampling_rate = (int)board_descr["sampling_rate"];
int fft_len = DataFilter::get_nearest_power_of_two (sampling_rate);
std::vector<int> eeg_channels = board_descr["eeg_channels"];
// for synthetic board second channel is a sine wave at 10 Hz, should see big alpha
int channel = eeg_channels[1];
// optional - detrend
DataFilter::detrend (
data.get_address (channel), data.get_size (1), (int)DetrendOperations::LINEAR);
std::cout << "Data after detrend:" << std::endl << data << std::endl;
int psd_len = 0;
std::pair<double *, double *> psd =
DataFilter::get_psd_welch (data.get_address (channel), data.get_size (1), fft_len,
fft_len / 2, sampling_rate, (int)WindowOperations::HANNING, &psd_len);
// calc band power
double band_power_alpha = DataFilter::get_band_power (psd, psd_len, 7.0, 13.0);
double band_power_beta = DataFilter::get_band_power (psd, psd_len, 14.0, 30.0);
std::cout << "alpha/beta:" << band_power_alpha / band_power_beta << std::endl;
delete[] psd.first;
delete[] psd.second;
}
catch (const MindRoveException &err)
{
BoardShim::log_message ((int)LogLevels::LEVEL_ERROR, err.what ());
res = err.exit_code;
if (board->is_prepared ())
{
board->release_session ();
}
}
delete board;
return res;
}
C++ EEG Metrics
#include <iostream>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "board_shim.h"
#include "data_filter.h"
#include "ml_model.h"
using namespace std;
bool parse_args (int argc, char *argv[], struct MindRoveInputParams *params, int *board_id);
int main (int argc, char *argv[])
{
BoardShim::enable_dev_board_logger ();
struct MindRoveInputParams params;
int board_id = 0;
if (!parse_args (argc, argv, ¶ms, &board_id))
{
return -1;
}
int res = 0;
BoardShim *board = new BoardShim (board_id, params);
try
{
board->prepare_session ();
board->start_stream ();
#ifdef _WIN32
Sleep (5000);
#else
sleep (5);
#endif
board->stop_stream ();
MindRoveArray<double, 2> data = board->get_board_data ();
board->release_session ();
std::cout << data << std::endl;
// calc band powers
int sampling_rate = BoardShim::get_sampling_rate ((int)BoardIds::SYNTHETIC_BOARD);
std::vector<int> eeg_channels = BoardShim::get_eeg_channels (board_id);
std::pair<double *, double *> bands =
DataFilter::get_avg_band_powers (data, eeg_channels, sampling_rate, true);
struct MindRoveModelParams mindfulness_params (
(int)MindRoveMetrics::MINDFULNESS, (int)MindRoveClassifiers::DEFAULT_CLASSIFIER);
MLModel mindfulness_model (mindfulness_params);
mindfulness_model.prepare ();
std::cout << "Mindfulness :" << mindfulness_model.predict (bands.first, 5)[0] << std::endl;
mindfulness_model.release ();
struct MindRoveModelParams restfulness_params (
(int)MindRoveMetrics::RESTFULNESS, (int)MindRoveClassifiers::DEFAULT_CLASSIFIER);
MLModel restfulness_model (restfulness_params);
restfulness_model.prepare ();
std::cout << "Restfulness :" << restfulness_model.predict (bands.first, 5)[0] << std::endl;
restfulness_model.release ();
delete[] bands.first;
delete[] bands.second;
}
catch (const MindRoveException &err)
{
BoardShim::log_message ((int)LogLevels::LEVEL_ERROR, err.what ());
res = err.exit_code;
if (board->is_prepared ())
{
board->release_session ();
}
}
delete board;
return res;
}
bool parse_args (int argc, char *argv[], struct MindRoveInputParams *params, int *board_id)
{
bool board_id_found = false;
for (int i = 1; i < argc; i++)
{
if (std::string (argv[i]) == std::string ("--board-id"))
{
if (i + 1 < argc)
{
i++;
board_id_found = true;
*board_id = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-address"))
{
if (i + 1 < argc)
{
i++;
params->ip_address = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-port"))
{
if (i + 1 < argc)
{
i++;
params->ip_port = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--serial-port"))
{
if (i + 1 < argc)
{
i++;
params->serial_port = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--ip-protocol"))
{
if (i + 1 < argc)
{
i++;
params->ip_protocol = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--timeout"))
{
if (i + 1 < argc)
{
i++;
params->timeout = std::stoi (std::string (argv[i]));
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--other-info"))
{
if (i + 1 < argc)
{
i++;
params->other_info = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--mac-address"))
{
if (i + 1 < argc)
{
i++;
params->mac_address = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--serial-number"))
{
if (i + 1 < argc)
{
i++;
params->serial_number = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
if (std::string (argv[i]) == std::string ("--file"))
{
if (i + 1 < argc)
{
i++;
params->file = std::string (argv[i]);
}
else
{
std::cerr << "missed argument" << std::endl;
return false;
}
}
}
if (!board_id_found)
{
std::cerr << "board id is not provided" << std::endl;
return false;
}
return true;
}
C++ ICA
#include <iostream>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include "board_shim.h"
#include "data_filter.h"
using namespace std;
int main (int argc, char *argv[])
{
BoardShim::enable_dev_board_logger ();
struct MindRoveInputParams params;
int res = 0;
int board_id = (int)BoardIds::SYNTHETIC_BOARD;
std::vector<int> eeg_channels = BoardShim::get_eeg_channels (board_id);
int channel_to_use = eeg_channels[4];
// use synthetic board for demo
BoardShim *board = new BoardShim (board_id, params);
try
{
board->prepare_session ();
board->start_stream ();
#ifdef _WIN32
Sleep (10000);
#else
sleep (10);
#endif
board->stop_stream ();
MindRoveArray<double, 2> data =
board->get_board_data (500, (int)MindRovePresets::DEFAULT_PRESET);
board->release_session ();
MindRoveArray<double, 2> data_reshaped (data.get_address (channel_to_use), 5, 100);
std::tuple<MindRoveArray<double, 2>, MindRoveArray<double, 2>, MindRoveArray<double, 2>,
MindRoveArray<double, 2>>
returned_matrixes = DataFilter::perform_ica (data_reshaped, 2);
std::cout << std::get<3> (returned_matrixes) << std::endl;
}
catch (const MindRoveException &err)
{
BoardShim::log_message ((int)LogLevels::LEVEL_ERROR, err.what ());
res = err.exit_code;
if (board->is_prepared ())
{
board->release_session ();
}
}
delete board;
return res;
}
Matlab
Matlab Get Data from a Board
BoardShim.set_log_file('mindrove.log');
BoardShim.enable_dev_board_logger();
params = MindRoveInputParams();
board_shim = BoardShim(int32(BoardIds.SYNTHETIC_BOARD), params);
preset = int32(MindRovePresets.DEFAULT_PRESET);
board_shim.prepare_session();
board_shim.add_streamer('file://data_default.csv:w', preset);
board_shim.start_stream(45000, '');
pause(5);
board_shim.stop_stream();
data = board_shim.get_current_board_data(10, preset);
disp(data);
board_shim.release_session();
Matlab Markers
BoardShim.set_log_file('mindrove.log');
BoardShim.enable_dev_board_logger();
params = MindRoveInputParams();
board_shim = BoardShim(int32(BoardIds.SYNTHETIC_BOARD), params);
preset = int32(MindRovePresets.DEFAULT_PRESET);
board_shim.prepare_session();
board_shim.start_stream(45000, '');
pause(2);
board_shim.insert_marker(1, preset);
pause(2);
board_shim.stop_stream();
data = board_shim.get_board_data(board_shim.get_board_data_count(preset), preset);
disp(data);
board_shim.release_session();
Matlab Read Write File
BoardShim.set_log_file('mindrove.log');
BoardShim.enable_dev_board_logger();
params = MindRoveInputParams();
board_shim = BoardShim(int32(BoardIds.SYNTHETIC_BOARD), params);
preset = int32(MindRovePresets.DEFAULT_PRESET);
board_shim.prepare_session();
board_shim.start_stream(45000, '');
pause(2)
board_shim.stop_stream()
data = board_shim.get_current_board_data(20, preset);
board_shim.release_session();
DataFilter.write_file(data, 'data.csv', 'w');
restored_data = DataFilter.read_file('data.csv');
Matlab Transforms
BoardShim.set_log_file('mindrove.log');
BoardShim.enable_dev_board_logger();
params = MindRoveInputParams();
board_shim = BoardShim(int32(BoardIds.SYNTHETIC_BOARD), params);
preset = int32(MindRovePresets.DEFAULT_PRESET);
sampling_rate = BoardShim.get_sampling_rate(int32(BoardIds.SYNTHETIC_BOARD), preset);
board_shim.prepare_session();
board_shim.start_stream(45000, '');
pause(5);
board_shim.stop_stream();
data = board_shim.get_current_board_data(256, preset);
board_shim.release_session();
eeg_channels = BoardShim.get_eeg_channels(int32(BoardIds.SYNTHETIC_BOARD), preset);
% wavelet for first eeg channel %
first_eeg_channel = eeg_channels(1);
original_data = data(first_eeg_channel, :);
[wavelet_data, wavelet_lenghts] = DataFilter.perform_wavelet_transform(original_data, int32(WaveletTypes.DB3), 3, int32(WaveletExtensionTypes.SYMMETRIC));
restored_data = DataFilter.perform_inverse_wavelet_transform(wavelet_data, wavelet_lenghts, size(original_data, 2), int32(WaveletTypes.DB3), 3, int32(WaveletExtensionTypes.SYMMETRIC));
% fft for first eeg channel %
fft_data = DataFilter.perform_fft(original_data, int32(WindowOperations.NO_WINDOW));
restored_fft_data = DataFilter.perform_ifft(fft_data);
Matlab Signal Filtering
BoardShim.set_log_file('mindrove.log');
BoardShim.enable_dev_board_logger();
params = MindRoveInputParams();
board_shim = BoardShim(int32(BoardIds.SYNTHETIC_BOARD), params);
preset = int32(MindRovePresets.DEFAULT_PRESET);
board_shim.prepare_session();
board_shim.start_stream(45000, '');
pause(5);
board_shim.stop_stream();
data = board_shim.get_current_board_data(64, preset);
board_shim.release_session();
eeg_channels = BoardShim.get_eeg_channels(int32(BoardIds.SYNTHETIC_BOARD), preset);
% apply iir filter to the first eeg channel %
first_eeg_channel = eeg_channels(1);
original_data = data(first_eeg_channel, :);
sampling_rate = BoardShim.get_sampling_rate(int32(BoardIds.SYNTHETIC_BOARD), preset);
filtered_data = DataFilter.perform_lowpass(original_data, sampling_rate, 50.0, 3, int32(FilterTypes.BUTTERWORTH), 0.0);
Matlab Denoising
BoardShim.set_log_file('mindrove.log');
BoardShim.enable_dev_board_logger();
params = MindRoveInputParams();
board_shim = BoardShim(int32(BoardIds.SYNTHETIC_BOARD), params);
preset = int32(MindRovePresets.DEFAULT_PRESET);
board_shim.prepare_session();
board_shim.start_stream(45000, '');
pause(5);
board_shim.stop_stream();
data = board_shim.get_current_board_data(64, preset);
board_shim.release_session();
eeg_channels = BoardShim.get_eeg_channels(int32(BoardIds.SYNTHETIC_BOARD), preset);
% apply wavelet denoising to the first eeg channel %
first_eeg_channel = eeg_channels(1);
noisy_data = data(first_eeg_channel, :);
denoised_data = DataFilter.perform_wavelet_denoising(noisy_data, int32(WaveletTypes.DB3), 3, int32(WaveletDenoisingTypes.SURESHRINK), int32(ThresholdTypes.HARD), int32(WaveletExtensionTypes.SYMMETRIC), int32(NoiseEstimationLevelTypes.FIRST_LEVEL));
Matlab Band Power
BoardShim.enable_dev_board_logger();
params = MindRoveInputParams();
board_shim = BoardShim(int32(BoardIds.SYNTHETIC_BOARD), params);
board_id = int32(BoardIds.SYNTHETIC_BOARD);
preset = int32(MindRovePresets.DEFAULT_PRESET);
board_descr = BoardShim.get_board_descr(board_id, preset);
sampling_rate = int32(board_descr.sampling_rate);
board_shim.prepare_session();
board_shim.start_stream(45000, '');
pause(10);
board_shim.stop_stream();
nfft = DataFilter.get_nearest_power_of_two(sampling_rate);
data = board_shim.get_board_data(board_shim.get_board_data_count(preset), preset);
board_shim.release_session();
eeg_channels = board_descr.eeg_channels;
eeg_channel = eeg_channels(3);
original_data = data(eeg_channel, :);
detrended = DataFilter.detrend(original_data, int32(DetrendOperations.LINEAR));
[ampls, freqs] = DataFilter.get_psd_welch(detrended, nfft, nfft / 2, sampling_rate, int32(WindowOperations.HANNING));
band_power_alpha = DataFilter.get_band_power(ampls, freqs, 7.0, 13.0);
band_power_beta = DataFilter.get_band_power(ampls, freqs, 14.0, 30.0);
ratio = band_power_alpha / band_power_beta;
Matlab EEG Metrics
BoardShim.set_log_file('mindrove.log');
MLModel.set_log_file('mindrove_ml.log');
BoardShim.enable_dev_board_logger();
params = MindRoveInputParams();
board_shim = BoardShim(int32(BoardIds.SYNTHETIC_BOARD), params);
preset = int32(MindRovePresets.DEFAULT_PRESET);
sampling_rate = BoardShim.get_sampling_rate(int32(BoardIds.SYNTHETIC_BOARD), preset);
board_shim.prepare_session();
board_shim.start_stream(45000, '');
pause(5);
board_shim.stop_stream();
nfft = DataFilter.get_nearest_power_of_two(sampling_rate);
data = board_shim.get_board_data(board_shim.get_board_data_count(preset), preset);
board_shim.release_session();
eeg_channels = BoardShim.get_eeg_channels(int32(BoardIds.SYNTHETIC_BOARD), preset);
[avgs, stddevs] = DataFilter.get_avg_band_powers(data, eeg_channels, sampling_rate, true);
feature_vector = avgs;
model_params = MindRoveModelParams(int32(MindRoveMetrics.RESTFULNESS), int32(MindRoveClassifiers.DEFAULT_CLASSIFIER));
model = MLModel(model_params);
model.prepare();
score = model.predict(feature_vector);
model.release();
Matlab ICA
params = MindRoveInputParams();
board_shim = BoardShim(int32(BoardIds.SYNTHETIC_BOARD), params);
preset = int32(MindRovePresets.DEFAULT_PRESET);
board_shim.prepare_session();
board_shim.start_stream(45000, '');
pause(10);
board_shim.stop_stream();
data = board_shim.get_board_data(500, preset);
board_shim.release_session();
eeg_channels = BoardShim.get_eeg_channels(int32(BoardIds.SYNTHETIC_BOARD), preset);
selected_channel = eeg_channels(4);
original_data = data(selected_channel, :);
original_data = transpose(reshape(original_data, [100, 5]));
[w,k,a,s] = DataFilter.perform_ica(original_data, 2);