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, &params, &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, &params, &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, &params, &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);